1 //===-- VEMCCodeEmitter.cpp - Convert VE code to machine code -------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the VEMCCodeEmitter class.
11 //===----------------------------------------------------------------------===//
13 #include "MCTargetDesc/VEFixupKinds.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/MC/MCCodeEmitter.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCFixup.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/Support/EndianStream.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/raw_ostream.h"
35 #define DEBUG_TYPE "mccodeemitter"
37 STATISTIC(MCNumEmitted
, "Number of MC instructions emitted");
41 class VEMCCodeEmitter
: public MCCodeEmitter
{
45 VEMCCodeEmitter(const MCInstrInfo
&, MCContext
&ctx
)
47 VEMCCodeEmitter(const VEMCCodeEmitter
&) = delete;
48 VEMCCodeEmitter
&operator=(const VEMCCodeEmitter
&) = delete;
49 ~VEMCCodeEmitter() override
= default;
51 void encodeInstruction(const MCInst
&MI
, SmallVectorImpl
<char> &CB
,
52 SmallVectorImpl
<MCFixup
> &Fixups
,
53 const MCSubtargetInfo
&STI
) const override
;
55 // getBinaryCodeForInstr - TableGen'erated function for getting the
56 // binary encoding for an instruction.
57 uint64_t getBinaryCodeForInstr(const MCInst
&MI
,
58 SmallVectorImpl
<MCFixup
> &Fixups
,
59 const MCSubtargetInfo
&STI
) const;
61 /// getMachineOpValue - Return binary encoding of operand. If the machine
62 /// operand requires relocation, record the relocation and return zero.
63 unsigned getMachineOpValue(const MCInst
&MI
, const MCOperand
&MO
,
64 SmallVectorImpl
<MCFixup
> &Fixups
,
65 const MCSubtargetInfo
&STI
) const;
67 uint64_t getBranchTargetOpValue(const MCInst
&MI
, unsigned OpNo
,
68 SmallVectorImpl
<MCFixup
> &Fixups
,
69 const MCSubtargetInfo
&STI
) const;
70 uint64_t getCCOpValue(const MCInst
&MI
, unsigned OpNo
,
71 SmallVectorImpl
<MCFixup
> &Fixups
,
72 const MCSubtargetInfo
&STI
) const;
73 uint64_t getRDOpValue(const MCInst
&MI
, unsigned OpNo
,
74 SmallVectorImpl
<MCFixup
> &Fixups
,
75 const MCSubtargetInfo
&STI
) const;
78 } // end anonymous namespace
80 void VEMCCodeEmitter::encodeInstruction(const MCInst
&MI
,
81 SmallVectorImpl
<char> &CB
,
82 SmallVectorImpl
<MCFixup
> &Fixups
,
83 const MCSubtargetInfo
&STI
) const {
84 uint64_t Bits
= getBinaryCodeForInstr(MI
, Fixups
, STI
);
85 support::endian::write
<uint64_t>(CB
, Bits
, llvm::endianness::little
);
87 ++MCNumEmitted
; // Keep track of the # of mi's emitted.
90 unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst
&MI
,
92 SmallVectorImpl
<MCFixup
> &Fixups
,
93 const MCSubtargetInfo
&STI
) const {
95 return Ctx
.getRegisterInfo()->getEncodingValue(MO
.getReg());
97 return static_cast<unsigned>(MO
.getImm());
101 const MCExpr
*Expr
= MO
.getExpr();
102 if (const VEMCExpr
*SExpr
= dyn_cast
<VEMCExpr
>(Expr
)) {
103 MCFixupKind Kind
= (MCFixupKind
)SExpr
->getFixupKind();
104 Fixups
.push_back(MCFixup::create(0, Expr
, Kind
));
109 if (Expr
->evaluateAsAbsolute(Res
))
112 llvm_unreachable("Unhandled expression!");
117 VEMCCodeEmitter::getBranchTargetOpValue(const MCInst
&MI
, unsigned OpNo
,
118 SmallVectorImpl
<MCFixup
> &Fixups
,
119 const MCSubtargetInfo
&STI
) const {
120 const MCOperand
&MO
= MI
.getOperand(OpNo
);
121 if (MO
.isReg() || MO
.isImm())
122 return getMachineOpValue(MI
, MO
, Fixups
, STI
);
125 MCFixup::create(0, MO
.getExpr(), (MCFixupKind
)VE::fixup_ve_srel32
));
129 uint64_t VEMCCodeEmitter::getCCOpValue(const MCInst
&MI
, unsigned OpNo
,
130 SmallVectorImpl
<MCFixup
> &Fixups
,
131 const MCSubtargetInfo
&STI
) const {
132 const MCOperand
&MO
= MI
.getOperand(OpNo
);
134 return VECondCodeToVal(
135 static_cast<VECC::CondCode
>(getMachineOpValue(MI
, MO
, Fixups
, STI
)));
139 uint64_t VEMCCodeEmitter::getRDOpValue(const MCInst
&MI
, unsigned OpNo
,
140 SmallVectorImpl
<MCFixup
> &Fixups
,
141 const MCSubtargetInfo
&STI
) const {
142 const MCOperand
&MO
= MI
.getOperand(OpNo
);
144 return VERDToVal(static_cast<VERD::RoundingMode
>(
145 getMachineOpValue(MI
, MO
, Fixups
, STI
)));
149 #include "VEGenMCCodeEmitter.inc"
151 MCCodeEmitter
*llvm::createVEMCCodeEmitter(const MCInstrInfo
&MCII
,
153 return new VEMCCodeEmitter(MCII
, Ctx
);