summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2016-02-11 03:28:15 +0000
committerTom Stellard <thomas.stellard@amd.com>2016-02-11 03:28:15 +0000
commita90b9526df693321a4dbebfeb1dcac672f403b41 (patch)
treec22cad9c7c2d52df235e032c7828da9327b8b305 /llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
parentba284b60b87f62fbb52f29541141cf2afb9502bc (diff)
downloadbcm5719-llvm-a90b9526df693321a4dbebfeb1dcac672f403b41.tar.gz
bcm5719-llvm-a90b9526df693321a4dbebfeb1dcac672f403b41.zip
[AMDGPU] Assembler: Fix VOP3 only instructions
Separate methods to convert parsed instructions to MCInst: - VOP3 only instructions (always create modifiers as operands in MCInst) - VOP2 instrunctions with modifiers (create modifiers as operands in MCInst when e64 encoding is forced or modifiers are parsed) - VOP2 instructions without modifiers (do not create modifiers as operands in MCInst) - Add VOP3Only flag. Pass HasMods flag to VOP3Common. - Simplify code that deals with modifiers (-1 is now same as 0). This is no longer needed. - Add few tests (more will be added separately). Update error message now correct. Patch By: Nikolay Haustov Differential Revision: http://reviews.llvm.org/D16778 llvm-svn: 260483
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp145
1 files changed, 92 insertions, 53 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 5b03059c119..aef4716b0b2 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -116,8 +116,7 @@ public:
}
void addRegWithInputModsOperands(MCInst &Inst, unsigned N) const {
- Inst.addOperand(MCOperand::createImm(
- Reg.Modifiers == -1 ? 0 : Reg.Modifiers));
+ Inst.addOperand(MCOperand::createImm(Reg.Modifiers));
addRegOperands(Inst, N);
}
@@ -176,11 +175,23 @@ public:
}
bool isReg() const override {
- return Kind == Register && Reg.Modifiers == -1;
+ return Kind == Register && Reg.Modifiers == 0;
}
bool isRegWithInputMods() const {
- return Kind == Register && (Reg.IsForcedVOP3 || Reg.Modifiers != -1);
+ return Kind == Register;
+ }
+
+ bool isClamp() const {
+ return isImm() && Imm.Type == ImmTyClamp;
+ }
+
+ bool isOMod() const {
+ return isImm() && Imm.Type == ImmTyOMod;
+ }
+
+ bool isMod() const {
+ return isClamp() || isOMod();
}
void setModifiers(unsigned Mods) {
@@ -190,7 +201,7 @@ public:
bool hasModifiers() const {
assert(isRegKind());
- return Reg.Modifiers != -1;
+ return Reg.Modifiers != 0;
}
unsigned getReg() const override {
@@ -202,7 +213,7 @@ public:
}
bool isRegClass(unsigned RCID) const {
- return Reg.TRI->getRegClass(RCID).contains(getReg());
+ return isReg() && Reg.TRI->getRegClass(RCID).contains(getReg());
}
bool isSCSrc32() const {
@@ -306,7 +317,7 @@ public:
Op->Reg.RegNo = RegNo;
Op->Reg.TRI = TRI;
Op->Reg.STI = STI;
- Op->Reg.Modifiers = -1;
+ Op->Reg.Modifiers = 0;
Op->Reg.IsForcedVOP3 = ForceVOP3;
Op->StartLoc = S;
Op->EndLoc = E;
@@ -462,6 +473,10 @@ public:
OperandMatchResultTy parseUNorm(OperandVector &Operands);
OperandMatchResultTy parseR128(OperandVector &Operands);
+ void cvtId(MCInst &Inst, const OperandVector &Operands);
+ void cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands);
+ void cvtVOP3_2_nomod(MCInst &Inst, const OperandVector &Operands);
+ void cvtVOP3_only(MCInst &Inst, const OperandVector &Operands);
void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
OperandMatchResultTy parseVOP3OptionalOps(OperandVector &Operands);
};
@@ -1103,7 +1118,7 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
// If we are parsing after we reach EndOfStatement then this means we
// are appending default values to the Operands list. This is only done
// by custom parser, so we shouldn't continue on to the generic parsing.
- if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail ||
+ if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail||
getLexer().is(AsmToken::EndOfStatement))
return ResTy;
@@ -1153,8 +1168,6 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
SMLoc S, E;
unsigned RegNo;
if (!ParseRegister(RegNo, S, E)) {
-
- bool HasModifiers = operandsHaveModifiers(Operands);
unsigned Modifiers = 0;
if (Negate)
@@ -1167,34 +1180,23 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
Modifiers |= 0x2;
}
- if (Modifiers && !HasModifiers) {
- // We are adding a modifier to src1 or src2 and previous sources
- // don't have modifiers, so we need to go back and empty modifers
- // for each previous source.
- for (unsigned PrevRegIdx = Operands.size() - 1; PrevRegIdx > 1;
- --PrevRegIdx) {
-
- AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[PrevRegIdx]);
- RegOp.setModifiers(0);
- }
- }
-
-
Operands.push_back(AMDGPUOperand::CreateReg(
RegNo, S, E, getContext().getRegisterInfo(), &getSTI(),
isForcedVOP3()));
- if (HasModifiers || Modifiers) {
+ if (Modifiers) {
AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[Operands.size() - 1]);
RegOp.setModifiers(Modifiers);
-
}
- } else {
- Operands.push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(),
- S));
- Parser.Lex();
- }
- return MatchOperand_Success;
+ } else {
+ ResTy = parseVOP3OptionalOps(Operands);
+ if (ResTy == MatchOperand_NoMatch) {
+ Operands.push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(),
+ S));
+ Parser.Lex();
+ }
+ }
+ return MatchOperand_Success;
}
default:
return MatchOperand_NoMatch;
@@ -1802,10 +1804,12 @@ static bool isVOP3(OperandVector &Operands) {
if (operandsHaveModifiers(Operands))
return true;
- AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]);
+ if (Operands.size() >= 2) {
+ AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]);
- if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID))
- return true;
+ if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID))
+ return true;
+ }
if (Operands.size() >= 5)
return true;
@@ -1848,35 +1852,70 @@ AMDGPUAsmParser::parseVOP3OptionalOps(OperandVector &Operands) {
return MatchOperand_NoMatch;
}
-void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
-
- unsigned i = 1;
+void AMDGPUAsmParser::cvtId(MCInst &Inst, const OperandVector &Operands) {
+ unsigned I = 1;
const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
if (Desc.getNumDefs() > 0) {
- ((AMDGPUOperand &)*Operands[i++]).addRegOperands(Inst, 1);
+ ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
}
+ for (unsigned E = Operands.size(); I != E; ++I)
+ ((AMDGPUOperand &)*Operands[I]).addRegOrImmOperands(Inst, 1);
+}
- std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
+void AMDGPUAsmParser::cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands) {
+ if (operandsHaveModifiers(Operands) || isForcedVOP3()) {
+ cvtVOP3(Inst, Operands);
+ } else {
+ cvtId(Inst, Operands);
+ }
+}
+void AMDGPUAsmParser::cvtVOP3_2_nomod(MCInst &Inst, const OperandVector &Operands) {
if (operandsHaveModifiers(Operands)) {
- for (unsigned e = Operands.size(); i != e; ++i) {
- AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
+ cvtVOP3(Inst, Operands);
+ } else {
+ cvtId(Inst, Operands);
+ }
+}
- if (Op.isRegWithInputMods()) {
- ((AMDGPUOperand &)*Operands[i]).addRegWithInputModsOperands(Inst, 2);
- continue;
- }
- OptionalIdx[Op.getImmTy()] = i;
- }
+void AMDGPUAsmParser::cvtVOP3_only(MCInst &Inst, const OperandVector &Operands) {
+ cvtVOP3(Inst, Operands);
+}
- unsigned ClampIdx = OptionalIdx[AMDGPUOperand::ImmTyClamp];
- unsigned OModIdx = OptionalIdx[AMDGPUOperand::ImmTyOMod];
+void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
+ unsigned I = 1;
+ const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
+ if (Desc.getNumDefs() > 0) {
+ ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
+ }
+
+ unsigned ClampIdx = 0, OModIdx = 0;
+ for (unsigned E = Operands.size(); I != E; ++I) {
+ AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
+ if (Op.isRegWithInputMods()) {
+ Op.addRegWithInputModsOperands(Inst, 2);
+ } else if (Op.isClamp()) {
+ ClampIdx = I;
+ } else if (Op.isOMod()) {
+ OModIdx = I;
+ } else if (Op.isImm()) {
+ Op.addImmOperands(Inst, 1);
+ } else {
+ assert(false);
+ }
+ }
- ((AMDGPUOperand &)*Operands[ClampIdx]).addImmOperands(Inst, 1);
- ((AMDGPUOperand &)*Operands[OModIdx]).addImmOperands(Inst, 1);
+ if (ClampIdx) {
+ AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[ClampIdx]);
+ Op.addImmOperands(Inst, 1);
+ } else {
+ Inst.addOperand(MCOperand::createImm(0));
+ }
+ if (OModIdx) {
+ AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[OModIdx]);
+ Op.addImmOperands(Inst, 1);
} else {
- for (unsigned e = Operands.size(); i != e; ++i)
- ((AMDGPUOperand &)*Operands[i]).addRegOrImmOperands(Inst, 1);
+ Inst.addOperand(MCOperand::createImm(0));
}
}
OpenPOWER on IntegriCloud