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