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 //===----------------------------------------------------------------------===// 139e1450bcSMatheus Almeida 14c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsFixupKinds.h" 15a5da588bSPetar Jovanovic #include "MCTargetDesc/MipsMCExpr.h" 16c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsMCTargetDesc.h" 17926883e1SEugene Zelenko #include "MipsMCCodeEmitter.h" 18c85e3ff3SBruno Cardoso Lopes #include "llvm/ADT/APFloat.h" 19926883e1SEugene Zelenko #include "llvm/ADT/APInt.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" 25926883e1SEugene Zelenko #include "llvm/MC/MCInstrDesc.h" 26750ecec7SAkira Hatanaka #include "llvm/MC/MCInstrInfo.h" 273de83e40SPete Cooper #include "llvm/MC/MCRegisterInfo.h" 28750ecec7SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h" 29926883e1SEugene Zelenko #include "llvm/Support/Casting.h" 30926883e1SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 31750ecec7SAkira Hatanaka #include "llvm/Support/raw_ostream.h" 32926883e1SEugene Zelenko #include <cassert> 33926883e1SEugene Zelenko #include <cstdint> 34926883e1SEugene Zelenko 35926883e1SEugene Zelenko using namespace llvm; 36750ecec7SAkira Hatanaka 3784e68b29SChandler Carruth #define DEBUG_TYPE "mccodeemitter" 3884e68b29SChandler Carruth 39be6a818fSAkira Hatanaka #define GET_INSTRMAP_INFO 40be6a818fSAkira Hatanaka #include "MipsGenInstrInfo.inc" 419e1450bcSMatheus Almeida #undef GET_INSTRMAP_INFO 42be6a818fSAkira Hatanaka 439e1450bcSMatheus Almeida namespace llvm { 44926883e1SEugene Zelenko 459e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 46c3b04279SJim Grosbach const MCRegisterInfo &MRI, 479e1450bcSMatheus Almeida MCContext &Ctx) { 48d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, false); 491ee768dbSAkira Hatanaka } 501ee768dbSAkira Hatanaka 519e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 52c3b04279SJim Grosbach const MCRegisterInfo &MRI, 539e1450bcSMatheus Almeida MCContext &Ctx) { 54d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, true); 55750ecec7SAkira Hatanaka } 56926883e1SEugene Zelenko 57926883e1SEugene Zelenko } // end namespace llvm 58f30f2cceSRafael Espindola 59f30f2cceSRafael Espindola // If the D<shift> instruction has a shift amount that is greater 60f30f2cceSRafael Espindola // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 61f30f2cceSRafael Espindola static void LowerLargeShift(MCInst& Inst) { 62f30f2cceSRafael Espindola assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 63f30f2cceSRafael Espindola assert(Inst.getOperand(2).isImm()); 64f30f2cceSRafael Espindola 65f30f2cceSRafael Espindola int64_t Shift = Inst.getOperand(2).getImm(); 66f30f2cceSRafael Espindola if (Shift <= 31) 67f30f2cceSRafael Espindola return; // Do nothing 68f30f2cceSRafael Espindola Shift -= 32; 69f30f2cceSRafael Espindola 70f30f2cceSRafael Espindola // saminus32 71f30f2cceSRafael Espindola Inst.getOperand(2).setImm(Shift); 72f30f2cceSRafael Espindola 73f30f2cceSRafael Espindola switch (Inst.getOpcode()) { 74f30f2cceSRafael Espindola default: 75f30f2cceSRafael Espindola // Calling function is not synchronized 76f30f2cceSRafael Espindola llvm_unreachable("Unexpected shift instruction"); 77f30f2cceSRafael Espindola case Mips::DSLL: 78f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSLL32); 79f30f2cceSRafael Espindola return; 80f30f2cceSRafael Espindola case Mips::DSRL: 81f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRL32); 82f30f2cceSRafael Espindola return; 83f30f2cceSRafael Espindola case Mips::DSRA: 84f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRA32); 85f30f2cceSRafael Espindola return; 866a3fe574SAkira Hatanaka case Mips::DROTR: 876a3fe574SAkira Hatanaka Inst.setOpcode(Mips::DROTR32); 886a3fe574SAkira Hatanaka return; 89f1e0a03dSHrvoje Varga case Mips::DSLL_MM64R6: 90f1e0a03dSHrvoje Varga Inst.setOpcode(Mips::DSLL32_MM64R6); 91f1e0a03dSHrvoje Varga return; 9224b975dcSHrvoje Varga case Mips::DSRL_MM64R6: 9324b975dcSHrvoje Varga Inst.setOpcode(Mips::DSRL32_MM64R6); 9424b975dcSHrvoje Varga return; 95f1e0a03dSHrvoje Varga case Mips::DSRA_MM64R6: 96f1e0a03dSHrvoje Varga Inst.setOpcode(Mips::DSRA32_MM64R6); 97f1e0a03dSHrvoje Varga return; 98f1e0a03dSHrvoje Varga case Mips::DROTR_MM64R6: 99f1e0a03dSHrvoje Varga Inst.setOpcode(Mips::DROTR32_MM64R6); 100f1e0a03dSHrvoje Varga return; 101f30f2cceSRafael Espindola } 102f30f2cceSRafael Espindola } 103f30f2cceSRafael Espindola 104611eb829SDaniel Sanders // Pick a DINS instruction variant based on the pos and size operands 105611eb829SDaniel Sanders static void LowerDins(MCInst& InstIn) { 106f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 5 && 107f30f2cceSRafael Espindola "Invalid no. of machine operands for DINS!"); 108f30f2cceSRafael Espindola 109f30f2cceSRafael Espindola assert(InstIn.getOperand(2).isImm()); 110f30f2cceSRafael Espindola int64_t pos = InstIn.getOperand(2).getImm(); 111f30f2cceSRafael Espindola assert(InstIn.getOperand(3).isImm()); 112f30f2cceSRafael Espindola int64_t size = InstIn.getOperand(3).getImm(); 113f30f2cceSRafael Espindola 114*f9fa62e5SStrahinja Petrovic assert((pos + size) <= 64 && 115*f9fa62e5SStrahinja Petrovic "DINS cannot have position plus size over 64"); 116*f9fa62e5SStrahinja Petrovic if (pos < 32) { 117*f9fa62e5SStrahinja Petrovic if ((pos + size) > 0 && (pos + size) <= 32) 118*f9fa62e5SStrahinja Petrovic return; // DINS, do nothing 119*f9fa62e5SStrahinja Petrovic else if ((pos + size) > 32) { 120*f9fa62e5SStrahinja Petrovic //DINSM 121*f9fa62e5SStrahinja Petrovic InstIn.getOperand(3).setImm(size - 32); 122*f9fa62e5SStrahinja Petrovic InstIn.setOpcode(Mips::DINSM); 123*f9fa62e5SStrahinja Petrovic } 124*f9fa62e5SStrahinja Petrovic } else if ((pos + size) > 32 && (pos + size) <= 64) { 125611eb829SDaniel Sanders // DINSU 126f30f2cceSRafael Espindola InstIn.getOperand(2).setImm(pos - 32); 127611eb829SDaniel Sanders InstIn.setOpcode(Mips::DINSU); 128f30f2cceSRafael Espindola } 129f30f2cceSRafael Espindola } 130f30f2cceSRafael Espindola 131669d8dd8SSimon Dardis // Fix a bad compact branch encoding for beqc/bnec. 132669d8dd8SSimon Dardis void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { 133669d8dd8SSimon Dardis // Encoding may be illegal !(rs < rt), but this situation is 134669d8dd8SSimon Dardis // easily fixed. 135669d8dd8SSimon Dardis unsigned RegOp0 = Inst.getOperand(0).getReg(); 136669d8dd8SSimon Dardis unsigned RegOp1 = Inst.getOperand(1).getReg(); 137669d8dd8SSimon Dardis 138669d8dd8SSimon Dardis unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); 139669d8dd8SSimon Dardis unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); 140669d8dd8SSimon Dardis 14168a204ddSSimon Dardis if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC || 14268a204ddSSimon Dardis Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) { 143669d8dd8SSimon Dardis assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!"); 144669d8dd8SSimon Dardis if (Reg0 < Reg1) 145669d8dd8SSimon Dardis return; 146b60833c0SSimon Dardis } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) { 147b60833c0SSimon Dardis if (Reg0 >= Reg1) 148b60833c0SSimon Dardis return; 149c962c493SHrvoje Varga } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || 150c962c493SHrvoje Varga Inst.getOpcode() == Mips::BOVC_MMR6) { 151c962c493SHrvoje Varga if (Reg1 >= Reg0) 152c962c493SHrvoje Varga return; 153b60833c0SSimon Dardis } else 154b60833c0SSimon Dardis llvm_unreachable("Cannot rewrite unknown branch!"); 155669d8dd8SSimon Dardis 156669d8dd8SSimon Dardis Inst.getOperand(0).setReg(RegOp1); 157669d8dd8SSimon Dardis Inst.getOperand(1).setReg(RegOp0); 158669d8dd8SSimon Dardis } 159669d8dd8SSimon Dardis 1609e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 161db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMicroMips]; 1629e1450bcSMatheus Almeida } 1639e1450bcSMatheus Almeida 164c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 165db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 166c22555d9SJozef Kolek } 167c22555d9SJozef Kolek 1689e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1699e1450bcSMatheus Almeida OS << (char)C; 1709e1450bcSMatheus Almeida } 1719e1450bcSMatheus Almeida 1729e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1739e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1749e1450bcSMatheus Almeida raw_ostream &OS) const { 1759e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1769e1450bcSMatheus Almeida // Little-endian byte ordering: 1779e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1789e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1799e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1809e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1819e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1829e1450bcSMatheus Almeida } else { 1839e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1849e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1859e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1869e1450bcSMatheus Almeida } 1879e1450bcSMatheus Almeida } 1889e1450bcSMatheus Almeida } 1899e1450bcSMatheus Almeida 19091df21f7SJim Grosbach /// encodeInstruction - Emit the instruction. 1914e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 192c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 19391df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS, 1949784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1959784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 196c85e3ff3SBruno Cardoso Lopes { 197aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 198aa7aeaa0SJack Carter // only based on operand values. 199aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 200aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 201aa7aeaa0SJack Carter MCInst TmpInst = MI; 202aa7aeaa0SJack Carter switch (MI.getOpcode()) { 203aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 204aa7aeaa0SJack Carter case Mips::DSLL: 205aa7aeaa0SJack Carter case Mips::DSRL: 206aa7aeaa0SJack Carter case Mips::DSRA: 2076a3fe574SAkira Hatanaka case Mips::DROTR: 208f1e0a03dSHrvoje Varga case Mips::DSLL_MM64R6: 20924b975dcSHrvoje Varga case Mips::DSRL_MM64R6: 210f1e0a03dSHrvoje Varga case Mips::DSRA_MM64R6: 211f1e0a03dSHrvoje Varga case Mips::DROTR_MM64R6: 212f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 213aa7aeaa0SJack Carter break; 214aa7aeaa0SJack Carter // Double extract instruction is chosen by pos and size operands 215aa7aeaa0SJack Carter case Mips::DINS: 216611eb829SDaniel Sanders LowerDins(TmpInst); 217669d8dd8SSimon Dardis break; 218b60833c0SSimon Dardis // Compact branches, enforce encoding restrictions. 219669d8dd8SSimon Dardis case Mips::BEQC: 220669d8dd8SSimon Dardis case Mips::BNEC: 22168a204ddSSimon Dardis case Mips::BEQC64: 22268a204ddSSimon Dardis case Mips::BNEC64: 223b60833c0SSimon Dardis case Mips::BOVC: 224c962c493SHrvoje Varga case Mips::BOVC_MMR6: 225b60833c0SSimon Dardis case Mips::BNVC: 226c962c493SHrvoje Varga case Mips::BNVC_MMR6: 227669d8dd8SSimon Dardis LowerCompactBranch(TmpInst); 228aa7aeaa0SJack Carter } 229aa7aeaa0SJack Carter 23097700977SJack Carter unsigned long N = Fixups.size(); 2313fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 232c85e3ff3SBruno Cardoso Lopes 233c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 234aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 235c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 236aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 237c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 238c7e220f6SJozef Kolek (Opcode != Mips::SLL_MM) && !Binary) 23991df21f7SJim Grosbach llvm_unreachable("unimplemented opcode in encodeInstruction()"); 240c85e3ff3SBruno Cardoso Lopes 241b59a5419SZoran Jovanovic int NewOpcode = -1; 2426ca13eafSJozef Kolek if (isMicroMips(STI)) { 243b59a5419SZoran Jovanovic if (isMips32r6(STI)) { 244b59a5419SZoran Jovanovic NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 245b59a5419SZoran Jovanovic if (NewOpcode == -1) 246b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 247b59a5419SZoran Jovanovic } 248b59a5419SZoran Jovanovic else 249b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 250b59a5419SZoran Jovanovic 2512e386d3dSZoran Jovanovic // Check whether it is Dsp instruction. 2522e386d3dSZoran Jovanovic if (NewOpcode == -1) 2532e386d3dSZoran Jovanovic NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 2542e386d3dSZoran Jovanovic 255be6a818fSAkira Hatanaka if (NewOpcode != -1) { 25697700977SJack Carter if (Fixups.size() > N) 25797700977SJack Carter Fixups.pop_back(); 258b59a5419SZoran Jovanovic 259be6a818fSAkira Hatanaka Opcode = NewOpcode; 260be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 2613fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 262be6a818fSAkira Hatanaka } 263be6a818fSAkira Hatanaka } 264be6a818fSAkira Hatanaka 265aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 266c85e3ff3SBruno Cardoso Lopes 2675b5559d3SJack Carter // Get byte count of instruction 2685b5559d3SJack Carter unsigned Size = Desc.getSize(); 2695b5559d3SJack Carter if (!Size) 2705b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 271c85e3ff3SBruno Cardoso Lopes 272d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 273c85e3ff3SBruno Cardoso Lopes } 274c85e3ff3SBruno Cardoso Lopes 275c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 276c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 277c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 278c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 279c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2803fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2813fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 282c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 28371e6a749SJack Carter 2844f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2854f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2864f69a0f2SJack Carter 28771e6a749SJack Carter assert(MO.isExpr() && 28871e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 289c85e3ff3SBruno Cardoso Lopes 290b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 291b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 292b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 293c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 294c85e3ff3SBruno Cardoso Lopes return 0; 295c85e3ff3SBruno Cardoso Lopes } 296c85e3ff3SBruno Cardoso Lopes 2976f09cdfdSHrvoje Varga /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 2986f09cdfdSHrvoje Varga /// target operand. If the machine operand requires relocation, 2996f09cdfdSHrvoje Varga /// record the relocation and return zero. 3006f09cdfdSHrvoje Varga unsigned MipsMCCodeEmitter:: 3016f09cdfdSHrvoje Varga getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 3026f09cdfdSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 3036f09cdfdSHrvoje Varga const MCSubtargetInfo &STI) const { 3046f09cdfdSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 3056f09cdfdSHrvoje Varga 3066f09cdfdSHrvoje Varga // If the destination is an immediate, divide by 2. 3076f09cdfdSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 1; 3086f09cdfdSHrvoje Varga 3096f09cdfdSHrvoje Varga assert(MO.isExpr() && 3106f09cdfdSHrvoje Varga "getBranchTargetOpValue expects only expressions or immediates"); 3116f09cdfdSHrvoje Varga 3126f09cdfdSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 3136f09cdfdSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 3146f09cdfdSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 3156f09cdfdSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 3166f09cdfdSHrvoje Varga return 0; 3176f09cdfdSHrvoje Varga } 3186f09cdfdSHrvoje Varga 319c962c493SHrvoje Varga /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch 320c962c493SHrvoje Varga /// target operand. If the machine operand requires relocation, 321c962c493SHrvoje Varga /// record the relocation and return zero. 322c962c493SHrvoje Varga unsigned MipsMCCodeEmitter:: 323c962c493SHrvoje Varga getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, 324c962c493SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 325c962c493SHrvoje Varga const MCSubtargetInfo &STI) const { 326c962c493SHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 327c962c493SHrvoje Varga 328c962c493SHrvoje Varga // If the destination is an immediate, divide by 2. 329c962c493SHrvoje Varga if (MO.isImm()) 330c962c493SHrvoje Varga return MO.getImm() >> 1; 331c962c493SHrvoje Varga 332c962c493SHrvoje Varga assert(MO.isExpr() && 333c962c493SHrvoje Varga "getBranchTargetOpValueMMR6 expects only expressions or immediates"); 334c962c493SHrvoje Varga 335c962c493SHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 336c962c493SHrvoje Varga MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); 337c962c493SHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 338c962c493SHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 339c962c493SHrvoje Varga return 0; 340c962c493SHrvoje Varga } 341c962c493SHrvoje Varga 342f0ed16eaSHrvoje Varga /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch 343f0ed16eaSHrvoje Varga /// target operand. If the machine operand requires relocation, 344f0ed16eaSHrvoje Varga /// record the relocation and return zero. 345f0ed16eaSHrvoje Varga unsigned MipsMCCodeEmitter:: 346f0ed16eaSHrvoje Varga getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, 347f0ed16eaSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 348f0ed16eaSHrvoje Varga const MCSubtargetInfo &STI) const { 349f0ed16eaSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 350f0ed16eaSHrvoje Varga 351f0ed16eaSHrvoje Varga // If the destination is an immediate, divide by 4. 352f0ed16eaSHrvoje Varga if (MO.isImm()) 353f0ed16eaSHrvoje Varga return MO.getImm() >> 2; 354f0ed16eaSHrvoje Varga 355f0ed16eaSHrvoje Varga assert(MO.isExpr() && 356f0ed16eaSHrvoje Varga "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates"); 357f0ed16eaSHrvoje Varga 358f0ed16eaSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 359f0ed16eaSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 360f0ed16eaSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 361f0ed16eaSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 362f0ed16eaSHrvoje Varga return 0; 363f0ed16eaSHrvoje Varga } 364f0ed16eaSHrvoje Varga 3659761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 3669761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 3679761e96bSJozef Kolek /// record the relocation and return zero. 3689761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 3699761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 3709761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3719761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 3729761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3739761e96bSJozef Kolek 3749761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 3759761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3769761e96bSJozef Kolek 3779761e96bSJozef Kolek assert(MO.isExpr() && 3789761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 3799761e96bSJozef Kolek 3809761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 38163661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3829761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 3839761e96bSJozef Kolek return 0; 3849761e96bSJozef Kolek } 3859761e96bSJozef Kolek 3865cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 3875cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 3885cfebddeSJozef Kolek /// record the relocation and return zero. 3895cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 3905cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 3915cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3925cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 3935cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3945cfebddeSJozef Kolek 3955cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 3965cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3975cfebddeSJozef Kolek 3985cfebddeSJozef Kolek assert(MO.isExpr() && 3995cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 4005cfebddeSJozef Kolek 4015cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 40263661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 4035cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 4045cfebddeSJozef Kolek return 0; 4055cfebddeSJozef Kolek } 4065cfebddeSJozef Kolek 4078a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 4088a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 4098a80aa76SZoran Jovanovic /// record the relocation and return zero. 4108a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 4118a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 4123fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4133fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 4148a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4158a80aa76SZoran Jovanovic 4168a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 4178a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 4188a80aa76SZoran Jovanovic 4198a80aa76SZoran Jovanovic assert(MO.isExpr() && 4208a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 4218a80aa76SZoran Jovanovic 4228a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 42363661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 4248a80aa76SZoran Jovanovic MCFixupKind(Mips:: 4258a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 4268a80aa76SZoran Jovanovic return 0; 4278a80aa76SZoran Jovanovic } 4288a80aa76SZoran Jovanovic 4293c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 4303c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4313c8869dcSZoran Jovanovic /// record the relocation and return zero. 4323c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4333c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 4343c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4353c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4363c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4373c8869dcSZoran Jovanovic 4383c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4393c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4403c8869dcSZoran Jovanovic 4413c8869dcSZoran Jovanovic assert(MO.isExpr() && 4423c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 4433c8869dcSZoran Jovanovic 444b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 445b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 446b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 44710e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 4483c8869dcSZoran Jovanovic return 0; 4493c8869dcSZoran Jovanovic } 4503c8869dcSZoran Jovanovic 45184e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch 45284e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires 45384e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero. 45484e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter:: 45584e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 45684e4d59eSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 45784e4d59eSZoran Jovanovic const MCSubtargetInfo &STI) const { 45884e4d59eSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 45984e4d59eSZoran Jovanovic 460f0ed16eaSHrvoje Varga // If the destination is an immediate, divide by 4. 461f0ed16eaSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 2; 46284e4d59eSZoran Jovanovic 46384e4d59eSZoran Jovanovic assert(MO.isExpr() && 46484e4d59eSZoran Jovanovic "getBranchTarget21OpValueMM expects only expressions or immediates"); 46584e4d59eSZoran Jovanovic 4665f94cedeSZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 4675f94cedeSZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 4685f94cedeSZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 4695f94cedeSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 47084e4d59eSZoran Jovanovic return 0; 47184e4d59eSZoran Jovanovic } 47284e4d59eSZoran Jovanovic 4733c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 4743c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4753c8869dcSZoran Jovanovic /// record the relocation and return zero. 4763c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4773c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 4783c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4793c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4803c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4813c8869dcSZoran Jovanovic 4823c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4833c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4843c8869dcSZoran Jovanovic 4853c8869dcSZoran Jovanovic assert(MO.isExpr() && 4863c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 4873c8869dcSZoran Jovanovic 488b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 489b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 490b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 49110e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 4923c8869dcSZoran Jovanovic return 0; 4933c8869dcSZoran Jovanovic } 4943c8869dcSZoran Jovanovic 495a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 496a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 497a887b361SZoran Jovanovic /// record the relocation and return zero. 498a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 499a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 500a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 501a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 502a887b361SZoran Jovanovic 503a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 504a887b361SZoran Jovanovic if (MO.isImm()) 505a887b361SZoran Jovanovic return MO.getImm() >> 1; 506a887b361SZoran Jovanovic 50702b70030SZoran Jovanovic assert(MO.isExpr() && 50802b70030SZoran Jovanovic "getBranchTarget26OpValueMM expects only expressions or immediates"); 50902b70030SZoran Jovanovic 51002b70030SZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 51102b70030SZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 51202b70030SZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 51302b70030SZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 514a887b361SZoran Jovanovic return 0; 515a887b361SZoran Jovanovic } 516a887b361SZoran Jovanovic 51752c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 51852c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 51952c56b93SZoran Jovanovic /// record the relocation and return zero. 52052c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 52152c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 52252c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 52352c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 52452c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 52552c56b93SZoran Jovanovic 52652c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 52752c56b93SZoran Jovanovic 52852c56b93SZoran Jovanovic assert(MO.isExpr() && 52952c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 53052c56b93SZoran Jovanovic 53152c56b93SZoran Jovanovic // TODO: Push fixup. 53252c56b93SZoran Jovanovic return 0; 53352c56b93SZoran Jovanovic } 53452c56b93SZoran Jovanovic 535c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 536c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 537c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 538c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 539c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 5403fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5413fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 542c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 5434f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 5444f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 5454f69a0f2SJack Carter 54671e6a749SJack Carter assert(MO.isExpr() && 54771e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 548c85e3ff3SBruno Cardoso Lopes 549c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 55063661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 551c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 552c85e3ff3SBruno Cardoso Lopes return 0; 553c85e3ff3SBruno Cardoso Lopes } 554c85e3ff3SBruno Cardoso Lopes 555c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 556507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 5573fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5583fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 559507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 560507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 561507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 562507e084aSZoran Jovanovic 563507e084aSZoran Jovanovic assert(MO.isExpr() && 564507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 565507e084aSZoran Jovanovic 566507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 56763661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 568507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 569507e084aSZoran Jovanovic return 0; 570507e084aSZoran Jovanovic } 571507e084aSZoran Jovanovic 572507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 573c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 574c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 575c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 576c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 577c74e3eb9SZoran Jovanovic if (MO.isImm()) { 578c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 579c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 580c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 581c74e3eb9SZoran Jovanovic return Res >> 2; 582c74e3eb9SZoran Jovanovic } 583c74e3eb9SZoran Jovanovic 584c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 585c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 586c74e3eb9SZoran Jovanovic 587c74e3eb9SZoran Jovanovic return 0; 588c74e3eb9SZoran Jovanovic } 589c74e3eb9SZoran Jovanovic 590c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 591bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 592bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 593bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 594bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 595bac3619bSZoran Jovanovic if (MO.isImm()) { 596bac3619bSZoran Jovanovic int Value = MO.getImm(); 597bac3619bSZoran Jovanovic return Value >> 2; 598bac3619bSZoran Jovanovic } 599bac3619bSZoran Jovanovic 600bac3619bSZoran Jovanovic return 0; 601bac3619bSZoran Jovanovic } 602bac3619bSZoran Jovanovic 603bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 60442b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 60542b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 60642b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 60742b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 60842b84443SZoran Jovanovic if (MO.isImm()) { 60942b84443SZoran Jovanovic unsigned Value = MO.getImm(); 61042b84443SZoran Jovanovic return Value >> 2; 61142b84443SZoran Jovanovic } 61242b84443SZoran Jovanovic 61342b84443SZoran Jovanovic return 0; 61442b84443SZoran Jovanovic } 61542b84443SZoran Jovanovic 61642b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 61798bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 61898bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 61998bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 62098bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 62198bd58caSZoran Jovanovic if (MO.isImm()) { 62298bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 62398bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 62498bd58caSZoran Jovanovic } 62598bd58caSZoran Jovanovic 62698bd58caSZoran Jovanovic return 0; 62798bd58caSZoran Jovanovic } 62898bd58caSZoran Jovanovic 62998bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 6303fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 6313fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 632b5cf5909SJack Carter int64_t Res; 633049e9e4dSAkira Hatanaka 63413760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 635b5cf5909SJack Carter return Res; 636fe384a2cSAkira Hatanaka 637fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 638b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 639b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 640b5cf5909SJack Carter } 641fe384a2cSAkira Hatanaka 642fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 6433fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 6443fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 645b5cf5909SJack Carter return Res; 646fe384a2cSAkira Hatanaka } 647a5da588bSPetar Jovanovic 648a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 649a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 650a5da588bSPetar Jovanovic 651a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 652a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 653fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_None: 654fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_Special: 655fe98b2f5SDaniel Sanders llvm_unreachable("Unhandled fixup kind!"); 656fe98b2f5SDaniel Sanders break; 657fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_HI16: 658fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_HI16; 659fe98b2f5SDaniel Sanders break; 660fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_LO16: 661fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_LO16; 662fe98b2f5SDaniel Sanders break; 663fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_HI: 664fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 665fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_HI; 666fe98b2f5SDaniel Sanders break; 667fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_LO: 668fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 669fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_LO; 670fe98b2f5SDaniel Sanders break; 671fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOTTPREL: 672fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOTTPREL; 673fe98b2f5SDaniel Sanders break; 674fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT: 675fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 676fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT; 677fe98b2f5SDaniel Sanders break; 678fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_CALL: 679fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 680fe98b2f5SDaniel Sanders : Mips::fixup_Mips_CALL16; 681fe98b2f5SDaniel Sanders break; 682fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_DISP: 683fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 684fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_DISP; 685fe98b2f5SDaniel Sanders break; 686fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_HI16: 687fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_HI16; 688fe98b2f5SDaniel Sanders break; 689fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_LO16: 690fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_LO16; 691fe98b2f5SDaniel Sanders break; 692fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_PAGE: 693fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 694fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_PAGE; 695fe98b2f5SDaniel Sanders break; 696fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_OFST: 697fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 698fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_OFST; 699fe98b2f5SDaniel Sanders break; 700fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GPREL: 701fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPREL16; 702fe98b2f5SDaniel Sanders break; 703926883e1SEugene Zelenko case MipsMCExpr::MEK_LO: 704fe98b2f5SDaniel Sanders // Check for %lo(%neg(%gp_rel(X))) 705fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 706fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_LO; 707fe98b2f5SDaniel Sanders break; 708fe98b2f5SDaniel Sanders } 709fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 710fe98b2f5SDaniel Sanders : Mips::fixup_Mips_LO16; 711fe98b2f5SDaniel Sanders break; 712fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHEST: 71306c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 71406c47803SSasa Stankovic break; 715fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHER: 71606c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 71706c47803SSasa Stankovic break; 718fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HI: 719fe98b2f5SDaniel Sanders // Check for %hi(%neg(%gp_rel(X))) 720fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 721fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_HI; 722fe98b2f5SDaniel Sanders break; 723fe98b2f5SDaniel Sanders } 724a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 725a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 726a5da588bSPetar Jovanovic break; 727fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_HI16: 728fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCHI16; 729fe98b2f5SDaniel Sanders break; 730fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_LO16: 731fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCLO16; 732fe98b2f5SDaniel Sanders break; 733fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSGD: 734fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 735fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSGD; 736fe98b2f5SDaniel Sanders break; 737fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSLDM: 738fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 739fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSLDM; 740fe98b2f5SDaniel Sanders break; 741fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_HI: 742fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 743fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_HI; 744fe98b2f5SDaniel Sanders break; 745fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_LO: 746fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 747fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_LO; 748a5da588bSPetar Jovanovic break; 7493feeb9c8SDaniel Sanders case MipsMCExpr::MEK_NEG: 7503feeb9c8SDaniel Sanders FixupKind = 7513feeb9c8SDaniel Sanders isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; 7523feeb9c8SDaniel Sanders break; 753a5da588bSPetar Jovanovic } 75463661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 755a5da588bSPetar Jovanovic return 0; 756a5da588bSPetar Jovanovic } 757a5da588bSPetar Jovanovic 758b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 759f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 760e2eed964SAkira Hatanaka 761049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 762b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 76360f1db05SDaniel Sanders break; 76460f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 76560f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 766b9f9de93SJack Carter break; 767c85e3ff3SBruno Cardoso Lopes } // switch 768fe384a2cSAkira Hatanaka 76963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 770fe384a2cSAkira Hatanaka return 0; 771c85e3ff3SBruno Cardoso Lopes } 772b5cf5909SJack Carter return 0; 773b5cf5909SJack Carter } 774b5cf5909SJack Carter 775b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 776b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 777b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 778b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 7793fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7803fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 781b5cf5909SJack Carter if (MO.isReg()) { 782b5cf5909SJack Carter unsigned Reg = MO.getReg(); 783bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 784b5cf5909SJack Carter return RegNo; 785b5cf5909SJack Carter } else if (MO.isImm()) { 786b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 787b5cf5909SJack Carter } else if (MO.isFPImm()) { 788b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 789b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 790b5cf5909SJack Carter } 791b5cf5909SJack Carter // MO must be an Expr. 792b5cf5909SJack Carter assert(MO.isExpr()); 7933fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 794b5cf5909SJack Carter } 795c85e3ff3SBruno Cardoso Lopes 796dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand. 797c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 798dc0602a2SDaniel Sanders template <unsigned ShiftAmount> 799dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 8003fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8013fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 802c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 803c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 8043fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 8053fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 806c85e3ff3SBruno Cardoso Lopes 807dc0602a2SDaniel Sanders // Apply the scale factor if there is one. 808dc0602a2SDaniel Sanders OffBits >>= ShiftAmount; 809dc0602a2SDaniel Sanders 810c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 811c85e3ff3SBruno Cardoso Lopes } 812c85e3ff3SBruno Cardoso Lopes 81397700977SJack Carter unsigned MipsMCCodeEmitter:: 814e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 815e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 816e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 817e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 818e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 819e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 820e8c9d1eaSJozef Kolek Fixups, STI) << 4; 821e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 822e8c9d1eaSJozef Kolek Fixups, STI); 823e8c9d1eaSJozef Kolek 824e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 825e8c9d1eaSJozef Kolek } 826e8c9d1eaSJozef Kolek 827e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 828e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 829e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 830e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 831e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 832e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 833e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 834e8c9d1eaSJozef Kolek Fixups, STI) << 4; 835e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 836e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 837e8c9d1eaSJozef Kolek 838e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 839e8c9d1eaSJozef Kolek } 840e8c9d1eaSJozef Kolek 841e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 842e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 843e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 844e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 845e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 846e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 847e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 848e8c9d1eaSJozef Kolek Fixups, STI) << 4; 849e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 850e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 851e8c9d1eaSJozef Kolek 852e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 853e8c9d1eaSJozef Kolek } 854e8c9d1eaSJozef Kolek 855e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 85612c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 85712c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 85812c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 85912c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 86012c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 86168be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 86268be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 86312c6982bSJozef Kolek "Unexpected base register!"); 86412c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 86512c6982bSJozef Kolek Fixups, STI) >> 2; 86612c6982bSJozef Kolek 86712c6982bSJozef Kolek return OffBits & 0x1F; 86812c6982bSJozef Kolek } 86912c6982bSJozef Kolek 87012c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 871e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 872e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 873e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 874e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 875e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 876e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 877e10a02ecSJozef Kolek "Unexpected base register!"); 878e10a02ecSJozef Kolek 879e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 880e10a02ecSJozef Kolek Fixups, STI) >> 2; 881e10a02ecSJozef Kolek 882e10a02ecSJozef Kolek return OffBits & 0x7F; 883e10a02ecSJozef Kolek } 884e10a02ecSJozef Kolek 8859eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 8869eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 8879eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8889eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 8899eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 8909eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 8919eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8929eaa30d2SZoran Jovanovic STI) << 16; 8939eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 8949eaa30d2SZoran Jovanovic 8959eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 8969eaa30d2SZoran Jovanovic } 8979eaa30d2SZoran Jovanovic 898e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 899cba9f80bSZlatko Buljan getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 900cba9f80bSZlatko Buljan SmallVectorImpl<MCFixup> &Fixups, 901cba9f80bSZlatko Buljan const MCSubtargetInfo &STI) const { 902cba9f80bSZlatko Buljan // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 903cba9f80bSZlatko Buljan assert(MI.getOperand(OpNo).isReg()); 904cba9f80bSZlatko Buljan unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 905cba9f80bSZlatko Buljan STI) << 16; 906cba9f80bSZlatko Buljan unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 907cba9f80bSZlatko Buljan 908cba9f80bSZlatko Buljan return (OffBits & 0x07FF) | RegBits; 909cba9f80bSZlatko Buljan } 910cba9f80bSZlatko Buljan 911cba9f80bSZlatko Buljan unsigned MipsMCCodeEmitter:: 91297700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 9133fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9143fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 915a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 916a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 917a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 918a4c4b5fcSZoran Jovanovic default: 919a4c4b5fcSZoran Jovanovic break; 920a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 921a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 922a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 923a4c4b5fcSZoran Jovanovic break; 924a4c4b5fcSZoran Jovanovic } 925a4c4b5fcSZoran Jovanovic 92697700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 92797700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 9283fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 9293fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 93097700977SJack Carter 93197700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 9323c88fbd3SHrvoje Varga } 9333c88fbd3SHrvoje Varga 9343c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 9353c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 9363c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 9373c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 9383c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 9393c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 9403c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 9413c88fbd3SHrvoje Varga STI) << 16; 9423c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 9433c88fbd3SHrvoje Varga 9443c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 94597700977SJack Carter } 94697700977SJack Carter 947f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 948f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 949f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 950f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 951f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 952f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 953f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 954f9a02500SZoran Jovanovic default: 955f9a02500SZoran Jovanovic break; 956f9a02500SZoran Jovanovic case Mips::SWM16_MM: 957797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 958f9a02500SZoran Jovanovic case Mips::LWM16_MM: 959797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 960f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 961f9a02500SZoran Jovanovic break; 962f9a02500SZoran Jovanovic } 963f9a02500SZoran Jovanovic 964f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 965f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 966f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 967f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 968f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 969f9a02500SZoran Jovanovic 970f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 971f9a02500SZoran Jovanovic } 972f9a02500SZoran Jovanovic 973049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 974049e9e4dSAkira Hatanaka // 975c85e3ff3SBruno Cardoso Lopes unsigned 976c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 9773fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9783fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 979049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 980049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 9813fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 9823fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 983049e9e4dSAkira Hatanaka 98456b70de0SBruno Cardoso Lopes return Position + Size - 1; 985c85e3ff3SBruno Cardoso Lopes } 986c85e3ff3SBruno Cardoso Lopes 987ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 988779c5937SMatheus Almeida unsigned 989ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 9903fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9913fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 992779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 993ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 994ea4f653dSDaniel Sanders Value -= Offset; 995ea4f653dSDaniel Sanders return Value; 996779c5937SMatheus Almeida } 997779c5937SMatheus Almeida 998b59e1a41SDaniel Sanders unsigned 999b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 1000b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 1001b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 1002b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 1003b9c07f3bSZoran Jovanovic if (MO.isImm()) { 1004b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 1005b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 1006b59e1a41SDaniel Sanders assert((Res & 3) == 0); 1007b59e1a41SDaniel Sanders return Res >> 2; 1008b59e1a41SDaniel Sanders } 1009c85e3ff3SBruno Cardoso Lopes 1010b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 1011b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 1012b9c07f3bSZoran Jovanovic 1013b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 10146764fa78SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 10156764fa78SZoran Jovanovic : Mips::fixup_MIPS_PC19_S2; 10166764fa78SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1017b9c07f3bSZoran Jovanovic return 0; 1018b9c07f3bSZoran Jovanovic } 1019b9c07f3bSZoran Jovanovic 10202855142aSZoran Jovanovic unsigned 10212855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 10222855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10232855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 1024a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 1025a5acdcf9SZoran Jovanovic if (MO.isImm()) { 10262855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 10272855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 10282855142aSZoran Jovanovic assert((Res & 7) == 0); 10292855142aSZoran Jovanovic return Res >> 3; 10302855142aSZoran Jovanovic } 10312855142aSZoran Jovanovic 1032a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 1033a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 1034a5acdcf9SZoran Jovanovic 1035a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 10368e366822SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 10378e366822SZoran Jovanovic : Mips::fixup_MIPS_PC18_S3; 10388e366822SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1039a5acdcf9SZoran Jovanovic return 0; 1040a5acdcf9SZoran Jovanovic } 1041a5acdcf9SZoran Jovanovic 10424a00fdc2SZoran Jovanovic unsigned 10434a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 10444a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10454a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 10464a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10474a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10484a00fdc2SZoran Jovanovic return MO.getImm() % 8; 10494a00fdc2SZoran Jovanovic } 10504a00fdc2SZoran Jovanovic 10518853171bSZoran Jovanovic unsigned 10528853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 10538853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10548853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 10558853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10568853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10578853171bSZoran Jovanovic unsigned Value = MO.getImm(); 10588853171bSZoran Jovanovic switch (Value) { 10598853171bSZoran Jovanovic case 128: return 0x0; 10608853171bSZoran Jovanovic case 1: return 0x1; 10618853171bSZoran Jovanovic case 2: return 0x2; 10628853171bSZoran Jovanovic case 3: return 0x3; 10638853171bSZoran Jovanovic case 4: return 0x4; 10648853171bSZoran Jovanovic case 7: return 0x5; 10658853171bSZoran Jovanovic case 8: return 0x6; 10668853171bSZoran Jovanovic case 15: return 0x7; 10678853171bSZoran Jovanovic case 16: return 0x8; 10688853171bSZoran Jovanovic case 31: return 0x9; 10698853171bSZoran Jovanovic case 32: return 0xa; 10708853171bSZoran Jovanovic case 63: return 0xb; 10718853171bSZoran Jovanovic case 64: return 0xc; 10728853171bSZoran Jovanovic case 255: return 0xd; 10738853171bSZoran Jovanovic case 32768: return 0xe; 10748853171bSZoran Jovanovic case 65535: return 0xf; 10758853171bSZoran Jovanovic } 10768853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 10778853171bSZoran Jovanovic } 10788853171bSZoran Jovanovic 1079a4c4b5fcSZoran Jovanovic unsigned 1080a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1081a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1082a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 1083a4c4b5fcSZoran Jovanovic unsigned res = 0; 1084a4c4b5fcSZoran Jovanovic 1085a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 1086a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 1087a4c4b5fcSZoran Jovanovic 1088a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1089a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 1090a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1091a4c4b5fcSZoran Jovanovic if (RegNo != 31) 1092a4c4b5fcSZoran Jovanovic res++; 1093a4c4b5fcSZoran Jovanovic else 1094a4c4b5fcSZoran Jovanovic res |= 0x10; 1095a4c4b5fcSZoran Jovanovic } 1096a4c4b5fcSZoran Jovanovic return res; 1097a4c4b5fcSZoran Jovanovic } 1098a4c4b5fcSZoran Jovanovic 1099f9a02500SZoran Jovanovic unsigned 1100f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1101f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1102f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 1103f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 1104f9a02500SZoran Jovanovic } 1105f9a02500SZoran Jovanovic 11062deca348SZoran Jovanovic unsigned 11072deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 11082deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 11092deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 11102deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 11112deca348SZoran Jovanovic } 11122deca348SZoran Jovanovic 11132c6d7320SJozef Kolek unsigned 111441688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 111541688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 111641688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 111741688679SZoran Jovanovic unsigned res = 0; 111841688679SZoran Jovanovic 111941688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 112041688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 112141688679SZoran Jovanovic res = 0; 112241688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 112341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 112441688679SZoran Jovanovic res = 1; 112541688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 112641688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 112741688679SZoran Jovanovic res = 2; 112841688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 112941688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 113041688679SZoran Jovanovic res = 3; 113141688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 113241688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 113341688679SZoran Jovanovic res = 4; 113441688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 113541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 113641688679SZoran Jovanovic res = 5; 113741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 113841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 113941688679SZoran Jovanovic res = 6; 114041688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 114141688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 114241688679SZoran Jovanovic res = 7; 114341688679SZoran Jovanovic 114441688679SZoran Jovanovic return res; 114541688679SZoran Jovanovic } 114641688679SZoran Jovanovic 114741688679SZoran Jovanovic unsigned 11482c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 11492c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 11502c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 11512c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 11522c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 11532c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 11542c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 11552c6d7320SJozef Kolek assert((Res & 3) == 0); 11562c6d7320SJozef Kolek return Res >> 2; 11572c6d7320SJozef Kolek } 11582c6d7320SJozef Kolek 1159b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1160