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