mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Add LLVM support for remaining integer divide and permute instructions from ISA 2.06
This is the patch corresponding to review: http://reviews.llvm.org/D8406 It adds some missing instructions from ISA 2.06 to the PPC back end. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234546 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
427c073035
commit
c58b8f0b65
@ -37,6 +37,25 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
|
||||
// generated by the PowerPC backend!
|
||||
def int_ppc_mtctr : Intrinsic<[], [llvm_anyint_ty], []>;
|
||||
def int_ppc_is_decremented_ctr_nonzero : Intrinsic<[llvm_i1_ty], [], []>;
|
||||
|
||||
// Intrinsics for [double]word extended forms of divide instructions
|
||||
def int_ppc_divwe : GCCBuiltin<"__builtin_divwe">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_divweu : GCCBuiltin<"__builtin_divweu">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_divde : GCCBuiltin<"__builtin_divde">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_divdeu : GCCBuiltin<"__builtin_divdeu">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
// Bit permute doubleword
|
||||
def int_ppc_bpermd : GCCBuiltin<"__builtin_bpermd">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
|
||||
[IntrNoMem]>;
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,6 +86,10 @@ def FeatureISEL : SubtargetFeature<"isel","HasISEL", "true",
|
||||
"Enable the isel instruction">;
|
||||
def FeaturePOPCNTD : SubtargetFeature<"popcntd","HasPOPCNTD", "true",
|
||||
"Enable the popcnt[dw] instructions">;
|
||||
def FeatureBPERMD : SubtargetFeature<"bpermd", "HasBPERMD", "true",
|
||||
"Enable the bpermd instruction">;
|
||||
def FeatureExtDiv : SubtargetFeature<"extdiv", "HasExtDiv", "true",
|
||||
"Enable extended divide instructions">;
|
||||
def FeatureLDBRX : SubtargetFeature<"ldbrx","HasLDBRX", "true",
|
||||
"Enable the ldbrx instruction">;
|
||||
def FeatureCMPB : SubtargetFeature<"cmpb", "HasCMPB", "true",
|
||||
@ -133,6 +137,38 @@ def DeprecatedMFTB : SubtargetFeature<"", "DeprecatedMFTB", "true",
|
||||
def DeprecatedDST : SubtargetFeature<"", "DeprecatedDST", "true",
|
||||
"Treat vector data stream cache control instructions as deprecated">;
|
||||
|
||||
/* Since new processors generally contain a superset of features of those that
|
||||
came before them, the idea is to make implementations of new processors
|
||||
less error prone and easier to read.
|
||||
Namely:
|
||||
list<SubtargetFeature> Power8FeatureList = ...
|
||||
list<SubtargetFeature> FutureProcessorSpecificFeatureList =
|
||||
[ features that Power8 does not support ]
|
||||
list<SubtargetFeature> FutureProcessorFeatureList =
|
||||
!listconcat(Power8FeatureList, FutureProcessorSpecificFeatureList)
|
||||
|
||||
Makes it explicit and obvious what is new in FutureProcesor vs. Power8 as
|
||||
well as providing a single point of definition if the feature set will be
|
||||
used elsewhere.
|
||||
*/
|
||||
def ProcessorFeatures {
|
||||
list<SubtargetFeature> Power7FeatureList =
|
||||
[DirectivePwr7, FeatureAltivec, FeatureVSX,
|
||||
FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, FeatureFRE,
|
||||
FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES,
|
||||
FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX,
|
||||
FeatureFPRND, FeatureFPCVT, FeatureISEL,
|
||||
FeaturePOPCNTD, FeatureCMPB, FeatureLDBRX,
|
||||
Feature64Bit /*, Feature64BitRegs */, FeaturePartwordAtomic,
|
||||
FeatureBPERMD, FeatureExtDiv,
|
||||
DeprecatedMFTB, DeprecatedDST];
|
||||
list<SubtargetFeature> Power8SpecificFeatures =
|
||||
[DirectivePwr8, FeatureP8Altivec, FeatureP8Vector, FeatureP8Crypto,
|
||||
FeatureHTM, FeatureICBT];
|
||||
list<SubtargetFeature> Power8FeatureList =
|
||||
!listconcat(Power7FeatureList, Power8SpecificFeatures);
|
||||
}
|
||||
|
||||
// Note: Future features to add when support is extended to more
|
||||
// recent ISA levels:
|
||||
//
|
||||
@ -243,33 +279,6 @@ def : Processor<"7450", G4PlusItineraries, [Directive7400, FeatureAltivec,
|
||||
def : Processor<"g4+", G4PlusItineraries, [Directive7400, FeatureAltivec,
|
||||
FeatureFRES, FeatureFRSQRTE]>;
|
||||
|
||||
/* Since new processors generally contain a superset of features of those that
|
||||
came before them, the idea is to make implementations of new processors
|
||||
less error prone and easier to read.
|
||||
Namely:
|
||||
list<SubtargetFeature> Power8FeatureList = ...
|
||||
list<SubtargetFeature> FutureProcessorSpecificFeatureList =
|
||||
[ features that Power8 does not support ]
|
||||
list<SubtargetFeature> FutureProcessorFeatureList =
|
||||
!listconcat(Power8FeatureList, FutureProcessorSpecificFeatureList)
|
||||
|
||||
Makes it explicit and obvious what is new in FutureProcesor vs. Power8 as
|
||||
well as providing a single point of definition if the feature set will be
|
||||
used elsewhere.
|
||||
|
||||
*/
|
||||
def ProcessorFeatures {
|
||||
list<SubtargetFeature> Power8FeatureList =
|
||||
[DirectivePwr8, FeatureAltivec, FeatureP8Altivec, FeatureVSX,
|
||||
FeatureP8Vector, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt,
|
||||
FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES,
|
||||
FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureHTM,
|
||||
FeatureFPRND, FeatureFPCVT, FeatureISEL,
|
||||
FeaturePOPCNTD, FeatureCMPB, FeatureLDBRX, FeatureP8Crypto,
|
||||
Feature64Bit /*, Feature64BitRegs */, FeatureICBT,
|
||||
FeaturePartwordAtomic, DeprecatedMFTB, DeprecatedDST];
|
||||
}
|
||||
|
||||
def : ProcessorModel<"970", G5Model,
|
||||
[Directive970, FeatureAltivec,
|
||||
FeatureMFOCRF, FeatureFSqrt,
|
||||
@ -339,15 +348,7 @@ def : ProcessorModel<"pwr6x", G5Model,
|
||||
FeatureSTFIWX, FeatureLFIWAX, FeatureCMPB,
|
||||
FeatureFPRND, Feature64Bit,
|
||||
DeprecatedMFTB, DeprecatedDST]>;
|
||||
def : ProcessorModel<"pwr7", P7Model,
|
||||
[DirectivePwr7, FeatureAltivec, FeatureVSX,
|
||||
FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, FeatureFRE,
|
||||
FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES,
|
||||
FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX,
|
||||
FeatureFPRND, FeatureFPCVT, FeatureISEL,
|
||||
FeaturePOPCNTD, FeatureCMPB, FeatureLDBRX,
|
||||
Feature64Bit /*, Feature64BitRegs */, FeaturePartwordAtomic,
|
||||
DeprecatedMFTB, DeprecatedDST]>;
|
||||
def : ProcessorModel<"pwr7", P7Model, ProcessorFeatures.Power7FeatureList>;
|
||||
def : ProcessorModel<"pwr8", P8Model, ProcessorFeatures.Power8FeatureList>;
|
||||
def : Processor<"ppc", G3Itineraries, [Directive32]>;
|
||||
def : ProcessorModel<"ppc64", G5Model,
|
||||
|
@ -603,6 +603,10 @@ defm CNTLZD : XForm_11r<31, 58, (outs g8rc:$rA), (ins g8rc:$rS),
|
||||
def POPCNTD : XForm_11<31, 506, (outs g8rc:$rA), (ins g8rc:$rS),
|
||||
"popcntd $rA, $rS", IIC_IntGeneral,
|
||||
[(set i64:$rA, (ctpop i64:$rS))]>;
|
||||
def BPERMD : XForm_6<31, 252, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
|
||||
"bpermd $rA, $rS, $rB", IIC_IntGeneral,
|
||||
[(set i64:$rA, (int_ppc_bpermd g8rc:$rS, g8rc:$rB))]>,
|
||||
isPPC64, Requires<[HasBPERMD]>;
|
||||
|
||||
let isCodeGenOnly = 1, isCommutable = 1 in
|
||||
def CMPB8 : XForm_6<31, 508, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
|
||||
@ -616,14 +620,30 @@ def POPCNTW : XForm_11<31, 378, (outs gprc:$rA), (ins gprc:$rS),
|
||||
"popcntw $rA, $rS", IIC_IntGeneral,
|
||||
[(set i32:$rA, (ctpop i32:$rS))]>;
|
||||
|
||||
defm DIVD : XOForm_1r<31, 489, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divd", "$rT, $rA, $rB", IIC_IntDivD,
|
||||
[(set i64:$rT, (sdiv i64:$rA, i64:$rB))]>, isPPC64,
|
||||
PPC970_DGroup_First, PPC970_DGroup_Cracked;
|
||||
defm DIVDU : XOForm_1r<31, 457, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divdu", "$rT, $rA, $rB", IIC_IntDivD,
|
||||
[(set i64:$rT, (udiv i64:$rA, i64:$rB))]>, isPPC64,
|
||||
PPC970_DGroup_First, PPC970_DGroup_Cracked;
|
||||
defm DIVD : XOForm_1rcr<31, 489, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divd", "$rT, $rA, $rB", IIC_IntDivD,
|
||||
[(set i64:$rT, (sdiv i64:$rA, i64:$rB))]>, isPPC64;
|
||||
defm DIVDU : XOForm_1rcr<31, 457, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divdu", "$rT, $rA, $rB", IIC_IntDivD,
|
||||
[(set i64:$rT, (udiv i64:$rA, i64:$rB))]>, isPPC64;
|
||||
def DIVDE : XOForm_1<31, 425, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divde $rT, $rA, $rB", IIC_IntDivD,
|
||||
[(set i64:$rT, (int_ppc_divde g8rc:$rA, g8rc:$rB))]>,
|
||||
isPPC64, Requires<[HasExtDiv]>;
|
||||
let Defs = [CR0] in
|
||||
def DIVDEo : XOForm_1<31, 425, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divde. $rT, $rA, $rB", IIC_IntDivD,
|
||||
[]>, isDOT, PPC970_DGroup_Cracked, PPC970_DGroup_First,
|
||||
isPPC64, Requires<[HasExtDiv]>;
|
||||
def DIVDEU : XOForm_1<31, 393, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divdeu $rT, $rA, $rB", IIC_IntDivD,
|
||||
[(set i64:$rT, (int_ppc_divdeu g8rc:$rA, g8rc:$rB))]>,
|
||||
isPPC64, Requires<[HasExtDiv]>;
|
||||
let Defs = [CR0] in
|
||||
def DIVDEUo : XOForm_1<31, 393, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"divdeu. $rT, $rA, $rB", IIC_IntDivD,
|
||||
[]>, isDOT, PPC970_DGroup_Cracked, PPC970_DGroup_First,
|
||||
isPPC64, Requires<[HasExtDiv]>;
|
||||
let isCommutable = 1 in
|
||||
defm MULLD : XOForm_1r<31, 233, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
|
||||
"mulld", "$rT, $rA, $rB", IIC_IntMulHD,
|
||||
|
@ -726,6 +726,8 @@ def HasICBT : Predicate<"PPCSubTarget->hasICBT()">;
|
||||
def HasPartwordAtomics : Predicate<"PPCSubTarget->hasPartwordAtomics()">;
|
||||
def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
|
||||
def NaNsFPMath : Predicate<"!TM.Options.NoNaNsFPMath">;
|
||||
def HasBPERMD : Predicate<"PPCSubTarget->hasBPERMD()">;
|
||||
def HasExtDiv : Predicate<"PPCSubTarget->hasExtDiv()">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PowerPC Multiclass Definitions.
|
||||
@ -802,6 +804,23 @@ multiclass XOForm_1r<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
|
||||
}
|
||||
}
|
||||
|
||||
// Multiclass for instructions for which the non record form is not cracked
|
||||
// and the record form is cracked (i.e. divw, mullw, etc.)
|
||||
multiclass XOForm_1rcr<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
|
||||
string asmbase, string asmstr, InstrItinClass itin,
|
||||
list<dag> pattern> {
|
||||
let BaseName = asmbase in {
|
||||
def NAME : XOForm_1<opcode, xo, oe, OOL, IOL,
|
||||
!strconcat(asmbase, !strconcat(" ", asmstr)), itin,
|
||||
pattern>, RecFormRel;
|
||||
let Defs = [CR0] in
|
||||
def o : XOForm_1<opcode, xo, oe, OOL, IOL,
|
||||
!strconcat(asmbase, !strconcat(". ", asmstr)), itin,
|
||||
[]>, isDOT, RecFormRel, PPC970_DGroup_First,
|
||||
PPC970_DGroup_Cracked;
|
||||
}
|
||||
}
|
||||
|
||||
multiclass XOForm_1rc<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
|
||||
string asmbase, string asmstr, InstrItinClass itin,
|
||||
list<dag> pattern> {
|
||||
@ -2300,14 +2319,30 @@ defm ADDC : XOForm_1rc<31, 10, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
[(set i32:$rT, (addc i32:$rA, i32:$rB))]>,
|
||||
PPC970_DGroup_Cracked;
|
||||
|
||||
defm DIVW : XOForm_1r<31, 491, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divw", "$rT, $rA, $rB", IIC_IntDivW,
|
||||
[(set i32:$rT, (sdiv i32:$rA, i32:$rB))]>,
|
||||
PPC970_DGroup_First, PPC970_DGroup_Cracked;
|
||||
defm DIVWU : XOForm_1r<31, 459, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divwu", "$rT, $rA, $rB", IIC_IntDivW,
|
||||
[(set i32:$rT, (udiv i32:$rA, i32:$rB))]>,
|
||||
PPC970_DGroup_First, PPC970_DGroup_Cracked;
|
||||
defm DIVW : XOForm_1rcr<31, 491, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divw", "$rT, $rA, $rB", IIC_IntDivW,
|
||||
[(set i32:$rT, (sdiv i32:$rA, i32:$rB))]>;
|
||||
defm DIVWU : XOForm_1rcr<31, 459, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divwu", "$rT, $rA, $rB", IIC_IntDivW,
|
||||
[(set i32:$rT, (udiv i32:$rA, i32:$rB))]>;
|
||||
def DIVWE : XOForm_1<31, 427, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divwe $rT, $rA, $rB", IIC_IntDivW,
|
||||
[(set i32:$rT, (int_ppc_divwe gprc:$rA, gprc:$rB))]>,
|
||||
Requires<[HasExtDiv]>;
|
||||
let Defs = [CR0] in
|
||||
def DIVWEo : XOForm_1<31, 427, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divwe. $rT, $rA, $rB", IIC_IntDivW,
|
||||
[]>, isDOT, PPC970_DGroup_Cracked, PPC970_DGroup_First,
|
||||
Requires<[HasExtDiv]>;
|
||||
def DIVWEU : XOForm_1<31, 395, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divweu $rT, $rA, $rB", IIC_IntDivW,
|
||||
[(set i32:$rT, (int_ppc_divweu gprc:$rA, gprc:$rB))]>,
|
||||
Requires<[HasExtDiv]>;
|
||||
let Defs = [CR0] in
|
||||
def DIVWEUo : XOForm_1<31, 395, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"divweu. $rT, $rA, $rB", IIC_IntDivW,
|
||||
[]>, isDOT, PPC970_DGroup_Cracked, PPC970_DGroup_First,
|
||||
Requires<[HasExtDiv]>;
|
||||
let isCommutable = 1 in {
|
||||
defm MULHW : XOForm_1r<31, 75, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
|
||||
"mulhw", "$rT, $rA, $rB", IIC_IntMulHW,
|
||||
|
@ -82,6 +82,8 @@ void PPCSubtarget::initializeEnvironment() {
|
||||
HasFPCVT = false;
|
||||
HasISEL = false;
|
||||
HasPOPCNTD = false;
|
||||
HasBPERMD = false;
|
||||
HasExtDiv = false;
|
||||
HasCMPB = false;
|
||||
HasLDBRX = false;
|
||||
IsBookE = false;
|
||||
|
@ -101,6 +101,8 @@ protected:
|
||||
bool HasFPCVT;
|
||||
bool HasISEL;
|
||||
bool HasPOPCNTD;
|
||||
bool HasBPERMD;
|
||||
bool HasExtDiv;
|
||||
bool HasCMPB;
|
||||
bool HasLDBRX;
|
||||
bool IsBookE;
|
||||
@ -225,6 +227,8 @@ public:
|
||||
bool hasMFOCRF() const { return HasMFOCRF; }
|
||||
bool hasISEL() const { return HasISEL; }
|
||||
bool hasPOPCNTD() const { return HasPOPCNTD; }
|
||||
bool hasBPERMD() const { return HasBPERMD; }
|
||||
bool hasExtDiv() const { return HasExtDiv; }
|
||||
bool hasCMPB() const { return HasCMPB; }
|
||||
bool hasLDBRX() const { return HasLDBRX; }
|
||||
bool isBookE() const { return IsBookE; }
|
||||
|
@ -622,6 +622,25 @@ void foo() {
|
||||
__asm__("" ::: "cr2");
|
||||
}
|
||||
|
||||
//===-------------------------------------------------------------------------===
|
||||
Naming convention for instruction formats is very haphazard.
|
||||
We have agreed on a naming scheme as follows:
|
||||
|
||||
<INST_form>{_<OP_type><OP_len>}+
|
||||
|
||||
Where:
|
||||
INST_form is the instruction format (X-form, etc.)
|
||||
OP_type is the operand type - one of OPC (opcode), RD (register destination),
|
||||
RS (register source),
|
||||
RDp (destination register pair),
|
||||
RSp (source register pair), IM (immediate),
|
||||
XO (extended opcode)
|
||||
OP_len is the length of the operand in bits
|
||||
|
||||
VSX register operands would be of length 6 (split across two fields),
|
||||
condition register fields of length 3.
|
||||
We would not need denote reserved fields in names of instruction formats.
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Instruction fusion was introduced in ISA 2.06 and more opportunities added in
|
||||
|
31
test/CodeGen/PowerPC/div-e-32.ll
Normal file
31
test/CodeGen/PowerPC/div-e-32.ll
Normal file
@ -0,0 +1,31 @@
|
||||
; RUN: llc -mtriple=powerpc-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=powerpc-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define signext i32 @test1() #0 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.ppc.divwe(i32 32, i32 16)
|
||||
ret i32 %0
|
||||
; CHECK: divwe 3, 4, 3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @llvm.ppc.divwe(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define signext i32 @test2() #0 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.ppc.divweu(i32 32, i32 16)
|
||||
ret i32 %0
|
||||
; CHECK: divweu 3, 4, 3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @llvm.ppc.divweu(i32, i32) #1
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { nounwind readnone }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 3.7.0 (trunk 231831) (llvm/trunk 231828:231843M)"}
|
54
test/CodeGen/PowerPC/div-e-all.ll
Normal file
54
test/CodeGen/PowerPC/div-e-all.ll
Normal file
@ -0,0 +1,54 @@
|
||||
; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define signext i32 @test1() #0 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.ppc.divwe(i32 32, i32 16)
|
||||
ret i32 %0
|
||||
; CHECK: divwe 3, 4, 3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @llvm.ppc.divwe(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define signext i32 @test2() #0 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.ppc.divweu(i32 32, i32 16)
|
||||
ret i32 %0
|
||||
; CHECK: divweu 3, 4, 3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @llvm.ppc.divweu(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test3() #0 {
|
||||
entry:
|
||||
%0 = call i64 @llvm.ppc.divde(i64 32, i64 16)
|
||||
ret i64 %0
|
||||
; CHECK: divde 3, 4, 3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i64 @llvm.ppc.divde(i64, i64) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test4() #0 {
|
||||
entry:
|
||||
%0 = call i64 @llvm.ppc.divdeu(i64 32, i64 16)
|
||||
ret i64 %0
|
||||
; CHECK: divdeu 3, 4, 3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i64 @llvm.ppc.divdeu(i64, i64) #1
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { nounwind readnone }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 3.7.0 (trunk 231831) (llvm/trunk 231828:231843M)"}
|
@ -328,6 +328,18 @@
|
||||
# CHECK: divwu. 2, 3, 4
|
||||
0x7c 0x43 0x23 0x97
|
||||
|
||||
# CHECK: divwe 2, 3, 4
|
||||
0x7c 0x43 0x23 0x56
|
||||
|
||||
# CHECK: divwe. 2, 3, 4
|
||||
0x7c 0x43 0x23 0x57
|
||||
|
||||
# CHECK: divweu 2, 3, 4
|
||||
0x7c 0x43 0x23 0x16
|
||||
|
||||
# CHECK: divweu. 2, 3, 4
|
||||
0x7c 0x43 0x23 0x17
|
||||
|
||||
# CHECK: mulld 2, 3, 4
|
||||
0x7c 0x43 0x21 0xd2
|
||||
|
||||
@ -358,6 +370,18 @@
|
||||
# CHECK: divdu. 2, 3, 4
|
||||
0x7c 0x43 0x23 0x93
|
||||
|
||||
# CHECK: divde 2, 3, 4
|
||||
0x7c 0x43 0x23 0x52
|
||||
|
||||
# CHECK: divde. 2, 3, 4
|
||||
0x7c 0x43 0x23 0x53
|
||||
|
||||
# CHECK: divdeu 2, 3, 4
|
||||
0x7c 0x43 0x23 0x12
|
||||
|
||||
# CHECK: divdeu. 2, 3, 4
|
||||
0x7c 0x43 0x23 0x13
|
||||
|
||||
# CHECK: cmpdi 2, 3, 128
|
||||
0x2d 0x23 0x00 0x80
|
||||
|
||||
@ -499,6 +523,9 @@
|
||||
# CHECK: popcntd 2, 3
|
||||
0x7c 0x62 0x03 0xf4
|
||||
|
||||
# CHECK: bpermd 2, 3, 4
|
||||
0x7c 0x62 0x21 0xf8
|
||||
|
||||
# CHECK: cmpb 7, 21, 4
|
||||
0x7e 0xa7 0x23 0xf8
|
||||
|
||||
|
@ -420,12 +420,20 @@
|
||||
divwu. 2, 3, 4
|
||||
# FIXME: divwuo 2, 3, 4
|
||||
# FIXME: divwuo. 2, 3, 4
|
||||
# FIXME: divwe 2, 3, 4
|
||||
# FIXME: divwe. 2, 3, 4
|
||||
# CHECK-BE: divwe 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x56]
|
||||
# CHECK-LE: divwe 2, 3, 4 # encoding: [0x56,0x23,0x43,0x7c]
|
||||
divwe 2, 3, 4
|
||||
# CHECK-BE: divwe. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x57]
|
||||
# CHECK-LE: divwe. 2, 3, 4 # encoding: [0x57,0x23,0x43,0x7c]
|
||||
divwe. 2, 3, 4
|
||||
# FIXME: divweo 2, 3, 4
|
||||
# FIXME: divweo. 2, 3, 4
|
||||
# FIXME: divweu 2, 3, 4
|
||||
# FIXME: divweu. 2, 3, 4
|
||||
# CHECK-BE: divweu 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x16]
|
||||
# CHECK-LE: divweu 2, 3, 4 # encoding: [0x16,0x23,0x43,0x7c]
|
||||
divweu 2, 3, 4
|
||||
# CHECK-BE: divweu. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x17]
|
||||
# CHECK-LE: divweu. 2, 3, 4 # encoding: [0x17,0x23,0x43,0x7c]
|
||||
divweu. 2, 3, 4
|
||||
# FIXME: divweuo 2, 3, 4
|
||||
# FIXME: divweuo. 2, 3, 4
|
||||
|
||||
@ -466,12 +474,20 @@
|
||||
divdu. 2, 3, 4
|
||||
# FIXME: divduo 2, 3, 4
|
||||
# FIXME: divduo. 2, 3, 4
|
||||
# FIXME: divde 2, 3, 4
|
||||
# FIXME: divde. 2, 3, 4
|
||||
# CHECK-BE: divde 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x52]
|
||||
# CHECK-LE: divde 2, 3, 4 # encoding: [0x52,0x23,0x43,0x7c]
|
||||
divde 2, 3, 4
|
||||
# CHECK-BE: divde. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x53]
|
||||
# CHECK-LE: divde. 2, 3, 4 # encoding: [0x53,0x23,0x43,0x7c]
|
||||
divde. 2, 3, 4
|
||||
# FIXME: divdeo 2, 3, 4
|
||||
# FIXME: divdeo. 2, 3, 4
|
||||
# FIXME: divdeu 2, 3, 4
|
||||
# FIXME: divdeu. 2, 3, 4
|
||||
# CHECK-BE: divdeu 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x12]
|
||||
# CHECK-LE: divdeu 2, 3, 4 # encoding: [0x12,0x23,0x43,0x7c]
|
||||
divdeu 2, 3, 4
|
||||
# CHECK-BE: divdeu. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x13]
|
||||
# CHECK-LE: divdeu. 2, 3, 4 # encoding: [0x13,0x23,0x43,0x7c]
|
||||
divdeu. 2, 3, 4
|
||||
# FIXME: divdeuo 2, 3, 4
|
||||
# FIXME: divdeuo. 2, 3, 4
|
||||
|
||||
@ -644,7 +660,9 @@
|
||||
# CHECK-BE: popcntd 2, 3 # encoding: [0x7c,0x62,0x03,0xf4]
|
||||
# CHECK-LE: popcntd 2, 3 # encoding: [0xf4,0x03,0x62,0x7c]
|
||||
popcntd 2, 3
|
||||
# FIXME: bpermd 2, 3, 4
|
||||
# CHECK-BE: bpermd 2, 3, 4 # encoding: [0x7c,0x62,0x21,0xf8]
|
||||
# CHECK-LE: bpermd 2, 3, 4 # encoding: [0xf8,0x21,0x62,0x7c]
|
||||
bpermd 2, 3, 4
|
||||
|
||||
# Fixed-point rotate and shift instructions
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user