;; Machine Description for Altera Nios II.
-;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2012-2024 Free Software Foundation, Inc.
;; Contributed by Jonah Graham (jgraham@altera.com) and
;; Will Reece (wreece@altera.com).
;; Contributed by Mentor Graphics, Inc.
UNSPECV_CUSTOM_XNXX
UNSPECV_LDXIO
UNSPECV_STXIO
+ UNSPECV_RDPRS
+ UNSPECV_FLUSHD
+ UNSPECV_FLUSHDA
+ UNSPECV_WRPIE
+ UNSPECV_ENI
+ UNSPECV_LDEX
+ UNSPECV_LDSEX
+ UNSPECV_STEX
+ UNSPECV_STSEX
])
(define_c_enum "unspec" [
"addi\\t%0, %1, %L2"
[(set_attr "type" "alu")])
-(define_insn "movqi_internal"
+(define_insn_and_split "movqi_internal"
[(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r")
(match_operand:QI 1 "general_operand" "rM,m,rI"))]
"(register_operand (operands[0], QImode)
gcc_unreachable ();
}
}
+ "(nios2_large_constant_memory_operand_p (operands[0])
+ || nios2_large_constant_memory_operand_p (operands[1]))"
+ [(set (match_dup 0) (match_dup 1))]
+ {
+ if (nios2_large_constant_memory_operand_p (operands[0]))
+ operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+ else
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "st,ld,mov")])
-(define_insn "movhi_internal"
+(define_insn_and_split "movhi_internal"
[(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r")
(match_operand:HI 1 "general_operand" "rM,m,rI"))]
"(register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode))"
- "@
- sth%o0%.\\t%z1, %0
- ldhu%o1%.\\t%0, %1
- mov%i1%.\\t%0, %z1"
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ return "sth%o0%.\\t%z1, %0";
+ case 1:
+ return "ldhu%o1%.\\t%0, %1";
+ case 2:
+ return "mov%i1%.\\t%0, %z1";
+ default:
+ gcc_unreachable ();
+ }
+ }
+ "(nios2_large_constant_memory_operand_p (operands[0])
+ || nios2_large_constant_memory_operand_p (operands[1]))"
+ [(set (match_dup 0) (match_dup 1))]
+ {
+ if (nios2_large_constant_memory_operand_p (operands[0]))
+ operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+ else
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "st,ld,mov")])
-(define_insn "movsi_internal"
+(define_insn_and_split "movsi_internal"
[(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r")
(match_operand:SI 1 "general_operand" "rM,m,rIJK,S"))]
"(register_operand (operands[0], SImode)
gcc_unreachable ();
}
}
+ "(nios2_large_constant_memory_operand_p (operands[0])
+ || nios2_large_constant_memory_operand_p (operands[1])
+ || (nios2_large_constant_p (operands[1])
+ && !(CONST_INT_P (operands[1])
+ && (SMALL_INT_UNSIGNED (INTVAL (operands[1]))
+ || UPPER16_INT (INTVAL (operands[1]))))))"
+ [(set (match_dup 0) (match_dup 1))]
+ {
+ if (nios2_large_constant_memory_operand_p (operands[0]))
+ operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+ else if (nios2_large_constant_memory_operand_p (operands[1]))
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ else
+ operands[1] = nios2_split_large_constant (operands[1], operands[0]);
+ }
[(set_attr "type" "st,ld,mov,alu")])
(define_mode_iterator BH [QI HI])
(define_mode_attr bhw [(QI "b") (HI "h") (SI "w")])
(define_mode_attr bhw_uns [(QI "bu") (HI "hu") (SI "w")])
-(define_insn "ld<bhw_uns>io"
+(define_insn_and_split "ld<bhw_uns>io"
[(set (match_operand:BHW 0 "register_operand" "=r")
(unspec_volatile:BHW
[(match_operand:BHW 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO))]
""
"ld<bhw_uns>io\\t%0, %1"
+ "nios2_large_constant_memory_operand_p (operands[1])"
+ [(set (match_dup 0)
+ (unspec_volatile:BHW [(match_dup 1)] UNSPECV_LDXIO))]
+ {
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "ld")])
(define_expand "ld<bh>io"
DONE;
})
-(define_insn "ld<bh>io_signed"
+(define_insn_and_split "ld<bh>io_signed"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(unspec_volatile:BH
[(match_operand:BH 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO)))]
""
"ld<bh>io\\t%0, %1"
+ "nios2_large_constant_memory_operand_p (operands[1])"
+ [(set (match_dup 0)
+ (sign_extend:SI (unspec_volatile:BH [(match_dup 1)] UNSPECV_LDXIO)))]
+ {
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "ld")])
-(define_insn "st<bhw>io"
+(define_insn_and_split "st<bhw>io"
[(set (match_operand:BHW 0 "ldstio_memory_operand" "=w")
(unspec_volatile:BHW
[(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))]
""
"st<bhw>io\\t%z1, %0"
+ "nios2_large_constant_memory_operand_p (operands[0])"
+ [(set (match_dup 0) (unspec_volatile:BHW [(match_dup 1)] UNSPECV_STXIO))]
+ {
+ operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+ }
[(set_attr "type" "st")])
\f
(define_mode_iterator QX [HI SI])
;; Zero extension patterns
-(define_insn "zero_extendhisi2"
+(define_insn_and_split "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
""
"@
andi%.\\t%0, %1, 0xffff
ldhu%o1%.\\t%0, %1"
+ "nios2_large_constant_memory_operand_p (operands[1])"
+ [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
+ {
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "and,ld")])
-(define_insn "zero_extendqi<mode>2"
+(define_insn_and_split "zero_extendqi<mode>2"
[(set (match_operand:QX 0 "register_operand" "=r,r")
(zero_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
""
"@
andi%.\\t%0, %1, 0xff
ldbu%o1%.\\t%0, %1"
+ "nios2_large_constant_memory_operand_p (operands[1])"
+ [(set (match_dup 0) (zero_extend:QX (match_dup 1)))]
+ {
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "and,ld")])
;; Sign extension patterns
-(define_insn "extendhisi2"
+(define_insn_and_split "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
""
"@
#
ldh%o1%.\\t%0, %1"
+ "nios2_large_constant_memory_operand_p (operands[1])"
+ [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
+ {
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "alu,ld")])
-(define_insn "extendqi<mode>2"
+(define_insn_and_split "extendqi<mode>2"
[(set (match_operand:QX 0 "register_operand" "=r,r")
(sign_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
""
"@
#
ldb%o1%.\\t%0, %1"
+ "nios2_large_constant_memory_operand_p (operands[1])"
+ [(set (match_dup 0) (sign_extend:QX (match_dup 1)))]
+ {
+ operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+ }
[(set_attr "type" "alu,ld")])
;; Split patterns for register alternative cases.
(define_expand "return"
[(simple_return)]
"nios2_can_use_return_insn ()"
- "")
+{
+ if (nios2_expand_return ())
+ DONE;
+})
(define_insn "simple_return"
[(simple_return)]
"wrctl\\tctl%0, %z1"
[(set_attr "type" "control")])
+(define_insn "rdprs"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")
+ (match_operand:SI 2 "arith_operand" "U")]
+ UNSPECV_RDPRS))]
+ ""
+ "rdprs\\t%0, %1, %2"
+ [(set_attr "type" "control")])
+
+;; Cache Instructions
+
+(define_insn "flushd"
+ [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
+ UNSPECV_FLUSHD)]
+ ""
+ "flushd\\t%0"
+ [(set_attr "type" "control")])
+
+(define_insn "flushda"
+ [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
+ UNSPECV_FLUSHDA)]
+ ""
+ "flushda\\t%0"
+ [(set_attr "type" "control")])
+
+;; R2 Instructions
+
+(define_insn "wrpie"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")]
+ UNSPECV_WRPIE))]
+ "TARGET_ARCH_R2"
+ "wrpie\\t%0, %1"
+ [(set_attr "type" "control")])
+
+(define_insn "eni"
+ [(unspec:VOID [(match_operand 0 "const_int_operand" "i")]
+ UNSPECV_ENI)]
+ "TARGET_ARCH_R2"
+ "eni\\t%0"
+ [(set_attr "type" "control")])
+
;; Trap patterns
(define_insn "trap"
[(trap_if (const_int 1) (const_int 3))]
emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO));
DONE;
})
+
+;; Synchronization Primitives
+(include "sync.md")
+
+;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes.
+(include "ldstwm.md")
+