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 "CSKYMCExpr.h" 17 #include "MCTargetDesc/CSKYFixupKinds.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 assert(MO.isImm() && "Unexpected MO type."); 53 return (MO.getImm() >> shift); 54 } 55 56 unsigned getOImmOpValue(const MCInst &MI, unsigned Idx, 57 SmallVectorImpl<MCFixup> &Fixups, 58 const MCSubtargetInfo &STI) const; 59 60 unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx, 61 SmallVectorImpl<MCFixup> &Fixups, 62 const MCSubtargetInfo &STI) const { 63 const MCOperand &MO = MI.getOperand(Idx); 64 assert(MO.isImm() && "Unexpected MO type."); 65 return 1 << MO.getImm(); 66 } 67 68 MCFixupKind getTargetFixup(const MCExpr *Expr) const; 69 70 template <llvm::CSKY::Fixups FIXUP> 71 unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx, 72 SmallVectorImpl<MCFixup> &Fixups, 73 const MCSubtargetInfo &STI) const { 74 const MCOperand &MO = MI.getOperand(Idx); 75 76 if (MO.isImm()) 77 return MO.getImm() >> 1; 78 79 assert(MO.isExpr() && "Unexpected MO type."); 80 81 MCFixupKind Kind = MCFixupKind(FIXUP); 82 if (MO.getExpr()->getKind() == MCExpr::Target) 83 Kind = getTargetFixup(MO.getExpr()); 84 85 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 86 return 0; 87 } 88 89 template <llvm::CSKY::Fixups FIXUP> 90 unsigned getConstpoolSymbolOpValue(const MCInst &MI, unsigned Idx, 91 SmallVectorImpl<MCFixup> &Fixups, 92 const MCSubtargetInfo &STI) const { 93 const MCOperand &MO = MI.getOperand(Idx); 94 assert(MO.isExpr() && "Unexpected MO type."); 95 96 MCFixupKind Kind = MCFixupKind(FIXUP); 97 if (MO.getExpr()->getKind() == MCExpr::Target) 98 Kind = getTargetFixup(MO.getExpr()); 99 100 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 101 return 0; 102 } 103 104 unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx, 105 SmallVectorImpl<MCFixup> &Fixups, 106 const MCSubtargetInfo &STI) const { 107 const MCOperand &MO = MI.getOperand(Idx); 108 assert(MO.isExpr() && "Unexpected MO type."); 109 110 MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm26_scale2); 111 if (MO.getExpr()->getKind() == MCExpr::Target) 112 Kind = getTargetFixup(MO.getExpr()); 113 114 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 115 return 0; 116 } 117 118 unsigned getBareSymbolOpValue(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(CSKY::fixup_csky_pcrel_imm18_scale2); 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 133 } // namespace llvm 134 135 #endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H 136