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 MCInstrInfo; 24 25 class CSKYMCCodeEmitter : public MCCodeEmitter { 26 MCContext &Ctx; 27 const MCInstrInfo &MII; 28 29 public: 30 CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII) 31 : Ctx(Ctx), MII(MII) {} 32 33 ~CSKYMCCodeEmitter() {} 34 35 void encodeInstruction(const MCInst &Inst, raw_ostream &OS, 36 SmallVectorImpl<MCFixup> &Fixups, 37 const MCSubtargetInfo &STI) const override; 38 39 // Generated by tablegen. 40 uint64_t getBinaryCodeForInstr(const MCInst &MI, 41 SmallVectorImpl<MCFixup> &Fixups, 42 const MCSubtargetInfo &STI) const; 43 44 // Default encoding method used by tablegen. 45 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 46 SmallVectorImpl<MCFixup> &Fixups, 47 const MCSubtargetInfo &STI) const; 48 49 template <int shift = 0> 50 unsigned getImmOpValue(const MCInst &MI, unsigned Idx, 51 SmallVectorImpl<MCFixup> &Fixups, 52 const MCSubtargetInfo &STI) const { 53 const MCOperand &MO = MI.getOperand(Idx); 54 if (MO.isImm()) 55 return (MO.getImm() >> shift); 56 57 assert(MO.isExpr() && "Unexpected MO type."); 58 59 MCFixupKind Kind = getTargetFixup(MO.getExpr()); 60 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 61 return 0; 62 } 63 64 unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx, 65 SmallVectorImpl<MCFixup> &Fixups, 66 const MCSubtargetInfo &STI) const; 67 68 unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op, 69 SmallVectorImpl<MCFixup> &Fixups, 70 const MCSubtargetInfo &STI) const; 71 72 unsigned getOImmOpValue(const MCInst &MI, unsigned Idx, 73 SmallVectorImpl<MCFixup> &Fixups, 74 const MCSubtargetInfo &STI) const; 75 76 unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx, 77 SmallVectorImpl<MCFixup> &Fixups, 78 const MCSubtargetInfo &STI) const; 79 80 unsigned getImmJMPIX(const MCInst &MI, unsigned Idx, 81 SmallVectorImpl<MCFixup> &Fixups, 82 const MCSubtargetInfo &STI) const; 83 84 unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx, 85 SmallVectorImpl<MCFixup> &Fixups, 86 const MCSubtargetInfo &STI) const; 87 88 unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx, 89 SmallVectorImpl<MCFixup> &Fixups, 90 const MCSubtargetInfo &STI) const { 91 const MCOperand &MO = MI.getOperand(Idx); 92 assert(MO.isImm() && "Unexpected MO type."); 93 return 1 << MO.getImm(); 94 } 95 96 MCFixupKind getTargetFixup(const MCExpr *Expr) const; 97 98 template <llvm::CSKY::Fixups FIXUP> 99 unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx, 100 SmallVectorImpl<MCFixup> &Fixups, 101 const MCSubtargetInfo &STI) const { 102 const MCOperand &MO = MI.getOperand(Idx); 103 104 if (MO.isImm()) 105 return MO.getImm() >> 1; 106 107 assert(MO.isExpr() && "Unexpected MO type."); 108 109 MCFixupKind Kind = MCFixupKind(FIXUP); 110 if (MO.getExpr()->getKind() == MCExpr::Target) 111 Kind = getTargetFixup(MO.getExpr()); 112 113 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 114 return 0; 115 } 116 117 template <llvm::CSKY::Fixups FIXUP> 118 unsigned getConstpoolSymbolOpValue(const MCInst &MI, unsigned Idx, 119 SmallVectorImpl<MCFixup> &Fixups, 120 const MCSubtargetInfo &STI) const { 121 const MCOperand &MO = MI.getOperand(Idx); 122 assert(MO.isExpr() && "Unexpected MO type."); 123 124 MCFixupKind Kind = MCFixupKind(FIXUP); 125 if (MO.getExpr()->getKind() == MCExpr::Target) 126 Kind = getTargetFixup(MO.getExpr()); 127 128 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 129 return 0; 130 } 131 132 template <llvm::CSKY::Fixups FIXUP> 133 unsigned getDataSymbolOpValue(const MCInst &MI, unsigned Idx, 134 SmallVectorImpl<MCFixup> &Fixups, 135 const MCSubtargetInfo &STI) const { 136 const MCOperand &MO = MI.getOperand(Idx); 137 assert(MO.isExpr() && "Unexpected MO type."); 138 139 MCFixupKind Kind = MCFixupKind(FIXUP); 140 if (MO.getExpr()->getKind() == MCExpr::Target) 141 Kind = getTargetFixup(MO.getExpr()); 142 143 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 144 return 0; 145 } 146 147 unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx, 148 SmallVectorImpl<MCFixup> &Fixups, 149 const MCSubtargetInfo &STI) const { 150 const MCOperand &MO = MI.getOperand(Idx); 151 assert(MO.isExpr() && "Unexpected MO type."); 152 153 MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm26_scale2); 154 if (MO.getExpr()->getKind() == MCExpr::Target) 155 Kind = getTargetFixup(MO.getExpr()); 156 157 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 158 return 0; 159 } 160 161 unsigned getBareSymbolOpValue(const MCInst &MI, unsigned Idx, 162 SmallVectorImpl<MCFixup> &Fixups, 163 const MCSubtargetInfo &STI) const { 164 const MCOperand &MO = MI.getOperand(Idx); 165 assert(MO.isExpr() && "Unexpected MO type."); 166 167 MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm18_scale2); 168 if (MO.getExpr()->getKind() == MCExpr::Target) 169 Kind = getTargetFixup(MO.getExpr()); 170 171 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 172 return 0; 173 } 174 175 void expandJBTF(const MCInst &MI, raw_ostream &OS, 176 SmallVectorImpl<MCFixup> &Fixups, 177 const MCSubtargetInfo &STI) const; 178 void expandNEG(const MCInst &MI, raw_ostream &OS, 179 SmallVectorImpl<MCFixup> &Fixups, 180 const MCSubtargetInfo &STI) const; 181 void expandRSUBI(const MCInst &MI, raw_ostream &OS, 182 SmallVectorImpl<MCFixup> &Fixups, 183 const MCSubtargetInfo &STI) const; 184 }; 185 186 } // namespace llvm 187 188 #endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H 189