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:
Richard Henderson 2001-09-09 01:42:40 -07:00 committed by Richard Henderson
parent 7b95ee3dda
commit 1eb356b98d
6 changed files with 581 additions and 77 deletions

View file

@ -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.

View file

@ -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 */

View file

@ -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;

View file

@ -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}}, \

View file

@ -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 "" "")

View file

@ -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;