[multiple changes]
2003-06-16 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.c (mn10300_unspec_int_label_counter): Moved from... * config/mn10300/mn10300.md (GOTaddr2picreg): ... here. * config/mn10300/mn10300.h: GTY-declare it. 2003-06-11 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.c (mn10300_encode_section_info): Fix prototype. Use incoming RTL argument. 2002-12-12 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.md (int_label): Move C statements... (GOTaddr2picreg): ... here. 2002-08-15 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.h (ENCODE_SECTION_INFO): Move... * config/mn10300/mn10300.c (mn10300_encode_section_info): ... here. New function.(TARGET_ENCODE_SECTION_INFO): Define to it. 2001-11-04 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.md (builtin_setjmp_receiver): Fix typo in pattern name. (mn10300_loadPC): Define as insn splittable after reload. 2001-05-13 Alexandre Oliva <aoliva@redhat.com> * config/sh/mn10300.h (JUMP_TABLES_IN_TEXT_SECTION): Let them be defined in .rodata even in PIC, now that the assembler supports that. 2001-05-09 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300.h (GOT_SYMBOL_NAME): Don't let the symbol take an underscore prefix. 2001-04-14 Alexandre Oliva <aoliva@redhat.com> * config/mn10300/mn10300-protos.h (legitimate_pic_operand_p, legitimize_pic_address): Declare. * config/mn10300/mn10300.h (CONDITIONAL_REGISTER_USAGE): Mark the PIC register as fixed. (EXTRA_CONSTRAINT): Match UNSPEC_PLT and UNSPEC_PIC for 'S'. (GO_IF_LEGITIMATE_ADDRESS): Require legitimate_pic_operand for PIC. (LEGITIMATE_PIC_OPERAND_P): Define. (PIC_OFFSET_TABLE_REGNUM): Define. (GOT_SYMBOL_NAME): Define. (SYMBOLIC_CONST_P): Define. (ENCODE_SECTION_INFO): Use SYMBOL_REF_FLAG to mark local symbols. (MN10300_GLOBAL_P): Test it. (OUTPUT_ADDR_CONST_EXTRA): Handle PIC-related unspecs. (JUMP_TABLES_IN_TEXT_SECTION): Enable for PIC. * config/mn10300/mn10300.c (print_operand): Handle unspec. (expand_prologue): Set PIC register. (call_address_operand): Don't match SYMBOL_REFs in PIC. (legitimize_address): Call legitimize_pic_address. (legitimize_pic_address): New fn. (legitimate_pic_operand_p): New fn. * config/mn10300/mn10300.md (PIC_REG, SP_REG): New constants. (UNSPEC_INT_LABEL, UNSPEC_PIC, UNSPEC_GOT, UNSPEC_GOTOFF, UNSPEC_PLT): New constants. (pop_pic_reg): New insn. (movsi): Adjust non-PIC addresses. (builtin_setjmp_receiver): Restore the PIC register. (casesi): New insn. (call): Adjust non-PIC addresses. (int_label, GOTaddr2picreg): New expands. (am33_loadPC): New insn. (mn10300_loadPC): New expand. (call_next_insn): New insn. (add_GOT_to_pic_reg): New expand. (symGOT2reg, symGOT2reg_i): New expands. (symGOTOFF2reg, symGOTOFF2reg_i): New expands. (sym2PIC, sym2PLT): New expands. From-SVN: r69169
This commit is contained in:
parent
e7f042e4cd
commit
d177606965
5 changed files with 498 additions and 1 deletions
|
@ -1,3 +1,72 @@
|
|||
2003-07-09 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
2003-06-16 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.c (mn10300_unspec_int_label_counter):
|
||||
Moved from...
|
||||
* config/mn10300/mn10300.md (GOTaddr2picreg): ... here.
|
||||
* config/mn10300/mn10300.h: GTY-declare it.
|
||||
2003-06-11 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.c (mn10300_encode_section_info): Fix
|
||||
prototype. Use incoming RTL argument.
|
||||
2002-12-12 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.md (int_label): Move C statements...
|
||||
(GOTaddr2picreg): ... here.
|
||||
2002-08-15 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.h (ENCODE_SECTION_INFO): Move...
|
||||
* config/mn10300/mn10300.c (mn10300_encode_section_info):
|
||||
... here. New function.
|
||||
(TARGET_ENCODE_SECTION_INFO): Define to it.
|
||||
2001-11-04 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.md (builtin_setjmp_receiver): Fix typo in
|
||||
pattern name.
|
||||
(mn10300_loadPC): Define as insn splittable after reload.
|
||||
2001-05-13 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/sh/mn10300.h (JUMP_TABLES_IN_TEXT_SECTION): Let them
|
||||
be defined in .rodata even in PIC, now that the assembler
|
||||
supports that.
|
||||
2001-05-09 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300.h (GOT_SYMBOL_NAME): Don't let the
|
||||
symbol take an underscore prefix.
|
||||
2001-04-14 Alexandre Oliva <aoliva@redhat.com>
|
||||
* config/mn10300/mn10300-protos.h (legitimate_pic_operand_p,
|
||||
legitimize_pic_address): Declare.
|
||||
* config/mn10300/mn10300.h (CONDITIONAL_REGISTER_USAGE): Mark
|
||||
the PIC register as fixed.
|
||||
(EXTRA_CONSTRAINT): Match UNSPEC_PLT and UNSPEC_PIC for 'S'.
|
||||
(GO_IF_LEGITIMATE_ADDRESS): Require legitimate_pic_operand for
|
||||
PIC.
|
||||
(LEGITIMATE_PIC_OPERAND_P): Define.
|
||||
(PIC_OFFSET_TABLE_REGNUM): Define.
|
||||
(GOT_SYMBOL_NAME): Define.
|
||||
(SYMBOLIC_CONST_P): Define.
|
||||
(ENCODE_SECTION_INFO): Use SYMBOL_REF_FLAG to mark local
|
||||
symbols.
|
||||
(MN10300_GLOBAL_P): Test it.
|
||||
(OUTPUT_ADDR_CONST_EXTRA): Handle PIC-related unspecs.
|
||||
(JUMP_TABLES_IN_TEXT_SECTION): Enable for PIC.
|
||||
* config/mn10300/mn10300.c (print_operand): Handle unspec.
|
||||
(expand_prologue): Set PIC register.
|
||||
(call_address_operand): Don't match SYMBOL_REFs in PIC.
|
||||
(legitimize_address): Call legitimize_pic_address.
|
||||
(legitimize_pic_address): New fn.
|
||||
(legitimate_pic_operand_p): New fn.
|
||||
* config/mn10300/mn10300.md (PIC_REG, SP_REG): New constants.
|
||||
(UNSPEC_INT_LABEL, UNSPEC_PIC, UNSPEC_GOT, UNSPEC_GOTOFF,
|
||||
UNSPEC_PLT): New constants.
|
||||
(pop_pic_reg): New insn.
|
||||
(movsi): Adjust non-PIC addresses.
|
||||
(builtin_setjmp_receiver): Restore the PIC register.
|
||||
(casesi): New insn.
|
||||
(call): Adjust non-PIC addresses.
|
||||
(int_label, GOTaddr2picreg): New expands.
|
||||
(am33_loadPC): New insn.
|
||||
(mn10300_loadPC): New expand.
|
||||
(call_next_insn): New insn.
|
||||
(add_GOT_to_pic_reg): New expand.
|
||||
(symGOT2reg, symGOT2reg_i): New expands.
|
||||
(symGOTOFF2reg, symGOTOFF2reg_i): New expands.
|
||||
(sym2PIC, sym2PLT): New expands.
|
||||
|
||||
2003-07-09 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* config/mn10300/mn10300.h (PREDICATE_CODES): Define.
|
||||
|
|
|
@ -26,6 +26,8 @@ extern void mn10300_va_start PARAMS ((tree, rtx));
|
|||
#endif /* TREE_CODE */
|
||||
|
||||
extern struct rtx_def *legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
|
||||
extern rtx legitimize_pic_address (rtx, rtx);
|
||||
extern int legitimate_pic_operand_p (rtx);
|
||||
extern void print_operand PARAMS ((FILE *, rtx, int));
|
||||
extern void print_operand_address PARAMS ((FILE *, rtx));
|
||||
extern void mn10300_print_reg_list PARAMS ((FILE *, int));
|
||||
|
|
|
@ -44,6 +44,10 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "target.h"
|
||||
#include "target-def.h"
|
||||
|
||||
/* This is used by GOTaddr2picreg to uniquely identify
|
||||
UNSPEC_INT_LABELs. */
|
||||
int mn10300_unspec_int_label_counter;
|
||||
|
||||
/* The size of the callee register save area. Right now we save everything
|
||||
on entry since it costs us nothing in code size. It does cost us from a
|
||||
speed standpoint, so we want to optimize this sooner or later. */
|
||||
|
@ -75,6 +79,10 @@ static void mn10300_file_start PARAMS ((void));
|
|||
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
|
||||
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
||||
|
||||
#undef TARGET_ENCODE_SECTION_INFO
|
||||
#define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info
|
||||
|
||||
static void mn10300_encode_section_info (tree, rtx, int);
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
static void
|
||||
|
@ -410,6 +418,7 @@ print_operand (file, x, code)
|
|||
case CONST:
|
||||
case LABEL_REF:
|
||||
case CODE_LABEL:
|
||||
case UNSPEC:
|
||||
print_operand_address (file, x);
|
||||
break;
|
||||
default:
|
||||
|
@ -881,6 +890,24 @@ expand_prologue ()
|
|||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (-size)));
|
||||
if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
|
||||
{
|
||||
rtx insn = get_last_insn ();
|
||||
rtx last = emit_insn (gen_GOTaddr2picreg ());
|
||||
|
||||
/* Mark these insns as possibly dead. Sometimes, flow2 may
|
||||
delete all uses of the PIC register. In this case, let it
|
||||
delete the initialization too. */
|
||||
do
|
||||
{
|
||||
insn = NEXT_INSN (insn);
|
||||
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
|
||||
const0_rtx,
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
while (insn != last);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1269,6 +1296,9 @@ call_address_operand (op, mode)
|
|||
rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (flag_pic)
|
||||
return (EXTRA_CONSTRAINT (op, 'S') || GET_CODE (op) == REG);
|
||||
|
||||
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
|
||||
}
|
||||
|
||||
|
@ -1756,6 +1786,9 @@ legitimize_address (x, oldx, mode)
|
|||
rtx oldx ATTRIBUTE_UNUSED;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (flag_pic && ! legitimate_pic_operand_p (x))
|
||||
x = legitimize_pic_address (oldx, NULL_RTX);
|
||||
|
||||
/* Uh-oh. We might have an address for x[n-100000]. This needs
|
||||
special handling to avoid creating an indexed memory address
|
||||
with x-100000 as the base. */
|
||||
|
@ -1786,6 +1819,75 @@ legitimize_address (x, oldx, mode)
|
|||
return x;
|
||||
}
|
||||
|
||||
/* Convert a non-PIC address in `orig' to a PIC address using @GOT or
|
||||
@GOTOFF in `reg'. */
|
||||
rtx
|
||||
legitimize_pic_address (orig, reg)
|
||||
rtx orig;
|
||||
rtx reg;
|
||||
{
|
||||
if (GET_CODE (orig) == LABEL_REF
|
||||
|| (GET_CODE (orig) == SYMBOL_REF
|
||||
&& (CONSTANT_POOL_ADDRESS_P (orig)
|
||||
|| ! MN10300_GLOBAL_P (orig))))
|
||||
{
|
||||
if (reg == 0)
|
||||
reg = gen_reg_rtx (Pmode);
|
||||
|
||||
emit_insn (gen_symGOTOFF2reg (reg, orig));
|
||||
return reg;
|
||||
}
|
||||
else if (GET_CODE (orig) == SYMBOL_REF)
|
||||
{
|
||||
if (reg == 0)
|
||||
reg = gen_reg_rtx (Pmode);
|
||||
|
||||
emit_insn (gen_symGOT2reg (reg, orig));
|
||||
return reg;
|
||||
}
|
||||
return orig;
|
||||
}
|
||||
|
||||
/* Return zero if X references a SYMBOL_REF or LABEL_REF whose symbol
|
||||
isn't protected by a PIC unspec; non-zero otherwise. */
|
||||
int
|
||||
legitimate_pic_operand_p (x)
|
||||
rtx x;
|
||||
{
|
||||
register const char *fmt;
|
||||
register int i;
|
||||
|
||||
if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (x) == UNSPEC
|
||||
&& (XINT (x, 1) == UNSPEC_PIC
|
||||
|| XINT (x, 1) == UNSPEC_GOT
|
||||
|| XINT (x, 1) == UNSPEC_GOTOFF
|
||||
|| XINT (x, 1) == UNSPEC_PLT))
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (x) == QUEUED)
|
||||
return legitimate_pic_operand_p (QUEUED_VAR (x));
|
||||
|
||||
fmt = GET_RTX_FORMAT (GET_CODE (x));
|
||||
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'E')
|
||||
{
|
||||
register int j;
|
||||
|
||||
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
||||
if (! legitimate_pic_operand_p (XVECEXP (x, i, j)))
|
||||
return 0;
|
||||
}
|
||||
else if (fmt[i] == 'e' && ! legitimate_pic_operand_p (XEXP (x, i)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mn10300_address_cost_1 (x, unsig)
|
||||
rtx x;
|
||||
|
@ -1973,3 +2075,23 @@ mn10300_wide_const_load_uses_clr (operands)
|
|||
|
||||
return val[0] == 0 || val[1] == 0;
|
||||
}
|
||||
/* If using PIC, mark a SYMBOL_REF for a non-global symbol so that we
|
||||
may access it using GOTOFF instead of GOT. */
|
||||
|
||||
static void
|
||||
mn10300_encode_section_info (decl, rtl, first)
|
||||
tree decl;
|
||||
rtx rtl;
|
||||
int first;
|
||||
{
|
||||
rtx symbol;
|
||||
|
||||
if (GET_CODE (rtl) != MEM)
|
||||
return;
|
||||
symbol = XEXP (rtl, 0);
|
||||
if (GET_CODE (symbol) != SYMBOL_REF)
|
||||
return;
|
||||
|
||||
if (flag_pic)
|
||||
SYMBOL_REF_FLAG (symbol) = (*targetm.binds_local_p) (decl);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ Boston, MA 02111-1307, USA. */
|
|||
|
||||
extern int target_flags;
|
||||
|
||||
extern GTY(()) int mn10300_unspec_int_label_counter;
|
||||
|
||||
/* Macros used in the machine description to test the flags. */
|
||||
|
||||
/* Macro to define tables used to set the flags.
|
||||
|
@ -212,6 +214,8 @@ extern int target_flags;
|
|||
i++) \
|
||||
fixed_regs[i] = call_used_regs[i] = 1; \
|
||||
} \
|
||||
if (flag_pic) \
|
||||
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
}
|
||||
|
||||
/* Return number of consecutive hard regs needed starting at reg REGNO
|
||||
|
@ -735,6 +739,9 @@ struct cum_arg {int nbytes; };
|
|||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
((C) == 'R' ? OK_FOR_R (OP) \
|
||||
: (C) == 'Q' ? OK_FOR_Q (OP) \
|
||||
: (C) == 'S' && flag_pic \
|
||||
? GET_CODE (OP) == UNSPEC && (XINT (OP, 1) == UNSPEC_PLT \
|
||||
|| XINT (OP, 1) == UNSPEC_PIC) \
|
||||
: (C) == 'S' ? GET_CODE (OP) == SYMBOL_REF \
|
||||
: (C) == 'T' ? OK_FOR_T (OP) \
|
||||
: 0)
|
||||
|
@ -775,7 +782,8 @@ struct cum_arg {int nbytes; };
|
|||
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
|
||||
{ \
|
||||
if (CONSTANT_ADDRESS_P (X)) \
|
||||
if (CONSTANT_ADDRESS_P (X) \
|
||||
&& (! flag_pic || legitimate_pic_operand_p (X))) \
|
||||
goto ADDR; \
|
||||
if (RTX_OK_FOR_BASE_P (X)) \
|
||||
goto ADDR; \
|
||||
|
@ -797,6 +805,8 @@ struct cum_arg {int nbytes; };
|
|||
{ \
|
||||
if (GET_CODE (index) == CONST_INT) \
|
||||
goto ADDR; \
|
||||
if (GET_CODE (index) == CONST) \
|
||||
goto ADDR; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
@ -833,6 +843,60 @@ struct cum_arg {int nbytes; };
|
|||
|
||||
#define LEGITIMATE_CONSTANT_P(X) 1
|
||||
|
||||
/* Zero if this needs fixing up to become PIC. */
|
||||
|
||||
#define LEGITIMATE_PIC_OPERAND_P(X) (legitimate_pic_operand_p (X))
|
||||
|
||||
/* Register to hold the addressing base for
|
||||
position independent code access to data items. */
|
||||
#define PIC_OFFSET_TABLE_REGNUM PIC_REG
|
||||
|
||||
/* The name of the pseudo-symbol representing the Global Offset Table. */
|
||||
#define GOT_SYMBOL_NAME "*_GLOBAL_OFFSET_TABLE_"
|
||||
|
||||
#define SYMBOLIC_CONST_P(X) \
|
||||
((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF) \
|
||||
&& ! LEGITIMATE_PIC_OPERAND_P (X))
|
||||
|
||||
/* Non-global SYMBOL_REFs have SYMBOL_REF_FLAG enabled. */
|
||||
#define MN10300_GLOBAL_P(X) (! SYMBOL_REF_FLAG (X))
|
||||
|
||||
/* Recognize machine-specific patterns that may appear within
|
||||
constants. Used for PIC-specific UNSPECs. */
|
||||
#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
|
||||
do \
|
||||
if (GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1) \
|
||||
{ \
|
||||
switch (XINT ((X), 1)) \
|
||||
{ \
|
||||
case UNSPEC_INT_LABEL: \
|
||||
asm_fprintf ((STREAM), ".%LLIL%d", \
|
||||
INTVAL (XVECEXP ((X), 0, 0))); \
|
||||
break; \
|
||||
case UNSPEC_PIC: \
|
||||
/* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */ \
|
||||
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||
break; \
|
||||
case UNSPEC_GOT: \
|
||||
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||
fputs ("@GOT", (STREAM)); \
|
||||
break; \
|
||||
case UNSPEC_GOTOFF: \
|
||||
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||
fputs ("@GOTOFF", (STREAM)); \
|
||||
break; \
|
||||
case UNSPEC_PLT: \
|
||||
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||
fputs ("@PLT", (STREAM)); \
|
||||
break; \
|
||||
default: \
|
||||
goto FAIL; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
goto FAIL; \
|
||||
while (0)
|
||||
|
||||
/* Tell final.c how to eliminate redundant test instructions. */
|
||||
|
||||
|
|
|
@ -37,6 +37,17 @@
|
|||
;; clobber - value of cc is unknown
|
||||
(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert"
|
||||
(const_string "clobber"))
|
||||
|
||||
(define_constants [
|
||||
(PIC_REG 6)
|
||||
(SP_REG 9)
|
||||
|
||||
(UNSPEC_INT_LABEL 0)
|
||||
(UNSPEC_PIC 1)
|
||||
(UNSPEC_GOT 2)
|
||||
(UNSPEC_GOTOFF 3)
|
||||
(UNSPEC_PLT 4)
|
||||
])
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; MOVE INSTRUCTIONS
|
||||
|
@ -269,6 +280,12 @@
|
|||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "pop_pic_reg"
|
||||
[(set (reg:SI PIC_REG)
|
||||
(mem:SI (post_inc:SI (reg:SI SP_REG))))]
|
||||
"reload_completed"
|
||||
"movm (sp),[a2]")
|
||||
|
||||
(define_expand "movsi"
|
||||
[(set (match_operand:SI 0 "general_operand" "")
|
||||
(match_operand:SI 1 "general_operand" ""))]
|
||||
|
@ -279,6 +296,33 @@
|
|||
if (!register_operand (operand1, SImode)
|
||||
&& !register_operand (operand0, SImode))
|
||||
operands[1] = copy_to_mode_reg (SImode, operand1);
|
||||
if (flag_pic)
|
||||
{
|
||||
rtx temp;
|
||||
if (SYMBOLIC_CONST_P (operands[1]))
|
||||
{
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
operands[1] = force_reg (Pmode, operands[1]);
|
||||
else
|
||||
{
|
||||
temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
|
||||
operands[1] = legitimize_pic_address (operands[1], temp);
|
||||
}
|
||||
}
|
||||
else if (GET_CODE (operands[1]) == CONST
|
||||
&& GET_CODE (XEXP (operands[1], 0)) == PLUS
|
||||
&& SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
|
||||
{
|
||||
temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
|
||||
temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
|
||||
temp);
|
||||
operands[1] = expand_binop (SImode, add_optab, temp,
|
||||
XEXP (XEXP (operands[1], 0), 1),
|
||||
no_new_pseudos ? temp
|
||||
: gen_reg_rtx (Pmode),
|
||||
0, OPTAB_LIB_WIDEN);
|
||||
}
|
||||
}
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
|
@ -1666,6 +1710,43 @@
|
|||
"jmp (%0)"
|
||||
[(set_attr "cc" "none")])
|
||||
|
||||
(define_expand "builtin_setjmp_receiver"
|
||||
[(match_operand 0 "" "")]
|
||||
"flag_pic"
|
||||
"
|
||||
{
|
||||
if (flag_pic)
|
||||
emit_insn (gen_GOTaddr2picreg ());
|
||||
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "casesi"
|
||||
[(match_operand:SI 0 "register_operand" "")
|
||||
(match_operand:SI 1 "immediate_operand" "")
|
||||
(match_operand:SI 2 "immediate_operand" "")
|
||||
(match_operand 3 "" "") (match_operand 4 "" "")]
|
||||
""
|
||||
"
|
||||
{
|
||||
rtx table = gen_reg_rtx (SImode);
|
||||
rtx index = gen_reg_rtx (SImode);
|
||||
rtx addr = gen_reg_rtx (Pmode);
|
||||
|
||||
emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
|
||||
emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
|
||||
emit_insn (gen_cmpsi (index, operands[2]));
|
||||
emit_jump_insn (gen_bgtu (operands[4]));
|
||||
emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, GEN_INT (2)));
|
||||
emit_move_insn (addr, gen_rtx_MEM (SImode,
|
||||
gen_rtx_PLUS (SImode, table, index)));
|
||||
if (flag_pic)
|
||||
emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
|
||||
|
||||
emit_jump_insn (gen_tablejump (addr, operands[3]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "tablejump"
|
||||
[(set (pc) (match_operand:SI 0 "register_operand" "a"))
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
|
@ -1681,6 +1762,20 @@
|
|||
""
|
||||
"
|
||||
{
|
||||
if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
|
||||
{
|
||||
if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
|
||||
{
|
||||
/* 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_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
|
||||
XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
|
||||
}
|
||||
else
|
||||
XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
|
||||
}
|
||||
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]));
|
||||
|
@ -1710,6 +1805,20 @@
|
|||
""
|
||||
"
|
||||
{
|
||||
if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
|
||||
{
|
||||
if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
|
||||
{
|
||||
/* 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_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
|
||||
XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
|
||||
}
|
||||
else
|
||||
XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
|
||||
}
|
||||
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],
|
||||
|
@ -2402,3 +2511,134 @@
|
|||
"add %0,%0\;bcc %1"
|
||||
[(set_attr "cc" "clobber")])
|
||||
|
||||
(define_expand "int_label"
|
||||
[(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
|
||||
"" "")
|
||||
|
||||
(define_expand "GOTaddr2picreg"
|
||||
[(match_dup 0)]
|
||||
"" "
|
||||
{
|
||||
/* It would be nice to be able to have int_label keep track of the
|
||||
counter and all, but if we add C code to it, we'll get an insn
|
||||
back, and we just want the pattern. */
|
||||
operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
|
||||
if (TARGET_AM33)
|
||||
emit_insn (gen_am33_loadPC (operands[0]));
|
||||
else
|
||||
emit_insn (gen_mn10300_loadPC (operands[0]));
|
||||
emit_insn (gen_add_GOT_to_pic_reg (operands[0]));
|
||||
DONE;
|
||||
}
|
||||
")
|
||||
|
||||
(define_insn "am33_loadPC"
|
||||
[(parallel
|
||||
[(set (reg:SI PIC_REG) (pc))
|
||||
(use (match_operand 0 "" ""))])]
|
||||
"TARGET_AM33"
|
||||
"%0:\;mov pc,a2")
|
||||
|
||||
|
||||
(define_insn_and_split "mn10300_loadPC"
|
||||
[(parallel
|
||||
[(set (reg:SI PIC_REG) (pc))
|
||||
(use (match_operand 0 "" ""))])]
|
||||
""
|
||||
"#"
|
||||
"reload_completed"
|
||||
[(match_operand 0 "" "")]
|
||||
"
|
||||
{
|
||||
rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
|
||||
int need_stack_space = (get_frame_size () == 0
|
||||
&& current_function_outgoing_args_size == 0);
|
||||
|
||||
if (need_stack_space)
|
||||
emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
|
||||
|
||||
emit_insn (gen_call_next_insn (operands[0]));
|
||||
|
||||
if (need_stack_space)
|
||||
emit_insn (gen_pop_pic_reg ());
|
||||
else
|
||||
emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
|
||||
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "call_next_insn"
|
||||
[(parallel
|
||||
[(set (mem:SI (reg:SI SP_REG)) (pc))
|
||||
(use (match_operand 0 "" ""))])]
|
||||
"reload_completed"
|
||||
"calls %0\;%0:")
|
||||
|
||||
(define_expand "add_GOT_to_pic_reg"
|
||||
[(set (reg:SI PIC_REG)
|
||||
(plus:SI
|
||||
(reg:SI PIC_REG)
|
||||
(const
|
||||
(unspec [(minus:SI
|
||||
(match_dup 1)
|
||||
(const (minus:SI
|
||||
(const (match_operand:SI 0 "" ""))
|
||||
(pc))))
|
||||
] UNSPEC_PIC))))]
|
||||
""
|
||||
"
|
||||
{
|
||||
operands[1] = 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]));
|
||||
|
||||
RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
|
||||
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
|
||||
REG_NOTES (insn));
|
||||
|
||||
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]));
|
||||
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
|
||||
REG_NOTES (insn));
|
||||
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "symGOTOFF2reg_i"
|
||||
[(set (match_operand:SI 0 "" "")
|
||||
(const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
|
||||
(set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "sym2PIC"
|
||||
[(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
|
||||
"" "")
|
||||
|
||||
(define_expand "sym2PLT"
|
||||
[(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
|
||||
"" "")
|
||||
|
|
Loading…
Add table
Reference in a new issue