rtx
mn10300_legitimize_pic_address (rtx orig, rtx reg)
{
+ rtx x;
+
if (GET_CODE (orig) == LABEL_REF
|| (GET_CODE (orig) == SYMBOL_REF
&& (CONSTANT_POOL_ADDRESS_P (orig)
|| ! MN10300_GLOBAL_P (orig))))
{
- if (reg == 0)
+ if (reg == NULL)
reg = gen_reg_rtx (Pmode);
- emit_insn (gen_symGOTOFF2reg (reg, orig));
- return reg;
+ x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOTOFF);
+ x = gen_rtx_CONST (SImode, x);
+ emit_move_insn (reg, x);
+
+ x = emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
}
else if (GET_CODE (orig) == SYMBOL_REF)
{
- if (reg == 0)
+ if (reg == NULL)
reg = gen_reg_rtx (Pmode);
- emit_insn (gen_symGOT2reg (reg, orig));
- return reg;
+ x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOT);
+ x = gen_rtx_CONST (SImode, x);
+ x = gen_rtx_PLUS (SImode, pic_offset_table_rtx, x);
+ x = gen_const_mem (SImode, x);
+
+ x = emit_move_insn (reg, x);
}
- return orig;
+ else
+ return orig;
+
+ set_unique_reg_note (x, REG_EQUAL, orig);
+ return reg;
}
/* Return zero if X references a SYMBOL_REF or LABEL_REF whose symbol
[(call (match_operand:QI 0 "general_operand")
(match_operand:SI 1 "general_operand"))]
""
- "
{
- if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
+ rtx fn = XEXP (operands[0], 0);
+
+ if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
{
- if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
+ if (MN10300_GLOBAL_P (fn))
{
/* The PLT code won't run on AM30, but then, there's no
shared library support for AM30 either, so we just assume
the linker is going to adjust all @PLT relocs to the
actual symbols. */
emit_use (pic_offset_table_rtx);
- XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
+ fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
}
else
- XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
+ fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
}
- if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
- XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
- emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
- DONE;
-}")
+ if (! call_address_operand (fn, VOIDmode))
+ fn = force_reg (SImode, fn);
+
+ XEXP (operands[0], 0) = fn;
+})
-;; NB: Mode on match_operand 0 deliberately omitted in
-;; order to be able to match UNSPECs in PIC mode.
-(define_insn "call_internal"
- [(call (mem:QI (match_operand 0 "call_address_operand" "a,S"))
- (match_operand:SI 1 "general_operand" "g,g"))]
+(define_insn "*call_internal"
+ [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S"))
+ (match_operand:SI 1 "" ""))]
""
"@
calls %C0
(call (match_operand:QI 1 "general_operand")
(match_operand:SI 2 "general_operand")))]
""
- "
{
- if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
+ rtx fn = XEXP (operands[1], 0);
+
+ if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
{
- if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
+ if (MN10300_GLOBAL_P (fn))
{
/* The PLT code won't run on AM30, but then, there's no
shared library support for AM30 either, so we just assume
the linker is going to adjust all @PLT relocs to the
actual symbols. */
emit_use (pic_offset_table_rtx);
- XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
+ fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
}
else
- XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
+ fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
}
- if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
- XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
- emit_call_insn (gen_call_value_internal (operands[0],
- XEXP (operands[1], 0),
- operands[2]));
- DONE;
-}")
+ if (! call_address_operand (fn, VOIDmode))
+ fn = force_reg (SImode, fn);
+
+ XEXP (operands[1], 0) = fn;
+})
-;; NB: Mode on match_operands 0 and 1 deliberately omitted
-;; in order to be able to match UNSPECs in PIC mode.
(define_insn "call_value_internal"
- [(set (match_operand 0 "register_operand" "=dax,dax")
- (call (mem:QI (match_operand 1 "call_address_operand" "a,S"))
- (match_operand:SI 2 "general_operand" "g,g")))]
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S"))
+ (match_operand:SI 2 "" "")))]
""
"@
calls %C1
""
"operands[3] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);"
)
-
-(define_expand "symGOT2reg"
- [(match_operand:SI 0 "")
- (match_operand:SI 1 "")]
- ""
- "
-{
- rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
-
- MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
-
- set_unique_reg_note (insn, REG_EQUAL, operands[1]);
-
- DONE;
-}")
-
-(define_expand "symGOT2reg_i"
- [(set (match_operand:SI 0 "")
- (mem:SI (plus:SI (reg:SI PIC_REG)
- (const (unspec [(match_operand:SI 1 "")]
- UNSPEC_GOT)))))]
- ""
- "")
-
-(define_expand "symGOTOFF2reg"
- [(match_operand:SI 0 "") (match_operand:SI 1 "")]
- ""
- "
-{
- rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
-
- set_unique_reg_note (insn, REG_EQUAL, operands[1]);
-
- DONE;
-}")
-
-(define_expand "symGOTOFF2reg_i"
- [(set (match_operand:SI 0 "")
- (const (unspec [(match_operand:SI 1 "")] UNSPEC_GOTOFF)))
- (parallel [(set (match_dup 0)
- (plus:SI (match_dup 0)
- (reg:SI PIC_REG)))
- (clobber (reg:CC CC_REG))
- ])
- ]
- ""
- "")
-
-(define_expand "sym2PIC"
- [(unspec [(match_operand:SI 0 "")] UNSPEC_PIC)]
- "" "")
-
-(define_expand "sym2PLT"
- [(unspec [(match_operand:SI 0 "")] UNSPEC_PLT)]
- "" "")