llvm.org GIT mirror llvm / 47fbbc2
R600/SI: Implement SIInstrInfo::verifyInstruction() for VOP* The function is used by the machine verifier and checks that VOP* instructions have legal operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192367 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 7 years ago
5 changed file(s) with 141 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
1313 namespace SIInstrFlags {
1414 enum {
1515 MIMG = 1 << 3,
16 SMRD = 1 << 4
16 SMRD = 1 << 4,
17 VOP1 = 1 << 5,
18 VOP2 = 1 << 6,
19 VOP3 = 1 << 7,
20 VOPC = 1 << 8
1721 };
1822 }
1923
1818 field bits<1> LGKM_CNT = 0;
1919 field bits<1> MIMG = 0;
2020 field bits<1> SMRD = 0;
21 field bits<1> VOP1 = 0;
22 field bits<1> VOP2 = 0;
23 field bits<1> VOP3 = 0;
24 field bits<1> VOPC = 0;
2125
2226 let TSFlags{0} = VM_CNT;
2327 let TSFlags{1} = EXP_CNT;
2428 let TSFlags{2} = LGKM_CNT;
2529 let TSFlags{3} = MIMG;
2630 let TSFlags{4} = SMRD;
31 let TSFlags{5} = VOP1;
32 let TSFlags{6} = VOP2;
33 let TSFlags{7} = VOP3;
34 let TSFlags{8} = VOPC;
2735 }
2836
2937 class Enc32 pattern> :
166174 let mayLoad = 0;
167175 let mayStore = 0;
168176 let hasSideEffects = 0;
177 let UseNamedOperandTable = 1;
178 let VOP1 = 1;
169179 }
170180
171181 class VOP2 op, dag outs, dag ins, string asm, list pattern> :
184194 let mayLoad = 0;
185195 let mayStore = 0;
186196 let hasSideEffects = 0;
197 let UseNamedOperandTable = 1;
198 let VOP2 = 1;
187199 }
188200
189201 class VOP3 op, dag outs, dag ins, string asm, list pattern> :
212224 let mayLoad = 0;
213225 let mayStore = 0;
214226 let hasSideEffects = 0;
227 let UseNamedOperandTable = 1;
228 let VOP3 = 1;
215229 }
216230
217231 class VOP3b op, dag outs, dag ins, string asm, list pattern> :
238252 let mayLoad = 0;
239253 let mayStore = 0;
240254 let hasSideEffects = 0;
255 let UseNamedOperandTable = 1;
256 let VOP3 = 1;
241257 }
242258
243259 class VOPC op, dag ins, string asm, list pattern> :
255271 let mayLoad = 0;
256272 let mayStore = 0;
257273 let hasSideEffects = 0;
274 let VOPC = 1;
258275 }
259276
260277 class VINTRP op, dag outs, dag ins, string asm, list pattern> :
231231 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
232232 }
233233
234 bool SIInstrInfo::isVOP1(uint16_t Opcode) const {
235 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
236 }
237
238 bool SIInstrInfo::isVOP2(uint16_t Opcode) const {
239 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
240 }
241
242 bool SIInstrInfo::isVOP3(uint16_t Opcode) const {
243 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
244 }
245
246 bool SIInstrInfo::isVOPC(uint16_t Opcode) const {
247 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
248 }
249
250 bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const {
251 if(MO.isImm()) {
252 return MO.getImm() >= -16 && MO.getImm() <= 64;
253 }
254 if (MO.isFPImm()) {
255 return MO.getFPImm()->isExactlyValue(0.0) ||
256 MO.getFPImm()->isExactlyValue(0.5) ||
257 MO.getFPImm()->isExactlyValue(-0.5) ||
258 MO.getFPImm()->isExactlyValue(1.0) ||
259 MO.getFPImm()->isExactlyValue(-1.0) ||
260 MO.getFPImm()->isExactlyValue(2.0) ||
261 MO.getFPImm()->isExactlyValue(-2.0) ||
262 MO.getFPImm()->isExactlyValue(4.0) ||
263 MO.getFPImm()->isExactlyValue(-4.0);
264 }
265 return false;
266 }
267
268 bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const {
269 return (MO.isImm() || MO.isFPImm()) && !isInlineConstant(MO);
270 }
271
272 bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
273 StringRef &ErrInfo) const {
274 uint16_t Opcode = MI->getOpcode();
275 int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
276 int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
277 int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
278
279 // Verify VOP*
280 if (isVOP1(Opcode) || isVOP2(Opcode) || isVOP3(Opcode) || isVOPC(Opcode)) {
281 unsigned ConstantBusCount = 0;
282 unsigned SGPRUsed = AMDGPU::NoRegister;
283 MI->dump();
284 for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
285 const MachineOperand &MO = MI->getOperand(i);
286 if (MO.isReg() && MO.isUse() &&
287 !TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
288
289 // EXEC register uses the constant bus.
290 if (!MO.isImplicit() && MO.getReg() == AMDGPU::EXEC)
291 ++ConstantBusCount;
292
293 // SGPRs use the constant bus
294 if (MO.getReg() == AMDGPU::M0 || MO.getReg() == AMDGPU::VCC ||
295 (!MO.isImplicit() &&
296 (AMDGPU::SGPR_32RegClass.contains(MO.getReg()) ||
297 AMDGPU::SGPR_64RegClass.contains(MO.getReg())))) {
298 if (SGPRUsed != MO.getReg()) {
299 ++ConstantBusCount;
300 SGPRUsed = MO.getReg();
301 }
302 }
303 }
304 // Literal constants use the constant bus.
305 if (isLiteralConstant(MO))
306 ++ConstantBusCount;
307 }
308 if (ConstantBusCount > 1) {
309 ErrInfo = "VOP* instruction uses the constant bus more than once";
310 return false;
311 }
312 }
313
314 // Verify SRC1 for VOP2 and VOPC
315 if (Src1Idx != -1 && (isVOP2(Opcode) || isVOPC(Opcode))) {
316 const MachineOperand &Src1 = MI->getOperand(Src1Idx);
317 if (Src1.isImm()) {
318 ErrInfo = "VOP[2C] src1 cannot be an immediate.";
319 return false;
320 }
321 }
322
323 // Verify VOP3
324 if (isVOP3(Opcode)) {
325 if (Src0Idx != -1 && isLiteralConstant(MI->getOperand(Src0Idx))) {
326 ErrInfo = "VOP3 src0 cannot be a literal constant.";
327 return false;
328 }
329 if (Src1Idx != -1 && isLiteralConstant(MI->getOperand(Src1Idx))) {
330 ErrInfo = "VOP3 src1 cannot be a literal constant.";
331 return false;
332 }
333 if (Src2Idx != -1 && isLiteralConstant(MI->getOperand(Src2Idx))) {
334 ErrInfo = "VOP3 src2 cannot be a literal constant.";
335 return false;
336 }
337 }
338 return true;
339 }
340
234341 //===----------------------------------------------------------------------===//
235342 // Indirect addressing callbacks
236343 //===----------------------------------------------------------------------===//
4848 virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const;
4949 int isMIMG(uint16_t Opcode) const;
5050 int isSMRD(uint16_t Opcode) const;
51 bool isVOP1(uint16_t Opcode) const;
52 bool isVOP2(uint16_t Opcode) const;
53 bool isVOP3(uint16_t Opcode) const;
54 bool isVOPC(uint16_t Opcode) const;
55 bool isInlineConstant(const MachineOperand &MO) const;
56 bool isLiteralConstant(const MachineOperand &MO) const;
5157
58 virtual bool verifyInstruction(const MachineInstr *MI,
59 StringRef &ErrInfo) const;
5260 virtual int getIndirectIndexBegin(const MachineFunction &MF) const;
5361
5462 virtual int getIndirectIndexEnd(const MachineFunction &MF) const;
4242 (add (sequence "SGPR%u", 0, 101))>;
4343
4444 // SGPR 64-bit registers
45 def SGPR_64 : RegisterTuples<[sub0, sub1],
45 def SGPR_64Regs : RegisterTuples<[sub0, sub1],
4646 [(add (decimate (trunc SGPR_32, 101), 2)),
4747 (add (decimate (shl SGPR_32, 1), 2))]>;
4848
152152 (add SGPR_32, M0Reg)
153153 >;
154154
155 def SGPR_64 : RegisterClass<"AMDGPU", [v2i32, i64], 64, (add SGPR_64Regs)>;
156
155157 def SReg_64 : RegisterClass<"AMDGPU", [v2i32, i64, i1], 64,
156 (add SGPR_64, VCCReg, EXECReg)
158 (add SGPR_64Regs, VCCReg, EXECReg)
157159 >;
158160
159161 def SReg_128 : RegisterClass<"AMDGPU", [i128], 128, (add SGPR_128)>;