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