void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, const MCSubtargetInfo &STI) { // If verbose assembly is enabled, we can print some informative comments. if (CommentStream) HasCustomInstComment = EmitAnyX86InstComments(MI, *CommentStream, MII); printInstFlags(MI, OS); // Output CALLpcrel32 as "callq" in 64-bit mode. // In Intel annotation it's always emitted as "call". // // TODO: Probably this hack should be redesigned via InstAlias in // InstrInfo.td as soon as Requires clause is supported properly // for InstAlias. if (MI->getOpcode() == X86::CALLpcrel32 && (STI.getFeatureBits()[X86::Mode64Bit])) { OS << "\tcallq\t"; printPCRelImm(MI, 0, OS); } // data16 and data32 both have the same encoding of 0x66. While data32 is // valid only in 16 bit systems, data16 is valid in the rest. // There seems to be some lack of support of the Requires clause that causes // 0x66 to be interpreted as "data16" by the asm printer. // Thus we add an adjustment here in order to print the "right" instruction. else if (MI->getOpcode() == X86::DATA16_PREFIX && STI.getFeatureBits()[X86::Mode16Bit]) { OS << "\tdata32"; } // Try to print any aliases first. else if (!printAliasInstr(MI, OS)) printInstruction(MI, OS); // Next always print the annotation. printAnnotation(OS, Annot); }
void R600MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { verifyInstructionPredicates(MI, computeAvailableFeatures(STI.getFeatureBits())); const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); if (MI.getOpcode() == R600::RETURN || MI.getOpcode() == R600::FETCH_CLAUSE || MI.getOpcode() == R600::ALU_CLAUSE || MI.getOpcode() == R600::BUNDLE || MI.getOpcode() == R600::KILL) { return; } else if (IS_VTX(Desc)) { uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups, STI); uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset if (!(STI.getFeatureBits()[R600::FeatureCaymanISA])) { InstWord2 |= 1 << 19; // Mega-Fetch bit } Emit(InstWord01, OS); Emit(InstWord2, OS); Emit((uint32_t) 0, OS); } else if (IS_TEX(Desc)) { int64_t Sampler = MI.getOperand(14).getImm(); int64_t SrcSelect[4] = { MI.getOperand(2).getImm(), MI.getOperand(3).getImm(), MI.getOperand(4).getImm(), MI.getOperand(5).getImm() }; int64_t Offsets[3] = { MI.getOperand(6).getImm() & 0x1F, MI.getOperand(7).getImm() & 0x1F, MI.getOperand(8).getImm() & 0x1F }; uint64_t Word01 = getBinaryCodeForInstr(MI, Fixups, STI); uint32_t Word2 = Sampler << 15 | SrcSelect[ELEMENT_X] << 20 | SrcSelect[ELEMENT_Y] << 23 | SrcSelect[ELEMENT_Z] << 26 | SrcSelect[ELEMENT_W] << 29 | Offsets[0] << 0 | Offsets[1] << 5 | Offsets[2] << 10; Emit(Word01, OS); Emit(Word2, OS); Emit((uint32_t) 0, OS); } else { uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, STI); if ((STI.getFeatureBits()[R600::FeatureR600ALUInst]) && ((Desc.TSFlags & R600_InstFlag::OP1) || Desc.TSFlags & R600_InstFlag::OP2)) { uint64_t ISAOpCode = Inst & (0x3FFULL << 39); Inst &= ~(0x3FFULL << 39); Inst |= ISAOpCode << 1; } Emit(Inst, OS); } }
void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { verifyInstructionPredicates(MI, computeAvailableFeatures(STI.getFeatureBits())); unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); if (Ctx.getAsmInfo()->isLittleEndian()) { // Output the bits in little-endian byte order. support::endian::Writer<support::little>(OS).write<uint32_t>(Bits); } else { // Output the bits in big-endian byte order. support::endian::Writer<support::big>(OS).write<uint32_t>(Bits); } unsigned tlsOpNo = 0; switch (MI.getOpcode()) { default: break; case SP::TLS_CALL: tlsOpNo = 1; break; case SP::TLS_ADDrr: case SP::TLS_ADDXrr: case SP::TLS_LDrr: case SP::TLS_LDXrr: tlsOpNo = 3; break; } if (tlsOpNo != 0) { const MCOperand &MO = MI.getOperand(tlsOpNo); uint64_t op = getMachineOpValue(MI, MO, Fixups, STI); assert(op == 0 && "Unexpected operand value!"); (void)op; // suppress warning. } ++MCNumEmitted; // Keep track of the # of mi's emitted. }
static bool getARMLoadDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string &Info) { assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] && "cannot predicate thumb instructions"); assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments"); bool ListContainsPC = false, ListContainsLR = false; for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) { assert(MI.getOperand(OI).isReg() && "expected register"); switch (MI.getOperand(OI).getReg()) { default: break; case ARM::LR: ListContainsLR = true; break; case ARM::PC: ListContainsPC = true; break; case ARM::SP: Info = "use of SP in the list is deprecated"; return true; } } if (ListContainsPC && ListContainsLR) { Info = "use of LR and PC simultaneously in the list is deprecated"; return true; } return false; }
void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, const MCSubtargetInfo &STI) { const MCInstrDesc &Desc = MII.get(MI->getOpcode()); uint64_t TSFlags = Desc.TSFlags; // If verbose assembly is enabled, we can print some informative comments. if (CommentStream) HasCustomInstComment = EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); if (TSFlags & X86II::LOCK) OS << "\tlock\t"; // Output CALLpcrel32 as "callq" in 64-bit mode. // In Intel annotation it's always emitted as "call". // // TODO: Probably this hack should be redesigned via InstAlias in // InstrInfo.td as soon as Requires clause is supported properly // for InstAlias. if (MI->getOpcode() == X86::CALLpcrel32 && (STI.getFeatureBits()[X86::Mode64Bit])) { OS << "\tcallq\t"; printPCRelImm(MI, 0, OS); } // Try to print any aliases first. else if (!printAliasInstr(MI, OS)) printInstruction(MI, OS); // Next always print the annotation. printAnnotation(OS, Annot); }
static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string &Info) { if (STI.getFeatureBits() & llvm::ARM::HasV7Ops && (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) && (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) && // Checks for the deprecated CP15ISB encoding: // mcr p15, #0, rX, c7, c5, #4 (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) { if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) { if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) { Info = "deprecated since v7, use 'isb'"; return true; } // Checks for the deprecated CP15DSB encoding: // mcr p15, #0, rX, c7, c10, #4 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) { Info = "deprecated since v7, use 'dsb'"; return true; } } // Checks for the deprecated CP15DMB encoding: // mcr p15, #0, rX, c7, c10, #5 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 && (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) { Info = "deprecated since v7, use 'dmb'"; return true; } } return false; }
PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI) : MCInstPrinter(MAI, MRI) { // Initialize the set of available features. setAvailableFeatures(STI.getFeatureBits()); }
static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string &Info) { if (STI.getFeatureBits() & llvm::ARM::HasV8Ops && MI.getOperand(1).isImm() && MI.getOperand(1).getImm() != 8) { Info = "applying IT instruction to more than one subsequent instruction is deprecated"; return true; } return false; }
bool MCInstrDesc::getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI, std::string &Info) const { if (ComplexDeprecationInfo) return ComplexDeprecationInfo(MI, STI, Info); if (DeprecatedFeature != -1 && STI.getFeatureBits()[DeprecatedFeature]) { // FIXME: it would be nice to include the subtarget feature here. Info = "deprecated"; return true; } return false; }
unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const { bool HasThumb2 = STI.getFeatureBits()[ARM::FeatureThumb2]; bool HasV8MBaselineOps = STI.getFeatureBits()[ARM::HasV8MBaselineOps]; switch (Op) { default: return Op; case ARM::tBcc: return HasThumb2 ? (unsigned)ARM::t2Bcc : Op; case ARM::tLDRpci: return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op; case ARM::tADR: return HasThumb2 ? (unsigned)ARM::t2ADR : Op; case ARM::tB: return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op; case ARM::tCBZ: return ARM::tHINT; case ARM::tCBNZ: return ARM::tHINT; } }
static bool getARMStoreDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string &Info) { assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] && "cannot predicate thumb instructions"); assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments"); for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) { assert(MI.getOperand(OI).isReg() && "expected register"); if (MI.getOperand(OI).getReg() == ARM::SP || MI.getOperand(OI).getReg() == ARM::PC) { Info = "use of SP or PC in the list is deprecated"; return true; } } return false; }
void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { verifyInstructionPredicates(MI, computeAvailableFeatures(STI.getFeatureBits())); if (MI.getOpcode() == AArch64::TLSDESCCALL) { // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the // following (BLR) instruction. It doesn't emit any code itself so it // doesn't go through the normal TableGenerated channels. MCFixupKind Fixup = MCFixupKind(AArch64::fixup_aarch64_tlsdesc_call); Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), Fixup)); return; } uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); support::endian::Writer<support::little>(OS).write<uint32_t>(Binary); ++MCNumEmitted; // Keep track of the # of mi's emitted. }
// Expand PseudoAddTPRel to a simple ADD with the correct relocation. void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { MCOperand DestReg = MI.getOperand(0); MCOperand SrcReg = MI.getOperand(1); MCOperand TPReg = MI.getOperand(2); assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 && "Expected thread pointer as second input to TP-relative add"); MCOperand SrcSymbol = MI.getOperand(3); assert(SrcSymbol.isExpr() && "Expected expression as third input to TP-relative add"); const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr()); assert(Expr && Expr->getKind() == RISCVMCExpr::VK_RISCV_TPREL_ADD && "Expected tprel_add relocation on TP-relative symbol"); // Emit the correct tprel_add relocation for the symbol. Fixups.push_back(MCFixup::create( 0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc())); // Emit fixup_riscv_relax for tprel_add where the relax feature is enabled. if (STI.getFeatureBits()[RISCV::FeatureRelax]) { const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); Fixups.push_back(MCFixup::create( 0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc())); } // Emit a normal ADD instruction with the given operands. MCInst TmpInst = MCInstBuilder(RISCV::ADD) .addOperand(DestReg) .addOperand(SrcReg) .addOperand(TPReg); uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); support::endian::write(OS, Binary, support::little); }
bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { return STI.getFeatureBits()[Mips::FeatureMips32r6]; }
bool Mos6502InstPrinter::isV9(const MCSubtargetInfo &STI) const { return (STI.getFeatureBits()[Mos6502::FeatureV9]) != 0; }
bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { return STI.getFeatureBits() & Mips::FeatureMicroMips; }
NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI) : MCInstPrinter(MAI, MII, MRI) { setAvailableFeatures(STI.getFeatureBits()); }
bool SparcInstPrinter::isV9(const MCSubtargetInfo &STI) const { return (STI.getFeatureBits()[Sparc::FeatureV9]) != 0; }
bool isSI(const MCSubtargetInfo &STI) { return STI.getFeatureBits()[AMDGPU::FeatureSouthernIslands]; }
void AMDGPUTargetAsmStreamer::EmitAmdhsaKernelDescriptor( const MCSubtargetInfo &STI, StringRef KernelName, const amdhsa::kernel_descriptor_t &KD, uint64_t NextVGPR, uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) { amdhsa::kernel_descriptor_t DefaultKD = getDefaultAmdhsaKernelDescriptor(); IsaInfo::IsaVersion IVersion = IsaInfo::getIsaVersion(STI.getFeatureBits()); OS << "\t.amdhsa_kernel " << KernelName << '\n'; #define PRINT_IF_NOT_DEFAULT(STREAM, DIRECTIVE, KERNEL_DESC, \ DEFAULT_KERNEL_DESC, MEMBER_NAME, FIELD_NAME) \ if (AMDHSA_BITS_GET(KERNEL_DESC.MEMBER_NAME, FIELD_NAME) != \ AMDHSA_BITS_GET(DEFAULT_KERNEL_DESC.MEMBER_NAME, FIELD_NAME)) \ STREAM << "\t\t" << DIRECTIVE << " " \ << AMDHSA_BITS_GET(KERNEL_DESC.MEMBER_NAME, FIELD_NAME) << '\n'; if (KD.group_segment_fixed_size != DefaultKD.group_segment_fixed_size) OS << "\t\t.amdhsa_group_segment_fixed_size " << KD.group_segment_fixed_size << '\n'; if (KD.private_segment_fixed_size != DefaultKD.private_segment_fixed_size) OS << "\t\t.amdhsa_private_segment_fixed_size " << KD.private_segment_fixed_size << '\n'; PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_user_sgpr_private_segment_buffer", KD, DefaultKD, kernel_code_properties, amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_user_sgpr_dispatch_ptr", KD, DefaultKD, kernel_code_properties, amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_user_sgpr_queue_ptr", KD, DefaultKD, kernel_code_properties, amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_user_sgpr_kernarg_segment_ptr", KD, DefaultKD, kernel_code_properties, amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_user_sgpr_dispatch_id", KD, DefaultKD, kernel_code_properties, amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_user_sgpr_flat_scratch_init", KD, DefaultKD, kernel_code_properties, amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_user_sgpr_private_segment_size", KD, DefaultKD, kernel_code_properties, amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_system_sgpr_private_segment_wavefront_offset", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_PRIVATE_SEGMENT_WAVEFRONT_OFFSET); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_id_x", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_id_y", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_id_z", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_info", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_vgpr_workitem_id", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID); // These directives are required. OS << "\t\t.amdhsa_next_free_vgpr " << NextVGPR << '\n'; OS << "\t\t.amdhsa_next_free_sgpr " << NextSGPR << '\n'; if (!ReserveVCC) OS << "\t\t.amdhsa_reserve_vcc " << ReserveVCC << '\n'; if (IVersion.Major >= 7 && !ReserveFlatScr) OS << "\t\t.amdhsa_reserve_flat_scratch " << ReserveFlatScr << '\n'; if (IVersion.Major >= 8 && ReserveXNACK != hasXNACK(STI)) OS << "\t\t.amdhsa_reserve_xnack_mask " << ReserveXNACK << '\n'; PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_round_mode_32", KD, DefaultKD, compute_pgm_rsrc1, amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_round_mode_16_64", KD, DefaultKD, compute_pgm_rsrc1, amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_denorm_mode_32", KD, DefaultKD, compute_pgm_rsrc1, amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_denorm_mode_16_64", KD, DefaultKD, compute_pgm_rsrc1, amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_dx10_clamp", KD, DefaultKD, compute_pgm_rsrc1, amdhsa::COMPUTE_PGM_RSRC1_ENABLE_DX10_CLAMP); PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_ieee_mode", KD, DefaultKD, compute_pgm_rsrc1, amdhsa::COMPUTE_PGM_RSRC1_ENABLE_IEEE_MODE); if (IVersion.Major >= 9) PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_fp16_overflow", KD, DefaultKD, compute_pgm_rsrc1, amdhsa::COMPUTE_PGM_RSRC1_FP16_OVFL); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_exception_fp_ieee_invalid_op", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_exception_fp_denorm_src", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_exception_fp_ieee_div_zero", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_exception_fp_ieee_overflow", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_exception_fp_ieee_underflow", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_exception_fp_ieee_inexact", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT); PRINT_IF_NOT_DEFAULT( OS, ".amdhsa_exception_int_div_zero", KD, DefaultKD, compute_pgm_rsrc2, amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO); #undef PRINT_IF_NOT_DEFAULT OS << "\t.end_amdhsa_kernel\n"; }
bool isVI(const MCSubtargetInfo &STI) { return STI.getFeatureBits()[AMDGPU::FeatureVolcanicIslands]; }
bool isCI(const MCSubtargetInfo &STI) { return STI.getFeatureBits()[AMDGPU::FeatureSeaIslands]; }