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" 26750ecec7SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h" 27750ecec7SAkira Hatanaka #include "llvm/Support/raw_ostream.h" 28750ecec7SAkira Hatanaka 2984e68b29SChandler Carruth #define DEBUG_TYPE "mccodeemitter" 3084e68b29SChandler Carruth 31be6a818fSAkira Hatanaka #define GET_INSTRMAP_INFO 32be6a818fSAkira Hatanaka #include "MipsGenInstrInfo.inc" 339e1450bcSMatheus Almeida #undef GET_INSTRMAP_INFO 34be6a818fSAkira Hatanaka 359e1450bcSMatheus Almeida namespace llvm { 369e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 37c3b04279SJim Grosbach const MCRegisterInfo &MRI, 38750ecec7SAkira Hatanaka const MCSubtargetInfo &STI, 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, 451ee768dbSAkira Hatanaka const MCSubtargetInfo &STI, 469e1450bcSMatheus Almeida MCContext &Ctx) { 47d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, true); 48750ecec7SAkira Hatanaka } 499e1450bcSMatheus Almeida } // End of namespace llvm. 50f30f2cceSRafael Espindola 51f30f2cceSRafael Espindola // If the D<shift> instruction has a shift amount that is greater 52f30f2cceSRafael Espindola // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 53f30f2cceSRafael Espindola static void LowerLargeShift(MCInst& Inst) { 54f30f2cceSRafael Espindola 55f30f2cceSRafael Espindola assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 56f30f2cceSRafael Espindola assert(Inst.getOperand(2).isImm()); 57f30f2cceSRafael Espindola 58f30f2cceSRafael Espindola int64_t Shift = Inst.getOperand(2).getImm(); 59f30f2cceSRafael Espindola if (Shift <= 31) 60f30f2cceSRafael Espindola return; // Do nothing 61f30f2cceSRafael Espindola Shift -= 32; 62f30f2cceSRafael Espindola 63f30f2cceSRafael Espindola // saminus32 64f30f2cceSRafael Espindola Inst.getOperand(2).setImm(Shift); 65f30f2cceSRafael Espindola 66f30f2cceSRafael Espindola switch (Inst.getOpcode()) { 67f30f2cceSRafael Espindola default: 68f30f2cceSRafael Espindola // Calling function is not synchronized 69f30f2cceSRafael Espindola llvm_unreachable("Unexpected shift instruction"); 70f30f2cceSRafael Espindola case Mips::DSLL: 71f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSLL32); 72f30f2cceSRafael Espindola return; 73f30f2cceSRafael Espindola case Mips::DSRL: 74f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRL32); 75f30f2cceSRafael Espindola return; 76f30f2cceSRafael Espindola case Mips::DSRA: 77f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRA32); 78f30f2cceSRafael Espindola return; 796a3fe574SAkira Hatanaka case Mips::DROTR: 806a3fe574SAkira Hatanaka Inst.setOpcode(Mips::DROTR32); 816a3fe574SAkira Hatanaka return; 82f30f2cceSRafael Espindola } 83f30f2cceSRafael Espindola } 84f30f2cceSRafael Espindola 85f30f2cceSRafael Espindola // Pick a DEXT or DINS instruction variant based on the pos and size operands 86f30f2cceSRafael Espindola static void LowerDextDins(MCInst& InstIn) { 87f30f2cceSRafael Espindola int Opcode = InstIn.getOpcode(); 88f30f2cceSRafael Espindola 89f30f2cceSRafael Espindola if (Opcode == Mips::DEXT) 90f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 4 && 91f30f2cceSRafael Espindola "Invalid no. of machine operands for DEXT!"); 92f30f2cceSRafael Espindola else // Only DEXT and DINS are possible 93f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 5 && 94f30f2cceSRafael Espindola "Invalid no. of machine operands for DINS!"); 95f30f2cceSRafael Espindola 96f30f2cceSRafael Espindola assert(InstIn.getOperand(2).isImm()); 97f30f2cceSRafael Espindola int64_t pos = InstIn.getOperand(2).getImm(); 98f30f2cceSRafael Espindola assert(InstIn.getOperand(3).isImm()); 99f30f2cceSRafael Espindola int64_t size = InstIn.getOperand(3).getImm(); 100f30f2cceSRafael Espindola 101f30f2cceSRafael Espindola if (size <= 32) { 102f30f2cceSRafael Espindola if (pos < 32) // DEXT/DINS, do nothing 103f30f2cceSRafael Espindola return; 104f30f2cceSRafael Espindola // DEXTU/DINSU 105f30f2cceSRafael Espindola InstIn.getOperand(2).setImm(pos - 32); 106f30f2cceSRafael Espindola InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); 107f30f2cceSRafael Espindola return; 108f30f2cceSRafael Espindola } 109f30f2cceSRafael Espindola // DEXTM/DINSM 110f30f2cceSRafael Espindola assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); 111f30f2cceSRafael Espindola InstIn.getOperand(3).setImm(size - 32); 112f30f2cceSRafael Espindola InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); 113f30f2cceSRafael Espindola return; 114f30f2cceSRafael Espindola } 115f30f2cceSRafael Espindola 1169e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 1179e1450bcSMatheus Almeida return STI.getFeatureBits() & Mips::FeatureMicroMips; 1189e1450bcSMatheus Almeida } 1199e1450bcSMatheus Almeida 1209e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1219e1450bcSMatheus Almeida OS << (char)C; 1229e1450bcSMatheus Almeida } 1239e1450bcSMatheus Almeida 1249e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1259e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1269e1450bcSMatheus Almeida raw_ostream &OS) const { 1279e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1289e1450bcSMatheus Almeida // Little-endian byte ordering: 1299e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1309e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1319e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1329e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1339e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1349e1450bcSMatheus Almeida } else { 1359e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1369e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1379e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1389e1450bcSMatheus Almeida } 1399e1450bcSMatheus Almeida } 1409e1450bcSMatheus Almeida } 1419e1450bcSMatheus Almeida 142c85e3ff3SBruno Cardoso Lopes /// EncodeInstruction - Emit the instruction. 1434e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 144c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 145c85e3ff3SBruno Cardoso Lopes EncodeInstruction(const MCInst &MI, raw_ostream &OS, 1469784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1479784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 148c85e3ff3SBruno Cardoso Lopes { 149aa7aeaa0SJack Carter 150aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 151aa7aeaa0SJack Carter // only based on operand values. 152aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 153aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 154aa7aeaa0SJack Carter MCInst TmpInst = MI; 155aa7aeaa0SJack Carter switch (MI.getOpcode()) { 156aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 157aa7aeaa0SJack Carter case Mips::DSLL: 158aa7aeaa0SJack Carter case Mips::DSRL: 159aa7aeaa0SJack Carter case Mips::DSRA: 1606a3fe574SAkira Hatanaka case Mips::DROTR: 161f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 162aa7aeaa0SJack Carter break; 163aa7aeaa0SJack Carter // Double extract instruction is chosen by pos and size operands 164aa7aeaa0SJack Carter case Mips::DEXT: 165aa7aeaa0SJack Carter case Mips::DINS: 166f30f2cceSRafael Espindola LowerDextDins(TmpInst); 167aa7aeaa0SJack Carter } 168aa7aeaa0SJack Carter 16997700977SJack Carter unsigned long N = Fixups.size(); 1703fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 171c85e3ff3SBruno Cardoso Lopes 172c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 173aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 174c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 175aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 176c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 177c7e220f6SJozef Kolek (Opcode != Mips::SLL_MM) && !Binary) 178c85e3ff3SBruno Cardoso Lopes llvm_unreachable("unimplemented opcode in EncodeInstruction()"); 179c85e3ff3SBruno Cardoso Lopes 180be6a818fSAkira Hatanaka if (STI.getFeatureBits() & Mips::FeatureMicroMips) { 181be6a818fSAkira Hatanaka int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips); 182be6a818fSAkira Hatanaka if (NewOpcode != -1) { 18397700977SJack Carter if (Fixups.size() > N) 18497700977SJack Carter Fixups.pop_back(); 185be6a818fSAkira Hatanaka Opcode = NewOpcode; 186be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 1873fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 188be6a818fSAkira Hatanaka } 189be6a818fSAkira Hatanaka } 190be6a818fSAkira Hatanaka 191aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 192c85e3ff3SBruno Cardoso Lopes 1935b5559d3SJack Carter // Get byte count of instruction 1945b5559d3SJack Carter unsigned Size = Desc.getSize(); 1955b5559d3SJack Carter if (!Size) 1965b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 197c85e3ff3SBruno Cardoso Lopes 198d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 199c85e3ff3SBruno Cardoso Lopes } 200c85e3ff3SBruno Cardoso Lopes 201c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 202c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 203c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 204c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 205c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2063fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2073fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 208c85e3ff3SBruno Cardoso Lopes 209c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 21071e6a749SJack Carter 2114f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2124f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2134f69a0f2SJack Carter 21471e6a749SJack Carter assert(MO.isExpr() && 21571e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 216c85e3ff3SBruno Cardoso Lopes 217c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 218c85e3ff3SBruno Cardoso Lopes Fixups.push_back(MCFixup::Create(0, Expr, 219c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 220c85e3ff3SBruno Cardoso Lopes return 0; 221c85e3ff3SBruno Cardoso Lopes } 222c85e3ff3SBruno Cardoso Lopes 2239761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 2249761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 2259761e96bSJozef Kolek /// record the relocation and return zero. 2269761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 2279761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 2289761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 2299761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 2309761e96bSJozef Kolek 2319761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 2329761e96bSJozef Kolek 2339761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 2349761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 2359761e96bSJozef Kolek 2369761e96bSJozef Kolek assert(MO.isExpr() && 2379761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 2389761e96bSJozef Kolek 2399761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 2409761e96bSJozef Kolek Fixups.push_back(MCFixup::Create(0, Expr, 2419761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 2429761e96bSJozef Kolek return 0; 2439761e96bSJozef Kolek } 2449761e96bSJozef Kolek 2458a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 2468a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 2478a80aa76SZoran Jovanovic /// record the relocation and return zero. 2488a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 2498a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 2503fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2513fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 2528a80aa76SZoran Jovanovic 2538a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 2548a80aa76SZoran Jovanovic 2558a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 2568a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 2578a80aa76SZoran Jovanovic 2588a80aa76SZoran Jovanovic assert(MO.isExpr() && 2598a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 2608a80aa76SZoran Jovanovic 2618a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 2628a80aa76SZoran Jovanovic Fixups.push_back(MCFixup::Create(0, Expr, 2638a80aa76SZoran Jovanovic MCFixupKind(Mips:: 2648a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 2658a80aa76SZoran Jovanovic return 0; 2668a80aa76SZoran Jovanovic } 2678a80aa76SZoran Jovanovic 2683c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 2693c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 2703c8869dcSZoran Jovanovic /// record the relocation and return zero. 2713c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 2723c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 2733c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 2743c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 2753c8869dcSZoran Jovanovic 2763c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 2773c8869dcSZoran Jovanovic 2783c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 2793c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 2803c8869dcSZoran Jovanovic 2813c8869dcSZoran Jovanovic assert(MO.isExpr() && 2823c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 2833c8869dcSZoran Jovanovic 28410e06da0SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 28510e06da0SZoran Jovanovic Fixups.push_back(MCFixup::Create(0, Expr, 28610e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 2873c8869dcSZoran Jovanovic return 0; 2883c8869dcSZoran Jovanovic } 2893c8869dcSZoran Jovanovic 2903c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 2913c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 2923c8869dcSZoran Jovanovic /// record the relocation and return zero. 2933c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 2943c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 2953c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 2963c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 2973c8869dcSZoran Jovanovic 2983c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 2993c8869dcSZoran Jovanovic 3003c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3013c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3023c8869dcSZoran Jovanovic 3033c8869dcSZoran Jovanovic assert(MO.isExpr() && 3043c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 3053c8869dcSZoran Jovanovic 30610e06da0SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 30710e06da0SZoran Jovanovic Fixups.push_back(MCFixup::Create(0, Expr, 30810e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 3093c8869dcSZoran Jovanovic return 0; 3103c8869dcSZoran Jovanovic } 3113c8869dcSZoran Jovanovic 31252c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 31352c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 31452c56b93SZoran Jovanovic /// record the relocation and return zero. 31552c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 31652c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 31752c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 31852c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 31952c56b93SZoran Jovanovic 32052c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 32152c56b93SZoran Jovanovic 32252c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 32352c56b93SZoran Jovanovic 32452c56b93SZoran Jovanovic assert(MO.isExpr() && 32552c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 32652c56b93SZoran Jovanovic 32752c56b93SZoran Jovanovic // TODO: Push fixup. 32852c56b93SZoran Jovanovic return 0; 32952c56b93SZoran Jovanovic } 33052c56b93SZoran Jovanovic 331c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 332c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 333c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 334c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 335c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 3363fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3373fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 338c85e3ff3SBruno Cardoso Lopes 339c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 3404f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 3414f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 3424f69a0f2SJack Carter 34371e6a749SJack Carter assert(MO.isExpr() && 34471e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 345c85e3ff3SBruno Cardoso Lopes 346c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 347c85e3ff3SBruno Cardoso Lopes Fixups.push_back(MCFixup::Create(0, Expr, 348c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 349c85e3ff3SBruno Cardoso Lopes return 0; 350c85e3ff3SBruno Cardoso Lopes } 351c85e3ff3SBruno Cardoso Lopes 352c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 353507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 3543fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3553fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 356507e084aSZoran Jovanovic 357507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 358507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 359507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 360507e084aSZoran Jovanovic 361507e084aSZoran Jovanovic assert(MO.isExpr() && 362507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 363507e084aSZoran Jovanovic 364507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 365507e084aSZoran Jovanovic Fixups.push_back(MCFixup::Create(0, Expr, 366507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 367507e084aSZoran Jovanovic return 0; 368507e084aSZoran Jovanovic } 369507e084aSZoran Jovanovic 370507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 371c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 372c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 373c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 374c74e3eb9SZoran Jovanovic 375c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 376c74e3eb9SZoran Jovanovic if (MO.isImm()) { 377c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 378c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 379c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 380c74e3eb9SZoran Jovanovic return Res >> 2; 381c74e3eb9SZoran Jovanovic } 382c74e3eb9SZoran Jovanovic 383c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 384c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 385c74e3eb9SZoran Jovanovic 386c74e3eb9SZoran Jovanovic return 0; 387c74e3eb9SZoran Jovanovic } 388c74e3eb9SZoran Jovanovic 389c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 390bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 391bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 392bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 393bac3619bSZoran Jovanovic 394bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 395bac3619bSZoran Jovanovic if (MO.isImm()) { 396bac3619bSZoran Jovanovic int Value = MO.getImm(); 397bac3619bSZoran Jovanovic return Value >> 2; 398bac3619bSZoran Jovanovic } 399bac3619bSZoran Jovanovic 400bac3619bSZoran Jovanovic return 0; 401bac3619bSZoran Jovanovic } 402bac3619bSZoran Jovanovic 403bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 40442b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 40542b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 40642b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 40742b84443SZoran Jovanovic 40842b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 40942b84443SZoran Jovanovic if (MO.isImm()) { 41042b84443SZoran Jovanovic unsigned Value = MO.getImm(); 41142b84443SZoran Jovanovic return Value >> 2; 41242b84443SZoran Jovanovic } 41342b84443SZoran Jovanovic 41442b84443SZoran Jovanovic return 0; 41542b84443SZoran Jovanovic } 41642b84443SZoran Jovanovic 41742b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 41898bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 41998bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 42098bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 42198bd58caSZoran Jovanovic 42298bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 42398bd58caSZoran Jovanovic if (MO.isImm()) { 42498bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 42598bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 42698bd58caSZoran Jovanovic } 42798bd58caSZoran Jovanovic 42898bd58caSZoran Jovanovic return 0; 42998bd58caSZoran Jovanovic } 43098bd58caSZoran Jovanovic 43198bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4323fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, 4333fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 434b5cf5909SJack Carter int64_t Res; 435049e9e4dSAkira Hatanaka 436b5cf5909SJack Carter if (Expr->EvaluateAsAbsolute(Res)) 437b5cf5909SJack Carter return Res; 438fe384a2cSAkira Hatanaka 439fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 440b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 441b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 442b5cf5909SJack Carter } 443fe384a2cSAkira Hatanaka 444fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 4453fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 4463fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 447b5cf5909SJack Carter return Res; 448fe384a2cSAkira Hatanaka } 449a5da588bSPetar Jovanovic 450a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 451a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 452a5da588bSPetar Jovanovic 453a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 454a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 455a5da588bSPetar Jovanovic default: llvm_unreachable("Unsupported fixup kind for target expression!"); 45606c47803SSasa Stankovic case MipsMCExpr::VK_Mips_HIGHEST: 45706c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 45806c47803SSasa Stankovic break; 45906c47803SSasa Stankovic case MipsMCExpr::VK_Mips_HIGHER: 46006c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 46106c47803SSasa Stankovic break; 46206c47803SSasa Stankovic case MipsMCExpr::VK_Mips_HI: 463a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 464a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 465a5da588bSPetar Jovanovic break; 46606c47803SSasa Stankovic case MipsMCExpr::VK_Mips_LO: 467a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 468a5da588bSPetar Jovanovic : Mips::fixup_Mips_LO16; 469a5da588bSPetar Jovanovic break; 470a5da588bSPetar Jovanovic } 471a5da588bSPetar Jovanovic Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind))); 472a5da588bSPetar Jovanovic return 0; 473a5da588bSPetar Jovanovic } 474a5da588bSPetar Jovanovic 475b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 476f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 477e2eed964SAkira Hatanaka 478049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 479b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 480b9f9de93SJack Carter break; 481b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GPOFF_HI : 482b9f9de93SJack Carter FixupKind = Mips::fixup_Mips_GPOFF_HI; 483b9f9de93SJack Carter break; 484b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GPOFF_LO : 485b9f9de93SJack Carter FixupKind = Mips::fixup_Mips_GPOFF_LO; 486b9f9de93SJack Carter break; 487b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GOT_PAGE : 488d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 489e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_PAGE; 490b9f9de93SJack Carter break; 491b9f9de93SJack Carter case MCSymbolRefExpr::VK_Mips_GOT_OFST : 492d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 493e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_OFST; 494b9f9de93SJack Carter break; 4955ddcfda8SJack Carter case MCSymbolRefExpr::VK_Mips_GOT_DISP : 496d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 497e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_DISP; 4985ddcfda8SJack Carter break; 499c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GPREL: 500c85e3ff3SBruno Cardoso Lopes FixupKind = Mips::fixup_Mips_GPREL16; 501c85e3ff3SBruno Cardoso Lopes break; 502c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOT_CALL: 503d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 504e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_CALL16; 505c85e3ff3SBruno Cardoso Lopes break; 50661e6d987SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOT16: 507d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 508e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_Global; 50961e6d987SBruno Cardoso Lopes break; 510c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOT: 511d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 512e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_GOT_Local; 513c85e3ff3SBruno Cardoso Lopes break; 514c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_ABS_HI: 515d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 516e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_HI16; 517c85e3ff3SBruno Cardoso Lopes break; 518c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_ABS_LO: 519d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 520e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_LO16; 521c85e3ff3SBruno Cardoso Lopes break; 522c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_TLSGD: 523d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 52469be811aSZoran Jovanovic : Mips::fixup_Mips_TLSGD; 525c85e3ff3SBruno Cardoso Lopes break; 526e2eed964SAkira Hatanaka case MCSymbolRefExpr::VK_Mips_TLSLDM: 527d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 52869be811aSZoran Jovanovic : Mips::fixup_Mips_TLSLDM; 529e2eed964SAkira Hatanaka break; 530e2eed964SAkira Hatanaka case MCSymbolRefExpr::VK_Mips_DTPREL_HI: 531d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 532e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_DTPREL_HI; 533e2eed964SAkira Hatanaka break; 534e2eed964SAkira Hatanaka case MCSymbolRefExpr::VK_Mips_DTPREL_LO: 535d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 536e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_DTPREL_LO; 537e2eed964SAkira Hatanaka break; 538c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_GOTTPREL: 539c85e3ff3SBruno Cardoso Lopes FixupKind = Mips::fixup_Mips_GOTTPREL; 540c85e3ff3SBruno Cardoso Lopes break; 541c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_TPREL_HI: 542d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 543e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_TPREL_HI; 544c85e3ff3SBruno Cardoso Lopes break; 545c85e3ff3SBruno Cardoso Lopes case MCSymbolRefExpr::VK_Mips_TPREL_LO: 546d2cca113SDavid Woodhouse FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 547e7ae8af8SZoran Jovanovic : Mips::fixup_Mips_TPREL_LO; 548c85e3ff3SBruno Cardoso Lopes break; 54984491abbSJack Carter case MCSymbolRefExpr::VK_Mips_HIGHER: 55084491abbSJack Carter FixupKind = Mips::fixup_Mips_HIGHER; 55184491abbSJack Carter break; 55284491abbSJack Carter case MCSymbolRefExpr::VK_Mips_HIGHEST: 55384491abbSJack Carter FixupKind = Mips::fixup_Mips_HIGHEST; 55484491abbSJack Carter break; 555b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_GOT_HI16: 556b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_GOT_HI16; 557b05cb67bSJack Carter break; 558b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_GOT_LO16: 559b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_GOT_LO16; 560b05cb67bSJack Carter break; 561b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_CALL_HI16: 562b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_CALL_HI16; 563b05cb67bSJack Carter break; 564b05cb67bSJack Carter case MCSymbolRefExpr::VK_Mips_CALL_LO16: 565b05cb67bSJack Carter FixupKind = Mips::fixup_Mips_CALL_LO16; 566b05cb67bSJack Carter break; 567b355e8f6SZoran Jovanovic case MCSymbolRefExpr::VK_Mips_PCREL_HI16: 568b355e8f6SZoran Jovanovic FixupKind = Mips::fixup_MIPS_PCHI16; 569b355e8f6SZoran Jovanovic break; 570b355e8f6SZoran Jovanovic case MCSymbolRefExpr::VK_Mips_PCREL_LO16: 571b355e8f6SZoran Jovanovic FixupKind = Mips::fixup_MIPS_PCLO16; 572b355e8f6SZoran Jovanovic break; 573c85e3ff3SBruno Cardoso Lopes } // switch 574fe384a2cSAkira Hatanaka 575b5cf5909SJack Carter Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind))); 576fe384a2cSAkira Hatanaka return 0; 577c85e3ff3SBruno Cardoso Lopes } 578b5cf5909SJack Carter return 0; 579b5cf5909SJack Carter } 580b5cf5909SJack Carter 581b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 582b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 583b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 584b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 5853fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5863fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 587b5cf5909SJack Carter if (MO.isReg()) { 588b5cf5909SJack Carter unsigned Reg = MO.getReg(); 589bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 590b5cf5909SJack Carter return RegNo; 591b5cf5909SJack Carter } else if (MO.isImm()) { 592b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 593b5cf5909SJack Carter } else if (MO.isFPImm()) { 594b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 595b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 596b5cf5909SJack Carter } 597b5cf5909SJack Carter // MO must be an Expr. 598b5cf5909SJack Carter assert(MO.isExpr()); 5993fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 600b5cf5909SJack Carter } 601c85e3ff3SBruno Cardoso Lopes 6026b59c449SMatheus Almeida /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST 6036b59c449SMatheus Almeida /// instructions. 6046b59c449SMatheus Almeida unsigned 6056b59c449SMatheus Almeida MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo, 6063fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 6073fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 6086b59c449SMatheus Almeida // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 6096b59c449SMatheus Almeida assert(MI.getOperand(OpNo).isReg()); 6103fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 6113fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 6126b59c449SMatheus Almeida 6136b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 6146b59c449SMatheus Almeida // be divided (when encoding) by the size (in bytes) of the instructions' 6156b59c449SMatheus Almeida // data format. 6166b59c449SMatheus Almeida // .b - 1 byte 6176b59c449SMatheus Almeida // .h - 2 bytes 6186b59c449SMatheus Almeida // .w - 4 bytes 6196b59c449SMatheus Almeida // .d - 8 bytes 6206b59c449SMatheus Almeida switch(MI.getOpcode()) 6216b59c449SMatheus Almeida { 6226b59c449SMatheus Almeida default: 6236b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 6246b59c449SMatheus Almeida break; 6256b59c449SMatheus Almeida case Mips::LD_B: 6266b59c449SMatheus Almeida case Mips::ST_B: 6276b59c449SMatheus Almeida // We don't need to scale the offset in this case 6286b59c449SMatheus Almeida break; 6296b59c449SMatheus Almeida case Mips::LD_H: 6306b59c449SMatheus Almeida case Mips::ST_H: 6316b59c449SMatheus Almeida OffBits >>= 1; 6326b59c449SMatheus Almeida break; 6336b59c449SMatheus Almeida case Mips::LD_W: 6346b59c449SMatheus Almeida case Mips::ST_W: 6356b59c449SMatheus Almeida OffBits >>= 2; 6366b59c449SMatheus Almeida break; 6376b59c449SMatheus Almeida case Mips::LD_D: 6386b59c449SMatheus Almeida case Mips::ST_D: 6396b59c449SMatheus Almeida OffBits >>= 3; 6406b59c449SMatheus Almeida break; 6416b59c449SMatheus Almeida } 6426b59c449SMatheus Almeida 6436b59c449SMatheus Almeida return (OffBits & 0xFFFF) | RegBits; 6446b59c449SMatheus Almeida } 6456b59c449SMatheus Almeida 646c85e3ff3SBruno Cardoso Lopes /// getMemEncoding - Return binary encoding of memory related operand. 647c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 648c85e3ff3SBruno Cardoso Lopes unsigned 649c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 6503fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 6513fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 652c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 653c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 6543fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 6553fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 656c85e3ff3SBruno Cardoso Lopes 657c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 658c85e3ff3SBruno Cardoso Lopes } 659c85e3ff3SBruno Cardoso Lopes 66097700977SJack Carter unsigned MipsMCCodeEmitter:: 661e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 662e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 663e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 664e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 665e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 666e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 667e8c9d1eaSJozef Kolek Fixups, STI) << 4; 668e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 669e8c9d1eaSJozef Kolek Fixups, STI); 670e8c9d1eaSJozef Kolek 671e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 672e8c9d1eaSJozef Kolek } 673e8c9d1eaSJozef Kolek 674e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 675e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 676e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 677e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 678e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 679e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 680e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 681e8c9d1eaSJozef Kolek Fixups, STI) << 4; 682e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 683e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 684e8c9d1eaSJozef Kolek 685e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 686e8c9d1eaSJozef Kolek } 687e8c9d1eaSJozef Kolek 688e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 689e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 690e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 691e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 692e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 693e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 694e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 695e8c9d1eaSJozef Kolek Fixups, STI) << 4; 696e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 697e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 698e8c9d1eaSJozef Kolek 699e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 700e8c9d1eaSJozef Kolek } 701e8c9d1eaSJozef Kolek 702e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 70312c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 70412c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 70512c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 70612c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 70712c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 70812c6982bSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::SP && 70912c6982bSJozef Kolek "Unexpected base register!"); 71012c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 71112c6982bSJozef Kolek Fixups, STI) >> 2; 71212c6982bSJozef Kolek 71312c6982bSJozef Kolek return OffBits & 0x1F; 71412c6982bSJozef Kolek } 71512c6982bSJozef Kolek 71612c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 71797700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 7183fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7193fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 720a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 721a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 722a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 723a4c4b5fcSZoran Jovanovic default: 724a4c4b5fcSZoran Jovanovic break; 725a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 726a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 727a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 728a4c4b5fcSZoran Jovanovic break; 729a4c4b5fcSZoran Jovanovic } 730a4c4b5fcSZoran Jovanovic 73197700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 73297700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 7333fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 7343fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 73597700977SJack Carter 73697700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 73797700977SJack Carter } 73897700977SJack Carter 739f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 740f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 741f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 742f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 743f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 744f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 745f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 746f9a02500SZoran Jovanovic default: 747f9a02500SZoran Jovanovic break; 748f9a02500SZoran Jovanovic case Mips::SWM16_MM: 749f9a02500SZoran Jovanovic case Mips::LWM16_MM: 750f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 751f9a02500SZoran Jovanovic break; 752f9a02500SZoran Jovanovic } 753f9a02500SZoran Jovanovic 754f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 755f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 756f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 757f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 758f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 759f9a02500SZoran Jovanovic 760f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 761f9a02500SZoran Jovanovic } 762f9a02500SZoran Jovanovic 763c85e3ff3SBruno Cardoso Lopes unsigned 764c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo, 7653fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7663fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 767049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 7683fa98a65SDavid Woodhouse unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 76956b70de0SBruno Cardoso Lopes return SizeEncoding - 1; 770c85e3ff3SBruno Cardoso Lopes } 771c85e3ff3SBruno Cardoso Lopes 772049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 773049e9e4dSAkira Hatanaka // 774c85e3ff3SBruno Cardoso Lopes unsigned 775c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 7763fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7773fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 778049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 779049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 7803fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 7813fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 782049e9e4dSAkira Hatanaka 78356b70de0SBruno Cardoso Lopes return Position + Size - 1; 784c85e3ff3SBruno Cardoso Lopes } 785c85e3ff3SBruno Cardoso Lopes 786779c5937SMatheus Almeida unsigned 787779c5937SMatheus Almeida MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, 7883fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7893fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 790779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 791779c5937SMatheus Almeida // The immediate is encoded as 'immediate - 1'. 7923fa98a65SDavid Woodhouse return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1; 793779c5937SMatheus Almeida } 794779c5937SMatheus Almeida 795b59e1a41SDaniel Sanders unsigned 796b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 797b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 798b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 799b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 800b9c07f3bSZoran Jovanovic if (MO.isImm()) { 801b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 802b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 803b59e1a41SDaniel Sanders assert((Res & 3) == 0); 804b59e1a41SDaniel Sanders return Res >> 2; 805b59e1a41SDaniel Sanders } 806c85e3ff3SBruno Cardoso Lopes 807b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 808b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 809b9c07f3bSZoran Jovanovic 810b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 811b9c07f3bSZoran Jovanovic Fixups.push_back(MCFixup::Create(0, Expr, 812b9c07f3bSZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC19_S2))); 813b9c07f3bSZoran Jovanovic return 0; 814b9c07f3bSZoran Jovanovic } 815b9c07f3bSZoran Jovanovic 8162855142aSZoran Jovanovic unsigned 8172855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 8182855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8192855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 820a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 821a5acdcf9SZoran Jovanovic if (MO.isImm()) { 8222855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 8232855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 8242855142aSZoran Jovanovic assert((Res & 7) == 0); 8252855142aSZoran Jovanovic return Res >> 3; 8262855142aSZoran Jovanovic } 8272855142aSZoran Jovanovic 828a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 829a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 830a5acdcf9SZoran Jovanovic 831a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 832a5acdcf9SZoran Jovanovic Fixups.push_back(MCFixup::Create(0, Expr, 833a5acdcf9SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC18_S3))); 834a5acdcf9SZoran Jovanovic return 0; 835a5acdcf9SZoran Jovanovic } 836a5acdcf9SZoran Jovanovic 8374a00fdc2SZoran Jovanovic unsigned 8384a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 8394a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8404a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 8414a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 8424a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 8434a00fdc2SZoran Jovanovic return MO.getImm() % 8; 8444a00fdc2SZoran Jovanovic } 8454a00fdc2SZoran Jovanovic 8468853171bSZoran Jovanovic unsigned 8478853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 8488853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8498853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 8508853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 8518853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 8528853171bSZoran Jovanovic unsigned Value = MO.getImm(); 8538853171bSZoran Jovanovic switch (Value) { 8548853171bSZoran Jovanovic case 128: return 0x0; 8558853171bSZoran Jovanovic case 1: return 0x1; 8568853171bSZoran Jovanovic case 2: return 0x2; 8578853171bSZoran Jovanovic case 3: return 0x3; 8588853171bSZoran Jovanovic case 4: return 0x4; 8598853171bSZoran Jovanovic case 7: return 0x5; 8608853171bSZoran Jovanovic case 8: return 0x6; 8618853171bSZoran Jovanovic case 15: return 0x7; 8628853171bSZoran Jovanovic case 16: return 0x8; 8638853171bSZoran Jovanovic case 31: return 0x9; 8648853171bSZoran Jovanovic case 32: return 0xa; 8658853171bSZoran Jovanovic case 63: return 0xb; 8668853171bSZoran Jovanovic case 64: return 0xc; 8678853171bSZoran Jovanovic case 255: return 0xd; 8688853171bSZoran Jovanovic case 32768: return 0xe; 8698853171bSZoran Jovanovic case 65535: return 0xf; 8708853171bSZoran Jovanovic } 8718853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 8728853171bSZoran Jovanovic } 8738853171bSZoran Jovanovic 874a4c4b5fcSZoran Jovanovic unsigned 875a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 876a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 877a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 878a4c4b5fcSZoran Jovanovic unsigned res = 0; 879a4c4b5fcSZoran Jovanovic 880a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 881a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 882a4c4b5fcSZoran Jovanovic 883a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 884a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 885a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 886a4c4b5fcSZoran Jovanovic if (RegNo != 31) 887a4c4b5fcSZoran Jovanovic res++; 888a4c4b5fcSZoran Jovanovic else 889a4c4b5fcSZoran Jovanovic res |= 0x10; 890a4c4b5fcSZoran Jovanovic } 891a4c4b5fcSZoran Jovanovic return res; 892a4c4b5fcSZoran Jovanovic } 893a4c4b5fcSZoran Jovanovic 894f9a02500SZoran Jovanovic unsigned 895f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 896f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 897f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 898f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 899f9a02500SZoran Jovanovic } 900f9a02500SZoran Jovanovic 9012deca348SZoran Jovanovic unsigned 9022deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 9032deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9042deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 9052deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 9062deca348SZoran Jovanovic } 9072deca348SZoran Jovanovic 908*2c6d7320SJozef Kolek unsigned 909*2c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 910*2c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 911*2c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 912*2c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 913*2c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 914*2c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 915*2c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 916*2c6d7320SJozef Kolek assert((Res & 3) == 0); 917*2c6d7320SJozef Kolek return Res >> 2; 918*2c6d7320SJozef Kolek } 919*2c6d7320SJozef Kolek 920b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 921