mips.h (ISA_HAS_EXTS): New macro.

* config/mips/mips.h (ISA_HAS_EXTS): New macro.
	* config/mips/mips.md (*ashr_trunc<mode>): Name the pattern
	combining an arithmetic right shift by more than 31 and a
	trunction.  Don't match for out-of-range shift amounts.  Set
	attribute mode to <MODE>.
	(*lshr32_trunc<mode>): Name the pattern combining a logical right
	shift by 32 and and a truncation.  Set attribute mode to <MODE>.
	(*<optab>_trunc<mode>_exts): New pattern for truncated right
	shifts by less than 32.
	(extv): Change predicate on first operand to accept registers.
	Change predicate of the other operands from immediate_operand to
	const_int_operand.  Expand exts when source is a register.
	(extzv): Change predicate of the constant operands from
	immediate_operand to const_int_operand.
	(extzv<mode>): Change predicate of the constant operands from
	immediate_operand to const_int_operand and no constraint. Also
	remove mode.
	(*extzv_trunc<mode>_exts): New pattern.

testsuite/
	* gcc.target/mips/truncate-2.c: New test.
	* gcc.target/mips/octeon-exts-1.c: New test.
	* gcc.target/mips/octeon-exts-2.c: New test.
	* gcc.target/mips/octeon-exts-3.c: New test.
	* gcc.target/mips/octeon-exts-4.c: New test.

From-SVN: r140009
This commit is contained in:
Adam Nemet 2008-09-04 21:24:31 +00:00 committed by Adam Nemet
parent 49912bcd97
commit c842413274
9 changed files with 220 additions and 12 deletions

View File

@ -1,3 +1,24 @@
2008-09-04 Adam Nemet <anemet@caviumnetworks.com>
* config/mips/mips.h (ISA_HAS_EXTS): New macro.
* config/mips/mips.md (*ashr_trunc<mode>): Name the pattern
combining an arithmetic right shift by more than 31 and a
trunction. Don't match for out-of-range shift amounts. Set
attribute mode to <MODE>.
(*lshr32_trunc<mode>): Name the pattern combining a logical right
shift by 32 and and a truncation. Set attribute mode to <MODE>.
(*<optab>_trunc<mode>_exts): New pattern for truncated right
shifts by less than 32.
(extv): Change predicate on first operand to accept registers.
Change predicate of the other operands from immediate_operand to
const_int_operand. Expand exts when source is a register.
(extzv): Change predicate of the constant operands from
immediate_operand to const_int_operand.
(extzv<mode>): Change predicate of the constant operands from
immediate_operand to const_int_operand and no constraint. Also
remove mode.
(*extzv_trunc<mode>_exts): New pattern.
2008-09-04 Adam Nemet <anemet@caviumnetworks.com>
* config/mips/mips.h (ISA_HAS_CINS): New macro.

View File

@ -1012,6 +1012,9 @@ enum mips_code_readable_setting {
/* ISA includes the cins instruction. */
#define ISA_HAS_CINS TARGET_OCTEON
/* ISA includes the exts instruction. */
#define ISA_HAS_EXTS TARGET_OCTEON
/* ISA includes the pop instruction. */
#define ISA_HAS_POP TARGET_OCTEON

View File

@ -772,6 +772,10 @@
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
;; This code iterator allows the two right shift instructions to be
;; generated from the same template.
(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
;; This code iterator allows the three shift instructions to be generated
;; from the same template.
(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
@ -2683,17 +2687,17 @@
;; Combiner patterns to optimize shift/truncate combinations.
(define_insn ""
(define_insn "*ashr_trunc<mode>"
[(set (match_operand:SUBDI 0 "register_operand" "=d")
(truncate:SUBDI
(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "const_arith_operand" ""))))]
"TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
"TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)"
"dsra\t%0,%1,%2"
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
(set_attr "mode" "<MODE>")])
(define_insn ""
(define_insn "*lshr32_trunc<mode>"
[(set (match_operand:SUBDI 0 "register_operand" "=d")
(truncate:SUBDI
(lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
@ -2701,8 +2705,19 @@
"TARGET_64BIT && !TARGET_MIPS16"
"dsra\t%0,%1,32"
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
(set_attr "mode" "<MODE>")])
;; Logical shift by 32 or more results in proper SI values so
;; truncation is removed by the middle end.
(define_insn "*<optab>_trunc<mode>_exts"
[(set (match_operand:SUBDI 0 "register_operand" "=d")
(truncate:SUBDI
(any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "const_arith_operand" ""))))]
"ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32"
"exts\t%0,%1,%2,31"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
;; Combiner patterns for truncate/sign_extend combinations. The SI versions
;; use the shift/truncate patterns above.
@ -3353,24 +3368,46 @@
(define_expand "extv"
[(set (match_operand 0 "register_operand")
(sign_extract (match_operand:QI 1 "memory_operand")
(match_operand 2 "immediate_operand")
(match_operand 3 "immediate_operand")))]
(sign_extract (match_operand 1 "nonimmediate_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])))
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>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
(match_operand 2 "const_int_operand" "")
(match_operand 3 "const_int_operand" "")))]
"ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32"
"exts\t%0,%1,%3,%m2"
[(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 "immediate_operand")
(match_operand 3 "immediate_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],
@ -3395,14 +3432,25 @@
(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")))]
(match_operand 2 "const_int_operand" "")
(match_operand 3 "const_int_operand" "")))]
"mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
INTVAL (operands[3]))"
"<d>ext\t%0,%1,%3,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
(define_insn "*extzv_trunc<mode>_exts"
[(set (match_operand:GPR 0 "register_operand" "=d")
(truncate:GPR
(zero_extract:DI (match_operand:DI 1 "register_operand" "d")
(match_operand 2 "const_int_operand" "")
(match_operand 3 "const_int_operand" ""))))]
"ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
"exts\t%0,%1,%3,31"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
(define_expand "insv"
[(set (zero_extract (match_operand 0 "nonimmediate_operand")

View File

@ -1,3 +1,11 @@
2008-09-04 Adam Nemet <anemet@caviumnetworks.com>
* gcc.target/mips/truncate-2.c: New test.
* gcc.target/mips/octeon-exts-1.c: New test.
* gcc.target/mips/octeon-exts-2.c: New test.
* gcc.target/mips/octeon-exts-3.c: New test.
* gcc.target/mips/octeon-exts-4.c: New test.
2008-09-04 Adam Nemet <anemet@caviumnetworks.com>
* gcc.target/mips/octeon-cins-1.c: New test.

View File

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-mips-options "-march=octeon" } */
/* { dg-final { scan-assembler "\texts\t" } } */
struct foo
{
long long a:3;
long long b:23;
long long c:38;
};
NOMIPS16 int
f (struct foo s)
{
return s.b;
}

View File

@ -0,0 +1,37 @@
/* { dg-do compile } */
/* { dg-mips-options "-O -march=octeon" } */
/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
struct bar
{
unsigned long long a:1;
long long b:14;
unsigned long long c:48;
long long d:1;
};
NOMIPS16 int
f1 (struct bar *s, int a)
{
return (int) s->b + a;
}
NOMIPS16 char
f2 (struct bar *s)
{
return s->d + 1;
}
NOMIPS16 int
f3 ()
{
struct bar s;
asm ("" : "=r"(s));
return (int) s.b + 1;
}
NOMIPS16 long long
f4 (struct bar *s)
{
return s->d;
}

View File

@ -0,0 +1,35 @@
/* { dg-do compile } */
/* { dg-mips-options "-O -march=octeon -mgp64" } */
/* { dg-final { scan-assembler-times "\texts\t" 3 } } */
struct foo
{
unsigned long long a:10;
unsigned long long b:32;
unsigned long long c:22;
};
NOMIPS16 unsigned
f (struct foo s)
{
return s.b;
}
struct bar
{
unsigned long long a:15;
unsigned long long b:48;
unsigned long long c:1;
};
NOMIPS16 int
g (struct bar s)
{
return (int) s.b;
}
NOMIPS16 int
h (int i)
{
return (i << 4) >> 24;
}

View File

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-mips-options "-O -march=octeon -mgp64" } */
/* { dg-final { scan-assembler-not "\tsll\t\[^\n\]*,0" } } */
/* { dg-final { scan-assembler-times "\texts\t" 6 } } */
#define TEST(ID, TYPE, SHIFT) \
int NOMIPS16 \
f##ID (long long y) \
{ \
return (TYPE) ((TYPE) (y >> SHIFT) + 1); \
} \
int NOMIPS16 \
g##ID (unsigned long long y) \
{ \
return (TYPE) ((TYPE) (y >> SHIFT) + 1); \
}
TEST (1, int, 10)
TEST (2, short, 5)
TEST (3, char, 31)

View File

@ -0,0 +1,20 @@
/* { dg-mips-options "-O -mgp64" } */
#define TEST(ID, TYPE, SHIFT) \
int NOMIPS16 \
f##ID (long long y) \
{ \
return (TYPE) ((TYPE) (y >> SHIFT) + 1); \
}
TEST (1, int, 32)
TEST (2, short, 32)
TEST (3, char, 32)
TEST (4, int, 33)
TEST (5, short, 33)
TEST (6, char, 33)
TEST (7, int, 61)
TEST (8, short, 61)
TEST (9, char, 61)
/* { dg-final { scan-assembler-not "\tsll\t\[^\n\]*,0" } } */