Commit a1747d2c by Torbjorn Granlund

(move_operand): Allow all CONST_INTs that can be moved to general registers with one insn.

(move_operand): Allow all CONST_INTs that can be moved to
general registers with one insn.
(pre_cint_operand): New predicate for predecrementing ldwm/stwm insns.
(zdepi_cint_p): New function.
(depi_cint_operand): Remove.
(and_mask_p): New name for consec_zeros_p.  All callers changed.
(srcsi_operand): Removed.
(all file): Use INT_14_BITS instead of synonym SMALL_INT.
(emit_move_sequence): Clean up CONST_INT case.
(compute_zdepi_operands): New name for
compute_xdepi_operands_from_integer.  Change second parm to return
plain integers (was RTXes).
(print_operand): Handle 'Z' for 'zdepi' source used to movCONST_INT.

From-SVN: r3238
parent 8d2f4374
...@@ -134,8 +134,12 @@ move_operand (op, mode) ...@@ -134,8 +134,12 @@ move_operand (op, mode)
if (register_operand (op, mode)) if (register_operand (op, mode))
return 1; return 1;
if (op == CONST0_RTX (mode)) if (GET_CODE (op) == CONST_INT)
return 1; {
/* OK if ldo, ldil, or zdepi, can be used. */
return (INT_14_BITS (op) || (INTVAL (op) & 0x7ff) == 0
|| zdepi_cint_p (INTVAL (op)));
}
if (GET_MODE (op) != mode) if (GET_MODE (op) != mode)
return 0; return 0;
...@@ -280,6 +284,15 @@ arith11_operand (op, mode) ...@@ -280,6 +284,15 @@ arith11_operand (op, mode)
} }
int int
pre_cint_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return (GET_CODE (op) == CONST_INT
&& INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
}
int
arith_double_operand (op, mode) arith_double_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
...@@ -330,27 +343,22 @@ arith5_operand (op, mode) ...@@ -330,27 +343,22 @@ arith5_operand (op, mode)
/* True iff zdepi can be used to generate this CONST_INT. */ /* True iff zdepi can be used to generate this CONST_INT. */
int int
depi_cint_operand (op, mode) zdepi_cint_p (x)
rtx op; unsigned x;
enum machine_mode mode;
{ {
unsigned x; unsigned lsb_mask, t;
unsigned lbmask, t;
if (GET_CODE (op) != CONST_INT)
return 0;
/* This might not be obvious, but it's at least fast. /* This might not be obvious, but it's at least fast.
This function is critcal; we don't have the time loops would take. */ This function is critcal; we don't have the time loops would take. */
x = INTVAL (op); lsb_mask = x & -x;
lbmask = x & -x; t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);
t = ((x >> 4) + lbmask) & ~(lbmask - 1); /* Return true iff t is a power of two. */
return ((t & (t - 1)) == 0); return ((t & (t - 1)) == 0);
} }
/* True iff depi or extru can be used to compute (reg & mask). */ /* True iff depi or extru can be used to compute (reg & mask). */
int int
consec_zeros_p (mask) and_mask_p (mask)
unsigned mask; unsigned mask;
{ {
mask = ~mask; mask = ~mask;
...@@ -365,7 +373,7 @@ and_operand (op, mode) ...@@ -365,7 +373,7 @@ and_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
return (register_operand (op, mode) return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && consec_zeros_p (INTVAL (op)))); || (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
} }
/* True iff depi can be used to compute (reg | MASK). */ /* True iff depi can be used to compute (reg | MASK). */
...@@ -394,29 +402,6 @@ arith32_operand (op, mode) ...@@ -394,29 +402,6 @@ arith32_operand (op, mode)
{ {
return register_operand (op, mode) || GET_CODE (op) == CONST_INT; return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
} }
/* True iff OP can be the source of a move to a general register. */
int
srcsi_operand (op, mode)
rtx op;
enum machine_mode mode;
{
/* Not intended for other modes than SImode. */
if (mode != SImode)
return 0;
/* Accept any register or memory reference. */
if (nonimmediate_operand (op, mode))
return 1;
if (depi_cint_operand (op, mode))
return 1;
/* OK if ldo or ldil can be used. */
return (GET_CODE (op) == CONST_INT
&& (INT_14_BITS (op) || (INTVAL (op) & 0x7ff) == 0));
}
/* Legitimize PIC addresses. If the address is already /* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated position-independent, we return ORIG. Newly generated
...@@ -471,7 +456,7 @@ legitimize_pic_address (orig, mode, reg) ...@@ -471,7 +456,7 @@ legitimize_pic_address (orig, mode, reg)
else abort (); else abort ();
if (GET_CODE (orig) == CONST_INT) if (GET_CODE (orig) == CONST_INT)
{ {
if (SMALL_INT (orig)) if (INT_14_BITS (orig))
return plus_constant_for_output (base, INTVAL (orig)); return plus_constant_for_output (base, INTVAL (orig));
orig = force_reg (Pmode, orig); orig = force_reg (Pmode, orig);
} }
...@@ -567,7 +552,7 @@ emit_move_sequence (operands, mode, scratch_reg) ...@@ -567,7 +552,7 @@ emit_move_sequence (operands, mode, scratch_reg)
else if (register_operand (operand0, mode)) else if (register_operand (operand0, mode))
{ {
if (register_operand (operand1, mode) if (register_operand (operand1, mode)
|| (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1)) || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
|| (GET_CODE (operand1) == HIGH || (GET_CODE (operand1) == HIGH
&& !symbolic_operand (XEXP (operand1, 0))) && !symbolic_operand (XEXP (operand1, 0)))
/* Only `general_operands' can come here, so MEM is ok. */ /* Only `general_operands' can come here, so MEM is ok. */
...@@ -654,11 +639,10 @@ emit_move_sequence (operands, mode, scratch_reg) ...@@ -654,11 +639,10 @@ emit_move_sequence (operands, mode, scratch_reg)
} }
return 1; return 1;
} }
else if (depi_cint_operand (operand1, VOIDmode)) else if (GET_CODE (operand1) != CONST_INT
return 0; || (! INT_14_BITS (operand1)
else if (GET_CODE (operand1) == CONST_INT && ! ((INTVAL (operand1) & 0x7ff) == 0)
? (! SMALL_INT (operand1) && !zdepi_cint_p (INTVAL (operand1))))
&& (INTVAL (operand1) & 0x7ff) != 0) : 1)
{ {
rtx temp = reload_in_progress ? operand0 : gen_reg_rtx (mode); rtx temp = reload_in_progress ? operand0 : gen_reg_rtx (mode);
emit_insn (gen_rtx (SET, VOIDmode, temp, emit_insn (gen_rtx (SET, VOIDmode, temp,
...@@ -705,13 +689,13 @@ singlemove_string (operands) ...@@ -705,13 +689,13 @@ singlemove_string (operands)
} }
/* Compute position (in OPERANDS[2]) and width (in OPERANDS[3]) /* Compute position (in OP[2]) and width (in OP[3])
useful for copying or or'ing IMM to a register using bit field useful for copying or or'ing IMM to a register using bit field
instructions. Store the immediate value to insert in OPERANDS[1]. */ instructions. Store the immediate value to insert in OP[1]. */
void void
compute_xdepi_operands_from_integer (imm, operands) compute_zdepi_operands (imm, op)
unsigned imm; unsigned imm;
rtx *operands; unsigned *op;
{ {
int lsb, len; int lsb, len;
...@@ -739,9 +723,9 @@ compute_xdepi_operands_from_integer (imm, operands) ...@@ -739,9 +723,9 @@ compute_xdepi_operands_from_integer (imm, operands)
imm = (imm & 0xf) - 0x10; imm = (imm & 0xf) - 0x10;
} }
operands[1] = gen_rtx (CONST_INT, VOIDmode, imm); op[0] = imm;
operands[2] = gen_rtx (CONST_INT, VOIDmode, 31 - lsb); op[1] = 31 - lsb;
operands[3] = gen_rtx (CONST_INT, VOIDmode, len); op[2] = len;
} }
/* Output assembler code to perform a doubleword move insn /* Output assembler code to perform a doubleword move insn
...@@ -2028,6 +2012,13 @@ print_operand (file, x, code) ...@@ -2028,6 +2012,13 @@ print_operand (file, x, code)
return; return;
case 0: /* Don't do anything special */ case 0: /* Don't do anything special */
break; break;
case 'Z':
{
unsigned op[3];
compute_zdepi_operands (INTVAL (x), op);
fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
return;
}
default: default:
abort (); abort ();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment