From 29402132f3e890a2771818f44987ede213297431 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 5 May 2010 23:44:43 +0000 Subject: [PATCH] Cleanup of ARMv7M support. Move hardware divide and Thumb2 extract/pack instructions to subtarget features and update tests to reflect. PR5717. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103136 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARM.td | 11 ++++++++--- lib/Target/ARM/ARMISelLowering.cpp | 5 +++-- lib/Target/ARM/ARMInstrInfo.td | 5 ++--- lib/Target/ARM/ARMInstrThumb2.td | 28 ++++++++++++++-------------- lib/Target/ARM/ARMSubtarget.cpp | 2 ++ lib/Target/ARM/ARMSubtarget.h | 11 +++++++++-- test/CodeGen/Thumb2/thumb2-pack.ll | 4 ++-- test/CodeGen/Thumb2/thumb2-rev.ll | 2 +- test/CodeGen/Thumb2/thumb2-shifter.ll | 2 +- test/CodeGen/Thumb2/thumb2-smla.ll | 2 +- test/CodeGen/Thumb2/thumb2-smul.ll | 2 +- test/CodeGen/Thumb2/thumb2-sxt_rot.ll | 2 +- test/CodeGen/Thumb2/thumb2-uxt_rot.ll | 2 +- test/CodeGen/Thumb2/thumb2-uxtb.ll | 2 +- 14 files changed, 47 insertions(+), 33 deletions(-) diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index a7425e61e8c..f1e6a9f083e 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -44,6 +44,10 @@ def FeatureThumb2 : SubtargetFeature<"thumb2", "ThumbMode", "Thumb2", "Enable Thumb2 instructions">; def FeatureFP16 : SubtargetFeature<"fp16", "HasFP16", "true", "Enable half-precision floating point">; +def FeatureHWDiv : SubtargetFeature<"hwdiv", "HasHardwareDivide", "true", + "Enable divide instructions">; +def FeatureT2ExtractPack: SubtargetFeature<"t2xtpk", "HasT2ExtractPack", "true", + "Enable Thumb2 extract and pack instructions">; // Some processors have multiply-accumulate instructions that don't // play nicely with other VFP instructions, and it's generally better @@ -125,10 +129,11 @@ def : Processor<"arm1156t2f-s", ARMV6Itineraries, // V7 Processors. def : Processor<"cortex-a8", CortexA8Itineraries, [ArchV7A, FeatureThumb2, FeatureNEON, FeatureHasSlowVMLx, - FeatureNEONForFP]>; + FeatureNEONForFP, FeatureT2ExtractPack]>; def : Processor<"cortex-a9", CortexA9Itineraries, - [ArchV7A, FeatureThumb2, FeatureNEON]>; -def : ProcNoItin<"cortex-m3", [ArchV7M, FeatureThumb2]>; + [ArchV7A, FeatureThumb2, FeatureNEON, FeatureT2ExtractPack]>; +def : ProcNoItin<"cortex-m3", [ArchV7M, FeatureThumb2, FeatureHWDiv]>; +def : ProcNoItin<"cortex-m4", [ArchV7M, FeatureThumb2, FeatureHWDiv]>; //===----------------------------------------------------------------------===// // Register File Description diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c1d2d3ac428..f8c17b8ac2d 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -363,7 +363,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::BSWAP, MVT::i32, Expand); // These are expanded into libcalls. - if (!Subtarget->hasV7MOps()) { + if (!Subtarget->hasDivide()) { // v7M has a hardware divider setOperationAction(ISD::SDIV, MVT::i32, Expand); setOperationAction(ISD::UDIV, MVT::i32, Expand); @@ -393,7 +393,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom); - if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2() || Subtarget->hasV7MOps()) { + if (!Subtarget->hasV6Ops() && (!Subtarget->isThumb2() + || !Subtarget->hasT2ExtractPack())) { setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index e74c85c1f0b..6540497d1e4 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -124,13 +124,12 @@ def HasV6 : Predicate<"Subtarget->hasV6Ops()">; def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">; def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; def HasV7 : Predicate<"Subtarget->hasV7Ops()">; -def HasV7A : Predicate<"Subtarget->hasV7AOps()">; -def HasV7M : Predicate<"Subtarget->hasV7MOps()">; -def NoV7M : Predicate<"!Subtarget->hasV7MOps()">; def NoVFP : Predicate<"!Subtarget->hasVFP2()">; def HasVFP2 : Predicate<"Subtarget->hasVFP2()">; def HasVFP3 : Predicate<"Subtarget->hasVFP3()">; def HasNEON : Predicate<"Subtarget->hasNEON()">; +def HasDivide : Predicate<"Subtarget->hasDivide()">; +def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">; def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; def IsThumb : Predicate<"Subtarget->isThumb()">; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 07d176742f5..78d1a75c086 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -640,7 +640,7 @@ multiclass T2I_unary_rrot opcod, string opc, PatFrag opnode> { def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, opc, ".w\t$dst, $src", [(set GPR:$dst, (opnode GPR:$src))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; let Inst{22-20} = opcod; @@ -652,7 +652,7 @@ multiclass T2I_unary_rrot opcod, string opc, PatFrag opnode> { def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi, opc, ".w\t$dst, $src, ror $rot", [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; let Inst{22-20} = opcod; @@ -668,7 +668,7 @@ multiclass T2I_unary_rrot_nw opcod, string opc, PatFrag opnode> { def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, opc, "\t$dst, $src", [(set GPR:$dst, (opnode GPR:$src))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; let Inst{22-20} = opcod; @@ -680,7 +680,7 @@ multiclass T2I_unary_rrot_nw opcod, string opc, PatFrag opnode> { def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi, opc, "\t$dst, $src, ror $rot", [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; let Inst{22-20} = opcod; @@ -722,7 +722,7 @@ multiclass T2I_bin_rrot opcod, string opc, PatFrag opnode> { def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr, opc, "\t$dst, $LHS, $RHS", [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; let Inst{22-20} = opcod; @@ -734,7 +734,7 @@ multiclass T2I_bin_rrot opcod, string opc, PatFrag opnode> { IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", [(set GPR:$dst, (opnode GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; let Inst{22-20} = opcod; @@ -866,7 +866,7 @@ def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi, "sdiv", "\t$dst, $a, $b", [(set GPR:$dst, (sdiv GPR:$a, GPR:$b))]>, - Requires<[HasV7M]> { + Requires<[HasDivide]> { let Inst{31-27} = 0b11111; let Inst{26-21} = 0b011100; let Inst{20} = 0b1; @@ -877,7 +877,7 @@ def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi, def t2UDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi, "udiv", "\t$dst, $a, $b", [(set GPR:$dst, (udiv GPR:$a, GPR:$b))]>, - Requires<[HasV7M]> { + Requires<[HasDivide]> { let Inst{31-27} = 0b11111; let Inst{26-21} = 0b011101; let Inst{20} = 0b1; @@ -2069,7 +2069,7 @@ def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), (and (shl GPR:$src2, (i32 imm:$shamt)), 0xFFFF0000)))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-20} = 0b01100; @@ -2080,17 +2080,17 @@ def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), // Alternate cases for PKHBT where identities eliminate some nodes. def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)), (t2PKHBT GPR:$src1, GPR:$src2, 0)>, - Requires<[NoV7M]>; + Requires<[HasT2ExtractPack]>; def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)), (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>, - Requires<[NoV7M]>; + Requires<[HasT2ExtractPack]>; def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt", [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), (and (sra GPR:$src2, imm16_31:$shamt), 0xFFFF)))]>, - Requires<[NoV7M]> { + Requires<[HasT2ExtractPack]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-20} = 0b01100; @@ -2102,11 +2102,11 @@ def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), // a shift amount of 0 is *not legal* here, it is PKHBT instead. def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))), (t2PKHTB GPR:$src1, GPR:$src2, 16)>, - Requires<[NoV7M]>; + Requires<[HasT2ExtractPack]>; def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)), (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>, - Requires<[NoV7M]>; + Requires<[HasT2ExtractPack]>; //===----------------------------------------------------------------------===// // Comparison Instructions... diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 0c777e2c4d9..10fd257055f 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -39,6 +39,8 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, , IsR9Reserved(ReserveR9) , UseMovt(UseMOVT) , HasFP16(false) + , HasHardwareDivide(false) + , HasT2ExtractPack(false) , stackAlignment(4) , CPUString("generic") , TargetType(isELF) // Default to ELF unless otherwise specified. diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 18715087b9a..3ba0a2e9410 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -74,6 +74,13 @@ protected: /// only so far) bool HasFP16; + /// HasHardwareDivide - True if subtarget supports [su]div + bool HasHardwareDivide; + + /// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack + /// instructions. + bool HasT2ExtractPack; + /// stackAlignment - The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned stackAlignment; @@ -117,14 +124,14 @@ protected: bool hasV6Ops() const { return ARMArchVersion >= V6; } bool hasV6T2Ops() const { return ARMArchVersion >= V6T2; } bool hasV7Ops() const { return ARMArchVersion >= V7A; } - bool hasV7AOps() const { return ARMArchVersion == V7A; } - bool hasV7MOps() const { return ARMArchVersion == V7M; } bool hasVFP2() const { return ARMFPUType >= VFPv2; } bool hasVFP3() const { return ARMFPUType >= VFPv3; } bool hasNEON() const { return ARMFPUType >= NEON; } bool useNEONForSinglePrecisionFP() const { return hasNEON() && UseNEONForSinglePrecisionFP; } + bool hasDivide() const { return HasHardwareDivide; }; + bool hasT2ExtractPack() const { return HasT2ExtractPack; }; bool useVMLx() const {return hasVFP2() && !SlowVMLx; } bool hasFP16() const { return HasFP16; } diff --git a/test/CodeGen/Thumb2/thumb2-pack.ll b/test/CodeGen/Thumb2/thumb2-pack.ll index a9822498fe0..c8302df78f6 100644 --- a/test/CodeGen/Thumb2/thumb2-pack.ll +++ b/test/CodeGen/Thumb2/thumb2-pack.ll @@ -1,6 +1,6 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | \ ; RUN: grep pkhbt | count 5 -; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | \ ; RUN: grep pkhtb | count 4 define i32 @test1(i32 %X, i32 %Y) { diff --git a/test/CodeGen/Thumb2/thumb2-rev.ll b/test/CodeGen/Thumb2/thumb2-rev.ll index 27b1672e554..2cee2e3d6fc 100644 --- a/test/CodeGen/Thumb2/thumb2-rev.ll +++ b/test/CodeGen/Thumb2/thumb2-rev.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7a | FileCheck %s +; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7a,+t2xtpk | FileCheck %s define i32 @f1(i32 %a) { ; CHECK: f1: diff --git a/test/CodeGen/Thumb2/thumb2-shifter.ll b/test/CodeGen/Thumb2/thumb2-shifter.ll index b106cedc092..98854a1205f 100644 --- a/test/CodeGen/Thumb2/thumb2-shifter.ll +++ b/test/CodeGen/Thumb2/thumb2-shifter.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) { ; CHECK: t2ADDrs_lsl diff --git a/test/CodeGen/Thumb2/thumb2-smla.ll b/test/CodeGen/Thumb2/thumb2-smla.ll index 092ec27de4c..bd4dcbe622f 100644 --- a/test/CodeGen/Thumb2/thumb2-smla.ll +++ b/test/CodeGen/Thumb2/thumb2-smla.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s define i32 @f3(i32 %a, i16 %x, i32 %y) { ; CHECK: f3 diff --git a/test/CodeGen/Thumb2/thumb2-smul.ll b/test/CodeGen/Thumb2/thumb2-smul.ll index 16ea85db69c..ae175355059 100644 --- a/test/CodeGen/Thumb2/thumb2-smul.ll +++ b/test/CodeGen/Thumb2/thumb2-smul.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s @x = weak global i16 0 ; [#uses=1] @y = weak global i16 0 ; [#uses=0] diff --git a/test/CodeGen/Thumb2/thumb2-sxt_rot.ll b/test/CodeGen/Thumb2/thumb2-sxt_rot.ll index 054d5df3583..4b685a86fd8 100644 --- a/test/CodeGen/Thumb2/thumb2-sxt_rot.ll +++ b/test/CodeGen/Thumb2/thumb2-sxt_rot.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s define i32 @test0(i8 %A) { ; CHECK: test0 diff --git a/test/CodeGen/Thumb2/thumb2-uxt_rot.ll b/test/CodeGen/Thumb2/thumb2-uxt_rot.ll index 75e1d70260c..b8e43812ed9 100644 --- a/test/CodeGen/Thumb2/thumb2-uxt_rot.ll +++ b/test/CodeGen/Thumb2/thumb2-uxt_rot.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s define i8 @test1(i32 %A.u) zeroext { ; CHECK: test1 diff --git a/test/CodeGen/Thumb2/thumb2-uxtb.ll b/test/CodeGen/Thumb2/thumb2-uxtb.ll index 91598cdc961..541191400b1 100644 --- a/test/CodeGen/Thumb2/thumb2-uxtb.ll +++ b/test/CodeGen/Thumb2/thumb2-uxtb.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s define i32 @test1(i32 %x) { ; CHECK: test1 -- 2.11.0