blob: d7452200e05fd9ea8391c19905656e28596466be [file] [log] [blame]
Alex Bradbury2fee9ea2017-08-15 13:08:29 +00001//===-- RISCVInstPrinter.cpp - Convert RISCV MCInst to asm syntax ---------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Alex Bradbury2fee9ea2017-08-15 13:08:29 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This class prints an RISCV MCInst to a .s file.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVInstPrinter.h"
Sameer AbuAsalc1b0e662018-04-06 21:07:05 +000014#include "MCTargetDesc/RISCVMCExpr.h"
Ana Pazos9d6c5532018-10-04 21:50:54 +000015#include "Utils/RISCVBaseInfo.h"
Alex Bradbury2fee9ea2017-08-15 13:08:29 +000016#include "llvm/MC/MCAsmInfo.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
Alex Bradbury0d6cf902017-12-07 10:26:05 +000019#include "llvm/MC/MCRegisterInfo.h"
Ana Pazose3d24832018-01-12 02:27:00 +000020#include "llvm/MC/MCSubtargetInfo.h"
Alex Bradbury2fee9ea2017-08-15 13:08:29 +000021#include "llvm/MC/MCSymbol.h"
Alex Bradbury9ed84c82017-12-12 15:46:15 +000022#include "llvm/Support/CommandLine.h"
Alex Bradbury2fee9ea2017-08-15 13:08:29 +000023#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/FormattedStream.h"
25using namespace llvm;
26
27#define DEBUG_TYPE "asm-printer"
28
29// Include the auto-generated portion of the assembly writer.
Alex Bradbury0d6cf902017-12-07 10:26:05 +000030#define PRINT_ALIAS_INSTR
Alex Bradbury2fee9ea2017-08-15 13:08:29 +000031#include "RISCVGenAsmWriter.inc"
32
Sameer AbuAsalc1b0e662018-04-06 21:07:05 +000033// Include the auto-generated portion of the compress emitter.
34#define GEN_UNCOMPRESS_INSTR
35#include "RISCVGenCompressInstEmitter.inc"
36
Alex Bradbury9ed84c82017-12-12 15:46:15 +000037static cl::opt<bool>
Ana Pazos9d6c5532018-10-04 21:50:54 +000038 NoAliases("riscv-no-aliases",
39 cl::desc("Disable the emission of assembler pseudo instructions"),
40 cl::init(false), cl::Hidden);
Alex Bradbury9ed84c82017-12-12 15:46:15 +000041
Alex Bradbury2fee9ea2017-08-15 13:08:29 +000042void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
43 StringRef Annot, const MCSubtargetInfo &STI) {
Sameer AbuAsalc1b0e662018-04-06 21:07:05 +000044 bool Res = false;
45 const MCInst *NewMI = MI;
46 MCInst UncompressedMI;
47 if (!NoAliases)
48 Res = uncompressInst(UncompressedMI, *MI, MRI, STI);
49 if (Res)
Ana Pazos9d6c5532018-10-04 21:50:54 +000050 NewMI = const_cast<MCInst *>(&UncompressedMI);
Sameer AbuAsalc1b0e662018-04-06 21:07:05 +000051 if (NoAliases || !printAliasInstr(NewMI, STI, O))
52 printInstruction(NewMI, STI, O);
Alex Bradbury2fee9ea2017-08-15 13:08:29 +000053 printAnnotation(O, Annot);
54}
55
56void RISCVInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
57 O << getRegisterName(RegNo);
58}
59
60void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
Ana Pazos9d6c5532018-10-04 21:50:54 +000061 const MCSubtargetInfo &STI, raw_ostream &O,
62 const char *Modifier) {
Alex Bradbury2fee9ea2017-08-15 13:08:29 +000063 assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
64 const MCOperand &MO = MI->getOperand(OpNo);
65
66 if (MO.isReg()) {
67 printRegName(O, MO.getReg());
68 return;
69 }
70
71 if (MO.isImm()) {
72 O << MO.getImm();
73 return;
74 }
75
76 assert(MO.isExpr() && "Unknown operand kind in printOperand");
77 MO.getExpr()->print(O, &MAI);
78}
Alex Bradbury6758ecb2017-09-17 14:27:35 +000079
Ana Pazos9d6c5532018-10-04 21:50:54 +000080void RISCVInstPrinter::printCSRSystemRegister(const MCInst *MI, unsigned OpNo,
81 const MCSubtargetInfo &STI,
82 raw_ostream &O) {
83 unsigned Imm = MI->getOperand(OpNo).getImm();
84 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
85 if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits()))
86 O << SysReg->Name;
87 else
88 O << Imm;
89}
90
Alex Bradbury6758ecb2017-09-17 14:27:35 +000091void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo,
Ana Pazose3d24832018-01-12 02:27:00 +000092 const MCSubtargetInfo &STI,
Alex Bradbury6758ecb2017-09-17 14:27:35 +000093 raw_ostream &O) {
94 unsigned FenceArg = MI->getOperand(OpNo).getImm();
Ana Pazos0a5fcef2018-10-11 22:49:13 +000095 assert (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg");
96
Alex Bradbury6758ecb2017-09-17 14:27:35 +000097 if ((FenceArg & RISCVFenceField::I) != 0)
98 O << 'i';
99 if ((FenceArg & RISCVFenceField::O) != 0)
100 O << 'o';
101 if ((FenceArg & RISCVFenceField::R) != 0)
102 O << 'r';
103 if ((FenceArg & RISCVFenceField::W) != 0)
104 O << 'w';
Ana Pazos0a5fcef2018-10-11 22:49:13 +0000105 if (FenceArg == 0)
106 O << "unknown";
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000107}
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000108
109void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo,
Ana Pazos9d6c5532018-10-04 21:50:54 +0000110 const MCSubtargetInfo &STI, raw_ostream &O) {
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000111 auto FRMArg =
112 static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm());
113 O << RISCVFPRndMode::roundingModeToString(FRMArg);
114}
Sam Elliottf596f452019-08-01 12:42:31 +0000115
116void RISCVInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo,
117 const MCSubtargetInfo &STI,
118 raw_ostream &O) {
119 const MCOperand &MO = MI->getOperand(OpNo);
120
121 assert(MO.isReg() && "printAtomicMemOp can only print register operands");
122 O << "(";
123 printRegName(O, MO.getReg());
124 O << ")";
125 return;
126}