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