Commit fc1c2d04 by Claudiu Zissulescu Committed by Claudiu Zissulescu

[ARC] Add new ARCv2 instructions.

gcc/
2016-05-02  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-protos.h (compact_memory_operand_p): Declare.
	* config/arc/arc.c (arc_output_commutative_cond_exec): Consider
	bmaskn instruction.
	(arc_dwarf_register_span): Remove enum keyword.
	(compact_memory_operand_p): New function.
	* config/arc/arc.h (reg_class): Add code density register classes.
	(REG_CLASS_NAMES): Likewise.
	(REG_CLASS_CONTENTS): Likewise.
	* config/arc/arc.md (*movqi_insn): Add code density instructions.
	(*movhi_insn, *movsi_insn, *movsf_insn): Likewise.
	(*extendhisi2_i, andsi3_i, cmpsi_cc_insn_mixed): Likewise.
	(*cmpsi_cc_c_insn, *movsi_ne): Likewise.
	* config/arc/constraints.md (C2p, Uts, Cm1, Cm3, Ucd): New
	constraints.
	(h, Rcd, Rsd, Rzd): New register constraints.
	(T): Use compact_memory_operand_p function.
	* config/arc/predicates.md (compact_load_memory_operand): Remove.

From-SVN: r235707
parent 02673c66
2016-05-02 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc-protos.h (compact_memory_operand_p): Declare.
* config/arc/arc.c (arc_output_commutative_cond_exec): Consider
bmaskn instruction.
(arc_dwarf_register_span): Remove enum keyword.
(compact_memory_operand_p): New function.
* config/arc/arc.h (reg_class): Add code density register classes.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Likewise.
* config/arc/arc.md (*movqi_insn): Add code density instructions.
(*movhi_insn, *movsi_insn, *movsf_insn): Likewise.
(*extendhisi2_i, andsi3_i, cmpsi_cc_insn_mixed): Likewise.
(*cmpsi_cc_c_insn, *movsi_ne): Likewise.
* config/arc/constraints.md (C2p, Uts, Cm1, Cm3, Ucd): New
constraints.
(h, Rcd, Rsd, Rzd): New register constraints.
(T): Use compact_memory_operand_p function.
* config/arc/predicates.md (compact_load_memory_operand): Remove.
2016-05-02 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/sh.md (*negnegt, *movtt): Remove.
......
......@@ -44,7 +44,7 @@ extern void emit_shift (enum rtx_code, rtx, rtx, rtx);
extern void arc_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
extern void arc_split_compare_and_swap (rtx *);
extern void arc_expand_compare_and_swap (rtx *);
extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool);
#endif /* RTX_CODE */
#ifdef TREE_CODE
......
......@@ -7389,6 +7389,11 @@ arc_output_commutative_cond_exec (rtx *operands, bool output_p)
case AND:
if (satisfies_constraint_C1p (operands[2]))
pat = "bmsk%? %0,%1,%Z2";
else if (satisfies_constraint_C2p (operands[2]))
{
operands[2] = GEN_INT ((~INTVAL (operands[2])));
pat = "bmskn%? %0,%1,%Z2";
}
else if (satisfies_constraint_Ccp (operands[2]))
pat = "bclr%? %0,%1,%M2";
else if (satisfies_constraint_CnL (operands[2]))
......@@ -9859,12 +9864,153 @@ arc_dwarf_register_span (rtx rtl)
/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
resource.h doesn't include the required header files. */
bool
insn_is_tls_gd_dispatch (rtx_insn *insn)
{
return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch;
}
/* Return true if OP is an acceptable memory operand for ARCompact
16-bit load instructions of MODE.
AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
non scaled instructions.
SCALED: TRUE if address can be scaled. */
bool
compact_memory_operand_p (rtx op, machine_mode mode,
bool av2short, bool scaled)
{
rtx addr, plus0, plus1;
int size, off;
/* Eliminate non-memory operations. */
if (GET_CODE (op) != MEM)
return 0;
/* .di instructions have no 16-bit form. */
if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
return false;
if (mode == VOIDmode)
mode = GET_MODE (op);
size = GET_MODE_SIZE (mode);
/* dword operations really put out 2 instructions, so eliminate
them. */
if (size > UNITS_PER_WORD)
return false;
/* Decode the address now. */
addr = XEXP (op, 0);
switch (GET_CODE (addr))
{
case REG:
return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
|| COMPACT_GP_REG_P (REGNO (addr))
|| (SP_REG_P (REGNO (addr)) && (size != 2)));
case PLUS:
plus0 = XEXP (addr, 0);
plus1 = XEXP (addr, 1);
if ((GET_CODE (plus0) == REG)
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|| COMPACT_GP_REG_P (REGNO (plus0)))
&& ((GET_CODE (plus1) == REG)
&& ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
|| COMPACT_GP_REG_P (REGNO (plus1)))))
{
return !av2short;
}
if ((GET_CODE (plus0) == REG)
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|| (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
|| (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
&& (GET_CODE (plus1) == CONST_INT))
{
bool valid = false;
off = INTVAL (plus1);
/* Negative offset is not supported in 16-bit load/store insns. */
if (off < 0)
return 0;
/* Only u5 immediates allowed in code density instructions. */
if (av2short)
{
switch (size)
{
case 1:
return false;
case 2:
/* This is an ldh_s.x instruction, check the u6
immediate. */
if (COMPACT_GP_REG_P (REGNO (plus0)))
valid = true;
break;
case 4:
/* Only u5 immediates allowed in 32bit access code
density instructions. */
if (REGNO (plus0) <= 31)
return ((off < 32) && (off % 4 == 0));
break;
default:
return false;
}
}
else
if (COMPACT_GP_REG_P (REGNO (plus0)))
valid = true;
if (valid)
{
switch (size)
{
case 1:
return (off < 32);
case 2:
/* The 6-bit constant get shifted to fit the real
5-bits field. Check also for the alignment. */
return ((off < 64) && (off % 2 == 0));
case 4:
return ((off < 128) && (off % 4 == 0));
default:
return false;
}
}
}
if (REG_P (plus0) && CONST_INT_P (plus1)
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|| SP_REG_P (REGNO (plus0)))
&& !av2short)
{
off = INTVAL (plus1);
return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
}
if ((GET_CODE (plus0) == MULT)
&& (GET_CODE (XEXP (plus0, 0)) == REG)
&& ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
|| COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
&& (GET_CODE (plus1) == REG)
&& ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
|| COMPACT_GP_REG_P (REGNO (plus1))))
return scaled;
default:
break ;
/* TODO: 'gp' and 'pcl' are to supported as base address operand
for 16-bit load instructions. */
}
return false;
}
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-arc.h"
......@@ -674,6 +674,9 @@ enum reg_class
WRITABLE_CORE_REGS, /* 'w' */
CHEAP_CORE_REGS, /* 'c' */
ALL_CORE_REGS, /* 'Rac' */
R0R3_CD_REGS, /* 'Rcd' */
R0R1_CD_REGS, /* 'Rsd' */
AC16_H_REGS, /* 'h' */
ALL_REGS,
LIM_REG_CLASSES
};
......@@ -700,6 +703,9 @@ enum reg_class
"MPY_WRITABLE_CORE_REGS", \
"WRITABLE_CORE_REGS", \
"CHEAP_CORE_REGS", \
"R0R3_CD_REGS", \
"R0R1_CD_REGS", \
"AC16_H_REGS", \
"ALL_CORE_REGS", \
"ALL_REGS" \
}
......@@ -732,6 +738,9 @@ enum reg_class
{0xffffffff, 0xd0000000, 0x00000000, 0x00000000, 0x00000000}, /* 'w', r0-r31, r60 */ \
{0xffffffff, 0xdfffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'c', r0-r60, ap, pcl */ \
{0xffffffff, 0xdfffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'Rac', r0-r60, ap, pcl */ \
{0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rcd', r0-r3 */ \
{0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsd', r0-r1 */ \
{0x9fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'h', r0-28, r30 */ \
{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff} /* All Registers */ \
}
......
......@@ -226,6 +226,14 @@
(and (match_code "const_int")
(match_test "ival && IS_POWEROF2_P (ival + 1)")))
(define_constraint "C2p"
"@internal
constant such that (~x)+1 is a power of two, and x < -1"
(and (match_code "const_int")
(match_test "TARGET_V2
&& (ival < -1)
&& IS_POWEROF2_P ((~ival) + 1)")))
(define_constraint "C3p"
"@internal
constant int used to select xbfu a,b,u6 instruction. The values accepted are 1 and 2."
......@@ -317,7 +325,13 @@
"@internal
A valid memory operand for ARCompact load instructions"
(and (match_code "mem")
(match_test "compact_load_memory_operand (op, VOIDmode)")))
(match_test "compact_memory_operand_p (op, mode, false, false)")))
(define_memory_constraint "Uts"
"@internal
A valid memory operand for ARCompact load instructions scaled"
(and (match_code "mem")
(match_test "compact_memory_operand_p (op, mode, false, TARGET_CODE_DENSITY)")))
(define_memory_constraint "S"
"@internal
......@@ -340,7 +354,7 @@
"@internal
A valid _small-data_ memory operand for ARCompact instructions"
(and (match_code "mem")
(match_test "compact_sda_memory_operand (op, VOIDmode)")))
(match_test "compact_sda_memory_operand (op, VOIDmode)")))
(define_memory_constraint "Usc"
"@internal
......@@ -483,12 +497,26 @@
(and (match_code "const_int")
(match_test "IS_ZERO (ival)")))
(define_constraint "Cm1"
"@internal
Integer signed constant in the interval [-1,6]"
(and (match_code "const_int")
(match_test "(ival >= -1) && (ival <=6)")
(match_test "TARGET_V2")))
(define_constraint "Cm2"
"@internal
A signed 9-bit integer constant."
(and (match_code "const_int")
(match_test "(ival >= -256) && (ival <=255)")))
(define_constraint "Cm3"
"@internal
A signed 6-bit integer constant."
(and (match_code "const_int")
(match_test "(ival >= -32) && (ival <=31)")
(match_test "TARGET_V2")))
(define_constraint "C62"
"@internal
An unsigned 6-bit integer constant, up to 62."
......@@ -511,3 +539,32 @@
An unsigned 16-bit integer constant"
(and (match_code "const_int")
(match_test "UNSIGNED_INT16 (ival)")))
; Memory addresses suited for code density load ops
(define_memory_constraint "Ucd"
"@internal
A valid memory operand for use with code density load ops"
(and (match_code "mem")
(match_test "compact_memory_operand_p (op, mode, true, false)")
(match_test "TARGET_V2")))
(define_register_constraint "h"
"TARGET_V2 ? AC16_H_REGS : NO_REGS"
"5-bit h register set except @code{r30} and @code{r29}:
@code{r0}-@code{r31}, nonfixed core register")
; Code density registers
(define_register_constraint "Rcd"
"TARGET_CODE_DENSITY ? R0R3_CD_REGS : NO_REGS"
"@internal
core register @code{r0}-@code{r3}")
(define_register_constraint "Rsd"
"TARGET_CODE_DENSITY ? R0R1_CD_REGS : NO_REGS"
"@internal
core register @code{r0}-@code{r1}")
(define_register_constraint "Rzd"
"TARGET_CODE_DENSITY ? R0_REGS : NO_REGS"
"@internal
@code{r0} register for code density instructions.")
......@@ -185,95 +185,6 @@
)
;; Return true if OP is an acceptable memory operand for ARCompact
;; 16-bit load instructions.
(define_predicate "compact_load_memory_operand"
(match_code "mem")
{
rtx addr, plus0, plus1;
int size, off;
/* Eliminate non-memory operations. */
if (GET_CODE (op) != MEM)
return 0;
/* .di instructions have no 16-bit form. */
if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
return 0;
if (mode == VOIDmode)
mode = GET_MODE (op);
size = GET_MODE_SIZE (mode);
/* dword operations really put out 2 instructions, so eliminate them. */
if (size > UNITS_PER_WORD)
return 0;
/* Decode the address now. */
addr = XEXP (op, 0);
switch (GET_CODE (addr))
{
case REG:
return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
|| COMPACT_GP_REG_P (REGNO (addr))
|| (SP_REG_P (REGNO (addr)) && (size != 2)));
/* Reverting for the moment since ldw_s does not have sp as a valid
parameter. */
case PLUS:
plus0 = XEXP (addr, 0);
plus1 = XEXP (addr, 1);
if ((GET_CODE (plus0) == REG)
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|| COMPACT_GP_REG_P (REGNO (plus0)))
&& ((GET_CODE (plus1) == REG)
&& ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
|| COMPACT_GP_REG_P (REGNO (plus1)))))
{
return 1;
}
if ((GET_CODE (plus0) == REG)
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|| COMPACT_GP_REG_P (REGNO (plus0)))
&& (GET_CODE (plus1) == CONST_INT))
{
off = INTVAL (plus1);
/* Negative offset is not supported in 16-bit load/store insns. */
if (off < 0)
return 0;
switch (size)
{
case 1:
return (off < 32);
case 2:
return ((off < 64) && (off % 2 == 0));
case 4:
return ((off < 128) && (off % 4 == 0));
}
}
if ((GET_CODE (plus0) == REG)
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|| SP_REG_P (REGNO (plus0)))
&& (GET_CODE (plus1) == CONST_INT))
{
off = INTVAL (plus1);
return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
}
default:
break ;
/* TODO: 'gp' and 'pcl' are to supported as base address operand
for 16-bit load instructions. */
}
return 0;
}
)
;; Return true if OP is an acceptable memory operand for ARCompact
;; 16-bit store instructions
(define_predicate "compact_store_memory_operand"
(match_code "mem")
......
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