diff options
author | davidu <davidu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-26 17:23:35 +0000 |
---|---|---|
committer | davidu <davidu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-26 17:23:35 +0000 |
commit | 483650218bc49133ba69faad6fc5931d2636a594 (patch) | |
tree | 2c115cbf4d0642b7f753a9bb5f736eecd964d555 | |
parent | 137c809d703b05dadd418e90b9f0a0dae7a664d0 (diff) | |
download | gcc-483650218bc49133ba69faad6fc5931d2636a594.tar.gz |
* gcc.target/mips/ext_ins.c: New test for testing the generation
of MIPS32/64 rev 2 ext/ins instructions.
* config/mips/mips.c (mips_use_ins_ext_p): New helper function
that determines whether the MIPS32/64 R2 ext/ins should be used.
* config/mips/mips.h (ISA_HAS_EXT_INS): New macro.
* config/mips/mips.md (extzv): Changed predicate for operand to
nonimmediate_operand. Add code to generate insn patterns for
extzvsi and extzvdi.
(extzv<mode>): New pattern to match mips32/64 r2 ext insn.
(insv): Similarly for insertion.
(insv<mode>): Similarly.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100212 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 34 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 5 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 49 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/ext_ins.c | 26 |
6 files changed, 126 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ffd7b7f0bed..696cd17f6c5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2005-05-26 David Ung <davidu@mips.com> + + * config/mips/mips.c (mips_use_ins_ext_p): New helper function + that determines whether the MIPS32/64 R2 ext/ins should be used. + * config/mips/mips.h (ISA_HAS_EXT_INS): New macro. + * config/mips/mips.md (extzv): Changed predicate for operand to + nonimmediate_operand. Add code to generate insn patterns for + extzvsi and extzvdi. + (extzv<mode>): New pattern to match mips32/64 r2 ext insn. + (insv): Similarly for insertion. + (insv<mode>): Similarly. + 2005-05-26 Paolo Bonzini <bonzini@gnu.org> * simplify-rtx.c (avoid_constant_pool_reference): Support diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 9ddcf4d72a0..76f681fb86a 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4158,7 +4158,39 @@ mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos) } return true; } - + +/* Return true if (zero_extract OP SIZE POSITION) can be used as the + source of an "ext" instruction or the destination of an "ins" + instruction. OP must be a register operand and the following + conditions must hold: + + 0 <= POSITION < GET_MODE_BITSIZE (GET_MODE (op)) + 0 < SIZE <= GET_MODE_BITSIZE (GET_MODE (op)) + 0 < POSITION + SIZE <= GET_MODE_BITSIZE (GET_MODE (op)) + + Also reject lengths equal to a word as they are better handled + by the move patterns. */ + +bool +mips_use_ins_ext_p (rtx op, rtx size, rtx position) +{ + HOST_WIDE_INT len, pos; + + if (!ISA_HAS_EXT_INS + || !register_operand (op, VOIDmode) + || GET_MODE_BITSIZE (GET_MODE (op)) > BITS_PER_WORD) + return false; + + len = INTVAL (size); + pos = INTVAL (position); + + if (len <= 0 || len >= GET_MODE_BITSIZE (GET_MODE (op)) + || pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (op))) + return false; + + return true; +} + /* Set up globals to generate code for the ISA or processor described by INFO. */ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 9de422d95d1..ef293bec8b6 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -670,6 +670,11 @@ extern const struct mips_cpu_info *mips_tune_info; && (ISA_MIPS32R2 \ )) +/* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */ +#define ISA_HAS_EXT_INS (!TARGET_MIPS16 \ + && (ISA_MIPS32R2 \ + )) + /* True if the result of a load is not available to the next instruction. A nop will then be needed between instructions like "lw $4,..." and "addiu $4,$4,1". */ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 5d58b735503..804d50ad864 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2818,7 +2818,7 @@ beq\t%2,%.,1b\;\ (define_expand "extzv" [(set (match_operand 0 "register_operand") - (zero_extract (match_operand:QI 1 "memory_operand") + (zero_extract (match_operand 1 "nonimmediate_operand") (match_operand 2 "immediate_operand") (match_operand 3 "immediate_operand")))] "!TARGET_MIPS16" @@ -2827,12 +2827,33 @@ beq\t%2,%.,1b\;\ INTVAL (operands[2]), INTVAL (operands[3]))) DONE; + else if (mips_use_ins_ext_p (operands[1], operands[2], 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>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:SI 2 "immediate_operand" "I") + (match_operand:SI 3 "immediate_operand" "I")))] + "mips_use_ins_ext_p (operands[1], operands[2], operands[3])" + "<d>ext\t%0,%1,%3,%2" + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + + (define_expand "insv" - [(set (zero_extract (match_operand:QI 0 "memory_operand") + [(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"))] @@ -2842,10 +2863,30 @@ beq\t%2,%.,1b\;\ INTVAL (operands[1]), INTVAL (operands[2]))) DONE; - else - FAIL; + else if (mips_use_ins_ext_p (operands[0], operands[1], 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; }) +(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:GPR 3 "reg_or_0_operand" "dJ"))] + "mips_use_ins_ext_p (operands[0], operands[1], operands[2])" + "<d>ins\t%0,%z3,%2,%1" + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + ;; Unaligned word moves generated by the bit field patterns. ;; ;; As far as the rtl is concerned, both the left-part and right-part diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c7db6067b6..545b1b1658f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-05-26 David Ung <davidu@mips.com> + + * gcc.target/mips/ext_ins.c: New test for testing the generation + of MIPS32/64 rev 2 ext/ins instructions. + 2005-05-26 Andreas Jaeger <aj@suse.de> * treelang/compile/unsigned.tree: Use gimple instead of diff --git a/gcc/testsuite/gcc.target/mips/ext_ins.c b/gcc/testsuite/gcc.target/mips/ext_ins.c new file mode 100644 index 00000000000..77df1d2ba87 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/ext_ins.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-march=mips32r2" } */ +/* { dg-final { scan-assembler "ext" } } */ +/* { dg-final { scan-assembler "ins" } } */ + +struct A +{ + unsigned int i : 2; + unsigned int j : 3; + unsigned int k : 4; + unsigned int l : 5; +}; + +void func (struct A); + +unsigned int f1 (struct A a) +{ + return a.j; +} + +void f2 (int i) +{ + struct A c; + c.j = i; + func (c); +} |