R600MCCodeEmitter.cpp revision 90bd1d52bbf95947955a66ec67f5f6c7dc87119a
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/AMDILMCTargetDesc.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/* 153 if (MI.getNumOperands() > 1 && MI.getOperand(0).isReg() && 154 MI.getOperand(0).isDead()) { 155 return; 156 } 157*/ 158 if (isTexOp(MI.getOpcode())) { 159 EmitTexInstr(MI, Fixups, OS); 160 } else if (isFCOp(MI.getOpcode())){ 161 EmitFCInstr(MI, OS); 162 } else if (MI.getOpcode() == AMDGPU::RETURN || 163 MI.getOpcode() == AMDGPU::BUNDLE || 164 MI.getOpcode() == AMDGPU::KILL) { 165 return; 166 } else { 167 switch(MI.getOpcode()) { 168 case AMDGPU::RAT_WRITE_CACHELESS_eg: 169 { 170 uint64_t inst = getBinaryCodeForInstr(MI, Fixups); 171 // XXX: Set End Of Program bit when necessary 172 // inst |= (((uint64_t)1) << 53); 173 EmitByte(INSTR_NATIVE, OS); 174 Emit(inst, OS); 175 break; 176 } 177 case AMDGPU::VTX_READ_PARAM_i32_eg: 178 case AMDGPU::VTX_READ_PARAM_f32_eg: 179 case AMDGPU::VTX_READ_GLOBAL_i32_eg: 180 case AMDGPU::VTX_READ_GLOBAL_f32_eg: 181 case AMDGPU::VTX_READ_GLOBAL_v4i32_eg: 182 case AMDGPU::VTX_READ_GLOBAL_v4f32_eg: 183 { 184 uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups); 185 uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset 186 187 EmitByte(INSTR_VTX, OS); 188 Emit(InstWord01, OS); 189 Emit(InstWord2, OS); 190 break; 191 } 192 193 default: 194 EmitALUInstr(MI, Fixups, OS); 195 break; 196 } 197 } 198} 199 200void R600MCCodeEmitter::EmitALUInstr(const MCInst &MI, 201 SmallVectorImpl<MCFixup> &Fixups, 202 raw_ostream &OS) const { 203 const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode()); 204 unsigned NumOperands = MI.getNumOperands(); 205 206 if(MCDesc.findFirstPredOperandIdx() > -1) 207 NumOperands--; 208 209 if (GET_FLAG_OPERAND_IDX(MCDesc.TSFlags) != 0) 210 NumOperands--; 211 212 // Some instructions are just place holder instructions that represent 213 // operations that the GPU does automatically. They should be ignored. 214// if (TII->isPlaceHolderOpcode(MI.getOpcode())) { 215// return; 216// } 217 218 if(MI.getOpcode() == AMDGPU::PRED_X) 219 NumOperands = 2; 220 221 // XXX Check if instruction writes a result 222 if (NumOperands < 1) { 223 return; 224 } 225 226 // Emit instruction type 227 EmitByte(0, OS); 228 229 unsigned int OpIndex; 230 for (OpIndex = 1; OpIndex < NumOperands; OpIndex++) { 231 // Literal constants are always stored as the last operand. 232 if (MI.getOperand(OpIndex).isImm() || MI.getOperand(OpIndex).isFPImm()) { 233 break; 234 } 235 EmitSrc(MI, OpIndex, OS); 236 } 237 238 // Emit zeros for unused sources 239 for ( ; OpIndex < 4; OpIndex++) { 240 EmitNullBytes(SRC_BYTE_COUNT, OS); 241 } 242 243 EmitDst(MI, OS); 244 245 EmitALU(MI, NumOperands - 1, Fixups, OS); 246} 247 248void R600MCCodeEmitter::EmitSrc(const MCInst &MI, unsigned OpIdx, 249 raw_ostream &OS) const { 250 const MCOperand &MO = MI.getOperand(OpIdx); 251 union { 252 float f; 253 uint32_t i; 254 } Value; 255 Value.i = 0; 256 // Emit the source select (2 bytes). For GPRs, this is the register index. 257 // For other potential instruction operands, (e.g. constant registers) the 258 // value of the source select is defined in the r600isa docs. 259 if (MO.isReg()) { 260 unsigned reg = MO.getReg(); 261 EmitTwoBytes(getHWReg(reg), OS); 262 if (reg == AMDGPU::ALU_LITERAL_X) { 263 unsigned ImmOpIndex = MI.getNumOperands() - 1; 264 MCOperand ImmOp = MI.getOperand(ImmOpIndex); 265 if (ImmOp.isFPImm()) { 266 Value.f = ImmOp.getFPImm(); 267 } else { 268 assert(ImmOp.isImm()); 269 Value.i = ImmOp.getImm(); 270 } 271 } 272 } else { 273 // XXX: Handle other operand types. 274 EmitTwoBytes(0, OS); 275 } 276 277 // Emit the source channel (1 byte) 278 if (MO.isReg()) { 279 EmitByte(getHWRegChan(MO.getReg()), OS); 280 } else { 281 EmitByte(0, OS); 282 } 283 284 // XXX: Emit isNegated (1 byte) 285 if ((!(isFlagSet(MI, OpIdx, MO_FLAG_ABS))) 286 && (isFlagSet(MI, OpIdx, MO_FLAG_NEG) || 287 (MO.isReg() && 288 (MO.getReg() == AMDGPU::NEG_ONE || MO.getReg() == AMDGPU::NEG_HALF)))){ 289 EmitByte(1, OS); 290 } else { 291 EmitByte(0, OS); 292 } 293 294 // Emit isAbsolute (1 byte) 295 if (isFlagSet(MI, OpIdx, MO_FLAG_ABS)) { 296 EmitByte(1, OS); 297 } else { 298 EmitByte(0, OS); 299 } 300 301 // XXX: Emit relative addressing mode (1 byte) 302 EmitByte(0, OS); 303 304 // Emit kc_bank, This will be adjusted later by r600_asm 305 EmitByte(0, OS); 306 307 // Emit the literal value, if applicable (4 bytes). 308 Emit(Value.i, OS); 309 310} 311 312void R600MCCodeEmitter::EmitDst(const MCInst &MI, raw_ostream &OS) const { 313 314 const MCOperand &MO = MI.getOperand(0); 315 if (MO.isReg() && MO.getReg() != AMDGPU::PREDICATE_BIT) { 316 // Emit the destination register index (1 byte) 317 EmitByte(getHWReg(MO.getReg()), OS); 318 319 // Emit the element of the destination register (1 byte) 320 EmitByte(getHWRegChan(MO.getReg()), OS); 321 322 // Emit isClamped (1 byte) 323 if (isFlagSet(MI, 0, MO_FLAG_CLAMP)) { 324 EmitByte(1, OS); 325 } else { 326 EmitByte(0, OS); 327 } 328 329 // Emit writemask (1 byte). 330 if (isFlagSet(MI, 0, MO_FLAG_MASK)) { 331 EmitByte(0, OS); 332 } else { 333 EmitByte(1, OS); 334 } 335 336 // XXX: Emit relative addressing mode 337 EmitByte(0, OS); 338 } else { 339 // XXX: Handle other operand types. Are there any for destination regs? 340 EmitNullBytes(DST_BYTE_COUNT, OS); 341 } 342} 343 344void R600MCCodeEmitter::EmitALU(const MCInst &MI, unsigned numSrc, 345 SmallVectorImpl<MCFixup> &Fixups, 346 raw_ostream &OS) const { 347 const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode()); 348 349 // Emit the instruction (2 bytes) 350 EmitTwoBytes(getBinaryCodeForInstr(MI, Fixups), OS); 351 352 // Emit IsLast (for this instruction group) (1 byte) 353 if (isFlagSet(MI, 0, MO_FLAG_NOT_LAST)) { 354 EmitByte(0, OS); 355 } else { 356 EmitByte(1, OS); 357 } 358 359 // Emit isOp3 (1 byte) 360 if (numSrc == 3) { 361 EmitByte(1, OS); 362 } else { 363 EmitByte(0, OS); 364 } 365 366 // XXX: Emit push modifier 367 if(isFlagSet(MI, 1, MO_FLAG_PUSH)) { 368 EmitByte(1, OS); 369 } else { 370 EmitByte(0, OS); 371 } 372 373 // XXX: Emit predicate (1 byte) 374 int PredIdx = MCDesc.findFirstPredOperandIdx(); 375 if (PredIdx > -1) 376 switch(MI.getOperand(PredIdx).getReg()) { 377 case AMDGPU::PRED_SEL_ZERO: 378 EmitByte(2, OS); 379 break; 380 case AMDGPU::PRED_SEL_ONE: 381 EmitByte(3, OS); 382 break; 383 default: 384 EmitByte(0, OS); 385 break; 386 } 387 else { 388 EmitByte(0, OS); 389 } 390 391 392 // XXX: Emit bank swizzle. (1 byte) Do we need this? It looks like 393 // r600_asm.c sets it. 394 EmitByte(0, OS); 395 396 // XXX: Emit bank_swizzle_force (1 byte) Not sure what this is for. 397 EmitByte(0, OS); 398 399 // XXX: Emit OMOD (1 byte) Not implemented. 400 EmitByte(0, OS); 401 402 // XXX: Emit index_mode. I think this is for indirect addressing, so we 403 // don't need to worry about it. 404 EmitByte(0, OS); 405} 406 407void R600MCCodeEmitter::EmitTexInstr(const MCInst &MI, 408 SmallVectorImpl<MCFixup> &Fixups, 409 raw_ostream &OS) const { 410 411 unsigned opcode = MI.getOpcode(); 412 bool hasOffsets = (opcode == AMDGPU::TEX_LD); 413 unsigned op_offset = hasOffsets ? 3 : 0; 414 int64_t sampler = MI.getOperand(op_offset+2).getImm(); 415 int64_t textureType = MI.getOperand(op_offset+3).getImm(); 416 unsigned srcSelect[4] = {0, 1, 2, 3}; 417 418 // Emit instruction type 419 EmitByte(1, OS); 420 421 // Emit instruction 422 EmitByte(getBinaryCodeForInstr(MI, Fixups), OS); 423 424 // XXX: Emit resource id r600_shader.c uses sampler + 1. Why? 425 EmitByte(sampler + 1 + 1, OS); 426 427 // Emit source register 428 EmitByte(getHWReg(MI.getOperand(1).getReg()), OS); 429 430 // XXX: Emit src isRelativeAddress 431 EmitByte(0, OS); 432 433 // Emit destination register 434 EmitByte(getHWReg(MI.getOperand(0).getReg()), OS); 435 436 // XXX: Emit dst isRealtiveAddress 437 EmitByte(0, OS); 438 439 // XXX: Emit dst select 440 EmitByte(0, OS); // X 441 EmitByte(1, OS); // Y 442 EmitByte(2, OS); // Z 443 EmitByte(3, OS); // W 444 445 // XXX: Emit lod bias 446 EmitByte(0, OS); 447 448 // XXX: Emit coord types 449 unsigned coordType[4] = {1, 1, 1, 1}; 450 451 if (textureType == TEXTURE_RECT 452 || textureType == TEXTURE_SHADOWRECT) { 453 coordType[ELEMENT_X] = 0; 454 coordType[ELEMENT_Y] = 0; 455 } 456 457 if (textureType == TEXTURE_1D_ARRAY 458 || textureType == TEXTURE_SHADOW1D_ARRAY) { 459 if (opcode == AMDGPU::TEX_SAMPLE_C_L || opcode == AMDGPU::TEX_SAMPLE_C_LB) { 460 coordType[ELEMENT_Y] = 0; 461 } else { 462 coordType[ELEMENT_Z] = 0; 463 srcSelect[ELEMENT_Z] = ELEMENT_Y; 464 } 465 } else if (textureType == TEXTURE_2D_ARRAY 466 || textureType == TEXTURE_SHADOW2D_ARRAY) { 467 coordType[ELEMENT_Z] = 0; 468 } 469 470 for (unsigned i = 0; i < 4; i++) { 471 EmitByte(coordType[i], OS); 472 } 473 474 // XXX: Emit offsets 475 if (hasOffsets) 476 for (unsigned i = 2; i < 5; i++) 477 EmitByte(MI.getOperand(i).getImm()<<1, OS); 478 else 479 EmitNullBytes(3, OS); 480 481 // Emit sampler id 482 EmitByte(sampler, OS); 483 484 // XXX:Emit source select 485 if ((textureType == TEXTURE_SHADOW1D 486 || textureType == TEXTURE_SHADOW2D 487 || textureType == TEXTURE_SHADOWRECT 488 || textureType == TEXTURE_SHADOW1D_ARRAY) 489 && opcode != AMDGPU::TEX_SAMPLE_C_L 490 && opcode != AMDGPU::TEX_SAMPLE_C_LB) { 491 srcSelect[ELEMENT_W] = ELEMENT_Z; 492 } 493 494 for (unsigned i = 0; i < 4; i++) { 495 EmitByte(srcSelect[i], OS); 496 } 497} 498 499void R600MCCodeEmitter::EmitFCInstr(const MCInst &MI, raw_ostream &OS) const { 500 501 // Emit instruction type 502 EmitByte(INSTR_FC, OS); 503 504 // Emit SRC 505 unsigned NumOperands = MI.getNumOperands(); 506 if (NumOperands > 0) { 507 assert(NumOperands == 1); 508 EmitSrc(MI, 0, OS); 509 } else { 510 EmitNullBytes(SRC_BYTE_COUNT, OS); 511 } 512 513 // Emit FC Instruction 514 enum FCInstr instr; 515 switch (MI.getOpcode()) { 516 case AMDGPU::BREAK_LOGICALZ_f32: 517 instr = FC_BREAK; 518 break; 519 case AMDGPU::BREAK_LOGICALNZ_f32: 520 instr = FC_BREAK_NZ; 521 break; 522 case AMDGPU::BREAK_LOGICALNZ_i32: 523 instr = FC_BREAK_NZ_INT; 524 break; 525 case AMDGPU::BREAK_LOGICALZ_i32: 526 instr = FC_BREAK_Z_INT; 527 break; 528 case AMDGPU::CONTINUE_LOGICALNZ_f32: 529 case AMDGPU::CONTINUE_LOGICALNZ_i32: 530 instr = FC_CONTINUE; 531 break; 532 case AMDGPU::IF_LOGICALNZ_f32: 533 instr = FC_IF; 534 case AMDGPU::IF_LOGICALNZ_i32: 535 instr = FC_IF_INT; 536 break; 537 case AMDGPU::IF_LOGICALZ_f32: 538 abort(); 539 break; 540 case AMDGPU::ELSE: 541 instr = FC_ELSE; 542 break; 543 case AMDGPU::ENDIF: 544 instr = FC_ENDIF; 545 break; 546 case AMDGPU::ENDLOOP: 547 instr = FC_ENDLOOP; 548 break; 549 case AMDGPU::WHILELOOP: 550 instr = FC_BGNLOOP; 551 break; 552 default: 553 abort(); 554 break; 555 } 556 EmitByte(instr, OS); 557} 558 559void R600MCCodeEmitter::EmitNullBytes(unsigned int ByteCount, 560 raw_ostream &OS) const { 561 562 for (unsigned int i = 0; i < ByteCount; i++) { 563 EmitByte(0, OS); 564 } 565} 566 567void R600MCCodeEmitter::EmitByte(unsigned int Byte, raw_ostream &OS) const { 568 OS.write((uint8_t) Byte & 0xff); 569} 570 571void R600MCCodeEmitter::EmitTwoBytes(unsigned int Bytes, 572 raw_ostream &OS) const { 573 OS.write((uint8_t) (Bytes & 0xff)); 574 OS.write((uint8_t) ((Bytes >> 8) & 0xff)); 575} 576 577void R600MCCodeEmitter::Emit(uint32_t Value, raw_ostream &OS) const { 578 for (unsigned i = 0; i < 4; i++) { 579 OS.write((uint8_t) ((Value >> (8 * i)) & 0xff)); 580 } 581} 582 583void R600MCCodeEmitter::Emit(uint64_t Value, raw_ostream &OS) const { 584 for (unsigned i = 0; i < 8; i++) { 585 EmitByte((Value >> (8 * i)) & 0xff, OS); 586 } 587} 588 589unsigned R600MCCodeEmitter::getHWRegIndex(unsigned reg) const { 590 switch(reg) { 591 case AMDGPU::ZERO: return 248; 592 case AMDGPU::ONE: 593 case AMDGPU::NEG_ONE: return 249; 594 case AMDGPU::ONE_INT: return 250; 595 case AMDGPU::HALF: 596 case AMDGPU::NEG_HALF: return 252; 597 case AMDGPU::ALU_LITERAL_X: return 253; 598 case AMDGPU::PREDICATE_BIT: 599 case AMDGPU::PRED_SEL_OFF: 600 case AMDGPU::PRED_SEL_ZERO: 601 case AMDGPU::PRED_SEL_ONE: 602 return 0; 603 default: return getHWRegIndexGen(reg); 604 } 605} 606 607unsigned R600MCCodeEmitter::getHWRegChan(unsigned reg) const { 608 switch(reg) { 609 case AMDGPU::ZERO: 610 case AMDGPU::ONE: 611 case AMDGPU::ONE_INT: 612 case AMDGPU::NEG_ONE: 613 case AMDGPU::HALF: 614 case AMDGPU::NEG_HALF: 615 case AMDGPU::ALU_LITERAL_X: 616 case AMDGPU::PREDICATE_BIT: 617 case AMDGPU::PRED_SEL_OFF: 618 case AMDGPU::PRED_SEL_ZERO: 619 case AMDGPU::PRED_SEL_ONE: 620 return 0; 621 default: return getHWRegChanGen(reg); 622 } 623} 624unsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const { 625 unsigned HWReg; 626 627 HWReg = getHWRegIndex(RegNo); 628 if (AMDGPUMCRegisterClasses[AMDGPU::R600_CReg32RegClassID].contains(RegNo)) { 629 HWReg += 512; 630 } 631 return HWReg; 632} 633 634uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI, 635 const MCOperand &MO, 636 SmallVectorImpl<MCFixup> &Fixup) const { 637 if (MO.isReg()) { 638 return getHWReg(MO.getReg()); 639 } else { 640 return MO.getImm(); 641 } 642} 643 644//===----------------------------------------------------------------------===// 645// Encoding helper functions 646//===----------------------------------------------------------------------===// 647 648bool R600MCCodeEmitter::isFCOp(unsigned opcode) const { 649 switch(opcode) { 650 default: return false; 651 case AMDGPU::BREAK_LOGICALZ_f32: 652 case AMDGPU::BREAK_LOGICALNZ_i32: 653 case AMDGPU::BREAK_LOGICALZ_i32: 654 case AMDGPU::BREAK_LOGICALNZ_f32: 655 case AMDGPU::CONTINUE_LOGICALNZ_f32: 656 case AMDGPU::IF_LOGICALNZ_i32: 657 case AMDGPU::IF_LOGICALZ_f32: 658 case AMDGPU::ELSE: 659 case AMDGPU::ENDIF: 660 case AMDGPU::ENDLOOP: 661 case AMDGPU::IF_LOGICALNZ_f32: 662 case AMDGPU::WHILELOOP: 663 return true; 664 } 665} 666 667bool R600MCCodeEmitter::isTexOp(unsigned opcode) const { 668 switch(opcode) { 669 default: return false; 670 case AMDGPU::TEX_LD: 671 case AMDGPU::TEX_GET_TEXTURE_RESINFO: 672 case AMDGPU::TEX_SAMPLE: 673 case AMDGPU::TEX_SAMPLE_C: 674 case AMDGPU::TEX_SAMPLE_L: 675 case AMDGPU::TEX_SAMPLE_C_L: 676 case AMDGPU::TEX_SAMPLE_LB: 677 case AMDGPU::TEX_SAMPLE_C_LB: 678 case AMDGPU::TEX_SAMPLE_G: 679 case AMDGPU::TEX_SAMPLE_C_G: 680 case AMDGPU::TEX_GET_GRADIENTS_H: 681 case AMDGPU::TEX_GET_GRADIENTS_V: 682 case AMDGPU::TEX_SET_GRADIENTS_H: 683 case AMDGPU::TEX_SET_GRADIENTS_V: 684 return true; 685 } 686} 687 688bool R600MCCodeEmitter::isFlagSet(const MCInst &MI, unsigned Operand, 689 unsigned Flag) const { 690 const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode()); 691 unsigned FlagIndex = GET_FLAG_OPERAND_IDX(MCDesc.TSFlags); 692 if (FlagIndex == 0) { 693 return false; 694 } 695 assert(MI.getOperand(FlagIndex).isImm()); 696 return !!((MI.getOperand(FlagIndex).getImm() >> 697 (NUM_MO_FLAGS * Operand)) & Flag); 698} 699#define R600RegisterInfo R600MCCodeEmitter 700#include "R600HwRegInfo.include" 701#undef R600RegisterInfo 702 703#include "AMDGPUGenMCCodeEmitter.inc" 704