forked from OSchip/llvm-project
[Sparc] Added software multiplication/division feature
Added a feature to the Sparc back-end that replaces the integer multiply and divide instructions with calls to .mul/.sdiv/.udiv. This is a step towards having full v7 support. Patch by: Eric Kedaigle Differential Revision: https://reviews.llvm.org/D35500 llvm-svn: 308343
This commit is contained in:
parent
028e619be8
commit
dda87cab7d
|
@ -20,6 +20,10 @@ include "llvm/Target/Target.td"
|
|||
// SPARC Subtarget features.
|
||||
//
|
||||
|
||||
def FeatureSoftMulDiv
|
||||
: SubtargetFeature<"soft-mul-div", "UseSoftMulDiv", "true",
|
||||
"Use software emulation for integer multiply and divide">;
|
||||
|
||||
def FeatureV9
|
||||
: SubtargetFeature<"v9", "IsV9", "true",
|
||||
"Enable SPARC-V9 instructions">;
|
||||
|
@ -75,7 +79,7 @@ class Proc<string Name, list<SubtargetFeature> Features>
|
|||
: Processor<Name, NoItineraries, Features>;
|
||||
|
||||
def : Proc<"generic", []>;
|
||||
def : Proc<"v7", []>;
|
||||
def : Proc<"v7", [FeatureSoftMulDiv]>;
|
||||
def : Proc<"v8", []>;
|
||||
def : Proc<"supersparc", []>;
|
||||
def : Proc<"sparclite", []>;
|
||||
|
|
|
@ -1689,6 +1689,19 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
|
|||
setOperationAction(ISD::MULHS, MVT::i32, Expand);
|
||||
setOperationAction(ISD::MUL, MVT::i32, Expand);
|
||||
|
||||
if (Subtarget->useSoftMulDiv()) {
|
||||
// .umul works for both signed and unsigned
|
||||
setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
|
||||
setLibcallName(RTLIB::MUL_I32, ".umul");
|
||||
|
||||
setOperationAction(ISD::SDIV, MVT::i32, Expand);
|
||||
setLibcallName(RTLIB::SDIV_I32, ".div");
|
||||
|
||||
setOperationAction(ISD::UDIV, MVT::i32, Expand);
|
||||
setLibcallName(RTLIB::UDIV_I32, ".udiv");
|
||||
}
|
||||
|
||||
if (Subtarget->is64Bit()) {
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
|
||||
|
|
|
@ -27,6 +27,9 @@ def Is32Bit : Predicate<"!Subtarget->is64Bit()">;
|
|||
// True when generating 64-bit code. This also implies HasV9.
|
||||
def Is64Bit : Predicate<"Subtarget->is64Bit()">;
|
||||
|
||||
def UseSoftMulDiv : Predicate<"Subtarget->useSoftMulDiv()">,
|
||||
AssemblerPredicate<"FeatureSoftMulDiv">;
|
||||
|
||||
// HasV9 - This predicate is true when the target processor supports V9
|
||||
// instructions. Note that the machine may be running in 32-bit mode.
|
||||
def HasV9 : Predicate<"Subtarget->isV9()">,
|
||||
|
|
|
@ -32,6 +32,7 @@ class StringRef;
|
|||
class SparcSubtarget : public SparcGenSubtargetInfo {
|
||||
Triple TargetTriple;
|
||||
virtual void anchor();
|
||||
bool UseSoftMulDiv;
|
||||
bool IsV9;
|
||||
bool IsLeon;
|
||||
bool V8DeprecatedInsts;
|
||||
|
@ -76,6 +77,7 @@ public:
|
|||
|
||||
bool enableMachineScheduler() const override;
|
||||
|
||||
bool useSoftMulDiv() const { return UseSoftMulDiv; }
|
||||
bool isV9() const { return IsV9; }
|
||||
bool isLeon() const { return IsLeon; }
|
||||
bool isVIS() const { return IsVIS; }
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
; RUN: llc -march=sparc -mcpu=v7 -O0 < %s | FileCheck %s
|
||||
|
||||
define i32 @test_mul32(i32 %a, i32 %b) #0 {
|
||||
; CHECK-LABEL: test_mul32
|
||||
; CHECK: call .umul
|
||||
%m = mul i32 %a, %b
|
||||
ret i32 %m
|
||||
}
|
||||
|
||||
define i16 @test_mul16(i16 %a, i16 %b) #0 {
|
||||
; CHECK-LABEL: test_mul16
|
||||
; CHECK: call .umul
|
||||
%m = mul i16 %a, %b
|
||||
ret i16 %m
|
||||
}
|
||||
|
||||
define i8 @test_mul8(i8 %a, i8 %b) #0 {
|
||||
; CHECK-LABEL: test_mul8
|
||||
; CHECK: call .umul
|
||||
%m = mul i8 %a, %b
|
||||
ret i8 %m
|
||||
}
|
||||
|
||||
define i32 @test_sdiv32(i32 %a, i32 %b) #0 {
|
||||
; CHECK-LABEL: test_sdiv32
|
||||
; CHECK: call .div
|
||||
%d = sdiv i32 %a, %b
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define i16 @test_sdiv16(i16 %a, i16 %b) #0 {
|
||||
; CHECK-LABEL: test_sdiv16
|
||||
; CHECK: call .div
|
||||
%d = sdiv i16 %a, %b
|
||||
ret i16 %d
|
||||
}
|
||||
|
||||
define i8 @test_sdiv8(i8 %a, i8 %b) #0 {
|
||||
; CHECK-LABEL: test_sdiv8
|
||||
; CHECK: call .div
|
||||
%d = sdiv i8 %a, %b
|
||||
ret i8 %d
|
||||
}
|
||||
|
||||
define i32 @test_udiv32(i32 %a, i32 %b) #0 {
|
||||
; CHECK-LABEL: test_udiv32
|
||||
; CHECK: call .udiv
|
||||
%d = udiv i32 %a, %b
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define i16 @test_udiv16(i16 %a, i16 %b) #0 {
|
||||
; CHECK-LABEL: test_udiv16
|
||||
; CHECK: call .udiv
|
||||
%d = udiv i16 %a, %b
|
||||
ret i16 %d
|
||||
}
|
||||
|
||||
define i8 @test_udiv8(i8 %a, i8 %b) #0 {
|
||||
; CHECK-LABEL: test_udiv8
|
||||
; CHECK: call .udiv
|
||||
%d = udiv i8 %a, %b
|
||||
ret i8 %d
|
||||
}
|
||||
|
Loading…
Reference in New Issue