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