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 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 349 SmallVectorImpl<MCFixup> &Fixups, 350 const MCSubtargetInfo &STI) const { 351 352 const MCOperand &MO = MI.getOperand(OpNo); 353 if (MO.isImm()) { 354 // The immediate is encoded as 'immediate << 2'. 355 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 356 assert((Res & 3) == 0); 357 return Res >> 2; 358 } 359 360 assert(MO.isExpr() && 361 "getUImm5Lsl2Encoding expects only expressions or an immediate"); 362 363 return 0; 364 } 365 366 unsigned MipsMCCodeEmitter:: 367 getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 368 SmallVectorImpl<MCFixup> &Fixups, 369 const MCSubtargetInfo &STI) const { 370 371 const MCOperand &MO = MI.getOperand(OpNo); 372 if (MO.isImm()) { 373 int Value = MO.getImm(); 374 return Value >> 2; 375 } 376 377 return 0; 378 } 379 380 unsigned MipsMCCodeEmitter:: 381 getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 382 SmallVectorImpl<MCFixup> &Fixups, 383 const MCSubtargetInfo &STI) const { 384 385 const MCOperand &MO = MI.getOperand(OpNo); 386 if (MO.isImm()) { 387 unsigned Value = MO.getImm(); 388 return Value >> 2; 389 } 390 391 return 0; 392 } 393 394 unsigned MipsMCCodeEmitter:: 395 getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 396 SmallVectorImpl<MCFixup> &Fixups, 397 const MCSubtargetInfo &STI) const { 398 399 const MCOperand &MO = MI.getOperand(OpNo); 400 if (MO.isImm()) { 401 unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 402 return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 403 } 404 405 return 0; 406 } 407 408 unsigned MipsMCCodeEmitter:: 409 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, 410 const MCSubtargetInfo &STI) const { 411 int64_t Res; 412 413 if (Expr->EvaluateAsAbsolute(Res)) 414 return Res; 415 416 MCExpr::ExprKind Kind = Expr->getKind(); 417 if (Kind == MCExpr::Constant) { 418 return cast<MCConstantExpr>(Expr)->getValue(); 419 } 420 421 if (Kind == MCExpr::Binary) { 422 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 423 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 424 return Res; 425 } 426 427 if (Kind == MCExpr::Target) { 428 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 429 430 Mips::Fixups FixupKind = Mips::Fixups(0); 431 switch (MipsExpr->getKind()) { 432 default: llvm_unreachable("Unsupported fixup kind for target expression!"); 433 case MipsMCExpr::VK_Mips_HIGHEST: 434 FixupKind = Mips::fixup_Mips_HIGHEST; 435 break; 436 case MipsMCExpr::VK_Mips_HIGHER: 437 FixupKind = Mips::fixup_Mips_HIGHER; 438 break; 439 case MipsMCExpr::VK_Mips_HI: 440 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 441 : Mips::fixup_Mips_HI16; 442 break; 443 case MipsMCExpr::VK_Mips_LO: 444 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 445 : Mips::fixup_Mips_LO16; 446 break; 447 } 448 Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind))); 449 return 0; 450 } 451 452 if (Kind == MCExpr::SymbolRef) { 453 Mips::Fixups FixupKind = Mips::Fixups(0); 454 455 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 456 default: llvm_unreachable("Unknown fixup kind!"); 457 break; 458 case MCSymbolRefExpr::VK_Mips_GPOFF_HI : 459 FixupKind = Mips::fixup_Mips_GPOFF_HI; 460 break; 461 case MCSymbolRefExpr::VK_Mips_GPOFF_LO : 462 FixupKind = Mips::fixup_Mips_GPOFF_LO; 463 break; 464 case MCSymbolRefExpr::VK_Mips_GOT_PAGE : 465 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 466 : Mips::fixup_Mips_GOT_PAGE; 467 break; 468 case MCSymbolRefExpr::VK_Mips_GOT_OFST : 469 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 470 : Mips::fixup_Mips_GOT_OFST; 471 break; 472 case MCSymbolRefExpr::VK_Mips_GOT_DISP : 473 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 474 : Mips::fixup_Mips_GOT_DISP; 475 break; 476 case MCSymbolRefExpr::VK_Mips_GPREL: 477 FixupKind = Mips::fixup_Mips_GPREL16; 478 break; 479 case MCSymbolRefExpr::VK_Mips_GOT_CALL: 480 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 481 : Mips::fixup_Mips_CALL16; 482 break; 483 case MCSymbolRefExpr::VK_Mips_GOT16: 484 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 485 : Mips::fixup_Mips_GOT_Global; 486 break; 487 case MCSymbolRefExpr::VK_Mips_GOT: 488 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 489 : Mips::fixup_Mips_GOT_Local; 490 break; 491 case MCSymbolRefExpr::VK_Mips_ABS_HI: 492 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 493 : Mips::fixup_Mips_HI16; 494 break; 495 case MCSymbolRefExpr::VK_Mips_ABS_LO: 496 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 497 : Mips::fixup_Mips_LO16; 498 break; 499 case MCSymbolRefExpr::VK_Mips_TLSGD: 500 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 501 : Mips::fixup_Mips_TLSGD; 502 break; 503 case MCSymbolRefExpr::VK_Mips_TLSLDM: 504 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 505 : Mips::fixup_Mips_TLSLDM; 506 break; 507 case MCSymbolRefExpr::VK_Mips_DTPREL_HI: 508 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 509 : Mips::fixup_Mips_DTPREL_HI; 510 break; 511 case MCSymbolRefExpr::VK_Mips_DTPREL_LO: 512 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 513 : Mips::fixup_Mips_DTPREL_LO; 514 break; 515 case MCSymbolRefExpr::VK_Mips_GOTTPREL: 516 FixupKind = Mips::fixup_Mips_GOTTPREL; 517 break; 518 case MCSymbolRefExpr::VK_Mips_TPREL_HI: 519 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 520 : Mips::fixup_Mips_TPREL_HI; 521 break; 522 case MCSymbolRefExpr::VK_Mips_TPREL_LO: 523 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 524 : Mips::fixup_Mips_TPREL_LO; 525 break; 526 case MCSymbolRefExpr::VK_Mips_HIGHER: 527 FixupKind = Mips::fixup_Mips_HIGHER; 528 break; 529 case MCSymbolRefExpr::VK_Mips_HIGHEST: 530 FixupKind = Mips::fixup_Mips_HIGHEST; 531 break; 532 case MCSymbolRefExpr::VK_Mips_GOT_HI16: 533 FixupKind = Mips::fixup_Mips_GOT_HI16; 534 break; 535 case MCSymbolRefExpr::VK_Mips_GOT_LO16: 536 FixupKind = Mips::fixup_Mips_GOT_LO16; 537 break; 538 case MCSymbolRefExpr::VK_Mips_CALL_HI16: 539 FixupKind = Mips::fixup_Mips_CALL_HI16; 540 break; 541 case MCSymbolRefExpr::VK_Mips_CALL_LO16: 542 FixupKind = Mips::fixup_Mips_CALL_LO16; 543 break; 544 case MCSymbolRefExpr::VK_Mips_PCREL_HI16: 545 FixupKind = Mips::fixup_MIPS_PCHI16; 546 break; 547 case MCSymbolRefExpr::VK_Mips_PCREL_LO16: 548 FixupKind = Mips::fixup_MIPS_PCLO16; 549 break; 550 } // switch 551 552 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind))); 553 return 0; 554 } 555 return 0; 556 } 557 558 /// getMachineOpValue - Return binary encoding of operand. If the machine 559 /// operand requires relocation, record the relocation and return zero. 560 unsigned MipsMCCodeEmitter:: 561 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 562 SmallVectorImpl<MCFixup> &Fixups, 563 const MCSubtargetInfo &STI) const { 564 if (MO.isReg()) { 565 unsigned Reg = MO.getReg(); 566 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 567 return RegNo; 568 } else if (MO.isImm()) { 569 return static_cast<unsigned>(MO.getImm()); 570 } else if (MO.isFPImm()) { 571 return static_cast<unsigned>(APFloat(MO.getFPImm()) 572 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 573 } 574 // MO must be an Expr. 575 assert(MO.isExpr()); 576 return getExprOpValue(MO.getExpr(),Fixups, STI); 577 } 578 579 /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST 580 /// instructions. 581 unsigned 582 MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo, 583 SmallVectorImpl<MCFixup> &Fixups, 584 const MCSubtargetInfo &STI) const { 585 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 586 assert(MI.getOperand(OpNo).isReg()); 587 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 588 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 589 590 // The immediate field of an LD/ST instruction is scaled which means it must 591 // be divided (when encoding) by the size (in bytes) of the instructions' 592 // data format. 593 // .b - 1 byte 594 // .h - 2 bytes 595 // .w - 4 bytes 596 // .d - 8 bytes 597 switch(MI.getOpcode()) 598 { 599 default: 600 assert (0 && "Unexpected instruction"); 601 break; 602 case Mips::LD_B: 603 case Mips::ST_B: 604 // We don't need to scale the offset in this case 605 break; 606 case Mips::LD_H: 607 case Mips::ST_H: 608 OffBits >>= 1; 609 break; 610 case Mips::LD_W: 611 case Mips::ST_W: 612 OffBits >>= 2; 613 break; 614 case Mips::LD_D: 615 case Mips::ST_D: 616 OffBits >>= 3; 617 break; 618 } 619 620 return (OffBits & 0xFFFF) | RegBits; 621 } 622 623 /// getMemEncoding - Return binary encoding of memory related operand. 624 /// If the offset operand requires relocation, record the relocation. 625 unsigned 626 MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 627 SmallVectorImpl<MCFixup> &Fixups, 628 const MCSubtargetInfo &STI) const { 629 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 630 assert(MI.getOperand(OpNo).isReg()); 631 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 632 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 633 634 return (OffBits & 0xFFFF) | RegBits; 635 } 636 637 unsigned MipsMCCodeEmitter:: 638 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 639 SmallVectorImpl<MCFixup> &Fixups, 640 const MCSubtargetInfo &STI) const { 641 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 642 assert(MI.getOperand(OpNo).isReg()); 643 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 644 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 645 646 return (OffBits & 0x0FFF) | RegBits; 647 } 648 649 unsigned 650 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo, 651 SmallVectorImpl<MCFixup> &Fixups, 652 const MCSubtargetInfo &STI) const { 653 assert(MI.getOperand(OpNo).isImm()); 654 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 655 return SizeEncoding - 1; 656 } 657 658 // FIXME: should be called getMSBEncoding 659 // 660 unsigned 661 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 662 SmallVectorImpl<MCFixup> &Fixups, 663 const MCSubtargetInfo &STI) const { 664 assert(MI.getOperand(OpNo-1).isImm()); 665 assert(MI.getOperand(OpNo).isImm()); 666 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 667 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 668 669 return Position + Size - 1; 670 } 671 672 unsigned 673 MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, 674 SmallVectorImpl<MCFixup> &Fixups, 675 const MCSubtargetInfo &STI) const { 676 assert(MI.getOperand(OpNo).isImm()); 677 // The immediate is encoded as 'immediate - 1'. 678 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1; 679 } 680 681 unsigned 682 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 683 SmallVectorImpl<MCFixup> &Fixups, 684 const MCSubtargetInfo &STI) const { 685 const MCOperand &MO = MI.getOperand(OpNo); 686 if (MO.isImm()) { 687 // The immediate is encoded as 'immediate << 2'. 688 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 689 assert((Res & 3) == 0); 690 return Res >> 2; 691 } 692 693 assert(MO.isExpr() && 694 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 695 696 const MCExpr *Expr = MO.getExpr(); 697 Fixups.push_back(MCFixup::Create(0, Expr, 698 MCFixupKind(Mips::fixup_MIPS_PC19_S2))); 699 return 0; 700 } 701 702 unsigned 703 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 704 SmallVectorImpl<MCFixup> &Fixups, 705 const MCSubtargetInfo &STI) const { 706 const MCOperand &MO = MI.getOperand(OpNo); 707 if (MO.isImm()) { 708 // The immediate is encoded as 'immediate << 3'. 709 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 710 assert((Res & 7) == 0); 711 return Res >> 3; 712 } 713 714 assert(MO.isExpr() && 715 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 716 717 const MCExpr *Expr = MO.getExpr(); 718 Fixups.push_back(MCFixup::Create(0, Expr, 719 MCFixupKind(Mips::fixup_MIPS_PC18_S3))); 720 return 0; 721 } 722 723 unsigned 724 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 725 SmallVectorImpl<MCFixup> &Fixups, 726 const MCSubtargetInfo &STI) const { 727 assert(MI.getOperand(OpNo).isImm()); 728 const MCOperand &MO = MI.getOperand(OpNo); 729 return MO.getImm() % 8; 730 } 731 732 #include "MipsGenMCCodeEmitter.inc" 733