@@ -249,9 +249,10 @@ expand_ccmp_expr (gimple *g)
enum insn_code icode;
enum machine_mode cc_mode = CCmode;
tree lhs = gimple_assign_lhs (g);
+ enum rtx_code cmp_code = GET_CODE (tmp);
#ifdef SELECT_CC_MODE
- cc_mode = SELECT_CC_MODE (NE, tmp, const0_rtx);
+ cc_mode = SELECT_CC_MODE (cmp_code, XEXP (tmp, 0), const0_rtx);
#endif
icode = optab_handler (cstore_optab, cc_mode);
if (icode != CODE_FOR_nothing)
@@ -262,8 +263,8 @@ expand_ccmp_expr (gimple *g)
emit_insn (prep_seq);
emit_insn (gen_seq);
- tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode,
- 0, tmp, const0_rtx, 1, mode);
+ tmp = emit_cstore (target, icode, cmp_code, cc_mode, cc_mode,
+ 0, XEXP (tmp, 0), const0_rtx, 1, mode);
if (tmp)
return tmp;
}
b/gcc/config/aarch64/aarch64-modes.def
@@ -25,16 +25,6 @@ CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make
it RHS). */
CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS). */
CC_MODE (CC_NZ); /* Only N and Z bits of condition flags are valid. */
CC_MODE (CC_Z); /* Only Z bit of condition flags is valid. */
-CC_MODE (CC_DNE);
-CC_MODE (CC_DEQ);
-CC_MODE (CC_DLE);
-CC_MODE (CC_DLT);
-CC_MODE (CC_DGE);
-CC_MODE (CC_DGT);
-CC_MODE (CC_DLEU);
-CC_MODE (CC_DLTU);
-CC_MODE (CC_DGEU);
-CC_MODE (CC_DGTU);
/* Half-precision floating point for __fp16. */
FLOAT_MODE (HF, 2, 0);
@@ -3907,7 +3907,6 @@ aarch64_get_condition_code (rtx x)
static int
aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code
comp_code)
{
- int ne = -1, eq = -1;
switch (mode)
{
case CCFPmode:
@@ -3930,56 +3929,6 @@ aarch64_get_condition_code_1 (enum machine_mode mode,
enum rtx_code comp_code)
}
break;
- case CC_DNEmode:
- ne = AARCH64_NE;
- eq = AARCH64_EQ;
- break;
-
- case CC_DEQmode:
- ne = AARCH64_EQ;
- eq = AARCH64_NE;
- break;
-
- case CC_DGEmode:
- ne = AARCH64_GE;
- eq = AARCH64_LT;
- break;
-
- case CC_DLTmode:
- ne = AARCH64_LT;
- eq = AARCH64_GE;
- break;
-
- case CC_DGTmode:
- ne = AARCH64_GT;
- eq = AARCH64_LE;
- break;
-
- case CC_DLEmode:
- ne = AARCH64_LE;
- eq = AARCH64_GT;
- break;
-
- case CC_DGEUmode:
- ne = AARCH64_CS;
- eq = AARCH64_CC;
- break;
-
- case CC_DLTUmode:
- ne = AARCH64_CC;
- eq = AARCH64_CS;
- break;
-
- case CC_DGTUmode:
- ne = AARCH64_HI;
- eq = AARCH64_LS;
- break;
-
- case CC_DLEUmode:
- ne = AARCH64_LS;
- eq = AARCH64_HI;
- break;
-
case CCmode:
switch (comp_code)
{
@@ -4041,12 +3990,6 @@ aarch64_get_condition_code_1 (enum machine_mode mode,
enum rtx_code comp_code)
break;
}
- if (comp_code == NE)
- return ne;
-
- if (comp_code == EQ)
- return eq;
-
return -1;
}
@@ -4087,69 +4030,27 @@ aarch64_const_vec_all_same_int_p (rtx x,
HOST_WIDE_INT val)
#define AARCH64_CC_Z (1 << 2)
#define AARCH64_CC_N (1 << 3)
-/* N Z C V flags for ccmp. The first code is for AND op and the other
- is for IOR op. Indexed by AARCH64_COND_CODE. */
-static const int aarch64_nzcv_codes[][2] =
-{
- {AARCH64_CC_Z, 0}, /* EQ, Z == 1. */
- {0, AARCH64_CC_Z}, /* NE, Z == 0. */
- {AARCH64_CC_C, 0}, /* CS, C == 1. */
- {0, AARCH64_CC_C}, /* CC, C == 0. */
- {AARCH64_CC_N, 0}, /* MI, N == 1. */
- {0, AARCH64_CC_N}, /* PL, N == 0. */
- {AARCH64_CC_V, 0}, /* VS, V == 1. */
- {0, AARCH64_CC_V}, /* VC, V == 0. */
- {AARCH64_CC_C, 0}, /* HI, C ==1 && Z == 0. */
- {0, AARCH64_CC_C}, /* LS, !(C == 1 && Z == 0). */
- {0, AARCH64_CC_V}, /* GE, N == V. */
- {AARCH64_CC_V, 0}, /* LT, N != V. */
- {0, AARCH64_CC_Z}, /* GT, Z == 0 && N == V. */
- {AARCH64_CC_Z, 0}, /* LE, !(Z == 0 && N == V). */
- {0, 0}, /* AL, Any. */
- {0, 0}, /* NV, Any. */
+/* N Z C V flags for ccmp. Indexed by AARCH64_COND_CODE. */
+static const int aarch64_nzcv_codes[] =
+{
+ 0, /* EQ, Z == 1. */
+ AARCH64_CC_Z, /* NE, Z == 0. */
+ 0, /* CS, C == 1. */
+ AARCH64_CC_C, /* CC, C == 0. */
+ 0, /* MI, N == 1. */
+ AARCH64_CC_N, /* PL, N == 0. */
+ 0, /* VS, V == 1. */
+ AARCH64_CC_V, /* VC, V == 0. */
+ 0, /* HI, C ==1 && Z == 0. */
+ AARCH64_CC_C, /* LS, !(C == 1 && Z == 0). */
+ AARCH64_CC_V, /* GE, N == V. */
+ 0, /* LT, N != V. */
+ AARCH64_CC_Z, /* GT, Z == 0 && N == V. */
+ 0, /* LE, !(Z == 0 && N == V). */
+ 0, /* AL, Any. */
+ 0 /* NV, Any. */
};
-int
-aarch64_ccmp_mode_to_code (enum machine_mode mode)
-{
- switch (mode)
- {
- case CC_DNEmode:
- return NE;
-
- case CC_DEQmode:
- return EQ;
-
- case CC_DLEmode:
- return LE;
-
- case CC_DGTmode:
- return GT;
-
- case CC_DLTmode:
- return LT;
-
- case CC_DGEmode:
- return GE;
-
- case CC_DLEUmode:
- return LEU;
-
- case CC_DGTUmode:
- return GTU;
-
- case CC_DLTUmode:
- return LTU;
-
- case CC_DGEUmode:
- return GEU;
-
- default:
- gcc_unreachable ();
- }
-}
-
-
void
aarch64_print_operand (FILE *f, rtx x, char code)
{
@@ -4248,36 +4149,17 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]);
break;
- case 'm':
- {
- int cond_code;
- /* Print a condition (eq, ne, etc). */
-
- /* CONST_TRUE_RTX means always -- that's the default. */
- if (x == const_true_rtx)
- return;
-
- if (!COMPARISON_P (x))
- {
- output_operand_lossage ("invalid operand for '%%%c'", code);
- return;
- }
-
- cond_code = aarch64_get_condition_code (x);
- gcc_assert (cond_code >= 0);
- fputs (aarch64_condition_codes[cond_code], f);
- }
- break;
-
case 'M':
+ case 'm':
{
int cond_code;
- /* Print the inverse of a condition (eq <-> ne, etc). */
+ /* Print a condition (eq, ne, etc) or its inverse. */
- /* CONST_TRUE_RTX means never -- that's the default. */
- if (x == const_true_rtx)
+ /* CONST_TRUE_RTX means al/nv (al is the default, don't print it).
*/
+ if (x == const_true_rtx)
{
- fputs ("nv", f);
+ if (code == 'M')
+ fputs ("nv", f);
return;
}
@@ -4286,10 +4168,12 @@ aarch64_print_operand (FILE *f, rtx x, char code)
output_operand_lossage ("invalid operand for '%%%c'", code);
return;
}
+
cond_code = aarch64_get_condition_code (x);
gcc_assert (cond_code >= 0);
- fputs (aarch64_condition_codes[AARCH64_INVERSE_CONDITION_CODE
- (cond_code)], f);
+ if (code == 'M')
+ cond_code = AARCH64_INVERSE_CONDITION_CODE (cond_code);
+ fputs (aarch64_condition_codes[cond_code], f);
}
break;
@@ -4533,37 +4417,20 @@ aarch64_print_operand (FILE *f, rtx x, char code)
output_addr_const (asm_out_file, x);
break;
- case 'K':
- {
- int cond_code;
- /* Print nzcv. */
-
- if (!COMPARISON_P (x))
- {
- output_operand_lossage ("invalid operand for '%%%c'", code);
- return;
- }
-
- cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x));
- gcc_assert (cond_code >= 0);
- asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][0]);
- }
- break;
-
case 'k':
{
- int cond_code;
+ HOST_WIDE_INT cond_code;
/* Print nzcv. */
- if (!COMPARISON_P (x))
+ if (!CONST_INT_P (x))
{
output_operand_lossage ("invalid operand for '%%%c'", code);
return;
}
- cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x));
- gcc_assert (cond_code >= 0);
- asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][1]);
+ cond_code = INTVAL (x);
+ gcc_assert (cond_code >= 0 && cond_code <= AARCH64_NV);
+ asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code]);
}
break;
@@ -12502,60 +12369,16 @@ aarch64_use_by_pieces_infrastructure_p (unsigned
HOST_WIDE_INT size,
return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
}
-static enum machine_mode
-aarch64_code_to_ccmode (enum rtx_code code)
-{
- switch (code)
- {
- case NE:
- return CC_DNEmode;
-
- case EQ:
- return CC_DEQmode;
-
- case LE:
- return CC_DLEmode;
-
- case LT:
- return CC_DLTmode;
-
- case GE:
- return CC_DGEmode;
-
- case GT:
- return CC_DGTmode;
-
- case LEU:
- return CC_DLEUmode;
-
- case LTU:
- return CC_DLTUmode;
-
- case GEU:
- return CC_DGEUmode;
-
- case GTU:
- return CC_DGTUmode;
-
- default:
- return CCmode;
- }
-}
-
static rtx
aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
int code, tree treeop0, tree treeop1)
{
- enum machine_mode op_mode, cmp_mode, cc_mode;
- rtx op0, op1, cmp, target;
+ enum machine_mode op_mode, cmp_mode, cc_mode = CCmode;
+ rtx op0, op1;
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
enum insn_code icode;
struct expand_operand ops[4];
- cc_mode = aarch64_code_to_ccmode ((enum rtx_code) code);
- if (cc_mode == CCmode)
- return NULL_RTX;
-
start_sequence ();
expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
@@ -12582,8 +12405,8 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
return NULL_RTX;
}
- op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
- op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp);
+ op0 = prepare_operand (icode, op0, 0, op_mode, cmp_mode, unsignedp);
+ op1 = prepare_operand (icode, op1, 1, op_mode, cmp_mode, unsignedp);
if (!op0 || !op1)
{
end_sequence ();
@@ -12592,16 +12415,11 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx
*gen_seq,
*prep_seq = get_insns ();
end_sequence ();
- cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1);
- target = gen_rtx_REG (CCmode, CC_REGNUM);
-
- create_output_operand (&ops[0], target, CCmode);
- create_fixed_operand (&ops[1], cmp);
- create_fixed_operand (&ops[2], op0);
- create_fixed_operand (&ops[3], op1);
+ create_fixed_operand (&ops[0], op0);
+ create_fixed_operand (&ops[1], op1);
start_sequence ();
- if (!maybe_expand_insn (icode, 4, ops))
+ if (!maybe_expand_insn (icode, 2, ops))
{
end_sequence ();
return NULL_RTX;
@@ -12609,22 +12427,20 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx
*gen_seq,
*gen_seq = get_insns ();
end_sequence ();
- return gen_rtx_REG (cc_mode, CC_REGNUM);
+ return gen_rtx_fmt_ee ((enum rtx_code) code, cc_mode,
+ gen_rtx_REG (cc_mode, CC_REGNUM), const0_rtx);
}
static rtx
aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
tree treeop0, tree treeop1, int bit_code)
{
- rtx op0, op1, cmp0, cmp1, target;
- enum machine_mode op_mode, cmp_mode, cc_mode;
+ rtx op0, op1, target;
+ enum machine_mode op_mode, cmp_mode, cc_mode = CCmode;
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
- enum insn_code icode = CODE_FOR_ccmp_andsi;
+ enum insn_code icode;
struct expand_operand ops[6];
-
- cc_mode = aarch64_code_to_ccmode ((enum rtx_code) cmp_code);
- if (cc_mode == CCmode)
- return NULL_RTX;
+ int aarch64_cond;
push_to_sequence ((rtx_insn*) *prep_seq);
expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
@@ -12639,14 +12455,12 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx
*gen_seq, rtx prev, int cmp_code,
case HImode:
case SImode:
cmp_mode = SImode;
- icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_andsi
- : CODE_FOR_ccmp_iorsi;
+ icode = CODE_FOR_ccmpsi;
break;
case DImode:
cmp_mode = DImode;
- icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_anddi
- : CODE_FOR_ccmp_iordi;
+ icode = CODE_FOR_ccmpdi;
break;
default:
@@ -12665,15 +12479,23 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx
*gen_seq, rtx prev, int cmp_code,
end_sequence ();
target = gen_rtx_REG (cc_mode, CC_REGNUM);
- cmp1 = gen_rtx_fmt_ee ((enum rtx_code) cmp_code, cmp_mode, op0, op1);
- cmp0 = gen_rtx_fmt_ee (NE, cmp_mode, prev, const0_rtx);
+ aarch64_cond = aarch64_get_condition_code_1 (cc_mode,
+ (enum rtx_code) cmp_code);
- create_fixed_operand (&ops[0], prev);
+ if (bit_code != AND)
+ {
+ prev = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (prev),
+ GET_MODE (XEXP (prev, 0))),
+ VOIDmode, XEXP (prev, 0), const0_rtx);
+ aarch64_cond = AARCH64_INVERSE_CONDITION_CODE (aarch64_cond);
+ }
+
+ create_fixed_operand (&ops[0], XEXP (prev, 0));
create_fixed_operand (&ops[1], target);
create_fixed_operand (&ops[2], op0);
create_fixed_operand (&ops[3], op1);
- create_fixed_operand (&ops[4], cmp0);
- create_fixed_operand (&ops[5], cmp1);
+ create_fixed_operand (&ops[4], prev);
+ create_fixed_operand (&ops[5], GEN_INT (aarch64_cond));
push_to_sequence ((rtx_insn*) *gen_seq);
if (!maybe_expand_insn (icode, 6, ops))
@@ -12685,7 +12507,8 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq,
rtx prev, int cmp_code,
*gen_seq = get_insns ();
end_sequence ();
- return target;
+ return gen_rtx_fmt_ee ((enum rtx_code) cmp_code, VOIDmode, target,
+ const0_rtx);
}
#undef TARGET_GEN_CCMP_FIRST
@@ -261,18 +261,17 @@
""
"")
-(define_insn "ccmp_and<mode>"
- [(set (match_operand 1 "ccmp_cc_register" "")
- (compare
- (and:SI
+(define_insn "ccmp<mode>"
+ [(set (match_operand:CC 1 "cc_register" "")
+ (if_then_else:CC
(match_operator 4 "aarch64_comparison_operator"
- [(match_operand 0 "ccmp_cc_register" "")
+ [(match_operand 0 "cc_register" "")
(const_int 0)])
- (match_operator 5 "aarch64_comparison_operator"
- [(match_operand:GPI 2 "register_operand" "r,r,r")
- (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
- (const_int 0)))]
- "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE
(operands[5])"
+ (compare:CC
+ (match_operand:GPI 2 "register_operand" "r,r,r")
+ (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn"))
+ (match_operand 5 "immediate_operand")))]
+ ""
"@
ccmp\\t%<w>2, %<w>3, %k5, %m4
ccmp\\t%<w>2, %3, %k5, %m4
@@ -280,39 +279,6 @@
[(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
)
-(define_insn "ccmp_ior<mode>"
- [(set (match_operand 1 "ccmp_cc_register" "")
- (compare
- (ior:SI
- (match_operator 4 "aarch64_comparison_operator"
- [(match_operand 0 "ccmp_cc_register" "")
- (const_int 0)])
- (match_operator 5 "aarch64_comparison_operator"
- [(match_operand:GPI 2 "register_operand" "r,r,r")
- (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
- (const_int 0)))]
- "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE
(operands[5])"
- "@
- ccmp\\t%<w>2, %<w>3, %K5, %M4
- ccmp\\t%<w>2, %3, %K5, %M4
- ccmn\\t%<w>2, #%n3, %K5, %M4"
- [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
-)
-
-(define_expand "cmp<mode>"
- [(set (match_operand 0 "cc_register" "")
- (match_operator:CC 1 "aarch64_comparison_operator"
- [(match_operand:GPI 2 "register_operand" "")
- (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
- ""
- {
- operands[1] = gen_rtx_fmt_ee (COMPARE,
- SELECT_CC_MODE (GET_CODE (operands[1]),
- operands[2], operands[3]),
- operands[2], operands[3]);
- }
-)
-
;; Expansion of signed mod by a power of 2 using CSNEG.
;; For x0 % n where n is a power of 2 produce:
;; negs x1, x0
@@ -2816,7 +2782,7 @@
;; Comparison insns
;; -------------------------------------------------------------------
-(define_insn "*cmp<mode>"
+(define_insn "cmp<mode>"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
(match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
@@ -2903,7 +2869,7 @@
(define_expand "cstorecc4"
[(set (match_operand:SI 0 "register_operand")
(match_operator 1 "aarch64_comparison_operator"
- [(match_operand 2 "ccmp_cc_register")
+ [(match_operand 2 "cc_register")
(match_operand 3 "const0_operand")]))]
""
"{
@@ -3072,19 +3038,15 @@
(match_operand:ALLI 3 "register_operand" "")))]
""
{
+ rtx ccreg;
enum rtx_code code = GET_CODE (operands[1]);
if (code == UNEQ || code == LTGT)
FAIL;
- if (!ccmp_cc_register (XEXP (operands[1], 0),
- GET_MODE (XEXP (operands[1], 0))))
- {
- rtx ccreg;
- ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
- XEXP (operands[1], 1));
- operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
- }
+ ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
}
)
b/gcc/config/aarch64/predicates.md
@@ -43,23 +43,6 @@
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_ccmp_immediate")))
-(define_special_predicate "ccmp_cc_register"
- (and (match_code "reg")
- (and (match_test "REGNO (op) == CC_REGNUM")
- (ior (match_test "mode == GET_MODE (op)")
- (match_test "mode == VOIDmode
- && (GET_MODE (op) == CC_DNEmode
- || GET_MODE (op) == CC_DEQmode
- || GET_MODE (op) == CC_DLEmode
- || GET_MODE (op) == CC_DLTmode
- || GET_MODE (op) == CC_DGEmode
- || GET_MODE (op) == CC_DGTmode
- || GET_MODE (op) == CC_DLEUmode
- || GET_MODE (op) == CC_DLTUmode
- || GET_MODE (op) == CC_DGEUmode
- || GET_MODE (op) == CC_DGTUmode)"))))
-)
-
(define_predicate "aarch64_simd_register"
(and (match_code "reg")
(ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")