19f610119SJia Liu //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===// 2750ecec7SAkira Hatanaka // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6750ecec7SAkira Hatanaka // 7750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===// 8750ecec7SAkira Hatanaka // 9750ecec7SAkira Hatanaka // This file implements the MipsMCCodeEmitter class. 10750ecec7SAkira Hatanaka // 11750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===// 129e1450bcSMatheus Almeida 136bda14b3SChandler Carruth #include "MipsMCCodeEmitter.h" 14c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsFixupKinds.h" 15a5da588bSPetar Jovanovic #include "MCTargetDesc/MipsMCExpr.h" 16c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsMCTargetDesc.h" 17c85e3ff3SBruno Cardoso Lopes #include "llvm/ADT/APFloat.h" 18926883e1SEugene Zelenko #include "llvm/ADT/APInt.h" 199e1450bcSMatheus Almeida #include "llvm/ADT/SmallVector.h" 205d6faed1SAkira Hatanaka #include "llvm/MC/MCContext.h" 21750ecec7SAkira Hatanaka #include "llvm/MC/MCExpr.h" 22d9903888SChandler Carruth #include "llvm/MC/MCFixup.h" 23750ecec7SAkira Hatanaka #include "llvm/MC/MCInst.h" 24926883e1SEugene Zelenko #include "llvm/MC/MCInstrDesc.h" 25750ecec7SAkira Hatanaka #include "llvm/MC/MCInstrInfo.h" 263de83e40SPete Cooper #include "llvm/MC/MCRegisterInfo.h" 27750ecec7SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h" 28926883e1SEugene Zelenko #include "llvm/Support/Casting.h" 29926883e1SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 30750ecec7SAkira Hatanaka #include "llvm/Support/raw_ostream.h" 31926883e1SEugene Zelenko #include <cassert> 32926883e1SEugene Zelenko #include <cstdint> 33926883e1SEugene Zelenko 34926883e1SEugene Zelenko using namespace llvm; 35750ecec7SAkira Hatanaka 3684e68b29SChandler Carruth #define DEBUG_TYPE "mccodeemitter" 3784e68b29SChandler Carruth 38be6a818fSAkira Hatanaka #define GET_INSTRMAP_INFO 39be6a818fSAkira Hatanaka #include "MipsGenInstrInfo.inc" 409e1450bcSMatheus Almeida #undef GET_INSTRMAP_INFO 41be6a818fSAkira Hatanaka 429e1450bcSMatheus Almeida namespace llvm { 43926883e1SEugene Zelenko 449e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 45c3b04279SJim Grosbach const MCRegisterInfo &MRI, 469e1450bcSMatheus Almeida MCContext &Ctx) { 47d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, false); 481ee768dbSAkira Hatanaka } 491ee768dbSAkira Hatanaka 509e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 51c3b04279SJim Grosbach const MCRegisterInfo &MRI, 529e1450bcSMatheus Almeida MCContext &Ctx) { 53d2cca113SDavid Woodhouse return new MipsMCCodeEmitter(MCII, Ctx, true); 54750ecec7SAkira Hatanaka } 55926883e1SEugene Zelenko 56926883e1SEugene Zelenko } // end namespace llvm 57f30f2cceSRafael Espindola 58f30f2cceSRafael Espindola // If the D<shift> instruction has a shift amount that is greater 59f30f2cceSRafael Espindola // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 60f30f2cceSRafael Espindola static void LowerLargeShift(MCInst& Inst) { 61f30f2cceSRafael Espindola assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 62f30f2cceSRafael Espindola assert(Inst.getOperand(2).isImm()); 63f30f2cceSRafael Espindola 64f30f2cceSRafael Espindola int64_t Shift = Inst.getOperand(2).getImm(); 65f30f2cceSRafael Espindola if (Shift <= 31) 66f30f2cceSRafael Espindola return; // Do nothing 67f30f2cceSRafael Espindola Shift -= 32; 68f30f2cceSRafael Espindola 69f30f2cceSRafael Espindola // saminus32 70f30f2cceSRafael Espindola Inst.getOperand(2).setImm(Shift); 71f30f2cceSRafael Espindola 72f30f2cceSRafael Espindola switch (Inst.getOpcode()) { 73f30f2cceSRafael Espindola default: 74f30f2cceSRafael Espindola // Calling function is not synchronized 75f30f2cceSRafael Espindola llvm_unreachable("Unexpected shift instruction"); 76f30f2cceSRafael Espindola case Mips::DSLL: 77f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSLL32); 78f30f2cceSRafael Espindola return; 79f30f2cceSRafael Espindola case Mips::DSRL: 80f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRL32); 81f30f2cceSRafael Espindola return; 82f30f2cceSRafael Espindola case Mips::DSRA: 83f30f2cceSRafael Espindola Inst.setOpcode(Mips::DSRA32); 84f30f2cceSRafael Espindola return; 856a3fe574SAkira Hatanaka case Mips::DROTR: 866a3fe574SAkira Hatanaka Inst.setOpcode(Mips::DROTR32); 876a3fe574SAkira Hatanaka return; 88f30f2cceSRafael Espindola } 89f30f2cceSRafael Espindola } 90f30f2cceSRafael Espindola 91669d8dd8SSimon Dardis // Fix a bad compact branch encoding for beqc/bnec. 92669d8dd8SSimon Dardis void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { 93669d8dd8SSimon Dardis // Encoding may be illegal !(rs < rt), but this situation is 94669d8dd8SSimon Dardis // easily fixed. 95669d8dd8SSimon Dardis unsigned RegOp0 = Inst.getOperand(0).getReg(); 96669d8dd8SSimon Dardis unsigned RegOp1 = Inst.getOperand(1).getReg(); 97669d8dd8SSimon Dardis 98669d8dd8SSimon Dardis unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); 99669d8dd8SSimon Dardis unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); 100669d8dd8SSimon Dardis 10168a204ddSSimon Dardis if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC || 10268a204ddSSimon Dardis Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) { 103669d8dd8SSimon Dardis assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!"); 104669d8dd8SSimon Dardis if (Reg0 < Reg1) 105669d8dd8SSimon Dardis return; 106b60833c0SSimon Dardis } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) { 107b60833c0SSimon Dardis if (Reg0 >= Reg1) 108b60833c0SSimon Dardis return; 109c962c493SHrvoje Varga } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || 110c962c493SHrvoje Varga Inst.getOpcode() == Mips::BOVC_MMR6) { 111c962c493SHrvoje Varga if (Reg1 >= Reg0) 112c962c493SHrvoje Varga return; 113b60833c0SSimon Dardis } else 114b60833c0SSimon Dardis llvm_unreachable("Cannot rewrite unknown branch!"); 115669d8dd8SSimon Dardis 116669d8dd8SSimon Dardis Inst.getOperand(0).setReg(RegOp1); 117669d8dd8SSimon Dardis Inst.getOperand(1).setReg(RegOp0); 118669d8dd8SSimon Dardis } 119669d8dd8SSimon Dardis 1209e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 121db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMicroMips]; 1229e1450bcSMatheus Almeida } 1239e1450bcSMatheus Almeida 124c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { 125db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 126c22555d9SJozef Kolek } 127c22555d9SJozef Kolek 1289e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 1299e1450bcSMatheus Almeida OS << (char)C; 1309e1450bcSMatheus Almeida } 1319e1450bcSMatheus Almeida 1329e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 1339e1450bcSMatheus Almeida const MCSubtargetInfo &STI, 1349e1450bcSMatheus Almeida raw_ostream &OS) const { 1359e1450bcSMatheus Almeida // Output the instruction encoding in little endian byte order. 1369e1450bcSMatheus Almeida // Little-endian byte ordering: 1379e1450bcSMatheus Almeida // mips32r2: 4 | 3 | 2 | 1 1389e1450bcSMatheus Almeida // microMIPS: 2 | 1 | 4 | 3 1399e1450bcSMatheus Almeida if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 1409e1450bcSMatheus Almeida EmitInstruction(Val >> 16, 2, STI, OS); 1419e1450bcSMatheus Almeida EmitInstruction(Val, 2, STI, OS); 1429e1450bcSMatheus Almeida } else { 1439e1450bcSMatheus Almeida for (unsigned i = 0; i < Size; ++i) { 1449e1450bcSMatheus Almeida unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 1459e1450bcSMatheus Almeida EmitByte((Val >> Shift) & 0xff, OS); 1469e1450bcSMatheus Almeida } 1479e1450bcSMatheus Almeida } 1489e1450bcSMatheus Almeida } 1499e1450bcSMatheus Almeida 15091df21f7SJim Grosbach /// encodeInstruction - Emit the instruction. 1514e07b95dSJack Carter /// Size the instruction with Desc.getSize(). 152c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter:: 15391df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS, 1549784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 1559784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const 156c85e3ff3SBruno Cardoso Lopes { 157aa7aeaa0SJack Carter // Non-pseudo instructions that get changed for direct object 158aa7aeaa0SJack Carter // only based on operand values. 159aa7aeaa0SJack Carter // If this list of instructions get much longer we will move 160aa7aeaa0SJack Carter // the check to a function call. Until then, this is more efficient. 161aa7aeaa0SJack Carter MCInst TmpInst = MI; 162aa7aeaa0SJack Carter switch (MI.getOpcode()) { 163aa7aeaa0SJack Carter // If shift amount is >= 32 it the inst needs to be lowered further 164aa7aeaa0SJack Carter case Mips::DSLL: 165aa7aeaa0SJack Carter case Mips::DSRL: 166aa7aeaa0SJack Carter case Mips::DSRA: 1676a3fe574SAkira Hatanaka case Mips::DROTR: 168f30f2cceSRafael Espindola LowerLargeShift(TmpInst); 169aa7aeaa0SJack Carter break; 170b60833c0SSimon Dardis // Compact branches, enforce encoding restrictions. 171669d8dd8SSimon Dardis case Mips::BEQC: 172669d8dd8SSimon Dardis case Mips::BNEC: 17368a204ddSSimon Dardis case Mips::BEQC64: 17468a204ddSSimon Dardis case Mips::BNEC64: 175b60833c0SSimon Dardis case Mips::BOVC: 176c962c493SHrvoje Varga case Mips::BOVC_MMR6: 177b60833c0SSimon Dardis case Mips::BNVC: 178c962c493SHrvoje Varga case Mips::BNVC_MMR6: 179669d8dd8SSimon Dardis LowerCompactBranch(TmpInst); 180aa7aeaa0SJack Carter } 181aa7aeaa0SJack Carter 18297700977SJack Carter unsigned long N = Fixups.size(); 1833fa98a65SDavid Woodhouse uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 184c85e3ff3SBruno Cardoso Lopes 185c85e3ff3SBruno Cardoso Lopes // Check for unimplemented opcodes. 186aa7aeaa0SJack Carter // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 187c85e3ff3SBruno Cardoso Lopes // so we have to special check for them. 188aa7aeaa0SJack Carter unsigned Opcode = TmpInst.getOpcode(); 189c7e220f6SJozef Kolek if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && 1901ade566cSSimon Dardis (Opcode != Mips::SLL_MM) && (Opcode != Mips::SLL_MMR6) && !Binary) 19191df21f7SJim Grosbach llvm_unreachable("unimplemented opcode in encodeInstruction()"); 192c85e3ff3SBruno Cardoso Lopes 193b59a5419SZoran Jovanovic int NewOpcode = -1; 1946ca13eafSJozef Kolek if (isMicroMips(STI)) { 195b59a5419SZoran Jovanovic if (isMips32r6(STI)) { 196b59a5419SZoran Jovanovic NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 197b59a5419SZoran Jovanovic if (NewOpcode == -1) 198b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); 199b59a5419SZoran Jovanovic } 200b59a5419SZoran Jovanovic else 201b59a5419SZoran Jovanovic NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); 202b59a5419SZoran Jovanovic 2032e386d3dSZoran Jovanovic // Check whether it is Dsp instruction. 2042e386d3dSZoran Jovanovic if (NewOpcode == -1) 2052e386d3dSZoran Jovanovic NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); 2062e386d3dSZoran Jovanovic 207be6a818fSAkira Hatanaka if (NewOpcode != -1) { 20897700977SJack Carter if (Fixups.size() > N) 20997700977SJack Carter Fixups.pop_back(); 210b59a5419SZoran Jovanovic 211be6a818fSAkira Hatanaka Opcode = NewOpcode; 212be6a818fSAkira Hatanaka TmpInst.setOpcode (NewOpcode); 2133fa98a65SDavid Woodhouse Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 214be6a818fSAkira Hatanaka } 215852dd83bSSimon Atanasyan 216852dd83bSSimon Atanasyan if (((MI.getOpcode() == Mips::MOVEP_MM) || 217852dd83bSSimon Atanasyan (MI.getOpcode() == Mips::MOVEP_MMR6))) { 218852dd83bSSimon Atanasyan unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI); 219852dd83bSSimon Atanasyan Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7); 220852dd83bSSimon Atanasyan } 221be6a818fSAkira Hatanaka } 222be6a818fSAkira Hatanaka 223aa7aeaa0SJack Carter const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 224c85e3ff3SBruno Cardoso Lopes 2255b5559d3SJack Carter // Get byte count of instruction 2265b5559d3SJack Carter unsigned Size = Desc.getSize(); 2275b5559d3SJack Carter if (!Size) 2285b5559d3SJack Carter llvm_unreachable("Desc.getSize() returns 0"); 229c85e3ff3SBruno Cardoso Lopes 230d2cca113SDavid Woodhouse EmitInstruction(Binary, Size, STI, OS); 231c85e3ff3SBruno Cardoso Lopes } 232c85e3ff3SBruno Cardoso Lopes 233c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch 234c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 235c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 236c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 237c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2383fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 2393fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 240c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 24171e6a749SJack Carter 2424f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 2434f69a0f2SJack Carter if (MO.isImm()) return MO.getImm() >> 2; 2444f69a0f2SJack Carter 24571e6a749SJack Carter assert(MO.isExpr() && 24671e6a749SJack Carter "getBranchTargetOpValue expects only expressions or immediates"); 247c85e3ff3SBruno Cardoso Lopes 248b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 249b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 250b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 251c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_PC16))); 252c85e3ff3SBruno Cardoso Lopes return 0; 253c85e3ff3SBruno Cardoso Lopes } 254c85e3ff3SBruno Cardoso Lopes 2556f09cdfdSHrvoje Varga /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch 2566f09cdfdSHrvoje Varga /// target operand. If the machine operand requires relocation, 2576f09cdfdSHrvoje Varga /// record the relocation and return zero. 2586f09cdfdSHrvoje Varga unsigned MipsMCCodeEmitter:: 2596f09cdfdSHrvoje Varga getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, 2606f09cdfdSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 2616f09cdfdSHrvoje Varga const MCSubtargetInfo &STI) const { 2626f09cdfdSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 2636f09cdfdSHrvoje Varga 2646f09cdfdSHrvoje Varga // If the destination is an immediate, divide by 2. 2656f09cdfdSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 1; 2666f09cdfdSHrvoje Varga 2676f09cdfdSHrvoje Varga assert(MO.isExpr() && 2686f09cdfdSHrvoje Varga "getBranchTargetOpValue expects only expressions or immediates"); 2696f09cdfdSHrvoje Varga 2706f09cdfdSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 2716f09cdfdSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 2726f09cdfdSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 2736f09cdfdSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 2746f09cdfdSHrvoje Varga return 0; 2756f09cdfdSHrvoje Varga } 2766f09cdfdSHrvoje Varga 277c962c493SHrvoje Varga /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch 278c962c493SHrvoje Varga /// target operand. If the machine operand requires relocation, 279c962c493SHrvoje Varga /// record the relocation and return zero. 280c962c493SHrvoje Varga unsigned MipsMCCodeEmitter:: 281c962c493SHrvoje Varga getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, 282c962c493SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 283c962c493SHrvoje Varga const MCSubtargetInfo &STI) const { 284c962c493SHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 285c962c493SHrvoje Varga 286c962c493SHrvoje Varga // If the destination is an immediate, divide by 2. 287c962c493SHrvoje Varga if (MO.isImm()) 288c962c493SHrvoje Varga return MO.getImm() >> 1; 289c962c493SHrvoje Varga 290c962c493SHrvoje Varga assert(MO.isExpr() && 291c962c493SHrvoje Varga "getBranchTargetOpValueMMR6 expects only expressions or immediates"); 292c962c493SHrvoje Varga 293c962c493SHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 294c962c493SHrvoje Varga MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); 295c962c493SHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 296c962c493SHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 297c962c493SHrvoje Varga return 0; 298c962c493SHrvoje Varga } 299c962c493SHrvoje Varga 300f0ed16eaSHrvoje Varga /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch 301f0ed16eaSHrvoje Varga /// target operand. If the machine operand requires relocation, 302f0ed16eaSHrvoje Varga /// record the relocation and return zero. 303f0ed16eaSHrvoje Varga unsigned MipsMCCodeEmitter:: 304f0ed16eaSHrvoje Varga getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, 305f0ed16eaSHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 306f0ed16eaSHrvoje Varga const MCSubtargetInfo &STI) const { 307f0ed16eaSHrvoje Varga const MCOperand &MO = MI.getOperand(OpNo); 308f0ed16eaSHrvoje Varga 309f0ed16eaSHrvoje Varga // If the destination is an immediate, divide by 4. 310f0ed16eaSHrvoje Varga if (MO.isImm()) 311f0ed16eaSHrvoje Varga return MO.getImm() >> 2; 312f0ed16eaSHrvoje Varga 313f0ed16eaSHrvoje Varga assert(MO.isExpr() && 314f0ed16eaSHrvoje Varga "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates"); 315f0ed16eaSHrvoje Varga 316f0ed16eaSHrvoje Varga const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 317f0ed16eaSHrvoje Varga MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 318f0ed16eaSHrvoje Varga Fixups.push_back(MCFixup::create(0, FixupExpression, 319f0ed16eaSHrvoje Varga MCFixupKind(Mips::fixup_Mips_PC16))); 320f0ed16eaSHrvoje Varga return 0; 321f0ed16eaSHrvoje Varga } 322f0ed16eaSHrvoje Varga 3239761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch 3249761e96bSJozef Kolek /// target operand. If the machine operand requires relocation, 3259761e96bSJozef Kolek /// record the relocation and return zero. 3269761e96bSJozef Kolek unsigned MipsMCCodeEmitter:: 3279761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, 3289761e96bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3299761e96bSJozef Kolek const MCSubtargetInfo &STI) const { 3309761e96bSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3319761e96bSJozef Kolek 3329761e96bSJozef Kolek // If the destination is an immediate, divide by 2. 3339761e96bSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3349761e96bSJozef Kolek 3359761e96bSJozef Kolek assert(MO.isExpr() && 3369761e96bSJozef Kolek "getBranchTargetOpValueMM expects only expressions or immediates"); 3379761e96bSJozef Kolek 3389761e96bSJozef Kolek const MCExpr *Expr = MO.getExpr(); 33963661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3409761e96bSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); 3419761e96bSJozef Kolek return 0; 3429761e96bSJozef Kolek } 3439761e96bSJozef Kolek 3445cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 3455cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation, 3465cfebddeSJozef Kolek /// record the relocation and return zero. 3475cfebddeSJozef Kolek unsigned MipsMCCodeEmitter:: 3485cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, 3495cfebddeSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 3505cfebddeSJozef Kolek const MCSubtargetInfo &STI) const { 3515cfebddeSJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 3525cfebddeSJozef Kolek 3535cfebddeSJozef Kolek // If the destination is an immediate, divide by 2. 3545cfebddeSJozef Kolek if (MO.isImm()) return MO.getImm() >> 1; 3555cfebddeSJozef Kolek 3565cfebddeSJozef Kolek assert(MO.isExpr() && 3575cfebddeSJozef Kolek "getBranchTargetOpValuePC10 expects only expressions or immediates"); 3585cfebddeSJozef Kolek 3595cfebddeSJozef Kolek const MCExpr *Expr = MO.getExpr(); 36063661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3615cfebddeSJozef Kolek MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); 3625cfebddeSJozef Kolek return 0; 3635cfebddeSJozef Kolek } 3645cfebddeSJozef Kolek 3658a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 3668a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation, 3678a80aa76SZoran Jovanovic /// record the relocation and return zero. 3688a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter:: 3698a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 3703fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 3713fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 3728a80aa76SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3738a80aa76SZoran Jovanovic 3748a80aa76SZoran Jovanovic // If the destination is an immediate, divide by 2. 3758a80aa76SZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 3768a80aa76SZoran Jovanovic 3778a80aa76SZoran Jovanovic assert(MO.isExpr() && 3788a80aa76SZoran Jovanovic "getBranchTargetOpValueMM expects only expressions or immediates"); 3798a80aa76SZoran Jovanovic 3808a80aa76SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 38163661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 3828a80aa76SZoran Jovanovic MCFixupKind(Mips:: 3838a80aa76SZoran Jovanovic fixup_MICROMIPS_PC16_S1))); 3848a80aa76SZoran Jovanovic return 0; 3858a80aa76SZoran Jovanovic } 3868a80aa76SZoran Jovanovic 3873c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch 3883c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 3893c8869dcSZoran Jovanovic /// record the relocation and return zero. 3903c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 3913c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 3923c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 3933c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 3943c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 3953c8869dcSZoran Jovanovic 3963c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 3973c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 3983c8869dcSZoran Jovanovic 3993c8869dcSZoran Jovanovic assert(MO.isExpr() && 4003c8869dcSZoran Jovanovic "getBranchTarget21OpValue expects only expressions or immediates"); 4013c8869dcSZoran Jovanovic 402b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 403b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 404b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 40510e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 4063c8869dcSZoran Jovanovic return 0; 4073c8869dcSZoran Jovanovic } 4083c8869dcSZoran Jovanovic 40984e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch 41084e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires 41184e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero. 41284e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter:: 41384e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, 41484e4d59eSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 41584e4d59eSZoran Jovanovic const MCSubtargetInfo &STI) const { 41684e4d59eSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 41784e4d59eSZoran Jovanovic 418f0ed16eaSHrvoje Varga // If the destination is an immediate, divide by 4. 419f0ed16eaSHrvoje Varga if (MO.isImm()) return MO.getImm() >> 2; 42084e4d59eSZoran Jovanovic 42184e4d59eSZoran Jovanovic assert(MO.isExpr() && 42284e4d59eSZoran Jovanovic "getBranchTarget21OpValueMM expects only expressions or immediates"); 42384e4d59eSZoran Jovanovic 4245f94cedeSZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 4255f94cedeSZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 4265f94cedeSZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 4275f94cedeSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); 42884e4d59eSZoran Jovanovic return 0; 42984e4d59eSZoran Jovanovic } 43084e4d59eSZoran Jovanovic 4313c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch 4323c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation, 4333c8869dcSZoran Jovanovic /// record the relocation and return zero. 4343c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter:: 4353c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 4363c8869dcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 4373c8869dcSZoran Jovanovic const MCSubtargetInfo &STI) const { 4383c8869dcSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 4393c8869dcSZoran Jovanovic 4403c8869dcSZoran Jovanovic // If the destination is an immediate, divide by 4. 4413c8869dcSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 2; 4423c8869dcSZoran Jovanovic 4433c8869dcSZoran Jovanovic assert(MO.isExpr() && 4443c8869dcSZoran Jovanovic "getBranchTarget26OpValue expects only expressions or immediates"); 4453c8869dcSZoran Jovanovic 446b7915a1fSPetar Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 447b7915a1fSPetar Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 448b7915a1fSPetar Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 44910e06da0SZoran Jovanovic MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 4503c8869dcSZoran Jovanovic return 0; 4513c8869dcSZoran Jovanovic } 4523c8869dcSZoran Jovanovic 453a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch 454a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation, 455a887b361SZoran Jovanovic /// record the relocation and return zero. 456a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( 457a887b361SZoran Jovanovic const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, 458a887b361SZoran Jovanovic const MCSubtargetInfo &STI) const { 459a887b361SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 460a887b361SZoran Jovanovic 461a887b361SZoran Jovanovic // If the destination is an immediate, divide by 2. 462a887b361SZoran Jovanovic if (MO.isImm()) 463a887b361SZoran Jovanovic return MO.getImm() >> 1; 464a887b361SZoran Jovanovic 46502b70030SZoran Jovanovic assert(MO.isExpr() && 46602b70030SZoran Jovanovic "getBranchTarget26OpValueMM expects only expressions or immediates"); 46702b70030SZoran Jovanovic 46802b70030SZoran Jovanovic const MCExpr *FixupExpression = MCBinaryExpr::createAdd( 46902b70030SZoran Jovanovic MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); 47002b70030SZoran Jovanovic Fixups.push_back(MCFixup::create(0, FixupExpression, 47102b70030SZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); 472a887b361SZoran Jovanovic return 0; 473a887b361SZoran Jovanovic } 474a887b361SZoran Jovanovic 47552c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump 47652c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation, 47752c56b93SZoran Jovanovic /// record the relocation and return zero. 47852c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter:: 47952c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 48052c56b93SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 48152c56b93SZoran Jovanovic const MCSubtargetInfo &STI) const { 48252c56b93SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 48352c56b93SZoran Jovanovic 48452c56b93SZoran Jovanovic if (MO.isImm()) return MO.getImm(); 48552c56b93SZoran Jovanovic 48652c56b93SZoran Jovanovic assert(MO.isExpr() && 48752c56b93SZoran Jovanovic "getJumpOffset16OpValue expects only expressions or an immediate"); 48852c56b93SZoran Jovanovic 48952c56b93SZoran Jovanovic // TODO: Push fixup. 49052c56b93SZoran Jovanovic return 0; 49152c56b93SZoran Jovanovic } 49252c56b93SZoran Jovanovic 493c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump 494c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation, 495c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero. 496c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 497c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 4983fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 4993fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 500c85e3ff3SBruno Cardoso Lopes const MCOperand &MO = MI.getOperand(OpNo); 5014f69a0f2SJack Carter // If the destination is an immediate, divide by 4. 5024f69a0f2SJack Carter if (MO.isImm()) return MO.getImm()>>2; 5034f69a0f2SJack Carter 50471e6a749SJack Carter assert(MO.isExpr() && 50571e6a749SJack Carter "getJumpTargetOpValue expects only expressions or an immediate"); 506c85e3ff3SBruno Cardoso Lopes 507c85e3ff3SBruno Cardoso Lopes const MCExpr *Expr = MO.getExpr(); 50863661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 509c85e3ff3SBruno Cardoso Lopes MCFixupKind(Mips::fixup_Mips_26))); 510c85e3ff3SBruno Cardoso Lopes return 0; 511c85e3ff3SBruno Cardoso Lopes } 512c85e3ff3SBruno Cardoso Lopes 513c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter:: 514507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 5153fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 5163fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 517507e084aSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 518507e084aSZoran Jovanovic // If the destination is an immediate, divide by 2. 519507e084aSZoran Jovanovic if (MO.isImm()) return MO.getImm() >> 1; 520507e084aSZoran Jovanovic 521507e084aSZoran Jovanovic assert(MO.isExpr() && 522507e084aSZoran Jovanovic "getJumpTargetOpValueMM expects only expressions or an immediate"); 523507e084aSZoran Jovanovic 524507e084aSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 52563661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, 526507e084aSZoran Jovanovic MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 527507e084aSZoran Jovanovic return 0; 528507e084aSZoran Jovanovic } 529507e084aSZoran Jovanovic 530507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter:: 531c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 532c74e3eb9SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 533c74e3eb9SZoran Jovanovic const MCSubtargetInfo &STI) const { 534c74e3eb9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 535c74e3eb9SZoran Jovanovic if (MO.isImm()) { 536c74e3eb9SZoran Jovanovic // The immediate is encoded as 'immediate << 2'. 537c74e3eb9SZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 538c74e3eb9SZoran Jovanovic assert((Res & 3) == 0); 539c74e3eb9SZoran Jovanovic return Res >> 2; 540c74e3eb9SZoran Jovanovic } 541c74e3eb9SZoran Jovanovic 542c74e3eb9SZoran Jovanovic assert(MO.isExpr() && 543c74e3eb9SZoran Jovanovic "getUImm5Lsl2Encoding expects only expressions or an immediate"); 544c74e3eb9SZoran Jovanovic 545c74e3eb9SZoran Jovanovic return 0; 546c74e3eb9SZoran Jovanovic } 547c74e3eb9SZoran Jovanovic 548c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter:: 549bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, 550bac3619bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 551bac3619bSZoran Jovanovic const MCSubtargetInfo &STI) const { 552bac3619bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 553bac3619bSZoran Jovanovic if (MO.isImm()) { 554bac3619bSZoran Jovanovic int Value = MO.getImm(); 555bac3619bSZoran Jovanovic return Value >> 2; 556bac3619bSZoran Jovanovic } 557bac3619bSZoran Jovanovic 558bac3619bSZoran Jovanovic return 0; 559bac3619bSZoran Jovanovic } 560bac3619bSZoran Jovanovic 561bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter:: 56242b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, 56342b84443SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 56442b84443SZoran Jovanovic const MCSubtargetInfo &STI) const { 56542b84443SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 56642b84443SZoran Jovanovic if (MO.isImm()) { 56742b84443SZoran Jovanovic unsigned Value = MO.getImm(); 56842b84443SZoran Jovanovic return Value >> 2; 56942b84443SZoran Jovanovic } 57042b84443SZoran Jovanovic 57142b84443SZoran Jovanovic return 0; 57242b84443SZoran Jovanovic } 57342b84443SZoran Jovanovic 57442b84443SZoran Jovanovic unsigned MipsMCCodeEmitter:: 57598bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, 57698bd58caSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 57798bd58caSZoran Jovanovic const MCSubtargetInfo &STI) const { 57898bd58caSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 57998bd58caSZoran Jovanovic if (MO.isImm()) { 58098bd58caSZoran Jovanovic unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; 58198bd58caSZoran Jovanovic return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); 58298bd58caSZoran Jovanovic } 58398bd58caSZoran Jovanovic 58498bd58caSZoran Jovanovic return 0; 58598bd58caSZoran Jovanovic } 58698bd58caSZoran Jovanovic 58798bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter:: 5883fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, 5893fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 590b5cf5909SJack Carter int64_t Res; 591049e9e4dSAkira Hatanaka 59213760bd1SJim Grosbach if (Expr->evaluateAsAbsolute(Res)) 593b5cf5909SJack Carter return Res; 594fe384a2cSAkira Hatanaka 595fe384a2cSAkira Hatanaka MCExpr::ExprKind Kind = Expr->getKind(); 596b5cf5909SJack Carter if (Kind == MCExpr::Constant) { 597b5cf5909SJack Carter return cast<MCConstantExpr>(Expr)->getValue(); 598b5cf5909SJack Carter } 599fe384a2cSAkira Hatanaka 600fe384a2cSAkira Hatanaka if (Kind == MCExpr::Binary) { 6013fa98a65SDavid Woodhouse unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 6023fa98a65SDavid Woodhouse Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 603b5cf5909SJack Carter return Res; 604fe384a2cSAkira Hatanaka } 605a5da588bSPetar Jovanovic 606a5da588bSPetar Jovanovic if (Kind == MCExpr::Target) { 607a5da588bSPetar Jovanovic const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 608a5da588bSPetar Jovanovic 609a5da588bSPetar Jovanovic Mips::Fixups FixupKind = Mips::Fixups(0); 610a5da588bSPetar Jovanovic switch (MipsExpr->getKind()) { 611fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_None: 612fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_Special: 613fe98b2f5SDaniel Sanders llvm_unreachable("Unhandled fixup kind!"); 614fe98b2f5SDaniel Sanders break; 615f76884b0SSimon Atanasyan case MipsMCExpr::MEK_DTPREL: 616f76884b0SSimon Atanasyan llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); 617f76884b0SSimon Atanasyan break; 618fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_HI16: 619fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_HI16; 620fe98b2f5SDaniel Sanders break; 621fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_CALL_LO16: 622fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_CALL_LO16; 623fe98b2f5SDaniel Sanders break; 624fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_HI: 625fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 626fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_HI; 627fe98b2f5SDaniel Sanders break; 628fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_DTPREL_LO: 629fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 630fe98b2f5SDaniel Sanders : Mips::fixup_Mips_DTPREL_LO; 631fe98b2f5SDaniel Sanders break; 632fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOTTPREL: 6333979f438SSimon Atanasyan FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL 6343979f438SSimon Atanasyan : Mips::fixup_Mips_GOTTPREL; 635fe98b2f5SDaniel Sanders break; 636fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT: 637fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 638fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT; 639fe98b2f5SDaniel Sanders break; 640fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_CALL: 641fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 642fe98b2f5SDaniel Sanders : Mips::fixup_Mips_CALL16; 643fe98b2f5SDaniel Sanders break; 644fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_DISP: 645fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 646fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_DISP; 647fe98b2f5SDaniel Sanders break; 648fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_HI16: 649fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_HI16; 650fe98b2f5SDaniel Sanders break; 651fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_LO16: 652fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GOT_LO16; 653fe98b2f5SDaniel Sanders break; 654fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_PAGE: 655fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 656fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_PAGE; 657fe98b2f5SDaniel Sanders break; 658fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GOT_OFST: 659fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 660fe98b2f5SDaniel Sanders : Mips::fixup_Mips_GOT_OFST; 661fe98b2f5SDaniel Sanders break; 662fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_GPREL: 663fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_Mips_GPREL16; 664fe98b2f5SDaniel Sanders break; 665926883e1SEugene Zelenko case MipsMCExpr::MEK_LO: 666fe98b2f5SDaniel Sanders // Check for %lo(%neg(%gp_rel(X))) 667a1d69f9eSSimon Atanasyan if (MipsExpr->isGpOff()) 668a1d69f9eSSimon Atanasyan FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO 669a1d69f9eSSimon Atanasyan : Mips::fixup_Mips_GPOFF_LO; 670a1d69f9eSSimon Atanasyan else 671fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 672fe98b2f5SDaniel Sanders : Mips::fixup_Mips_LO16; 673fe98b2f5SDaniel Sanders break; 674fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHEST: 6756be87bceSSimon Atanasyan FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST 6766be87bceSSimon Atanasyan : Mips::fixup_Mips_HIGHEST; 67706c47803SSasa Stankovic break; 678fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HIGHER: 6796be87bceSSimon Atanasyan FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER 6806be87bceSSimon Atanasyan : Mips::fixup_Mips_HIGHER; 68106c47803SSasa Stankovic break; 682fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_HI: 683fe98b2f5SDaniel Sanders // Check for %hi(%neg(%gp_rel(X))) 684a1d69f9eSSimon Atanasyan if (MipsExpr->isGpOff()) 685a1d69f9eSSimon Atanasyan FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI 686a1d69f9eSSimon Atanasyan : Mips::fixup_Mips_GPOFF_HI; 687a1d69f9eSSimon Atanasyan else 688a5da588bSPetar Jovanovic FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 689a5da588bSPetar Jovanovic : Mips::fixup_Mips_HI16; 690a5da588bSPetar Jovanovic break; 691fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_HI16: 692fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCHI16; 693fe98b2f5SDaniel Sanders break; 694fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_PCREL_LO16: 695fe98b2f5SDaniel Sanders FixupKind = Mips::fixup_MIPS_PCLO16; 696fe98b2f5SDaniel Sanders break; 697fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSGD: 698fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 699fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSGD; 700fe98b2f5SDaniel Sanders break; 701fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TLSLDM: 702fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 703fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TLSLDM; 704fe98b2f5SDaniel Sanders break; 705fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_HI: 706fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 707fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_HI; 708fe98b2f5SDaniel Sanders break; 709fe98b2f5SDaniel Sanders case MipsMCExpr::MEK_TPREL_LO: 710fe98b2f5SDaniel Sanders FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 711fe98b2f5SDaniel Sanders : Mips::fixup_Mips_TPREL_LO; 712a5da588bSPetar Jovanovic break; 7133feeb9c8SDaniel Sanders case MipsMCExpr::MEK_NEG: 7143feeb9c8SDaniel Sanders FixupKind = 7153feeb9c8SDaniel Sanders isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; 7163feeb9c8SDaniel Sanders break; 717a5da588bSPetar Jovanovic } 71863661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); 719a5da588bSPetar Jovanovic return 0; 720a5da588bSPetar Jovanovic } 721a5da588bSPetar Jovanovic 722b5cf5909SJack Carter if (Kind == MCExpr::SymbolRef) { 723f9774c32SBill Wendling Mips::Fixups FixupKind = Mips::Fixups(0); 724e2eed964SAkira Hatanaka 725049e9e4dSAkira Hatanaka switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 726b9f9de93SJack Carter default: llvm_unreachable("Unknown fixup kind!"); 72760f1db05SDaniel Sanders break; 72860f1db05SDaniel Sanders case MCSymbolRefExpr::VK_None: 72960f1db05SDaniel Sanders FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. 730b9f9de93SJack Carter break; 731c85e3ff3SBruno Cardoso Lopes } // switch 732fe384a2cSAkira Hatanaka 73363661f8dSJim Grosbach Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 734fe384a2cSAkira Hatanaka return 0; 735c85e3ff3SBruno Cardoso Lopes } 736b5cf5909SJack Carter return 0; 737b5cf5909SJack Carter } 738b5cf5909SJack Carter 739b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine 740b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero. 741b5cf5909SJack Carter unsigned MipsMCCodeEmitter:: 742b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO, 7433fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7443fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 745b5cf5909SJack Carter if (MO.isReg()) { 746b5cf5909SJack Carter unsigned Reg = MO.getReg(); 747bc07a890SBill Wendling unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 748b5cf5909SJack Carter return RegNo; 749b5cf5909SJack Carter } else if (MO.isImm()) { 750b5cf5909SJack Carter return static_cast<unsigned>(MO.getImm()); 751b5cf5909SJack Carter } else if (MO.isFPImm()) { 752b5cf5909SJack Carter return static_cast<unsigned>(APFloat(MO.getFPImm()) 753b5cf5909SJack Carter .bitcastToAPInt().getHiBits(32).getLimitedValue()); 754b5cf5909SJack Carter } 755b5cf5909SJack Carter // MO must be an Expr. 756b5cf5909SJack Carter assert(MO.isExpr()); 7573fa98a65SDavid Woodhouse return getExprOpValue(MO.getExpr(),Fixups, STI); 758b5cf5909SJack Carter } 759c85e3ff3SBruno Cardoso Lopes 760dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand. 761c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation. 762dc0602a2SDaniel Sanders template <unsigned ShiftAmount> 763dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 7643fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 7653fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 766c85e3ff3SBruno Cardoso Lopes // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 767c85e3ff3SBruno Cardoso Lopes assert(MI.getOperand(OpNo).isReg()); 7683fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 7693fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 770c85e3ff3SBruno Cardoso Lopes 771dc0602a2SDaniel Sanders // Apply the scale factor if there is one. 772dc0602a2SDaniel Sanders OffBits >>= ShiftAmount; 773dc0602a2SDaniel Sanders 774c85e3ff3SBruno Cardoso Lopes return (OffBits & 0xFFFF) | RegBits; 775c85e3ff3SBruno Cardoso Lopes } 776c85e3ff3SBruno Cardoso Lopes 77797700977SJack Carter unsigned MipsMCCodeEmitter:: 778e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, 779e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 780e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 781e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 782e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 783e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 784e8c9d1eaSJozef Kolek Fixups, STI) << 4; 785e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 786e8c9d1eaSJozef Kolek Fixups, STI); 787e8c9d1eaSJozef Kolek 788e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 789e8c9d1eaSJozef Kolek } 790e8c9d1eaSJozef Kolek 791e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 792e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, 793e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 794e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 795e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 796e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 797e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 798e8c9d1eaSJozef Kolek Fixups, STI) << 4; 799e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 800e8c9d1eaSJozef Kolek Fixups, STI) >> 1; 801e8c9d1eaSJozef Kolek 802e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 803e8c9d1eaSJozef Kolek } 804e8c9d1eaSJozef Kolek 805e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 806e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, 807e8c9d1eaSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 808e8c9d1eaSJozef Kolek const MCSubtargetInfo &STI) const { 809e8c9d1eaSJozef Kolek // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. 810e8c9d1eaSJozef Kolek assert(MI.getOperand(OpNo).isReg()); 811e8c9d1eaSJozef Kolek unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), 812e8c9d1eaSJozef Kolek Fixups, STI) << 4; 813e8c9d1eaSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 814e8c9d1eaSJozef Kolek Fixups, STI) >> 2; 815e8c9d1eaSJozef Kolek 816e8c9d1eaSJozef Kolek return (OffBits & 0xF) | RegBits; 817e8c9d1eaSJozef Kolek } 818e8c9d1eaSJozef Kolek 819e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter:: 82012c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, 82112c6982bSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 82212c6982bSJozef Kolek const MCSubtargetInfo &STI) const { 82312c6982bSJozef Kolek // Register is encoded in bits 9-5, offset is encoded in bits 4-0. 82412c6982bSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 82568be5f21SZoran Jovanovic (MI.getOperand(OpNo).getReg() == Mips::SP || 82668be5f21SZoran Jovanovic MI.getOperand(OpNo).getReg() == Mips::SP_64) && 82712c6982bSJozef Kolek "Unexpected base register!"); 82812c6982bSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 82912c6982bSJozef Kolek Fixups, STI) >> 2; 83012c6982bSJozef Kolek 83112c6982bSJozef Kolek return OffBits & 0x1F; 83212c6982bSJozef Kolek } 83312c6982bSJozef Kolek 83412c6982bSJozef Kolek unsigned MipsMCCodeEmitter:: 835e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, 836e10a02ecSJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 837e10a02ecSJozef Kolek const MCSubtargetInfo &STI) const { 838e10a02ecSJozef Kolek // Register is encoded in bits 9-7, offset is encoded in bits 6-0. 839e10a02ecSJozef Kolek assert(MI.getOperand(OpNo).isReg() && 840e10a02ecSJozef Kolek MI.getOperand(OpNo).getReg() == Mips::GP && 841e10a02ecSJozef Kolek "Unexpected base register!"); 842e10a02ecSJozef Kolek 843e10a02ecSJozef Kolek unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), 844e10a02ecSJozef Kolek Fixups, STI) >> 2; 845e10a02ecSJozef Kolek 846e10a02ecSJozef Kolek return OffBits & 0x7F; 847e10a02ecSJozef Kolek } 848e10a02ecSJozef Kolek 8499eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter:: 8509eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, 8519eaa30d2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 8529eaa30d2SZoran Jovanovic const MCSubtargetInfo &STI) const { 8539eaa30d2SZoran Jovanovic // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. 8549eaa30d2SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 8559eaa30d2SZoran Jovanovic unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 8569eaa30d2SZoran Jovanovic STI) << 16; 8579eaa30d2SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); 8589eaa30d2SZoran Jovanovic 8599eaa30d2SZoran Jovanovic return (OffBits & 0x1FF) | RegBits; 8609eaa30d2SZoran Jovanovic } 8619eaa30d2SZoran Jovanovic 862e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter:: 863cba9f80bSZlatko Buljan getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, 864cba9f80bSZlatko Buljan SmallVectorImpl<MCFixup> &Fixups, 865cba9f80bSZlatko Buljan const MCSubtargetInfo &STI) const { 866cba9f80bSZlatko Buljan // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. 867cba9f80bSZlatko Buljan assert(MI.getOperand(OpNo).isReg()); 868cba9f80bSZlatko Buljan unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 869cba9f80bSZlatko Buljan STI) << 16; 870cba9f80bSZlatko Buljan unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 871cba9f80bSZlatko Buljan 872cba9f80bSZlatko Buljan return (OffBits & 0x07FF) | RegBits; 873cba9f80bSZlatko Buljan } 874cba9f80bSZlatko Buljan 875cba9f80bSZlatko Buljan unsigned MipsMCCodeEmitter:: 87697700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 8773fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 8783fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 879a4c4b5fcSZoran Jovanovic // opNum can be invalid if instruction had reglist as operand. 880a4c4b5fcSZoran Jovanovic // MemOperand is always last operand of instruction (base + offset). 881a4c4b5fcSZoran Jovanovic switch (MI.getOpcode()) { 882a4c4b5fcSZoran Jovanovic default: 883a4c4b5fcSZoran Jovanovic break; 884a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 885a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 886a4c4b5fcSZoran Jovanovic OpNo = MI.getNumOperands() - 2; 887a4c4b5fcSZoran Jovanovic break; 888a4c4b5fcSZoran Jovanovic } 889a4c4b5fcSZoran Jovanovic 89097700977SJack Carter // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 89197700977SJack Carter assert(MI.getOperand(OpNo).isReg()); 8923fa98a65SDavid Woodhouse unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 8933fa98a65SDavid Woodhouse unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 89497700977SJack Carter 89597700977SJack Carter return (OffBits & 0x0FFF) | RegBits; 8963c88fbd3SHrvoje Varga } 8973c88fbd3SHrvoje Varga 8983c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter:: 8993c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, 9003c88fbd3SHrvoje Varga SmallVectorImpl<MCFixup> &Fixups, 9013c88fbd3SHrvoje Varga const MCSubtargetInfo &STI) const { 9023c88fbd3SHrvoje Varga // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 9033c88fbd3SHrvoje Varga assert(MI.getOperand(OpNo).isReg()); 9043c88fbd3SHrvoje Varga unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, 9053c88fbd3SHrvoje Varga STI) << 16; 9063c88fbd3SHrvoje Varga unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 9073c88fbd3SHrvoje Varga 9083c88fbd3SHrvoje Varga return (OffBits & 0xFFFF) | RegBits; 90997700977SJack Carter } 91097700977SJack Carter 911f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter:: 912f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, 913f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 914f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 915f9a02500SZoran Jovanovic // opNum can be invalid if instruction had reglist as operand 916f9a02500SZoran Jovanovic // MemOperand is always last operand of instruction (base + offset) 917f9a02500SZoran Jovanovic switch (MI.getOpcode()) { 918f9a02500SZoran Jovanovic default: 919f9a02500SZoran Jovanovic break; 920f9a02500SZoran Jovanovic case Mips::SWM16_MM: 921797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 922f9a02500SZoran Jovanovic case Mips::LWM16_MM: 923797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 924f9a02500SZoran Jovanovic OpNo = MI.getNumOperands() - 2; 925f9a02500SZoran Jovanovic break; 926f9a02500SZoran Jovanovic } 927f9a02500SZoran Jovanovic 928f9a02500SZoran Jovanovic // Offset is encoded in bits 4-0. 929f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo).isReg()); 930f9a02500SZoran Jovanovic // Base register is always SP - thus it is not encoded. 931f9a02500SZoran Jovanovic assert(MI.getOperand(OpNo+1).isImm()); 932f9a02500SZoran Jovanovic unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 933f9a02500SZoran Jovanovic 934f9a02500SZoran Jovanovic return ((OffBits >> 2) & 0x0F); 935f9a02500SZoran Jovanovic } 936f9a02500SZoran Jovanovic 937049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding 938049e9e4dSAkira Hatanaka // 939c85e3ff3SBruno Cardoso Lopes unsigned 940c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 9413fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9423fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 943049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo-1).isImm()); 944049e9e4dSAkira Hatanaka assert(MI.getOperand(OpNo).isImm()); 9453fa98a65SDavid Woodhouse unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 9463fa98a65SDavid Woodhouse unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 947049e9e4dSAkira Hatanaka 94856b70de0SBruno Cardoso Lopes return Position + Size - 1; 949c85e3ff3SBruno Cardoso Lopes } 950c85e3ff3SBruno Cardoso Lopes 951ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 952779c5937SMatheus Almeida unsigned 953ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, 9543fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups, 9553fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const { 956779c5937SMatheus Almeida assert(MI.getOperand(OpNo).isImm()); 957ea4f653dSDaniel Sanders unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 958ea4f653dSDaniel Sanders Value -= Offset; 959ea4f653dSDaniel Sanders return Value; 960779c5937SMatheus Almeida } 961779c5937SMatheus Almeida 962b59e1a41SDaniel Sanders unsigned 963b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 964b59e1a41SDaniel Sanders SmallVectorImpl<MCFixup> &Fixups, 965b59e1a41SDaniel Sanders const MCSubtargetInfo &STI) const { 966b9c07f3bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 967b9c07f3bSZoran Jovanovic if (MO.isImm()) { 968b59e1a41SDaniel Sanders // The immediate is encoded as 'immediate << 2'. 969b9c07f3bSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 970b59e1a41SDaniel Sanders assert((Res & 3) == 0); 971b59e1a41SDaniel Sanders return Res >> 2; 972b59e1a41SDaniel Sanders } 973c85e3ff3SBruno Cardoso Lopes 974b9c07f3bSZoran Jovanovic assert(MO.isExpr() && 975b9c07f3bSZoran Jovanovic "getSimm19Lsl2Encoding expects only expressions or an immediate"); 976b9c07f3bSZoran Jovanovic 977b9c07f3bSZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 9786764fa78SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 9796764fa78SZoran Jovanovic : Mips::fixup_MIPS_PC19_S2; 9806764fa78SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 981b9c07f3bSZoran Jovanovic return 0; 982b9c07f3bSZoran Jovanovic } 983b9c07f3bSZoran Jovanovic 9842855142aSZoran Jovanovic unsigned 9852855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 9862855142aSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 9872855142aSZoran Jovanovic const MCSubtargetInfo &STI) const { 988a5acdcf9SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 989a5acdcf9SZoran Jovanovic if (MO.isImm()) { 9902855142aSZoran Jovanovic // The immediate is encoded as 'immediate << 3'. 9912855142aSZoran Jovanovic unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 9922855142aSZoran Jovanovic assert((Res & 7) == 0); 9932855142aSZoran Jovanovic return Res >> 3; 9942855142aSZoran Jovanovic } 9952855142aSZoran Jovanovic 996a5acdcf9SZoran Jovanovic assert(MO.isExpr() && 997a5acdcf9SZoran Jovanovic "getSimm18Lsl2Encoding expects only expressions or an immediate"); 998a5acdcf9SZoran Jovanovic 999a5acdcf9SZoran Jovanovic const MCExpr *Expr = MO.getExpr(); 10008e366822SZoran Jovanovic Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 10018e366822SZoran Jovanovic : Mips::fixup_MIPS_PC18_S3; 10028e366822SZoran Jovanovic Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); 1003a5acdcf9SZoran Jovanovic return 0; 1004a5acdcf9SZoran Jovanovic } 1005a5acdcf9SZoran Jovanovic 10064a00fdc2SZoran Jovanovic unsigned 10074a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, 10084a00fdc2SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10094a00fdc2SZoran Jovanovic const MCSubtargetInfo &STI) const { 10104a00fdc2SZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10114a00fdc2SZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10124a00fdc2SZoran Jovanovic return MO.getImm() % 8; 10134a00fdc2SZoran Jovanovic } 10144a00fdc2SZoran Jovanovic 10158853171bSZoran Jovanovic unsigned 10168853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, 10178853171bSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 10188853171bSZoran Jovanovic const MCSubtargetInfo &STI) const { 10198853171bSZoran Jovanovic assert(MI.getOperand(OpNo).isImm()); 10208853171bSZoran Jovanovic const MCOperand &MO = MI.getOperand(OpNo); 10218853171bSZoran Jovanovic unsigned Value = MO.getImm(); 10228853171bSZoran Jovanovic switch (Value) { 10238853171bSZoran Jovanovic case 128: return 0x0; 10248853171bSZoran Jovanovic case 1: return 0x1; 10258853171bSZoran Jovanovic case 2: return 0x2; 10268853171bSZoran Jovanovic case 3: return 0x3; 10278853171bSZoran Jovanovic case 4: return 0x4; 10288853171bSZoran Jovanovic case 7: return 0x5; 10298853171bSZoran Jovanovic case 8: return 0x6; 10308853171bSZoran Jovanovic case 15: return 0x7; 10318853171bSZoran Jovanovic case 16: return 0x8; 10328853171bSZoran Jovanovic case 31: return 0x9; 10338853171bSZoran Jovanovic case 32: return 0xa; 10348853171bSZoran Jovanovic case 63: return 0xb; 10358853171bSZoran Jovanovic case 64: return 0xc; 10368853171bSZoran Jovanovic case 255: return 0xd; 10378853171bSZoran Jovanovic case 32768: return 0xe; 10388853171bSZoran Jovanovic case 65535: return 0xf; 10398853171bSZoran Jovanovic } 10408853171bSZoran Jovanovic llvm_unreachable("Unexpected value"); 10418853171bSZoran Jovanovic } 10428853171bSZoran Jovanovic 1043a4c4b5fcSZoran Jovanovic unsigned 1044a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, 1045a4c4b5fcSZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1046a4c4b5fcSZoran Jovanovic const MCSubtargetInfo &STI) const { 1047a4c4b5fcSZoran Jovanovic unsigned res = 0; 1048a4c4b5fcSZoran Jovanovic 1049a4c4b5fcSZoran Jovanovic // Register list operand is always first operand of instruction and it is 1050a4c4b5fcSZoran Jovanovic // placed before memory operand (register + imm). 1051a4c4b5fcSZoran Jovanovic 1052a4c4b5fcSZoran Jovanovic for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { 1053a4c4b5fcSZoran Jovanovic unsigned Reg = MI.getOperand(I).getReg(); 1054a4c4b5fcSZoran Jovanovic unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 1055a4c4b5fcSZoran Jovanovic if (RegNo != 31) 1056a4c4b5fcSZoran Jovanovic res++; 1057a4c4b5fcSZoran Jovanovic else 1058a4c4b5fcSZoran Jovanovic res |= 0x10; 1059a4c4b5fcSZoran Jovanovic } 1060a4c4b5fcSZoran Jovanovic return res; 1061a4c4b5fcSZoran Jovanovic } 1062a4c4b5fcSZoran Jovanovic 1063f9a02500SZoran Jovanovic unsigned 1064f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, 1065f9a02500SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 1066f9a02500SZoran Jovanovic const MCSubtargetInfo &STI) const { 1067f9a02500SZoran Jovanovic return (MI.getNumOperands() - 4); 1068f9a02500SZoran Jovanovic } 1069f9a02500SZoran Jovanovic 10702deca348SZoran Jovanovic unsigned 107141688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, 107241688679SZoran Jovanovic SmallVectorImpl<MCFixup> &Fixups, 107341688679SZoran Jovanovic const MCSubtargetInfo &STI) const { 107441688679SZoran Jovanovic unsigned res = 0; 107541688679SZoran Jovanovic 107641688679SZoran Jovanovic if (MI.getOperand(0).getReg() == Mips::A1 && 107741688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 107841688679SZoran Jovanovic res = 0; 107941688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A1 && 108041688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 108141688679SZoran Jovanovic res = 1; 108241688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A2 && 108341688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 108441688679SZoran Jovanovic res = 2; 108541688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 108641688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S5) 108741688679SZoran Jovanovic res = 3; 108841688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 108941688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::S6) 109041688679SZoran Jovanovic res = 4; 109141688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 109241688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A1) 109341688679SZoran Jovanovic res = 5; 109441688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 109541688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A2) 109641688679SZoran Jovanovic res = 6; 109741688679SZoran Jovanovic else if (MI.getOperand(0).getReg() == Mips::A0 && 109841688679SZoran Jovanovic MI.getOperand(1).getReg() == Mips::A3) 109941688679SZoran Jovanovic res = 7; 110041688679SZoran Jovanovic 110141688679SZoran Jovanovic return res; 110241688679SZoran Jovanovic } 110341688679SZoran Jovanovic 110441688679SZoran Jovanovic unsigned 1105169df4e2SSimon Dardis MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, 1106169df4e2SSimon Dardis SmallVectorImpl<MCFixup> &Fixups, 1107169df4e2SSimon Dardis const MCSubtargetInfo &STI) const { 1108169df4e2SSimon Dardis assert(((OpNo == 2) || (OpNo == 3)) && 1109169df4e2SSimon Dardis "Unexpected OpNo for movep operand encoding!"); 1110169df4e2SSimon Dardis 1111169df4e2SSimon Dardis MCOperand Op = MI.getOperand(OpNo); 1112169df4e2SSimon Dardis assert(Op.isReg() && "Operand of movep is not a register!"); 1113169df4e2SSimon Dardis switch (Op.getReg()) { 1114169df4e2SSimon Dardis default: 1115169df4e2SSimon Dardis llvm_unreachable("Unknown register for movep!"); 1116169df4e2SSimon Dardis case Mips::ZERO: return 0; 1117169df4e2SSimon Dardis case Mips::S1: return 1; 1118169df4e2SSimon Dardis case Mips::V0: return 2; 1119169df4e2SSimon Dardis case Mips::V1: return 3; 1120169df4e2SSimon Dardis case Mips::S0: return 4; 1121169df4e2SSimon Dardis case Mips::S2: return 5; 1122169df4e2SSimon Dardis case Mips::S3: return 6; 1123169df4e2SSimon Dardis case Mips::S4: return 7; 1124169df4e2SSimon Dardis } 1125169df4e2SSimon Dardis } 1126169df4e2SSimon Dardis 1127169df4e2SSimon Dardis unsigned 11282c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, 11292c6d7320SJozef Kolek SmallVectorImpl<MCFixup> &Fixups, 11302c6d7320SJozef Kolek const MCSubtargetInfo &STI) const { 11312c6d7320SJozef Kolek const MCOperand &MO = MI.getOperand(OpNo); 11322c6d7320SJozef Kolek assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); 11332c6d7320SJozef Kolek // The immediate is encoded as 'immediate >> 2'. 11342c6d7320SJozef Kolek unsigned Res = static_cast<unsigned>(MO.getImm()); 11352c6d7320SJozef Kolek assert((Res & 3) == 0); 11362c6d7320SJozef Kolek return Res >> 2; 11372c6d7320SJozef Kolek } 11382c6d7320SJozef Kolek 1139b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc" 1140