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 #include "MCTargetDesc/MipsFixupKinds.h" 15 #include "MCTargetDesc/MipsMCExpr.h" 16 #include "MCTargetDesc/MipsMCTargetDesc.h" 17 #include "MipsMCCodeEmitter.h" 18 #include "llvm/ADT/APFloat.h" 19 #include "llvm/ADT/APInt.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/MCInstrDesc.h" 26 #include "llvm/MC/MCInstrInfo.h" 27 #include "llvm/MC/MCRegisterInfo.h" 28 #include "llvm/MC/MCSubtargetInfo.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include <cassert> 33 #include <cstdint> 34 35 using namespace llvm; 36 37 #define DEBUG_TYPE "mccodeemitter" 38 39 #define GET_INSTRMAP_INFO 40 #include "MipsGenInstrInfo.inc" 41 #undef GET_INSTRMAP_INFO 42 43 namespace llvm { 44 45 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 46 const MCRegisterInfo &MRI, 47 MCContext &Ctx) { 48 return new MipsMCCodeEmitter(MCII, Ctx, false); 49 } 50 51 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 52 const MCRegisterInfo &MRI, 53 MCContext &Ctx) { 54 return new MipsMCCodeEmitter(MCII, Ctx, true); 55 } 56 57 } // end namespace llvm 58 59 // If the D<shift> instruction has a shift amount that is greater 60 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 61 static void LowerLargeShift(MCInst& Inst) { 62 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 63 assert(Inst.getOperand(2).isImm()); 64 65 int64_t Shift = Inst.getOperand(2).getImm(); 66 if (Shift <= 31) 67 return; // Do nothing 68 Shift -= 32; 69 70 // saminus32 71 Inst.getOperand(2).setImm(Shift); 72 73 switch (Inst.getOpcode()) { 74 default: 75 // Calling function is not synchronized 76 llvm_unreachable("Unexpected shift instruction"); 77 case Mips::DSLL: 78 Inst.setOpcode(Mips::DSLL32); 79 return; 80 case Mips::DSRL: 81 Inst.setOpcode(Mips::DSRL32); 82 return; 83 case Mips::DSRA: 84 Inst.setOpcode(Mips::DSRA32); 85 return; 86 case Mips::DROTR: 87 Inst.setOpcode(Mips::DROTR32); 88 return; 89 case Mips::DSLL_MM64R6: 90 Inst.setOpcode(Mips::DSLL32_MM64R6); 91 return; 92 case Mips::DSRL_MM64R6: 93 Inst.setOpcode(Mips::DSRL32_MM64R6); 94 return; 95 case Mips::DSRA_MM64R6: 96 Inst.setOpcode(Mips::DSRA32_MM64R6); 97 return; 98 case Mips::DROTR_MM64R6: 99 Inst.setOpcode(Mips::DROTR32_MM64R6); 100 return; 101 } 102 } 103 104 // Pick a DINS instruction variant based on the pos and size operands 105 static void LowerDins(MCInst& InstIn) { 106 assert(InstIn.getNumOperands() == 5 && 107 "Invalid no. of machine operands for DINS!"); 108 109 assert(InstIn.getOperand(2).isImm()); 110 int64_t pos = InstIn.getOperand(2).getImm(); 111 assert(InstIn.getOperand(3).isImm()); 112 int64_t size = InstIn.getOperand(3).getImm(); 113 114 if (size <= 32) { 115 if (pos < 32) // DINS, do nothing 116 return; 117 // DINSU 118 InstIn.getOperand(2).setImm(pos - 32); 119 InstIn.setOpcode(Mips::DINSU); 120 return; 121 } 122 // DINSM 123 assert(pos < 32 && "DINS cannot have both size and pos > 32"); 124 InstIn.getOperand(3).setImm(size - 32); 125 InstIn.setOpcode(Mips::DINSM); 126 } 127 128 // Fix a bad compact branch encoding for beqc/bnec. 129 void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { 130 // Encoding may be illegal !(rs < rt), but this situation is 131 // easily fixed. 132 unsigned RegOp0 = Inst.getOperand(0).getReg(); 133 unsigned RegOp1 = Inst.getOperand(1).getReg(); 134 135 unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); 136 unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); 137 138 if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC || 139 Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) { 140 assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!"); 141 if (Reg0 < Reg1) 142 return; 143 } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) { 144 if (Reg0 >= Reg1) 145 return; 146 } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || 147 Inst.getOpcode() == Mips::BOVC_MMR6) { 148 if (Reg1 >= Reg0) 149 return; 150 } else 151 llvm_unreachable("Cannot rewrite unknown branch!"); 152 153 Inst.getOperand(0).setReg(RegOp1); 154 Inst.getOperand(1).setReg(RegOp0); 155 } 156 157 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 158 return STI.getFeatureBits()[Mips::FeatureMicroMips]; 159 } 160 161 bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 162 return STI.getFeatureBits()[Mips::FeatureMips32r6]; 163 } 164 165 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 166 OS << (char)C; 167 } 168 169 void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 170 const MCSubtargetInfo &STI, 171 raw_ostream &OS) const { 172 // Output the instruction encoding in little endian byte order. 173 // Little-endian byte ordering: 174 // mips32r2: 4 | 3 | 2 | 1 175 // microMIPS: 2 | 1 | 4 | 3 176 if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 177 EmitInstruction(Val >> 16, 2, STI, OS); 178 EmitInstruction(Val, 2, STI, OS); 179 } else { 180 for (unsigned i = 0; i < Size; ++i) { 181 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 182 EmitByte((Val >> Shift) & 0xff, OS); 183 } 184 } 185 } 186 187 /// encodeInstruction - Emit the instruction. 188 /// Size the instruction with Desc.getSize(). 189 void MipsMCCodeEmitter:: 190 encodeInstruction(const MCInst &MI, raw_ostream &OS, 191 SmallVectorImpl<MCFixup> &Fixups, 192 const MCSubtargetInfo &STI) const 193 { 194 // Non-pseudo instructions that get changed for direct object 195 // only based on operand values. 196 // If this list of instructions get much longer we will move 197 // the check to a function call. Until then, this is more efficient. 198 MCInst TmpInst = MI; 199 switch (MI.getOpcode()) { 200 // If shift amount is >= 32 it the inst needs to be lowered further 201 case Mips::DSLL: 202 case Mips::DSRL: 203 case Mips::DSRA: 204 case Mips::DROTR: 205 case Mips::DSLL_MM64R6: 206 case Mips::DSRL_MM64R6: 207 case Mips::DSRA_MM64R6: 208 case Mips::DROTR_MM64R6: 209 LowerLargeShift(TmpInst); 210 break; 211 // Double extract instruction is chosen by pos and size operands 212 case Mips::DINS: 213 LowerDins(TmpInst); 214 break; 215 // Compact branches, enforce encoding restrictions. 216 case Mips::BEQC: 217 case Mips::BNEC: 218 case Mips::BEQC64: 219 case Mips::BNEC64: 220 case Mips::BOVC: 221 case Mips::BOVC_MMR6: 222 case Mips::BNVC: 223 case Mips::BNVC_MMR6: 224 LowerCompactBranch(TmpInst); 225 } 226 227 unsigned long N = Fixups.size(); 228 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 229 230 // Check for unimplemented opcodes. 231 // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 232 // so we have to special check for them. 233 unsigned Opcode = TmpInst.getOpcode(); 234 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 235 (Opcode != Mips::SLL_MM) && !Binary) 236 llvm_unreachable("unimplemented opcode in encodeInstruction()"); 237 238 int NewOpcode = -1; 239 if (isMicroMips(STI)) { 240 if (isMips32r6(STI)) { 241 NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 242 if (NewOpcode == -1) 243 NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 244 } 245 else 246 NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 247 248 // Check whether it is Dsp instruction. 249 if (NewOpcode == -1) 250 NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 251 252 if (NewOpcode != -1) { 253 if (Fixups.size() > N) 254 Fixups.pop_back(); 255 256 Opcode = NewOpcode; 257 TmpInst.setOpcode (NewOpcode); 258 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 259 } 260 } 261 262 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 263 264 // Get byte count of instruction 265 unsigned Size = Desc.getSize(); 266 if (!Size) 267 llvm_unreachable("Desc.getSize() returns 0"); 268 269 EmitInstruction(Binary, Size, STI, OS); 270 } 271 272 /// getBranchTargetOpValue - Return binary encoding of the branch 273 /// target operand. If the machine operand requires relocation, 274 /// record the relocation and return zero. 275 unsigned MipsMCCodeEmitter:: 276 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 277 SmallVectorImpl<MCFixup> &Fixups, 278 const MCSubtargetInfo &STI) const { 279 const MCOperand &MO = MI.getOperand(OpNo); 280 281 // If the destination is an immediate, divide by 4. 282 if (MO.isImm()) return MO.getImm() >> 2; 283 284 assert(MO.isExpr() && 285 "getBranchTargetOpValue expects only expressions or immediates"); 286 287 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 288 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 289 Fixups.push_back(MCFixup::create(0, FixupExpression, 290 MCFixupKind(Mips::fixup_Mips_PC16))); 291 return 0; 292 } 293 294 /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 295 /// target operand. If the machine operand requires relocation, 296 /// record the relocation and return zero. 297 unsigned MipsMCCodeEmitter:: 298 getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 299 SmallVectorImpl<MCFixup> &Fixups, 300 const MCSubtargetInfo &STI) const { 301 const MCOperand &MO = MI.getOperand(OpNo); 302 303 // If the destination is an immediate, divide by 2. 304 if (MO.isImm()) return MO.getImm() >> 1; 305 306 assert(MO.isExpr() && 307 "getBranchTargetOpValue expects only expressions or immediates"); 308 309 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 310 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 311 Fixups.push_back(MCFixup::create(0, FixupExpression, 312 MCFixupKind(Mips::fixup_Mips_PC16))); 313 return 0; 314 } 315 316 /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch 317 /// target operand. If the machine operand requires relocation, 318 /// record the relocation and return zero. 319 unsigned MipsMCCodeEmitter:: 320 getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, 321 SmallVectorImpl<MCFixup> &Fixups, 322 const MCSubtargetInfo &STI) const { 323 const MCOperand &MO = MI.getOperand(OpNo); 324 325 // If the destination is an immediate, divide by 2. 326 if (MO.isImm()) 327 return MO.getImm() >> 1; 328 329 assert(MO.isExpr() && 330 "getBranchTargetOpValueMMR6 expects only expressions or immediates"); 331 332 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 333 MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); 334 Fixups.push_back(MCFixup::create(0, FixupExpression, 335 MCFixupKind(Mips::fixup_Mips_PC16))); 336 return 0; 337 } 338 339 /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch 340 /// target operand. If the machine operand requires relocation, 341 /// record the relocation and return zero. 342 unsigned MipsMCCodeEmitter:: 343 getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, 344 SmallVectorImpl<MCFixup> &Fixups, 345 const MCSubtargetInfo &STI) const { 346 const MCOperand &MO = MI.getOperand(OpNo); 347 348 // If the destination is an immediate, divide by 4. 349 if (MO.isImm()) 350 return MO.getImm() >> 2; 351 352 assert(MO.isExpr() && 353 "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates"); 354 355 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 356 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 357 Fixups.push_back(MCFixup::create(0, FixupExpression, 358 MCFixupKind(Mips::fixup_Mips_PC16))); 359 return 0; 360 } 361 362 /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 363 /// target operand. If the machine operand requires relocation, 364 /// record the relocation and return zero. 365 unsigned MipsMCCodeEmitter:: 366 getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 367 SmallVectorImpl<MCFixup> &Fixups, 368 const MCSubtargetInfo &STI) const { 369 const MCOperand &MO = MI.getOperand(OpNo); 370 371 // If the destination is an immediate, divide by 2. 372 if (MO.isImm()) return MO.getImm() >> 1; 373 374 assert(MO.isExpr() && 375 "getBranchTargetOpValueMM expects only expressions or immediates"); 376 377 const MCExpr *Expr = MO.getExpr(); 378 Fixups.push_back(MCFixup::create(0, Expr, 379 MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 380 return 0; 381 } 382 383 /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 384 /// 10-bit branch target operand. If the machine operand requires relocation, 385 /// record the relocation and return zero. 386 unsigned MipsMCCodeEmitter:: 387 getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 388 SmallVectorImpl<MCFixup> &Fixups, 389 const MCSubtargetInfo &STI) const { 390 const MCOperand &MO = MI.getOperand(OpNo); 391 392 // If the destination is an immediate, divide by 2. 393 if (MO.isImm()) return MO.getImm() >> 1; 394 395 assert(MO.isExpr() && 396 "getBranchTargetOpValuePC10 expects only expressions or immediates"); 397 398 const MCExpr *Expr = MO.getExpr(); 399 Fixups.push_back(MCFixup::create(0, Expr, 400 MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 401 return 0; 402 } 403 404 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 405 /// target operand. If the machine operand requires relocation, 406 /// record the relocation and return zero. 407 unsigned MipsMCCodeEmitter:: 408 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 409 SmallVectorImpl<MCFixup> &Fixups, 410 const MCSubtargetInfo &STI) const { 411 const MCOperand &MO = MI.getOperand(OpNo); 412 413 // If the destination is an immediate, divide by 2. 414 if (MO.isImm()) return MO.getImm() >> 1; 415 416 assert(MO.isExpr() && 417 "getBranchTargetOpValueMM expects only expressions or immediates"); 418 419 const MCExpr *Expr = MO.getExpr(); 420 Fixups.push_back(MCFixup::create(0, Expr, 421 MCFixupKind(Mips:: 422 fixup_MICROMIPS_PC16_S1))); 423 return 0; 424 } 425 426 /// getBranchTarget21OpValue - Return binary encoding of the branch 427 /// target operand. If the machine operand requires relocation, 428 /// record the relocation and return zero. 429 unsigned MipsMCCodeEmitter:: 430 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 431 SmallVectorImpl<MCFixup> &Fixups, 432 const MCSubtargetInfo &STI) const { 433 const MCOperand &MO = MI.getOperand(OpNo); 434 435 // If the destination is an immediate, divide by 4. 436 if (MO.isImm()) return MO.getImm() >> 2; 437 438 assert(MO.isExpr() && 439 "getBranchTarget21OpValue expects only expressions or immediates"); 440 441 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 442 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 443 Fixups.push_back(MCFixup::create(0, FixupExpression, 444 MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 445 return 0; 446 } 447 448 /// getBranchTarget21OpValueMM - Return binary encoding of the branch 449 /// target operand for microMIPS. If the machine operand requires 450 /// relocation, record the relocation and return zero. 451 unsigned MipsMCCodeEmitter:: 452 getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 453 SmallVectorImpl<MCFixup> &Fixups, 454 const MCSubtargetInfo &STI) const { 455 const MCOperand &MO = MI.getOperand(OpNo); 456 457 // If the destination is an immediate, divide by 4. 458 if (MO.isImm()) return MO.getImm() >> 2; 459 460 assert(MO.isExpr() && 461 "getBranchTarget21OpValueMM expects only expressions or immediates"); 462 463 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 464 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 465 Fixups.push_back(MCFixup::create(0, FixupExpression, 466 MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 467 return 0; 468 } 469 470 /// getBranchTarget26OpValue - Return binary encoding of the branch 471 /// target operand. If the machine operand requires relocation, 472 /// record the relocation and return zero. 473 unsigned MipsMCCodeEmitter:: 474 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 475 SmallVectorImpl<MCFixup> &Fixups, 476 const MCSubtargetInfo &STI) const { 477 const MCOperand &MO = MI.getOperand(OpNo); 478 479 // If the destination is an immediate, divide by 4. 480 if (MO.isImm()) return MO.getImm() >> 2; 481 482 assert(MO.isExpr() && 483 "getBranchTarget26OpValue expects only expressions or immediates"); 484 485 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 486 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 487 Fixups.push_back(MCFixup::create(0, FixupExpression, 488 MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 489 return 0; 490 } 491 492 /// getBranchTarget26OpValueMM - Return binary encoding of the branch 493 /// target operand. If the machine operand requires relocation, 494 /// record the relocation and return zero. 495 unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 496 const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 497 const MCSubtargetInfo &STI) const { 498 const MCOperand &MO = MI.getOperand(OpNo); 499 500 // If the destination is an immediate, divide by 2. 501 if (MO.isImm()) 502 return MO.getImm() >> 1; 503 504 assert(MO.isExpr() && 505 "getBranchTarget26OpValueMM expects only expressions or immediates"); 506 507 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 508 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 509 Fixups.push_back(MCFixup::create(0, FixupExpression, 510 MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 511 return 0; 512 } 513 514 /// getJumpOffset16OpValue - Return binary encoding of the jump 515 /// target operand. If the machine operand requires relocation, 516 /// record the relocation and return zero. 517 unsigned MipsMCCodeEmitter:: 518 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 519 SmallVectorImpl<MCFixup> &Fixups, 520 const MCSubtargetInfo &STI) const { 521 const MCOperand &MO = MI.getOperand(OpNo); 522 523 if (MO.isImm()) return MO.getImm(); 524 525 assert(MO.isExpr() && 526 "getJumpOffset16OpValue expects only expressions or an immediate"); 527 528 // TODO: Push fixup. 529 return 0; 530 } 531 532 /// getJumpTargetOpValue - Return binary encoding of the jump 533 /// target operand. If the machine operand requires relocation, 534 /// record the relocation and return zero. 535 unsigned MipsMCCodeEmitter:: 536 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 537 SmallVectorImpl<MCFixup> &Fixups, 538 const MCSubtargetInfo &STI) const { 539 const MCOperand &MO = MI.getOperand(OpNo); 540 // If the destination is an immediate, divide by 4. 541 if (MO.isImm()) return MO.getImm()>>2; 542 543 assert(MO.isExpr() && 544 "getJumpTargetOpValue expects only expressions or an immediate"); 545 546 const MCExpr *Expr = MO.getExpr(); 547 Fixups.push_back(MCFixup::create(0, Expr, 548 MCFixupKind(Mips::fixup_Mips_26))); 549 return 0; 550 } 551 552 unsigned MipsMCCodeEmitter:: 553 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 554 SmallVectorImpl<MCFixup> &Fixups, 555 const MCSubtargetInfo &STI) const { 556 const MCOperand &MO = MI.getOperand(OpNo); 557 // If the destination is an immediate, divide by 2. 558 if (MO.isImm()) return MO.getImm() >> 1; 559 560 assert(MO.isExpr() && 561 "getJumpTargetOpValueMM expects only expressions or an immediate"); 562 563 const MCExpr *Expr = MO.getExpr(); 564 Fixups.push_back(MCFixup::create(0, Expr, 565 MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 566 return 0; 567 } 568 569 unsigned MipsMCCodeEmitter:: 570 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 571 SmallVectorImpl<MCFixup> &Fixups, 572 const MCSubtargetInfo &STI) const { 573 const MCOperand &MO = MI.getOperand(OpNo); 574 if (MO.isImm()) { 575 // The immediate is encoded as 'immediate << 2'. 576 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 577 assert((Res & 3) == 0); 578 return Res >> 2; 579 } 580 581 assert(MO.isExpr() && 582 "getUImm5Lsl2Encoding expects only expressions or an immediate"); 583 584 return 0; 585 } 586 587 unsigned MipsMCCodeEmitter:: 588 getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 589 SmallVectorImpl<MCFixup> &Fixups, 590 const MCSubtargetInfo &STI) const { 591 const MCOperand &MO = MI.getOperand(OpNo); 592 if (MO.isImm()) { 593 int Value = MO.getImm(); 594 return Value >> 2; 595 } 596 597 return 0; 598 } 599 600 unsigned MipsMCCodeEmitter:: 601 getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 602 SmallVectorImpl<MCFixup> &Fixups, 603 const MCSubtargetInfo &STI) const { 604 const MCOperand &MO = MI.getOperand(OpNo); 605 if (MO.isImm()) { 606 unsigned Value = MO.getImm(); 607 return Value >> 2; 608 } 609 610 return 0; 611 } 612 613 unsigned MipsMCCodeEmitter:: 614 getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 615 SmallVectorImpl<MCFixup> &Fixups, 616 const MCSubtargetInfo &STI) const { 617 const MCOperand &MO = MI.getOperand(OpNo); 618 if (MO.isImm()) { 619 unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 620 return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 621 } 622 623 return 0; 624 } 625 626 unsigned MipsMCCodeEmitter:: 627 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 628 const MCSubtargetInfo &STI) const { 629 int64_t Res; 630 631 if (Expr->evaluateAsAbsolute(Res)) 632 return Res; 633 634 MCExpr::ExprKind Kind = Expr->getKind(); 635 if (Kind == MCExpr::Constant) { 636 return cast<MCConstantExpr>(Expr)->getValue(); 637 } 638 639 if (Kind == MCExpr::Binary) { 640 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 641 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 642 return Res; 643 } 644 645 if (Kind == MCExpr::Target) { 646 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 647 648 Mips::Fixups FixupKind = Mips::Fixups(0); 649 switch (MipsExpr->getKind()) { 650 case MipsMCExpr::MEK_None: 651 case MipsMCExpr::MEK_Special: 652 llvm_unreachable("Unhandled fixup kind!"); 653 break; 654 case MipsMCExpr::MEK_CALL_HI16: 655 FixupKind = Mips::fixup_Mips_CALL_HI16; 656 break; 657 case MipsMCExpr::MEK_CALL_LO16: 658 FixupKind = Mips::fixup_Mips_CALL_LO16; 659 break; 660 case MipsMCExpr::MEK_DTPREL_HI: 661 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 662 : Mips::fixup_Mips_DTPREL_HI; 663 break; 664 case MipsMCExpr::MEK_DTPREL_LO: 665 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 666 : Mips::fixup_Mips_DTPREL_LO; 667 break; 668 case MipsMCExpr::MEK_GOTTPREL: 669 FixupKind = Mips::fixup_Mips_GOTTPREL; 670 break; 671 case MipsMCExpr::MEK_GOT: 672 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 673 : Mips::fixup_Mips_GOT; 674 break; 675 case MipsMCExpr::MEK_GOT_CALL: 676 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 677 : Mips::fixup_Mips_CALL16; 678 break; 679 case MipsMCExpr::MEK_GOT_DISP: 680 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 681 : Mips::fixup_Mips_GOT_DISP; 682 break; 683 case MipsMCExpr::MEK_GOT_HI16: 684 FixupKind = Mips::fixup_Mips_GOT_HI16; 685 break; 686 case MipsMCExpr::MEK_GOT_LO16: 687 FixupKind = Mips::fixup_Mips_GOT_LO16; 688 break; 689 case MipsMCExpr::MEK_GOT_PAGE: 690 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 691 : Mips::fixup_Mips_GOT_PAGE; 692 break; 693 case MipsMCExpr::MEK_GOT_OFST: 694 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 695 : Mips::fixup_Mips_GOT_OFST; 696 break; 697 case MipsMCExpr::MEK_GPREL: 698 FixupKind = Mips::fixup_Mips_GPREL16; 699 break; 700 case MipsMCExpr::MEK_LO: 701 // Check for %lo(%neg(%gp_rel(X))) 702 if (MipsExpr->isGpOff()) { 703 FixupKind = Mips::fixup_Mips_GPOFF_LO; 704 break; 705 } 706 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 707 : Mips::fixup_Mips_LO16; 708 break; 709 case MipsMCExpr::MEK_HIGHEST: 710 FixupKind = Mips::fixup_Mips_HIGHEST; 711 break; 712 case MipsMCExpr::MEK_HIGHER: 713 FixupKind = Mips::fixup_Mips_HIGHER; 714 break; 715 case MipsMCExpr::MEK_HI: 716 // Check for %hi(%neg(%gp_rel(X))) 717 if (MipsExpr->isGpOff()) { 718 FixupKind = Mips::fixup_Mips_GPOFF_HI; 719 break; 720 } 721 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 722 : Mips::fixup_Mips_HI16; 723 break; 724 case MipsMCExpr::MEK_PCREL_HI16: 725 FixupKind = Mips::fixup_MIPS_PCHI16; 726 break; 727 case MipsMCExpr::MEK_PCREL_LO16: 728 FixupKind = Mips::fixup_MIPS_PCLO16; 729 break; 730 case MipsMCExpr::MEK_TLSGD: 731 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 732 : Mips::fixup_Mips_TLSGD; 733 break; 734 case MipsMCExpr::MEK_TLSLDM: 735 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 736 : Mips::fixup_Mips_TLSLDM; 737 break; 738 case MipsMCExpr::MEK_TPREL_HI: 739 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 740 : Mips::fixup_Mips_TPREL_HI; 741 break; 742 case MipsMCExpr::MEK_TPREL_LO: 743 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 744 : Mips::fixup_Mips_TPREL_LO; 745 break; 746 case MipsMCExpr::MEK_NEG: 747 FixupKind = 748 isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; 749 break; 750 } 751 Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 752 return 0; 753 } 754 755 if (Kind == MCExpr::SymbolRef) { 756 Mips::Fixups FixupKind = Mips::Fixups(0); 757 758 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 759 default: llvm_unreachable("Unknown fixup kind!"); 760 break; 761 case MCSymbolRefExpr::VK_None: 762 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 763 break; 764 } // switch 765 766 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 767 return 0; 768 } 769 return 0; 770 } 771 772 /// getMachineOpValue - Return binary encoding of operand. If the machine 773 /// operand requires relocation, record the relocation and return zero. 774 unsigned MipsMCCodeEmitter:: 775 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 776 SmallVectorImpl<MCFixup> &Fixups, 777 const MCSubtargetInfo &STI) const { 778 if (MO.isReg()) { 779 unsigned Reg = MO.getReg(); 780 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 781 return RegNo; 782 } else if (MO.isImm()) { 783 return static_cast<unsigned>(MO.getImm()); 784 } else if (MO.isFPImm()) { 785 return static_cast<unsigned>(APFloat(MO.getFPImm()) 786 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 787 } 788 // MO must be an Expr. 789 assert(MO.isExpr()); 790 return getExprOpValue(MO.getExpr(),Fixups, STI); 791 } 792 793 /// Return binary encoding of memory related operand. 794 /// If the offset operand requires relocation, record the relocation. 795 template <unsigned ShiftAmount> 796 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 797 SmallVectorImpl<MCFixup> &Fixups, 798 const MCSubtargetInfo &STI) const { 799 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 800 assert(MI.getOperand(OpNo).isReg()); 801 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 802 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 803 804 // Apply the scale factor if there is one. 805 OffBits >>= ShiftAmount; 806 807 return (OffBits & 0xFFFF) | RegBits; 808 } 809 810 unsigned MipsMCCodeEmitter:: 811 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 812 SmallVectorImpl<MCFixup> &Fixups, 813 const MCSubtargetInfo &STI) const { 814 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 815 assert(MI.getOperand(OpNo).isReg()); 816 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 817 Fixups, STI) << 4; 818 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 819 Fixups, STI); 820 821 return (OffBits & 0xF) | RegBits; 822 } 823 824 unsigned MipsMCCodeEmitter:: 825 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 826 SmallVectorImpl<MCFixup> &Fixups, 827 const MCSubtargetInfo &STI) const { 828 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 829 assert(MI.getOperand(OpNo).isReg()); 830 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 831 Fixups, STI) << 4; 832 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 833 Fixups, STI) >> 1; 834 835 return (OffBits & 0xF) | RegBits; 836 } 837 838 unsigned MipsMCCodeEmitter:: 839 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 840 SmallVectorImpl<MCFixup> &Fixups, 841 const MCSubtargetInfo &STI) const { 842 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 843 assert(MI.getOperand(OpNo).isReg()); 844 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 845 Fixups, STI) << 4; 846 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 847 Fixups, STI) >> 2; 848 849 return (OffBits & 0xF) | RegBits; 850 } 851 852 unsigned MipsMCCodeEmitter:: 853 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 854 SmallVectorImpl<MCFixup> &Fixups, 855 const MCSubtargetInfo &STI) const { 856 // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 857 assert(MI.getOperand(OpNo).isReg() && 858 (MI.getOperand(OpNo).getReg() == Mips::SP || 859 MI.getOperand(OpNo).getReg() == Mips::SP_64) && 860 "Unexpected base register!"); 861 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 862 Fixups, STI) >> 2; 863 864 return OffBits & 0x1F; 865 } 866 867 unsigned MipsMCCodeEmitter:: 868 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 869 SmallVectorImpl<MCFixup> &Fixups, 870 const MCSubtargetInfo &STI) const { 871 // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 872 assert(MI.getOperand(OpNo).isReg() && 873 MI.getOperand(OpNo).getReg() == Mips::GP && 874 "Unexpected base register!"); 875 876 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 877 Fixups, STI) >> 2; 878 879 return OffBits & 0x7F; 880 } 881 882 unsigned MipsMCCodeEmitter:: 883 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 884 SmallVectorImpl<MCFixup> &Fixups, 885 const MCSubtargetInfo &STI) const { 886 // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 887 assert(MI.getOperand(OpNo).isReg()); 888 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 889 STI) << 16; 890 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 891 892 return (OffBits & 0x1FF) | RegBits; 893 } 894 895 unsigned MipsMCCodeEmitter:: 896 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 897 SmallVectorImpl<MCFixup> &Fixups, 898 const MCSubtargetInfo &STI) const { 899 // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 900 assert(MI.getOperand(OpNo).isReg()); 901 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 902 STI) << 16; 903 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 904 905 return (OffBits & 0x07FF) | RegBits; 906 } 907 908 unsigned MipsMCCodeEmitter:: 909 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 910 SmallVectorImpl<MCFixup> &Fixups, 911 const MCSubtargetInfo &STI) const { 912 // opNum can be invalid if instruction had reglist as operand. 913 // MemOperand is always last operand of instruction (base + offset). 914 switch (MI.getOpcode()) { 915 default: 916 break; 917 case Mips::SWM32_MM: 918 case Mips::LWM32_MM: 919 OpNo = MI.getNumOperands() - 2; 920 break; 921 } 922 923 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 924 assert(MI.getOperand(OpNo).isReg()); 925 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 926 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 927 928 return (OffBits & 0x0FFF) | RegBits; 929 } 930 931 unsigned MipsMCCodeEmitter:: 932 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 933 SmallVectorImpl<MCFixup> &Fixups, 934 const MCSubtargetInfo &STI) const { 935 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 936 assert(MI.getOperand(OpNo).isReg()); 937 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 938 STI) << 16; 939 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 940 941 return (OffBits & 0xFFFF) | RegBits; 942 } 943 944 unsigned MipsMCCodeEmitter:: 945 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 946 SmallVectorImpl<MCFixup> &Fixups, 947 const MCSubtargetInfo &STI) const { 948 // opNum can be invalid if instruction had reglist as operand 949 // MemOperand is always last operand of instruction (base + offset) 950 switch (MI.getOpcode()) { 951 default: 952 break; 953 case Mips::SWM16_MM: 954 case Mips::SWM16_MMR6: 955 case Mips::LWM16_MM: 956 case Mips::LWM16_MMR6: 957 OpNo = MI.getNumOperands() - 2; 958 break; 959 } 960 961 // Offset is encoded in bits 4-0. 962 assert(MI.getOperand(OpNo).isReg()); 963 // Base register is always SP - thus it is not encoded. 964 assert(MI.getOperand(OpNo+1).isImm()); 965 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 966 967 return ((OffBits >> 2) & 0x0F); 968 } 969 970 // FIXME: should be called getMSBEncoding 971 // 972 unsigned 973 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 974 SmallVectorImpl<MCFixup> &Fixups, 975 const MCSubtargetInfo &STI) const { 976 assert(MI.getOperand(OpNo-1).isImm()); 977 assert(MI.getOperand(OpNo).isImm()); 978 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 979 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 980 981 return Position + Size - 1; 982 } 983 984 template <unsigned Bits, int Offset> 985 unsigned 986 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 987 SmallVectorImpl<MCFixup> &Fixups, 988 const MCSubtargetInfo &STI) const { 989 assert(MI.getOperand(OpNo).isImm()); 990 unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 991 Value -= Offset; 992 return Value; 993 } 994 995 unsigned 996 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 997 SmallVectorImpl<MCFixup> &Fixups, 998 const MCSubtargetInfo &STI) const { 999 const MCOperand &MO = MI.getOperand(OpNo); 1000 if (MO.isImm()) { 1001 // The immediate is encoded as 'immediate << 2'. 1002 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 1003 assert((Res & 3) == 0); 1004 return Res >> 2; 1005 } 1006 1007 assert(MO.isExpr() && 1008 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 1009 1010 const MCExpr *Expr = MO.getExpr(); 1011 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 1012 : Mips::fixup_MIPS_PC19_S2; 1013 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1014 return 0; 1015 } 1016 1017 unsigned 1018 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 1019 SmallVectorImpl<MCFixup> &Fixups, 1020 const MCSubtargetInfo &STI) const { 1021 const MCOperand &MO = MI.getOperand(OpNo); 1022 if (MO.isImm()) { 1023 // The immediate is encoded as 'immediate << 3'. 1024 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 1025 assert((Res & 7) == 0); 1026 return Res >> 3; 1027 } 1028 1029 assert(MO.isExpr() && 1030 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 1031 1032 const MCExpr *Expr = MO.getExpr(); 1033 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 1034 : Mips::fixup_MIPS_PC18_S3; 1035 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1036 return 0; 1037 } 1038 1039 unsigned 1040 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 1041 SmallVectorImpl<MCFixup> &Fixups, 1042 const MCSubtargetInfo &STI) const { 1043 assert(MI.getOperand(OpNo).isImm()); 1044 const MCOperand &MO = MI.getOperand(OpNo); 1045 return MO.getImm() % 8; 1046 } 1047 1048 unsigned 1049 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 1050 SmallVectorImpl<MCFixup> &Fixups, 1051 const MCSubtargetInfo &STI) const { 1052 assert(MI.getOperand(OpNo).isImm()); 1053 const MCOperand &MO = MI.getOperand(OpNo); 1054 unsigned Value = MO.getImm(); 1055 switch (Value) { 1056 case 128: return 0x0; 1057 case 1: return 0x1; 1058 case 2: return 0x2; 1059 case 3: return 0x3; 1060 case 4: return 0x4; 1061 case 7: return 0x5; 1062 case 8: return 0x6; 1063 case 15: return 0x7; 1064 case 16: return 0x8; 1065 case 31: return 0x9; 1066 case 32: return 0xa; 1067 case 63: return 0xb; 1068 case 64: return 0xc; 1069 case 255: return 0xd; 1070 case 32768: return 0xe; 1071 case 65535: return 0xf; 1072 } 1073 llvm_unreachable("Unexpected value"); 1074 } 1075 1076 unsigned 1077 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1078 SmallVectorImpl<MCFixup> &Fixups, 1079 const MCSubtargetInfo &STI) const { 1080 unsigned res = 0; 1081 1082 // Register list operand is always first operand of instruction and it is 1083 // placed before memory operand (register + imm). 1084 1085 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1086 unsigned Reg = MI.getOperand(I).getReg(); 1087 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1088 if (RegNo != 31) 1089 res++; 1090 else 1091 res |= 0x10; 1092 } 1093 return res; 1094 } 1095 1096 unsigned 1097 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1098 SmallVectorImpl<MCFixup> &Fixups, 1099 const MCSubtargetInfo &STI) const { 1100 return (MI.getNumOperands() - 4); 1101 } 1102 1103 unsigned 1104 MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 1105 SmallVectorImpl<MCFixup> &Fixups, 1106 const MCSubtargetInfo &STI) const { 1107 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 1108 } 1109 1110 unsigned 1111 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 1112 SmallVectorImpl<MCFixup> &Fixups, 1113 const MCSubtargetInfo &STI) const { 1114 unsigned res = 0; 1115 1116 if (MI.getOperand(0).getReg() == Mips::A1 && 1117 MI.getOperand(1).getReg() == Mips::A2) 1118 res = 0; 1119 else if (MI.getOperand(0).getReg() == Mips::A1 && 1120 MI.getOperand(1).getReg() == Mips::A3) 1121 res = 1; 1122 else if (MI.getOperand(0).getReg() == Mips::A2 && 1123 MI.getOperand(1).getReg() == Mips::A3) 1124 res = 2; 1125 else if (MI.getOperand(0).getReg() == Mips::A0 && 1126 MI.getOperand(1).getReg() == Mips::S5) 1127 res = 3; 1128 else if (MI.getOperand(0).getReg() == Mips::A0 && 1129 MI.getOperand(1).getReg() == Mips::S6) 1130 res = 4; 1131 else if (MI.getOperand(0).getReg() == Mips::A0 && 1132 MI.getOperand(1).getReg() == Mips::A1) 1133 res = 5; 1134 else if (MI.getOperand(0).getReg() == Mips::A0 && 1135 MI.getOperand(1).getReg() == Mips::A2) 1136 res = 6; 1137 else if (MI.getOperand(0).getReg() == Mips::A0 && 1138 MI.getOperand(1).getReg() == Mips::A3) 1139 res = 7; 1140 1141 return res; 1142 } 1143 1144 unsigned 1145 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 1146 SmallVectorImpl<MCFixup> &Fixups, 1147 const MCSubtargetInfo &STI) const { 1148 const MCOperand &MO = MI.getOperand(OpNo); 1149 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 1150 // The immediate is encoded as 'immediate >> 2'. 1151 unsigned Res = static_cast<unsigned>(MO.getImm()); 1152 assert((Res & 3) == 0); 1153 return Res >> 2; 1154 } 1155 1156 #include "MipsGenMCCodeEmitter.inc" 1157