Files
TheRock/compiler/amd-llvm/llvm/lib/Target/M68k/MCTargetDesc/M68kInstPrinter.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

176 lines
5.4 KiB
C++

//===-- M68kInstPrinter.cpp - Convert M68k MCInst to asm --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains definitions for an M68k MCInst printer.
///
//===----------------------------------------------------------------------===//
// TODO Conform with all supported Motorola ASM syntax
// Motorola's assembly has several syntax variants, especially on
// addressing modes.
// For example, you can write pc indirect w/ displacement as
// `x(%pc)`, where `x` is the displacement imm, or `(x,%pc)`.
// Currently we're picking the variant that is different from
// GCC, albeit being recognizable by GNU AS.
// Not sure what is the impact now (e.g. some syntax might
// not be recognized by some old consoles' toolchains, in which
// case we can not use our integrated assembler), but either way,
// it will be great to support all of the variants in the future.
#include "M68kInstPrinter.h"
#include "M68kBaseInfo.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
#define PRINT_ALIAS_INSTR
#include "M68kGenAsmWriter.inc"
void M68kInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {
OS << "%" << getRegisterName(Reg);
}
void M68kInstPrinter::printInst(const MCInst *MI, uint64_t Address,
StringRef Annot, const MCSubtargetInfo &STI,
raw_ostream &O) {
if (!printAliasInstr(MI, Address, O))
printInstruction(MI, Address, O);
printAnnotation(O, Annot);
}
void M68kInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);
if (MO.isReg()) {
MCRegister Reg = MO.getReg();
if (Reg.isValid())
printRegName(O, Reg);
return;
}
if (MO.isImm()) {
printImmediate(MI, OpNo, O);
return;
}
assert(MO.isExpr() && "Unknown operand kind in printOperand");
MAI.printExpr(O, *MO.getExpr());
}
void M68kInstPrinter::printImmediate(const MCInst *MI, unsigned opNum,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(opNum);
if (MO.isImm())
O << '#' << MO.getImm();
else if (MO.isExpr()) {
O << '#';
MAI.printExpr(O, *MO.getExpr());
} else
llvm_unreachable("Unknown immediate kind");
}
void M68kInstPrinter::printMoveMask(const MCInst *MI, unsigned opNum,
raw_ostream &O) {
unsigned Mask = MI->getOperand(opNum).getImm();
assert((Mask & 0xFFFF) == Mask && "Mask is always 16 bits");
// A move mask is splitted into two parts:
// bits 0 ~ 7 correspond to D0 ~ D7 regs
// bits 8 ~ 15 correspond to A0 ~ A7 regs
//
// In the assembly syntax, we want to use a dash to replace
// a continuous range of registers. For example, if the bit
// mask is 0b101110, we want to print "D1-D3,D5" instead of
// "D1,D2,D3,D4,D5".
//
// However, we don't want a dash to cross between data registers
// and address registers (i.e. there shouldn't be a dash crossing
// bit 7 and 8) since that is not really intuitive. So we simply
// print the data register part (bit 0~7) and address register part
// separately.
uint8_t HalfMask;
unsigned Reg;
for (int s = 0; s < 16; s += 8) {
HalfMask = (Mask >> s) & 0xFF;
// Print separation comma only if
// both data & register parts have bit(s) set
if (s != 0 && (Mask & 0xFF) && HalfMask)
O << '/';
for (int i = 0; HalfMask; ++i) {
if ((HalfMask >> i) & 0b1) {
HalfMask ^= 0b1 << i;
Reg = M68kII::getMaskedSpillRegister(i + s);
printRegName(O, Reg);
int j = i;
while ((HalfMask >> (j + 1)) & 0b1)
HalfMask ^= 0b1 << ++j;
if (j != i) {
O << '-';
Reg = M68kII::getMaskedSpillRegister(j + s);
printRegName(O, Reg);
}
i = j;
if (HalfMask)
O << '/';
}
}
}
}
void M68kInstPrinter::printDisp(const MCInst *MI, unsigned opNum,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(opNum);
if (Op.isImm()) {
O << Op.getImm();
return;
}
assert(Op.isExpr() && "Unknown operand kind in printOperand");
MAI.printExpr(O, *Op.getExpr());
}
void M68kInstPrinter::printScale(const MCInst *MI, unsigned opNum,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(opNum);
// Scale has to be an immediate.
unsigned Scale = Op.getImm();
// We only print it out when it's larger than 1
if (Scale > 1)
O << "*" << Scale;
}
// NOTE forcing (W,L) size available since M68020 only
void M68kInstPrinter::printAbsMem(const MCInst *MI, unsigned opNum,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(opNum);
if (MO.isExpr()) {
MAI.printExpr(O, *MO.getExpr());
return;
}
assert(MO.isImm() && "absolute memory addressing needs an immediate");
O << format("$%0" PRIx64, (uint64_t)MO.getImm());
}