Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/MCTargetDesc/M68kInstPrinter.cpp
35294 views
1
//===-- M68kInstPrinter.cpp - Convert M68k MCInst to asm --------*- C++ -*-===//
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
/// \file
10
/// This file contains definitions for an M68k MCInst printer.
11
///
12
//===----------------------------------------------------------------------===//
13
14
// TODO Conform with all supported Motorola ASM syntax
15
// Motorola's assembly has several syntax variants, especially on
16
// addressing modes.
17
// For example, you can write pc indirect w/ displacement as
18
// `x(%pc)`, where `x` is the displacement imm, or `(x,%pc)`.
19
// Currently we're picking the variant that is different from
20
// GCC, albeit being recognizable by GNU AS.
21
// Not sure what is the impact now (e.g. some syntax might
22
// not be recognized by some old consoles' toolchains, in which
23
// case we can not use our integrated assembler), but either way,
24
// it will be great to support all of the variants in the future.
25
26
#include "M68kInstPrinter.h"
27
#include "M68kBaseInfo.h"
28
29
#include "llvm/ADT/StringExtras.h"
30
#include "llvm/MC/MCExpr.h"
31
#include "llvm/MC/MCInst.h"
32
#include "llvm/MC/MCInstrInfo.h"
33
#include "llvm/MC/MCSymbol.h"
34
#include "llvm/Support/ErrorHandling.h"
35
#include "llvm/Support/raw_ostream.h"
36
37
using namespace llvm;
38
39
#define DEBUG_TYPE "asm-printer"
40
41
#define PRINT_ALIAS_INSTR
42
#include "M68kGenAsmWriter.inc"
43
44
void M68kInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
45
OS << "%" << getRegisterName(Reg);
46
}
47
48
void M68kInstPrinter::printInst(const MCInst *MI, uint64_t Address,
49
StringRef Annot, const MCSubtargetInfo &STI,
50
raw_ostream &O) {
51
if (!printAliasInstr(MI, Address, O))
52
printInstruction(MI, Address, O);
53
54
printAnnotation(O, Annot);
55
}
56
57
void M68kInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
58
raw_ostream &O) {
59
const MCOperand &MO = MI->getOperand(OpNo);
60
if (MO.isReg()) {
61
printRegName(O, MO.getReg());
62
return;
63
}
64
65
if (MO.isImm()) {
66
printImmediate(MI, OpNo, O);
67
return;
68
}
69
70
assert(MO.isExpr() && "Unknown operand kind in printOperand");
71
MO.getExpr()->print(O, &MAI);
72
}
73
74
void M68kInstPrinter::printImmediate(const MCInst *MI, unsigned opNum,
75
raw_ostream &O) {
76
const MCOperand &MO = MI->getOperand(opNum);
77
if (MO.isImm())
78
O << '#' << MO.getImm();
79
else if (MO.isExpr()) {
80
O << '#';
81
MO.getExpr()->print(O, &MAI);
82
} else
83
llvm_unreachable("Unknown immediate kind");
84
}
85
86
void M68kInstPrinter::printMoveMask(const MCInst *MI, unsigned opNum,
87
raw_ostream &O) {
88
unsigned Mask = MI->getOperand(opNum).getImm();
89
assert((Mask & 0xFFFF) == Mask && "Mask is always 16 bits");
90
91
// A move mask is splitted into two parts:
92
// bits 0 ~ 7 correspond to D0 ~ D7 regs
93
// bits 8 ~ 15 correspond to A0 ~ A7 regs
94
//
95
// In the assembly syntax, we want to use a dash to replace
96
// a continuous range of registers. For example, if the bit
97
// mask is 0b101110, we want to print "D1-D3,D5" instead of
98
// "D1,D2,D3,D4,D5".
99
//
100
// However, we don't want a dash to cross between data registers
101
// and address registers (i.e. there shouldn't be a dash crossing
102
// bit 7 and 8) since that is not really intuitive. So we simply
103
// print the data register part (bit 0~7) and address register part
104
// separately.
105
uint8_t HalfMask;
106
unsigned Reg;
107
for (int s = 0; s < 16; s += 8) {
108
HalfMask = (Mask >> s) & 0xFF;
109
// Print separation comma only if
110
// both data & register parts have bit(s) set
111
if (s != 0 && (Mask & 0xFF) && HalfMask)
112
O << '/';
113
114
for (int i = 0; HalfMask; ++i) {
115
if ((HalfMask >> i) & 0b1) {
116
HalfMask ^= 0b1 << i;
117
Reg = M68kII::getMaskedSpillRegister(i + s);
118
printRegName(O, Reg);
119
120
int j = i;
121
while ((HalfMask >> (j + 1)) & 0b1)
122
HalfMask ^= 0b1 << ++j;
123
124
if (j != i) {
125
O << '-';
126
Reg = M68kII::getMaskedSpillRegister(j + s);
127
printRegName(O, Reg);
128
}
129
130
i = j;
131
132
if (HalfMask)
133
O << '/';
134
}
135
}
136
}
137
}
138
139
void M68kInstPrinter::printDisp(const MCInst *MI, unsigned opNum,
140
raw_ostream &O) {
141
const MCOperand &Op = MI->getOperand(opNum);
142
if (Op.isImm()) {
143
O << Op.getImm();
144
return;
145
}
146
assert(Op.isExpr() && "Unknown operand kind in printOperand");
147
Op.getExpr()->print(O, &MAI);
148
}
149
150
// NOTE forcing (W,L) size available since M68020 only
151
void M68kInstPrinter::printAbsMem(const MCInst *MI, unsigned opNum,
152
raw_ostream &O) {
153
const MCOperand &MO = MI->getOperand(opNum);
154
155
if (MO.isExpr()) {
156
MO.getExpr()->print(O, &MAI);
157
return;
158
}
159
160
assert(MO.isImm() && "absolute memory addressing needs an immediate");
161
O << format("$%0" PRIx64, (uint64_t)MO.getImm());
162
}
163
164