1//===- R600MCCodeEmitter.cpp - Code Emitter for R600->Cayman GPU families -===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This code emitters outputs bytecode that is understood by the r600g driver 11// in the Mesa [1] project. The bytecode is very similar to the hardware's ISA, 12// except that the size of the instruction fields are rounded up to the 13// nearest byte. 14// 15// [1] http://www.mesa3d.org/ 16// 17//===----------------------------------------------------------------------===// 18 19#include "R600Defines.h" 20#include "MCTargetDesc/AMDGPUMCTargetDesc.h" 21#include "MCTargetDesc/AMDGPUMCCodeEmitter.h" 22#include "llvm/MC/MCCodeEmitter.h" 23#include "llvm/MC/MCContext.h" 24#include "llvm/MC/MCInst.h" 25#include "llvm/MC/MCInstrInfo.h" 26#include "llvm/MC/MCRegisterInfo.h" 27#include "llvm/MC/MCSubtargetInfo.h" 28#include "llvm/Support/raw_ostream.h" 29 30#include <stdio.h> 31 32#define SRC_BYTE_COUNT 11 33#define DST_BYTE_COUNT 5 34 35using namespace llvm; 36 37namespace { 38 39class R600MCCodeEmitter : public AMDGPUMCCodeEmitter { 40 R600MCCodeEmitter(const R600MCCodeEmitter &); // DO NOT IMPLEMENT 41 void operator=(const R600MCCodeEmitter &); // DO NOT IMPLEMENT 42 const MCInstrInfo &MCII; 43 const MCSubtargetInfo &STI; 44 MCContext &Ctx; 45 46public: 47 48 R600MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, 49 MCContext &ctx) 50 : MCII(mcii), STI(sti), Ctx(ctx) { } 51 52 /// EncodeInstruction - Encode the instruction and write it to the OS. 53 virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 54 SmallVectorImpl<MCFixup> &Fixups) const; 55 56 /// getMachineOpValue - Reutrn the encoding for an MCOperand. 57 virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, 58 SmallVectorImpl<MCFixup> &Fixups) const; 59private: 60 61 void EmitALUInstr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups, 62 raw_ostream &OS) const; 63 void EmitSrc(const MCInst &MI, unsigned OpIdx, raw_ostream &OS) const; 64 void EmitDst(const MCInst &MI, raw_ostream &OS) const; 65 void EmitALU(const MCInst &MI, unsigned numSrc, 66 SmallVectorImpl<MCFixup> &Fixups, 67 raw_ostream &OS) const; 68 void EmitTexInstr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups, 69 raw_ostream &OS) const; 70 void EmitFCInstr(const MCInst &MI, raw_ostream &OS) const; 71 72 void EmitNullBytes(unsigned int byteCount, raw_ostream &OS) const; 73 74 void EmitByte(unsigned int byte, raw_ostream &OS) const; 75 76 void EmitTwoBytes(uint32_t bytes, raw_ostream &OS) const; 77 78 void Emit(uint32_t value, raw_ostream &OS) const; 79 void Emit(uint64_t value, raw_ostream &OS) const; 80 81 unsigned getHWRegIndex(unsigned reg) const; 82 unsigned getHWRegChan(unsigned reg) const; 83 unsigned getHWReg(unsigned regNo) const; 84 85 bool isFCOp(unsigned opcode) const; 86 bool isTexOp(unsigned opcode) const; 87 bool isFlagSet(const MCInst &MI, unsigned Operand, unsigned Flag) const; 88 89 /// getHWRegIndexGen - Get the register's hardware index. Implemented in 90 /// R600HwRegInfo.include. 91 unsigned getHWRegIndexGen(unsigned int Reg) const; 92 93 /// getHWRegChanGen - Get the register's channel. Implemented in 94 /// R600HwRegInfo.include. 95 unsigned getHWRegChanGen(unsigned int Reg) const; 96}; 97 98} // End anonymous namespace 99 100enum RegElement { 101 ELEMENT_X = 0, 102 ELEMENT_Y, 103 ELEMENT_Z, 104 ELEMENT_W 105}; 106 107enum InstrTypes { 108 INSTR_ALU = 0, 109 INSTR_TEX, 110 INSTR_FC, 111 INSTR_NATIVE, 112 INSTR_VTX 113}; 114 115enum FCInstr { 116 FC_IF = 0, 117 FC_IF_INT, 118 FC_ELSE, 119 FC_ENDIF, 120 FC_BGNLOOP, 121 FC_ENDLOOP, 122 FC_BREAK, 123 FC_BREAK_NZ_INT, 124 FC_CONTINUE, 125 FC_BREAK_Z_INT, 126 FC_BREAK_NZ 127}; 128 129enum TextureTypes { 130 TEXTURE_1D = 1, 131 TEXTURE_2D, 132 TEXTURE_3D, 133 TEXTURE_CUBE, 134 TEXTURE_RECT, 135 TEXTURE_SHADOW1D, 136 TEXTURE_SHADOW2D, 137 TEXTURE_SHADOWRECT, 138 TEXTURE_1D_ARRAY, 139 TEXTURE_2D_ARRAY, 140 TEXTURE_SHADOW1D_ARRAY, 141 TEXTURE_SHADOW2D_ARRAY 142}; 143 144MCCodeEmitter *llvm::createR600MCCodeEmitter(const MCInstrInfo &MCII, 145 const MCSubtargetInfo &STI, 146 MCContext &Ctx) { 147 return new R600MCCodeEmitter(MCII, STI, Ctx); 148} 149 150void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, 151 SmallVectorImpl<MCFixup> &Fixups) const { 152 if (isTexOp(MI.getOpcode())) { 153 EmitTexInstr(MI, Fixups, OS); 154 } else if (isFCOp(MI.getOpcode())){ 155 EmitFCInstr(MI, OS); 156 } else if (MI.getOpcode() == AMDGPU::RETURN || 157 MI.getOpcode() == AMDGPU::BUNDLE || 158 MI.getOpcode() == AMDGPU::KILL) { 159 return; 160 } else { 161 switch(MI.getOpcode()) { 162 case AMDGPU::RAT_WRITE_CACHELESS_eg: 163 { 164 uint64_t inst = getBinaryCodeForInstr(MI, Fixups); 165 EmitByte(INSTR_NATIVE, OS); 166 Emit(inst, OS); 167 break; 168 } 169 case AMDGPU::VTX_READ_PARAM_i32_eg: 170 case AMDGPU::VTX_READ_PARAM_f32_eg: 171 case AMDGPU::VTX_READ_GLOBAL_i32_eg: 172 case AMDGPU::VTX_READ_GLOBAL_f32_eg: 173 case AMDGPU::VTX_READ_GLOBAL_v4i32_eg: 174 case AMDGPU::VTX_READ_GLOBAL_v4f32_eg: 175 { 176 uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups); 177 uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset 178 179 EmitByte(INSTR_VTX, OS); 180 Emit(InstWord01, OS); 181 Emit(InstWord2, OS); 182 break; 183 } 184 185 default: 186 EmitALUInstr(MI, Fixups, OS); 187 break; 188 } 189 } 190} 191 192void R600MCCodeEmitter::EmitALUInstr(const MCInst &MI, 193 SmallVectorImpl<MCFixup> &Fixups, 194 raw_ostream &OS) const { 195 const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode()); 196 unsigned NumOperands = MI.getNumOperands(); 197 198 if(MCDesc.findFirstPredOperandIdx() > -1) 199 NumOperands--; 200 201 if (GET_FLAG_OPERAND_IDX(MCDesc.TSFlags) != 0) 202 NumOperands--; 203 204 if(MI.getOpcode() == AMDGPU::PRED_X) 205 NumOperands = 2; 206 207 // XXX Check if instruction writes a result 208 if (NumOperands < 1) { 209 return; 210 } 211 212 // Emit instruction type 213 EmitByte(0, OS); 214 215 unsigned int OpIndex; 216 for (OpIndex = 1; OpIndex < NumOperands; OpIndex++) { 217 // Literal constants are always stored as the last operand. 218 if (MI.getOperand(OpIndex).isImm() || MI.getOperand(OpIndex).isFPImm()) { 219 break; 220 } 221 EmitSrc(MI, OpIndex, OS); 222 } 223 224 // Emit zeros for unused sources 225 for ( ; OpIndex < 4; OpIndex++) { 226 EmitNullBytes(SRC_BYTE_COUNT, OS); 227 } 228 229 EmitDst(MI, OS); 230 231 EmitALU(MI, NumOperands - 1, Fixups, OS); 232} 233 234void R600MCCodeEmitter::EmitSrc(const MCInst &MI, unsigned OpIdx, 235 raw_ostream &OS) const { 236 const MCOperand &MO = MI.getOperand(OpIdx); 237 union { 238 float f; 239 uint32_t i; 240 } Value; 241 Value.i = 0; 242 // Emit the source select (2 bytes). For GPRs, this is the register index. 243 // For other potential instruction operands, (e.g. constant registers) the 244 // value of the source select is defined in the r600isa docs. 245 if (MO.isReg()) { 246 unsigned reg = MO.getReg(); 247 EmitTwoBytes(getHWReg(reg), OS); 248 if (reg == AMDGPU::ALU_LITERAL_X) { 249 unsigned ImmOpIndex = MI.getNumOperands() - 1; 250 MCOperand ImmOp = MI.getOperand(ImmOpIndex); 251 if (ImmOp.isFPImm()) { 252 Value.f = ImmOp.getFPImm(); 253 } else { 254 assert(ImmOp.isImm()); 255 Value.i = ImmOp.getImm(); 256 } 257 } 258 } else { 259 // XXX: Handle other operand types. 260 EmitTwoBytes(0, OS); 261 } 262 263 // Emit the source channel (1 byte) 264 if (MO.isReg()) { 265 EmitByte(getHWRegChan(MO.getReg()), OS); 266 } else { 267 EmitByte(0, OS); 268 } 269 270 // XXX: Emit isNegated (1 byte) 271 if ((!(isFlagSet(MI, OpIdx, MO_FLAG_ABS))) 272 && (isFlagSet(MI, OpIdx, MO_FLAG_NEG) || 273 (MO.isReg() && 274 (MO.getReg() == AMDGPU::NEG_ONE || MO.getReg() == AMDGPU::NEG_HALF)))){ 275 EmitByte(1, OS); 276 } else { 277 EmitByte(0, OS); 278 } 279 280 // Emit isAbsolute (1 byte) 281 if (isFlagSet(MI, OpIdx, MO_FLAG_ABS)) { 282 EmitByte(1, OS); 283 } else { 284 EmitByte(0, OS); 285 } 286 287 // XXX: Emit relative addressing mode (1 byte) 288 EmitByte(0, OS); 289 290 // Emit kc_bank, This will be adjusted later by r600_asm 291 EmitByte(0, OS); 292 293 // Emit the literal value, if applicable (4 bytes). 294 Emit(Value.i, OS); 295 296} 297 298void R600MCCodeEmitter::EmitDst(const MCInst &MI, raw_ostream &OS) const { 299 300 const MCOperand &MO = MI.getOperand(0); 301 if (MO.isReg() && MO.getReg() != AMDGPU::PREDICATE_BIT) { 302 // Emit the destination register index (1 byte) 303 EmitByte(getHWReg(MO.getReg()), OS); 304 305 // Emit the element of the destination register (1 byte) 306 EmitByte(getHWRegChan(MO.getReg()), OS); 307 308 // Emit isClamped (1 byte) 309 if (isFlagSet(MI, 0, MO_FLAG_CLAMP)) { 310 EmitByte(1, OS); 311 } else { 312 EmitByte(0, OS); 313 } 314 315 // Emit writemask (1 byte). 316 if (isFlagSet(MI, 0, MO_FLAG_MASK)) { 317 EmitByte(0, OS); 318 } else { 319 EmitByte(1, OS); 320 } 321 322 // XXX: Emit relative addressing mode 323 EmitByte(0, OS); 324 } else { 325 // XXX: Handle other operand types. Are there any for destination regs? 326 EmitNullBytes(DST_BYTE_COUNT, OS); 327 } 328} 329 330void R600MCCodeEmitter::EmitALU(const MCInst &MI, unsigned numSrc, 331 SmallVectorImpl<MCFixup> &Fixups, 332 raw_ostream &OS) const { 333 const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode()); 334 335 // Emit the instruction (2 bytes) 336 EmitTwoBytes(getBinaryCodeForInstr(MI, Fixups), OS); 337 338 // Emit IsLast (for this instruction group) (1 byte) 339 if (isFlagSet(MI, 0, MO_FLAG_NOT_LAST)) { 340 EmitByte(0, OS); 341 } else { 342 EmitByte(1, OS); 343 } 344 345 // Emit isOp3 (1 byte) 346 if (numSrc == 3) { 347 EmitByte(1, OS); 348 } else { 349 EmitByte(0, OS); 350 } 351 352 // XXX: Emit push modifier 353 if(isFlagSet(MI, 1, MO_FLAG_PUSH)) { 354 EmitByte(1, OS); 355 } else { 356 EmitByte(0, OS); 357 } 358 359 // XXX: Emit predicate (1 byte) 360 int PredIdx = MCDesc.findFirstPredOperandIdx(); 361 if (PredIdx > -1) 362 switch(MI.getOperand(PredIdx).getReg()) { 363 case AMDGPU::PRED_SEL_ZERO: 364 EmitByte(2, OS); 365 break; 366 case AMDGPU::PRED_SEL_ONE: 367 EmitByte(3, OS); 368 break; 369 default: 370 EmitByte(0, OS); 371 break; 372 } 373 else { 374 EmitByte(0, OS); 375 } 376 377 378 // XXX: Emit bank swizzle. (1 byte) Do we need this? It looks like 379 // r600_asm.c sets it. 380 EmitByte(0, OS); 381 382 // XXX: Emit bank_swizzle_force (1 byte) Not sure what this is for. 383 EmitByte(0, OS); 384 385 // XXX: Emit OMOD (1 byte) Not implemented. 386 EmitByte(0, OS); 387 388 // XXX: Emit index_mode. I think this is for indirect addressing, so we 389 // don't need to worry about it. 390 EmitByte(0, OS); 391} 392 393void R600MCCodeEmitter::EmitTexInstr(const MCInst &MI, 394 SmallVectorImpl<MCFixup> &Fixups, 395 raw_ostream &OS) const { 396 397 unsigned opcode = MI.getOpcode(); 398 bool hasOffsets = (opcode == AMDGPU::TEX_LD); 399 unsigned op_offset = hasOffsets ? 3 : 0; 400 int64_t sampler = MI.getOperand(op_offset+2).getImm(); 401 int64_t textureType = MI.getOperand(op_offset+3).getImm(); 402 unsigned srcSelect[4] = {0, 1, 2, 3}; 403 404 // Emit instruction type 405 EmitByte(1, OS); 406 407 // Emit instruction 408 EmitByte(getBinaryCodeForInstr(MI, Fixups), OS); 409 410 // XXX: Emit resource id r600_shader.c uses sampler + 1. Why? 411 EmitByte(sampler + 1 + 1, OS); 412 413 // Emit source register 414 EmitByte(getHWReg(MI.getOperand(1).getReg()), OS); 415 416 // XXX: Emit src isRelativeAddress 417 EmitByte(0, OS); 418 419 // Emit destination register 420 EmitByte(getHWReg(MI.getOperand(0).getReg()), OS); 421 422 // XXX: Emit dst isRealtiveAddress 423 EmitByte(0, OS); 424 425 // XXX: Emit dst select 426 EmitByte(0, OS); // X 427 EmitByte(1, OS); // Y 428 EmitByte(2, OS); // Z 429 EmitByte(3, OS); // W 430 431 // XXX: Emit lod bias 432 EmitByte(0, OS); 433 434 // XXX: Emit coord types 435 unsigned coordType[4] = {1, 1, 1, 1}; 436 437 if (textureType == TEXTURE_RECT 438 || textureType == TEXTURE_SHADOWRECT) { 439 coordType[ELEMENT_X] = 0; 440 coordType[ELEMENT_Y] = 0; 441 } 442 443 if (textureType == TEXTURE_1D_ARRAY 444 || textureType == TEXTURE_SHADOW1D_ARRAY) { 445 if (opcode == AMDGPU::TEX_SAMPLE_C_L || opcode == AMDGPU::TEX_SAMPLE_C_LB) { 446 coordType[ELEMENT_Y] = 0; 447 } else { 448 coordType[ELEMENT_Z] = 0; 449 srcSelect[ELEMENT_Z] = ELEMENT_Y; 450 } 451 } else if (textureType == TEXTURE_2D_ARRAY 452 || textureType == TEXTURE_SHADOW2D_ARRAY) { 453 coordType[ELEMENT_Z] = 0; 454 } 455 456 for (unsigned i = 0; i < 4; i++) { 457 EmitByte(coordType[i], OS); 458 } 459 460 // XXX: Emit offsets 461 if (hasOffsets) 462 for (unsigned i = 2; i < 5; i++) 463 EmitByte(MI.getOperand(i).getImm()<<1, OS); 464 else 465 EmitNullBytes(3, OS); 466 467 // Emit sampler id 468 EmitByte(sampler, OS); 469 470 // XXX:Emit source select 471 if ((textureType == TEXTURE_SHADOW1D 472 || textureType == TEXTURE_SHADOW2D 473 || textureType == TEXTURE_SHADOWRECT 474 || textureType == TEXTURE_SHADOW1D_ARRAY) 475 && opcode != AMDGPU::TEX_SAMPLE_C_L 476 && opcode != AMDGPU::TEX_SAMPLE_C_LB) { 477 srcSelect[ELEMENT_W] = ELEMENT_Z; 478 } 479 480 for (unsigned i = 0; i < 4; i++) { 481 EmitByte(srcSelect[i], OS); 482 } 483} 484 485void R600MCCodeEmitter::EmitFCInstr(const MCInst &MI, raw_ostream &OS) const { 486 487 // Emit instruction type 488 EmitByte(INSTR_FC, OS); 489 490 // Emit SRC 491 unsigned NumOperands = MI.getNumOperands(); 492 if (NumOperands > 0) { 493 assert(NumOperands == 1); 494 EmitSrc(MI, 0, OS); 495 } else { 496 EmitNullBytes(SRC_BYTE_COUNT, OS); 497 } 498 499 // Emit FC Instruction 500 enum FCInstr instr; 501 switch (MI.getOpcode()) { 502 case AMDGPU::BREAK_LOGICALZ_f32: 503 instr = FC_BREAK; 504 break; 505 case AMDGPU::BREAK_LOGICALNZ_f32: 506 instr = FC_BREAK_NZ; 507 break; 508 case AMDGPU::BREAK_LOGICALNZ_i32: 509 instr = FC_BREAK_NZ_INT; 510 break; 511 case AMDGPU::BREAK_LOGICALZ_i32: 512 instr = FC_BREAK_Z_INT; 513 break; 514 case AMDGPU::CONTINUE_LOGICALNZ_f32: 515 case AMDGPU::CONTINUE_LOGICALNZ_i32: 516 instr = FC_CONTINUE; 517 break; 518 case AMDGPU::IF_LOGICALNZ_f32: 519 instr = FC_IF; 520 case AMDGPU::IF_LOGICALNZ_i32: 521 instr = FC_IF_INT; 522 break; 523 case AMDGPU::IF_LOGICALZ_f32: 524 abort(); 525 break; 526 case AMDGPU::ELSE: 527 instr = FC_ELSE; 528 break; 529 case AMDGPU::ENDIF: 530 instr = FC_ENDIF; 531 break; 532 case AMDGPU::ENDLOOP: 533 instr = FC_ENDLOOP; 534 break; 535 case AMDGPU::WHILELOOP: 536 instr = FC_BGNLOOP; 537 break; 538 default: 539 abort(); 540 break; 541 } 542 EmitByte(instr, OS); 543} 544 545void R600MCCodeEmitter::EmitNullBytes(unsigned int ByteCount, 546 raw_ostream &OS) const { 547 548 for (unsigned int i = 0; i < ByteCount; i++) { 549 EmitByte(0, OS); 550 } 551} 552 553void R600MCCodeEmitter::EmitByte(unsigned int Byte, raw_ostream &OS) const { 554 OS.write((uint8_t) Byte & 0xff); 555} 556 557void R600MCCodeEmitter::EmitTwoBytes(unsigned int Bytes, 558 raw_ostream &OS) const { 559 OS.write((uint8_t) (Bytes & 0xff)); 560 OS.write((uint8_t) ((Bytes >> 8) & 0xff)); 561} 562 563void R600MCCodeEmitter::Emit(uint32_t Value, raw_ostream &OS) const { 564 for (unsigned i = 0; i < 4; i++) { 565 OS.write((uint8_t) ((Value >> (8 * i)) & 0xff)); 566 } 567} 568 569void R600MCCodeEmitter::Emit(uint64_t Value, raw_ostream &OS) const { 570 for (unsigned i = 0; i < 8; i++) { 571 EmitByte((Value >> (8 * i)) & 0xff, OS); 572 } 573} 574 575unsigned R600MCCodeEmitter::getHWRegIndex(unsigned reg) const { 576 switch(reg) { 577 case AMDGPU::ZERO: return 248; 578 case AMDGPU::ONE: 579 case AMDGPU::NEG_ONE: return 249; 580 case AMDGPU::ONE_INT: return 250; 581 case AMDGPU::HALF: 582 case AMDGPU::NEG_HALF: return 252; 583 case AMDGPU::ALU_LITERAL_X: return 253; 584 case AMDGPU::PREDICATE_BIT: 585 case AMDGPU::PRED_SEL_OFF: 586 case AMDGPU::PRED_SEL_ZERO: 587 case AMDGPU::PRED_SEL_ONE: 588 return 0; 589 default: return getHWRegIndexGen(reg); 590 } 591} 592 593unsigned R600MCCodeEmitter::getHWRegChan(unsigned reg) const { 594 switch(reg) { 595 case AMDGPU::ZERO: 596 case AMDGPU::ONE: 597 case AMDGPU::ONE_INT: 598 case AMDGPU::NEG_ONE: 599 case AMDGPU::HALF: 600 case AMDGPU::NEG_HALF: 601 case AMDGPU::ALU_LITERAL_X: 602 case AMDGPU::PREDICATE_BIT: 603 case AMDGPU::PRED_SEL_OFF: 604 case AMDGPU::PRED_SEL_ZERO: 605 case AMDGPU::PRED_SEL_ONE: 606 return 0; 607 default: return getHWRegChanGen(reg); 608 } 609} 610unsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const { 611 unsigned HWReg; 612 613 HWReg = getHWRegIndex(RegNo); 614 if (AMDGPUMCRegisterClasses[AMDGPU::R600_CReg32RegClassID].contains(RegNo)) { 615 HWReg += 512; 616 } 617 return HWReg; 618} 619 620uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI, 621 const MCOperand &MO, 622 SmallVectorImpl<MCFixup> &Fixup) const { 623 if (MO.isReg()) { 624 return getHWReg(MO.getReg()); 625 } else { 626 return MO.getImm(); 627 } 628} 629 630//===----------------------------------------------------------------------===// 631// Encoding helper functions 632//===----------------------------------------------------------------------===// 633 634bool R600MCCodeEmitter::isFCOp(unsigned opcode) const { 635 switch(opcode) { 636 default: return false; 637 case AMDGPU::BREAK_LOGICALZ_f32: 638 case AMDGPU::BREAK_LOGICALNZ_i32: 639 case AMDGPU::BREAK_LOGICALZ_i32: 640 case AMDGPU::BREAK_LOGICALNZ_f32: 641 case AMDGPU::CONTINUE_LOGICALNZ_f32: 642 case AMDGPU::IF_LOGICALNZ_i32: 643 case AMDGPU::IF_LOGICALZ_f32: 644 case AMDGPU::ELSE: 645 case AMDGPU::ENDIF: 646 case AMDGPU::ENDLOOP: 647 case AMDGPU::IF_LOGICALNZ_f32: 648 case AMDGPU::WHILELOOP: 649 return true; 650 } 651} 652 653bool R600MCCodeEmitter::isTexOp(unsigned opcode) const { 654 switch(opcode) { 655 default: return false; 656 case AMDGPU::TEX_LD: 657 case AMDGPU::TEX_GET_TEXTURE_RESINFO: 658 case AMDGPU::TEX_SAMPLE: 659 case AMDGPU::TEX_SAMPLE_C: 660 case AMDGPU::TEX_SAMPLE_L: 661 case AMDGPU::TEX_SAMPLE_C_L: 662 case AMDGPU::TEX_SAMPLE_LB: 663 case AMDGPU::TEX_SAMPLE_C_LB: 664 case AMDGPU::TEX_SAMPLE_G: 665 case AMDGPU::TEX_SAMPLE_C_G: 666 case AMDGPU::TEX_GET_GRADIENTS_H: 667 case AMDGPU::TEX_GET_GRADIENTS_V: 668 case AMDGPU::TEX_SET_GRADIENTS_H: 669 case AMDGPU::TEX_SET_GRADIENTS_V: 670 return true; 671 } 672} 673 674bool R600MCCodeEmitter::isFlagSet(const MCInst &MI, unsigned Operand, 675 unsigned Flag) const { 676 const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode()); 677 unsigned FlagIndex = GET_FLAG_OPERAND_IDX(MCDesc.TSFlags); 678 if (FlagIndex == 0) { 679 return false; 680 } 681 assert(MI.getOperand(FlagIndex).isImm()); 682 return !!((MI.getOperand(FlagIndex).getImm() >> 683 (NUM_MO_FLAGS * Operand)) & Flag); 684} 685#define R600RegisterInfo R600MCCodeEmitter 686#include "R600HwRegInfo.include" 687#undef R600RegisterInfo 688 689#include "AMDGPUGenMCCodeEmitter.inc" 690