1 //===-- MipsMCCodeEmitter.cpp - Convert Mips 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 MipsMCCodeEmitter class. 11 // 12 //===----------------------------------------------------------------------===// 13 // 14 15 #include "MipsMCCodeEmitter.h" 16 #include "MCTargetDesc/MipsFixupKinds.h" 17 #include "MCTargetDesc/MipsMCExpr.h" 18 #include "MCTargetDesc/MipsMCTargetDesc.h" 19 #include "llvm/ADT/APFloat.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/MC/MCContext.h" 22 #include "llvm/MC/MCExpr.h" 23 #include "llvm/MC/MCInst.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCFixup.h" 26 #include "llvm/MC/MCSubtargetInfo.h" 27 #include "llvm/Support/raw_ostream.h" 28 29 #define DEBUG_TYPE "mccodeemitter" 30 31 #define GET_INSTRMAP_INFO 32 #include "MipsGenInstrInfo.inc" 33 #undef GET_INSTRMAP_INFO 34 35 namespace llvm { 36 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 37 const MCRegisterInfo &MRI, 38 const MCSubtargetInfo &STI, 39 MCContext &Ctx) { 40 return new MipsMCCodeEmitter(MCII, Ctx, false); 41 } 42 43 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 44 const MCRegisterInfo &MRI, 45 const MCSubtargetInfo &STI, 46 MCContext &Ctx) { 47 return new MipsMCCodeEmitter(MCII, Ctx, true); 48 } 49 } // End of namespace llvm. 50 51 // If the D<shift> instruction has a shift amount that is greater 52 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 53 static void LowerLargeShift(MCInst& Inst) { 54 55 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 56 assert(Inst.getOperand(2).isImm()); 57 58 int64_t Shift = Inst.getOperand(2).getImm(); 59 if (Shift <= 31) 60 return; // Do nothing 61 Shift -= 32; 62 63 // saminus32 64 Inst.getOperand(2).setImm(Shift); 65 66 switch (Inst.getOpcode()) { 67 default: 68 // Calling function is not synchronized 69 llvm_unreachable("Unexpected shift instruction"); 70 case Mips::DSLL: 71 Inst.setOpcode(Mips::DSLL32); 72 return; 73 case Mips::DSRL: 74 Inst.setOpcode(Mips::DSRL32); 75 return; 76 case Mips::DSRA: 77 Inst.setOpcode(Mips::DSRA32); 78 return; 79 case Mips::DROTR: 80 Inst.setOpcode(Mips::DROTR32); 81 return; 82 } 83 } 84 85 // Pick a DEXT or DINS instruction variant based on the pos and size operands 86 static void LowerDextDins(MCInst& InstIn) { 87 int Opcode = InstIn.getOpcode(); 88 89 if (Opcode == Mips::DEXT) 90 assert(InstIn.getNumOperands() == 4 && 91 "Invalid no. of machine operands for DEXT!"); 92 else // Only DEXT and DINS are possible 93 assert(InstIn.getNumOperands() == 5 && 94 "Invalid no. of machine operands for DINS!"); 95 96 assert(InstIn.getOperand(2).isImm()); 97 int64_t pos = InstIn.getOperand(2).getImm(); 98 assert(InstIn.getOperand(3).isImm()); 99 int64_t size = InstIn.getOperand(3).getImm(); 100 101 if (size <= 32) { 102 if (pos < 32) // DEXT/DINS, do nothing 103 return; 104 // DEXTU/DINSU 105 InstIn.getOperand(2).setImm(pos - 32); 106 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); 107 return; 108 } 109 // DEXTM/DINSM 110 assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); 111 InstIn.getOperand(3).setImm(size - 32); 112 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); 113 return; 114 } 115 116 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 117 return STI.getFeatureBits() & Mips::FeatureMicroMips; 118 } 119 120 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 121 OS << (char)C; 122 } 123 124 void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 125 const MCSubtargetInfo &STI, 126 raw_ostream &OS) const { 127 // Output the instruction encoding in little endian byte order. 128 // Little-endian byte ordering: 129 // mips32r2: 4 | 3 | 2 | 1 130 // microMIPS: 2 | 1 | 4 | 3 131 if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 132 EmitInstruction(Val >> 16, 2, STI, OS); 133 EmitInstruction(Val, 2, STI, OS); 134 } else { 135 for (unsigned i = 0; i < Size; ++i) { 136 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 137 EmitByte((Val >> Shift) & 0xff, OS); 138 } 139 } 140 } 141 142 /// EncodeInstruction - Emit the instruction. 143 /// Size the instruction with Desc.getSize(). 144 void MipsMCCodeEmitter:: 145 EncodeInstruction(const MCInst &MI, raw_ostream &OS, 146 SmallVectorImpl<MCFixup> &Fixups, 147 const MCSubtargetInfo &STI) const 148 { 149 150 // Non-pseudo instructions that get changed for direct object 151 // only based on operand values. 152 // If this list of instructions get much longer we will move 153 // the check to a function call. Until then, this is more efficient. 154 MCInst TmpInst = MI; 155 switch (MI.getOpcode()) { 156 // If shift amount is >= 32 it the inst needs to be lowered further 157 case Mips::DSLL: 158 case Mips::DSRL: 159 case Mips::DSRA: 160 case Mips::DROTR: 161 LowerLargeShift(TmpInst); 162 break; 163 // Double extract instruction is chosen by pos and size operands 164 case Mips::DEXT: 165 case Mips::DINS: 166 LowerDextDins(TmpInst); 167 } 168 169 unsigned long N = Fixups.size(); 170 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 171 172 // Check for unimplemented opcodes. 173 // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 174 // so we have to special check for them. 175 unsigned Opcode = TmpInst.getOpcode(); 176 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary) 177 llvm_unreachable("unimplemented opcode in EncodeInstruction()"); 178 179 if (STI.getFeatureBits() & Mips::FeatureMicroMips) { 180 int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips); 181 if (NewOpcode != -1) { 182 if (Fixups.size() > N) 183 Fixups.pop_back(); 184 Opcode = NewOpcode; 185 TmpInst.setOpcode (NewOpcode); 186 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 187 } 188 } 189 190 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 191 192 // Get byte count of instruction 193 unsigned Size = Desc.getSize(); 194 if (!Size) 195 llvm_unreachable("Desc.getSize() returns 0"); 196 197 EmitInstruction(Binary, Size, STI, OS); 198 } 199 200 /// getBranchTargetOpValue - Return binary encoding of the branch 201 /// target operand. If the machine operand requires relocation, 202 /// record the relocation and return zero. 203 unsigned MipsMCCodeEmitter:: 204 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 205 SmallVectorImpl<MCFixup> &Fixups, 206 const MCSubtargetInfo &STI) const { 207 208 const MCOperand &MO = MI.getOperand(OpNo); 209 210 // If the destination is an immediate, divide by 4. 211 if (MO.isImm()) return MO.getImm() >> 2; 212 213 assert(MO.isExpr() && 214 "getBranchTargetOpValue expects only expressions or immediates"); 215 216 const MCExpr *Expr = MO.getExpr(); 217 Fixups.push_back(MCFixup::Create(0, Expr, 218 MCFixupKind(Mips::fixup_Mips_PC16))); 219 return 0; 220 } 221 222 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 223 /// target operand. If the machine operand requires relocation, 224 /// record the relocation and return zero. 225 unsigned MipsMCCodeEmitter:: 226 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 227 SmallVectorImpl<MCFixup> &Fixups, 228 const MCSubtargetInfo &STI) const { 229 230 const MCOperand &MO = MI.getOperand(OpNo); 231 232 // If the destination is an immediate, divide by 2. 233 if (MO.isImm()) return MO.getImm() >> 1; 234 235 assert(MO.isExpr() && 236 "getBranchTargetOpValueMM expects only expressions or immediates"); 237 238 const MCExpr *Expr = MO.getExpr(); 239 Fixups.push_back(MCFixup::Create(0, Expr, 240 MCFixupKind(Mips:: 241 fixup_MICROMIPS_PC16_S1))); 242 return 0; 243 } 244 245 /// getBranchTarget21OpValue - Return binary encoding of the branch 246 /// target operand. If the machine operand requires relocation, 247 /// record the relocation and return zero. 248 unsigned MipsMCCodeEmitter:: 249 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 250 SmallVectorImpl<MCFixup> &Fixups, 251 const MCSubtargetInfo &STI) const { 252 253 const MCOperand &MO = MI.getOperand(OpNo); 254 255 // If the destination is an immediate, divide by 4. 256 if (MO.isImm()) return MO.getImm() >> 2; 257 258 assert(MO.isExpr() && 259 "getBranchTarget21OpValue expects only expressions or immediates"); 260 261 const MCExpr *Expr = MO.getExpr(); 262 Fixups.push_back(MCFixup::Create(0, Expr, 263 MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 264 return 0; 265 } 266 267 /// getBranchTarget26OpValue - Return binary encoding of the branch 268 /// target operand. If the machine operand requires relocation, 269 /// record the relocation and return zero. 270 unsigned MipsMCCodeEmitter:: 271 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 272 SmallVectorImpl<MCFixup> &Fixups, 273 const MCSubtargetInfo &STI) const { 274 275 const MCOperand &MO = MI.getOperand(OpNo); 276 277 // If the destination is an immediate, divide by 4. 278 if (MO.isImm()) return MO.getImm() >> 2; 279 280 assert(MO.isExpr() && 281 "getBranchTarget26OpValue expects only expressions or immediates"); 282 283 const MCExpr *Expr = MO.getExpr(); 284 Fixups.push_back(MCFixup::Create(0, Expr, 285 MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 286 return 0; 287 } 288 289 /// getJumpOffset16OpValue - Return binary encoding of the jump 290 /// target operand. If the machine operand requires relocation, 291 /// record the relocation and return zero. 292 unsigned MipsMCCodeEmitter:: 293 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 294 SmallVectorImpl<MCFixup> &Fixups, 295 const MCSubtargetInfo &STI) const { 296 297 const MCOperand &MO = MI.getOperand(OpNo); 298 299 if (MO.isImm()) return MO.getImm(); 300 301 assert(MO.isExpr() && 302 "getJumpOffset16OpValue expects only expressions or an immediate"); 303 304 // TODO: Push fixup. 305 return 0; 306 } 307 308 /// getJumpTargetOpValue - Return binary encoding of the jump 309 /// target operand. If the machine operand requires relocation, 310 /// record the relocation and return zero. 311 unsigned MipsMCCodeEmitter:: 312 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 313 SmallVectorImpl<MCFixup> &Fixups, 314 const MCSubtargetInfo &STI) const { 315 316 const MCOperand &MO = MI.getOperand(OpNo); 317 // If the destination is an immediate, divide by 4. 318 if (MO.isImm()) return MO.getImm()>>2; 319 320 assert(MO.isExpr() && 321 "getJumpTargetOpValue expects only expressions or an immediate"); 322 323 const MCExpr *Expr = MO.getExpr(); 324 Fixups.push_back(MCFixup::Create(0, Expr, 325 MCFixupKind(Mips::fixup_Mips_26))); 326 return 0; 327 } 328 329 unsigned MipsMCCodeEmitter:: 330 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 331 SmallVectorImpl<MCFixup> &Fixups, 332 const MCSubtargetInfo &STI) const { 333 334 const MCOperand &MO = MI.getOperand(OpNo); 335 // If the destination is an immediate, divide by 2. 336 if (MO.isImm()) return MO.getImm() >> 1; 337 338 assert(MO.isExpr() && 339 "getJumpTargetOpValueMM expects only expressions or an immediate"); 340 341 const MCExpr *Expr = MO.getExpr(); 342 Fixups.push_back(MCFixup::Create(0, Expr, 343 MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 344 return 0; 345 } 346 347 unsigned MipsMCCodeEmitter:: 348 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, 349 const MCSubtargetInfo &STI) const { 350 int64_t Res; 351 352 if (Expr->EvaluateAsAbsolute(Res)) 353 return Res; 354 355 MCExpr::ExprKind Kind = Expr->getKind(); 356 if (Kind == MCExpr::Constant) { 357 return cast<MCConstantExpr>(Expr)->getValue(); 358 } 359 360 if (Kind == MCExpr::Binary) { 361 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 362 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 363 return Res; 364 } 365 366 if (Kind == MCExpr::Target) { 367 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 368 369 Mips::Fixups FixupKind = Mips::Fixups(0); 370 switch (MipsExpr->getKind()) { 371 default: llvm_unreachable("Unsupported fixup kind for target expression!"); 372 case MipsMCExpr::VK_Mips_HIGHEST: 373 FixupKind = Mips::fixup_Mips_HIGHEST; 374 break; 375 case MipsMCExpr::VK_Mips_HIGHER: 376 FixupKind = Mips::fixup_Mips_HIGHER; 377 break; 378 case MipsMCExpr::VK_Mips_HI: 379 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 380 : Mips::fixup_Mips_HI16; 381 break; 382 case MipsMCExpr::VK_Mips_LO: 383 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 384 : Mips::fixup_Mips_LO16; 385 break; 386 } 387 Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind))); 388 return 0; 389 } 390 391 if (Kind == MCExpr::SymbolRef) { 392 Mips::Fixups FixupKind = Mips::Fixups(0); 393 394 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 395 default: llvm_unreachable("Unknown fixup kind!"); 396 break; 397 case MCSymbolRefExpr::VK_Mips_GPOFF_HI : 398 FixupKind = Mips::fixup_Mips_GPOFF_HI; 399 break; 400 case MCSymbolRefExpr::VK_Mips_GPOFF_LO : 401 FixupKind = Mips::fixup_Mips_GPOFF_LO; 402 break; 403 case MCSymbolRefExpr::VK_Mips_GOT_PAGE : 404 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 405 : Mips::fixup_Mips_GOT_PAGE; 406 break; 407 case MCSymbolRefExpr::VK_Mips_GOT_OFST : 408 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 409 : Mips::fixup_Mips_GOT_OFST; 410 break; 411 case MCSymbolRefExpr::VK_Mips_GOT_DISP : 412 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 413 : Mips::fixup_Mips_GOT_DISP; 414 break; 415 case MCSymbolRefExpr::VK_Mips_GPREL: 416 FixupKind = Mips::fixup_Mips_GPREL16; 417 break; 418 case MCSymbolRefExpr::VK_Mips_GOT_CALL: 419 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 420 : Mips::fixup_Mips_CALL16; 421 break; 422 case MCSymbolRefExpr::VK_Mips_GOT16: 423 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 424 : Mips::fixup_Mips_GOT_Global; 425 break; 426 case MCSymbolRefExpr::VK_Mips_GOT: 427 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 428 : Mips::fixup_Mips_GOT_Local; 429 break; 430 case MCSymbolRefExpr::VK_Mips_ABS_HI: 431 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 432 : Mips::fixup_Mips_HI16; 433 break; 434 case MCSymbolRefExpr::VK_Mips_ABS_LO: 435 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 436 : Mips::fixup_Mips_LO16; 437 break; 438 case MCSymbolRefExpr::VK_Mips_TLSGD: 439 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 440 : Mips::fixup_Mips_TLSGD; 441 break; 442 case MCSymbolRefExpr::VK_Mips_TLSLDM: 443 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 444 : Mips::fixup_Mips_TLSLDM; 445 break; 446 case MCSymbolRefExpr::VK_Mips_DTPREL_HI: 447 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 448 : Mips::fixup_Mips_DTPREL_HI; 449 break; 450 case MCSymbolRefExpr::VK_Mips_DTPREL_LO: 451 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 452 : Mips::fixup_Mips_DTPREL_LO; 453 break; 454 case MCSymbolRefExpr::VK_Mips_GOTTPREL: 455 FixupKind = Mips::fixup_Mips_GOTTPREL; 456 break; 457 case MCSymbolRefExpr::VK_Mips_TPREL_HI: 458 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 459 : Mips::fixup_Mips_TPREL_HI; 460 break; 461 case MCSymbolRefExpr::VK_Mips_TPREL_LO: 462 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 463 : Mips::fixup_Mips_TPREL_LO; 464 break; 465 case MCSymbolRefExpr::VK_Mips_HIGHER: 466 FixupKind = Mips::fixup_Mips_HIGHER; 467 break; 468 case MCSymbolRefExpr::VK_Mips_HIGHEST: 469 FixupKind = Mips::fixup_Mips_HIGHEST; 470 break; 471 case MCSymbolRefExpr::VK_Mips_GOT_HI16: 472 FixupKind = Mips::fixup_Mips_GOT_HI16; 473 break; 474 case MCSymbolRefExpr::VK_Mips_GOT_LO16: 475 FixupKind = Mips::fixup_Mips_GOT_LO16; 476 break; 477 case MCSymbolRefExpr::VK_Mips_CALL_HI16: 478 FixupKind = Mips::fixup_Mips_CALL_HI16; 479 break; 480 case MCSymbolRefExpr::VK_Mips_CALL_LO16: 481 FixupKind = Mips::fixup_Mips_CALL_LO16; 482 break; 483 case MCSymbolRefExpr::VK_Mips_PCREL_HI16: 484 FixupKind = Mips::fixup_MIPS_PCHI16; 485 break; 486 case MCSymbolRefExpr::VK_Mips_PCREL_LO16: 487 FixupKind = Mips::fixup_MIPS_PCLO16; 488 break; 489 } // switch 490 491 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind))); 492 return 0; 493 } 494 return 0; 495 } 496 497 /// getMachineOpValue - Return binary encoding of operand. If the machine 498 /// operand requires relocation, record the relocation and return zero. 499 unsigned MipsMCCodeEmitter:: 500 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 501 SmallVectorImpl<MCFixup> &Fixups, 502 const MCSubtargetInfo &STI) const { 503 if (MO.isReg()) { 504 unsigned Reg = MO.getReg(); 505 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 506 return RegNo; 507 } else if (MO.isImm()) { 508 return static_cast<unsigned>(MO.getImm()); 509 } else if (MO.isFPImm()) { 510 return static_cast<unsigned>(APFloat(MO.getFPImm()) 511 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 512 } 513 // MO must be an Expr. 514 assert(MO.isExpr()); 515 return getExprOpValue(MO.getExpr(),Fixups, STI); 516 } 517 518 /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST 519 /// instructions. 520 unsigned 521 MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo, 522 SmallVectorImpl<MCFixup> &Fixups, 523 const MCSubtargetInfo &STI) const { 524 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 525 assert(MI.getOperand(OpNo).isReg()); 526 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 527 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 528 529 // The immediate field of an LD/ST instruction is scaled which means it must 530 // be divided (when encoding) by the size (in bytes) of the instructions' 531 // data format. 532 // .b - 1 byte 533 // .h - 2 bytes 534 // .w - 4 bytes 535 // .d - 8 bytes 536 switch(MI.getOpcode()) 537 { 538 default: 539 assert (0 && "Unexpected instruction"); 540 break; 541 case Mips::LD_B: 542 case Mips::ST_B: 543 // We don't need to scale the offset in this case 544 break; 545 case Mips::LD_H: 546 case Mips::ST_H: 547 OffBits >>= 1; 548 break; 549 case Mips::LD_W: 550 case Mips::ST_W: 551 OffBits >>= 2; 552 break; 553 case Mips::LD_D: 554 case Mips::ST_D: 555 OffBits >>= 3; 556 break; 557 } 558 559 return (OffBits & 0xFFFF) | RegBits; 560 } 561 562 /// getMemEncoding - Return binary encoding of memory related operand. 563 /// If the offset operand requires relocation, record the relocation. 564 unsigned 565 MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 566 SmallVectorImpl<MCFixup> &Fixups, 567 const MCSubtargetInfo &STI) const { 568 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 569 assert(MI.getOperand(OpNo).isReg()); 570 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 571 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 572 573 return (OffBits & 0xFFFF) | RegBits; 574 } 575 576 unsigned MipsMCCodeEmitter:: 577 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 578 SmallVectorImpl<MCFixup> &Fixups, 579 const MCSubtargetInfo &STI) const { 580 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 581 assert(MI.getOperand(OpNo).isReg()); 582 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 583 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 584 585 return (OffBits & 0x0FFF) | RegBits; 586 } 587 588 unsigned 589 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo, 590 SmallVectorImpl<MCFixup> &Fixups, 591 const MCSubtargetInfo &STI) const { 592 assert(MI.getOperand(OpNo).isImm()); 593 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 594 return SizeEncoding - 1; 595 } 596 597 // FIXME: should be called getMSBEncoding 598 // 599 unsigned 600 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 601 SmallVectorImpl<MCFixup> &Fixups, 602 const MCSubtargetInfo &STI) const { 603 assert(MI.getOperand(OpNo-1).isImm()); 604 assert(MI.getOperand(OpNo).isImm()); 605 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 606 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 607 608 return Position + Size - 1; 609 } 610 611 unsigned 612 MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, 613 SmallVectorImpl<MCFixup> &Fixups, 614 const MCSubtargetInfo &STI) const { 615 assert(MI.getOperand(OpNo).isImm()); 616 // The immediate is encoded as 'immediate - 1'. 617 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1; 618 } 619 620 unsigned 621 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 622 SmallVectorImpl<MCFixup> &Fixups, 623 const MCSubtargetInfo &STI) const { 624 const MCOperand &MO = MI.getOperand(OpNo); 625 if (MO.isImm()) { 626 // The immediate is encoded as 'immediate << 2'. 627 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 628 assert((Res & 3) == 0); 629 return Res >> 2; 630 } 631 632 assert(MO.isExpr() && 633 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 634 635 const MCExpr *Expr = MO.getExpr(); 636 Fixups.push_back(MCFixup::Create(0, Expr, 637 MCFixupKind(Mips::fixup_MIPS_PC19_S2))); 638 return 0; 639 } 640 641 unsigned 642 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 643 SmallVectorImpl<MCFixup> &Fixups, 644 const MCSubtargetInfo &STI) const { 645 const MCOperand &MO = MI.getOperand(OpNo); 646 if (MO.isImm()) { 647 // The immediate is encoded as 'immediate << 3'. 648 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 649 assert((Res & 7) == 0); 650 return Res >> 3; 651 } 652 653 assert(MO.isExpr() && 654 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 655 656 const MCExpr *Expr = MO.getExpr(); 657 Fixups.push_back(MCFixup::Create(0, Expr, 658 MCFixupKind(Mips::fixup_MIPS_PC18_S3))); 659 return 0; 660 } 661 662 #include "MipsGenMCCodeEmitter.inc" 663