diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2014-03-17 17:03:49 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2014-03-17 17:03:49 +0000 |
commit | 27b614fcd30c8fe80bc8f11f00d89c260a88fd74 (patch) | |
tree | 089c86cc9bbb6c160dcc0bd971a8146878804e49 | |
parent | bbbc2b1140e67f0c8783d4f8dd3977a482e1211e (diff) | |
download | llvm-27b614fcd30c8fe80bc8f11f00d89c260a88fd74.tar.gz llvm-27b614fcd30c8fe80bc8f11f00d89c260a88fd74.tar.bz2 llvm-27b614fcd30c8fe80bc8f11f00d89c260a88fd74.tar.xz |
R600/SI: Add generic checks to SIInstrInfo::verifyInstruction()
Added checks for number of operands and operand register classes.
Tested-by: Michel Dänzer <michel.daenzer@amd.com>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204054 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/R600/SIInstrInfo.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp index 676e0388b0..f68dc2e0e4 100644 --- a/lib/Target/R600/SIInstrInfo.cpp +++ b/lib/Target/R600/SIInstrInfo.cpp @@ -377,6 +377,47 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1); int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2); + // Make sure the number of operands is correct. + const MCInstrDesc &Desc = get(Opcode); + if (!Desc.isVariadic() && + Desc.getNumOperands() != MI->getNumExplicitOperands()) { + ErrInfo = "Instruction has wrong number of operands."; + return false; + } + + // Make sure the register classes are correct + for (unsigned i = 0, e = Desc.getNumOperands(); i != e; ++i) { + switch (Desc.OpInfo[i].OperandType) { + case MCOI::OPERAND_REGISTER: + break; + case MCOI::OPERAND_IMMEDIATE: + if (!MI->getOperand(i).isImm() && !MI->getOperand(i).isFPImm()) { + ErrInfo = "Expected immediate, but got non-immediate"; + return false; + } + // Fall-through + default: + continue; + } + + if (!MI->getOperand(i).isReg()) + continue; + + int RegClass = Desc.OpInfo[i].RegClass; + if (RegClass != -1) { + unsigned Reg = MI->getOperand(i).getReg(); + if (TargetRegisterInfo::isVirtualRegister(Reg)) + continue; + + const TargetRegisterClass *RC = RI.getRegClass(RegClass); + if (!RC->contains(Reg)) { + ErrInfo = "Operand has incorrect register class."; + return false; + } + } + } + + // Verify VOP* if (isVOP1(Opcode) || isVOP2(Opcode) || isVOP3(Opcode) || isVOPC(Opcode)) { unsigned ConstantBusCount = 0; |