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