static int s390_split_branches PARAMS ((rtx, bool *));
static void find_constant_pool_ref PARAMS ((rtx, rtx *));
static void replace_constant_pool_ref PARAMS ((rtx *, rtx, rtx));
-static int find_base_register_in_addr PARAMS ((struct s390_address *));
-static bool find_base_register_ref PARAMS ((rtx));
-static void replace_base_register_ref PARAMS ((rtx *, rtx));
+static rtx find_ltrel_base PARAMS ((rtx));
+static void replace_ltrel_base PARAMS ((rtx *, rtx));
static void s390_optimize_prolog PARAMS ((int));
static bool s390_fixup_clobbered_return_reg PARAMS ((rtx));
static int find_unused_clobbered_reg PARAMS ((void));
/* Now we must have a @GOTENT offset or @PLT stub
or an @INDNTPOFF TLS offset. */
if (GET_CODE (op) == UNSPEC
- && XINT (op, 1) == 111)
+ && XINT (op, 1) == UNSPEC_GOTENT)
return 1;
if (GET_CODE (op) == UNSPEC
- && XINT (op, 1) == 113)
+ && XINT (op, 1) == UNSPEC_PLT)
return 1;
if (GET_CODE (op) == UNSPEC
&& XINT (op, 1) == UNSPEC_INDNTPOFF)
/* GOT offset is not OK, the GOT can be large. */
if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
- && XINT (XEXP (disp, 0), 1) == 110)
+ && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
return 0;
/* All other symbolic constants are literal pool references,
/* Allow @PLT stubs. */
if (code == CONST
&& GET_CODE (XEXP (op, 0)) == UNSPEC
- && XINT (XEXP (op, 0), 1) == 113)
+ && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
return 1;
return 0;
}
switch (XINT (x, 1))
{
/* Only lt-relative or GOT-relative UNSPECs are OK. */
- case 100:
- case 104:
- case 112:
- case 114:
+ case UNSPEC_LTREL_OFFSET:
+ case UNSPEC_GOT:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLTOFF:
case UNSPEC_TLSGD:
case UNSPEC_TLSLDM:
case UNSPEC_NTPOFF:
rtx indx = NULL_RTX;
rtx disp = NULL_RTX;
int pointer = FALSE;
+ int base_ptr = FALSE;
+ int indx_ptr = FALSE;
/* Decompose address into base + index + displacement. */
disp = addr; /* displacement */
- /* Prefer to use pointer as base, not index. */
- if (base && indx)
- {
- int base_ptr = GET_CODE (base) == UNSPEC
- || (REG_P (base) && REG_POINTER (base));
- int indx_ptr = GET_CODE (indx) == UNSPEC
- || (REG_P (indx) && REG_POINTER (indx));
-
- if (!base_ptr && indx_ptr)
- {
- rtx tmp = base;
- base = indx;
- indx = tmp;
- }
- }
-
/* Validate base register. */
if (base)
{
if (GET_CODE (base) == UNSPEC)
{
- if (XVECLEN (base, 0) != 1 || XINT (base, 1) != 101)
- return FALSE;
- base = XVECEXP (base, 0, 0);
- pointer = TRUE;
+ if (XVECLEN (base, 0) != 1 || XINT (base, 1) != UNSPEC_LTREL_BASE)
+ return FALSE;
+ base = gen_rtx_REG (Pmode, BASE_REGISTER);
}
if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
- return FALSE;
+ return FALSE;
if (REGNO (base) == BASE_REGISTER
|| REGNO (base) == STACK_POINTER_REGNUM
&& REGNO (base) <= LAST_VIRTUAL_REGISTER)
|| (flag_pic
&& REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
- pointer = TRUE;
+ pointer = base_ptr = TRUE;
}
/* Validate index register. */
{
if (GET_CODE (indx) == UNSPEC)
{
- if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != 101)
- return FALSE;
- indx = XVECEXP (indx, 0, 0);
- pointer = TRUE;
+ if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != UNSPEC_LTREL_BASE)
+ return FALSE;
+ indx = gen_rtx_REG (Pmode, BASE_REGISTER);
}
if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
- return FALSE;
+ return FALSE;
if (REGNO (indx) == BASE_REGISTER
|| REGNO (indx) == STACK_POINTER_REGNUM
&& REGNO (indx) <= LAST_VIRTUAL_REGISTER)
|| (flag_pic
&& REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
- pointer = TRUE;
+ pointer = indx_ptr = TRUE;
+ }
+
+ /* Prefer to use pointer as base, not index. */
+ if (base && indx && !base_ptr
+ && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
+ {
+ rtx tmp = base;
+ base = indx;
+ indx = tmp;
}
/* Validate displacement. */
}
}
- /* In the small-PIC case, the linker converts @GOT12
+ /* In the small-PIC case, the linker converts @GOT
and @GOTNTPOFF offsets to possible displacements. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
- && (XINT (XEXP (disp, 0), 1) == 110
+ && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
|| XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
{
if (flag_pic != 1)
else
base = gen_rtx_REG (Pmode, BASE_REGISTER);
- disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp), 100);
+ disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
+ UNSPEC_LTREL_OFFSET);
disp = gen_rtx_CONST (Pmode, disp);
if (offset)
}
else
{
- /* Access local symbols relative to the literal pool. */
+ /* Access local symbols relative to the GOT. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 100);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
-
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
if (flag_pic == 1)
{
/* Assume GOT offset < 4k. This is handled the same way
- in both 31- and 64-bit code (@GOT12). */
+ in both 31- and 64-bit code (@GOT). */
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 110);
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
new = gen_rtx_CONST (Pmode, new);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
new = gen_rtx_MEM (Pmode, new);
rtx temp = gen_reg_rtx (Pmode);
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 111);
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
new = gen_rtx_CONST (Pmode, new);
emit_move_insn (temp, new);
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 112);
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
abort ();
switch (XINT (addr, 1))
{
- /* If someone moved an @GOT or lt-relative UNSPEC
+ /* If someone moved a GOT-relative UNSPEC
out of the literal pool, force them back in. */
- case 100:
- case 112:
- case 114:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLTOFF:
new = force_const_mem (Pmode, orig);
break;
+ /* @GOT is OK as is if small. */
+ case UNSPEC_GOT:
+ if (flag_pic == 2)
+ new = force_const_mem (Pmode, orig);
+ break;
+
/* @GOTENT is OK as is. */
- case 111:
+ case UNSPEC_GOTENT:
break;
/* @PLT is OK as is on 64-bit, must be converted to
- lt-relative PLT on 31-bit. */
- case 113:
+ GOT-relative @PLTOFF on 31-bit. */
+ case UNSPEC_PLT:
if (!TARGET_64BIT)
{
rtx temp = reg? reg : gen_reg_rtx (Pmode);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
addr = XVECEXP (addr, 0, 0);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 114);
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
+ UNSPEC_PLTOFF);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
-
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
}
else
{
- /* Access local symbols relative to the literal pool. */
+ /* Access local symbols relative to the GOT. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 100);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
+ UNSPEC_GOTOFF);
addr = gen_rtx_PLUS (Pmode, addr, op1);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
-
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
}
}
- /* Now, check whether it is an LT-relative symbol plus offset
+ /* Now, check whether it is a GOT relative symbol plus offset
that was pulled out of the literal pool. Force it back in. */
else if (GET_CODE (op0) == UNSPEC
{
if (XVECLEN (op0, 0) != 1)
abort ();
- if (XINT (op0, 1) != 100)
+ if (XINT (op0, 1) != UNSPEC_GOTOFF)
abort ();
new = force_const_mem (Pmode, orig);
{
y = XEXP (XEXP (x, 1), 0);
if (GET_CODE (y) == UNSPEC
- && XINT (y, 1) == 110)
+ && XINT (y, 1) == UNSPEC_GOT)
return XVECEXP (y, 0, 0);
return orig_x;
}
{
y = XEXP (x, 0);
if (GET_CODE (y) == UNSPEC
- && XINT (y, 1) == 111)
+ && XINT (y, 1) == UNSPEC_GOTENT)
return XVECEXP (y, 0, 0);
return orig_x;
}
output_operand_lossage ("invalid UNSPEC as operand (1)");
switch (XINT (x, 1))
{
- case 100:
- case 104:
+ case UNSPEC_LTREL_OFFSET:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "-");
s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
break;
- case 105:
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
- fprintf (file, "-");
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- break;
- case 110:
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "@GOT12");
- break;
- case 111:
+ case UNSPEC_GOTENT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@GOTENT");
break;
- case 112:
+ case UNSPEC_GOT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@GOT");
break;
- case 113:
+ case UNSPEC_GOTOFF:
+ s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
+ fprintf (file, "@GOTOFF");
+ break;
+ case UNSPEC_PLT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@PLT");
break;
- case 114:
+ case UNSPEC_PLTOFF:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "@PLT-");
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
+ fprintf (file, "@PLTOFF");
break;
case UNSPEC_TLSGD:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
else
{
new_literal = 1;
- tmp = gen_rtx_UNSPEC (SImode, gen_rtvec (1, *label), 104);
- tmp = gen_rtx_CONST (SImode, tmp);
- tmp = force_const_mem (SImode, tmp);
- tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
+ target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
+ UNSPEC_LTREL_OFFSET);
+ target = gen_rtx_CONST (Pmode, target);
+ target = force_const_mem (Pmode, target);
+ tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
INSN_ADDRESSES_NEW (tmp, -1);
- target = gen_rtx_REG (Pmode, BASE_REGISTER);
- target = gen_rtx_PLUS (Pmode, target, temp_reg);
+ target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (target, 0)),
+ UNSPEC_LTREL_BASE);
+ target = gen_rtx_PLUS (Pmode, temp_reg, target);
}
if (!validate_change (insn, label, target, 0))
int i, j;
const char *fmt;
+ /* Ignore LTREL_BASE references. */
+ if (GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_LTREL_BASE)
+ return;
+
if (GET_CODE (x) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x))
{
}
}
-/* Check whether ADDR is an address that uses the base register,
- without actually constituting a literal pool access. (This happens
- in 31-bit PIC mode, where the base register is used as anchor for
- relative addressing of local symbols.)
-
- Returns 1 if the base register occupies the base slot,
- returns 2 if the base register occupies the index slot,
- returns 0 if the address is not of this form. */
-
-static int
-find_base_register_in_addr (addr)
- struct s390_address *addr;
-{
- /* If DISP is complex, we might have a literal pool reference. */
- if (addr->disp && GET_CODE (addr->disp) != CONST_INT)
- return 0;
-
- if (addr->base && REG_P (addr->base) && REGNO (addr->base) == BASE_REGISTER)
- return 1;
-
- if (addr->indx && REG_P (addr->indx) && REGNO (addr->indx) == BASE_REGISTER)
- return 2;
-
- return 0;
-}
-
-/* Return true if X contains an address that uses the base register,
- without actually constituting a literal pool access. */
+/* Check whether X contains an UNSPEC_LTREL_BASE.
+ Return its constant pool symbol if found, NULL_RTX otherwise. */
-static bool
-find_base_register_ref (x)
+static rtx
+find_ltrel_base (x)
rtx x;
{
- bool retv = FALSE;
- struct s390_address addr;
int i, j;
const char *fmt;
- /* Addresses can only occur inside a MEM ... */
- if (GET_CODE (x) == MEM)
- {
- if (s390_decompose_address (XEXP (x, 0), &addr)
- && find_base_register_in_addr (&addr))
- return TRUE;
- }
-
- /* ... or a load-address type pattern. */
- if (GET_CODE (x) == SET && GET_CODE (SET_DEST (x)) == REG)
- {
- if (s390_decompose_address (SET_SRC (x), &addr)
- && find_base_register_in_addr (&addr))
- return TRUE;
- }
+ if (GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_LTREL_BASE)
+ return XVECEXP (x, 0, 0);
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
- retv |= find_base_register_ref (XEXP (x, i));
+ rtx fnd = find_ltrel_base (XEXP (x, i));
+ if (fnd)
+ return fnd;
}
else if (fmt[i] == 'E')
{
for (j = 0; j < XVECLEN (x, i); j++)
- retv |= find_base_register_ref (XVECEXP (x, i, j));
+ {
+ rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
+ if (fnd)
+ return fnd;
+ }
}
}
- return retv;
+ return NULL_RTX;
}
-/* If X contains an address that uses the base register,
- without actually constituting a literal pool access,
- replace the base register with REPL in all such cases.
-
- Handles both MEMs and load address patterns. */
+/* Replace any occurrence of UNSPEC_LTREL_BASE in X with BASE. */
static void
-replace_base_register_ref (x, repl)
+replace_ltrel_base (x, base)
rtx *x;
- rtx repl;
+ rtx base;
{
- struct s390_address addr;
- rtx new_addr;
- int i, j, pos;
+ int i, j;
const char *fmt;
- /* Addresses can only occur inside a MEM ... */
- if (GET_CODE (*x) == MEM)
+ if (GET_CODE (*x) == UNSPEC
+ && XINT (*x, 1) == UNSPEC_LTREL_BASE)
{
- if (s390_decompose_address (XEXP (*x, 0), &addr)
- && (pos = find_base_register_in_addr (&addr)))
- {
- if (pos == 1)
- addr.base = repl;
- else
- addr.indx = repl;
-
- new_addr = addr.base;
- if (addr.indx)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
- if (addr.disp)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
-
- *x = replace_equiv_address (*x, new_addr);
- return;
- }
- }
-
- /* ... or a load-address type pattern. */
- if (GET_CODE (*x) == SET && GET_CODE (SET_DEST (*x)) == REG)
- {
- if (s390_decompose_address (SET_SRC (*x), &addr)
- && (pos = find_base_register_in_addr (&addr)))
- {
- if (pos == 1)
- addr.base = repl;
- else
- addr.indx = repl;
-
- new_addr = addr.base;
- if (addr.indx)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
- if (addr.disp)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
-
- SET_SRC (*x) = new_addr;
- return;
- }
+ *x = base;
+ return;
}
fmt = GET_RTX_FORMAT (GET_CODE (*x));
{
if (fmt[i] == 'e')
{
- replace_base_register_ref (&XEXP (*x, i), repl);
+ replace_ltrel_base (&XEXP (*x, i), base);
}
else if (fmt[i] == 'E')
{
for (j = 0; j < XVECLEN (*x, i); j++)
- replace_base_register_ref (&XVECEXP (*x, i, j), repl);
+ replace_ltrel_base (&XVECEXP (*x, i, j), base);
}
}
}
-/* We keep a list of constants we which we have to add to internal
+/* We keep a list of constants which we have to add to internal
constant tables in the middle of large functions. */
-#define NR_C_MODES 6
+#define NR_C_MODES 7
enum machine_mode constant_modes[NR_C_MODES] =
{
+ TImode,
DFmode, DImode,
SFmode, SImode,
HImode,
rtx (*gen_consttable[NR_C_MODES])(rtx) =
{
+ gen_consttable_ti,
gen_consttable_df, gen_consttable_di,
gen_consttable_sf, gen_consttable_si,
gen_consttable_hi,
struct constant *constants[NR_C_MODES];
rtx label;
int size;
- bool anchor;
};
-static struct constant_pool * s390_chunkify_start PARAMS ((rtx, bool *));
-static void s390_chunkify_finish PARAMS ((struct constant_pool *, rtx));
+static struct constant_pool * s390_chunkify_start PARAMS ((void));
+static void s390_chunkify_finish PARAMS ((struct constant_pool *));
static void s390_chunkify_cancel PARAMS ((struct constant_pool *));
static struct constant_pool *s390_start_pool PARAMS ((struct constant_pool **, rtx));
static struct constant_pool *s390_find_pool PARAMS ((struct constant_pool *, rtx));
static void s390_add_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
static rtx s390_find_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
-static void s390_add_anchor PARAMS ((struct constant_pool *));
static rtx s390_dump_pool PARAMS ((struct constant_pool *));
static void s390_free_pool PARAMS ((struct constant_pool *));
pool->pool_insn = NULL_RTX;
pool->insns = BITMAP_XMALLOC ();
pool->size = 0;
- pool->anchor = FALSE;
for (prev = pool_list; *prev; prev = &(*prev)->next)
;
return offset;
}
-/* Set 'anchor' flag in POOL. */
-
-static void
-s390_add_anchor (pool)
- struct constant_pool *pool;
-{
- if (!pool->anchor)
- {
- pool->anchor = TRUE;
- pool->size += 4;
- }
-}
-
/* Dump out the constants in POOL. */
static rtx
insn = emit_label_after (pool->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
- /* Emit anchor if we need one. */
- if (pool->anchor)
- {
- rtx anchor = gen_rtx_LABEL_REF (VOIDmode, pool->label);
- anchor = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, anchor), 105);
- anchor = gen_rtx_CONST (VOIDmode, anchor);
- insn = emit_insn_after (gen_consttable_si (anchor), insn);
- INSN_ADDRESSES_NEW (insn, -1);
- }
-
/* Dump constants in descending alignment requirement order,
ensuring proper alignment for every constant. */
for (i = 0; i < NR_C_MODES; i++)
for (c = pool->constants[i]; c; c = c->next)
{
- /* Convert 104 unspecs to pool-relative references. */
+ /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
rtx value = c->value;
if (GET_CODE (value) == CONST
&& GET_CODE (XEXP (value, 0)) == UNSPEC
- && XINT (XEXP (value, 0), 1) == 104
+ && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
&& XVECLEN (XEXP (value, 0), 0) == 1)
{
value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
}
-/* Chunkify the literal pool if required.
-
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. If this is
- done, TEMP_USED is set to true. */
+/* Chunkify the literal pool if required. */
#define S390_POOL_CHUNK_MIN 0xc00
#define S390_POOL_CHUNK_MAX 0xe00
static struct constant_pool *
-s390_chunkify_start (temp_reg, temp_used)
- rtx temp_reg;
- bool *temp_used;
+s390_chunkify_start (void)
{
rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
struct constant_pool *curr_pool = NULL, *pool_list = NULL;
int extra_size = 0;
bitmap far_labels;
+ rtx pending_ltrel = NULL_RTX;
rtx insn;
rtx (*gen_reload_base) PARAMS ((rtx, rtx)) =
shorten_branches (get_insns ());
- /* Scan all insns and move literals to pool chunks.
- Also, emit anchor reload insns before every insn that uses
- the literal pool base register as anchor pointer. */
+ /* Scan all insns and move literals to pool chunks. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
+ /* Check for pending LTREL_BASE. */
+ if (INSN_P (insn))
+ {
+ rtx ltrel_base = find_ltrel_base (PATTERN (insn));
+ if (ltrel_base)
+ {
+ if (ltrel_base == pending_ltrel)
+ pending_ltrel = NULL_RTX;
+ else
+ abort ();
+ }
+ }
+
if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
{
rtx pool_ref = NULL_RTX;
find_constant_pool_ref (PATTERN (insn), &pool_ref);
if (pool_ref)
{
+ rtx constant = get_pool_constant (pool_ref);
+ enum machine_mode mode = get_pool_mode (pool_ref);
+
if (!curr_pool)
curr_pool = s390_start_pool (&pool_list, insn);
- s390_add_constant (curr_pool, get_pool_constant (pool_ref),
- get_pool_mode (pool_ref));
+ s390_add_constant (curr_pool, constant, mode);
s390_add_pool_insn (curr_pool, insn);
- }
- else if (!TARGET_64BIT && flag_pic
- && find_base_register_ref (PATTERN (insn)))
- {
- rtx new = gen_reload_anchor (temp_reg, base_reg);
- new = emit_insn_before (new, insn);
- INSN_ADDRESSES_NEW (new, INSN_ADDRESSES (INSN_UID (insn)));
- extra_size += 8;
- *temp_used = 1;
-
- if (!curr_pool)
- curr_pool = s390_start_pool (&pool_list, new);
-
- s390_add_anchor (curr_pool);
- s390_add_pool_insn (curr_pool, insn);
+ /* Don't split the pool chunk between a LTREL_OFFSET load
+ and the corresponding LTREL_BASE. */
+ if (GET_CODE (constant) == CONST
+ && GET_CODE (XEXP (constant, 0)) == UNSPEC
+ && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
+ {
+ if (pending_ltrel)
+ abort ();
+ pending_ltrel = pool_ref;
+ }
}
}
if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
- if (curr_pool)
- s390_add_pool_insn (curr_pool, insn);
+ {
+ if (curr_pool)
+ s390_add_pool_insn (curr_pool, insn);
+ /* An LTREL_BASE must follow within the same basic block. */
+ if (pending_ltrel)
+ abort ();
+ }
if (!curr_pool
|| INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
if (get_attr_length (insn) == 0)
continue;
- /* Don't separate insns created by s390_split_branches. */
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET
- && rtx_equal_p (SET_DEST (PATTERN (insn)), temp_reg))
+ /* Don't separate LTREL_BASE from the corresponding
+ LTREL_OFFSET load. */
+ if (pending_ltrel)
continue;
label = gen_label_rtx ();
if (curr_pool)
s390_end_pool (curr_pool, NULL_RTX);
+ if (pending_ltrel)
+ abort ();
/* Find all labels that are branched into
/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
After we have decided to use this list, finish implementing
- all changes to the current function as required.
-
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. */
+ all changes to the current function as required. */
static void
-s390_chunkify_finish (pool_list, temp_reg)
+s390_chunkify_finish (pool_list)
struct constant_pool *pool_list;
- rtx temp_reg;
{
rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
struct constant_pool *curr_pool = NULL;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
+ if (INSN_P (insn))
+ replace_ltrel_base (&PATTERN (insn), base_reg);
+
curr_pool = s390_find_pool (pool_list, insn);
if (!curr_pool)
continue;
replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
INSN_CODE (insn) = -1;
}
-
- else if (!TARGET_64BIT && flag_pic
- && find_base_register_ref (PATTERN (insn)))
- {
- replace_base_register_ref (&PATTERN (insn), temp_reg);
- }
}
}
remove_insn (curr_pool->pool_insn);
}
- /* Remove all base/anchor register reload insns. */
+ /* Remove all base register reload insns. */
for (insn = get_insns (); insn; )
{
if (GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) == SET
&& GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
- && (XINT (SET_SRC (PATTERN (insn)), 1) == 210
- || XINT (SET_SRC (PATTERN (insn)), 1) == 211))
+ && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
remove_insn (insn);
insn = next_insn;
struct constant_pool *pool_list;
/* Try to chunkify the literal pool. */
- pool_list = s390_chunkify_start (temp_reg, &temp_used);
+ pool_list = s390_chunkify_start ();
/* Split out-of-range branches. If this has created new
literal pool entries, cancel current chunk list and
/* If we made it up to here, both conditions are satisfied.
Finish up pool chunkification if required. */
if (pool_list)
- s390_chunkify_finish (pool_list, temp_reg);
+ s390_chunkify_finish (pool_list);
break;
}
return insn;
}
+/* Emit code to load the GOT register. If MAYBE_DEAD is true,
+ annotate generated insns with REG_MAYBE_DEAD notes. */
+
+static GTY(()) rtx got_symbol;
+void
+s390_load_got (maybe_dead)
+ int maybe_dead;
+{
+ if (!got_symbol)
+ {
+ got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
+ }
+
+ if (TARGET_64BIT)
+ {
+ rtx insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+ }
+ else
+ {
+ rtx offset, insn;
+
+ offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
+ UNSPEC_LTREL_OFFSET);
+ offset = gen_rtx_CONST (Pmode, offset);
+ offset = force_const_mem (Pmode, offset);
+
+ insn = emit_move_insn (pic_offset_table_rtx, offset);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+
+ offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
+ UNSPEC_LTREL_BASE);
+ offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
+
+ insn = emit_move_insn (pic_offset_table_rtx, offset);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+ }
+}
+
/* Expand the prologue into a bunch of separate insns. */
void
/* Set up got pointer, if needed. */
if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
- {
- rtx got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
- SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
-
- if (TARGET_64BIT)
- {
- insn = emit_insn (gen_movdi (pic_offset_table_rtx,
- got_symbol));
-
- /* It can happen that the GOT pointer isn't really needed ... */
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
- }
- else
- {
- got_symbol = gen_rtx_UNSPEC (VOIDmode,
- gen_rtvec (1, got_symbol), 100);
- got_symbol = gen_rtx_CONST (VOIDmode, got_symbol);
- got_symbol = force_const_mem (Pmode, got_symbol);
- insn = emit_move_insn (pic_offset_table_rtx,
- got_symbol);
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
-
- got_symbol = gen_rtx_REG (Pmode, BASE_REGISTER);
- got_symbol = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol), 101);
- got_symbol = gen_rtx_PLUS (Pmode, got_symbol, pic_offset_table_rtx);
- insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
- }
- }
+ s390_load_got (true);
}
/* Expand the epilogue into a bunch of separate insns. */
op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
if (flag_pic)
{
- op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), 113);
+ op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
op[4] = gen_rtx_CONST (Pmode, op[4]);
}
{
nonlocal = 1;
op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
- TARGET_64BIT ? 113 : flag_pic == 2 ? 112 : 110);
+ TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
op[0] = gen_rtx_CONST (Pmode, op[0]);
}
;;
(define_constants
- [; TLS relocation specifiers
+ [; GOT/PLT and lt-relative accesses
+ (UNSPEC_LTREL_OFFSET 100)
+ (UNSPEC_LTREL_BASE 101)
+ (UNSPEC_GOTENT 110)
+ (UNSPEC_GOT 111)
+ (UNSPEC_GOTOFF 112)
+ (UNSPEC_PLT 113)
+ (UNSPEC_PLTOFF 114)
+
+ ; Literal pool
+ (UNSPEC_RELOAD_BASE 210)
+
+ ; TLS relocation specifiers
(UNSPEC_TLSGD 500)
(UNSPEC_TLSLDM 501)
(UNSPEC_NTPOFF 502)
;;
(define_constants
- [; TLS support
+ [; Literal pool
+ (UNSPECV_POOL 200)
+ (UNSPECV_POOL_START 201)
+ (UNSPECV_POOL_END 202)
+ (UNSPECV_POOL_QI 203)
+ (UNSPECV_POOL_HI 204)
+ (UNSPECV_POOL_SI 205)
+ (UNSPECV_POOL_DI 206)
+ (UNSPECV_POOL_TI 207)
+ (UNSPECV_POOL_SF 208)
+ (UNSPECV_POOL_DF 209)
+ (UNSPECV_MAIN_POOL 300)
+
+ ; TLS support
(UNSPECV_SET_TP 500)
])
""
"
{
- int plt_call = 0;
rtx insn;
/* Direct function calls need special treatment. */
replace the symbol itself with the PLT stub. */
if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
{
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
-
- plt_call = 1;
}
/* Unless we can use the bras(l) insn, force the
routine address into a register. */
if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
- {
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
- }
+ {
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
+ }
operands[0] = gen_rtx_MEM (QImode, sym);
}
/* Emit insn. */
insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
gen_rtx_REG (Pmode, RETURN_REGNUM)));
-
- /* In 31-bit, we must load the GOT register even if the
- compiler doesn't know about it, because the PLT glue
- code uses it. In 64-bit, this is not necessary. */
- if (plt_call && !TARGET_64BIT)
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
DONE;
}")
""
"
{
- int plt_call = 0;
rtx insn;
/* Direct function calls need special treatment. */
replace the symbol itself with the PLT stub. */
if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
{
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
-
- plt_call = 1;
}
/* Unless we can use the bras(l) insn, force the
routine address into a register. */
if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
{
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
}
operands[1] = gen_rtx_MEM (QImode, sym);
insn = emit_call_insn (
gen_call_value_exp (operands[0], operands[1], operands[2],
gen_rtx_REG (Pmode, RETURN_REGNUM)));
-
- /* In 31-bit, we must load the GOT register even if the
- compiler doesn't know about it, because the PLT glue
- code uses it. In 64-bit, this is not necessary. */
- if (plt_call && !TARGET_64BIT)
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
DONE;
}")
abort ();
sym = s390_tls_get_offset ();
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
/* Unless we can use the bras(l) insn, force the
routine address into a register. */
if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
{
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
}
sym = gen_rtx_MEM (QImode, sym);
;
(define_expand "builtin_setjmp_setup"
- [(unspec [(match_operand 0 "register_operand" "a")] 1)]
+ [(match_operand 0 "register_operand" "")]
""
- "
{
rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
emit_move_insn (base, basereg);
DONE;
-}")
+})
(define_expand "builtin_setjmp_receiver"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
+ [(match_operand 0 "" "")]
"flag_pic"
- "
{
- rtx gotreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
- rtx got = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
- SYMBOL_REF_FLAGS (got) = SYMBOL_FLAG_LOCAL;
-
- emit_move_insn (gotreg, got);
- emit_insn (gen_rtx_USE (VOIDmode, gotreg));
+ s390_load_got (false);
+ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
DONE;
-}")
+})
(define_expand "builtin_longjmp"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
+ [(match_operand 0 "register_operand" "")]
""
- "
{
/* The elements of the buffer are, in order: */
rtx fp = gen_rtx_MEM (Pmode, operands[0]);
rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2 * GET_MODE_SIZE (Pmode)));
rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
- rtx jmp = gen_rtx_REG (Pmode, 14);
+ rtx jmp = gen_reg_rtx (Pmode);
emit_move_insn (jmp, lab);
emit_move_insn (basereg, base);
emit_insn (gen_rtx_USE (VOIDmode, basereg));
emit_indirect_jump (jmp);
DONE;
-}")
+})
;; These patterns say how to save and restore the stack pointer. We need not
;
(define_insn "consttable_qi"
- [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")] 200)]
+ [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")]
+ UNSPECV_POOL_QI)]
""
- "*
{
assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
- return \"\";
-}"
+ return "";
+}
[(set_attr "op_type" "NN")
(set_attr "length" "1")])
(define_insn "consttable_hi"
- [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")] 201)]
+ [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")]
+ UNSPECV_POOL_HI)]
""
- "*
{
assemble_integer (operands[0], 2, 2*BITS_PER_UNIT, 1);
- return \"\";
-}"
+ return "";
+}
[(set_attr "op_type" "NN")
(set_attr "length" "2")])
(define_insn "consttable_si"
- [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")] 202)]
+ [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")]
+ UNSPECV_POOL_SI)]
""
- "*
-{
- if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[0]))
- return \".long\\t%0\";
-
- assemble_integer (operands[0], 4, 4*BITS_PER_UNIT, 1);
- return \"\";
-}"
+ ".long\t%0"
[(set_attr "op_type" "NN")
(set_attr "length" "4")])
(define_insn "consttable_di"
- [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")] 203)]
+ [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")]
+ UNSPECV_POOL_DI)]
""
- "*
-{
- assemble_integer (operands[0], 8, 8*BITS_PER_UNIT, 1);
- return \"\";
-}"
+ ".quad\t%0"
[(set_attr "op_type" "NN")
(set_attr "length" "8")])
+(define_insn "consttable_ti"
+ [(unspec_volatile [(match_operand:TI 0 "consttable_operand" "X")]
+ UNSPECV_POOL_TI)]
+ ""
+{
+ assemble_integer (operands[0], 16, 16*BITS_PER_UNIT, 1);
+ return "";
+}
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "16")])
+
(define_insn "consttable_sf"
- [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")] 204)]
+ [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")]
+ UNSPECV_POOL_SF)]
""
- "*
{
REAL_VALUE_TYPE r;
REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
assemble_real (r, SFmode, 4*BITS_PER_UNIT);
- return \"\";
-}"
+ return "";
+}
[(set_attr "op_type" "NN")
(set_attr "length" "4")])
(define_insn "consttable_df"
- [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")] 205)]
+ [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")]
+ UNSPECV_POOL_DF)]
""
- "*
{
REAL_VALUE_TYPE r;
REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
assemble_real (r, DFmode, 8*BITS_PER_UNIT);
- return \"\";
-}"
+ return "";
+}
[(set_attr "op_type" "NN")
(set_attr "length" "8")])
(define_insn "pool_start_31"
- [(unspec_volatile [(const_int 0)] 206)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
"!TARGET_64BIT"
".align\\t4"
[(set_attr "op_type" "NN")
(set_attr "length" "2")])
(define_insn "pool_end_31"
- [(unspec_volatile [(const_int 0)] 207)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
"!TARGET_64BIT"
".align\\t2"
[(set_attr "op_type" "NN")
(set_attr "length" "2")])
(define_insn "pool_start_64"
- [(unspec_volatile [(const_int 0)] 206)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
"TARGET_64BIT"
".section\\t.rodata\;.align\\t8"
[(set_attr "op_type" "NN")
(set_attr "length" "0")])
(define_insn "pool_end_64"
- [(unspec_volatile [(const_int 0)] 207)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
"TARGET_64BIT"
".previous"
[(set_attr "op_type" "NN")
(define_insn "reload_base_31"
[(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(label_ref (match_operand 1 "" ""))] 210))]
+ (unspec:SI [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
"!TARGET_64BIT"
"basr\\t%0,0\;la\\t%0,%1-.(%0)"
[(set_attr "op_type" "NN")
(define_insn "reload_base_64"
[(set (match_operand:DI 0 "register_operand" "=a")
- (unspec:DI [(label_ref (match_operand 1 "" ""))] 210))]
+ (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
"TARGET_64BIT"
"larl\\t%0,%1"
[(set_attr "op_type" "RIL")
(set_attr "type" "larl")])
-(define_insn "reload_anchor"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 211))]
- "!TARGET_64BIT"
- "l\\t%0,0(%1)\;la\\t%0,0(%0,%1)"
- [(set_attr "op_type" "NN")
- (set_attr "type" "la")
- (set_attr "atype" "agen")
- (set_attr "length" "8")])
-
(define_insn "pool"
- [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] 220)]
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
""
"* abort ();"
[(set_attr "op_type" "NN")
(set_attr "atype" "agen")])
(define_insn "literal_pool_31"
- [(unspec_volatile [(const_int 0)] 300)
+ [(unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL)
(set (match_operand:SI 0 "register_operand" "=a")
(label_ref (match_operand 1 "" "")))
(use (label_ref (match_operand 2 "" "")))]
(set_attr "type" "larl")])
(define_insn "literal_pool_64"
- [(unspec_volatile [(const_int 0)] 300)
+ [(unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL)
(set (match_operand:DI 0 "register_operand" "=a")
(label_ref (match_operand 1 "" "")))
(use (label_ref (match_operand 2 "" "")))]