19f610119SJia Liu //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===// 2750ecec7SAkira Hatanaka // 3750ecec7SAkira Hatanaka // The LLVM Compiler Infrastructure 4750ecec7SAkira Hatanaka // 5750ecec7SAkira Hatanaka // This file is distributed under the University of Illinois Open Source 6750ecec7SAkira Hatanaka // License. See LICENSE.TXT for details. 7750ecec7SAkira Hatanaka // 8750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===// 9750ecec7SAkira Hatanaka // 10750ecec7SAkira Hatanaka // This file implements the MipsMCCodeEmitter class. 11750ecec7SAkira Hatanaka // 12750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===// 13750ecec7SAkira Hatanaka // 149e1450bcSMatheus Almeida 159e1450bcSMatheus Almeida #include "MipsMCCodeEmitter.h" 16c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsFixupKinds.h" 17a5da588bSPetar Jovanovic #include "MCTargetDesc/MipsMCExpr.h" 18c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsMCTargetDesc.h" 19c85e3ff3SBruno Cardoso Lopes #include "llvm/ADT/APFloat.h" 209e1450bcSMatheus Almeida #include "llvm/ADT/SmallVector.h" 215d6faed1SAkira Hatanaka #include "llvm/MC/MCContext.h" 22750ecec7SAkira Hatanaka #include "llvm/MC/MCExpr.h" 23d9903888SChandler Carruth #include "llvm/MC/MCFixup.h" 24750ecec7SAkira Hatanaka #include "llvm/MC/MCInst.h" 25750ecec7SAkira Hatanaka #include "llvm/MC/MCInstrInfo.h" 263de83e40SPete Cooper #include "llvm/MC/MCRegisterInfo.h" 27750ecec7SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h" 28750ecec7SAkira Hatanaka #include "llvm/Support/raw_ostream.h" 29750ecec7SAkira Hatanaka 3084e68b29SChandler Carruth #define DEBUG_TYPE "mccodeemitter" 3184e68b29SChandler Carruth 32be6a818fSAkira Hatanaka #define GET_INSTRMAP_INFO 33be6a818fSAkira Hatanaka #include "MipsGenInstrInfo.inc" 349e1450bcSMatheus Almeida #undef GET_INSTRMAP_INFO 35be6a818fSAkira Hatanaka 369e1450bcSMatheus Almeida namespace llvm { 379e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 38c3b04279SJim Grosbach const MCRegisterInfo &MRI, 399e1450bcSMatheus Almeida MCContext &Ctx) { 40d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, false); 411ee768dbSAkira Hatanaka } 421ee768dbSAkira Hatanaka 439e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 44c3b04279SJim Grosbach const MCRegisterInfo &MRI, 459e1450bcSMatheus Almeida MCContext &Ctx) { 46d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, true); 47750ecec7SAkira Hatanaka } 489e1450bcSMatheus Almeida } // End of namespace llvm. 49f30f2cceSRafael Espindola 50f30f2cceSRafael Espindola // If the D<shift> instruction has a shift amount that is greater 51f30f2cceSRafael Espindola // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 52f30f2cceSRafael Espindola static void LowerLargeShift(MCInst& Inst) { 53f30f2cceSRafael Espindola 54f30f2cceSRafael Espindola assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 55f30f2cceSRafael Espindola assert(Inst.getOperand(2).isImm()); 56f30f2cceSRafael Espindola 57f30f2cceSRafael Espindola int64_t Shift = Inst.getOperand(2).getImm(); 58f30f2cceSRafael Espindola if (Shift <= 31) 59f30f2cceSRafael Espindola return; // Do nothing 60f30f2cceSRafael Espindola Shift -= 32; 61f30f2cceSRafael Espindola 62f30f2cceSRafael Espindola // saminus32 63f30f2cceSRafael Espindola Inst.getOperand(2).setImm(Shift); 64f30f2cceSRafael Espindola 65f30f2cceSRafael Espindola switch (Inst.getOpcode()) { 66f30f2cceSRafael Espindola default: 67f30f2cceSRafael Espindola // Calling function is not synchronized 68f30f2cceSRafael Espindola llvm_unreachable("Unexpected shift instruction"); 69f30f2cceSRafael Espindola case Mips::DSLL: 70f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSLL32); 71f30f2cceSRafael Espindola return; 72f30f2cceSRafael Espindola case Mips::DSRL: 73f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRL32); 74f30f2cceSRafael Espindola return; 75f30f2cceSRafael Espindola case Mips::DSRA: 76f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRA32); 77f30f2cceSRafael Espindola return; 786a3fe574SAkira Hatanaka case Mips::DROTR: 796a3fe574SAkira Hatanaka Inst.setOpcode(Mips::DROTR32); 806a3fe574SAkira Hatanaka return; 81f30f2cceSRafael Espindola } 82f30f2cceSRafael Espindola } 83f30f2cceSRafael Espindola 84611eb829SDaniel Sanders // Pick a DINS instruction variant based on the pos and size operands 85611eb829SDaniel Sanders static void LowerDins(MCInst& InstIn) { 86f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 5 && 87f30f2cceSRafael Espindola "Invalid no. of machine operands for DINS!"); 88f30f2cceSRafael Espindola 89f30f2cceSRafael Espindola assert(InstIn.getOperand(2).isImm()); 90f30f2cceSRafael Espindola int64_t pos = InstIn.getOperand(2).getImm(); 91f30f2cceSRafael Espindola assert(InstIn.getOperand(3).isImm()); 92f30f2cceSRafael Espindola int64_t size = InstIn.getOperand(3).getImm(); 93f30f2cceSRafael Espindola 94f30f2cceSRafael Espindola if (size <= 32) { 95611eb829SDaniel Sanders if (pos < 32) // DINS, do nothing 96f30f2cceSRafael Espindola return; 97611eb829SDaniel Sanders // DINSU 98f30f2cceSRafael Espindola InstIn.getOperand(2).setImm(pos - 32); 99611eb829SDaniel Sanders InstIn.setOpcode(Mips::DINSU); 100f30f2cceSRafael Espindola return; 101f30f2cceSRafael Espindola } 102611eb829SDaniel Sanders // DINSM 103611eb829SDaniel Sanders assert(pos < 32 && "DINS cannot have both size and pos > 32"); 104f30f2cceSRafael Espindola InstIn.getOperand(3).setImm(size - 32); 105611eb829SDaniel Sanders InstIn.setOpcode(Mips::DINSM); 106f30f2cceSRafael Espindola return; 107f30f2cceSRafael Espindola } 108f30f2cceSRafael Espindola 109669d8dd8SSimon Dardis // Fix a bad compact branch encoding for beqc/bnec. 110669d8dd8SSimon Dardis void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { 111669d8dd8SSimon Dardis 112669d8dd8SSimon Dardis // Encoding may be illegal !(rs < rt), but this situation is 113669d8dd8SSimon Dardis // easily fixed. 114669d8dd8SSimon Dardis unsigned RegOp0 = Inst.getOperand(0).getReg(); 115669d8dd8SSimon Dardis unsigned RegOp1 = Inst.getOperand(1).getReg(); 116669d8dd8SSimon Dardis 117669d8dd8SSimon Dardis unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); 118669d8dd8SSimon Dardis unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); 119669d8dd8SSimon Dardis 120b60833c0SSimon Dardis if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC) { 121669d8dd8SSimon Dardis assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!"); 122669d8dd8SSimon Dardis if (Reg0 < Reg1) 123669d8dd8SSimon Dardis return; 124b60833c0SSimon Dardis } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) { 125b60833c0SSimon Dardis if (Reg0 >= Reg1) 126b60833c0SSimon Dardis return; 127*c962c493SHrvoje Varga } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || 128*c962c493SHrvoje Varga Inst.getOpcode() == Mips::BOVC_MMR6) { 129*c962c493SHrvoje Varga if (Reg1 >= Reg0) 130*c962c493SHrvoje Varga return; 131b60833c0SSimon Dardis } else 132b60833c0SSimon Dardis llvm_unreachable("Cannot rewrite unknown branch!"); 133669d8dd8SSimon Dardis 134669d8dd8SSimon Dardis Inst.getOperand(0).setReg(RegOp1); 135669d8dd8SSimon Dardis Inst.getOperand(1).setReg(RegOp0); 136669d8dd8SSimon Dardis 137669d8dd8SSimon Dardis } 138669d8dd8SSimon Dardis 1399e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 140db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMicroMips]; 1419e1450bcSMatheus Almeida } 1429e1450bcSMatheus Almeida 143c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 144db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 145c22555d9SJozef Kolek } 146c22555d9SJozef Kolek 1479e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1489e1450bcSMatheus Almeida OS << (char)C; 1499e1450bcSMatheus Almeida } 1509e1450bcSMatheus Almeida 1519e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1529e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1539e1450bcSMatheus Almeida raw_ostream &OS) const { 1549e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1559e1450bcSMatheus Almeida // Little-endian byte ordering: 1569e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1579e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1589e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1599e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1609e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1619e1450bcSMatheus Almeida } else { 1629e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1639e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1649e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1659e1450bcSMatheus Almeida } 1669e1450bcSMatheus Almeida } 1679e1450bcSMatheus Almeida } 1689e1450bcSMatheus Almeida 16991df21f7SJim Grosbach /// encodeInstruction - Emit the instruction. 1704e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 171c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 17291df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS, 1739784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1749784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 175c85e3ff3SBruno Cardoso Lopes { 176aa7aeaa0SJack Carter 177aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 178aa7aeaa0SJack Carter // only based on operand values. 179aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 180aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 181aa7aeaa0SJack Carter MCInst TmpInst = MI; 182aa7aeaa0SJack Carter switch (MI.getOpcode()) { 183aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 184aa7aeaa0SJack Carter case Mips::DSLL: 185aa7aeaa0SJack Carter case Mips::DSRL: 186aa7aeaa0SJack Carter case Mips::DSRA: 1876a3fe574SAkira Hatanaka case Mips::DROTR: 188f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 189aa7aeaa0SJack Carter break; 190aa7aeaa0SJack Carter // Double extract instruction is chosen by pos and size operands 191aa7aeaa0SJack Carter case Mips::DINS: 192611eb829SDaniel Sanders LowerDins(TmpInst); 193669d8dd8SSimon Dardis break; 194b60833c0SSimon Dardis // Compact branches, enforce encoding restrictions. 195669d8dd8SSimon Dardis case Mips::BEQC: 196669d8dd8SSimon Dardis case Mips::BNEC: 197b60833c0SSimon Dardis case Mips::BOVC: 198*c962c493SHrvoje Varga case Mips::BOVC_MMR6: 199b60833c0SSimon Dardis case Mips::BNVC: 200*c962c493SHrvoje Varga case Mips::BNVC_MMR6: 201669d8dd8SSimon Dardis LowerCompactBranch(TmpInst); 202aa7aeaa0SJack Carter } 203aa7aeaa0SJack Carter 20497700977SJack Carter unsigned long N = Fixups.size(); 2053fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 206c85e3ff3SBruno Cardoso Lopes 207c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 208aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 209c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 210aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 211c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 212c7e220f6SJozef Kolek (Opcode != Mips::SLL_MM) && !Binary) 21391df21f7SJim Grosbach llvm_unreachable("unimplemented opcode in encodeInstruction()"); 214c85e3ff3SBruno Cardoso Lopes 215b59a5419SZoran Jovanovic int NewOpcode = -1; 2166ca13eafSJozef Kolek if (isMicroMips(STI)) { 217b59a5419SZoran Jovanovic if (isMips32r6(STI)) { 218b59a5419SZoran Jovanovic NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 219b59a5419SZoran Jovanovic if (NewOpcode == -1) 220b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 221b59a5419SZoran Jovanovic } 222b59a5419SZoran Jovanovic else 223b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 224b59a5419SZoran Jovanovic 2252e386d3dSZoran Jovanovic // Check whether it is Dsp instruction. 2262e386d3dSZoran Jovanovic if (NewOpcode == -1) 2272e386d3dSZoran Jovanovic NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 2282e386d3dSZoran Jovanovic 229be6a818fSAkira Hatanaka if (NewOpcode != -1) { 23097700977SJack Carter if (Fixups.size() > N) 23197700977SJack Carter Fixups.pop_back(); 232b59a5419SZoran Jovanovic 233be6a818fSAkira Hatanaka Opcode = NewOpcode; 234be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 2353fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 236be6a818fSAkira Hatanaka } 237be6a818fSAkira Hatanaka } 238be6a818fSAkira Hatanaka 239aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 240c85e3ff3SBruno Cardoso Lopes 2415b5559d3SJack Carter // Get byte count of instruction 2425b5559d3SJack Carter unsigned Size = Desc.getSize(); 2435b5559d3SJack Carter if (!Size) 2445b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 245c85e3ff3SBruno Cardoso Lopes 246d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 247c85e3ff3SBruno Cardoso Lopes } 248c85e3ff3SBruno Cardoso Lopes 249c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 250c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 251c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 252c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 253c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2543fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2553fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 256c85e3ff3SBruno Cardoso Lopes 257c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 25871e6a749SJack Carter 2594f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2604f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2614f69a0f2SJack Carter 26271e6a749SJack Carter assert(MO.isExpr() && 26371e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 264c85e3ff3SBruno Cardoso Lopes 265b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 266b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 267b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 268c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 269c85e3ff3SBruno Cardoso Lopes return 0; 270c85e3ff3SBruno Cardoso Lopes } 271c85e3ff3SBruno Cardoso Lopes 2726f09cdfdSHrvoje Varga /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 2736f09cdfdSHrvoje Varga /// target operand. If the machine operand requires relocation, 2746f09cdfdSHrvoje Varga /// record the relocation and return zero. 2756f09cdfdSHrvoje Varga unsigned MipsMCCodeEmitter:: 2766f09cdfdSHrvoje Varga getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 2776f09cdfdSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 2786f09cdfdSHrvoje Varga const MCSubtargetInfo &STI) const { 2796f09cdfdSHrvoje Varga 2806f09cdfdSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 2816f09cdfdSHrvoje Varga 2826f09cdfdSHrvoje Varga // If the destination is an immediate, divide by 2. 2836f09cdfdSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 1; 2846f09cdfdSHrvoje Varga 2856f09cdfdSHrvoje Varga assert(MO.isExpr() && 2866f09cdfdSHrvoje Varga "getBranchTargetOpValue expects only expressions or immediates"); 2876f09cdfdSHrvoje Varga 2886f09cdfdSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 2896f09cdfdSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 2906f09cdfdSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 2916f09cdfdSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 2926f09cdfdSHrvoje Varga return 0; 2936f09cdfdSHrvoje Varga } 2946f09cdfdSHrvoje Varga 295*c962c493SHrvoje Varga /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch 296*c962c493SHrvoje Varga /// target operand. If the machine operand requires relocation, 297*c962c493SHrvoje Varga /// record the relocation and return zero. 298*c962c493SHrvoje Varga unsigned MipsMCCodeEmitter:: 299*c962c493SHrvoje Varga getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, 300*c962c493SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 301*c962c493SHrvoje Varga const MCSubtargetInfo &STI) const { 302*c962c493SHrvoje Varga 303*c962c493SHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 304*c962c493SHrvoje Varga 305*c962c493SHrvoje Varga // If the destination is an immediate, divide by 2. 306*c962c493SHrvoje Varga if (MO.isImm()) 307*c962c493SHrvoje Varga return MO.getImm() >> 1; 308*c962c493SHrvoje Varga 309*c962c493SHrvoje Varga assert(MO.isExpr() && 310*c962c493SHrvoje Varga "getBranchTargetOpValueMMR6 expects only expressions or immediates"); 311*c962c493SHrvoje Varga 312*c962c493SHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 313*c962c493SHrvoje Varga MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); 314*c962c493SHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 315*c962c493SHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 316*c962c493SHrvoje Varga return 0; 317*c962c493SHrvoje Varga } 318*c962c493SHrvoje Varga 3199761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 3209761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 3219761e96bSJozef Kolek /// record the relocation and return zero. 3229761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 3239761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 3249761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3259761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 3269761e96bSJozef Kolek 3279761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3289761e96bSJozef Kolek 3299761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 3309761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3319761e96bSJozef Kolek 3329761e96bSJozef Kolek assert(MO.isExpr() && 3339761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 3349761e96bSJozef Kolek 3359761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 33663661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3379761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 3389761e96bSJozef Kolek return 0; 3399761e96bSJozef Kolek } 3409761e96bSJozef Kolek 3415cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 3425cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 3435cfebddeSJozef Kolek /// record the relocation and return zero. 3445cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 3455cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 3465cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3475cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 3485cfebddeSJozef Kolek 3495cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3505cfebddeSJozef Kolek 3515cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 3525cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3535cfebddeSJozef Kolek 3545cfebddeSJozef Kolek assert(MO.isExpr() && 3555cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 3565cfebddeSJozef Kolek 3575cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 35863661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3595cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 3605cfebddeSJozef Kolek return 0; 3615cfebddeSJozef Kolek } 3625cfebddeSJozef Kolek 3638a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 3648a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 3658a80aa76SZoran Jovanovic /// record the relocation and return zero. 3668a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 3678a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 3683fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3693fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 3708a80aa76SZoran Jovanovic 3718a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3728a80aa76SZoran Jovanovic 3738a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 3748a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 3758a80aa76SZoran Jovanovic 3768a80aa76SZoran Jovanovic assert(MO.isExpr() && 3778a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 3788a80aa76SZoran Jovanovic 3798a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 38063661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3818a80aa76SZoran Jovanovic MCFixupKind(Mips:: 3828a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 3838a80aa76SZoran Jovanovic return 0; 3848a80aa76SZoran Jovanovic } 3858a80aa76SZoran Jovanovic 3863c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 3873c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3883c8869dcSZoran Jovanovic /// record the relocation and return zero. 3893c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3903c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 3913c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 3923c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 3933c8869dcSZoran Jovanovic 3943c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3953c8869dcSZoran Jovanovic 3963c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3973c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3983c8869dcSZoran Jovanovic 3993c8869dcSZoran Jovanovic assert(MO.isExpr() && 4003c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 4013c8869dcSZoran Jovanovic 402b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 403b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 404b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 40510e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 4063c8869dcSZoran Jovanovic return 0; 4073c8869dcSZoran Jovanovic } 4083c8869dcSZoran Jovanovic 40984e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch 41084e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires 41184e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero. 41284e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter:: 41384e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 41484e4d59eSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 41584e4d59eSZoran Jovanovic const MCSubtargetInfo &STI) const { 41684e4d59eSZoran Jovanovic 41784e4d59eSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 41884e4d59eSZoran Jovanovic 41984e4d59eSZoran Jovanovic // If the destination is an immediate, divide by 2. 42084e4d59eSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 42184e4d59eSZoran Jovanovic 42284e4d59eSZoran Jovanovic assert(MO.isExpr() && 42384e4d59eSZoran Jovanovic "getBranchTarget21OpValueMM expects only expressions or immediates"); 42484e4d59eSZoran Jovanovic 4255f94cedeSZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 4265f94cedeSZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 4275f94cedeSZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 4285f94cedeSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 42984e4d59eSZoran Jovanovic return 0; 43084e4d59eSZoran Jovanovic } 43184e4d59eSZoran Jovanovic 4323c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 4333c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4343c8869dcSZoran Jovanovic /// record the relocation and return zero. 4353c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4363c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 4373c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4383c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4393c8869dcSZoran Jovanovic 4403c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4413c8869dcSZoran Jovanovic 4423c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4433c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4443c8869dcSZoran Jovanovic 4453c8869dcSZoran Jovanovic assert(MO.isExpr() && 4463c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 4473c8869dcSZoran Jovanovic 448b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 449b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 450b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 45110e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 4523c8869dcSZoran Jovanovic return 0; 4533c8869dcSZoran Jovanovic } 4543c8869dcSZoran Jovanovic 455a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 456a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 457a887b361SZoran Jovanovic /// record the relocation and return zero. 458a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 459a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 460a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 461a887b361SZoran Jovanovic 462a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 463a887b361SZoran Jovanovic 464a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 465a887b361SZoran Jovanovic if (MO.isImm()) 466a887b361SZoran Jovanovic return MO.getImm() >> 1; 467a887b361SZoran Jovanovic 46802b70030SZoran Jovanovic assert(MO.isExpr() && 46902b70030SZoran Jovanovic "getBranchTarget26OpValueMM expects only expressions or immediates"); 47002b70030SZoran Jovanovic 47102b70030SZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 47202b70030SZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 47302b70030SZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 47402b70030SZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 475a887b361SZoran Jovanovic return 0; 476a887b361SZoran Jovanovic } 477a887b361SZoran Jovanovic 47852c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 47952c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 48052c56b93SZoran Jovanovic /// record the relocation and return zero. 48152c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 48252c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 48352c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 48452c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 48552c56b93SZoran Jovanovic 48652c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 48752c56b93SZoran Jovanovic 48852c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 48952c56b93SZoran Jovanovic 49052c56b93SZoran Jovanovic assert(MO.isExpr() && 49152c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 49252c56b93SZoran Jovanovic 49352c56b93SZoran Jovanovic // TODO: Push fixup. 49452c56b93SZoran Jovanovic return 0; 49552c56b93SZoran Jovanovic } 49652c56b93SZoran Jovanovic 497c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 498c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 499c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 500c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 501c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 5023fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5033fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 504c85e3ff3SBruno Cardoso Lopes 505c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 5064f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 5074f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 5084f69a0f2SJack Carter 50971e6a749SJack Carter assert(MO.isExpr() && 51071e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 511c85e3ff3SBruno Cardoso Lopes 512c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 51363661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 514c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 515c85e3ff3SBruno Cardoso Lopes return 0; 516c85e3ff3SBruno Cardoso Lopes } 517c85e3ff3SBruno Cardoso Lopes 518c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 519507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 5203fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5213fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 522507e084aSZoran Jovanovic 523507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 524507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 525507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 526507e084aSZoran Jovanovic 527507e084aSZoran Jovanovic assert(MO.isExpr() && 528507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 529507e084aSZoran Jovanovic 530507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 53163661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 532507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 533507e084aSZoran Jovanovic return 0; 534507e084aSZoran Jovanovic } 535507e084aSZoran Jovanovic 536507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 537c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 538c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 539c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 540c74e3eb9SZoran Jovanovic 541c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 542c74e3eb9SZoran Jovanovic if (MO.isImm()) { 543c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 544c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 545c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 546c74e3eb9SZoran Jovanovic return Res >> 2; 547c74e3eb9SZoran Jovanovic } 548c74e3eb9SZoran Jovanovic 549c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 550c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 551c74e3eb9SZoran Jovanovic 552c74e3eb9SZoran Jovanovic return 0; 553c74e3eb9SZoran Jovanovic } 554c74e3eb9SZoran Jovanovic 555c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 556bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 557bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 558bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 559bac3619bSZoran Jovanovic 560bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 561bac3619bSZoran Jovanovic if (MO.isImm()) { 562bac3619bSZoran Jovanovic int Value = MO.getImm(); 563bac3619bSZoran Jovanovic return Value >> 2; 564bac3619bSZoran Jovanovic } 565bac3619bSZoran Jovanovic 566bac3619bSZoran Jovanovic return 0; 567bac3619bSZoran Jovanovic } 568bac3619bSZoran Jovanovic 569bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 57042b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 57142b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 57242b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 57342b84443SZoran Jovanovic 57442b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 57542b84443SZoran Jovanovic if (MO.isImm()) { 57642b84443SZoran Jovanovic unsigned Value = MO.getImm(); 57742b84443SZoran Jovanovic return Value >> 2; 57842b84443SZoran Jovanovic } 57942b84443SZoran Jovanovic 58042b84443SZoran Jovanovic return 0; 58142b84443SZoran Jovanovic } 58242b84443SZoran Jovanovic 58342b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 58498bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 58598bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 58698bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 58798bd58caSZoran Jovanovic 58898bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 58998bd58caSZoran Jovanovic if (MO.isImm()) { 59098bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 59198bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 59298bd58caSZoran Jovanovic } 59398bd58caSZoran Jovanovic 59498bd58caSZoran Jovanovic return 0; 59598bd58caSZoran Jovanovic } 59698bd58caSZoran Jovanovic 59798bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 5983fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 5993fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 600b5cf5909SJack Carter int64_t Res; 601049e9e4dSAkira Hatanaka 60213760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 603b5cf5909SJack Carter return Res; 604fe384a2cSAkira Hatanaka 605fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 606b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 607b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 608b5cf5909SJack Carter } 609fe384a2cSAkira Hatanaka 610fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 6113fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 6123fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 613b5cf5909SJack Carter return Res; 614fe384a2cSAkira Hatanaka } 615a5da588bSPetar Jovanovic 616a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 617a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 618a5da588bSPetar Jovanovic 619a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 620a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 621fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_NEG: 622fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_None: 623fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_Special: 624fe98b2f5SDaniel Sanders llvm_unreachable("Unhandled fixup kind!"); 625fe98b2f5SDaniel Sanders break; 626fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_HI16: 627fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_HI16; 628fe98b2f5SDaniel Sanders break; 629fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_LO16: 630fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_LO16; 631fe98b2f5SDaniel Sanders break; 632fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_HI: 633fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 634fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_HI; 635fe98b2f5SDaniel Sanders break; 636fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_LO: 637fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 638fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_LO; 639fe98b2f5SDaniel Sanders break; 640fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOTTPREL: 641fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOTTPREL; 642fe98b2f5SDaniel Sanders break; 643fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT: 644fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 645fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT; 646fe98b2f5SDaniel Sanders break; 647fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_CALL: 648fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 649fe98b2f5SDaniel Sanders : Mips::fixup_Mips_CALL16; 650fe98b2f5SDaniel Sanders break; 651fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_DISP: 652fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 653fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_DISP; 654fe98b2f5SDaniel Sanders break; 655fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_HI16: 656fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_HI16; 657fe98b2f5SDaniel Sanders break; 658fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_LO16: 659fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_LO16; 660fe98b2f5SDaniel Sanders break; 661fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_PAGE: 662fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 663fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_PAGE; 664fe98b2f5SDaniel Sanders break; 665fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_OFST: 666fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 667fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_OFST; 668fe98b2f5SDaniel Sanders break; 669fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GPREL: 670fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPREL16; 671fe98b2f5SDaniel Sanders break; 672fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_LO: { 673fe98b2f5SDaniel Sanders // Check for %lo(%neg(%gp_rel(X))) 674fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 675fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_LO; 676fe98b2f5SDaniel Sanders break; 677fe98b2f5SDaniel Sanders } 678fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 679fe98b2f5SDaniel Sanders : Mips::fixup_Mips_LO16; 680fe98b2f5SDaniel Sanders break; 681fe98b2f5SDaniel Sanders } 682fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHEST: 68306c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 68406c47803SSasa Stankovic break; 685fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHER: 68606c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 68706c47803SSasa Stankovic break; 688fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HI: 689fe98b2f5SDaniel Sanders // Check for %hi(%neg(%gp_rel(X))) 690fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 691fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_HI; 692fe98b2f5SDaniel Sanders break; 693fe98b2f5SDaniel Sanders } 694a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 695a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 696a5da588bSPetar Jovanovic break; 697fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_HI16: 698fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCHI16; 699fe98b2f5SDaniel Sanders break; 700fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_LO16: 701fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCLO16; 702fe98b2f5SDaniel Sanders break; 703fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSGD: 704fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 705fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSGD; 706fe98b2f5SDaniel Sanders break; 707fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSLDM: 708fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 709fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSLDM; 710fe98b2f5SDaniel Sanders break; 711fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_HI: 712fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 713fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_HI; 714fe98b2f5SDaniel Sanders break; 715fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_LO: 716fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 717fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_LO; 718a5da588bSPetar Jovanovic break; 719a5da588bSPetar Jovanovic } 72063661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 721a5da588bSPetar Jovanovic return 0; 722a5da588bSPetar Jovanovic } 723a5da588bSPetar Jovanovic 724b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 725f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 726e2eed964SAkira Hatanaka 727049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 728b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 72960f1db05SDaniel Sanders break; 73060f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 73160f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 732b9f9de93SJack Carter break; 733c85e3ff3SBruno Cardoso Lopes } // switch 734fe384a2cSAkira Hatanaka 73563661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 736fe384a2cSAkira Hatanaka return 0; 737c85e3ff3SBruno Cardoso Lopes } 738b5cf5909SJack Carter return 0; 739b5cf5909SJack Carter } 740b5cf5909SJack Carter 741b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 742b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 743b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 744b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 7453fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7463fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 747b5cf5909SJack Carter if (MO.isReg()) { 748b5cf5909SJack Carter unsigned Reg = MO.getReg(); 749bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 750b5cf5909SJack Carter return RegNo; 751b5cf5909SJack Carter } else if (MO.isImm()) { 752b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 753b5cf5909SJack Carter } else if (MO.isFPImm()) { 754b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 755b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 756b5cf5909SJack Carter } 757b5cf5909SJack Carter // MO must be an Expr. 758b5cf5909SJack Carter assert(MO.isExpr()); 7593fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 760b5cf5909SJack Carter } 761c85e3ff3SBruno Cardoso Lopes 762dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand. 763c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 764dc0602a2SDaniel Sanders template <unsigned ShiftAmount> 765dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 7663fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7673fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 768c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 769c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 7703fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 7713fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 772c85e3ff3SBruno Cardoso Lopes 773dc0602a2SDaniel Sanders // Apply the scale factor if there is one. 774dc0602a2SDaniel Sanders OffBits >>= ShiftAmount; 775dc0602a2SDaniel Sanders 776c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 777c85e3ff3SBruno Cardoso Lopes } 778c85e3ff3SBruno Cardoso Lopes 77997700977SJack Carter unsigned MipsMCCodeEmitter:: 780e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 781e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 782e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 783e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 784e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 785e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 786e8c9d1eaSJozef Kolek Fixups, STI) << 4; 787e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 788e8c9d1eaSJozef Kolek Fixups, STI); 789e8c9d1eaSJozef Kolek 790e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 791e8c9d1eaSJozef Kolek } 792e8c9d1eaSJozef Kolek 793e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 794e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 795e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 796e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 797e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 798e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 799e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 800e8c9d1eaSJozef Kolek Fixups, STI) << 4; 801e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 802e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 803e8c9d1eaSJozef Kolek 804e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 805e8c9d1eaSJozef Kolek } 806e8c9d1eaSJozef Kolek 807e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 808e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 809e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 810e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 811e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 812e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 813e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 814e8c9d1eaSJozef Kolek Fixups, STI) << 4; 815e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 816e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 817e8c9d1eaSJozef Kolek 818e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 819e8c9d1eaSJozef Kolek } 820e8c9d1eaSJozef Kolek 821e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 82212c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 82312c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 82412c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 82512c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 82612c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 82768be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 82868be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 82912c6982bSJozef Kolek "Unexpected base register!"); 83012c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 83112c6982bSJozef Kolek Fixups, STI) >> 2; 83212c6982bSJozef Kolek 83312c6982bSJozef Kolek return OffBits & 0x1F; 83412c6982bSJozef Kolek } 83512c6982bSJozef Kolek 83612c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 837e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 838e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 839e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 840e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 841e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 842e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 843e10a02ecSJozef Kolek "Unexpected base register!"); 844e10a02ecSJozef Kolek 845e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 846e10a02ecSJozef Kolek Fixups, STI) >> 2; 847e10a02ecSJozef Kolek 848e10a02ecSJozef Kolek return OffBits & 0x7F; 849e10a02ecSJozef Kolek } 850e10a02ecSJozef Kolek 8519eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 8529eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 8539eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8549eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 8559eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 8569eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 8579eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8589eaa30d2SZoran Jovanovic STI) << 16; 8599eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 8609eaa30d2SZoran Jovanovic 8619eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 8629eaa30d2SZoran Jovanovic } 8639eaa30d2SZoran Jovanovic 864e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 86597700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 8663fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8673fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 868a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 869a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 870a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 871a4c4b5fcSZoran Jovanovic default: 872a4c4b5fcSZoran Jovanovic break; 873a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 874a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 875a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 876a4c4b5fcSZoran Jovanovic break; 877a4c4b5fcSZoran Jovanovic } 878a4c4b5fcSZoran Jovanovic 87997700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 88097700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 8813fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 8823fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 88397700977SJack Carter 88497700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 8853c88fbd3SHrvoje Varga } 8863c88fbd3SHrvoje Varga 8873c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 8883c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 8893c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 8903c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 8913c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 8923c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 8933c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8943c88fbd3SHrvoje Varga STI) << 16; 8953c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 8963c88fbd3SHrvoje Varga 8973c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 89897700977SJack Carter } 89997700977SJack Carter 900f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 901f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 902f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 903f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 904f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 905f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 906f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 907f9a02500SZoran Jovanovic default: 908f9a02500SZoran Jovanovic break; 909f9a02500SZoran Jovanovic case Mips::SWM16_MM: 910797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 911f9a02500SZoran Jovanovic case Mips::LWM16_MM: 912797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 913f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 914f9a02500SZoran Jovanovic break; 915f9a02500SZoran Jovanovic } 916f9a02500SZoran Jovanovic 917f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 918f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 919f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 920f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 921f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 922f9a02500SZoran Jovanovic 923f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 924f9a02500SZoran Jovanovic } 925f9a02500SZoran Jovanovic 926049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 927049e9e4dSAkira Hatanaka // 928c85e3ff3SBruno Cardoso Lopes unsigned 929c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 9303fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9313fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 932049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 933049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 9343fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 9353fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 936049e9e4dSAkira Hatanaka 93756b70de0SBruno Cardoso Lopes return Position + Size - 1; 938c85e3ff3SBruno Cardoso Lopes } 939c85e3ff3SBruno Cardoso Lopes 940ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 941779c5937SMatheus Almeida unsigned 942ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 9433fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9443fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 945779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 946ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 947ea4f653dSDaniel Sanders Value -= Offset; 948ea4f653dSDaniel Sanders return Value; 949779c5937SMatheus Almeida } 950779c5937SMatheus Almeida 951b59e1a41SDaniel Sanders unsigned 952b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 953b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 954b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 955b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 956b9c07f3bSZoran Jovanovic if (MO.isImm()) { 957b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 958b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 959b59e1a41SDaniel Sanders assert((Res & 3) == 0); 960b59e1a41SDaniel Sanders return Res >> 2; 961b59e1a41SDaniel Sanders } 962c85e3ff3SBruno Cardoso Lopes 963b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 964b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 965b9c07f3bSZoran Jovanovic 966b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9676764fa78SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 9686764fa78SZoran Jovanovic : Mips::fixup_MIPS_PC19_S2; 9696764fa78SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 970b9c07f3bSZoran Jovanovic return 0; 971b9c07f3bSZoran Jovanovic } 972b9c07f3bSZoran Jovanovic 9732855142aSZoran Jovanovic unsigned 9742855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 9752855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9762855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 977a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 978a5acdcf9SZoran Jovanovic if (MO.isImm()) { 9792855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 9802855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 9812855142aSZoran Jovanovic assert((Res & 7) == 0); 9822855142aSZoran Jovanovic return Res >> 3; 9832855142aSZoran Jovanovic } 9842855142aSZoran Jovanovic 985a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 986a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 987a5acdcf9SZoran Jovanovic 988a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9898e366822SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 9908e366822SZoran Jovanovic : Mips::fixup_MIPS_PC18_S3; 9918e366822SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 992a5acdcf9SZoran Jovanovic return 0; 993a5acdcf9SZoran Jovanovic } 994a5acdcf9SZoran Jovanovic 9954a00fdc2SZoran Jovanovic unsigned 9964a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 9974a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9984a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 9994a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10004a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10014a00fdc2SZoran Jovanovic return MO.getImm() % 8; 10024a00fdc2SZoran Jovanovic } 10034a00fdc2SZoran Jovanovic 10048853171bSZoran Jovanovic unsigned 10058853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 10068853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10078853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 10088853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10098853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10108853171bSZoran Jovanovic unsigned Value = MO.getImm(); 10118853171bSZoran Jovanovic switch (Value) { 10128853171bSZoran Jovanovic case 128: return 0x0; 10138853171bSZoran Jovanovic case 1: return 0x1; 10148853171bSZoran Jovanovic case 2: return 0x2; 10158853171bSZoran Jovanovic case 3: return 0x3; 10168853171bSZoran Jovanovic case 4: return 0x4; 10178853171bSZoran Jovanovic case 7: return 0x5; 10188853171bSZoran Jovanovic case 8: return 0x6; 10198853171bSZoran Jovanovic case 15: return 0x7; 10208853171bSZoran Jovanovic case 16: return 0x8; 10218853171bSZoran Jovanovic case 31: return 0x9; 10228853171bSZoran Jovanovic case 32: return 0xa; 10238853171bSZoran Jovanovic case 63: return 0xb; 10248853171bSZoran Jovanovic case 64: return 0xc; 10258853171bSZoran Jovanovic case 255: return 0xd; 10268853171bSZoran Jovanovic case 32768: return 0xe; 10278853171bSZoran Jovanovic case 65535: return 0xf; 10288853171bSZoran Jovanovic } 10298853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 10308853171bSZoran Jovanovic } 10318853171bSZoran Jovanovic 1032a4c4b5fcSZoran Jovanovic unsigned 1033a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1034a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1035a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 1036a4c4b5fcSZoran Jovanovic unsigned res = 0; 1037a4c4b5fcSZoran Jovanovic 1038a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 1039a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 1040a4c4b5fcSZoran Jovanovic 1041a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1042a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 1043a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1044a4c4b5fcSZoran Jovanovic if (RegNo != 31) 1045a4c4b5fcSZoran Jovanovic res++; 1046a4c4b5fcSZoran Jovanovic else 1047a4c4b5fcSZoran Jovanovic res |= 0x10; 1048a4c4b5fcSZoran Jovanovic } 1049a4c4b5fcSZoran Jovanovic return res; 1050a4c4b5fcSZoran Jovanovic } 1051a4c4b5fcSZoran Jovanovic 1052f9a02500SZoran Jovanovic unsigned 1053f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1054f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1055f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 1056f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 1057f9a02500SZoran Jovanovic } 1058f9a02500SZoran Jovanovic 10592deca348SZoran Jovanovic unsigned 10602deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 10612deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10622deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 10632deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 10642deca348SZoran Jovanovic } 10652deca348SZoran Jovanovic 10662c6d7320SJozef Kolek unsigned 106741688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 106841688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 106941688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 107041688679SZoran Jovanovic unsigned res = 0; 107141688679SZoran Jovanovic 107241688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 107341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 107441688679SZoran Jovanovic res = 0; 107541688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 107641688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 107741688679SZoran Jovanovic res = 1; 107841688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 107941688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 108041688679SZoran Jovanovic res = 2; 108141688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 108241688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 108341688679SZoran Jovanovic res = 3; 108441688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 108541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 108641688679SZoran Jovanovic res = 4; 108741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 108841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 108941688679SZoran Jovanovic res = 5; 109041688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 109141688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 109241688679SZoran Jovanovic res = 6; 109341688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 109441688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 109541688679SZoran Jovanovic res = 7; 109641688679SZoran Jovanovic 109741688679SZoran Jovanovic return res; 109841688679SZoran Jovanovic } 109941688679SZoran Jovanovic 110041688679SZoran Jovanovic unsigned 11012c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 11022c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 11032c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 11042c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 11052c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 11062c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 11072c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 11082c6d7320SJozef Kolek assert((Res & 3) == 0); 11092c6d7320SJozef Kolek return Res >> 2; 11102c6d7320SJozef Kolek } 11112c6d7320SJozef Kolek 1112b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1113