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