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 1099e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 110db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMicroMips]; 1119e1450bcSMatheus Almeida } 1129e1450bcSMatheus Almeida 113c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 114db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 115c22555d9SJozef Kolek } 116c22555d9SJozef Kolek 1179e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1189e1450bcSMatheus Almeida OS << (char)C; 1199e1450bcSMatheus Almeida } 1209e1450bcSMatheus Almeida 1219e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1229e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1239e1450bcSMatheus Almeida raw_ostream &OS) const { 1249e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1259e1450bcSMatheus Almeida // Little-endian byte ordering: 1269e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1279e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1289e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1299e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1309e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1319e1450bcSMatheus Almeida } else { 1329e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1339e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1349e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1359e1450bcSMatheus Almeida } 1369e1450bcSMatheus Almeida } 1379e1450bcSMatheus Almeida } 1389e1450bcSMatheus Almeida 13991df21f7SJim Grosbach /// encodeInstruction - Emit the instruction. 1404e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 141c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 14291df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS, 1439784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1449784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 145c85e3ff3SBruno Cardoso Lopes { 146aa7aeaa0SJack Carter 147aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 148aa7aeaa0SJack Carter // only based on operand values. 149aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 150aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 151aa7aeaa0SJack Carter MCInst TmpInst = MI; 152aa7aeaa0SJack Carter switch (MI.getOpcode()) { 153aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 154aa7aeaa0SJack Carter case Mips::DSLL: 155aa7aeaa0SJack Carter case Mips::DSRL: 156aa7aeaa0SJack Carter case Mips::DSRA: 1576a3fe574SAkira Hatanaka case Mips::DROTR: 158f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 159aa7aeaa0SJack Carter break; 160aa7aeaa0SJack Carter // Double extract instruction is chosen by pos and size operands 161aa7aeaa0SJack Carter case Mips::DINS: 162611eb829SDaniel Sanders LowerDins(TmpInst); 163aa7aeaa0SJack Carter } 164aa7aeaa0SJack Carter 16597700977SJack Carter unsigned long N = Fixups.size(); 1663fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 167c85e3ff3SBruno Cardoso Lopes 168c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 169aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 170c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 171aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 172c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 173c7e220f6SJozef Kolek (Opcode != Mips::SLL_MM) && !Binary) 17491df21f7SJim Grosbach llvm_unreachable("unimplemented opcode in encodeInstruction()"); 175c85e3ff3SBruno Cardoso Lopes 176b59a5419SZoran Jovanovic int NewOpcode = -1; 1776ca13eafSJozef Kolek if (isMicroMips(STI)) { 178b59a5419SZoran Jovanovic if (isMips32r6(STI)) { 179b59a5419SZoran Jovanovic NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 180b59a5419SZoran Jovanovic if (NewOpcode == -1) 181b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 182b59a5419SZoran Jovanovic } 183b59a5419SZoran Jovanovic else 184b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 185b59a5419SZoran Jovanovic 1862e386d3dSZoran Jovanovic // Check whether it is Dsp instruction. 1872e386d3dSZoran Jovanovic if (NewOpcode == -1) 1882e386d3dSZoran Jovanovic NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 1892e386d3dSZoran Jovanovic 190be6a818fSAkira Hatanaka if (NewOpcode != -1) { 19197700977SJack Carter if (Fixups.size() > N) 19297700977SJack Carter Fixups.pop_back(); 193b59a5419SZoran Jovanovic 194be6a818fSAkira Hatanaka Opcode = NewOpcode; 195be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 1963fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 197be6a818fSAkira Hatanaka } 198be6a818fSAkira Hatanaka } 199be6a818fSAkira Hatanaka 200aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 201c85e3ff3SBruno Cardoso Lopes 2025b5559d3SJack Carter // Get byte count of instruction 2035b5559d3SJack Carter unsigned Size = Desc.getSize(); 2045b5559d3SJack Carter if (!Size) 2055b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 206c85e3ff3SBruno Cardoso Lopes 207d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 208c85e3ff3SBruno Cardoso Lopes } 209c85e3ff3SBruno Cardoso Lopes 210c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 211c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 212c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 213c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 214c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2153fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2163fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 217c85e3ff3SBruno Cardoso Lopes 218c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 21971e6a749SJack Carter 2204f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2214f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2224f69a0f2SJack Carter 22371e6a749SJack Carter assert(MO.isExpr() && 22471e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 225c85e3ff3SBruno Cardoso Lopes 226b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 227b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 228b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 229c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 230c85e3ff3SBruno Cardoso Lopes return 0; 231c85e3ff3SBruno Cardoso Lopes } 232c85e3ff3SBruno Cardoso Lopes 2336f09cdfdSHrvoje Varga /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 2346f09cdfdSHrvoje Varga /// target operand. If the machine operand requires relocation, 2356f09cdfdSHrvoje Varga /// record the relocation and return zero. 2366f09cdfdSHrvoje Varga unsigned MipsMCCodeEmitter:: 2376f09cdfdSHrvoje Varga getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 2386f09cdfdSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 2396f09cdfdSHrvoje Varga const MCSubtargetInfo &STI) const { 2406f09cdfdSHrvoje Varga 2416f09cdfdSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 2426f09cdfdSHrvoje Varga 2436f09cdfdSHrvoje Varga // If the destination is an immediate, divide by 2. 2446f09cdfdSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 1; 2456f09cdfdSHrvoje Varga 2466f09cdfdSHrvoje Varga assert(MO.isExpr() && 2476f09cdfdSHrvoje Varga "getBranchTargetOpValue expects only expressions or immediates"); 2486f09cdfdSHrvoje Varga 2496f09cdfdSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 2506f09cdfdSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 2516f09cdfdSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 2526f09cdfdSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 2536f09cdfdSHrvoje Varga return 0; 2546f09cdfdSHrvoje Varga } 2556f09cdfdSHrvoje Varga 2569761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 2579761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 2589761e96bSJozef Kolek /// record the relocation and return zero. 2599761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 2609761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 2619761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 2629761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 2639761e96bSJozef Kolek 2649761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 2659761e96bSJozef Kolek 2669761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 2679761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 2689761e96bSJozef Kolek 2699761e96bSJozef Kolek assert(MO.isExpr() && 2709761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 2719761e96bSJozef Kolek 2729761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 27363661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 2749761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 2759761e96bSJozef Kolek return 0; 2769761e96bSJozef Kolek } 2779761e96bSJozef Kolek 2785cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 2795cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 2805cfebddeSJozef Kolek /// record the relocation and return zero. 2815cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 2825cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 2835cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 2845cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 2855cfebddeSJozef Kolek 2865cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 2875cfebddeSJozef Kolek 2885cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 2895cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 2905cfebddeSJozef Kolek 2915cfebddeSJozef Kolek assert(MO.isExpr() && 2925cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 2935cfebddeSJozef Kolek 2945cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 29563661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 2965cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 2975cfebddeSJozef Kolek return 0; 2985cfebddeSJozef Kolek } 2995cfebddeSJozef Kolek 3008a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 3018a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 3028a80aa76SZoran Jovanovic /// record the relocation and return zero. 3038a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 3048a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 3053fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3063fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 3078a80aa76SZoran Jovanovic 3088a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3098a80aa76SZoran Jovanovic 3108a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 3118a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 3128a80aa76SZoran Jovanovic 3138a80aa76SZoran Jovanovic assert(MO.isExpr() && 3148a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 3158a80aa76SZoran Jovanovic 3168a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 31763661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3188a80aa76SZoran Jovanovic MCFixupKind(Mips:: 3198a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 3208a80aa76SZoran Jovanovic return 0; 3218a80aa76SZoran Jovanovic } 3228a80aa76SZoran Jovanovic 3233c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 3243c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3253c8869dcSZoran Jovanovic /// record the relocation and return zero. 3263c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3273c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 3283c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 3293c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 3303c8869dcSZoran Jovanovic 3313c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3323c8869dcSZoran Jovanovic 3333c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3343c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3353c8869dcSZoran Jovanovic 3363c8869dcSZoran Jovanovic assert(MO.isExpr() && 3373c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 3383c8869dcSZoran Jovanovic 339b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 340b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 341b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 34210e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 3433c8869dcSZoran Jovanovic return 0; 3443c8869dcSZoran Jovanovic } 3453c8869dcSZoran Jovanovic 346*84e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch 347*84e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires 348*84e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero. 349*84e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter:: 350*84e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 351*84e4d59eSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 352*84e4d59eSZoran Jovanovic const MCSubtargetInfo &STI) const { 353*84e4d59eSZoran Jovanovic 354*84e4d59eSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 355*84e4d59eSZoran Jovanovic 356*84e4d59eSZoran Jovanovic // If the destination is an immediate, divide by 2. 357*84e4d59eSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 358*84e4d59eSZoran Jovanovic 359*84e4d59eSZoran Jovanovic assert(MO.isExpr() && 360*84e4d59eSZoran Jovanovic "getBranchTarget21OpValueMM expects only expressions or immediates"); 361*84e4d59eSZoran Jovanovic 362*84e4d59eSZoran Jovanovic // TODO: Push fixup. 363*84e4d59eSZoran Jovanovic return 0; 364*84e4d59eSZoran Jovanovic } 365*84e4d59eSZoran Jovanovic 3663c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 3673c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3683c8869dcSZoran Jovanovic /// record the relocation and return zero. 3693c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3703c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 3713c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 3723c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 3733c8869dcSZoran Jovanovic 3743c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3753c8869dcSZoran Jovanovic 3763c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3773c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3783c8869dcSZoran Jovanovic 3793c8869dcSZoran Jovanovic assert(MO.isExpr() && 3803c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 3813c8869dcSZoran Jovanovic 382b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 383b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 384b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 38510e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 3863c8869dcSZoran Jovanovic return 0; 3873c8869dcSZoran Jovanovic } 3883c8869dcSZoran Jovanovic 389a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 390a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 391a887b361SZoran Jovanovic /// record the relocation and return zero. 392a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 393a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 394a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 395a887b361SZoran Jovanovic 396a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 397a887b361SZoran Jovanovic 398a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 399a887b361SZoran Jovanovic if (MO.isImm()) 400a887b361SZoran Jovanovic return MO.getImm() >> 1; 401a887b361SZoran Jovanovic 40202b70030SZoran Jovanovic assert(MO.isExpr() && 40302b70030SZoran Jovanovic "getBranchTarget26OpValueMM expects only expressions or immediates"); 40402b70030SZoran Jovanovic 40502b70030SZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 40602b70030SZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 40702b70030SZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 40802b70030SZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 409a887b361SZoran Jovanovic return 0; 410a887b361SZoran Jovanovic } 411a887b361SZoran Jovanovic 41252c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 41352c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 41452c56b93SZoran Jovanovic /// record the relocation and return zero. 41552c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 41652c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 41752c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 41852c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 41952c56b93SZoran Jovanovic 42052c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 42152c56b93SZoran Jovanovic 42252c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 42352c56b93SZoran Jovanovic 42452c56b93SZoran Jovanovic assert(MO.isExpr() && 42552c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 42652c56b93SZoran Jovanovic 42752c56b93SZoran Jovanovic // TODO: Push fixup. 42852c56b93SZoran Jovanovic return 0; 42952c56b93SZoran Jovanovic } 43052c56b93SZoran Jovanovic 431c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 432c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 433c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 434c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 435c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 4363fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4373fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 438c85e3ff3SBruno Cardoso Lopes 439c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 4404f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 4414f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 4424f69a0f2SJack Carter 44371e6a749SJack Carter assert(MO.isExpr() && 44471e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 445c85e3ff3SBruno Cardoso Lopes 446c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 44763661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 448c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 449c85e3ff3SBruno Cardoso Lopes return 0; 450c85e3ff3SBruno Cardoso Lopes } 451c85e3ff3SBruno Cardoso Lopes 452c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 453507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 4543fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4553fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 456507e084aSZoran Jovanovic 457507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 458507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 459507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 460507e084aSZoran Jovanovic 461507e084aSZoran Jovanovic assert(MO.isExpr() && 462507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 463507e084aSZoran Jovanovic 464507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 46563661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 466507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 467507e084aSZoran Jovanovic return 0; 468507e084aSZoran Jovanovic } 469507e084aSZoran Jovanovic 470507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 471c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 472c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 473c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 474c74e3eb9SZoran Jovanovic 475c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 476c74e3eb9SZoran Jovanovic if (MO.isImm()) { 477c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 478c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 479c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 480c74e3eb9SZoran Jovanovic return Res >> 2; 481c74e3eb9SZoran Jovanovic } 482c74e3eb9SZoran Jovanovic 483c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 484c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 485c74e3eb9SZoran Jovanovic 486c74e3eb9SZoran Jovanovic return 0; 487c74e3eb9SZoran Jovanovic } 488c74e3eb9SZoran Jovanovic 489c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 490bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 491bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 492bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 493bac3619bSZoran Jovanovic 494bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 495bac3619bSZoran Jovanovic if (MO.isImm()) { 496bac3619bSZoran Jovanovic int Value = MO.getImm(); 497bac3619bSZoran Jovanovic return Value >> 2; 498bac3619bSZoran Jovanovic } 499bac3619bSZoran Jovanovic 500bac3619bSZoran Jovanovic return 0; 501bac3619bSZoran Jovanovic } 502bac3619bSZoran Jovanovic 503bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 50442b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 50542b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 50642b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 50742b84443SZoran Jovanovic 50842b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 50942b84443SZoran Jovanovic if (MO.isImm()) { 51042b84443SZoran Jovanovic unsigned Value = MO.getImm(); 51142b84443SZoran Jovanovic return Value >> 2; 51242b84443SZoran Jovanovic } 51342b84443SZoran Jovanovic 51442b84443SZoran Jovanovic return 0; 51542b84443SZoran Jovanovic } 51642b84443SZoran Jovanovic 51742b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 51898bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 51998bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 52098bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 52198bd58caSZoran Jovanovic 52298bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 52398bd58caSZoran Jovanovic if (MO.isImm()) { 52498bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 52598bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 52698bd58caSZoran Jovanovic } 52798bd58caSZoran Jovanovic 52898bd58caSZoran Jovanovic return 0; 52998bd58caSZoran Jovanovic } 53098bd58caSZoran Jovanovic 53198bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 5323fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 5333fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 534b5cf5909SJack Carter int64_t Res; 535049e9e4dSAkira Hatanaka 53613760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 537b5cf5909SJack Carter return Res; 538fe384a2cSAkira Hatanaka 539fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 540b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 541b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 542b5cf5909SJack Carter } 543fe384a2cSAkira Hatanaka 544fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 5453fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 5463fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 547b5cf5909SJack Carter return Res; 548fe384a2cSAkira Hatanaka } 549a5da588bSPetar Jovanovic 550a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 551a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 552a5da588bSPetar Jovanovic 553a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 554a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 555fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_NEG: 556fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_None: 557fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_Special: 558fe98b2f5SDaniel Sanders llvm_unreachable("Unhandled fixup kind!"); 559fe98b2f5SDaniel Sanders break; 560fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_HI16: 561fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_HI16; 562fe98b2f5SDaniel Sanders break; 563fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_LO16: 564fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_LO16; 565fe98b2f5SDaniel Sanders break; 566fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_HI: 567fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 568fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_HI; 569fe98b2f5SDaniel Sanders break; 570fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_LO: 571fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 572fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_LO; 573fe98b2f5SDaniel Sanders break; 574fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOTTPREL: 575fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOTTPREL; 576fe98b2f5SDaniel Sanders break; 577fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT: 578fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 579fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT; 580fe98b2f5SDaniel Sanders break; 581fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_CALL: 582fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 583fe98b2f5SDaniel Sanders : Mips::fixup_Mips_CALL16; 584fe98b2f5SDaniel Sanders break; 585fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_DISP: 586fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 587fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_DISP; 588fe98b2f5SDaniel Sanders break; 589fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_HI16: 590fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_HI16; 591fe98b2f5SDaniel Sanders break; 592fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_LO16: 593fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_LO16; 594fe98b2f5SDaniel Sanders break; 595fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_PAGE: 596fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 597fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_PAGE; 598fe98b2f5SDaniel Sanders break; 599fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_OFST: 600fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 601fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_OFST; 602fe98b2f5SDaniel Sanders break; 603fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GPREL: 604fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPREL16; 605fe98b2f5SDaniel Sanders break; 606fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_LO: { 607fe98b2f5SDaniel Sanders // Check for %lo(%neg(%gp_rel(X))) 608fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 609fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_LO; 610fe98b2f5SDaniel Sanders break; 611fe98b2f5SDaniel Sanders } 612fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 613fe98b2f5SDaniel Sanders : Mips::fixup_Mips_LO16; 614fe98b2f5SDaniel Sanders break; 615fe98b2f5SDaniel Sanders } 616fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHEST: 61706c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 61806c47803SSasa Stankovic break; 619fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHER: 62006c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 62106c47803SSasa Stankovic break; 622fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HI: 623fe98b2f5SDaniel Sanders // Check for %hi(%neg(%gp_rel(X))) 624fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 625fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_HI; 626fe98b2f5SDaniel Sanders break; 627fe98b2f5SDaniel Sanders } 628a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 629a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 630a5da588bSPetar Jovanovic break; 631fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_HI16: 632fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCHI16; 633fe98b2f5SDaniel Sanders break; 634fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_LO16: 635fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCLO16; 636fe98b2f5SDaniel Sanders break; 637fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSGD: 638fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 639fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSGD; 640fe98b2f5SDaniel Sanders break; 641fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSLDM: 642fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 643fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSLDM; 644fe98b2f5SDaniel Sanders break; 645fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_HI: 646fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 647fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_HI; 648fe98b2f5SDaniel Sanders break; 649fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_LO: 650fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 651fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_LO; 652a5da588bSPetar Jovanovic break; 653a5da588bSPetar Jovanovic } 65463661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 655a5da588bSPetar Jovanovic return 0; 656a5da588bSPetar Jovanovic } 657a5da588bSPetar Jovanovic 658b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 659f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 660e2eed964SAkira Hatanaka 661049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 662b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 66360f1db05SDaniel Sanders break; 66460f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 66560f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 666b9f9de93SJack Carter break; 667c85e3ff3SBruno Cardoso Lopes } // switch 668fe384a2cSAkira Hatanaka 66963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 670fe384a2cSAkira Hatanaka return 0; 671c85e3ff3SBruno Cardoso Lopes } 672b5cf5909SJack Carter return 0; 673b5cf5909SJack Carter } 674b5cf5909SJack Carter 675b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 676b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 677b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 678b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 6793fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 6803fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 681b5cf5909SJack Carter if (MO.isReg()) { 682b5cf5909SJack Carter unsigned Reg = MO.getReg(); 683bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 684b5cf5909SJack Carter return RegNo; 685b5cf5909SJack Carter } else if (MO.isImm()) { 686b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 687b5cf5909SJack Carter } else if (MO.isFPImm()) { 688b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 689b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 690b5cf5909SJack Carter } 691b5cf5909SJack Carter // MO must be an Expr. 692b5cf5909SJack Carter assert(MO.isExpr()); 6933fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 694b5cf5909SJack Carter } 695c85e3ff3SBruno Cardoso Lopes 696dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand. 697c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 698dc0602a2SDaniel Sanders template <unsigned ShiftAmount> 699dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 7003fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7013fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 702c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 703c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 7043fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 7053fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 706c85e3ff3SBruno Cardoso Lopes 707dc0602a2SDaniel Sanders // Apply the scale factor if there is one. 708dc0602a2SDaniel Sanders OffBits >>= ShiftAmount; 709dc0602a2SDaniel Sanders 710c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 711c85e3ff3SBruno Cardoso Lopes } 712c85e3ff3SBruno Cardoso Lopes 71397700977SJack Carter unsigned MipsMCCodeEmitter:: 714e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 715e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 716e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 717e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 718e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 719e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 720e8c9d1eaSJozef Kolek Fixups, STI) << 4; 721e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 722e8c9d1eaSJozef Kolek Fixups, STI); 723e8c9d1eaSJozef Kolek 724e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 725e8c9d1eaSJozef Kolek } 726e8c9d1eaSJozef Kolek 727e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 728e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 729e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 730e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 731e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 732e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 733e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 734e8c9d1eaSJozef Kolek Fixups, STI) << 4; 735e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 736e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 737e8c9d1eaSJozef Kolek 738e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 739e8c9d1eaSJozef Kolek } 740e8c9d1eaSJozef Kolek 741e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 742e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 743e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 744e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 745e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 746e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 747e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 748e8c9d1eaSJozef Kolek Fixups, STI) << 4; 749e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 750e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 751e8c9d1eaSJozef Kolek 752e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 753e8c9d1eaSJozef Kolek } 754e8c9d1eaSJozef Kolek 755e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 75612c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 75712c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 75812c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 75912c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 76012c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 76168be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 76268be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 76312c6982bSJozef Kolek "Unexpected base register!"); 76412c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 76512c6982bSJozef Kolek Fixups, STI) >> 2; 76612c6982bSJozef Kolek 76712c6982bSJozef Kolek return OffBits & 0x1F; 76812c6982bSJozef Kolek } 76912c6982bSJozef Kolek 77012c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 771e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 772e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 773e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 774e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 775e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 776e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 777e10a02ecSJozef Kolek "Unexpected base register!"); 778e10a02ecSJozef Kolek 779e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 780e10a02ecSJozef Kolek Fixups, STI) >> 2; 781e10a02ecSJozef Kolek 782e10a02ecSJozef Kolek return OffBits & 0x7F; 783e10a02ecSJozef Kolek } 784e10a02ecSJozef Kolek 7859eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 7869eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 7879eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 7889eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 7899eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 7909eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 7919eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 7929eaa30d2SZoran Jovanovic STI) << 16; 7939eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 7949eaa30d2SZoran Jovanovic 7959eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 7969eaa30d2SZoran Jovanovic } 7979eaa30d2SZoran Jovanovic 798e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 79997700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 8003fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8013fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 802a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 803a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 804a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 805a4c4b5fcSZoran Jovanovic default: 806a4c4b5fcSZoran Jovanovic break; 807a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 808a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 809a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 810a4c4b5fcSZoran Jovanovic break; 811a4c4b5fcSZoran Jovanovic } 812a4c4b5fcSZoran Jovanovic 81397700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 81497700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 8153fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 8163fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 81797700977SJack Carter 81897700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 8193c88fbd3SHrvoje Varga } 8203c88fbd3SHrvoje Varga 8213c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 8223c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 8233c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 8243c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 8253c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 8263c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 8273c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8283c88fbd3SHrvoje Varga STI) << 16; 8293c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 8303c88fbd3SHrvoje Varga 8313c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 83297700977SJack Carter } 83397700977SJack Carter 834f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 835f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 836f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 837f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 838f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 839f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 840f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 841f9a02500SZoran Jovanovic default: 842f9a02500SZoran Jovanovic break; 843f9a02500SZoran Jovanovic case Mips::SWM16_MM: 844797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 845f9a02500SZoran Jovanovic case Mips::LWM16_MM: 846797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 847f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 848f9a02500SZoran Jovanovic break; 849f9a02500SZoran Jovanovic } 850f9a02500SZoran Jovanovic 851f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 852f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 853f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 854f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 855f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 856f9a02500SZoran Jovanovic 857f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 858f9a02500SZoran Jovanovic } 859f9a02500SZoran Jovanovic 860049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 861049e9e4dSAkira Hatanaka // 862c85e3ff3SBruno Cardoso Lopes unsigned 863c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 8643fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8653fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 866049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 867049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 8683fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 8693fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 870049e9e4dSAkira Hatanaka 87156b70de0SBruno Cardoso Lopes return Position + Size - 1; 872c85e3ff3SBruno Cardoso Lopes } 873c85e3ff3SBruno Cardoso Lopes 874ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 875779c5937SMatheus Almeida unsigned 876ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 8773fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8783fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 879779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 880ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 881ea4f653dSDaniel Sanders Value -= Offset; 882ea4f653dSDaniel Sanders return Value; 883779c5937SMatheus Almeida } 884779c5937SMatheus Almeida 885b59e1a41SDaniel Sanders unsigned 886b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 887b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 888b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 889b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 890b9c07f3bSZoran Jovanovic if (MO.isImm()) { 891b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 892b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 893b59e1a41SDaniel Sanders assert((Res & 3) == 0); 894b59e1a41SDaniel Sanders return Res >> 2; 895b59e1a41SDaniel Sanders } 896c85e3ff3SBruno Cardoso Lopes 897b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 898b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 899b9c07f3bSZoran Jovanovic 900b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9016764fa78SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 9026764fa78SZoran Jovanovic : Mips::fixup_MIPS_PC19_S2; 9036764fa78SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 904b9c07f3bSZoran Jovanovic return 0; 905b9c07f3bSZoran Jovanovic } 906b9c07f3bSZoran Jovanovic 9072855142aSZoran Jovanovic unsigned 9082855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 9092855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9102855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 911a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 912a5acdcf9SZoran Jovanovic if (MO.isImm()) { 9132855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 9142855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 9152855142aSZoran Jovanovic assert((Res & 7) == 0); 9162855142aSZoran Jovanovic return Res >> 3; 9172855142aSZoran Jovanovic } 9182855142aSZoran Jovanovic 919a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 920a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 921a5acdcf9SZoran Jovanovic 922a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9238e366822SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 9248e366822SZoran Jovanovic : Mips::fixup_MIPS_PC18_S3; 9258e366822SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 926a5acdcf9SZoran Jovanovic return 0; 927a5acdcf9SZoran Jovanovic } 928a5acdcf9SZoran Jovanovic 9294a00fdc2SZoran Jovanovic unsigned 9304a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 9314a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9324a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 9334a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 9344a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 9354a00fdc2SZoran Jovanovic return MO.getImm() % 8; 9364a00fdc2SZoran Jovanovic } 9374a00fdc2SZoran Jovanovic 9388853171bSZoran Jovanovic unsigned 9398853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 9408853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9418853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 9428853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 9438853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 9448853171bSZoran Jovanovic unsigned Value = MO.getImm(); 9458853171bSZoran Jovanovic switch (Value) { 9468853171bSZoran Jovanovic case 128: return 0x0; 9478853171bSZoran Jovanovic case 1: return 0x1; 9488853171bSZoran Jovanovic case 2: return 0x2; 9498853171bSZoran Jovanovic case 3: return 0x3; 9508853171bSZoran Jovanovic case 4: return 0x4; 9518853171bSZoran Jovanovic case 7: return 0x5; 9528853171bSZoran Jovanovic case 8: return 0x6; 9538853171bSZoran Jovanovic case 15: return 0x7; 9548853171bSZoran Jovanovic case 16: return 0x8; 9558853171bSZoran Jovanovic case 31: return 0x9; 9568853171bSZoran Jovanovic case 32: return 0xa; 9578853171bSZoran Jovanovic case 63: return 0xb; 9588853171bSZoran Jovanovic case 64: return 0xc; 9598853171bSZoran Jovanovic case 255: return 0xd; 9608853171bSZoran Jovanovic case 32768: return 0xe; 9618853171bSZoran Jovanovic case 65535: return 0xf; 9628853171bSZoran Jovanovic } 9638853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 9648853171bSZoran Jovanovic } 9658853171bSZoran Jovanovic 966a4c4b5fcSZoran Jovanovic unsigned 967a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 968a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 969a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 970a4c4b5fcSZoran Jovanovic unsigned res = 0; 971a4c4b5fcSZoran Jovanovic 972a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 973a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 974a4c4b5fcSZoran Jovanovic 975a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 976a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 977a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 978a4c4b5fcSZoran Jovanovic if (RegNo != 31) 979a4c4b5fcSZoran Jovanovic res++; 980a4c4b5fcSZoran Jovanovic else 981a4c4b5fcSZoran Jovanovic res |= 0x10; 982a4c4b5fcSZoran Jovanovic } 983a4c4b5fcSZoran Jovanovic return res; 984a4c4b5fcSZoran Jovanovic } 985a4c4b5fcSZoran Jovanovic 986f9a02500SZoran Jovanovic unsigned 987f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 988f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 989f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 990f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 991f9a02500SZoran Jovanovic } 992f9a02500SZoran Jovanovic 9932deca348SZoran Jovanovic unsigned 9942deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 9952deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9962deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 9972deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 9982deca348SZoran Jovanovic } 9992deca348SZoran Jovanovic 10002c6d7320SJozef Kolek unsigned 100141688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 100241688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 100341688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 100441688679SZoran Jovanovic unsigned res = 0; 100541688679SZoran Jovanovic 100641688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 100741688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 100841688679SZoran Jovanovic res = 0; 100941688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 101041688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 101141688679SZoran Jovanovic res = 1; 101241688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 101341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 101441688679SZoran Jovanovic res = 2; 101541688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 101641688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 101741688679SZoran Jovanovic res = 3; 101841688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 101941688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 102041688679SZoran Jovanovic res = 4; 102141688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 102241688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 102341688679SZoran Jovanovic res = 5; 102441688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 102541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 102641688679SZoran Jovanovic res = 6; 102741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 102841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 102941688679SZoran Jovanovic res = 7; 103041688679SZoran Jovanovic 103141688679SZoran Jovanovic return res; 103241688679SZoran Jovanovic } 103341688679SZoran Jovanovic 103441688679SZoran Jovanovic unsigned 10352c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 10362c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 10372c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 10382c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 10392c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 10402c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 10412c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 10422c6d7320SJozef Kolek assert((Res & 3) == 0); 10432c6d7320SJozef Kolek return Res >> 2; 10442c6d7320SJozef Kolek } 10452c6d7320SJozef Kolek 1046b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1047