Skip to content

Commit 4c88873

Browse files
authored
[SPARC][IAS] Add definitions for OSA 2011 instructions
Reviewers: rorth, brad0, s-barannikov Reviewed By: s-barannikov Pull Request: #138403
1 parent a78a37f commit 4c88873

File tree

14 files changed

+816
-39
lines changed

14 files changed

+816
-39
lines changed

llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
261261

262262
static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address,
263263
const MCDisassembler *Decoder);
264+
static DecodeStatus DecodeSIMM5(MCInst &Inst, unsigned insn, uint64_t Address,
265+
const MCDisassembler *Decoder);
264266
static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address,
265267
const MCDisassembler *Decoder);
266268
template <unsigned N>
@@ -336,6 +338,13 @@ static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,
336338
return MCDisassembler::Success;
337339
}
338340

341+
static DecodeStatus DecodeSIMM5(MCInst &MI, unsigned insn, uint64_t Address,
342+
const MCDisassembler *Decoder) {
343+
assert(isUInt<5>(insn));
344+
MI.addOperand(MCOperand::createImm(SignExtend64<5>(insn)));
345+
return MCDisassembler::Success;
346+
}
347+
339348
static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,
340349
const MCDisassembler *Decoder) {
341350
assert(isUInt<13>(insn));

llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
5050
return (d16hi << 20) | d16lo;
5151
}
5252

53+
case ELF::R_SPARC_WDISP10: {
54+
// FIXME this really should be an error reporting check.
55+
assert((Value & 0x3) == 0);
56+
57+
// 7.17 Compare and Branch
58+
// Inst{20-19} = d10hi;
59+
// Inst{12-5} = d10lo;
60+
unsigned d10hi = (Value >> 10) & 0x3;
61+
unsigned d10lo = (Value >> 2) & 0xff;
62+
return (d10hi << 19) | (d10lo << 5);
63+
}
64+
5365
case ELF::R_SPARC_HIX22:
5466
return (~Value >> 10) & 0x3fffff;
5567

@@ -61,6 +73,9 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
6173
case Sparc::fixup_sparc_13:
6274
return Value & 0x1fff;
6375

76+
case ELF::R_SPARC_5:
77+
return Value & 0x1f;
78+
6479
case ELF::R_SPARC_LOX10:
6580
return (Value & 0x3ff) | 0x1c00;
6681

@@ -163,6 +178,9 @@ namespace {
163178
case ELF::R_SPARC_PC22:
164179
Info = {"", 10, 22, MCFixupKindInfo::FKF_IsPCRel};
165180
break;
181+
case ELF::R_SPARC_WDISP10:
182+
Info = {"", 0, 32, MCFixupKindInfo::FKF_IsPCRel};
183+
break;
166184
case ELF::R_SPARC_WDISP16:
167185
Info = {"", 0, 32, MCFixupKindInfo::FKF_IsPCRel};
168186
break;

llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "llvm/MC/MCFixup.h"
1313

14+
// clang-format off
1415
namespace llvm {
1516
namespace Sparc {
1617
// clang-format off
@@ -28,5 +29,5 @@ namespace llvm {
2829
// clang-format on
2930
}
3031
}
31-
32+
// clang-format on
3233
#endif

llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ class SparcMCCodeEmitter : public MCCodeEmitter {
7272
unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
7373
SmallVectorImpl<MCFixup> &Fixups,
7474
const MCSubtargetInfo &STI) const;
75+
unsigned getSImm5OpValue(const MCInst &MI, unsigned OpNo,
76+
SmallVectorImpl<MCFixup> &Fixups,
77+
const MCSubtargetInfo &STI) const;
7578
unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo,
7679
SmallVectorImpl<MCFixup> &Fixups,
7780
const MCSubtargetInfo &STI) const;
@@ -81,6 +84,9 @@ class SparcMCCodeEmitter : public MCCodeEmitter {
8184
unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
8285
SmallVectorImpl<MCFixup> &Fixups,
8386
const MCSubtargetInfo &STI) const;
87+
unsigned getCompareAndBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
88+
SmallVectorImpl<MCFixup> &Fixups,
89+
const MCSubtargetInfo &STI) const;
8490
};
8591

8692
} // end anonymous namespace
@@ -141,6 +147,31 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
141147
return 0;
142148
}
143149

150+
unsigned SparcMCCodeEmitter::getSImm5OpValue(const MCInst &MI, unsigned OpNo,
151+
SmallVectorImpl<MCFixup> &Fixups,
152+
const MCSubtargetInfo &STI) const {
153+
const MCOperand &MO = MI.getOperand(OpNo);
154+
155+
if (MO.isImm())
156+
return MO.getImm();
157+
158+
assert(MO.isExpr() &&
159+
"getSImm5OpValue expects only expressions or an immediate");
160+
161+
const MCExpr *Expr = MO.getExpr();
162+
163+
// Constant value, no fixup is needed
164+
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
165+
return CE->getValue();
166+
167+
if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
168+
Fixups.push_back(MCFixup::create(0, Expr, SExpr->getFixupKind()));
169+
return 0;
170+
}
171+
Fixups.push_back(MCFixup::create(0, Expr, ELF::R_SPARC_5));
172+
return 0;
173+
}
174+
144175
unsigned
145176
SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
146177
SmallVectorImpl<MCFixup> &Fixups,
@@ -217,6 +248,18 @@ unsigned SparcMCCodeEmitter::getBranchOnRegTargetOpValue(
217248
return 0;
218249
}
219250

251+
unsigned SparcMCCodeEmitter::getCompareAndBranchTargetOpValue(
252+
const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
253+
const MCSubtargetInfo &STI) const {
254+
const MCOperand &MO = MI.getOperand(OpNo);
255+
if (MO.isImm())
256+
return getMachineOpValue(MI, MO, Fixups, STI);
257+
258+
Fixups.push_back(MCFixup::create(0, MO.getExpr(), ELF::R_SPARC_WDISP10));
259+
260+
return 0;
261+
}
262+
220263
#include "SparcGenMCCodeEmitter.inc"
221264

222265
MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,

llvm/lib/Target/Sparc/Sparc.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ def FeatureUA2005
5555
def FeatureUA2007
5656
: SubtargetFeature<"ua2007", "IsUA2007", "true",
5757
"Enable UltraSPARC Architecture 2007 extensions">;
58+
def FeatureOSA2011
59+
: SubtargetFeature<"osa2011", "IsOSA2011", "true",
60+
"Enable Oracle SPARC Architecture 2011 extensions">;
5861
def FeatureLeon
5962
: SubtargetFeature<"leon", "IsLeon", "true",
6063
"Enable LEON extensions">;
@@ -166,7 +169,7 @@ def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated, UsePopc,
166169
FeatureUA2005, FeatureUA2007]>;
167170
def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated, UsePopc,
168171
FeatureVIS, FeatureVIS2, FeatureVIS3,
169-
FeatureUA2005, FeatureUA2007]>;
172+
FeatureUA2005, FeatureUA2007, FeatureOSA2011]>;
170173

171174
// LEON 2 FT generic
172175
def : Processor<"leon2", LEON2Itineraries,

llvm/lib/Target/Sparc/SparcInstrAliases.td

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,25 @@ multiclass reg_cond_alias<string rcond, int condVal> {
331331
Requires<[Is64Bit]>;
332332
}
333333

334+
// Instruction aliases for compare-and-branch.
335+
multiclass cwb_cond_alias<string cond, int condVal> {
336+
def : InstAlias<"cwb" # cond # " $rs1, $rs2, $imm",
337+
(CWBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
338+
Requires<[HasOSA2011]>;
339+
def : InstAlias<"cwb" # cond # " $rs1, $simm5, $imm",
340+
(CWBCONDri cbtarget:$imm, condVal, IntRegs:$rs1, simm5Op:$simm5)>,
341+
Requires<[HasOSA2011]>;
342+
}
343+
344+
multiclass cxb_cond_alias<string cond, int condVal> {
345+
def : InstAlias<"cxb" # cond # " $rs1, $rs2, $imm",
346+
(CXBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
347+
Requires<[HasOSA2011]>;
348+
def : InstAlias<"cxb" # cond # " $rs1, $simm5, $imm",
349+
(CXBCONDri cbtarget:$imm, condVal, IntRegs:$rs1, simm5Op:$simm5)>,
350+
Requires<[HasOSA2011]>;
351+
}
352+
334353
defm : int_cond_alias<"a", 0b1000>;
335354
defm : int_cond_alias<"n", 0b0000>;
336355
defm : int_cond_alias<"ne", 0b1001>;
@@ -408,6 +427,44 @@ defm : reg_cond_alias<"ne", 0b101>;
408427
defm : reg_cond_alias<"gz", 0b110>;
409428
defm : reg_cond_alias<"gez", 0b111>;
410429

430+
defm : cwb_cond_alias<"ne", 0b1001>;
431+
defm : cwb_cond_alias<"e", 0b0001>;
432+
defm : cwb_cond_alias<"g", 0b1010>;
433+
defm : cwb_cond_alias<"le", 0b0010>;
434+
defm : cwb_cond_alias<"ge", 0b1011>;
435+
defm : cwb_cond_alias<"l", 0b0011>;
436+
defm : cwb_cond_alias<"gu", 0b1100>;
437+
defm : cwb_cond_alias<"leu", 0b0100>;
438+
defm : cwb_cond_alias<"cc", 0b1101>;
439+
defm : cwb_cond_alias<"cs", 0b0101>;
440+
defm : cwb_cond_alias<"pos", 0b1110>;
441+
defm : cwb_cond_alias<"neg", 0b0110>;
442+
defm : cwb_cond_alias<"vc", 0b1111>;
443+
defm : cwb_cond_alias<"vs", 0b0111>;
444+
let EmitPriority = 0 in {
445+
defm : cwb_cond_alias<"geu", 0b1101>; // same as cc
446+
defm : cwb_cond_alias<"lu", 0b0101>; // same as cs
447+
}
448+
449+
defm : cxb_cond_alias<"ne", 0b1001>;
450+
defm : cxb_cond_alias<"e", 0b0001>;
451+
defm : cxb_cond_alias<"g", 0b1010>;
452+
defm : cxb_cond_alias<"le", 0b0010>;
453+
defm : cxb_cond_alias<"ge", 0b1011>;
454+
defm : cxb_cond_alias<"l", 0b0011>;
455+
defm : cxb_cond_alias<"gu", 0b1100>;
456+
defm : cxb_cond_alias<"leu", 0b0100>;
457+
defm : cxb_cond_alias<"cc", 0b1101>;
458+
defm : cxb_cond_alias<"cs", 0b0101>;
459+
defm : cxb_cond_alias<"pos", 0b1110>;
460+
defm : cxb_cond_alias<"neg", 0b0110>;
461+
defm : cxb_cond_alias<"vc", 0b1111>;
462+
defm : cxb_cond_alias<"vs", 0b0111>;
463+
let EmitPriority = 0 in {
464+
defm : cxb_cond_alias<"geu", 0b1101>; // same as cc
465+
defm : cxb_cond_alias<"lu", 0b0101>; // same as cs
466+
}
467+
411468
// Section A.3 Synthetic Instructions
412469

413470
// Most are marked as Emit=0, so that they are not used for disassembly. This is
@@ -665,3 +722,9 @@ def : InstAlias<"signx $rs1, $rd", (SRArr IntRegs:$rd, IntRegs:$rs1, G0), 0>, Re
665722

666723
// sir -> sir 0
667724
def : InstAlias<"sir", (SIR 0), 0>;
725+
726+
// pause reg_or_imm -> wrasr %g0, reg_or_imm, %asr27
727+
let Predicates = [HasOSA2011] in {
728+
def : InstAlias<"pause $rs2", (WRASRrr ASR27, G0, IntRegs:$rs2), 1>;
729+
def : InstAlias<"pause $simm13", (WRASRri ASR27, G0, simm13Op:$simm13), 1>;
730+
} // Predicates = [HasOSA2011]

llvm/lib/Target/Sparc/SparcInstrFormats.td

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,49 @@ class F2_4<bit annul, bit pred, dag outs, dag ins,
102102
let Inst{13-0} = imm16{13-0};
103103
}
104104

105+
class F2_5<bit cc, dag outs, dag ins, string asmstr,
106+
list<dag> pattern = [], InstrItinClass itin = NoItinerary>
107+
: InstSP<outs, ins, asmstr, pattern, itin> {
108+
bits<10> imm10;
109+
bits<5> rs1;
110+
bits<5> rs2;
111+
bits<4> cond;
112+
113+
let op = 0; // op = 0
114+
115+
let Inst{29} = cond{3};
116+
let Inst{28} = 1;
117+
let Inst{27-25} = cond{2-0};
118+
let Inst{24-22} = 0b011;
119+
let Inst{21} = cc;
120+
let Inst{20-19} = imm10{9-8};
121+
let Inst{18-14} = rs1;
122+
let Inst{13} = 0; // i = 0
123+
let Inst{12-5} = imm10{7-0};
124+
let Inst{4-0} = rs2;
125+
}
126+
127+
class F2_6<bit cc, dag outs, dag ins, string asmstr,
128+
list<dag> pattern = [], InstrItinClass itin = NoItinerary>
129+
: InstSP<outs, ins, asmstr, pattern, itin> {
130+
bits<10> imm10;
131+
bits<5> rs1;
132+
bits<5> simm5;
133+
bits<4> cond;
134+
135+
let op = 0; // op = 0
136+
137+
let Inst{29} = cond{3};
138+
let Inst{28} = 1;
139+
let Inst{27-25} = cond{2-0};
140+
let Inst{24-22} = 0b011;
141+
let Inst{21} = cc;
142+
let Inst{20-19} = imm10{9-8};
143+
let Inst{18-14} = rs1;
144+
let Inst{13} = 1; // i = 1
145+
let Inst{12-5} = imm10{7-0};
146+
let Inst{4-0} = simm5;
147+
}
105148

106149
//===----------------------------------------------------------------------===//
107150
// Format #3 instruction classes in the Sparc

llvm/lib/Target/Sparc/SparcInstrInfo.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ def HasUA2005 : Predicate<"Subtarget->isUA2005()">,
5555
def HasUA2007 : Predicate<"Subtarget->isUA2007()">,
5656
AssemblerPredicate<(all_of FeatureUA2007)>;
5757

58+
// HasOSA2011 - This is true when the target processor has OSA 2011 extensions.
59+
def HasOSA2011 : Predicate<"Subtarget->isOSA2011()">,
60+
AssemblerPredicate<(all_of FeatureOSA2011)>;
61+
5862
// HasHardQuad - This is true when the target processor supports quad floating
5963
// point instructions.
6064
def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">;
@@ -93,6 +97,8 @@ def UseDeprecatedInsts : Predicate<"Subtarget->useV8DeprecatedInsts()">;
9397
// FIXME these should have AsmOperandClass.
9498
def uimm3 : PatLeaf<(imm), [{ return isUInt<3>(N->getZExtValue()); }]>;
9599

100+
def simm5 : PatLeaf<(imm), [{ return isInt<5>(N->getSExtValue()); }]>;
101+
96102
def simm10 : PatLeaf<(imm), [{ return isInt<10>(N->getSExtValue()); }]>;
97103

98104
def simm11 : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>;
@@ -153,6 +159,12 @@ def SparcMEMriAsmOperand : AsmOperandClass {
153159
let ParserMethod = "parseMEMOperand";
154160
}
155161

162+
def simm5Op : Operand<iPTR> {
163+
let OperandType = "OPERAND_IMMEDIATE";
164+
let DecoderMethod = "DecodeSIMM5";
165+
let EncoderMethod = "getSImm5OpValue";
166+
}
167+
156168
def simm13Op : Operand<iPTR> {
157169
let OperandType = "OPERAND_IMMEDIATE";
158170
let DecoderMethod = "DecodeSIMM13";
@@ -246,6 +258,13 @@ def bprtarget16 : Operand<OtherVT> {
246258
let OperandType = "OPERAND_PCREL";
247259
}
248260

261+
def cbtarget : Operand<OtherVT> {
262+
let EncoderMethod = "getCompareAndBranchTargetOpValue";
263+
let DecoderMethod = "DecodeDisp<10>";
264+
let PrintMethod = "printCTILabel";
265+
let OperandType = "OPERAND_PCREL";
266+
}
267+
249268
def SparcCallTargetAsmOperand : AsmOperandClass {
250269
let Name = "CallTarget";
251270
let ParserMethod = "parseCallTarget";

llvm/lib/Target/Sparc/SparcInstrUAOSA.td

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//===----------------------------------------------------------------------===//
88
//
99
// This file contains instruction formats, definitions and patterns needed for
10-
// UA 2005 and UA 2007 instructions on SPARC.
10+
// UA 2005, UA 2007, and OSA 2011 instructions on SPARC.
1111
//===----------------------------------------------------------------------===//
1212

1313
class UA2005RegWin<string asmstr, bits<5> fcn>
@@ -23,6 +23,16 @@ class FourOp<string OpcStr, bits<6> op3val, bits<4> op5val,
2323
: F3_4<op3val, op5val, (outs RC:$rd), (ins RC:$rs1, RC:$rs2, RC:$rs3),
2424
!strconcat(OpcStr, " $rs1, $rs2, $rs3, $rd")>;
2525

26+
/// F2_56 multiclass - Define a F2_5/F2_6 pattern in one shot.
27+
multiclass F2_56<string OpcStr, bits<1> cc> {
28+
def rr : F2_5<cc, (outs),
29+
(ins cbtarget:$imm10, CCOp:$cond, IntRegs:$rs1, IntRegs:$rs2),
30+
!strconcat(OpcStr, "$cond $rs1, $rs2, $imm10")>;
31+
def ri : F2_6<cc, (outs),
32+
(ins cbtarget:$imm10, CCOp:$cond, IntRegs:$rs1, simm5Op:$simm5),
33+
!strconcat(OpcStr, "$cond $rs1, $simm5, $imm10")>;
34+
}
35+
2636
// UltraSPARC Architecture 2005 Instructions
2737
let Predicates = [HasUA2005] in {
2838
let hasSideEffects = 1 in {
@@ -45,3 +55,14 @@ def FNMADDD : FourOp<"fnmaddd", 0b110111, 0b1110, DFPRegs>;
4555
def FNMSUBS : FourOp<"fnmsubs", 0b110111, 0b1001, FPRegs>;
4656
def FNMSUBD : FourOp<"fnmsubd", 0b110111, 0b1010, DFPRegs>;
4757
} // Predicates = [HasUA2007]
58+
59+
// Oracle SPARC Architecture 2011 Instructions
60+
let Predicates = [HasOSA2011] in {
61+
let isBranch = 1, isTerminator = 1, hasDelaySlot = 0 in {
62+
defm CWBCOND : F2_56<"cwb", 0>;
63+
defm CXBCOND : F2_56<"cxb", 1>;
64+
}
65+
66+
def FPMADDX : FourOp<"fpmaddx", 0b110111, 0b0000, DFPRegs>;
67+
def FPMADDXHI : FourOp<"fpmaddxhi", 0b110111, 0b0100, DFPRegs>;
68+
} // Predicates = [HasOSA2011]

0 commit comments

Comments
 (0)