diff options
author | Artem Tamazov <artem.tamazov@amd.com> | 2016-04-25 14:13:51 +0000 |
---|---|---|
committer | Artem Tamazov <artem.tamazov@amd.com> | 2016-04-25 14:13:51 +0000 |
commit | d6468666b540364feec63b5abed9aa428832fe8d (patch) | |
tree | 8efdccb79942350a8a772d349eda9fc43cef6c54 /llvm/lib | |
parent | 926bff8c3e3f3fd12395968423380b84caf087f1 (diff) | |
download | bcm5719-llvm-d6468666b540364feec63b5abed9aa428832fe8d.tar.gz bcm5719-llvm-d6468666b540364feec63b5abed9aa428832fe8d.zip |
[AMDGPU][llvm-mc] s_getreg/setreg* - Add hwreg(...) syntax.
Added hwreg(reg[,offset,width]) syntax.
Default offset = 0, default width = 32.
Possibility to specify 16-bit immediate kept.
Added out-of-range checks.
Disassembling is always to hwreg(...) format.
Tests updated/added.
Differential Revision: http://reviews.llvm.org/D19329
llvm-svn: 267410
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 94 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstrInfo.td | 12 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstructions.td | 9 |
5 files changed, 127 insertions, 3 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index e6462689d24..c099c9b3a36 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -79,6 +79,7 @@ public: ImmTyDA, ImmTyR128, ImmTyLWE, + ImmTyHwreg, }; struct TokOp { @@ -406,6 +407,7 @@ public: bool isDSOffset() const; bool isDSOffset01() const; bool isSWaitCnt() const; + bool isHwreg() const; bool isMubufOffset() const; bool isSMRDOffset() const; bool isSMRDLiteralOffset() const; @@ -530,6 +532,8 @@ public: bool parseCnt(int64_t &IntVal); OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands); + bool parseHwreg(int64_t &HwRegCode, int64_t &Offset, int64_t &Width); + OperandMatchResultTy parseHwregOp(OperandVector &Operands); OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands); OperandMatchResultTy parseFlatOptionalOps(OperandVector &Operands); @@ -1570,10 +1574,100 @@ AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) { return MatchOperand_Success; } +bool AMDGPUAsmParser::parseHwreg(int64_t &HwRegCode, int64_t &Offset, int64_t &Width) { + if (Parser.getTok().getString() != "hwreg") + return true; + Parser.Lex(); + + if (getLexer().isNot(AsmToken::LParen)) + return true; + Parser.Lex(); + + if (getLexer().isNot(AsmToken::Integer)) + return true; + if (getParser().parseAbsoluteExpression(HwRegCode)) + return true; + + if (getLexer().is(AsmToken::RParen)) { + Parser.Lex(); + return false; + } + + // optional params + if (getLexer().isNot(AsmToken::Comma)) + return true; + Parser.Lex(); + + if (getLexer().isNot(AsmToken::Integer)) + return true; + if (getParser().parseAbsoluteExpression(Offset)) + return true; + + if (getLexer().isNot(AsmToken::Comma)) + return true; + Parser.Lex(); + + if (getLexer().isNot(AsmToken::Integer)) + return true; + if (getParser().parseAbsoluteExpression(Width)) + return true; + + if (getLexer().isNot(AsmToken::RParen)) + return true; + Parser.Lex(); + + return false; +} + +AMDGPUAsmParser::OperandMatchResultTy +AMDGPUAsmParser::parseHwregOp(OperandVector &Operands) { + int64_t Imm16Val = 0; + SMLoc S = Parser.getTok().getLoc(); + + switch(getLexer().getKind()) { + default: return MatchOperand_ParseFail; + case AsmToken::Integer: + // The operand can be an integer value. + if (getParser().parseAbsoluteExpression(Imm16Val)) + return MatchOperand_ParseFail; + if (!isInt<16>(Imm16Val) && !isUInt<16>(Imm16Val)) { + Error(S, "invalid immediate: only 16-bit values are legal"); + // Do not return error code, but create an imm operand anyway and proceed + // to the next operand, if any. That avoids unneccessary error messages. + } + break; + + case AsmToken::Identifier: { + int64_t HwRegCode = 0; + int64_t Offset = 0; // default + int64_t Width = 32; // default + if (parseHwreg(HwRegCode, Offset, Width)) + return MatchOperand_ParseFail; + // HwRegCode (6) [5:0] + // Offset (5) [10:6] + // WidthMinusOne (5) [15:11] + if (HwRegCode < 0 || HwRegCode > 63) + Error(S, "invalid code of hardware register: only 6-bit values are legal"); + if (Offset < 0 || Offset > 31) + Error(S, "invalid bit offset: only 5-bit values are legal"); + if (Width < 1 || Width > 32) + Error(S, "invalid bitfield width: only values from 1 to 32 are legal"); + Imm16Val = HwRegCode | (Offset << 6) | ((Width-1) << 11); + } + break; + } + Operands.push_back(AMDGPUOperand::CreateImm(Imm16Val, S, AMDGPUOperand::ImmTyHwreg)); + return MatchOperand_Success; +} + bool AMDGPUOperand::isSWaitCnt() const { return isImm(); } +bool AMDGPUOperand::isHwreg() const { + return isImmTy(ImmTyHwreg); +} + //===----------------------------------------------------------------------===// // sopp branch targets //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp index 0bdff1af82c..e02bc90e89c 100644 --- a/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp @@ -760,4 +760,18 @@ void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, } } +void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned SImm16 = MI->getOperand(OpNo).getImm(); + const unsigned HwRegCode = SImm16 & 0x3F; + const unsigned Offset = (SImm16 >> 6) & 0x1f; + const unsigned Width = ((SImm16 >> 11) & 0x1F) + 1; + + if (Width == 32 && Offset == 0) { + O << "hwreg(" << HwRegCode << ')'; + } else { + O << "hwreg(" << HwRegCode << ", " << Offset << ", " << Width << ')'; + } +} + #include "AMDGPUGenAsmWriter.inc" diff --git a/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h b/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h index 682894f92df..64618c737e7 100644 --- a/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h +++ b/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h @@ -91,6 +91,7 @@ private: static void printKCache(const MCInst *MI, unsigned OpNo, raw_ostream &O); static void printSendMsg(const MCInst *MI, unsigned OpNo, raw_ostream &O); static void printWaitFlag(const MCInst *MI, unsigned OpNo, raw_ostream &O); + static void printHwreg(const MCInst *MI, unsigned OpNo, raw_ostream &O); }; } // End namespace llvm diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index fa19af19c80..79ef1c66218 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -603,6 +603,13 @@ class NamedBitOperand<string BitName> : Operand<i1> { let PrintMethod = "print"#BitName; } +def HwregMatchClass : AsmOperandClass { + let Name = "Hwreg"; + let PredicateMethod = "isHwreg"; + let ParserMethod = "parseHwregOp"; + let RenderMethod = "addImmOperands"; +} + let OperandType = "OPERAND_IMMEDIATE" in { def offen : Operand<i1> { @@ -730,6 +737,11 @@ def bound_ctrl : Operand <i1> { let ParserMatchClass = DPPOptionalMatchClass<"BoundCtrl">; } +def hwreg : Operand <i16> { + let PrintMethod = "printHwreg"; + let ParserMatchClass = HwregMatchClass; +} + } // End OperandType = "OPERAND_IMMEDIATE" diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td index b2c059d2770..64d42b76d44 100644 --- a/llvm/lib/Target/AMDGPU/SIInstructions.td +++ b/llvm/lib/Target/AMDGPU/SIInstructions.td @@ -418,18 +418,21 @@ defm S_CBRANCH_I_FORK : SOPK_m < >; let mayLoad = 1 in { -defm S_GETREG_B32 : SOPK_32 <sopk<0x12, 0x11>, "s_getreg_b32", []>; +defm S_GETREG_B32 : SOPK_m < + sopk<0x12, 0x11>, "s_getreg_b32", (outs SReg_32:$sdst), + (ins hwreg:$simm16), " $sdst, $simm16" +>; } defm S_SETREG_B32 : SOPK_m < sopk<0x13, 0x12>, "s_setreg_b32", (outs), - (ins SReg_32:$sdst, u16imm:$simm16), " $simm16, $sdst" + (ins SReg_32:$sdst, hwreg:$simm16), " $simm16, $sdst" >; // FIXME: Not on SI? //defm S_GETREG_REGRD_B32 : SOPK_32 <sopk<0x14, 0x13>, "s_getreg_regrd_b32", []>; defm S_SETREG_IMM32_B32 : SOPK_IMM32 < sopk<0x15, 0x14>, "s_setreg_imm32_b32", (outs), - (ins i32imm:$imm, u16imm:$simm16), " $simm16, $imm" + (ins i32imm:$imm, hwreg:$simm16), " $simm16, $imm" >; //===----------------------------------------------------------------------===// |