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