1//===-- VEInstPrinter.cpp - Convert VE MCInst to assembly 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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This class prints an VE MCInst to a .s file.
10//
11//===----------------------------------------------------------------------===//
12
13#include "VEInstPrinter.h"
14#include "VE.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCRegisterInfo.h"
18#include "llvm/MC/MCSubtargetInfo.h"
19#include "llvm/MC/MCSymbol.h"
20#include "llvm/Support/raw_ostream.h"
21
22using namespace llvm;
23
24#define DEBUG_TYPE "ve-asmprinter"
25
26// The generated AsmMatcher VEGenAsmWriter uses "VE" as the target
27// namespace.
28namespace llvm {
29namespace VE {
30using namespace VE;
31}
32} // namespace llvm
33
34#define GET_INSTRUCTION_NAME
35#define PRINT_ALIAS_INSTR
36#include "VEGenAsmWriter.inc"
37
38void VEInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
39  OS << '%' << StringRef(getRegisterName(RegNo)).lower();
40}
41
42void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address,
43                              StringRef Annot, const MCSubtargetInfo &STI,
44                              raw_ostream &OS) {
45  if (!printAliasInstr(MI, STI, OS))
46    printInstruction(MI, Address, STI, OS);
47  printAnnotation(OS, Annot);
48}
49
50void VEInstPrinter::printOperand(const MCInst *MI, int opNum,
51                                 const MCSubtargetInfo &STI, raw_ostream &O) {
52  const MCOperand &MO = MI->getOperand(opNum);
53
54  if (MO.isReg()) {
55    printRegName(O, MO.getReg());
56    return;
57  }
58
59  if (MO.isImm()) {
60    switch (MI->getOpcode()) {
61    default:
62      // Expects signed 32bit literals
63      assert(isInt<32>(MO.getImm()) && "Immediate too large");
64      int32_t TruncatedImm = static_cast<int32_t>(MO.getImm());
65      O << TruncatedImm;
66      return;
67    }
68  }
69
70  assert(MO.isExpr() && "Unknown operand kind in printOperand");
71  MO.getExpr()->print(O, &MAI);
72}
73
74void VEInstPrinter::printMemASXOperand(const MCInst *MI, int opNum,
75                                       const MCSubtargetInfo &STI,
76                                       raw_ostream &O, const char *Modifier) {
77  // If this is an ADD operand, emit it like normal operands.
78  if (Modifier && !strcmp(Modifier, "arith")) {
79    printOperand(MI, opNum, STI, O);
80    O << ", ";
81    printOperand(MI, opNum + 1, STI, O);
82    return;
83  }
84
85  const MCOperand &MO = MI->getOperand(opNum + 1);
86  if (!MO.isImm() || MO.getImm() != 0) {
87    printOperand(MI, opNum + 1, STI, O);
88  }
89  O << "(,";
90  printOperand(MI, opNum, STI, O);
91  O << ")";
92}
93
94void VEInstPrinter::printMemASOperand(const MCInst *MI, int opNum,
95                                      const MCSubtargetInfo &STI,
96                                      raw_ostream &O, const char *Modifier) {
97  // If this is an ADD operand, emit it like normal operands.
98  if (Modifier && !strcmp(Modifier, "arith")) {
99    printOperand(MI, opNum, STI, O);
100    O << ", ";
101    printOperand(MI, opNum + 1, STI, O);
102    return;
103  }
104
105  const MCOperand &MO = MI->getOperand(opNum + 1);
106  if (!MO.isImm() || MO.getImm() != 0) {
107    printOperand(MI, opNum + 1, STI, O);
108  }
109  O << "(";
110  printOperand(MI, opNum, STI, O);
111  O << ")";
112}
113
114void VEInstPrinter::printCCOperand(const MCInst *MI, int opNum,
115                                   const MCSubtargetInfo &STI, raw_ostream &O) {
116  int CC = (int)MI->getOperand(opNum).getImm();
117  O << VECondCodeToString((VECC::CondCodes)CC);
118}
119