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 22 using namespace llvm; 23 24 #define DEBUG_TYPE "ve-asmprinter" 25 26 // The generated AsmMatcher VEGenAsmWriter uses "VE" as the target 27 // namespace. 28 namespace llvm { 29 namespace VE { 30 using namespace VE; 31 } 32 } // namespace llvm 33 34 #define GET_INSTRUCTION_NAME 35 #define PRINT_ALIAS_INSTR 36 #include "VEGenAsmWriter.inc" 37 38 void VEInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 39 OS << '%' << StringRef(getRegisterName(RegNo)).lower(); 40 } 41 42 void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address, 43 StringRef Annot, const MCSubtargetInfo &STI, 44 raw_ostream &OS) { 45 if (!printAliasInstr(MI, Address, STI, OS)) 46 printInstruction(MI, Address, STI, OS); 47 printAnnotation(OS, Annot); 48 } 49 50 void 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 int32_t TruncatedImm = static_cast<int32_t>(MO.getImm()); 64 O << TruncatedImm; 65 return; 66 } 67 } 68 69 assert(MO.isExpr() && "Unknown operand kind in printOperand"); 70 MO.getExpr()->print(O, &MAI); 71 } 72 73 void VEInstPrinter::printMemASXOperand(const MCInst *MI, int OpNum, 74 const MCSubtargetInfo &STI, 75 raw_ostream &O, const char *Modifier) { 76 // If this is an ADD operand, emit it like normal operands. 77 if (Modifier && !strcmp(Modifier, "arith")) { 78 printOperand(MI, OpNum, STI, O); 79 O << ", "; 80 printOperand(MI, OpNum + 1, STI, O); 81 return; 82 } 83 84 if (MI->getOperand(OpNum + 2).isImm() && 85 MI->getOperand(OpNum + 2).getImm() == 0) { 86 // don't print "+0" 87 } else { 88 printOperand(MI, OpNum + 2, STI, O); 89 } 90 if (MI->getOperand(OpNum + 1).isImm() && 91 MI->getOperand(OpNum + 1).getImm() == 0 && 92 MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 93 if (MI->getOperand(OpNum + 2).isImm() && 94 MI->getOperand(OpNum + 2).getImm() == 0) { 95 O << "0"; 96 } else { 97 // don't print "+0,+0" 98 } 99 } else { 100 O << "("; 101 if (MI->getOperand(OpNum + 1).isImm() && 102 MI->getOperand(OpNum + 1).getImm() == 0) { 103 // don't print "+0" 104 } else { 105 printOperand(MI, OpNum + 1, STI, O); 106 } 107 if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 108 // don't print "+0" 109 } else { 110 O << ", "; 111 printOperand(MI, OpNum, STI, O); 112 } 113 O << ")"; 114 } 115 } 116 117 void VEInstPrinter::printMemASOperandASX(const MCInst *MI, int OpNum, 118 const MCSubtargetInfo &STI, 119 raw_ostream &O, const char *Modifier) { 120 // If this is an ADD operand, emit it like normal operands. 121 if (Modifier && !strcmp(Modifier, "arith")) { 122 printOperand(MI, OpNum, STI, O); 123 O << ", "; 124 printOperand(MI, OpNum + 1, STI, O); 125 return; 126 } 127 128 if (MI->getOperand(OpNum + 1).isImm() && 129 MI->getOperand(OpNum + 1).getImm() == 0) { 130 // don't print "+0" 131 } else { 132 printOperand(MI, OpNum + 1, STI, O); 133 } 134 if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 135 if (MI->getOperand(OpNum + 1).isImm() && 136 MI->getOperand(OpNum + 1).getImm() == 0) { 137 O << "0"; 138 } else { 139 // don't print "(0)" 140 } 141 } else { 142 O << "(, "; 143 printOperand(MI, OpNum, STI, O); 144 O << ")"; 145 } 146 } 147 148 void VEInstPrinter::printMemASOperand(const MCInst *MI, int OpNum, 149 const MCSubtargetInfo &STI, 150 raw_ostream &O, const char *Modifier) { 151 // If this is an ADD operand, emit it like normal operands. 152 if (Modifier && !strcmp(Modifier, "arith")) { 153 printOperand(MI, OpNum, STI, O); 154 O << ", "; 155 printOperand(MI, OpNum + 1, STI, O); 156 return; 157 } 158 159 const MCOperand &MO = MI->getOperand(OpNum + 1); 160 if (!MO.isImm() || MO.getImm() != 0) { 161 printOperand(MI, OpNum + 1, STI, O); 162 } 163 O << "("; 164 printOperand(MI, OpNum, STI, O); 165 O << ")"; 166 } 167 168 void VEInstPrinter::printMImmOperand(const MCInst *MI, int OpNum, 169 const MCSubtargetInfo &STI, 170 raw_ostream &O) { 171 int MImm = (int)MI->getOperand(OpNum).getImm() & 0x7f; 172 if (MImm > 63) 173 O << "(" << MImm - 64 << ")0"; 174 else 175 O << "(" << MImm << ")1"; 176 } 177 178 void VEInstPrinter::printCCOperand(const MCInst *MI, int OpNum, 179 const MCSubtargetInfo &STI, raw_ostream &O) { 180 int CC = (int)MI->getOperand(OpNum).getImm(); 181 O << VECondCodeToString((VECC::CondCode)CC); 182 } 183