brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 778d312 Raw
164 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains definitions for an M68k MCInst printer.11///12//===----------------------------------------------------------------------===//13 14// TODO Conform with all supported Motorola ASM syntax15// Motorola's assembly has several syntax variants, especially on16// addressing modes.17// For example, you can write pc indirect w/ displacement as18// `x(%pc)`, where `x` is the displacement imm, or `(x,%pc)`.19// Currently we're picking the variant that is different from20// GCC, albeit being recognizable by GNU AS.21// Not sure what is the impact now (e.g. some syntax might22// not be recognized by some old consoles' toolchains, in which23// 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/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"35#include "llvm/Support/ErrorHandling.h"36#include "llvm/Support/raw_ostream.h"37 38using namespace llvm;39 40#define DEBUG_TYPE "asm-printer"41 42#define PRINT_ALIAS_INSTR43#include "M68kGenAsmWriter.inc"44 45void M68kInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {46  OS << "%" << getRegisterName(Reg);47}48 49void M68kInstPrinter::printInst(const MCInst *MI, uint64_t Address,50                                StringRef Annot, const MCSubtargetInfo &STI,51                                raw_ostream &O) {52  if (!printAliasInstr(MI, Address, O))53    printInstruction(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  } else84    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 regs94  // bits 8 ~ 15 correspond to A0 ~ A7 regs95  //96  // In the assembly syntax, we want to use a dash to replace97  // a continuous range of registers. For example, if the bit98  // mask is 0b101110, we want to print "D1-D3,D5" instead of99  // "D1,D2,D3,D4,D5".100  //101  // However, we don't want a dash to cross between data registers102  // and address registers (i.e. there shouldn't be a dash crossing103  // bit 7 and 8) since that is not really intuitive. So we simply104  // print the data register part (bit 0~7) and address register part105  // 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 if111    // both data & register parts have bit(s) set112    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;118        Reg = M68kII::getMaskedSpillRegister(i + s);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 << '-';127          Reg = M68kII::getMaskedSpillRegister(j + s);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 only152void 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}164