mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-23 06:19:14 +08:00
re PR target/14040 (ARM cross compiler: error: could not split insn)
PR target/14040 * genemit.c (gen_split): Change prototype of generated code. * genrecog.c (write_action): Adjust prototype for and calls to gen_split_*. * gensupport.c (struct queue_elem): Add split field. (queue_pattern): Return a value. Clear the split field. (process_rtx): Maintain an association between an insn and the split generated from it for a define_insn_and_split. (process_one_cond_exec): Generate a new split for a define_insn_and_split. * config/arm/arm-protos.h (arm_split_constant): Add insn parameter. (emit_constant_insn): New function. (arm_gen_constant): Use it. * config/arm/arm.md: Adjust calls to arm_split_constant. From-SVN: r80335
This commit is contained in:
parent
18c6ada9b2
commit
a406f5669b
@ -1,3 +1,20 @@
|
||||
2004-04-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* genemit.c (gen_split): Change prototype of generated code.
|
||||
* genrecog.c (write_action): Adjust prototype for and calls to
|
||||
gen_split_*.
|
||||
* gensupport.c (struct queue_elem): Add split field.
|
||||
(queue_pattern): Return a value. Clear the split field.
|
||||
(process_rtx): Maintain an association between an insn and the
|
||||
split generated from it for a define_insn_and_split.
|
||||
(process_one_cond_exec): Generate a new split for a
|
||||
define_insn_and_split.
|
||||
* config/arm/arm-protos.h (arm_split_constant): Add insn
|
||||
parameter.
|
||||
(emit_constant_insn): New function.
|
||||
(arm_gen_constant): Use it.
|
||||
* config/arm/arm.md: Adjust calls to arm_split_constant.
|
||||
|
||||
2004-04-02 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraph.c: Add overall comment.
|
||||
|
@ -46,8 +46,8 @@ extern void arm_encode_call_attribute (tree, int);
|
||||
#ifdef RTX_CODE
|
||||
extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
|
||||
extern int const_ok_for_arm (HOST_WIDE_INT);
|
||||
extern int arm_split_constant (RTX_CODE, enum machine_mode, HOST_WIDE_INT, rtx,
|
||||
rtx, int);
|
||||
extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
|
||||
HOST_WIDE_INT, rtx, rtx, int);
|
||||
extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
|
||||
extern int legitimate_pic_operand_p (rtx);
|
||||
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
|
||||
|
@ -61,8 +61,8 @@ const struct attribute_spec arm_attribute_table[];
|
||||
/* Forward function declarations. */
|
||||
static arm_stack_offsets *arm_get_frame_offsets (void);
|
||||
static void arm_add_gc_roots (void);
|
||||
static int arm_gen_constant (enum rtx_code, enum machine_mode, HOST_WIDE_INT,
|
||||
rtx, rtx, int, int);
|
||||
static int arm_gen_constant (enum rtx_code, enum machine_mode, rtx,
|
||||
HOST_WIDE_INT, rtx, rtx, int, int);
|
||||
static unsigned bit_count (unsigned long);
|
||||
static int arm_address_register_rtx_p (rtx, int);
|
||||
static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int);
|
||||
@ -140,6 +140,7 @@ static rtx safe_vector_operand (rtx, enum machine_mode);
|
||||
static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
|
||||
static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
|
||||
static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
|
||||
static void emit_constant_insn (rtx cond, rtx pattern);
|
||||
|
||||
#ifdef OBJECT_FORMAT_ELF
|
||||
static void arm_elf_asm_named_section (const char *, unsigned int);
|
||||
@ -1343,9 +1344,16 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
|
||||
Return value is the number of insns emitted. */
|
||||
|
||||
int
|
||||
arm_split_constant (enum rtx_code code, enum machine_mode mode,
|
||||
arm_split_constant (enum rtx_code code, enum machine_mode mode, rtx insn,
|
||||
HOST_WIDE_INT val, rtx target, rtx source, int subtargets)
|
||||
{
|
||||
rtx cond;
|
||||
|
||||
if (insn && GET_CODE (PATTERN (insn)) == COND_EXEC)
|
||||
cond = COND_EXEC_TEST (PATTERN (insn));
|
||||
else
|
||||
cond = NULL_RTX;
|
||||
|
||||
if (subtargets || code == SET
|
||||
|| (GET_CODE (target) == REG && GET_CODE (source) == REG
|
||||
&& REGNO (target) != REGNO (source)))
|
||||
@ -1360,7 +1368,9 @@ arm_split_constant (enum rtx_code code, enum machine_mode mode,
|
||||
Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
|
||||
*/
|
||||
if (!after_arm_reorg
|
||||
&& (arm_gen_constant (code, mode, val, target, source, 1, 0)
|
||||
&& !cond
|
||||
&& (arm_gen_constant (code, mode, NULL_RTX, val, target, source,
|
||||
1, 0)
|
||||
> arm_constant_limit + (code != SET)))
|
||||
{
|
||||
if (code == SET)
|
||||
@ -1388,7 +1398,8 @@ arm_split_constant (enum rtx_code code, enum machine_mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
return arm_gen_constant (code, mode, val, target, source, subtargets, 1);
|
||||
return arm_gen_constant (code, mode, cond, val, target, source, subtargets,
|
||||
1);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1418,11 +1429,23 @@ count_insns_for_constant (HOST_WIDE_INT remainder, int i)
|
||||
return num_insns;
|
||||
}
|
||||
|
||||
/* Emit an instruction with the indicated PATTERN. If COND is
|
||||
non-NULL, conditionalize the execution of the instruction on COND
|
||||
being true. */
|
||||
|
||||
static void
|
||||
emit_constant_insn (rtx cond, rtx pattern)
|
||||
{
|
||||
if (cond)
|
||||
pattern = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (cond), pattern);
|
||||
emit_insn (pattern);
|
||||
}
|
||||
|
||||
/* As above, but extra parameter GENERATE which, if clear, suppresses
|
||||
RTL generation. */
|
||||
|
||||
static int
|
||||
arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
|
||||
HOST_WIDE_INT val, rtx target, rtx source, int subtargets,
|
||||
int generate)
|
||||
{
|
||||
@ -1460,8 +1483,9 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (remainder == 0xffffffff)
|
||||
{
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
GEN_INT (ARM_SIGN_EXTEND (val))));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
GEN_INT (ARM_SIGN_EXTEND (val))));
|
||||
return 1;
|
||||
}
|
||||
if (remainder == 0)
|
||||
@ -1469,7 +1493,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (reload_completed && rtx_equal_p (target, source))
|
||||
return 0;
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target, source));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target, source));
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@ -1478,7 +1503,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (remainder == 0)
|
||||
{
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target, const0_rtx));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target, const0_rtx));
|
||||
return 1;
|
||||
}
|
||||
if (remainder == 0xffffffff)
|
||||
@ -1486,7 +1512,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (reload_completed && rtx_equal_p (target, source))
|
||||
return 0;
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target, source));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target, source));
|
||||
return 1;
|
||||
}
|
||||
can_invert = 1;
|
||||
@ -1498,14 +1525,16 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (reload_completed && rtx_equal_p (target, source))
|
||||
return 0;
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target, source));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target, source));
|
||||
return 1;
|
||||
}
|
||||
if (remainder == 0xffffffff)
|
||||
{
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode, source)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode, source)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1518,16 +1547,18 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (remainder == 0)
|
||||
{
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NEG (mode, source)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NEG (mode, source)));
|
||||
return 1;
|
||||
}
|
||||
if (const_ok_for_arm (val))
|
||||
{
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_MINUS (mode, GEN_INT (val),
|
||||
source)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_MINUS (mode, GEN_INT (val),
|
||||
source)));
|
||||
return 1;
|
||||
}
|
||||
can_negate = 1;
|
||||
@ -1544,10 +1575,12 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
|| (can_invert && const_ok_for_arm (~val)))
|
||||
{
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
(source ? gen_rtx_fmt_ee (code, mode, source,
|
||||
GEN_INT (val))
|
||||
: GEN_INT (val))));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
(source
|
||||
? gen_rtx_fmt_ee (code, mode, source,
|
||||
GEN_INT (val))
|
||||
: GEN_INT (val))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1600,10 +1633,12 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (generate)
|
||||
{
|
||||
rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
|
||||
emit_insn (gen_rtx_SET (VOIDmode, new_src,
|
||||
GEN_INT (temp1)));
|
||||
emit_insn (gen_ashrsi3 (target, new_src,
|
||||
GEN_INT (set_sign_bit_copies - 1)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, new_src,
|
||||
GEN_INT (temp1)));
|
||||
emit_constant_insn (cond,
|
||||
gen_ashrsi3 (target, new_src,
|
||||
GEN_INT (set_sign_bit_copies - 1)));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
@ -1615,10 +1650,12 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (generate)
|
||||
{
|
||||
rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
|
||||
emit_insn (gen_rtx_SET (VOIDmode, new_src,
|
||||
GEN_INT (temp1)));
|
||||
emit_insn (gen_ashrsi3 (target, new_src,
|
||||
GEN_INT (set_sign_bit_copies - 1)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, new_src,
|
||||
GEN_INT (temp1)));
|
||||
emit_constant_insn (cond,
|
||||
gen_ashrsi3 (target, new_src,
|
||||
GEN_INT (set_sign_bit_copies - 1)));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
@ -1643,16 +1680,18 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
rtx new_src = (subtargets
|
||||
? (generate ? gen_reg_rtx (mode) : NULL_RTX)
|
||||
: target);
|
||||
insns = arm_gen_constant (code, mode, temp2, new_src,
|
||||
insns = arm_gen_constant (code, mode, cond, temp2, new_src,
|
||||
source, subtargets, generate);
|
||||
source = new_src;
|
||||
if (generate)
|
||||
emit_insn (gen_rtx_SET
|
||||
(VOIDmode, target,
|
||||
gen_rtx_IOR (mode,
|
||||
gen_rtx_ASHIFT (mode, source,
|
||||
GEN_INT (i)),
|
||||
source)));
|
||||
emit_constant_insn
|
||||
(cond,
|
||||
gen_rtx_SET
|
||||
(VOIDmode, target,
|
||||
gen_rtx_IOR (mode,
|
||||
gen_rtx_ASHIFT (mode, source,
|
||||
GEN_INT (i)),
|
||||
source)));
|
||||
return insns + 1;
|
||||
}
|
||||
}
|
||||
@ -1666,12 +1705,13 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
rtx new_src = (subtargets
|
||||
? (generate ? gen_reg_rtx (mode) : NULL_RTX)
|
||||
: target);
|
||||
insns = arm_gen_constant (code, mode, temp1, new_src,
|
||||
insns = arm_gen_constant (code, mode, cond, temp1, new_src,
|
||||
source, subtargets, generate);
|
||||
source = new_src;
|
||||
if (generate)
|
||||
emit_insn
|
||||
(gen_rtx_SET (VOIDmode, target,
|
||||
emit_constant_insn
|
||||
(cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_IOR
|
||||
(mode,
|
||||
gen_rtx_LSHIFTRT (mode, source,
|
||||
@ -1698,9 +1738,13 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
{
|
||||
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
|
||||
|
||||
emit_insn (gen_rtx_SET (VOIDmode, sub, GEN_INT (val)));
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_fmt_ee (code, mode, source, sub)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, sub,
|
||||
GEN_INT (val)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_fmt_ee (code, mode,
|
||||
source, sub)));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
@ -1717,15 +1761,19 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
|
||||
rtx shift = GEN_INT (set_sign_bit_copies);
|
||||
|
||||
emit_insn (gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_ASHIFT (mode,
|
||||
source,
|
||||
shift))));
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_LSHIFTRT (mode, sub,
|
||||
shift))));
|
||||
emit_constant_insn
|
||||
(cond,
|
||||
gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_ASHIFT (mode,
|
||||
source,
|
||||
shift))));
|
||||
emit_constant_insn
|
||||
(cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_LSHIFTRT (mode, sub,
|
||||
shift))));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
@ -1738,15 +1786,19 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
|
||||
rtx shift = GEN_INT (set_zero_bit_copies);
|
||||
|
||||
emit_insn (gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_LSHIFTRT (mode,
|
||||
source,
|
||||
shift))));
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_ASHIFT (mode, sub,
|
||||
shift))));
|
||||
emit_constant_insn
|
||||
(cond,
|
||||
gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_LSHIFTRT (mode,
|
||||
source,
|
||||
shift))));
|
||||
emit_constant_insn
|
||||
(cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode,
|
||||
gen_rtx_ASHIFT (mode, sub,
|
||||
shift))));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
@ -1756,16 +1808,19 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (generate)
|
||||
{
|
||||
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
|
||||
emit_insn (gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_NOT (mode, source)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_NOT (mode, source)));
|
||||
source = sub;
|
||||
if (subtargets)
|
||||
sub = gen_reg_rtx (mode);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_AND (mode, source,
|
||||
GEN_INT (temp1))));
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode, sub)));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, sub,
|
||||
gen_rtx_AND (mode, source,
|
||||
GEN_INT (temp1))));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_NOT (mode, sub)));
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
@ -1784,14 +1839,16 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
if (generate)
|
||||
{
|
||||
rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
|
||||
insns = arm_gen_constant (AND, mode, remainder | shift_mask,
|
||||
insns = arm_gen_constant (AND, mode, cond,
|
||||
remainder | shift_mask,
|
||||
new_src, source, subtargets, 1);
|
||||
source = new_src;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx targ = subtargets ? NULL_RTX : target;
|
||||
insns = arm_gen_constant (AND, mode, remainder | shift_mask,
|
||||
insns = arm_gen_constant (AND, mode, cond,
|
||||
remainder | shift_mask,
|
||||
targ, source, subtargets, 0);
|
||||
}
|
||||
}
|
||||
@ -1818,7 +1875,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
{
|
||||
rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
|
||||
|
||||
insns = arm_gen_constant (AND, mode, remainder | shift_mask,
|
||||
insns = arm_gen_constant (AND, mode, cond,
|
||||
remainder | shift_mask,
|
||||
new_src, source, subtargets, 1);
|
||||
source = new_src;
|
||||
}
|
||||
@ -1826,7 +1884,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
{
|
||||
rtx targ = subtargets ? NULL_RTX : target;
|
||||
|
||||
insns = arm_gen_constant (AND, mode, remainder | shift_mask,
|
||||
insns = arm_gen_constant (AND, mode, cond,
|
||||
remainder | shift_mask,
|
||||
targ, source, subtargets, 0);
|
||||
}
|
||||
}
|
||||
@ -1971,7 +2030,9 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
|
||||
else
|
||||
temp1_rtx = gen_rtx_fmt_ee (code, mode, source, temp1_rtx);
|
||||
|
||||
emit_insn (gen_rtx_SET (VOIDmode, new_src, temp1_rtx));
|
||||
emit_constant_insn (cond,
|
||||
gen_rtx_SET (VOIDmode, new_src,
|
||||
temp1_rtx));
|
||||
source = new_src;
|
||||
}
|
||||
|
||||
|
@ -454,8 +454,8 @@
|
||||
"
|
||||
if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
|
||||
{
|
||||
arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
|
||||
operands[1],
|
||||
arm_split_constant (PLUS, SImode, NULL_RTX,
|
||||
INTVAL (operands[2]), operands[0], operands[1],
|
||||
(no_new_pseudos ? 0 : preserve_subexpressions_p ()));
|
||||
DONE;
|
||||
}
|
||||
@ -493,7 +493,8 @@
|
||||
|| const_ok_for_arm (-INTVAL (operands[2])))"
|
||||
[(clobber (const_int 0))]
|
||||
"
|
||||
arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
|
||||
arm_split_constant (PLUS, SImode, curr_insn,
|
||||
INTVAL (operands[2]), operands[0],
|
||||
operands[1], 0);
|
||||
DONE;
|
||||
"
|
||||
@ -940,7 +941,8 @@
|
||||
{
|
||||
if (TARGET_ARM)
|
||||
{
|
||||
arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
|
||||
arm_split_constant (MINUS, SImode, NULL_RTX,
|
||||
INTVAL (operands[1]), operands[0],
|
||||
operands[2],
|
||||
(no_new_pseudos ? 0
|
||||
: preserve_subexpressions_p ()));
|
||||
@ -974,8 +976,8 @@
|
||||
&& !const_ok_for_arm (INTVAL (operands[1]))"
|
||||
[(clobber (const_int 0))]
|
||||
"
|
||||
arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
|
||||
operands[2], 0);
|
||||
arm_split_constant (MINUS, SImode, curr_insn,
|
||||
INTVAL (operands[1]), operands[0], operands[2], 0);
|
||||
DONE;
|
||||
"
|
||||
[(set_attr "length" "4,16")
|
||||
@ -1516,7 +1518,8 @@
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_INT)
|
||||
{
|
||||
arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
|
||||
arm_split_constant (AND, SImode, NULL_RTX,
|
||||
INTVAL (operands[2]), operands[0],
|
||||
operands[1],
|
||||
(no_new_pseudos
|
||||
? 0 : preserve_subexpressions_p ()));
|
||||
@ -1583,8 +1586,8 @@
|
||||
|| const_ok_for_arm (~INTVAL (operands[2])))"
|
||||
[(clobber (const_int 0))]
|
||||
"
|
||||
arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
|
||||
operands[1], 0);
|
||||
arm_split_constant (AND, SImode, curr_insn,
|
||||
INTVAL (operands[2]), operands[0], operands[1], 0);
|
||||
DONE;
|
||||
"
|
||||
[(set_attr "length" "4,4,16")
|
||||
@ -2069,8 +2072,8 @@
|
||||
{
|
||||
if (TARGET_ARM)
|
||||
{
|
||||
arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
|
||||
operands[1],
|
||||
arm_split_constant (IOR, SImode, NULL_RTX,
|
||||
INTVAL (operands[2]), operands[0], operands[1],
|
||||
(no_new_pseudos
|
||||
? 0 : preserve_subexpressions_p ()));
|
||||
DONE;
|
||||
@ -2094,8 +2097,8 @@
|
||||
&& !const_ok_for_arm (INTVAL (operands[2]))"
|
||||
[(clobber (const_int 0))]
|
||||
"
|
||||
arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
|
||||
operands[1], 0);
|
||||
arm_split_constant (IOR, SImode, curr_insn,
|
||||
INTVAL (operands[2]), operands[0], operands[1], 0);
|
||||
DONE;
|
||||
"
|
||||
[(set_attr "length" "4,16")
|
||||
@ -4146,8 +4149,8 @@
|
||||
&& !(const_ok_for_arm (INTVAL (operands[1]))
|
||||
|| const_ok_for_arm (~INTVAL (operands[1]))))
|
||||
{
|
||||
arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
|
||||
NULL_RTX,
|
||||
arm_split_constant (SET, SImode, NULL_RTX,
|
||||
INTVAL (operands[1]), operands[0], NULL_RTX,
|
||||
(no_new_pseudos ? 0
|
||||
: preserve_subexpressions_p ()));
|
||||
DONE;
|
||||
@ -4197,8 +4200,8 @@
|
||||
|| const_ok_for_arm (~INTVAL (operands[1]))))"
|
||||
[(clobber (const_int 0))]
|
||||
"
|
||||
arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
|
||||
NULL_RTX, 0);
|
||||
arm_split_constant (SET, SImode, NULL_RTX,
|
||||
INTVAL (operands[1]), operands[0], NULL_RTX, 0);
|
||||
DONE;
|
||||
"
|
||||
)
|
||||
|
@ -599,8 +599,9 @@ gen_split (rtx split)
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("extern rtx gen_split_%d (rtx *);\n", insn_code_number);
|
||||
printf ("rtx\ngen_%s_%d (rtx *operands%s)\n", name, insn_code_number, unused);
|
||||
printf ("extern rtx gen_split_%d (rtx, rtx *);\n", insn_code_number);
|
||||
printf ("rtx\ngen_split_%d (rtx curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
|
||||
insn_code_number, unused);
|
||||
}
|
||||
printf ("{\n");
|
||||
|
||||
|
@ -2086,7 +2086,7 @@ write_action (struct decision *p, struct decision_test *test,
|
||||
break;
|
||||
|
||||
case SPLIT:
|
||||
printf ("%sreturn gen_split_%d (operands);\n",
|
||||
printf ("%sreturn gen_split_%d (insn, operands);\n",
|
||||
indent, test->u.insn.code_number);
|
||||
break;
|
||||
|
||||
@ -2583,7 +2583,7 @@ make_insn_sequence (rtx insn, enum routine_type type)
|
||||
|
||||
case SPLIT:
|
||||
/* Define the subroutine we will call below and emit in genemit. */
|
||||
printf ("extern rtx gen_split_%d (rtx *);\n", next_insn_code);
|
||||
printf ("extern rtx gen_split_%d (rtx, rtx *);\n", next_insn_code);
|
||||
break;
|
||||
|
||||
case PEEPHOLE2:
|
||||
|
@ -58,6 +58,9 @@ struct queue_elem
|
||||
const char *filename;
|
||||
int lineno;
|
||||
struct queue_elem *next;
|
||||
/* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
|
||||
points to the generated DEFINE_SPLIT. */
|
||||
struct queue_elem *split;
|
||||
};
|
||||
|
||||
static struct queue_elem *define_attr_queue;
|
||||
@ -69,8 +72,8 @@ static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
|
||||
static struct queue_elem *other_queue;
|
||||
static struct queue_elem **other_tail = &other_queue;
|
||||
|
||||
static void queue_pattern (rtx, struct queue_elem ***,
|
||||
const char *, int);
|
||||
static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
|
||||
const char *, int);
|
||||
|
||||
/* Current maximum length of directory names in the search path
|
||||
for include files. (Altered as we get more of them.) */
|
||||
@ -134,9 +137,10 @@ gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
return rt;
|
||||
}
|
||||
|
||||
/* Queue PATTERN on LIST_TAIL. */
|
||||
/* Queue PATTERN on LIST_TAIL. Return the address of the new queue
|
||||
element. */
|
||||
|
||||
static void
|
||||
static struct queue_elem *
|
||||
queue_pattern (rtx pattern, struct queue_elem ***list_tail,
|
||||
const char *filename, int lineno)
|
||||
{
|
||||
@ -145,8 +149,10 @@ queue_pattern (rtx pattern, struct queue_elem ***list_tail,
|
||||
e->filename = filename;
|
||||
e->lineno = lineno;
|
||||
e->next = NULL;
|
||||
e->split = NULL;
|
||||
**list_tail = e;
|
||||
*list_tail = &e->next;
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Recursively remove constraints from an rtx. */
|
||||
@ -288,6 +294,8 @@ process_rtx (rtx desc, int lineno)
|
||||
rtx split;
|
||||
rtvec attr;
|
||||
int i;
|
||||
struct queue_elem *insn_elem;
|
||||
struct queue_elem *split_elem;
|
||||
|
||||
/* Create a split with values from the insn_and_split. */
|
||||
split = rtx_alloc (DEFINE_SPLIT);
|
||||
@ -315,8 +323,12 @@ process_rtx (rtx desc, int lineno)
|
||||
XVEC (desc, 4) = attr;
|
||||
|
||||
/* Queue them. */
|
||||
queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
|
||||
queue_pattern (split, &other_tail, read_rtx_filename, lineno);
|
||||
insn_elem
|
||||
= queue_pattern (desc, &define_insn_tail, read_rtx_filename,
|
||||
lineno);
|
||||
split_elem
|
||||
= queue_pattern (split, &other_tail, read_rtx_filename, lineno);
|
||||
insn_elem->split = split_elem;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -755,7 +767,8 @@ process_one_cond_exec (struct queue_elem *ce_elem)
|
||||
for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
|
||||
{
|
||||
int alternatives, max_operand;
|
||||
rtx pred, insn, pattern;
|
||||
rtx pred, insn, pattern, split;
|
||||
int i;
|
||||
|
||||
if (! is_predicable (insn_elem))
|
||||
continue;
|
||||
@ -818,6 +831,40 @@ process_one_cond_exec (struct queue_elem *ce_elem)
|
||||
|
||||
queue_pattern (insn, &other_tail, insn_elem->filename,
|
||||
insn_elem->lineno);
|
||||
|
||||
if (!insn_elem->split)
|
||||
continue;
|
||||
|
||||
/* If the original insn came from a define_insn_and_split,
|
||||
generate a new split to handle the predicated insn. */
|
||||
split = copy_rtx (insn_elem->split->data);
|
||||
/* Predicate the pattern matched by the split. */
|
||||
pattern = rtx_alloc (COND_EXEC);
|
||||
XEXP (pattern, 0) = pred;
|
||||
if (XVECLEN (split, 0) == 1)
|
||||
{
|
||||
XEXP (pattern, 1) = XVECEXP (split, 0, 0);
|
||||
XVECEXP (split, 0, 0) = pattern;
|
||||
PUT_NUM_ELEM (XVEC (split, 0), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
XEXP (pattern, 1) = rtx_alloc (PARALLEL);
|
||||
XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
|
||||
XVEC (split, 0) = rtvec_alloc (1);
|
||||
XVECEXP (split, 0, 0) = pattern;
|
||||
}
|
||||
/* Predicate all of the insns generated by the split. */
|
||||
for (i = 0; i < XVECLEN (split, 2); i++)
|
||||
{
|
||||
pattern = rtx_alloc (COND_EXEC);
|
||||
XEXP (pattern, 0) = pred;
|
||||
XEXP (pattern, 1) = XVECEXP (split, 2, i);
|
||||
XVECEXP (split, 2, i) = pattern;
|
||||
}
|
||||
/* Add the new split to the queue. */
|
||||
queue_pattern (split, &other_tail, read_rtx_filename,
|
||||
insn_elem->split->lineno);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user