mips.c (mips_symbol_insns_1): Allow LEAs of SYMBOL_FORCE_TO_MEM constants.
gcc/ * config/mips/mips.c (mips_symbol_insns_1): Allow LEAs of SYMBOL_FORCE_TO_MEM constants. (mips_rtx_costs): Give a cost of 1 to force_to_mem_operands. (mips16_rewrite_pool_refs_info): New structure. (mips16_rewrite_pool_constant): New function, split out from... (mips16_rewrite_pool_refs): ...here. Take a pointer to a mips16_rewrite_pool_refs_info structure rather than a pointer to a constant pool. Force force_to_mem_operands into memory. (mips16_lay_out_constants): Update call to mips16_rewrite_pool_refs. * config/mips/predicates.md (force_to_mem_operand): New predicate. * config/mips/constraints.md (kf): New constraint. * config/mips/mips.md (*movdi_64bit_mips16): Add a d <- kf alternative. (*movsi_mips16): Likewise. From-SVN: r128365
This commit is contained in:
parent
8144a1a812
commit
206c2d7add
@ -1,3 +1,19 @@
|
|||||||
|
2007-09-11 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
|
* config/mips/mips.c (mips_symbol_insns_1): Allow LEAs of
|
||||||
|
SYMBOL_FORCE_TO_MEM constants.
|
||||||
|
(mips_rtx_costs): Give a cost of 1 to force_to_mem_operands.
|
||||||
|
(mips16_rewrite_pool_refs_info): New structure.
|
||||||
|
(mips16_rewrite_pool_constant): New function, split out from...
|
||||||
|
(mips16_rewrite_pool_refs): ...here. Take a pointer to a
|
||||||
|
mips16_rewrite_pool_refs_info structure rather than a pointer
|
||||||
|
to a constant pool. Force force_to_mem_operands into memory.
|
||||||
|
(mips16_lay_out_constants): Update call to mips16_rewrite_pool_refs.
|
||||||
|
* config/mips/predicates.md (force_to_mem_operand): New predicate.
|
||||||
|
* config/mips/constraints.md (kf): New constraint.
|
||||||
|
* config/mips/mips.md (*movdi_64bit_mips16): Add a d <- kf alternative.
|
||||||
|
(*movsi_mips16): Likewise.
|
||||||
|
|
||||||
2007-09-11 Richard Sandiford <richard@codesourcery.com>
|
2007-09-11 Richard Sandiford <richard@codesourcery.com>
|
||||||
Nigel Stephens <nigel@mips.com>
|
Nigel Stephens <nigel@mips.com>
|
||||||
David Ung <davidu@mips.com>
|
David Ung <davidu@mips.com>
|
||||||
|
@ -82,6 +82,10 @@
|
|||||||
;; but the DSPr2 version allows any accumulator target.
|
;; but the DSPr2 version allows any accumulator target.
|
||||||
(define_register_constraint "ka" "TARGET_DSPR2 ? ACC_REGS : MD_REGS")
|
(define_register_constraint "ka" "TARGET_DSPR2 ? ACC_REGS : MD_REGS")
|
||||||
|
|
||||||
|
(define_constraint "kf"
|
||||||
|
"@internal"
|
||||||
|
(match_operand 0 "force_to_mem_operand"))
|
||||||
|
|
||||||
;; This is a normal rather than a register constraint because we can
|
;; This is a normal rather than a register constraint because we can
|
||||||
;; never use the stack pointer as a reload register.
|
;; never use the stack pointer as a reload register.
|
||||||
(define_constraint "ks"
|
(define_constraint "ks"
|
||||||
|
@ -1908,6 +1908,11 @@ mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SYMBOL_FORCE_TO_MEM:
|
case SYMBOL_FORCE_TO_MEM:
|
||||||
|
/* LEAs will be converted into constant-pool references by
|
||||||
|
mips_reorg. */
|
||||||
|
if (mode == MAX_MACHINE_MODE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* The constant must be loaded from the constant pool. */
|
/* The constant must be loaded from the constant pool. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -3140,6 +3145,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
|
|||||||
case SYMBOL_REF:
|
case SYMBOL_REF:
|
||||||
case LABEL_REF:
|
case LABEL_REF:
|
||||||
case CONST_DOUBLE:
|
case CONST_DOUBLE:
|
||||||
|
if (force_to_mem_operand (x, VOIDmode))
|
||||||
|
{
|
||||||
|
*total = COSTS_N_INSNS (1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
cost = mips_const_insns (x);
|
cost = mips_const_insns (x);
|
||||||
if (cost > 0)
|
if (cost > 0)
|
||||||
{
|
{
|
||||||
@ -10099,20 +10109,14 @@ mips16_insn_length (rtx insn)
|
|||||||
return get_attr_length (insn);
|
return get_attr_length (insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rewrite *X so that constant pool references refer to the constant's
|
/* If *X is a symbolic constant that refers to the constant pool, add
|
||||||
label instead. DATA points to the constant pool structure. */
|
the constant to POOL and rewrite *X to use the constant's label. */
|
||||||
|
|
||||||
static int
|
static void
|
||||||
mips16_rewrite_pool_refs (rtx *x, void *data)
|
mips16_rewrite_pool_constant (struct mips16_constant_pool *pool, rtx *x)
|
||||||
{
|
{
|
||||||
struct mips16_constant_pool *pool = data;
|
|
||||||
rtx base, offset, label;
|
rtx base, offset, label;
|
||||||
|
|
||||||
if (MEM_P (*x))
|
|
||||||
x = &XEXP (*x, 0);
|
|
||||||
else if (!TARGET_MIPS16_TEXT_LOADS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
split_const (*x, &base, &offset);
|
split_const (*x, &base, &offset);
|
||||||
if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
|
if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
|
||||||
{
|
{
|
||||||
@ -10120,8 +10124,41 @@ mips16_rewrite_pool_refs (rtx *x, void *data)
|
|||||||
get_pool_mode (base));
|
get_pool_mode (base));
|
||||||
base = gen_rtx_LABEL_REF (Pmode, label);
|
base = gen_rtx_LABEL_REF (Pmode, label);
|
||||||
*x = mips_unspec_address_offset (base, offset, SYMBOL_PC_RELATIVE);
|
*x = mips_unspec_address_offset (base, offset, SYMBOL_PC_RELATIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This structure is used to communicate with mips16_rewrite_pool_refs.
|
||||||
|
INSN is the instruction we're rewriting and POOL points to the current
|
||||||
|
constant pool. */
|
||||||
|
struct mips16_rewrite_pool_refs_info {
|
||||||
|
rtx insn;
|
||||||
|
struct mips16_constant_pool *pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Rewrite *X so that constant pool references refer to the constant's
|
||||||
|
label instead. DATA points to a mips16_rewrite_pool_refs_info
|
||||||
|
structure. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
mips16_rewrite_pool_refs (rtx *x, void *data)
|
||||||
|
{
|
||||||
|
struct mips16_rewrite_pool_refs_info *info = data;
|
||||||
|
|
||||||
|
if (force_to_mem_operand (*x, Pmode))
|
||||||
|
{
|
||||||
|
rtx mem = force_const_mem (GET_MODE (*x), *x);
|
||||||
|
validate_change (info->insn, x, mem, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MEM_P (*x))
|
||||||
|
{
|
||||||
|
mips16_rewrite_pool_constant (info->pool, &XEXP (*x, 0));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TARGET_MIPS16_TEXT_LOADS)
|
||||||
|
mips16_rewrite_pool_constant (info->pool, x);
|
||||||
|
|
||||||
return GET_CODE (*x) == CONST ? -1 : 0;
|
return GET_CODE (*x) == CONST ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10131,6 +10168,7 @@ static void
|
|||||||
mips16_lay_out_constants (void)
|
mips16_lay_out_constants (void)
|
||||||
{
|
{
|
||||||
struct mips16_constant_pool pool;
|
struct mips16_constant_pool pool;
|
||||||
|
struct mips16_rewrite_pool_refs_info info;
|
||||||
rtx insn, barrier;
|
rtx insn, barrier;
|
||||||
|
|
||||||
if (!TARGET_MIPS16_PCREL_LOADS)
|
if (!TARGET_MIPS16_PCREL_LOADS)
|
||||||
@ -10142,7 +10180,11 @@ mips16_lay_out_constants (void)
|
|||||||
{
|
{
|
||||||
/* Rewrite constant pool references in INSN. */
|
/* Rewrite constant pool references in INSN. */
|
||||||
if (INSN_P (insn))
|
if (INSN_P (insn))
|
||||||
for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &pool);
|
{
|
||||||
|
info.insn = insn;
|
||||||
|
info.pool = &pool;
|
||||||
|
for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &info);
|
||||||
|
}
|
||||||
|
|
||||||
pool.insn_address += mips16_insn_length (insn);
|
pool.insn_address += mips16_insn_length (insn);
|
||||||
|
|
||||||
|
@ -3428,13 +3428,13 @@
|
|||||||
(set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
|
(set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
|
||||||
|
|
||||||
(define_insn "*movdi_64bit_mips16"
|
(define_insn "*movdi_64bit_mips16"
|
||||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m")
|
||||||
(match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
|
(match_operand:DI 1 "move_operand" "d,d,y,K,N,kf,U,m,d"))]
|
||||||
"TARGET_64BIT && TARGET_MIPS16
|
"TARGET_64BIT && TARGET_MIPS16
|
||||||
&& (register_operand (operands[0], DImode)
|
&& (register_operand (operands[0], DImode)
|
||||||
|| register_operand (operands[1], DImode))"
|
|| register_operand (operands[1], DImode))"
|
||||||
{ return mips_output_move (operands[0], operands[1]); }
|
{ return mips_output_move (operands[0], operands[1]); }
|
||||||
[(set_attr "type" "move,move,move,arith,arith,const,load,store")
|
[(set_attr "type" "move,move,move,arith,arith,load,const,load,store")
|
||||||
(set_attr "mode" "DI")
|
(set_attr "mode" "DI")
|
||||||
(set_attr_alternative "length"
|
(set_attr_alternative "length"
|
||||||
[(const_int 4)
|
[(const_int 4)
|
||||||
@ -3446,6 +3446,7 @@
|
|||||||
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
|
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
|
||||||
(const_int 8)
|
(const_int 8)
|
||||||
(const_int 12))
|
(const_int 12))
|
||||||
|
(const_int 8)
|
||||||
(const_string "*")
|
(const_string "*")
|
||||||
(const_string "*")
|
(const_string "*")
|
||||||
(const_string "*")])])
|
(const_string "*")])])
|
||||||
@ -3524,13 +3525,13 @@
|
|||||||
(set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
|
(set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
|
||||||
|
|
||||||
(define_insn "*movsi_mips16"
|
(define_insn "*movsi_mips16"
|
||||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
|
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m")
|
||||||
(match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
|
(match_operand:SI 1 "move_operand" "d,d,y,K,N,kf,U,m,d"))]
|
||||||
"TARGET_MIPS16
|
"TARGET_MIPS16
|
||||||
&& (register_operand (operands[0], SImode)
|
&& (register_operand (operands[0], SImode)
|
||||||
|| register_operand (operands[1], SImode))"
|
|| register_operand (operands[1], SImode))"
|
||||||
{ return mips_output_move (operands[0], operands[1]); }
|
{ return mips_output_move (operands[0], operands[1]); }
|
||||||
[(set_attr "type" "move,move,move,arith,arith,const,load,store")
|
[(set_attr "type" "move,move,move,arith,arith,load,const,load,store")
|
||||||
(set_attr "mode" "SI")
|
(set_attr "mode" "SI")
|
||||||
(set_attr_alternative "length"
|
(set_attr_alternative "length"
|
||||||
[(const_int 4)
|
[(const_int 4)
|
||||||
@ -3542,6 +3543,7 @@
|
|||||||
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
|
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
|
||||||
(const_int 8)
|
(const_int 8)
|
||||||
(const_int 12))
|
(const_int 12))
|
||||||
|
(const_int 8)
|
||||||
(const_string "*")
|
(const_string "*")
|
||||||
(const_string "*")
|
(const_string "*")
|
||||||
(const_string "*")])])
|
(const_string "*")])])
|
||||||
|
@ -227,6 +227,14 @@
|
|||||||
&& type == SYMBOL_ABSOLUTE);
|
&& type == SYMBOL_ABSOLUTE);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
(define_predicate "force_to_mem_operand"
|
||||||
|
(match_code "const,symbol_ref,label_ref")
|
||||||
|
{
|
||||||
|
enum mips_symbol_type symbol_type;
|
||||||
|
return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
|
||||||
|
&& symbol_type == SYMBOL_FORCE_TO_MEM);
|
||||||
|
})
|
||||||
|
|
||||||
(define_predicate "got_disp_operand"
|
(define_predicate "got_disp_operand"
|
||||||
(match_code "const,symbol_ref,label_ref")
|
(match_code "const,symbol_ref,label_ref")
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user