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/MCFixup.h" 24#include "llvm/MC/MCInst.h" 25#include "llvm/MC/MCInstrInfo.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 35namespace llvm { 36MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 37 const MCRegisterInfo &MRI, 38 MCContext &Ctx) { 39 return new MipsMCCodeEmitter(MCII, Ctx, false); 40} 41 42MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 43 const MCRegisterInfo &MRI, 44 MCContext &Ctx) { 45 return new MipsMCCodeEmitter(MCII, Ctx, true); 46} 47} // End of namespace llvm. 48 49// If the D<shift> instruction has a shift amount that is greater 50// than 31 (checked in calling routine), lower it to a D<shift>32 instruction 51static void LowerLargeShift(MCInst& Inst) { 52 53 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 54 assert(Inst.getOperand(2).isImm()); 55 56 int64_t Shift = Inst.getOperand(2).getImm(); 57 if (Shift <= 31) 58 return; // Do nothing 59 Shift -= 32; 60 61 // saminus32 62 Inst.getOperand(2).setImm(Shift); 63 64 switch (Inst.getOpcode()) { 65 default: 66 // Calling function is not synchronized 67 llvm_unreachable("Unexpected shift instruction"); 68 case Mips::DSLL: 69 Inst.setOpcode(Mips::DSLL32); 70 return; 71 case Mips::DSRL: 72 Inst.setOpcode(Mips::DSRL32); 73 return; 74 case Mips::DSRA: 75 Inst.setOpcode(Mips::DSRA32); 76 return; 77 case Mips::DROTR: 78 Inst.setOpcode(Mips::DROTR32); 79 return; 80 } 81} 82 83// Pick a DEXT or DINS instruction variant based on the pos and size operands 84static void LowerDextDins(MCInst& InstIn) { 85 int Opcode = InstIn.getOpcode(); 86 87 if (Opcode == Mips::DEXT) 88 assert(InstIn.getNumOperands() == 4 && 89 "Invalid no. of machine operands for DEXT!"); 90 else // Only DEXT and DINS are possible 91 assert(InstIn.getNumOperands() == 5 && 92 "Invalid no. of machine operands for DINS!"); 93 94 assert(InstIn.getOperand(2).isImm()); 95 int64_t pos = InstIn.getOperand(2).getImm(); 96 assert(InstIn.getOperand(3).isImm()); 97 int64_t size = InstIn.getOperand(3).getImm(); 98 99 if (size <= 32) { 100 if (pos < 32) // DEXT/DINS, do nothing 101 return; 102 // DEXTU/DINSU 103 InstIn.getOperand(2).setImm(pos - 32); 104 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); 105 return; 106 } 107 // DEXTM/DINSM 108 assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); 109 InstIn.getOperand(3).setImm(size - 32); 110 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); 111 return; 112} 113 114bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 115 return STI.getFeatureBits() & Mips::FeatureMicroMips; 116} 117 118void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 119 OS << (char)C; 120} 121 122void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 123 const MCSubtargetInfo &STI, 124 raw_ostream &OS) const { 125 // Output the instruction encoding in little endian byte order. 126 // Little-endian byte ordering: 127 // mips32r2: 4 | 3 | 2 | 1 128 // microMIPS: 2 | 1 | 4 | 3 129 if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 130 EmitInstruction(Val >> 16, 2, STI, OS); 131 EmitInstruction(Val, 2, STI, OS); 132 } else { 133 for (unsigned i = 0; i < Size; ++i) { 134 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 135 EmitByte((Val >> Shift) & 0xff, OS); 136 } 137 } 138} 139 140/// EncodeInstruction - Emit the instruction. 141/// Size the instruction with Desc.getSize(). 142void MipsMCCodeEmitter:: 143EncodeInstruction(const MCInst &MI, raw_ostream &OS, 144 SmallVectorImpl<MCFixup> &Fixups, 145 const MCSubtargetInfo &STI) const 146{ 147 148 // Non-pseudo instructions that get changed for direct object 149 // only based on operand values. 150 // If this list of instructions get much longer we will move 151 // the check to a function call. Until then, this is more efficient. 152 MCInst TmpInst = MI; 153 switch (MI.getOpcode()) { 154 // If shift amount is >= 32 it the inst needs to be lowered further 155 case Mips::DSLL: 156 case Mips::DSRL: 157 case Mips::DSRA: 158 case Mips::DROTR: 159 LowerLargeShift(TmpInst); 160 break; 161 // Double extract instruction is chosen by pos and size operands 162 case Mips::DEXT: 163 case Mips::DINS: 164 LowerDextDins(TmpInst); 165 } 166 167 unsigned long N = Fixups.size(); 168 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 169 170 // Check for unimplemented opcodes. 171 // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 172 // so we have to special check for them. 173 unsigned Opcode = TmpInst.getOpcode(); 174 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 175 (Opcode != Mips::SLL_MM) && !Binary) 176 llvm_unreachable("unimplemented opcode in EncodeInstruction()"); 177 178 if (STI.getFeatureBits() & Mips::FeatureMicroMips) { 179 int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips); 180 if (NewOpcode != -1) { 181 if (Fixups.size() > N) 182 Fixups.pop_back(); 183 Opcode = NewOpcode; 184 TmpInst.setOpcode (NewOpcode); 185 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 186 } 187 } 188 189 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 190 191 // Get byte count of instruction 192 unsigned Size = Desc.getSize(); 193 if (!Size) 194 llvm_unreachable("Desc.getSize() returns 0"); 195 196 EmitInstruction(Binary, Size, STI, OS); 197} 198 199/// getBranchTargetOpValue - Return binary encoding of the branch 200/// target operand. If the machine operand requires relocation, 201/// record the relocation and return zero. 202unsigned MipsMCCodeEmitter:: 203getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 204 SmallVectorImpl<MCFixup> &Fixups, 205 const MCSubtargetInfo &STI) const { 206 207 const MCOperand &MO = MI.getOperand(OpNo); 208 209 // If the destination is an immediate, divide by 4. 210 if (MO.isImm()) return MO.getImm() >> 2; 211 212 assert(MO.isExpr() && 213 "getBranchTargetOpValue expects only expressions or immediates"); 214 215 const MCExpr *Expr = MO.getExpr(); 216 Fixups.push_back(MCFixup::Create(0, Expr, 217 MCFixupKind(Mips::fixup_Mips_PC16))); 218 return 0; 219} 220 221/// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 222/// target operand. If the machine operand requires relocation, 223/// record the relocation and return zero. 224unsigned MipsMCCodeEmitter:: 225getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 226 SmallVectorImpl<MCFixup> &Fixups, 227 const MCSubtargetInfo &STI) const { 228 229 const MCOperand &MO = MI.getOperand(OpNo); 230 231 // If the destination is an immediate, divide by 2. 232 if (MO.isImm()) return MO.getImm() >> 1; 233 234 assert(MO.isExpr() && 235 "getBranchTargetOpValueMM expects only expressions or immediates"); 236 237 const MCExpr *Expr = MO.getExpr(); 238 Fixups.push_back(MCFixup::Create(0, Expr, 239 MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 240 return 0; 241} 242 243/// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 244/// 10-bit branch target operand. If the machine operand requires relocation, 245/// record the relocation and return zero. 246unsigned MipsMCCodeEmitter:: 247getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 248 SmallVectorImpl<MCFixup> &Fixups, 249 const MCSubtargetInfo &STI) const { 250 251 const MCOperand &MO = MI.getOperand(OpNo); 252 253 // If the destination is an immediate, divide by 2. 254 if (MO.isImm()) return MO.getImm() >> 1; 255 256 assert(MO.isExpr() && 257 "getBranchTargetOpValuePC10 expects only expressions or immediates"); 258 259 const MCExpr *Expr = MO.getExpr(); 260 Fixups.push_back(MCFixup::Create(0, Expr, 261 MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 262 return 0; 263} 264 265/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 266/// target operand. If the machine operand requires relocation, 267/// record the relocation and return zero. 268unsigned MipsMCCodeEmitter:: 269getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 270 SmallVectorImpl<MCFixup> &Fixups, 271 const MCSubtargetInfo &STI) const { 272 273 const MCOperand &MO = MI.getOperand(OpNo); 274 275 // If the destination is an immediate, divide by 2. 276 if (MO.isImm()) return MO.getImm() >> 1; 277 278 assert(MO.isExpr() && 279 "getBranchTargetOpValueMM expects only expressions or immediates"); 280 281 const MCExpr *Expr = MO.getExpr(); 282 Fixups.push_back(MCFixup::Create(0, Expr, 283 MCFixupKind(Mips:: 284 fixup_MICROMIPS_PC16_S1))); 285 return 0; 286} 287 288/// getBranchTarget21OpValue - Return binary encoding of the branch 289/// target operand. If the machine operand requires relocation, 290/// record the relocation and return zero. 291unsigned MipsMCCodeEmitter:: 292getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 293 SmallVectorImpl<MCFixup> &Fixups, 294 const MCSubtargetInfo &STI) const { 295 296 const MCOperand &MO = MI.getOperand(OpNo); 297 298 // If the destination is an immediate, divide by 4. 299 if (MO.isImm()) return MO.getImm() >> 2; 300 301 assert(MO.isExpr() && 302 "getBranchTarget21OpValue expects only expressions or immediates"); 303 304 const MCExpr *Expr = MO.getExpr(); 305 Fixups.push_back(MCFixup::Create(0, Expr, 306 MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 307 return 0; 308} 309 310/// getBranchTarget26OpValue - Return binary encoding of the branch 311/// target operand. If the machine operand requires relocation, 312/// record the relocation and return zero. 313unsigned MipsMCCodeEmitter:: 314getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 315 SmallVectorImpl<MCFixup> &Fixups, 316 const MCSubtargetInfo &STI) const { 317 318 const MCOperand &MO = MI.getOperand(OpNo); 319 320 // If the destination is an immediate, divide by 4. 321 if (MO.isImm()) return MO.getImm() >> 2; 322 323 assert(MO.isExpr() && 324 "getBranchTarget26OpValue expects only expressions or immediates"); 325 326 const MCExpr *Expr = MO.getExpr(); 327 Fixups.push_back(MCFixup::Create(0, Expr, 328 MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 329 return 0; 330} 331 332/// getJumpOffset16OpValue - Return binary encoding of the jump 333/// target operand. If the machine operand requires relocation, 334/// record the relocation and return zero. 335unsigned MipsMCCodeEmitter:: 336getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 337 SmallVectorImpl<MCFixup> &Fixups, 338 const MCSubtargetInfo &STI) const { 339 340 const MCOperand &MO = MI.getOperand(OpNo); 341 342 if (MO.isImm()) return MO.getImm(); 343 344 assert(MO.isExpr() && 345 "getJumpOffset16OpValue expects only expressions or an immediate"); 346 347 // TODO: Push fixup. 348 return 0; 349} 350 351/// getJumpTargetOpValue - Return binary encoding of the jump 352/// target operand. If the machine operand requires relocation, 353/// record the relocation and return zero. 354unsigned MipsMCCodeEmitter:: 355getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 356 SmallVectorImpl<MCFixup> &Fixups, 357 const MCSubtargetInfo &STI) const { 358 359 const MCOperand &MO = MI.getOperand(OpNo); 360 // If the destination is an immediate, divide by 4. 361 if (MO.isImm()) return MO.getImm()>>2; 362 363 assert(MO.isExpr() && 364 "getJumpTargetOpValue expects only expressions or an immediate"); 365 366 const MCExpr *Expr = MO.getExpr(); 367 Fixups.push_back(MCFixup::Create(0, Expr, 368 MCFixupKind(Mips::fixup_Mips_26))); 369 return 0; 370} 371 372unsigned MipsMCCodeEmitter:: 373getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 374 SmallVectorImpl<MCFixup> &Fixups, 375 const MCSubtargetInfo &STI) const { 376 377 const MCOperand &MO = MI.getOperand(OpNo); 378 // If the destination is an immediate, divide by 2. 379 if (MO.isImm()) return MO.getImm() >> 1; 380 381 assert(MO.isExpr() && 382 "getJumpTargetOpValueMM expects only expressions or an immediate"); 383 384 const MCExpr *Expr = MO.getExpr(); 385 Fixups.push_back(MCFixup::Create(0, Expr, 386 MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 387 return 0; 388} 389 390unsigned MipsMCCodeEmitter:: 391getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 392 SmallVectorImpl<MCFixup> &Fixups, 393 const MCSubtargetInfo &STI) const { 394 395 const MCOperand &MO = MI.getOperand(OpNo); 396 if (MO.isImm()) { 397 // The immediate is encoded as 'immediate << 2'. 398 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 399 assert((Res & 3) == 0); 400 return Res >> 2; 401 } 402 403 assert(MO.isExpr() && 404 "getUImm5Lsl2Encoding expects only expressions or an immediate"); 405 406 return 0; 407} 408 409unsigned MipsMCCodeEmitter:: 410getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 411 SmallVectorImpl<MCFixup> &Fixups, 412 const MCSubtargetInfo &STI) const { 413 414 const MCOperand &MO = MI.getOperand(OpNo); 415 if (MO.isImm()) { 416 int Value = MO.getImm(); 417 return Value >> 2; 418 } 419 420 return 0; 421} 422 423unsigned MipsMCCodeEmitter:: 424getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 425 SmallVectorImpl<MCFixup> &Fixups, 426 const MCSubtargetInfo &STI) const { 427 428 const MCOperand &MO = MI.getOperand(OpNo); 429 if (MO.isImm()) { 430 unsigned Value = MO.getImm(); 431 return Value >> 2; 432 } 433 434 return 0; 435} 436 437unsigned MipsMCCodeEmitter:: 438getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 439 SmallVectorImpl<MCFixup> &Fixups, 440 const MCSubtargetInfo &STI) const { 441 442 const MCOperand &MO = MI.getOperand(OpNo); 443 if (MO.isImm()) { 444 unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 445 return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 446 } 447 448 return 0; 449} 450 451unsigned MipsMCCodeEmitter:: 452getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 453 const MCSubtargetInfo &STI) const { 454 int64_t Res; 455 456 if (Expr->EvaluateAsAbsolute(Res)) 457 return Res; 458 459 MCExpr::ExprKind Kind = Expr->getKind(); 460 if (Kind == MCExpr::Constant) { 461 return cast<MCConstantExpr>(Expr)->getValue(); 462 } 463 464 if (Kind == MCExpr::Binary) { 465 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 466 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 467 return Res; 468 } 469 470 if (Kind == MCExpr::Target) { 471 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 472 473 Mips::Fixups FixupKind = Mips::Fixups(0); 474 switch (MipsExpr->getKind()) { 475 default: llvm_unreachable("Unsupported fixup kind for target expression!"); 476 case MipsMCExpr::VK_Mips_HIGHEST: 477 FixupKind = Mips::fixup_Mips_HIGHEST; 478 break; 479 case MipsMCExpr::VK_Mips_HIGHER: 480 FixupKind = Mips::fixup_Mips_HIGHER; 481 break; 482 case MipsMCExpr::VK_Mips_HI: 483 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 484 : Mips::fixup_Mips_HI16; 485 break; 486 case MipsMCExpr::VK_Mips_LO: 487 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 488 : Mips::fixup_Mips_LO16; 489 break; 490 } 491 Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind))); 492 return 0; 493 } 494 495 if (Kind == MCExpr::SymbolRef) { 496 Mips::Fixups FixupKind = Mips::Fixups(0); 497 498 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 499 default: llvm_unreachable("Unknown fixup kind!"); 500 break; 501 case MCSymbolRefExpr::VK_None: 502 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 503 break; 504 case MCSymbolRefExpr::VK_Mips_GPOFF_HI : 505 FixupKind = Mips::fixup_Mips_GPOFF_HI; 506 break; 507 case MCSymbolRefExpr::VK_Mips_GPOFF_LO : 508 FixupKind = Mips::fixup_Mips_GPOFF_LO; 509 break; 510 case MCSymbolRefExpr::VK_Mips_GOT_PAGE : 511 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 512 : Mips::fixup_Mips_GOT_PAGE; 513 break; 514 case MCSymbolRefExpr::VK_Mips_GOT_OFST : 515 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 516 : Mips::fixup_Mips_GOT_OFST; 517 break; 518 case MCSymbolRefExpr::VK_Mips_GOT_DISP : 519 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 520 : Mips::fixup_Mips_GOT_DISP; 521 break; 522 case MCSymbolRefExpr::VK_Mips_GPREL: 523 FixupKind = Mips::fixup_Mips_GPREL16; 524 break; 525 case MCSymbolRefExpr::VK_Mips_GOT_CALL: 526 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 527 : Mips::fixup_Mips_CALL16; 528 break; 529 case MCSymbolRefExpr::VK_Mips_GOT16: 530 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 531 : Mips::fixup_Mips_GOT_Global; 532 break; 533 case MCSymbolRefExpr::VK_Mips_GOT: 534 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 535 : Mips::fixup_Mips_GOT_Local; 536 break; 537 case MCSymbolRefExpr::VK_Mips_ABS_HI: 538 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 539 : Mips::fixup_Mips_HI16; 540 break; 541 case MCSymbolRefExpr::VK_Mips_ABS_LO: 542 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 543 : Mips::fixup_Mips_LO16; 544 break; 545 case MCSymbolRefExpr::VK_Mips_TLSGD: 546 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 547 : Mips::fixup_Mips_TLSGD; 548 break; 549 case MCSymbolRefExpr::VK_Mips_TLSLDM: 550 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 551 : Mips::fixup_Mips_TLSLDM; 552 break; 553 case MCSymbolRefExpr::VK_Mips_DTPREL_HI: 554 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 555 : Mips::fixup_Mips_DTPREL_HI; 556 break; 557 case MCSymbolRefExpr::VK_Mips_DTPREL_LO: 558 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 559 : Mips::fixup_Mips_DTPREL_LO; 560 break; 561 case MCSymbolRefExpr::VK_Mips_GOTTPREL: 562 FixupKind = Mips::fixup_Mips_GOTTPREL; 563 break; 564 case MCSymbolRefExpr::VK_Mips_TPREL_HI: 565 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 566 : Mips::fixup_Mips_TPREL_HI; 567 break; 568 case MCSymbolRefExpr::VK_Mips_TPREL_LO: 569 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 570 : Mips::fixup_Mips_TPREL_LO; 571 break; 572 case MCSymbolRefExpr::VK_Mips_HIGHER: 573 FixupKind = Mips::fixup_Mips_HIGHER; 574 break; 575 case MCSymbolRefExpr::VK_Mips_HIGHEST: 576 FixupKind = Mips::fixup_Mips_HIGHEST; 577 break; 578 case MCSymbolRefExpr::VK_Mips_GOT_HI16: 579 FixupKind = Mips::fixup_Mips_GOT_HI16; 580 break; 581 case MCSymbolRefExpr::VK_Mips_GOT_LO16: 582 FixupKind = Mips::fixup_Mips_GOT_LO16; 583 break; 584 case MCSymbolRefExpr::VK_Mips_CALL_HI16: 585 FixupKind = Mips::fixup_Mips_CALL_HI16; 586 break; 587 case MCSymbolRefExpr::VK_Mips_CALL_LO16: 588 FixupKind = Mips::fixup_Mips_CALL_LO16; 589 break; 590 case MCSymbolRefExpr::VK_Mips_PCREL_HI16: 591 FixupKind = Mips::fixup_MIPS_PCHI16; 592 break; 593 case MCSymbolRefExpr::VK_Mips_PCREL_LO16: 594 FixupKind = Mips::fixup_MIPS_PCLO16; 595 break; 596 } // switch 597 598 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind))); 599 return 0; 600 } 601 return 0; 602} 603 604/// getMachineOpValue - Return binary encoding of operand. If the machine 605/// operand requires relocation, record the relocation and return zero. 606unsigned MipsMCCodeEmitter:: 607getMachineOpValue(const MCInst &MI, const MCOperand &MO, 608 SmallVectorImpl<MCFixup> &Fixups, 609 const MCSubtargetInfo &STI) const { 610 if (MO.isReg()) { 611 unsigned Reg = MO.getReg(); 612 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 613 return RegNo; 614 } else if (MO.isImm()) { 615 return static_cast<unsigned>(MO.getImm()); 616 } else if (MO.isFPImm()) { 617 return static_cast<unsigned>(APFloat(MO.getFPImm()) 618 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 619 } 620 // MO must be an Expr. 621 assert(MO.isExpr()); 622 return getExprOpValue(MO.getExpr(),Fixups, STI); 623} 624 625/// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST 626/// instructions. 627unsigned 628MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo, 629 SmallVectorImpl<MCFixup> &Fixups, 630 const MCSubtargetInfo &STI) const { 631 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 632 assert(MI.getOperand(OpNo).isReg()); 633 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 634 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 635 636 // The immediate field of an LD/ST instruction is scaled which means it must 637 // be divided (when encoding) by the size (in bytes) of the instructions' 638 // data format. 639 // .b - 1 byte 640 // .h - 2 bytes 641 // .w - 4 bytes 642 // .d - 8 bytes 643 switch(MI.getOpcode()) 644 { 645 default: 646 assert (0 && "Unexpected instruction"); 647 break; 648 case Mips::LD_B: 649 case Mips::ST_B: 650 // We don't need to scale the offset in this case 651 break; 652 case Mips::LD_H: 653 case Mips::ST_H: 654 OffBits >>= 1; 655 break; 656 case Mips::LD_W: 657 case Mips::ST_W: 658 OffBits >>= 2; 659 break; 660 case Mips::LD_D: 661 case Mips::ST_D: 662 OffBits >>= 3; 663 break; 664 } 665 666 return (OffBits & 0xFFFF) | RegBits; 667} 668 669/// getMemEncoding - Return binary encoding of memory related operand. 670/// If the offset operand requires relocation, record the relocation. 671unsigned 672MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 673 SmallVectorImpl<MCFixup> &Fixups, 674 const MCSubtargetInfo &STI) const { 675 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 676 assert(MI.getOperand(OpNo).isReg()); 677 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 678 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 679 680 return (OffBits & 0xFFFF) | RegBits; 681} 682 683unsigned MipsMCCodeEmitter:: 684getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 685 SmallVectorImpl<MCFixup> &Fixups, 686 const MCSubtargetInfo &STI) const { 687 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 688 assert(MI.getOperand(OpNo).isReg()); 689 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 690 Fixups, STI) << 4; 691 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 692 Fixups, STI); 693 694 return (OffBits & 0xF) | RegBits; 695} 696 697unsigned MipsMCCodeEmitter:: 698getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 699 SmallVectorImpl<MCFixup> &Fixups, 700 const MCSubtargetInfo &STI) const { 701 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 702 assert(MI.getOperand(OpNo).isReg()); 703 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 704 Fixups, STI) << 4; 705 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 706 Fixups, STI) >> 1; 707 708 return (OffBits & 0xF) | RegBits; 709} 710 711unsigned MipsMCCodeEmitter:: 712getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 713 SmallVectorImpl<MCFixup> &Fixups, 714 const MCSubtargetInfo &STI) const { 715 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 716 assert(MI.getOperand(OpNo).isReg()); 717 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 718 Fixups, STI) << 4; 719 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 720 Fixups, STI) >> 2; 721 722 return (OffBits & 0xF) | RegBits; 723} 724 725unsigned MipsMCCodeEmitter:: 726getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 727 SmallVectorImpl<MCFixup> &Fixups, 728 const MCSubtargetInfo &STI) const { 729 // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 730 assert(MI.getOperand(OpNo).isReg() && 731 MI.getOperand(OpNo).getReg() == Mips::SP && 732 "Unexpected base register!"); 733 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 734 Fixups, STI) >> 2; 735 736 return OffBits & 0x1F; 737} 738 739unsigned MipsMCCodeEmitter:: 740getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 741 SmallVectorImpl<MCFixup> &Fixups, 742 const MCSubtargetInfo &STI) const { 743 // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 744 assert(MI.getOperand(OpNo).isReg() && 745 MI.getOperand(OpNo).getReg() == Mips::GP && 746 "Unexpected base register!"); 747 748 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 749 Fixups, STI) >> 2; 750 751 return OffBits & 0x7F; 752} 753 754unsigned MipsMCCodeEmitter:: 755getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 756 SmallVectorImpl<MCFixup> &Fixups, 757 const MCSubtargetInfo &STI) const { 758 // opNum can be invalid if instruction had reglist as operand. 759 // MemOperand is always last operand of instruction (base + offset). 760 switch (MI.getOpcode()) { 761 default: 762 break; 763 case Mips::SWM32_MM: 764 case Mips::LWM32_MM: 765 OpNo = MI.getNumOperands() - 2; 766 break; 767 } 768 769 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 770 assert(MI.getOperand(OpNo).isReg()); 771 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 772 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 773 774 return (OffBits & 0x0FFF) | RegBits; 775} 776 777unsigned MipsMCCodeEmitter:: 778getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 779 SmallVectorImpl<MCFixup> &Fixups, 780 const MCSubtargetInfo &STI) const { 781 // opNum can be invalid if instruction had reglist as operand 782 // MemOperand is always last operand of instruction (base + offset) 783 switch (MI.getOpcode()) { 784 default: 785 break; 786 case Mips::SWM16_MM: 787 case Mips::LWM16_MM: 788 OpNo = MI.getNumOperands() - 2; 789 break; 790 } 791 792 // Offset is encoded in bits 4-0. 793 assert(MI.getOperand(OpNo).isReg()); 794 // Base register is always SP - thus it is not encoded. 795 assert(MI.getOperand(OpNo+1).isImm()); 796 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 797 798 return ((OffBits >> 2) & 0x0F); 799} 800 801unsigned 802MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo, 803 SmallVectorImpl<MCFixup> &Fixups, 804 const MCSubtargetInfo &STI) const { 805 assert(MI.getOperand(OpNo).isImm()); 806 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 807 return SizeEncoding - 1; 808} 809 810// FIXME: should be called getMSBEncoding 811// 812unsigned 813MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 814 SmallVectorImpl<MCFixup> &Fixups, 815 const MCSubtargetInfo &STI) const { 816 assert(MI.getOperand(OpNo-1).isImm()); 817 assert(MI.getOperand(OpNo).isImm()); 818 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 819 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 820 821 return Position + Size - 1; 822} 823 824unsigned 825MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, 826 SmallVectorImpl<MCFixup> &Fixups, 827 const MCSubtargetInfo &STI) const { 828 assert(MI.getOperand(OpNo).isImm()); 829 // The immediate is encoded as 'immediate - 1'. 830 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1; 831} 832 833unsigned 834MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 835 SmallVectorImpl<MCFixup> &Fixups, 836 const MCSubtargetInfo &STI) const { 837 const MCOperand &MO = MI.getOperand(OpNo); 838 if (MO.isImm()) { 839 // The immediate is encoded as 'immediate << 2'. 840 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 841 assert((Res & 3) == 0); 842 return Res >> 2; 843 } 844 845 assert(MO.isExpr() && 846 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 847 848 const MCExpr *Expr = MO.getExpr(); 849 Fixups.push_back(MCFixup::Create(0, Expr, 850 MCFixupKind(Mips::fixup_MIPS_PC19_S2))); 851 return 0; 852} 853 854unsigned 855MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 856 SmallVectorImpl<MCFixup> &Fixups, 857 const MCSubtargetInfo &STI) const { 858 const MCOperand &MO = MI.getOperand(OpNo); 859 if (MO.isImm()) { 860 // The immediate is encoded as 'immediate << 3'. 861 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 862 assert((Res & 7) == 0); 863 return Res >> 3; 864 } 865 866 assert(MO.isExpr() && 867 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 868 869 const MCExpr *Expr = MO.getExpr(); 870 Fixups.push_back(MCFixup::Create(0, Expr, 871 MCFixupKind(Mips::fixup_MIPS_PC18_S3))); 872 return 0; 873} 874 875unsigned 876MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 877 SmallVectorImpl<MCFixup> &Fixups, 878 const MCSubtargetInfo &STI) const { 879 assert(MI.getOperand(OpNo).isImm()); 880 const MCOperand &MO = MI.getOperand(OpNo); 881 return MO.getImm() % 8; 882} 883 884unsigned 885MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 886 SmallVectorImpl<MCFixup> &Fixups, 887 const MCSubtargetInfo &STI) const { 888 assert(MI.getOperand(OpNo).isImm()); 889 const MCOperand &MO = MI.getOperand(OpNo); 890 unsigned Value = MO.getImm(); 891 switch (Value) { 892 case 128: return 0x0; 893 case 1: return 0x1; 894 case 2: return 0x2; 895 case 3: return 0x3; 896 case 4: return 0x4; 897 case 7: return 0x5; 898 case 8: return 0x6; 899 case 15: return 0x7; 900 case 16: return 0x8; 901 case 31: return 0x9; 902 case 32: return 0xa; 903 case 63: return 0xb; 904 case 64: return 0xc; 905 case 255: return 0xd; 906 case 32768: return 0xe; 907 case 65535: return 0xf; 908 } 909 llvm_unreachable("Unexpected value"); 910} 911 912unsigned 913MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 914 SmallVectorImpl<MCFixup> &Fixups, 915 const MCSubtargetInfo &STI) const { 916 unsigned res = 0; 917 918 // Register list operand is always first operand of instruction and it is 919 // placed before memory operand (register + imm). 920 921 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 922 unsigned Reg = MI.getOperand(I).getReg(); 923 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 924 if (RegNo != 31) 925 res++; 926 else 927 res |= 0x10; 928 } 929 return res; 930} 931 932unsigned 933MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 934 SmallVectorImpl<MCFixup> &Fixups, 935 const MCSubtargetInfo &STI) const { 936 return (MI.getNumOperands() - 4); 937} 938 939unsigned 940MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 941 SmallVectorImpl<MCFixup> &Fixups, 942 const MCSubtargetInfo &STI) const { 943 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 944} 945 946unsigned 947MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 948 SmallVectorImpl<MCFixup> &Fixups, 949 const MCSubtargetInfo &STI) const { 950 unsigned res = 0; 951 952 if (MI.getOperand(0).getReg() == Mips::A1 && 953 MI.getOperand(1).getReg() == Mips::A2) 954 res = 0; 955 else if (MI.getOperand(0).getReg() == Mips::A1 && 956 MI.getOperand(1).getReg() == Mips::A3) 957 res = 1; 958 else if (MI.getOperand(0).getReg() == Mips::A2 && 959 MI.getOperand(1).getReg() == Mips::A3) 960 res = 2; 961 else if (MI.getOperand(0).getReg() == Mips::A0 && 962 MI.getOperand(1).getReg() == Mips::S5) 963 res = 3; 964 else if (MI.getOperand(0).getReg() == Mips::A0 && 965 MI.getOperand(1).getReg() == Mips::S6) 966 res = 4; 967 else if (MI.getOperand(0).getReg() == Mips::A0 && 968 MI.getOperand(1).getReg() == Mips::A1) 969 res = 5; 970 else if (MI.getOperand(0).getReg() == Mips::A0 && 971 MI.getOperand(1).getReg() == Mips::A2) 972 res = 6; 973 else if (MI.getOperand(0).getReg() == Mips::A0 && 974 MI.getOperand(1).getReg() == Mips::A3) 975 res = 7; 976 977 return res; 978} 979 980unsigned 981MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 982 SmallVectorImpl<MCFixup> &Fixups, 983 const MCSubtargetInfo &STI) const { 984 const MCOperand &MO = MI.getOperand(OpNo); 985 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 986 // The immediate is encoded as 'immediate >> 2'. 987 unsigned Res = static_cast<unsigned>(MO.getImm()); 988 assert((Res & 3) == 0); 989 return Res >> 2; 990} 991 992#include "MipsGenMCCodeEmitter.inc" 993