brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.4 KiB · add4096 Raw
302 lines · cpp
1//===-- LanaiInstPrinter.cpp - Convert Lanai MCInst to asm syntax ---------===//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// This class prints an Lanai MCInst to a .s file.10//11//===----------------------------------------------------------------------===//12 13#include "LanaiInstPrinter.h"14#include "LanaiAluCode.h"15#include "LanaiCondCode.h"16#include "MCTargetDesc/LanaiMCTargetDesc.h"17#include "llvm/MC/MCAsmInfo.h"18#include "llvm/MC/MCExpr.h"19#include "llvm/MC/MCInst.h"20#include "llvm/MC/MCSymbol.h"21#include "llvm/Support/ErrorHandling.h"22 23using namespace llvm;24 25#define DEBUG_TYPE "asm-printer"26 27// Include the auto-generated portion of the assembly writer.28#define PRINT_ALIAS_INSTR29#include "LanaiGenAsmWriter.inc"30 31void LanaiInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {32  OS << StringRef(getRegisterName(Reg)).lower();33}34 35bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,36                                 StringRef Alias, unsigned OpNo0,37                                 unsigned OpNo1) {38  OS << "\t" << Alias << " ";39  printOperand(MI, OpNo0, OS);40  OS << ", ";41  printOperand(MI, OpNo1, OS);42  return true;43}44 45static bool usesGivenOffset(const MCInst *MI, int AddOffset) {46  unsigned AluCode = MI->getOperand(3).getImm();47  return LPAC::encodeLanaiAluCode(AluCode) == LPAC::ADD &&48         (MI->getOperand(2).getImm() == AddOffset ||49          MI->getOperand(2).getImm() == -AddOffset);50}51 52static bool isPreIncrementForm(const MCInst *MI, int AddOffset) {53  unsigned AluCode = MI->getOperand(3).getImm();54  return LPAC::isPreOp(AluCode) && usesGivenOffset(MI, AddOffset);55}56 57static bool isPostIncrementForm(const MCInst *MI, int AddOffset) {58  unsigned AluCode = MI->getOperand(3).getImm();59  return LPAC::isPostOp(AluCode) && usesGivenOffset(MI, AddOffset);60}61 62static StringRef decIncOperator(const MCInst *MI) {63  if (MI->getOperand(2).getImm() < 0)64    return "--";65  return "++";66}67 68bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI,69                                                raw_ostream &OS,70                                                StringRef Opcode,71                                                int AddOffset) {72  if (isPreIncrementForm(MI, AddOffset)) {73    OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%"74       << getRegisterName(MI->getOperand(1).getReg()) << "], %"75       << getRegisterName(MI->getOperand(0).getReg());76    return true;77  }78  if (isPostIncrementForm(MI, AddOffset)) {79    OS << "\t" << Opcode << "\t[%"80       << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI)81       << "], %" << getRegisterName(MI->getOperand(0).getReg());82    return true;83  }84  return false;85}86 87bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI,88                                                 raw_ostream &OS,89                                                 StringRef Opcode,90                                                 int AddOffset) {91  if (isPreIncrementForm(MI, AddOffset)) {92    OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())93       << ", [" << decIncOperator(MI) << "%"94       << getRegisterName(MI->getOperand(1).getReg()) << "]";95    return true;96  }97  if (isPostIncrementForm(MI, AddOffset)) {98    OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())99       << ", [%" << getRegisterName(MI->getOperand(1).getReg())100       << decIncOperator(MI) << "]";101    return true;102  }103  return false;104}105 106bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) {107  switch (MI->getOpcode()) {108  case Lanai::LDW_RI:109    // ld 4[*%rN], %rX => ld [++imm], %rX110    // ld -4[*%rN], %rX => ld [--imm], %rX111    // ld 4[%rN*], %rX => ld [imm++], %rX112    // ld -4[%rN*], %rX => ld [imm--], %rX113    return printMemoryLoadIncrement(MI, OS, "ld", 4);114  case Lanai::LDHs_RI:115    return printMemoryLoadIncrement(MI, OS, "ld.h", 2);116  case Lanai::LDHz_RI:117    return printMemoryLoadIncrement(MI, OS, "uld.h", 2);118  case Lanai::LDBs_RI:119    return printMemoryLoadIncrement(MI, OS, "ld.b", 1);120  case Lanai::LDBz_RI:121    return printMemoryLoadIncrement(MI, OS, "uld.b", 1);122  case Lanai::SW_RI:123    // st %rX, 4[*%rN] => st %rX, [++imm]124    // st %rX, -4[*%rN] => st %rX, [--imm]125    // st %rX, 4[%rN*] => st %rX, [imm++]126    // st %rX, -4[%rN*] => st %rX, [imm--]127    return printMemoryStoreIncrement(MI, OS, "st", 4);128  case Lanai::STH_RI:129    return printMemoryStoreIncrement(MI, OS, "st.h", 2);130  case Lanai::STB_RI:131    return printMemoryStoreIncrement(MI, OS, "st.b", 1);132  default:133    return false;134  }135}136 137void LanaiInstPrinter::printInst(const MCInst *MI, uint64_t Address,138                                 StringRef Annotation,139                                 const MCSubtargetInfo & /*STI*/,140                                 raw_ostream &OS) {141  if (!printAlias(MI, OS) && !printAliasInstr(MI, Address, OS))142    printInstruction(MI, Address, OS);143  printAnnotation(OS, Annotation);144}145 146void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,147                                    raw_ostream &OS) {148  const MCOperand &Op = MI->getOperand(OpNo);149  if (Op.isReg())150    OS << "%" << getRegisterName(Op.getReg());151  else if (Op.isImm())152    OS << formatHex(Op.getImm());153  else {154    assert(Op.isExpr() && "Expected an expression");155    MAI.printExpr(OS, *Op.getExpr());156  }157}158 159void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo,160                                          raw_ostream &OS) {161  const MCOperand &Op = MI->getOperand(OpNo);162  if (Op.isImm()) {163    OS << '[' << formatHex(Op.getImm()) << ']';164  } else {165    // Symbolic operand will be lowered to immediate value by linker166    assert(Op.isExpr() && "Expected an expression");167    OS << '[';168    MAI.printExpr(OS, *Op.getExpr());169    OS << ']';170  }171}172 173void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo,174                                           raw_ostream &OS) {175  const MCOperand &Op = MI->getOperand(OpNo);176  if (Op.isImm()) {177    OS << formatHex(Op.getImm() << 16);178  } else {179    // Symbolic operand will be lowered to immediate value by linker180    assert(Op.isExpr() && "Expected an expression");181    MAI.printExpr(OS, *Op.getExpr());182  }183}184 185void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo,186                                              raw_ostream &OS) {187  const MCOperand &Op = MI->getOperand(OpNo);188  if (Op.isImm()) {189    OS << formatHex((Op.getImm() << 16) | 0xffff);190  } else {191    // Symbolic operand will be lowered to immediate value by linker192    assert(Op.isExpr() && "Expected an expression");193    MAI.printExpr(OS, *Op.getExpr());194  }195}196 197void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo,198                                              raw_ostream &OS) {199  const MCOperand &Op = MI->getOperand(OpNo);200  if (Op.isImm()) {201    OS << formatHex(0xffff0000 | Op.getImm());202  } else {203    // Symbolic operand will be lowered to immediate value by linker204    assert(Op.isExpr() && "Expected an expression");205    MAI.printExpr(OS, *Op.getExpr());206  }207}208 209static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode,210                                    const MCOperand &RegOp) {211  assert(RegOp.isReg() && "Register operand expected");212  OS << "[";213  if (LPAC::isPreOp(AluCode))214    OS << "*";215  OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg());216  if (LPAC::isPostOp(AluCode))217    OS << "*";218  OS << "]";219}220 221template <unsigned SizeInBits>222static void printMemoryImmediateOffset(const MCAsmInfo &MAI,223                                       const MCOperand &OffsetOp,224                                       raw_ostream &OS) {225  assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");226  if (OffsetOp.isImm()) {227    assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");228    OS << OffsetOp.getImm();229  } else230    MAI.printExpr(OS, *OffsetOp.getExpr());231}232 233void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo,234                                         raw_ostream &OS) {235  const MCOperand &RegOp = MI->getOperand(OpNo);236  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);237  const MCOperand &AluOp = MI->getOperand(OpNo + 2);238  const unsigned AluCode = AluOp.getImm();239 240  // Offset241  printMemoryImmediateOffset<16>(MAI, OffsetOp, OS);242 243  // Register244  printMemoryBaseRegister(OS, AluCode, RegOp);245}246 247void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo,248                                         raw_ostream &OS) {249  const MCOperand &RegOp = MI->getOperand(OpNo);250  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);251  const MCOperand &AluOp = MI->getOperand(OpNo + 2);252  const unsigned AluCode = AluOp.getImm();253  assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected.");254 255  // [ Base OP Offset ]256  OS << "[";257  if (LPAC::isPreOp(AluCode))258    OS << "*";259  OS << "%" << getRegisterName(RegOp.getReg());260  if (LPAC::isPostOp(AluCode))261    OS << "*";262  OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " ";263  OS << "%" << getRegisterName(OffsetOp.getReg());264  OS << "]";265}266 267void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo,268                                           raw_ostream &OS) {269  const MCOperand &RegOp = MI->getOperand(OpNo);270  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);271  const MCOperand &AluOp = MI->getOperand(OpNo + 2);272  const unsigned AluCode = AluOp.getImm();273 274  // Offset275  printMemoryImmediateOffset<10>(MAI, OffsetOp, OS);276 277  // Register278  printMemoryBaseRegister(OS, AluCode, RegOp);279}280 281void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,282                                      raw_ostream &OS) {283  LPCC::CondCode CC =284      static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());285  // Handle the undefined value here for printing so we don't abort().286  if (CC >= LPCC::UNKNOWN)287    OS << "<und>";288  else289    OS << lanaiCondCodeToString(CC);290}291 292void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,293                                             raw_ostream &OS) {294  LPCC::CondCode CC =295      static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());296  // Handle the undefined value here for printing so we don't abort().297  if (CC >= LPCC::UNKNOWN)298    OS << "<und>";299  else if (CC != LPCC::ICC_T)300    OS << "." << lanaiCondCodeToString(CC);301}302