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