diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCV.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 84 |
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 |