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 // TODO: Push fixup. 489 return 0; 490 } 491 492 /// getJumpTargetOpValue - Return binary encoding of the jump 493 /// target operand. If the machine operand requires relocation, 494 /// record the relocation and return zero. 495 unsigned MipsMCCodeEmitter:: 496 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 497 SmallVectorImpl<MCFixup> &Fixups, 498 const MCSubtargetInfo &STI) const { 499 const MCOperand &MO = MI.getOperand(OpNo); 500 // If the destination is an immediate, divide by 4. 501 if (MO.isImm()) return MO.getImm()>>2; 502 503 assert(MO.isExpr() && 504 "getJumpTargetOpValue expects only expressions or an immediate"); 505 506 const MCExpr *Expr = MO.getExpr(); 507 Fixups.push_back(MCFixup::create(0, Expr, 508 MCFixupKind(Mips::fixup_Mips_26))); 509 return 0; 510 } 511 512 unsigned MipsMCCodeEmitter:: 513 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 514 SmallVectorImpl<MCFixup> &Fixups, 515 const MCSubtargetInfo &STI) const { 516 const MCOperand &MO = MI.getOperand(OpNo); 517 // If the destination is an immediate, divide by 2. 518 if (MO.isImm()) return MO.getImm() >> 1; 519 520 assert(MO.isExpr() && 521 "getJumpTargetOpValueMM expects only expressions or an immediate"); 522 523 const MCExpr *Expr = MO.getExpr(); 524 Fixups.push_back(MCFixup::create(0, Expr, 525 MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 526 return 0; 527 } 528 529 unsigned MipsMCCodeEmitter:: 530 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 531 SmallVectorImpl<MCFixup> &Fixups, 532 const MCSubtargetInfo &STI) const { 533 const MCOperand &MO = MI.getOperand(OpNo); 534 if (MO.isImm()) { 535 // The immediate is encoded as 'immediate << 2'. 536 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 537 assert((Res & 3) == 0); 538 return Res >> 2; 539 } 540 541 assert(MO.isExpr() && 542 "getUImm5Lsl2Encoding expects only expressions or an immediate"); 543 544 return 0; 545 } 546 547 unsigned MipsMCCodeEmitter:: 548 getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 549 SmallVectorImpl<MCFixup> &Fixups, 550 const MCSubtargetInfo &STI) const { 551 const MCOperand &MO = MI.getOperand(OpNo); 552 if (MO.isImm()) { 553 int Value = MO.getImm(); 554 return Value >> 2; 555 } 556 557 return 0; 558 } 559 560 unsigned MipsMCCodeEmitter:: 561 getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 562 SmallVectorImpl<MCFixup> &Fixups, 563 const MCSubtargetInfo &STI) const { 564 const MCOperand &MO = MI.getOperand(OpNo); 565 if (MO.isImm()) { 566 unsigned Value = MO.getImm(); 567 return Value >> 2; 568 } 569 570 return 0; 571 } 572 573 unsigned MipsMCCodeEmitter:: 574 getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 575 SmallVectorImpl<MCFixup> &Fixups, 576 const MCSubtargetInfo &STI) const { 577 const MCOperand &MO = MI.getOperand(OpNo); 578 if (MO.isImm()) { 579 unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 580 return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 581 } 582 583 return 0; 584 } 585 586 unsigned MipsMCCodeEmitter:: 587 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 588 const MCSubtargetInfo &STI) const { 589 int64_t Res; 590 591 if (Expr->evaluateAsAbsolute(Res)) 592 return Res; 593 594 MCExpr::ExprKind Kind = Expr->getKind(); 595 if (Kind == MCExpr::Constant) { 596 return cast<MCConstantExpr>(Expr)->getValue(); 597 } 598 599 if (Kind == MCExpr::Binary) { 600 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 601 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 602 return Res; 603 } 604 605 if (Kind == MCExpr::Target) { 606 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 607 608 Mips::Fixups FixupKind = Mips::Fixups(0); 609 switch (MipsExpr->getKind()) { 610 case MipsMCExpr::MEK_None: 611 case MipsMCExpr::MEK_Special: 612 llvm_unreachable("Unhandled fixup kind!"); 613 break; 614 case MipsMCExpr::MEK_DTPREL: 615 // MEK_DTPREL is used for marking TLS DIEExpr only 616 // and contains a regular sub-expression. 617 return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI); 618 case MipsMCExpr::MEK_CALL_HI16: 619 FixupKind = Mips::fixup_Mips_CALL_HI16; 620 break; 621 case MipsMCExpr::MEK_CALL_LO16: 622 FixupKind = Mips::fixup_Mips_CALL_LO16; 623 break; 624 case MipsMCExpr::MEK_DTPREL_HI: 625 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 626 : Mips::fixup_Mips_DTPREL_HI; 627 break; 628 case MipsMCExpr::MEK_DTPREL_LO: 629 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 630 : Mips::fixup_Mips_DTPREL_LO; 631 break; 632 case MipsMCExpr::MEK_GOTTPREL: 633 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL 634 : Mips::fixup_Mips_GOTTPREL; 635 break; 636 case MipsMCExpr::MEK_GOT: 637 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 638 : Mips::fixup_Mips_GOT; 639 break; 640 case MipsMCExpr::MEK_GOT_CALL: 641 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 642 : Mips::fixup_Mips_CALL16; 643 break; 644 case MipsMCExpr::MEK_GOT_DISP: 645 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 646 : Mips::fixup_Mips_GOT_DISP; 647 break; 648 case MipsMCExpr::MEK_GOT_HI16: 649 FixupKind = Mips::fixup_Mips_GOT_HI16; 650 break; 651 case MipsMCExpr::MEK_GOT_LO16: 652 FixupKind = Mips::fixup_Mips_GOT_LO16; 653 break; 654 case MipsMCExpr::MEK_GOT_PAGE: 655 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 656 : Mips::fixup_Mips_GOT_PAGE; 657 break; 658 case MipsMCExpr::MEK_GOT_OFST: 659 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 660 : Mips::fixup_Mips_GOT_OFST; 661 break; 662 case MipsMCExpr::MEK_GPREL: 663 FixupKind = Mips::fixup_Mips_GPREL16; 664 break; 665 case MipsMCExpr::MEK_LO: 666 // Check for %lo(%neg(%gp_rel(X))) 667 if (MipsExpr->isGpOff()) 668 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO 669 : Mips::fixup_Mips_GPOFF_LO; 670 else 671 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 672 : Mips::fixup_Mips_LO16; 673 break; 674 case MipsMCExpr::MEK_HIGHEST: 675 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST 676 : Mips::fixup_Mips_HIGHEST; 677 break; 678 case MipsMCExpr::MEK_HIGHER: 679 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER 680 : Mips::fixup_Mips_HIGHER; 681 break; 682 case MipsMCExpr::MEK_HI: 683 // Check for %hi(%neg(%gp_rel(X))) 684 if (MipsExpr->isGpOff()) 685 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI 686 : Mips::fixup_Mips_GPOFF_HI; 687 else 688 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 689 : Mips::fixup_Mips_HI16; 690 break; 691 case MipsMCExpr::MEK_PCREL_HI16: 692 FixupKind = Mips::fixup_MIPS_PCHI16; 693 break; 694 case MipsMCExpr::MEK_PCREL_LO16: 695 FixupKind = Mips::fixup_MIPS_PCLO16; 696 break; 697 case MipsMCExpr::MEK_TLSGD: 698 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 699 : Mips::fixup_Mips_TLSGD; 700 break; 701 case MipsMCExpr::MEK_TLSLDM: 702 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 703 : Mips::fixup_Mips_TLSLDM; 704 break; 705 case MipsMCExpr::MEK_TPREL_HI: 706 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 707 : Mips::fixup_Mips_TPREL_HI; 708 break; 709 case MipsMCExpr::MEK_TPREL_LO: 710 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 711 : Mips::fixup_Mips_TPREL_LO; 712 break; 713 case MipsMCExpr::MEK_NEG: 714 FixupKind = 715 isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; 716 break; 717 } 718 Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 719 return 0; 720 } 721 722 if (Kind == MCExpr::SymbolRef) { 723 Mips::Fixups FixupKind = Mips::Fixups(0); 724 725 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 726 default: llvm_unreachable("Unknown fixup kind!"); 727 break; 728 case MCSymbolRefExpr::VK_None: 729 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 730 break; 731 } // switch 732 733 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 734 return 0; 735 } 736 return 0; 737 } 738 739 /// getMachineOpValue - Return binary encoding of operand. If the machine 740 /// operand requires relocation, record the relocation and return zero. 741 unsigned MipsMCCodeEmitter:: 742 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 743 SmallVectorImpl<MCFixup> &Fixups, 744 const MCSubtargetInfo &STI) const { 745 if (MO.isReg()) { 746 unsigned Reg = MO.getReg(); 747 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 748 return RegNo; 749 } else if (MO.isImm()) { 750 return static_cast<unsigned>(MO.getImm()); 751 } else if (MO.isFPImm()) { 752 return static_cast<unsigned>(APFloat(MO.getFPImm()) 753 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 754 } 755 // MO must be an Expr. 756 assert(MO.isExpr()); 757 return getExprOpValue(MO.getExpr(),Fixups, STI); 758 } 759 760 /// Return binary encoding of memory related operand. 761 /// If the offset operand requires relocation, record the relocation. 762 template <unsigned ShiftAmount> 763 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 764 SmallVectorImpl<MCFixup> &Fixups, 765 const MCSubtargetInfo &STI) const { 766 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 767 assert(MI.getOperand(OpNo).isReg()); 768 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 769 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 770 771 // Apply the scale factor if there is one. 772 OffBits >>= ShiftAmount; 773 774 return (OffBits & 0xFFFF) | RegBits; 775 } 776 777 unsigned MipsMCCodeEmitter:: 778 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 779 SmallVectorImpl<MCFixup> &Fixups, 780 const MCSubtargetInfo &STI) const { 781 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 782 assert(MI.getOperand(OpNo).isReg()); 783 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 784 Fixups, STI) << 4; 785 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 786 Fixups, STI); 787 788 return (OffBits & 0xF) | RegBits; 789 } 790 791 unsigned MipsMCCodeEmitter:: 792 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 793 SmallVectorImpl<MCFixup> &Fixups, 794 const MCSubtargetInfo &STI) const { 795 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 796 assert(MI.getOperand(OpNo).isReg()); 797 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 798 Fixups, STI) << 4; 799 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 800 Fixups, STI) >> 1; 801 802 return (OffBits & 0xF) | RegBits; 803 } 804 805 unsigned MipsMCCodeEmitter:: 806 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 807 SmallVectorImpl<MCFixup> &Fixups, 808 const MCSubtargetInfo &STI) const { 809 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 810 assert(MI.getOperand(OpNo).isReg()); 811 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 812 Fixups, STI) << 4; 813 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 814 Fixups, STI) >> 2; 815 816 return (OffBits & 0xF) | RegBits; 817 } 818 819 unsigned MipsMCCodeEmitter:: 820 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 821 SmallVectorImpl<MCFixup> &Fixups, 822 const MCSubtargetInfo &STI) const { 823 // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 824 assert(MI.getOperand(OpNo).isReg() && 825 (MI.getOperand(OpNo).getReg() == Mips::SP || 826 MI.getOperand(OpNo).getReg() == Mips::SP_64) && 827 "Unexpected base register!"); 828 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 829 Fixups, STI) >> 2; 830 831 return OffBits & 0x1F; 832 } 833 834 unsigned MipsMCCodeEmitter:: 835 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 836 SmallVectorImpl<MCFixup> &Fixups, 837 const MCSubtargetInfo &STI) const { 838 // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 839 assert(MI.getOperand(OpNo).isReg() && 840 MI.getOperand(OpNo).getReg() == Mips::GP && 841 "Unexpected base register!"); 842 843 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 844 Fixups, STI) >> 2; 845 846 return OffBits & 0x7F; 847 } 848 849 unsigned MipsMCCodeEmitter:: 850 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 851 SmallVectorImpl<MCFixup> &Fixups, 852 const MCSubtargetInfo &STI) const { 853 // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 854 assert(MI.getOperand(OpNo).isReg()); 855 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 856 STI) << 16; 857 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 858 859 return (OffBits & 0x1FF) | RegBits; 860 } 861 862 unsigned MipsMCCodeEmitter:: 863 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 864 SmallVectorImpl<MCFixup> &Fixups, 865 const MCSubtargetInfo &STI) const { 866 // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 867 assert(MI.getOperand(OpNo).isReg()); 868 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 869 STI) << 16; 870 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 871 872 return (OffBits & 0x07FF) | RegBits; 873 } 874 875 unsigned MipsMCCodeEmitter:: 876 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 877 SmallVectorImpl<MCFixup> &Fixups, 878 const MCSubtargetInfo &STI) const { 879 // opNum can be invalid if instruction had reglist as operand. 880 // MemOperand is always last operand of instruction (base + offset). 881 switch (MI.getOpcode()) { 882 default: 883 break; 884 case Mips::SWM32_MM: 885 case Mips::LWM32_MM: 886 OpNo = MI.getNumOperands() - 2; 887 break; 888 } 889 890 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 891 assert(MI.getOperand(OpNo).isReg()); 892 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 893 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 894 895 return (OffBits & 0x0FFF) | RegBits; 896 } 897 898 unsigned MipsMCCodeEmitter:: 899 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 900 SmallVectorImpl<MCFixup> &Fixups, 901 const MCSubtargetInfo &STI) const { 902 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 903 assert(MI.getOperand(OpNo).isReg()); 904 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 905 STI) << 16; 906 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 907 908 return (OffBits & 0xFFFF) | RegBits; 909 } 910 911 unsigned MipsMCCodeEmitter:: 912 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 913 SmallVectorImpl<MCFixup> &Fixups, 914 const MCSubtargetInfo &STI) const { 915 // opNum can be invalid if instruction had reglist as operand 916 // MemOperand is always last operand of instruction (base + offset) 917 switch (MI.getOpcode()) { 918 default: 919 break; 920 case Mips::SWM16_MM: 921 case Mips::SWM16_MMR6: 922 case Mips::LWM16_MM: 923 case Mips::LWM16_MMR6: 924 OpNo = MI.getNumOperands() - 2; 925 break; 926 } 927 928 // Offset is encoded in bits 4-0. 929 assert(MI.getOperand(OpNo).isReg()); 930 // Base register is always SP - thus it is not encoded. 931 assert(MI.getOperand(OpNo+1).isImm()); 932 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 933 934 return ((OffBits >> 2) & 0x0F); 935 } 936 937 // FIXME: should be called getMSBEncoding 938 // 939 unsigned 940 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 941 SmallVectorImpl<MCFixup> &Fixups, 942 const MCSubtargetInfo &STI) const { 943 assert(MI.getOperand(OpNo-1).isImm()); 944 assert(MI.getOperand(OpNo).isImm()); 945 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 946 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 947 948 return Position + Size - 1; 949 } 950 951 template <unsigned Bits, int Offset> 952 unsigned 953 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 954 SmallVectorImpl<MCFixup> &Fixups, 955 const MCSubtargetInfo &STI) const { 956 assert(MI.getOperand(OpNo).isImm()); 957 unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 958 Value -= Offset; 959 return Value; 960 } 961 962 unsigned 963 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 964 SmallVectorImpl<MCFixup> &Fixups, 965 const MCSubtargetInfo &STI) const { 966 const MCOperand &MO = MI.getOperand(OpNo); 967 if (MO.isImm()) { 968 // The immediate is encoded as 'immediate << 2'. 969 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 970 assert((Res & 3) == 0); 971 return Res >> 2; 972 } 973 974 assert(MO.isExpr() && 975 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 976 977 const MCExpr *Expr = MO.getExpr(); 978 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 979 : Mips::fixup_MIPS_PC19_S2; 980 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 981 return 0; 982 } 983 984 unsigned 985 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 986 SmallVectorImpl<MCFixup> &Fixups, 987 const MCSubtargetInfo &STI) const { 988 const MCOperand &MO = MI.getOperand(OpNo); 989 if (MO.isImm()) { 990 // The immediate is encoded as 'immediate << 3'. 991 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 992 assert((Res & 7) == 0); 993 return Res >> 3; 994 } 995 996 assert(MO.isExpr() && 997 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 998 999 const MCExpr *Expr = MO.getExpr(); 1000 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 1001 : Mips::fixup_MIPS_PC18_S3; 1002 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1003 return 0; 1004 } 1005 1006 unsigned 1007 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 1008 SmallVectorImpl<MCFixup> &Fixups, 1009 const MCSubtargetInfo &STI) const { 1010 assert(MI.getOperand(OpNo).isImm()); 1011 const MCOperand &MO = MI.getOperand(OpNo); 1012 return MO.getImm() % 8; 1013 } 1014 1015 unsigned 1016 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 1017 SmallVectorImpl<MCFixup> &Fixups, 1018 const MCSubtargetInfo &STI) const { 1019 assert(MI.getOperand(OpNo).isImm()); 1020 const MCOperand &MO = MI.getOperand(OpNo); 1021 unsigned Value = MO.getImm(); 1022 switch (Value) { 1023 case 128: return 0x0; 1024 case 1: return 0x1; 1025 case 2: return 0x2; 1026 case 3: return 0x3; 1027 case 4: return 0x4; 1028 case 7: return 0x5; 1029 case 8: return 0x6; 1030 case 15: return 0x7; 1031 case 16: return 0x8; 1032 case 31: return 0x9; 1033 case 32: return 0xa; 1034 case 63: return 0xb; 1035 case 64: return 0xc; 1036 case 255: return 0xd; 1037 case 32768: return 0xe; 1038 case 65535: return 0xf; 1039 } 1040 llvm_unreachable("Unexpected value"); 1041 } 1042 1043 unsigned 1044 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1045 SmallVectorImpl<MCFixup> &Fixups, 1046 const MCSubtargetInfo &STI) const { 1047 unsigned res = 0; 1048 1049 // Register list operand is always first operand of instruction and it is 1050 // placed before memory operand (register + imm). 1051 1052 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1053 unsigned Reg = MI.getOperand(I).getReg(); 1054 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1055 if (RegNo != 31) 1056 res++; 1057 else 1058 res |= 0x10; 1059 } 1060 return res; 1061 } 1062 1063 unsigned 1064 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1065 SmallVectorImpl<MCFixup> &Fixups, 1066 const MCSubtargetInfo &STI) const { 1067 return (MI.getNumOperands() - 4); 1068 } 1069 1070 unsigned 1071 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 1072 SmallVectorImpl<MCFixup> &Fixups, 1073 const MCSubtargetInfo &STI) const { 1074 unsigned res = 0; 1075 1076 if (MI.getOperand(0).getReg() == Mips::A1 && 1077 MI.getOperand(1).getReg() == Mips::A2) 1078 res = 0; 1079 else if (MI.getOperand(0).getReg() == Mips::A1 && 1080 MI.getOperand(1).getReg() == Mips::A3) 1081 res = 1; 1082 else if (MI.getOperand(0).getReg() == Mips::A2 && 1083 MI.getOperand(1).getReg() == Mips::A3) 1084 res = 2; 1085 else if (MI.getOperand(0).getReg() == Mips::A0 && 1086 MI.getOperand(1).getReg() == Mips::S5) 1087 res = 3; 1088 else if (MI.getOperand(0).getReg() == Mips::A0 && 1089 MI.getOperand(1).getReg() == Mips::S6) 1090 res = 4; 1091 else if (MI.getOperand(0).getReg() == Mips::A0 && 1092 MI.getOperand(1).getReg() == Mips::A1) 1093 res = 5; 1094 else if (MI.getOperand(0).getReg() == Mips::A0 && 1095 MI.getOperand(1).getReg() == Mips::A2) 1096 res = 6; 1097 else if (MI.getOperand(0).getReg() == Mips::A0 && 1098 MI.getOperand(1).getReg() == Mips::A3) 1099 res = 7; 1100 1101 return res; 1102 } 1103 1104 unsigned 1105 MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, 1106 SmallVectorImpl<MCFixup> &Fixups, 1107 const MCSubtargetInfo &STI) const { 1108 assert(((OpNo == 2) || (OpNo == 3)) && 1109 "Unexpected OpNo for movep operand encoding!"); 1110 1111 MCOperand Op = MI.getOperand(OpNo); 1112 assert(Op.isReg() && "Operand of movep is not a register!"); 1113 switch (Op.getReg()) { 1114 default: 1115 llvm_unreachable("Unknown register for movep!"); 1116 case Mips::ZERO: return 0; 1117 case Mips::S1: return 1; 1118 case Mips::V0: return 2; 1119 case Mips::V1: return 3; 1120 case Mips::S0: return 4; 1121 case Mips::S2: return 5; 1122 case Mips::S3: return 6; 1123 case Mips::S4: return 7; 1124 } 1125 } 1126 1127 unsigned 1128 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 1129 SmallVectorImpl<MCFixup> &Fixups, 1130 const MCSubtargetInfo &STI) const { 1131 const MCOperand &MO = MI.getOperand(OpNo); 1132 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 1133 // The immediate is encoded as 'immediate >> 2'. 1134 unsigned Res = static_cast<unsigned>(MO.getImm()); 1135 assert((Res & 3) == 0); 1136 return Res >> 2; 1137 } 1138 1139 #include "MipsGenMCCodeEmitter.inc" 1140