mirror of git://gcc.gnu.org/git/gcc.git
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, mask_low_and_shift_len): Declare. * config/mips/mips.c (mask_low_and_shift_p, mask_low_and_shift_len): New functions. (mips_print_operand): Handle new operand prefix "m". * config/mips/mips.md (*cins<mode>): New pattern. testsuite/ * gcc.target/mips/octeon-cins-1.c: New test. * gcc.target/mips/octeon-cins-2.c: New test. From-SVN: r140008
This commit is contained in:
parent
192a671ee3
commit
49912bcd97
|
@ -1,3 +1,13 @@
|
||||||
|
2008-09-04 Adam Nemet <anemet@caviumnetworks.com>
|
||||||
|
|
||||||
|
* config/mips/mips.h (ISA_HAS_CINS): New macro.
|
||||||
|
* config/mips/mips-protos.h (mask_low_and_shift_p,
|
||||||
|
mask_low_and_shift_len): Declare.
|
||||||
|
* config/mips/mips.c (mask_low_and_shift_p,
|
||||||
|
mask_low_and_shift_len): New functions.
|
||||||
|
(mips_print_operand): Handle new operand prefix "m".
|
||||||
|
* config/mips/mips.md (*cins<mode>): New pattern.
|
||||||
|
|
||||||
2008-09-04 Bernd Schmidt <bernd.schmidt@analog.com>
|
2008-09-04 Bernd Schmidt <bernd.schmidt@analog.com>
|
||||||
|
|
||||||
* config/bfin/bfin.c (gen_one_bundle): Don't create new nops when
|
* config/bfin/bfin.c (gen_one_bundle): Don't create new nops when
|
||||||
|
|
|
@ -314,6 +314,10 @@ extern bool mips_use_ins_ext_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
|
||||||
extern const char *mips16e_output_save_restore (rtx, HOST_WIDE_INT);
|
extern const char *mips16e_output_save_restore (rtx, HOST_WIDE_INT);
|
||||||
extern bool mips16e_save_restore_pattern_p (rtx, HOST_WIDE_INT,
|
extern bool mips16e_save_restore_pattern_p (rtx, HOST_WIDE_INT,
|
||||||
struct mips16e_save_restore_info *);
|
struct mips16e_save_restore_info *);
|
||||||
|
|
||||||
|
extern bool mask_low_and_shift_p (enum machine_mode, rtx, rtx, int);
|
||||||
|
extern int mask_low_and_shift_len (enum machine_mode, rtx, rtx);
|
||||||
|
|
||||||
union mips_gen_fn_ptrs
|
union mips_gen_fn_ptrs
|
||||||
{
|
{
|
||||||
rtx (*fn_6) (rtx, rtx, rtx, rtx, rtx, rtx);
|
rtx (*fn_6) (rtx, rtx, rtx, rtx, rtx, rtx);
|
||||||
|
|
|
@ -6659,6 +6659,32 @@ mips_use_ins_ext_p (rtx op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if MASK and SHIFT are valid in mask-low-and-shift-left
|
||||||
|
operation if MAXLEN is the maxium length of consecutive bits that
|
||||||
|
can make up MASK. MODE is the mode of the operation. See
|
||||||
|
mask_low_and_shift_len for the actual definition. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
mask_low_and_shift_p (enum machine_mode mode, rtx mask, rtx shift, int maxlen)
|
||||||
|
{
|
||||||
|
return IN_RANGE (mask_low_and_shift_len (mode, mask, shift), 1, maxlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The canonical form of a mask-low-and-shift-left operation is
|
||||||
|
(and (ashift X SHIFT) MASK) where MASK has the lower SHIFT number of bits
|
||||||
|
cleared. Thus we need to shift MASK to the right before checking if it
|
||||||
|
is a valid mask value. MODE is the mode of the operation. If true
|
||||||
|
return the length of the mask, otherwise return -1. */
|
||||||
|
|
||||||
|
int
|
||||||
|
mask_low_and_shift_len (enum machine_mode mode, rtx mask, rtx shift)
|
||||||
|
{
|
||||||
|
HOST_WIDE_INT shval;
|
||||||
|
|
||||||
|
shval = INTVAL (shift) & (GET_MODE_BITSIZE (mode) - 1);
|
||||||
|
return exact_log2 ((UINTVAL (mask) >> shval) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return true if -msplit-addresses is selected and should be honored.
|
/* Return true if -msplit-addresses is selected and should be honored.
|
||||||
|
|
||||||
|
@ -7026,6 +7052,7 @@ mips_print_float_branch_condition (FILE *file, enum rtx_code code, int letter)
|
||||||
'X' Print CONST_INT OP in hexadecimal format.
|
'X' Print CONST_INT OP in hexadecimal format.
|
||||||
'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
|
'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
|
||||||
'd' Print CONST_INT OP in decimal.
|
'd' Print CONST_INT OP in decimal.
|
||||||
|
'm' Print one less than CONST_INT OP in decimal.
|
||||||
'h' Print the high-part relocation associated with OP, after stripping
|
'h' Print the high-part relocation associated with OP, after stripping
|
||||||
any outermost HIGH.
|
any outermost HIGH.
|
||||||
'R' Print the low-part relocation associated with OP.
|
'R' Print the low-part relocation associated with OP.
|
||||||
|
@ -7081,6 +7108,13 @@ mips_print_operand (FILE *file, rtx op, int letter)
|
||||||
output_operand_lossage ("invalid use of '%%%c'", letter);
|
output_operand_lossage ("invalid use of '%%%c'", letter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
if (GET_CODE (op) == CONST_INT)
|
||||||
|
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1);
|
||||||
|
else
|
||||||
|
output_operand_lossage ("invalid use of '%%%c'", letter);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
if (code == HIGH)
|
if (code == HIGH)
|
||||||
op = XEXP (op, 0);
|
op = XEXP (op, 0);
|
||||||
|
|
|
@ -1009,6 +1009,9 @@ enum mips_code_readable_setting {
|
||||||
/* ISA includes the bbit* instructions. */
|
/* ISA includes the bbit* instructions. */
|
||||||
#define ISA_HAS_BBIT TARGET_OCTEON
|
#define ISA_HAS_BBIT TARGET_OCTEON
|
||||||
|
|
||||||
|
/* ISA includes the cins instruction. */
|
||||||
|
#define ISA_HAS_CINS TARGET_OCTEON
|
||||||
|
|
||||||
/* ISA includes the pop instruction. */
|
/* ISA includes the pop instruction. */
|
||||||
#define ISA_HAS_POP TARGET_OCTEON
|
#define ISA_HAS_POP TARGET_OCTEON
|
||||||
|
|
||||||
|
|
|
@ -3441,6 +3441,28 @@
|
||||||
[(set_attr "type" "arith")
|
[(set_attr "type" "arith")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
|
|
||||||
|
;; Combiner pattern for cins (clear and insert bit field). We can
|
||||||
|
;; implement mask-and-shift-left operation with this. Note that if
|
||||||
|
;; the upper bit of the mask is set in an SImode operation, the mask
|
||||||
|
;; itself will be sign-extended. mask_low_and_shift_len will
|
||||||
|
;; therefore be greater than our threshold of 32.
|
||||||
|
|
||||||
|
(define_insn "*cins<mode>"
|
||||||
|
[(set (match_operand:GPR 0 "register_operand" "=d")
|
||||||
|
(and:GPR
|
||||||
|
(ashift:GPR (match_operand:GPR 1 "register_operand" "d")
|
||||||
|
(match_operand:GPR 2 "const_int_operand" ""))
|
||||||
|
(match_operand:GPR 3 "const_int_operand" "")))]
|
||||||
|
"ISA_HAS_CINS
|
||||||
|
&& mask_low_and_shift_p (<MODE>mode, operands[3], operands[2], 32)"
|
||||||
|
{
|
||||||
|
operands[3] =
|
||||||
|
GEN_INT (mask_low_and_shift_len (<MODE>mode, operands[3], operands[2]));
|
||||||
|
return "cins\t%0,%1,%2,%m3";
|
||||||
|
}
|
||||||
|
[(set_attr "type" "shift")
|
||||||
|
(set_attr "mode" "<MODE>")])
|
||||||
|
|
||||||
;; Unaligned word moves generated by the bit field patterns.
|
;; Unaligned word moves generated by the bit field patterns.
|
||||||
;;
|
;;
|
||||||
;; As far as the rtl is concerned, both the left-part and right-part
|
;; As far as the rtl is concerned, both the left-part and right-part
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2008-09-04 Adam Nemet <anemet@caviumnetworks.com>
|
||||||
|
|
||||||
|
* gcc.target/mips/octeon-cins-1.c: New test.
|
||||||
|
* gcc.target/mips/octeon-cins-2.c: New test.
|
||||||
|
|
||||||
2008-09-04 Richard Guenther <rguenther@suse.de>
|
2008-09-04 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
* gfortran.dg/internal_pack_4.f90: Adjust pattern.
|
* gfortran.dg/internal_pack_4.f90: Adjust pattern.
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* The tests also work with -mgp32. For long long tests, only one of
|
||||||
|
the 32-bit parts is used. */
|
||||||
|
/* { dg-mips-options "-O -march=octeon" } */
|
||||||
|
/* { dg-final { scan-assembler-times "\tcins\t" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\tandi\t|sll\t" } } */
|
||||||
|
|
||||||
|
NOMIPS16 long long
|
||||||
|
f (long long i)
|
||||||
|
{
|
||||||
|
return (i & 0xff) << 34;
|
||||||
|
}
|
||||||
|
|
||||||
|
NOMIPS16 int
|
||||||
|
g (int i)
|
||||||
|
{
|
||||||
|
return (i << 4) & 0xff0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NOMIPS16 long long
|
||||||
|
h (long long i)
|
||||||
|
{
|
||||||
|
return (i << 4) & 0xfff;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-mips-options "-O -march=octeon -mgp64" } */
|
||||||
|
/* { dg-final { scan-assembler-not "\tcins\t" } } */
|
||||||
|
|
||||||
|
NOMIPS16 unsigned
|
||||||
|
f (unsigned i)
|
||||||
|
{
|
||||||
|
return (i & 0xff) << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
NOMIPS16 unsigned long long
|
||||||
|
g (unsigned long long i)
|
||||||
|
{
|
||||||
|
return (i & 0x1ffffffffULL) << 4;
|
||||||
|
}
|
Loading…
Reference in New Issue