LLVM 22.0.0git
M68kInstPrinter.cpp
Go to the documentation of this file.
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
30#include "llvm/MC/MCAsmInfo.h"
31#include "llvm/MC/MCExpr.h"
32#include "llvm/MC/MCInst.h"
33#include "llvm/MC/MCInstrInfo.h"
34#include "llvm/MC/MCSymbol.h"
37
38using namespace llvm;
39
40#define DEBUG_TYPE "asm-printer"
41
42#define PRINT_ALIAS_INSTR
43#include "M68kGenAsmWriter.inc"
44
46 OS << "%" << getRegisterName(Reg);
47}
48
50 StringRef Annot, const MCSubtargetInfo &STI,
51 raw_ostream &O) {
52 if (!printAliasInstr(MI, Address, O))
54
55 printAnnotation(O, Annot);
56}
57
58void M68kInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
59 raw_ostream &O) {
60 const MCOperand &MO = MI->getOperand(OpNo);
61 if (MO.isReg()) {
62 printRegName(O, MO.getReg());
63 return;
64 }
65
66 if (MO.isImm()) {
67 printImmediate(MI, OpNo, O);
68 return;
69 }
70
71 assert(MO.isExpr() && "Unknown operand kind in printOperand");
72 MAI.printExpr(O, *MO.getExpr());
73}
74
75void M68kInstPrinter::printImmediate(const MCInst *MI, unsigned opNum,
76 raw_ostream &O) {
77 const MCOperand &MO = MI->getOperand(opNum);
78 if (MO.isImm())
79 O << '#' << MO.getImm();
80 else if (MO.isExpr()) {
81 O << '#';
82 MAI.printExpr(O, *MO.getExpr());
83 } else
84 llvm_unreachable("Unknown immediate kind");
85}
86
87void M68kInstPrinter::printMoveMask(const MCInst *MI, unsigned opNum,
88 raw_ostream &O) {
89 unsigned Mask = MI->getOperand(opNum).getImm();
90 assert((Mask & 0xFFFF) == Mask && "Mask is always 16 bits");
91
92 // A move mask is splitted into two parts:
93 // bits 0 ~ 7 correspond to D0 ~ D7 regs
94 // bits 8 ~ 15 correspond to A0 ~ A7 regs
95 //
96 // In the assembly syntax, we want to use a dash to replace
97 // a continuous range of registers. For example, if the bit
98 // mask is 0b101110, we want to print "D1-D3,D5" instead of
99 // "D1,D2,D3,D4,D5".
100 //
101 // However, we don't want a dash to cross between data registers
102 // and address registers (i.e. there shouldn't be a dash crossing
103 // bit 7 and 8) since that is not really intuitive. So we simply
104 // print the data register part (bit 0~7) and address register part
105 // separately.
106 uint8_t HalfMask;
107 unsigned Reg;
108 for (int s = 0; s < 16; s += 8) {
109 HalfMask = (Mask >> s) & 0xFF;
110 // Print separation comma only if
111 // both data & register parts have bit(s) set
112 if (s != 0 && (Mask & 0xFF) && HalfMask)
113 O << '/';
114
115 for (int i = 0; HalfMask; ++i) {
116 if ((HalfMask >> i) & 0b1) {
117 HalfMask ^= 0b1 << i;
119 printRegName(O, Reg);
120
121 int j = i;
122 while ((HalfMask >> (j + 1)) & 0b1)
123 HalfMask ^= 0b1 << ++j;
124
125 if (j != i) {
126 O << '-';
128 printRegName(O, Reg);
129 }
130
131 i = j;
132
133 if (HalfMask)
134 O << '/';
135 }
136 }
137 }
138}
139
140void M68kInstPrinter::printDisp(const MCInst *MI, unsigned opNum,
141 raw_ostream &O) {
142 const MCOperand &Op = MI->getOperand(opNum);
143 if (Op.isImm()) {
144 O << Op.getImm();
145 return;
146 }
147 assert(Op.isExpr() && "Unknown operand kind in printOperand");
148 MAI.printExpr(O, *Op.getExpr());
149}
150
151// NOTE forcing (W,L) size available since M68020 only
152void M68kInstPrinter::printAbsMem(const MCInst *MI, unsigned opNum,
153 raw_ostream &O) {
154 const MCOperand &MO = MI->getOperand(opNum);
155
156 if (MO.isExpr()) {
157 MAI.printExpr(O, *MO.getExpr());
158 return;
159 }
160
161 assert(MO.isImm() && "absolute memory addressing needs an immediate");
162 O << format("$%0" PRIx64, (uint64_t)MO.getImm());
163}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
IRTranslator LLVM IR MI
This file contains small standalone helper functions and enum definitions for the M68k target useful ...
This file contains declarations for an M68k MCInst printer.
Register Reg
This file contains some functions that are useful when dealing with strings.
bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &OS)
void printRegName(raw_ostream &OS, MCRegister Reg) override
Print the assembler register name.
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
static const char * getRegisterName(MCRegister Reg)
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
Generic base class for all target subtargets.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static unsigned getMaskedSpillRegister(unsigned order)
This is an optimization pass for GlobalISel generic memory operations.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:126
DWARFExpression::Operation Op