diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2012-11-18 17:34:06 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2012-11-18 17:34:06 +0000 |
commit | d2eeb2d179a4353af0a8ff989222301c4f7dc11b (patch) | |
tree | 2d71577e02e248f2a39d8d852e69ab9ea07433d6 /gcc/config/mips | |
parent | fcdd52b73c0b23bffd5ce5ba591f994547333429 (diff) | |
download | gcc-d2eeb2d179a4353af0a8ff989222301c4f7dc11b.zip gcc-d2eeb2d179a4353af0a8ff989222301c4f7dc11b.tar.gz gcc-d2eeb2d179a4353af0a8ff989222301c4f7dc11b.tar.bz2 |
gcc/
* doc/md.texi (extv@var{m}, extvmisalign@var{m}, extzv@var{m})
(extzvmisalign@var{m}, insv@var{m}, insvmisalign@var{m}): Document.
(insv, extv, extzv): Deprecate.
* optabs.def (insv_optab, extv_optab, extzv_optab)
(insvmisalign_optab, extvmisalign_optab, extzvmisalign_optab):
New optabs.
* optabs.c (get_optab_extraction_insn): New function.
(get_extraction_insn): Use it.
* config/mips/mips.md (extv): Split into...
(extvmisalign<mode>, extv<mode>): ...these new patterns. Rename
existing extv<mode> pattern to...
(*extv<mode>): ...this.
(extzv): Split into...
(extzvmisalign<mode>, extzv<mode>): ...these new patterns. Rename
existing extzv<mode> pattern to...
(*extzv<mode>): ...this.
(insv): Split into...
(insvmisalign<mode>, insv<mode>): ...these new patterns. Rename
existing insv<mode> pattern to...
(*insv<mode>): ...this. Use const_int_operand rather than
immediate_operand.
* config/mips/mips.c (mips_block_move_straight): Use set_mem_size
to set the size of BLKmode accesses.
(mips_get_unaligned_mem): Require OP0 to be a BLKmode memory,
turning it from an "rtx *" to an rtx.
(mips_expand_ext_as_unaligned_load): Simplify for new optab
interface. Update call to mips_get_unaligned_mem.
(mips_expand_ins_as_unaligned_store): Update call to
mips_get_unaligned_mem.
From-SVN: r193606
Diffstat (limited to 'gcc/config/mips')
-rw-r--r-- | gcc/config/mips/mips.c | 48 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 115 |
2 files changed, 69 insertions, 94 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 78c5a88..b6a2290 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -7096,6 +7096,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length) else { rtx part = adjust_address (src, BLKmode, offset); + set_mem_size (part, delta); if (!mips_expand_ext_as_unaligned_load (regs[i], part, bits, 0, 0)) gcc_unreachable (); } @@ -7108,6 +7109,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length) else { rtx part = adjust_address (dest, BLKmode, offset); + set_mem_size (part, delta); if (!mips_expand_ins_as_unaligned_store (part, regs[i], bits, 0)) gcc_unreachable (); } @@ -7359,10 +7361,8 @@ mips_expand_atomic_qihi (union mips_gen_fn_ptrs generator, } /* Return true if it is possible to use left/right accesses for a - bitfield of WIDTH bits starting BITPOS bits into *OP. When - returning true, update *OP, *LEFT and *RIGHT as follows: - - *OP is a BLKmode reference to the whole field. + bitfield of WIDTH bits starting BITPOS bits into BLKmode memory OP. + When returning true, update *LEFT and *RIGHT as follows: *LEFT is a QImode reference to the first byte if big endian or the last byte if little endian. This address can be used in the @@ -7372,16 +7372,11 @@ mips_expand_atomic_qihi (union mips_gen_fn_ptrs generator, can be used in the patterning right-side instruction. */ static bool -mips_get_unaligned_mem (rtx *op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos, +mips_get_unaligned_mem (rtx op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos, rtx *left, rtx *right) { rtx first, last; - /* Check that the operand really is a MEM. Not all the extv and - extzv predicates are checked. */ - if (!MEM_P (*op)) - return false; - /* Check that the size is valid. */ if (width != 32 && (!TARGET_64BIT || width != 64)) return false; @@ -7394,20 +7389,12 @@ mips_get_unaligned_mem (rtx *op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos, /* Reject aligned bitfields: we want to use a normal load or store instead of a left/right pair. */ - if (MEM_ALIGN (*op) >= width) + if (MEM_ALIGN (op) >= width) return false; - /* Create a copy of *OP that refers to the whole field. This also has - the effect of legitimizing *OP's address for BLKmode, possibly - simplifying it. */ - *op = copy_rtx (adjust_address (*op, BLKmode, 0)); - set_mem_size (*op, width / BITS_PER_UNIT); - - /* Get references to both ends of the field. We deliberately don't - use the original QImode *OP for FIRST since the new BLKmode one - might have a simpler address. */ - first = adjust_address (*op, QImode, 0); - last = adjust_address (*op, QImode, width / BITS_PER_UNIT - 1); + /* Get references to both ends of the field. */ + first = adjust_address (op, QImode, 0); + last = adjust_address (op, QImode, width / BITS_PER_UNIT - 1); /* Allocate to LEFT and RIGHT according to endianness. LEFT should correspond to the MSB and RIGHT to the LSB. */ @@ -7435,14 +7422,6 @@ mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width, rtx dest1 = NULL_RTX; /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will - be a paradoxical word_mode subreg. This is the only case in which - we allow the destination to be larger than the source. */ - if (GET_CODE (dest) == SUBREG - && GET_MODE (dest) == DImode - && GET_MODE (SUBREG_REG (dest)) == SImode) - dest = SUBREG_REG (dest); - - /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will be a DImode, create a new temp and emit a zero extend at the end. */ if (GET_MODE (dest) == DImode && REG_P (dest) @@ -7452,12 +7431,7 @@ mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width, dest = gen_reg_rtx (SImode); } - /* After the above adjustment, the destination must be the same - width as the source. */ - if (GET_MODE_BITSIZE (GET_MODE (dest)) != width) - return false; - - if (!mips_get_unaligned_mem (&src, width, bitpos, &left, &right)) + if (!mips_get_unaligned_mem (src, width, bitpos, &left, &right)) return false; temp = gen_reg_rtx (GET_MODE (dest)); @@ -7499,7 +7473,7 @@ mips_expand_ins_as_unaligned_store (rtx dest, rtx src, HOST_WIDE_INT width, rtx left, right; enum machine_mode mode; - if (!mips_get_unaligned_mem (&dest, width, bitpos, &left, &right)) + if (!mips_get_unaligned_mem (dest, width, bitpos, &left, &right)) return false; mode = mode_for_size (width, MODE_INT, 0); diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index f6a1312..a3aa922 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -3777,11 +3777,11 @@ ;; Bit field extract patterns which use lwl/lwr or ldl/ldr. -(define_expand "extv" - [(set (match_operand 0 "register_operand") - (sign_extract (match_operand 1 "nonimmediate_operand") - (match_operand 2 "const_int_operand") - (match_operand 3 "const_int_operand")))] +(define_expand "extvmisalign<mode>" + [(set (match_operand:GPR 0 "register_operand") + (sign_extract:GPR (match_operand:BLK 1 "memory_operand") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] "!TARGET_MIPS16" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], @@ -3789,22 +3789,22 @@ INTVAL (operands[3]), /*unsigned=*/ false)) DONE; - else if (register_operand (operands[1], GET_MODE (operands[0])) - && ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32) - { - if (GET_MODE (operands[0]) == DImode) - emit_insn (gen_extvdi (operands[0], operands[1], operands[2], - operands[3])); - else - emit_insn (gen_extvsi (operands[0], operands[1], operands[2], - operands[3])); - DONE; - } else FAIL; }) -(define_insn "extv<mode>" +(define_expand "extv<mode>" + [(set (match_operand:GPR 0 "register_operand") + (sign_extract:GPR (match_operand:GPR 1 "register_operand") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "ISA_HAS_EXTS" +{ + if (UINTVAL (operands[2]) > 32) + FAIL; +}) + +(define_insn "*extv<mode>" [(set (match_operand:GPR 0 "register_operand" "=d") (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d") (match_operand 2 "const_int_operand" "") @@ -3814,35 +3814,35 @@ [(set_attr "type" "arith") (set_attr "mode" "<MODE>")]) - -(define_expand "extzv" - [(set (match_operand 0 "register_operand") - (zero_extract (match_operand 1 "nonimmediate_operand") - (match_operand 2 "const_int_operand") - (match_operand 3 "const_int_operand")))] +(define_expand "extzvmisalign<mode>" + [(set (match_operand:GPR 0 "register_operand") + (zero_extract:GPR (match_operand:BLK 1 "memory_operand") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] "!TARGET_MIPS16" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), INTVAL (operands[3]), - /*unsigned=*/true)) + /*unsigned=*/ true)) DONE; - else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), - INTVAL (operands[3]))) - { - if (GET_MODE (operands[0]) == DImode) - emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], - operands[3])); - else - emit_insn (gen_extzvsi (operands[0], operands[1], operands[2], - operands[3])); - DONE; - } else FAIL; }) -(define_insn "extzv<mode>" +(define_expand "extzv<mode>" + [(set (match_operand:GPR 0 "register_operand") + (zero_extract:GPR (match_operand:GPR 1 "register_operand") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "" +{ + if (!mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), + INTVAL (operands[3]))) + FAIL; +}) + +(define_insn "*extzv<mode>" [(set (match_operand:GPR 0 "register_operand" "=d") (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") (match_operand 2 "const_int_operand" "") @@ -3865,36 +3865,37 @@ (set_attr "mode" "SI")]) -(define_expand "insv" - [(set (zero_extract (match_operand 0 "nonimmediate_operand") - (match_operand 1 "immediate_operand") - (match_operand 2 "immediate_operand")) - (match_operand 3 "reg_or_0_operand"))] +(define_expand "insvmisalign<mode>" + [(set (zero_extract:GPR (match_operand:BLK 0 "memory_operand") + (match_operand 1 "const_int_operand") + (match_operand 2 "const_int_operand")) + (match_operand:GPR 3 "reg_or_0_operand"))] "!TARGET_MIPS16" { if (mips_expand_ins_as_unaligned_store (operands[0], operands[3], INTVAL (operands[1]), INTVAL (operands[2]))) DONE; - else if (mips_use_ins_ext_p (operands[0], INTVAL (operands[1]), - INTVAL (operands[2]))) - { - if (GET_MODE (operands[0]) == DImode) - emit_insn (gen_insvdi (operands[0], operands[1], operands[2], - operands[3])); - else - emit_insn (gen_insvsi (operands[0], operands[1], operands[2], - operands[3])); - DONE; - } - else - FAIL; + else + FAIL; +}) + +(define_expand "insv<mode>" + [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand") + (match_operand 1 "const_int_operand") + (match_operand 2 "const_int_operand")) + (match_operand:GPR 3 "reg_or_0_operand"))] + "" +{ + if (!mips_use_ins_ext_p (operands[0], INTVAL (operands[1]), + INTVAL (operands[2]))) + FAIL; }) -(define_insn "insv<mode>" +(define_insn "*insv<mode>" [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d") - (match_operand:SI 1 "immediate_operand" "I") - (match_operand:SI 2 "immediate_operand" "I")) + (match_operand:SI 1 "const_int_operand" "") + (match_operand:SI 2 "const_int_operand" "")) (match_operand:GPR 3 "reg_or_0_operand" "dJ"))] "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]), INTVAL (operands[2]))" |