19f610119SJia Liu //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===// 2750ecec7SAkira Hatanaka // 3750ecec7SAkira Hatanaka // The LLVM Compiler Infrastructure 4750ecec7SAkira Hatanaka // 5750ecec7SAkira Hatanaka // This file is distributed under the University of Illinois Open Source 6750ecec7SAkira Hatanaka // License. See LICENSE.TXT for details. 7750ecec7SAkira Hatanaka // 8750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===// 9750ecec7SAkira Hatanaka // 10750ecec7SAkira Hatanaka // This file implements the MipsMCCodeEmitter class. 11750ecec7SAkira Hatanaka // 12750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===// 13750ecec7SAkira Hatanaka // 149e1450bcSMatheus Almeida 159e1450bcSMatheus Almeida #include "MipsMCCodeEmitter.h" 16c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsFixupKinds.h" 17a5da588bSPetar Jovanovic #include "MCTargetDesc/MipsMCExpr.h" 18c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsMCTargetDesc.h" 19c85e3ff3SBruno Cardoso Lopes #include "llvm/ADT/APFloat.h" 209e1450bcSMatheus Almeida #include "llvm/ADT/SmallVector.h" 215d6faed1SAkira Hatanaka #include "llvm/MC/MCContext.h" 22750ecec7SAkira Hatanaka #include "llvm/MC/MCExpr.h" 23d9903888SChandler Carruth #include "llvm/MC/MCFixup.h" 24750ecec7SAkira Hatanaka #include "llvm/MC/MCInst.h" 25750ecec7SAkira Hatanaka #include "llvm/MC/MCInstrInfo.h" 263de83e40SPete Cooper #include "llvm/MC/MCRegisterInfo.h" 27750ecec7SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h" 28750ecec7SAkira Hatanaka #include "llvm/Support/raw_ostream.h" 29750ecec7SAkira Hatanaka 3084e68b29SChandler Carruth #define DEBUG_TYPE "mccodeemitter" 3184e68b29SChandler Carruth 32be6a818fSAkira Hatanaka #define GET_INSTRMAP_INFO 33be6a818fSAkira Hatanaka #include "MipsGenInstrInfo.inc" 349e1450bcSMatheus Almeida #undef GET_INSTRMAP_INFO 35be6a818fSAkira Hatanaka 369e1450bcSMatheus Almeida namespace llvm { 379e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 38c3b04279SJim Grosbach const MCRegisterInfo &MRI, 399e1450bcSMatheus Almeida MCContext &Ctx) { 40d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, false); 411ee768dbSAkira Hatanaka } 421ee768dbSAkira Hatanaka 439e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 44c3b04279SJim Grosbach const MCRegisterInfo &MRI, 459e1450bcSMatheus Almeida MCContext &Ctx) { 46d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, true); 47750ecec7SAkira Hatanaka } 489e1450bcSMatheus Almeida } // End of namespace llvm. 49f30f2cceSRafael Espindola 50f30f2cceSRafael Espindola // If the D<shift> instruction has a shift amount that is greater 51f30f2cceSRafael Espindola // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 52f30f2cceSRafael Espindola static void LowerLargeShift(MCInst& Inst) { 53f30f2cceSRafael Espindola 54f30f2cceSRafael Espindola assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 55f30f2cceSRafael Espindola assert(Inst.getOperand(2).isImm()); 56f30f2cceSRafael Espindola 57f30f2cceSRafael Espindola int64_t Shift = Inst.getOperand(2).getImm(); 58f30f2cceSRafael Espindola if (Shift <= 31) 59f30f2cceSRafael Espindola return; // Do nothing 60f30f2cceSRafael Espindola Shift -= 32; 61f30f2cceSRafael Espindola 62f30f2cceSRafael Espindola // saminus32 63f30f2cceSRafael Espindola Inst.getOperand(2).setImm(Shift); 64f30f2cceSRafael Espindola 65f30f2cceSRafael Espindola switch (Inst.getOpcode()) { 66f30f2cceSRafael Espindola default: 67f30f2cceSRafael Espindola // Calling function is not synchronized 68f30f2cceSRafael Espindola llvm_unreachable("Unexpected shift instruction"); 69f30f2cceSRafael Espindola case Mips::DSLL: 70f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSLL32); 71f30f2cceSRafael Espindola return; 72f30f2cceSRafael Espindola case Mips::DSRL: 73f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRL32); 74f30f2cceSRafael Espindola return; 75f30f2cceSRafael Espindola case Mips::DSRA: 76f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRA32); 77f30f2cceSRafael Espindola return; 786a3fe574SAkira Hatanaka case Mips::DROTR: 796a3fe574SAkira Hatanaka Inst.setOpcode(Mips::DROTR32); 806a3fe574SAkira Hatanaka return; 81f30f2cceSRafael Espindola } 82f30f2cceSRafael Espindola } 83f30f2cceSRafael Espindola 84611eb829SDaniel Sanders // Pick a DINS instruction variant based on the pos and size operands 85611eb829SDaniel Sanders static void LowerDins(MCInst& InstIn) { 86f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 5 && 87f30f2cceSRafael Espindola "Invalid no. of machine operands for DINS!"); 88f30f2cceSRafael Espindola 89f30f2cceSRafael Espindola assert(InstIn.getOperand(2).isImm()); 90f30f2cceSRafael Espindola int64_t pos = InstIn.getOperand(2).getImm(); 91f30f2cceSRafael Espindola assert(InstIn.getOperand(3).isImm()); 92f30f2cceSRafael Espindola int64_t size = InstIn.getOperand(3).getImm(); 93f30f2cceSRafael Espindola 94f30f2cceSRafael Espindola if (size <= 32) { 95611eb829SDaniel Sanders if (pos < 32) // DINS, do nothing 96f30f2cceSRafael Espindola return; 97611eb829SDaniel Sanders // DINSU 98f30f2cceSRafael Espindola InstIn.getOperand(2).setImm(pos - 32); 99611eb829SDaniel Sanders InstIn.setOpcode(Mips::DINSU); 100f30f2cceSRafael Espindola return; 101f30f2cceSRafael Espindola } 102611eb829SDaniel Sanders // DINSM 103611eb829SDaniel Sanders assert(pos < 32 && "DINS cannot have both size and pos > 32"); 104f30f2cceSRafael Espindola InstIn.getOperand(3).setImm(size - 32); 105611eb829SDaniel Sanders InstIn.setOpcode(Mips::DINSM); 106f30f2cceSRafael Espindola return; 107f30f2cceSRafael Espindola } 108f30f2cceSRafael Espindola 109669d8dd8SSimon Dardis // Fix a bad compact branch encoding for beqc/bnec. 110669d8dd8SSimon Dardis void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { 111669d8dd8SSimon Dardis 112669d8dd8SSimon Dardis // Encoding may be illegal !(rs < rt), but this situation is 113669d8dd8SSimon Dardis // easily fixed. 114669d8dd8SSimon Dardis unsigned RegOp0 = Inst.getOperand(0).getReg(); 115669d8dd8SSimon Dardis unsigned RegOp1 = Inst.getOperand(1).getReg(); 116669d8dd8SSimon Dardis 117669d8dd8SSimon Dardis unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); 118669d8dd8SSimon Dardis unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); 119669d8dd8SSimon Dardis 120669d8dd8SSimon Dardis assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!"); 121669d8dd8SSimon Dardis if (Reg0 < Reg1) 122669d8dd8SSimon Dardis return; 123669d8dd8SSimon Dardis 124669d8dd8SSimon Dardis Inst.getOperand(0).setReg(RegOp1); 125669d8dd8SSimon Dardis Inst.getOperand(1).setReg(RegOp0); 126669d8dd8SSimon Dardis 127669d8dd8SSimon Dardis } 128669d8dd8SSimon Dardis 1299e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 130db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMicroMips]; 1319e1450bcSMatheus Almeida } 1329e1450bcSMatheus Almeida 133c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 134db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 135c22555d9SJozef Kolek } 136c22555d9SJozef Kolek 1379e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1389e1450bcSMatheus Almeida OS << (char)C; 1399e1450bcSMatheus Almeida } 1409e1450bcSMatheus Almeida 1419e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1429e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1439e1450bcSMatheus Almeida raw_ostream &OS) const { 1449e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1459e1450bcSMatheus Almeida // Little-endian byte ordering: 1469e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1479e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1489e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1499e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1509e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1519e1450bcSMatheus Almeida } else { 1529e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1539e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1549e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1559e1450bcSMatheus Almeida } 1569e1450bcSMatheus Almeida } 1579e1450bcSMatheus Almeida } 1589e1450bcSMatheus Almeida 15991df21f7SJim Grosbach /// encodeInstruction - Emit the instruction. 1604e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 161c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 16291df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS, 1639784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1649784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 165c85e3ff3SBruno Cardoso Lopes { 166aa7aeaa0SJack Carter 167aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 168aa7aeaa0SJack Carter // only based on operand values. 169aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 170aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 171aa7aeaa0SJack Carter MCInst TmpInst = MI; 172aa7aeaa0SJack Carter switch (MI.getOpcode()) { 173aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 174aa7aeaa0SJack Carter case Mips::DSLL: 175aa7aeaa0SJack Carter case Mips::DSRL: 176aa7aeaa0SJack Carter case Mips::DSRA: 1776a3fe574SAkira Hatanaka case Mips::DROTR: 178f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 179aa7aeaa0SJack Carter break; 180aa7aeaa0SJack Carter // Double extract instruction is chosen by pos and size operands 181aa7aeaa0SJack Carter case Mips::DINS: 182611eb829SDaniel Sanders LowerDins(TmpInst); 183669d8dd8SSimon Dardis break; 184669d8dd8SSimon Dardis // Compact branches. 185669d8dd8SSimon Dardis case Mips::BEQC: 186669d8dd8SSimon Dardis case Mips::BNEC: 187669d8dd8SSimon Dardis LowerCompactBranch(TmpInst); 188aa7aeaa0SJack Carter } 189aa7aeaa0SJack Carter 19097700977SJack Carter unsigned long N = Fixups.size(); 1913fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 192c85e3ff3SBruno Cardoso Lopes 193c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 194aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 195c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 196aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 197c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 198c7e220f6SJozef Kolek (Opcode != Mips::SLL_MM) && !Binary) 19991df21f7SJim Grosbach llvm_unreachable("unimplemented opcode in encodeInstruction()"); 200c85e3ff3SBruno Cardoso Lopes 201b59a5419SZoran Jovanovic int NewOpcode = -1; 2026ca13eafSJozef Kolek if (isMicroMips(STI)) { 203b59a5419SZoran Jovanovic if (isMips32r6(STI)) { 204b59a5419SZoran Jovanovic NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 205b59a5419SZoran Jovanovic if (NewOpcode == -1) 206b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 207b59a5419SZoran Jovanovic } 208b59a5419SZoran Jovanovic else 209b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 210b59a5419SZoran Jovanovic 2112e386d3dSZoran Jovanovic // Check whether it is Dsp instruction. 2122e386d3dSZoran Jovanovic if (NewOpcode == -1) 2132e386d3dSZoran Jovanovic NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 2142e386d3dSZoran Jovanovic 215be6a818fSAkira Hatanaka if (NewOpcode != -1) { 21697700977SJack Carter if (Fixups.size() > N) 21797700977SJack Carter Fixups.pop_back(); 218b59a5419SZoran Jovanovic 219be6a818fSAkira Hatanaka Opcode = NewOpcode; 220be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 2213fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 222be6a818fSAkira Hatanaka } 223be6a818fSAkira Hatanaka } 224be6a818fSAkira Hatanaka 225aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 226c85e3ff3SBruno Cardoso Lopes 2275b5559d3SJack Carter // Get byte count of instruction 2285b5559d3SJack Carter unsigned Size = Desc.getSize(); 2295b5559d3SJack Carter if (!Size) 2305b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 231c85e3ff3SBruno Cardoso Lopes 232d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 233c85e3ff3SBruno Cardoso Lopes } 234c85e3ff3SBruno Cardoso Lopes 235c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 236c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 237c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 238c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 239c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2403fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2413fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 242c85e3ff3SBruno Cardoso Lopes 243c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 24471e6a749SJack Carter 2454f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2464f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2474f69a0f2SJack Carter 24871e6a749SJack Carter assert(MO.isExpr() && 24971e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 250c85e3ff3SBruno Cardoso Lopes 251b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 252b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 253b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 254c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 255c85e3ff3SBruno Cardoso Lopes return 0; 256c85e3ff3SBruno Cardoso Lopes } 257c85e3ff3SBruno Cardoso Lopes 2586f09cdfdSHrvoje Varga /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 2596f09cdfdSHrvoje Varga /// target operand. If the machine operand requires relocation, 2606f09cdfdSHrvoje Varga /// record the relocation and return zero. 2616f09cdfdSHrvoje Varga unsigned MipsMCCodeEmitter:: 2626f09cdfdSHrvoje Varga getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 2636f09cdfdSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 2646f09cdfdSHrvoje Varga const MCSubtargetInfo &STI) const { 2656f09cdfdSHrvoje Varga 2666f09cdfdSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 2676f09cdfdSHrvoje Varga 2686f09cdfdSHrvoje Varga // If the destination is an immediate, divide by 2. 2696f09cdfdSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 1; 2706f09cdfdSHrvoje Varga 2716f09cdfdSHrvoje Varga assert(MO.isExpr() && 2726f09cdfdSHrvoje Varga "getBranchTargetOpValue expects only expressions or immediates"); 2736f09cdfdSHrvoje Varga 2746f09cdfdSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 2756f09cdfdSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 2766f09cdfdSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 2776f09cdfdSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 2786f09cdfdSHrvoje Varga return 0; 2796f09cdfdSHrvoje Varga } 2806f09cdfdSHrvoje Varga 2819761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 2829761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 2839761e96bSJozef Kolek /// record the relocation and return zero. 2849761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 2859761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 2869761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 2879761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 2889761e96bSJozef Kolek 2899761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 2909761e96bSJozef Kolek 2919761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 2929761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 2939761e96bSJozef Kolek 2949761e96bSJozef Kolek assert(MO.isExpr() && 2959761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 2969761e96bSJozef Kolek 2979761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 29863661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 2999761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 3009761e96bSJozef Kolek return 0; 3019761e96bSJozef Kolek } 3029761e96bSJozef Kolek 3035cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 3045cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 3055cfebddeSJozef Kolek /// record the relocation and return zero. 3065cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 3075cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 3085cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3095cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 3105cfebddeSJozef Kolek 3115cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3125cfebddeSJozef Kolek 3135cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 3145cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3155cfebddeSJozef Kolek 3165cfebddeSJozef Kolek assert(MO.isExpr() && 3175cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 3185cfebddeSJozef Kolek 3195cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 32063661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3215cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 3225cfebddeSJozef Kolek return 0; 3235cfebddeSJozef Kolek } 3245cfebddeSJozef Kolek 3258a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 3268a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 3278a80aa76SZoran Jovanovic /// record the relocation and return zero. 3288a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 3298a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 3303fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3313fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 3328a80aa76SZoran Jovanovic 3338a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3348a80aa76SZoran Jovanovic 3358a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 3368a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 3378a80aa76SZoran Jovanovic 3388a80aa76SZoran Jovanovic assert(MO.isExpr() && 3398a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 3408a80aa76SZoran Jovanovic 3418a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 34263661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3438a80aa76SZoran Jovanovic MCFixupKind(Mips:: 3448a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 3458a80aa76SZoran Jovanovic return 0; 3468a80aa76SZoran Jovanovic } 3478a80aa76SZoran Jovanovic 3483c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 3493c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3503c8869dcSZoran Jovanovic /// record the relocation and return zero. 3513c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3523c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 3533c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 3543c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 3553c8869dcSZoran Jovanovic 3563c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3573c8869dcSZoran Jovanovic 3583c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3593c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3603c8869dcSZoran Jovanovic 3613c8869dcSZoran Jovanovic assert(MO.isExpr() && 3623c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 3633c8869dcSZoran Jovanovic 364b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 365b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 366b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 36710e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 3683c8869dcSZoran Jovanovic return 0; 3693c8869dcSZoran Jovanovic } 3703c8869dcSZoran Jovanovic 37184e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch 37284e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires 37384e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero. 37484e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter:: 37584e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 37684e4d59eSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 37784e4d59eSZoran Jovanovic const MCSubtargetInfo &STI) const { 37884e4d59eSZoran Jovanovic 37984e4d59eSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 38084e4d59eSZoran Jovanovic 38184e4d59eSZoran Jovanovic // If the destination is an immediate, divide by 2. 38284e4d59eSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 38384e4d59eSZoran Jovanovic 38484e4d59eSZoran Jovanovic assert(MO.isExpr() && 38584e4d59eSZoran Jovanovic "getBranchTarget21OpValueMM expects only expressions or immediates"); 38684e4d59eSZoran Jovanovic 387*5f94cedeSZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 388*5f94cedeSZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 389*5f94cedeSZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 390*5f94cedeSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 39184e4d59eSZoran Jovanovic return 0; 39284e4d59eSZoran Jovanovic } 39384e4d59eSZoran Jovanovic 3943c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 3953c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3963c8869dcSZoran Jovanovic /// record the relocation and return zero. 3973c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3983c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 3993c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4003c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4013c8869dcSZoran Jovanovic 4023c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4033c8869dcSZoran Jovanovic 4043c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4053c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4063c8869dcSZoran Jovanovic 4073c8869dcSZoran Jovanovic assert(MO.isExpr() && 4083c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 4093c8869dcSZoran Jovanovic 410b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 411b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 412b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 41310e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 4143c8869dcSZoran Jovanovic return 0; 4153c8869dcSZoran Jovanovic } 4163c8869dcSZoran Jovanovic 417a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 418a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 419a887b361SZoran Jovanovic /// record the relocation and return zero. 420a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 421a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 422a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 423a887b361SZoran Jovanovic 424a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 425a887b361SZoran Jovanovic 426a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 427a887b361SZoran Jovanovic if (MO.isImm()) 428a887b361SZoran Jovanovic return MO.getImm() >> 1; 429a887b361SZoran Jovanovic 43002b70030SZoran Jovanovic assert(MO.isExpr() && 43102b70030SZoran Jovanovic "getBranchTarget26OpValueMM expects only expressions or immediates"); 43202b70030SZoran Jovanovic 43302b70030SZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 43402b70030SZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 43502b70030SZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 43602b70030SZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 437a887b361SZoran Jovanovic return 0; 438a887b361SZoran Jovanovic } 439a887b361SZoran Jovanovic 44052c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 44152c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 44252c56b93SZoran Jovanovic /// record the relocation and return zero. 44352c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 44452c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 44552c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 44652c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 44752c56b93SZoran Jovanovic 44852c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 44952c56b93SZoran Jovanovic 45052c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 45152c56b93SZoran Jovanovic 45252c56b93SZoran Jovanovic assert(MO.isExpr() && 45352c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 45452c56b93SZoran Jovanovic 45552c56b93SZoran Jovanovic // TODO: Push fixup. 45652c56b93SZoran Jovanovic return 0; 45752c56b93SZoran Jovanovic } 45852c56b93SZoran Jovanovic 459c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 460c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 461c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 462c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 463c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 4643fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4653fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 466c85e3ff3SBruno Cardoso Lopes 467c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 4684f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 4694f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 4704f69a0f2SJack Carter 47171e6a749SJack Carter assert(MO.isExpr() && 47271e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 473c85e3ff3SBruno Cardoso Lopes 474c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 47563661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 476c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 477c85e3ff3SBruno Cardoso Lopes return 0; 478c85e3ff3SBruno Cardoso Lopes } 479c85e3ff3SBruno Cardoso Lopes 480c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 481507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 4823fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4833fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 484507e084aSZoran Jovanovic 485507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 486507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 487507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 488507e084aSZoran Jovanovic 489507e084aSZoran Jovanovic assert(MO.isExpr() && 490507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 491507e084aSZoran Jovanovic 492507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 49363661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 494507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 495507e084aSZoran Jovanovic return 0; 496507e084aSZoran Jovanovic } 497507e084aSZoran Jovanovic 498507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 499c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 500c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 501c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 502c74e3eb9SZoran Jovanovic 503c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 504c74e3eb9SZoran Jovanovic if (MO.isImm()) { 505c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 506c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 507c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 508c74e3eb9SZoran Jovanovic return Res >> 2; 509c74e3eb9SZoran Jovanovic } 510c74e3eb9SZoran Jovanovic 511c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 512c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 513c74e3eb9SZoran Jovanovic 514c74e3eb9SZoran Jovanovic return 0; 515c74e3eb9SZoran Jovanovic } 516c74e3eb9SZoran Jovanovic 517c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 518bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 519bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 520bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 521bac3619bSZoran Jovanovic 522bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 523bac3619bSZoran Jovanovic if (MO.isImm()) { 524bac3619bSZoran Jovanovic int Value = MO.getImm(); 525bac3619bSZoran Jovanovic return Value >> 2; 526bac3619bSZoran Jovanovic } 527bac3619bSZoran Jovanovic 528bac3619bSZoran Jovanovic return 0; 529bac3619bSZoran Jovanovic } 530bac3619bSZoran Jovanovic 531bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 53242b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 53342b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 53442b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 53542b84443SZoran Jovanovic 53642b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 53742b84443SZoran Jovanovic if (MO.isImm()) { 53842b84443SZoran Jovanovic unsigned Value = MO.getImm(); 53942b84443SZoran Jovanovic return Value >> 2; 54042b84443SZoran Jovanovic } 54142b84443SZoran Jovanovic 54242b84443SZoran Jovanovic return 0; 54342b84443SZoran Jovanovic } 54442b84443SZoran Jovanovic 54542b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 54698bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 54798bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 54898bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 54998bd58caSZoran Jovanovic 55098bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 55198bd58caSZoran Jovanovic if (MO.isImm()) { 55298bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 55398bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 55498bd58caSZoran Jovanovic } 55598bd58caSZoran Jovanovic 55698bd58caSZoran Jovanovic return 0; 55798bd58caSZoran Jovanovic } 55898bd58caSZoran Jovanovic 55998bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 5603fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 5613fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 562b5cf5909SJack Carter int64_t Res; 563049e9e4dSAkira Hatanaka 56413760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 565b5cf5909SJack Carter return Res; 566fe384a2cSAkira Hatanaka 567fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 568b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 569b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 570b5cf5909SJack Carter } 571fe384a2cSAkira Hatanaka 572fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 5733fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 5743fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 575b5cf5909SJack Carter return Res; 576fe384a2cSAkira Hatanaka } 577a5da588bSPetar Jovanovic 578a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 579a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 580a5da588bSPetar Jovanovic 581a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 582a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 583fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_NEG: 584fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_None: 585fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_Special: 586fe98b2f5SDaniel Sanders llvm_unreachable("Unhandled fixup kind!"); 587fe98b2f5SDaniel Sanders break; 588fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_HI16: 589fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_HI16; 590fe98b2f5SDaniel Sanders break; 591fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_LO16: 592fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_LO16; 593fe98b2f5SDaniel Sanders break; 594fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_HI: 595fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 596fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_HI; 597fe98b2f5SDaniel Sanders break; 598fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_LO: 599fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 600fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_LO; 601fe98b2f5SDaniel Sanders break; 602fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOTTPREL: 603fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOTTPREL; 604fe98b2f5SDaniel Sanders break; 605fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT: 606fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 607fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT; 608fe98b2f5SDaniel Sanders break; 609fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_CALL: 610fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 611fe98b2f5SDaniel Sanders : Mips::fixup_Mips_CALL16; 612fe98b2f5SDaniel Sanders break; 613fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_DISP: 614fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 615fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_DISP; 616fe98b2f5SDaniel Sanders break; 617fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_HI16: 618fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_HI16; 619fe98b2f5SDaniel Sanders break; 620fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_LO16: 621fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_LO16; 622fe98b2f5SDaniel Sanders break; 623fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_PAGE: 624fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 625fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_PAGE; 626fe98b2f5SDaniel Sanders break; 627fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_OFST: 628fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 629fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_OFST; 630fe98b2f5SDaniel Sanders break; 631fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GPREL: 632fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPREL16; 633fe98b2f5SDaniel Sanders break; 634fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_LO: { 635fe98b2f5SDaniel Sanders // Check for %lo(%neg(%gp_rel(X))) 636fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 637fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_LO; 638fe98b2f5SDaniel Sanders break; 639fe98b2f5SDaniel Sanders } 640fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 641fe98b2f5SDaniel Sanders : Mips::fixup_Mips_LO16; 642fe98b2f5SDaniel Sanders break; 643fe98b2f5SDaniel Sanders } 644fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHEST: 64506c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 64606c47803SSasa Stankovic break; 647fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHER: 64806c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 64906c47803SSasa Stankovic break; 650fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HI: 651fe98b2f5SDaniel Sanders // Check for %hi(%neg(%gp_rel(X))) 652fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 653fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_HI; 654fe98b2f5SDaniel Sanders break; 655fe98b2f5SDaniel Sanders } 656a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 657a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 658a5da588bSPetar Jovanovic break; 659fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_HI16: 660fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCHI16; 661fe98b2f5SDaniel Sanders break; 662fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_LO16: 663fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCLO16; 664fe98b2f5SDaniel Sanders break; 665fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSGD: 666fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 667fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSGD; 668fe98b2f5SDaniel Sanders break; 669fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSLDM: 670fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 671fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSLDM; 672fe98b2f5SDaniel Sanders break; 673fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_HI: 674fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 675fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_HI; 676fe98b2f5SDaniel Sanders break; 677fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_LO: 678fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 679fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_LO; 680a5da588bSPetar Jovanovic break; 681a5da588bSPetar Jovanovic } 68263661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 683a5da588bSPetar Jovanovic return 0; 684a5da588bSPetar Jovanovic } 685a5da588bSPetar Jovanovic 686b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 687f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 688e2eed964SAkira Hatanaka 689049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 690b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 69160f1db05SDaniel Sanders break; 69260f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 69360f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 694b9f9de93SJack Carter break; 695c85e3ff3SBruno Cardoso Lopes } // switch 696fe384a2cSAkira Hatanaka 69763661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 698fe384a2cSAkira Hatanaka return 0; 699c85e3ff3SBruno Cardoso Lopes } 700b5cf5909SJack Carter return 0; 701b5cf5909SJack Carter } 702b5cf5909SJack Carter 703b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 704b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 705b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 706b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 7073fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7083fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 709b5cf5909SJack Carter if (MO.isReg()) { 710b5cf5909SJack Carter unsigned Reg = MO.getReg(); 711bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 712b5cf5909SJack Carter return RegNo; 713b5cf5909SJack Carter } else if (MO.isImm()) { 714b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 715b5cf5909SJack Carter } else if (MO.isFPImm()) { 716b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 717b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 718b5cf5909SJack Carter } 719b5cf5909SJack Carter // MO must be an Expr. 720b5cf5909SJack Carter assert(MO.isExpr()); 7213fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 722b5cf5909SJack Carter } 723c85e3ff3SBruno Cardoso Lopes 724dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand. 725c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 726dc0602a2SDaniel Sanders template <unsigned ShiftAmount> 727dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 7283fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7293fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 730c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 731c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 7323fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 7333fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 734c85e3ff3SBruno Cardoso Lopes 735dc0602a2SDaniel Sanders // Apply the scale factor if there is one. 736dc0602a2SDaniel Sanders OffBits >>= ShiftAmount; 737dc0602a2SDaniel Sanders 738c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 739c85e3ff3SBruno Cardoso Lopes } 740c85e3ff3SBruno Cardoso Lopes 74197700977SJack Carter unsigned MipsMCCodeEmitter:: 742e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 743e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 744e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 745e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 746e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 747e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 748e8c9d1eaSJozef Kolek Fixups, STI) << 4; 749e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 750e8c9d1eaSJozef Kolek Fixups, STI); 751e8c9d1eaSJozef Kolek 752e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 753e8c9d1eaSJozef Kolek } 754e8c9d1eaSJozef Kolek 755e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 756e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 757e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 758e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 759e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 760e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 761e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 762e8c9d1eaSJozef Kolek Fixups, STI) << 4; 763e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 764e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 765e8c9d1eaSJozef Kolek 766e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 767e8c9d1eaSJozef Kolek } 768e8c9d1eaSJozef Kolek 769e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 770e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 771e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 772e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 773e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 774e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 775e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 776e8c9d1eaSJozef Kolek Fixups, STI) << 4; 777e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 778e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 779e8c9d1eaSJozef Kolek 780e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 781e8c9d1eaSJozef Kolek } 782e8c9d1eaSJozef Kolek 783e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 78412c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 78512c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 78612c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 78712c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 78812c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 78968be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 79068be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 79112c6982bSJozef Kolek "Unexpected base register!"); 79212c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 79312c6982bSJozef Kolek Fixups, STI) >> 2; 79412c6982bSJozef Kolek 79512c6982bSJozef Kolek return OffBits & 0x1F; 79612c6982bSJozef Kolek } 79712c6982bSJozef Kolek 79812c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 799e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 800e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 801e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 802e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 803e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 804e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 805e10a02ecSJozef Kolek "Unexpected base register!"); 806e10a02ecSJozef Kolek 807e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 808e10a02ecSJozef Kolek Fixups, STI) >> 2; 809e10a02ecSJozef Kolek 810e10a02ecSJozef Kolek return OffBits & 0x7F; 811e10a02ecSJozef Kolek } 812e10a02ecSJozef Kolek 8139eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 8149eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 8159eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8169eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 8179eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 8189eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 8199eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8209eaa30d2SZoran Jovanovic STI) << 16; 8219eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 8229eaa30d2SZoran Jovanovic 8239eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 8249eaa30d2SZoran Jovanovic } 8259eaa30d2SZoran Jovanovic 826e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 82797700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 8283fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8293fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 830a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 831a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 832a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 833a4c4b5fcSZoran Jovanovic default: 834a4c4b5fcSZoran Jovanovic break; 835a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 836a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 837a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 838a4c4b5fcSZoran Jovanovic break; 839a4c4b5fcSZoran Jovanovic } 840a4c4b5fcSZoran Jovanovic 84197700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 84297700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 8433fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 8443fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 84597700977SJack Carter 84697700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 8473c88fbd3SHrvoje Varga } 8483c88fbd3SHrvoje Varga 8493c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 8503c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 8513c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 8523c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 8533c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 8543c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 8553c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8563c88fbd3SHrvoje Varga STI) << 16; 8573c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 8583c88fbd3SHrvoje Varga 8593c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 86097700977SJack Carter } 86197700977SJack Carter 862f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 863f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 864f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 865f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 866f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 867f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 868f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 869f9a02500SZoran Jovanovic default: 870f9a02500SZoran Jovanovic break; 871f9a02500SZoran Jovanovic case Mips::SWM16_MM: 872797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 873f9a02500SZoran Jovanovic case Mips::LWM16_MM: 874797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 875f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 876f9a02500SZoran Jovanovic break; 877f9a02500SZoran Jovanovic } 878f9a02500SZoran Jovanovic 879f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 880f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 881f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 882f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 883f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 884f9a02500SZoran Jovanovic 885f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 886f9a02500SZoran Jovanovic } 887f9a02500SZoran Jovanovic 888049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 889049e9e4dSAkira Hatanaka // 890c85e3ff3SBruno Cardoso Lopes unsigned 891c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 8923fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8933fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 894049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 895049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 8963fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 8973fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 898049e9e4dSAkira Hatanaka 89956b70de0SBruno Cardoso Lopes return Position + Size - 1; 900c85e3ff3SBruno Cardoso Lopes } 901c85e3ff3SBruno Cardoso Lopes 902ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 903779c5937SMatheus Almeida unsigned 904ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 9053fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9063fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 907779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 908ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 909ea4f653dSDaniel Sanders Value -= Offset; 910ea4f653dSDaniel Sanders return Value; 911779c5937SMatheus Almeida } 912779c5937SMatheus Almeida 913b59e1a41SDaniel Sanders unsigned 914b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 915b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 916b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 917b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 918b9c07f3bSZoran Jovanovic if (MO.isImm()) { 919b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 920b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 921b59e1a41SDaniel Sanders assert((Res & 3) == 0); 922b59e1a41SDaniel Sanders return Res >> 2; 923b59e1a41SDaniel Sanders } 924c85e3ff3SBruno Cardoso Lopes 925b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 926b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 927b9c07f3bSZoran Jovanovic 928b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9296764fa78SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 9306764fa78SZoran Jovanovic : Mips::fixup_MIPS_PC19_S2; 9316764fa78SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 932b9c07f3bSZoran Jovanovic return 0; 933b9c07f3bSZoran Jovanovic } 934b9c07f3bSZoran Jovanovic 9352855142aSZoran Jovanovic unsigned 9362855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 9372855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9382855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 939a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 940a5acdcf9SZoran Jovanovic if (MO.isImm()) { 9412855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 9422855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 9432855142aSZoran Jovanovic assert((Res & 7) == 0); 9442855142aSZoran Jovanovic return Res >> 3; 9452855142aSZoran Jovanovic } 9462855142aSZoran Jovanovic 947a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 948a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 949a5acdcf9SZoran Jovanovic 950a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9518e366822SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 9528e366822SZoran Jovanovic : Mips::fixup_MIPS_PC18_S3; 9538e366822SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 954a5acdcf9SZoran Jovanovic return 0; 955a5acdcf9SZoran Jovanovic } 956a5acdcf9SZoran Jovanovic 9574a00fdc2SZoran Jovanovic unsigned 9584a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 9594a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9604a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 9614a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 9624a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 9634a00fdc2SZoran Jovanovic return MO.getImm() % 8; 9644a00fdc2SZoran Jovanovic } 9654a00fdc2SZoran Jovanovic 9668853171bSZoran Jovanovic unsigned 9678853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 9688853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9698853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 9708853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 9718853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 9728853171bSZoran Jovanovic unsigned Value = MO.getImm(); 9738853171bSZoran Jovanovic switch (Value) { 9748853171bSZoran Jovanovic case 128: return 0x0; 9758853171bSZoran Jovanovic case 1: return 0x1; 9768853171bSZoran Jovanovic case 2: return 0x2; 9778853171bSZoran Jovanovic case 3: return 0x3; 9788853171bSZoran Jovanovic case 4: return 0x4; 9798853171bSZoran Jovanovic case 7: return 0x5; 9808853171bSZoran Jovanovic case 8: return 0x6; 9818853171bSZoran Jovanovic case 15: return 0x7; 9828853171bSZoran Jovanovic case 16: return 0x8; 9838853171bSZoran Jovanovic case 31: return 0x9; 9848853171bSZoran Jovanovic case 32: return 0xa; 9858853171bSZoran Jovanovic case 63: return 0xb; 9868853171bSZoran Jovanovic case 64: return 0xc; 9878853171bSZoran Jovanovic case 255: return 0xd; 9888853171bSZoran Jovanovic case 32768: return 0xe; 9898853171bSZoran Jovanovic case 65535: return 0xf; 9908853171bSZoran Jovanovic } 9918853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 9928853171bSZoran Jovanovic } 9938853171bSZoran Jovanovic 994a4c4b5fcSZoran Jovanovic unsigned 995a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 996a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 997a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 998a4c4b5fcSZoran Jovanovic unsigned res = 0; 999a4c4b5fcSZoran Jovanovic 1000a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 1001a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 1002a4c4b5fcSZoran Jovanovic 1003a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1004a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 1005a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1006a4c4b5fcSZoran Jovanovic if (RegNo != 31) 1007a4c4b5fcSZoran Jovanovic res++; 1008a4c4b5fcSZoran Jovanovic else 1009a4c4b5fcSZoran Jovanovic res |= 0x10; 1010a4c4b5fcSZoran Jovanovic } 1011a4c4b5fcSZoran Jovanovic return res; 1012a4c4b5fcSZoran Jovanovic } 1013a4c4b5fcSZoran Jovanovic 1014f9a02500SZoran Jovanovic unsigned 1015f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1016f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1017f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 1018f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 1019f9a02500SZoran Jovanovic } 1020f9a02500SZoran Jovanovic 10212deca348SZoran Jovanovic unsigned 10222deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 10232deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10242deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 10252deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 10262deca348SZoran Jovanovic } 10272deca348SZoran Jovanovic 10282c6d7320SJozef Kolek unsigned 102941688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 103041688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 103141688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 103241688679SZoran Jovanovic unsigned res = 0; 103341688679SZoran Jovanovic 103441688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 103541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 103641688679SZoran Jovanovic res = 0; 103741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 103841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 103941688679SZoran Jovanovic res = 1; 104041688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 104141688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 104241688679SZoran Jovanovic res = 2; 104341688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 104441688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 104541688679SZoran Jovanovic res = 3; 104641688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 104741688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 104841688679SZoran Jovanovic res = 4; 104941688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 105041688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 105141688679SZoran Jovanovic res = 5; 105241688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 105341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 105441688679SZoran Jovanovic res = 6; 105541688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 105641688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 105741688679SZoran Jovanovic res = 7; 105841688679SZoran Jovanovic 105941688679SZoran Jovanovic return res; 106041688679SZoran Jovanovic } 106141688679SZoran Jovanovic 106241688679SZoran Jovanovic unsigned 10632c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 10642c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 10652c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 10662c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 10672c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 10682c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 10692c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 10702c6d7320SJozef Kolek assert((Res & 3) == 0); 10712c6d7320SJozef Kolek return Res >> 2; 10722c6d7320SJozef Kolek } 10732c6d7320SJozef Kolek 1074b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1075