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 13268a204ddSSimon Dardis if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC || 13368a204ddSSimon 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: 21468a204ddSSimon Dardis case Mips::BEQC64: 21568a204ddSSimon 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 338*f0ed16eaSHrvoje Varga /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch 339*f0ed16eaSHrvoje Varga /// target operand. If the machine operand requires relocation, 340*f0ed16eaSHrvoje Varga /// record the relocation and return zero. 341*f0ed16eaSHrvoje Varga unsigned MipsMCCodeEmitter:: 342*f0ed16eaSHrvoje Varga getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, 343*f0ed16eaSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 344*f0ed16eaSHrvoje Varga const MCSubtargetInfo &STI) const { 345*f0ed16eaSHrvoje Varga 346*f0ed16eaSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 347*f0ed16eaSHrvoje Varga 348*f0ed16eaSHrvoje Varga // If the destination is an immediate, divide by 4. 349*f0ed16eaSHrvoje Varga if (MO.isImm()) 350*f0ed16eaSHrvoje Varga return MO.getImm() >> 2; 351*f0ed16eaSHrvoje Varga 352*f0ed16eaSHrvoje Varga assert(MO.isExpr() && 353*f0ed16eaSHrvoje Varga "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates"); 354*f0ed16eaSHrvoje Varga 355*f0ed16eaSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 356*f0ed16eaSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 357*f0ed16eaSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 358*f0ed16eaSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 359*f0ed16eaSHrvoje Varga return 0; 360*f0ed16eaSHrvoje Varga } 361*f0ed16eaSHrvoje Varga 3629761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 3639761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 3649761e96bSJozef Kolek /// record the relocation and return zero. 3659761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 3669761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 3679761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3689761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 3699761e96bSJozef Kolek 3709761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3719761e96bSJozef Kolek 3729761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 3739761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3749761e96bSJozef Kolek 3759761e96bSJozef Kolek assert(MO.isExpr() && 3769761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 3779761e96bSJozef Kolek 3789761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 37963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3809761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 3819761e96bSJozef Kolek return 0; 3829761e96bSJozef Kolek } 3839761e96bSJozef Kolek 3845cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 3855cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 3865cfebddeSJozef Kolek /// record the relocation and return zero. 3875cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 3885cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 3895cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3905cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 3915cfebddeSJozef Kolek 3925cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3935cfebddeSJozef Kolek 3945cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 3955cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3965cfebddeSJozef Kolek 3975cfebddeSJozef Kolek assert(MO.isExpr() && 3985cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 3995cfebddeSJozef Kolek 4005cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 40163661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 4025cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 4035cfebddeSJozef Kolek return 0; 4045cfebddeSJozef Kolek } 4055cfebddeSJozef Kolek 4068a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 4078a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 4088a80aa76SZoran Jovanovic /// record the relocation and return zero. 4098a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 4108a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 4113fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4123fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 4138a80aa76SZoran Jovanovic 4148a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4158a80aa76SZoran Jovanovic 4168a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 4178a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 4188a80aa76SZoran Jovanovic 4198a80aa76SZoran Jovanovic assert(MO.isExpr() && 4208a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 4218a80aa76SZoran Jovanovic 4228a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 42363661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 4248a80aa76SZoran Jovanovic MCFixupKind(Mips:: 4258a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 4268a80aa76SZoran Jovanovic return 0; 4278a80aa76SZoran Jovanovic } 4288a80aa76SZoran Jovanovic 4293c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 4303c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4313c8869dcSZoran Jovanovic /// record the relocation and return zero. 4323c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4333c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 4343c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4353c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4363c8869dcSZoran Jovanovic 4373c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4383c8869dcSZoran Jovanovic 4393c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4403c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4413c8869dcSZoran Jovanovic 4423c8869dcSZoran Jovanovic assert(MO.isExpr() && 4433c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 4443c8869dcSZoran Jovanovic 445b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 446b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 447b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 44810e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 4493c8869dcSZoran Jovanovic return 0; 4503c8869dcSZoran Jovanovic } 4513c8869dcSZoran Jovanovic 45284e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch 45384e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires 45484e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero. 45584e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter:: 45684e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 45784e4d59eSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 45884e4d59eSZoran Jovanovic const MCSubtargetInfo &STI) const { 45984e4d59eSZoran Jovanovic 46084e4d59eSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 46184e4d59eSZoran Jovanovic 462*f0ed16eaSHrvoje Varga // If the destination is an immediate, divide by 4. 463*f0ed16eaSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 2; 46484e4d59eSZoran Jovanovic 46584e4d59eSZoran Jovanovic assert(MO.isExpr() && 46684e4d59eSZoran Jovanovic "getBranchTarget21OpValueMM expects only expressions or immediates"); 46784e4d59eSZoran Jovanovic 4685f94cedeSZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 4695f94cedeSZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 4705f94cedeSZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 4715f94cedeSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 47284e4d59eSZoran Jovanovic return 0; 47384e4d59eSZoran Jovanovic } 47484e4d59eSZoran Jovanovic 4753c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 4763c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4773c8869dcSZoran Jovanovic /// record the relocation and return zero. 4783c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4793c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 4803c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4813c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4823c8869dcSZoran Jovanovic 4833c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4843c8869dcSZoran Jovanovic 4853c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4863c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4873c8869dcSZoran Jovanovic 4883c8869dcSZoran Jovanovic assert(MO.isExpr() && 4893c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 4903c8869dcSZoran Jovanovic 491b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 492b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 493b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 49410e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 4953c8869dcSZoran Jovanovic return 0; 4963c8869dcSZoran Jovanovic } 4973c8869dcSZoran Jovanovic 498a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 499a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 500a887b361SZoran Jovanovic /// record the relocation and return zero. 501a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 502a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 503a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 504a887b361SZoran Jovanovic 505a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 506a887b361SZoran Jovanovic 507a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 508a887b361SZoran Jovanovic if (MO.isImm()) 509a887b361SZoran Jovanovic return MO.getImm() >> 1; 510a887b361SZoran Jovanovic 51102b70030SZoran Jovanovic assert(MO.isExpr() && 51202b70030SZoran Jovanovic "getBranchTarget26OpValueMM expects only expressions or immediates"); 51302b70030SZoran Jovanovic 51402b70030SZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 51502b70030SZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 51602b70030SZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 51702b70030SZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 518a887b361SZoran Jovanovic return 0; 519a887b361SZoran Jovanovic } 520a887b361SZoran Jovanovic 52152c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 52252c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 52352c56b93SZoran Jovanovic /// record the relocation and return zero. 52452c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 52552c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 52652c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 52752c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 52852c56b93SZoran Jovanovic 52952c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 53052c56b93SZoran Jovanovic 53152c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 53252c56b93SZoran Jovanovic 53352c56b93SZoran Jovanovic assert(MO.isExpr() && 53452c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 53552c56b93SZoran Jovanovic 53652c56b93SZoran Jovanovic // TODO: Push fixup. 53752c56b93SZoran Jovanovic return 0; 53852c56b93SZoran Jovanovic } 53952c56b93SZoran Jovanovic 540c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 541c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 542c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 543c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 544c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 5453fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5463fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 547c85e3ff3SBruno Cardoso Lopes 548c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 5494f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 5504f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 5514f69a0f2SJack Carter 55271e6a749SJack Carter assert(MO.isExpr() && 55371e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 554c85e3ff3SBruno Cardoso Lopes 555c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 55663661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 557c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 558c85e3ff3SBruno Cardoso Lopes return 0; 559c85e3ff3SBruno Cardoso Lopes } 560c85e3ff3SBruno Cardoso Lopes 561c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 562507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 5633fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5643fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 565507e084aSZoran Jovanovic 566507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 567507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 568507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 569507e084aSZoran Jovanovic 570507e084aSZoran Jovanovic assert(MO.isExpr() && 571507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 572507e084aSZoran Jovanovic 573507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 57463661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 575507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 576507e084aSZoran Jovanovic return 0; 577507e084aSZoran Jovanovic } 578507e084aSZoran Jovanovic 579507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 580c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 581c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 582c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 583c74e3eb9SZoran Jovanovic 584c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 585c74e3eb9SZoran Jovanovic if (MO.isImm()) { 586c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 587c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 588c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 589c74e3eb9SZoran Jovanovic return Res >> 2; 590c74e3eb9SZoran Jovanovic } 591c74e3eb9SZoran Jovanovic 592c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 593c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 594c74e3eb9SZoran Jovanovic 595c74e3eb9SZoran Jovanovic return 0; 596c74e3eb9SZoran Jovanovic } 597c74e3eb9SZoran Jovanovic 598c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 599bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 600bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 601bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 602bac3619bSZoran Jovanovic 603bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 604bac3619bSZoran Jovanovic if (MO.isImm()) { 605bac3619bSZoran Jovanovic int Value = MO.getImm(); 606bac3619bSZoran Jovanovic return Value >> 2; 607bac3619bSZoran Jovanovic } 608bac3619bSZoran Jovanovic 609bac3619bSZoran Jovanovic return 0; 610bac3619bSZoran Jovanovic } 611bac3619bSZoran Jovanovic 612bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 61342b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 61442b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 61542b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 61642b84443SZoran Jovanovic 61742b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 61842b84443SZoran Jovanovic if (MO.isImm()) { 61942b84443SZoran Jovanovic unsigned Value = MO.getImm(); 62042b84443SZoran Jovanovic return Value >> 2; 62142b84443SZoran Jovanovic } 62242b84443SZoran Jovanovic 62342b84443SZoran Jovanovic return 0; 62442b84443SZoran Jovanovic } 62542b84443SZoran Jovanovic 62642b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 62798bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 62898bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 62998bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 63098bd58caSZoran Jovanovic 63198bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 63298bd58caSZoran Jovanovic if (MO.isImm()) { 63398bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 63498bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 63598bd58caSZoran Jovanovic } 63698bd58caSZoran Jovanovic 63798bd58caSZoran Jovanovic return 0; 63898bd58caSZoran Jovanovic } 63998bd58caSZoran Jovanovic 64098bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 6413fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 6423fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 643b5cf5909SJack Carter int64_t Res; 644049e9e4dSAkira Hatanaka 64513760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 646b5cf5909SJack Carter return Res; 647fe384a2cSAkira Hatanaka 648fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 649b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 650b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 651b5cf5909SJack Carter } 652fe384a2cSAkira Hatanaka 653fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 6543fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 6553fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 656b5cf5909SJack Carter return Res; 657fe384a2cSAkira Hatanaka } 658a5da588bSPetar Jovanovic 659a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 660a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 661a5da588bSPetar Jovanovic 662a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 663a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 664fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_None: 665fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_Special: 666fe98b2f5SDaniel Sanders llvm_unreachable("Unhandled fixup kind!"); 667fe98b2f5SDaniel Sanders break; 668fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_HI16: 669fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_HI16; 670fe98b2f5SDaniel Sanders break; 671fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_LO16: 672fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_LO16; 673fe98b2f5SDaniel Sanders break; 674fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_HI: 675fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 676fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_HI; 677fe98b2f5SDaniel Sanders break; 678fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_LO: 679fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 680fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_LO; 681fe98b2f5SDaniel Sanders break; 682fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOTTPREL: 683fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOTTPREL; 684fe98b2f5SDaniel Sanders break; 685fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT: 686fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 687fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT; 688fe98b2f5SDaniel Sanders break; 689fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_CALL: 690fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 691fe98b2f5SDaniel Sanders : Mips::fixup_Mips_CALL16; 692fe98b2f5SDaniel Sanders break; 693fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_DISP: 694fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 695fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_DISP; 696fe98b2f5SDaniel Sanders break; 697fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_HI16: 698fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_HI16; 699fe98b2f5SDaniel Sanders break; 700fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_LO16: 701fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_LO16; 702fe98b2f5SDaniel Sanders break; 703fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_PAGE: 704fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 705fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_PAGE; 706fe98b2f5SDaniel Sanders break; 707fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_OFST: 708fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 709fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_OFST; 710fe98b2f5SDaniel Sanders break; 711fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GPREL: 712fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPREL16; 713fe98b2f5SDaniel Sanders break; 714fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_LO: { 715fe98b2f5SDaniel Sanders // Check for %lo(%neg(%gp_rel(X))) 716fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 717fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_LO; 718fe98b2f5SDaniel Sanders break; 719fe98b2f5SDaniel Sanders } 720fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 721fe98b2f5SDaniel Sanders : Mips::fixup_Mips_LO16; 722fe98b2f5SDaniel Sanders break; 723fe98b2f5SDaniel Sanders } 724fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHEST: 72506c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHEST; 72606c47803SSasa Stankovic break; 727fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHER: 72806c47803SSasa Stankovic FixupKind = Mips::fixup_Mips_HIGHER; 72906c47803SSasa Stankovic break; 730fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HI: 731fe98b2f5SDaniel Sanders // Check for %hi(%neg(%gp_rel(X))) 732fe98b2f5SDaniel Sanders if (MipsExpr->isGpOff()) { 733fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPOFF_HI; 734fe98b2f5SDaniel Sanders break; 735fe98b2f5SDaniel Sanders } 736a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 737a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 738a5da588bSPetar Jovanovic break; 739fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_HI16: 740fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCHI16; 741fe98b2f5SDaniel Sanders break; 742fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_LO16: 743fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCLO16; 744fe98b2f5SDaniel Sanders break; 745fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSGD: 746fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 747fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSGD; 748fe98b2f5SDaniel Sanders break; 749fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSLDM: 750fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 751fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSLDM; 752fe98b2f5SDaniel Sanders break; 753fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_HI: 754fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 755fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_HI; 756fe98b2f5SDaniel Sanders break; 757fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_LO: 758fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 759fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_LO; 760a5da588bSPetar Jovanovic break; 7613feeb9c8SDaniel Sanders case MipsMCExpr::MEK_NEG: 7623feeb9c8SDaniel Sanders FixupKind = 7633feeb9c8SDaniel Sanders isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; 7643feeb9c8SDaniel Sanders break; 765a5da588bSPetar Jovanovic } 76663661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 767a5da588bSPetar Jovanovic return 0; 768a5da588bSPetar Jovanovic } 769a5da588bSPetar Jovanovic 770b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 771f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 772e2eed964SAkira Hatanaka 773049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 774b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 77560f1db05SDaniel Sanders break; 77660f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 77760f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 778b9f9de93SJack Carter break; 779c85e3ff3SBruno Cardoso Lopes } // switch 780fe384a2cSAkira Hatanaka 78163661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 782fe384a2cSAkira Hatanaka return 0; 783c85e3ff3SBruno Cardoso Lopes } 784b5cf5909SJack Carter return 0; 785b5cf5909SJack Carter } 786b5cf5909SJack Carter 787b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 788b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 789b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 790b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 7913fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7923fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 793b5cf5909SJack Carter if (MO.isReg()) { 794b5cf5909SJack Carter unsigned Reg = MO.getReg(); 795bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 796b5cf5909SJack Carter return RegNo; 797b5cf5909SJack Carter } else if (MO.isImm()) { 798b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 799b5cf5909SJack Carter } else if (MO.isFPImm()) { 800b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 801b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 802b5cf5909SJack Carter } 803b5cf5909SJack Carter // MO must be an Expr. 804b5cf5909SJack Carter assert(MO.isExpr()); 8053fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 806b5cf5909SJack Carter } 807c85e3ff3SBruno Cardoso Lopes 808dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand. 809c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 810dc0602a2SDaniel Sanders template <unsigned ShiftAmount> 811dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 8123fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8133fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 814c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 815c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 8163fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 8173fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 818c85e3ff3SBruno Cardoso Lopes 819dc0602a2SDaniel Sanders // Apply the scale factor if there is one. 820dc0602a2SDaniel Sanders OffBits >>= ShiftAmount; 821dc0602a2SDaniel Sanders 822c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 823c85e3ff3SBruno Cardoso Lopes } 824c85e3ff3SBruno Cardoso Lopes 82597700977SJack Carter unsigned MipsMCCodeEmitter:: 826e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 827e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 828e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 829e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 830e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 831e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 832e8c9d1eaSJozef Kolek Fixups, STI) << 4; 833e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 834e8c9d1eaSJozef Kolek Fixups, STI); 835e8c9d1eaSJozef Kolek 836e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 837e8c9d1eaSJozef Kolek } 838e8c9d1eaSJozef Kolek 839e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 840e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 841e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 842e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 843e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 844e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 845e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 846e8c9d1eaSJozef Kolek Fixups, STI) << 4; 847e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 848e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 849e8c9d1eaSJozef Kolek 850e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 851e8c9d1eaSJozef Kolek } 852e8c9d1eaSJozef Kolek 853e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 854e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 855e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 856e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 857e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 858e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 859e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 860e8c9d1eaSJozef Kolek Fixups, STI) << 4; 861e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 862e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 863e8c9d1eaSJozef Kolek 864e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 865e8c9d1eaSJozef Kolek } 866e8c9d1eaSJozef Kolek 867e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 86812c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 86912c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 87012c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 87112c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 87212c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 87368be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 87468be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 87512c6982bSJozef Kolek "Unexpected base register!"); 87612c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 87712c6982bSJozef Kolek Fixups, STI) >> 2; 87812c6982bSJozef Kolek 87912c6982bSJozef Kolek return OffBits & 0x1F; 88012c6982bSJozef Kolek } 88112c6982bSJozef Kolek 88212c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 883e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 884e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 885e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 886e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 887e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 888e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 889e10a02ecSJozef Kolek "Unexpected base register!"); 890e10a02ecSJozef Kolek 891e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 892e10a02ecSJozef Kolek Fixups, STI) >> 2; 893e10a02ecSJozef Kolek 894e10a02ecSJozef Kolek return OffBits & 0x7F; 895e10a02ecSJozef Kolek } 896e10a02ecSJozef Kolek 8979eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 8989eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 8999eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9009eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 9019eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 9029eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 9039eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 9049eaa30d2SZoran Jovanovic STI) << 16; 9059eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 9069eaa30d2SZoran Jovanovic 9079eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 9089eaa30d2SZoran Jovanovic } 9099eaa30d2SZoran Jovanovic 910e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 911cba9f80bSZlatko Buljan getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 912cba9f80bSZlatko Buljan SmallVectorImpl<MCFixup> &Fixups, 913cba9f80bSZlatko Buljan const MCSubtargetInfo &STI) const { 914cba9f80bSZlatko Buljan // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 915cba9f80bSZlatko Buljan assert(MI.getOperand(OpNo).isReg()); 916cba9f80bSZlatko Buljan unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 917cba9f80bSZlatko Buljan STI) << 16; 918cba9f80bSZlatko Buljan unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 919cba9f80bSZlatko Buljan 920cba9f80bSZlatko Buljan return (OffBits & 0x07FF) | RegBits; 921cba9f80bSZlatko Buljan } 922cba9f80bSZlatko Buljan 923cba9f80bSZlatko Buljan unsigned MipsMCCodeEmitter:: 92497700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 9253fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9263fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 927a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 928a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 929a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 930a4c4b5fcSZoran Jovanovic default: 931a4c4b5fcSZoran Jovanovic break; 932a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 933a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 934a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 935a4c4b5fcSZoran Jovanovic break; 936a4c4b5fcSZoran Jovanovic } 937a4c4b5fcSZoran Jovanovic 93897700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 93997700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 9403fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 9413fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 94297700977SJack Carter 94397700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 9443c88fbd3SHrvoje Varga } 9453c88fbd3SHrvoje Varga 9463c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 9473c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 9483c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 9493c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 9503c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 9513c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 9523c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 9533c88fbd3SHrvoje Varga STI) << 16; 9543c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 9553c88fbd3SHrvoje Varga 9563c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 95797700977SJack Carter } 95897700977SJack Carter 959f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 960f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 961f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 962f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 963f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 964f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 965f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 966f9a02500SZoran Jovanovic default: 967f9a02500SZoran Jovanovic break; 968f9a02500SZoran Jovanovic case Mips::SWM16_MM: 969797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 970f9a02500SZoran Jovanovic case Mips::LWM16_MM: 971797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 972f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 973f9a02500SZoran Jovanovic break; 974f9a02500SZoran Jovanovic } 975f9a02500SZoran Jovanovic 976f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 977f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 978f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 979f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 980f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 981f9a02500SZoran Jovanovic 982f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 983f9a02500SZoran Jovanovic } 984f9a02500SZoran Jovanovic 985049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 986049e9e4dSAkira Hatanaka // 987c85e3ff3SBruno Cardoso Lopes unsigned 988c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 9893fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9903fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 991049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 992049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 9933fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 9943fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 995049e9e4dSAkira Hatanaka 99656b70de0SBruno Cardoso Lopes return Position + Size - 1; 997c85e3ff3SBruno Cardoso Lopes } 998c85e3ff3SBruno Cardoso Lopes 999ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 1000779c5937SMatheus Almeida unsigned 1001ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 10023fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 10033fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 1004779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 1005ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 1006ea4f653dSDaniel Sanders Value -= Offset; 1007ea4f653dSDaniel Sanders return Value; 1008779c5937SMatheus Almeida } 1009779c5937SMatheus Almeida 1010b59e1a41SDaniel Sanders unsigned 1011b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 1012b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 1013b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 1014b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 1015b9c07f3bSZoran Jovanovic if (MO.isImm()) { 1016b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 1017b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 1018b59e1a41SDaniel Sanders assert((Res & 3) == 0); 1019b59e1a41SDaniel Sanders return Res >> 2; 1020b59e1a41SDaniel Sanders } 1021c85e3ff3SBruno Cardoso Lopes 1022b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 1023b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 1024b9c07f3bSZoran Jovanovic 1025b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 10266764fa78SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 10276764fa78SZoran Jovanovic : Mips::fixup_MIPS_PC19_S2; 10286764fa78SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1029b9c07f3bSZoran Jovanovic return 0; 1030b9c07f3bSZoran Jovanovic } 1031b9c07f3bSZoran Jovanovic 10322855142aSZoran Jovanovic unsigned 10332855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 10342855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10352855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 1036a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 1037a5acdcf9SZoran Jovanovic if (MO.isImm()) { 10382855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 10392855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 10402855142aSZoran Jovanovic assert((Res & 7) == 0); 10412855142aSZoran Jovanovic return Res >> 3; 10422855142aSZoran Jovanovic } 10432855142aSZoran Jovanovic 1044a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 1045a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 1046a5acdcf9SZoran Jovanovic 1047a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 10488e366822SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 10498e366822SZoran Jovanovic : Mips::fixup_MIPS_PC18_S3; 10508e366822SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1051a5acdcf9SZoran Jovanovic return 0; 1052a5acdcf9SZoran Jovanovic } 1053a5acdcf9SZoran Jovanovic 10544a00fdc2SZoran Jovanovic unsigned 10554a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 10564a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10574a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 10584a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10594a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10604a00fdc2SZoran Jovanovic return MO.getImm() % 8; 10614a00fdc2SZoran Jovanovic } 10624a00fdc2SZoran Jovanovic 10638853171bSZoran Jovanovic unsigned 10648853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 10658853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10668853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 10678853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10688853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10698853171bSZoran Jovanovic unsigned Value = MO.getImm(); 10708853171bSZoran Jovanovic switch (Value) { 10718853171bSZoran Jovanovic case 128: return 0x0; 10728853171bSZoran Jovanovic case 1: return 0x1; 10738853171bSZoran Jovanovic case 2: return 0x2; 10748853171bSZoran Jovanovic case 3: return 0x3; 10758853171bSZoran Jovanovic case 4: return 0x4; 10768853171bSZoran Jovanovic case 7: return 0x5; 10778853171bSZoran Jovanovic case 8: return 0x6; 10788853171bSZoran Jovanovic case 15: return 0x7; 10798853171bSZoran Jovanovic case 16: return 0x8; 10808853171bSZoran Jovanovic case 31: return 0x9; 10818853171bSZoran Jovanovic case 32: return 0xa; 10828853171bSZoran Jovanovic case 63: return 0xb; 10838853171bSZoran Jovanovic case 64: return 0xc; 10848853171bSZoran Jovanovic case 255: return 0xd; 10858853171bSZoran Jovanovic case 32768: return 0xe; 10868853171bSZoran Jovanovic case 65535: return 0xf; 10878853171bSZoran Jovanovic } 10888853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 10898853171bSZoran Jovanovic } 10908853171bSZoran Jovanovic 1091a4c4b5fcSZoran Jovanovic unsigned 1092a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1093a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1094a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 1095a4c4b5fcSZoran Jovanovic unsigned res = 0; 1096a4c4b5fcSZoran Jovanovic 1097a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 1098a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 1099a4c4b5fcSZoran Jovanovic 1100a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1101a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 1102a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1103a4c4b5fcSZoran Jovanovic if (RegNo != 31) 1104a4c4b5fcSZoran Jovanovic res++; 1105a4c4b5fcSZoran Jovanovic else 1106a4c4b5fcSZoran Jovanovic res |= 0x10; 1107a4c4b5fcSZoran Jovanovic } 1108a4c4b5fcSZoran Jovanovic return res; 1109a4c4b5fcSZoran Jovanovic } 1110a4c4b5fcSZoran Jovanovic 1111f9a02500SZoran Jovanovic unsigned 1112f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1113f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1114f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 1115f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 1116f9a02500SZoran Jovanovic } 1117f9a02500SZoran Jovanovic 11182deca348SZoran Jovanovic unsigned 11192deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, 11202deca348SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 11212deca348SZoran Jovanovic const MCSubtargetInfo &STI) const { 11222deca348SZoran Jovanovic return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 11232deca348SZoran Jovanovic } 11242deca348SZoran Jovanovic 11252c6d7320SJozef Kolek unsigned 112641688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 112741688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 112841688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 112941688679SZoran Jovanovic unsigned res = 0; 113041688679SZoran Jovanovic 113141688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 113241688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 113341688679SZoran Jovanovic res = 0; 113441688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 113541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 113641688679SZoran Jovanovic res = 1; 113741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 113841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 113941688679SZoran Jovanovic res = 2; 114041688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 114141688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 114241688679SZoran Jovanovic res = 3; 114341688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 114441688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 114541688679SZoran Jovanovic res = 4; 114641688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 114741688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 114841688679SZoran Jovanovic res = 5; 114941688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 115041688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 115141688679SZoran Jovanovic res = 6; 115241688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 115341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 115441688679SZoran Jovanovic res = 7; 115541688679SZoran Jovanovic 115641688679SZoran Jovanovic return res; 115741688679SZoran Jovanovic } 115841688679SZoran Jovanovic 115941688679SZoran Jovanovic unsigned 11602c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 11612c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 11622c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 11632c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 11642c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 11652c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 11662c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 11672c6d7320SJozef Kolek assert((Res & 3) == 0); 11682c6d7320SJozef Kolek return Res >> 2; 11692c6d7320SJozef Kolek } 11702c6d7320SJozef Kolek 1171b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1172