Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SOL] Create explicit sign extension instruction #114

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions llvm/lib/Target/SBF/SBFISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -933,24 +933,29 @@ SBFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB,
unsigned Reg, bool isSigned) const {
const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
int RShiftOp = isSigned ? SBF::SRA_ri : SBF::SRL_ri;
MachineFunction *F = BB->getParent();
DebugLoc DL = MI.getDebugLoc();

MachineRegisterInfo &RegInfo = F->getRegInfo();

if (!isSigned) {
unsigned MovOp =
Subtarget->getHasExplicitSignExt()
? SBF::MOV_rr : SBF::MOV_32_64;
Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
BuildMI(BB, DL, TII.get(SBF::MOV_32_64), PromotedReg0).addReg(Reg);
BuildMI(BB, DL, TII.get(MovOp), PromotedReg0).addReg(Reg);
return PromotedReg0;
}
Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
BuildMI(BB, DL, TII.get(SBF::MOV_32_64), PromotedReg0).addReg(Reg);
if (Subtarget->getHasExplicitSignExt())
return PromotedReg0;

Register PromotedReg1 = RegInfo.createVirtualRegister(RC);
Register PromotedReg2 = RegInfo.createVirtualRegister(RC);
BuildMI(BB, DL, TII.get(SBF::MOV_32_64), PromotedReg0).addReg(Reg);
BuildMI(BB, DL, TII.get(SBF::SLL_ri), PromotedReg1)
.addReg(PromotedReg0).addImm(32);
BuildMI(BB, DL, TII.get(RShiftOp), PromotedReg2)
BuildMI(BB, DL, TII.get(SBF::SRA_ri), PromotedReg2)
.addReg(PromotedReg1).addImm(32);

return PromotedReg2;
Expand Down
12 changes: 10 additions & 2 deletions llvm/lib/Target/SBF/SBFInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,24 @@ using namespace llvm;
SBFInstrInfo::SBFInstrInfo()
: SBFGenInstrInfo(SBF::ADJCALLSTACKDOWN, SBF::ADJCALLSTACKUP) {}

void SBFInstrInfo::setHasExplicitSignExt(bool HasExplicitSext) {
this->HasExplicitSignExt = HasExplicitSext;
}

void SBFInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
const DebugLoc &DL, MCRegister DestReg,
MCRegister SrcReg, bool KillSrc) const {
if (SBF::GPRRegClass.contains(DestReg, SrcReg))
BuildMI(MBB, I, DL, get(SBF::MOV_rr), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
else if (SBF::GPR32RegClass.contains(DestReg, SrcReg))
BuildMI(MBB, I, DL, get(SBF::MOV_rr_32), DestReg)
else if (SBF::GPR32RegClass.contains(DestReg, SrcReg)) {
unsigned OpCode =
HasExplicitSignExt ? SBF::MOV_rr_32_no_sext_v2
: SBF::MOV_rr_32_no_sext_v1;
BuildMI(MBB, I, DL, get(OpCode), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
}
else
llvm_unreachable("Impossible reg-to-reg copy");
}
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/SBF/SBFInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ class SBFInstrInfo : public SBFGenInstrInfo {
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
void setHasExplicitSignExt(bool HasExplicitSext);

private:
void expandMEMCPY(MachineBasicBlock::iterator) const;

bool HasExplicitSignExt;
};
}

Expand Down
59 changes: 47 additions & 12 deletions llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def SBFNoCallxSrc : Predicate<"!Subtarget->getCallXRegSrc()">;
def SBFPqrInstr : Predicate<"Subtarget->getHasPqrClass()">;
def SBFNoPqrInstr : Predicate<"!Subtarget->getHasPqrClass()">;
def SBFHasStoreImm : Predicate<"Subtarget->getHasStoreImm()">;
def SBFExplicitSignExt : Predicate<"Subtarget->getHasExplicitSignExt()">;
def SBFNoExplicitSignExt : Predicate<"!Subtarget->getHasExplicitSignExt()">;

def brtarget : Operand<OtherVT> {
let PrintMethod = "printBrTargetOperand";
Expand Down Expand Up @@ -415,16 +417,26 @@ def MOV_ri : MATH_RI<SBF_ALU64, SBF_MOV,
(ins i64imm:$imm),
"mov64 $dst, $imm",
[(set GPR:$dst, (i64 i64immSExt32:$imm))]>;
def MOV_rr_32 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins GPR32:$src),
"mov32 $dst, $src",
[]>;

def MOV_ri_32 : MATH_RI<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins i32imm:$imm),
"mov32 $dst, $imm",
[(set GPR32:$dst, (i32 i32immSExt32:$imm))]>;

let Predicates = [SBFExplicitSignExt], DecoderNamespace = "SBFv2" in {
def MOV_rr_32_no_sext_v2 : MATH_RR<SBF_ALU64, SBF_MOV,
(outs GPR32:$dst),
(ins GPR32:$src),
"mov64 $dst, $src",
[]>;
}

def MOV_rr_32_no_sext_v1 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins GPR32:$src),
"mov32 $dst, $src",
[]>, Requires<[SBFNoExplicitSignExt]>;
}

def FI_ri
Expand Down Expand Up @@ -993,10 +1005,13 @@ let Constraints = "$dst = $src" in {
}
}

let isCodeGenOnly = 1 in {
let DecoderNamespace = "SBFv2" in {
def MOV_32_64 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins GPR32:$src),
"mov32 $dst, $src", []>;
}

let isCodeGenOnly = 1 in {
def MOV_32_64_addr : MATH_RI<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins u64imm:$imm),
"mov32 $dst, $imm", []>, Requires<[SBFNoLddw]>;
Expand All @@ -1023,19 +1038,39 @@ def : Pat<(SBFWrapper tglobaladdr:$in),
(HOR_addr (MOV_32_64_addr tglobaladdr:$in),
tglobaladdr:$in)>, Requires<[SBFNoLddw]>;

// SBFv2 sign extension
def : Pat<(i64 (sext GPR32:$src)),
(MOV_32_64 GPR32:$src)>, Requires<[SBFExplicitSignExt]>;

// SBFv1 sign extension
def : Pat<(i64 (sext GPR32:$src)),
(SRA_ri (SLL_ri (MOV_32_64 GPR32:$src), 32), 32)>;
(SRA_ri (SLL_ri (MOV_32_64 GPR32:$src), 32), 32)>,
Requires<[SBFNoExplicitSignExt]>;

// SBFv2 zero extension
def : Pat<(i64 (zext GPR32:$src)), (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
GPR32:$src, sub_32)>, Requires<[SBFExplicitSignExt]>;

def : Pat<(i64 (zext GPR32:$src)), (MOV_32_64 GPR32:$src)>;
// SBFv1 zero extension
def : Pat<(i64 (zext GPR32:$src)), (MOV_32_64 GPR32:$src)>,
Requires<[SBFNoExplicitSignExt]>;

// For i64 -> i32 truncation, use the 32-bit subregister directly.
// SBFv2 truncation
def : Pat<(i32 (trunc GPR:$src)),
(i32 (EXTRACT_SUBREG GPR:$src, sub_32))>;
(AND_ri_32 (i32 (EXTRACT_SUBREG GPR:$src, sub_32)),
(i32 0xffffffff))>, Requires<[SBFExplicitSignExt]>;

// SBFv1 truncation
def : Pat<(i32 (trunc GPR:$src)),
(i32 (EXTRACT_SUBREG GPR:$src, sub_32))>, Requires<[SBFNoExplicitSignExt]>;

// SBFv2 anyext
def : Pat<(i64 (anyext GPR32:$src)),
(MOV_32_64 GPR32:$src)>, Requires<[SBFExplicitSignExt]>;

// For i32 -> i64 anyext, we don't care about the high bits.
// SBFv1 anyext
def : Pat<(i64 (anyext GPR32:$src)),
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>;
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>, Requires<[SBFNoExplicitSignExt]>;

class STORE32<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
: TYPE_LD_ST<SBF_MEM.Value, SizeOp.Value,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SBF/SBFSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ SBFSubtarget &SBFSubtarget::initializeSubtargetDependencies(const Triple &TT,
StringRef FS) {
initializeEnvironment(TT);
initSubtargetFeatures(CPU, FS);
InstrInfo.setHasExplicitSignExt(HasExplicitSignExt);
return *this;
}

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/SBF/SBFSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
// Whether we have store imm instructions
bool HasStoreImm;

// Whether we have the explicit sign extension instruction (mov32)
bool HasExplicitSignExt;

public:
// This constructor initializes the data members to match that
// of the specified triple.
Expand All @@ -105,6 +108,7 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
return HasDynamicFrames && NewCallConvention;
}
bool getHasStoreImm() const { return HasStoreImm; }
bool getHasExplicitSignExt() const { return HasExplicitSignExt; }
const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const SBFFrameLowering *getFrameLowering() const override {
return &FrameLowering;
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/SBF/SBFTargetFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ def FeatureCallConv : SubtargetFeature<"new-call-conv", "NewCallConvention", "tr
def FeatureStoreImm : SubtargetFeature<"store-imm", "HasStoreImm", "true",
"Enable store imm instructions">;

def FeatureExplicitSext : SubtargetFeature<"explicit-sext", "HasExplicitSignExt",
"true", "Enable the explicit sign extension instruction mov32">;

class Proc<string Name, list<SubtargetFeature> Features>
: Processor<Name, NoItineraries, Features>;

Expand All @@ -55,4 +58,4 @@ def : Proc<"v2", []>;
def : Proc<"v3", [ALU32]>;
def : Proc<"sbfv2", [FeatureDynamicFrames, FeatureRelocAbs64, FeatureStaticSyscalls,
FeatureDisableNeg, FeatureReverseSubImm, FeatureDisableLddw, FeatureCallxRegSrc,
FeaturePqrInstr, FeatureCallConv]>;
FeaturePqrInstr, FeatureCallConv, FeatureExplicitSext]>;
110 changes: 110 additions & 0 deletions llvm/test/CodeGen/SBF/explicit-sign-ext.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
; RUN: llc -march=sbf -mattr=+alu32 < %s | FileCheck --check-prefixes=CHECK-v1,CHECK %s
; RUN: llc -march=sbf -mattr=+alu32,+explicit-sext < %s | FileCheck --check-prefixes=CHECK-v2,CHECK %s


define dso_local i64 @my_sext(i32 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: my_sext
%res = sext i32 %a to i64

; CHECK-v1: mov32 r0, w1
; CHECK-v1: lsh64 r0, 32
; CHECK-v1: arsh64 r0, 32

; CHECK-v2: mov32 r0, w1
ret i64 %res
}

define dso_local i64 @my_zext(i32 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: my_zext
%res = zext i32 %a to i64

; CHECK-v1: mov32 r0, w1
; CHECK-v2: mov64 w0, w1

ret i64 %res
}

define dso_local i32 @my_trunc(i64 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: my_trunc
%res = trunc i64 %a to i32

; CHECK-v1: mov64 r0, r1
; CHECK-v2: mov64 r0, r1
; CHECK-v2: and32 w0, -1
ret i32 %res
}

define dso_local i32 @copy_phys(i32 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: copy_phys
%res = add i32 %a, 2
%b = sub i32 %res, 5
; CHECK-v1: mov32 w0, w1
; CHECK-v2: mov64 w0, w1
ret i32 %b
}

define dso_local i32 @select_cc_imm(i32 %a, i32 %c, i32 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_imm
%cmp = icmp sgt i32 %a, 10
; CHECK-v1: mov32 w0, w2
; CHECK-v2: mov64 w0, w2

; CHECK-v1: mov32 r1, w1
; CHECK-v1: lsh64 r1, 32
; CHECK-v1: arsh64 r1, 32
; CHECK-v2: mov32 r1, w1

%c.d = select i1 %cmp, i32 %c, i32 %d
; CHECK-v1: mov32 w0, w3
; CHECK-v2: mov64 w0, w3

ret i32 %c.d
}

define dso_local i32 @select_cc_reg(i32 %a, i32 %b, i32 %c, i32 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_reg
%cmp = icmp sgt i32 %a, %b
; CHECK-v1: mov32 w0, w3
; CHECK-v2: mov64 w0, w3

; CHECK-v1: mov32 r1, w1
; CHECK-v1: lsh64 r1, 32
; CHECK-v1: arsh64 r1, 32
; CHECK-v2: mov32 r1, w1

; CHECK-v1: mov32 r2, w2
; CHECK-v1: lsh64 r2, 32
; CHECK-v1: arsh64 r2, 32
; CHECK-v2: mov32 r2, w2

%c.d = select i1 %cmp, i32 %c, i32 %d
; CHECK-v1: mov32 w0, w4
; CHECK-v2: mov64 w0, w4
ret i32 %c.d
}

define dso_local i64 @select_cc_imm_64(i32 %a, i64 %c, i64 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_imm_64
; CHECK-v1: mov64 r0, r2
%cmp = icmp sgt i32 %a, 10
%c.d = select i1 %cmp, i64 %c, i64 %d
; CHECK: mov64 r0, r3
ret i64 %c.d
}

define dso_local i64 @select_cc_reg_64(i32 %a, i32 %b, i64 %c, i64 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_reg_64
; CHECK: mov64 r0, r3
%cmp = icmp sgt i32 %a, %b
%c.d = select i1 %cmp, i64 %c, i64 %d
; CHECK: mov64 r0, r4
ret i64 %c.d
}
8 changes: 8 additions & 0 deletions llvm/test/MC/SBF/sbf-alu.s
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ mov64 r0, r9
# CHECK-ASM-NEW: encoding: [0xbf,0x23,0x00,0x00,0x00,0x00,0x00,0x00]
mov64 r3, r2

# CHECK-OBJ-NEW: mov64 r3, r2
# CHECK-ASM-NEW: encoding: [0xbf,0x23,0x00,0x00,0x00,0x00,0x00,0x00]
mov64 w3, w2

# CHECK-OBJ-NEW: mov64 r3, 0x7b
# CHECK-ASM-NEW: encoding: [0xb7,0x03,0x00,0x00,0x7b,0x00,0x00,0x00]
mov64 r3, 123
Expand All @@ -303,6 +307,10 @@ mov64 r5, -123
# CHECK-ASM-NEW: encoding: [0xbc,0x26,0x00,0x00,0x00,0x00,0x00,0x00]
mov32 w6, w2

# CHECK-OBJ-NEW: mov32 w6, w2
# CHECK-ASM-NEW: encoding: [0xbc,0x26,0x00,0x00,0x00,0x00,0x00,0x00]
mov32 r6, w2

# CHECK-OBJ-NEW: mov32 w5, -0x7b
# CHECK-ASM-NEW: encoding: [0xb4,0x05,0x00,0x00,0x85,0xff,0xff,0xff]
mov32 w5, -123
Expand Down
Loading