109467b48Spatrick //===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file implements the SparcMCCodeEmitter class.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "MCTargetDesc/SparcFixupKinds.h"
1409467b48Spatrick #include "SparcMCExpr.h"
1509467b48Spatrick #include "SparcMCTargetDesc.h"
1609467b48Spatrick #include "llvm/ADT/SmallVector.h"
1709467b48Spatrick #include "llvm/ADT/Statistic.h"
1809467b48Spatrick #include "llvm/MC/MCAsmInfo.h"
1909467b48Spatrick #include "llvm/MC/MCCodeEmitter.h"
2009467b48Spatrick #include "llvm/MC/MCContext.h"
2109467b48Spatrick #include "llvm/MC/MCExpr.h"
2209467b48Spatrick #include "llvm/MC/MCFixup.h"
2309467b48Spatrick #include "llvm/MC/MCInst.h"
2409467b48Spatrick #include "llvm/MC/MCInstrInfo.h"
2573471bf0Spatrick #include "llvm/MC/MCObjectFileInfo.h"
2609467b48Spatrick #include "llvm/MC/MCRegisterInfo.h"
2709467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h"
2809467b48Spatrick #include "llvm/MC/MCSymbol.h"
2909467b48Spatrick #include "llvm/MC/SubtargetFeature.h"
3009467b48Spatrick #include "llvm/Support/Casting.h"
3109467b48Spatrick #include "llvm/Support/Endian.h"
3209467b48Spatrick #include "llvm/Support/EndianStream.h"
3309467b48Spatrick #include "llvm/Support/ErrorHandling.h"
3409467b48Spatrick #include "llvm/Support/raw_ostream.h"
3509467b48Spatrick #include <cassert>
3609467b48Spatrick #include <cstdint>
3709467b48Spatrick 
3809467b48Spatrick using namespace llvm;
3909467b48Spatrick 
4009467b48Spatrick #define DEBUG_TYPE "mccodeemitter"
4109467b48Spatrick 
4209467b48Spatrick STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
4309467b48Spatrick 
4409467b48Spatrick namespace {
4509467b48Spatrick 
4609467b48Spatrick class SparcMCCodeEmitter : public MCCodeEmitter {
4709467b48Spatrick   MCContext &Ctx;
4809467b48Spatrick 
4909467b48Spatrick public:
SparcMCCodeEmitter(const MCInstrInfo &,MCContext & ctx)50*d415bd75Srobert   SparcMCCodeEmitter(const MCInstrInfo &, MCContext &ctx)
51*d415bd75Srobert       : Ctx(ctx) {}
5209467b48Spatrick   SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete;
5309467b48Spatrick   SparcMCCodeEmitter &operator=(const SparcMCCodeEmitter &) = delete;
5409467b48Spatrick   ~SparcMCCodeEmitter() override = default;
5509467b48Spatrick 
5609467b48Spatrick   void encodeInstruction(const MCInst &MI, raw_ostream &OS,
5709467b48Spatrick                          SmallVectorImpl<MCFixup> &Fixups,
5809467b48Spatrick                          const MCSubtargetInfo &STI) const override;
5909467b48Spatrick 
6009467b48Spatrick   // getBinaryCodeForInstr - TableGen'erated function for getting the
6109467b48Spatrick   // binary encoding for an instruction.
6209467b48Spatrick   uint64_t getBinaryCodeForInstr(const MCInst &MI,
6309467b48Spatrick                                  SmallVectorImpl<MCFixup> &Fixups,
6409467b48Spatrick                                  const MCSubtargetInfo &STI) const;
6509467b48Spatrick 
6609467b48Spatrick   /// getMachineOpValue - Return binary encoding of operand. If the machine
6709467b48Spatrick   /// operand requires relocation, record the relocation and return zero.
6809467b48Spatrick   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
6909467b48Spatrick                              SmallVectorImpl<MCFixup> &Fixups,
7009467b48Spatrick                              const MCSubtargetInfo &STI) const;
7109467b48Spatrick   unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
7209467b48Spatrick                              SmallVectorImpl<MCFixup> &Fixups,
7309467b48Spatrick                              const MCSubtargetInfo &STI) const;
7409467b48Spatrick   unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
7509467b48Spatrick                              SmallVectorImpl<MCFixup> &Fixups,
7609467b48Spatrick                              const MCSubtargetInfo &STI) const;
7773471bf0Spatrick   unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo,
7873471bf0Spatrick                             SmallVectorImpl<MCFixup> &Fixups,
7973471bf0Spatrick                             const MCSubtargetInfo &STI) const;
8009467b48Spatrick   unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
8109467b48Spatrick                                       SmallVectorImpl<MCFixup> &Fixups,
8209467b48Spatrick                                       const MCSubtargetInfo &STI) const;
8309467b48Spatrick   unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
8409467b48Spatrick                                        SmallVectorImpl<MCFixup> &Fixups,
8509467b48Spatrick                                        const MCSubtargetInfo &STI) const;
8609467b48Spatrick };
8709467b48Spatrick 
8809467b48Spatrick } // end anonymous namespace
8909467b48Spatrick 
encodeInstruction(const MCInst & MI,raw_ostream & OS,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const9009467b48Spatrick void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
9109467b48Spatrick                                            SmallVectorImpl<MCFixup> &Fixups,
9209467b48Spatrick                                            const MCSubtargetInfo &STI) const {
9309467b48Spatrick   unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);
9409467b48Spatrick   support::endian::write(OS, Bits,
9509467b48Spatrick                          Ctx.getAsmInfo()->isLittleEndian() ? support::little
9609467b48Spatrick                                                             : support::big);
97*d415bd75Srobert 
98*d415bd75Srobert   // Some instructions have phantom operands that only contribute a fixup entry.
99*d415bd75Srobert   unsigned SymOpNo = 0;
10009467b48Spatrick   switch (MI.getOpcode()) {
10109467b48Spatrick   default: break;
102*d415bd75Srobert   case SP::TLS_CALL:   SymOpNo = 1; break;
103*d415bd75Srobert   case SP::GDOP_LDrr:
104*d415bd75Srobert   case SP::GDOP_LDXrr:
10509467b48Spatrick   case SP::TLS_ADDrr:
10609467b48Spatrick   case SP::TLS_ADDXrr:
10709467b48Spatrick   case SP::TLS_LDrr:
108*d415bd75Srobert   case SP::TLS_LDXrr:  SymOpNo = 3; break;
10909467b48Spatrick   }
110*d415bd75Srobert   if (SymOpNo != 0) {
111*d415bd75Srobert     const MCOperand &MO = MI.getOperand(SymOpNo);
11209467b48Spatrick     uint64_t op = getMachineOpValue(MI, MO, Fixups, STI);
11309467b48Spatrick     assert(op == 0 && "Unexpected operand value!");
11409467b48Spatrick     (void)op; // suppress warning.
11509467b48Spatrick   }
11609467b48Spatrick 
11709467b48Spatrick   ++MCNumEmitted;  // Keep track of the # of mi's emitted.
11809467b48Spatrick }
11909467b48Spatrick 
12009467b48Spatrick unsigned SparcMCCodeEmitter::
getMachineOpValue(const MCInst & MI,const MCOperand & MO,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const12109467b48Spatrick getMachineOpValue(const MCInst &MI, const MCOperand &MO,
12209467b48Spatrick                   SmallVectorImpl<MCFixup> &Fixups,
12309467b48Spatrick                   const MCSubtargetInfo &STI) const {
12409467b48Spatrick   if (MO.isReg())
12509467b48Spatrick     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
12609467b48Spatrick 
12709467b48Spatrick   if (MO.isImm())
12809467b48Spatrick     return MO.getImm();
12909467b48Spatrick 
13009467b48Spatrick   assert(MO.isExpr());
13109467b48Spatrick   const MCExpr *Expr = MO.getExpr();
13209467b48Spatrick   if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
13309467b48Spatrick     MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
13409467b48Spatrick     Fixups.push_back(MCFixup::create(0, Expr, Kind));
13509467b48Spatrick     return 0;
13609467b48Spatrick   }
13709467b48Spatrick 
13809467b48Spatrick   int64_t Res;
13909467b48Spatrick   if (Expr->evaluateAsAbsolute(Res))
14009467b48Spatrick     return Res;
14109467b48Spatrick 
14209467b48Spatrick   llvm_unreachable("Unhandled expression!");
14309467b48Spatrick   return 0;
14409467b48Spatrick }
14509467b48Spatrick 
14673471bf0Spatrick unsigned
getSImm13OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const14773471bf0Spatrick SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
14873471bf0Spatrick                                      SmallVectorImpl<MCFixup> &Fixups,
14973471bf0Spatrick                                      const MCSubtargetInfo &STI) const {
15073471bf0Spatrick   const MCOperand &MO = MI.getOperand(OpNo);
15173471bf0Spatrick 
15273471bf0Spatrick   if (MO.isImm())
15373471bf0Spatrick     return MO.getImm();
15473471bf0Spatrick 
15573471bf0Spatrick   assert(MO.isExpr() &&
15673471bf0Spatrick          "getSImm13OpValue expects only expressions or an immediate");
15773471bf0Spatrick 
15873471bf0Spatrick   const MCExpr *Expr = MO.getExpr();
15973471bf0Spatrick 
16073471bf0Spatrick   // Constant value, no fixup is needed
16173471bf0Spatrick   if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
16273471bf0Spatrick     return CE->getValue();
16373471bf0Spatrick 
16473471bf0Spatrick   MCFixupKind Kind;
16573471bf0Spatrick   if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
16673471bf0Spatrick     Kind = MCFixupKind(SExpr->getFixupKind());
16773471bf0Spatrick   } else {
16873471bf0Spatrick     bool IsPic = Ctx.getObjectFileInfo()->isPositionIndependent();
16973471bf0Spatrick     Kind = IsPic ? MCFixupKind(Sparc::fixup_sparc_got13)
17073471bf0Spatrick                  : MCFixupKind(Sparc::fixup_sparc_13);
17173471bf0Spatrick   }
17273471bf0Spatrick 
17373471bf0Spatrick   Fixups.push_back(MCFixup::create(0, Expr, Kind));
17473471bf0Spatrick   return 0;
17573471bf0Spatrick }
17673471bf0Spatrick 
17709467b48Spatrick unsigned SparcMCCodeEmitter::
getCallTargetOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const17809467b48Spatrick getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
17909467b48Spatrick                      SmallVectorImpl<MCFixup> &Fixups,
18009467b48Spatrick                      const MCSubtargetInfo &STI) const {
18109467b48Spatrick   const MCOperand &MO = MI.getOperand(OpNo);
18273471bf0Spatrick   const MCExpr *Expr = MO.getExpr();
18373471bf0Spatrick   const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr);
18409467b48Spatrick 
18509467b48Spatrick   if (MI.getOpcode() == SP::TLS_CALL) {
18609467b48Spatrick     // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in
18709467b48Spatrick     // encodeInstruction.
18809467b48Spatrick #ifndef NDEBUG
18909467b48Spatrick     // Verify that the callee is actually __tls_get_addr.
19009467b48Spatrick     assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef &&
19109467b48Spatrick            "Unexpected expression in TLS_CALL");
19209467b48Spatrick     const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr());
19309467b48Spatrick     assert(SymExpr->getSymbol().getName() == "__tls_get_addr" &&
19409467b48Spatrick            "Unexpected function for TLS_CALL");
19509467b48Spatrick #endif
19609467b48Spatrick     return 0;
19709467b48Spatrick   }
19809467b48Spatrick 
19973471bf0Spatrick   MCFixupKind Kind = MCFixupKind(SExpr->getFixupKind());
20073471bf0Spatrick   Fixups.push_back(MCFixup::create(0, Expr, Kind));
20109467b48Spatrick   return 0;
20209467b48Spatrick }
20309467b48Spatrick 
20409467b48Spatrick unsigned SparcMCCodeEmitter::
getBranchTargetOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const20509467b48Spatrick getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
20609467b48Spatrick                   SmallVectorImpl<MCFixup> &Fixups,
20709467b48Spatrick                   const MCSubtargetInfo &STI) const {
20809467b48Spatrick   const MCOperand &MO = MI.getOperand(OpNo);
20909467b48Spatrick   if (MO.isReg() || MO.isImm())
21009467b48Spatrick     return getMachineOpValue(MI, MO, Fixups, STI);
21109467b48Spatrick 
21209467b48Spatrick   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
21309467b48Spatrick                                    (MCFixupKind)Sparc::fixup_sparc_br22));
21409467b48Spatrick   return 0;
21509467b48Spatrick }
21609467b48Spatrick 
21709467b48Spatrick unsigned SparcMCCodeEmitter::
getBranchPredTargetOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const21809467b48Spatrick getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
21909467b48Spatrick                            SmallVectorImpl<MCFixup> &Fixups,
22009467b48Spatrick                            const MCSubtargetInfo &STI) const {
22109467b48Spatrick   const MCOperand &MO = MI.getOperand(OpNo);
22209467b48Spatrick   if (MO.isReg() || MO.isImm())
22309467b48Spatrick     return getMachineOpValue(MI, MO, Fixups, STI);
22409467b48Spatrick 
22509467b48Spatrick   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
22609467b48Spatrick                                    (MCFixupKind)Sparc::fixup_sparc_br19));
22709467b48Spatrick   return 0;
22809467b48Spatrick }
22909467b48Spatrick 
23009467b48Spatrick unsigned SparcMCCodeEmitter::
getBranchOnRegTargetOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const23109467b48Spatrick getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
23209467b48Spatrick                            SmallVectorImpl<MCFixup> &Fixups,
23309467b48Spatrick                            const MCSubtargetInfo &STI) const {
23409467b48Spatrick   const MCOperand &MO = MI.getOperand(OpNo);
23509467b48Spatrick   if (MO.isReg() || MO.isImm())
23609467b48Spatrick     return getMachineOpValue(MI, MO, Fixups, STI);
23709467b48Spatrick 
23809467b48Spatrick   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
23909467b48Spatrick                                    (MCFixupKind)Sparc::fixup_sparc_br16_2));
24009467b48Spatrick   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
24109467b48Spatrick                                    (MCFixupKind)Sparc::fixup_sparc_br16_14));
24209467b48Spatrick 
24309467b48Spatrick   return 0;
24409467b48Spatrick }
24509467b48Spatrick 
24609467b48Spatrick #include "SparcGenMCCodeEmitter.inc"
24709467b48Spatrick 
createSparcMCCodeEmitter(const MCInstrInfo & MCII,MCContext & Ctx)24809467b48Spatrick MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
24909467b48Spatrick                                               MCContext &Ctx) {
25009467b48Spatrick   return new SparcMCCodeEmitter(MCII, Ctx);
25109467b48Spatrick }
252