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