[ARM] Replace HasT2ExtractPack with HasDSP

Removed the HasT2ExtractPack feature and replaced its references
with HasDSP. This then allows the Thumb2 extend instructions to be
selected for ARMv8M +dsp. These instruction descriptions have also
been refactored and more target tests have been added for their isel.

Differential Revision: https://reviews.llvm.org/D29623


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295452 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sam Parker 2017-02-17 15:42:44 +00:00
parent 2566cbcc53
commit 50a37dcbc4
10 changed files with 216 additions and 259 deletions

View File

@ -72,8 +72,6 @@ def FeatureHWDiv : SubtargetFeature<"hwdiv", "HasHardwareDivide", "true",
def FeatureHWDivARM : SubtargetFeature<"hwdiv-arm",
"HasHardwareDivideInARM", "true",
"Enable divide instructions in ARM mode">;
def FeatureT2XtPk : SubtargetFeature<"t2xtpk", "HasT2ExtractPack", "true",
"Enable Thumb2 extract and pack instructions">;
def FeatureDB : SubtargetFeature<"db", "HasDataBarrier", "true",
"Has data barrier (dmb / dsb) instructions">;
def FeatureV7Clrex : SubtargetFeature<"v7clrex", "HasV7Clrex", "true",
@ -297,8 +295,7 @@ def HasV7Ops : SubtargetFeature<"v7", "HasV7Ops", "true",
FeatureV7Clrex]>;
def HasV8Ops : SubtargetFeature<"v8", "HasV8Ops", "true",
"Support ARM v8 instructions",
[HasV7Ops, FeatureAcquireRelease,
FeatureT2XtPk]>;
[HasV7Ops, FeatureAcquireRelease]>;
def HasV8_1aOps : SubtargetFeature<"v8.1a", "HasV8_1aOps", "true",
"Support ARM v8.1a instructions",
[HasV8Ops]>;
@ -393,8 +390,7 @@ def ARMv5tej : Architecture<"armv5tej", "ARMv5tej", [HasV5TEOps]>;
def ARMv6 : Architecture<"armv6", "ARMv6", [HasV6Ops]>;
def ARMv6t2 : Architecture<"armv6t2", "ARMv6t2", [HasV6T2Ops,
FeatureDSP,
FeatureT2XtPk]>;
FeatureDSP]>;
def ARMv6k : Architecture<"armv6k", "ARMv6k", [HasV6KOps]>;
@ -415,8 +411,7 @@ def ARMv7a : Architecture<"armv7-a", "ARMv7a", [HasV7Ops,
FeatureNEON,
FeatureDB,
FeatureDSP,
FeatureAClass,
FeatureT2XtPk]>;
FeatureAClass]>;
def ARMv7ve : Architecture<"armv7ve", "ARMv7ve", [HasV7Ops,
FeatureNEON,
@ -425,15 +420,13 @@ def ARMv7ve : Architecture<"armv7ve", "ARMv7ve", [HasV7Ops,
FeatureTrustZone,
FeatureMP,
FeatureVirtualization,
FeatureAClass,
FeatureT2XtPk]>;
FeatureAClass]>;
def ARMv7r : Architecture<"armv7-r", "ARMv7r", [HasV7Ops,
FeatureDB,
FeatureDSP,
FeatureHWDiv,
FeatureRClass,
FeatureT2XtPk]>;
FeatureRClass]>;
def ARMv7m : Architecture<"armv7-m", "ARMv7m", [HasV7Ops,
FeatureThumb2,
@ -448,8 +441,7 @@ def ARMv7em : Architecture<"armv7e-m", "ARMv7em", [HasV7Ops,
FeatureDB,
FeatureHWDiv,
FeatureMClass,
FeatureDSP,
FeatureT2XtPk]>;
FeatureDSP]>;
def ARMv8a : Architecture<"armv8-a", "ARMv8a", [HasV8Ops,
FeatureAClass,
@ -491,7 +483,6 @@ def ARMv82a : Architecture<"armv8.2-a", "ARMv82a", [HasV8_2aOps,
def ARMv8r : Architecture<"armv8-r", "ARMv8r", [HasV8Ops,
FeatureRClass,
FeatureDB,
FeatureT2XtPk,
FeatureDSP,
FeatureCRC,
FeatureMP,
@ -764,7 +755,6 @@ def : ProcNoItin<"cortex-m23", [ARMv8mBaseline,
def : ProcNoItin<"cortex-m33", [ARMv8mMainline,
FeatureDSP,
FeatureT2XtPk,
FeatureFPARMv8,
FeatureD16,
FeatureVFPOnlySP]>;

View File

@ -10031,7 +10031,7 @@ static SDValue PerformORCombine(SDNode *N,
(Mask == ~Mask2)) {
// The pack halfword instruction works better for masks that fit it,
// so use that when it's available.
if (Subtarget->hasT2ExtractPack() &&
if (Subtarget->hasDSP() &&
(Mask == 0xffff || Mask == 0xffff0000))
return SDValue();
// 2a
@ -10047,7 +10047,7 @@ static SDValue PerformORCombine(SDNode *N,
(~Mask == Mask2)) {
// The pack halfword instruction works better for masks that fit it,
// so use that when it's available.
if (Subtarget->hasT2ExtractPack() &&
if (Subtarget->hasDSP() &&
(Mask2 == 0xffff || Mask2 == 0xffff0000))
return SDValue();
// 2b

View File

@ -1013,9 +1013,6 @@ class Thumb2DSPPat<dag pattern, dag result> : Pat<pattern, result> {
class Thumb2DSPMulPat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsThumb2, UseMulOps, HasDSP];
}
class Thumb2ExtractPat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsThumb2, HasT2ExtractPack];
}
//===----------------------------------------------------------------------===//
// Thumb Instruction Format Definitions.
//

View File

@ -249,9 +249,6 @@ def HasDivide : Predicate<"Subtarget->hasDivide()">,
AssemblerPredicate<"FeatureHWDiv", "divide in THUMB">;
def HasDivideInARM : Predicate<"Subtarget->hasDivideInARMMode()">,
AssemblerPredicate<"FeatureHWDivARM", "divide in ARM">;
def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
AssemblerPredicate<"FeatureT2XtPk",
"pack/extract">;
def HasDSP : Predicate<"Subtarget->hasDSP()">,
AssemblerPredicate<"FeatureDSP", "dsp">;
def HasDB : Predicate<"Subtarget->hasDataBarrier()">,

View File

@ -1121,28 +1121,10 @@ multiclass T2I_st<bits<2> opcod, string opc,
/// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
/// register and one whose operand is a register rotated by 8/16/24.
class T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode>
: T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
opc, ".w\t$Rd, $Rm$rot",
[(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
Requires<[IsThumb2]> {
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0100;
let Inst{22-20} = opcod;
let Inst{19-16} = 0b1111; // Rn
let Inst{15-12} = 0b1111;
let Inst{7} = 1;
bits<2> rot;
let Inst{5-4} = rot{1-0}; // rotate
}
// UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
class T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode>
: T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot),
IIC_iEXTr, opc, "\t$Rd, $Rm$rot",
[(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
Requires<[HasT2ExtractPack, IsThumb2]> {
class T2I_ext_rrot_base<bits<3> opcod, dag iops, dag oops,
string opc, string oprs,
list<dag> pattern>
: T2TwoReg<iops, oops, IIC_iEXTr, opc, oprs, pattern> {
bits<2> rot;
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0100;
@ -1150,46 +1132,31 @@ class T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode>
let Inst{19-16} = 0b1111; // Rn
let Inst{15-12} = 0b1111;
let Inst{7} = 1;
let Inst{5-4} = rot;
let Inst{5-4} = rot; // rotate
}
// SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
// supported yet.
class T2I_ext_rrot_sxtb16<bits<3> opcod, string opc>
: T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
opc, "\t$Rd, $Rm$rot", []>,
Requires<[IsThumb2, HasT2ExtractPack]> {
bits<2> rot;
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0100;
let Inst{22-20} = opcod;
let Inst{19-16} = 0b1111; // Rn
let Inst{15-12} = 0b1111;
let Inst{7} = 1;
let Inst{5-4} = rot;
}
class T2I_ext_rrot<bits<3> opcod, string opc>
: T2I_ext_rrot_base<opcod,
(outs rGPR:$Rd),
(ins rGPR:$Rm, rot_imm:$rot),
opc, ".w\t$Rd, $Rm$rot", []>,
Requires<[IsThumb2]>;
// UXTB16, SXTB16 - Requires HasDSP, does not need the .w qualifier.
class T2I_ext_rrot_xtb16<bits<3> opcod, string opc>
: T2I_ext_rrot_base<opcod,
(outs rGPR:$Rd),
(ins rGPR:$Rm, rot_imm:$rot),
opc, "\t$Rd, $Rm$rot", []>,
Requires<[HasDSP, IsThumb2]>;
/// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
/// register and one whose operand is a register rotated by 8/16/24.
class T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode>
class T2I_exta_rrot<bits<3> opcod, string opc>
: T2ThreeReg<(outs rGPR:$Rd),
(ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot),
IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot",
[(set rGPR:$Rd, (opnode rGPR:$Rn, (rotr rGPR:$Rm,rot_imm:$rot)))]>,
Requires<[HasT2ExtractPack, IsThumb2]> {
bits<2> rot;
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0100;
let Inst{22-20} = opcod;
let Inst{15-12} = 0b1111;
let Inst{7} = 1;
let Inst{5-4} = rot;
}
class T2I_exta_rrot_np<bits<3> opcod, string opc>
: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm,rot_imm:$rot),
IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot", []>,
Requires<[HasT2ExtractPack, IsThumb2]> {
Requires<[HasDSP, IsThumb2]> {
bits<2> rot;
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0100;
@ -1969,31 +1936,39 @@ def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
// Sign extenders
def t2SXTB : T2I_ext_rrot<0b100, "sxtb",
UnOpFrag<(sext_inreg node:$Src, i8)>>;
def t2SXTH : T2I_ext_rrot<0b000, "sxth",
UnOpFrag<(sext_inreg node:$Src, i16)>>;
def t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
def t2SXTB : T2I_ext_rrot<0b100, "sxtb">;
def t2SXTH : T2I_ext_rrot<0b000, "sxth">;
def t2SXTB16 : T2I_ext_rrot_xtb16<0b010, "sxtb16">;
def t2SXTAB : T2I_exta_rrot<0b100, "sxtab">;
def t2SXTAH : T2I_exta_rrot<0b000, "sxtah">;
def t2SXTAB16 : T2I_exta_rrot<0b010, "sxtab16">;
def : T2Pat<(sext_inreg (rotr rGPR:$Rn, rot_imm:$rot), i8),
(t2SXTB rGPR:$Rn, rot_imm:$rot)>;
def : T2Pat<(sext_inreg (rotr rGPR:$Rn, rot_imm:$rot), i16),
(t2SXTH rGPR:$Rn, rot_imm:$rot)>;
def : Thumb2DSPPat<(add rGPR:$Rn,
(sext_inreg (rotr rGPR:$Rm, rot_imm:$rot), i8)),
(t2SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2DSPPat<(add rGPR:$Rn,
(sext_inreg (rotr rGPR:$Rm, rot_imm:$rot), i16)),
(t2SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
def t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
def t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
def t2SXTAB16 : T2I_exta_rrot_np<0b010, "sxtab16">;
// A simple right-shift can also be used in most cases (the exception is the
// SXTH operations with a rotate of 24: there the non-contiguous bits are
// relevant).
def : Thumb2ExtractPat<(add rGPR:$Rn, (sext_inreg
def : Thumb2DSPPat<(add rGPR:$Rn, (sext_inreg
(srl rGPR:$Rm, rot_imm:$rot), i8)),
(t2SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2ExtractPat<(add rGPR:$Rn, (sext_inreg
def : Thumb2DSPPat<(add rGPR:$Rn, (sext_inreg
(srl rGPR:$Rm, imm8_or_16:$rot), i16)),
(t2SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2ExtractPat<(add rGPR:$Rn, (sext_inreg
def : Thumb2DSPPat<(add rGPR:$Rn, (sext_inreg
(rotr rGPR:$Rm, (i32 24)), i16)),
(t2SXTAH rGPR:$Rn, rGPR:$Rm, (i32 3))>;
def : Thumb2ExtractPat<(add rGPR:$Rn, (sext_inreg
def : Thumb2DSPPat<(add rGPR:$Rn, (sext_inreg
(or (srl rGPR:$Rm, (i32 24)),
(shl rGPR:$Rm, (i32 8))), i16)),
(t2SXTAH rGPR:$Rn, rGPR:$Rm, (i32 3))>;
@ -2001,12 +1976,16 @@ def : Thumb2ExtractPat<(add rGPR:$Rn, (sext_inreg
// Zero extenders
let AddedComplexity = 16 in {
def t2UXTB : T2I_ext_rrot<0b101, "uxtb",
UnOpFrag<(and node:$Src, 0x000000FF)>>;
def t2UXTH : T2I_ext_rrot<0b001, "uxth",
UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
def t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
def t2UXTB : T2I_ext_rrot<0b101, "uxtb">;
def t2UXTH : T2I_ext_rrot<0b001, "uxth">;
def t2UXTB16 : T2I_ext_rrot_xtb16<0b011, "uxtb16">;
def : Thumb2DSPPat<(and (rotr rGPR:$Rm, rot_imm:$rot), 0x000000FF),
(t2UXTB rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2DSPPat<(and (rotr rGPR:$Rm, rot_imm:$rot), 0x0000FFFF),
(t2UXTH rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2DSPPat<(and (rotr rGPR:$Rm, rot_imm:$rot), 0x00FF00FF),
(t2UXTB16 rGPR:$Rm, rot_imm:$rot)>;
// FIXME: This pattern incorrectly assumes the shl operator is a rotate.
// The transformation should probably be done as a combiner action
@ -2014,21 +1993,25 @@ def t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
// eight bits of the source into the lower eight bits of the result.
//def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
// (t2UXTB16 rGPR:$Src, 3)>,
// Requires<[HasT2ExtractPack, IsThumb2]>;
// Requires<[HasDSP, IsThumb2]>;
def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
(t2UXTB16 rGPR:$Src, 1)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
def t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
def t2UXTAB16 : T2I_exta_rrot_np<0b011, "uxtab16">;
def t2UXTAB : T2I_exta_rrot<0b101, "uxtab">;
def t2UXTAH : T2I_exta_rrot<0b001, "uxtah">;
def t2UXTAB16 : T2I_exta_rrot<0b011, "uxtab16">;
def : Thumb2ExtractPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot),
def : Thumb2DSPPat<(add rGPR:$Rn, (and (rotr rGPR:$Rm, rot_imm:$rot),
0x00FF)),
(t2UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2DSPPat<(add rGPR:$Rn, (and (rotr rGPR:$Rm, rot_imm:$rot),
0xFFFF)),
(t2UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2DSPPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot),
0xFF)),
(t2UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
def : Thumb2ExtractPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot),
def : Thumb2DSPPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot),
0xFFFF)),
(t2UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
}
@ -2819,7 +2802,7 @@ def t2PKHBT : T2ThreeReg<
[(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
(and (shl rGPR:$Rm, pkh_lsl_amt:$sh),
0xFFFF0000)))]>,
Requires<[HasT2ExtractPack, IsThumb2]>,
Requires<[HasDSP, IsThumb2]>,
Sched<[WriteALUsi, ReadALU]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
@ -2835,10 +2818,10 @@ def t2PKHBT : T2ThreeReg<
// Alternate cases for PKHBT where identities eliminate some nodes.
def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
(t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
(t2PKHBT rGPR:$src1, rGPR:$src2, imm16_31:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
// will match the pattern below.
@ -2848,7 +2831,7 @@ def t2PKHTB : T2ThreeReg<
[(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
(and (sra rGPR:$Rm, pkh_asr_amt:$sh),
0xFFFF)))]>,
Requires<[HasT2ExtractPack, IsThumb2]>,
Requires<[HasDSP, IsThumb2]>,
Sched<[WriteALUsi, ReadALU]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
@ -2867,14 +2850,14 @@ def t2PKHTB : T2ThreeReg<
// pkhtb src1, src2, asr (17..31).
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16:$sh)),
(t2PKHTB rGPR:$src1, rGPR:$src2, imm16:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (sra rGPR:$src2, imm16_31:$sh)),
(t2PKHTB rGPR:$src1, rGPR:$src2, imm16_31:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
(and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
(t2PKHTB rGPR:$src1, rGPR:$src2, imm1_15:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
//===----------------------------------------------------------------------===//
// CRC32 Instructions
@ -4216,13 +4199,13 @@ def : T2Pat<(and rGPR:$Rm, 0x000000FF), (t2UXTB rGPR:$Rm, 0)>,
def : T2Pat<(and rGPR:$Rm, 0x0000FFFF), (t2UXTH rGPR:$Rm, 0)>,
Requires<[IsThumb2]>;
def : T2Pat<(and rGPR:$Rm, 0x00FF00FF), (t2UXTB16 rGPR:$Rm, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0x00FF)),
(t2UXTAB rGPR:$Rn, rGPR:$Rm, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0xFFFF)),
(t2UXTAH rGPR:$Rn, rGPR:$Rm, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
}
def : T2Pat<(sext_inreg rGPR:$Src, i8), (t2SXTB rGPR:$Src, 0)>,
@ -4231,10 +4214,10 @@ def : T2Pat<(sext_inreg rGPR:$Src, i16), (t2SXTH rGPR:$Src, 0)>,
Requires<[IsThumb2]>;
def : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i8)),
(t2SXTAB rGPR:$Rn, rGPR:$Rm, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i16)),
(t2SXTAH rGPR:$Rn, rGPR:$Rm, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
// Atomic load/store patterns
def : T2Pat<(atomic_load_8 t2addrmode_imm12:$addr),
@ -4431,10 +4414,10 @@ def : t2InstAlias<"mvn${s}${p} $Rd, $ShiftedRm",
// input operands swapped when the shift amount is zero (i.e., unspecified).
def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm",
(t2PKHBT rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm",
(t2PKHBT rGPR:$Rd, rGPR:$Rm, rGPR:$Rn, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
// PUSH/POP aliases for STM/LDM
def : t2InstAlias<"push${p}.w $regs", (t2STMDB_UPD SP, pred:$p, reglist:$regs)>;
@ -4513,16 +4496,16 @@ def : t2InstAlias<"strh${p} $Rt, $addr",
// Extend instruction optional rotate operand.
def : InstAlias<"sxtab${p} $Rd, $Rn, $Rm",
(t2SXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : InstAlias<"sxtah${p} $Rd, $Rn, $Rm",
(t2SXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : InstAlias<"sxtab16${p} $Rd, $Rn, $Rm",
(t2SXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : InstAlias<"sxtb16${p} $Rd, $Rm",
(t2SXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : t2InstAlias<"sxtb${p} $Rd, $Rm",
(t2SXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
@ -4535,16 +4518,16 @@ def : t2InstAlias<"sxth${p}.w $Rd, $Rm",
def : InstAlias<"uxtab${p} $Rd, $Rn, $Rm",
(t2UXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : InstAlias<"uxtah${p} $Rd, $Rn, $Rm",
(t2UXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : InstAlias<"uxtab16${p} $Rd, $Rn, $Rm",
(t2UXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : InstAlias<"uxtb16${p} $Rd, $Rm",
(t2UXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : t2InstAlias<"uxtb${p} $Rd, $Rm",
(t2UXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
@ -4560,7 +4543,7 @@ def : t2InstAlias<"uxtb${p} $Rd, $Rm$rot",
(t2UXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;
def : InstAlias<"uxtb16${p} $Rd, $Rm$rot",
(t2UXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : t2InstAlias<"uxth${p} $Rd, $Rm$rot",
(t2UXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;
@ -4568,7 +4551,7 @@ def : t2InstAlias<"sxtb${p} $Rd, $Rm$rot",
(t2SXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;
def : InstAlias<"sxtb16${p} $Rd, $Rm$rot",
(t2SXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p), 0>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Requires<[HasDSP, IsThumb2]>;
def : t2InstAlias<"sxth${p} $Rd, $Rm$rot",
(t2SXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;

View File

@ -213,10 +213,6 @@ protected:
/// HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode
bool HasHardwareDivideInARM = false;
/// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack
/// instructions.
bool HasT2ExtractPack = false;
/// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier
/// instructions.
bool HasDataBarrier = false;
@ -508,7 +504,6 @@ public:
bool hasDivide() const { return HasHardwareDivide; }
bool hasDivideInARMMode() const { return HasHardwareDivideInARM; }
bool hasT2ExtractPack() const { return HasT2ExtractPack; }
bool hasDataBarrier() const { return HasDataBarrier; }
bool hasV7Clrex() const { return HasV7Clrex; }
bool hasAcquireRelease() const { return HasAcquireRelease; }

View File

@ -1,38 +1,45 @@
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m4 %s -o - | FileCheck %s --check-prefix=CHECK-M4
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s --check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m4 %s -o - | FileCheck %s --check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumbv7em-eabi %s -o - | FileCheck %s -check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s -check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi -mattr=+dsp %s -o - | FileCheck %s -check-prefix=CHECK-DSP
define i32 @test1(i16 zeroext %z) nounwind {
; CHECK-LABEL: test1:
; CHECK: sxth
; CHECK-DSP: sxth
; CHECK-NO-DSP: sxth
%r = sext i16 %z to i32
ret i32 %r
}
define i32 @test2(i8 zeroext %z) nounwind {
; CHECK-LABEL: test2:
; CHECK: sxtb
; CHECK-DSP: sxtb
; CHECK-NO-DSP: sxtb
%r = sext i8 %z to i32
ret i32 %r
}
define i32 @test3(i16 signext %z) nounwind {
; CHECK-LABEL: test3:
; CHECK: uxth
; CHECK-DSP: uxth
; CHECK-NO-DSP: uxth
%r = zext i16 %z to i32
ret i32 %r
}
define i32 @test4(i8 signext %z) nounwind {
; CHECK-LABEL: test4:
; CHECK: uxtb
; CHECK-DSP: uxtb
; CHECK-NO-DSP: uxtb
%r = zext i8 %z to i32
ret i32 %r
}
define i32 @test5(i32 %a, i8 %b) {
; CHECK-LABEL: test5:
; CHECK-NOT: sxtab
; CHECK-M4: sxtab r0, r0, r1
; CHECK-DSP: sxtab r0, r0, r1
; CHECK-NO-DSP-NOT: sxtab
%sext = sext i8 %b to i32
%add = add i32 %a, %sext
ret i32 %add
@ -40,8 +47,8 @@ define i32 @test5(i32 %a, i8 %b) {
define i32 @test6(i32 %a, i32 %b) {
; CHECK-LABEL: test6:
; CHECK-NOT: sxtab
; CHECK-M4: sxtab r0, r0, r1
; CHECK-DSP: sxtab r0, r0, r1
; CHECK-NO-DSP-NOT: sxtab
%shl = shl i32 %b, 24
%ashr = ashr i32 %shl, 24
%add = add i32 %a, %ashr
@ -50,8 +57,8 @@ define i32 @test6(i32 %a, i32 %b) {
define i32 @test7(i32 %a, i16 %b) {
; CHECK-LABEL: test7:
; CHECK-NOT: sxtah
; CHECK-M4: sxtah r0, r0, r1
; CHECK-DSP: sxtah r0, r0, r1
; CHECK-NO-DSPNOT: sxtah
%sext = sext i16 %b to i32
%add = add i32 %a, %sext
ret i32 %add
@ -59,8 +66,8 @@ define i32 @test7(i32 %a, i16 %b) {
define i32 @test8(i32 %a, i32 %b) {
; CHECK-LABEL: test8:
; CHECK-NOT: sxtah
; CHECK-M4: sxtah r0, r0, r1
; CHECK-DSP: sxtah r0, r0, r1
; CHECK-NO-DSP-NOT: sxtah
%shl = shl i32 %b, 16
%ashr = ashr i32 %shl, 16
%add = add i32 %a, %ashr
@ -69,8 +76,8 @@ define i32 @test8(i32 %a, i32 %b) {
define i32 @test9(i32 %a, i8 %b) {
; CHECK-LABEL: test9:
; CHECK-NOT: uxtab
; CHECK-M4: uxtab r0, r0, r1
; CHECK-DSP: uxtab r0, r0, r1
; CHECK-NO-DSP-NOT: uxtab
%zext = zext i8 %b to i32
%add = add i32 %a, %zext
ret i32 %add
@ -78,8 +85,8 @@ define i32 @test9(i32 %a, i8 %b) {
define i32 @test10(i32 %a, i32 %b) {
;CHECK-LABEL: test10:
;CHECK-NOT: uxtab
;CHECK-M4: uxtab r0, r0, r1
;CHECK-DSP: uxtab r0, r0, r1
;CHECK-NO-DSP-NOT: uxtab
%and = and i32 %b, 255
%add = add i32 %a, %and
ret i32 %add
@ -87,8 +94,8 @@ define i32 @test10(i32 %a, i32 %b) {
define i32 @test11(i32 %a, i16 %b) {
; CHECK-LABEL: test11:
; CHECK-NOT: uxtah
; CHECK-M4: uxtah r0, r0, r1
; CHECK-DSP: uxtah r0, r0, r1
; CHECK-NO-DSP-NOT: uxtah
%zext = zext i16 %b to i32
%add = add i32 %a, %zext
ret i32 %add
@ -96,8 +103,8 @@ define i32 @test11(i32 %a, i16 %b) {
define i32 @test12(i32 %a, i32 %b) {
;CHECK-LABEL: test12:
;CHECK-NOT: uxtah
;CHECK-M4: uxtah r0, r0, r1
;CHECK-DSP: uxtah r0, r0, r1
;CHECK-NO-DSP-NOT: uxtah
%and = and i32 %b, 65535
%add = add i32 %a, %and
ret i32 %add

View File

@ -1,18 +1,21 @@
; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2,+t2xtpk %s -o - | FileCheck %s
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s --check-prefix=CHECK-M3
; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s %s -o - | FileCheck %s --check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s --check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumbv7em-eabi %s -o - | FileCheck %s -check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s -check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi -mattr=+dsp %s -o - | FileCheck %s -check-prefix=CHECK-DSP
define i32 @test0(i8 %A) {
; CHECK-LABEL: test0:
; CHECK: sxtb r0, r0
; CHECK-M3: sxtb r0, r0
; CHECK-DSP: sxtb r0, r0
; CHECK-NO-DSP: sxtb r0, r0
%B = sext i8 %A to i32
ret i32 %B
}
define signext i8 @test1(i32 %A) {
; CHECK-LABEL: test1:
; CHECK: sbfx r0, r0, #8, #8
; CHECK-M3: sbfx r0, r0, #8, #8
; CHECK-DSP: sbfx r0, r0, #8, #8
; CHECK-NO-DSP: sbfx r0, r0, #8, #8
%B = lshr i32 %A, 8
%C = shl i32 %A, 24
%D = or i32 %B, %C
@ -22,8 +25,8 @@ define signext i8 @test1(i32 %A) {
define signext i32 @test2(i32 %A, i32 %X) {
; CHECK-LABEL: test2:
; CHECK: sxtab r0, r1, r0, ror #8
; CHECK-M3-NOT: sxtab
; CHECK-DSP: sxtab r0, r1, r0, ror #8
; CHECK-NO-DSP-NOT: sxtab
%B = lshr i32 %A, 8
%C = shl i32 %A, 24
%D = or i32 %B, %C
@ -35,8 +38,8 @@ define signext i32 @test2(i32 %A, i32 %X) {
define i32 @test3(i32 %A, i32 %X) {
; CHECK-LABEL: test3:
; CHECK: sxtah r0, r0, r1, ror #8
; CHECK-M3-NOT: sxtah
; CHECK-DSP: sxtah r0, r0, r1, ror #8
; CHECK-NO-DSP-NOT: sxtah
%X.hi = lshr i32 %X, 8
%X.trunc = trunc i32 %X.hi to i16
%addend = sext i16 %X.trunc to i32
@ -46,8 +49,8 @@ define i32 @test3(i32 %A, i32 %X) {
define signext i32 @test4(i32 %A, i32 %X) {
; CHECK-LABEL: test4:
; CHECK: sxtab r0, r1, r0, ror #16
; CHECK-M3-NOT: sxtab
; CHECK-DSP: sxtab r0, r1, r0, ror #16
; CHECK-NO-DSP-NOT: sxtab
%B = lshr i32 %A, 16
%C = shl i32 %A, 16
%D = or i32 %B, %C
@ -59,8 +62,8 @@ define signext i32 @test4(i32 %A, i32 %X) {
define signext i32 @test5(i32 %A, i32 %X) {
; CHECK-LABEL: test5:
; CHECK: sxtah r0, r1, r0, ror #24
; CHECK-M3-NOT: sxtah
; CHECK-DSP: sxtah r0, r1, r0, ror #24
; CHECK-NO-DSP-NOT: sxtah
%B = lshr i32 %A, 24
%C = shl i32 %A, 8
%D = or i32 %B, %C

View File

@ -1,21 +1,22 @@
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s --check-prefix=A8
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s --check-prefix=M3
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s --check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s --check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumbv7em-eabi %s -o - | FileCheck %s -check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s -check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi -mattr=+dsp %s -o - | FileCheck %s -check-prefix=CHECK-DSP
; rdar://11318438
define zeroext i8 @test1(i32 %A.u) {
; CHECK-LABEL: test1:
; A8: uxtb r0, r0
; CHECK-DSP: uxtb r0, r0
; CHECK-NO-DSP: uxtb r0, r0
%B.u = trunc i32 %A.u to i8
ret i8 %B.u
}
define zeroext i32 @test2(i32 %A.u, i32 %B.u) {
; CHECK-LABEL: test2:
; A8: uxtab r0, r0, r1
; M3: uxtb r1, r1
; M3-NOT: uxtab
; M3: add r0, r1
; CHECK-DSP: uxtab r0, r0, r1
; CHECK-NO-DSP-NOT: uxtab
%C.u = trunc i32 %B.u to i8
%D.u = zext i8 %C.u to i32
%E.u = add i32 %A.u, %D.u
@ -24,8 +25,8 @@ define zeroext i32 @test2(i32 %A.u, i32 %B.u) {
define zeroext i32 @test3(i32 %A.u) {
; CHECK-LABEL: test3:
; A8: ubfx r0, r0, #8, #16
; M3: ubfx r0, r0, #8, #16
; CHECK-DSP: ubfx r0, r0, #8, #16
; CHECK-NO-DSP: ubfx r0, r0, #8, #16
%B.u = lshr i32 %A.u, 8
%C.u = shl i32 %A.u, 24
%D.u = or i32 %B.u, %C.u
@ -36,8 +37,8 @@ define zeroext i32 @test3(i32 %A.u) {
define i32 @test4(i32 %A, i32 %X) {
; CHECK-LABEL: test4:
; A8: uxtab r0, r0, r1, ror #16
; M3-NOT: uxtab
; CHECK-DSP: uxtab r0, r0, r1, ror #16
; CHECK-NO-DSP-NOT: uxtab
%X.hi = lshr i32 %X, 16
%X.trunc = trunc i32 %X.hi to i8
%addend = zext i8 %X.trunc to i32
@ -47,8 +48,8 @@ define i32 @test4(i32 %A, i32 %X) {
define i32 @test5(i32 %A, i32 %X) {
; CHECK-LABEL: test5:
; A8: uxtah r0, r0, r1, ror #8
; M3-NOT: uxtah
; CHECK-DSP: uxtah r0, r0, r1, ror #8
; CHECK-NO-DSP-NOT: uxtah
%X.hi = lshr i32 %X, 8
%X.trunc = trunc i32 %X.hi to i16
%addend = zext i16 %X.trunc to i32
@ -58,8 +59,8 @@ define i32 @test5(i32 %A, i32 %X) {
define i32 @test6(i32 %A, i32 %X) {
; CHECK-LABEL: test6:
; A8: uxtab r0, r0, r1, ror #8
; M3-NOT: uxtab
; CHECK-DSP: uxtab r0, r0, r1, ror #8
; CHECK-NO-DSP-NOT: uxtab
%X.hi = lshr i32 %X, 8
%X.trunc = trunc i32 %X.hi to i8
%addend = zext i8 %X.trunc to i32
@ -69,8 +70,8 @@ define i32 @test6(i32 %A, i32 %X) {
define i32 @test7(i32 %A, i32 %X) {
; CHECK-LABEL: test7:
; A8: uxtah r0, r0, r1, ror #24
; M3-NOT: uxtah
; CHECK-DSP: uxtah r0, r0, r1, ror #24
; CHECK-NO-DSP-NOT: uxtah
%lshr = lshr i32 %X, 24
%shl = shl i32 %X, 8
%or = or i32 %lshr, %shl
@ -82,8 +83,8 @@ define i32 @test7(i32 %A, i32 %X) {
define i32 @test8(i32 %A, i32 %X) {
; CHECK-LABEL: test8:
; A8: uxtah r0, r0, r1, ror #24
; M3-NOT: uxtah
; CHECK-DSP: uxtah r0, r0, r1, ror #24
; CHECK-NO-DSP-NOT: uxtah
%lshr = lshr i32 %X, 24
%shl = shl i32 %X, 8
%or = or i32 %lshr, %shl

View File

@ -1,72 +1,63 @@
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s -check-prefix=ARMv7A
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s -check-prefix=ARMv7M
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s -check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s -check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumbv7em-eabi %s -o - | FileCheck %s -check-prefix=CHECK-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s -check-prefix=CHECK-NO-DSP
; RUN: llc -mtriple=thumbv8m.main-none-eabi -mattr=+dsp %s -o - | FileCheck %s -check-prefix=CHECK-DSP
define i32 @test1(i32 %x) {
; ARMv7A: test1
; ARMv7A: uxtb16 r0, r0
; ARMv7M: test1
; ARMv7M: bic r0, r0, #-16711936
; CHECK-LABEL: test1
; CHECK-DSP: uxtb16 r0, r0
; CHECK-NO-DSP: bic r0, r0, #-16711936
%tmp1 = and i32 %x, 16711935 ; <i32> [#uses=1]
ret i32 %tmp1
}
; PR7503
define i32 @test2(i32 %x) {
; ARMv7A: test2
; ARMv7A: uxtb16 r0, r0, ror #8
; ARMv7M: test2
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, lsr #8
; CHECK-LABEL: test2
; CHECK-DSP: uxtb16 r0, r0, ror #8
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, lsr #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp2
}
define i32 @test3(i32 %x) {
; ARMv7A: test3
; ARMv7A: uxtb16 r0, r0, ror #8
; ARMv7M: test3
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, lsr #8
; CHECK-LABEL: test3
; CHECK-DSP: uxtb16 r0, r0, ror #8
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, lsr #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp2
}
define i32 @test4(i32 %x) {
; ARMv7A: test4
; ARMv7A: uxtb16 r0, r0, ror #8
; ARMv7M: test4
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, lsr #8
; CHECK-LABEL: test4
; CHECK-DSP: uxtb16 r0, r0, ror #8
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, lsr #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp6 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp6
}
define i32 @test5(i32 %x) {
; ARMv7A: test5
; ARMv7A: uxtb16 r0, r0, ror #8
; ARMv7M: test5
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, lsr #8
; CHECK-LABEL: test5
; CHECK-DSP: uxtb16 r0, r0, ror #8
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, lsr #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp2
}
define i32 @test6(i32 %x) {
; ARMv7A: test6
; ARMv7A: uxtb16 r0, r0, ror #16
; ARMv7M: test6
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, ror #16
; CHECK-LABEL: test6
; CHECK-DSP: uxtb16 r0, r0, ror #16
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, ror #16
%tmp1 = lshr i32 %x, 16 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 255 ; <i32> [#uses=1]
%tmp4 = shl i32 %x, 16 ; <i32> [#uses=1]
@ -76,12 +67,10 @@ define i32 @test6(i32 %x) {
}
define i32 @test7(i32 %x) {
; ARMv7A: test7
; ARMv7A: uxtb16 r0, r0, ror #16
; ARMv7M: test7
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, ror #16
; CHECK-LABEL: test7
; CHECK-DSP: uxtb16 r0, r0, ror #16
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, ror #16
%tmp1 = lshr i32 %x, 16 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 255 ; <i32> [#uses=1]
%tmp4 = shl i32 %x, 16 ; <i32> [#uses=1]
@ -91,12 +80,10 @@ define i32 @test7(i32 %x) {
}
define i32 @test8(i32 %x) {
; ARMv7A: test8
; ARMv7A: uxtb16 r0, r0, ror #24
; ARMv7M: test8
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, ror #24
; CHECK-LABEL: test8
; CHECK-DSP: uxtb16 r0, r0, ror #24
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, ror #24
%tmp1 = shl i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711680 ; <i32> [#uses=1]
%tmp5 = lshr i32 %x, 24 ; <i32> [#uses=1]
@ -105,12 +92,10 @@ define i32 @test8(i32 %x) {
}
define i32 @test9(i32 %x) {
; ARMv7A: test9
; ARMv7A: uxtb16 r0, r0, ror #24
; ARMv7M: test9
; ARMv7M: mov.w r1, #16711935
; ARMv7M: and.w r0, r1, r0, ror #24
; CHECK-LABEL: test9
; CHECK-DSP: uxtb16 r0, r0, ror #24
; CHECK-NO-DSP: mov.w r1, #16711935
; CHECK-NO-DSP: and.w r0, r1, r0, ror #24
%tmp1 = lshr i32 %x, 24 ; <i32> [#uses=1]
%tmp4 = shl i32 %x, 8 ; <i32> [#uses=1]
%tmp5 = and i32 %tmp4, 16711680 ; <i32> [#uses=1]
@ -119,19 +104,18 @@ define i32 @test9(i32 %x) {
}
define i32 @test10(i32 %p0) {
; ARMv7A: test10
; ARMv7A: mov.w r1, #16253176
; ARMv7A: and.w r0, r1, r0, lsr #7
; ARMv7A: lsrs r1, r0, #5
; ARMv7A: uxtb16 r1, r1
; ARMv7A: orrs r0, r1
; CHECK-LABEL: test10
; CHECK-DSP: mov.w r1, #16253176
; CHECK-DSP: and.w r0, r1, r0, lsr #7
; CHECK-DSP: lsrs r1, r0, #5
; CHECK-DSP: uxtb16 r1, r1
; CHECk-DSP: orrs r0, r1
; ARMv7M: test10
; ARMv7M: mov.w r1, #16253176
; ARMv7M: and.w r0, r1, r0, lsr #7
; ARMv7M: mov.w r1, #458759
; ARMv7M: and.w r1, r1, r0, lsr #5
; ARMv7M: orrs r0, r1
; CHECK-NO-DSP: mov.w r1, #16253176
; CHECK-NO-DSP: and.w r0, r1, r0, lsr #7
; CHECK-NO-DSP: mov.w r1, #458759
; CHECK-NO-DSP: and.w r1, r1, r0, lsr #5
; CHECK-NO-DSP: orrs r0, r1
%tmp1 = lshr i32 %p0, 7 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16253176 ; <i32> [#uses=2]
%tmp4 = lshr i32 %tmp2, 5 ; <i32> [#uses=1]