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 = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO 661 : Mips::fixup_Mips_GPOFF_LO; 662 else 663 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 664 : Mips::fixup_Mips_LO16; 665 break; 666 case MipsMCExpr::MEK_HIGHEST: 667 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST 668 : Mips::fixup_Mips_HIGHEST; 669 break; 670 case MipsMCExpr::MEK_HIGHER: 671 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER 672 : Mips::fixup_Mips_HIGHER; 673 break; 674 case MipsMCExpr::MEK_HI: 675 // Check for %hi(%neg(%gp_rel(X))) 676 if (MipsExpr->isGpOff()) 677 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI 678 : Mips::fixup_Mips_GPOFF_HI; 679 else 680 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 681 : Mips::fixup_Mips_HI16; 682 break; 683 case MipsMCExpr::MEK_PCREL_HI16: 684 FixupKind = Mips::fixup_MIPS_PCHI16; 685 break; 686 case MipsMCExpr::MEK_PCREL_LO16: 687 FixupKind = Mips::fixup_MIPS_PCLO16; 688 break; 689 case MipsMCExpr::MEK_TLSGD: 690 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 691 : Mips::fixup_Mips_TLSGD; 692 break; 693 case MipsMCExpr::MEK_TLSLDM: 694 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 695 : Mips::fixup_Mips_TLSLDM; 696 break; 697 case MipsMCExpr::MEK_TPREL_HI: 698 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 699 : Mips::fixup_Mips_TPREL_HI; 700 break; 701 case MipsMCExpr::MEK_TPREL_LO: 702 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 703 : Mips::fixup_Mips_TPREL_LO; 704 break; 705 case MipsMCExpr::MEK_NEG: 706 FixupKind = 707 isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; 708 break; 709 } 710 Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 711 return 0; 712 } 713 714 if (Kind == MCExpr::SymbolRef) { 715 Mips::Fixups FixupKind = Mips::Fixups(0); 716 717 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 718 default: llvm_unreachable("Unknown fixup kind!"); 719 break; 720 case MCSymbolRefExpr::VK_None: 721 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 722 break; 723 } // switch 724 725 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 726 return 0; 727 } 728 return 0; 729 } 730 731 /// getMachineOpValue - Return binary encoding of operand. If the machine 732 /// operand requires relocation, record the relocation and return zero. 733 unsigned MipsMCCodeEmitter:: 734 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 735 SmallVectorImpl<MCFixup> &Fixups, 736 const MCSubtargetInfo &STI) const { 737 if (MO.isReg()) { 738 unsigned Reg = MO.getReg(); 739 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 740 return RegNo; 741 } else if (MO.isImm()) { 742 return static_cast<unsigned>(MO.getImm()); 743 } else if (MO.isFPImm()) { 744 return static_cast<unsigned>(APFloat(MO.getFPImm()) 745 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 746 } 747 // MO must be an Expr. 748 assert(MO.isExpr()); 749 return getExprOpValue(MO.getExpr(),Fixups, STI); 750 } 751 752 /// Return binary encoding of memory related operand. 753 /// If the offset operand requires relocation, record the relocation. 754 template <unsigned ShiftAmount> 755 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 756 SmallVectorImpl<MCFixup> &Fixups, 757 const MCSubtargetInfo &STI) const { 758 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 759 assert(MI.getOperand(OpNo).isReg()); 760 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 761 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 762 763 // Apply the scale factor if there is one. 764 OffBits >>= ShiftAmount; 765 766 return (OffBits & 0xFFFF) | RegBits; 767 } 768 769 unsigned MipsMCCodeEmitter:: 770 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 771 SmallVectorImpl<MCFixup> &Fixups, 772 const MCSubtargetInfo &STI) const { 773 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 774 assert(MI.getOperand(OpNo).isReg()); 775 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 776 Fixups, STI) << 4; 777 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 778 Fixups, STI); 779 780 return (OffBits & 0xF) | RegBits; 781 } 782 783 unsigned MipsMCCodeEmitter:: 784 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 785 SmallVectorImpl<MCFixup> &Fixups, 786 const MCSubtargetInfo &STI) const { 787 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 788 assert(MI.getOperand(OpNo).isReg()); 789 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 790 Fixups, STI) << 4; 791 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 792 Fixups, STI) >> 1; 793 794 return (OffBits & 0xF) | RegBits; 795 } 796 797 unsigned MipsMCCodeEmitter:: 798 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 799 SmallVectorImpl<MCFixup> &Fixups, 800 const MCSubtargetInfo &STI) const { 801 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 802 assert(MI.getOperand(OpNo).isReg()); 803 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 804 Fixups, STI) << 4; 805 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 806 Fixups, STI) >> 2; 807 808 return (OffBits & 0xF) | RegBits; 809 } 810 811 unsigned MipsMCCodeEmitter:: 812 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 813 SmallVectorImpl<MCFixup> &Fixups, 814 const MCSubtargetInfo &STI) const { 815 // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 816 assert(MI.getOperand(OpNo).isReg() && 817 (MI.getOperand(OpNo).getReg() == Mips::SP || 818 MI.getOperand(OpNo).getReg() == Mips::SP_64) && 819 "Unexpected base register!"); 820 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 821 Fixups, STI) >> 2; 822 823 return OffBits & 0x1F; 824 } 825 826 unsigned MipsMCCodeEmitter:: 827 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 828 SmallVectorImpl<MCFixup> &Fixups, 829 const MCSubtargetInfo &STI) const { 830 // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 831 assert(MI.getOperand(OpNo).isReg() && 832 MI.getOperand(OpNo).getReg() == Mips::GP && 833 "Unexpected base register!"); 834 835 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 836 Fixups, STI) >> 2; 837 838 return OffBits & 0x7F; 839 } 840 841 unsigned MipsMCCodeEmitter:: 842 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 843 SmallVectorImpl<MCFixup> &Fixups, 844 const MCSubtargetInfo &STI) const { 845 // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 846 assert(MI.getOperand(OpNo).isReg()); 847 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 848 STI) << 16; 849 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 850 851 return (OffBits & 0x1FF) | RegBits; 852 } 853 854 unsigned MipsMCCodeEmitter:: 855 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 856 SmallVectorImpl<MCFixup> &Fixups, 857 const MCSubtargetInfo &STI) const { 858 // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 859 assert(MI.getOperand(OpNo).isReg()); 860 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 861 STI) << 16; 862 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 863 864 return (OffBits & 0x07FF) | RegBits; 865 } 866 867 unsigned MipsMCCodeEmitter:: 868 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 869 SmallVectorImpl<MCFixup> &Fixups, 870 const MCSubtargetInfo &STI) const { 871 // opNum can be invalid if instruction had reglist as operand. 872 // MemOperand is always last operand of instruction (base + offset). 873 switch (MI.getOpcode()) { 874 default: 875 break; 876 case Mips::SWM32_MM: 877 case Mips::LWM32_MM: 878 OpNo = MI.getNumOperands() - 2; 879 break; 880 } 881 882 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 883 assert(MI.getOperand(OpNo).isReg()); 884 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 885 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 886 887 return (OffBits & 0x0FFF) | RegBits; 888 } 889 890 unsigned MipsMCCodeEmitter:: 891 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 892 SmallVectorImpl<MCFixup> &Fixups, 893 const MCSubtargetInfo &STI) const { 894 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 895 assert(MI.getOperand(OpNo).isReg()); 896 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 897 STI) << 16; 898 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 899 900 return (OffBits & 0xFFFF) | RegBits; 901 } 902 903 unsigned MipsMCCodeEmitter:: 904 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 905 SmallVectorImpl<MCFixup> &Fixups, 906 const MCSubtargetInfo &STI) const { 907 // opNum can be invalid if instruction had reglist as operand 908 // MemOperand is always last operand of instruction (base + offset) 909 switch (MI.getOpcode()) { 910 default: 911 break; 912 case Mips::SWM16_MM: 913 case Mips::SWM16_MMR6: 914 case Mips::LWM16_MM: 915 case Mips::LWM16_MMR6: 916 OpNo = MI.getNumOperands() - 2; 917 break; 918 } 919 920 // Offset is encoded in bits 4-0. 921 assert(MI.getOperand(OpNo).isReg()); 922 // Base register is always SP - thus it is not encoded. 923 assert(MI.getOperand(OpNo+1).isImm()); 924 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 925 926 return ((OffBits >> 2) & 0x0F); 927 } 928 929 // FIXME: should be called getMSBEncoding 930 // 931 unsigned 932 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 933 SmallVectorImpl<MCFixup> &Fixups, 934 const MCSubtargetInfo &STI) const { 935 assert(MI.getOperand(OpNo-1).isImm()); 936 assert(MI.getOperand(OpNo).isImm()); 937 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 938 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 939 940 return Position + Size - 1; 941 } 942 943 template <unsigned Bits, int Offset> 944 unsigned 945 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 946 SmallVectorImpl<MCFixup> &Fixups, 947 const MCSubtargetInfo &STI) const { 948 assert(MI.getOperand(OpNo).isImm()); 949 unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 950 Value -= Offset; 951 return Value; 952 } 953 954 unsigned 955 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 956 SmallVectorImpl<MCFixup> &Fixups, 957 const MCSubtargetInfo &STI) const { 958 const MCOperand &MO = MI.getOperand(OpNo); 959 if (MO.isImm()) { 960 // The immediate is encoded as 'immediate << 2'. 961 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 962 assert((Res & 3) == 0); 963 return Res >> 2; 964 } 965 966 assert(MO.isExpr() && 967 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 968 969 const MCExpr *Expr = MO.getExpr(); 970 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 971 : Mips::fixup_MIPS_PC19_S2; 972 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 973 return 0; 974 } 975 976 unsigned 977 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 978 SmallVectorImpl<MCFixup> &Fixups, 979 const MCSubtargetInfo &STI) const { 980 const MCOperand &MO = MI.getOperand(OpNo); 981 if (MO.isImm()) { 982 // The immediate is encoded as 'immediate << 3'. 983 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 984 assert((Res & 7) == 0); 985 return Res >> 3; 986 } 987 988 assert(MO.isExpr() && 989 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 990 991 const MCExpr *Expr = MO.getExpr(); 992 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 993 : Mips::fixup_MIPS_PC18_S3; 994 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 995 return 0; 996 } 997 998 unsigned 999 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 1000 SmallVectorImpl<MCFixup> &Fixups, 1001 const MCSubtargetInfo &STI) const { 1002 assert(MI.getOperand(OpNo).isImm()); 1003 const MCOperand &MO = MI.getOperand(OpNo); 1004 return MO.getImm() % 8; 1005 } 1006 1007 unsigned 1008 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 1009 SmallVectorImpl<MCFixup> &Fixups, 1010 const MCSubtargetInfo &STI) const { 1011 assert(MI.getOperand(OpNo).isImm()); 1012 const MCOperand &MO = MI.getOperand(OpNo); 1013 unsigned Value = MO.getImm(); 1014 switch (Value) { 1015 case 128: return 0x0; 1016 case 1: return 0x1; 1017 case 2: return 0x2; 1018 case 3: return 0x3; 1019 case 4: return 0x4; 1020 case 7: return 0x5; 1021 case 8: return 0x6; 1022 case 15: return 0x7; 1023 case 16: return 0x8; 1024 case 31: return 0x9; 1025 case 32: return 0xa; 1026 case 63: return 0xb; 1027 case 64: return 0xc; 1028 case 255: return 0xd; 1029 case 32768: return 0xe; 1030 case 65535: return 0xf; 1031 } 1032 llvm_unreachable("Unexpected value"); 1033 } 1034 1035 unsigned 1036 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1037 SmallVectorImpl<MCFixup> &Fixups, 1038 const MCSubtargetInfo &STI) const { 1039 unsigned res = 0; 1040 1041 // Register list operand is always first operand of instruction and it is 1042 // placed before memory operand (register + imm). 1043 1044 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1045 unsigned Reg = MI.getOperand(I).getReg(); 1046 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1047 if (RegNo != 31) 1048 res++; 1049 else 1050 res |= 0x10; 1051 } 1052 return res; 1053 } 1054 1055 unsigned 1056 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1057 SmallVectorImpl<MCFixup> &Fixups, 1058 const MCSubtargetInfo &STI) const { 1059 return (MI.getNumOperands() - 4); 1060 } 1061 1062 unsigned 1063 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 1064 SmallVectorImpl<MCFixup> &Fixups, 1065 const MCSubtargetInfo &STI) const { 1066 unsigned res = 0; 1067 1068 if (MI.getOperand(0).getReg() == Mips::A1 && 1069 MI.getOperand(1).getReg() == Mips::A2) 1070 res = 0; 1071 else if (MI.getOperand(0).getReg() == Mips::A1 && 1072 MI.getOperand(1).getReg() == Mips::A3) 1073 res = 1; 1074 else if (MI.getOperand(0).getReg() == Mips::A2 && 1075 MI.getOperand(1).getReg() == Mips::A3) 1076 res = 2; 1077 else if (MI.getOperand(0).getReg() == Mips::A0 && 1078 MI.getOperand(1).getReg() == Mips::S5) 1079 res = 3; 1080 else if (MI.getOperand(0).getReg() == Mips::A0 && 1081 MI.getOperand(1).getReg() == Mips::S6) 1082 res = 4; 1083 else if (MI.getOperand(0).getReg() == Mips::A0 && 1084 MI.getOperand(1).getReg() == Mips::A1) 1085 res = 5; 1086 else if (MI.getOperand(0).getReg() == Mips::A0 && 1087 MI.getOperand(1).getReg() == Mips::A2) 1088 res = 6; 1089 else if (MI.getOperand(0).getReg() == Mips::A0 && 1090 MI.getOperand(1).getReg() == Mips::A3) 1091 res = 7; 1092 1093 return res; 1094 } 1095 1096 unsigned 1097 MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, 1098 SmallVectorImpl<MCFixup> &Fixups, 1099 const MCSubtargetInfo &STI) const { 1100 assert(((OpNo == 2) || (OpNo == 3)) && 1101 "Unexpected OpNo for movep operand encoding!"); 1102 1103 MCOperand Op = MI.getOperand(OpNo); 1104 assert(Op.isReg() && "Operand of movep is not a register!"); 1105 switch (Op.getReg()) { 1106 default: 1107 llvm_unreachable("Unknown register for movep!"); 1108 case Mips::ZERO: return 0; 1109 case Mips::S1: return 1; 1110 case Mips::V0: return 2; 1111 case Mips::V1: return 3; 1112 case Mips::S0: return 4; 1113 case Mips::S2: return 5; 1114 case Mips::S3: return 6; 1115 case Mips::S4: return 7; 1116 } 1117 } 1118 1119 unsigned 1120 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 1121 SmallVectorImpl<MCFixup> &Fixups, 1122 const MCSubtargetInfo &STI) const { 1123 const MCOperand &MO = MI.getOperand(OpNo); 1124 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 1125 // The immediate is encoded as 'immediate >> 2'. 1126 unsigned Res = static_cast<unsigned>(MO.getImm()); 1127 assert((Res & 3) == 0); 1128 return Res >> 2; 1129 } 1130 1131 #include "MipsGenMCCodeEmitter.inc" 1132