1 //===-- VEMCCodeEmitter.cpp - Convert VE code to machine code -------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the VEMCCodeEmitter class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/VEFixupKinds.h" 14 #include "VE.h" 15 #include "VEMCExpr.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/MC/MCCodeEmitter.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCExpr.h" 21 #include "llvm/MC/MCFixup.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCInstrInfo.h" 24 #include "llvm/MC/MCRegisterInfo.h" 25 #include "llvm/MC/MCSubtargetInfo.h" 26 #include "llvm/MC/MCSymbol.h" 27 #include "llvm/Support/EndianStream.h" 28 #include "llvm/Support/ErrorHandling.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include <cassert> 31 #include <cstdint> 32 33 using namespace llvm; 34 35 #define DEBUG_TYPE "mccodeemitter" 36 37 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 38 39 namespace { 40 41 class VEMCCodeEmitter : public MCCodeEmitter { 42 const MCInstrInfo &MCII; 43 MCContext &Ctx; 44 45 public: 46 VEMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) 47 : MCII(mcii), Ctx(ctx) {} 48 VEMCCodeEmitter(const VEMCCodeEmitter &) = delete; 49 VEMCCodeEmitter &operator=(const VEMCCodeEmitter &) = delete; 50 ~VEMCCodeEmitter() override = default; 51 52 void encodeInstruction(const MCInst &MI, raw_ostream &OS, 53 SmallVectorImpl<MCFixup> &Fixups, 54 const MCSubtargetInfo &STI) const override; 55 56 // getBinaryCodeForInstr - TableGen'erated function for getting the 57 // binary encoding for an instruction. 58 uint64_t getBinaryCodeForInstr(const MCInst &MI, 59 SmallVectorImpl<MCFixup> &Fixups, 60 const MCSubtargetInfo &STI) const; 61 62 /// getMachineOpValue - Return binary encoding of operand. If the machine 63 /// operand requires relocation, record the relocation and return zero. 64 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 65 SmallVectorImpl<MCFixup> &Fixups, 66 const MCSubtargetInfo &STI) const; 67 68 uint64_t getCCOpValue(const MCInst &MI, unsigned OpNo, 69 SmallVectorImpl<MCFixup> &Fixups, 70 const MCSubtargetInfo &STI) const; 71 uint64_t getRDOpValue(const MCInst &MI, unsigned OpNo, 72 SmallVectorImpl<MCFixup> &Fixups, 73 const MCSubtargetInfo &STI) const; 74 75 private: 76 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const; 77 void 78 verifyInstructionPredicates(const MCInst &MI, 79 const FeatureBitset &AvailableFeatures) const; 80 }; 81 82 } // end anonymous namespace 83 84 void VEMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 85 SmallVectorImpl<MCFixup> &Fixups, 86 const MCSubtargetInfo &STI) const { 87 verifyInstructionPredicates(MI, 88 computeAvailableFeatures(STI.getFeatureBits())); 89 90 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 91 support::endian::write<uint64_t>(OS, Bits, support::little); 92 93 ++MCNumEmitted; // Keep track of the # of mi's emitted. 94 } 95 96 unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst &MI, 97 const MCOperand &MO, 98 SmallVectorImpl<MCFixup> &Fixups, 99 const MCSubtargetInfo &STI) const { 100 if (MO.isReg()) 101 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 102 103 if (MO.isImm()) 104 return MO.getImm(); 105 106 assert(MO.isExpr()); 107 const MCExpr *Expr = MO.getExpr(); 108 if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Expr)) { 109 MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind(); 110 Fixups.push_back(MCFixup::create(0, Expr, Kind)); 111 return 0; 112 } 113 114 int64_t Res; 115 if (Expr->evaluateAsAbsolute(Res)) 116 return Res; 117 118 llvm_unreachable("Unhandled expression!"); 119 return 0; 120 } 121 122 uint64_t VEMCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned OpNo, 123 SmallVectorImpl<MCFixup> &Fixups, 124 const MCSubtargetInfo &STI) const { 125 const MCOperand &MO = MI.getOperand(OpNo); 126 if (MO.isImm()) 127 return VECondCodeToVal( 128 static_cast<VECC::CondCode>(getMachineOpValue(MI, MO, Fixups, STI))); 129 return 0; 130 } 131 132 uint64_t VEMCCodeEmitter::getRDOpValue(const MCInst &MI, unsigned OpNo, 133 SmallVectorImpl<MCFixup> &Fixups, 134 const MCSubtargetInfo &STI) const { 135 const MCOperand &MO = MI.getOperand(OpNo); 136 if (MO.isImm()) 137 return VERDToVal(static_cast<VERD::RoundingMode>( 138 getMachineOpValue(MI, MO, Fixups, STI))); 139 return 0; 140 } 141 142 #define ENABLE_INSTR_PREDICATE_VERIFIER 143 #include "VEGenMCCodeEmitter.inc" 144 145 MCCodeEmitter *llvm::createVEMCCodeEmitter(const MCInstrInfo &MCII, 146 const MCRegisterInfo &MRI, 147 MCContext &Ctx) { 148 return new VEMCCodeEmitter(MCII, Ctx); 149 } 150