Commit ceaaa9fe by Joern Rennecke Committed by Joern Rennecke

arc.h (SYMBOL_FLAG_CMEM): Define.

2016-04-28  Joern Rennecke  <joern.rennecke@embecosm.com>
            Andrew Burgess  <andrew.burgess@embecosm.com>
gcc:
        * config/arc/arc.h (SYMBOL_FLAG_CMEM): Define.
        (TARGET_NPS_CMEM_DEFAULT): Provide default definition.
        * config/arc/arc.c (arc_address_cost): Return 0 for cmem_address.
        (arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated.
        * config/arc/arc.opt (mcmem): New option.
        * config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative,
        supply length for r/m alternative.
        (*extendqisi2_ac): Likewise.
        (*extendhisi2_i): Add r/Uex alternative, supply length for r/m and
        r/Uex alternative.
        (movqi_insn): Add r/Ucm and Ucm/?Rac alternatives.
        (movhi_insn): Likewise.
        (movsi_insn): Add r/Ucm,Ucm/w alternatives.
        (*zero_extendqihi2_i): Add r/Ucm alternative.
        (*zero_extendqisi2_ac): Likewise.
        (*zero_extendhisi2_i): Likewise.
        * config/arc/constraints.md (Uex): New memory constraint.
        (Ucm): New define_constraint.
        * config/arc/predicates.md (long_immediate_loadstore_operand):
        Return 0 for MEM with cmem_address address.
        (cmem_address_0): New predicates.
        (cmem_address_1): Likewise.
        (cmem_address_2): Likewise.
        (cmem_address): Likewise.
gcc/testsuite:
        * gcc.target/arc/cmem-1.c: New file.
        * gcc.target/arc/cmem-2.c: New file.
        * gcc.target/arc/cmem-3.c: New file.
        * gcc.target/arc/cmem-4.c: New file.
        * gcc.target/arc/cmem-5.c: New file.
        * gcc.target/arc/cmem-6.c: New file.
        * gcc.target/arc/cmem-7.c: New file.
        * gcc.target/arc/cmem-ld.inc: New file.
        * gcc.target/arc/cmem-st.inc: New file.

Co-Authored-By: Andrew Burgess <andrew.burgess@embecosm.com>

From-SVN: r235595
parent dc236a9d
2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com>
Andrew Burgess <andrew.burgess@embecosm.com>
* config/arc/arc.c (arc_conditional_register_usage): Take
TARGET_RRQ_CLASS into account.
(arc_print_operand): Support printing 'p' and 's' operands.
* config/arc/arc.h (TARGET_NPS_BITOPS_DEFAULT): Provide default
as 0.
(TARGET_RRQ_CLASS): Define.
(IS_POWEROF2_OR_0_P): Define.
* config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi
alternatives.
(*tst_movb): New define_insn.
(*tst): Avoid recognition if it could prevent '*tst_movb'
combination; replace c/CnL with c/Chs alternative.
(*tst_bitfield_tst): New define_insn.
(*tst_bitfield_asr): New define_insn.
(*tst_bitfield): New define_insn.
(andsi3_i): Add Rrq variant.
(extzv): New define_expand.
(insv): New define_expand.
(*insv_i): New define_insn.
(*movb): New define_insn.
(*movb_signed): New define_insn.
(*movb_high): New define_insn.
(*movb_high_signed): New define_insn.
(*movb_high_signed + 1): New define_split pattern.
(*mrgb): New define_insn.
(*mrgb + 1): New define_peephole2 pattern.
(*mrgb + 2): New define_peephole2 pattern.
* config/arc/arc.opt (mbitops): New option for nps400, uses
TARGET_NPS_BITOPS_DEFAULT.
* config/arc/constraints.md (q): Make register class conditional.
(Rrq): New register constraint.
(Chs): New constraint.
(Clo): New constraint.
(Chi): New constraint.
(Cbf): New constraint.
(Cbn): New constraint.
(C18): New constraint.
(Cbi): New constraint.
2016-04-28 Segher Boessenkool <segher@kernel.crashing.org> 2016-04-28 Segher Boessenkool <segher@kernel.crashing.org>
* cfganal.c (bitmap_intersection_of_succs): Delete assert checking * cfganal.c (bitmap_intersection_of_succs): Delete assert checking
......
...@@ -1430,7 +1430,8 @@ arc_conditional_register_usage (void) ...@@ -1430,7 +1430,8 @@ arc_conditional_register_usage (void)
{ {
if (i < 29) if (i < 29)
{ {
if (TARGET_Q_CLASS && ((i <= 3) || ((i >= 12) && (i <= 15)))) if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
&& ((i <= 3) || ((i >= 12) && (i <= 15))))
arc_regno_reg_class[i] = ARCOMPACT16_REGS; arc_regno_reg_class[i] = ARCOMPACT16_REGS;
else else
arc_regno_reg_class[i] = GENERAL_REGS; arc_regno_reg_class[i] = GENERAL_REGS;
...@@ -1447,12 +1448,12 @@ arc_conditional_register_usage (void) ...@@ -1447,12 +1448,12 @@ arc_conditional_register_usage (void)
arc_regno_reg_class[i] = NO_REGS; arc_regno_reg_class[i] = NO_REGS;
} }
/* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS has not been activated. */ /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
has not been activated. */
if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
if (!TARGET_Q_CLASS) if (!TARGET_Q_CLASS)
{ CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
}
gcc_assert (FIRST_PSEUDO_REGISTER >= 144); gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
...@@ -2994,6 +2995,8 @@ static int output_scaled = 0; ...@@ -2994,6 +2995,8 @@ static int output_scaled = 0;
'Z': log2(x+1)-1 'Z': log2(x+1)-1
'z': log2 'z': log2
'M': log2(~x) 'M': log2(~x)
'p': bit Position of lsb
's': size of bit field
'#': condbranch delay slot suffix '#': condbranch delay slot suffix
'*': jump delay slot suffix '*': jump delay slot suffix
'?' : nonjump-insn suffix for conditional execution or short instruction '?' : nonjump-insn suffix for conditional execution or short instruction
...@@ -3044,6 +3047,24 @@ arc_print_operand (FILE *file, rtx x, int code) ...@@ -3044,6 +3047,24 @@ arc_print_operand (FILE *file, rtx x, int code)
return; return;
case 'p':
if (GET_CODE (x) == CONST_INT)
fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
else
output_operand_lossage ("invalid operand to %%p code");
return;
case 's':
if (GET_CODE (x) == CONST_INT)
{
HOST_WIDE_INT i = INTVAL (x);
HOST_WIDE_INT s = exact_log2 (i & -i);
fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
}
else
output_operand_lossage ("invalid operand to %%s code");
return;
case '#' : case '#' :
/* Conditional branches depending on condition codes. /* Conditional branches depending on condition codes.
Note that this is only for branches that were known to depend on Note that this is only for branches that were known to depend on
......
...@@ -326,10 +326,18 @@ along with GCC; see the file COPYING3. If not see ...@@ -326,10 +326,18 @@ along with GCC; see the file COPYING3. If not see
#define UNALIGNED_ACCESS_DEFAULT 0 #define UNALIGNED_ACCESS_DEFAULT 0
#endif #endif
#ifndef TARGET_NPS_BITOPS_DEFAULT
#define TARGET_NPS_BITOPS_DEFAULT 0
#endif
#ifndef TARGET_NPS_CMEM_DEFAULT #ifndef TARGET_NPS_CMEM_DEFAULT
#define TARGET_NPS_CMEM_DEFAULT 0 #define TARGET_NPS_CMEM_DEFAULT 0
#endif #endif
/* Enable the RRQ instruction alternatives. */
#define TARGET_RRQ_CLASS TARGET_NPS_BITOPS
/* Target machine storage layout. */ /* Target machine storage layout. */
/* We want zero_extract to mean the same /* We want zero_extract to mean the same
...@@ -1033,6 +1041,7 @@ extern int arc_initial_elimination_offset(int from, int to); ...@@ -1033,6 +1041,7 @@ extern int arc_initial_elimination_offset(int from, int to);
/* Is the argument a const_int rtx, containing an exact power of 2 */ /* Is the argument a const_int rtx, containing an exact power of 2 */
#define IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X)) #define IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X))
#define IS_POWEROF2_OR_0_P(X) (! ( (X) & ((X) - 1)))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class. and check its validity for a certain class.
......
...@@ -700,8 +700,8 @@ ...@@ -700,8 +700,8 @@
; insns it should lengthen the return insn. ; insns it should lengthen the return insn.
; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
(define_insn "*movsi_insn" (define_insn "*movsi_insn"
[(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w, w,???w, ?w, w,Rcq#q, w,Rcq, S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc") [(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,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))] (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"))]
"register_operand (operands[0], SImode) "register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode) || register_operand (operands[1], SImode)
|| (CONSTANT_P (operands[1]) || (CONSTANT_P (operands[1])
...@@ -716,29 +716,32 @@ ...@@ -716,29 +716,32 @@
mov%? %0,%1 ;3 mov%? %0,%1 ;3
mov%? %0,%1 ;4 mov%? %0,%1 ;4
ror %0,((%1*2+1) & 0x3f) ;5 ror %0,((%1*2+1) & 0x3f) ;5
mov%? %0,%1 ;6 movl.cl %0,%1 ;6
add %0,%S1 ;7 movh.cl %0,%L1>>16 ;7
* 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
* return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\"; * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
mov%? %0,%S1%& ;9 mov%? %0,%S1%& ;12
mov%? %0,%S1 ;10 mov%? %0,%S1 ;13
ld%? %0,%1%& ;11 ld%? %0,%1%& ;14
st%? %1,%0%& ;12 st%? %1,%0%& ;15
* return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
* return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
ld%? %0,%1%& ;15 ld%? %0,%1%& ;18
xld%U1 %0,%1 ;16 xld%U1 %0,%1 ;19
ld%U1%V1 %0,%1 ;17 ld%U1%V1 %0,%1 ;20
xst%U0 %1,%0 ;18 xst%U0 %1,%0 ;21
st%U0%V0 %1,%0 ;19 st%U0%V0 %1,%0 ;22
st%U0%V0 %1,%0 ;20 st%U0%V0 %1,%0 ;23
st%U0%V0 %S1,%0 ;21" st%U0%V0 %S1,%0 ;24"
[(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store") [(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,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false") (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")
; Use default length for iscompact to allow for COND_EXEC. But set length ; Use default length for iscompact to allow for COND_EXEC. But set length
; of Crr to 4. ; of Crr to 4.
(set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8") (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,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no") (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 "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
;; Sometimes generated by the epilogue code. We don't want to ;; Sometimes generated by the epilogue code. We don't want to
;; recognize these addresses in general, because the limm is costly, ;; recognize these addresses in general, because the limm is costly,
...@@ -809,6 +812,24 @@ ...@@ -809,6 +812,24 @@
(set_attr "cond" "set_zn") (set_attr "cond" "set_zn")
(set_attr "length" "4")]) (set_attr "length" "4")])
; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
; even if we don't need the clobber.
(define_insn_and_split "*tst_movb"
[(set
(match_operand 0 "cc_register" "")
(match_operator 4 "zn_compare_operator"
[(and:SI
(match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c")
(match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
(const_int 0)]))
(clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
"TARGET_NPS_BITOPS"
"movb.f.cl %3,%1,%p2,%p2,%s2"
"reload_completed
&& (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
[(set (match_dup 0) (match_dup 4))])
(define_insn "*tst" (define_insn "*tst"
[(set [(set
(match_operand 0 "cc_register" "") (match_operand 0 "cc_register" "")
...@@ -817,12 +838,14 @@ ...@@ -817,12 +838,14 @@
(match_operand:SI 1 "register_operand" (match_operand:SI 1 "register_operand"
"%Rcq,Rcq, c, c, c, c, c, c") "%Rcq,Rcq, c, c, c, c, c, c")
(match_operand:SI 2 "nonmemory_operand" (match_operand:SI 2 "nonmemory_operand"
" Rcq,C0p,cI,cL,C1p,Ccp,CnL,Cal")) " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
(const_int 0)]))] (const_int 0)]))]
"(register_operand (operands[1], SImode) "reload_completed
&& nonmemory_operand (operands[2], SImode)) || !satisfies_constraint_Cbf (operands[2])
|| (memory_operand (operands[1], SImode) || satisfies_constraint_C0p (operands[2])
&& satisfies_constraint_Cux (operands[2]))" || satisfies_constraint_I (operands[2])
|| satisfies_constraint_C1p (operands[2])
|| satisfies_constraint_Chs (operands[2])"
"* "*
switch (which_alternative) switch (which_alternative)
{ {
...@@ -835,17 +858,79 @@ ...@@ -835,17 +858,79 @@
case 5: case 5:
return \"bclr%?.f 0,%1,%M2%&\"; return \"bclr%?.f 0,%1,%M2%&\";
case 6: case 6:
return \"bic%?.f 0,%1,%n2-1\"; return \"asr.f 0,%1,%p2\";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
" "
[(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false") [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
(set_attr "type" "compare") (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
(set_attr "length" "*,*,4,4,4,4,4,8") (set_attr "length" "*,*,4,4,4,4,4,8")
(set_attr "predicable" "no,yes,no,yes,no,no,no,yes") (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
(set_attr "cond" "set_zn")]) (set_attr "cond" "set_zn")])
; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
; combine will do that and not try the AND.
; It would take 66 constraint combinations to describe the zero_extract
; constants that are covered by the 12-bit signed constant for tst
; (excluding the ones that are better done by mov or btst).
; so we rather use an extra pattern for tst;
; since this is about constants, reload shouldn't care.
(define_insn "*tst_bitfield_tst"
[(set (match_operand:CC_ZN 0 "cc_set_register" "")
(match_operator 4 "zn_compare_operator"
[(zero_extract:SI
(match_operand:SI 1 "register_operand" "c")
(match_operand:SI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n"))
(const_int 0)]))]
"INTVAL (operands[2]) > 1
&& (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
|| (INTVAL (operands[3]) <= 11
&& INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
"tst %1,(1<<%2)-1<<%3"
[(set_attr "type" "compare")
(set_attr "cond" "set_zn")
(set_attr "length" "4")])
; Likewise for asr.f.
(define_insn "*tst_bitfield_asr"
[(set (match_operand:CC_ZN 0 "cc_set_register" "")
(match_operator 4 "zn_compare_operator"
[(zero_extract:SI
(match_operand:SI 1 "register_operand" "c")
(match_operand:SI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n"))
(const_int 0)]))]
"INTVAL (operands[2]) > 1
&& INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
"asr.f 0,%1,%3"
[(set_attr "type" "shift")
(set_attr "cond" "set_zn")
(set_attr "length" "4")])
(define_insn "*tst_bitfield"
[(set (match_operand:CC_ZN 0 "cc_set_register" "")
(match_operator 5 "zn_compare_operator"
[(zero_extract:SI
(match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c")
(match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n")
(match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
(const_int 0)]))
(clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
""
"@
btst%? %1,%3
btst %1,%3
bmsk.f 0,%1,%2-1
movb.f.cl %4,%1,%3,%3,%2
and.f 0,%1,((1<<%2)-1)<<%3"
[(set_attr "iscompact" "maybe,false,false,false,false")
(set_attr "type" "compare,compare,compare,shift,compare")
(set_attr "cond" "set_zn")
(set_attr "length" "*,4,4,4,8")])
(define_insn "*commutative_binary_comparison" (define_insn "*commutative_binary_comparison"
[(set (match_operand:CC_ZN 0 "cc_set_register" "") [(set (match_operand:CC_ZN 0 "cc_set_register" "")
(match_operator:CC_ZN 5 "zn_compare_operator" (match_operator:CC_ZN 5 "zn_compare_operator"
...@@ -2956,30 +3041,40 @@ ...@@ -2956,30 +3041,40 @@
operands[1] = arc_rewrite_small_data (operands[1]);") operands[1] = arc_rewrite_small_data (operands[1]);")
(define_insn "andsi3_i" (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,w,Rcw, w, W") [(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,0, 0, c, o") (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,I,Cal,Cal,Cux")))] (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")))]
"(register_operand (operands[1], SImode) "(register_operand (operands[1], SImode)
&& nonmemory_operand (operands[2], SImode)) && nonmemory_operand (operands[2], SImode))
|| (memory_operand (operands[1], SImode) || (memory_operand (operands[1], SImode)
&& satisfies_constraint_Cux (operands[2]))" && satisfies_constraint_Cux (operands[2]))"
"*
{ {
switch (which_alternative) switch (which_alternative)
{ {
case 0: case 5: case 10: case 11: case 15: case 16: case 17: case 0: case 5: case 10: case 11: case 16: case 17: case 18:
return \"and%? %0,%1,%2%&\"; return "and%? %0,%1,%2%&";
case 1: case 6: case 1: case 6:
return \"and%? %0,%2,%1%&\"; return "and%? %0,%2,%1%&";
case 2: case 7: case 12: case 2: case 7: case 12:
return \"bmsk%? %0,%1,%Z2%&\"; return "bmsk%? %0,%1,%Z2%&";
case 3: case 8: case 13: case 3: case 8: case 13:
return \"bclr%? %0,%1,%M2%&\"; return "bclr%? %0,%1,%M2%&";
case 4: case 4:
return (INTVAL (operands[2]) == 0xff return (INTVAL (operands[2]) == 0xff
? \"extb%? %0,%1%&\" : \"ext%_%? %0,%1%&\"); ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
case 9: case 14: return \"bic%? %0,%1,%n2-1\"; case 9: case 14: return \"bic%? %0,%1,%n2-1\";
case 18: case 15:
return "movb.cl %0,%1,%p2,%p2,%s2";
case 19:
const char *tmpl;
if (satisfies_constraint_Ucm (operands[1]))
tmpl = (INTVAL (operands[2]) == 0xff
? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
else
tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
if (TARGET_BIG_ENDIAN) if (TARGET_BIG_ENDIAN)
{ {
rtx xop[2]; rtx xop[2];
...@@ -2987,21 +3082,19 @@ ...@@ -2987,21 +3082,19 @@
xop[0] = operands[0]; xop[0] = operands[0];
xop[1] = adjust_address (operands[1], QImode, xop[1] = adjust_address (operands[1], QImode,
INTVAL (operands[2]) == 0xff ? 3 : 2); INTVAL (operands[2]) == 0xff ? 3 : 2);
output_asm_insn (INTVAL (operands[2]) == 0xff output_asm_insn (tmpl, xop);
? \"ldb %0,%1\" : \"ld%_ %0,%1\", return "";
xop);
return \"\";
} }
return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ld%_ %0,%1\"; return tmpl;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
}" }
[(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false") [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
(set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load") (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
(set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*") (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
(set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no") (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
(set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")]) (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
; combiner splitter, pattern found in ldtoa.c . ; combiner splitter, pattern found in ldtoa.c .
; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
...@@ -5717,7 +5810,6 @@ ...@@ -5717,7 +5810,6 @@
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "type" "misc")]) (set_attr "type" "misc")])
;; FPU/FPX expands ;; FPU/FPX expands
;;add ;;add
...@@ -5862,6 +5954,196 @@ ...@@ -5862,6 +5954,196 @@
gcc_unreachable (); gcc_unreachable ();
") ")
(define_expand "extzv"
[(set (match_operand:SI 0 "register_operand" "")
(zero_extract:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"TARGET_NPS_BITOPS")
; We need a sanity check in the instuction predicate because combine
; will throw any old rubbish at us and see what sticks.
(define_insn "*extzv_i"
[(set (match_operand:SI 0 "register_operand" "=Rrq")
(zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
(match_operand:SI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n")))]
"TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
"movb.cl %0,%1,0,%3,%2"
[(set_attr "type" "shift")
(set_attr "length" "4")])
(define_expand "insv"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "nonmemory_operand" ""))]
"TARGET_NPS_BITOPS"
{
int size = INTVAL (operands[1]);
if (size != 1 && size != 2 && size != 4 && size != 8)
operands[3] = force_reg (SImode, operands[3]);
})
(define_insn "*insv_i"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
(match_operand:SI 1 "const_int_operand" "C18,n")
(match_operand:SI 2 "const_int_operand" "n,n"))
(match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
"TARGET_NPS_BITOPS
&& (register_operand (operands[3], SImode)
|| satisfies_constraint_C18 (operands[1]))"
"@
movbi %0,%0,%3,%2,%1
movb %0,%0,%3,%2,0,%1"
[(set_attr "type" "shift")
(set_attr "length" "4")])
(define_insn "*movb"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
(match_dup 1)
(match_operand:SI 4 "const_int_operand" "n")))]
"TARGET_NPS_BITOPS"
"movb %0,%0,%3,%2,%4,%1"
[(set_attr "type" "shift")
(set_attr "length" "4")])
(define_insn "*movb_signed"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
(match_dup 1)
(match_operand:SI 4 "const_int_operand" "n")))]
"TARGET_NPS_BITOPS"
"movb %0,%0,%3,%2,%4,%1"
[(set_attr "type" "shift")
(set_attr "length" "4")])
(define_insn "*movb_high"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
(match_operand:SI 4 "const_int_operand" "n")))]
"TARGET_NPS_BITOPS
&& INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
"movb %0,%0,%3,%2,%4,%1"
[(set_attr "type" "shift")
(set_attr "length" "4")])
; N.B.: when processing signed bitfields that fit in the top half of
; a word, gcc will use a narrow sign extending load, and in this case
; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
(define_insn "*movb_high_signed"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
(match_operand:SI 4 "const_int_operand" "n")))]
"TARGET_NPS_BITOPS
&& INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
"movb %0,%0,%3,%2,%4,%1"
[(set_attr "type" "shift")
(set_attr "length" "4")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(subreg:SI (match_operand 3 "") 0)))]
"TARGET_NPS_BITOPS
&& GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
&& !reg_overlap_mentioned_p (operands[0], operands[1])"
[(set (match_dup 0) (zero_extend:SI (match_dup 3)))
(set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
(match_dup 1))]
"operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
(define_insn "*mrgb"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(zero_extract:SI (match_dup 0) (match_dup 1)
(match_operand:SI 3 "const_int_operand" "n")))
(set (zero_extract:SI (match_dup 0)
(match_operand:SI 4 "const_int_operand" "n")
(match_operand:SI 5 "const_int_operand" "n"))
(zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
(match_dup 4)
(match_operand:SI 7 "const_int_operand" "n")))]
"TARGET_NPS_BITOPS"
{
output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
/* The ;%? updates the known unalignment. */
return arc_short_long (insn, ";%?", "nop_s");
}
[(set_attr "type" "shift")
(set_attr "length" "6")
(set_attr "iscompact" "true")])
;; combine fumbles combination of two movb patterns, and then the
;; combination is rejected by combinable_i3pat.
;; Thus, we can only use a peephole2 to combine two such insns.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" ""))
(set (zero_extract:SI (match_dup 0)
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" ""))
(zero_extract:SI (match_dup 1)
(match_dup 2)
(match_operand:SI 4 "const_int_operand" "")))
(match_operand 9) ; unrelated insn scheduled here
(set (zero_extract:SI (match_dup 0)
(match_operand:SI 5 "const_int_operand" "")
(match_operand:SI 6 "const_int_operand" ""))
(zero_extract:SI (match_operand:SI 7 "register_operand" "")
(match_dup 5)
(match_operand:SI 8 "const_int_operand" "")))]
"TARGET_NPS_BITOPS
// Check that the second movb doesn't clobber an input of the extra insn.
&& !reg_overlap_mentioned_p (operands[0], operands[9])
// And vice versa.
&& !reg_set_p (operands[0], operands[9])
&& !reg_set_p (operands[7], operands[9])"
[(set (match_dup 0) (match_dup 1))
(parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
(zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
(zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
(match_dup 9)])
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" ""))
(set (zero_extract:SI (match_dup 0)
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" ""))
(zero_extract:SI (match_dup 1)
(match_dup 2)
(match_operand:SI 4 "const_int_operand" "")))
(set (match_dup 1) (match_operand 8))
(set (zero_extract:SI (match_dup 0)
(match_operand:SI 5 "const_int_operand" "")
(match_operand:SI 6 "const_int_operand" ""))
(zero_extract:SI (match_dup 1) (match_dup 5)
(match_operand:SI 7 "const_int_operand" "")))]
"TARGET_NPS_BITOPS
&& !reg_overlap_mentioned_p (operands[0], operands[8])"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 1) (match_dup 8))
(parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
(zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
(set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
(zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
(match_dup 1)])
;; include the arc-FPX instructions ;; include the arc-FPX instructions
(include "fpx.md") (include "fpx.md")
......
...@@ -470,6 +470,10 @@ Specify thread pointer register number ...@@ -470,6 +470,10 @@ Specify thread pointer register number
mtp-regno=none mtp-regno=none
Target RejectNegative Var(arc_tp_regno,-1) Target RejectNegative Var(arc_tp_regno,-1)
mbitops
Target Report Var(TARGET_NPS_BITOPS) Init(TARGET_NPS_BITOPS_DEFAULT)
Enable use of NPS400 bit operations.
mcmem mcmem
Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT) Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT)
Enable use of NPS400 xld/xst extension. Enable use of NPS400 xld/xst extension.
......
...@@ -66,10 +66,18 @@ ...@@ -66,10 +66,18 @@
Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30}, Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30},
@code{blink}:@code{r31},") @code{blink}:@code{r31},")
(define_register_constraint "q" "ARCOMPACT16_REGS" (define_register_constraint "q" "TARGET_Q_CLASS ? ARCOMPACT16_REGS : NO_REGS"
"Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3}, "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
@code{r12}-@code{r15}") @code{r12}-@code{r15}")
; NPS400 bitfield instructions require registers from the r0-r3,r12-r15
; range, and thus we need a register class and constraint that works
; independently of size optimization.
(define_register_constraint
"Rrq" "TARGET_RRQ_CLASS ? ARCOMPACT16_REGS : NO_REGS"
"Registers usable in NPS400 bitfield instructions: @code{r0}-@code{r3},
@code{r12}-@code{r15}")
(define_register_constraint "e" "AC16_BASE_REGS" (define_register_constraint "e" "AC16_BASE_REGS"
"Registers usable as base-regs of memory addresses in ARCompact 16-bit memory "Registers usable as base-regs of memory addresses in ARCompact 16-bit memory
instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}") instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}")
...@@ -236,12 +244,60 @@ ...@@ -236,12 +244,60 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "ival == 0xff || ival == 0xffff"))) (match_test "ival == 0xff || ival == 0xffff")))
(define_constraint "Chs"
"@internal
constant for a highpart that can be checked with a shift (asr.f 0,rn,m)"
(and (match_code "const_int")
(match_test "IS_POWEROF2_P (-ival)")))
(define_constraint "Clo"
"@internal
constant that fits into 16 lower bits, for movl"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "(ival & ~0xffffU) == 0")))
(define_constraint "Chi"
"@internal
constant that fits into 16 higher bits, for movh_i"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "trunc_int_for_mode (ival >> 16, HImode) << 16 == ival")))
(define_constraint "Cbf"
"@internal
a mask for a bit field, for AND using movb_i"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "IS_POWEROF2_OR_0_P (ival + (ival & -ival))")))
(define_constraint "Cbn"
"@internal
a constant integer, valid only if TARGET_NPS_BITOPS is true"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")))
(define_constraint "C18"
"@internal
1,2,4 or 8"
(and (match_code "const_int")
(match_test "ival == 1 || ival == 2 || ival == 4 || ival == 8")))
(define_constraint "Crr" (define_constraint "Crr"
"@internal "@internal
constant that can be loaded with ror b,u6" constant that can be loaded with ror b,u6"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()"))) (match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()")))
(define_constraint "Cbi"
"@internal
constant that can be loaded with movbi.cl"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "!ival
|| ((ival & 0xffffffffUL) >> exact_log2 (ival & -ival)
<= 0xff)")))
;; Floating-point constraints ;; Floating-point constraints
(define_constraint "G" (define_constraint "G"
......
2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com> 2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com>
Andrew Burgess <andrew.burgess@embecosm.com> Andrew Burgess <andrew.burgess@embecosm.com>
* gcc.target/arc/extzv-1.c: New file.
* gcc.target/arc/insv-1.c: New file.
* gcc.target/arc/insv-2.c: New file.
* gcc.target/arc/movb-1.c: New file.
* gcc.target/arc/movb-2.c: New file.
* gcc.target/arc/movb-3.c: New file.
* gcc.target/arc/movb-4.c: New file.
* gcc.target/arc/movb-5.c: New file.
* gcc.target/arc/movb_cl-1.c: New file.
* gcc.target/arc/movb_cl-2.c: New file.
* gcc.target/arc/movbi_cl-1.c: New file.
* gcc.target/arc/movl-1.c: New file.
2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com>
Andrew Burgess <andrew.burgess@embecosm.com>
* gcc.target/arc/cmem-1.c: New file. * gcc.target/arc/cmem-1.c: New file.
* gcc.target/arc/cmem-2.c: New file. * gcc.target/arc/cmem-2.c: New file.
* gcc.target/arc/cmem-3.c: New file. * gcc.target/arc/cmem-3.c: New file.
......
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct foo { unsigned a: 3, b: 5, c: 24; };
int
f (struct foo i)
{
return i.b;
}
/* { dg-final { scan-assembler "movb\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
/* ??? Irrespective of insn set, generated code for this is a mess. */
struct foo { unsigned a: 3, b: 8, c: 21; };
struct foo
f (struct foo i)
{
i.b = 42;
return i;
}
struct foo
g (struct foo i, int j)
{
i.b = j;
return i;
}
/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
/* { dg-final { scan-assembler "movb\[ \t\]" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct foo { unsigned a: 3, b: 8, c: 21; } bar;
void
f (void)
{
bar.b = 42;
}
void
g (int j)
{
bar.b = j;
}
/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
/* { dg-final { scan-assembler "movb\[ \t\]" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { unsigned a: 5, b: 8, c: 19; } foo;
struct { unsigned a: 3, b: 8, c: 21; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { unsigned a: 23, b: 9; } foo;
struct { unsigned a: 23, b: 9; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { int a: 23, b: 9; } foo;
struct { int a: 23, b: 9; } bar;
void
f (void)
{
bar.a = foo.a;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *23" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *9, *9, *23" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { int a: 13, b: 19; } foo;
struct { int a: 13, b: 19; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *13, *13, *19" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *19" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { int a: 23, b: 9; } foo;
struct { int a: 23, b: 9; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
int
f (int i)
{
return i & 0x0ffff000;
}
/* { dg-final { scan-assembler "movb\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
extern void g (void);
int
f (int i)
{
if (i & 0x0ffff000)
g ();
}
/* { dg-final { scan-assembler "movb\.f\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
int
f (int i)
{
return 0x6e00;
}
/* { dg-final { scan-assembler "mov(bi|l)\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
int
f (void)
{
return 0xd00d;
}
int
g (void)
{
return 0x7ff00000;
}
/* { dg-final { scan-assembler "movl\.cl\[ \t\]" } } */
/* { dg-final { scan-assembler "movh\.cl\[ \t\]" } } */
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