mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
49912bcd97
commit
c842413274
|
@ -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>
|
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.
|
||||||
|
|
|
@ -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 @@
|
||||||
;; 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 @@
|
||||||
|
|
||||||
;; 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 @@
|
||||||
"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 @@
|
||||||
|
|
||||||
(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 @@
|
||||||
(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")
|
||||||
|
|
|
@ -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>
|
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.
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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)
|
|
@ -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" } } */
|
Loading…
Reference in New Issue