Skip to content

Commit 7532925

Browse files
authored
[SOL] Implement JMP32 instruction class (#176)
1 parent 3ba634f commit 7532925

File tree

16 files changed

+680
-104
lines changed

16 files changed

+680
-104
lines changed

llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class SBFDisassembler : public MCDisassembler {
4040
SBF_STX = 0x3,
4141
SBF_ALU = 0x4,
4242
SBF_JMP = 0x5,
43-
SBF_PQR = 0x6,
43+
SBF_PQR_OR_JMP32 = 0x6,
4444
SBF_ALU64 = 0x7
4545
};
4646

@@ -215,6 +215,9 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
215215
Result =
216216
decodeInstruction(DecoderTableSBFv264,
217217
Instr, Insn, Address, this, STI);
218+
} else if (InstClass == SBF_PQR_OR_JMP32 && !STI.hasFeature(SBF::FeaturePqrInstr)) {
219+
Result = decodeInstruction(DecoderTableSBFv364,
220+
Instr, Insn, Address, this, STI);
218221
}
219222
else
220223
Result =

llvm/lib/Target/SBF/SBFISelLowering.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,12 @@ SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM,
120120
if (STI.getHasAlu32()) {
121121
setOperationAction(ISD::BSWAP, MVT::i32, Promote);
122122
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
123-
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
124-
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
125-
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
126-
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
123+
if (!STI.getHasJmp32()) {
124+
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
125+
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
126+
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
127+
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
128+
}
127129
}
128130

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

169171
// CPU/Feature control
170172
HasAlu32 = STI.getHasAlu32();
173+
HasJmp32 = STI.getHasJmp32();
171174
SBFRegisterInfo::FrameLength = 4096;
172175
}
173176

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

701+
if (getHasJmp32()) {
702+
return DAG.getNode(SBFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
703+
DAG.getConstant(CC, DL, LHS.getValueType()), Dest);
704+
}
705+
698706
bool IsSignedCmp = (CC == ISD::SETGT ||
699707
CC == ISD::SETGE ||
700708
CC == ISD::SETLT ||
@@ -1005,7 +1013,10 @@ SBFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
10051013
switch (CC) {
10061014
#define SET_NEWCC(X, Y) \
10071015
case ISD::X: \
1008-
NewCC = isSelectRROp ? SBF::Y##_rr : SBF::Y##_ri; \
1016+
if (is32BitCmp && HasJmp32) \
1017+
NewCC = isSelectRROp ? SBF::Y##_rr_32 : SBF::Y##_ri_32; \
1018+
else \
1019+
NewCC = isSelectRROp ? SBF::Y##_rr : SBF::Y##_ri; \
10091020
break
10101021
SET_NEWCC(SETGT, JSGT);
10111022
SET_NEWCC(SETUGT, JUGT);
@@ -1027,17 +1038,17 @@ SBFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
10271038
CC == ISD::SETLT ||
10281039
CC == ISD::SETLE);
10291040

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

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

1040-
if (is32BitCmp)
1051+
if (is32BitCmp && !HasJmp32)
10411052
RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);
10421053

10431054
BuildMI(BB, DL, TII.get(NewCC)).addReg(LHS).addReg(RHS).addMBB(Copy1MBB);

llvm/lib/Target/SBF/SBFISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class SBFTargetLowering : public TargetLowering {
6262
MachineBasicBlock *BB) const override;
6363

6464
bool getHasAlu32() const { return HasAlu32; }
65+
bool getHasJmp32() const { return HasJmp32; }
6566

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

7577
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
7678
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;

llvm/lib/Target/SBF/SBFInstrFormats.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def SBF_STX : SBFOpClass<0x3>;
1717
def SBF_ALU : SBFOpClass<0x4>;
1818
def SBF_JMP : SBFOpClass<0x5>;
1919
def SBF_PQR : SBFOpClass<0x6>;
20+
def SBF_JMP32 : SBFOpClass<0x6>;
2021
def SBF_ALU64 : SBFOpClass<0x7>;
2122

2223
def SBF_LD_V2 : SBFOpClass<0x4>;

llvm/lib/Target/SBF/SBFInstrInfo.cpp

Lines changed: 41 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,22 @@ static inline bool isUncondBranchOpcode(int Opc) { return Opc == SBF::JMP; }
2828

2929
static inline bool isCondBranchOpcode(int Opc) {
3030
switch (Opc) {
31-
case SBF::JEQ_ri:
32-
case SBF::JEQ_rr:
33-
case SBF::JUGT_ri:
34-
case SBF::JUGT_rr:
35-
case SBF::JUGE_ri:
36-
case SBF::JUGE_rr:
37-
case SBF::JNE_ri:
38-
case SBF::JNE_rr:
39-
case SBF::JSGT_ri:
40-
case SBF::JSGT_rr:
41-
case SBF::JSGE_ri:
42-
case SBF::JSGE_rr:
43-
case SBF::JULT_ri:
44-
case SBF::JULT_rr:
45-
case SBF::JULE_ri:
46-
case SBF::JULE_rr:
47-
case SBF::JSLT_ri:
48-
case SBF::JSLT_rr:
49-
case SBF::JSLE_ri:
50-
case SBF::JSLE_rr:
31+
#define BRANCH_INSTR(X) \
32+
case SBF::X##_ri: \
33+
case SBF::X##_rr: \
34+
case SBF::X##_ri_32: \
35+
case SBF::X##_rr_32: \
36+
37+
BRANCH_INSTR(JEQ)
38+
BRANCH_INSTR(JNE)
39+
BRANCH_INSTR(JUGT)
40+
BRANCH_INSTR(JUGE)
41+
BRANCH_INSTR(JSGT)
42+
BRANCH_INSTR(JSGE)
43+
BRANCH_INSTR(JULT)
44+
BRANCH_INSTR(JULE)
45+
BRANCH_INSTR(JSLT)
46+
BRANCH_INSTR(JSLE)
5147
return true;
5248
default:
5349
return false;
@@ -388,66 +384,31 @@ bool SBFInstrInfo::reverseBranchCondition(
388384
switch (Cond[0].getImm()) {
389385
default:
390386
llvm_unreachable("Unknown conditional branch!");
391-
case SBF::JEQ_ri:
392-
Cond[0].setImm(SBF::JNE_ri);
393-
break;
394-
case SBF::JEQ_rr:
395-
Cond[0].setImm(SBF::JNE_rr);
396-
break;
397-
case SBF::JUGT_ri:
398-
Cond[0].setImm(SBF::JULE_ri);
399-
break;
400-
case SBF::JUGT_rr:
401-
Cond[0].setImm(SBF::JULE_rr);
402-
break;
403-
case SBF::JUGE_ri:
404-
Cond[0].setImm(SBF::JULT_ri);
405-
break;
406-
case SBF::JUGE_rr:
407-
Cond[0].setImm(SBF::JULT_rr);
408-
break;
409-
case SBF::JNE_ri:
410-
Cond[0].setImm(SBF::JEQ_ri);
411-
break;
412-
case SBF::JNE_rr:
413-
Cond[0].setImm(SBF::JEQ_rr);
414-
break;
415-
case SBF::JSGT_ri:
416-
Cond[0].setImm(SBF::JSLE_ri);
417-
break;
418-
case SBF::JSGT_rr:
419-
Cond[0].setImm(SBF::JSLE_rr);
420-
break;
421-
case SBF::JSGE_ri:
422-
Cond[0].setImm(SBF::JSLT_ri);
423-
break;
424-
case SBF::JSGE_rr:
425-
Cond[0].setImm(SBF::JSLT_rr);
426-
break;
427-
case SBF::JULT_ri:
428-
Cond[0].setImm(SBF::JUGE_ri);
429-
break;
430-
case SBF::JULT_rr:
431-
Cond[0].setImm(SBF::JUGE_rr);
432-
break;
433-
case SBF::JULE_ri:
434-
Cond[0].setImm(SBF::JUGT_ri);
435-
break;
436-
case SBF::JULE_rr:
437-
Cond[0].setImm(SBF::JUGT_rr);
438-
break;
439-
case SBF::JSLT_ri:
440-
Cond[0].setImm(SBF::JSGE_ri);
441-
break;
442-
case SBF::JSLT_rr:
443-
Cond[0].setImm(SBF::JSGE_rr);
444-
break;
445-
case SBF::JSLE_ri:
446-
Cond[0].setImm(SBF::JSGT_ri);
447-
break;
448-
case SBF::JSLE_rr:
449-
Cond[0].setImm(SBF::JSGT_rr);
450-
break;
387+
388+
#define REVERSE_X_FOR_Y(X, Y) \
389+
case SBF::X##_ri: \
390+
Cond[0].setImm(SBF::Y##_ri); \
391+
break; \
392+
case SBF::X##_rr: \
393+
Cond[0].setImm(SBF::Y##_rr); \
394+
break; \
395+
case SBF::X##_ri_32: \
396+
Cond[0].setImm(SBF::Y##_ri_32); \
397+
break; \
398+
case SBF::X##_rr_32: \
399+
Cond[0].setImm(SBF::Y##_rr_32); \
400+
break; \
401+
402+
REVERSE_X_FOR_Y(JEQ, JNE)
403+
REVERSE_X_FOR_Y(JNE, JEQ)
404+
REVERSE_X_FOR_Y(JUGT, JULE)
405+
REVERSE_X_FOR_Y(JUGE, JULT)
406+
REVERSE_X_FOR_Y(JSGT, JSLE)
407+
REVERSE_X_FOR_Y(JSGE, JSLT)
408+
REVERSE_X_FOR_Y(JULT, JUGE)
409+
REVERSE_X_FOR_Y(JULE, JUGT)
410+
REVERSE_X_FOR_Y(JSLT, JSGE)
411+
REVERSE_X_FOR_Y(JSLE, JSGT)
451412
}
452413

453414
return false;

llvm/lib/Target/SBF/SBFInstrInfo.td

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,26 @@ def SBF_CC_LTU : PatLeaf<(i64 imm),
133133
[{return (N->getZExtValue() == ISD::SETULT);}]>;
134134
def SBF_CC_LEU : PatLeaf<(i64 imm),
135135
[{return (N->getZExtValue() == ISD::SETULE);}]>;
136+
def SBF_CC_EQ_32 : PatLeaf<(i32 imm),
137+
[{return (N->getZExtValue() == ISD::SETEQ);}]>;
138+
def SBF_CC_NE_32 : PatLeaf<(i32 imm),
139+
[{return (N->getZExtValue() == ISD::SETNE);}]>;
140+
def SBF_CC_GE_32 : PatLeaf<(i32 imm),
141+
[{return (N->getZExtValue() == ISD::SETGE);}]>;
142+
def SBF_CC_GT_32 : PatLeaf<(i32 imm),
143+
[{return (N->getZExtValue() == ISD::SETGT);}]>;
144+
def SBF_CC_GTU_32 : PatLeaf<(i32 imm),
145+
[{return (N->getZExtValue() == ISD::SETUGT);}]>;
146+
def SBF_CC_GEU_32 : PatLeaf<(i32 imm),
147+
[{return (N->getZExtValue() == ISD::SETUGE);}]>;
148+
def SBF_CC_LE_32 : PatLeaf<(i32 imm),
149+
[{return (N->getZExtValue() == ISD::SETLE);}]>;
150+
def SBF_CC_LT_32 : PatLeaf<(i32 imm),
151+
[{return (N->getZExtValue() == ISD::SETLT);}]>;
152+
def SBF_CC_LTU_32 : PatLeaf<(i32 imm),
153+
[{return (N->getZExtValue() == ISD::SETULT);}]>;
154+
def SBF_CC_LEU_32 : PatLeaf<(i32 imm),
155+
[{return (N->getZExtValue() == ISD::SETULE);}]>;
136156

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

220-
multiclass J<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond> {
240+
class JMP_RR_32<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond>
241+
: TYPE_ALU_JMP<Opc.Value, SBF_X.Value,
242+
(outs),
243+
(ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
244+
Mnemonic # "32 $dst, $src, $BrDst",
245+
[(SBFbrcc i32:$dst, i32:$src, Cond, bb:$BrDst)]> {
246+
bits<4> dst;
247+
bits<4> src;
248+
bits<16> BrDst;
249+
250+
let Inst{55-52} = src;
251+
let Inst{51-48} = dst;
252+
let Inst{47-32} = BrDst;
253+
let SBFClass = SBF_JMP32;
254+
}
255+
256+
class JMP_RI_32<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond>
257+
: TYPE_ALU_JMP<Opc.Value, SBF_K.Value,
258+
(outs),
259+
(ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
260+
Mnemonic # "32 $dst, $imm, $BrDst",
261+
[(SBFbrcc i32:$dst, i32immSExt32:$imm, Cond, bb:$BrDst)]> {
262+
bits<4> dst;
263+
bits<16> BrDst;
264+
bits<32> imm;
265+
266+
let Inst{51-48} = dst;
267+
let Inst{47-32} = BrDst;
268+
let Inst{31-0} = imm;
269+
let SBFClass = SBF_JMP32;
270+
}
271+
272+
multiclass J<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond, PatLeaf Cond32> {
221273
def _rr : JMP_RR<Opc, Mnemonic, Cond>;
222274
def _ri : JMP_RI<Opc, Mnemonic, Cond>;
275+
let DecoderNamespace = "SBFv3" in {
276+
def _rr_32 : JMP_RR_32<Opc, Mnemonic, Cond32>;
277+
def _ri_32 : JMP_RI_32<Opc, Mnemonic, Cond32>;
278+
}
223279
}
224280

225281
let isBranch = 1, isTerminator = 1, hasDelaySlot=0 in {
226282
// cmp+goto instructions
227-
defm JEQ : J<SBF_JEQ, "jeq", SBF_CC_EQ>;
228-
defm JUGT : J<SBF_JGT, "jgt", SBF_CC_GTU>;
229-
defm JUGE : J<SBF_JGE, "jge", SBF_CC_GEU>;
230-
defm JNE : J<SBF_JNE, "jne", SBF_CC_NE>;
231-
defm JSGT : J<SBF_JSGT, "jsgt", SBF_CC_GT>;
232-
defm JSGE : J<SBF_JSGE, "jsge", SBF_CC_GE>;
233-
defm JULT : J<SBF_JLT, "jlt", SBF_CC_LTU>;
234-
defm JULE : J<SBF_JLE, "jle", SBF_CC_LEU>;
235-
defm JSLT : J<SBF_JSLT, "jslt", SBF_CC_LT>;
236-
defm JSLE : J<SBF_JSLE, "jsle", SBF_CC_LE>;
283+
defm JEQ : J<SBF_JEQ, "jeq", SBF_CC_EQ, SBF_CC_EQ_32>;
284+
defm JUGT : J<SBF_JGT, "jgt", SBF_CC_GTU, SBF_CC_GTU_32>;
285+
defm JUGE : J<SBF_JGE, "jge", SBF_CC_GEU, SBF_CC_GEU_32>;
286+
defm JNE : J<SBF_JNE, "jne", SBF_CC_NE, SBF_CC_NE_32>;
287+
defm JSGT : J<SBF_JSGT, "jsgt", SBF_CC_GT, SBF_CC_GT_32>;
288+
defm JSGE : J<SBF_JSGE, "jsge", SBF_CC_GE, SBF_CC_GE_32>;
289+
defm JULT : J<SBF_JLT, "jlt", SBF_CC_LTU, SBF_CC_LTU_32>;
290+
defm JULE : J<SBF_JLE, "jle", SBF_CC_LEU, SBF_CC_LEU_32>;
291+
defm JSLT : J<SBF_JSLT, "jslt", SBF_CC_LT, SBF_CC_LT_32>;
292+
defm JSLE : J<SBF_JSLE, "jsle", SBF_CC_LE, SBF_CC_LE_32>;
237293
}
238294

239295
// ALU instructions

llvm/lib/Target/SBF/SBFSubtarget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ void SBFSubtarget::initializeEnvironment(const Triple &TT) {
5656
NewMemEncoding = false;
5757
HasStaticSyscalls = false;
5858
IsAbiV2 = false;
59+
HasJmp32 = false;
5960
}
6061

6162
void SBFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {

llvm/lib/Target/SBF/SBFSubtarget.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
8888
// Whether we are using AbiV2
8989
bool IsAbiV2;
9090

91+
// Whether we support JMP32
92+
// JMP32 support depends on ALU32 being enabled
93+
bool HasJmp32;
94+
9195
std::unique_ptr<CallLowering> CallLoweringInfo;
9296
std::unique_ptr<InstructionSelector> InstSelector;
9397
std::unique_ptr<LegalizerInfo> Legalizer;
@@ -117,6 +121,7 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
117121
bool getHasExplicitSignExt() const { return HasExplicitSignExt; }
118122
bool getNewMemEncoding() const { return NewMemEncoding; }
119123
bool getHasStaticSyscalls() const { return HasStaticSyscalls; }
124+
bool getHasJmp32() const { return HasJmp32; }
120125
const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; }
121126
const SBFFrameLowering *getFrameLowering() const override {
122127
return &FrameLowering;

llvm/lib/Target/SBF/SBFTargetFeatures.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ def FeatureNewMemEncoding : SubtargetFeature<"mem-encoding", "NewMemEncoding",
5050
"true", "Enable the new encoding for memory instructions">;
5151

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

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

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

0 commit comments

Comments
 (0)