summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authordavidu <davidu@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-26 17:23:35 +0000
committerdavidu <davidu@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-26 17:23:35 +0000
commit483650218bc49133ba69faad6fc5931d2636a594 (patch)
tree2c115cbf4d0642b7f753a9bb5f736eecd964d555 /gcc
parent137c809d703b05dadd418e90b9f0a0dae7a664d0 (diff)
downloadppe42-gcc-483650218bc49133ba69faad6fc5931d2636a594.tar.gz
ppe42-gcc-483650218bc49133ba69faad6fc5931d2636a594.zip
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/mips/mips.c34
-rw-r--r--gcc/config/mips/mips.h5
-rw-r--r--gcc/config/mips/mips.md49
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/mips/ext_ins.c26
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);
+}
OpenPOWER on IntegriCloud