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"
34 #define DEBUG_TYPE "mccodeemitter"
36 STATISTIC(MCNumEmitted
, "Number of MC instructions emitted");
40 class VEMCCodeEmitter
: public MCCodeEmitter
{
44 VEMCCodeEmitter(const MCInstrInfo
&, MCContext
&ctx
)
46 VEMCCodeEmitter(const VEMCCodeEmitter
&) = delete;
47 VEMCCodeEmitter
&operator=(const VEMCCodeEmitter
&) = delete;
48 ~VEMCCodeEmitter() override
= default;
50 void encodeInstruction(const MCInst
&MI
, SmallVectorImpl
<char> &CB
,
51 SmallVectorImpl
<MCFixup
> &Fixups
,
52 const MCSubtargetInfo
&STI
) const override
;
54 // getBinaryCodeForInstr - TableGen'erated function for getting the
55 // binary encoding for an instruction.
56 uint64_t getBinaryCodeForInstr(const MCInst
&MI
,
57 SmallVectorImpl
<MCFixup
> &Fixups
,
58 const MCSubtargetInfo
&STI
) const;
60 /// getMachineOpValue - Return binary encoding of operand. If the machine
61 /// operand requires relocation, record the relocation and return zero.
62 unsigned getMachineOpValue(const MCInst
&MI
, const MCOperand
&MO
,
63 SmallVectorImpl
<MCFixup
> &Fixups
,
64 const MCSubtargetInfo
&STI
) const;
66 uint64_t getBranchTargetOpValue(const MCInst
&MI
, unsigned OpNo
,
67 SmallVectorImpl
<MCFixup
> &Fixups
,
68 const MCSubtargetInfo
&STI
) const;
69 uint64_t getCCOpValue(const MCInst
&MI
, unsigned OpNo
,
70 SmallVectorImpl
<MCFixup
> &Fixups
,
71 const MCSubtargetInfo
&STI
) const;
72 uint64_t getRDOpValue(const MCInst
&MI
, unsigned OpNo
,
73 SmallVectorImpl
<MCFixup
> &Fixups
,
74 const MCSubtargetInfo
&STI
) const;
77 } // end anonymous namespace
79 void VEMCCodeEmitter::encodeInstruction(const MCInst
&MI
,
80 SmallVectorImpl
<char> &CB
,
81 SmallVectorImpl
<MCFixup
> &Fixups
,
82 const MCSubtargetInfo
&STI
) const {
83 uint64_t Bits
= getBinaryCodeForInstr(MI
, Fixups
, STI
);
84 support::endian::write
<uint64_t>(CB
, Bits
, llvm::endianness::little
);
86 ++MCNumEmitted
; // Keep track of the # of mi's emitted.
89 unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst
&MI
,
91 SmallVectorImpl
<MCFixup
> &Fixups
,
92 const MCSubtargetInfo
&STI
) const {
94 return Ctx
.getRegisterInfo()->getEncodingValue(MO
.getReg());
96 return static_cast<unsigned>(MO
.getImm());
100 const MCExpr
*Expr
= MO
.getExpr();
101 if (const VEMCExpr
*SExpr
= dyn_cast
<VEMCExpr
>(Expr
)) {
102 MCFixupKind Kind
= (MCFixupKind
)SExpr
->getFixupKind();
103 Fixups
.push_back(MCFixup::create(0, Expr
, Kind
));
108 if (Expr
->evaluateAsAbsolute(Res
))
111 llvm_unreachable("Unhandled expression!");
116 VEMCCodeEmitter::getBranchTargetOpValue(const MCInst
&MI
, unsigned OpNo
,
117 SmallVectorImpl
<MCFixup
> &Fixups
,
118 const MCSubtargetInfo
&STI
) const {
119 const MCOperand
&MO
= MI
.getOperand(OpNo
);
120 if (MO
.isReg() || MO
.isImm())
121 return getMachineOpValue(MI
, MO
, Fixups
, STI
);
124 MCFixup::create(0, MO
.getExpr(), (MCFixupKind
)VE::fixup_ve_srel32
));
128 uint64_t VEMCCodeEmitter::getCCOpValue(const MCInst
&MI
, unsigned OpNo
,
129 SmallVectorImpl
<MCFixup
> &Fixups
,
130 const MCSubtargetInfo
&STI
) const {
131 const MCOperand
&MO
= MI
.getOperand(OpNo
);
133 return VECondCodeToVal(
134 static_cast<VECC::CondCode
>(getMachineOpValue(MI
, MO
, Fixups
, STI
)));
138 uint64_t VEMCCodeEmitter::getRDOpValue(const MCInst
&MI
, unsigned OpNo
,
139 SmallVectorImpl
<MCFixup
> &Fixups
,
140 const MCSubtargetInfo
&STI
) const {
141 const MCOperand
&MO
= MI
.getOperand(OpNo
);
143 return VERDToVal(static_cast<VERD::RoundingMode
>(
144 getMachineOpValue(MI
, MO
, Fixups
, STI
)));
148 #include "VEGenMCCodeEmitter.inc"
150 MCCodeEmitter
*llvm::createVEMCCodeEmitter(const MCInstrInfo
&MCII
,
152 return new VEMCCodeEmitter(MCII
, Ctx
);