Skip to content

Commit

Permalink
[AArch64][SVE] Added GPR64shifted and GPR64NoXZRshifted register clas…
Browse files Browse the repository at this point in the history
…ses.

Summary:
This is patch [3/4] in a series to add assembler/disassembler support for
SVE's contiguous LD1 (scalar+scalar) instructions:
- Patch [1/4]: https://reviews.llvm.org/D45687
- Patch [2/4]: https://reviews.llvm.org/D45688
- Patch [3/4]: https://reviews.llvm.org/D45689
- Patch [4/4]: https://reviews.llvm.org/D45690

Reviewers: fhahn, rengolin, javed.absar, huntergr, SjoerdMeijer, t.p.northover, echristo, evandro

Reviewed By: SjoerdMeijer

Subscribers: tschuett, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D45689

llvm-svn: 330406
  • Loading branch information
sdesmalen-arm committed Apr 20, 2018
1 parent 0e0906c commit 367694b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 7 deletions.
21 changes: 21 additions & 0 deletions llvm/lib/Target/AArch64/AArch64RegisterInfo.td
Expand Up @@ -933,3 +933,24 @@ def ZZZZ_s : RegisterOperand<ZPR4, "printTypedVectorList<0,'s'>"> {
def ZZZZ_d : RegisterOperand<ZPR4, "printTypedVectorList<0,'d'>"> {
let ParserMatchClass = ZPRVectorList<64, 4>;
}

class GPR64ShiftExtendAsmOperand <string AsmOperandName, int Scale, string RegClass> : AsmOperandClass {
let Name = AsmOperandName # Scale;
let PredicateMethod = "isGPR64WithShiftExtend<AArch64::"#RegClass#"RegClassID, " # Scale # ">";
let DiagnosticType = "Invalid" # AsmOperandName # Scale;
let RenderMethod = "addRegOperands";
let ParserMethod = "tryParseGPROperand<true>";
}

class GPR64ExtendRegisterOperand<string Name, int Scale, RegisterClass RegClass> : RegisterOperand<RegClass>{
let ParserMatchClass = !cast<AsmOperandClass>(Name);
let PrintMethod = "printRegWithShiftExtend<false, " # Scale # ", 'x'>";
}

foreach Scale = [8, 16, 32, 64] in {
def GPR64shiftedAsmOpnd # Scale : GPR64ShiftExtendAsmOperand<"GPR64shifted", Scale, "GPR64">;
def GPR64shifted # Scale : GPR64ExtendRegisterOperand<"GPR64shiftedAsmOpnd" # Scale, Scale, GPR64>;

def GPR64NoXZRshiftedAsmOpnd # Scale : GPR64ShiftExtendAsmOperand<"GPR64NoXZRshifted", Scale, "GPR64common">;
def GPR64NoXZRshifted # Scale : GPR64ExtendRegisterOperand<"GPR64NoXZRshiftedAsmOpnd" # Scale, Scale, GPR64common>;
}
24 changes: 24 additions & 0 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Expand Up @@ -3823,6 +3823,22 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
ComputeAvailableFeatures(STI->getFeatureBits()));
return Error(Loc, "unrecognized instruction mnemonic" + Suggestion);
}
case Match_InvalidGPR64shifted8:
return Error(Loc, "register must be x0..x30 or xzr, without shift");
case Match_InvalidGPR64shifted16:
return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #1'");
case Match_InvalidGPR64shifted32:
return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #2'");
case Match_InvalidGPR64shifted64:
return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #3'");
case Match_InvalidGPR64NoXZRshifted8:
return Error(Loc, "register must be x0..x30 without shift");
case Match_InvalidGPR64NoXZRshifted16:
return Error(Loc, "register must be x0..x30 with required shift 'lsl #1'");
case Match_InvalidGPR64NoXZRshifted32:
return Error(Loc, "register must be x0..x30 with required shift 'lsl #2'");
case Match_InvalidGPR64NoXZRshifted64:
return Error(Loc, "register must be x0..x30 with required shift 'lsl #3'");
case Match_InvalidSVEPattern:
return Error(Loc, "invalid predicate pattern");
case Match_InvalidSVEPredicateAnyReg:
Expand Down Expand Up @@ -4268,6 +4284,14 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidLabel:
case Match_InvalidComplexRotationEven:
case Match_InvalidComplexRotationOdd:
case Match_InvalidGPR64shifted8:
case Match_InvalidGPR64shifted16:
case Match_InvalidGPR64shifted32:
case Match_InvalidGPR64shifted64:
case Match_InvalidGPR64NoXZRshifted8:
case Match_InvalidGPR64NoXZRshifted16:
case Match_InvalidGPR64NoXZRshifted32:
case Match_InvalidGPR64NoXZRshifted64:
case Match_InvalidSVEPredicateAnyReg:
case Match_InvalidSVEPattern:
case Match_InvalidSVEPredicateBReg:
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
Expand Up @@ -55,6 +55,10 @@ static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
LLVM_ATTRIBUTE_UNUSED
static DecodeStatus DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
Expand Down Expand Up @@ -402,6 +406,17 @@ static const unsigned GPR64DecoderTable[] = {
AArch64::LR, AArch64::XZR
};

static DecodeStatus DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 30)
return Fail;

unsigned Register = GPR64DecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Register));
return Success;
}

static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
Expand Down
31 changes: 25 additions & 6 deletions llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
Expand Up @@ -969,12 +969,9 @@ void AArch64InstPrinter::printArithExtend(const MCInst *MI, unsigned OpNum,
O << " #" << ShiftVal;
}

void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum,
raw_ostream &O, char SrcRegKind,
unsigned Width) {
unsigned SignExtend = MI->getOperand(OpNum).getImm();
unsigned DoShift = MI->getOperand(OpNum + 1).getImm();

static void printMemExtendImpl(bool SignExtend, bool DoShift,
unsigned Width, char SrcRegKind,
raw_ostream &O) {
// sxtw, sxtx, uxtw or lsl (== uxtx)
bool IsLSL = !SignExtend && SrcRegKind == 'x';
if (IsLSL)
Expand All @@ -986,6 +983,28 @@ void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum,
O << " #" << Log2_32(Width / 8);
}

void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum,
raw_ostream &O, char SrcRegKind,
unsigned Width) {
bool SignExtend = MI->getOperand(OpNum).getImm();
bool DoShift = MI->getOperand(OpNum + 1).getImm();
printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O);
}

template <bool SignExtend, int ExtWidth, char SrcRegKind>
void AArch64InstPrinter::printRegWithShiftExtend(const MCInst *MI,
unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
printOperand(MI, OpNum, STI, O);

bool DoShift = ExtWidth != 8;
if (SignExtend || DoShift || SrcRegKind == 'w') {
O << ", ";
printMemExtendImpl(SignExtend, DoShift, ExtWidth, SrcRegKind, O);
}
}

void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
Expand Up @@ -90,7 +90,9 @@ class AArch64InstPrinter : public MCInstPrinter {
const MCSubtargetInfo &STI, raw_ostream &O) {
printMemExtend(MI, OpNum, O, SrcRegKind, Width);
}

template <bool SignedExtend, int ExtWidth, char SrcRegKind>
void printRegWithShiftExtend(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
void printCondCode(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
void printInverseCondCode(const MCInst *MI, unsigned OpNum,
Expand Down

0 comments on commit 367694b

Please sign in to comment.