summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp11
-rw-r--r--llvm/lib/Target/RISCV/RISCV.td2
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfo.td84
3 files changed, 96 insertions, 1 deletions
diff --git a/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp
index a396025ccc4..d21c48ec65a 100644
--- a/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
@@ -28,9 +29,17 @@ using namespace llvm;
#define PRINT_ALIAS_INSTR
#include "RISCVGenAsmWriter.inc"
+// Alias instruction emission is disabled by default. A subsequent patch will
+// change this default and fix all affected tests.
+static cl::opt<bool>
+NoAliases("riscv-no-aliases",
+ cl::desc("Disable the emission of assembler pseudo instructions"),
+ cl::init(true),
+ cl::Hidden);
+
void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
StringRef Annot, const MCSubtargetInfo &STI) {
- if (!printAliasInstr(MI, O))
+ if (NoAliases || !printAliasInstr(MI, O))
printInstruction(MI, O);
printAnnotation(O, Annot);
}
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index be339770ed1..c74d560b2e0 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -49,6 +49,8 @@ def Feature64Bit
: SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">;
def IsRV64 : Predicate<"Subtarget->is64Bit()">,
AssemblerPredicate<"Feature64Bit">;
+def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
+ AssemblerPredicate<"!Feature64Bit">;
def RV64 : HwMode<"+64bit">;
def RV32 : HwMode<"-64bit">;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index dcfcccf4960..b4450027439 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -376,6 +376,90 @@ def SFENCE_VMA : RVInstR<0b0001001, 0b000, OPC_SYSTEM, (outs),
}
//===----------------------------------------------------------------------===//
+// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
+//===----------------------------------------------------------------------===//
+
+// TODO la
+// TODO lb lh lw
+// TODO RV64I: ld
+// TODO sb sh sw
+// TODO RV64I: sd
+
+def : InstAlias<"nop", (ADDI X0, X0, 0)>;
+// TODO li
+def : InstAlias<"mv $rd, $rs", (ADDI GPR:$rd, GPR:$rs, 0)>;
+def : InstAlias<"not $rd, $rs", (XORI GPR:$rd, GPR:$rs, -1)>;
+def : InstAlias<"neg $rd, $rs", (SUB GPR:$rd, X0, GPR:$rs)>;
+
+let Predicates = [IsRV64] in {
+def : InstAlias<"negw $rd, $rs", (SUBW GPR:$rd, X0, GPR:$rs)>;
+def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs, 0)>;
+} // Predicates = [IsRV64]
+
+def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs, 1)>;
+def : InstAlias<"snez $rd, $rs", (SLTU GPR:$rd, X0, GPR:$rs)>;
+def : InstAlias<"sltz $rd, $rs", (SLT GPR:$rd, GPR:$rs, X0)>;
+def : InstAlias<"sgtz $rd, $rs", (SLT GPR:$rd, X0, GPR:$rs)>;
+
+def : InstAlias<"beqz $rs, $offset",
+ (BEQ GPR:$rs, X0, simm13_lsb0:$offset)>;
+def : InstAlias<"bnez $rs, $offset",
+ (BNE GPR:$rs, X0, simm13_lsb0:$offset)>;
+def : InstAlias<"blez $rs, $offset",
+ (BGE X0, GPR:$rs, simm13_lsb0:$offset)>;
+def : InstAlias<"bgez $rs, $offset",
+ (BGE GPR:$rs, X0, simm13_lsb0:$offset)>;
+def : InstAlias<"bltz $rs, $offset",
+ (BLT GPR:$rs, X0, simm13_lsb0:$offset)>;
+def : InstAlias<"bgtz $rs, $offset",
+ (BLT X0, GPR:$rs, simm13_lsb0:$offset)>;
+
+// Always output the canonical mnemonic for the pseudo branch instructions.
+// The GNU tools emit the canonical mnemonic for the branch pseudo instructions
+// as well (e.g. "bgt" will be recognised by the assembler but never printed by
+// objdump). Match this behaviour by setting a zero weight.
+def : InstAlias<"bgt $rs, $rt, $offset",
+ (BLT GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
+def : InstAlias<"ble $rs, $rt, $offset",
+ (BGE GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
+def : InstAlias<"bgtu $rs, $rt, $offset",
+ (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
+def : InstAlias<"bleu $rs, $rt, $offset",
+ (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
+
+// "ret" has more weight since "ret" and "jr" alias the same "jalr" instruction.
+def : InstAlias<"j $offset", (JAL X0, simm21_lsb0:$offset)>;
+def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0:$offset)>;
+def : InstAlias<"jr $rs", (JALR X0, GPR:$rs, 0)>;
+def : InstAlias<"jalr $rs", (JALR X1, GPR:$rs, 0)>;
+def : InstAlias<"ret", (JALR X0, X1, 0), 2>;
+// TODO call
+// TODO tail
+
+def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw
+
+// CSR Addresses: 0xC00 == cycle, 0xC01 == time, 0xC02 == instret
+// 0xC80 == cycleh, 0xC81 == timeh, 0xC82 == instreth
+def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, 0xC02, X0)>;
+def : InstAlias<"rdcycle $rd", (CSRRS GPR:$rd, 0xC00, X0)>;
+def : InstAlias<"rdtime $rd", (CSRRS GPR:$rd, 0xC01, X0)>;
+
+let Predicates = [IsRV32] in {
+def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, 0xC82, X0)>;
+def : InstAlias<"rdcycleh $rd", (CSRRS GPR:$rd, 0xC80, X0)>;
+def : InstAlias<"rdtimeh $rd", (CSRRS GPR:$rd, 0xC81, X0)>;
+} // Predicates = [IsRV32]
+
+def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, uimm12:$csr, X0)>;
+def : InstAlias<"csrw $csr, $rs", (CSRRW X0, uimm12:$csr, GPR:$rs)>;
+def : InstAlias<"csrs $csr, $rs", (CSRRS X0, uimm12:$csr, GPR:$rs)>;
+def : InstAlias<"csrc $csr, $rs", (CSRRC X0, uimm12:$csr, GPR:$rs)>;
+
+def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, uimm12:$csr, uimm5:$imm)>;
+def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, uimm12:$csr, uimm5:$imm)>;
+def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, uimm12:$csr, uimm5:$imm)>;
+
+//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
//
// Naming convention: For 'generic' pattern classes, we use the naming
OpenPOWER on IntegriCloud