15ffd83dbSDimitry Andric //===-- VEInstPrinter.cpp - Convert VE MCInst to assembly syntax -----------==// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric // 95ffd83dbSDimitry Andric // This class prints an VE MCInst to a .s file. 105ffd83dbSDimitry Andric // 115ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 125ffd83dbSDimitry Andric 135ffd83dbSDimitry Andric #include "VEInstPrinter.h" 145ffd83dbSDimitry Andric #include "VE.h" 155ffd83dbSDimitry Andric #include "llvm/MC/MCExpr.h" 165ffd83dbSDimitry Andric #include "llvm/MC/MCInst.h" 175ffd83dbSDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 185ffd83dbSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 195ffd83dbSDimitry Andric #include "llvm/MC/MCSymbol.h" 205ffd83dbSDimitry Andric #include "llvm/Support/raw_ostream.h" 215ffd83dbSDimitry Andric 225ffd83dbSDimitry Andric using namespace llvm; 235ffd83dbSDimitry Andric 245ffd83dbSDimitry Andric #define DEBUG_TYPE "ve-asmprinter" 255ffd83dbSDimitry Andric 265ffd83dbSDimitry Andric #define GET_INSTRUCTION_NAME 275ffd83dbSDimitry Andric #define PRINT_ALIAS_INSTR 285ffd83dbSDimitry Andric #include "VEGenAsmWriter.inc" 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric void VEInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 315ffd83dbSDimitry Andric // Generic registers have identical register name among register classes. 325ffd83dbSDimitry Andric unsigned AltIdx = VE::AsmName; 335ffd83dbSDimitry Andric // Misc registers have each own name, so no use alt-names. 345ffd83dbSDimitry Andric if (MRI.getRegClass(VE::MISCRegClassID).contains(RegNo)) 355ffd83dbSDimitry Andric AltIdx = VE::NoRegAltName; 365ffd83dbSDimitry Andric OS << '%' << getRegisterName(RegNo, AltIdx); 375ffd83dbSDimitry Andric } 385ffd83dbSDimitry Andric 395ffd83dbSDimitry Andric void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address, 405ffd83dbSDimitry Andric StringRef Annot, const MCSubtargetInfo &STI, 415ffd83dbSDimitry Andric raw_ostream &OS) { 425ffd83dbSDimitry Andric if (!printAliasInstr(MI, Address, STI, OS)) 435ffd83dbSDimitry Andric printInstruction(MI, Address, STI, OS); 445ffd83dbSDimitry Andric printAnnotation(OS, Annot); 455ffd83dbSDimitry Andric } 465ffd83dbSDimitry Andric 475ffd83dbSDimitry Andric void VEInstPrinter::printOperand(const MCInst *MI, int OpNum, 485ffd83dbSDimitry Andric const MCSubtargetInfo &STI, raw_ostream &O) { 495ffd83dbSDimitry Andric const MCOperand &MO = MI->getOperand(OpNum); 505ffd83dbSDimitry Andric 515ffd83dbSDimitry Andric if (MO.isReg()) { 525ffd83dbSDimitry Andric printRegName(O, MO.getReg()); 535ffd83dbSDimitry Andric return; 545ffd83dbSDimitry Andric } 555ffd83dbSDimitry Andric 565ffd83dbSDimitry Andric if (MO.isImm()) { 57*4824e7fdSDimitry Andric // Expects signed 32bit literals. 585ffd83dbSDimitry Andric int32_t TruncatedImm = static_cast<int32_t>(MO.getImm()); 595ffd83dbSDimitry Andric O << TruncatedImm; 605ffd83dbSDimitry Andric return; 615ffd83dbSDimitry Andric } 625ffd83dbSDimitry Andric 635ffd83dbSDimitry Andric assert(MO.isExpr() && "Unknown operand kind in printOperand"); 645ffd83dbSDimitry Andric MO.getExpr()->print(O, &MAI); 655ffd83dbSDimitry Andric } 665ffd83dbSDimitry Andric 675ffd83dbSDimitry Andric void VEInstPrinter::printMemASXOperand(const MCInst *MI, int OpNum, 685ffd83dbSDimitry Andric const MCSubtargetInfo &STI, 695ffd83dbSDimitry Andric raw_ostream &O, const char *Modifier) { 705ffd83dbSDimitry Andric // If this is an ADD operand, emit it like normal operands. 715ffd83dbSDimitry Andric if (Modifier && !strcmp(Modifier, "arith")) { 725ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 735ffd83dbSDimitry Andric O << ", "; 745ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 755ffd83dbSDimitry Andric return; 765ffd83dbSDimitry Andric } 775ffd83dbSDimitry Andric 785ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 2).isImm() && 795ffd83dbSDimitry Andric MI->getOperand(OpNum + 2).getImm() == 0) { 805ffd83dbSDimitry Andric // don't print "+0" 815ffd83dbSDimitry Andric } else { 825ffd83dbSDimitry Andric printOperand(MI, OpNum + 2, STI, O); 835ffd83dbSDimitry Andric } 845ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 1).isImm() && 855ffd83dbSDimitry Andric MI->getOperand(OpNum + 1).getImm() == 0 && 865ffd83dbSDimitry Andric MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 875ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 2).isImm() && 885ffd83dbSDimitry Andric MI->getOperand(OpNum + 2).getImm() == 0) { 895ffd83dbSDimitry Andric O << "0"; 905ffd83dbSDimitry Andric } else { 915ffd83dbSDimitry Andric // don't print "+0,+0" 925ffd83dbSDimitry Andric } 935ffd83dbSDimitry Andric } else { 945ffd83dbSDimitry Andric O << "("; 955ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 1).isImm() && 965ffd83dbSDimitry Andric MI->getOperand(OpNum + 1).getImm() == 0) { 975ffd83dbSDimitry Andric // don't print "+0" 985ffd83dbSDimitry Andric } else { 995ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 1005ffd83dbSDimitry Andric } 1015ffd83dbSDimitry Andric if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 1025ffd83dbSDimitry Andric // don't print "+0" 1035ffd83dbSDimitry Andric } else { 1045ffd83dbSDimitry Andric O << ", "; 1055ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 1065ffd83dbSDimitry Andric } 1075ffd83dbSDimitry Andric O << ")"; 1085ffd83dbSDimitry Andric } 1095ffd83dbSDimitry Andric } 1105ffd83dbSDimitry Andric 1115ffd83dbSDimitry Andric void VEInstPrinter::printMemASOperandASX(const MCInst *MI, int OpNum, 1125ffd83dbSDimitry Andric const MCSubtargetInfo &STI, 1135ffd83dbSDimitry Andric raw_ostream &O, const char *Modifier) { 1145ffd83dbSDimitry Andric // If this is an ADD operand, emit it like normal operands. 1155ffd83dbSDimitry Andric if (Modifier && !strcmp(Modifier, "arith")) { 1165ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 1175ffd83dbSDimitry Andric O << ", "; 1185ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 1195ffd83dbSDimitry Andric return; 1205ffd83dbSDimitry Andric } 1215ffd83dbSDimitry Andric 1225ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 1).isImm() && 1235ffd83dbSDimitry Andric MI->getOperand(OpNum + 1).getImm() == 0) { 1245ffd83dbSDimitry Andric // don't print "+0" 1255ffd83dbSDimitry Andric } else { 1265ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 1275ffd83dbSDimitry Andric } 1285ffd83dbSDimitry Andric if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 1295ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 1).isImm() && 1305ffd83dbSDimitry Andric MI->getOperand(OpNum + 1).getImm() == 0) { 1315ffd83dbSDimitry Andric O << "0"; 1325ffd83dbSDimitry Andric } else { 1335ffd83dbSDimitry Andric // don't print "(0)" 1345ffd83dbSDimitry Andric } 1355ffd83dbSDimitry Andric } else { 1365ffd83dbSDimitry Andric O << "(, "; 1375ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 1385ffd83dbSDimitry Andric O << ")"; 1395ffd83dbSDimitry Andric } 1405ffd83dbSDimitry Andric } 1415ffd83dbSDimitry Andric 1425ffd83dbSDimitry Andric void VEInstPrinter::printMemASOperandRRM(const MCInst *MI, int OpNum, 1435ffd83dbSDimitry Andric const MCSubtargetInfo &STI, 1445ffd83dbSDimitry Andric raw_ostream &O, const char *Modifier) { 1455ffd83dbSDimitry Andric // If this is an ADD operand, emit it like normal operands. 1465ffd83dbSDimitry Andric if (Modifier && !strcmp(Modifier, "arith")) { 1475ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 1485ffd83dbSDimitry Andric O << ", "; 1495ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 1505ffd83dbSDimitry Andric return; 1515ffd83dbSDimitry Andric } 1525ffd83dbSDimitry Andric 1535ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 1).isImm() && 1545ffd83dbSDimitry Andric MI->getOperand(OpNum + 1).getImm() == 0) { 1555ffd83dbSDimitry Andric // don't print "+0" 1565ffd83dbSDimitry Andric } else { 1575ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 1585ffd83dbSDimitry Andric } 1595ffd83dbSDimitry Andric if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) { 1605ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 1).isImm() && 1615ffd83dbSDimitry Andric MI->getOperand(OpNum + 1).getImm() == 0) { 1625ffd83dbSDimitry Andric O << "0"; 1635ffd83dbSDimitry Andric } else { 1645ffd83dbSDimitry Andric // don't print "(0)" 1655ffd83dbSDimitry Andric } 1665ffd83dbSDimitry Andric } else { 1675ffd83dbSDimitry Andric O << "("; 1685ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 1695ffd83dbSDimitry Andric O << ")"; 1705ffd83dbSDimitry Andric } 1715ffd83dbSDimitry Andric } 1725ffd83dbSDimitry Andric 1735ffd83dbSDimitry Andric void VEInstPrinter::printMemASOperandHM(const MCInst *MI, int OpNum, 1745ffd83dbSDimitry Andric const MCSubtargetInfo &STI, 1755ffd83dbSDimitry Andric raw_ostream &O, const char *Modifier) { 1765ffd83dbSDimitry Andric // If this is an ADD operand, emit it like normal operands. 1775ffd83dbSDimitry Andric if (Modifier && !strcmp(Modifier, "arith")) { 1785ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 1795ffd83dbSDimitry Andric O << ", "; 1805ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 1815ffd83dbSDimitry Andric return; 1825ffd83dbSDimitry Andric } 1835ffd83dbSDimitry Andric 1845ffd83dbSDimitry Andric if (MI->getOperand(OpNum + 1).isImm() && 1855ffd83dbSDimitry Andric MI->getOperand(OpNum + 1).getImm() == 0) { 1865ffd83dbSDimitry Andric // don't print "+0" 1875ffd83dbSDimitry Andric } else { 1885ffd83dbSDimitry Andric printOperand(MI, OpNum + 1, STI, O); 1895ffd83dbSDimitry Andric } 1905ffd83dbSDimitry Andric O << "("; 1915ffd83dbSDimitry Andric if (MI->getOperand(OpNum).isReg()) 1925ffd83dbSDimitry Andric printOperand(MI, OpNum, STI, O); 1935ffd83dbSDimitry Andric O << ")"; 1945ffd83dbSDimitry Andric } 1955ffd83dbSDimitry Andric 1965ffd83dbSDimitry Andric void VEInstPrinter::printMImmOperand(const MCInst *MI, int OpNum, 1975ffd83dbSDimitry Andric const MCSubtargetInfo &STI, 1985ffd83dbSDimitry Andric raw_ostream &O) { 1995ffd83dbSDimitry Andric int MImm = (int)MI->getOperand(OpNum).getImm() & 0x7f; 2005ffd83dbSDimitry Andric if (MImm > 63) 2015ffd83dbSDimitry Andric O << "(" << MImm - 64 << ")0"; 2025ffd83dbSDimitry Andric else 2035ffd83dbSDimitry Andric O << "(" << MImm << ")1"; 2045ffd83dbSDimitry Andric } 2055ffd83dbSDimitry Andric 2065ffd83dbSDimitry Andric void VEInstPrinter::printCCOperand(const MCInst *MI, int OpNum, 2075ffd83dbSDimitry Andric const MCSubtargetInfo &STI, raw_ostream &O) { 2085ffd83dbSDimitry Andric int CC = (int)MI->getOperand(OpNum).getImm(); 2095ffd83dbSDimitry Andric O << VECondCodeToString((VECC::CondCode)CC); 2105ffd83dbSDimitry Andric } 2115ffd83dbSDimitry Andric 2125ffd83dbSDimitry Andric void VEInstPrinter::printRDOperand(const MCInst *MI, int OpNum, 2135ffd83dbSDimitry Andric const MCSubtargetInfo &STI, raw_ostream &O) { 2145ffd83dbSDimitry Andric int RD = (int)MI->getOperand(OpNum).getImm(); 2155ffd83dbSDimitry Andric O << VERDToString((VERD::RoundingMode)RD); 2165ffd83dbSDimitry Andric } 217