Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
35294 views
1
//===-- MSP430MCCodeEmitter.cpp - Convert MSP430 code to machine code -----===//
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 MSP430MCCodeEmitter class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "MSP430.h"
14
#include "MCTargetDesc/MSP430MCTargetDesc.h"
15
#include "MCTargetDesc/MSP430FixupKinds.h"
16
17
#include "llvm/ADT/APFloat.h"
18
#include "llvm/ADT/SmallVector.h"
19
#include "llvm/MC/MCCodeEmitter.h"
20
#include "llvm/MC/MCContext.h"
21
#include "llvm/MC/MCExpr.h"
22
#include "llvm/MC/MCFixup.h"
23
#include "llvm/MC/MCInst.h"
24
#include "llvm/MC/MCInstrInfo.h"
25
#include "llvm/MC/MCRegisterInfo.h"
26
#include "llvm/MC/MCSubtargetInfo.h"
27
#include "llvm/Support/Endian.h"
28
#include "llvm/Support/EndianStream.h"
29
#include "llvm/Support/raw_ostream.h"
30
31
#define DEBUG_TYPE "mccodeemitter"
32
33
namespace llvm {
34
35
class MSP430MCCodeEmitter : public MCCodeEmitter {
36
MCContext &Ctx;
37
MCInstrInfo const &MCII;
38
39
// Offset keeps track of current word number being emitted
40
// inside a particular instruction.
41
mutable unsigned Offset;
42
43
/// TableGen'erated function for getting the binary encoding for an
44
/// instruction.
45
uint64_t getBinaryCodeForInstr(const MCInst &MI,
46
SmallVectorImpl<MCFixup> &Fixups,
47
const MCSubtargetInfo &STI) const;
48
49
/// Returns the binary encoding of operands.
50
///
51
/// If an operand requires relocation, the relocation is recorded
52
/// and zero is returned.
53
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
54
SmallVectorImpl<MCFixup> &Fixups,
55
const MCSubtargetInfo &STI) const;
56
57
unsigned getMemOpValue(const MCInst &MI, unsigned Op,
58
SmallVectorImpl<MCFixup> &Fixups,
59
const MCSubtargetInfo &STI) const;
60
61
unsigned getPCRelImmOpValue(const MCInst &MI, unsigned Op,
62
SmallVectorImpl<MCFixup> &Fixups,
63
const MCSubtargetInfo &STI) const;
64
65
unsigned getCGImmOpValue(const MCInst &MI, unsigned Op,
66
SmallVectorImpl<MCFixup> &Fixups,
67
const MCSubtargetInfo &STI) const;
68
69
unsigned getCCOpValue(const MCInst &MI, unsigned Op,
70
SmallVectorImpl<MCFixup> &Fixups,
71
const MCSubtargetInfo &STI) const;
72
73
public:
74
MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
75
: Ctx(ctx), MCII(MCII) {}
76
77
void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
78
SmallVectorImpl<MCFixup> &Fixups,
79
const MCSubtargetInfo &STI) const override;
80
};
81
82
void MSP430MCCodeEmitter::encodeInstruction(const MCInst &MI,
83
SmallVectorImpl<char> &CB,
84
SmallVectorImpl<MCFixup> &Fixups,
85
const MCSubtargetInfo &STI) const {
86
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
87
// Get byte count of instruction.
88
unsigned Size = Desc.getSize();
89
90
// Initialize fixup offset
91
Offset = 2;
92
93
uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);
94
size_t WordCount = Size / 2;
95
96
while (WordCount--) {
97
support::endian::write(CB, (uint16_t)BinaryOpCode,
98
llvm::endianness::little);
99
BinaryOpCode >>= 16;
100
}
101
}
102
103
unsigned MSP430MCCodeEmitter::getMachineOpValue(const MCInst &MI,
104
const MCOperand &MO,
105
SmallVectorImpl<MCFixup> &Fixups,
106
const MCSubtargetInfo &STI) const {
107
if (MO.isReg())
108
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
109
110
if (MO.isImm()) {
111
Offset += 2;
112
return MO.getImm();
113
}
114
115
assert(MO.isExpr() && "Expected expr operand");
116
Fixups.push_back(MCFixup::create(Offset, MO.getExpr(),
117
static_cast<MCFixupKind>(MSP430::fixup_16_byte), MI.getLoc()));
118
Offset += 2;
119
return 0;
120
}
121
122
unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op,
123
SmallVectorImpl<MCFixup> &Fixups,
124
const MCSubtargetInfo &STI) const {
125
const MCOperand &MO1 = MI.getOperand(Op);
126
assert(MO1.isReg() && "Register operand expected");
127
unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
128
129
const MCOperand &MO2 = MI.getOperand(Op + 1);
130
if (MO2.isImm()) {
131
Offset += 2;
132
return ((unsigned)MO2.getImm() << 4) | Reg;
133
}
134
135
assert(MO2.isExpr() && "Expr operand expected");
136
MSP430::Fixups FixupKind;
137
switch (Reg) {
138
case 0:
139
FixupKind = MSP430::fixup_16_pcrel_byte;
140
break;
141
case 2:
142
FixupKind = MSP430::fixup_16_byte;
143
break;
144
default:
145
FixupKind = MSP430::fixup_16_byte;
146
break;
147
}
148
Fixups.push_back(MCFixup::create(Offset, MO2.getExpr(),
149
static_cast<MCFixupKind>(FixupKind), MI.getLoc()));
150
Offset += 2;
151
return Reg;
152
}
153
154
unsigned MSP430MCCodeEmitter::getPCRelImmOpValue(const MCInst &MI, unsigned Op,
155
SmallVectorImpl<MCFixup> &Fixups,
156
const MCSubtargetInfo &STI) const {
157
const MCOperand &MO = MI.getOperand(Op);
158
if (MO.isImm())
159
return MO.getImm();
160
161
assert(MO.isExpr() && "Expr operand expected");
162
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
163
static_cast<MCFixupKind>(MSP430::fixup_10_pcrel), MI.getLoc()));
164
return 0;
165
}
166
167
unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op,
168
SmallVectorImpl<MCFixup> &Fixups,
169
const MCSubtargetInfo &STI) const {
170
const MCOperand &MO = MI.getOperand(Op);
171
assert(MO.isImm() && "Expr operand expected");
172
173
int64_t Imm = MO.getImm();
174
switch (Imm) {
175
default:
176
llvm_unreachable("Invalid immediate value");
177
case 4: return 0x22;
178
case 8: return 0x32;
179
case 0: return 0x03;
180
case 1: return 0x13;
181
case 2: return 0x23;
182
case -1: return 0x33;
183
}
184
}
185
186
unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
187
SmallVectorImpl<MCFixup> &Fixups,
188
const MCSubtargetInfo &STI) const {
189
const MCOperand &MO = MI.getOperand(Op);
190
assert(MO.isImm() && "Immediate operand expected");
191
switch (MO.getImm()) {
192
case MSP430CC::COND_NE: return 0;
193
case MSP430CC::COND_E: return 1;
194
case MSP430CC::COND_LO: return 2;
195
case MSP430CC::COND_HS: return 3;
196
case MSP430CC::COND_N: return 4;
197
case MSP430CC::COND_GE: return 5;
198
case MSP430CC::COND_L: return 6;
199
default:
200
llvm_unreachable("Unknown condition code");
201
}
202
}
203
204
MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII,
205
MCContext &Ctx) {
206
return new MSP430MCCodeEmitter(Ctx, MCII);
207
}
208
209
#include "MSP430GenMCCodeEmitter.inc"
210
211
} // end of namespace llvm
212
213