Skip to content

Commit 50aac2c

Browse files
4vtomatBeMgtopperc
authored
[RISCV] Add XSfmm pseudo instruction and vset* insertion support (llvm#143068)
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. This is follow up patch for: llvm#133031 Co-authored-by: Piyou Chen <[email protected]> Co-authored-by: Craig Topper <[email protected]>
1 parent 1d89844 commit 50aac2c

File tree

13 files changed

+1013
-29
lines changed

13 files changed

+1013
-29
lines changed

llvm/include/llvm/TargetParser/RISCVTargetParser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ inline static bool isAltFmt(unsigned VType) { return VType & 0x100; }
161161

162162
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS);
163163

164+
LLVM_ABI void printXSfmmVType(unsigned VType, raw_ostream &OS);
165+
164166
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul);
165167

166168
LLVM_ABI std::optional<VLMUL> getSameRatioLMUL(unsigned SEW, VLMUL VLMUL,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
16591659
return generateImmOutOfRangeError(
16601660
Operands, ErrorInfo, -1, (1 << 5) - 1,
16611661
"immediate must be non-zero in the range");
1662+
case Match_InvalidXSfmmVType: {
1663+
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1664+
return generateXSfmmVTypeError(ErrorLoc);
1665+
}
16621666
case Match_InvalidVTypeI: {
16631667
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
16641668
return generateVTypeError(ErrorLoc);

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

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,22 @@ enum {
142142

143143
ReadsPastVLShift = DestEEWShift + 2,
144144
ReadsPastVLMask = 1ULL << ReadsPastVLShift,
145+
146+
// 0 -> Don't care about altfmt bit in VTYPE.
147+
// 1 -> Is not altfmt.
148+
// 2 -> Is altfmt(BF16).
149+
AltFmtTypeShift = ReadsPastVLShift + 1,
150+
AltFmtTypeMask = 3ULL << AltFmtTypeShift,
151+
152+
// XSfmmbase
153+
HasTWidenOpShift = AltFmtTypeShift + 2,
154+
HasTWidenOpMask = 1ULL << HasTWidenOpShift,
155+
156+
HasTMOpShift = HasTWidenOpShift + 1,
157+
HasTMOpMask = 1ULL << HasTMOpShift,
158+
159+
HasTKOpShift = HasTMOpShift + 1,
160+
HasTKOpMask = 1ULL << HasTKOpShift,
145161
};
146162

147163
// Helper functions to read TSFlags.
@@ -183,6 +199,11 @@ static inline bool hasRoundModeOp(uint64_t TSFlags) {
183199
return TSFlags & HasRoundModeOpMask;
184200
}
185201

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

@@ -204,11 +225,47 @@ static inline bool readsPastVL(uint64_t TSFlags) {
204225
return TSFlags & ReadsPastVLMask;
205226
}
206227

228+
// XSfmmbase
229+
static inline bool hasTWidenOp(uint64_t TSFlags) {
230+
return TSFlags & HasTWidenOpMask;
231+
}
232+
233+
static inline bool hasTMOp(uint64_t TSFlags) { return TSFlags & HasTMOpMask; }
234+
235+
static inline bool hasTKOp(uint64_t TSFlags) { return TSFlags & HasTKOpMask; }
236+
237+
static inline unsigned getTNOpNum(const MCInstrDesc &Desc) {
238+
const uint64_t TSFlags = Desc.TSFlags;
239+
assert(hasTWidenOp(TSFlags) && hasVLOp(TSFlags));
240+
unsigned Offset = 3;
241+
if (hasTKOp(TSFlags))
242+
Offset = 4;
243+
return Desc.getNumOperands() - Offset;
244+
}
245+
246+
static inline unsigned getTMOpNum(const MCInstrDesc &Desc) {
247+
const uint64_t TSFlags = Desc.TSFlags;
248+
assert(hasTWidenOp(TSFlags) && hasTMOp(TSFlags));
249+
if (hasTKOp(TSFlags))
250+
return Desc.getNumOperands() - 5;
251+
// vtzero.t
252+
return Desc.getNumOperands() - 4;
253+
}
254+
255+
static inline unsigned getTKOpNum(const MCInstrDesc &Desc) {
256+
const uint64_t TSFlags = Desc.TSFlags;
257+
assert(hasTWidenOp(TSFlags) && hasTKOp(TSFlags));
258+
return Desc.getNumOperands() - 3;
259+
}
260+
207261
static inline unsigned getVLOpNum(const MCInstrDesc &Desc) {
208262
const uint64_t TSFlags = Desc.TSFlags;
209263
// This method is only called if we expect to have a VL operand, and all
210264
// instructions with VL also have SEW.
211265
assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags));
266+
// In Xsfmmbase, TN is an alias for VL, so here we use the same TSFlags bit.
267+
if (hasTWidenOp(TSFlags))
268+
return getTNOpNum(Desc);
212269
unsigned Offset = 2;
213270
if (hasVecPolicyOp(TSFlags))
214271
Offset = 3;
@@ -226,7 +283,7 @@ static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) {
226283
const uint64_t TSFlags = Desc.TSFlags;
227284
assert(hasSEWOp(TSFlags));
228285
unsigned Offset = 1;
229-
if (hasVecPolicyOp(TSFlags))
286+
if (hasVecPolicyOp(TSFlags) || hasTWidenOp(TSFlags))
230287
Offset = 2;
231288
return Desc.getNumOperands() - Offset;
232289
}
@@ -243,6 +300,9 @@ static inline int getFRMOpNum(const MCInstrDesc &Desc) {
243300
if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags))
244301
return -1;
245302

303+
if (hasTWidenOp(TSFlags) && hasTMOp(TSFlags))
304+
return getTMOpNum(Desc) - 1;
305+
246306
// The operand order
247307
// --------------------------------------
248308
// | n-1 (if any) | n-2 | n-3 | n-4 |
@@ -385,7 +445,9 @@ enum OperandType : unsigned {
385445
OPERAND_SEW_MASK,
386446
// Vector rounding mode for VXRM or FRM.
387447
OPERAND_VEC_RM,
388-
OPERAND_LAST_RISCV_IMM = OPERAND_VEC_RM,
448+
// Vtype operand for XSfmm extension.
449+
OPERAND_XSFMM_VTYPE,
450+
OPERAND_LAST_RISCV_IMM = OPERAND_XSFMM_VTYPE,
389451
// Operand is either a register or uimm5, this is used by V extension pseudo
390452
// instructions to represent a value that be passed as AVL to either vsetvli
391453
// or vsetivli.

0 commit comments

Comments
 (0)