Commit e689b870 by David Ung Committed by David Ung

ext_ins.c: New test for testing the generation of MIPS32/64 rev 2 ext/ins instructions.

* 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.

From-SVN: r100212
parent 764e01e6
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
......
......@@ -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. */
......
......@@ -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". */
......
......@@ -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
......
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
......
/* { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment