alpha.c (alpha_next_sequence_number): New.
* config/alpha/alpha.c (alpha_next_sequence_number): New. (alpha_this_literal_sequence_number): New. (alpha_this_gpdisp_sequence_number): New. (some_operand, input_operand): Add HIGH. (local_symbolic_operand): New. (alpha_encode_section_info): New. (alpha_legitimate_address_p): Allow LO_SUM. (alpha_legitimize_address): Generate HIGH+LO_SUM. (alpha_expand_mov): Likewise. (secondary_reload_class): Check memory_operand not general_operand for FP_REGS test. (alpha_expand_unaligned_load): Force LO_SUM addresses into a register. (alpha_expand_unaligned_store): Likewise. (alpha_expand_unaligned_load_words): Likewise. (alpha_expand_unaligned_store_words): Likewise. (alpha_expand_block_clear): Likewise. (print_operand): Handle %#, %*, %H. (print_operand_address): Handle LO_SUM. (find_lo_sum): New. (alpha_does_function_need_gp): Use it. (alpha_expand_block_move): Fix signed compare warnings. (alpha_sa_mask, alpha_align_insns): Likewise. * config/alpha/alpha-protos.h: Update. * config/alpha/alpha.h (TARGET_EXPLICIT_RELOCS): New. (MASK_EXPLICIT_RELOCS): New. (TARGET_SWITCHES): Add -mexplicit-relocs. (EXTRA_CONSTRAINT): Add 'T'. (PREFERRED_RELOAD_CLASS): HIGH goes in GENERAL_REGS. (ASM_APP_ON, ASM_APP_OFF): Turn on and off asm macro expansion. (ENCODE_SECTION_INFO): Out line. (REDO_SECTION_INFO_P): New. (STRIP_NAME_ENCODING): New. (ASM_OUTPUT_LABELREF): New. (PRINT_OPERAND_PUNCT_VALID_P): Add #, *. (PREDICATE_CODES): Update. * config/alpha/alpha.md (divmodsi_internal_er, divmoddi_internal_er, call_osf_1_er_noreturn, call_osf_1_er, movdi_er_low, movdi_er_nofix, movdi_er_fix, prologue_ldgp_1_er, builtin_setjmp_receiver_sub_label_er, builtin_setjmp_receiver_er, exception_receiver_1_er, call_value_osf_1_er): New patterns. (sibcall_osf_1, sibcall_value_osf_1): Remove register alternative. (movqi, movhi, movsi): Add explicit $31 base register to lda. * config/alpha/elf.h (ASM_FILE_START): Set nomacro if explicit relocs. (FINAL_PRESCAN_INSN): New. From-SVN: r45493
This commit is contained in:
parent
7b95ee3dda
commit
1eb356b98d
6 changed files with 581 additions and 77 deletions
|
@ -1,3 +1,50 @@
|
|||
2001-09-09 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/alpha/alpha.c (alpha_next_sequence_number): New.
|
||||
(alpha_this_literal_sequence_number): New.
|
||||
(alpha_this_gpdisp_sequence_number): New.
|
||||
(some_operand, input_operand): Add HIGH.
|
||||
(local_symbolic_operand): New.
|
||||
(alpha_encode_section_info): New.
|
||||
(alpha_legitimate_address_p): Allow LO_SUM.
|
||||
(alpha_legitimize_address): Generate HIGH+LO_SUM.
|
||||
(alpha_expand_mov): Likewise.
|
||||
(secondary_reload_class): Check memory_operand not general_operand
|
||||
for FP_REGS test.
|
||||
(alpha_expand_unaligned_load): Force LO_SUM addresses into a register.
|
||||
(alpha_expand_unaligned_store): Likewise.
|
||||
(alpha_expand_unaligned_load_words): Likewise.
|
||||
(alpha_expand_unaligned_store_words): Likewise.
|
||||
(alpha_expand_block_clear): Likewise.
|
||||
(print_operand): Handle %#, %*, %H.
|
||||
(print_operand_address): Handle LO_SUM.
|
||||
(find_lo_sum): New.
|
||||
(alpha_does_function_need_gp): Use it.
|
||||
(alpha_expand_block_move): Fix signed compare warnings.
|
||||
(alpha_sa_mask, alpha_align_insns): Likewise.
|
||||
* config/alpha/alpha-protos.h: Update.
|
||||
* config/alpha/alpha.h (TARGET_EXPLICIT_RELOCS): New.
|
||||
(MASK_EXPLICIT_RELOCS): New.
|
||||
(TARGET_SWITCHES): Add -mexplicit-relocs.
|
||||
(EXTRA_CONSTRAINT): Add 'T'.
|
||||
(PREFERRED_RELOAD_CLASS): HIGH goes in GENERAL_REGS.
|
||||
(ASM_APP_ON, ASM_APP_OFF): Turn on and off asm macro expansion.
|
||||
(ENCODE_SECTION_INFO): Out line.
|
||||
(REDO_SECTION_INFO_P): New.
|
||||
(STRIP_NAME_ENCODING): New.
|
||||
(ASM_OUTPUT_LABELREF): New.
|
||||
(PRINT_OPERAND_PUNCT_VALID_P): Add #, *.
|
||||
(PREDICATE_CODES): Update.
|
||||
* config/alpha/alpha.md (divmodsi_internal_er, divmoddi_internal_er,
|
||||
call_osf_1_er_noreturn, call_osf_1_er, movdi_er_low, movdi_er_nofix,
|
||||
movdi_er_fix, prologue_ldgp_1_er, builtin_setjmp_receiver_sub_label_er,
|
||||
builtin_setjmp_receiver_er, exception_receiver_1_er,
|
||||
call_value_osf_1_er): New patterns.
|
||||
(sibcall_osf_1, sibcall_value_osf_1): Remove register alternative.
|
||||
(movqi, movhi, movsi): Add explicit $31 base register to lda.
|
||||
* config/alpha/elf.h (ASM_FILE_START): Set nomacro if explicit relocs.
|
||||
(FINAL_PRESCAN_INSN): New.
|
||||
|
||||
Sat Sep 8 22:00:55 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* reg-stack.c (subst_stack_regs_pat): Fix fcmov reversal code.
|
||||
|
|
|
@ -54,6 +54,7 @@ extern int some_operand PARAMS ((rtx, enum machine_mode));
|
|||
extern int some_ni_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int input_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int call_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));
|
||||
extern int alpha_zero_comparison_operator PARAMS ((rtx, enum machine_mode));
|
||||
|
@ -146,4 +147,5 @@ extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
|
|||
#endif
|
||||
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
|
||||
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
|
||||
extern void alpha_encode_section_info PARAMS ((tree));
|
||||
#endif /* TREE CODE */
|
||||
|
|
|
@ -105,6 +105,14 @@ static int alpha_sr_alias_set;
|
|||
|
||||
static const char *alpha_fnname;
|
||||
|
||||
/* The next explicit relocation sequence number. */
|
||||
int alpha_next_sequence_number = 1;
|
||||
|
||||
/* The literal and gpdisp sequence numbers for this insn, as printed
|
||||
by %# and %* respectively. */
|
||||
int alpha_this_literal_sequence_number;
|
||||
int alpha_this_gpdisp_sequence_number;
|
||||
|
||||
/* Declarations of static functions. */
|
||||
static void alpha_set_memflags_1
|
||||
PARAMS ((rtx, int, int, int));
|
||||
|
@ -116,6 +124,8 @@ static void alpha_expand_unaligned_store_words
|
|||
PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
|
||||
static void alpha_sa_mask
|
||||
PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
|
||||
static int find_lo_sum
|
||||
PARAMS ((rtx *, void *));
|
||||
static int alpha_does_function_need_gp
|
||||
PARAMS ((void));
|
||||
static int alpha_ra_ever_killed
|
||||
|
@ -662,7 +672,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 SYMBOL_REF: case CONST: case HIGH:
|
||||
return 1;
|
||||
|
||||
case SUBREG:
|
||||
|
@ -733,6 +743,10 @@ 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;
|
||||
}
|
||||
|
@ -754,6 +768,41 @@ current_file_function_operand (op, mode)
|
|||
|| op == XEXP (DECL_RTL (current_function_decl), 0)));
|
||||
}
|
||||
|
||||
/* Return true if OP is a SYMBOL_REF or CONST referencing a variable
|
||||
known to be defined in this file. */
|
||||
|
||||
int
|
||||
local_symbolic_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
const char *str;
|
||||
|
||||
if (GET_CODE (op) == LABEL_REF)
|
||||
return 1;
|
||||
|
||||
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;
|
||||
|
||||
str = XSTR (op, 0);
|
||||
|
||||
/* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
|
||||
run into problems with the rtl inliner in that the symbol was
|
||||
once external, but is local after inlining, which results in
|
||||
unrecognizable insns. */
|
||||
|
||||
return (CONSTANT_POOL_ADDRESS_P (op)
|
||||
/* If @, then ENCODE_SECTION_INFO sez it's local. */
|
||||
|| str[0] == '@'
|
||||
/* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local. */
|
||||
|| (str[0] == '*' && str[1] == '$'));
|
||||
}
|
||||
|
||||
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
|
||||
|
||||
int
|
||||
|
@ -1154,6 +1203,120 @@ alpha_tablejump_best_label (insn)
|
|||
return best_label ? best_label : const0_rtx;
|
||||
}
|
||||
|
||||
/* If we are referencing a function that is static, make the SYMBOL_REF
|
||||
special. We use this to see indicate we can branch to this function
|
||||
without setting PV or restoring GP.
|
||||
|
||||
If this is a variable that is known to be defined locally, add "@v"
|
||||
to the name. If in addition the variable is to go in .sdata/.sbss,
|
||||
then add "@s" instead. */
|
||||
|
||||
void
|
||||
alpha_encode_section_info (decl)
|
||||
tree decl;
|
||||
{
|
||||
const char *symbol_str;
|
||||
bool is_local, is_small;
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
if (! TREE_PUBLIC (decl))
|
||||
SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Early out if we're not going to do anything with this data. */
|
||||
if (! TARGET_EXPLICIT_RELOCS)
|
||||
return;
|
||||
|
||||
/* Careful not to prod global register variables. */
|
||||
if (TREE_CODE (decl) != VAR_DECL
|
||||
|| GET_CODE (DECL_RTL (decl)) != MEM
|
||||
|| GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
|
||||
return;
|
||||
|
||||
symbol_str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
|
||||
|
||||
/* A variable is considered "local" if it is defined in this module. */
|
||||
|
||||
if (DECL_EXTERNAL (decl))
|
||||
is_local = false;
|
||||
/* Linkonce and weak data is never local. */
|
||||
else if (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
|
||||
is_local = false;
|
||||
else if (! TREE_PUBLIC (decl))
|
||||
is_local = true;
|
||||
/* If PIC, then assume that any global name can be overridden by
|
||||
symbols resolved from other modules. */
|
||||
else if (flag_pic)
|
||||
is_local = false;
|
||||
/* Uninitialized COMMON variable may be unified with symbols
|
||||
resolved from other modules. */
|
||||
else if (DECL_COMMON (decl)
|
||||
&& (DECL_INITIAL (decl) == NULL
|
||||
|| DECL_INITIAL (decl) == error_mark_node))
|
||||
is_local = false;
|
||||
/* Otherwise we're left with initialized (or non-common) global data
|
||||
which is of necessity defined locally. */
|
||||
else
|
||||
is_local = true;
|
||||
|
||||
/* Determine if DECL will wind up in .sdata/.sbss. */
|
||||
|
||||
is_small = false;
|
||||
if (DECL_SECTION_NAME (decl))
|
||||
{
|
||||
const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
|
||||
if (strcmp (section, ".sdata") == 0
|
||||
|| strcmp (section, ".sbss") == 0)
|
||||
is_small = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
|
||||
|
||||
/* If the variable has already been defined in the output file, then it
|
||||
is too late to put it in sdata if it wasn't put there in the first
|
||||
place. The test is here rather than above, because if it is already
|
||||
in sdata, then it can stay there. */
|
||||
|
||||
if (TREE_ASM_WRITTEN (decl))
|
||||
;
|
||||
|
||||
/* If this is an incomplete type with size 0, then we can't put it in
|
||||
sdata because it might be too big when completed. */
|
||||
else if (size > 0 && size <= g_switch_value)
|
||||
is_small = true;
|
||||
}
|
||||
|
||||
/* Finally, encode this into the symbol string. */
|
||||
if (is_local)
|
||||
{
|
||||
const char *string;
|
||||
char *newstr;
|
||||
size_t len;
|
||||
|
||||
if (symbol_str[0] == '@')
|
||||
{
|
||||
if (symbol_str[1] == (is_small ? 's' : 'v'))
|
||||
return;
|
||||
symbol_str += 2;
|
||||
}
|
||||
|
||||
len = strlen (symbol_str) + 1;
|
||||
newstr = alloca (len + 2);
|
||||
|
||||
newstr[0] = '@';
|
||||
newstr[1] = (is_small ? 's' : 'v');
|
||||
memcpy (newstr + 2, symbol_str, len);
|
||||
|
||||
string = ggc_alloc_string (newstr, len + 2 - 1);
|
||||
XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
|
||||
}
|
||||
else if (symbol_str[0] == '@')
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* legitimate_address_p recognizes an RTL expression that is a valid
|
||||
memory address for an instruction. The MODE argument is the
|
||||
machine mode for the MEM expression that wants to use this address.
|
||||
|
@ -1222,6 +1385,30 @@ alpha_legitimate_address_p (mode, x, strict)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* If we're managing explicit relocations, LO_SUM is valid. */
|
||||
else if (TARGET_EXPLICIT_RELOCS && GET_CODE (x) == LO_SUM)
|
||||
{
|
||||
rtx ofs = XEXP (x, 1);
|
||||
x = XEXP (x, 0);
|
||||
|
||||
/* Discard non-paradoxical subregs. */
|
||||
if (GET_CODE (x) == SUBREG
|
||||
&& (GET_MODE_SIZE (GET_MODE (x))
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
|
||||
x = SUBREG_REG (x);
|
||||
|
||||
/* Must have a valid base register. */
|
||||
if (! (REG_P (x)
|
||||
&& (strict
|
||||
? STRICT_REG_OK_FOR_BASE_P (x)
|
||||
: NONSTRICT_REG_OK_FOR_BASE_P (x))))
|
||||
return false;
|
||||
|
||||
/* The symbol must be local. */
|
||||
if (local_symbolic_operand (ofs, Pmode))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1278,6 +1465,14 @@ alpha_legitimize_address (x, oldx, mode)
|
|||
goto split_addend;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
split_addend:
|
||||
|
@ -1465,7 +1660,8 @@ secondary_reload_class (class, mode, x, in)
|
|||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
|
||||
return GENERAL_REGS;
|
||||
|
||||
if (in && INTEGRAL_MODE_P (mode) && ! general_operand (x, mode))
|
||||
if (in && INTEGRAL_MODE_P (mode)
|
||||
&& ! (memory_operand (x, mode) || x == const0_rtx))
|
||||
return GENERAL_REGS;
|
||||
}
|
||||
|
||||
|
@ -1830,6 +2026,15 @@ alpha_expand_mov (mode, operands)
|
|||
&& ! reg_or_0_operand (operands[1], mode))
|
||||
operands[1] = force_reg (mode, operands[1]);
|
||||
|
||||
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])));
|
||||
operands[1] = gen_rtx_LO_SUM (Pmode, scratch, operands[1]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Early out for non-constants and valid constants. */
|
||||
if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
|
||||
return false;
|
||||
|
@ -2961,7 +3166,7 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
|
|||
HOST_WIDE_INT size, ofs;
|
||||
int sign;
|
||||
{
|
||||
rtx meml, memh, addr, extl, exth, tmp;
|
||||
rtx meml, memh, addr, extl, exth, tmp, mema;
|
||||
enum machine_mode mode;
|
||||
|
||||
meml = gen_reg_rtx (DImode);
|
||||
|
@ -2970,28 +3175,31 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
|
|||
extl = gen_reg_rtx (DImode);
|
||||
exth = gen_reg_rtx (DImode);
|
||||
|
||||
mema = XEXP (mem, 0);
|
||||
if (GET_CODE (mema) == LO_SUM)
|
||||
mema = force_reg (Pmode, mema);
|
||||
|
||||
/* AND addresses cannot be in any alias set, since they may implicitly
|
||||
alias surrounding code. Ideally we'd have some alias set that
|
||||
covered all types except those with alignment 8 or higher. */
|
||||
|
||||
tmp = change_address (mem, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP (mem, 0), ofs),
|
||||
plus_constant (mema, ofs),
|
||||
GEN_INT (-8)));
|
||||
set_mem_alias_set (tmp, 0);
|
||||
emit_move_insn (meml, tmp);
|
||||
|
||||
tmp = change_address (mem, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP (mem, 0),
|
||||
ofs + size - 1),
|
||||
plus_constant (mema, ofs + size - 1),
|
||||
GEN_INT (-8)));
|
||||
set_mem_alias_set (tmp, 0);
|
||||
emit_move_insn (memh, tmp);
|
||||
|
||||
if (sign && size == 2)
|
||||
{
|
||||
emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
|
||||
emit_move_insn (addr, plus_constant (mema, ofs+2));
|
||||
|
||||
emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
|
||||
emit_insn (gen_extqh (exth, memh, addr));
|
||||
|
@ -3005,7 +3213,7 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
|
|||
}
|
||||
else
|
||||
{
|
||||
emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
|
||||
emit_move_insn (addr, plus_constant (mema, ofs));
|
||||
emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
|
||||
switch ((int) size)
|
||||
{
|
||||
|
@ -3044,33 +3252,36 @@ alpha_expand_unaligned_store (dst, src, size, ofs)
|
|||
rtx dst, src;
|
||||
HOST_WIDE_INT size, ofs;
|
||||
{
|
||||
rtx dstl, dsth, addr, insl, insh, meml, memh;
|
||||
rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
|
||||
|
||||
dstl = gen_reg_rtx (DImode);
|
||||
dsth = gen_reg_rtx (DImode);
|
||||
insl = gen_reg_rtx (DImode);
|
||||
insh = gen_reg_rtx (DImode);
|
||||
|
||||
dsta = XEXP (dst, 0);
|
||||
if (GET_CODE (dsta) == LO_SUM)
|
||||
dsta = force_reg (Pmode, dsta);
|
||||
|
||||
/* AND addresses cannot be in any alias set, since they may implicitly
|
||||
alias surrounding code. Ideally we'd have some alias set that
|
||||
covered all types except those with alignment 8 or higher. */
|
||||
|
||||
meml = change_address (dst, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP (dst, 0), ofs),
|
||||
plus_constant (dsta, ofs),
|
||||
GEN_INT (-8)));
|
||||
set_mem_alias_set (meml, 0);
|
||||
|
||||
memh = change_address (dst, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP (dst, 0),
|
||||
ofs+size-1),
|
||||
plus_constant (dsta, ofs + size - 1),
|
||||
GEN_INT (-8)));
|
||||
set_mem_alias_set (memh, 0);
|
||||
|
||||
emit_move_insn (dsth, memh);
|
||||
emit_move_insn (dstl, meml);
|
||||
addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
|
||||
addr = copy_addr_to_reg (plus_constant (dsta, ofs));
|
||||
|
||||
if (src != const0_rtx)
|
||||
{
|
||||
|
@ -3143,9 +3354,13 @@ alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
|
|||
rtx const im8 = GEN_INT (-8);
|
||||
rtx const i64 = GEN_INT (64);
|
||||
rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
|
||||
rtx sreg, areg, tmp;
|
||||
rtx sreg, areg, tmp, smema;
|
||||
HOST_WIDE_INT i;
|
||||
|
||||
smema = XEXP (smem, 0);
|
||||
if (GET_CODE (smema) == LO_SUM)
|
||||
smema = force_reg (Pmode, smema);
|
||||
|
||||
/* Generate all the tmp registers we need. */
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
|
@ -3162,7 +3377,7 @@ alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
|
|||
{
|
||||
tmp = change_address (smem, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP(smem,0), 8*i),
|
||||
plus_constant (smema, 8*i),
|
||||
im8));
|
||||
set_mem_alias_set (tmp, 0);
|
||||
emit_move_insn (data_regs[i], tmp);
|
||||
|
@ -3170,7 +3385,7 @@ alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
|
|||
|
||||
tmp = change_address (smem, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP(smem,0), 8*words - 1),
|
||||
plus_constant (smema, 8*words - 1),
|
||||
im8));
|
||||
set_mem_alias_set (tmp, 0);
|
||||
emit_move_insn (data_regs[words], tmp);
|
||||
|
@ -3179,7 +3394,7 @@ alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
|
|||
extxh with offset zero a noop instead of zeroing the register, so
|
||||
we must take care of that edge condition ourselves with cmov. */
|
||||
|
||||
sreg = copy_addr_to_reg (XEXP (smem, 0));
|
||||
sreg = copy_addr_to_reg (smema);
|
||||
areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
|
||||
1, OPTAB_WIDEN);
|
||||
for (i = 0; i < words; ++i)
|
||||
|
@ -3220,9 +3435,13 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
|
|||
#endif
|
||||
rtx ins_tmps[MAX_MOVE_WORDS];
|
||||
rtx st_tmp_1, st_tmp_2, dreg;
|
||||
rtx st_addr_1, st_addr_2;
|
||||
rtx st_addr_1, st_addr_2, dmema;
|
||||
HOST_WIDE_INT i;
|
||||
|
||||
dmema = XEXP (dmem, 0);
|
||||
if (GET_CODE (dmema) == LO_SUM)
|
||||
dmema = force_reg (Pmode, dmema);
|
||||
|
||||
/* Generate all the tmp registers we need. */
|
||||
if (data_regs != NULL)
|
||||
for (i = 0; i < words; ++i)
|
||||
|
@ -3235,15 +3454,12 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
|
|||
|
||||
st_addr_2 = change_address (dmem, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP(dmem,0),
|
||||
words*8 - 1),
|
||||
plus_constant (dmema, words*8 - 1),
|
||||
im8));
|
||||
set_mem_alias_set (st_addr_2, 0);
|
||||
|
||||
st_addr_1 = change_address (dmem, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
XEXP (dmem, 0),
|
||||
im8));
|
||||
gen_rtx_AND (DImode, dmema, im8));
|
||||
set_mem_alias_set (st_addr_1, 0);
|
||||
|
||||
/* Load up the destination end bits. */
|
||||
|
@ -3251,7 +3467,7 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
|
|||
emit_move_insn (st_tmp_1, st_addr_1);
|
||||
|
||||
/* Shift the input data into place. */
|
||||
dreg = copy_addr_to_reg (XEXP (dmem, 0));
|
||||
dreg = copy_addr_to_reg (dmema);
|
||||
if (data_regs != NULL)
|
||||
{
|
||||
for (i = words-1; i >= 0; --i)
|
||||
|
@ -3285,7 +3501,7 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
|
|||
{
|
||||
rtx tmp = change_address (dmem, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant(XEXP (dmem,0), i*8),
|
||||
plus_constant(dmema, i*8),
|
||||
im8));
|
||||
set_mem_alias_set (tmp, 0);
|
||||
emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
|
||||
|
@ -3315,7 +3531,7 @@ alpha_expand_block_move (operands)
|
|||
rtx orig_dst = operands[0];
|
||||
rtx data_regs[2 * MAX_MOVE_WORDS + 16];
|
||||
rtx tmp;
|
||||
int i, words, ofs, nregs = 0;
|
||||
unsigned int i, words, ofs, nregs = 0;
|
||||
|
||||
if (orig_bytes <= 0)
|
||||
return 1;
|
||||
|
@ -3773,7 +3989,7 @@ alpha_expand_block_clear (operands)
|
|||
words = bytes / 8;
|
||||
|
||||
for (i = 0; i < words; ++i)
|
||||
emit_move_insn (adjust_address(orig_dst, DImode, ofs + i * 8),
|
||||
emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
|
||||
const0_rtx);
|
||||
|
||||
bytes -= words * 8;
|
||||
|
@ -3785,18 +4001,23 @@ alpha_expand_block_clear (operands)
|
|||
|
||||
if (align >= 32 && bytes > 16)
|
||||
{
|
||||
rtx orig_dsta;
|
||||
|
||||
emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
|
||||
bytes -= 4;
|
||||
ofs += 4;
|
||||
|
||||
orig_dsta = XEXP (orig_dst, 0);
|
||||
if (GET_CODE (orig_dsta) == LO_SUM)
|
||||
orig_dsta = force_reg (Pmode, orig_dsta);
|
||||
|
||||
words = bytes / 8;
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
rtx mem
|
||||
= change_address (orig_dst, DImode,
|
||||
gen_rtx_AND (DImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
ofs + i*8),
|
||||
plus_constant (orig_dsta, ofs + i*8),
|
||||
GEN_INT (-8)));
|
||||
set_mem_alias_set (mem, 0);
|
||||
emit_move_insn (mem, const0_rtx);
|
||||
|
@ -4272,6 +4493,28 @@ print_operand (file, x, code)
|
|||
fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
|
||||
break;
|
||||
|
||||
case '#':
|
||||
if (alpha_this_literal_sequence_number == 0)
|
||||
alpha_this_literal_sequence_number = alpha_next_sequence_number++;
|
||||
fprintf (file, "%d", alpha_this_literal_sequence_number);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (alpha_this_gpdisp_sequence_number == 0)
|
||||
alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
|
||||
fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
if (GET_CODE (x) == HIGH)
|
||||
{
|
||||
output_addr_const (file, XEXP (x, 0));
|
||||
fputs ("($29)\t\t!gprelhigh", file);
|
||||
}
|
||||
else
|
||||
output_operand_lossage ("invalid %%H value");
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
/* If this operand is the constant zero, write it as "$31". */
|
||||
if (GET_CODE (x) == REG)
|
||||
|
@ -4280,7 +4523,6 @@ print_operand (file, x, code)
|
|||
fprintf (file, "$31");
|
||||
else
|
||||
output_operand_lossage ("invalid %%r value");
|
||||
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
|
@ -4291,7 +4533,6 @@ print_operand (file, x, code)
|
|||
fprintf (file, "$f31");
|
||||
else
|
||||
output_operand_lossage ("invalid %%R value");
|
||||
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
|
@ -4512,12 +4753,33 @@ print_operand_address (file, addr)
|
|||
offset = INTVAL (XEXP (addr, 1));
|
||||
addr = XEXP (addr, 0);
|
||||
}
|
||||
|
||||
if (GET_CODE (addr) == LO_SUM)
|
||||
{
|
||||
output_addr_const (file, XEXP (addr, 1));
|
||||
if (offset)
|
||||
{
|
||||
fputc ('+', file);
|
||||
fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
|
||||
}
|
||||
|
||||
addr = XEXP (addr, 0);
|
||||
if (GET_CODE (addr) == REG)
|
||||
basereg = REGNO (addr);
|
||||
else if (GET_CODE (addr) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (addr)) == REG)
|
||||
basereg = subreg_regno (addr);
|
||||
else
|
||||
abort ();
|
||||
fprintf (file, "($%d)\t\t!gprellow", basereg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GET_CODE (addr) == REG)
|
||||
basereg = REGNO (addr);
|
||||
else if (GET_CODE (addr) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (addr)) == REG)
|
||||
basereg = REGNO (SUBREG_REG (addr))
|
||||
+ SUBREG_BYTE (addr) / GET_MODE_SIZE (GET_MODE (addr));
|
||||
basereg = subreg_regno (addr);
|
||||
else if (GET_CODE (addr) == CONST_INT)
|
||||
offset = INTVAL (addr);
|
||||
else
|
||||
|
@ -4827,7 +5089,7 @@ alpha_sa_mask (imaskP, fmaskP)
|
|||
{
|
||||
unsigned long imask = 0;
|
||||
unsigned long fmask = 0;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
#ifdef ASM_OUTPUT_MI_THUNK
|
||||
if (!current_function_is_thunk)
|
||||
|
@ -4968,6 +5230,14 @@ vms_valid_decl_attribute_p (decl, attributes, identifier, args)
|
|||
|
||||
#endif
|
||||
|
||||
static int
|
||||
find_lo_sum (px, data)
|
||||
rtx *px;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return GET_CODE (*px) == LO_SUM;
|
||||
}
|
||||
|
||||
static int
|
||||
alpha_does_function_need_gp ()
|
||||
{
|
||||
|
@ -5001,6 +5271,9 @@ alpha_does_function_need_gp ()
|
|||
enum attr_type type = get_attr_type (insn);
|
||||
if (type == TYPE_LDSYM || type == TYPE_JSR)
|
||||
return 1;
|
||||
if (TARGET_EXPLICIT_RELOCS
|
||||
&& for_each_rtx (&PATTERN (insn), find_lo_sum, NULL) > 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -6606,7 +6879,7 @@ alpha_align_insns (insns, max_align, next_group, next_nop)
|
|||
|
||||
/* If the known alignment is smaller than the recognized insn group,
|
||||
realign the output. */
|
||||
else if (align < len)
|
||||
else if ((int) align < len)
|
||||
{
|
||||
unsigned int new_log_align = len > 8 ? 4 : 3;
|
||||
rtx where;
|
||||
|
@ -6626,7 +6899,7 @@ alpha_align_insns (insns, max_align, next_group, next_nop)
|
|||
can make use of the knowledge of what sorts of instructions
|
||||
were issued in the previous group to make sure that all of
|
||||
the added nops are really free. */
|
||||
else if (ofs + len > align)
|
||||
else if (ofs + len > (int) align)
|
||||
{
|
||||
int nop_count = (align - ofs) / 4;
|
||||
rtx where;
|
||||
|
|
|
@ -158,6 +158,10 @@ extern enum alpha_fp_trap_mode alpha_fptm;
|
|||
#define MASK_CIX (1 << 11)
|
||||
#define TARGET_CIX (target_flags & MASK_CIX)
|
||||
|
||||
/* This means use !literal style explicit relocations. */
|
||||
#define MASK_EXPLICIT_RELOCS (1 << 12)
|
||||
#define TARGET_EXPLICIT_RELOCS (target_flags & MASK_EXPLICIT_RELOCS)
|
||||
|
||||
/* 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)
|
||||
|
@ -227,6 +231,9 @@ extern enum alpha_fp_trap_mode alpha_fptm;
|
|||
{"no-fix", -MASK_FIX, ""}, \
|
||||
{"cix", MASK_CIX, N_("Emit code for the counting ISA extension")}, \
|
||||
{"no-cix", -MASK_CIX, ""}, \
|
||||
{"explicit-relocs", MASK_EXPLICIT_RELOCS, \
|
||||
N_("Emit code using explicit relocation directives")}, \
|
||||
{"no-explicit-relocs", -MASK_EXPLICIT_RELOCS, ""}, \
|
||||
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} }
|
||||
|
||||
#define TARGET_DEFAULT MASK_FP|MASK_FPREGS
|
||||
|
@ -792,6 +799,7 @@ enum reg_class { NO_REGS, PV_REG, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
|
|||
: (C) == 'R' ? current_file_function_operand (OP, Pmode) \
|
||||
: (C) == 'S' ? (GET_CODE (OP) == CONST_INT \
|
||||
&& (unsigned HOST_WIDE_INT) INTVAL (OP) < 64) \
|
||||
: (C) == 'T' ? GET_CODE (OP) == HIGH \
|
||||
: 0)
|
||||
|
||||
/* Given an rtx X being reloaded into a reg required to be
|
||||
|
@ -803,8 +811,9 @@ enum reg_class { NO_REGS, PV_REG, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
|
|||
register via memory. */
|
||||
|
||||
#define PREFERRED_RELOAD_CLASS(X, CLASS) \
|
||||
(CONSTANT_P (X) && (X) != const0_rtx && (X) != CONST0_RTX (GET_MODE (X)) \
|
||||
? ((CLASS) == FLOAT_REGS || (CLASS) == NO_REGS ? NO_REGS : GENERAL_REGS)\
|
||||
(GET_CODE (X) == HIGH ? GENERAL_REGS \
|
||||
: CONSTANT_P (X) && (X) != const0_rtx && (X) != CONST0_RTX (GET_MODE (X)) \
|
||||
? ((CLASS) == FLOAT_REGS || (CLASS) == NO_REGS ? NO_REGS : GENERAL_REGS) \
|
||||
: (CLASS))
|
||||
|
||||
/* Loading and storing HImode or QImode values to and from memory
|
||||
|
@ -1737,13 +1746,11 @@ do { \
|
|||
|
||||
/* Output to assembler file text saying following lines
|
||||
may contain character constants, extra white space, comments, etc. */
|
||||
|
||||
#define ASM_APP_ON ""
|
||||
#define ASM_APP_ON (TARGET_EXPLICIT_RELOCS ? "\t.set\tmacro\n" : "")
|
||||
|
||||
/* Output to assembler file text saying following lines
|
||||
no longer contain unusual constructs. */
|
||||
|
||||
#define ASM_APP_OFF ""
|
||||
#define ASM_APP_OFF (TARGET_EXPLICIT_RELOCS ? "\t.set\tnomacro\n" : "")
|
||||
|
||||
#define TEXT_SECTION_ASM_OP "\t.text"
|
||||
|
||||
|
@ -1785,13 +1792,29 @@ literal_section () \
|
|||
|
||||
#define READONLY_DATA_SECTION literal_section
|
||||
|
||||
/* If we are referencing a function that is static, make the SYMBOL_REF
|
||||
special. We use this to see indicate we can branch to this function
|
||||
without setting PV or restoring GP. */
|
||||
/* Define this macro if references to a symbol must be treated differently
|
||||
depending on something about the variable or function named by the symbol
|
||||
(such as what section it is in). */
|
||||
|
||||
#define ENCODE_SECTION_INFO(DECL) \
|
||||
if (TREE_CODE (DECL) == FUNCTION_DECL && ! TREE_PUBLIC (DECL)) \
|
||||
SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
|
||||
#define ENCODE_SECTION_INFO(DECL) alpha_encode_section_info (DECL)
|
||||
|
||||
/* If a variable is weakened, made one only or moved into a different
|
||||
section, it may be necessary to redo the section info to move the
|
||||
variable out of sdata. */
|
||||
|
||||
#define REDO_SECTION_INFO_P(DECL) \
|
||||
((TREE_CODE (DECL) == VAR_DECL) \
|
||||
&& (DECL_ONE_ONLY (DECL) || DECL_WEAK (DECL) || DECL_COMMON (DECL) \
|
||||
|| DECL_SECTION_NAME (DECL) != 0))
|
||||
|
||||
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
|
||||
do { \
|
||||
(VAR) = (SYMBOL_NAME); \
|
||||
if ((VAR)[0] == '@') \
|
||||
(VAR) += 2; \
|
||||
if ((VAR)[0] == '*') \
|
||||
(VAR)++; \
|
||||
} while (0)
|
||||
|
||||
/* How to refer to registers in assembler output.
|
||||
This sequence is indexed by compiler's hard-register-number (see above). */
|
||||
|
@ -1810,6 +1833,20 @@ literal_section () \
|
|||
|
||||
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
|
||||
|
||||
/* Strip name encoding when emitting labels. */
|
||||
|
||||
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
|
||||
do { \
|
||||
const char *name_ = NAME; \
|
||||
if (*name_ == '@') \
|
||||
name_ += 2; \
|
||||
if (*name_ == '*') \
|
||||
name_++; \
|
||||
else \
|
||||
fputs (user_label_prefix, STREAM); \
|
||||
fputs (name_, STREAM); \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output the definition of a user-level label named NAME,
|
||||
such as the label on a static function or variable NAME. */
|
||||
|
||||
|
@ -2089,7 +2126,8 @@ do { \
|
|||
*/
|
||||
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
|
||||
((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~')
|
||||
((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
|
||||
|| (CODE) == '#' || (CODE) == '*')
|
||||
|
||||
/* Print a memory address as an operand to reference that memory location. */
|
||||
|
||||
|
@ -2121,11 +2159,12 @@ do { \
|
|||
{"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \
|
||||
{"fp0_operand", {CONST_DOUBLE}}, \
|
||||
{"current_file_function_operand", {SYMBOL_REF}}, \
|
||||
{"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}}, \
|
||||
SYMBOL_REF, CONST, LABEL_REF, HIGH, LO_SUM}}, \
|
||||
{"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
|
||||
SYMBOL_REF, CONST, LABEL_REF}}, \
|
||||
SYMBOL_REF, CONST, LABEL_REF, HIGH, LO_SUM}}, \
|
||||
{"some_ni_operand", {SUBREG, REG, MEM}}, \
|
||||
{"aligned_memory_operand", {MEM}}, \
|
||||
{"unaligned_memory_operand", {MEM}}, \
|
||||
|
|
|
@ -1103,6 +1103,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|
||||
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
|
||||
;; expanded by the assembler.
|
||||
|
||||
(define_insn "*divmodsi_internal_er"
|
||||
[(set (reg:DI 27)
|
||||
(sign_extend:DI (match_operator:SI 0 "divmod_operator"
|
||||
[(reg:DI 24) (reg:DI 25)])))
|
||||
(clobber (reg:DI 23))
|
||||
(clobber (reg:DI 28))]
|
||||
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
||||
"ldq $27,__%E0($29)\t\t!literal!%#\;jsr $23,($27),__%E0\t\t!lituse_jsr!%#"
|
||||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*divmodsi_internal"
|
||||
[(set (reg:DI 27)
|
||||
(sign_extend:DI (match_operator:SI 0 "divmod_operator"
|
||||
|
@ -1114,6 +1126,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*divmoddi_internal_er"
|
||||
[(set (reg:DI 27)
|
||||
(match_operator:DI 0 "divmod_operator"
|
||||
[(reg:DI 24) (reg:DI 25)]))
|
||||
(clobber (reg:DI 23))
|
||||
(clobber (reg:DI 28))]
|
||||
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
||||
"ldq $27,__%E0($29)\t\t!literal!%#\;jsr $23,($27),__%E0\t\t!lituse_jsr!%#"
|
||||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*divmoddi_internal"
|
||||
[(set (reg:DI 27)
|
||||
(match_operator:DI 0 "divmod_operator"
|
||||
|
@ -4346,6 +4369,33 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
}
|
||||
})
|
||||
|
||||
(define_insn "*call_osf_1_er_noreturn"
|
||||
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
|
||||
(match_operand 1 "" ""))
|
||||
(clobber (reg:DI 27))
|
||||
(clobber (reg:DI 26))]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
||||
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
||||
"@
|
||||
jsr $26,($27),0
|
||||
bsr $26,$%0..ng
|
||||
ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
|
||||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "*,*,8")])
|
||||
|
||||
(define_insn "*call_osf_1_er"
|
||||
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
|
||||
(match_operand 1 "" ""))
|
||||
(clobber (reg:DI 27))
|
||||
(clobber (reg:DI 26))]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
||||
"@
|
||||
jsr $26,($27),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
|
||||
bsr $26,$%0..ng
|
||||
ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
|
||||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "12,*,16")])
|
||||
|
||||
(define_insn "*call_osf_1_noreturn"
|
||||
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
|
||||
(match_operand 1 "" ""))
|
||||
|
@ -4373,14 +4423,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
(set_attr "length" "12,*,16")])
|
||||
|
||||
(define_insn "*sibcall_osf_1"
|
||||
[(call (mem:DI (match_operand:DI 0 "call_operand" "R,i"))
|
||||
[(call (mem:DI (match_operand:DI 0 "current_file_function_operand" "R"))
|
||||
(match_operand 1 "" ""))]
|
||||
"TARGET_ABI_OSF"
|
||||
"@
|
||||
br $31,$%0..ng
|
||||
jmp $31,%0"
|
||||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "*,8")])
|
||||
"br $31,$%0..ng"
|
||||
[(set_attr "type" "jsr")])
|
||||
|
||||
(define_insn "*call_nt_1"
|
||||
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
|
||||
|
@ -4707,8 +4754,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%1
|
||||
ldah %0,%h1
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
ldl %0,%1
|
||||
stl %r1,%0
|
||||
fmov %R1,%0
|
||||
|
@ -4724,8 +4771,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%1
|
||||
ldah %0,%h1
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
ldl %0,%1
|
||||
stl %r1,%0
|
||||
fmov %R1,%0
|
||||
|
@ -4761,7 +4808,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|| register_operand (operands[1], HImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%L1"
|
||||
lda %0,%L1($31)"
|
||||
[(set_attr "type" "ilog,iadd")])
|
||||
|
||||
(define_insn "*movhi_bwx"
|
||||
|
@ -4772,7 +4819,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|| reg_or_0_operand (operands[1], HImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%L1
|
||||
lda %0,%L1($31)
|
||||
ldwu %0,%1
|
||||
stw %r1,%0"
|
||||
[(set_attr "type" "ilog,iadd,ild,ist")])
|
||||
|
@ -4785,7 +4832,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|| register_operand (operands[1], QImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%L1"
|
||||
lda %0,%L1($31)"
|
||||
[(set_attr "type" "ilog,iadd")])
|
||||
|
||||
(define_insn "*movqi_bwx"
|
||||
|
@ -4796,7 +4843,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|| reg_or_0_operand (operands[1], QImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%L1
|
||||
lda %0,%L1($31)
|
||||
ldbu %0,%1
|
||||
stb %r1,%0"
|
||||
[(set_attr "type" "ilog,iadd,ild,ist")])
|
||||
|
@ -4832,16 +4879,43 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
FAIL;
|
||||
})
|
||||
|
||||
(define_insn "*movdi_er_low"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(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")
|
||||
|
||||
(define_insn "*movdi_er_nofix"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
|
||||
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
|
||||
"TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
|
||||
&& (register_operand (operands[0], DImode)
|
||||
|| reg_or_0_operand (operands[1], DImode))
|
||||
&& ! local_symbolic_operand (operands[1], DImode)"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
ldah %0,%H1
|
||||
ldq %0,%1($29)\t\t!literal
|
||||
ldq%A1 %0,%1
|
||||
stq%A0 %r1,%0
|
||||
fmov %R1,%0
|
||||
ldt %0,%1
|
||||
stt %R1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
|
||||
|
||||
(define_insn "*movdi_nofix"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
|
||||
(match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
|
||||
"! TARGET_FIX
|
||||
"! TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
|
||||
&& (register_operand (operands[0], DImode)
|
||||
|| reg_or_0_operand (operands[1], DImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%1
|
||||
ldah %0,%h1
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
lda %0,%1
|
||||
ldq%A1 %0,%1
|
||||
stq%A0 %r1,%0
|
||||
|
@ -4850,16 +4924,38 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
stt %R1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
|
||||
|
||||
(define_insn "*movdi_er_fix"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q,r,*f")
|
||||
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f,*f,r"))]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_FIX
|
||||
&& (register_operand (operands[0], DImode)
|
||||
|| reg_or_0_operand (operands[1], DImode))
|
||||
&& ! local_symbolic_operand (operands[1], DImode)"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
ldah %0,%H1
|
||||
ldq %0,%1($29)\t\t!literal
|
||||
ldq%A1 %0,%1
|
||||
stq%A0 %r1,%0
|
||||
fmov %R1,%0
|
||||
ldt %0,%1
|
||||
stt %R1,%0
|
||||
ftoit %1,%0
|
||||
itoft %1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
|
||||
|
||||
(define_insn "*movdi_fix"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
|
||||
(match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
|
||||
"TARGET_FIX
|
||||
"! TARGET_EXPLICIT_RELOCS && TARGET_FIX
|
||||
&& (register_operand (operands[0], DImode)
|
||||
|| reg_or_0_operand (operands[1], DImode))"
|
||||
"@
|
||||
mov %r1,%0
|
||||
lda %0,%1
|
||||
ldah %0,%h1
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
lda %0,%1
|
||||
ldq%A1 %0,%1
|
||||
stq%A0 %r1,%0
|
||||
|
@ -5548,6 +5644,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
""
|
||||
"")
|
||||
|
||||
(define_insn "*prologue_ldgp_1_er"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_LDGP1)]
|
||||
"TARGET_EXPLICIT_RELOCS"
|
||||
"ldah $29,0($27)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*\n$%~..ng:")
|
||||
|
||||
(define_insn "*prologue_ldgp_1"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_LDGP1)]
|
||||
""
|
||||
|
@ -5637,6 +5738,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
"jmp $31,(%0),0"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_sub_label_er"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
|
||||
"\n$LSJ%=:\;ldah $29,0($27)\t\t!gpdisp!%*\;lda $29,$LSJ%=-%l0($29)\t\t!gpdisp!%*"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_sub_label"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
|
||||
|
@ -5644,6 +5752,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_er"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
||||
"br $29,$LSJ%=\n$LSJ%=:\;ldah $29,0($29)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
|
||||
[(set_attr "length" "12")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "builtin_setjmp_receiver"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF"
|
||||
|
@ -5661,6 +5776,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
operands[0] = const0_rtx;
|
||||
})
|
||||
|
||||
(define_insn "*exception_receiver_1_er"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
||||
"TARGET_EXPLICIT_RELOCS && ! TARGET_LD_BUGGY_LDGP"
|
||||
"ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*exception_receiver_1"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
||||
"! TARGET_LD_BUGGY_LDGP"
|
||||
|
@ -5752,6 +5874,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
;; The call patterns are at the end of the file because their
|
||||
;; wildcard operand0 interferes with nice recognition.
|
||||
|
||||
(define_insn "*call_value_osf_1_er"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,i"))
|
||||
(match_operand 2 "" "")))
|
||||
(clobber (reg:DI 27))
|
||||
(clobber (reg:DI 26))]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
||||
"@
|
||||
jsr $26,($27),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
|
||||
bsr $26,$%1..ng
|
||||
ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
|
||||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "12,*,16")])
|
||||
|
||||
(define_insn "*call_value_osf_1"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,i"))
|
||||
|
@ -5768,14 +5904,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
|||
|
||||
(define_insn "*sibcall_value_osf_1"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (mem:DI (match_operand:DI 1 "call_operand" "R,i"))
|
||||
(call (mem:DI (match_operand:DI 1 "current_file_function_operand" "R"))
|
||||
(match_operand 2 "" "")))]
|
||||
"TARGET_ABI_OSF"
|
||||
"@
|
||||
br $31,$%1..ng
|
||||
jmp $31,%1"
|
||||
[(set_attr "type" "jsr")
|
||||
(set_attr "length" "*,8")])
|
||||
"br $31,$%1..ng"
|
||||
[(set_attr "type" "jsr")])
|
||||
|
||||
(define_insn "*call_value_nt_1"
|
||||
[(set (match_operand 0 "" "")
|
||||
|
|
|
@ -58,6 +58,8 @@ do { \
|
|||
} \
|
||||
fprintf (FILE, "\t.set noat\n"); \
|
||||
fprintf (FILE, "\t.set noreorder\n"); \
|
||||
if (TARGET_EXPLICIT_RELOCS) \
|
||||
fprintf (FILE, "\t.set nomacro\n"); \
|
||||
if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
|
||||
{ \
|
||||
fprintf (FILE, "\t.arch %s\n", \
|
||||
|
@ -591,3 +593,11 @@ void FN () \
|
|||
only EH sections. */
|
||||
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
|
||||
(((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4)
|
||||
|
||||
/* If defined, a C statement to be executed just prior to the output of
|
||||
assembler code for INSN. */
|
||||
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
|
||||
(alpha_this_literal_sequence_number = 0, \
|
||||
alpha_this_gpdisp_sequence_number = 0)
|
||||
extern int alpha_this_literal_sequence_number;
|
||||
extern int alpha_this_gpdisp_sequence_number;
|
||||
|
|
Loading…
Add table
Reference in a new issue