alpha.c (small_symbolic_operand): New.
* config/alpha/alpha.c (small_symbolic_operand): New. (override_options): Set MASK_SMALL_DATA based on pic/PIC. (some_operand, input_operand): Don't handle HIGH. (alpha_legitimize_address): Use it. Emit HIGH with PLUS gp. (alpha_expand_mov): Likewise. (print_operand) [H]: Just print HIGH symbol. (print_operand_address): Handle small data. * config/alpha/alpha.h (MASK_SMALL_DATA, TARGET_SMALL_DATA): New. (TARGET_SWITCHES): Add -msmall-data/large-data. (PIC_OFFSET_TABLE_REGNUM): New. (PREFERRED_RELOAD_CLASS): Don't handle HIGH. (PREDICATE_COES): Update. * config/alpha/alpha.md (adddi_er_high): New. (adddi_er_low): Handle small data. * config/alpha/elf.h (DO_SELECT_SECTION): If SMALL_DATA, prefer .sdata to .rodata. (SELECT_RTX_SECTION): Likewise. From-SVN: r45576
This commit is contained in:
parent
97f4007957
commit
133d313361
5 changed files with 154 additions and 27 deletions
|
@ -1,3 +1,23 @@
|
|||
2001-09-13 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/alpha/alpha.c (small_symbolic_operand): New.
|
||||
(override_options): Set MASK_SMALL_DATA based on pic/PIC.
|
||||
(some_operand, input_operand): Don't handle HIGH.
|
||||
(alpha_legitimize_address): Use it. Emit HIGH with PLUS gp.
|
||||
(alpha_expand_mov): Likewise.
|
||||
(print_operand) [H]: Just print HIGH symbol.
|
||||
(print_operand_address): Handle small data.
|
||||
* config/alpha/alpha.h (MASK_SMALL_DATA, TARGET_SMALL_DATA): New.
|
||||
(TARGET_SWITCHES): Add -msmall-data/large-data.
|
||||
(PIC_OFFSET_TABLE_REGNUM): New.
|
||||
(PREFERRED_RELOAD_CLASS): Don't handle HIGH.
|
||||
(PREDICATE_COES): Update.
|
||||
* config/alpha/alpha.md (adddi_er_high): New.
|
||||
(adddi_er_low): Handle small data.
|
||||
* config/alpha/elf.h (DO_SELECT_SECTION): If SMALL_DATA,
|
||||
prefer .sdata to .rodata.
|
||||
(SELECT_RTX_SECTION): Likewise.
|
||||
|
||||
2001-09-12 Josh Martin <josh.martin@abq.sc.philips.com>
|
||||
|
||||
* fixinc/inclhack.def(hpux11_size_t): Keep HP-UX headers from
|
||||
|
|
|
@ -448,6 +448,12 @@ override_options ()
|
|||
if (!g_switch_set)
|
||||
g_switch_value = 8;
|
||||
|
||||
/* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
|
||||
if (flag_pic == 1)
|
||||
target_flags |= MASK_SMALL_DATA;
|
||||
else if (flag_pic == 2)
|
||||
target_flags &= ~MASK_SMALL_DATA;
|
||||
|
||||
/* Align labels and loops for optimal branching. */
|
||||
/* ??? Kludge these by not doing anything if we don't optimize and also if
|
||||
we are writing ECOFF symbols to work around a bug in DEC's assembler. */
|
||||
|
@ -742,7 +748,7 @@ some_operand (op, mode)
|
|||
switch (GET_CODE (op))
|
||||
{
|
||||
case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
|
||||
case SYMBOL_REF: case CONST: case HIGH:
|
||||
case SYMBOL_REF: case CONST:
|
||||
return 1;
|
||||
|
||||
case SUBREG:
|
||||
|
@ -813,10 +819,6 @@ input_operand (op, mode)
|
|||
case CONSTANT_P_RTX:
|
||||
return 1;
|
||||
|
||||
case HIGH:
|
||||
return (TARGET_EXPLICIT_RELOCS
|
||||
&& local_symbolic_operand (XEXP (op, 0), mode));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -876,6 +878,36 @@ local_symbolic_operand (op, mode)
|
|||
|| (str[0] == '*' && str[1] == '$'));
|
||||
}
|
||||
|
||||
/* Return true if OP is a SYMBOL_REF or CONST referencing a variable
|
||||
known to be defined in this file in the small data area. */
|
||||
|
||||
int
|
||||
small_symbolic_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
const char *str;
|
||||
|
||||
if (! TARGET_SMALL_DATA)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (op) == CONST
|
||||
&& GET_CODE (XEXP (op, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
|
||||
op = XEXP (XEXP (op, 0), 0);
|
||||
|
||||
if (GET_CODE (op) != SYMBOL_REF)
|
||||
return 0;
|
||||
|
||||
if (CONSTANT_POOL_ADDRESS_P (op))
|
||||
return GET_MODE_SIZE (get_pool_mode (op)) <= g_switch_value;
|
||||
else
|
||||
{
|
||||
str = XSTR (op, 0);
|
||||
return str[0] == '@' && str[1] == 's';
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
|
||||
|
||||
int
|
||||
|
@ -1563,9 +1595,24 @@ alpha_legitimize_address (x, oldx, mode)
|
|||
/* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
|
||||
if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, Pmode))
|
||||
{
|
||||
rtx temp = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_HIGH (Pmode, x)));
|
||||
return gen_rtx_LO_SUM (Pmode, temp, x);
|
||||
rtx scratch;
|
||||
|
||||
if (small_symbolic_operand (x, Pmode))
|
||||
scratch = pic_offset_table_rtx;
|
||||
else
|
||||
{
|
||||
rtx insn, tmp;
|
||||
|
||||
scratch = gen_reg_rtx (Pmode);
|
||||
|
||||
tmp = gen_rtx_HIGH (Pmode, x);
|
||||
tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
|
||||
insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
|
||||
return gen_rtx_LO_SUM (Pmode, scratch, x);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -2127,9 +2174,23 @@ alpha_expand_mov (mode, operands)
|
|||
|
||||
if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (operands[1], mode))
|
||||
{
|
||||
rtx scratch = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, scratch,
|
||||
gen_rtx_HIGH (Pmode, operands[1])));
|
||||
rtx scratch;
|
||||
|
||||
if (small_symbolic_operand (operands[1], Pmode))
|
||||
scratch = pic_offset_table_rtx;
|
||||
else
|
||||
{
|
||||
rtx insn, tmp;
|
||||
|
||||
scratch = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
|
||||
|
||||
tmp = gen_rtx_HIGH (Pmode, operands[1]);
|
||||
tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
|
||||
insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
|
||||
operands[1] = gen_rtx_LO_SUM (Pmode, scratch, operands[1]);
|
||||
return false;
|
||||
}
|
||||
|
@ -4773,10 +4834,7 @@ print_operand (file, x, code)
|
|||
|
||||
case 'H':
|
||||
if (GET_CODE (x) == HIGH)
|
||||
{
|
||||
output_addr_const (file, XEXP (x, 0));
|
||||
fputs ("($29)\t\t!gprelhigh", file);
|
||||
}
|
||||
output_addr_const (file, XEXP (x, 0));
|
||||
else
|
||||
output_operand_lossage ("invalid %%H value");
|
||||
break;
|
||||
|
@ -5056,7 +5114,9 @@ print_operand_address (file, addr)
|
|||
basereg = subreg_regno (addr);
|
||||
else
|
||||
abort ();
|
||||
fprintf (file, "($%d)\t\t!gprellow", basereg);
|
||||
|
||||
fprintf (file, "($%d)\t\t!%s", basereg,
|
||||
(basereg == 29 ? "gprel" : "gprellow"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,6 +162,10 @@ extern enum alpha_fp_trap_mode alpha_fptm;
|
|||
#define MASK_EXPLICIT_RELOCS (1 << 12)
|
||||
#define TARGET_EXPLICIT_RELOCS (target_flags & MASK_EXPLICIT_RELOCS)
|
||||
|
||||
/* This means use 16-bit relocations to .sdata/.sbss. */
|
||||
#define MASK_SMALL_DATA (1 << 13)
|
||||
#define TARGET_SMALL_DATA (target_flags & MASK_SMALL_DATA)
|
||||
|
||||
/* This means that the processor is an EV5, EV56, or PCA56.
|
||||
Unlike alpha_cpu this is not affected by -mtune= setting. */
|
||||
#define MASK_CPU_EV5 (1 << 28)
|
||||
|
@ -240,6 +244,10 @@ extern enum alpha_fp_trap_mode alpha_fptm;
|
|||
{"explicit-relocs", MASK_EXPLICIT_RELOCS, \
|
||||
N_("Emit code using explicit relocation directives")}, \
|
||||
{"no-explicit-relocs", -MASK_EXPLICIT_RELOCS, ""}, \
|
||||
{"small-data", MASK_SMALL_DATA, \
|
||||
N_("Emit 16-bit relocations to the small data areas")}, \
|
||||
{"large-data", -MASK_SMALL_DATA, \
|
||||
N_("Emit 32-bit relocations to the small data areas")}, \
|
||||
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} }
|
||||
|
||||
#define TARGET_DEFAULT MASK_FP|MASK_FPREGS
|
||||
|
@ -684,6 +692,18 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
|||
doesn't seem to specify this. */
|
||||
#define STATIC_CHAIN_REGNUM 1
|
||||
|
||||
/* The register number of the register used to address a table of
|
||||
static data addresses in memory. */
|
||||
#define PIC_OFFSET_TABLE_REGNUM 29
|
||||
|
||||
/* Define this macro if the register defined by `PIC_OFFSET_TABLE_REGNUM'
|
||||
is clobbered by calls. */
|
||||
/* ??? It is and it isn't. It's required to be valid for a given
|
||||
function when the function returns. It isn't clobbered by
|
||||
current_file functions. Moreover, we do not expose the ldgp
|
||||
until after reload, so we're probably safe. */
|
||||
/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
|
||||
|
||||
/* Register in which address to store a structure value
|
||||
arrives in the function. On the Alpha, the address is passed
|
||||
as a hidden argument. */
|
||||
|
@ -821,8 +841,7 @@ enum reg_class { NO_REGS, PV_REG, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
|
|||
register via memory. */
|
||||
|
||||
#define PREFERRED_RELOAD_CLASS(X, CLASS) \
|
||||
(GET_CODE (X) == HIGH ? GENERAL_REGS \
|
||||
: CONSTANT_P (X) && (X) != const0_rtx && (X) != CONST0_RTX (GET_MODE (X)) \
|
||||
(CONSTANT_P (X) && (X) != const0_rtx && (X) != CONST0_RTX (GET_MODE (X)) \
|
||||
? ((CLASS) == FLOAT_REGS || (CLASS) == NO_REGS ? NO_REGS : GENERAL_REGS) \
|
||||
: (CLASS))
|
||||
|
||||
|
@ -2172,9 +2191,9 @@ do { \
|
|||
{"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
|
||||
{"call_operand", {REG, SYMBOL_REF}}, \
|
||||
{"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
|
||||
SYMBOL_REF, CONST, LABEL_REF, HIGH, LO_SUM}}, \
|
||||
SYMBOL_REF, CONST, LABEL_REF}}, \
|
||||
{"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
|
||||
SYMBOL_REF, CONST, LABEL_REF, HIGH, LO_SUM}}, \
|
||||
SYMBOL_REF, CONST, LABEL_REF}}, \
|
||||
{"some_ni_operand", {SUBREG, REG, MEM}}, \
|
||||
{"aligned_memory_operand", {MEM}}, \
|
||||
{"unaligned_memory_operand", {MEM}}, \
|
||||
|
|
|
@ -638,6 +638,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn "*adddi_er_high"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
||||
(high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
|
||||
"TARGET_EXPLICIT_RELOCS"
|
||||
"ldah %0,%2(%1)\t\t!gprelhigh")
|
||||
|
||||
;; We used to expend quite a lot of effort choosing addq/subq/lda.
|
||||
;; With complications like
|
||||
;;
|
||||
|
@ -5298,7 +5305,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
||||
(match_operand:DI 2 "local_symbolic_operand" "")))]
|
||||
"TARGET_EXPLICIT_RELOCS"
|
||||
"lda %0,%2(%1)\t\t!gprellow")
|
||||
{
|
||||
if (true_regnum (operands[1]) == 29)
|
||||
return "lda %0,%2(%1)\t\t!gprel";
|
||||
else
|
||||
return "lda %0,%2(%1)\t\t!gprellow";
|
||||
})
|
||||
|
||||
(define_insn "*movdi_er_nofix"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
|
||||
|
|
|
@ -302,15 +302,20 @@ void FN () \
|
|||
#define DO_SELECT_SECTION(SECNUM, DECL, RELOC) \
|
||||
do \
|
||||
{ \
|
||||
HOST_WIDE_INT size; \
|
||||
SECNUM = 1; \
|
||||
if (TREE_CODE (DECL) == FUNCTION_DECL) \
|
||||
SECNUM = 0; \
|
||||
{ \
|
||||
SECNUM = 0; \
|
||||
break; \
|
||||
} \
|
||||
else if (TREE_CODE (DECL) == STRING_CST) \
|
||||
{ \
|
||||
if (flag_writable_strings) \
|
||||
SECNUM = 2; \
|
||||
else \
|
||||
SECNUM = 0x101; \
|
||||
break; \
|
||||
} \
|
||||
else if (TREE_CODE (DECL) == VAR_DECL) \
|
||||
{ \
|
||||
|
@ -344,11 +349,16 @@ void FN () \
|
|||
} \
|
||||
\
|
||||
/* Select small data sections based on size. */ \
|
||||
if ((SECNUM & 0xff) >= 2) \
|
||||
size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
||||
if (size >= 0 && size <= g_switch_value) \
|
||||
{ \
|
||||
int size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
||||
if (size >= 0 && size <= g_switch_value) \
|
||||
if ((SECNUM & 0xff) >= 2) \
|
||||
SECNUM += 1; \
|
||||
/* Move readonly data to .sdata only if -msmall-data. */ \
|
||||
/* ??? Consider .sdata.{lit4,lit8} as \
|
||||
SHF_MERGE|SHF_ALPHA_GPREL. */ \
|
||||
else if (TARGET_SMALL_DATA) \
|
||||
SECNUM = 3; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
@ -437,8 +447,14 @@ void FN () \
|
|||
go into the const section. */
|
||||
|
||||
#undef SELECT_RTX_SECTION
|
||||
#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
|
||||
mergeable_constant_section((MODE), (ALIGN), 0)
|
||||
#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
|
||||
do { \
|
||||
if (TARGET_SMALL_DATA && GET_MODE_SIZE (MODE) <= g_switch_value) \
|
||||
/* ??? Consider .sdata.{lit4,lit8} as SHF_MERGE|SHF_ALPHA_GPREL. */ \
|
||||
sdata_section (); \
|
||||
else \
|
||||
mergeable_constant_section((MODE), (ALIGN), 0); \
|
||||
} while (0)
|
||||
|
||||
/* Define the strings used for the special svr4 .type and .size directives.
|
||||
These strings generally do not vary from one system running svr4 to
|
||||
|
|
Loading…
Add table
Reference in a new issue