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