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