2014-05-23 Yvan Roux <yvan.roux@linaro.org>
Backport from trunk r209701, 209702, 209703, 209704, 209705.
2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.md (arm_rev16si2): New pattern.
(arm_rev16si2_alt): Likewise.
* config/arm/arm.c (arm_new_rtx_costs): Handle rev16 case.
2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/aarch64.md (rev16<mode>2): New pattern.
(rev16<mode>2_alt): Likewise.
* config/aarch64/aarch64.c (aarch64_rtx_costs): Handle rev16 case.
* config/arm/aarch-common.c (aarch_rev16_shright_mask_imm_p): New.
(aarch_rev16_shleft_mask_imm_p): Likewise.
(aarch_rev16_p_1): Likewise.
(aarch_rev16_p): Likewise.
* config/arm/aarch-common-protos.h (aarch_rev16_p): Declare extern.
(aarch_rev16_shright_mask_imm_p): Likewise.
(aarch_rev16_shleft_mask_imm_p): Likewise.
2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/aarch-common-protos.h (alu_cost_table): Add rev field.
* config/arm/aarch-cost-tables.h (generic_extra_costs): Specify
rev cost.
(cortex_a53_extra_costs): Likewise.
(cortex_a57_extra_costs): Likewise.
* config/arm/arm.c (cortexa9_extra_costs): Likewise.
(cortexa7_extra_costs): Likewise.
(cortexa8_extra_costs): Likewise.
(cortexa12_extra_costs): Likewise.
(cortexa15_extra_costs): Likewise.
(v7m_extra_costs): Likewise.
(arm_new_rtx_costs): Handle BSWAP.
2013-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.c (cortexa8_extra_costs): New table.
(arm_cortex_a8_tune): New tuning struct.
* config/arm/arm-cores.def (cortex-a8): Use cortex_a8 tuning struct.
2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.c (arm_new_rtx_costs): Handle FMA.
gcc/testsuite/
2014-05-23 Yvan Roux <yvan.roux@linaro.org>
Backport from trunk r209704, 209705.
2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/arm/rev16.c: New test.
2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/aarch64/rev16_1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@211520
138bc75d-0d04-0410-961f-
82ee72b054a4
2014-05-23 Yvan Roux <yvan.roux@linaro.org>
+ Backport from trunk r209701, 209702, 209703, 209704, 209705.
+ 2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.md (arm_rev16si2): New pattern.
+ (arm_rev16si2_alt): Likewise.
+ * config/arm/arm.c (arm_new_rtx_costs): Handle rev16 case.
+
+ 2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+ * config/aarch64/aarch64.md (rev16<mode>2): New pattern.
+ (rev16<mode>2_alt): Likewise.
+ * config/aarch64/aarch64.c (aarch64_rtx_costs): Handle rev16 case.
+ * config/arm/aarch-common.c (aarch_rev16_shright_mask_imm_p): New.
+ (aarch_rev16_shleft_mask_imm_p): Likewise.
+ (aarch_rev16_p_1): Likewise.
+ (aarch_rev16_p): Likewise.
+ * config/arm/aarch-common-protos.h (aarch_rev16_p): Declare extern.
+ (aarch_rev16_shright_mask_imm_p): Likewise.
+ (aarch_rev16_shleft_mask_imm_p): Likewise.
+
+ 2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/aarch-common-protos.h (alu_cost_table): Add rev field.
+ * config/arm/aarch-cost-tables.h (generic_extra_costs): Specify
+ rev cost.
+ (cortex_a53_extra_costs): Likewise.
+ (cortex_a57_extra_costs): Likewise.
+ * config/arm/arm.c (cortexa9_extra_costs): Likewise.
+ (cortexa7_extra_costs): Likewise.
+ (cortexa8_extra_costs): Likewise.
+ (cortexa12_extra_costs): Likewise.
+ (cortexa15_extra_costs): Likewise.
+ (v7m_extra_costs): Likewise.
+ (arm_new_rtx_costs): Handle BSWAP.
+
+ 2013-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (cortexa8_extra_costs): New table.
+ (arm_cortex_a8_tune): New tuning struct.
+ * config/arm/arm-cores.def (cortex-a8): Use cortex_a8 tuning struct.
+
+ 2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (arm_new_rtx_costs): Handle FMA.
+
+2014-05-23 Yvan Roux <yvan.roux@linaro.org>
+
Backport from trunk r209659.
2014-04-22 Richard Henderson <rth@redhat.com>
return false;
case IOR:
+ if (aarch_rev16_p (x))
+ {
+ *cost = COSTS_N_INSNS (1);
+
+ if (speed)
+ *cost += extra_cost->alu.rev;
+
+ return true;
+ }
+ /* Fall through. */
case XOR:
case AND:
cost_logic:
[(set_attr "type" "rev")]
)
+;; There are no canonicalisation rules for the position of the lshiftrt, ashift
+;; operations within an IOR/AND RTX, therefore we have two patterns matching
+;; each valid permutation.
+
+(define_insn "rev16<mode>2"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
+ (const_int 8))
+ (match_operand:GPI 3 "const_int_operand" "n"))
+ (and:GPI (lshiftrt:GPI (match_dup 1)
+ (const_int 8))
+ (match_operand:GPI 2 "const_int_operand" "n"))))]
+ "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
+ && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
+ "rev16\\t%<w>0, %<w>1"
+ [(set_attr "type" "rev")]
+)
+
+(define_insn "rev16<mode>2_alt"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
+ (const_int 8))
+ (match_operand:GPI 2 "const_int_operand" "n"))
+ (and:GPI (ashift:GPI (match_dup 1)
+ (const_int 8))
+ (match_operand:GPI 3 "const_int_operand" "n"))))]
+ "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
+ && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
+ "rev16\\t%<w>0, %<w>1"
+ [(set_attr "type" "rev")]
+)
+
;; zero_extend version of above
(define_insn "*bswapsi2_uxtw"
[(set (match_operand:DI 0 "register_operand" "=r")
#define GCC_AARCH_COMMON_PROTOS_H
extern int aarch_crypto_can_dual_issue (rtx, rtx);
+extern bool aarch_rev16_p (rtx);
+extern bool aarch_rev16_shleft_mask_imm_p (rtx, enum machine_mode);
+extern bool aarch_rev16_shright_mask_imm_p (rtx, enum machine_mode);
extern int arm_early_load_addr_dep (rtx, rtx);
extern int arm_early_store_addr_dep (rtx, rtx);
extern int arm_mac_accumulator_is_mul_result (rtx, rtx);
const int bfi; /* Bit-field insert. */
const int bfx; /* Bit-field extraction. */
const int clz; /* Count Leading Zeros. */
+ const int rev; /* Reverse bits/bytes. */
const int non_exec; /* Extra cost when not executing insn. */
const bool non_exec_costs_exec; /* True if non-execution must add the exec
cost. */
return 0;
}
+bool
+aarch_rev16_shright_mask_imm_p (rtx val, enum machine_mode mode)
+{
+ return CONST_INT_P (val)
+ && INTVAL (val) == trunc_int_for_mode (0xff00ff00ff00ff, mode);
+}
+
+bool
+aarch_rev16_shleft_mask_imm_p (rtx val, enum machine_mode mode)
+{
+ return CONST_INT_P (val)
+ && INTVAL (val) == trunc_int_for_mode (0xff00ff00ff00ff00, mode);
+}
+
+
+static bool
+aarch_rev16_p_1 (rtx lhs, rtx rhs, enum machine_mode mode)
+{
+ if (GET_CODE (lhs) == AND
+ && GET_CODE (XEXP (lhs, 0)) == ASHIFT
+ && CONST_INT_P (XEXP (XEXP (lhs, 0), 1))
+ && INTVAL (XEXP (XEXP (lhs, 0), 1)) == 8
+ && REG_P (XEXP (XEXP (lhs, 0), 0))
+ && CONST_INT_P (XEXP (lhs, 1))
+ && GET_CODE (rhs) == AND
+ && GET_CODE (XEXP (rhs, 0)) == LSHIFTRT
+ && REG_P (XEXP (XEXP (rhs, 0), 0))
+ && CONST_INT_P (XEXP (XEXP (rhs, 0), 1))
+ && INTVAL (XEXP (XEXP (rhs, 0), 1)) == 8
+ && CONST_INT_P (XEXP (rhs, 1))
+ && REGNO (XEXP (XEXP (rhs, 0), 0)) == REGNO (XEXP (XEXP (lhs, 0), 0)))
+
+ {
+ rtx lhs_mask = XEXP (lhs, 1);
+ rtx rhs_mask = XEXP (rhs, 1);
+
+ return aarch_rev16_shright_mask_imm_p (rhs_mask, mode)
+ && aarch_rev16_shleft_mask_imm_p (lhs_mask, mode);
+ }
+
+ return false;
+}
+
+/* Recognise a sequence of bitwise operations corresponding to a rev16 operation.
+ These will be of the form:
+ ((x >> 8) & 0x00ff00ff)
+ | ((x << 8) & 0xff00ff00)
+ for SImode and with similar but wider bitmasks for DImode.
+ The two sub-expressions of the IOR can appear on either side so check both
+ permutations with the help of aarch_rev16_p_1 above. */
+
+bool
+aarch_rev16_p (rtx x)
+{
+ rtx left_sub_rtx, right_sub_rtx;
+ bool is_rev = false;
+
+ if (GET_CODE (x) != IOR)
+ return false;
+
+ left_sub_rtx = XEXP (x, 0);
+ right_sub_rtx = XEXP (x, 1);
+
+ /* There are no canonicalisation rules for the position of the two shifts
+ involved in a rev, so try both permutations. */
+ is_rev = aarch_rev16_p_1 (left_sub_rtx, right_sub_rtx, GET_MODE (x));
+
+ if (!is_rev)
+ is_rev = aarch_rev16_p_1 (right_sub_rtx, left_sub_rtx, GET_MODE (x));
+
+ return is_rev;
+}
+
/* Return nonzero if the CONSUMER instruction (a load) does need
PRODUCER's value to calculate the address. */
int
0, /* bfi. */
0, /* bfx. */
0, /* clz. */
+ 0, /* rev. */
COSTS_N_INSNS (1), /* non_exec. */
false /* non_exec_costs_exec. */
},
COSTS_N_INSNS (1), /* bfi. */
COSTS_N_INSNS (1), /* bfx. */
0, /* clz. */
+ 0, /* rev. */
0, /* non_exec. */
true /* non_exec_costs_exec. */
},
COSTS_N_INSNS (1), /* bfi. */
0, /* bfx. */
0, /* clz. */
+ 0, /* rev. */
0, /* non_exec. */
true /* non_exec_costs_exec. */
},
ARM_CORE("generic-armv7-a", genericv7a, genericv7a, 7A, FL_LDSCHED, cortex)
ARM_CORE("cortex-a5", cortexa5, cortexa5, 7A, FL_LDSCHED, cortex_a5)
ARM_CORE("cortex-a7", cortexa7, cortexa7, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a7)
-ARM_CORE("cortex-a8", cortexa8, cortexa8, 7A, FL_LDSCHED, cortex)
+ARM_CORE("cortex-a8", cortexa8, cortexa8, 7A, FL_LDSCHED, cortex_a8)
ARM_CORE("cortex-a9", cortexa9, cortexa9, 7A, FL_LDSCHED, cortex_a9)
ARM_CORE("cortex-a12", cortexa12, cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a12)
ARM_CORE("cortex-a15", cortexa15, cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15)
COSTS_N_INSNS (1), /* bfi. */
COSTS_N_INSNS (1), /* bfx. */
0, /* clz. */
+ 0, /* rev. */
0, /* non_exec. */
true /* non_exec_costs_exec. */
},
}
};
+const struct cpu_cost_table cortexa8_extra_costs =
+{
+ /* ALU */
+ {
+ 0, /* arith. */
+ 0, /* logical. */
+ COSTS_N_INSNS (1), /* shift. */
+ 0, /* shift_reg. */
+ COSTS_N_INSNS (1), /* arith_shift. */
+ 0, /* arith_shift_reg. */
+ COSTS_N_INSNS (1), /* log_shift. */
+ 0, /* log_shift_reg. */
+ 0, /* extend. */
+ 0, /* extend_arith. */
+ 0, /* bfi. */
+ 0, /* bfx. */
+ 0, /* clz. */
+ 0, /* rev. */
+ 0, /* non_exec. */
+ true /* non_exec_costs_exec. */
+ },
+ {
+ /* MULT SImode */
+ {
+ COSTS_N_INSNS (1), /* simple. */
+ COSTS_N_INSNS (1), /* flag_setting. */
+ COSTS_N_INSNS (1), /* extend. */
+ COSTS_N_INSNS (1), /* add. */
+ COSTS_N_INSNS (1), /* extend_add. */
+ COSTS_N_INSNS (30) /* idiv. No HW div on Cortex A8. */
+ },
+ /* MULT DImode */
+ {
+ 0, /* simple (N/A). */
+ 0, /* flag_setting (N/A). */
+ COSTS_N_INSNS (2), /* extend. */
+ 0, /* add (N/A). */
+ COSTS_N_INSNS (2), /* extend_add. */
+ 0 /* idiv (N/A). */
+ }
+ },
+ /* LD/ST */
+ {
+ COSTS_N_INSNS (1), /* load. */
+ COSTS_N_INSNS (1), /* load_sign_extend. */
+ COSTS_N_INSNS (1), /* ldrd. */
+ COSTS_N_INSNS (1), /* ldm_1st. */
+ 1, /* ldm_regs_per_insn_1st. */
+ 2, /* ldm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (1), /* loadf. */
+ COSTS_N_INSNS (1), /* loadd. */
+ COSTS_N_INSNS (1), /* load_unaligned. */
+ COSTS_N_INSNS (1), /* store. */
+ COSTS_N_INSNS (1), /* strd. */
+ COSTS_N_INSNS (1), /* stm_1st. */
+ 1, /* stm_regs_per_insn_1st. */
+ 2, /* stm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (1), /* storef. */
+ COSTS_N_INSNS (1), /* stored. */
+ COSTS_N_INSNS (1) /* store_unaligned. */
+ },
+ {
+ /* FP SFmode */
+ {
+ COSTS_N_INSNS (36), /* div. */
+ COSTS_N_INSNS (11), /* mult. */
+ COSTS_N_INSNS (20), /* mult_addsub. */
+ COSTS_N_INSNS (30), /* fma. */
+ COSTS_N_INSNS (9), /* addsub. */
+ COSTS_N_INSNS (3), /* fpconst. */
+ COSTS_N_INSNS (3), /* neg. */
+ COSTS_N_INSNS (6), /* compare. */
+ COSTS_N_INSNS (4), /* widen. */
+ COSTS_N_INSNS (4), /* narrow. */
+ COSTS_N_INSNS (8), /* toint. */
+ COSTS_N_INSNS (8), /* fromint. */
+ COSTS_N_INSNS (8) /* roundint. */
+ },
+ /* FP DFmode */
+ {
+ COSTS_N_INSNS (64), /* div. */
+ COSTS_N_INSNS (16), /* mult. */
+ COSTS_N_INSNS (25), /* mult_addsub. */
+ COSTS_N_INSNS (30), /* fma. */
+ COSTS_N_INSNS (9), /* addsub. */
+ COSTS_N_INSNS (3), /* fpconst. */
+ COSTS_N_INSNS (3), /* neg. */
+ COSTS_N_INSNS (6), /* compare. */
+ COSTS_N_INSNS (6), /* widen. */
+ COSTS_N_INSNS (6), /* narrow. */
+ COSTS_N_INSNS (8), /* toint. */
+ COSTS_N_INSNS (8), /* fromint. */
+ COSTS_N_INSNS (8) /* roundint. */
+ }
+ },
+ /* Vector */
+ {
+ COSTS_N_INSNS (1) /* alu. */
+ }
+};
+
+
const struct cpu_cost_table cortexa7_extra_costs =
{
COSTS_N_INSNS (1), /* bfi. */
COSTS_N_INSNS (1), /* bfx. */
COSTS_N_INSNS (1), /* clz. */
+ COSTS_N_INSNS (1), /* rev. */
0, /* non_exec. */
true /* non_exec_costs_exec. */
},
0, /* bfi. */
COSTS_N_INSNS (1), /* bfx. */
COSTS_N_INSNS (1), /* clz. */
+ COSTS_N_INSNS (1), /* rev. */
0, /* non_exec. */
true /* non_exec_costs_exec. */
},
COSTS_N_INSNS (1), /* bfi. */
0, /* bfx. */
0, /* clz. */
+ 0, /* rev. */
0, /* non_exec. */
true /* non_exec_costs_exec. */
},
0, /* bfi. */
0, /* bfx. */
0, /* clz. */
+ 0, /* rev. */
COSTS_N_INSNS (1), /* non_exec. */
false /* non_exec_costs_exec. */
},
false, false /* Prefer 32-bit encodings. */
};
+const struct tune_params arm_cortex_a8_tune =
+{
+ arm_9e_rtx_costs,
+ &cortexa8_extra_costs,
+ NULL, /* Sched adj cost. */
+ 1, /* Constant limit. */
+ 5, /* Max cond insns. */
+ ARM_PREFETCH_NOT_BENEFICIAL,
+ false, /* Prefer constant pool. */
+ arm_default_branch_cost,
+ false, /* Prefer LDRD/STRD. */
+ {true, true}, /* Prefer non short circuit. */
+ &arm_default_vec_cost, /* Vectorizer costs. */
+ false /* Prefer Neon for 64-bits bitops. */
+};
+
const struct tune_params arm_cortex_a7_tune =
{
arm_9e_rtx_costs,
*cost = LIBCALL_COST (2);
return false;
+ case BSWAP:
+ if (arm_arch6)
+ {
+ if (mode == SImode)
+ {
+ *cost = COSTS_N_INSNS (1);
+ if (speed_p)
+ *cost += extra_cost->alu.rev;
+
+ return false;
+ }
+ }
+ else
+ {
+ /* No rev instruction available. Look at arm_legacy_rev
+ and thumb_legacy_rev for the form of RTL used then. */
+ if (TARGET_THUMB)
+ {
+ *cost = COSTS_N_INSNS (10);
+
+ if (speed_p)
+ {
+ *cost += 6 * extra_cost->alu.shift;
+ *cost += 3 * extra_cost->alu.logical;
+ }
+ }
+ else
+ {
+ *cost = COSTS_N_INSNS (5);
+
+ if (speed_p)
+ {
+ *cost += 2 * extra_cost->alu.shift;
+ *cost += extra_cost->alu.arith_shift;
+ *cost += 2 * extra_cost->alu.logical;
+ }
+ }
+ return true;
+ }
+ return false;
+
case MINUS:
if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
&& (mode == SFmode || !TARGET_VFP_SINGLE))
/* Vector mode? */
*cost = LIBCALL_COST (2);
return false;
+ case IOR:
+ if (mode == SImode && arm_arch6 && aarch_rev16_p (x))
+ {
+ *cost = COSTS_N_INSNS (1);
+ if (speed_p)
+ *cost += extra_cost->alu.rev;
- case AND: case XOR: case IOR:
+ return true;
+ }
+ /* Fall through. */
+ case AND: case XOR:
if (mode == SImode)
{
enum rtx_code subcode = GET_CODE (XEXP (x, 0));
*cost = LIBCALL_COST (1);
return false;
+ case FMA:
+ if (TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA)
+ {
+ rtx op0 = XEXP (x, 0);
+ rtx op1 = XEXP (x, 1);
+ rtx op2 = XEXP (x, 2);
+
+ *cost = COSTS_N_INSNS (1);
+
+ /* vfms or vfnma. */
+ if (GET_CODE (op0) == NEG)
+ op0 = XEXP (op0, 0);
+
+ /* vfnms or vfnma. */
+ if (GET_CODE (op2) == NEG)
+ op2 = XEXP (op2, 0);
+
+ *cost += rtx_cost (op0, FMA, 0, speed_p);
+ *cost += rtx_cost (op1, FMA, 1, speed_p);
+ *cost += rtx_cost (op2, FMA, 2, speed_p);
+
+ if (speed_p)
+ *cost += extra_cost->fp[mode ==DFmode].fma;
+
+ return true;
+ }
+
+ *cost = LIBCALL_COST (3);
+ return false;
+
case FIX:
case UNSIGNED_FIX:
if (TARGET_HARD_FLOAT)
(set_attr "type" "rev")]
)
+;; There are no canonicalisation rules for the position of the lshiftrt, ashift
+;; operations within an IOR/AND RTX, therefore we have two patterns matching
+;; each valid permutation.
+
+(define_insn "arm_rev16si2"
+ [(set (match_operand:SI 0 "register_operand" "=l,l,r")
+ (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
+ (const_int 8))
+ (match_operand:SI 3 "const_int_operand" "n,n,n"))
+ (and:SI (lshiftrt:SI (match_dup 1)
+ (const_int 8))
+ (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
+ "arm_arch6
+ && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
+ && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
+ "rev16\\t%0, %1"
+ [(set_attr "arch" "t1,t2,32")
+ (set_attr "length" "2,2,4")
+ (set_attr "type" "rev")]
+)
+
+(define_insn "arm_rev16si2_alt"
+ [(set (match_operand:SI 0 "register_operand" "=l,l,r")
+ (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
+ (const_int 8))
+ (match_operand:SI 2 "const_int_operand" "n,n,n"))
+ (and:SI (ashift:SI (match_dup 1)
+ (const_int 8))
+ (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
+ "arm_arch6
+ && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
+ && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
+ "rev16\\t%0, %1"
+ [(set_attr "arch" "t1,t2,32")
+ (set_attr "length" "2,2,4")
+ (set_attr "type" "rev")]
+)
+
(define_expand "bswaphi2"
[(set (match_operand:HI 0 "s_register_operand" "=r")
(bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
2014-05-23 Yvan Roux <yvan.roux@linaro.org>
+ Backport from trunk r209704, 209705.
+ 2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/arm/rev16.c: New test.
+
+ 2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/rev16_1.c: New test.
+
+2014-05-23 Yvan Roux <yvan.roux@linaro.org>
+
Backport from trunk r209642.
2014-04-22 Alex Velenko <Alex.Velenko@arm.com>
--- /dev/null
+/* { dg-options "-O2" } */
+/* { dg-do run } */
+
+extern void abort (void);
+
+typedef unsigned int __u32;
+
+__u32
+__rev16_32_alt (__u32 x)
+{
+ return (((__u32)(x) & (__u32)0xff00ff00UL) >> 8)
+ | (((__u32)(x) & (__u32)0x00ff00ffUL) << 8);
+}
+
+__u32
+__rev16_32 (__u32 x)
+{
+ return (((__u32)(x) & (__u32)0x00ff00ffUL) << 8)
+ | (((__u32)(x) & (__u32)0xff00ff00UL) >> 8);
+}
+
+typedef unsigned long long __u64;
+
+__u64
+__rev16_64_alt (__u64 x)
+{
+ return (((__u64)(x) & (__u64)0xff00ff00ff00ff00UL) >> 8)
+ | (((__u64)(x) & (__u64)0x00ff00ff00ff00ffUL) << 8);
+}
+
+__u64
+__rev16_64 (__u64 x)
+{
+ return (((__u64)(x) & (__u64)0x00ff00ff00ff00ffUL) << 8)
+ | (((__u64)(x) & (__u64)0xff00ff00ff00ff00UL) >> 8);
+}
+
+int
+main (void)
+{
+ volatile __u32 in32 = 0x12345678;
+ volatile __u32 expected32 = 0x34127856;
+ volatile __u64 in64 = 0x1234567890abcdefUL;
+ volatile __u64 expected64 = 0x34127856ab90efcdUL;
+
+ if (__rev16_32 (in32) != expected32)
+ abort ();
+
+ if (__rev16_32_alt (in32) != expected32)
+ abort ();
+
+ if (__rev16_64 (in64) != expected64)
+ abort ();
+
+ if (__rev16_64_alt (in64) != expected64)
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-O2" } */
+/* { dg-do run } */
+
+extern void abort (void);
+
+typedef unsigned int __u32;
+
+__u32
+__rev16_32_alt (__u32 x)
+{
+ return (((__u32)(x) & (__u32)0xff00ff00UL) >> 8)
+ | (((__u32)(x) & (__u32)0x00ff00ffUL) << 8);
+}
+
+__u32
+__rev16_32 (__u32 x)
+{
+ return (((__u32)(x) & (__u32)0x00ff00ffUL) << 8)
+ | (((__u32)(x) & (__u32)0xff00ff00UL) >> 8);
+}
+
+int
+main (void)
+{
+ volatile __u32 in32 = 0x12345678;
+ volatile __u32 expected32 = 0x34127856;
+
+ if (__rev16_32 (in32) != expected32)
+ abort ();
+
+ if (__rev16_32_alt (in32) != expected32)
+ abort ();
+
+ return 0;
+}