Skip to content
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
5 changes: 4 additions & 1 deletion llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SBFDisassembler : public MCDisassembler {
SBF_STX = 0x3,
SBF_ALU = 0x4,
SBF_JMP = 0x5,
SBF_PQR = 0x6,
SBF_PQR_OR_JMP32 = 0x6,
SBF_ALU64 = 0x7
};

Expand Down Expand Up @@ -215,6 +215,9 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Result =
decodeInstruction(DecoderTableSBFv264,
Instr, Insn, Address, this, STI);
} else if (InstClass == SBF_PQR_OR_JMP32 && !STI.hasFeature(SBF::FeaturePqrInstr)) {
Result = decodeInstruction(DecoderTableSBFv364,
Instr, Insn, Address, this, STI);
}
else
Result =
Expand Down
27 changes: 19 additions & 8 deletions llvm/lib/Target/SBF/SBFISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM,
if (STI.getHasAlu32()) {
setOperationAction(ISD::BSWAP, MVT::i32, Promote);
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
if (!STI.getHasJmp32()) {
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
}
}

setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Expand Down Expand Up @@ -168,6 +170,7 @@ SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM,

// CPU/Feature control
HasAlu32 = STI.getHasAlu32();
HasJmp32 = STI.getHasJmp32();
SBFRegisterInfo::FrameLength = 4096;
}

Expand Down Expand Up @@ -695,6 +698,11 @@ SDValue SBFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue Dest = Op.getOperand(4);
SDLoc DL(Op);

if (getHasJmp32()) {
return DAG.getNode(SBFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
DAG.getConstant(CC, DL, LHS.getValueType()), Dest);
}

bool IsSignedCmp = (CC == ISD::SETGT ||
CC == ISD::SETGE ||
CC == ISD::SETLT ||
Expand Down Expand Up @@ -1005,7 +1013,10 @@ SBFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
switch (CC) {
#define SET_NEWCC(X, Y) \
case ISD::X: \
NewCC = isSelectRROp ? SBF::Y##_rr : SBF::Y##_ri; \
if (is32BitCmp && HasJmp32) \
NewCC = isSelectRROp ? SBF::Y##_rr_32 : SBF::Y##_ri_32; \
else \
NewCC = isSelectRROp ? SBF::Y##_rr : SBF::Y##_ri; \
break
SET_NEWCC(SETGT, JSGT);
SET_NEWCC(SETUGT, JUGT);
Expand All @@ -1027,17 +1038,17 @@ SBFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
CC == ISD::SETLT ||
CC == ISD::SETLE);

// SBF at the moment only has 64-bit comparison. Any 32-bit comparison needs
// When JMP32 is not available, any 32-bit comparison needs
// to be promoted. If we are comparing against an immediate value, we must
// sign extend the registers. Likewise for signed comparisons. Unsigned
// comparisons will zero extent registers.
if (is32BitCmp)
if (is32BitCmp && !HasJmp32)
LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp || !isSelectRROp);

if (isSelectRROp) {
Register RHS = MI.getOperand(2).getReg();

if (is32BitCmp)
if (is32BitCmp && !HasJmp32)
RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);

BuildMI(BB, DL, TII.get(NewCC)).addReg(LHS).addReg(RHS).addMBB(Copy1MBB);
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SBF/SBFISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class SBFTargetLowering : public TargetLowering {
MachineBasicBlock *BB) const override;

bool getHasAlu32() const { return HasAlu32; }
bool getHasJmp32() const { return HasJmp32; }

EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
EVT VT) const override;
Expand All @@ -71,6 +72,7 @@ class SBFTargetLowering : public TargetLowering {
private:
// Control Instruction Selection Features
bool HasAlu32;
bool HasJmp32;

SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SBF/SBFInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def SBF_STX : SBFOpClass<0x3>;
def SBF_ALU : SBFOpClass<0x4>;
def SBF_JMP : SBFOpClass<0x5>;
def SBF_PQR : SBFOpClass<0x6>;
def SBF_JMP32 : SBFOpClass<0x6>;
def SBF_ALU64 : SBFOpClass<0x7>;

def SBF_LD_V2 : SBFOpClass<0x4>;
Expand Down
121 changes: 41 additions & 80 deletions llvm/lib/Target/SBF/SBFInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,22 @@ static inline bool isUncondBranchOpcode(int Opc) { return Opc == SBF::JMP; }

static inline bool isCondBranchOpcode(int Opc) {
switch (Opc) {
case SBF::JEQ_ri:
case SBF::JEQ_rr:
case SBF::JUGT_ri:
case SBF::JUGT_rr:
case SBF::JUGE_ri:
case SBF::JUGE_rr:
case SBF::JNE_ri:
case SBF::JNE_rr:
case SBF::JSGT_ri:
case SBF::JSGT_rr:
case SBF::JSGE_ri:
case SBF::JSGE_rr:
case SBF::JULT_ri:
case SBF::JULT_rr:
case SBF::JULE_ri:
case SBF::JULE_rr:
case SBF::JSLT_ri:
case SBF::JSLT_rr:
case SBF::JSLE_ri:
case SBF::JSLE_rr:
#define BRANCH_INSTR(X) \
case SBF::X##_ri: \
case SBF::X##_rr: \
case SBF::X##_ri_32: \
case SBF::X##_rr_32: \

BRANCH_INSTR(JEQ)
BRANCH_INSTR(JNE)
BRANCH_INSTR(JUGT)
BRANCH_INSTR(JUGE)
BRANCH_INSTR(JSGT)
BRANCH_INSTR(JSGE)
BRANCH_INSTR(JULT)
BRANCH_INSTR(JULE)
BRANCH_INSTR(JSLT)
BRANCH_INSTR(JSLE)
return true;
default:
return false;
Expand Down Expand Up @@ -388,66 +384,31 @@ bool SBFInstrInfo::reverseBranchCondition(
switch (Cond[0].getImm()) {
default:
llvm_unreachable("Unknown conditional branch!");
case SBF::JEQ_ri:
Cond[0].setImm(SBF::JNE_ri);
break;
case SBF::JEQ_rr:
Cond[0].setImm(SBF::JNE_rr);
break;
case SBF::JUGT_ri:
Cond[0].setImm(SBF::JULE_ri);
break;
case SBF::JUGT_rr:
Cond[0].setImm(SBF::JULE_rr);
break;
case SBF::JUGE_ri:
Cond[0].setImm(SBF::JULT_ri);
break;
case SBF::JUGE_rr:
Cond[0].setImm(SBF::JULT_rr);
break;
case SBF::JNE_ri:
Cond[0].setImm(SBF::JEQ_ri);
break;
case SBF::JNE_rr:
Cond[0].setImm(SBF::JEQ_rr);
break;
case SBF::JSGT_ri:
Cond[0].setImm(SBF::JSLE_ri);
break;
case SBF::JSGT_rr:
Cond[0].setImm(SBF::JSLE_rr);
break;
case SBF::JSGE_ri:
Cond[0].setImm(SBF::JSLT_ri);
break;
case SBF::JSGE_rr:
Cond[0].setImm(SBF::JSLT_rr);
break;
case SBF::JULT_ri:
Cond[0].setImm(SBF::JUGE_ri);
break;
case SBF::JULT_rr:
Cond[0].setImm(SBF::JUGE_rr);
break;
case SBF::JULE_ri:
Cond[0].setImm(SBF::JUGT_ri);
break;
case SBF::JULE_rr:
Cond[0].setImm(SBF::JUGT_rr);
break;
case SBF::JSLT_ri:
Cond[0].setImm(SBF::JSGE_ri);
break;
case SBF::JSLT_rr:
Cond[0].setImm(SBF::JSGE_rr);
break;
case SBF::JSLE_ri:
Cond[0].setImm(SBF::JSGT_ri);
break;
case SBF::JSLE_rr:
Cond[0].setImm(SBF::JSGT_rr);
break;

#define REVERSE_X_FOR_Y(X, Y) \
case SBF::X##_ri: \
Cond[0].setImm(SBF::Y##_ri); \
break; \
case SBF::X##_rr: \
Cond[0].setImm(SBF::Y##_rr); \
break; \
case SBF::X##_ri_32: \
Cond[0].setImm(SBF::Y##_ri_32); \
break; \
case SBF::X##_rr_32: \
Cond[0].setImm(SBF::Y##_rr_32); \
break; \

REVERSE_X_FOR_Y(JEQ, JNE)
REVERSE_X_FOR_Y(JNE, JEQ)
REVERSE_X_FOR_Y(JUGT, JULE)
REVERSE_X_FOR_Y(JUGE, JULT)
REVERSE_X_FOR_Y(JSGT, JSLE)
REVERSE_X_FOR_Y(JSGE, JSLT)
REVERSE_X_FOR_Y(JULT, JUGE)
REVERSE_X_FOR_Y(JULE, JUGT)
REVERSE_X_FOR_Y(JSLT, JSGE)
REVERSE_X_FOR_Y(JSLE, JSGT)
}

return false;
Expand Down
78 changes: 67 additions & 11 deletions llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,26 @@ def SBF_CC_LTU : PatLeaf<(i64 imm),
[{return (N->getZExtValue() == ISD::SETULT);}]>;
def SBF_CC_LEU : PatLeaf<(i64 imm),
[{return (N->getZExtValue() == ISD::SETULE);}]>;
def SBF_CC_EQ_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETEQ);}]>;
def SBF_CC_NE_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETNE);}]>;
def SBF_CC_GE_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETGE);}]>;
def SBF_CC_GT_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETGT);}]>;
def SBF_CC_GTU_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETUGT);}]>;
def SBF_CC_GEU_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETUGE);}]>;
def SBF_CC_LE_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETLE);}]>;
def SBF_CC_LT_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETLT);}]>;
def SBF_CC_LTU_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETULT);}]>;
def SBF_CC_LEU_32 : PatLeaf<(i32 imm),
[{return (N->getZExtValue() == ISD::SETULE);}]>;

// For arithmetic and jump instructions the 8-bit 'code'
// field is divided into three parts:
Expand Down Expand Up @@ -217,23 +237,59 @@ class JMP_RI<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond>
let SBFClass = SBF_JMP;
}

multiclass J<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond> {
class JMP_RR_32<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond>
: TYPE_ALU_JMP<Opc.Value, SBF_X.Value,
(outs),
(ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
Mnemonic # "32 $dst, $src, $BrDst",
[(SBFbrcc i32:$dst, i32:$src, Cond, bb:$BrDst)]> {
bits<4> dst;
bits<4> src;
bits<16> BrDst;

let Inst{55-52} = src;
let Inst{51-48} = dst;
let Inst{47-32} = BrDst;
let SBFClass = SBF_JMP32;
}

class JMP_RI_32<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond>
: TYPE_ALU_JMP<Opc.Value, SBF_K.Value,
(outs),
(ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
Mnemonic # "32 $dst, $imm, $BrDst",
[(SBFbrcc i32:$dst, i32immSExt32:$imm, Cond, bb:$BrDst)]> {
bits<4> dst;
bits<16> BrDst;
bits<32> imm;

let Inst{51-48} = dst;
let Inst{47-32} = BrDst;
let Inst{31-0} = imm;
let SBFClass = SBF_JMP32;
}

multiclass J<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond, PatLeaf Cond32> {
def _rr : JMP_RR<Opc, Mnemonic, Cond>;
def _ri : JMP_RI<Opc, Mnemonic, Cond>;
let DecoderNamespace = "SBFv3" in {
def _rr_32 : JMP_RR_32<Opc, Mnemonic, Cond32>;
def _ri_32 : JMP_RI_32<Opc, Mnemonic, Cond32>;
}
}

let isBranch = 1, isTerminator = 1, hasDelaySlot=0 in {
// cmp+goto instructions
defm JEQ : J<SBF_JEQ, "jeq", SBF_CC_EQ>;
defm JUGT : J<SBF_JGT, "jgt", SBF_CC_GTU>;
defm JUGE : J<SBF_JGE, "jge", SBF_CC_GEU>;
defm JNE : J<SBF_JNE, "jne", SBF_CC_NE>;
defm JSGT : J<SBF_JSGT, "jsgt", SBF_CC_GT>;
defm JSGE : J<SBF_JSGE, "jsge", SBF_CC_GE>;
defm JULT : J<SBF_JLT, "jlt", SBF_CC_LTU>;
defm JULE : J<SBF_JLE, "jle", SBF_CC_LEU>;
defm JSLT : J<SBF_JSLT, "jslt", SBF_CC_LT>;
defm JSLE : J<SBF_JSLE, "jsle", SBF_CC_LE>;
defm JEQ : J<SBF_JEQ, "jeq", SBF_CC_EQ, SBF_CC_EQ_32>;
defm JUGT : J<SBF_JGT, "jgt", SBF_CC_GTU, SBF_CC_GTU_32>;
defm JUGE : J<SBF_JGE, "jge", SBF_CC_GEU, SBF_CC_GEU_32>;
defm JNE : J<SBF_JNE, "jne", SBF_CC_NE, SBF_CC_NE_32>;
defm JSGT : J<SBF_JSGT, "jsgt", SBF_CC_GT, SBF_CC_GT_32>;
defm JSGE : J<SBF_JSGE, "jsge", SBF_CC_GE, SBF_CC_GE_32>;
defm JULT : J<SBF_JLT, "jlt", SBF_CC_LTU, SBF_CC_LTU_32>;
defm JULE : J<SBF_JLE, "jle", SBF_CC_LEU, SBF_CC_LEU_32>;
defm JSLT : J<SBF_JSLT, "jslt", SBF_CC_LT, SBF_CC_LT_32>;
defm JSLE : J<SBF_JSLE, "jsle", SBF_CC_LE, SBF_CC_LE_32>;
}

// ALU instructions
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 @@ -56,6 +56,7 @@ void SBFSubtarget::initializeEnvironment(const Triple &TT) {
NewMemEncoding = false;
HasStaticSyscalls = false;
IsAbiV2 = false;
HasJmp32 = false;
}

void SBFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/SBF/SBFSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
// Whether we are using AbiV2
bool IsAbiV2;

// Whether we support JMP32
// JMP32 support depends on ALU32 being enabled
bool HasJmp32;

std::unique_ptr<CallLowering> CallLoweringInfo;
std::unique_ptr<InstructionSelector> InstSelector;
std::unique_ptr<LegalizerInfo> Legalizer;
Expand Down Expand Up @@ -117,6 +121,7 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
bool getHasExplicitSignExt() const { return HasExplicitSignExt; }
bool getNewMemEncoding() const { return NewMemEncoding; }
bool getHasStaticSyscalls() const { return HasStaticSyscalls; }
bool getHasJmp32() const { return HasJmp32; }
const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const SBFFrameLowering *getFrameLowering() const override {
return &FrameLowering;
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/SBF/SBFTargetFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ def FeatureNewMemEncoding : SubtargetFeature<"mem-encoding", "NewMemEncoding",
"true", "Enable the new encoding for memory instructions">;

def FeatureAbiV2 : SubtargetFeature<"abi-v2", "IsAbiV2",
"true", "Enables AbiV2 in SBF (no-op in LLVM)">;
"true", "Enable AbiV2 in SBF (no-op in LLVM)">;

def FeatureJmp32 : SubtargetFeature<"jmp-32", "HasJmp32", "true",
"Enable the JMP32 instruction class">;

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