Skip to content

Commit 7802640

Browse files
4vtomatBeMg
andcommitted
[RISCV] Add XSfmm pseudo instruction and vset* insertion support
This patch supports the naive vset* insertion. If the state(tm, tn, tk, sew, widen) changes, it emits all of the vset* instructions that are needed, partial compatibility is not supported yet. Co-authored-by: Piyou Chen <[email protected]>
1 parent d5d6f60 commit 7802640

File tree

11 files changed

+1008
-23
lines changed

11 files changed

+1008
-23
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
16161616
"operand must be a valid system register "
16171617
"name or an integer in the range");
16181618
}
1619+
case Match_InvalidXSfmmVType: {
1620+
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1621+
return generateXSfmmVTypeError(ErrorLoc);
1622+
}
16191623
case Match_InvalidVTypeI: {
16201624
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
16211625
return generateVTypeError(ErrorLoc);

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ enum {
138138
// 3 -> SEW * 4
139139
DestEEWShift = ElementsDependOnMaskShift + 1,
140140
DestEEWMask = 3ULL << DestEEWShift,
141+
142+
// 0 -> Don't care about altfmt bit in VTYPE.
143+
// 1 -> Is not altfmt.
144+
// 2 -> Is altfmt(BF16).
145+
AltFmtTypeShift = DestEEWShift + 2,
146+
AltFmtTypeMask = 3ULL << AltFmtTypeShift,
147+
148+
IsWidenShift = AltFmtTypeShift + 2,
149+
IsWidenMask = 1ULL << IsWidenShift,
150+
151+
// XSfmmbase
152+
HasTWidenOpShift = IsWidenShift + 1,
153+
HasTWidenOpMask = 1ULL << HasTWidenOpShift,
154+
155+
HasTMOpShift = HasTWidenOpShift + 1,
156+
HasTMOpMask = 1ULL << HasTMOpShift,
157+
158+
HasTKOpShift = HasTMOpShift + 1,
159+
HasTKOpMask = 1ULL << HasTKOpShift,
141160
};
142161

143162
// Helper functions to read TSFlags.
@@ -179,6 +198,11 @@ static inline bool hasRoundModeOp(uint64_t TSFlags) {
179198
return TSFlags & HasRoundModeOpMask;
180199
}
181200

201+
enum class AltFmtType { DontCare, NotAltFmt, AltFmt };
202+
static inline AltFmtType getAltFmtType(uint64_t TSFlags) {
203+
return static_cast<AltFmtType>((TSFlags & AltFmtTypeMask) >> AltFmtTypeShift);
204+
}
205+
182206
/// \returns true if this instruction uses vxrm
183207
static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; }
184208

@@ -194,11 +218,47 @@ static inline bool elementsDependOnMask(uint64_t TSFlags) {
194218
return TSFlags & ElementsDependOnMaskMask;
195219
}
196220

221+
// XSfmmbase
222+
static inline bool hasTWidenOp(uint64_t TSFlags) {
223+
return TSFlags & HasTWidenOpMask;
224+
}
225+
226+
static inline bool hasTMOp(uint64_t TSFlags) { return TSFlags & HasTMOpMask; }
227+
228+
static inline bool hasTKOp(uint64_t TSFlags) { return TSFlags & HasTKOpMask; }
229+
230+
static inline unsigned getTNOpNum(const MCInstrDesc &Desc) {
231+
const uint64_t TSFlags = Desc.TSFlags;
232+
assert(hasTWidenOp(TSFlags) && hasVLOp(TSFlags));
233+
unsigned Offset = 3;
234+
if (hasTKOp(TSFlags))
235+
Offset = 4;
236+
return Desc.getNumOperands() - Offset;
237+
}
238+
239+
static inline unsigned getTMOpNum(const MCInstrDesc &Desc) {
240+
const uint64_t TSFlags = Desc.TSFlags;
241+
assert(hasTWidenOp(TSFlags) && hasTMOp(TSFlags));
242+
if (hasTKOp(TSFlags))
243+
return Desc.getNumOperands() - 5;
244+
// vtzero.t
245+
return Desc.getNumOperands() - 4;
246+
}
247+
248+
static inline unsigned getTKOpNum(const MCInstrDesc &Desc) {
249+
const uint64_t TSFlags = Desc.TSFlags;
250+
assert(hasTWidenOp(TSFlags) && hasTKOp(TSFlags));
251+
return Desc.getNumOperands() - 3;
252+
}
253+
197254
static inline unsigned getVLOpNum(const MCInstrDesc &Desc) {
198255
const uint64_t TSFlags = Desc.TSFlags;
199256
// This method is only called if we expect to have a VL operand, and all
200257
// instructions with VL also have SEW.
201258
assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags));
259+
// In Xsfmmbase, TN is alias for VL, so here we use the same TSFlags bit.
260+
if (hasTWidenOp(TSFlags))
261+
return getTNOpNum(Desc);
202262
unsigned Offset = 2;
203263
if (hasVecPolicyOp(TSFlags))
204264
Offset = 3;
@@ -216,7 +276,7 @@ static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) {
216276
const uint64_t TSFlags = Desc.TSFlags;
217277
assert(hasSEWOp(TSFlags));
218278
unsigned Offset = 1;
219-
if (hasVecPolicyOp(TSFlags))
279+
if (hasVecPolicyOp(TSFlags) || hasTWidenOp(TSFlags))
220280
Offset = 2;
221281
return Desc.getNumOperands() - Offset;
222282
}
@@ -233,6 +293,9 @@ static inline int getFRMOpNum(const MCInstrDesc &Desc) {
233293
if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags))
234294
return -1;
235295

296+
if (hasTWidenOp(TSFlags) && hasTMOp(TSFlags))
297+
return getTMOpNum(Desc) - 1;
298+
236299
// The operand order
237300
// --------------------------------------
238301
// | n-1 (if any) | n-2 | n-3 | n-4 |
@@ -375,6 +438,7 @@ enum OperandType : unsigned {
375438
// instructions to represent a value that be passed as AVL to either vsetvli
376439
// or vsetivli.
377440
OPERAND_AVL,
441+
OPERAND_XSFMM_VTYPE,
378442
};
379443
} // namespace RISCVOp
380444

0 commit comments

Comments
 (0)