1 //===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===// 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 file implements the PPCMCCodeEmitter class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MCTargetDesc/PPCMCTargetDesc.h" 15 #include "MCTargetDesc/PPCFixupKinds.h" 16 #include "llvm/ADT/Statistic.h" 17 #include "llvm/MC/MCCodeEmitter.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCExpr.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/MC/MCInstrInfo.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include "llvm/Target/TargetOpcodes.h" 26 using namespace llvm; 27 28 #define DEBUG_TYPE "mccodeemitter" 29 30 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 31 32 namespace { 33 class PPCMCCodeEmitter : public MCCodeEmitter { 34 PPCMCCodeEmitter(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION; 35 void operator=(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION; 36 37 const MCInstrInfo &MCII; 38 const MCContext &CTX; 39 bool IsLittleEndian; 40 41 public: 42 PPCMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool isLittle) 43 : MCII(mcii), CTX(ctx), IsLittleEndian(isLittle) { 44 } 45 46 ~PPCMCCodeEmitter() {} 47 48 unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo, 49 SmallVectorImpl<MCFixup> &Fixups, 50 const MCSubtargetInfo &STI) const; 51 unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo, 52 SmallVectorImpl<MCFixup> &Fixups, 53 const MCSubtargetInfo &STI) const; 54 unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, 55 SmallVectorImpl<MCFixup> &Fixups, 56 const MCSubtargetInfo &STI) const; 57 unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, 58 SmallVectorImpl<MCFixup> &Fixups, 59 const MCSubtargetInfo &STI) const; 60 unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo, 61 SmallVectorImpl<MCFixup> &Fixups, 62 const MCSubtargetInfo &STI) const; 63 unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo, 64 SmallVectorImpl<MCFixup> &Fixups, 65 const MCSubtargetInfo &STI) const; 66 unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo, 67 SmallVectorImpl<MCFixup> &Fixups, 68 const MCSubtargetInfo &STI) const; 69 unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo, 70 SmallVectorImpl<MCFixup> &Fixups, 71 const MCSubtargetInfo &STI) const; 72 unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo, 73 SmallVectorImpl<MCFixup> &Fixups, 74 const MCSubtargetInfo &STI) const; 75 unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, 76 SmallVectorImpl<MCFixup> &Fixups, 77 const MCSubtargetInfo &STI) const; 78 79 /// getMachineOpValue - Return binary encoding of operand. If the machine 80 /// operand requires relocation, record the relocation and return zero. 81 unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, 82 SmallVectorImpl<MCFixup> &Fixups, 83 const MCSubtargetInfo &STI) const; 84 85 // getBinaryCodeForInstr - TableGen'erated function for getting the 86 // binary encoding for an instruction. 87 uint64_t getBinaryCodeForInstr(const MCInst &MI, 88 SmallVectorImpl<MCFixup> &Fixups, 89 const MCSubtargetInfo &STI) const; 90 void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 91 SmallVectorImpl<MCFixup> &Fixups, 92 const MCSubtargetInfo &STI) const override { 93 // For fast-isel, a float COPY_TO_REGCLASS can survive this long. 94 // It's just a nop to keep the register classes happy, so don't 95 // generate anything. 96 unsigned Opcode = MI.getOpcode(); 97 const MCInstrDesc &Desc = MCII.get(Opcode); 98 if (Opcode == TargetOpcode::COPY_TO_REGCLASS) 99 return; 100 101 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 102 103 // Output the constant in big/little endian byte order. 104 unsigned Size = Desc.getSize(); 105 switch (Size) { 106 case 4: 107 if (IsLittleEndian) { 108 OS << (char)(Bits); 109 OS << (char)(Bits >> 8); 110 OS << (char)(Bits >> 16); 111 OS << (char)(Bits >> 24); 112 } else { 113 OS << (char)(Bits >> 24); 114 OS << (char)(Bits >> 16); 115 OS << (char)(Bits >> 8); 116 OS << (char)(Bits); 117 } 118 break; 119 case 8: 120 // If we emit a pair of instructions, the first one is 121 // always in the top 32 bits, even on little-endian. 122 if (IsLittleEndian) { 123 OS << (char)(Bits >> 32); 124 OS << (char)(Bits >> 40); 125 OS << (char)(Bits >> 48); 126 OS << (char)(Bits >> 56); 127 OS << (char)(Bits); 128 OS << (char)(Bits >> 8); 129 OS << (char)(Bits >> 16); 130 OS << (char)(Bits >> 24); 131 } else { 132 OS << (char)(Bits >> 56); 133 OS << (char)(Bits >> 48); 134 OS << (char)(Bits >> 40); 135 OS << (char)(Bits >> 32); 136 OS << (char)(Bits >> 24); 137 OS << (char)(Bits >> 16); 138 OS << (char)(Bits >> 8); 139 OS << (char)(Bits); 140 } 141 break; 142 default: 143 llvm_unreachable ("Invalid instruction size"); 144 } 145 146 ++MCNumEmitted; // Keep track of the # of mi's emitted. 147 } 148 149 }; 150 151 } // end anonymous namespace 152 153 MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII, 154 const MCRegisterInfo &MRI, 155 const MCSubtargetInfo &STI, 156 MCContext &Ctx) { 157 Triple TT(STI.getTargetTriple()); 158 bool IsLittleEndian = TT.getArch() == Triple::ppc64le; 159 return new PPCMCCodeEmitter(MCII, Ctx, IsLittleEndian); 160 } 161 162 unsigned PPCMCCodeEmitter:: 163 getDirectBrEncoding(const MCInst &MI, unsigned OpNo, 164 SmallVectorImpl<MCFixup> &Fixups, 165 const MCSubtargetInfo &STI) const { 166 const MCOperand &MO = MI.getOperand(OpNo); 167 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 168 169 // Add a fixup for the branch target. 170 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 171 (MCFixupKind)PPC::fixup_ppc_br24)); 172 return 0; 173 } 174 175 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo, 176 SmallVectorImpl<MCFixup> &Fixups, 177 const MCSubtargetInfo &STI) const { 178 const MCOperand &MO = MI.getOperand(OpNo); 179 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 180 181 // Add a fixup for the branch target. 182 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 183 (MCFixupKind)PPC::fixup_ppc_brcond14)); 184 return 0; 185 } 186 187 unsigned PPCMCCodeEmitter:: 188 getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, 189 SmallVectorImpl<MCFixup> &Fixups, 190 const MCSubtargetInfo &STI) const { 191 const MCOperand &MO = MI.getOperand(OpNo); 192 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 193 194 // Add a fixup for the branch target. 195 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 196 (MCFixupKind)PPC::fixup_ppc_br24abs)); 197 return 0; 198 } 199 200 unsigned PPCMCCodeEmitter:: 201 getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, 202 SmallVectorImpl<MCFixup> &Fixups, 203 const MCSubtargetInfo &STI) const { 204 const MCOperand &MO = MI.getOperand(OpNo); 205 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 206 207 // Add a fixup for the branch target. 208 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 209 (MCFixupKind)PPC::fixup_ppc_brcond14abs)); 210 return 0; 211 } 212 213 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo, 214 SmallVectorImpl<MCFixup> &Fixups, 215 const MCSubtargetInfo &STI) const { 216 const MCOperand &MO = MI.getOperand(OpNo); 217 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 218 219 // Add a fixup for the immediate field. 220 Fixups.push_back(MCFixup::Create(IsLittleEndian? 0 : 2, MO.getExpr(), 221 (MCFixupKind)PPC::fixup_ppc_half16)); 222 return 0; 223 } 224 225 unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo, 226 SmallVectorImpl<MCFixup> &Fixups, 227 const MCSubtargetInfo &STI) const { 228 // Encode (imm, reg) as a memri, which has the low 16-bits as the 229 // displacement and the next 5 bits as the register #. 230 assert(MI.getOperand(OpNo+1).isReg()); 231 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 16; 232 233 const MCOperand &MO = MI.getOperand(OpNo); 234 if (MO.isImm()) 235 return (getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF) | RegBits; 236 237 // Add a fixup for the displacement field. 238 Fixups.push_back(MCFixup::Create(IsLittleEndian? 0 : 2, MO.getExpr(), 239 (MCFixupKind)PPC::fixup_ppc_half16)); 240 return RegBits; 241 } 242 243 244 unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo, 245 SmallVectorImpl<MCFixup> &Fixups, 246 const MCSubtargetInfo &STI) const { 247 // Encode (imm, reg) as a memrix, which has the low 14-bits as the 248 // displacement and the next 5 bits as the register #. 249 assert(MI.getOperand(OpNo+1).isReg()); 250 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 14; 251 252 const MCOperand &MO = MI.getOperand(OpNo); 253 if (MO.isImm()) 254 return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF) | RegBits; 255 256 // Add a fixup for the displacement field. 257 Fixups.push_back(MCFixup::Create(IsLittleEndian? 0 : 2, MO.getExpr(), 258 (MCFixupKind)PPC::fixup_ppc_half16ds)); 259 return RegBits; 260 } 261 262 263 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo, 264 SmallVectorImpl<MCFixup> &Fixups, 265 const MCSubtargetInfo &STI) const { 266 const MCOperand &MO = MI.getOperand(OpNo); 267 if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI); 268 269 // Add a fixup for the TLS register, which simply provides a relocation 270 // hint to the linker that this statement is part of a relocation sequence. 271 // Return the thread-pointer register's encoding. 272 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 273 (MCFixupKind)PPC::fixup_ppc_nofixup)); 274 Triple TT(STI.getTargetTriple()); 275 bool isPPC64 = TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le; 276 return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2); 277 } 278 279 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo, 280 SmallVectorImpl<MCFixup> &Fixups, 281 const MCSubtargetInfo &STI) const { 282 // For special TLS calls, we need two fixups; one for the branch target 283 // (__tls_get_addr), which we create via getDirectBrEncoding as usual, 284 // and one for the TLSGD or TLSLD symbol, which is emitted here. 285 const MCOperand &MO = MI.getOperand(OpNo+1); 286 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 287 (MCFixupKind)PPC::fixup_ppc_nofixup)); 288 return getDirectBrEncoding(MI, OpNo, Fixups, STI); 289 } 290 291 unsigned PPCMCCodeEmitter:: 292 get_crbitm_encoding(const MCInst &MI, unsigned OpNo, 293 SmallVectorImpl<MCFixup> &Fixups, 294 const MCSubtargetInfo &STI) const { 295 const MCOperand &MO = MI.getOperand(OpNo); 296 assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 || 297 MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) && 298 (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); 299 return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 300 } 301 302 303 unsigned PPCMCCodeEmitter:: 304 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 305 SmallVectorImpl<MCFixup> &Fixups, 306 const MCSubtargetInfo &STI) const { 307 if (MO.isReg()) { 308 // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand. 309 // The GPR operand should come through here though. 310 assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 && 311 MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) || 312 MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); 313 return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 314 } 315 316 assert(MO.isImm() && 317 "Relocation required in an instruction that we cannot encode!"); 318 return MO.getImm(); 319 } 320 321 322 #include "PPCGenMCCodeEmitter.inc" 323