Commit c8424132 by Adam Nemet Committed by Adam Nemet

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
parent 49912bcd
2008-09-04 Adam Nemet <anemet@caviumnetworks.com> 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. * config/mips/mips.h (ISA_HAS_CINS): New macro.
* config/mips/mips-protos.h (mask_low_and_shift_p, * config/mips/mips-protos.h (mask_low_and_shift_p,
mask_low_and_shift_len): Declare. mask_low_and_shift_len): Declare.
......
...@@ -1012,6 +1012,9 @@ enum mips_code_readable_setting { ...@@ -1012,6 +1012,9 @@ enum mips_code_readable_setting {
/* ISA includes the cins instruction. */ /* ISA includes the cins instruction. */
#define ISA_HAS_CINS TARGET_OCTEON #define ISA_HAS_CINS TARGET_OCTEON
/* ISA includes the exts instruction. */
#define ISA_HAS_EXTS TARGET_OCTEON
/* ISA includes the pop instruction. */ /* ISA includes the pop instruction. */
#define ISA_HAS_POP TARGET_OCTEON #define ISA_HAS_POP TARGET_OCTEON
......
...@@ -772,6 +772,10 @@ ...@@ -772,6 +772,10 @@
;; to use the same template. ;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend]) (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 ;; This code iterator allows the three shift instructions to be generated
;; from the same template. ;; from the same template.
(define_code_iterator any_shift [ashift ashiftrt lshiftrt]) (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
...@@ -2683,17 +2687,17 @@ ...@@ -2683,17 +2687,17 @@
;; Combiner patterns to optimize shift/truncate combinations. ;; Combiner patterns to optimize shift/truncate combinations.
(define_insn "" (define_insn "*ashr_trunc<mode>"
[(set (match_operand:SUBDI 0 "register_operand" "=d") [(set (match_operand:SUBDI 0 "register_operand" "=d")
(truncate:SUBDI (truncate:SUBDI
(ashiftrt:DI (match_operand:DI 1 "register_operand" "d") (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "const_arith_operand" ""))))] (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" "dsra\t%0,%1,%2"
[(set_attr "type" "shift") [(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") [(set (match_operand:SUBDI 0 "register_operand" "=d")
(truncate:SUBDI (truncate:SUBDI
(lshiftrt:DI (match_operand:DI 1 "register_operand" "d") (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
...@@ -2701,8 +2705,19 @@ ...@@ -2701,8 +2705,19 @@
"TARGET_64BIT && !TARGET_MIPS16" "TARGET_64BIT && !TARGET_MIPS16"
"dsra\t%0,%1,32" "dsra\t%0,%1,32"
[(set_attr "type" "shift") [(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 ;; Combiner patterns for truncate/sign_extend combinations. The SI versions
;; use the shift/truncate patterns above. ;; use the shift/truncate patterns above.
...@@ -3353,24 +3368,46 @@ ...@@ -3353,24 +3368,46 @@
(define_expand "extv" (define_expand "extv"
[(set (match_operand 0 "register_operand") [(set (match_operand 0 "register_operand")
(sign_extract (match_operand:QI 1 "memory_operand") (sign_extract (match_operand 1 "nonimmediate_operand")
(match_operand 2 "immediate_operand") (match_operand 2 "const_int_operand")
(match_operand 3 "immediate_operand")))] (match_operand 3 "const_int_operand")))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
{ {
if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
INTVAL (operands[2]), INTVAL (operands[2]),
INTVAL (operands[3]))) INTVAL (operands[3])))
DONE; 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 else
FAIL; 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" (define_expand "extzv"
[(set (match_operand 0 "register_operand") [(set (match_operand 0 "register_operand")
(zero_extract (match_operand 1 "nonimmediate_operand") (zero_extract (match_operand 1 "nonimmediate_operand")
(match_operand 2 "immediate_operand") (match_operand 2 "const_int_operand")
(match_operand 3 "immediate_operand")))] (match_operand 3 "const_int_operand")))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
{ {
if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
...@@ -3395,14 +3432,25 @@ ...@@ -3395,14 +3432,25 @@
(define_insn "extzv<mode>" (define_insn "extzv<mode>"
[(set (match_operand:GPR 0 "register_operand" "=d") [(set (match_operand:GPR 0 "register_operand" "=d")
(zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
(match_operand:SI 2 "immediate_operand" "I") (match_operand 2 "const_int_operand" "")
(match_operand:SI 3 "immediate_operand" "I")))] (match_operand 3 "const_int_operand" "")))]
"mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
INTVAL (operands[3]))" INTVAL (operands[3]))"
"<d>ext\t%0,%1,%3,%2" "<d>ext\t%0,%1,%3,%2"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "mode" "<MODE>")]) (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" (define_expand "insv"
[(set (zero_extract (match_operand 0 "nonimmediate_operand") [(set (zero_extract (match_operand 0 "nonimmediate_operand")
......
2008-09-04 Adam Nemet <anemet@caviumnetworks.com> 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. * gcc.target/mips/octeon-cins-1.c: New test.
* gcc.target/mips/octeon-cins-2.c: New test. * gcc.target/mips/octeon-cins-2.c: New test.
......
/* { 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;
}
/* { 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;
}
/* { 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;
}
/* { 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)
/* { 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" } } */
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