s390.c (pool_stop_uid, [...]): Delete.
* config/s390/s390.c (pool_stop_uid, other_chunk, far_away, check_and_change_labels, s390_final_chunkify): Delete. (s390_split_branches, s390_chunkify_pool): New functions. (s390_function_prologue): Call them. * config/s390/s390.h (S390_REL_MAX): Delete. (S390_CHUNK_MAX, S390_CHUNK_OV): Adjust values. * config/s390/s390.md (cjump, icjump, jump): Fix length attribute calculation. From-SVN: r49797
This commit is contained in:
parent
34d1b01d2e
commit
13e58269a6
@ -1,3 +1,17 @@
|
|||||||
|
2002-02-16 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
* config/s390/s390.c (pool_stop_uid, other_chunk, far_away,
|
||||||
|
check_and_change_labels, s390_final_chunkify): Delete.
|
||||||
|
(s390_split_branches, s390_chunkify_pool): New functions.
|
||||||
|
(s390_function_prologue): Call them.
|
||||||
|
|
||||||
|
* config/s390/s390.h (S390_REL_MAX): Delete.
|
||||||
|
(S390_CHUNK_MAX, S390_CHUNK_OV): Adjust values.
|
||||||
|
|
||||||
|
* config/s390/s390.md (cjump, icjump, jump): Fix length
|
||||||
|
attribute calculation.
|
||||||
|
|
||||||
|
|
||||||
2002-02-15 David Edelsohn <edelsohn@gnu.org>
|
2002-02-15 David Edelsohn <edelsohn@gnu.org>
|
||||||
|
|
||||||
* config/rs6000/linux64.h (STRIP_NAME_ENCODING): Delete.
|
* config/rs6000/linux64.h (STRIP_NAME_ENCODING): Delete.
|
||||||
|
@ -129,10 +129,8 @@ static int general_s_operand PARAMS ((rtx, enum machine_mode, int));
|
|||||||
static int s390_decompose_address PARAMS ((rtx, struct s390_address *, int));
|
static int s390_decompose_address PARAMS ((rtx, struct s390_address *, int));
|
||||||
static int reg_used_in_mem_p PARAMS ((int, rtx));
|
static int reg_used_in_mem_p PARAMS ((int, rtx));
|
||||||
static int addr_generation_dependency_p PARAMS ((rtx, rtx));
|
static int addr_generation_dependency_p PARAMS ((rtx, rtx));
|
||||||
static int other_chunk PARAMS ((int *, int, int));
|
static void s390_split_branches PARAMS ((void));
|
||||||
static int far_away PARAMS ((int, int));
|
static void s390_chunkify_pool PARAMS ((void));
|
||||||
static rtx check_and_change_labels PARAMS ((rtx, int *));
|
|
||||||
static void s390_final_chunkify PARAMS ((int));
|
|
||||||
static int save_fprs_p PARAMS ((void));
|
static int save_fprs_p PARAMS ((void));
|
||||||
static int find_unused_clobbered_reg PARAMS ((void));
|
static int find_unused_clobbered_reg PARAMS ((void));
|
||||||
static void s390_frame_info PARAMS ((struct s390_frame *));
|
static void s390_frame_info PARAMS ((struct s390_frame *));
|
||||||
@ -2341,10 +2339,6 @@ int s390_pool_count = -1;
|
|||||||
processed. */
|
processed. */
|
||||||
rtx s390_pool_start_insn = NULL_RTX;
|
rtx s390_pool_start_insn = NULL_RTX;
|
||||||
|
|
||||||
/* UID of last insn using the constant pool chunk that is currently
|
|
||||||
being processed. */
|
|
||||||
static int pool_stop_uid;
|
|
||||||
|
|
||||||
/* Called from the ASM_OUTPUT_POOL_PROLOGUE macro to
|
/* Called from the ASM_OUTPUT_POOL_PROLOGUE macro to
|
||||||
prepare for printing a literal pool chunk to stdio stream FILE.
|
prepare for printing a literal pool chunk to stdio stream FILE.
|
||||||
|
|
||||||
@ -2382,312 +2376,206 @@ s390_asm_output_pool_prologue (file, fname, fndecl, size)
|
|||||||
function_section (fndecl);
|
function_section (fndecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if OTHER_ADDR is in different chunk than MY_ADDR.
|
/* Split all branches that exceed the maximum distance. */
|
||||||
LTORG points to a list of all literal pools inserted
|
|
||||||
into the current function. */
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
other_chunk (ltorg, my_addr, other_addr)
|
s390_split_branches (void)
|
||||||
int *ltorg;
|
|
||||||
int my_addr;
|
|
||||||
int other_addr;
|
|
||||||
{
|
|
||||||
int ad, i=0, j=0;
|
|
||||||
|
|
||||||
while ((ad = ltorg[i++])) {
|
|
||||||
if (INSN_ADDRESSES (ad) >= my_addr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((ad = ltorg[j++])) {
|
|
||||||
if (INSN_ADDRESSES (ad) > other_addr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i==j)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true if OTHER_ADDR is too far away from MY_ADDR
|
|
||||||
to use a relative branch instruction. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
far_away (my_addr, other_addr)
|
|
||||||
int my_addr;
|
|
||||||
int other_addr;
|
|
||||||
{
|
|
||||||
/* In 64 bit mode we can jump +- 4GB. */
|
|
||||||
if (TARGET_64BIT)
|
|
||||||
return 0;
|
|
||||||
if (abs (my_addr - other_addr) > S390_REL_MAX)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Go through all insns in the current function (starting
|
|
||||||
at INSN), replacing branch insn if necessary. A branch
|
|
||||||
needs to be modified if either the distance to the
|
|
||||||
target is too far to use a relative branch, or if the
|
|
||||||
target uses a different literal pool than the origin.
|
|
||||||
LTORG_UIDS points to a list of all literal pool insns
|
|
||||||
that have been inserted. */
|
|
||||||
|
|
||||||
static rtx
|
|
||||||
check_and_change_labels (insn, ltorg_uids)
|
|
||||||
rtx insn;
|
|
||||||
int *ltorg_uids;
|
|
||||||
{
|
{
|
||||||
rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
|
rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
|
||||||
rtx target, jump, cjump;
|
rtx insn, pat, label, target, jump, tmp;
|
||||||
rtx pattern, tmp, body, label1;
|
|
||||||
int addr0, addr1;
|
|
||||||
|
|
||||||
if (GET_CODE (insn) != JUMP_INSN)
|
/* In 64-bit mode we can jump +- 4GB. */
|
||||||
return insn;
|
|
||||||
|
|
||||||
pattern = PATTERN (insn);
|
if (TARGET_64BIT)
|
||||||
|
return;
|
||||||
addr0 = INSN_ADDRESSES (INSN_UID (insn));
|
|
||||||
if (GET_CODE (pattern) == SET)
|
/* Find all branches that exceed 64KB, and split them. */
|
||||||
|
|
||||||
|
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||||
{
|
{
|
||||||
body = XEXP (pattern, 1);
|
if (GET_CODE (insn) != JUMP_INSN)
|
||||||
if (GET_CODE (body) == LABEL_REF)
|
continue;
|
||||||
|
|
||||||
|
pat = PATTERN (insn);
|
||||||
|
if (GET_CODE (pat) != SET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
|
||||||
{
|
{
|
||||||
addr1 = INSN_ADDRESSES (INSN_UID (XEXP (body, 0)));
|
label = SET_SRC (pat);
|
||||||
|
|
||||||
if (other_chunk (ltorg_uids, addr0, addr1))
|
|
||||||
{
|
|
||||||
SYMBOL_REF_USED (XEXP (body, 0)) = 1;
|
|
||||||
}
|
|
||||||
if (far_away (addr0, addr1))
|
|
||||||
{
|
|
||||||
if (flag_pic)
|
|
||||||
{
|
|
||||||
target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, body), 100);
|
|
||||||
target = gen_rtx_CONST (SImode, target);
|
|
||||||
target = force_const_mem (SImode, target);
|
|
||||||
jump = gen_rtx_REG (Pmode, BASE_REGISTER);
|
|
||||||
jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
target = force_const_mem (Pmode, body);
|
|
||||||
jump = temp_reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit_insn_before (gen_movsi (temp_reg, target), insn);
|
|
||||||
tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
|
|
||||||
remove_insn (insn);
|
|
||||||
INSN_ADDRESSES_NEW (tmp, -1);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (GET_CODE (body) == IF_THEN_ELSE)
|
else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
|
||||||
{
|
{
|
||||||
if (GET_CODE (XEXP (body, 1)) == LABEL_REF)
|
if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
|
||||||
{
|
label = XEXP (SET_SRC (pat), 1);
|
||||||
addr1 = INSN_ADDRESSES (INSN_UID (XEXP (XEXP (body, 1), 0)));
|
else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
|
||||||
|
label = XEXP (SET_SRC (pat), 2);
|
||||||
if (other_chunk (ltorg_uids, addr0, addr1))
|
else
|
||||||
{
|
continue;
|
||||||
SYMBOL_REF_USED (XEXP (XEXP (body, 1), 0)) = 1;
|
}
|
||||||
}
|
else
|
||||||
|
continue;
|
||||||
if (far_away (addr0, addr1))
|
|
||||||
{
|
if (get_attr_length (insn) == 4)
|
||||||
if (flag_pic)
|
continue;
|
||||||
{
|
|
||||||
target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, XEXP (body, 1)), 100);
|
if (flag_pic)
|
||||||
target = gen_rtx_CONST (SImode, target);
|
|
||||||
target = force_const_mem (SImode, target);
|
|
||||||
jump = gen_rtx_REG (Pmode, BASE_REGISTER);
|
|
||||||
jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
target = force_const_mem (Pmode, XEXP (body, 1));
|
|
||||||
jump = temp_reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
label1 = gen_label_rtx ();
|
|
||||||
cjump = gen_rtx_LABEL_REF (VOIDmode, label1);
|
|
||||||
cjump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (body, 0), pc_rtx, cjump);
|
|
||||||
cjump = gen_rtx_SET (VOIDmode, pc_rtx, cjump);
|
|
||||||
emit_jump_insn_before (cjump, insn);
|
|
||||||
emit_insn_before (gen_movsi (temp_reg, target), insn);
|
|
||||||
tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
|
|
||||||
INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1);
|
|
||||||
remove_insn (insn);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (GET_CODE (XEXP (body, 2)) == LABEL_REF)
|
|
||||||
{
|
|
||||||
addr1 = INSN_ADDRESSES (INSN_UID (XEXP (XEXP (body, 2), 0)));
|
|
||||||
|
|
||||||
if (other_chunk (ltorg_uids, addr0, addr1))
|
|
||||||
{
|
|
||||||
SYMBOL_REF_USED (XEXP (XEXP (body, 2), 0)) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (far_away (addr0, addr1))
|
|
||||||
{
|
|
||||||
if (flag_pic)
|
|
||||||
{
|
|
||||||
target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, XEXP (body, 2)), 100);
|
|
||||||
target = gen_rtx_CONST (SImode, target);
|
|
||||||
target = force_const_mem (SImode, target);
|
|
||||||
jump = gen_rtx_REG (Pmode, BASE_REGISTER);
|
|
||||||
jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
target = force_const_mem (Pmode, XEXP (body, 2));
|
|
||||||
jump = temp_reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
label1 = gen_label_rtx ();
|
|
||||||
cjump = gen_rtx_LABEL_REF (VOIDmode, label1);
|
|
||||||
cjump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (body, 0), cjump, pc_rtx);
|
|
||||||
cjump = gen_rtx_SET (VOIDmode, pc_rtx, cjump);
|
|
||||||
emit_jump_insn_before (cjump, insn);
|
|
||||||
emit_insn_before (gen_movsi (temp_reg, target), insn);
|
|
||||||
tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
|
|
||||||
INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1);
|
|
||||||
remove_insn (insn);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (GET_CODE (pattern) == ADDR_VEC ||
|
|
||||||
GET_CODE (pattern) == ADDR_DIFF_VEC)
|
|
||||||
{
|
|
||||||
int i, diff_vec_p = GET_CODE (pattern) == ADDR_DIFF_VEC;
|
|
||||||
int len = XVECLEN (pattern, diff_vec_p);
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
{
|
||||||
addr1 = INSN_ADDRESSES (INSN_UID (XEXP (XVECEXP (pattern, diff_vec_p, i), 0)));
|
target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, label), 100);
|
||||||
if (other_chunk (ltorg_uids, addr0, addr1))
|
target = gen_rtx_CONST (SImode, target);
|
||||||
{
|
target = force_const_mem (SImode, target);
|
||||||
SYMBOL_REF_USED (XEXP (XVECEXP (pattern, diff_vec_p, i), 0)) = 1;
|
jump = gen_rtx_REG (Pmode, BASE_REGISTER);
|
||||||
}
|
jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target = force_const_mem (Pmode, label);
|
||||||
|
jump = temp_reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
|
||||||
|
{
|
||||||
|
if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
|
||||||
|
jump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (SET_SRC (pat), 0),
|
||||||
|
jump, pc_rtx);
|
||||||
|
else
|
||||||
|
jump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (SET_SRC (pat), 0),
|
||||||
|
pc_rtx, jump);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
|
||||||
|
INSN_ADDRESSES_NEW (tmp, -1);
|
||||||
|
|
||||||
|
tmp = emit_jump_insn_before (gen_rtx_SET (VOIDmode, pc_rtx, jump), insn);
|
||||||
|
INSN_ADDRESSES_NEW (tmp, -1);
|
||||||
|
|
||||||
|
remove_insn (insn);
|
||||||
|
insn = tmp;
|
||||||
}
|
}
|
||||||
return insn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from s390_function_prologue to make final adjustments
|
/* Chunkify the literal pool if required. */
|
||||||
before outputting code. CHUNKIFY specifies whether we need
|
|
||||||
to use multiple literal pools (because the total size of the
|
|
||||||
literals exceeds 4K). */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
s390_final_chunkify (chunkify)
|
s390_chunkify_pool (void)
|
||||||
int chunkify;
|
|
||||||
{
|
{
|
||||||
rtx insn, ninsn, tmp;
|
int *ltorg_uids, max_ltorg, chunk, last_addr;
|
||||||
int addr, naddr = 0, uids;
|
rtx insn;
|
||||||
int chunk_max = 0;
|
|
||||||
|
|
||||||
int size = insn_current_address;
|
/* Do we need to chunkify the literal pool? */
|
||||||
|
|
||||||
int *ltorg_uids;
|
if (get_pool_size () <= S390_POOL_MAX)
|
||||||
int max_ltorg=0;
|
return;
|
||||||
|
|
||||||
ltorg_uids = alloca (size / 1024 + 1024);
|
/* Find all insns where a literal pool chunk must be inserted. */
|
||||||
memset (ltorg_uids, 0, size / 1024 + 1024);
|
|
||||||
|
|
||||||
if (chunkify == 1)
|
ltorg_uids = alloca (insn_current_address / 1024 + 1024);
|
||||||
|
max_ltorg = 0;
|
||||||
|
|
||||||
|
last_addr = 0;
|
||||||
|
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||||
{
|
{
|
||||||
chunk_max = size * 2048 / get_pool_size ();
|
if (INSN_ADDRESSES (INSN_UID (insn)) - last_addr < S390_CHUNK_MAX)
|
||||||
chunk_max = chunk_max > S390_CHUNK_MAX
|
|
||||||
? S390_CHUNK_MAX : chunk_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (insn=get_insns (); insn;insn = next_real_insn (insn))
|
|
||||||
{
|
|
||||||
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
|
|
||||||
continue;
|
continue;
|
||||||
|
if (INSN_ADDRESSES (INSN_UID (insn)) - last_addr > S390_CHUNK_OV)
|
||||||
addr = INSN_ADDRESSES (INSN_UID (insn));
|
abort ();
|
||||||
if ((ninsn = next_real_insn (insn)))
|
|
||||||
|
if (GET_CODE (insn) == CODE_LABEL
|
||||||
|
&& !(GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
|
||||||
|
&& (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
|
||||||
|
|| GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC)))
|
||||||
{
|
{
|
||||||
naddr = INSN_ADDRESSES (INSN_UID (ninsn));
|
ltorg_uids[max_ltorg++] = INSN_UID (prev_real_insn (insn));
|
||||||
|
last_addr = INSN_ADDRESSES (ltorg_uids[max_ltorg-1]);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunkify && (addr / chunk_max != naddr / chunk_max))
|
if (GET_CODE (insn) == CALL_INSN)
|
||||||
{
|
{
|
||||||
for (tmp = insn; tmp; tmp = NEXT_INSN (tmp))
|
ltorg_uids[max_ltorg++] = INSN_UID (insn);
|
||||||
{
|
last_addr = INSN_ADDRESSES (ltorg_uids[max_ltorg-1]);
|
||||||
if (GET_CODE (tmp) == CODE_LABEL &&
|
continue;
|
||||||
GET_CODE (NEXT_INSN (tmp)) != JUMP_INSN)
|
}
|
||||||
{
|
|
||||||
ltorg_uids[max_ltorg++] = INSN_UID (prev_real_insn (tmp));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (GET_CODE (tmp) == CALL_INSN)
|
|
||||||
{
|
|
||||||
ltorg_uids[max_ltorg++] = INSN_UID (tmp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (INSN_ADDRESSES (INSN_UID (tmp)) - naddr > S390_CHUNK_OV)
|
|
||||||
{
|
|
||||||
debug_rtx (insn);
|
|
||||||
debug_rtx (tmp);
|
|
||||||
fprintf (stderr, "s390 multiple literalpool support:\n No code label between this insn %X %X",
|
|
||||||
naddr, INSN_ADDRESSES (INSN_UID (tmp)));
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tmp == NULL)
|
|
||||||
{
|
|
||||||
warning ("no code label found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ltorg_uids[max_ltorg] = 0;
|
|
||||||
|
|
||||||
if (max_ltorg > 0)
|
|
||||||
{
|
|
||||||
for (insn = get_insns (), uids = 0; insn; insn = next_real_insn (insn))
|
|
||||||
if (INSN_UID (insn) == ltorg_uids[uids])
|
|
||||||
{
|
|
||||||
INSN_ADDRESSES_NEW (emit_insn_after (gen_ltorg (
|
|
||||||
gen_rtx_CONST_INT (Pmode, ltorg_uids[++uids])),
|
|
||||||
insn), -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
init_insn_lengths ();
|
|
||||||
shorten_branches (get_insns ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (insn = get_insns (); insn; insn = next_real_insn (insn))
|
ltorg_uids[max_ltorg] = insn_current_address + 1;
|
||||||
|
|
||||||
|
/* Find and mark all labels that are branched into
|
||||||
|
from an insn belonging to a different chunk. */
|
||||||
|
|
||||||
|
chunk = last_addr = 0;
|
||||||
|
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||||
{
|
{
|
||||||
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
|
|
||||||
continue;
|
|
||||||
if (GET_CODE (insn) == JUMP_INSN)
|
if (GET_CODE (insn) == JUMP_INSN)
|
||||||
insn = check_and_change_labels (insn, ltorg_uids);
|
{
|
||||||
|
rtx pat = PATTERN (insn);
|
||||||
|
if (GET_CODE (pat) == SET)
|
||||||
|
{
|
||||||
|
rtx label = 0;
|
||||||
|
|
||||||
|
if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
|
||||||
|
{
|
||||||
|
label = XEXP (SET_SRC (pat), 0);
|
||||||
|
}
|
||||||
|
else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
|
||||||
|
{
|
||||||
|
if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
|
||||||
|
label = XEXP (XEXP (SET_SRC (pat), 1), 0);
|
||||||
|
else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
|
||||||
|
label = XEXP (XEXP (SET_SRC (pat), 2), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label)
|
||||||
|
{
|
||||||
|
if (INSN_ADDRESSES (INSN_UID (label)) <= last_addr
|
||||||
|
|| INSN_ADDRESSES (INSN_UID (label)) > ltorg_uids[chunk])
|
||||||
|
SYMBOL_REF_USED (label) = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (GET_CODE (pat) == ADDR_VEC
|
||||||
|
|| GET_CODE (pat) == ADDR_DIFF_VEC)
|
||||||
|
{
|
||||||
|
int i, diff_p = GET_CODE (pat) == ADDR_DIFF_VEC;
|
||||||
|
|
||||||
|
for (i = 0; i < XVECLEN (pat, diff_p); i++)
|
||||||
|
{
|
||||||
|
rtx label = XEXP (XVECEXP (pat, diff_p, i), 0);
|
||||||
|
|
||||||
|
if (INSN_ADDRESSES (INSN_UID (label)) <= last_addr
|
||||||
|
|| INSN_ADDRESSES (INSN_UID (label)) > ltorg_uids[chunk])
|
||||||
|
SYMBOL_REF_USED (label) = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (INSN_UID (insn) == ltorg_uids[chunk])
|
||||||
|
{
|
||||||
|
last_addr = ltorg_uids[chunk++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunkify)
|
/* Insert literal pools and base register reload insns. */
|
||||||
|
|
||||||
|
chunk = 0;
|
||||||
|
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||||
{
|
{
|
||||||
for (insn=get_insns (); insn;insn = next_insn (insn))
|
if (INSN_UID (insn) == ltorg_uids[chunk])
|
||||||
{
|
{
|
||||||
if (GET_CODE (insn) == CODE_LABEL)
|
rtx new_insn = gen_ltorg (GEN_INT (chunk++));
|
||||||
|
INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GET_CODE (insn) == CODE_LABEL && SYMBOL_REF_USED (insn))
|
||||||
{
|
{
|
||||||
if (SYMBOL_REF_USED (insn))
|
rtx new_insn = gen_reload_base (insn);
|
||||||
{
|
INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
|
||||||
INSN_ADDRESSES_NEW (emit_insn_after (gen_reload_base (
|
|
||||||
gen_rtx_LABEL_REF (Pmode, XEXP (insn, 0))), insn), -1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pool_stop_uid = ltorg_uids[0];
|
|
||||||
|
/* Recompute insn addresses. */
|
||||||
|
|
||||||
|
init_insn_lengths ();
|
||||||
|
shorten_branches (get_insns ());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if INSN is a 'ltorg' insn. */
|
/* Return true if INSN is a 'ltorg' insn. */
|
||||||
@ -2719,7 +2607,6 @@ s390_dump_literal_pool (act_insn, stop)
|
|||||||
rtx stop;
|
rtx stop;
|
||||||
{
|
{
|
||||||
s390_pool_start_insn = act_insn;
|
s390_pool_start_insn = act_insn;
|
||||||
pool_stop_uid = INTVAL (stop);
|
|
||||||
s390_pool_count++;
|
s390_pool_count++;
|
||||||
output_constant_pool (current_function_name, current_function_decl);
|
output_constant_pool (current_function_name, current_function_decl);
|
||||||
function_section (current_function_decl);
|
function_section (current_function_decl);
|
||||||
@ -2927,10 +2814,8 @@ s390_function_prologue (file, lsize)
|
|||||||
FILE *file ATTRIBUTE_UNUSED;
|
FILE *file ATTRIBUTE_UNUSED;
|
||||||
HOST_WIDE_INT lsize ATTRIBUTE_UNUSED;
|
HOST_WIDE_INT lsize ATTRIBUTE_UNUSED;
|
||||||
{
|
{
|
||||||
if (get_pool_size () > S390_POOL_MAX)
|
s390_chunkify_pool ();
|
||||||
s390_final_chunkify (1);
|
s390_split_branches ();
|
||||||
else
|
|
||||||
s390_final_chunkify (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output the function epilogue assembly code to the
|
/* Output the function epilogue assembly code to the
|
||||||
|
@ -1330,9 +1330,8 @@ extern int s390_nr_constants;
|
|||||||
/* Function is splitted in chunk, if literal pool could overflow
|
/* Function is splitted in chunk, if literal pool could overflow
|
||||||
Value need to be lowered, if problems with displacement overflow. */
|
Value need to be lowered, if problems with displacement overflow. */
|
||||||
|
|
||||||
#define S390_REL_MAX 55000
|
#define S390_CHUNK_MAX 0xe00
|
||||||
#define S390_CHUNK_MAX 0x2000
|
#define S390_CHUNK_OV 0x1000
|
||||||
#define S390_CHUNK_OV 0x8000
|
|
||||||
#define S390_POOL_MAX 0xe00
|
#define S390_POOL_MAX 0xe00
|
||||||
|
|
||||||
#define ASM_OUTPUT_POOL_PROLOGUE(FILE, FUNNAME, fndecl, size) \
|
#define ASM_OUTPUT_POOL_PROLOGUE(FILE, FUNNAME, fndecl, size) \
|
||||||
|
@ -5660,15 +5660,21 @@
|
|||||||
""
|
""
|
||||||
"*
|
"*
|
||||||
{
|
{
|
||||||
if (get_attr_length (insn) == 4 || !TARGET_64BIT)
|
if (get_attr_length (insn) == 4)
|
||||||
return \"j%C1\\t%l0\";
|
return \"j%C1\\t%l0\";
|
||||||
|
else if (TARGET_64BIT)
|
||||||
|
return \"jg%C1\\t%l0\";
|
||||||
else
|
else
|
||||||
return \"jg%C1\\t%l0\";
|
abort ();
|
||||||
}"
|
}"
|
||||||
[(set_attr "op_type" "RI")
|
[(set_attr "op_type" "RI")
|
||||||
(set (attr "length") (if_then_else
|
(set (attr "length")
|
||||||
(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
||||||
(const_int 4) (const_int 6)))])
|
(const_int 4)
|
||||||
|
(ne (symbol_ref "TARGET_64BIT") (const_int 0))
|
||||||
|
(const_int 6)
|
||||||
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
||||||
|
(const_int 6)] (const_int 8)))])
|
||||||
|
|
||||||
(define_insn "*cjump_long"
|
(define_insn "*cjump_long"
|
||||||
[(set (pc)
|
[(set (pc)
|
||||||
@ -5703,15 +5709,21 @@
|
|||||||
""
|
""
|
||||||
"*
|
"*
|
||||||
{
|
{
|
||||||
if (get_attr_length (insn) == 4 || !TARGET_64BIT)
|
if (get_attr_length (insn) == 4)
|
||||||
return \"j%D1\\t%l0\";
|
return \"j%D1\\t%l0\";
|
||||||
|
else if (TARGET_64BIT)
|
||||||
|
return \"jg%D1\\t%l0\";
|
||||||
else
|
else
|
||||||
return \"jg%D1\\t%l0\";
|
abort ();
|
||||||
}"
|
}"
|
||||||
[(set_attr "op_type" "RI")
|
[(set_attr "op_type" "RI")
|
||||||
(set (attr "length") (if_then_else
|
(set (attr "length")
|
||||||
(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
||||||
(const_int 4) (const_int 6)))])
|
(const_int 4)
|
||||||
|
(ne (symbol_ref "TARGET_64BIT") (const_int 0))
|
||||||
|
(const_int 6)
|
||||||
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
||||||
|
(const_int 6)] (const_int 8)))])
|
||||||
|
|
||||||
(define_insn "*icjump_long"
|
(define_insn "*icjump_long"
|
||||||
[(set (pc)
|
[(set (pc)
|
||||||
@ -5794,15 +5806,21 @@
|
|||||||
""
|
""
|
||||||
"*
|
"*
|
||||||
{
|
{
|
||||||
if (get_attr_length (insn) == 4 || !TARGET_64BIT)
|
if (get_attr_length (insn) == 4)
|
||||||
return \"j\\t%l0\";
|
return \"j\\t%l0\";
|
||||||
|
else if (TARGET_64BIT)
|
||||||
|
return \"jg\\t%l0\";
|
||||||
else
|
else
|
||||||
return \"jg\\t%l0\";
|
abort ();
|
||||||
}"
|
}"
|
||||||
[(set_attr "op_type" "RI")
|
[(set_attr "op_type" "RI")
|
||||||
(set (attr "length") (if_then_else
|
(set (attr "length")
|
||||||
(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
||||||
(const_int 4) (const_int 6)))])
|
(const_int 4)
|
||||||
|
(ne (symbol_ref "TARGET_64BIT") (const_int 0))
|
||||||
|
(const_int 6)
|
||||||
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
||||||
|
(const_int 6)] (const_int 8)))])
|
||||||
|
|
||||||
;
|
;
|
||||||
; indirect-jump instruction pattern(s).
|
; indirect-jump instruction pattern(s).
|
||||||
|
Loading…
Reference in New Issue
Block a user