brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · c54f33c Raw
208 lines · cpp
1//===- ARCInstPrinter.cpp - ARC MCInst to assembly syntax -------*- 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// This class prints an ARC MCInst to a .s file.10//11//===----------------------------------------------------------------------===//12 13#include "ARCInstPrinter.h"14#include "MCTargetDesc/ARCInfo.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCInst.h"18#include "llvm/MC/MCInstrInfo.h"19#include "llvm/MC/MCSymbol.h"20#include "llvm/Support/Casting.h"21#include "llvm/Support/Debug.h"22#include "llvm/Support/raw_ostream.h"23 24using namespace llvm;25 26#define DEBUG_TYPE "asm-printer"27 28#include "ARCGenAsmWriter.inc"29 30template <class T>31static const char *BadConditionCode(T cc) {32  LLVM_DEBUG(dbgs() << "Unknown condition code passed: " << cc << "\n");33  return "{unknown-cc}";34}35 36static const char *ARCBRCondCodeToString(ARCCC::BRCondCode BRCC) {37  switch (BRCC) {38  case ARCCC::BREQ:39    return "eq";40  case ARCCC::BRNE:41    return "ne";42  case ARCCC::BRLT:43    return "lt";44  case ARCCC::BRGE:45    return "ge";46  case ARCCC::BRLO:47    return "lo";48  case ARCCC::BRHS:49    return "hs";50  }51  return BadConditionCode(BRCC);52}53 54static const char *ARCCondCodeToString(ARCCC::CondCode CC) {55  switch (CC) {56  case ARCCC::EQ:57    return "eq";58  case ARCCC::NE:59    return "ne";60  case ARCCC::P:61    return "p";62  case ARCCC::N:63    return "n";64  case ARCCC::HS:65    return "hs";66  case ARCCC::LO:67    return "lo";68  case ARCCC::GT:69    return "gt";70  case ARCCC::GE:71    return "ge";72  case ARCCC::VS:73    return "vs";74  case ARCCC::VC:75    return "vc";76  case ARCCC::LT:77    return "lt";78  case ARCCC::LE:79    return "le";80  case ARCCC::HI:81    return "hi";82  case ARCCC::LS:83    return "ls";84  case ARCCC::PNZ:85    return "pnz";86  case ARCCC::AL:87    return "al";88  case ARCCC::NZ:89    return "nz";90  case ARCCC::Z:91    return "z";92  }93  return BadConditionCode(CC);94}95 96void ARCInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {97  OS << StringRef(getRegisterName(Reg)).lower();98}99 100void ARCInstPrinter::printInst(const MCInst *MI, uint64_t Address,101                               StringRef Annot, const MCSubtargetInfo &STI,102                               raw_ostream &O) {103  printInstruction(MI, Address, O);104  printAnnotation(O, Annot);105}106 107static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,108                      raw_ostream &OS) {109  int Offset = 0;110  const MCSymbolRefExpr *SRE;111 112  if (const auto *CE = dyn_cast<MCConstantExpr>(Expr)) {113    OS << "0x";114    OS.write_hex(CE->getValue());115    return;116  }117 118  if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr)) {119    SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());120    const auto *CE = dyn_cast<MCConstantExpr>(BE->getRHS());121    assert(SRE && CE && "Binary expression must be sym+const.");122    Offset = CE->getValue();123  } else {124    SRE = dyn_cast<MCSymbolRefExpr>(Expr);125    assert(SRE && "Unexpected MCExpr type.");126  }127  assert(SRE->getSpecifier() == 0);128 129  // Symbols are prefixed with '@'130  OS << '@';131  SRE->getSymbol().print(OS, MAI);132 133  if (Offset) {134    if (Offset > 0)135      OS << '+';136    OS << Offset;137  }138}139 140void ARCInstPrinter::printOperand(const MCInst *MI, unsigned OpNum,141                                  raw_ostream &O) {142  const MCOperand &Op = MI->getOperand(OpNum);143  if (Op.isReg()) {144    printRegName(O, Op.getReg());145    return;146  }147 148  if (Op.isImm()) {149    O << Op.getImm();150    return;151  }152 153  assert(Op.isExpr() && "unknown operand kind in printOperand");154  printExpr(Op.getExpr(), &MAI, O);155}156 157void ARCInstPrinter::printMemOperandRI(const MCInst *MI, unsigned OpNum,158                                       raw_ostream &O) {159  const MCOperand &base = MI->getOperand(OpNum);160  const MCOperand &offset = MI->getOperand(OpNum + 1);161  assert(base.isReg() && "Base should be register.");162  assert(offset.isImm() && "Offset should be immediate.");163  printRegName(O, base.getReg());164  O << "," << offset.getImm();165}166 167void ARCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,168                                           raw_ostream &O) {169 170  const MCOperand &Op = MI->getOperand(OpNum);171  assert(Op.isImm() && "Predicate operand is immediate.");172  O << ARCCondCodeToString((ARCCC::CondCode)Op.getImm());173}174 175void ARCInstPrinter::printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum,176                                               raw_ostream &O) {177  const MCOperand &Op = MI->getOperand(OpNum);178  assert(Op.isImm() && "Predicate operand is immediate.");179  O << ARCBRCondCodeToString((ARCCC::BRCondCode)Op.getImm());180}181 182void ARCInstPrinter::printCCOperand(const MCInst *MI, int OpNum,183                                    raw_ostream &O) {184  O << ARCCondCodeToString((ARCCC::CondCode)MI->getOperand(OpNum).getImm());185}186 187void ARCInstPrinter::printU6ShiftedBy(unsigned ShiftBy, const MCInst *MI,188                                      int OpNum, raw_ostream &O) {189  const MCOperand &MO = MI->getOperand(OpNum);190  if (MO.isImm()) {191    unsigned Value = MO.getImm();192    unsigned Value2 = Value >> ShiftBy;193    if (Value2 > 0x3F || (Value2 << ShiftBy != Value)) {194      errs() << "!!! Instruction has out-of-range U6 immediate operand:\n"195             << "    Opcode is " << MI->getOpcode() << "; operand value is "196             << Value;197      if (ShiftBy)198        errs() << " scaled by " << (1 << ShiftBy) << "\n";199      assert(false && "instruction has wrong format");200    }201  }202  printOperand(MI, OpNum, O);203}204 205void ARCInstPrinter::printU6(const MCInst *MI, int OpNum, raw_ostream &O) {206  printU6ShiftedBy(0, MI, OpNum, O);207}208