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 // Generic registers have identical register name among register classes. 40 unsigned AltIdx = VE::AsmName; 41 OS << '%' << getRegisterName(RegNo, AltIdx); 42 } 43 44 void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address, 45 StringRef Annot, const MCSubtargetInfo &STI, 46 raw_ostream &OS) { 47 if (!printAliasInstr(MI, Address, STI, OS)) 48 printInstruction(MI, Address, STI, OS); 49 printAnnotation(OS, Annot); 50 } 51 52 void VEInstPrinter::printOperand(const MCInst *MI, int OpNum, 53 const MCSubtargetInfo &STI, raw_ostream &O) { 54 const MCOperand &MO = MI->getOperand(OpNum); 55 56 if (MO.isReg()) { 57 printRegName(O, MO.getReg()); 58 return; 59 } 60 61 if (MO.isImm()) { 62 switch (MI->getOpcode()) { 63 default: 64 // Expects signed 32bit literals 65 int32_t TruncatedImm = static_cast<int32_t>(MO.getImm()); 66 O << TruncatedImm; 67 return; 68 } 69 } 70 71 assert(MO.isExpr() && "Unknown operand kind in printOperand"); 72 MO.getExpr()->print(O, &MAI); 73 } 74 75 void VEInstPrinter::printMemASXOperand(const MCInst *MI, int OpNum, 76 const MCSubtargetInfo &STI, 77 raw_ostream &O, const char *Modifier) { 78 // If this is an ADD operand, emit it like normal operands. 79 if (Modifier && !strcmp(Modifier, "arith")) { 80 printOperand(MI, OpNum, STI, O); 81 O << ", "; 82 printOperand(MI, OpNum + 1, STI, O); 83 return; 84 } 85 86 if (MI->getOperand(OpNum + 2).isImm() && 87 MI->getOperand(OpNum + 2).getImm() == 0) { 88 // don't print "+0" 89 } else { 90 printOperand(MI, OpNum + 2, STI, O); 91 } 92 if (MI->getOperand(OpNum + 1).isImm() && 93 MI->getOperand(OpNum + 1).getImm() == 0 && 94 MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 95 if (MI->getOperand(OpNum + 2).isImm() && 96 MI->getOperand(OpNum + 2).getImm() == 0) { 97 O << "0"; 98 } else { 99 // don't print "+0,+0" 100 } 101 } else { 102 O << "("; 103 if (MI->getOperand(OpNum + 1).isImm() && 104 MI->getOperand(OpNum + 1).getImm() == 0) { 105 // don't print "+0" 106 } else { 107 printOperand(MI, OpNum + 1, STI, O); 108 } 109 if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 110 // don't print "+0" 111 } else { 112 O << ", "; 113 printOperand(MI, OpNum, STI, O); 114 } 115 O << ")"; 116 } 117 } 118 119 void VEInstPrinter::printMemASOperandASX(const MCInst *MI, int OpNum, 120 const MCSubtargetInfo &STI, 121 raw_ostream &O, const char *Modifier) { 122 // If this is an ADD operand, emit it like normal operands. 123 if (Modifier && !strcmp(Modifier, "arith")) { 124 printOperand(MI, OpNum, STI, O); 125 O << ", "; 126 printOperand(MI, OpNum + 1, STI, O); 127 return; 128 } 129 130 if (MI->getOperand(OpNum + 1).isImm() && 131 MI->getOperand(OpNum + 1).getImm() == 0) { 132 // don't print "+0" 133 } else { 134 printOperand(MI, OpNum + 1, STI, O); 135 } 136 if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 137 if (MI->getOperand(OpNum + 1).isImm() && 138 MI->getOperand(OpNum + 1).getImm() == 0) { 139 O << "0"; 140 } else { 141 // don't print "(0)" 142 } 143 } else { 144 O << "(, "; 145 printOperand(MI, OpNum, STI, O); 146 O << ")"; 147 } 148 } 149 150 void VEInstPrinter::printMemASOperand(const MCInst *MI, int OpNum, 151 const MCSubtargetInfo &STI, 152 raw_ostream &O, const char *Modifier) { 153 // If this is an ADD operand, emit it like normal operands. 154 if (Modifier && !strcmp(Modifier, "arith")) { 155 printOperand(MI, OpNum, STI, O); 156 O << ", "; 157 printOperand(MI, OpNum + 1, STI, O); 158 return; 159 } 160 161 const MCOperand &MO = MI->getOperand(OpNum + 1); 162 if (!MO.isImm() || MO.getImm() != 0) { 163 printOperand(MI, OpNum + 1, STI, O); 164 } 165 O << "("; 166 printOperand(MI, OpNum, STI, O); 167 O << ")"; 168 } 169 170 void VEInstPrinter::printMImmOperand(const MCInst *MI, int OpNum, 171 const MCSubtargetInfo &STI, 172 raw_ostream &O) { 173 int MImm = (int)MI->getOperand(OpNum).getImm() & 0x7f; 174 if (MImm > 63) 175 O << "(" << MImm - 64 << ")0"; 176 else 177 O << "(" << MImm << ")1"; 178 } 179 180 void VEInstPrinter::printCCOperand(const MCInst *MI, int OpNum, 181 const MCSubtargetInfo &STI, raw_ostream &O) { 182 int CC = (int)MI->getOperand(OpNum).getImm(); 183 O << VECondCodeToString((VECC::CondCode)CC); 184 } 185 186 void VEInstPrinter::printRDOperand(const MCInst *MI, int OpNum, 187 const MCSubtargetInfo &STI, raw_ostream &O) { 188 int RD = (int)MI->getOperand(OpNum).getImm(); 189 O << VERDToString((VERD::RoundingMode)RD); 190 } 191