Skip to content
Open
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
1 change: 1 addition & 0 deletions clang/test/Driver/print-supported-extensions-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@
// CHECK-NEXT: zibi 0.1 'Zibi' (Branch with Immediate)
// CHECK-NEXT: zicfilp 1.0 'Zicfilp' (Landing pad)
// CHECK-NEXT: zicfiss 1.0 'Zicfiss' (Shadow stack)
// CHECK-NEXT: ztt 0.1 'Ztt' (Attached Matrix Extension)
// CHECK-NEXT: zvabd 0.7 'Zvabd' (Vector Absolute Difference)
// CHECK-NEXT: zvbc32e 0.7 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements)
// CHECK-NEXT: zvdot4a8i 0.1 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers)
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/IntrinsicsRISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -2141,5 +2141,6 @@ include "llvm/IR/IntrinsicsRISCVXCV.td"
include "llvm/IR/IntrinsicsRISCVXAndes.td"
include "llvm/IR/IntrinsicsRISCVXMIPS.td"
include "llvm/IR/IntrinsicsRISCVExt.td"
include "llvm/IR/IntrinsicsRISCVStdExtZtt.td"
include "llvm/IR/IntrinsicsRISCVBOSCExt.td"
include "llvm/IR/IntrinsicsRISCVBuckyballExt.td"
574 changes: 574 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsRISCVStdExtZtt.td

Large diffs are not rendered by default.

99 changes: 93 additions & 6 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ class RISCVAsmParser : public MCTargetAsmParser {
ParseStatus parseJALOffset(OperandVector &Operands);
ParseStatus parseVTypeI(OperandVector &Operands);
ParseStatus parseMaskReg(OperandVector &Operands);
ParseStatus parseMatrixReg(OperandVector &Operands);
ParseStatus parseTHeadAMEMatrixReg(OperandVector &Operands);
ParseStatus parseZttMatrixRegIndex(OperandVector &Operands);
ParseStatus parseZttAccRegIndex(OperandVector &Operands);
ParseStatus parseVScaleReg(OperandVector &Operands);
ParseStatus parseTileLambda(OperandVector &Operands);
ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands);
Expand Down Expand Up @@ -494,9 +496,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isV0Reg() const {
return Kind == KindTy::Register && Reg.Reg == RISCV::V0;
}
bool isMatrixReg() const {
return Kind == KindTy::Register && Reg.Reg >= RISCV::AMEM0 &&
Reg.Reg <= RISCV::AMEM7;
bool isTHeadAMEMatrixReg() const {
return Kind == KindTy::Register && Reg.Reg >= RISCV::THeadAMEM0 &&
Reg.Reg <= RISCV::THeadAMEM7;
}
bool isAnyReg() const {
return Kind == KindTy::Register &&
Expand Down Expand Up @@ -1055,6 +1057,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
[](int64_t Imm) { return Imm != INT64_MIN && isInt<5>(Imm - 1); });
}

bool isSImm7() const { return isSImm<7>(); }

bool isSImm18() const {
return isSImmPred([](int64_t Imm) { return isInt<18>(Imm); });
}
Expand Down Expand Up @@ -2654,7 +2658,7 @@ ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
return ParseStatus::Success;
}

ParseStatus RISCVAsmParser::parseMatrixReg(OperandVector &Operands) {
ParseStatus RISCVAsmParser::parseTHeadAMEMatrixReg(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::Identifier))
return ParseStatus::NoMatch;

Expand All @@ -2666,7 +2670,90 @@ ParseStatus RISCVAsmParser::parseMatrixReg(OperandVector &Operands) {
SMLoc E = getTok().getEndLoc();
getLexer().Lex();
Operands.push_back(
RISCVOperand::createReg(RISCV::AMEM0 + (Name[1] - '0'), S, E));
RISCVOperand::createReg(RISCV::THeadAMEM0 + (Name[1] - '0'), S, E));
return ParseStatus::Success;
}

ParseStatus RISCVAsmParser::parseZttMatrixRegIndex(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::Identifier))
return ParseStatus::NoMatch;

StringRef Name = getLexer().getTok().getIdentifier();
if (!Name.consume_front("m"))
return ParseStatus::NoMatch;

unsigned Index;
if (Name.getAsInteger(10, Index))
return ParseStatus::NoMatch;

unsigned MaxIndex;
const auto &Features = STI->getFeatureBits();

bool HasZttMatrixRegs32 = Features[RISCV::FeatureStdExtZttMatrixRegs32];
bool HasZttMatrixRegs16 = Features[RISCV::FeatureStdExtZttMatrixRegs16];
if (HasZttMatrixRegs16 && HasZttMatrixRegs32)
return Error(getLoc(),
"conflicting ztt (AME) matrix register bounds chosen; cannot enable both 16 and 32 matrix registers simultaneously");

if (HasZttMatrixRegs32)
MaxIndex = 31;
else if (HasZttMatrixRegs16)
MaxIndex = 15;
else
return Error(getLoc(),
"no ztt (AME) matrix register count feature enabled");

if (Index > MaxIndex)
return generateImmOutOfRangeError(getLoc(), 0, MaxIndex);

SMLoc S = getLoc();
SMLoc E = getTok().getEndLoc();
getLexer().Lex();
Operands.push_back(RISCVOperand::createExpr(
MCConstantExpr::create(Index, getContext()), S, E, isRV64()));
return ParseStatus::Success;
}

ParseStatus RISCVAsmParser::parseZttAccRegIndex(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::Identifier))
return ParseStatus::NoMatch;

StringRef Name = getLexer().getTok().getIdentifier();
if (!Name.consume_front("acc"))
return ParseStatus::NoMatch;

unsigned Index;
if (Name.getAsInteger(10, Index))
return ParseStatus::NoMatch;

unsigned MaxIndex;
const auto &Features = STI->getFeatureBits();

bool HasZttAccRegs4 = Features[RISCV::FeatureStdExtZttAccRegs4];
bool HasZttAccRegs2 = Features[RISCV::FeatureStdExtZttAccRegs2];
bool HasZttAccRegs1 = Features[RISCV::FeatureStdExtZttAccRegs1];
if ((HasZttAccRegs4 + HasZttAccRegs2 + HasZttAccRegs1) > 1)
return Error(getLoc(),
"conflicting ztt (AME) accumulator register bounds chosen; cannot enable multiple accumulator register configurations simultaneously");

if (Features[RISCV::FeatureStdExtZttAccRegs4])
MaxIndex = 3;
else if (Features[RISCV::FeatureStdExtZttAccRegs2])
MaxIndex = 1;
else if (Features[RISCV::FeatureStdExtZttAccRegs1])
MaxIndex = 0;
else
return Error(getLoc(),
"no ztt (AME) accumulator register count feature enabled");

if (Index > MaxIndex)
return generateImmOutOfRangeError(getLoc(), 0, MaxIndex);

SMLoc S = getLoc();
SMLoc E = getTok().getEndLoc();
getLexer().Lex();
Operands.push_back(RISCVOperand::createExpr(
MCConstantExpr::create(Index, getContext()), S, E, isRV64()));
return ParseStatus::Success;
}

Expand Down
31 changes: 17 additions & 14 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Endian.h"
#include <cstdint>

using namespace llvm;
using namespace llvm::MCD;
Expand Down Expand Up @@ -96,28 +97,30 @@ static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, uint32_t RegNo,
constexpr auto DecodeGPRRegisterClass =
DecodeSimpleRegisterClass<RISCV::X0, 32, /*RVELimit=*/16>;

static DecodeStatus DecodeTileRegRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
return DecodeSimpleRegisterClass<RISCV::TR0, 8>(Inst, RegNo, Address,
Decoder);
static DecodeStatus
DecodeBOSCAMETileRegRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
return DecodeSimpleRegisterClass<RISCV::BOSCAMETR0, 8>(Inst, RegNo, Address,
Decoder);
}

static DecodeStatus DecodeAccRegRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
static DecodeStatus
DecodeBOSCAMEAccRegRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address,
const MCDisassembler *Decoder) {
if (RegNo < 8 || RegNo > 15)
return MCDisassembler::Fail;

Inst.addOperand(MCOperand::createReg(RISCV::ACC0 + (RegNo - 8)));
Inst.addOperand(MCOperand::createReg(RISCV::BOSCAMEACC0 + (RegNo - 8)));
return MCDisassembler::Success;
}

static DecodeStatus DecodeMatrixRegRegisterClass(
MCInst &Inst, uint32_t RegNo, uint64_t Address,
const MCDisassembler *Decoder) {
return DecodeSimpleRegisterClass<RISCV::AMEM0, 8>(Inst, RegNo, Address,
Decoder);
static DecodeStatus
DecodeTHeadAMEMatrixRegRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
return DecodeSimpleRegisterClass<RISCV::THeadAMEM0, 8>(Inst, RegNo, Address,
Decoder);
}

static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ enum OperandType : unsigned {
OPERAND_VMASK,
OPERAND_SMTVType,
OPERAND_SMTI8,

OPERAND_ZTT_MATRIX_REG,
OPERAND_ZTT_ACC_REG,
};
} // namespace RISCVOp

Expand Down
33 changes: 27 additions & 6 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "RISCVInstPrinter.h"
#include "RISCVBaseInfo.h"
#include "RISCVMCAsmInfo.h"
#include "RISCVMCTargetDesc.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
Expand Down Expand Up @@ -346,15 +347,35 @@ void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo,
O << ".t";
}

void RISCVInstPrinter::printMatrixReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
void RISCVInstPrinter::printTHeadAMEMatrixReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);

assert(MO.isReg() && "printMatrixReg can only print register operands");
assert(MO.getReg() >= RISCV::AMEM0 && MO.getReg() <= RISCV::AMEM7 &&
assert(MO.isReg() &&
"printTHeadAMEMatrixReg can only print register operands");
assert(MO.getReg() >= RISCV::THeadAMEM0 && MO.getReg() <= RISCV::THeadAMEM7 &&
"unexpected matrix register");
O << "m" << (MO.getReg() - RISCV::AMEM0);
O << "m" << (MO.getReg() - RISCV::THeadAMEM0);
}

void RISCVInstPrinter::printZttMatrixRegIndex(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);

assert(MO.isImm() &&
"printZttMatrixRegIndex can only print immediate operands");
O << "m" << MO.getImm();
}

void RISCVInstPrinter::printZttAccRegIndex(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);

assert(MO.isImm() && "printZttAccRegIndex can only print immediate operands");
O << "acc" << MO.getImm();
}

void RISCVInstPrinter::printVScaleReg(const MCInst *MI, unsigned OpNo,
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ class RISCVInstPrinter : public MCInstPrinter {
const MCSubtargetInfo &STI, raw_ostream &O);
void printVMaskReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printMatrixReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printTHeadAMEMatrixReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printZttMatrixRegIndex(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printZttAccRegIndex(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printVScaleReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printTileLambda(const MCInst *MI, unsigned OpNo,
Expand Down
34 changes: 19 additions & 15 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "MCTargetDesc/RISCVELFStreamer.h"
#include "MCTargetDesc/RISCVInstPrinter.h"
#include "MCTargetDesc/RISCVMCAsmInfo.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "MCTargetDesc/RISCVMatInt.h"
#include "MCTargetDesc/RISCVTargetStreamer.h"
#include "RISCV.h"
Expand Down Expand Up @@ -379,26 +380,29 @@ void RISCVAsmPrinter::emitNTLHint(const MachineInstr *MI) {
EmitToStreamer(*OutStreamer, Hint);
}

static unsigned getAMETileReg(unsigned Index) {
static const unsigned Regs[] = {RISCV::TR0, RISCV::TR1, RISCV::TR2,
RISCV::TR3, RISCV::TR4, RISCV::TR5,
RISCV::TR6, RISCV::TR7};
static unsigned getBOSCAMETileReg(unsigned Index) {
static const unsigned Regs[] = {RISCV::BOSCAMETR0, RISCV::BOSCAMETR1,
RISCV::BOSCAMETR2, RISCV::BOSCAMETR3,
RISCV::BOSCAMETR4, RISCV::BOSCAMETR5,
RISCV::BOSCAMETR4, RISCV::BOSCAMETR7};
assert(Index < 8 && "invalid AME tile register index");
return Regs[Index];
}

static unsigned getAMEAccReg(unsigned Index) {
static const unsigned Regs[] = {RISCV::ACC0, RISCV::ACC1, RISCV::ACC2,
RISCV::ACC3, RISCV::ACC4, RISCV::ACC5,
RISCV::ACC6, RISCV::ACC7};
static unsigned getBOSCAMEAccReg(unsigned Index) {
static const unsigned Regs[] = {RISCV::BOSCAMEACC0, RISCV::BOSCAMEACC1,
RISCV::BOSCAMEACC2, RISCV::BOSCAMEACC3,
RISCV::BOSCAMEACC4, RISCV::BOSCAMEACC5,
RISCV::BOSCAMEACC6, RISCV::BOSCAMEACC7};
assert(Index < 8 && "invalid AME accumulator register index");
return Regs[Index];
}

static unsigned getAMEMatrixReg(unsigned Index) {
static const unsigned Regs[] = {RISCV::AMEM0, RISCV::AMEM1, RISCV::AMEM2,
RISCV::AMEM3, RISCV::AMEM4, RISCV::AMEM5,
RISCV::AMEM6, RISCV::AMEM7};
static unsigned getTHeadAMEMatrixReg(unsigned Index) {
static const unsigned Regs[] = {RISCV::THeadAMEM0, RISCV::THeadAMEM1,
RISCV::THeadAMEM2, RISCV::THeadAMEM3,
RISCV::THeadAMEM4, RISCV::THeadAMEM5,
RISCV::THeadAMEM6, RISCV::THeadAMEM7};
assert(Index < 8 && "invalid AME matrix register index");
return Regs[Index];
}
Expand All @@ -419,15 +423,15 @@ bool RISCVAsmPrinter::lowerMatrixExtPseudo(const MachineInstr *MI,

auto AddTileIndex = [&](unsigned OpNo) {
Inst.addOperand(
MCOperand::createReg(getAMETileReg(MI->getOperand(OpNo).getImm())));
MCOperand::createReg(getBOSCAMETileReg(MI->getOperand(OpNo).getImm())));
};
auto AddAccIndex = [&](unsigned OpNo) {
Inst.addOperand(
MCOperand::createReg(getAMEAccReg(MI->getOperand(OpNo).getImm())));
MCOperand::createReg(getBOSCAMEAccReg(MI->getOperand(OpNo).getImm())));
};
auto AddMatrixIndex = [&](unsigned OpNo) {
Inst.addOperand(MCOperand::createReg(
getAMEMatrixReg(MI->getOperand(OpNo).getImm())));
getTHeadAMEMatrixReg(MI->getOperand(OpNo).getImm())));
};

switch (MI->getOpcode()) {
Expand Down
30 changes: 30 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,36 @@ def HasStdExtZvvmttls : Predicate<"Subtarget->hasStdExtZvvmttls()">,
AssemblerPredicate<(all_of FeatureStdExtZvvmttls),
"'Zvvmttls' (Transposing Matrix Tile Load/Store)">;

// Attached Matrix Extension
def FeatureStdExtZttMatrixRegs16
: SubtargetFeature<"experimental-ztt-ame-mregs-16", "HasZttMatrixRegs16", "true",
"Enable support for 16 AME matrix registers">;

def FeatureStdExtZttMatrixRegs32
: SubtargetFeature<"experimental-ztt-ame-mregs-32", "HasZttMatrixRegs32", "true",
"Enable support for 32 AME matrix registers">;

def FeatureStdExtZttAccRegs1
: SubtargetFeature<"experimental-ztt-ame-accregs-1", "HasZttAccRegs1", "true",
"Enable support for AME accumulator register">;

def FeatureStdExtZttAccRegs2
: SubtargetFeature<"experimental-ztt-ame-accregs-2", "HasZttAccRegs2", "true",
"Enable support for 2 AME accumulator registers">;

def FeatureStdExtZttAccRegs4
: SubtargetFeature<"experimental-ztt-ame-accregs-4", "HasZttAccRegs4", "true",
"Enable support for 4 AME accumulator registers">;

let Implies = [FeatureStdExtZttMatrixRegs32, FeatureStdExtZttAccRegs4] in {
def FeatureStdExtZtt // By default, enabling "+experimental-ztt" implies 32 Matrix Regs and 4 Accumulators.
: RISCVExperimentalExtension<0, 1, "Attached Matrix Extension">;
}

def HasStdExtZtt : Predicate<"Subtarget->hasStdExtZtt()">,
AssemblerPredicate<(all_of FeatureStdExtZtt),
"'Ztt' (Attached Matrix Extension)">;

// Zvbdota family of batched dot-product extensions
def FeatureStdExtZvqwbdota8i
: RISCVExperimentalExtension<0, 2,
Expand Down
Loading