VincentWu updated this revision to Diff 497206.
VincentWu marked 19 inline comments as done.
VincentWu added a comment.
address comments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D132819/new/
https://reviews.llvm.org/D132819
Files:
clang/test/Preprocessor/riscv-target-features.c
llvm/lib/Support/RISCVISAInfo.cpp
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
llvm/lib/Target/RISCV/RISCVFeatures.td
llvm/lib/Target/RISCV/RISCVInstrInfoZc.td
llvm/lib/Target/RISCV/RISCVRegisterInfo.td
llvm/test/MC/RISCV/attribute-arch.s
llvm/test/MC/RISCV/rv32zcmp-invalid.s
llvm/test/MC/RISCV/rv32zcmp-valid.s
llvm/test/MC/RISCV/rv64zcb-invalid.s
llvm/test/MC/RISCV/rv64zcmp-invalid.s
llvm/test/MC/RISCV/rv64zcmp-valid.s
Index: llvm/test/MC/RISCV/rv64zcmp-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zcmp-valid.s
@@ -0,0 +1,149 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=experimental-zcmp -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=experimental-zcmp < %s \
+# RUN: | llvm-objdump --mattr=-c,experimental-zcmp -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: cm.mvsa01 s1, s0
+# CHECK-ASM: encoding: [0xa2,0xac]
+cm.mvsa01 s1, s0
+
+# CHECK-ASM-AND-OBJ: cm.mva01s s1, s0
+# CHECK-ASM: encoding: [0xe2,0xac]
+cm.mva01s s1, s0
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xbe]
+cm.popret {ra}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xbe]
+cm.popret {ra}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0}, 64
+# CHECK-ASM: encoding: [0x5e,0xbe]
+cm.popret {ra, s0}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s1}, 32
+# CHECK-ASM: encoding: [0x62,0xbe]
+cm.popret {ra,s0-s1}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x72,0xbe]
+cm.popret {ra, s0-s2}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s3}, 64
+# CHECK-ASM: encoding: [0x86,0xbe]
+cm.popret {ra, s0-s3}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s5}, 64
+# CHECK-ASM: encoding: [0xa2,0xbe]
+cm.popret {ra, s0-s5}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s7}, 80
+# CHECK-ASM: encoding: [0xc2,0xbe]
+cm.popret {ra, s0-s7}, 80
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s11}, 112
+# CHECK-ASM: encoding: [0xf2,0xbe]
+cm.popret {ra, s0-s11}, 112
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xbc]
+cm.popretz {ra}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xbc]
+cm.popretz {ra}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0}, 64
+# CHECK-ASM: encoding: [0x5e,0xbc]
+cm.popretz {ra, s0}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s1}, 32
+# CHECK-ASM: encoding: [0x62,0xbc]
+cm.popretz {ra, s0-s1}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x72,0xbc]
+cm.popretz {ra, s0-s2}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s3}, 64
+# CHECK-ASM: encoding: [0x86,0xbc]
+cm.popretz {ra, s0-s3}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s5}, 64
+# CHECK-ASM: encoding: [0xa2,0xbc]
+cm.popretz {ra, s0-s5}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s7}, 80
+# CHECK-ASM: encoding: [0xc2,0xbc]
+cm.popretz {ra, s0-s7}, 80
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s11}, 112
+# CHECK-ASM: encoding: [0xf2,0xbc]
+cm.popretz {ra, s0-s11}, 112
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xba]
+cm.pop {ra}, 16
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xba]
+cm.pop {ra}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0}, 16
+# CHECK-ASM: encoding: [0x52,0xba]
+cm.pop {ra, s0}, 16
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s1}, 32
+# CHECK-ASM: encoding: [0x62,0xba]
+cm.pop {ra, s0-s1}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x72,0xba]
+cm.pop {ra, s0-s2}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s5}, 64
+# CHECK-ASM: encoding: [0xa2,0xba]
+cm.pop {ra, s0-s5}, 64
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s7}, 80
+# CHECK-ASM: encoding: [0xc2,0xba]
+cm.pop {ra, s0-s7}, 80
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s11}, 112
+# CHECK-ASM: encoding: [0xf2,0xba]
+cm.pop {ra, s0-s11}, 112
+
+# CHECK-ASM-AND-OBJ: cm.push {ra}, -16
+# CHECK-ASM: encoding: [0x42,0xb8]
+cm.push {ra}, -16
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0}, -32
+# CHECK-ASM: encoding: [0x56,0xb8]
+cm.push {ra, s0}, -32
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s1}, -32
+# CHECK-ASM: encoding: [0x62,0xb8]
+cm.push {ra, s0-s1}, -32
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s3}, -64
+# CHECK-ASM: encoding: [0x86,0xb8]
+cm.push {ra, s0-s3}, -64
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s7}, -80
+# CHECK-ASM: encoding: [0xc2,0xb8]
+cm.push {ra, s0-s7}, -80
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s7}, -80
+# CHECK-ASM: encoding: [0xc2,0xb8]
+cm.push {ra, s0-s7}, -80
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s11}, -112
+# CHECK-ASM: encoding: [0xf2,0xb8]
+cm.push {ra, s0-s11}, -112
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s11}, -128
+# CHECK-ASM: encoding: [0xf6,0xb8]
+cm.push {ra, s0-s11}, -128
Index: llvm/test/MC/RISCV/rv64zcmp-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zcmp-invalid.s
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc -triple=riscv64 -mattr=experimental-zcmp -riscv-no-aliases -show-encoding < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s
+
+# CHECK-ERROR: error: invalid operand for instruction
+cm.mvsa01 a1, a2
+
+# CHECK-ERROR: error: invalid operand for instruction
+cm.mva01s a1, a2
+
+# CHECK-ERROR: error: invalid register list, {ra, s0-s10} is not supported.
+cm.popretz {ra, s0-s10}, 112
+
+# CHECK-ERROR: error: This stack adjustment is invalid for this instruction and register list, Please refer to Zc spec for a detailed range of stack adjustment.
+cm.popretz {ra, s0-s1}, 112
Index: llvm/test/MC/RISCV/rv64zcb-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zcb-invalid.s
@@ -0,0 +1,17 @@
+# RUN: not llvm-mc -triple=riscv64 -mattr=experimental-zcb -riscv-no-aliases -show-encoding < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s
+
+# CHECK-ERROR: error: immediate must be an integer in the range [0, 3]
+c.lbu a5, 10(a4)
+
+# CHECK-ERROR: error: immediate must be one of [0, 2]
+c.lhu a5, 10(a4)
+
+# CHECK-ERROR: error: immediate must be one of [0, 2]
+c.lh a5, 10(a4)
+
+# CHECK-ERROR: error: immediate must be an integer in the range [0, 3]
+c.sb a5, 10(a4)
+
+# CHECK-ERROR: error: immediate must be one of [0, 2]
+c.sh a5, 10(a4)
Index: llvm/test/MC/RISCV/rv32zcmp-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zcmp-valid.s
@@ -0,0 +1,285 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=experimental-zcmp -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=experimental-zcmp < %s \
+# RUN: | llvm-objdump --mattr=-c,experimental-zcmp -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: cm.mvsa01 s1, s0
+# CHECK-ASM: encoding: [0xa2,0xac]
+cm.mvsa01 s1, s0
+
+# CHECK-ASM-AND-OBJ: cm.mva01s s1, s0
+# CHECK-ASM: encoding: [0xe2,0xac]
+cm.mva01s s1, s0
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xbe]
+cm.popret {ra}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xbe]
+cm.popret {x1}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xbe]
+cm.popret {ra}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xbe]
+cm.popret {x1}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0}, 64
+# CHECK-ASM: encoding: [0x5e,0xbe]
+cm.popret {ra, s0}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0}, 64
+# CHECK-ASM: encoding: [0x5e,0xbe]
+cm.popret {x1, x8}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s1}, 16
+# CHECK-ASM: encoding: [0x62,0xbe]
+cm.popret {ra,s0-s1}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s1}, 16
+# CHECK-ASM: encoding: [0x62,0xbe]
+cm.popret {x1, x8-x9}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x76,0xbe]
+cm.popret {ra, s0-s2}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x76,0xbe]
+cm.popret {x1, x8-x9, x18}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s3}, 32
+# CHECK-ASM: encoding: [0x82,0xbe]
+cm.popret {ra, s0-s3}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s3}, 32
+# CHECK-ASM: encoding: [0x82,0xbe]
+cm.popret {x1, x8-x9, x18-x19}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s5}, 32
+# CHECK-ASM: encoding: [0xa2,0xbe]
+cm.popret {ra, s0-s5}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s5}, 32
+# CHECK-ASM: encoding: [0xa2,0xbe]
+cm.popret {x1, x8-x9, x18-x21}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s7}, 48
+# CHECK-ASM: encoding: [0xc2,0xbe]
+cm.popret {ra, s0-s7}, 48
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s7}, 48
+# CHECK-ASM: encoding: [0xc2,0xbe]
+cm.popret {x1, x8-x9, x18-x23}, 48
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s11}, 112
+# CHECK-ASM: encoding: [0xfe,0xbe]
+cm.popret {ra, s0-s11}, 112
+
+# CHECK-ASM-AND-OBJ: cm.popret {ra, s0-s11}, 112
+# CHECK-ASM: encoding: [0xfe,0xbe]
+cm.popret {x1, x8-x9, x18-x27}, 112
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xbc]
+cm.popretz {ra}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xbc]
+cm.popretz {x1}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xbc]
+cm.popretz {ra}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xbc]
+cm.popretz {x1}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0}, 64
+# CHECK-ASM: encoding: [0x5e,0xbc]
+cm.popretz {ra, s0}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0}, 64
+# CHECK-ASM: encoding: [0x5e,0xbc]
+cm.popretz {x1, x8}, 64
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s1}, 16
+# CHECK-ASM: encoding: [0x62,0xbc]
+cm.popretz {ra, s0-s1}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s1}, 16
+# CHECK-ASM: encoding: [0x62,0xbc]
+cm.popretz {x1, x8-x9}, 16
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x76,0xbc]
+cm.popretz {ra, s0-s2}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x76,0xbc]
+cm.popretz {x1, x8-x9, x18}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s3}, 32
+# CHECK-ASM: encoding: [0x82,0xbc]
+cm.popretz {ra, s0-s3}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s3}, 32
+# CHECK-ASM: encoding: [0x82,0xbc]
+cm.popretz {x1, x8-x9, x18-x19}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s5}, 32
+# CHECK-ASM: encoding: [0xa2,0xbc]
+cm.popretz {ra, s0-s5}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s5}, 32
+# CHECK-ASM: encoding: [0xa2,0xbc]
+cm.popretz {x1, x8-x9, x18-x21}, 32
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s7}, 48
+# CHECK-ASM: encoding: [0xc2,0xbc]
+cm.popretz {ra, s0-s7}, 48
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s7}, 48
+# CHECK-ASM: encoding: [0xc2,0xbc]
+cm.popretz {x1, x8-x9, x18-x23}, 48
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s11}, 112
+# CHECK-ASM: encoding: [0xfe,0xbc]
+cm.popretz {ra, s0-s11}, 112
+
+# CHECK-ASM-AND-OBJ: cm.popretz {ra, s0-s11}, 112
+# CHECK-ASM: encoding: [0xfe,0xbc]
+cm.popretz {x1, x8-x9, x18-x27}, 112
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xba]
+cm.pop {ra}, 16
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra}, 16
+# CHECK-ASM: encoding: [0x42,0xba]
+cm.pop {x1}, 16
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xba]
+cm.pop {ra}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra}, 32
+# CHECK-ASM: encoding: [0x46,0xba]
+cm.pop {x1}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0}, 16
+# CHECK-ASM: encoding: [0x52,0xba]
+cm.pop {ra, s0}, 16
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0}, 16
+# CHECK-ASM: encoding: [0x52,0xba]
+cm.pop {x1, x8}, 16
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s1}, 32
+# CHECK-ASM: encoding: [0x66,0xba]
+cm.pop {ra, s0-s1}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s1}, 32
+# CHECK-ASM: encoding: [0x66,0xba]
+cm.pop {x1, x8-x9}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x76,0xba]
+cm.pop {ra, s0-s2}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s2}, 32
+# CHECK-ASM: encoding: [0x76,0xba]
+cm.pop {x1, x8-x9, x18}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s5}, 32
+# CHECK-ASM: encoding: [0xa2,0xba]
+cm.pop {ra, s0-s5}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s5}, 32
+# CHECK-ASM: encoding: [0xa2,0xba]
+cm.pop {x1, x8-x9, x18-x21}, 32
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s7}, 48
+# CHECK-ASM: encoding: [0xc2,0xba]
+cm.pop {ra, s0-s7}, 48
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s7}, 48
+# CHECK-ASM: encoding: [0xc2,0xba]
+cm.pop {x1, x8-x9, x18-x23}, 48
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s11}, 64
+# CHECK-ASM: encoding: [0xf2,0xba]
+cm.pop {ra, s0-s11}, 64
+
+# CHECK-ASM-AND-OBJ: cm.pop {ra, s0-s11}, 64
+# CHECK-ASM: encoding: [0xf2,0xba]
+cm.pop {x1, x8-x9, x18-x27}, 64
+
+# CHECK-ASM-AND-OBJ: cm.push {ra}, -16
+# CHECK-ASM: encoding: [0x42,0xb8]
+cm.push {ra}, -16
+
+# CHECK-ASM-AND-OBJ: cm.push {ra}, -16
+# CHECK-ASM: encoding: [0x42,0xb8]
+cm.push {x1}, -16
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0}, -32
+# CHECK-ASM: encoding: [0x56,0xb8]
+cm.push {ra, s0}, -32
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0}, -32
+# CHECK-ASM: encoding: [0x56,0xb8]
+cm.push {x1, x8}, -32
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s1}, -16
+# CHECK-ASM: encoding: [0x62,0xb8]
+cm.push {ra, s0-s1}, -16
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s1}, -16
+# CHECK-ASM: encoding: [0x62,0xb8]
+cm.push {x1, x8-x9}, -16
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s3}, -32
+# CHECK-ASM: encoding: [0x82,0xb8]
+cm.push {ra, s0-s3}, -32
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s3}, -32
+# CHECK-ASM: encoding: [0x82,0xb8]
+cm.push {x1, x8-x9, x18-x19}, -32
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s7}, -48
+# CHECK-ASM: encoding: [0xc2,0xb8]
+cm.push {ra, s0-s7}, -48
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s7}, -48
+# CHECK-ASM: encoding: [0xc2,0xb8]
+cm.push {x1, x8-x9, x18-x23}, -48
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s7}, -64
+# CHECK-ASM: encoding: [0xc6,0xb8]
+cm.push {ra, s0-s7}, -64
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s7}, -64
+# CHECK-ASM: encoding: [0xc6,0xb8]
+cm.push {x1, x8-x9, x18-x23}, -64
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s11}, -80
+# CHECK-ASM: encoding: [0xf6,0xb8]
+cm.push {ra, s0-s11}, -80
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s11}, -80
+# CHECK-ASM: encoding: [0xf6,0xb8]
+cm.push {x1, x8-x9, x18-x27}, -80
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s11}, -112
+# CHECK-ASM: encoding: [0xfe,0xb8]
+cm.push {ra, s0-s11}, -112
+
+# CHECK-ASM-AND-OBJ: cm.push {ra, s0-s11}, -112
+# CHECK-ASM: encoding: [0xfe,0xb8]
+cm.push {x1, x8-x9, x18-x27}, -112
Index: llvm/test/MC/RISCV/rv32zcmp-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zcmp-invalid.s
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc -triple=riscv32 -mattr=experimental-zcmp -riscv-no-aliases -show-encoding < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s
+
+# CHECK-ERROR: error: invalid operand for instruction
+cm.mvsa01 a1, a2
+
+# CHECK-ERROR: error: invalid operand for instruction
+cm.mva01s a1, a2
+
+# CHECK-ERROR: error: invalid register list, {ra, s0-s10} is not supported.
+cm.popretz {ra, s0-s10}, 112
+
+# CHECK-ERROR: error: This stack adjustment is invalid for this instruction and register list, Please refer to Zc spec for a detailed range of stack adjustment.
+cm.popretz {ra, s0-s1}, 112
Index: llvm/test/MC/RISCV/attribute-arch.s
===================================================================
--- llvm/test/MC/RISCV/attribute-arch.s
+++ llvm/test/MC/RISCV/attribute-arch.s
@@ -188,6 +188,9 @@
.attribute arch, "rv32izcb1p0"
# CHECK: attribute 5, "rv32i2p0_zca1p0_zcb1p0"
+.attribute arch, "rv32izcmp1p0"
+# CHECK: attribute 5, "rv32i2p0_zca1p0_zcmp1p0"
+
.attribute arch, "rv32izawrs1p0"
# CHECK: attribute 5, "rv32i2p0_zawrs1p0"
Index: llvm/lib/Target/RISCV/RISCVRegisterInfo.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -174,6 +174,14 @@
let RegInfos = XLenRI;
}
+// Saved Registers from s0 to s7, for C.MVA01S07 instruction in Zcmp extension
+def SR07 : RegisterClass<"RISCV", [XLenVT], 32, (add
+ (sequence "X%u", 8, 9),
+ (sequence "X%u", 18, 23)
+ )> {
+ let RegInfos = XLenRI;
+}
+
// Floating point registers
let RegAltNameIndices = [ABIRegAltName] in {
def F0_H : RISCVReg16<0, "f0", ["ft0"]>, DwarfRegNum<[32]>;
Index: llvm/lib/Target/RISCV/RISCVInstrInfoZc.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoZc.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfoZc.td
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
///
/// This file describes the RISC-V instructions from the 'Zc*' compressed
-/// instruction extensions, version 1.0.1.
+/// instruction extensions, version 1.0.3.
/// This version is still experimental as the 'Zc*' extensions haven't been
/// ratified yet.
///
@@ -32,6 +32,45 @@
}];
}
+def RlistAsmOperand : AsmOperandClass {
+ let Name = "Rlist";
+ let ParserMethod = "parseReglist";
+ let DiagnosticType = "InvalidRlist";
+}
+
+def SpimmAsmOperand : AsmOperandClass {
+ let Name = "Spimm";
+ let ParserMethod = "parseZcSpimm";
+ let DiagnosticType = "InvalidSpimm";
+}
+
+def rlist : Operand<OtherVT>, ImmLeaf<OtherVT, [{return isUInt<4>(Imm);}]> {
+ let ParserMatchClass = RlistAsmOperand;
+ let PrintMethod = "printRlist";
+ let DecoderMethod = "decodeZcRlist";
+ let EncoderMethod = "getRlistOpValue";
+ let MCOperandPredicate = [{
+ int64_t Imm;
+ if (!MCOp.evaluateAsConstantImm(Imm))
+ return false;
+ if (!isUInt<4>(Imm)) return false;
+ // 0~3 Reserved for EABI
+ return (Imm>=4) && (Imm <=15);
+ }];
+ }
+
+def spimm : Operand<OtherVT>, ImmLeaf<OtherVT, [{return isShiftedUInt<5, 4>(Imm);}]>{
+ let ParserMatchClass = SpimmAsmOperand;
+ let PrintMethod = "printSpimm";
+ let DecoderMethod = "decodeZcSpimm";
+ let MCOperandPredicate = [{
+ int64_t Imm;
+ if (!MCOp.evaluateAsConstantImm(Imm))
+ return false;
+ return isShiftedUInt<5, 4>(Imm);
+ }];
+}
+
//===----------------------------------------------------------------------===//
// Instruction Class Templates
//===----------------------------------------------------------------------===//
@@ -43,6 +82,31 @@
let Constraints = "$rd = $rd_wb";
}
+class RVZcArith_rr<bits<6> funct6,bits<2> funct2, bits<2> opcode, string opcodestr>
+ : RVInst16CA<funct6, funct2, opcode, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, GPRC:$rs2),
+ opcodestr, "$rs1, $rs2"> {
+ let Constraints = "$rs1 = $rs1_wb";
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class ZcLoad_ri<bits<3> funct3, bits<2> opcode, string opcodestr,
+ RegisterClass cls, DAGOperand opnd>
+ : RVInst16CL<funct3, opcode, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
+ opcodestr, "$rd, ${imm}(${rs1})">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class ZcStore_ri<bits<3> funct3, bits<2> opcode, string opcodestr,
+ RegisterClass cls, DAGOperand opnd>
+ : RVInst16CS<funct3, opcode, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
+ opcodestr, "$rs2, ${imm}(${rs1})">;
+
+class RVInstZcCPPP<dag outs, dag ins, string opcodestr, string argstr>
+ : RVInst16<outs, ins, opcodestr, argstr, [], InstFormatOther> {
+
+ let Inst{1-0} = 0b10;
+ let Inst{15-13} = 0b101;
+}
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -116,6 +180,62 @@
}
}
+// ZCMP
+let Predicates = [HasStdExtZcmp], Defs = [X10, X11],
+ hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+def CM_MVA01S : RVInst16CA<0b101011, 0b11, 0b10, (outs),
+ (ins SR07:$rs1, SR07:$rs2), "cm.mva01s", "$rs1, $rs2">;
+
+def CM_MVSA01 : RVInst16CA<0b101011, 0b01, 0b10, (outs SR07:$rs1, SR07:$rs2),
+ (ins), "cm.mvsa01", "$rs1, $rs2">;
+}
+
+let Predicates = [HasStdExtZcmp] in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+def CM_PUSH : RVInstZcCPPP<(outs), (ins rlist:$rlist, spimm:$spimm),
+ "cm.push", "{$rlist}, $spimm"> {
+ bits<4> rlist;
+ bits<16> spimm;
+
+ let Inst{12-8} = 0b11000;
+ let Inst{7-4} = rlist;
+ let Inst{3-2} = spimm{5-4};
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def CM_POPRET : RVInstZcCPPP<(outs), (ins rlist:$rlist, spimm:$spimm),
+ "cm.popret", "{$rlist}, $spimm"> {
+ bits<4> rlist;
+ bits<16> spimm;
+
+ let Inst{12-8} = 0b11110;
+ let Inst{7-4} = rlist;
+ let Inst{3-2} = spimm{5-4};
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def CM_POPRETZ : RVInstZcCPPP<(outs), (ins rlist:$rlist, spimm:$spimm),
+ "cm.popretz", "{$rlist}, $spimm"> {
+ bits<4> rlist;
+ bits<16> spimm;
+
+ let Inst{12-8} = 0b11100;
+ let Inst{7-4} = rlist;
+ let Inst{3-2} = spimm{5-4};
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def CM_POP : RVInstZcCPPP<(outs), (ins rlist:$rlist, spimm:$spimm),
+ "cm.pop", "{$rlist}, $spimm"> {
+ bits<4> rlist;
+ bits<16> spimm;
+
+ let Inst{12-8} = 0b11010;
+ let Inst{7-4} = rlist;
+ let Inst{3-2} = spimm{5-4};
+}
+}
+
let Predicates = [HasStdExtZcb, HasStdExtMOrZmmul] in{
def : CompressPat<(MUL GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
(C_MUL GPRC:$rs1, GPRC:$rs2)>;
Index: llvm/lib/Target/RISCV/RISCVFeatures.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVFeatures.td
+++ llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -327,6 +327,14 @@
"'C' (Compressed Instructions) or "
"'Zcf' (Compressed Single-Precision Floating-Point Instructions)">;
+def FeatureExtZcmp
+ : SubtargetFeature<"experimental-zcmp", "HasStdExtZcmp", "true",
+ "'Zcmp' (sequenced instuctions for code-size reduction.)",
+ [FeatureExtZca]>;
+def HasStdExtZcmp : Predicate<"Subtarget->hasStdExtZcmp() && !Subtarget->hasStdExtC()">,
+ AssemblerPredicate<(all_of FeatureExtZcmp, (not FeatureStdExtC)),
+ "'Zcmp' (sequenced instuctions for code-size reduction.)">;
+
def FeatureNoRVCHints
: SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false",
"Disable RVC Hint Instructions.">;
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -88,6 +88,11 @@
unsigned getVMaskReg(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+
+ unsigned getRlistOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
};
} // end anonymous namespace
@@ -483,4 +488,14 @@
}
}
+unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ MCOperand MO = MI.getOperand(OpNo);
+ assert(MO.isImm() && "Rlist operand must be immidiate");
+ auto Imm = MO.getImm();
+ assert(Imm >= 4 && "EABI is currently not implemented");
+ return Imm;
+}
+
#include "RISCVGenMCCodeEmitter.inc"
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -46,6 +46,10 @@
raw_ostream &O);
void printVMaskReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
+ void printRlist(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
+ void printSpimm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
// Autogenerated by tblgen.
std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -179,6 +179,31 @@
RISCVVType::printVType(Imm, O);
}
+void RISCVInstPrinter::printRlist(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O) {
+ unsigned Imm = MI->getOperand(OpNo).getImm();
+ RISCVZC::printRlist(Imm, O);
+}
+
+void RISCVInstPrinter::printSpimm(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O) {
+ int64_t Imm = MI->getOperand(OpNo).getImm();
+ unsigned Opcode = MI->getOpcode();
+ bool IsRV64 = STI.getFeatureBits()[RISCV::Feature64Bit];
+ int64_t Spimm = 0;
+ bool IsEABI = false; // Reserved for future implementation
+ auto RlistVal = MI->getOperand(0).getImm();
+ assert(RlistVal != 16 && "Incorrect rlist.");
+ auto Base = RISCVZC::getStackAdjBase(RlistVal, IsRV64, IsEABI);
+ Spimm = Imm + Base;
+ assert((Spimm >= Base && Spimm <= Base + 48) && "Incorrect spimm");
+ if (Opcode == RISCV::CM_PUSH) {
+ Spimm *= -1;
+ }
+
+ RISCVZC::printSpimm(Spimm, O);
+}
+
void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -474,6 +474,128 @@
bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI);
} // namespace RISCVRVC
+namespace RISCVZC {
+enum RLISTENCODE {
+ RA = 4,
+ RA_S0,
+ RA_S0_S1,
+ RA_S0_S2,
+ RA_S0_S3,
+ RA_S0_S4,
+ RA_S0_S5,
+ RA_S0_S6,
+ RA_S0_S7,
+ RA_S0_S8,
+ RA_S0_S9,
+ // note - to include s10, s11 must also be included
+ RA_S0_S11,
+ INVALID_RLIST,
+};
+
+inline unsigned encodeRlist(MCRegister EndReg, bool isCInst,
+ bool IsRV32E = false) {
+ auto RlistEncode = [=] {
+ switch (EndReg) {
+ case RISCV::X1:
+ return RLISTENCODE::RA;
+ case RISCV::X8:
+ return RLISTENCODE::RA_S0;
+ case RISCV::X9:
+ return RLISTENCODE::RA_S0_S1;
+ case RISCV::X18:
+ return RLISTENCODE::RA_S0_S2;
+ case RISCV::X19:
+ return RLISTENCODE::RA_S0_S3;
+ case RISCV::X20:
+ return RLISTENCODE::RA_S0_S4;
+ case RISCV::X21:
+ return RLISTENCODE::RA_S0_S5;
+ case RISCV::X22:
+ return RLISTENCODE::RA_S0_S6;
+ case RISCV::X23:
+ return RLISTENCODE::RA_S0_S7;
+ case RISCV::X24:
+ return RLISTENCODE::RA_S0_S8;
+ case RISCV::X25:
+ return RLISTENCODE::RA_S0_S9;
+ case RISCV::X26:
+ return RLISTENCODE::INVALID_RLIST;
+ case RISCV::X27:
+ return RLISTENCODE::RA_S0_S11;
+ default:
+ llvm_unreachable("Undefined input.");
+ }
+ }();
+ return static_cast<unsigned int>(RlistEncode);
+}
+
+inline static unsigned getStackAdjBase(unsigned rlistVal, bool isRV64,
+ bool isEABI) {
+ if (rlistVal == RLISTENCODE::INVALID_RLIST)
+ assert(0 && "{ra, s0-s10} is not supported, s11 must be included.");
+ if (isEABI) {
+ return 16;
+ }
+ if (!isRV64) {
+ switch (rlistVal) {
+ case RLISTENCODE::RA:
+ case RLISTENCODE::RA_S0:
+ case RLISTENCODE::RA_S0_S1:
+ case RLISTENCODE::RA_S0_S2:
+ return 16;
+ case RLISTENCODE::RA_S0_S3:
+ case RLISTENCODE::RA_S0_S4:
+ case RLISTENCODE::RA_S0_S5:
+ case RLISTENCODE::RA_S0_S6:
+ return 32;
+ case RLISTENCODE::RA_S0_S7:
+ case RLISTENCODE::RA_S0_S8:
+ case RLISTENCODE::RA_S0_S9:
+ return 48;
+ case RLISTENCODE::RA_S0_S11:
+ return 64;
+ }
+ } else {
+ switch (rlistVal) {
+ case RLISTENCODE::RA:
+ case RLISTENCODE::RA_S0:
+ return 16;
+ case RLISTENCODE::RA_S0_S1:
+ case RLISTENCODE::RA_S0_S2:
+ return 32;
+ case RLISTENCODE::RA_S0_S3:
+ case RLISTENCODE::RA_S0_S4:
+ return 48;
+ case RLISTENCODE::RA_S0_S5:
+ case RLISTENCODE::RA_S0_S6:
+ return 64;
+ case RLISTENCODE::RA_S0_S7:
+ case RLISTENCODE::RA_S0_S8:
+ return 80;
+ case RLISTENCODE::RA_S0_S9:
+ return 96;
+ case RLISTENCODE::RA_S0_S11:
+ return 112;
+ }
+ }
+ llvm_unreachable("Unexpected rlistVal");
+}
+
+inline static bool getSpimm(unsigned rlistVal, unsigned &spimmVal,
+ int64_t stackAdjustment, bool isRV64, bool isEABI) {
+ if (rlistVal == 16)
+ return false;
+ unsigned stackAdj = getStackAdjBase(rlistVal, isRV64, isEABI);
+ spimmVal = (stackAdjustment - stackAdj) / 16;
+ if (spimmVal > 3)
+ return false;
+ return true;
+}
+
+void printRlist(unsigned SlistEncode, raw_ostream &OS);
+void printSpimm(int64_t Spimm, raw_ostream &OS);
+} // namespace RISCVZC
+
} // namespace llvm
#endif
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
@@ -214,4 +214,18 @@
return uncompressInst(OutInst, MI, STI);
}
+void RISCVZC::printRlist(unsigned SlistEncode, raw_ostream &OS) {
+ OS << "{ra";
+ if (SlistEncode > 4) {
+ OS << ", s0";
+ if (SlistEncode == 15)
+ OS << "-s11";
+ else if (SlistEncode > 5 && SlistEncode <= 14)
+ OS << "-s" << (SlistEncode - 5);
+ }
+ OS << "}";
+}
+
+void RISCVZC::printSpimm(int64_t Spimm, raw_ostream &OS) { OS << Spimm; }
+
} // namespace llvm
Index: llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
===================================================================
--- llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -170,6 +170,17 @@
return MCDisassembler::Success;
}
+static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo >= 8)
+ return MCDisassembler::Fail;
+
+ MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
@@ -369,6 +380,12 @@
uint64_t Address,
const MCDisassembler *Decoder);
+static DecodeStatus decodeZcRlist(MCInst &Inst, unsigned Imm, uint64_t Address,
+ const void *Decoder);
+
+static DecodeStatus decodeZcSpimm(MCInst &Inst, unsigned Imm, uint64_t Address,
+ const void *Decoder);
+
#include "RISCVGenDisassemblerTables.inc"
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
@@ -429,6 +446,22 @@
return MCDisassembler::Success;
}
+static DecodeStatus decodeZcRlist(MCInst &Inst, unsigned Imm, uint64_t Address,
+ const void *Decoder) {
+ if (Imm <= 3)
+ return MCDisassembler::Fail;
+ Inst.addOperand(MCOperand::createImm(Imm));
+ return MCDisassembler::Success;
+}
+
+// spimm is based on rlist now.
+static DecodeStatus decodeZcSpimm(MCInst &Inst, unsigned Imm, uint64_t Address,
+ const void *Decoder) {
+ // TODO: check if spimm matches rlist
+ Inst.addOperand(MCOperand::createImm(Imm));
+ return MCDisassembler::Success;
+}
+
DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address,
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -174,6 +174,9 @@
OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands);
OperandMatchResultTy parseFRMArg(OperandVector &Operands);
OperandMatchResultTy parseFenceArg(OperandVector &Operands);
+ OperandMatchResultTy parseReglist(OperandVector &Operands);
+ OperandMatchResultTy parseRetval(OperandVector &Operands);
+ OperandMatchResultTy parseZcSpimm(OperandVector &Operands);
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
@@ -283,6 +286,8 @@
VType,
FRM,
Fence,
+ Rlist,
+ Spimm,
} Kind;
struct RegOp {
@@ -314,6 +319,15 @@
struct FenceOp {
unsigned Val;
};
+
+ struct RlistOp {
+ bool IsCInst;
+ unsigned Val;
+ };
+
+ struct SpimmOp {
+ unsigned Val;
+ };
SMLoc StartLoc, EndLoc;
union {
@@ -324,6 +338,8 @@
struct VTypeOp VType;
struct FRMOp FRM;
struct FenceOp Fence;
+ struct RlistOp Rlist;
+ struct SpimmOp Spimm;
};
RISCVOperand(KindTy K) : Kind(K) {}
@@ -355,6 +371,12 @@
case KindTy::Fence:
Fence = o.Fence;
break;
+ case KindTy::Rlist:
+ Rlist = o.Rlist;
+ break;
+ case KindTy::Spimm:
+ Spimm = o.Spimm;
+ break;
}
}
@@ -366,6 +388,8 @@
bool isImm() const override { return Kind == KindTy::Immediate; }
bool isMem() const override { return false; }
bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
+ bool isRlist() const { return Kind == KindTy::Rlist; }
+ bool isSpimm() const { return Kind == KindTy::Spimm; }
bool isGPR() const {
return Kind == KindTy::Register &&
@@ -841,6 +865,16 @@
OS << getFence();
OS << '>';
break;
+ case KindTy::Rlist:
+ OS << "<rlist: ";
+ RISCVZC::printRlist(Rlist.Val, OS);
+ OS << '>';
+ break;
+ case KindTy::Spimm:
+ OS << "{Spimm: ";
+ RISCVZC::printSpimm(Spimm.Val, OS);
+ OS << '}';
+ break;
}
}
@@ -908,6 +942,23 @@
return Op;
}
+ static std::unique_ptr<RISCVOperand>
+ createRlist(unsigned RlistEncode, SMLoc S, bool IsRV64, bool IsCInst) {
+ auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
+ Op->Rlist.Val = RlistEncode;
+ Op->Rlist.IsCInst = IsCInst;
+ Op->StartLoc = S;
+ return Op;
+ }
+
+ static std::unique_ptr<RISCVOperand> createSpimm(unsigned spimm, SMLoc S,
+ bool IsRV64) {
+ auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
+ Op->Spimm.Val = spimm;
+ Op->StartLoc = S;
+ return Op;
+ }
+
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
assert(Expr && "Expr shouldn't be null!");
int64_t Imm = 0;
@@ -958,6 +1009,16 @@
Inst.addOperand(MCOperand::createImm(Imm));
}
+ void addRlistOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createImm(Rlist.Val));
+ }
+
+ void addSpimmOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createImm(Spimm.Val));
+ }
+
void addFRMArgOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createImm(getFRM()));
@@ -1269,6 +1330,18 @@
(1 << 4),
"immediate must be in the range");
}
+ case Match_InvalidRlist: {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
+ return Error(ErrorLoc, "operand must be {}, {a0}, or {a0-a[1|2|3]}");
+ }
+ case Match_InvalidSpimm: {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
+ return Error(
+ ErrorLoc,
+ "This stack adjustment is invalid for this instruction and register "
+ "list, "
+ "Please refer to Zc spec for a detailed range of stack adjustment.");
+ }
case Match_InvalidRnumArg: {
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
}
@@ -1987,6 +2060,115 @@
return MatchOperand_Success;
}
+OperandMatchResultTy RISCVAsmParser::parseReglist(OperandVector &Operands) {
+ // Rlist grammar: {ra [, s0[-sN]]} (UABI)
+ // XRlist :{x1 [, x8[-x9][, x18[-xN]]]} (UABI)
+ SMLoc S = getLoc();
+ if (getLexer().isNot(AsmToken::LCurly))
+ return MatchOperand_NoMatch;
+ getLexer().Lex(); // eat '{'
+ bool IsEmptyList = getLexer().is(AsmToken::RCurly);
+
+ StringRef Memonic =
+ static_cast<RISCVOperand *>(Operands.front().get())->getToken();
+ bool Is16Bit = Memonic.startswith("cm.");
+ bool IsEABI = isRV32E() || Memonic.endswith(".e");
+ bool IsXReglist = Memonic.find("x");
+
+ MCRegister RegStart = RISCV::NoRegister;
+ MCRegister RegEnd = RISCV::NoRegister;
+ if (!IsEmptyList) {
+ StringRef RegName = getLexer().getTok().getIdentifier();
+ matchRegisterNameHelper(IsEABI, RegStart, RegName);
+ if (RegStart != RISCV::X1)
+ return MatchOperand_NoMatch;
+ getLexer().Lex();
+ }
+
+ // parse case like ,s0
+ if (getLexer().is(AsmToken::Comma)) {
+ getLexer().Lex();
+ if (getLexer().isNot(AsmToken::Identifier))
+ return MatchOperand_NoMatch;
+ StringRef RegName = getLexer().getTok().getIdentifier();
+ if (matchRegisterNameHelper(/*IsEABI*/ false, RegStart, RegName))
+ return MatchOperand_NoMatch;
+ if (RegStart != RISCV::X8)
+ return MatchOperand_NoMatch;
+ getLexer().Lex(); // eat reg
+ }
+
+ // parse case like -s1
+ if (getLexer().is(AsmToken::Minus)) {
+ getLexer().Lex();
+ StringRef EndName = getLexer().getTok().getIdentifier();
+ // FIXME: the register mapping and checks of EABI is wrong
+ if (matchRegisterNameHelper(/*IsEABI*/ false, RegEnd, EndName))
+ return MatchOperand_NoMatch;
+ getLexer().Lex();
+ }
+
+ // parse extra part like ', x18[-x20]' for XRegList
+ if (IsXReglist && getLexer().is(AsmToken::Comma)) {
+ if (RegEnd != RISCV::X9)
+ return MatchOperand_NoMatch;
+
+ // parse ', x18' for extra part
+ getLexer().Lex();
+ if (getLexer().isNot(AsmToken::Identifier))
+ return MatchOperand_NoMatch;
+ StringRef EndName = getLexer().getTok().getIdentifier();
+ if (MatchRegisterName(EndName) != RISCV::X18)
+ return MatchOperand_NoMatch;
+ getLexer().Lex();
+
+ // parse '-x20' for extra part
+ if (getLexer().is(AsmToken::Minus)) {
+ getLexer().Lex();
+ if (getLexer().isNot(AsmToken::Identifier))
+ return MatchOperand_NoMatch;
+ EndName = getLexer().getTok().getIdentifier();
+ if (MatchRegisterName(EndName) == RISCV::NoRegister)
+ return MatchOperand_NoMatch;
+ getLexer().Lex();
+ }
+ RegEnd = MatchRegisterName(EndName);
+ }
+
+ if (getLexer().isNot(AsmToken::RCurly))
+ return MatchOperand_NoMatch;
+ getLexer().Lex(); // eat '}'
+
+ if (RegEnd == RISCV::NoRegister)
+ RegEnd = RegStart;
+
+ auto Encode = RISCVZC::encodeRlist(RegEnd, Is16Bit, IsEABI);
+ if (Encode == 16)
+ Error(getLoc(), "invalid register list, {ra, s0-s10} is not supported.");
+ Operands.push_back(RISCVOperand::createRlist(Encode, S, isRV64(), Is16Bit));
+
+ return MatchOperand_Success;
+}
+
+OperandMatchResultTy RISCVAsmParser::parseZcSpimm(OperandVector &Operands) {
+ if (getLexer().is(AsmToken::Minus))
+ getLexer().Lex();
+
+ SMLoc S = getLoc();
+
+ StringRef Memonic =
+ static_cast<RISCVOperand *>(Operands.front().get())->getToken();
+ int64_t StackAdjustment = getLexer().getTok().getIntVal();
+ unsigned Spimm = 0;
+ unsigned RlistVal = static_cast<RISCVOperand *>(Operands[1].get())->Rlist.Val;
+
+ bool IsEABI = isRV32E() || Memonic.endswith(".e");
+ if (!RISCVZC::getSpimm(RlistVal, Spimm, StackAdjustment, isRV64(), IsEABI))
+ return MatchOperand_NoMatch;
+ Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S, isRV64()));
+ getLexer().Lex();
+ return MatchOperand_Success;
+}
/// Looks at a token type and creates the relevant operand from this
/// information, adding to Operands. If operand was parsed, returns false, else
@@ -2856,7 +3038,16 @@
.addImm(Imm - 1)
.addOperand(Inst.getOperand(3)));
}
-
+ return false;
+ }
+ case RISCV::CM_POPRET:
+ case RISCV::CM_POPRETZ:
+ case RISCV::CM_POP:
+ case RISCV::CM_PUSH: {
+ unsigned Opc = Inst.getOpcode();
+ emitToStreamer(Out, MCInstBuilder(Opc)
+ .addOperand(Inst.getOperand(0))
+ .addOperand(Inst.getOperand(1)));
return false;
}
}
Index: llvm/lib/Support/RISCVISAInfo.cpp
===================================================================
--- llvm/lib/Support/RISCVISAInfo.cpp
+++ llvm/lib/Support/RISCVISAInfo.cpp
@@ -122,6 +122,7 @@
{"zcb", RISCVExtensionVersion{1, 0}},
{"zcd", RISCVExtensionVersion{1, 0}},
{"zcf", RISCVExtensionVersion{1, 0}},
+ {"zcmp", RISCVExtensionVersion{1, 0}},
{"zvfh", RISCVExtensionVersion{0, 1}},
{"zawrs", RISCVExtensionVersion{1, 0}},
{"ztso", RISCVExtensionVersion{0, 1}},
@@ -832,6 +833,7 @@
static const char *ImpliedExtsZvfh[] = {"zve32f"};
static const char *ImpliedExtsXTHeadVdot[] = {"v"};
static const char *ImpliedExtsZcb[] = {"zca"};
+static const char *ImpliedExtsZcmp[] = {"zca"};
struct ImpliedExtsEntry {
StringLiteral Name;
@@ -849,6 +851,7 @@
{{"v"}, {ImpliedExtsV}},
{{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
{{"zcb"}, {ImpliedExtsZcb}},
+ {{"zcmp"}, {ImpliedExtsZcmp}},
{{"zdinx"}, {ImpliedExtsZdinx}},
{{"zfh"}, {ImpliedExtsZfh}},
{{"zfhmin"}, {ImpliedExtsZfhmin}},
Index: clang/test/Preprocessor/riscv-target-features.c
===================================================================
--- clang/test/Preprocessor/riscv-target-features.c
+++ clang/test/Preprocessor/riscv-target-features.c
@@ -48,6 +48,7 @@
// CHECK-NOT: __riscv_zcb
// CHECK-NOT: __riscv_zcd
// CHECK-NOT: __riscv_zcf
+// CHECK-NOT: __riscv_zcmp
// CHECK-NOT: __riscv_h
// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32im -x c -E -dM %s \
@@ -488,3 +489,10 @@
// RUN: %clang -target riscv32 -march=rv32izcf1p0 -menable-experimental-extensions \
// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCF-EXT %s
// CHECK-ZCF-EXT: __riscv_zcf 1000000{{$}}
+
+// RUN: %clang -target riscv32 -march=rv32izcmp1p0 -menable-experimental-extensions \
+// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCMP-EXT %s
+// RUN: %clang -target riscv64 -march=rv64izcmp1p0 -menable-experimental-extensions \
+// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCMP-EXT %s
+// CHECK-ZCMP-EXT: __riscv_zca 1000000{{$}}
+// CHECK-ZCMP-EXT: __riscv_zcmp 1000000{{$}}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits