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 84f30f2cceSRafael Espindola // Pick a DEXT or DINS instruction variant based on the pos and size operands 85f30f2cceSRafael Espindola static void LowerDextDins(MCInst& InstIn) { 86f30f2cceSRafael Espindola int Opcode = InstIn.getOpcode(); 87f30f2cceSRafael Espindola 88f30f2cceSRafael Espindola if (Opcode == Mips::DEXT) 89f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 4 && 90f30f2cceSRafael Espindola "Invalid no. of machine operands for DEXT!"); 91f30f2cceSRafael Espindola else // Only DEXT and DINS are possible 92f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 5 && 93f30f2cceSRafael Espindola "Invalid no. of machine operands for DINS!"); 94f30f2cceSRafael Espindola 95f30f2cceSRafael Espindola assert(InstIn.getOperand(2).isImm()); 96f30f2cceSRafael Espindola int64_t pos = InstIn.getOperand(2).getImm(); 97f30f2cceSRafael Espindola assert(InstIn.getOperand(3).isImm()); 98f30f2cceSRafael Espindola int64_t size = InstIn.getOperand(3).getImm(); 99f30f2cceSRafael Espindola 100f30f2cceSRafael Espindola if (size <= 32) { 101f30f2cceSRafael Espindola if (pos < 32) // DEXT/DINS, do nothing 102f30f2cceSRafael Espindola return; 103f30f2cceSRafael Espindola // DEXTU/DINSU 104f30f2cceSRafael Espindola InstIn.getOperand(2).setImm(pos - 32); 105f30f2cceSRafael Espindola InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); 106f30f2cceSRafael Espindola return; 107f30f2cceSRafael Espindola } 108f30f2cceSRafael Espindola // DEXTM/DINSM 109f30f2cceSRafael Espindola assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); 110f30f2cceSRafael Espindola InstIn.getOperand(3).setImm(size - 32); 111f30f2cceSRafael Espindola InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); 112f30f2cceSRafael Espindola return; 113f30f2cceSRafael Espindola } 114f30f2cceSRafael Espindola 1159e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 116db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMicroMips]; 1179e1450bcSMatheus Almeida } 1189e1450bcSMatheus Almeida 119c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 120db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 121c22555d9SJozef Kolek } 122c22555d9SJozef Kolek 1239e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1249e1450bcSMatheus Almeida OS << (char)C; 1259e1450bcSMatheus Almeida } 1269e1450bcSMatheus Almeida 1279e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1289e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1299e1450bcSMatheus Almeida raw_ostream &OS) const { 1309e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1319e1450bcSMatheus Almeida // Little-endian byte ordering: 1329e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1339e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1349e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1359e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1369e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1379e1450bcSMatheus Almeida } else { 1389e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1399e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1409e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1419e1450bcSMatheus Almeida } 1429e1450bcSMatheus Almeida } 1439e1450bcSMatheus Almeida } 1449e1450bcSMatheus Almeida 14591df21f7SJim Grosbach /// encodeInstruction - Emit the instruction. 1464e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 147c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 14891df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS, 1499784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1509784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 151c85e3ff3SBruno Cardoso Lopes { 152aa7aeaa0SJack Carter 153aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 154aa7aeaa0SJack Carter // only based on operand values. 155aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 156aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 157aa7aeaa0SJack Carter MCInst TmpInst = MI; 158aa7aeaa0SJack Carter switch (MI.getOpcode()) { 159aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 160aa7aeaa0SJack Carter case Mips::DSLL: 161aa7aeaa0SJack Carter case Mips::DSRL: 162aa7aeaa0SJack Carter case Mips::DSRA: 1636a3fe574SAkira Hatanaka case Mips::DROTR: 164f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 165aa7aeaa0SJack Carter break; 166aa7aeaa0SJack Carter // Double extract instruction is chosen by pos and size operands 167aa7aeaa0SJack Carter case Mips::DEXT: 168aa7aeaa0SJack Carter case Mips::DINS: 169f30f2cceSRafael Espindola LowerDextDins(TmpInst); 170aa7aeaa0SJack Carter } 171aa7aeaa0SJack Carter 17297700977SJack Carter unsigned long N = Fixups.size(); 1733fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 174c85e3ff3SBruno Cardoso Lopes 175c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 176aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 177c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 178aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 179c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 180c7e220f6SJozef Kolek (Opcode != Mips::SLL_MM) && !Binary) 18191df21f7SJim Grosbach llvm_unreachable("unimplemented opcode in encodeInstruction()"); 182c85e3ff3SBruno Cardoso Lopes 183b59a5419SZoran Jovanovic int NewOpcode = -1; 1846ca13eafSJozef Kolek if (isMicroMips(STI)) { 185b59a5419SZoran Jovanovic if (isMips32r6(STI)) { 186b59a5419SZoran Jovanovic NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 187b59a5419SZoran Jovanovic if (NewOpcode == -1) 188b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 189b59a5419SZoran Jovanovic } 190b59a5419SZoran Jovanovic else 191b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 192b59a5419SZoran Jovanovic 1932e386d3dSZoran Jovanovic // Check whether it is Dsp instruction. 1942e386d3dSZoran Jovanovic if (NewOpcode == -1) 1952e386d3dSZoran Jovanovic NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 1962e386d3dSZoran Jovanovic 197be6a818fSAkira Hatanaka if (NewOpcode != -1) { 19897700977SJack Carter if (Fixups.size() > N) 19997700977SJack Carter Fixups.pop_back(); 200b59a5419SZoran Jovanovic 201be6a818fSAkira Hatanaka Opcode = NewOpcode; 202be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 2033fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 204be6a818fSAkira Hatanaka } 205be6a818fSAkira Hatanaka } 206be6a818fSAkira Hatanaka 207aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 208c85e3ff3SBruno Cardoso Lopes 2095b5559d3SJack Carter // Get byte count of instruction 2105b5559d3SJack Carter unsigned Size = Desc.getSize(); 2115b5559d3SJack Carter if (!Size) 2125b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 213c85e3ff3SBruno Cardoso Lopes 214d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 215c85e3ff3SBruno Cardoso Lopes } 216c85e3ff3SBruno Cardoso Lopes 217c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 218c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 219c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 220c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 221c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2223fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2233fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 224c85e3ff3SBruno Cardoso Lopes 225c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 22671e6a749SJack Carter 2274f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2284f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2294f69a0f2SJack Carter 23071e6a749SJack Carter assert(MO.isExpr() && 23171e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 232c85e3ff3SBruno Cardoso Lopes 233b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 234b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 235b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 236c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 237c85e3ff3SBruno Cardoso Lopes return 0; 238c85e3ff3SBruno Cardoso Lopes } 239c85e3ff3SBruno Cardoso Lopes 2409761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 2419761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 2429761e96bSJozef Kolek /// record the relocation and return zero. 2439761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 2449761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 2459761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 2469761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 2479761e96bSJozef Kolek 2489761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 2499761e96bSJozef Kolek 2509761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 2519761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 2529761e96bSJozef Kolek 2539761e96bSJozef Kolek assert(MO.isExpr() && 2549761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 2559761e96bSJozef Kolek 2569761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 25763661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 2589761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 2599761e96bSJozef Kolek return 0; 2609761e96bSJozef Kolek } 2619761e96bSJozef Kolek 2625cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 2635cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 2645cfebddeSJozef Kolek /// record the relocation and return zero. 2655cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 2665cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 2675cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 2685cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 2695cfebddeSJozef Kolek 2705cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 2715cfebddeSJozef Kolek 2725cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 2735cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 2745cfebddeSJozef Kolek 2755cfebddeSJozef Kolek assert(MO.isExpr() && 2765cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 2775cfebddeSJozef Kolek 2785cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 27963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 2805cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 2815cfebddeSJozef Kolek return 0; 2825cfebddeSJozef Kolek } 2835cfebddeSJozef Kolek 2848a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 2858a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 2868a80aa76SZoran Jovanovic /// record the relocation and return zero. 2878a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 2888a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 2893fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2903fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 2918a80aa76SZoran Jovanovic 2928a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 2938a80aa76SZoran Jovanovic 2948a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 2958a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 2968a80aa76SZoran Jovanovic 2978a80aa76SZoran Jovanovic assert(MO.isExpr() && 2988a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 2998a80aa76SZoran Jovanovic 3008a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 30163661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3028a80aa76SZoran Jovanovic MCFixupKind(Mips:: 3038a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 3048a80aa76SZoran Jovanovic return 0; 3058a80aa76SZoran Jovanovic } 3068a80aa76SZoran Jovanovic 3073c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 3083c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3093c8869dcSZoran Jovanovic /// record the relocation and return zero. 3103c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3113c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 3123c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 3133c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 3143c8869dcSZoran Jovanovic 3153c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3163c8869dcSZoran Jovanovic 3173c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3183c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3193c8869dcSZoran Jovanovic 3203c8869dcSZoran Jovanovic assert(MO.isExpr() && 3213c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 3223c8869dcSZoran Jovanovic 323b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 324b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 325b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 32610e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 3273c8869dcSZoran Jovanovic return 0; 3283c8869dcSZoran Jovanovic } 3293c8869dcSZoran Jovanovic 3303c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 3313c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3323c8869dcSZoran Jovanovic /// record the relocation and return zero. 3333c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3343c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 3353c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 3363c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 3373c8869dcSZoran Jovanovic 3383c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3393c8869dcSZoran Jovanovic 3403c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3413c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3423c8869dcSZoran Jovanovic 3433c8869dcSZoran Jovanovic assert(MO.isExpr() && 3443c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 3453c8869dcSZoran Jovanovic 346b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 347b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 348b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 34910e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 3503c8869dcSZoran Jovanovic return 0; 3513c8869dcSZoran Jovanovic } 3523c8869dcSZoran Jovanovic 353*a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 354*a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 355*a887b361SZoran Jovanovic /// record the relocation and return zero. 356*a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 357*a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 358*a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 359*a887b361SZoran Jovanovic 360*a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 361*a887b361SZoran Jovanovic 362*a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 363*a887b361SZoran Jovanovic if (MO.isImm()) 364*a887b361SZoran Jovanovic return MO.getImm() >> 1; 365*a887b361SZoran Jovanovic 366*a887b361SZoran Jovanovic // TODO: Push 26 PC fixup. 367*a887b361SZoran Jovanovic return 0; 368*a887b361SZoran Jovanovic } 369*a887b361SZoran Jovanovic 37052c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 37152c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 37252c56b93SZoran Jovanovic /// record the relocation and return zero. 37352c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 37452c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 37552c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 37652c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 37752c56b93SZoran Jovanovic 37852c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 37952c56b93SZoran Jovanovic 38052c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 38152c56b93SZoran Jovanovic 38252c56b93SZoran Jovanovic assert(MO.isExpr() && 38352c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 38452c56b93SZoran Jovanovic 38552c56b93SZoran Jovanovic // TODO: Push fixup. 38652c56b93SZoran Jovanovic return 0; 38752c56b93SZoran Jovanovic } 38852c56b93SZoran Jovanovic 389c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 390c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 391c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 392c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 393c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 3943fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3953fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 396c85e3ff3SBruno Cardoso Lopes 397c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 3984f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 3994f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 4004f69a0f2SJack Carter 40171e6a749SJack Carter assert(MO.isExpr() && 40271e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 403c85e3ff3SBruno Cardoso Lopes 404c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 40563661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 406c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 407c85e3ff3SBruno Cardoso Lopes return 0; 408c85e3ff3SBruno Cardoso Lopes } 409c85e3ff3SBruno Cardoso Lopes 410c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 411507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 4123fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4133fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 414507e084aSZoran Jovanovic 415507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 416507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 417507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 418507e084aSZoran Jovanovic 419507e084aSZoran Jovanovic assert(MO.isExpr() && 420507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 421507e084aSZoran Jovanovic 422507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 42363661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 424507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 425507e084aSZoran Jovanovic return 0; 426507e084aSZoran Jovanovic } 427507e084aSZoran Jovanovic 428507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 429c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 430c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 431c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 432c74e3eb9SZoran Jovanovic 433c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 434c74e3eb9SZoran Jovanovic if (MO.isImm()) { 435c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 436c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 437c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 438c74e3eb9SZoran Jovanovic return Res >> 2; 439c74e3eb9SZoran Jovanovic } 440c74e3eb9SZoran Jovanovic 441c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 442c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 443c74e3eb9SZoran Jovanovic 444c74e3eb9SZoran Jovanovic return 0; 445c74e3eb9SZoran Jovanovic } 446c74e3eb9SZoran Jovanovic 447c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 448bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 449bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 450bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 451bac3619bSZoran Jovanovic 452bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 453bac3619bSZoran Jovanovic if (MO.isImm()) { 454bac3619bSZoran Jovanovic int Value = MO.getImm(); 455bac3619bSZoran Jovanovic return Value >> 2; 456bac3619bSZoran Jovanovic } 457bac3619bSZoran Jovanovic 458bac3619bSZoran Jovanovic return 0; 459bac3619bSZoran Jovanovic } 460bac3619bSZoran Jovanovic 461bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 46242b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 46342b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 46442b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 46542b84443SZoran Jovanovic 46642b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 46742b84443SZoran Jovanovic if (MO.isImm()) { 46842b84443SZoran Jovanovic unsigned Value = MO.getImm(); 46942b84443SZoran Jovanovic return Value >> 2; 47042b84443SZoran Jovanovic } 47142b84443SZoran Jovanovic 47242b84443SZoran Jovanovic return 0; 47342b84443SZoran Jovanovic } 47442b84443SZoran Jovanovic 47542b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 47698bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 47798bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 47898bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 47998bd58caSZoran Jovanovic 48098bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 48198bd58caSZoran Jovanovic if (MO.isImm()) { 48298bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 48398bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 48498bd58caSZoran Jovanovic } 48598bd58caSZoran Jovanovic 48698bd58caSZoran Jovanovic return 0; 48798bd58caSZoran Jovanovic } 48898bd58caSZoran Jovanovic 48998bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4903fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 4913fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 492b5cf5909SJack Carter int64_t Res; 493049e9e4dSAkira Hatanaka 49413760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 495b5cf5909SJack Carter return Res; 496fe384a2cSAkira Hatanaka 497fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 498b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 499b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 500b5cf5909SJack Carter } 501fe384a2cSAkira Hatanaka 502fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 5033fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 5043fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 505b5cf5909SJack Carter return Res; 506fe384a2cSAkira Hatanaka } 507a5da588bSPetar Jovanovic 508a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 509a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 510a5da588bSPetar Jovanovic 511a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 512a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 513a5da588bSPetar Jovanovic default: llvm_unreachable("Unsupported fixup kind for target expression!"); 51406c47803SSasa Stankovic case MipsMCExpr::VK_Mips_HIGHEST: 51506c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 51606c47803SSasa Stankovic break; 51706c47803SSasa Stankovic case MipsMCExpr::VK_Mips_HIGHER: 51806c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 51906c47803SSasa Stankovic break; 52006c47803SSasa Stankovic case MipsMCExpr::VK_Mips_HI: 521a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 522a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 523a5da588bSPetar Jovanovic break; 52406c47803SSasa Stankovic case MipsMCExpr::VK_Mips_LO: 525a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 526a5da588bSPetar Jovanovic : Mips::fixup_Mips_LO16; 527a5da588bSPetar Jovanovic break; 528a5da588bSPetar Jovanovic } 52963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 530a5da588bSPetar Jovanovic return 0; 531a5da588bSPetar Jovanovic } 532a5da588bSPetar Jovanovic 533b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 534f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 535e2eed964SAkira Hatanaka 536049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 537b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 53860f1db05SDaniel Sanders break; 53960f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 54060f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 541b9f9de93SJack Carter break; 542b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GPOFF_HI : 543b9f9de93SJack Carter FixupKind = Mips::fixup_Mips_GPOFF_HI; 544b9f9de93SJack Carter break; 545b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GPOFF_LO : 546b9f9de93SJack Carter FixupKind = Mips::fixup_Mips_GPOFF_LO; 547b9f9de93SJack Carter break; 548b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GOT_PAGE : 549d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 550e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_PAGE; 551b9f9de93SJack Carter break; 552b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GOT_OFST : 553d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 554e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_OFST; 555b9f9de93SJack Carter break; 5565ddcfda8SJack Carter case MCSymbolRefExpr::VK_Mips_GOT_DISP : 557d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 558e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_DISP; 5595ddcfda8SJack Carter break; 560c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GPREL: 561c85e3ff3SBruno Cardoso Lopes FixupKind = Mips::fixup_Mips_GPREL16; 562c85e3ff3SBruno Cardoso Lopes break; 563c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOT_CALL: 564d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 565e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_CALL16; 566c85e3ff3SBruno Cardoso Lopes break; 56761e6d987SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOT16: 568d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 569e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_Global; 57061e6d987SBruno Cardoso Lopes break; 571c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOT: 572d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 573e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_Local; 574c85e3ff3SBruno Cardoso Lopes break; 575c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_ABS_HI: 576d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 577e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_HI16; 578c85e3ff3SBruno Cardoso Lopes break; 579c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_ABS_LO: 580d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 581e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_LO16; 582c85e3ff3SBruno Cardoso Lopes break; 583c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_TLSGD: 584d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 58569be811aSZoran Jovanovic : Mips::fixup_Mips_TLSGD; 586c85e3ff3SBruno Cardoso Lopes break; 587e2eed964SAkira Hatanaka case MCSymbolRefExpr::VK_Mips_TLSLDM: 588d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 58969be811aSZoran Jovanovic : Mips::fixup_Mips_TLSLDM; 590e2eed964SAkira Hatanaka break; 591e2eed964SAkira Hatanaka case MCSymbolRefExpr::VK_Mips_DTPREL_HI: 592d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 593e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_DTPREL_HI; 594e2eed964SAkira Hatanaka break; 595e2eed964SAkira Hatanaka case MCSymbolRefExpr::VK_Mips_DTPREL_LO: 596d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 597e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_DTPREL_LO; 598e2eed964SAkira Hatanaka break; 599c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOTTPREL: 600c85e3ff3SBruno Cardoso Lopes FixupKind = Mips::fixup_Mips_GOTTPREL; 601c85e3ff3SBruno Cardoso Lopes break; 602c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_TPREL_HI: 603d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 604e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_TPREL_HI; 605c85e3ff3SBruno Cardoso Lopes break; 606c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_TPREL_LO: 607d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 608e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_TPREL_LO; 609c85e3ff3SBruno Cardoso Lopes break; 61084491abbSJack Carter case MCSymbolRefExpr::VK_Mips_HIGHER: 61184491abbSJack Carter FixupKind = Mips::fixup_Mips_HIGHER; 61284491abbSJack Carter break; 61384491abbSJack Carter case MCSymbolRefExpr::VK_Mips_HIGHEST: 61484491abbSJack Carter FixupKind = Mips::fixup_Mips_HIGHEST; 61584491abbSJack Carter break; 616b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_GOT_HI16: 617b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_GOT_HI16; 618b05cb67bSJack Carter break; 619b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_GOT_LO16: 620b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_GOT_LO16; 621b05cb67bSJack Carter break; 622b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_CALL_HI16: 623b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_CALL_HI16; 624b05cb67bSJack Carter break; 625b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_CALL_LO16: 626b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_CALL_LO16; 627b05cb67bSJack Carter break; 628b355e8f6SZoran Jovanovic case MCSymbolRefExpr::VK_Mips_PCREL_HI16: 629b355e8f6SZoran Jovanovic FixupKind = Mips::fixup_MIPS_PCHI16; 630b355e8f6SZoran Jovanovic break; 631b355e8f6SZoran Jovanovic case MCSymbolRefExpr::VK_Mips_PCREL_LO16: 632b355e8f6SZoran Jovanovic FixupKind = Mips::fixup_MIPS_PCLO16; 633b355e8f6SZoran Jovanovic break; 634c85e3ff3SBruno Cardoso Lopes } // switch 635fe384a2cSAkira Hatanaka 63663661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 637fe384a2cSAkira Hatanaka return 0; 638c85e3ff3SBruno Cardoso Lopes } 639b5cf5909SJack Carter return 0; 640b5cf5909SJack Carter } 641b5cf5909SJack Carter 642b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 643b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 644b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 645b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 6463fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 6473fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 648b5cf5909SJack Carter if (MO.isReg()) { 649b5cf5909SJack Carter unsigned Reg = MO.getReg(); 650bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 651b5cf5909SJack Carter return RegNo; 652b5cf5909SJack Carter } else if (MO.isImm()) { 653b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 654b5cf5909SJack Carter } else if (MO.isFPImm()) { 655b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 656b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 657b5cf5909SJack Carter } 658b5cf5909SJack Carter // MO must be an Expr. 659b5cf5909SJack Carter assert(MO.isExpr()); 6603fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 661b5cf5909SJack Carter } 662c85e3ff3SBruno Cardoso Lopes 6636b59c449SMatheus Almeida /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST 6646b59c449SMatheus Almeida /// instructions. 6656b59c449SMatheus Almeida unsigned 6666b59c449SMatheus Almeida MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo, 6673fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 6683fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 6696b59c449SMatheus Almeida // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 6706b59c449SMatheus Almeida assert(MI.getOperand(OpNo).isReg()); 6713fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 6723fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 6736b59c449SMatheus Almeida 6746b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 6756b59c449SMatheus Almeida // be divided (when encoding) by the size (in bytes) of the instructions' 6766b59c449SMatheus Almeida // data format. 6776b59c449SMatheus Almeida // .b - 1 byte 6786b59c449SMatheus Almeida // .h - 2 bytes 6796b59c449SMatheus Almeida // .w - 4 bytes 6806b59c449SMatheus Almeida // .d - 8 bytes 6816b59c449SMatheus Almeida switch(MI.getOpcode()) 6826b59c449SMatheus Almeida { 6836b59c449SMatheus Almeida default: 6846b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 6856b59c449SMatheus Almeida break; 6866b59c449SMatheus Almeida case Mips::LD_B: 6876b59c449SMatheus Almeida case Mips::ST_B: 6886b59c449SMatheus Almeida // We don't need to scale the offset in this case 6896b59c449SMatheus Almeida break; 6906b59c449SMatheus Almeida case Mips::LD_H: 6916b59c449SMatheus Almeida case Mips::ST_H: 6926b59c449SMatheus Almeida OffBits >>= 1; 6936b59c449SMatheus Almeida break; 6946b59c449SMatheus Almeida case Mips::LD_W: 6956b59c449SMatheus Almeida case Mips::ST_W: 6966b59c449SMatheus Almeida OffBits >>= 2; 6976b59c449SMatheus Almeida break; 6986b59c449SMatheus Almeida case Mips::LD_D: 6996b59c449SMatheus Almeida case Mips::ST_D: 7006b59c449SMatheus Almeida OffBits >>= 3; 7016b59c449SMatheus Almeida break; 7026b59c449SMatheus Almeida } 7036b59c449SMatheus Almeida 7046b59c449SMatheus Almeida return (OffBits & 0xFFFF) | RegBits; 7056b59c449SMatheus Almeida } 7066b59c449SMatheus Almeida 707c85e3ff3SBruno Cardoso Lopes /// getMemEncoding - Return binary encoding of memory related operand. 708c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 709c85e3ff3SBruno Cardoso Lopes unsigned 710c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 7113fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7123fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 713c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 714c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 7153fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 7163fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 717c85e3ff3SBruno Cardoso Lopes 718c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 719c85e3ff3SBruno Cardoso Lopes } 720c85e3ff3SBruno Cardoso Lopes 72197700977SJack Carter unsigned MipsMCCodeEmitter:: 722e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 723e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 724e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 725e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 726e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 727e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 728e8c9d1eaSJozef Kolek Fixups, STI) << 4; 729e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 730e8c9d1eaSJozef Kolek Fixups, STI); 731e8c9d1eaSJozef Kolek 732e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 733e8c9d1eaSJozef Kolek } 734e8c9d1eaSJozef Kolek 735e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 736e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 737e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 738e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 739e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 740e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 741e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 742e8c9d1eaSJozef Kolek Fixups, STI) << 4; 743e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 744e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 745e8c9d1eaSJozef Kolek 746e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 747e8c9d1eaSJozef Kolek } 748e8c9d1eaSJozef Kolek 749e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 750e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 751e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 752e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 753e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 754e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 755e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 756e8c9d1eaSJozef Kolek Fixups, STI) << 4; 757e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 758e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 759e8c9d1eaSJozef Kolek 760e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 761e8c9d1eaSJozef Kolek } 762e8c9d1eaSJozef Kolek 763e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 76412c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 76512c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 76612c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 76712c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 76812c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 76968be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 77068be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 77112c6982bSJozef Kolek "Unexpected base register!"); 77212c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 77312c6982bSJozef Kolek Fixups, STI) >> 2; 77412c6982bSJozef Kolek 77512c6982bSJozef Kolek return OffBits & 0x1F; 77612c6982bSJozef Kolek } 77712c6982bSJozef Kolek 77812c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 779e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 780e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 781e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 782e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 783e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 784e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 785e10a02ecSJozef Kolek "Unexpected base register!"); 786e10a02ecSJozef Kolek 787e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 788e10a02ecSJozef Kolek Fixups, STI) >> 2; 789e10a02ecSJozef Kolek 790e10a02ecSJozef Kolek return OffBits & 0x7F; 791e10a02ecSJozef Kolek } 792e10a02ecSJozef Kolek 7939eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 7949eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 7959eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 7969eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 7979eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 7989eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 7999eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8009eaa30d2SZoran Jovanovic STI) << 16; 8019eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 8029eaa30d2SZoran Jovanovic 8039eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 8049eaa30d2SZoran Jovanovic } 8059eaa30d2SZoran Jovanovic 806e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 80797700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 8083fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8093fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 810a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 811a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 812a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 813a4c4b5fcSZoran Jovanovic default: 814a4c4b5fcSZoran Jovanovic break; 815a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 816a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 817a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 818a4c4b5fcSZoran Jovanovic break; 819a4c4b5fcSZoran Jovanovic } 820a4c4b5fcSZoran Jovanovic 82197700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 82297700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 8233fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 8243fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 82597700977SJack Carter 82697700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 8273c88fbd3SHrvoje Varga } 8283c88fbd3SHrvoje Varga 8293c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 8303c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 8313c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 8323c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 8333c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 8343c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 8353c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8363c88fbd3SHrvoje Varga STI) << 16; 8373c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 8383c88fbd3SHrvoje Varga 8393c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 84097700977SJack Carter } 84197700977SJack Carter 842f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 843f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 844f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 845f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 846f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 847f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 848f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 849f9a02500SZoran Jovanovic default: 850f9a02500SZoran Jovanovic break; 851f9a02500SZoran Jovanovic case Mips::SWM16_MM: 852797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 853f9a02500SZoran Jovanovic case Mips::LWM16_MM: 854797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 855f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 856f9a02500SZoran Jovanovic break; 857f9a02500SZoran Jovanovic } 858f9a02500SZoran Jovanovic 859f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 860f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 861f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 862f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 863f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 864f9a02500SZoran Jovanovic 865f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 866f9a02500SZoran Jovanovic } 867f9a02500SZoran Jovanovic 868c85e3ff3SBruno Cardoso Lopes unsigned 869c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo, 8703fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8713fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 872049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 8733fa98a65SDavid Woodhouse unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 87456b70de0SBruno Cardoso Lopes return SizeEncoding - 1; 875c85e3ff3SBruno Cardoso Lopes } 876c85e3ff3SBruno Cardoso Lopes 877049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 878049e9e4dSAkira Hatanaka // 879c85e3ff3SBruno Cardoso Lopes unsigned 880c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 8813fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8823fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 883049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 884049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 8853fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 8863fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 887049e9e4dSAkira Hatanaka 88856b70de0SBruno Cardoso Lopes return Position + Size - 1; 889c85e3ff3SBruno Cardoso Lopes } 890c85e3ff3SBruno Cardoso Lopes 891ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 892779c5937SMatheus Almeida unsigned 893ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 8943fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8953fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 896779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 897ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 898ea4f653dSDaniel Sanders Value -= Offset; 899ea4f653dSDaniel Sanders return Value; 900779c5937SMatheus Almeida } 901779c5937SMatheus Almeida 902b59e1a41SDaniel Sanders unsigned 903b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 904b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 905b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 906b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 907b9c07f3bSZoran Jovanovic if (MO.isImm()) { 908b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 909b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 910b59e1a41SDaniel Sanders assert((Res & 3) == 0); 911b59e1a41SDaniel Sanders return Res >> 2; 912b59e1a41SDaniel Sanders } 913c85e3ff3SBruno Cardoso Lopes 914b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 915b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 916b9c07f3bSZoran Jovanovic 917b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 91863661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 919b9c07f3bSZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC19_S2))); 920b9c07f3bSZoran Jovanovic return 0; 921b9c07f3bSZoran Jovanovic } 922b9c07f3bSZoran Jovanovic 9232855142aSZoran Jovanovic unsigned 9242855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 9252855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9262855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 927a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 928a5acdcf9SZoran Jovanovic if (MO.isImm()) { 9292855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 9302855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 9312855142aSZoran Jovanovic assert((Res & 7) == 0); 9322855142aSZoran Jovanovic return Res >> 3; 9332855142aSZoran Jovanovic } 9342855142aSZoran Jovanovic 935a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 936a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 937a5acdcf9SZoran Jovanovic 938a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 93963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 940a5acdcf9SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC18_S3))); 941a5acdcf9SZoran Jovanovic return 0; 942a5acdcf9SZoran Jovanovic } 943a5acdcf9SZoran Jovanovic 9444a00fdc2SZoran Jovanovic unsigned 9454a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 9464a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9474a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 9484a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 9494a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 9504a00fdc2SZoran Jovanovic return MO.getImm() % 8; 9514a00fdc2SZoran Jovanovic } 9524a00fdc2SZoran Jovanovic 9538853171bSZoran Jovanovic unsigned 9548853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 9558853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9568853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 9578853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 9588853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 9598853171bSZoran Jovanovic unsigned Value = MO.getImm(); 9608853171bSZoran Jovanovic switch (Value) { 9618853171bSZoran Jovanovic case 128: return 0x0; 9628853171bSZoran Jovanovic case 1: return 0x1; 9638853171bSZoran Jovanovic case 2: return 0x2; 9648853171bSZoran Jovanovic case 3: return 0x3; 9658853171bSZoran Jovanovic case 4: return 0x4; 9668853171bSZoran Jovanovic case 7: return 0x5; 9678853171bSZoran Jovanovic case 8: return 0x6; 9688853171bSZoran Jovanovic case 15: return 0x7; 9698853171bSZoran Jovanovic case 16: return 0x8; 9708853171bSZoran Jovanovic case 31: return 0x9; 9718853171bSZoran Jovanovic case 32: return 0xa; 9728853171bSZoran Jovanovic case 63: return 0xb; 9738853171bSZoran Jovanovic case 64: return 0xc; 9748853171bSZoran Jovanovic case 255: return 0xd; 9758853171bSZoran Jovanovic case 32768: return 0xe; 9768853171bSZoran Jovanovic case 65535: return 0xf; 9778853171bSZoran Jovanovic } 9788853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 9798853171bSZoran Jovanovic } 9808853171bSZoran Jovanovic 981a4c4b5fcSZoran Jovanovic unsigned 982a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 983a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 984a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 985a4c4b5fcSZoran Jovanovic unsigned res = 0; 986a4c4b5fcSZoran Jovanovic 987a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 988a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 989a4c4b5fcSZoran Jovanovic 990a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 991a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 992a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 993a4c4b5fcSZoran Jovanovic if (RegNo != 31) 994a4c4b5fcSZoran Jovanovic res++; 995a4c4b5fcSZoran Jovanovic else 996a4c4b5fcSZoran Jovanovic res |= 0x10; 997a4c4b5fcSZoran Jovanovic } 998a4c4b5fcSZoran Jovanovic return res; 999a4c4b5fcSZoran Jovanovic } 1000a4c4b5fcSZoran Jovanovic 1001f9a02500SZoran Jovanovic unsigned 1002f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1003f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1004f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 1005f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 1006f9a02500SZoran Jovanovic } 1007f9a02500SZoran Jovanovic 10082deca348SZoran Jovanovic unsigned 10092deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 10102deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10112deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 10122deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 10132deca348SZoran Jovanovic } 10142deca348SZoran Jovanovic 10152c6d7320SJozef Kolek unsigned 101641688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 101741688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 101841688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 101941688679SZoran Jovanovic unsigned res = 0; 102041688679SZoran Jovanovic 102141688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 102241688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 102341688679SZoran Jovanovic res = 0; 102441688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 102541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 102641688679SZoran Jovanovic res = 1; 102741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 102841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 102941688679SZoran Jovanovic res = 2; 103041688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 103141688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 103241688679SZoran Jovanovic res = 3; 103341688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 103441688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 103541688679SZoran Jovanovic res = 4; 103641688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 103741688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 103841688679SZoran Jovanovic res = 5; 103941688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 104041688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 104141688679SZoran Jovanovic res = 6; 104241688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 104341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 104441688679SZoran Jovanovic res = 7; 104541688679SZoran Jovanovic 104641688679SZoran Jovanovic return res; 104741688679SZoran Jovanovic } 104841688679SZoran Jovanovic 104941688679SZoran Jovanovic unsigned 10502c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 10512c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 10522c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 10532c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 10542c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 10552c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 10562c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 10572c6d7320SJozef Kolek assert((Res & 3) == 0); 10582c6d7320SJozef Kolek return Res >> 2; 10592c6d7320SJozef Kolek } 10602c6d7320SJozef Kolek 1061b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1062