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 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 Opcode = NewOpcode; 212 TmpInst.setOpcode (NewOpcode); 213 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 214 } 215 216 if (((MI.getOpcode() == Mips::MOVEP_MM) || 217 (MI.getOpcode() == Mips::MOVEP_MMR6))) { 218 unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI); 219 Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7); 220 } 221 } 222 223 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 224 225 // Get byte count of instruction 226 unsigned Size = Desc.getSize(); 227 if (!Size) 228 llvm_unreachable("Desc.getSize() returns 0"); 229 230 EmitInstruction(Binary, Size, STI, OS); 231 } 232 233 /// getBranchTargetOpValue - Return binary encoding of the branch 234 /// target operand. If the machine operand requires relocation, 235 /// record the relocation and return zero. 236 unsigned MipsMCCodeEmitter:: 237 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 238 SmallVectorImpl<MCFixup> &Fixups, 239 const MCSubtargetInfo &STI) const { 240 const MCOperand &MO = MI.getOperand(OpNo); 241 242 // If the destination is an immediate, divide by 4. 243 if (MO.isImm()) return MO.getImm() >> 2; 244 245 assert(MO.isExpr() && 246 "getBranchTargetOpValue expects only expressions or immediates"); 247 248 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 249 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 250 Fixups.push_back(MCFixup::create(0, FixupExpression, 251 MCFixupKind(Mips::fixup_Mips_PC16))); 252 return 0; 253 } 254 255 /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 256 /// target operand. If the machine operand requires relocation, 257 /// record the relocation and return zero. 258 unsigned MipsMCCodeEmitter:: 259 getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 260 SmallVectorImpl<MCFixup> &Fixups, 261 const MCSubtargetInfo &STI) const { 262 const MCOperand &MO = MI.getOperand(OpNo); 263 264 // If the destination is an immediate, divide by 2. 265 if (MO.isImm()) return MO.getImm() >> 1; 266 267 assert(MO.isExpr() && 268 "getBranchTargetOpValue expects only expressions or immediates"); 269 270 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 271 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 272 Fixups.push_back(MCFixup::create(0, FixupExpression, 273 MCFixupKind(Mips::fixup_Mips_PC16))); 274 return 0; 275 } 276 277 /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch 278 /// target operand. If the machine operand requires relocation, 279 /// record the relocation and return zero. 280 unsigned MipsMCCodeEmitter:: 281 getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, 282 SmallVectorImpl<MCFixup> &Fixups, 283 const MCSubtargetInfo &STI) const { 284 const MCOperand &MO = MI.getOperand(OpNo); 285 286 // If the destination is an immediate, divide by 2. 287 if (MO.isImm()) 288 return MO.getImm() >> 1; 289 290 assert(MO.isExpr() && 291 "getBranchTargetOpValueMMR6 expects only expressions or immediates"); 292 293 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 294 MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); 295 Fixups.push_back(MCFixup::create(0, FixupExpression, 296 MCFixupKind(Mips::fixup_Mips_PC16))); 297 return 0; 298 } 299 300 /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch 301 /// target operand. If the machine operand requires relocation, 302 /// record the relocation and return zero. 303 unsigned MipsMCCodeEmitter:: 304 getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, 305 SmallVectorImpl<MCFixup> &Fixups, 306 const MCSubtargetInfo &STI) const { 307 const MCOperand &MO = MI.getOperand(OpNo); 308 309 // If the destination is an immediate, divide by 4. 310 if (MO.isImm()) 311 return MO.getImm() >> 2; 312 313 assert(MO.isExpr() && 314 "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates"); 315 316 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 317 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 318 Fixups.push_back(MCFixup::create(0, FixupExpression, 319 MCFixupKind(Mips::fixup_Mips_PC16))); 320 return 0; 321 } 322 323 /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 324 /// target operand. If the machine operand requires relocation, 325 /// record the relocation and return zero. 326 unsigned MipsMCCodeEmitter:: 327 getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 328 SmallVectorImpl<MCFixup> &Fixups, 329 const MCSubtargetInfo &STI) const { 330 const MCOperand &MO = MI.getOperand(OpNo); 331 332 // If the destination is an immediate, divide by 2. 333 if (MO.isImm()) return MO.getImm() >> 1; 334 335 assert(MO.isExpr() && 336 "getBranchTargetOpValueMM expects only expressions or immediates"); 337 338 const MCExpr *Expr = MO.getExpr(); 339 Fixups.push_back(MCFixup::create(0, Expr, 340 MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 341 return 0; 342 } 343 344 /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 345 /// 10-bit branch target operand. If the machine operand requires relocation, 346 /// record the relocation and return zero. 347 unsigned MipsMCCodeEmitter:: 348 getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 349 SmallVectorImpl<MCFixup> &Fixups, 350 const MCSubtargetInfo &STI) const { 351 const MCOperand &MO = MI.getOperand(OpNo); 352 353 // If the destination is an immediate, divide by 2. 354 if (MO.isImm()) return MO.getImm() >> 1; 355 356 assert(MO.isExpr() && 357 "getBranchTargetOpValuePC10 expects only expressions or immediates"); 358 359 const MCExpr *Expr = MO.getExpr(); 360 Fixups.push_back(MCFixup::create(0, Expr, 361 MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 362 return 0; 363 } 364 365 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 366 /// target operand. If the machine operand requires relocation, 367 /// record the relocation and return zero. 368 unsigned MipsMCCodeEmitter:: 369 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 370 SmallVectorImpl<MCFixup> &Fixups, 371 const MCSubtargetInfo &STI) const { 372 const MCOperand &MO = MI.getOperand(OpNo); 373 374 // If the destination is an immediate, divide by 2. 375 if (MO.isImm()) return MO.getImm() >> 1; 376 377 assert(MO.isExpr() && 378 "getBranchTargetOpValueMM expects only expressions or immediates"); 379 380 const MCExpr *Expr = MO.getExpr(); 381 Fixups.push_back(MCFixup::create(0, Expr, 382 MCFixupKind(Mips:: 383 fixup_MICROMIPS_PC16_S1))); 384 return 0; 385 } 386 387 /// getBranchTarget21OpValue - Return binary encoding of the branch 388 /// target operand. If the machine operand requires relocation, 389 /// record the relocation and return zero. 390 unsigned MipsMCCodeEmitter:: 391 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 392 SmallVectorImpl<MCFixup> &Fixups, 393 const MCSubtargetInfo &STI) const { 394 const MCOperand &MO = MI.getOperand(OpNo); 395 396 // If the destination is an immediate, divide by 4. 397 if (MO.isImm()) return MO.getImm() >> 2; 398 399 assert(MO.isExpr() && 400 "getBranchTarget21OpValue expects only expressions or immediates"); 401 402 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 403 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 404 Fixups.push_back(MCFixup::create(0, FixupExpression, 405 MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 406 return 0; 407 } 408 409 /// getBranchTarget21OpValueMM - Return binary encoding of the branch 410 /// target operand for microMIPS. If the machine operand requires 411 /// relocation, record the relocation and return zero. 412 unsigned MipsMCCodeEmitter:: 413 getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 414 SmallVectorImpl<MCFixup> &Fixups, 415 const MCSubtargetInfo &STI) const { 416 const MCOperand &MO = MI.getOperand(OpNo); 417 418 // If the destination is an immediate, divide by 4. 419 if (MO.isImm()) return MO.getImm() >> 2; 420 421 assert(MO.isExpr() && 422 "getBranchTarget21OpValueMM expects only expressions or immediates"); 423 424 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 425 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 426 Fixups.push_back(MCFixup::create(0, FixupExpression, 427 MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 428 return 0; 429 } 430 431 /// getBranchTarget26OpValue - Return binary encoding of the branch 432 /// target operand. If the machine operand requires relocation, 433 /// record the relocation and return zero. 434 unsigned MipsMCCodeEmitter:: 435 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 436 SmallVectorImpl<MCFixup> &Fixups, 437 const MCSubtargetInfo &STI) const { 438 const MCOperand &MO = MI.getOperand(OpNo); 439 440 // If the destination is an immediate, divide by 4. 441 if (MO.isImm()) return MO.getImm() >> 2; 442 443 assert(MO.isExpr() && 444 "getBranchTarget26OpValue expects only expressions or immediates"); 445 446 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 447 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 448 Fixups.push_back(MCFixup::create(0, FixupExpression, 449 MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 450 return 0; 451 } 452 453 /// getBranchTarget26OpValueMM - Return binary encoding of the branch 454 /// target operand. If the machine operand requires relocation, 455 /// record the relocation and return zero. 456 unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 457 const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 458 const MCSubtargetInfo &STI) const { 459 const MCOperand &MO = MI.getOperand(OpNo); 460 461 // If the destination is an immediate, divide by 2. 462 if (MO.isImm()) 463 return MO.getImm() >> 1; 464 465 assert(MO.isExpr() && 466 "getBranchTarget26OpValueMM expects only expressions or immediates"); 467 468 const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 469 MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 470 Fixups.push_back(MCFixup::create(0, FixupExpression, 471 MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 472 return 0; 473 } 474 475 /// getJumpOffset16OpValue - Return binary encoding of the jump 476 /// target operand. If the machine operand requires relocation, 477 /// record the relocation and return zero. 478 unsigned MipsMCCodeEmitter:: 479 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 480 SmallVectorImpl<MCFixup> &Fixups, 481 const MCSubtargetInfo &STI) const { 482 const MCOperand &MO = MI.getOperand(OpNo); 483 484 if (MO.isImm()) return MO.getImm(); 485 486 assert(MO.isExpr() && 487 "getJumpOffset16OpValue expects only expressions or an immediate"); 488 489 // TODO: Push fixup. 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 = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 602 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 603 return Res; 604 } 605 606 if (Kind == MCExpr::Target) { 607 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 608 609 Mips::Fixups FixupKind = Mips::Fixups(0); 610 switch (MipsExpr->getKind()) { 611 case MipsMCExpr::MEK_None: 612 case MipsMCExpr::MEK_Special: 613 llvm_unreachable("Unhandled fixup kind!"); 614 break; 615 case MipsMCExpr::MEK_DTPREL: 616 // MEK_DTPREL is used for marking TLS DIEExpr only 617 // and contains a regular sub-expression. 618 return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI); 619 case MipsMCExpr::MEK_CALL_HI16: 620 FixupKind = Mips::fixup_Mips_CALL_HI16; 621 break; 622 case MipsMCExpr::MEK_CALL_LO16: 623 FixupKind = Mips::fixup_Mips_CALL_LO16; 624 break; 625 case MipsMCExpr::MEK_DTPREL_HI: 626 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 627 : Mips::fixup_Mips_DTPREL_HI; 628 break; 629 case MipsMCExpr::MEK_DTPREL_LO: 630 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 631 : Mips::fixup_Mips_DTPREL_LO; 632 break; 633 case MipsMCExpr::MEK_GOTTPREL: 634 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL 635 : Mips::fixup_Mips_GOTTPREL; 636 break; 637 case MipsMCExpr::MEK_GOT: 638 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 639 : Mips::fixup_Mips_GOT; 640 break; 641 case MipsMCExpr::MEK_GOT_CALL: 642 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 643 : Mips::fixup_Mips_CALL16; 644 break; 645 case MipsMCExpr::MEK_GOT_DISP: 646 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 647 : Mips::fixup_Mips_GOT_DISP; 648 break; 649 case MipsMCExpr::MEK_GOT_HI16: 650 FixupKind = Mips::fixup_Mips_GOT_HI16; 651 break; 652 case MipsMCExpr::MEK_GOT_LO16: 653 FixupKind = Mips::fixup_Mips_GOT_LO16; 654 break; 655 case MipsMCExpr::MEK_GOT_PAGE: 656 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 657 : Mips::fixup_Mips_GOT_PAGE; 658 break; 659 case MipsMCExpr::MEK_GOT_OFST: 660 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 661 : Mips::fixup_Mips_GOT_OFST; 662 break; 663 case MipsMCExpr::MEK_GPREL: 664 FixupKind = Mips::fixup_Mips_GPREL16; 665 break; 666 case MipsMCExpr::MEK_LO: 667 // Check for %lo(%neg(%gp_rel(X))) 668 if (MipsExpr->isGpOff()) 669 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO 670 : Mips::fixup_Mips_GPOFF_LO; 671 else 672 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 673 : Mips::fixup_Mips_LO16; 674 break; 675 case MipsMCExpr::MEK_HIGHEST: 676 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST 677 : Mips::fixup_Mips_HIGHEST; 678 break; 679 case MipsMCExpr::MEK_HIGHER: 680 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER 681 : Mips::fixup_Mips_HIGHER; 682 break; 683 case MipsMCExpr::MEK_HI: 684 // Check for %hi(%neg(%gp_rel(X))) 685 if (MipsExpr->isGpOff()) 686 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI 687 : Mips::fixup_Mips_GPOFF_HI; 688 else 689 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 690 : Mips::fixup_Mips_HI16; 691 break; 692 case MipsMCExpr::MEK_PCREL_HI16: 693 FixupKind = Mips::fixup_MIPS_PCHI16; 694 break; 695 case MipsMCExpr::MEK_PCREL_LO16: 696 FixupKind = Mips::fixup_MIPS_PCLO16; 697 break; 698 case MipsMCExpr::MEK_TLSGD: 699 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 700 : Mips::fixup_Mips_TLSGD; 701 break; 702 case MipsMCExpr::MEK_TLSLDM: 703 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 704 : Mips::fixup_Mips_TLSLDM; 705 break; 706 case MipsMCExpr::MEK_TPREL_HI: 707 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 708 : Mips::fixup_Mips_TPREL_HI; 709 break; 710 case MipsMCExpr::MEK_TPREL_LO: 711 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 712 : Mips::fixup_Mips_TPREL_LO; 713 break; 714 case MipsMCExpr::MEK_NEG: 715 FixupKind = 716 isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; 717 break; 718 } 719 Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 720 return 0; 721 } 722 723 if (Kind == MCExpr::SymbolRef) { 724 Mips::Fixups FixupKind = Mips::Fixups(0); 725 726 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 727 default: llvm_unreachable("Unknown fixup kind!"); 728 break; 729 case MCSymbolRefExpr::VK_None: 730 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 731 break; 732 } // switch 733 734 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 735 return 0; 736 } 737 return 0; 738 } 739 740 /// getMachineOpValue - Return binary encoding of operand. If the machine 741 /// operand requires relocation, record the relocation and return zero. 742 unsigned MipsMCCodeEmitter:: 743 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 744 SmallVectorImpl<MCFixup> &Fixups, 745 const MCSubtargetInfo &STI) const { 746 if (MO.isReg()) { 747 unsigned Reg = MO.getReg(); 748 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 749 return RegNo; 750 } else if (MO.isImm()) { 751 return static_cast<unsigned>(MO.getImm()); 752 } else if (MO.isFPImm()) { 753 return static_cast<unsigned>(APFloat(MO.getFPImm()) 754 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 755 } 756 // MO must be an Expr. 757 assert(MO.isExpr()); 758 return getExprOpValue(MO.getExpr(),Fixups, STI); 759 } 760 761 /// Return binary encoding of memory related operand. 762 /// If the offset operand requires relocation, record the relocation. 763 template <unsigned ShiftAmount> 764 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 765 SmallVectorImpl<MCFixup> &Fixups, 766 const MCSubtargetInfo &STI) const { 767 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 768 assert(MI.getOperand(OpNo).isReg()); 769 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 770 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 771 772 // Apply the scale factor if there is one. 773 OffBits >>= ShiftAmount; 774 775 return (OffBits & 0xFFFF) | RegBits; 776 } 777 778 unsigned MipsMCCodeEmitter:: 779 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 780 SmallVectorImpl<MCFixup> &Fixups, 781 const MCSubtargetInfo &STI) const { 782 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 783 assert(MI.getOperand(OpNo).isReg()); 784 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 785 Fixups, STI) << 4; 786 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 787 Fixups, STI); 788 789 return (OffBits & 0xF) | RegBits; 790 } 791 792 unsigned MipsMCCodeEmitter:: 793 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 794 SmallVectorImpl<MCFixup> &Fixups, 795 const MCSubtargetInfo &STI) const { 796 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 797 assert(MI.getOperand(OpNo).isReg()); 798 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 799 Fixups, STI) << 4; 800 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 801 Fixups, STI) >> 1; 802 803 return (OffBits & 0xF) | RegBits; 804 } 805 806 unsigned MipsMCCodeEmitter:: 807 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 808 SmallVectorImpl<MCFixup> &Fixups, 809 const MCSubtargetInfo &STI) const { 810 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 811 assert(MI.getOperand(OpNo).isReg()); 812 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 813 Fixups, STI) << 4; 814 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 815 Fixups, STI) >> 2; 816 817 return (OffBits & 0xF) | RegBits; 818 } 819 820 unsigned MipsMCCodeEmitter:: 821 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 822 SmallVectorImpl<MCFixup> &Fixups, 823 const MCSubtargetInfo &STI) const { 824 // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 825 assert(MI.getOperand(OpNo).isReg() && 826 (MI.getOperand(OpNo).getReg() == Mips::SP || 827 MI.getOperand(OpNo).getReg() == Mips::SP_64) && 828 "Unexpected base register!"); 829 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 830 Fixups, STI) >> 2; 831 832 return OffBits & 0x1F; 833 } 834 835 unsigned MipsMCCodeEmitter:: 836 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 837 SmallVectorImpl<MCFixup> &Fixups, 838 const MCSubtargetInfo &STI) const { 839 // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 840 assert(MI.getOperand(OpNo).isReg() && 841 MI.getOperand(OpNo).getReg() == Mips::GP && 842 "Unexpected base register!"); 843 844 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 845 Fixups, STI) >> 2; 846 847 return OffBits & 0x7F; 848 } 849 850 unsigned MipsMCCodeEmitter:: 851 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 852 SmallVectorImpl<MCFixup> &Fixups, 853 const MCSubtargetInfo &STI) const { 854 // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 855 assert(MI.getOperand(OpNo).isReg()); 856 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 857 STI) << 16; 858 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 859 860 return (OffBits & 0x1FF) | RegBits; 861 } 862 863 unsigned MipsMCCodeEmitter:: 864 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 865 SmallVectorImpl<MCFixup> &Fixups, 866 const MCSubtargetInfo &STI) const { 867 // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 868 assert(MI.getOperand(OpNo).isReg()); 869 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 870 STI) << 16; 871 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 872 873 return (OffBits & 0x07FF) | RegBits; 874 } 875 876 unsigned MipsMCCodeEmitter:: 877 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 878 SmallVectorImpl<MCFixup> &Fixups, 879 const MCSubtargetInfo &STI) const { 880 // opNum can be invalid if instruction had reglist as operand. 881 // MemOperand is always last operand of instruction (base + offset). 882 switch (MI.getOpcode()) { 883 default: 884 break; 885 case Mips::SWM32_MM: 886 case Mips::LWM32_MM: 887 OpNo = MI.getNumOperands() - 2; 888 break; 889 } 890 891 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 892 assert(MI.getOperand(OpNo).isReg()); 893 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 894 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 895 896 return (OffBits & 0x0FFF) | RegBits; 897 } 898 899 unsigned MipsMCCodeEmitter:: 900 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 901 SmallVectorImpl<MCFixup> &Fixups, 902 const MCSubtargetInfo &STI) const { 903 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 904 assert(MI.getOperand(OpNo).isReg()); 905 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 906 STI) << 16; 907 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 908 909 return (OffBits & 0xFFFF) | RegBits; 910 } 911 912 unsigned MipsMCCodeEmitter:: 913 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 914 SmallVectorImpl<MCFixup> &Fixups, 915 const MCSubtargetInfo &STI) const { 916 // opNum can be invalid if instruction had reglist as operand 917 // MemOperand is always last operand of instruction (base + offset) 918 switch (MI.getOpcode()) { 919 default: 920 break; 921 case Mips::SWM16_MM: 922 case Mips::SWM16_MMR6: 923 case Mips::LWM16_MM: 924 case Mips::LWM16_MMR6: 925 OpNo = MI.getNumOperands() - 2; 926 break; 927 } 928 929 // Offset is encoded in bits 4-0. 930 assert(MI.getOperand(OpNo).isReg()); 931 // Base register is always SP - thus it is not encoded. 932 assert(MI.getOperand(OpNo+1).isImm()); 933 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 934 935 return ((OffBits >> 2) & 0x0F); 936 } 937 938 // FIXME: should be called getMSBEncoding 939 // 940 unsigned 941 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 942 SmallVectorImpl<MCFixup> &Fixups, 943 const MCSubtargetInfo &STI) const { 944 assert(MI.getOperand(OpNo-1).isImm()); 945 assert(MI.getOperand(OpNo).isImm()); 946 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 947 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 948 949 return Position + Size - 1; 950 } 951 952 template <unsigned Bits, int Offset> 953 unsigned 954 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 955 SmallVectorImpl<MCFixup> &Fixups, 956 const MCSubtargetInfo &STI) const { 957 assert(MI.getOperand(OpNo).isImm()); 958 unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 959 Value -= Offset; 960 return Value; 961 } 962 963 unsigned 964 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 965 SmallVectorImpl<MCFixup> &Fixups, 966 const MCSubtargetInfo &STI) const { 967 const MCOperand &MO = MI.getOperand(OpNo); 968 if (MO.isImm()) { 969 // The immediate is encoded as 'immediate << 2'. 970 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 971 assert((Res & 3) == 0); 972 return Res >> 2; 973 } 974 975 assert(MO.isExpr() && 976 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 977 978 const MCExpr *Expr = MO.getExpr(); 979 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 980 : Mips::fixup_MIPS_PC19_S2; 981 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 982 return 0; 983 } 984 985 unsigned 986 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 987 SmallVectorImpl<MCFixup> &Fixups, 988 const MCSubtargetInfo &STI) const { 989 const MCOperand &MO = MI.getOperand(OpNo); 990 if (MO.isImm()) { 991 // The immediate is encoded as 'immediate << 3'. 992 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 993 assert((Res & 7) == 0); 994 return Res >> 3; 995 } 996 997 assert(MO.isExpr() && 998 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 999 1000 const MCExpr *Expr = MO.getExpr(); 1001 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 1002 : Mips::fixup_MIPS_PC18_S3; 1003 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1004 return 0; 1005 } 1006 1007 unsigned 1008 MipsMCCodeEmitter::getUImm3Mod8Encoding(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 return MO.getImm() % 8; 1014 } 1015 1016 unsigned 1017 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 1018 SmallVectorImpl<MCFixup> &Fixups, 1019 const MCSubtargetInfo &STI) const { 1020 assert(MI.getOperand(OpNo).isImm()); 1021 const MCOperand &MO = MI.getOperand(OpNo); 1022 unsigned Value = MO.getImm(); 1023 switch (Value) { 1024 case 128: return 0x0; 1025 case 1: return 0x1; 1026 case 2: return 0x2; 1027 case 3: return 0x3; 1028 case 4: return 0x4; 1029 case 7: return 0x5; 1030 case 8: return 0x6; 1031 case 15: return 0x7; 1032 case 16: return 0x8; 1033 case 31: return 0x9; 1034 case 32: return 0xa; 1035 case 63: return 0xb; 1036 case 64: return 0xc; 1037 case 255: return 0xd; 1038 case 32768: return 0xe; 1039 case 65535: return 0xf; 1040 } 1041 llvm_unreachable("Unexpected value"); 1042 } 1043 1044 unsigned 1045 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1046 SmallVectorImpl<MCFixup> &Fixups, 1047 const MCSubtargetInfo &STI) const { 1048 unsigned res = 0; 1049 1050 // Register list operand is always first operand of instruction and it is 1051 // placed before memory operand (register + imm). 1052 1053 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1054 unsigned Reg = MI.getOperand(I).getReg(); 1055 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1056 if (RegNo != 31) 1057 res++; 1058 else 1059 res |= 0x10; 1060 } 1061 return res; 1062 } 1063 1064 unsigned 1065 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1066 SmallVectorImpl<MCFixup> &Fixups, 1067 const MCSubtargetInfo &STI) const { 1068 return (MI.getNumOperands() - 4); 1069 } 1070 1071 unsigned 1072 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 1073 SmallVectorImpl<MCFixup> &Fixups, 1074 const MCSubtargetInfo &STI) const { 1075 unsigned res = 0; 1076 1077 if (MI.getOperand(0).getReg() == Mips::A1 && 1078 MI.getOperand(1).getReg() == Mips::A2) 1079 res = 0; 1080 else if (MI.getOperand(0).getReg() == Mips::A1 && 1081 MI.getOperand(1).getReg() == Mips::A3) 1082 res = 1; 1083 else if (MI.getOperand(0).getReg() == Mips::A2 && 1084 MI.getOperand(1).getReg() == Mips::A3) 1085 res = 2; 1086 else if (MI.getOperand(0).getReg() == Mips::A0 && 1087 MI.getOperand(1).getReg() == Mips::S5) 1088 res = 3; 1089 else if (MI.getOperand(0).getReg() == Mips::A0 && 1090 MI.getOperand(1).getReg() == Mips::S6) 1091 res = 4; 1092 else if (MI.getOperand(0).getReg() == Mips::A0 && 1093 MI.getOperand(1).getReg() == Mips::A1) 1094 res = 5; 1095 else if (MI.getOperand(0).getReg() == Mips::A0 && 1096 MI.getOperand(1).getReg() == Mips::A2) 1097 res = 6; 1098 else if (MI.getOperand(0).getReg() == Mips::A0 && 1099 MI.getOperand(1).getReg() == Mips::A3) 1100 res = 7; 1101 1102 return res; 1103 } 1104 1105 unsigned 1106 MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, 1107 SmallVectorImpl<MCFixup> &Fixups, 1108 const MCSubtargetInfo &STI) const { 1109 assert(((OpNo == 2) || (OpNo == 3)) && 1110 "Unexpected OpNo for movep operand encoding!"); 1111 1112 MCOperand Op = MI.getOperand(OpNo); 1113 assert(Op.isReg() && "Operand of movep is not a register!"); 1114 switch (Op.getReg()) { 1115 default: 1116 llvm_unreachable("Unknown register for movep!"); 1117 case Mips::ZERO: return 0; 1118 case Mips::S1: return 1; 1119 case Mips::V0: return 2; 1120 case Mips::V1: return 3; 1121 case Mips::S0: return 4; 1122 case Mips::S2: return 5; 1123 case Mips::S3: return 6; 1124 case Mips::S4: return 7; 1125 } 1126 } 1127 1128 unsigned 1129 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 1130 SmallVectorImpl<MCFixup> &Fixups, 1131 const MCSubtargetInfo &STI) const { 1132 const MCOperand &MO = MI.getOperand(OpNo); 1133 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 1134 // The immediate is encoded as 'immediate >> 2'. 1135 unsigned Res = static_cast<unsigned>(MO.getImm()); 1136 assert((Res & 3) == 0); 1137 return Res >> 2; 1138 } 1139 1140 #include "MipsGenMCCodeEmitter.inc" 1141