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; 81f1e0a03dSHrvoje Varga case Mips::DSLL_MM64R6: 82f1e0a03dSHrvoje Varga Inst.setOpcode(Mips::DSLL32_MM64R6); 83f1e0a03dSHrvoje Varga return; 8424b975dcSHrvoje Varga case Mips::DSRL_MM64R6: 8524b975dcSHrvoje Varga Inst.setOpcode(Mips::DSRL32_MM64R6); 8624b975dcSHrvoje Varga return; 87f1e0a03dSHrvoje Varga case Mips::DSRA_MM64R6: 88f1e0a03dSHrvoje Varga Inst.setOpcode(Mips::DSRA32_MM64R6); 89f1e0a03dSHrvoje Varga return; 90f1e0a03dSHrvoje Varga case Mips::DROTR_MM64R6: 91f1e0a03dSHrvoje Varga Inst.setOpcode(Mips::DROTR32_MM64R6); 92f1e0a03dSHrvoje Varga return; 93f30f2cceSRafael Espindola } 94f30f2cceSRafael Espindola } 95f30f2cceSRafael Espindola 96611eb829SDaniel Sanders // Pick a DINS instruction variant based on the pos and size operands 97611eb829SDaniel Sanders static void LowerDins(MCInst& InstIn) { 98f30f2cceSRafael Espindola assert(InstIn.getNumOperands() == 5 && 99f30f2cceSRafael Espindola "Invalid no. of machine operands for DINS!"); 100f30f2cceSRafael Espindola 101f30f2cceSRafael Espindola assert(InstIn.getOperand(2).isImm()); 102f30f2cceSRafael Espindola int64_t pos = InstIn.getOperand(2).getImm(); 103f30f2cceSRafael Espindola assert(InstIn.getOperand(3).isImm()); 104f30f2cceSRafael Espindola int64_t size = InstIn.getOperand(3).getImm(); 105f30f2cceSRafael Espindola 106f30f2cceSRafael Espindola if (size <= 32) { 107611eb829SDaniel Sanders if (pos < 32) // DINS, do nothing 108f30f2cceSRafael Espindola return; 109611eb829SDaniel Sanders // DINSU 110f30f2cceSRafael Espindola InstIn.getOperand(2).setImm(pos - 32); 111611eb829SDaniel Sanders InstIn.setOpcode(Mips::DINSU); 112f30f2cceSRafael Espindola return; 113f30f2cceSRafael Espindola } 114611eb829SDaniel Sanders // DINSM 115611eb829SDaniel Sanders assert(pos < 32 && "DINS cannot have both size and pos > 32"); 116f30f2cceSRafael Espindola InstIn.getOperand(3).setImm(size - 32); 117611eb829SDaniel Sanders InstIn.setOpcode(Mips::DINSM); 118f30f2cceSRafael Espindola return; 119f30f2cceSRafael Espindola } 120f30f2cceSRafael Espindola 121669d8dd8SSimon Dardis // Fix a bad compact branch encoding for beqc/bnec. 122669d8dd8SSimon Dardis void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { 123669d8dd8SSimon Dardis 124669d8dd8SSimon Dardis // Encoding may be illegal !(rs < rt), but this situation is 125669d8dd8SSimon Dardis // easily fixed. 126669d8dd8SSimon Dardis unsigned RegOp0 = Inst.getOperand(0).getReg(); 127669d8dd8SSimon Dardis unsigned RegOp1 = Inst.getOperand(1).getReg(); 128669d8dd8SSimon Dardis 129669d8dd8SSimon Dardis unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); 130669d8dd8SSimon Dardis unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); 131669d8dd8SSimon Dardis 132*68a204ddSSimon Dardis if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC || 133*68a204ddSSimon Dardis Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) { 134669d8dd8SSimon Dardis assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!"); 135669d8dd8SSimon Dardis if (Reg0 < Reg1) 136669d8dd8SSimon Dardis return; 137b60833c0SSimon Dardis } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) { 138b60833c0SSimon Dardis if (Reg0 >= Reg1) 139b60833c0SSimon Dardis return; 140c962c493SHrvoje Varga } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || 141c962c493SHrvoje Varga Inst.getOpcode() == Mips::BOVC_MMR6) { 142c962c493SHrvoje Varga if (Reg1 >= Reg0) 143c962c493SHrvoje Varga return; 144b60833c0SSimon Dardis } else 145b60833c0SSimon Dardis llvm_unreachable("Cannot rewrite unknown branch!"); 146669d8dd8SSimon Dardis 147669d8dd8SSimon Dardis Inst.getOperand(0).setReg(RegOp1); 148669d8dd8SSimon Dardis Inst.getOperand(1).setReg(RegOp0); 149669d8dd8SSimon Dardis 150669d8dd8SSimon Dardis } 151669d8dd8SSimon Dardis 1529e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 153db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMicroMips]; 1549e1450bcSMatheus Almeida } 1559e1450bcSMatheus Almeida 156c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 157db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 158c22555d9SJozef Kolek } 159c22555d9SJozef Kolek 1609e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1619e1450bcSMatheus Almeida OS << (char)C; 1629e1450bcSMatheus Almeida } 1639e1450bcSMatheus Almeida 1649e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1659e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1669e1450bcSMatheus Almeida raw_ostream &OS) const { 1679e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1689e1450bcSMatheus Almeida // Little-endian byte ordering: 1699e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1709e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1719e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1729e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1739e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1749e1450bcSMatheus Almeida } else { 1759e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1769e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1779e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1789e1450bcSMatheus Almeida } 1799e1450bcSMatheus Almeida } 1809e1450bcSMatheus Almeida } 1819e1450bcSMatheus Almeida 18291df21f7SJim Grosbach /// encodeInstruction - Emit the instruction. 1834e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 184c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 18591df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS, 1869784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1879784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 188c85e3ff3SBruno Cardoso Lopes { 189aa7aeaa0SJack Carter 190aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 191aa7aeaa0SJack Carter // only based on operand values. 192aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 193aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 194aa7aeaa0SJack Carter MCInst TmpInst = MI; 195aa7aeaa0SJack Carter switch (MI.getOpcode()) { 196aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 197aa7aeaa0SJack Carter case Mips::DSLL: 198aa7aeaa0SJack Carter case Mips::DSRL: 199aa7aeaa0SJack Carter case Mips::DSRA: 2006a3fe574SAkira Hatanaka case Mips::DROTR: 201f1e0a03dSHrvoje Varga case Mips::DSLL_MM64R6: 20224b975dcSHrvoje Varga case Mips::DSRL_MM64R6: 203f1e0a03dSHrvoje Varga case Mips::DSRA_MM64R6: 204f1e0a03dSHrvoje Varga case Mips::DROTR_MM64R6: 205f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 206aa7aeaa0SJack Carter break; 207aa7aeaa0SJack Carter // Double extract instruction is chosen by pos and size operands 208aa7aeaa0SJack Carter case Mips::DINS: 209611eb829SDaniel Sanders LowerDins(TmpInst); 210669d8dd8SSimon Dardis break; 211b60833c0SSimon Dardis // Compact branches, enforce encoding restrictions. 212669d8dd8SSimon Dardis case Mips::BEQC: 213669d8dd8SSimon Dardis case Mips::BNEC: 214*68a204ddSSimon Dardis case Mips::BEQC64: 215*68a204ddSSimon Dardis case Mips::BNEC64: 216b60833c0SSimon Dardis case Mips::BOVC: 217c962c493SHrvoje Varga case Mips::BOVC_MMR6: 218b60833c0SSimon Dardis case Mips::BNVC: 219c962c493SHrvoje Varga case Mips::BNVC_MMR6: 220669d8dd8SSimon Dardis LowerCompactBranch(TmpInst); 221aa7aeaa0SJack Carter } 222aa7aeaa0SJack Carter 22397700977SJack Carter unsigned long N = Fixups.size(); 2243fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 225c85e3ff3SBruno Cardoso Lopes 226c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 227aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 228c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 229aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 230c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 231c7e220f6SJozef Kolek (Opcode != Mips::SLL_MM) && !Binary) 23291df21f7SJim Grosbach llvm_unreachable("unimplemented opcode in encodeInstruction()"); 233c85e3ff3SBruno Cardoso Lopes 234b59a5419SZoran Jovanovic int NewOpcode = -1; 2356ca13eafSJozef Kolek if (isMicroMips(STI)) { 236b59a5419SZoran Jovanovic if (isMips32r6(STI)) { 237b59a5419SZoran Jovanovic NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 238b59a5419SZoran Jovanovic if (NewOpcode == -1) 239b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 240b59a5419SZoran Jovanovic } 241b59a5419SZoran Jovanovic else 242b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 243b59a5419SZoran Jovanovic 2442e386d3dSZoran Jovanovic // Check whether it is Dsp instruction. 2452e386d3dSZoran Jovanovic if (NewOpcode == -1) 2462e386d3dSZoran Jovanovic NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 2472e386d3dSZoran Jovanovic 248be6a818fSAkira Hatanaka if (NewOpcode != -1) { 24997700977SJack Carter if (Fixups.size() > N) 25097700977SJack Carter Fixups.pop_back(); 251b59a5419SZoran Jovanovic 252be6a818fSAkira Hatanaka Opcode = NewOpcode; 253be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 2543fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 255be6a818fSAkira Hatanaka } 256be6a818fSAkira Hatanaka } 257be6a818fSAkira Hatanaka 258aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 259c85e3ff3SBruno Cardoso Lopes 2605b5559d3SJack Carter // Get byte count of instruction 2615b5559d3SJack Carter unsigned Size = Desc.getSize(); 2625b5559d3SJack Carter if (!Size) 2635b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 264c85e3ff3SBruno Cardoso Lopes 265d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 266c85e3ff3SBruno Cardoso Lopes } 267c85e3ff3SBruno Cardoso Lopes 268c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 269c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 270c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 271c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 272c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2733fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2743fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 275c85e3ff3SBruno Cardoso Lopes 276c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 27771e6a749SJack Carter 2784f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2794f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2804f69a0f2SJack Carter 28171e6a749SJack Carter assert(MO.isExpr() && 28271e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 283c85e3ff3SBruno Cardoso Lopes 284b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 285b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 286b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 287c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 288c85e3ff3SBruno Cardoso Lopes return 0; 289c85e3ff3SBruno Cardoso Lopes } 290c85e3ff3SBruno Cardoso Lopes 2916f09cdfdSHrvoje Varga /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 2926f09cdfdSHrvoje Varga /// target operand. If the machine operand requires relocation, 2936f09cdfdSHrvoje Varga /// record the relocation and return zero. 2946f09cdfdSHrvoje Varga unsigned MipsMCCodeEmitter:: 2956f09cdfdSHrvoje Varga getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 2966f09cdfdSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 2976f09cdfdSHrvoje Varga const MCSubtargetInfo &STI) const { 2986f09cdfdSHrvoje Varga 2996f09cdfdSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 3006f09cdfdSHrvoje Varga 3016f09cdfdSHrvoje Varga // If the destination is an immediate, divide by 2. 3026f09cdfdSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 1; 3036f09cdfdSHrvoje Varga 3046f09cdfdSHrvoje Varga assert(MO.isExpr() && 3056f09cdfdSHrvoje Varga "getBranchTargetOpValue expects only expressions or immediates"); 3066f09cdfdSHrvoje Varga 3076f09cdfdSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 3086f09cdfdSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 3096f09cdfdSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 3106f09cdfdSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 3116f09cdfdSHrvoje Varga return 0; 3126f09cdfdSHrvoje Varga } 3136f09cdfdSHrvoje Varga 314c962c493SHrvoje Varga /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch 315c962c493SHrvoje Varga /// target operand. If the machine operand requires relocation, 316c962c493SHrvoje Varga /// record the relocation and return zero. 317c962c493SHrvoje Varga unsigned MipsMCCodeEmitter:: 318c962c493SHrvoje Varga getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, 319c962c493SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 320c962c493SHrvoje Varga const MCSubtargetInfo &STI) const { 321c962c493SHrvoje Varga 322c962c493SHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 323c962c493SHrvoje Varga 324c962c493SHrvoje Varga // If the destination is an immediate, divide by 2. 325c962c493SHrvoje Varga if (MO.isImm()) 326c962c493SHrvoje Varga return MO.getImm() >> 1; 327c962c493SHrvoje Varga 328c962c493SHrvoje Varga assert(MO.isExpr() && 329c962c493SHrvoje Varga "getBranchTargetOpValueMMR6 expects only expressions or immediates"); 330c962c493SHrvoje Varga 331c962c493SHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 332c962c493SHrvoje Varga MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); 333c962c493SHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 334c962c493SHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 335c962c493SHrvoje Varga return 0; 336c962c493SHrvoje Varga } 337c962c493SHrvoje Varga 3389761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 3399761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 3409761e96bSJozef Kolek /// record the relocation and return zero. 3419761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 3429761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 3439761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3449761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 3459761e96bSJozef Kolek 3469761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3479761e96bSJozef Kolek 3489761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 3499761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3509761e96bSJozef Kolek 3519761e96bSJozef Kolek assert(MO.isExpr() && 3529761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 3539761e96bSJozef Kolek 3549761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 35563661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3569761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 3579761e96bSJozef Kolek return 0; 3589761e96bSJozef Kolek } 3599761e96bSJozef Kolek 3605cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 3615cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 3625cfebddeSJozef Kolek /// record the relocation and return zero. 3635cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 3645cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 3655cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3665cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 3675cfebddeSJozef Kolek 3685cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3695cfebddeSJozef Kolek 3705cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 3715cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3725cfebddeSJozef Kolek 3735cfebddeSJozef Kolek assert(MO.isExpr() && 3745cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 3755cfebddeSJozef Kolek 3765cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 37763661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3785cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 3795cfebddeSJozef Kolek return 0; 3805cfebddeSJozef Kolek } 3815cfebddeSJozef Kolek 3828a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 3838a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 3848a80aa76SZoran Jovanovic /// record the relocation and return zero. 3858a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 3868a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 3873fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3883fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 3898a80aa76SZoran Jovanovic 3908a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3918a80aa76SZoran Jovanovic 3928a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 3938a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 3948a80aa76SZoran Jovanovic 3958a80aa76SZoran Jovanovic assert(MO.isExpr() && 3968a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 3978a80aa76SZoran Jovanovic 3988a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 39963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 4008a80aa76SZoran Jovanovic MCFixupKind(Mips:: 4018a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 4028a80aa76SZoran Jovanovic return 0; 4038a80aa76SZoran Jovanovic } 4048a80aa76SZoran Jovanovic 4053c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 4063c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4073c8869dcSZoran Jovanovic /// record the relocation and return zero. 4083c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4093c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 4103c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4113c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4123c8869dcSZoran Jovanovic 4133c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4143c8869dcSZoran Jovanovic 4153c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4163c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4173c8869dcSZoran Jovanovic 4183c8869dcSZoran Jovanovic assert(MO.isExpr() && 4193c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 4203c8869dcSZoran Jovanovic 421b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 422b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 423b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 42410e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 4253c8869dcSZoran Jovanovic return 0; 4263c8869dcSZoran Jovanovic } 4273c8869dcSZoran Jovanovic 42884e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch 42984e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires 43084e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero. 43184e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter:: 43284e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 43384e4d59eSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 43484e4d59eSZoran Jovanovic const MCSubtargetInfo &STI) const { 43584e4d59eSZoran Jovanovic 43684e4d59eSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 43784e4d59eSZoran Jovanovic 43884e4d59eSZoran Jovanovic // If the destination is an immediate, divide by 2. 43984e4d59eSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 44084e4d59eSZoran Jovanovic 44184e4d59eSZoran Jovanovic assert(MO.isExpr() && 44284e4d59eSZoran Jovanovic "getBranchTarget21OpValueMM expects only expressions or immediates"); 44384e4d59eSZoran Jovanovic 4445f94cedeSZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 4455f94cedeSZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 4465f94cedeSZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 4475f94cedeSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 44884e4d59eSZoran Jovanovic return 0; 44984e4d59eSZoran Jovanovic } 45084e4d59eSZoran Jovanovic 4513c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 4523c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4533c8869dcSZoran Jovanovic /// record the relocation and return zero. 4543c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4553c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 4563c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4573c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4583c8869dcSZoran Jovanovic 4593c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4603c8869dcSZoran Jovanovic 4613c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4623c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4633c8869dcSZoran Jovanovic 4643c8869dcSZoran Jovanovic assert(MO.isExpr() && 4653c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 4663c8869dcSZoran Jovanovic 467b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 468b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 469b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 47010e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 4713c8869dcSZoran Jovanovic return 0; 4723c8869dcSZoran Jovanovic } 4733c8869dcSZoran Jovanovic 474a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 475a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 476a887b361SZoran Jovanovic /// record the relocation and return zero. 477a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 478a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 479a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 480a887b361SZoran Jovanovic 481a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 482a887b361SZoran Jovanovic 483a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 484a887b361SZoran Jovanovic if (MO.isImm()) 485a887b361SZoran Jovanovic return MO.getImm() >> 1; 486a887b361SZoran Jovanovic 48702b70030SZoran Jovanovic assert(MO.isExpr() && 48802b70030SZoran Jovanovic "getBranchTarget26OpValueMM expects only expressions or immediates"); 48902b70030SZoran Jovanovic 49002b70030SZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 49102b70030SZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 49202b70030SZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 49302b70030SZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 494a887b361SZoran Jovanovic return 0; 495a887b361SZoran Jovanovic } 496a887b361SZoran Jovanovic 49752c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 49852c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 49952c56b93SZoran Jovanovic /// record the relocation and return zero. 50052c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 50152c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 50252c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 50352c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 50452c56b93SZoran Jovanovic 50552c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 50652c56b93SZoran Jovanovic 50752c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 50852c56b93SZoran Jovanovic 50952c56b93SZoran Jovanovic assert(MO.isExpr() && 51052c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 51152c56b93SZoran Jovanovic 51252c56b93SZoran Jovanovic // TODO: Push fixup. 51352c56b93SZoran Jovanovic return 0; 51452c56b93SZoran Jovanovic } 51552c56b93SZoran Jovanovic 516c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 517c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 518c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 519c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 520c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 5213fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5223fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 523c85e3ff3SBruno Cardoso Lopes 524c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 5254f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 5264f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 5274f69a0f2SJack Carter 52871e6a749SJack Carter assert(MO.isExpr() && 52971e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 530c85e3ff3SBruno Cardoso Lopes 531c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 53263661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 533c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 534c85e3ff3SBruno Cardoso Lopes return 0; 535c85e3ff3SBruno Cardoso Lopes } 536c85e3ff3SBruno Cardoso Lopes 537c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 538507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 5393fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5403fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 541507e084aSZoran Jovanovic 542507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 543507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 544507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 545507e084aSZoran Jovanovic 546507e084aSZoran Jovanovic assert(MO.isExpr() && 547507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 548507e084aSZoran Jovanovic 549507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 55063661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 551507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 552507e084aSZoran Jovanovic return 0; 553507e084aSZoran Jovanovic } 554507e084aSZoran Jovanovic 555507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 556c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 557c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 558c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 559c74e3eb9SZoran Jovanovic 560c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 561c74e3eb9SZoran Jovanovic if (MO.isImm()) { 562c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 563c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 564c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 565c74e3eb9SZoran Jovanovic return Res >> 2; 566c74e3eb9SZoran Jovanovic } 567c74e3eb9SZoran Jovanovic 568c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 569c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 570c74e3eb9SZoran Jovanovic 571c74e3eb9SZoran Jovanovic return 0; 572c74e3eb9SZoran Jovanovic } 573c74e3eb9SZoran Jovanovic 574c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 575bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 576bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 577bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 578bac3619bSZoran Jovanovic 579bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 580bac3619bSZoran Jovanovic if (MO.isImm()) { 581bac3619bSZoran Jovanovic int Value = MO.getImm(); 582bac3619bSZoran Jovanovic return Value >> 2; 583bac3619bSZoran Jovanovic } 584bac3619bSZoran Jovanovic 585bac3619bSZoran Jovanovic return 0; 586bac3619bSZoran Jovanovic } 587bac3619bSZoran Jovanovic 588bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 58942b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 59042b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 59142b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 59242b84443SZoran Jovanovic 59342b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 59442b84443SZoran Jovanovic if (MO.isImm()) { 59542b84443SZoran Jovanovic unsigned Value = MO.getImm(); 59642b84443SZoran Jovanovic return Value >> 2; 59742b84443SZoran Jovanovic } 59842b84443SZoran Jovanovic 59942b84443SZoran Jovanovic return 0; 60042b84443SZoran Jovanovic } 60142b84443SZoran Jovanovic 60242b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 60398bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 60498bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 60598bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 60698bd58caSZoran Jovanovic 60798bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 60898bd58caSZoran Jovanovic if (MO.isImm()) { 60998bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 61098bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 61198bd58caSZoran Jovanovic } 61298bd58caSZoran Jovanovic 61398bd58caSZoran Jovanovic return 0; 61498bd58caSZoran Jovanovic } 61598bd58caSZoran Jovanovic 61698bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 6173fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 6183fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 619b5cf5909SJack Carter int64_t Res; 620049e9e4dSAkira Hatanaka 62113760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 622b5cf5909SJack Carter return Res; 623fe384a2cSAkira Hatanaka 624fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 625b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 626b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 627b5cf5909SJack Carter } 628fe384a2cSAkira Hatanaka 629fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 6303fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 6313fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 632b5cf5909SJack Carter return Res; 633fe384a2cSAkira Hatanaka } 634a5da588bSPetar Jovanovic 635a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 636a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 637a5da588bSPetar Jovanovic 638a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 639a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 640fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_NEG: 641fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_None: 642fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_Special: 643fe98b2f5SDaniel Sanders llvm_unreachable("Unhandled fixup kind!"); 644fe98b2f5SDaniel Sanders break; 645fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_HI16: 646fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_HI16; 647fe98b2f5SDaniel Sanders break; 648fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_LO16: 649fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_LO16; 650fe98b2f5SDaniel Sanders break; 651fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_HI: 652fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 653fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_HI; 654fe98b2f5SDaniel Sanders break; 655fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_LO: 656fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 657fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_LO; 658fe98b2f5SDaniel Sanders break; 659fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOTTPREL: 660fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOTTPREL; 661fe98b2f5SDaniel Sanders break; 662fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT: 663fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 664fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT; 665fe98b2f5SDaniel Sanders break; 666fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_CALL: 667fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 668fe98b2f5SDaniel Sanders : Mips::fixup_Mips_CALL16; 669fe98b2f5SDaniel Sanders break; 670fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_DISP: 671fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 672fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_DISP; 673fe98b2f5SDaniel Sanders break; 674fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_HI16: 675fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_HI16; 676fe98b2f5SDaniel Sanders break; 677fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_LO16: 678fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_LO16; 679fe98b2f5SDaniel Sanders break; 680fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_PAGE: 681fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 682fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_PAGE; 683fe98b2f5SDaniel Sanders break; 684fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_OFST: 685fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 686fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_OFST; 687fe98b2f5SDaniel Sanders break; 688fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GPREL: 689fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPREL16; 690fe98b2f5SDaniel Sanders break; 691fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_LO: { 692fe98b2f5SDaniel Sanders // Check for %lo(%neg(%gp_rel(X))) 693fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 694fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_LO; 695fe98b2f5SDaniel Sanders break; 696fe98b2f5SDaniel Sanders } 697fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 698fe98b2f5SDaniel Sanders : Mips::fixup_Mips_LO16; 699fe98b2f5SDaniel Sanders break; 700fe98b2f5SDaniel Sanders } 701fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHEST: 70206c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 70306c47803SSasa Stankovic break; 704fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHER: 70506c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 70606c47803SSasa Stankovic break; 707fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HI: 708fe98b2f5SDaniel Sanders // Check for %hi(%neg(%gp_rel(X))) 709fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 710fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_HI; 711fe98b2f5SDaniel Sanders break; 712fe98b2f5SDaniel Sanders } 713a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 714a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 715a5da588bSPetar Jovanovic break; 716fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_HI16: 717fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCHI16; 718fe98b2f5SDaniel Sanders break; 719fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_LO16: 720fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCLO16; 721fe98b2f5SDaniel Sanders break; 722fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSGD: 723fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 724fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSGD; 725fe98b2f5SDaniel Sanders break; 726fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSLDM: 727fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 728fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSLDM; 729fe98b2f5SDaniel Sanders break; 730fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_HI: 731fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 732fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_HI; 733fe98b2f5SDaniel Sanders break; 734fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_LO: 735fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 736fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_LO; 737a5da588bSPetar Jovanovic break; 738a5da588bSPetar Jovanovic } 73963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 740a5da588bSPetar Jovanovic return 0; 741a5da588bSPetar Jovanovic } 742a5da588bSPetar Jovanovic 743b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 744f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 745e2eed964SAkira Hatanaka 746049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 747b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 74860f1db05SDaniel Sanders break; 74960f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 75060f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 751b9f9de93SJack Carter break; 752c85e3ff3SBruno Cardoso Lopes } // switch 753fe384a2cSAkira Hatanaka 75463661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 755fe384a2cSAkira Hatanaka return 0; 756c85e3ff3SBruno Cardoso Lopes } 757b5cf5909SJack Carter return 0; 758b5cf5909SJack Carter } 759b5cf5909SJack Carter 760b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 761b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 762b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 763b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 7643fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7653fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 766b5cf5909SJack Carter if (MO.isReg()) { 767b5cf5909SJack Carter unsigned Reg = MO.getReg(); 768bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 769b5cf5909SJack Carter return RegNo; 770b5cf5909SJack Carter } else if (MO.isImm()) { 771b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 772b5cf5909SJack Carter } else if (MO.isFPImm()) { 773b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 774b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 775b5cf5909SJack Carter } 776b5cf5909SJack Carter // MO must be an Expr. 777b5cf5909SJack Carter assert(MO.isExpr()); 7783fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 779b5cf5909SJack Carter } 780c85e3ff3SBruno Cardoso Lopes 781dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand. 782c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 783dc0602a2SDaniel Sanders template <unsigned ShiftAmount> 784dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 7853fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7863fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 787c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 788c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 7893fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 7903fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 791c85e3ff3SBruno Cardoso Lopes 792dc0602a2SDaniel Sanders // Apply the scale factor if there is one. 793dc0602a2SDaniel Sanders OffBits >>= ShiftAmount; 794dc0602a2SDaniel Sanders 795c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 796c85e3ff3SBruno Cardoso Lopes } 797c85e3ff3SBruno Cardoso Lopes 79897700977SJack Carter unsigned MipsMCCodeEmitter:: 799e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 800e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 801e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 802e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 803e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 804e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 805e8c9d1eaSJozef Kolek Fixups, STI) << 4; 806e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 807e8c9d1eaSJozef Kolek Fixups, STI); 808e8c9d1eaSJozef Kolek 809e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 810e8c9d1eaSJozef Kolek } 811e8c9d1eaSJozef Kolek 812e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 813e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 814e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 815e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 816e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 817e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 818e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 819e8c9d1eaSJozef Kolek Fixups, STI) << 4; 820e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 821e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 822e8c9d1eaSJozef Kolek 823e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 824e8c9d1eaSJozef Kolek } 825e8c9d1eaSJozef Kolek 826e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 827e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 828e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 829e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 830e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 831e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 832e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 833e8c9d1eaSJozef Kolek Fixups, STI) << 4; 834e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 835e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 836e8c9d1eaSJozef Kolek 837e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 838e8c9d1eaSJozef Kolek } 839e8c9d1eaSJozef Kolek 840e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 84112c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 84212c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 84312c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 84412c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 84512c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 84668be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 84768be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 84812c6982bSJozef Kolek "Unexpected base register!"); 84912c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 85012c6982bSJozef Kolek Fixups, STI) >> 2; 85112c6982bSJozef Kolek 85212c6982bSJozef Kolek return OffBits & 0x1F; 85312c6982bSJozef Kolek } 85412c6982bSJozef Kolek 85512c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 856e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 857e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 858e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 859e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 860e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 861e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 862e10a02ecSJozef Kolek "Unexpected base register!"); 863e10a02ecSJozef Kolek 864e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 865e10a02ecSJozef Kolek Fixups, STI) >> 2; 866e10a02ecSJozef Kolek 867e10a02ecSJozef Kolek return OffBits & 0x7F; 868e10a02ecSJozef Kolek } 869e10a02ecSJozef Kolek 8709eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 8719eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 8729eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8739eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 8749eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 8759eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 8769eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8779eaa30d2SZoran Jovanovic STI) << 16; 8789eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 8799eaa30d2SZoran Jovanovic 8809eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 8819eaa30d2SZoran Jovanovic } 8829eaa30d2SZoran Jovanovic 883e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 884cba9f80bSZlatko Buljan getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 885cba9f80bSZlatko Buljan SmallVectorImpl<MCFixup> &Fixups, 886cba9f80bSZlatko Buljan const MCSubtargetInfo &STI) const { 887cba9f80bSZlatko Buljan // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 888cba9f80bSZlatko Buljan assert(MI.getOperand(OpNo).isReg()); 889cba9f80bSZlatko Buljan unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 890cba9f80bSZlatko Buljan STI) << 16; 891cba9f80bSZlatko Buljan unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 892cba9f80bSZlatko Buljan 893cba9f80bSZlatko Buljan return (OffBits & 0x07FF) | RegBits; 894cba9f80bSZlatko Buljan } 895cba9f80bSZlatko Buljan 896cba9f80bSZlatko Buljan unsigned MipsMCCodeEmitter:: 89797700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 8983fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8993fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 900a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 901a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 902a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 903a4c4b5fcSZoran Jovanovic default: 904a4c4b5fcSZoran Jovanovic break; 905a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 906a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 907a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 908a4c4b5fcSZoran Jovanovic break; 909a4c4b5fcSZoran Jovanovic } 910a4c4b5fcSZoran Jovanovic 91197700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 91297700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 9133fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 9143fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 91597700977SJack Carter 91697700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 9173c88fbd3SHrvoje Varga } 9183c88fbd3SHrvoje Varga 9193c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 9203c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 9213c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 9223c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 9233c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 9243c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 9253c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 9263c88fbd3SHrvoje Varga STI) << 16; 9273c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 9283c88fbd3SHrvoje Varga 9293c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 93097700977SJack Carter } 93197700977SJack Carter 932f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 933f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 934f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 935f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 936f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 937f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 938f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 939f9a02500SZoran Jovanovic default: 940f9a02500SZoran Jovanovic break; 941f9a02500SZoran Jovanovic case Mips::SWM16_MM: 942797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 943f9a02500SZoran Jovanovic case Mips::LWM16_MM: 944797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 945f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 946f9a02500SZoran Jovanovic break; 947f9a02500SZoran Jovanovic } 948f9a02500SZoran Jovanovic 949f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 950f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 951f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 952f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 953f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 954f9a02500SZoran Jovanovic 955f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 956f9a02500SZoran Jovanovic } 957f9a02500SZoran Jovanovic 958049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 959049e9e4dSAkira Hatanaka // 960c85e3ff3SBruno Cardoso Lopes unsigned 961c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 9623fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9633fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 964049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 965049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 9663fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 9673fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 968049e9e4dSAkira Hatanaka 96956b70de0SBruno Cardoso Lopes return Position + Size - 1; 970c85e3ff3SBruno Cardoso Lopes } 971c85e3ff3SBruno Cardoso Lopes 972ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 973779c5937SMatheus Almeida unsigned 974ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 9753fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9763fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 977779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 978ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 979ea4f653dSDaniel Sanders Value -= Offset; 980ea4f653dSDaniel Sanders return Value; 981779c5937SMatheus Almeida } 982779c5937SMatheus Almeida 983b59e1a41SDaniel Sanders unsigned 984b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 985b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 986b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 987b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 988b9c07f3bSZoran Jovanovic if (MO.isImm()) { 989b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 990b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 991b59e1a41SDaniel Sanders assert((Res & 3) == 0); 992b59e1a41SDaniel Sanders return Res >> 2; 993b59e1a41SDaniel Sanders } 994c85e3ff3SBruno Cardoso Lopes 995b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 996b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 997b9c07f3bSZoran Jovanovic 998b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9996764fa78SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 10006764fa78SZoran Jovanovic : Mips::fixup_MIPS_PC19_S2; 10016764fa78SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1002b9c07f3bSZoran Jovanovic return 0; 1003b9c07f3bSZoran Jovanovic } 1004b9c07f3bSZoran Jovanovic 10052855142aSZoran Jovanovic unsigned 10062855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 10072855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10082855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 1009a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 1010a5acdcf9SZoran Jovanovic if (MO.isImm()) { 10112855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 10122855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 10132855142aSZoran Jovanovic assert((Res & 7) == 0); 10142855142aSZoran Jovanovic return Res >> 3; 10152855142aSZoran Jovanovic } 10162855142aSZoran Jovanovic 1017a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 1018a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 1019a5acdcf9SZoran Jovanovic 1020a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 10218e366822SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 10228e366822SZoran Jovanovic : Mips::fixup_MIPS_PC18_S3; 10238e366822SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1024a5acdcf9SZoran Jovanovic return 0; 1025a5acdcf9SZoran Jovanovic } 1026a5acdcf9SZoran Jovanovic 10274a00fdc2SZoran Jovanovic unsigned 10284a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 10294a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10304a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 10314a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10324a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10334a00fdc2SZoran Jovanovic return MO.getImm() % 8; 10344a00fdc2SZoran Jovanovic } 10354a00fdc2SZoran Jovanovic 10368853171bSZoran Jovanovic unsigned 10378853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 10388853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10398853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 10408853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10418853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10428853171bSZoran Jovanovic unsigned Value = MO.getImm(); 10438853171bSZoran Jovanovic switch (Value) { 10448853171bSZoran Jovanovic case 128: return 0x0; 10458853171bSZoran Jovanovic case 1: return 0x1; 10468853171bSZoran Jovanovic case 2: return 0x2; 10478853171bSZoran Jovanovic case 3: return 0x3; 10488853171bSZoran Jovanovic case 4: return 0x4; 10498853171bSZoran Jovanovic case 7: return 0x5; 10508853171bSZoran Jovanovic case 8: return 0x6; 10518853171bSZoran Jovanovic case 15: return 0x7; 10528853171bSZoran Jovanovic case 16: return 0x8; 10538853171bSZoran Jovanovic case 31: return 0x9; 10548853171bSZoran Jovanovic case 32: return 0xa; 10558853171bSZoran Jovanovic case 63: return 0xb; 10568853171bSZoran Jovanovic case 64: return 0xc; 10578853171bSZoran Jovanovic case 255: return 0xd; 10588853171bSZoran Jovanovic case 32768: return 0xe; 10598853171bSZoran Jovanovic case 65535: return 0xf; 10608853171bSZoran Jovanovic } 10618853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 10628853171bSZoran Jovanovic } 10638853171bSZoran Jovanovic 1064a4c4b5fcSZoran Jovanovic unsigned 1065a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1066a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1067a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 1068a4c4b5fcSZoran Jovanovic unsigned res = 0; 1069a4c4b5fcSZoran Jovanovic 1070a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 1071a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 1072a4c4b5fcSZoran Jovanovic 1073a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1074a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 1075a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1076a4c4b5fcSZoran Jovanovic if (RegNo != 31) 1077a4c4b5fcSZoran Jovanovic res++; 1078a4c4b5fcSZoran Jovanovic else 1079a4c4b5fcSZoran Jovanovic res |= 0x10; 1080a4c4b5fcSZoran Jovanovic } 1081a4c4b5fcSZoran Jovanovic return res; 1082a4c4b5fcSZoran Jovanovic } 1083a4c4b5fcSZoran Jovanovic 1084f9a02500SZoran Jovanovic unsigned 1085f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1086f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1087f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 1088f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 1089f9a02500SZoran Jovanovic } 1090f9a02500SZoran Jovanovic 10912deca348SZoran Jovanovic unsigned 10922deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 10932deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10942deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 10952deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 10962deca348SZoran Jovanovic } 10972deca348SZoran Jovanovic 10982c6d7320SJozef Kolek unsigned 109941688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 110041688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 110141688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 110241688679SZoran Jovanovic unsigned res = 0; 110341688679SZoran Jovanovic 110441688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 110541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 110641688679SZoran Jovanovic res = 0; 110741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 110841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 110941688679SZoran Jovanovic res = 1; 111041688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 111141688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 111241688679SZoran Jovanovic res = 2; 111341688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 111441688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 111541688679SZoran Jovanovic res = 3; 111641688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 111741688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 111841688679SZoran Jovanovic res = 4; 111941688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 112041688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 112141688679SZoran Jovanovic res = 5; 112241688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 112341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 112441688679SZoran Jovanovic res = 6; 112541688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 112641688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 112741688679SZoran Jovanovic res = 7; 112841688679SZoran Jovanovic 112941688679SZoran Jovanovic return res; 113041688679SZoran Jovanovic } 113141688679SZoran Jovanovic 113241688679SZoran Jovanovic unsigned 11332c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 11342c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 11352c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 11362c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 11372c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 11382c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 11392c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 11402c6d7320SJozef Kolek assert((Res & 3) == 0); 11412c6d7320SJozef Kolek return Res >> 2; 11422c6d7320SJozef Kolek } 11432c6d7320SJozef Kolek 1144b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1145