1 //===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the CSKYMCCodeEmitter class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H 14 #define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H 15 16 #include "MCTargetDesc/CSKYFixupKinds.h" 17 #include "MCTargetDesc/CSKYMCExpr.h" 18 #include "llvm/MC/MCCodeEmitter.h" 19 #include "llvm/MC/MCContext.h" 20 21 namespace llvm { 22 23 class CSKYMCCodeEmitter : public MCCodeEmitter { 24 MCContext &Ctx; 25 const MCInstrInfo &MII; 26 27 public: 28 CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII) 29 : Ctx(Ctx), MII(MII) {} 30 31 ~CSKYMCCodeEmitter() {} 32 33 void encodeInstruction(const MCInst &Inst, raw_ostream &OS, 34 SmallVectorImpl<MCFixup> &Fixups, 35 const MCSubtargetInfo &STI) const override; 36 37 // Generated by tablegen. 38 uint64_t getBinaryCodeForInstr(const MCInst &MI, 39 SmallVectorImpl<MCFixup> &Fixups, 40 const MCSubtargetInfo &STI) const; 41 42 // Default encoding method used by tablegen. 43 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 44 SmallVectorImpl<MCFixup> &Fixups, 45 const MCSubtargetInfo &STI) const; 46 47 template <int shift = 0> 48 unsigned getImmOpValue(const MCInst &MI, unsigned Idx, 49 SmallVectorImpl<MCFixup> &Fixups, 50 const MCSubtargetInfo &STI) const { 51 const MCOperand &MO = MI.getOperand(Idx); 52 if (MO.isImm()) 53 return (MO.getImm() >> shift); 54 55 assert(MO.isExpr() && "Unexpected MO type."); 56 57 MCFixupKind Kind = getTargetFixup(MO.getExpr()); 58 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 59 return 0; 60 } 61 62 unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx, 63 SmallVectorImpl<MCFixup> &Fixups, 64 const MCSubtargetInfo &STI) const; 65 66 unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op, 67 SmallVectorImpl<MCFixup> &Fixups, 68 const MCSubtargetInfo &STI) const; 69 70 unsigned getOImmOpValue(const MCInst &MI, unsigned Idx, 71 SmallVectorImpl<MCFixup> &Fixups, 72 const MCSubtargetInfo &STI) const; 73 74 unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx, 75 SmallVectorImpl<MCFixup> &Fixups, 76 const MCSubtargetInfo &STI) const; 77 78 unsigned getImmJMPIX(const MCInst &MI, unsigned Idx, 79 SmallVectorImpl<MCFixup> &Fixups, 80 const MCSubtargetInfo &STI) const; 81 82 unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx, 83 SmallVectorImpl<MCFixup> &Fixups, 84 const MCSubtargetInfo &STI) const; 85 86 unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx, 87 SmallVectorImpl<MCFixup> &Fixups, 88 const MCSubtargetInfo &STI) const { 89 const MCOperand &MO = MI.getOperand(Idx); 90 assert(MO.isImm() && "Unexpected MO type."); 91 return 1 << MO.getImm(); 92 } 93 94 MCFixupKind getTargetFixup(const MCExpr *Expr) const; 95 96 template <llvm::CSKY::Fixups FIXUP> 97 unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx, 98 SmallVectorImpl<MCFixup> &Fixups, 99 const MCSubtargetInfo &STI) const { 100 const MCOperand &MO = MI.getOperand(Idx); 101 102 if (MO.isImm()) 103 return MO.getImm() >> 1; 104 105 assert(MO.isExpr() && "Unexpected MO type."); 106 107 MCFixupKind Kind = MCFixupKind(FIXUP); 108 if (MO.getExpr()->getKind() == MCExpr::Target) 109 Kind = getTargetFixup(MO.getExpr()); 110 111 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 112 return 0; 113 } 114 115 template <llvm::CSKY::Fixups FIXUP> 116 unsigned getConstpoolSymbolOpValue(const MCInst &MI, unsigned Idx, 117 SmallVectorImpl<MCFixup> &Fixups, 118 const MCSubtargetInfo &STI) const { 119 const MCOperand &MO = MI.getOperand(Idx); 120 assert(MO.isExpr() && "Unexpected MO type."); 121 122 MCFixupKind Kind = MCFixupKind(FIXUP); 123 if (MO.getExpr()->getKind() == MCExpr::Target) 124 Kind = getTargetFixup(MO.getExpr()); 125 126 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 127 return 0; 128 } 129 130 template <llvm::CSKY::Fixups FIXUP> 131 unsigned getDataSymbolOpValue(const MCInst &MI, unsigned Idx, 132 SmallVectorImpl<MCFixup> &Fixups, 133 const MCSubtargetInfo &STI) const { 134 const MCOperand &MO = MI.getOperand(Idx); 135 assert(MO.isExpr() && "Unexpected MO type."); 136 137 MCFixupKind Kind = MCFixupKind(FIXUP); 138 if (MO.getExpr()->getKind() == MCExpr::Target) 139 Kind = getTargetFixup(MO.getExpr()); 140 141 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 142 return 0; 143 } 144 145 unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx, 146 SmallVectorImpl<MCFixup> &Fixups, 147 const MCSubtargetInfo &STI) const { 148 const MCOperand &MO = MI.getOperand(Idx); 149 assert(MO.isExpr() && "Unexpected MO type."); 150 151 MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm26_scale2); 152 if (MO.getExpr()->getKind() == MCExpr::Target) 153 Kind = getTargetFixup(MO.getExpr()); 154 155 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 156 return 0; 157 } 158 159 unsigned getBareSymbolOpValue(const MCInst &MI, unsigned Idx, 160 SmallVectorImpl<MCFixup> &Fixups, 161 const MCSubtargetInfo &STI) const { 162 const MCOperand &MO = MI.getOperand(Idx); 163 assert(MO.isExpr() && "Unexpected MO type."); 164 165 MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm18_scale2); 166 if (MO.getExpr()->getKind() == MCExpr::Target) 167 Kind = getTargetFixup(MO.getExpr()); 168 169 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 170 return 0; 171 } 172 }; 173 174 } // namespace llvm 175 176 #endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H 177