mips-protos.h (SYMBOL_FORCE_TO_MEM): Delete.
gcc/ 2012-01-08 Chung-Lin Tang <cltang@codesourcery.com> Richard Sandiford <rdsandiford@googlemail.com> * config/mips/mips-protos.h (SYMBOL_FORCE_TO_MEM): Delete. (SYMBOL_32_HIGH): Likewise. (mips_output_tls_reloc_directive): Declare. * config/mips/mips.h (PIC_FUNCTION_ADDR_REGNUM): Move to mips.md. (mips_use_pcrel_pool_p, mips_lo_relocs, mips_hi_relocs): Declare. * config/mips/mips.c (mips_use_pcrel_pool_p): New variable. (mips_lo_relocs, mips_hi_relocs): Make extern. (mips16_stub_function): Move up file. (mips_classify_symbol): Remove SYMBOL_FORCE_TO_MEM handling. (mips_symbolic_constant_p): Likewise. Remove SYMBOL_32_HIGH too. (mips_symbol_insns_1): Likewise. Check mips_use_pcrel_pool_p. (mips_cannot_force_const_mem): Use mips_use_pcrel_pool_p instead of SYMBOL_FORCE_TO_MEM. Only check mips_tls_symbol_ref_1 if it's false. (mips_get_tp): Add MIPS16 support. (mips_legitimize_tls_address): Remove MIPS16 sorry(). Generalize DTPREL and TPREL handling. (mips_init_relocs): Initialize mips_use_pcrel_pool_p. Add MIPS16 TLS support. (mips_output_tls_reloc_directive): New function. (mips16_rewrite_pool_refs): Ignore UNSPEC_TLS_GET_TPs. * config/mips/predicates.md (symbolic_operand_with_high) (tls_reloc_operand): New predicates. (force_to_mem_operand): Use mips_use_pcrel_pool_p. * config/mips/mips.md (UNSPEC_UNSHIFTED_HIGH): New unspec. (PIC_FUNCTION_ADDR_REGNUM): Moved from mips.h. (*unshifted_high): New instruction. Use it for MIPS16 high splitter. (consttable_tls_reloc, tls_get_tp_mips16_<mode>): New patterns. (*tls_get_tp_mips16_call_<mode>): Likewise. gcc/testsuite/ * gcc.target/mips/code-readable-2.c: Allow the jump table address to be loaded from the constant pool, rather than via %hi and %lo. libgcc/ 2012-01-08 Chung-Lin Tang <cltang@codesourcery.com> Richard Sandiford <rdsandiford@googlemail.com> * config/mips/libgcc-mips16.ver (__mips16_rdhwr): Add. * config/mips/mips16.S (__mips16_rdhwr): New function. * config/mips/t-mips16 (LIB1ASMFUNCS): Add _m16rdhwr. From-SVN: r183195
This commit is contained in:
parent
bf63ef6c22
commit
ddaf812593
@ -1,3 +1,37 @@
|
||||
2012-01-15 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* config/mips/mips-protos.h (SYMBOL_FORCE_TO_MEM): Delete.
|
||||
(SYMBOL_32_HIGH): Likewise.
|
||||
(mips_output_tls_reloc_directive): Declare.
|
||||
* config/mips/mips.h (PIC_FUNCTION_ADDR_REGNUM): Move to mips.md.
|
||||
(mips_use_pcrel_pool_p, mips_lo_relocs, mips_hi_relocs): Declare.
|
||||
* config/mips/mips.c (mips_use_pcrel_pool_p): New variable.
|
||||
(mips_lo_relocs, mips_hi_relocs): Make extern.
|
||||
(mips16_stub_function): Move up file.
|
||||
(mips_classify_symbol): Remove SYMBOL_FORCE_TO_MEM handling.
|
||||
(mips_symbolic_constant_p): Likewise. Remove SYMBOL_32_HIGH too.
|
||||
(mips_symbol_insns_1): Likewise. Check mips_use_pcrel_pool_p.
|
||||
(mips_cannot_force_const_mem): Use mips_use_pcrel_pool_p instead
|
||||
of SYMBOL_FORCE_TO_MEM. Only check mips_tls_symbol_ref_1
|
||||
if it's false.
|
||||
(mips_get_tp): Add MIPS16 support.
|
||||
(mips_legitimize_tls_address): Remove MIPS16 sorry().
|
||||
Generalize DTPREL and TPREL handling.
|
||||
(mips_init_relocs): Initialize mips_use_pcrel_pool_p.
|
||||
Add MIPS16 TLS support.
|
||||
(mips_output_tls_reloc_directive): New function.
|
||||
(mips16_rewrite_pool_refs): Ignore UNSPEC_TLS_GET_TPs.
|
||||
* config/mips/predicates.md (symbolic_operand_with_high)
|
||||
(tls_reloc_operand): New predicates.
|
||||
(force_to_mem_operand): Use mips_use_pcrel_pool_p.
|
||||
* config/mips/mips.md (UNSPEC_UNSHIFTED_HIGH): New unspec.
|
||||
(PIC_FUNCTION_ADDR_REGNUM): Moved from mips.h.
|
||||
(*unshifted_high): New instruction. Use it for MIPS16
|
||||
high splitter.
|
||||
(consttable_tls_reloc, tls_get_tp_mips16_<mode>): New patterns.
|
||||
(*tls_get_tp_mips16_call_<mode>): Likewise.
|
||||
|
||||
2012-01-15 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR rtl-optimization/51821
|
||||
|
@ -56,9 +56,6 @@ enum mips_symbol_context {
|
||||
The symbol's value will be calculated using a MIPS16 PC-relative
|
||||
calculation.
|
||||
|
||||
SYMBOL_FORCE_TO_MEM
|
||||
The symbol's value must be forced to memory and loaded from there.
|
||||
|
||||
SYMBOL_GOT_PAGE_OFST
|
||||
The symbol's value will be calculated by loading an address
|
||||
from the GOT and then applying a 16-bit offset.
|
||||
@ -94,9 +91,6 @@ enum mips_symbol_context {
|
||||
UNSPEC wrappers around SYMBOL_TLS, corresponding to the
|
||||
thread-local storage relocation operators.
|
||||
|
||||
SYMBOL_32_HIGH
|
||||
For a 32-bit symbolic address X, this is the value of %hi(X).
|
||||
|
||||
SYMBOL_64_HIGH
|
||||
For a 64-bit symbolic address X, this is the value of
|
||||
(%highest(X) << 16) + %higher(X).
|
||||
@ -116,7 +110,6 @@ enum mips_symbol_type {
|
||||
SYMBOL_ABSOLUTE,
|
||||
SYMBOL_GP_RELATIVE,
|
||||
SYMBOL_PC_RELATIVE,
|
||||
SYMBOL_FORCE_TO_MEM,
|
||||
SYMBOL_GOT_PAGE_OFST,
|
||||
SYMBOL_GOT_DISP,
|
||||
SYMBOL_GOTOFF_PAGE,
|
||||
@ -129,7 +122,6 @@ enum mips_symbol_type {
|
||||
SYMBOL_DTPREL,
|
||||
SYMBOL_GOTTPREL,
|
||||
SYMBOL_TPREL,
|
||||
SYMBOL_32_HIGH,
|
||||
SYMBOL_64_HIGH,
|
||||
SYMBOL_64_MID,
|
||||
SYMBOL_64_LOW,
|
||||
@ -260,6 +252,7 @@ extern void mips_push_asm_switch (struct mips_asm_switch *);
|
||||
extern void mips_pop_asm_switch (struct mips_asm_switch *);
|
||||
extern void mips_output_external (FILE *, tree, const char *);
|
||||
extern void mips_output_ascii (FILE *, const char *, size_t);
|
||||
extern const char *mips_output_tls_reloc_directive (rtx *);
|
||||
extern void mips_output_aligned_decl_common (FILE *, tree, const char *,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned int);
|
||||
|
@ -573,13 +573,17 @@ bool mips_split_p[NUM_SYMBOL_TYPES];
|
||||
can be split by mips_split_symbol. */
|
||||
bool mips_split_hi_p[NUM_SYMBOL_TYPES];
|
||||
|
||||
/* mips_use_pcrel_pool_p[X] is true if symbols of type X should be
|
||||
forced into a PC-relative constant pool. */
|
||||
bool mips_use_pcrel_pool_p[NUM_SYMBOL_TYPES];
|
||||
|
||||
/* mips_lo_relocs[X] is the relocation to use when a symbol of type X
|
||||
appears in a LO_SUM. It can be null if such LO_SUMs aren't valid or
|
||||
if they are matched by a special .md file pattern. */
|
||||
static const char *mips_lo_relocs[NUM_SYMBOL_TYPES];
|
||||
const char *mips_lo_relocs[NUM_SYMBOL_TYPES];
|
||||
|
||||
/* Likewise for HIGHs. */
|
||||
static const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
|
||||
const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
|
||||
|
||||
/* Target state for MIPS16. */
|
||||
struct target_globals *mips16_globals;
|
||||
@ -1440,6 +1444,18 @@ mips_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
|
||||
return mips_const_insns (x) > 0;
|
||||
}
|
||||
|
||||
/* Return a SYMBOL_REF for a MIPS16 function called NAME. */
|
||||
|
||||
static rtx
|
||||
mips16_stub_function (const char *name)
|
||||
{
|
||||
rtx x;
|
||||
|
||||
x = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
|
||||
SYMBOL_REF_FLAGS (x) |= (SYMBOL_FLAG_EXTERNAL | SYMBOL_FLAG_FUNCTION);
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Return true if symbols of type TYPE require a GOT access. */
|
||||
|
||||
static bool
|
||||
@ -1644,9 +1660,6 @@ mips_classify_symbol (const_rtx x, enum mips_symbol_context context)
|
||||
return SYMBOL_GOT_PAGE_OFST;
|
||||
}
|
||||
|
||||
if (TARGET_MIPS16_PCREL_LOADS && context != SYMBOL_CONTEXT_CALL)
|
||||
return SYMBOL_FORCE_TO_MEM;
|
||||
|
||||
return SYMBOL_ABSOLUTE;
|
||||
}
|
||||
|
||||
@ -1709,8 +1722,6 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_context context,
|
||||
switch (*symbol_type)
|
||||
{
|
||||
case SYMBOL_ABSOLUTE:
|
||||
case SYMBOL_FORCE_TO_MEM:
|
||||
case SYMBOL_32_HIGH:
|
||||
case SYMBOL_64_HIGH:
|
||||
case SYMBOL_64_MID:
|
||||
case SYMBOL_64_LOW:
|
||||
@ -1776,6 +1787,17 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_context context,
|
||||
static int
|
||||
mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode)
|
||||
{
|
||||
if (mips_use_pcrel_pool_p[(int) type])
|
||||
{
|
||||
if (mode == MAX_MACHINE_MODE)
|
||||
/* LEAs will be converted into constant-pool references by
|
||||
mips_reorg. */
|
||||
type = SYMBOL_PC_RELATIVE;
|
||||
else
|
||||
/* The constant must be loaded and then dereferenced. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SYMBOL_ABSOLUTE:
|
||||
@ -1809,15 +1831,6 @@ mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode)
|
||||
/* The constant must be loaded using ADDIUPC or DADDIUPC first. */
|
||||
return 0;
|
||||
|
||||
case SYMBOL_FORCE_TO_MEM:
|
||||
/* LEAs will be converted into constant-pool references by
|
||||
mips_reorg. */
|
||||
if (mode == MAX_MACHINE_MODE)
|
||||
return 1;
|
||||
|
||||
/* The constant must be loaded and then dereferenced. */
|
||||
return 0;
|
||||
|
||||
case SYMBOL_GOT_DISP:
|
||||
/* The constant will have to be loaded from the GOT before it
|
||||
is used in an address. */
|
||||
@ -1850,7 +1863,6 @@ mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode)
|
||||
case SYMBOL_GOTOFF_DISP:
|
||||
case SYMBOL_GOTOFF_CALL:
|
||||
case SYMBOL_GOTOFF_LOADGP:
|
||||
case SYMBOL_32_HIGH:
|
||||
case SYMBOL_64_HIGH:
|
||||
case SYMBOL_64_MID:
|
||||
case SYMBOL_64_LOW:
|
||||
@ -1925,9 +1937,12 @@ mips_cannot_force_const_mem (enum machine_mode mode, rtx x)
|
||||
return true;
|
||||
|
||||
split_const (x, &base, &offset);
|
||||
if (mips_symbolic_constant_p (base, SYMBOL_CONTEXT_LEA, &type)
|
||||
&& type != SYMBOL_FORCE_TO_MEM)
|
||||
if (mips_symbolic_constant_p (base, SYMBOL_CONTEXT_LEA, &type))
|
||||
{
|
||||
/* See whether we explicitly want these symbols in the pool. */
|
||||
if (mips_use_pcrel_pool_p[(int) type])
|
||||
return false;
|
||||
|
||||
/* The same optimization as for CONST_INT. */
|
||||
if (SMALL_INT (offset) && mips_symbol_insns (type, MAX_MACHINE_MODE) > 0)
|
||||
return true;
|
||||
@ -2822,13 +2837,18 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
|
||||
static rtx
|
||||
mips_get_tp (void)
|
||||
{
|
||||
rtx tp;
|
||||
rtx tp, fn;
|
||||
|
||||
tp = gen_reg_rtx (Pmode);
|
||||
if (Pmode == DImode)
|
||||
emit_insn (gen_tls_get_tp_di (tp));
|
||||
if (TARGET_MIPS16)
|
||||
{
|
||||
fn = mips16_stub_function ("__mips16_rdhwr");
|
||||
if (!call_insn_operand (fn, VOIDmode))
|
||||
fn = force_reg (Pmode, fn);
|
||||
emit_insn (PMODE_INSN (gen_tls_get_tp_mips16, (tp, fn)));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_tls_get_tp_si (tp));
|
||||
emit_insn (PMODE_INSN (gen_tls_get_tp, (tp)));
|
||||
return tp;
|
||||
}
|
||||
|
||||
@ -2839,15 +2859,9 @@ mips_get_tp (void)
|
||||
static rtx
|
||||
mips_legitimize_tls_address (rtx loc)
|
||||
{
|
||||
rtx dest, insn, v0, tp, tmp1, tmp2, eqv;
|
||||
rtx dest, insn, v0, tp, tmp1, tmp2, eqv, offset;
|
||||
enum tls_model model;
|
||||
|
||||
if (TARGET_MIPS16)
|
||||
{
|
||||
sorry ("MIPS16 TLS");
|
||||
return gen_reg_rtx (Pmode);
|
||||
}
|
||||
|
||||
model = SYMBOL_REF_TLS_MODEL (loc);
|
||||
/* Only TARGET_ABICALLS code can have more than one module; other
|
||||
code must be be static and should not use a GOT. All TLS models
|
||||
@ -2875,9 +2889,15 @@ mips_legitimize_tls_address (rtx loc)
|
||||
UNSPEC_TLS_LDM);
|
||||
emit_libcall_block (insn, tmp1, v0, eqv);
|
||||
|
||||
tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_DTPREL);
|
||||
dest = gen_rtx_LO_SUM (Pmode, tmp2,
|
||||
mips_unspec_address (loc, SYMBOL_DTPREL));
|
||||
offset = mips_unspec_address (loc, SYMBOL_DTPREL);
|
||||
if (mips_split_p[SYMBOL_DTPREL])
|
||||
{
|
||||
tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_DTPREL);
|
||||
dest = gen_rtx_LO_SUM (Pmode, tmp2, offset);
|
||||
}
|
||||
else
|
||||
dest = expand_binop (Pmode, add_optab, tmp1, offset,
|
||||
0, 0, OPTAB_DIRECT);
|
||||
break;
|
||||
|
||||
case TLS_MODEL_INITIAL_EXEC:
|
||||
@ -2893,10 +2913,16 @@ mips_legitimize_tls_address (rtx loc)
|
||||
break;
|
||||
|
||||
case TLS_MODEL_LOCAL_EXEC:
|
||||
tp = mips_get_tp ();
|
||||
tmp1 = mips_unspec_offset_high (NULL, tp, loc, SYMBOL_TPREL);
|
||||
dest = gen_rtx_LO_SUM (Pmode, tmp1,
|
||||
mips_unspec_address (loc, SYMBOL_TPREL));
|
||||
tmp1 = mips_get_tp ();
|
||||
offset = mips_unspec_address (loc, SYMBOL_TPREL);
|
||||
if (mips_split_p[SYMBOL_TPREL])
|
||||
{
|
||||
tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_TPREL);
|
||||
dest = gen_rtx_LO_SUM (Pmode, tmp2, offset);
|
||||
}
|
||||
else
|
||||
dest = expand_binop (Pmode, add_optab, tmp1, offset,
|
||||
0, 0, OPTAB_DIRECT);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -5866,18 +5892,6 @@ struct mips16_stub {
|
||||
};
|
||||
static struct mips16_stub *mips16_stubs;
|
||||
|
||||
/* Return a SYMBOL_REF for a MIPS16 function called NAME. */
|
||||
|
||||
static rtx
|
||||
mips16_stub_function (const char *name)
|
||||
{
|
||||
rtx x;
|
||||
|
||||
x = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
|
||||
SYMBOL_REF_FLAGS (x) |= (SYMBOL_FLAG_EXTERNAL | SYMBOL_FLAG_FUNCTION);
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Return the two-character string that identifies floating-point
|
||||
return mode MODE in the name of a MIPS16 function stub. */
|
||||
|
||||
@ -7192,38 +7206,44 @@ mips_init_relocs (void)
|
||||
{
|
||||
memset (mips_split_p, '\0', sizeof (mips_split_p));
|
||||
memset (mips_split_hi_p, '\0', sizeof (mips_split_hi_p));
|
||||
memset (mips_use_pcrel_pool_p, '\0', sizeof (mips_use_pcrel_pool_p));
|
||||
memset (mips_hi_relocs, '\0', sizeof (mips_hi_relocs));
|
||||
memset (mips_lo_relocs, '\0', sizeof (mips_lo_relocs));
|
||||
|
||||
if (ABI_HAS_64BIT_SYMBOLS)
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
mips_split_p[SYMBOL_64_HIGH] = true;
|
||||
mips_hi_relocs[SYMBOL_64_HIGH] = "%highest(";
|
||||
mips_lo_relocs[SYMBOL_64_HIGH] = "%higher(";
|
||||
|
||||
mips_split_p[SYMBOL_64_MID] = true;
|
||||
mips_hi_relocs[SYMBOL_64_MID] = "%higher(";
|
||||
mips_lo_relocs[SYMBOL_64_MID] = "%hi(";
|
||||
|
||||
mips_split_p[SYMBOL_64_LOW] = true;
|
||||
mips_hi_relocs[SYMBOL_64_LOW] = "%hi(";
|
||||
mips_lo_relocs[SYMBOL_64_LOW] = "%lo(";
|
||||
|
||||
mips_split_p[SYMBOL_ABSOLUTE] = true;
|
||||
mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
|
||||
}
|
||||
}
|
||||
if (TARGET_MIPS16_PCREL_LOADS)
|
||||
mips_use_pcrel_pool_p[SYMBOL_ABSOLUTE] = true;
|
||||
else
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS || mips_split_addresses_p () || TARGET_MIPS16)
|
||||
if (ABI_HAS_64BIT_SYMBOLS)
|
||||
{
|
||||
mips_split_p[SYMBOL_ABSOLUTE] = true;
|
||||
mips_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
|
||||
mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
mips_split_p[SYMBOL_64_HIGH] = true;
|
||||
mips_hi_relocs[SYMBOL_64_HIGH] = "%highest(";
|
||||
mips_lo_relocs[SYMBOL_64_HIGH] = "%higher(";
|
||||
|
||||
mips_lo_relocs[SYMBOL_32_HIGH] = "%hi(";
|
||||
mips_split_p[SYMBOL_64_MID] = true;
|
||||
mips_hi_relocs[SYMBOL_64_MID] = "%higher(";
|
||||
mips_lo_relocs[SYMBOL_64_MID] = "%hi(";
|
||||
|
||||
mips_split_p[SYMBOL_64_LOW] = true;
|
||||
mips_hi_relocs[SYMBOL_64_LOW] = "%hi(";
|
||||
mips_lo_relocs[SYMBOL_64_LOW] = "%lo(";
|
||||
|
||||
mips_split_p[SYMBOL_ABSOLUTE] = true;
|
||||
mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS
|
||||
|| mips_split_addresses_p ()
|
||||
|| TARGET_MIPS16)
|
||||
{
|
||||
mips_split_p[SYMBOL_ABSOLUTE] = true;
|
||||
mips_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
|
||||
mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7291,16 +7311,23 @@ mips_init_relocs (void)
|
||||
mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd(";
|
||||
mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm(";
|
||||
|
||||
mips_split_p[SYMBOL_DTPREL] = true;
|
||||
mips_hi_relocs[SYMBOL_DTPREL] = "%dtprel_hi(";
|
||||
mips_lo_relocs[SYMBOL_DTPREL] = "%dtprel_lo(";
|
||||
if (TARGET_MIPS16_PCREL_LOADS)
|
||||
{
|
||||
mips_use_pcrel_pool_p[SYMBOL_DTPREL] = true;
|
||||
mips_use_pcrel_pool_p[SYMBOL_TPREL] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mips_split_p[SYMBOL_DTPREL] = true;
|
||||
mips_hi_relocs[SYMBOL_DTPREL] = "%dtprel_hi(";
|
||||
mips_lo_relocs[SYMBOL_DTPREL] = "%dtprel_lo(";
|
||||
|
||||
mips_split_p[SYMBOL_TPREL] = true;
|
||||
mips_hi_relocs[SYMBOL_TPREL] = "%tprel_hi(";
|
||||
mips_lo_relocs[SYMBOL_TPREL] = "%tprel_lo(";
|
||||
}
|
||||
|
||||
mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottprel(";
|
||||
|
||||
mips_split_p[SYMBOL_TPREL] = true;
|
||||
mips_hi_relocs[SYMBOL_TPREL] = "%tprel_hi(";
|
||||
mips_lo_relocs[SYMBOL_TPREL] = "%tprel_lo(";
|
||||
|
||||
mips_lo_relocs[SYMBOL_HALF] = "%half(";
|
||||
}
|
||||
|
||||
@ -8082,6 +8109,29 @@ mips_output_ascii (FILE *stream, const char *string, size_t len)
|
||||
fprintf (stream, "\"\n");
|
||||
}
|
||||
|
||||
/* Return the pseudo-op for full SYMBOL_(D)TPREL address *ADDR.
|
||||
Update *ADDR with the operand that should be printed. */
|
||||
|
||||
const char *
|
||||
mips_output_tls_reloc_directive (rtx *addr)
|
||||
{
|
||||
enum mips_symbol_type type;
|
||||
|
||||
type = mips_classify_symbolic_expression (*addr, SYMBOL_CONTEXT_LEA);
|
||||
*addr = mips_strip_unspec_address (*addr);
|
||||
switch (type)
|
||||
{
|
||||
case SYMBOL_DTPREL:
|
||||
return Pmode == SImode ? ".dtprelword\t%0" : ".dtpreldword\t%0";
|
||||
|
||||
case SYMBOL_TPREL:
|
||||
return Pmode == SImode ? ".tprelword\t%0" : ".tpreldword\t%0";
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit either a label, .comm, or .lcomm directive. When using assembler
|
||||
macros, mark the symbol as written so that mips_asm_output_external
|
||||
won't emit an .extern for it. STREAM is the output file, NAME is the
|
||||
@ -13783,6 +13833,10 @@ mips16_rewrite_pool_refs (rtx *x, void *data)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Don't rewrite the __mips16_rdwr symbol. */
|
||||
if (GET_CODE (*x) == UNSPEC && XINT (*x, 1) == UNSPEC_TLS_GET_TP)
|
||||
return -1;
|
||||
|
||||
if (TARGET_MIPS16_TEXT_LOADS)
|
||||
mips16_rewrite_pool_constant (info->pool, x);
|
||||
|
||||
|
@ -1785,8 +1785,6 @@ struct mips_cpu_info {
|
||||
from there after reload. */
|
||||
#define PIC_OFFSET_TABLE_REGNUM \
|
||||
(reload_completed ? REGNO (pic_offset_table_rtx) : GLOBAL_POINTER_REGNUM)
|
||||
|
||||
#define PIC_FUNCTION_ADDR_REGNUM (GP_REG_FIRST + 25)
|
||||
|
||||
/* Define the classes of registers for register constraints in the
|
||||
machine description. Also define ranges of constants.
|
||||
@ -2868,6 +2866,9 @@ extern int mips_dbx_regno[];
|
||||
extern int mips_dwarf_regno[];
|
||||
extern bool mips_split_p[];
|
||||
extern bool mips_split_hi_p[];
|
||||
extern bool mips_use_pcrel_pool_p[];
|
||||
extern const char *mips_lo_relocs[];
|
||||
extern const char *mips_hi_relocs[];
|
||||
extern enum processor mips_arch; /* which cpu to codegen for */
|
||||
extern enum processor mips_tune; /* which cpu to schedule for */
|
||||
extern int mips_isa; /* architectural level */
|
||||
|
@ -103,6 +103,7 @@
|
||||
UNSPEC_LOAD_GOT
|
||||
UNSPEC_TLS_LDM
|
||||
UNSPEC_TLS_GET_TP
|
||||
UNSPEC_UNSHIFTED_HIGH
|
||||
|
||||
;; MIPS16 constant pools.
|
||||
UNSPEC_ALIGN
|
||||
@ -135,6 +136,7 @@
|
||||
|
||||
(define_constants
|
||||
[(TLS_GET_TP_REGNUM 3)
|
||||
(PIC_FUNCTION_ADDR_REGNUM 25)
|
||||
(RETURN_ADDR_REGNUM 31)
|
||||
(CPRESTORE_SLOT_REGNUM 76)
|
||||
(GOT_VERSION_REGNUM 79)
|
||||
@ -3924,14 +3926,19 @@
|
||||
;;
|
||||
;; on MIPS16 targets.
|
||||
(define_split
|
||||
[(set (match_operand:SI 0 "d_operand")
|
||||
(high:SI (match_operand:SI 1 "absolute_symbolic_operand")))]
|
||||
[(set (match_operand:P 0 "d_operand")
|
||||
(high:P (match_operand:P 1 "symbolic_operand_with_high")))]
|
||||
"TARGET_MIPS16 && reload_completed"
|
||||
[(set (match_dup 0) (match_dup 2))
|
||||
(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16)))]
|
||||
{
|
||||
operands[2] = mips_unspec_address (operands[1], SYMBOL_32_HIGH);
|
||||
})
|
||||
[(set (match_dup 0) (unspec:P [(match_dup 1)] UNSPEC_UNSHIFTED_HIGH))
|
||||
(set (match_dup 0) (ashift:P (match_dup 0) (const_int 16)))])
|
||||
|
||||
(define_insn "*unshifted_high"
|
||||
[(set (match_operand:P 0 "d_operand" "=d")
|
||||
(unspec:P [(match_operand:P 1 "symbolic_operand_with_high")]
|
||||
UNSPEC_UNSHIFTED_HIGH))]
|
||||
""
|
||||
"li\t%0,%h1"
|
||||
[(set_attr "extended_mips16" "yes")])
|
||||
|
||||
;; Insns to fetch a symbol from a big GOT.
|
||||
|
||||
@ -6492,6 +6499,14 @@
|
||||
;; ....................
|
||||
;;
|
||||
|
||||
(define_insn "consttable_tls_reloc"
|
||||
[(unspec_volatile [(match_operand 0 "tls_reloc_operand" "")
|
||||
(match_operand 1 "const_int_operand" "")]
|
||||
UNSPEC_CONSTTABLE_INT)]
|
||||
"TARGET_MIPS16_PCREL_LOADS"
|
||||
{ return mips_output_tls_reloc_directive (&operands[0]); }
|
||||
[(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
|
||||
|
||||
(define_insn "consttable_int"
|
||||
[(unspec_volatile [(match_operand 0 "consttable_operand" "")
|
||||
(match_operand 1 "const_int_operand" "")]
|
||||
@ -6593,6 +6608,49 @@
|
||||
; See tls_get_tp_<mode>
|
||||
(set_attr "can_delay" "no")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; In MIPS16 mode, the TLS base pointer is accessed by a
|
||||
;; libgcc helper function __mips16_rdhwr(), as 'rdhwr' is not
|
||||
;; accessible in MIPS16.
|
||||
;;
|
||||
;; This is not represented as a call insn, to avoid the
|
||||
;; unnecesarry clobbering of caller-save registers by a
|
||||
;; function consisting only of: "rdhwr $3,$29; j $31; nop;"
|
||||
;;
|
||||
;; A $25 clobber is added to cater for a $25 load stub added by the
|
||||
;; linker to __mips16_rdhwr when the call is made from non-PIC code.
|
||||
|
||||
(define_insn_and_split "tls_get_tp_mips16_<mode>"
|
||||
[(set (match_operand:P 0 "register_operand" "=d")
|
||||
(unspec:P [(match_operand:P 1 "call_insn_operand" "dS")]
|
||||
UNSPEC_TLS_GET_TP))
|
||||
(clobber (reg:P TLS_GET_TP_REGNUM))
|
||||
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
||||
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
||||
"HAVE_AS_TLS && TARGET_MIPS16"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (reg:P TLS_GET_TP_REGNUM)
|
||||
(unspec:P [(match_dup 1)] UNSPEC_TLS_GET_TP))
|
||||
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
||||
(clobber (reg:P RETURN_ADDR_REGNUM))])
|
||||
(set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
|
||||
""
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "16")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "*tls_get_tp_mips16_call_<mode>"
|
||||
[(set (reg:P TLS_GET_TP_REGNUM)
|
||||
(unspec:P [(match_operand:P 0 "call_insn_operand" "dS")]
|
||||
UNSPEC_TLS_GET_TP))
|
||||
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
||||
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
||||
"HAVE_AS_TLS && TARGET_MIPS16"
|
||||
{ return MIPS_CALL ("jal", operands, 0, -1); }
|
||||
[(set_attr "type" "call")
|
||||
(set_attr "length" "12")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; Synchronization instructions.
|
||||
|
||||
|
@ -288,12 +288,20 @@
|
||||
&& type == SYMBOL_ABSOLUTE);
|
||||
})
|
||||
|
||||
(define_predicate "symbolic_operand_with_high"
|
||||
(match_code "const,symbol_ref,label_ref")
|
||||
{
|
||||
enum mips_symbol_type type;
|
||||
return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
|
||||
&& mips_hi_relocs[(int) type]);
|
||||
})
|
||||
|
||||
(define_predicate "force_to_mem_operand"
|
||||
(match_code "const,symbol_ref,label_ref")
|
||||
{
|
||||
enum mips_symbol_type symbol_type;
|
||||
return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
|
||||
&& symbol_type == SYMBOL_FORCE_TO_MEM);
|
||||
&& mips_use_pcrel_pool_p[(int) symbol_type]);
|
||||
})
|
||||
|
||||
(define_predicate "got_disp_operand"
|
||||
@ -312,6 +320,14 @@
|
||||
&& type == SYMBOL_GOT_PAGE_OFST);
|
||||
})
|
||||
|
||||
(define_predicate "tls_reloc_operand"
|
||||
(match_code "const,symbol_ref,label_ref")
|
||||
{
|
||||
enum mips_symbol_type type;
|
||||
return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
|
||||
&& (type == SYMBOL_DTPREL || type == SYMBOL_TPREL));
|
||||
})
|
||||
|
||||
(define_predicate "symbol_ref_operand"
|
||||
(match_code "symbol_ref"))
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-01-15 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* gcc.target/mips/code-readable-2.c: Allow the jump table address
|
||||
to be loaded from the constant pool, rather than via %hi and %lo.
|
||||
|
||||
2012-01-15 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR rtl-optimization/51821
|
||||
|
@ -26,8 +26,7 @@ bar (void)
|
||||
|
||||
/* { dg-final { scan-assembler-not "\tla\t" } } */
|
||||
/* { dg-final { scan-assembler-not "\t\\.half\t" } } */
|
||||
/* { dg-final { scan-assembler "%hi\\(\[^)\]*L" } } */
|
||||
/* { dg-final { scan-assembler "%lo\\(\[^)\]*L" } } */
|
||||
/* { dg-final { scan-assembler "\t\\.word\t\[^\n\]*L" } } */
|
||||
|
||||
/* { dg-final { scan-assembler "\t\\.word\tk\n" } } */
|
||||
/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
|
||||
|
@ -1,3 +1,10 @@
|
||||
2012-01-15 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* config/mips/libgcc-mips16.ver (__mips16_rdhwr): Add.
|
||||
* config/mips/mips16.S (__mips16_rdhwr): New function.
|
||||
* config/mips/t-mips16 (LIB1ASMFUNCS): Add _m16rdhwr.
|
||||
|
||||
2012-01-11 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* libgcov.c (__gcov_init): Ignore objects with no functions.
|
||||
|
@ -84,3 +84,7 @@ GCC_4.4.0 {
|
||||
__mips16_call_stub_dc_9
|
||||
__mips16_call_stub_dc_10
|
||||
}
|
||||
|
||||
GCC_4.7.0 {
|
||||
__mips16_rdhwr
|
||||
}
|
||||
|
@ -709,4 +709,15 @@ CALL_STUB_RET (__mips16_call_stub_dc_9, 9, DC)
|
||||
CALL_STUB_RET (__mips16_call_stub_dc_10, 10, DC)
|
||||
#endif
|
||||
#endif /* !__mips_single_float */
|
||||
|
||||
#ifdef L_m16rdhwr
|
||||
STARTFN (__mips16_rdhwr)
|
||||
.set push
|
||||
.set mips32r2
|
||||
.set noreorder
|
||||
rdhwr $3,$29
|
||||
.set pop
|
||||
j $31
|
||||
ENDFN (__mips16_rdhwr)
|
||||
#endif
|
||||
#endif
|
||||
|
@ -36,7 +36,8 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
|
||||
_m16stubsc0 _m16stubsc1 _m16stubsc2 _m16stubsc5 _m16stubsc6 \
|
||||
_m16stubsc9 _m16stubsc10 \
|
||||
_m16stubdc0 _m16stubdc1 _m16stubdc2 _m16stubdc5 _m16stubdc6 \
|
||||
_m16stubdc9 _m16stubdc10
|
||||
_m16stubdc9 _m16stubdc10 \
|
||||
_m16rdhwr
|
||||
|
||||
SYNC = yes
|
||||
SYNC_CFLAGS = -mno-mips16
|
||||
|
Loading…
Reference in New Issue
Block a user