[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
This commit is contained in:
parent
02673c66c6
commit
fc1c2d0482
@ -1,3 +1,23 @@
|
||||
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 */ \
|
||||
}
|
||||
|
||||
|
@ -620,14 +620,15 @@
|
||||
; The iscompact attribute allows the epilogue expander to know for which
|
||||
; insns it should lengthen the return insn.
|
||||
(define_insn "*movqi_insn"
|
||||
[(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,w,Rcq,S,!*x,r,r,Ucm,m,???m")
|
||||
(match_operand:QI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))]
|
||||
[(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w, w,Rcq, S,!*x, r,r, Ucm,m,???m")
|
||||
(match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))]
|
||||
"register_operand (operands[0], QImode)
|
||||
|| register_operand (operands[1], QImode)"
|
||||
"@
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1
|
||||
mov%? %0,%1
|
||||
mov%? %0,%1
|
||||
@ -640,10 +641,10 @@
|
||||
xstb%U0 %1,%0
|
||||
stb%U0%V0 %1,%0
|
||||
stb%U0%V0 %1,%0"
|
||||
[(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,load,store,store,store")
|
||||
(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false,false,false")
|
||||
(set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no,no,no")
|
||||
(set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*")])
|
||||
[(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store")
|
||||
(set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,false,true,true,true,false,false,false,false,false")
|
||||
(set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,no,no,no,no,no,no,no,no")
|
||||
(set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*")])
|
||||
|
||||
(define_expand "movhi"
|
||||
[(set (match_operand:HI 0 "move_dest_operand" "")
|
||||
@ -652,8 +653,8 @@
|
||||
"if (prepare_move_operands (operands, HImode)) DONE;")
|
||||
|
||||
(define_insn "*movhi_insn"
|
||||
[(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,Rcq#q,w,Rcq,S,r,r,Ucm,m,???m,VUsc")
|
||||
(match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,?i,T,Rcq,Ucm,m,?Rac,c,?Rac,i"))]
|
||||
[(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w,Rcq#q, w,Rcq, S, r,r, Ucm,m,???m,VUsc,VUsc")
|
||||
(match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac, ?i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))]
|
||||
"register_operand (operands[0], HImode)
|
||||
|| register_operand (operands[1], HImode)
|
||||
|| (CONSTANT_P (operands[1])
|
||||
@ -665,6 +666,7 @@
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1%&
|
||||
mov%? %0,%1
|
||||
mov%? %0,%1
|
||||
mov%? %0,%1
|
||||
@ -677,11 +679,12 @@
|
||||
xst%_%U0 %1,%0
|
||||
st%_%U0%V0 %1,%0
|
||||
st%_%U0%V0 %1,%0
|
||||
st%_%U0%V0 %S1,%0
|
||||
st%_%U0%V0 %S1,%0"
|
||||
[(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store")
|
||||
(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false")
|
||||
(set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no")
|
||||
(set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*")])
|
||||
[(set_attr "type" "move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
|
||||
(set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false,false")
|
||||
(set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no")
|
||||
(set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
|
||||
|
||||
(define_expand "movsi"
|
||||
[(set (match_operand:SI 0 "move_dest_operand" "")
|
||||
@ -699,9 +702,9 @@
|
||||
; the iscompact attribute allows the epilogue expander to know for which
|
||||
; insns it should lengthen the return insn.
|
||||
; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
|
||||
(define_insn "*movsi_insn"
|
||||
[(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,w,w,w,w,???w,?w,w,Rcq#q,w,Rcq,S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
|
||||
(match_operand:SI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
|
||||
(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
||||
[(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc")
|
||||
(match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))]
|
||||
"register_operand (operands[0], SImode)
|
||||
|| register_operand (operands[1], SImode)
|
||||
|| (CONSTANT_P (operands[1])
|
||||
@ -713,35 +716,40 @@
|
||||
mov%? %0,%1%& ;0
|
||||
mov%? %0,%1%& ;1
|
||||
mov%? %0,%1%& ;2
|
||||
mov%? %0,%1 ;3
|
||||
mov%? %0,%1%& ;3
|
||||
mov%? %0,%1 ;4
|
||||
ror %0,((%1*2+1) & 0x3f) ;5
|
||||
movl.cl %0,%1 ;6
|
||||
movh.cl %0,%L1>>16 ;7
|
||||
mov%? %0,%1 ;5
|
||||
ror %0,((%1*2+1) & 0x3f) ;6
|
||||
movl.cl %0,%1 ;7
|
||||
movh.cl %0,%L1>>16 ;8
|
||||
* return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\";
|
||||
mov%? %0,%1 ;9
|
||||
add %0,%S1 ;10
|
||||
mov%? %0,%1 ;10
|
||||
add %0,%S1 ;11
|
||||
* return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
|
||||
mov%? %0,%S1%& ;12
|
||||
mov%? %0,%S1 ;13
|
||||
ld%? %0,%1%& ;14
|
||||
st%? %1,%0%& ;15
|
||||
mov%? %0,%S1%& ;13
|
||||
mov%? %0,%S1 ;14
|
||||
ld%? %0,%1%& ;15
|
||||
st%? %1,%0%& ;16
|
||||
* return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
|
||||
* return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
|
||||
ld%? %0,%1%& ;18
|
||||
xld%U1 %0,%1 ;19
|
||||
ld%U1%V1 %0,%1 ;20
|
||||
xst%U0 %1,%0 ;21
|
||||
st%U0%V0 %1,%0 ;22
|
||||
st%U0%V0 %1,%0 ;23
|
||||
st%U0%V0 %S1,%0 ;24"
|
||||
[(set_attr "type" "move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
|
||||
(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
|
||||
ld%? %0,%1%& ;19
|
||||
xld%U1 %0,%1 ;20
|
||||
ld%? %0,%1%& ;21
|
||||
ld%? %0,%1%& ;22
|
||||
ld%U1%V1 %0,%1 ;23
|
||||
xst%U0 %1,%0 ;24
|
||||
st%? %1,%0%& ;25
|
||||
st%U0%V0 %1,%0 ;26
|
||||
st%U0%V0 %1,%0 ;27
|
||||
st%U0%V0 %1,%0 ;28
|
||||
st%U0%V0 %S1,%0 ;29"
|
||||
[(set_attr "type" "move,move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,load,load,store,store,store,store,store,store")
|
||||
(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false")
|
||||
; Use default length for iscompact to allow for COND_EXEC. But set length
|
||||
; of Crr to 4.
|
||||
(set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
|
||||
(set_attr "predicable" "yes,no,yes,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
|
||||
(set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
|
||||
(set_attr "length" "*,*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8")
|
||||
(set_attr "predicable" "yes,no,yes,no,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
|
||||
(set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
|
||||
|
||||
;; Sometimes generated by the epilogue code. We don't want to
|
||||
;; recognize these addresses in general, because the limm is costly,
|
||||
@ -1136,17 +1144,19 @@
|
||||
"if (prepare_move_operands (operands, SFmode)) DONE;")
|
||||
|
||||
(define_insn "*movsf_insn"
|
||||
[(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m")
|
||||
(match_operand:SF 1 "move_src_operand" "c,E,m,c"))]
|
||||
[(set (match_operand:SF 0 "move_dest_operand" "=h,w,w,r,m")
|
||||
(match_operand:SF 1 "move_src_operand" "hCm1,c,E,m,c"))]
|
||||
"register_operand (operands[0], SFmode)
|
||||
|| register_operand (operands[1], SFmode)"
|
||||
"@
|
||||
mov%? %0,%1
|
||||
mov%? %0,%1
|
||||
mov%? %0,%1 ; %A1
|
||||
ld%U1%V1 %0,%1
|
||||
st%U0%V0 %1,%0"
|
||||
[(set_attr "type" "move,move,load,store")
|
||||
(set_attr "predicable" "yes,yes,no,no")])
|
||||
[(set_attr "type" "move,move,move,load,store")
|
||||
(set_attr "predicable" "no,yes,yes,no,no")
|
||||
(set_attr "iscompact" "true,false,false,false,false")])
|
||||
|
||||
(define_expand "movdf"
|
||||
[(set (match_operand:DF 0 "nonimmediate_operand" "")
|
||||
@ -1664,17 +1674,18 @@
|
||||
)
|
||||
|
||||
(define_insn "*extendhisi2_i"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
|
||||
(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r")
|
||||
(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
|
||||
""
|
||||
"@
|
||||
sex%_%? %0,%1%&
|
||||
sex%_ %0,%1
|
||||
ldh%?.x %0,%1%&
|
||||
ld%_.x%U1%V1 %0,%1
|
||||
ld%_.x%U1%V1 %0,%1"
|
||||
[(set_attr "type" "unary,unary,load,load")
|
||||
(set_attr "iscompact" "true,false,false,false")
|
||||
(set_attr "length" "*,*,4,8")])
|
||||
[(set_attr "type" "unary,unary,load,load,load")
|
||||
(set_attr "iscompact" "true,false,true,false,false")
|
||||
(set_attr "length" "*,*,*,4,8")])
|
||||
|
||||
(define_expand "extendhisi2"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "")
|
||||
@ -3041,9 +3052,9 @@
|
||||
operands[1] = arc_rewrite_small_data (operands[1]);")
|
||||
|
||||
(define_insn "andsi3_i"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,w,w,w,w,Rrq,w,Rcw,w,W")
|
||||
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,0,0,Rcqq,0,c,0,0,0,0,c,c,c,c,Rrq,0,0,c,o")
|
||||
(match_operand:SI 2 "nonmemory_operand" "Rcqq,0,C1p,Ccp,Cux,cL,0,C1p,Ccp,CnL,I,Lc,C1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw, Rcw,Rcw,Rcw,Rcw, w, w, w, w,Rrq,w,Rcw, w,W")
|
||||
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,Rrq,0, 0, c,o")
|
||||
(match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C1p, Ccp, Cux, cL, 0,C2pC1p,Ccp,CnL, I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
|
||||
"(register_operand (operands[1], SImode)
|
||||
&& nonmemory_operand (operands[2], SImode))
|
||||
|| (memory_operand (operands[1], SImode)
|
||||
@ -3055,8 +3066,18 @@
|
||||
return "and%? %0,%1,%2%&";
|
||||
case 1: case 6:
|
||||
return "and%? %0,%2,%1%&";
|
||||
case 2: case 7: case 12:
|
||||
case 2:
|
||||
return "bmsk%? %0,%1,%Z2%&";
|
||||
case 7: case 12:
|
||||
if (satisfies_constraint_C2p (operands[2]))
|
||||
{
|
||||
operands[2] = GEN_INT ((~INTVAL (operands[2])));
|
||||
return "bmskn%? %0,%1,%Z2%&";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "bmsk%? %0,%1,%Z2%&";
|
||||
}
|
||||
case 3: case 8: case 13:
|
||||
return "bclr%? %0,%1,%M2%&";
|
||||
case 4:
|
||||
@ -3368,15 +3389,15 @@
|
||||
;; modifed cc user if second, but not first operand is a compact register.
|
||||
(define_insn "cmpsi_cc_insn_mixed"
|
||||
[(set (reg:CC CC_REG)
|
||||
(compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,c,c, qRcq, c")
|
||||
(match_operand:SI 1 "nonmemory_operand" "cO,cI,cL, Cal, Cal")))]
|
||||
(compare:CC (match_operand:SI 0 "register_operand" "Rcq#q, h, c, c,qRcq,c")
|
||||
(match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI,cL, Cal,Cal")))]
|
||||
""
|
||||
"cmp%? %0,%B1%&"
|
||||
[(set_attr "type" "compare")
|
||||
(set_attr "iscompact" "true,false,false,true_limm,false")
|
||||
(set_attr "predicable" "no,no,yes,no,yes")
|
||||
(set_attr "iscompact" "true,true,false,false,true_limm,false")
|
||||
(set_attr "predicable" "no,no,no,yes,no,yes")
|
||||
(set_attr "cond" "set")
|
||||
(set_attr "length" "*,4,4,*,8")])
|
||||
(set_attr "length" "*,*,4,4,*,8")])
|
||||
|
||||
(define_insn "*cmpsi_cc_zn_insn"
|
||||
[(set (reg:CC_ZN CC_REG)
|
||||
@ -3452,14 +3473,14 @@
|
||||
|
||||
(define_insn "*cmpsi_cc_c_insn"
|
||||
[(set (reg:CC_C CC_REG)
|
||||
(compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, c,Rcqq, c")
|
||||
(match_operand:SI 1 "nonmemory_operand" "cO, cI, Cal,Cal")))]
|
||||
(compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, h, c,Rcqq, c")
|
||||
(match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI, Cal,Cal")))]
|
||||
""
|
||||
"cmp%? %0,%S1%&"
|
||||
[(set_attr "type" "compare")
|
||||
(set_attr "iscompact" "true,false,true_limm,false")
|
||||
(set_attr "iscompact" "true,true,false,true_limm,false")
|
||||
(set_attr "cond" "set")
|
||||
(set_attr "length" "*,4,*,8")])
|
||||
(set_attr "length" "*,*,4,*,8")])
|
||||
|
||||
;; Next come the scc insns.
|
||||
|
||||
@ -3552,17 +3573,20 @@
|
||||
; cond_exec patterns
|
||||
(define_insn "*movsi_ne"
|
||||
[(cond_exec
|
||||
(ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc") (const_int 0))
|
||||
(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
|
||||
(match_operand:SI 1 "nonmemory_operand" "C_0,Lc,?Cal")))]
|
||||
(ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0))
|
||||
(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w")
|
||||
(match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))]
|
||||
""
|
||||
"@
|
||||
* current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
|
||||
* current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
|
||||
* current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
|
||||
mov.ne %0,%1
|
||||
mov.ne %0,%S1"
|
||||
[(set_attr "type" "cmove,cmove,cmove")
|
||||
(set_attr "iscompact" "true,false,false")
|
||||
(set_attr "length" "2,4,8")])
|
||||
[(set_attr "type" "cmove")
|
||||
(set_attr "iscompact" "true,true,true_limm,false,false")
|
||||
(set_attr "length" "2,2,6,4,8")
|
||||
(set_attr "cpu_facility" "*,av2,av2,*,*")])
|
||||
|
||||
(define_insn "*movsi_cond_exec"
|
||||
[(cond_exec
|
||||
|
@ -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.")
|
||||
|
@ -184,95 +184,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"
|
||||
|
Loading…
Reference in New Issue
Block a user