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