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
printRegName(raw_ostream & OS,MCRegister Reg) const30*bdd1243dSDimitry Andric void VEInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) 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.
34*bdd1243dSDimitry Andric if (MRI.getRegClass(VE::MISCRegClassID).contains(Reg))
355ffd83dbSDimitry Andric AltIdx = VE::NoRegAltName;
36*bdd1243dSDimitry Andric OS << '%' << getRegisterName(Reg, AltIdx);
375ffd83dbSDimitry Andric }
385ffd83dbSDimitry Andric
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & OS)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
printOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)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()) {
574824e7fdSDimitry 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
printMemASXOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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
printMemASOperandASX(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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
printMemASOperandRRM(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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
printMemASOperandHM(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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
printMImmOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)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
printCCOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)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
printRDOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)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