;; UNSPEC usage:
(define_constants
- [(UNSPEC_SIN 1)
- (UNSPEC_COS 2)
+ [(UNSPEC_SIN 1)
+ (UNSPEC_COS 2)
+ (UNSPEC_GOT 3)
])
;; UNSPEC_VOLATILE usage:
(define_constants
[(D0_REG 0)
(A0_REG 8)
+ (A1_REG 9)
+ (PIC_REG 13)
(SP_REG 15)
+ (FP0_REG 16)
])
(include "predicates.md")
""
"nop")
+(define_expand "prologue"
+ [(const_int 0)]
+ ""
+{
+ m68k_expand_prologue ();
+ DONE;
+})
+
+(define_expand "epilogue"
+ [(return)]
+ ""
+{
+ m68k_expand_epilogue ();
+ DONE;
+})
+
;; Used for frameless functions which save no regs and allocate no locals.
-(define_insn "return"
+(define_expand "return"
[(return)]
"m68k_use_return_insn ()"
+ "")
+
+(define_insn "*return"
+ [(return)]
+ ""
{
- if (current_function_pops_args == 0)
+ if (m68k_interrupt_function_p (current_function_decl))
+ return "rte";
+ else if (current_function_pops_args)
+ {
+ operands[0] = GEN_INT (current_function_pops_args);
+ return "rtd %0";
+ }
+ else
return "rts";
- operands[0] = GEN_INT (current_function_pops_args);
- return "rtd %0";
+})
+
+(define_insn "*m68k_store_multiple"
+ [(match_parallel 0 "" [(match_operand 1 "")])]
+ "m68k_movem_pattern_p (operands[0], NULL, 0, true)"
+{
+ return m68k_output_movem (operands, operands[0], 0, true);
+})
+
+(define_insn "*m68k_store_multiple_automod"
+ [(match_parallel 0 ""
+ [(set (match_operand:SI 1 "register_operand" "=a")
+ (plus:SI (match_operand:SI 2 "register_operand" "1")
+ (match_operand:SI 3 "const_int_operand")))])]
+ "m68k_movem_pattern_p (operands[0], operands[1], INTVAL (operands[3]), true)"
+{
+ return m68k_output_movem (operands, operands[0], INTVAL (operands[3]), true);
+})
+
+(define_insn "*m68k_load_multiple"
+ [(match_parallel 0 "" [(match_operand 1 "")])]
+ "m68k_movem_pattern_p (operands[0], NULL, 0, false)"
+{
+ return m68k_output_movem (operands, operands[0], 0, false);
+})
+
+(define_insn "*m68k_load_multiple_automod"
+ [(match_parallel 0 ""
+ [(set (match_operand:SI 1 "register_operand" "=a")
+ (plus:SI (match_operand:SI 2 "register_operand" "1")
+ (match_operand:SI 3 "const_int_operand")))])]
+ "m68k_movem_pattern_p (operands[0], operands[1],
+ INTVAL (operands[3]), false)"
+{
+ return m68k_output_movem (operands, operands[0],
+ INTVAL (operands[3]), false);
+})
+
+(define_expand "link"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand")
+ (plus:SI (reg:SI SP_REG) (const_int -4)))
+ (set (match_dup 2)
+ (match_dup 0))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 1 "const_int_operand")))])]
+ "TARGET_68020 || INTVAL (operands[1]) >= -0x8004"
+{
+ operands[2] = gen_frame_mem (SImode, plus_constant (stack_pointer_rtx, -4));
+})
+
+(define_insn "*link"
+ [(set (match_operand:SI 0 "register_operand" "+r")
+ (plus:SI (reg:SI SP_REG) (const_int -4)))
+ (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
+ (match_dup 0))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 1 "const_int_operand")))]
+ "TARGET_68020 || INTVAL (operands[1]) >= -0x8004"
+{
+ operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
+ if (!MOTOROLA)
+ return "link %0,%1";
+ else if (INTVAL (operands[1]) >= -0x8000)
+ return "link.w %0,%1";
+ else
+ return "link.l %0,%1";
+})
+
+(define_expand "unlink"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand")
+ (match_dup 1))
+ (set (reg:SI SP_REG)
+ (plus:SI (match_dup 0)
+ (const_int 4)))])]
+ ""
+{
+ operands[1] = gen_frame_mem (SImode, copy_rtx (operands[0]));
+})
+
+(define_insn "*unlink"
+ [(set (match_operand:SI 0 "register_operand" "+r")
+ (mem:SI (match_dup 0)))
+ (set (reg:SI SP_REG)
+ (plus:SI (match_dup 0)
+ (const_int 4)))]
+ ""
+ "unlk %0")
+
+(define_insn "load_got"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(const_int 0)] UNSPEC_GOT))]
+ ""
+{
+ if (TARGET_ID_SHARED_LIBRARY)
+ {
+ operands[1] = gen_rtx_REG (Pmode, PIC_REG);
+ return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
+ }
+ else if (MOTOROLA)
+ {
+ if (TARGET_COLDFIRE)
+ /* Load the full 32-bit PC-relative offset of
+ _GLOBAL_OFFSET_TABLE_ into the PIC register, then use it to
+ calculate the absolute value. The offset and "lea"
+ operation word together occupy 6 bytes. */
+ return ("move.l #_GLOBAL_OFFSET_TABLE_@GOTPC, %0\n\t"
+ "lea (-6, %%pc, %0), %0");
+ else
+ return "lea (%%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %0";
+ }
+ else
+ return ("movel #_GLOBAL_OFFSET_TABLE_, %0\n\t"
+ "lea %%pc@(0,%0:l),%0");
})
(define_insn "indirect_jump"