diff options
author | Richard Sandiford <richard@codesourcery.com> | 2007-09-11 09:51:17 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-09-11 09:51:17 +0000 |
commit | 206c2d7add4a9bc3955e455bbe2c23a90422fcf8 (patch) | |
tree | 3c5276c1b094c85b929083de7f24493b91d6b978 /gcc | |
parent | 8144a1a8120beac962f0dfa6dc76dbd00b407aad (diff) | |
download | gcc-206c2d7add4a9bc3955e455bbe2c23a90422fcf8.zip gcc-206c2d7add4a9bc3955e455bbe2c23a90422fcf8.tar.gz gcc-206c2d7add4a9bc3955e455bbe2c23a90422fcf8.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/config/mips/constraints.md | 4 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 64 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 14 | ||||
-rw-r--r-- | gcc/config/mips/predicates.md | 8 |
5 files changed, 89 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5523d0..470e254 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,20 @@ 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> Nigel Stephens <nigel@mips.com> David Ung <davidu@mips.com> diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index 47b3966..98e8d6f 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -82,6 +82,10 @@ ;; but the DSPr2 version allows any accumulator target. (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 ;; never use the stack pointer as a reload register. (define_constraint "ks" diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 34c4420..0e69827 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1908,6 +1908,11 @@ mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode) return 0; 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. */ return 0; @@ -3140,6 +3145,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total) case SYMBOL_REF: case LABEL_REF: case CONST_DOUBLE: + if (force_to_mem_operand (x, VOIDmode)) + { + *total = COSTS_N_INSNS (1); + return true; + } cost = mips_const_insns (x); if (cost > 0) { @@ -10099,20 +10109,14 @@ mips16_insn_length (rtx insn) return get_attr_length (insn); } -/* Rewrite *X so that constant pool references refer to the constant's - label instead. DATA points to the constant pool structure. */ +/* If *X is a symbolic constant that refers to the constant pool, add + the constant to POOL and rewrite *X to use the constant's label. */ -static int -mips16_rewrite_pool_refs (rtx *x, void *data) +static void +mips16_rewrite_pool_constant (struct mips16_constant_pool *pool, rtx *x) { - struct mips16_constant_pool *pool = data; 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); 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)); base = gen_rtx_LABEL_REF (Pmode, label); *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; } + + if (TARGET_MIPS16_TEXT_LOADS) + mips16_rewrite_pool_constant (info->pool, x); + return GET_CODE (*x) == CONST ? -1 : 0; } @@ -10131,6 +10168,7 @@ static void mips16_lay_out_constants (void) { struct mips16_constant_pool pool; + struct mips16_rewrite_pool_refs_info info; rtx insn, barrier; if (!TARGET_MIPS16_PCREL_LOADS) @@ -10142,7 +10180,11 @@ mips16_lay_out_constants (void) { /* Rewrite constant pool references in 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); diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index a6a5ea4..c1cffb1 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -3428,13 +3428,13 @@ (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")]) (define_insn "*movdi_64bit_mips16" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m") - (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))] + [(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,kf,U,m,d"))] "TARGET_64BIT && TARGET_MIPS16 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" { 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_alternative "length" [(const_int 4) @@ -3446,6 +3446,7 @@ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") (const_int 8) (const_int 12)) + (const_int 8) (const_string "*") (const_string "*") (const_string "*")])]) @@ -3524,13 +3525,13 @@ (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")]) (define_insn "*movsi_mips16" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m") - (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))] + [(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,kf,U,m,d"))] "TARGET_MIPS16 && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" { 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_alternative "length" [(const_int 4) @@ -3542,6 +3543,7 @@ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") (const_int 8) (const_int 12)) + (const_int 8) (const_string "*") (const_string "*") (const_string "*")])]) diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md index e275283..6c533e5 100644 --- a/gcc/config/mips/predicates.md +++ b/gcc/config/mips/predicates.md @@ -227,6 +227,14 @@ && 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" (match_code "const,symbol_ref,label_ref") { |