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