achieveartificialintelligence updated this revision to Diff 399527.
achieveartificialintelligence marked 3 inline comments as done.
achieveartificialintelligence added a comment.

Address @craig.topper's comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D93298/new/

https://reviews.llvm.org/D93298

Files:
  llvm/lib/Support/RISCVISAInfo.cpp
  llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
  llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
  llvm/lib/Target/RISCV/RISCV.td
  llvm/lib/Target/RISCV/RISCVInstrInfoD.td
  llvm/lib/Target/RISCV/RISCVInstrInfoF.td
  llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
  llvm/lib/Target/RISCV/RISCVRegisterInfo.td
  llvm/lib/Target/RISCV/RISCVSubtarget.h
  llvm/test/MC/RISCV/attribute-arch.s
  llvm/test/MC/RISCV/rv32i-invalid.s
  llvm/test/MC/RISCV/rv32zdinx-invalid.s
  llvm/test/MC/RISCV/rv32zdinx-valid.s
  llvm/test/MC/RISCV/rv32zfinx-invalid.s
  llvm/test/MC/RISCV/rv32zfinx-valid.s
  llvm/test/MC/RISCV/rv32zhinx-invalid.s
  llvm/test/MC/RISCV/rv32zhinx-valid.s
  llvm/test/MC/RISCV/rv32zhinxmin-invalid.s
  llvm/test/MC/RISCV/rv32zhinxmin-valid.s
  llvm/test/MC/RISCV/rv64zdinx-invalid.s
  llvm/test/MC/RISCV/rv64zdinx-valid.s
  llvm/test/MC/RISCV/rv64zfinx-invalid.s
  llvm/test/MC/RISCV/rv64zfinx-valid.s
  llvm/test/MC/RISCV/rv64zhinx-invalid.s
  llvm/test/MC/RISCV/rv64zhinx-valid.s
  llvm/test/MC/RISCV/rv64zhinxmin-invalid.s
  llvm/test/MC/RISCV/rv64zhinxmin-valid.s
  llvm/test/MC/RISCV/rvzdinx-aliases-valid.s
  llvm/test/MC/RISCV/rvzfinx-aliases-valid.s
  llvm/test/MC/RISCV/rvzhinx-aliases-valid.s

Index: llvm/test/MC/RISCV/rvzhinx-aliases-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rvzhinx-aliases-valid.s
@@ -0,0 +1,82 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zhinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zhinx -M no-aliases - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zhinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zhinx - \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zhinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zhinx -M no-aliases - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zhinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zhinx - \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+
+##===----------------------------------------------------------------------===##
+## Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
+##===----------------------------------------------------------------------===##
+
+# CHECK-INST: fsgnjx.h s1, s2, s2
+# CHECK-ALIAS: fabs.h s1, s2
+fabs.h s1, s2
+# CHECK-INST: fsgnjn.h s2, s3, s3
+# CHECK-ALIAS: fneg.h s2, s3
+fneg.h s2, s3
+
+# CHECK-INST: flt.h tp, s6, s5
+# CHECK-ALIAS: flt.h tp, s6, s5
+fgt.h x4, s5, s6
+# CHECK-INST: fle.h t2, s1, s0
+# CHECK-ALIAS: fle.h t2, s1, s0
+fge.h x7, x8, x9
+
+##===----------------------------------------------------------------------===##
+## Aliases which omit the rounding mode.
+##===----------------------------------------------------------------------===##
+
+# CHECK-INST: fmadd.h a0, a1, a2, a3, dyn
+# CHECK-ALIAS: fmadd.h a0, a1, a2, a3
+fmadd.h x10, x11, x12, x13
+# CHECK-INST: fmsub.h a4, a5, a6, a7, dyn
+# CHECK-ALIAS: fmsub.h a4, a5, a6, a7
+fmsub.h x14, x15, x16, x17
+# CHECK-INST: fnmsub.h s2, s3, s4, s5, dyn
+# CHECK-ALIAS: fnmsub.h s2, s3, s4, s5
+fnmsub.h x18, x19, x20, x21
+# CHECK-INST: fnmadd.h s6, s7, s8, s9, dyn
+# CHECK-ALIAS: fnmadd.h s6, s7, s8, s9
+fnmadd.h x22, x23, x24, x25
+# CHECK-INST: fadd.h s10, s11, t3, dyn
+# CHECK-ALIAS: fadd.h s10, s11, t3
+fadd.h x26, x27, x28
+# CHECK-INST: fsub.h t4, t5, t6, dyn
+# CHECK-ALIAS: fsub.h t4, t5, t6
+fsub.h x29, x30, x31
+# CHECK-INST: fmul.h s0, s1, s2, dyn
+# CHECK-ALIAS: fmul.h s0, s1, s2
+fmul.h s0, s1, s2
+# CHECK-INST: fdiv.h s3, s4, s5, dyn
+# CHECK-ALIAS: fdiv.h s3, s4, s5
+fdiv.h s3, s4, s5
+# CHECK-INST: fsqrt.h s6, s7, dyn
+# CHECK-ALIAS: fsqrt.h s6, s7
+fsqrt.h s6, s7
+# CHECK-INST: fcvt.w.h a0, s5, dyn
+# CHECK-ALIAS: fcvt.w.h a0, s5
+fcvt.w.h a0, s5
+# CHECK-INST: fcvt.wu.h a1, s6, dyn
+# CHECK-ALIAS: fcvt.wu.h a1, s6
+fcvt.wu.h a1, s6
+# CHECK-INST: fcvt.h.w t6, a4, dyn
+# CHECK-ALIAS: fcvt.h.w t6, a4
+fcvt.h.w t6, a4
+# CHECK-INST: fcvt.h.wu s0, a5, dyn
+# CHECK-ALIAS: fcvt.h.wu s0, a5
+fcvt.h.wu s0, a5
Index: llvm/test/MC/RISCV/rvzfinx-aliases-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rvzfinx-aliases-valid.s
@@ -0,0 +1,82 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zfinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zfinx -M no-aliases - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zfinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zfinx - \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zfinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zfinx -M no-aliases - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zfinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zfinx - \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+
+##===----------------------------------------------------------------------===##
+## Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
+##===----------------------------------------------------------------------===##
+
+# CHECK-INST: fsgnjx.s s1, s2, s2
+# CHECK-ALIAS: fabs.s s1, s2
+fabs.s s1, s2
+# CHECK-INST: fsgnjn.s s2, s3, s3
+# CHECK-ALIAS: fneg.s s2, s3
+fneg.s s2, s3
+
+# CHECK-INST: flt.s tp, s6, s5
+# CHECK-ALIAS: flt.s tp, s6, s5
+fgt.s x4, s5, s6
+# CHECK-INST: fle.s t2, s1, s0
+# CHECK-ALIAS: fle.s t2, s1, s0
+fge.s x7, x8, x9
+
+##===----------------------------------------------------------------------===##
+## Aliases which omit the rounding mode.
+##===----------------------------------------------------------------------===##
+
+# CHECK-INST: fmadd.s a0, a1, a2, a3, dyn
+# CHECK-ALIAS: fmadd.s a0, a1, a2, a3
+fmadd.s x10, x11, x12, x13
+# CHECK-INST: fmsub.s a4, a5, a6, a7, dyn
+# CHECK-ALIAS: fmsub.s a4, a5, a6, a7
+fmsub.s x14, x15, x16, x17
+# CHECK-INST: fnmsub.s s2, s3, s4, s5, dyn
+# CHECK-ALIAS: fnmsub.s s2, s3, s4, s5
+fnmsub.s x18, x19, x20, x21
+# CHECK-INST: fnmadd.s s6, s7, s8, s9, dyn
+# CHECK-ALIAS: fnmadd.s s6, s7, s8, s9
+fnmadd.s x22, x23, x24, x25
+# CHECK-INST: fadd.s s10, s11, t3, dyn
+# CHECK-ALIAS: fadd.s s10, s11, t3
+fadd.s x26, x27, x28
+# CHECK-INST: fsub.s t4, t5, t6, dyn
+# CHECK-ALIAS: fsub.s t4, t5, t6
+fsub.s x29, x30, x31
+# CHECK-INST: fmul.s s0, s1, s2, dyn
+# CHECK-ALIAS: fmul.s s0, s1, s2
+fmul.s s0, s1, s2
+# CHECK-INST: fdiv.s s3, s4, s5, dyn
+# CHECK-ALIAS: fdiv.s s3, s4, s5
+fdiv.s s3, s4, s5
+# CHECK-INST: sqrt.s s6, s7, dyn
+# CHECK-ALIAS: sqrt.s s6, s7
+fsqrt.s s6, s7
+# CHECK-INST: fcvt.w.s a0, s5, dyn
+# CHECK-ALIAS: fcvt.w.s a0, s5
+fcvt.w.s a0, s5
+# CHECK-INST: fcvt.wu.s a1, s6, dyn
+# CHECK-ALIAS: fcvt.wu.s a1, s6
+fcvt.wu.s a1, s6
+# CHECK-INST: fcvt.s.w t6, a4, dyn
+# CHECK-ALIAS: fcvt.s.w t6, a4
+fcvt.s.w t6, a4
+# CHECK-INST: fcvt.s.wu s0, a5, dyn
+# CHECK-ALIAS: fcvt.s.wu s0, a5
+fcvt.s.wu s0, a5
Index: llvm/test/MC/RISCV/rvzdinx-aliases-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rvzdinx-aliases-valid.s
@@ -0,0 +1,49 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zdinx -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zdinx \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zdinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zdinx -M no-aliases - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zdinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zdinx - \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zdinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zdinx -M no-aliases - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zdinx %s \
+# RUN:     | llvm-objdump -d --mattr=+zdinx - \
+# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+
+##===----------------------------------------------------------------------===##
+## Aliases which omit the rounding mode.
+##===----------------------------------------------------------------------===##
+
+# CHECK-INST: fmadd.d a0, a2, a4, a6, dyn
+# CHECK-ALIAS: fmadd.d a0, a2, a4, a6
+fmadd.d x10, x12, x14, x16
+# CHECK-INST: fmsub.d a0, a2, a4, a6, dyn
+# CHECK-ALIAS: fmsub.d a0, a2, a4, a6
+fmsub.d x10, x12, x14, x16
+# CHECK-INST: fnmsub.d a0, a2, a4, a6, dyn
+# CHECK-ALIAS: fnmsub.d a0, a2, a4, a6
+fnmsub.d x10, x12, x14, x16
+# CHECK-INST: fnmadd.d a0, a2, a4, a6, dyn
+# CHECK-ALIAS: fnmadd.d a0, a2, a4, a6
+fnmadd.d x10, x12, x14, x16
+# CHECK-INST: fadd.d a0, a2, a4, dyn
+# CHECK-ALIAS: fadd.d a0, a2, a4
+fadd.d x10, x12, x14
+# CHECK-INST: fsub.d a0, a2, a4, dyn
+# CHECK-ALIAS: fsub.d a0, a2, a4
+fsub.d x10, x12, x14
+# CHECK-INST: fmul.d a0, a2, a4, dyn
+# CHECK-ALIAS: fmul.d a0, a2, a4
+fmul.d x10, x12, x14
+# CHECK-INST: fdiv.d a0, a2, a4, dyn
+# CHECK-ALIAS: fdiv.d a0, a2, a4
+fdiv.d x10, x12, x14
Index: llvm/test/MC/RISCV/rv64zhinxmin-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zhinxmin-valid.s
@@ -0,0 +1,13 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx,+zdinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx,+zdinx %s \
+# RUN:     | llvm-objdump --mattr=+zhinx,+zdinx -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: fcvt.d.h a0, a2
+# CHECK-ASM: encoding: [0x53,0x05,0x26,0x42]
+fcvt.d.h a0, a2
+
+# CHECK-ASM-AND-OBJ: fcvt.h.d a0, a2, dyn
+# CHECK-ASM: encoding: [0x53,0x75,0x16,0x44]
+fcvt.h.d a0, a2, dyn
Index: llvm/test/MC/RISCV/rv64zhinxmin-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zhinxmin-invalid.s
@@ -0,0 +1,5 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+zhinx %s 2>&1 | FileCheck %s
+
+# Invalid instructions
+fmv.x.h t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+fmv.h.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
Index: llvm/test/MC/RISCV/rv64zhinx-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zhinx-valid.s
@@ -0,0 +1,43 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx %s \
+# RUN:     | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+#
+# RUN: not llvm-mc -triple riscv32 -mattr=+zhinx %s 2>&1 \
+# RUN:     | FileCheck -check-prefix=CHECK-RV32 %s
+
+# CHECK-ASM-AND-OBJ: fcvt.l.h a0, t0, dyn
+# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.l.h a0, t0, dyn
+# CHECK-ASM-AND-OBJ: fcvt.lu.h a1, t1, dyn
+# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.lu.h a1, t1, dyn
+# CHECK-ASM-AND-OBJ: fcvt.h.l t2, a2, dyn
+# CHECK-ASM: encoding: [0xd3,0x73,0x26,0xd4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.h.l t2, a2, dyn
+# CHECK-ASM-AND-OBJ: fcvt.h.lu t3, a3, dyn
+# CHECK-ASM: encoding: [0x53,0xfe,0x36,0xd4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.h.lu t3, a3, dyn
+
+# Rounding modes
+# CHECK-ASM-AND-OBJ: fcvt.l.h a4, t4, rne
+# CHECK-ASM: encoding: [0x53,0x87,0x2e,0xc4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.l.h a4, t4, rne
+# CHECK-ASM-AND-OBJ: fcvt.lu.h a5, t5, rtz
+# CHECK-ASM: encoding: [0xd3,0x17,0x3f,0xc4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.lu.h a5, t5, rtz
+# CHECK-ASM-AND-OBJ: fcvt.h.l t6, a6, rdn
+# CHECK-ASM: encoding: [0xd3,0x2f,0x28,0xd4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.h.l t6, a6, rdn
+# CHECK-ASM-AND-OBJ: fcvt.h.lu s7, a7, rup
+# CHECK-ASM: encoding: [0xd3,0xbb,0x38,0xd4]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.h.lu s7, a7, rup
Index: llvm/test/MC/RISCV/rv64zhinx-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zhinx-invalid.s
@@ -0,0 +1,5 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+zhinx %s 2>&1 | FileCheck %s
+
+# Invalid instructions
+fmv.x.h t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+fmv.h.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
Index: llvm/test/MC/RISCV/rv64zfinx-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zfinx-valid.s
@@ -0,0 +1,43 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zfinx %s \
+# RUN:     | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+#
+# RUN: not llvm-mc -triple riscv32 -mattr=+zfinx %s 2>&1 \
+# RUN:     | FileCheck -check-prefix=CHECK-RV32 %s
+
+# CHECK-ASM-AND-OBJ: fcvt.l.s a0, t0, dyn
+# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.l.s a0, t0, dyn
+# CHECK-ASM-AND-OBJ: fcvt.lu.s a1, t1, dyn
+# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.lu.s a1, t1, dyn
+# CHECK-ASM-AND-OBJ: fcvt.s.l t2, a2, dyn
+# CHECK-ASM: encoding: [0xd3,0x73,0x26,0xd0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.s.l t2, a2, dyn
+# CHECK-ASM-AND-OBJ: fcvt.s.lu t3, a3, dyn
+# CHECK-ASM: encoding: [0x53,0xfe,0x36,0xd0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.s.lu t3, a3, dyn
+
+# Rounding modes
+# CHECK-ASM-AND-OBJ: fcvt.l.s a4, t4, rne
+# CHECK-ASM: encoding: [0x53,0x87,0x2e,0xc0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.l.s a4, t4, rne
+# CHECK-ASM-AND-OBJ: fcvt.lu.s a5, t5, rtz
+# CHECK-ASM: encoding: [0xd3,0x17,0x3f,0xc0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.lu.s a5, t5, rtz
+# CHECK-ASM-AND-OBJ: fcvt.s.l t6, a6, rdn
+# CHECK-ASM: encoding: [0xd3,0x2f,0x28,0xd0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.s.l t6, a6, rdn
+# CHECK-ASM-AND-OBJ: fcvt.s.lu s7, a7, rup
+# CHECK-ASM: encoding: [0xd3,0xbb,0x38,0xd0]
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
+fcvt.s.lu s7, a7, rup
Index: llvm/test/MC/RISCV/rv64zfinx-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zfinx-invalid.s
@@ -0,0 +1,5 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+zfinx %s 2>&1 | FileCheck %s
+
+# Invalid instructions
+fmv.x.w t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+fmv.w.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
Index: llvm/test/MC/RISCV/rv64zdinx-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zdinx-valid.s
@@ -0,0 +1,43 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zdinx %s \
+# RUN:     | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+#
+# RUN: not llvm-mc -triple riscv32 -mattr=+zdinx %s 2>&1 \
+# RUN:     | FileCheck -check-prefix=CHECK-RV32 %s
+
+# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, dyn
+# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc2]
+# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction
+fcvt.l.d a0, t0, dyn
+# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, dyn
+# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc2]
+# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction
+fcvt.lu.d a1, t1, dyn
+# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, dyn
+# CHECK-ASM: encoding: [0x53,0xfe,0x26,0xd2]
+# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction
+fcvt.d.l t3, a3, dyn
+# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, dyn
+# CHECK-ASM: encoding: [0xd3,0x7e,0x37,0xd2]
+# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction
+fcvt.d.lu t4, a4, dyn
+
+# Rounding modes
+# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, rne
+# CHECK-ASM: encoding: [0x53,0x8e,0x26,0xd2]
+# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction
+fcvt.d.l t3, a3, rne
+# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, rtz
+# CHECK-ASM: encoding: [0xd3,0x1e,0x37,0xd2]
+# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction
+fcvt.d.lu t4, a4, rtz
+# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, rdn
+# CHECK-ASM: encoding: [0x53,0xa5,0x22,0xc2]
+# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction
+fcvt.l.d a0, t0, rdn
+# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, rup
+# CHECK-ASM: encoding: [0xd3,0x35,0x33,0xc2]
+# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction
+fcvt.lu.d a1, t1, rup
Index: llvm/test/MC/RISCV/rv64zdinx-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zdinx-invalid.s
@@ -0,0 +1,5 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+zdinx %s 2>&1 | FileCheck %s
+
+# Invalid Instructions
+fmv.x.d t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+fmv.d.x a5, t5 # CHECK: :[[@LINE]]:9:  error: invalid operand for instruction
Index: llvm/test/MC/RISCV/rv32zhinxmin-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zhinxmin-valid.s
@@ -0,0 +1,50 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinxmin -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinxmin -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zhinxmin %s \
+# RUN:     | llvm-objdump --mattr=+zhinxmin -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinxmin %s \
+# RUN:     | llvm-objdump --mattr=+zhinxmin -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: lh s0, 12(a0)
+# CHECK-ASM: encoding: [0x03,0x14,0xc5,0x00]
+lh s0, 12(a0)
+# CHECK-ASM-AND-OBJ: lh s1, 4(ra)
+# CHECK-ASM: encoding: [0x83,0x94,0x40,0x00]
+lh s1, +4(ra)
+# CHECK-ASM-AND-OBJ: lh s2, -2048(a3)
+# CHECK-ASM: encoding: [0x03,0x99,0x06,0x80]
+lh s2, -2048(x13)
+# CHECK-ASM-AND-OBJ: lh s3, -2048(s1)
+# CHECK-ASM: encoding: [0x83,0x99,0x04,0x80]
+lh s3, %lo(2048)(s1)
+# CHECK-ASM-AND-OBJ: lh s4, 2047(s2)
+# CHECK-ASM: encoding: [0x03,0x1a,0xf9,0x7f]
+lh s4, 2047(s2)
+# CHECK-ASM-AND-OBJ: lh s5, 0(s3)
+# CHECK-ASM: encoding: [0x83,0x9a,0x09,0x00]
+lh s5, 0(s3)
+
+# CHECK-ASM-AND-OBJ: sh s6, 2047(s4)
+# CHECK-ASM: encoding: [0xa3,0x1f,0x6a,0x7f]
+sh s6, 2047(s4)
+# CHECK-ASM-AND-OBJ: sh s7, -2048(s5)
+# CHECK-ASM: encoding: [0x23,0x90,0x7a,0x81]
+sh s7, -2048(s5)
+# CHECK-ASM-AND-OBJ: sh s0, -2048(s6)
+# CHECK-ASM: encoding: [0x23,0x10,0x8b,0x80]
+sh x8, %lo(2048)(s6)
+# CHECK-ASM-AND-OBJ: sh s1, 999(s7)
+# CHECK-ASM: encoding: [0xa3,0x93,0x9b,0x3e]
+sh x9, 999(s7)
+
+# CHECK-ASM-AND-OBJ: fcvt.s.h a0, a1
+# CHECK-ASM: encoding: [0x53,0x85,0x25,0x40]
+fcvt.s.h a0, a1
+
+# CHECK-ASM-AND-OBJ: fcvt.h.s a0, a1, dyn
+# CHECK-ASM: encoding: [0x53,0xf5,0x05,0x44]
+fcvt.h.s a0, a1
Index: llvm/test/MC/RISCV/rv32zhinxmin-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zhinxmin-invalid.s
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+zhinxmin %s 2>&1 | FileCheck %s
+
+# Invalid instructions
+flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
+fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
+fmv.x.h s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+
+# Invalid register names
+lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction
+lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register
+fadd.h a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+
+# Valid in Zhinx
+fmadd.h x10, x11, x12, x13, dyn # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zhinx' (Half Float in Integer)
Index: llvm/test/MC/RISCV/rv32zhinx-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zhinx-valid.s
@@ -0,0 +1,160 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zhinx %s \
+# RUN:     | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx %s \
+# RUN:     | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: lh s0, 12(a0)
+# CHECK-ASM: encoding: [0x03,0x14,0xc5,0x00]
+lh s0, 12(a0)
+# CHECK-ASM-AND-OBJ: lh s1, 4(ra)
+# CHECK-ASM: encoding: [0x83,0x94,0x40,0x00]
+lh s1, +4(ra)
+# CHECK-ASM-AND-OBJ: lh s2, -2048(a3)
+# CHECK-ASM: encoding: [0x03,0x99,0x06,0x80]
+lh s2, -2048(x13)
+# CHECK-ASM-AND-OBJ: lh s3, -2048(s1)
+# CHECK-ASM: encoding: [0x83,0x99,0x04,0x80]
+lh s3, %lo(2048)(s1)
+# CHECK-ASM-AND-OBJ: lh s4, 2047(s2)
+# CHECK-ASM: encoding: [0x03,0x1a,0xf9,0x7f]
+lh s4, 2047(s2)
+# CHECK-ASM-AND-OBJ: lh s5, 0(s3)
+# CHECK-ASM: encoding: [0x83,0x9a,0x09,0x00]
+lh s5, 0(s3)
+
+# CHECK-ASM-AND-OBJ: sh s6, 2047(s4)
+# CHECK-ASM: encoding: [0xa3,0x1f,0x6a,0x7f]
+sh s6, 2047(s4)
+# CHECK-ASM-AND-OBJ: sh s7, -2048(s5)
+# CHECK-ASM: encoding: [0x23,0x90,0x7a,0x81]
+sh s7, -2048(s5)
+# CHECK-ASM-AND-OBJ: sh s0, -2048(s6)
+# CHECK-ASM: encoding: [0x23,0x10,0x8b,0x80]
+sh x8, %lo(2048)(s6)
+# CHECK-ASM-AND-OBJ: sh s1, 999(s7)
+# CHECK-ASM: encoding: [0xa3,0x93,0x9b,0x3e]
+sh x9, 999(s7)
+
+# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, dyn
+# CHECK-ASM: encoding: [0x43,0xf5,0xc5,0x6c]
+fmadd.h x10, x11, x12, x13, dyn
+# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7, dyn
+# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x8d]
+fmsub.h x14, x15, x16, x17, dyn
+# CHECK-ASM-AND-OBJ: fnmsub.h s2, s3, s4, s5, dyn
+# CHECK-ASM: encoding: [0x4b,0xf9,0x49,0xad]
+fnmsub.h x18, x19, x20, x21, dyn
+# CHECK-ASM-AND-OBJ: fnmadd.h s6, s7, s8, s9, dyn
+# CHECK-ASM: encoding: [0x4f,0xfb,0x8b,0xcd]
+fnmadd.h x22, x23, x24, x25, dyn
+
+# CHECK-ASM-AND-OBJ: fadd.h s10, s11, t3, dyn
+# CHECK-ASM: encoding: [0x53,0xfd,0xcd,0x05]
+fadd.h x26, x27, x28, dyn
+# CHECK-ASM-AND-OBJ: fsub.h t4, t5, t6, dyn
+# CHECK-ASM: encoding: [0xd3,0x7e,0xff,0x0d]
+fsub.h x29, x30, x31, dyn
+# CHECK-ASM-AND-OBJ: fmul.h s0, s1, s2, dyn
+# CHECK-ASM: encoding: [0x53,0xf4,0x24,0x15]
+fmul.h s0, s1, s2, dyn
+# CHECK-ASM-AND-OBJ: fdiv.h s3, s4, s5, dyn
+# CHECK-ASM: encoding: [0xd3,0x79,0x5a,0x1d]
+fdiv.h s3, s4, s5, dyn
+# CHECK-ASM-AND-OBJ: fsqrt.h s6, s7, dyn
+# CHECK-ASM: encoding: [0x53,0xfb,0x0b,0x5c]
+fsqrt.h s6, s7, dyn
+# CHECK-ASM-AND-OBJ: fsgnj.h s1, a0, a1
+# CHECK-ASM: encoding: [0xd3,0x04,0xb5,0x24]
+fsgnj.h x9, x10, x11
+# CHECK-ASM-AND-OBJ: fsgnjn.h a1, a3, a4
+# CHECK-ASM: encoding: [0xd3,0x95,0xe6,0x24]
+fsgnjn.h x11, x13, x14
+# CHECK-ASM-AND-OBJ: fsgnjx.h a4, a3, a2
+# CHECK-ASM: encoding: [0x53,0xa7,0xc6,0x24]
+fsgnjx.h x14, x13, x12
+# CHECK-ASM-AND-OBJ: fmin.h a5, a6, a7
+# CHECK-ASM: encoding: [0xd3,0x07,0x18,0x2d]
+fmin.h x15, x16, x17
+# CHECK-ASM-AND-OBJ: fmax.h s2, s3, s4
+# CHECK-ASM: encoding: [0x53,0x99,0x49,0x2d]
+fmax.h x18, x19, x20
+# CHECK-ASM-AND-OBJ: fcvt.w.h a0, s5, dyn
+# CHECK-ASM: encoding: [0x53,0xf5,0x0a,0xc4]
+fcvt.w.h x10, x21, dyn
+# CHECK-ASM-AND-OBJ: fcvt.wu.h a1, s6, dyn
+# CHECK-ASM: encoding: [0xd3,0x75,0x1b,0xc4]
+fcvt.wu.h x11, x22, dyn
+# CHECK-ASM-AND-OBJ: feq.h a1, s8, s9
+# CHECK-ASM: encoding: [0xd3,0x25,0x9c,0xa5]
+feq.h x11, x24, x25
+# CHECK-ASM-AND-OBJ: flt.h a2, s10, s11
+# CHECK-ASM: encoding: [0x53,0x16,0xbd,0xa5]
+flt.h x12, x26, x27
+# CHECK-ASM-AND-OBJ: fle.h a3, t3, t4
+# CHECK-ASM: encoding: [0xd3,0x06,0xde,0xa5]
+fle.h x13, x28, x29
+# CHECK-ASM-AND-OBJ: fclass.h a3, t5
+# CHECK-ASM: encoding: [0xd3,0x16,0x0f,0xe4]
+fclass.h x13, x30
+# CHECK-ASM-AND-OBJ: fcvt.h.w t6, a4, dyn
+# CHECK-ASM: encoding: [0xd3,0x7f,0x07,0xd4]
+fcvt.h.w x31, x14, dyn
+# CHECK-ASM-AND-OBJ: fcvt.h.wu s0, a5, dyn
+# CHECK-ASM: encoding: [0x53,0xf4,0x17,0xd4]
+fcvt.h.wu s0, x15, dyn
+
+# Rounding modes
+
+# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, rne
+# CHECK-ASM: encoding: [0x43,0x85,0xc5,0x6c]
+fmadd.h x10, x11, x12, x13, rne
+# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7, rtz
+# CHECK-ASM: encoding: [0x47,0x97,0x07,0x8d]
+fmsub.h x14, x15, x16, x17, rtz
+# CHECK-ASM-AND-OBJ: fnmsub.h s2, s3, s4, s5, rdn
+# CHECK-ASM: encoding: [0x4b,0xa9,0x49,0xad]
+fnmsub.h x18, x19, x20, x21, rdn
+# CHECK-ASM-AND-OBJ: fnmadd.h s6, s7, s8, s9, rup
+# CHECK-ASM: encoding: [0x4f,0xbb,0x8b,0xcd]
+fnmadd.h x22, x23, x24, x25, rup
+# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, rmm
+# CHECK-ASM: encoding: [0x43,0xc5,0xc5,0x6c]
+fmadd.h x10, x11, x12, x13, rmm
+# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7
+# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x8d]
+fmsub.h x14, x15, x16, x17, dyn
+
+# CHECK-ASM-AND-OBJ: fadd.h s10, s11, t3, rne
+# CHECK-ASM: encoding: [0x53,0x8d,0xcd,0x05]
+fadd.h x26, x27, x28, rne
+# CHECK-ASM-AND-OBJ: fsub.h t4, t5, t6, rtz
+# CHECK-ASM: encoding: [0xd3,0x1e,0xff,0x0d]
+fsub.h x29, x30, x31, rtz
+# CHECK-ASM-AND-OBJ: fmul.h s0, s1, s2, rdn
+# CHECK-ASM: encoding: [0x53,0xa4,0x24,0x15]
+fmul.h s0, s1, s2, rdn
+# CHECK-ASM-AND-OBJ: fdiv.h s3, s4, s5, rup
+# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x1d]
+fdiv.h s3, s4, s5, rup
+
+# CHECK-ASM-AND-OBJ: fsqrt.h s6, s7, rmm
+# CHECK-ASM: encoding: [0x53,0xcb,0x0b,0x5c]
+fsqrt.h s6, s7, rmm
+# CHECK-ASM-AND-OBJ: fcvt.w.h a0, s5, rup
+# CHECK-ASM: encoding: [0x53,0xb5,0x0a,0xc4]
+fcvt.w.h x10, x21, rup
+# CHECK-ASM-AND-OBJ: fcvt.wu.h a1, s6, rdn
+# CHECK-ASM: encoding: [0xd3,0x25,0x1b,0xc4]
+fcvt.wu.h x11, x22, rdn
+# CHECK-ASM-AND-OBJ: fcvt.h.w t6, a4, rtz
+# CHECK-ASM: encoding: [0xd3,0x1f,0x07,0xd4]
+fcvt.h.w x31, x14, rtz
+# CHECK-ASM-AND-OBJ: fcvt.h.wu s0, a5, rne
+# CHECK-ASM: encoding: [0x53,0x84,0x17,0xd4]
+fcvt.h.wu s0, a5, rne
Index: llvm/test/MC/RISCV/rv32zhinx-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zhinx-invalid.s
@@ -0,0 +1,11 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+zhinx %s 2>&1 | FileCheck %s
+
+# Invalid instructions
+flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
+fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
+fmv.x.h s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+
+# Invalid register names
+lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction
+lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register
+fadd.h a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
Index: llvm/test/MC/RISCV/rv32zfinx-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zfinx-valid.s
@@ -0,0 +1,160 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zfinx %s \
+# RUN:     | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zfinx %s \
+# RUN:     | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: lw s0, 12(a0)
+# CHECK-ASM: encoding: [0x03,0x24,0xc5,0x00]
+lw s0, 12(a0)
+# CHECK-ASM-AND-OBJ: lw s1, 4(ra)
+# CHECK-ASM: encoding: [0x83,0xa4,0x40,0x00]
+lw s1, +4(ra)
+# CHECK-ASM-AND-OBJ: lw s2, -2048(a3)
+# CHECK-ASM: encoding: [0x03,0xa9,0x06,0x80]
+lw s2, -2048(x13)
+# CHECK-ASM-AND-OBJ: lw s3, -2048(s1)
+# CHECK-ASM: encoding: [0x83,0xa9,0x04,0x80]
+lw s3, %lo(2048)(s1)
+# CHECK-ASM-AND-OBJ: lw s4, 2047(s2)
+# CHECK-ASM: encoding: [0x03,0x2a,0xf9,0x7f]
+lw s4, 2047(s2)
+# CHECK-ASM-AND-OBJ: lw s5, 0(s3)
+# CHECK-ASM: encoding: [0x83,0xaa,0x09,0x00]
+lw s5, 0(s3)
+
+# CHECK-ASM-AND-OBJ: sw s6, 2047(s4)
+# CHECK-ASM: encoding: [0xa3,0x2f,0x6a,0x7f]
+sw s6, 2047(s4)
+# CHECK-ASM-AND-OBJ: sw s7, -2048(s5)
+# CHECK-ASM: encoding: [0x23,0xa0,0x7a,0x81]
+sw s7, -2048(s5)
+# CHECK-ASM-AND-OBJ: sw s8, -2048(s6)
+# CHECK-ASM: encoding: [0x23,0x20,0x8b,0x81]
+sw s8, %lo(2048)(s6)
+# CHECK-ASM-AND-OBJ: sw s9, 999(s7)
+# CHECK-ASM: encoding: [0xa3,0xa3,0x9b,0x3f]
+sw s9, 999(s7)
+
+# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, dyn
+# CHECK-ASM: encoding: [0x43,0xf5,0xc5,0x68]
+fmadd.s x10, x11, x12, x13, dyn
+# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7, dyn
+# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x89]
+fmsub.s x14, x15, x16, x17, dyn
+# CHECK-ASM-AND-OBJ: fnmsub.s s2, s3, s4, s5, dyn
+# CHECK-ASM: encoding: [0x4b,0xf9,0x49,0xa9]
+fnmsub.s x18, x19, x20, x21, dyn
+# CHECK-ASM-AND-OBJ: fnmadd.s s6, s7, s8, s9, dyn
+# CHECK-ASM: encoding: [0x4f,0xfb,0x8b,0xc9]
+fnmadd.s x22, x23, x24, x25, dyn
+
+# CHECK-ASM-AND-OBJ: fadd.s s10, s11, t3, dyn
+# CHECK-ASM: encoding: [0x53,0xfd,0xcd,0x01]
+fadd.s x26, x27, x28, dyn
+# CHECK-ASM-AND-OBJ: fsub.s t4, t5, t6, dyn
+# CHECK-ASM: encoding: [0xd3,0x7e,0xff,0x09]
+fsub.s x29, x30, x31, dyn
+# CHECK-ASM-AND-OBJ: fmul.s s0, s1, s2, dyn
+# CHECK-ASM: encoding: [0x53,0xf4,0x24,0x11]
+fmul.s s0, s1, s2, dyn
+# CHECK-ASM-AND-OBJ: fdiv.s s3, s4, s5, dyn
+# CHECK-ASM: encoding: [0xd3,0x79,0x5a,0x19]
+fdiv.s s3, s4, s5, dyn
+# CHECK-ASM-AND-OBJ: fsqrt.s t1, t2, dyn
+# CHECK-ASM: encoding: [0x53,0xf3,0x03,0x58]
+fsqrt.s t1, t2, dyn
+# CHECK-ASM-AND-OBJ: fsgnj.s s1, a0, a1
+# CHECK-ASM: encoding: [0xd3,0x04,0xb5,0x20]
+fsgnj.s s1, a0, a1
+# CHECK-ASM-AND-OBJ: fsgnjn.s a1, a3, a4
+# CHECK-ASM: encoding: [0xd3,0x95,0xe6,0x20]
+fsgnjn.s a1, a3, a4
+# CHECK-ASM-AND-OBJ: fsgnjx.s a4, a3, a2
+# CHECK-ASM: encoding: [0x53,0xa7,0xc6,0x20]
+fsgnjx.s a4, a3, a2
+# CHECK-ASM-AND-OBJ: fmin.s a5, a6, a7
+# CHECK-ASM: encoding: [0xd3,0x07,0x18,0x29]
+fmin.s a5, a6, a7
+# CHECK-ASM-AND-OBJ: fmax.s s2, s3, s4
+# CHECK-ASM: encoding: [0x53,0x99,0x49,0x29]
+fmax.s s2, s3, s4
+# CHECK-ASM-AND-OBJ: fcvt.w.s a0, s5, dyn
+# CHECK-ASM: encoding: [0x53,0xf5,0x0a,0xc0]
+fcvt.w.s a0, s5, dyn
+# CHECK-ASM-AND-OBJ: fcvt.wu.s a1, s6, dyn
+# CHECK-ASM: encoding: [0xd3,0x75,0x1b,0xc0]
+fcvt.wu.s a1, s6, dyn
+# CHECK-ASM-AND-OBJ: feq.s a1, s8, s9
+# CHECK-ASM: encoding: [0xd3,0x25,0x9c,0xa1]
+feq.s a1, s8, s9
+# CHECK-ASM-AND-OBJ: flt.s a2, s10, s11
+# CHECK-ASM: encoding: [0x53,0x16,0xbd,0xa1]
+flt.s a2, s10, s11
+# CHECK-ASM-AND-OBJ: fle.s a3, t3, t4
+# CHECK-ASM: encoding: [0xd3,0x06,0xde,0xa1]
+fle.s a3, t3, t4
+# CHECK-ASM-AND-OBJ: fclass.s a3, t5
+# CHECK-ASM: encoding: [0xd3,0x16,0x0f,0xe0]
+fclass.s a3, t5
+# CHECK-ASM-AND-OBJ: fcvt.s.w t6, a4, dyn
+# CHECK-ASM: encoding: [0xd3,0x7f,0x07,0xd0]
+fcvt.s.w t6, a4, dyn
+# CHECK-ASM-AND-OBJ: fcvt.s.wu s0, a5, dyn
+# CHECK-ASM: encoding: [0x53,0xf4,0x17,0xd0]
+fcvt.s.wu s0, a5, dyn
+
+# Rounding modes
+
+# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, rne
+# CHECK-ASM: encoding: [0x43,0x85,0xc5,0x68]
+fmadd.s x10, x11, x12, x13, rne
+# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7, rtz
+# CHECK-ASM: encoding: [0x47,0x97,0x07,0x89]
+fmsub.s x14, x15, x16, x17, rtz
+# CHECK-ASM-AND-OBJ: fnmsub.s s2, s3, s4, s5, rdn
+# CHECK-ASM: encoding: [0x4b,0xa9,0x49,0xa9]
+fnmsub.s x18, x19, x20, x21, rdn
+# CHECK-ASM-AND-OBJ: fnmadd.s s6, s7, s8, s9, rup
+# CHECK-ASM: encoding: [0x4f,0xbb,0x8b,0xc9]
+fnmadd.s x22, x23, x24, x25, rup
+# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, rmm
+# CHECK-ASM: encoding: [0x43,0xc5,0xc5,0x68]
+fmadd.s x10, x11, x12, x13, rmm
+# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7
+# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x89]
+fmsub.s x14, x15, x16, x17, dyn
+
+# CHECK-ASM-AND-OBJ: fadd.s s10, s11, t3, rne
+# CHECK-ASM: encoding: [0x53,0x8d,0xcd,0x01]
+fadd.s x26, x27, x28, rne
+# CHECK-ASM-AND-OBJ: fsub.s t4, t5, t6, rtz
+# CHECK-ASM: encoding: [0xd3,0x1e,0xff,0x09]
+fsub.s x29, x30, x31, rtz
+# CHECK-ASM-AND-OBJ: fmul.s s0, s1, s2, rdn
+# CHECK-ASM: encoding: [0x53,0xa4,0x24,0x11]
+fmul.s s0, s1, s2, rdn
+# CHECK-ASM-AND-OBJ: fdiv.s s3, s4, s5, rup
+# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x19]
+fdiv.s s3, s4, s5, rup
+
+# CHECK-ASM-AND-OBJ: fsqrt.s t1, t2, rmm
+# CHECK-ASM: encoding: [0x53,0xc3,0x03,0x58]
+fsqrt.s t1, t2, rmm
+# CHECK-ASM-AND-OBJ: fcvt.w.s a0, s5, rup
+# CHECK-ASM: encoding: [0x53,0xb5,0x0a,0xc0]
+fcvt.w.s a0, s5, rup
+# CHECK-ASM-AND-OBJ: fcvt.wu.s a1, s6, rdn
+# CHECK-ASM: encoding: [0xd3,0x25,0x1b,0xc0]
+fcvt.wu.s a1, s6, rdn
+# CHECK-ASM-AND-OBJ: fcvt.s.w t6, a4, rtz
+# CHECK-ASM: encoding: [0xd3,0x1f,0x07,0xd0]
+fcvt.s.w t6, a4, rtz
+# CHECK-ASM-AND-OBJ: fcvt.s.wu s0, a5, rne
+# CHECK-ASM: encoding: [0x53,0x84,0x17,0xd0]
+fcvt.s.wu s0, a5, rne
Index: llvm/test/MC/RISCV/rv32zfinx-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zfinx-invalid.s
@@ -0,0 +1,12 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+zfinx %s 2>&1 | FileCheck %s
+
+# Invalid instructions
+flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
+fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
+fmv.x.d s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+fadd.d t1, t3, t5 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer)
+
+# Invalid register names
+lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction
+lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register
+fadd.s a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
Index: llvm/test/MC/RISCV/rv32zdinx-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zdinx-valid.s
@@ -0,0 +1,156 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zdinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zdinx %s \
+# RUN:     | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zdinx %s \
+# RUN:     | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: lw s0, 12(a0)
+# CHECK-ASM: encoding: [0x03,0x24,0xc5,0x00]
+lw s0, 12(a0)
+# CHECK-ASM-AND-OBJ: lw s1, 4(ra)
+# CHECK-ASM: encoding: [0x83,0xa4,0x40,0x00]
+lw s1, +4(ra)
+# CHECK-ASM-AND-OBJ: lw s2, -2048(a3)
+# CHECK-ASM: encoding: [0x03,0xa9,0x06,0x80]
+lw s2, -2048(x13)
+# CHECK-ASM-AND-OBJ: lw s3, -2048(s1)
+# CHECK-ASM: encoding: [0x83,0xa9,0x04,0x80]
+lw s3, %lo(2048)(s1)
+# CHECK-ASM-AND-OBJ: lw s4, 2047(s2)
+# CHECK-ASM: encoding: [0x03,0x2a,0xf9,0x7f]
+lw s4, 2047(s2)
+# CHECK-ASM-AND-OBJ: lw s5, 0(s3)
+# CHECK-ASM: encoding: [0x83,0xaa,0x09,0x00]
+lw s5, 0(s3)
+
+# CHECK-ASM-AND-OBJ: sw s6, 2047(s4)
+# CHECK-ASM: encoding: [0xa3,0x2f,0x6a,0x7f]
+sw s6, 2047(s4)
+# CHECK-ASM-AND-OBJ: sw s7, -2048(s5)
+# CHECK-ASM: encoding: [0x23,0xa0,0x7a,0x81]
+sw s7, -2048(s5)
+# CHECK-ASM-AND-OBJ: sw s8, -2048(s6)
+# CHECK-ASM: encoding: [0x23,0x20,0x8b,0x81]
+sw s8, %lo(2048)(s6)
+# CHECK-ASM-AND-OBJ: sw s9, 999(s7)
+# CHECK-ASM: encoding: [0xa3,0xa3,0x9b,0x3f]
+sw s9, 999(s7)
+
+# CHECK-ASM-AND-OBJ: fmadd.d a0, a2, a4, a6, dyn
+# CHECK-ASM: encoding: [0x43,0x75,0xe6,0x82]
+fmadd.d x10, x12, x14, x16, dyn
+# CHECK-ASM-AND-OBJ: fmsub.d a0, a2, a4, a6, dyn
+# CHECK-ASM: encoding: [0x47,0x75,0xe6,0x82]
+fmsub.d x10, x12, x14, x16, dyn
+# CHECK-ASM-AND-OBJ: fnmsub.d a0, a2, a4, a6, dyn
+# CHECK-ASM: encoding: [0x4b,0x75,0xe6,0x82]
+fnmsub.d x10, x12, x14, x16, dyn
+# CHECK-ASM-AND-OBJ: fnmadd.d a0, a2, a4, a6, dyn
+# CHECK-ASM: encoding: [0x4f,0x75,0xe6,0x82]
+fnmadd.d x10, x12, x14, x16, dyn
+
+# CHECK-ASM-AND-OBJ: fadd.d s10, t3, t5, dyn
+# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x03]
+fadd.d x26, x28, x30, dyn
+# CHECK-ASM-AND-OBJ: fsub.d s10, t3, t5, dyn
+# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x0b]
+fsub.d x26, x28, x30, dyn
+# CHECK-ASM-AND-OBJ: fmul.d s10, t3, t5, dyn
+# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x13]
+fmul.d x26, x28, x30, dyn
+# CHECK-ASM-AND-OBJ: fdiv.d s10, t3, t5, dyn
+# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x1b]
+fdiv.d x26, x28, x30, dyn
+# CHECK-ASM-AND-OBJ: fsqrt.d s4, s6, dyn
+# CHECK-ASM: encoding: [0x53,0x7a,0x0b,0x5a]
+fsqrt.d x20, x22, dyn
+# CHECK-ASM-AND-OBJ: fsgnj.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x23]
+fsgnj.d x26, x28, x30
+# CHECK-ASM-AND-OBJ: fsgnjn.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x23]
+fsgnjn.d x26, x28, x30
+# CHECK-ASM-AND-OBJ: fsgnjx.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x2d,0xee,0x23]
+fsgnjx.d x26, x28, x30
+# CHECK-ASM-AND-OBJ: fmin.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x2b]
+fmin.d x26, x28, x30
+# CHECK-ASM-AND-OBJ: fmax.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x2b]
+fmax.d x26, x28, x30
+
+# CHECK-ASM-AND-OBJ: fcvt.s.d s10, t3, dyn
+# CHECK-ASM: encoding: [0x53,0x7d,0x1e,0x40]
+fcvt.s.d x26, x28, dyn
+# CHECK-ASM-AND-OBJ: fcvt.d.s s10, t3
+# CHECK-ASM: encoding: [0x53,0x0d,0x0e,0x42]
+fcvt.d.s x26, x28
+# CHECK-ASM-AND-OBJ: feq.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x2d,0xee,0xa3]
+feq.d x26, x28, x30
+# CHECK-ASM-AND-OBJ: flt.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x1d,0xee,0xa3]
+flt.d x26, x28, x30
+# CHECK-ASM-AND-OBJ: fle.d s10, t3, t5
+# CHECK-ASM: encoding: [0x53,0x0d,0xee,0xa3]
+fle.d x26, x28, x30
+# CHECK-ASM-AND-OBJ: fclass.d s10, t3
+# CHECK-ASM: encoding: [0x53,0x1d,0x0e,0xe2]
+fclass.d x26, x28
+
+# CHECK-ASM-AND-OBJ: fcvt.w.d s4, s6, dyn
+# CHECK-ASM: encoding: [0x53,0x7a,0x0b,0xc2]
+fcvt.w.d x20, x22, dyn
+# CHECK-ASM-AND-OBJ: fcvt.d.w s10, t3
+# CHECK-ASM: encoding: [0x53,0x0d,0x0e,0xd2]
+fcvt.d.w x26, x28
+# CHECK-ASM-AND-OBJ: fcvt.d.wu s10, t3
+# CHECK-ASM: encoding: [0x53,0x0d,0x1e,0xd2]
+fcvt.d.wu x26, x28
+
+# Rounding modes
+
+# CHECK-ASM-AND-OBJ: fmadd.d a0, a2, a4, a6, rne
+# CHECK-ASM: encoding: [0x43,0x05,0xe6,0x82]
+fmadd.d x10, x12, x14, x16, rne
+# CHECK-ASM-AND-OBJ: fmsub.d a0, a2, a4, a6, rtz
+# CHECK-ASM: encoding: [0x47,0x15,0xe6,0x82]
+fmsub.d x10, x12, x14, x16, rtz
+# CHECK-ASM-AND-OBJ: fnmsub.d a0, a2, a4, a6, rdn
+# CHECK-ASM: encoding: [0x4b,0x25,0xe6,0x82]
+fnmsub.d x10, x12, x14, x16, rdn
+# CHECK-ASM-AND-OBJ: fnmadd.d a0, a2, a4, a6, rup
+# CHECK-ASM: encoding: [0x4f,0x35,0xe6,0x82]
+fnmadd.d x10, x12, x14, x16, rup
+
+# CHECK-ASM-AND-OBJ: fadd.d s10, t3, t5, rmm
+# CHECK-ASM: encoding: [0x53,0x4d,0xee,0x03]
+fadd.d x26, x28, x30, rmm
+# CHECK-ASM-AND-OBJ: fsub.d s10, t3, t5, dyn
+# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x0b]
+fsub.d x26, x28, x30, dyn
+# CHECK-ASM-AND-OBJ: fmul.d s10, t3, t5, rne
+# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x13]
+fmul.d x26, x28, x30, rne
+# CHECK-ASM-AND-OBJ: fdiv.d s10, t3, t5, rtz
+# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x1b]
+fdiv.d x26, x28, x30, rtz
+
+# CHECK-ASM-AND-OBJ: fsqrt.d s4, s6, rdn
+# CHECK-ASM: encoding: [0x53,0x2a,0x0b,0x5a]
+fsqrt.d x20, x22, rdn
+# CHECK-ASM-AND-OBJ: fcvt.s.d s4, s6, rup
+# CHECK-ASM: encoding: [0x53,0x3a,0x1b,0x40]
+fcvt.s.d x20, x22, rup
+# CHECK-ASM-AND-OBJ: fcvt.w.d s4, s6, rmm
+# CHECK-ASM: encoding: [0x53,0x4a,0x0b,0xc2]
+fcvt.w.d x20, x22, rmm
+# CHECK-ASM-AND-OBJ: fcvt.wu.d s4, s6, dyn
+# CHECK-ASM: encoding: [0x53,0x7a,0x1b,0xc2]
+fcvt.wu.d x20, x22, dyn
Index: llvm/test/MC/RISCV/rv32zdinx-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zdinx-invalid.s
@@ -0,0 +1,11 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+zdinx %s 2>&1 | FileCheck %s
+
+# Invalid instructions
+flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
+fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
+fmv.x.w s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+
+# Invalid register names
+lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction
+lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register
+fadd.d a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
Index: llvm/test/MC/RISCV/rv32i-invalid.s
===================================================================
--- llvm/test/MC/RISCV/rv32i-invalid.s
+++ llvm/test/MC/RISCV/rv32i-invalid.s
@@ -1,4 +1,4 @@
-# RUN: not llvm-mc -triple riscv32 < %s 2>&1 | FileCheck %s
+# RUN: not llvm-mc -triple riscv32 %s 2>&1 | FileCheck %s
 
 # Out of range immediates
 ## fencearg
@@ -173,6 +173,9 @@
 amomaxu.w s5, s4, (s3) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'A' (Atomic Instructions)
 fadd.s ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
 fadd.h ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point)
+fadd.s a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfinx' (Float in Integer)
+fadd.d a0, a2, a4 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer)
+fadd.h a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zhinx' (Half Float in Integer)
 
 # Using floating point registers when integer registers are expected
 addi a2, ft0, 24 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
Index: llvm/test/MC/RISCV/attribute-arch.s
===================================================================
--- llvm/test/MC/RISCV/attribute-arch.s
+++ llvm/test/MC/RISCV/attribute-arch.s
@@ -74,5 +74,17 @@
 .attribute arch, "rv32ifzfh0p1"
 # CHECK: attribute      5, "rv32i2p0_f2p0_zfh0p1_zfhmin0p1"
 
+.attribute arch, "rv32izfinx"
+# CHECK: attribute      5, "rv32i2p0_zfinx1p0"
+
+.attribute arch, "rv32izfinx_zdinx"
+# CHECK: attribute      5, "rv32i2p0_zfinx1p0_zdinx1p0"
+
+.attribute arch, "rv32izfinx_zhinxmin"
+# CHECK: attribute      5, "rv32i2p0_zfinx1p0_zhinxmin1p0"
+
+.attribute arch, "rv32izfinx_zhinx1p0"
+# CHECK: attribute      5, "rv32i2p0_zfinx1p0_zhinx1p0_zhinxmin1p0"
+
 .attribute arch, "rv32iv0p10zvlsseg0p10"
 # CHECK: attribute      5, "rv32i2p0_v0p10_zvlsseg0p10"
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -63,6 +63,10 @@
   bool HasStdExtZvlsseg = false;
   bool HasStdExtZfhmin = false;
   bool HasStdExtZfh = false;
+  bool HasStdExtZfinx = false;
+  bool HasStdExtZdinx = false;
+  bool HasStdExtZhinxmin = false;
+  bool HasStdExtZhinx = false;
   bool HasRV64 = false;
   bool IsRV32E = false;
   bool EnableLinkerRelax = false;
@@ -136,6 +140,10 @@
   bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; }
   bool hasStdExtZfhmin() const { return HasStdExtZfhmin; }
   bool hasStdExtZfh() const { return HasStdExtZfh; }
+  bool hasStdExtZfinx() const { return HasStdExtZfinx; }
+  bool hasStdExtZdinx() const { return HasStdExtZdinx; }
+  bool hasStdExtZhinxmin() const { return HasStdExtZhinxmin; }
+  bool hasStdExtZhinx() const { return HasStdExtZhinx; }
   bool is64Bit() const { return HasRV64; }
   bool isRV32E() const { return IsRV32E; }
   bool enableLinkerRelax() const { return EnableLinkerRelax; }
Index: llvm/lib/Target/RISCV/RISCVRegisterInfo.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -66,6 +66,7 @@
 def sub_vrm1_6 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_0>;
 def sub_vrm1_7 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_1>;
 
+def sub_32_hi  : SubRegIndex<32, 32>;
 } // Namespace = "RISCV"
 
 // Integer registers
@@ -123,14 +124,17 @@
 
 // The order of registers represents the preferred allocation sequence.
 // Registers are listed in the order caller-save, callee-save, specials.
-def GPR : RegisterClass<"RISCV", [XLenVT], 32, (add
+
+defvar GPRAllocationList = (add
     (sequence "X%u", 10, 17),
     (sequence "X%u", 5, 7),
     (sequence "X%u", 28, 31),
     (sequence "X%u", 8, 9),
     (sequence "X%u", 18, 27),
     (sequence "X%u", 0, 4)
-  )> {
+  );
+
+def GPR : RegisterClass<"RISCV", [XLenVT], 32, GPRAllocationList> {
   let RegInfos = XLenRI;
 }
 
@@ -535,6 +539,42 @@
   let Size = 64;
 }
 
+let RegAltNameIndices = [ABIRegAltName] in {
+  foreach Index = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22,
+                   24, 26, 28, 30] in {
+    defvar Reg = !cast<Register>("X"#Index);
+    def X#Index#_PD : RISCVRegWithSubRegs<Index, Reg.AsmName,
+                       [!cast<Register>("X"#Index),
+                        !cast<Register>("X"#!add(Index, 1))],
+                       Reg.AltNames> {
+      let SubRegIndices = [sub_32, sub_32_hi];
+    }
+  }
+}
+
+def GPRF16 : RegisterClass<"RISCV", [f16], 16, GPRAllocationList> {
+  let RegInfos = XLenRI;
+}
+
+def GPRF32 : RegisterClass<"RISCV", [f32], 32, GPRAllocationList> {
+  let RegInfos = XLenRI;
+}
+
+def GPRF64 : RegisterClass<"RISCV", [f64], 64, GPRAllocationList> {
+  let RegInfos = XLenRI;
+}
+
+def GPRPF64 : RegisterClass<"RISCV", [f64], 64, (add
+    X10_PD, X12_PD, X14_PD, X16_PD,
+    X6_PD,
+    X28_PD, X30_PD,
+    X8_PD,
+    X18_PD, X20_PD, X22_PD, X24_PD, X26_PD,
+    X0_PD, X2_PD, X4_PD
+)> {
+  let RegInfos = XLenRI;
+}
+
 // The register class is added for inline assembly for vector mask types.
 def VM : VReg<VMaskVTs,
            (add (sequence "V%u", 8, 31),
Index: llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -27,6 +27,63 @@
 def riscv_fmv_x_anyexth
     : SDNode<"RISCVISD::FMV_X_ANYEXTH", SDT_RISCVFMV_X_ANYEXTH>;
 
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+// Zhinxmin and Zhinx
+
+def FPR16INX : RegisterOperand<GPRF16> {
+  let ParserMatchClass = GPRAsFPR;
+  let DecoderMethod = "DecodeGPRRegisterClass";
+}
+
+def ZfhExt           : ExtInfo<0, [HasStdExtZfh]>;
+def Zfh64Ext         : ExtInfo<0, [HasStdExtZfh, IsRV64]>;
+def ZfhminExt        : ExtInfo<0, [HasStdExtZfhmin]>;
+def ZhinxExt         : ExtInfo<1, [HasStdExtZhinx]>;
+def ZhinxminExt      : ExtInfo<1, [HasStdExtZhinxmin]>;
+def Zhinx64Ext       : ExtInfo<1, [HasStdExtZhinx, IsRV64]>;
+
+def ZfhminDExt       : ExtInfo<0, [HasStdExtZfhmin,   HasStdExtD]>;
+def ZhinxminZdinxExt : ExtInfo<1, [HasStdExtZhinxmin, HasStdExtZdinx]>;
+
+def H     : ExtInfo_r<ZfhExt,     FPR16>;
+def H_INX : ExtInfo_r<ZhinxExt, FPR16INX>;
+
+def HH        : ExtInfo_rr<ZfhExt,           FPR16,    FPR16>;
+def HH_INX    : ExtInfo_rr<ZhinxExt,         FPR16INX, FPR16INX>;
+def XH        : ExtInfo_rr<ZfhExt,           GPR,      FPR16>;
+def XH_INX    : ExtInfo_rr<ZhinxExt,         GPR,      FPR16INX>;
+def HX        : ExtInfo_rr<ZfhExt,           FPR16,    GPR>;
+def HX_INX    : ExtInfo_rr<ZhinxExt,         FPR16INX, GPR>;
+def XH_64     : ExtInfo_rr<Zfh64Ext,         GPR,      FPR16>;
+def HX_64     : ExtInfo_rr<Zfh64Ext,         FPR16,    GPR>;
+def XH_INX_64 : ExtInfo_rr<Zhinx64Ext,       GPR,      FPR16INX>;
+def HX_INX_64 : ExtInfo_rr<Zhinx64Ext,       FPR16INX, GPR>;
+def HFmin     : ExtInfo_rr<ZfhminExt,        FPR16,    FPR32>;
+def HF_INXmin : ExtInfo_rr<ZhinxminExt,      FPR16INX, FPR32INX>;
+def HF_INX    : ExtInfo_rr<ZhinxExt,         FPR16INX, FPR32INX>;
+def FHmin     : ExtInfo_rr<ZfhminExt,        FPR32,    FPR16>;
+def FH_INXmin : ExtInfo_rr<ZhinxminExt,      FPR32INX, FPR16INX>;
+def FH_INX    : ExtInfo_rr<ZhinxExt,         FPR32INX, FPR16INX>;
+def DHmin     : ExtInfo_rr<ZfhminDExt,       FPR64,    FPR16>;
+def DH_INXmin : ExtInfo_rr<ZhinxminZdinxExt, FPR64INX, FPR16INX>;
+def HDmin     : ExtInfo_rr<ZfhminDExt,       FPR16,    FPR64>;
+def HD_INXmin : ExtInfo_rr<ZhinxminZdinxExt, FPR16INX, FPR64INX>;
+
+defvar HFINXmin = [HFmin, HF_INXmin];
+defvar FHINXmin = [FHmin, FH_INXmin];
+defvar HINX     = [H,     H_INX];
+defvar HHINX    = [HH,    HH_INX];
+defvar XHINX    = [XH,    XH_INX];
+defvar HXINX    = [HX,    HX_INX];
+defvar XHIN64X  = [XH_64, XH_INX_64];
+defvar HXIN64X  = [HX_64, HX_INX_64];
+
+defvar DHINXmin = [DHmin, DH_INXmin];
+defvar HDINXmin = [HDmin, HD_INXmin];
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -40,74 +97,73 @@
 def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>;
 } // Predicates = [HasStdExtZfhmin]
 
-let Predicates = [HasStdExtZfh] in {
 let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16] in {
-def FMADD_H  : FPFMA_rrr_frm<OPC_MADD,  0b10, "fmadd.h",  FPR16>;
-def FMSUB_H  : FPFMA_rrr_frm<OPC_MSUB,  0b10, "fmsub.h",  FPR16>;
-def FNMSUB_H : FPFMA_rrr_frm<OPC_NMSUB, 0b10, "fnmsub.h", FPR16>;
-def FNMADD_H : FPFMA_rrr_frm<OPC_NMADD, 0b10, "fnmadd.h", FPR16>;
+defm FMADD_H  : FPFMA_rrr_frm_m<OPC_MADD,  0b10, "fmadd.h",  HINX>;
+defm FMSUB_H  : FPFMA_rrr_frm_m<OPC_MSUB,  0b10, "fmsub.h",  HINX>;
+defm FNMSUB_H : FPFMA_rrr_frm_m<OPC_NMSUB, 0b10, "fnmsub.h", HINX>;
+defm FNMADD_H : FPFMA_rrr_frm_m<OPC_NMADD, 0b10, "fnmadd.h", HINX>;
 }
 
-def : FPFMADynFrmAlias<FMADD_H,  "fmadd.h",  FPR16>;
-def : FPFMADynFrmAlias<FMSUB_H,  "fmsub.h",  FPR16>;
-def : FPFMADynFrmAlias<FNMSUB_H, "fnmsub.h", FPR16>;
-def : FPFMADynFrmAlias<FNMADD_H, "fnmadd.h", FPR16>;
-
-def FADD_H : FPALU_rr_frm<0b0000010, "fadd.h", FPR16>,
-             Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>;
-def FSUB_H : FPALU_rr_frm<0b0000110, "fsub.h", FPR16>,
-             Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>;
-def FMUL_H : FPALU_rr_frm<0b0001010, "fmul.h", FPR16>,
-             Sched<[WriteFMul16, ReadFMul16, ReadFMul16]>;
-def FDIV_H : FPALU_rr_frm<0b0001110, "fdiv.h", FPR16>,
-             Sched<[WriteFDiv16, ReadFDiv16, ReadFDiv16]>;
-
-def        : FPALUDynFrmAlias<FADD_H, "fadd.h", FPR16>;
-def        : FPALUDynFrmAlias<FSUB_H, "fsub.h", FPR16>;
-def        : FPALUDynFrmAlias<FMUL_H, "fmul.h", FPR16>;
-def        : FPALUDynFrmAlias<FDIV_H, "fdiv.h", FPR16>;
-
-def FSQRT_H : FPUnaryOp_r_frm<0b0101110, 0b00000, FPR16, FPR16, "fsqrt.h">,
-              Sched<[WriteFSqrt16, ReadFSqrt16]>;
-def         : FPUnaryOpDynFrmAlias<FSQRT_H, "fsqrt.h", FPR16, FPR16>;
+defm : FPFMADynFrmAlias_m<FMADD_H,  "fmadd.h",  HINX>;
+defm : FPFMADynFrmAlias_m<FMSUB_H,  "fmsub.h",  HINX>;
+defm : FPFMADynFrmAlias_m<FNMSUB_H, "fnmsub.h", HINX>;
+defm : FPFMADynFrmAlias_m<FNMADD_H, "fnmadd.h", HINX>;
+
+let SchedRW = [WriteFALU16, ReadFALU16, ReadFALU16] in {
+defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", HINX>;
+defm FSUB_H : FPALU_rr_frm_m<0b0000110, "fsub.h", HINX>;
+}
+let SchedRW = [WriteFMul16, ReadFMul16, ReadFMul16] in
+defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", HINX>;
+
+let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in
+defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", HINX>;
+
+defm : FPALUDynFrmAlias_m<FADD_H, "fadd.h", HINX>;
+defm : FPALUDynFrmAlias_m<FSUB_H, "fsub.h", HINX>;
+defm : FPALUDynFrmAlias_m<FMUL_H, "fmul.h", HINX>;
+defm : FPALUDynFrmAlias_m<FDIV_H, "fdiv.h", HINX>;
+
+defm FSQRT_H : FPUnaryOp_r_frm_m<0b0101110, 0b00000, HHINX, "fsqrt.h">,
+               Sched<[WriteFSqrt16, ReadFSqrt16]>;
+defm         : FPUnaryOpDynFrmAlias_m<FSQRT_H, "fsqrt.h", HHINX>;
 
 let SchedRW = [WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16],
     mayRaiseFPException = 0 in {
-def FSGNJ_H  : FPALU_rr<0b0010010, 0b000, "fsgnj.h", FPR16>;
-def FSGNJN_H : FPALU_rr<0b0010010, 0b001, "fsgnjn.h", FPR16>;
-def FSGNJX_H : FPALU_rr<0b0010010, 0b010, "fsgnjx.h", FPR16>;
+defm FSGNJ_H  : FPALU_rr_m<0b0010010, 0b000, "fsgnj.h",  HINX>;
+defm FSGNJN_H : FPALU_rr_m<0b0010010, 0b001, "fsgnjn.h", HINX>;
+defm FSGNJX_H : FPALU_rr_m<0b0010010, 0b010, "fsgnjx.h", HINX>;
 }
 
 let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in {
-def FMIN_H   : FPALU_rr<0b0010110, 0b000, "fmin.h", FPR16>;
-def FMAX_H   : FPALU_rr<0b0010110, 0b001, "fmax.h", FPR16>;
+defm FMIN_H   : FPALU_rr_m<0b0010110, 0b000, "fmin.h", HINX>;
+defm FMAX_H   : FPALU_rr_m<0b0010110, 0b001, "fmax.h", HINX>;
 }
 
-def FCVT_W_H : FPUnaryOp_r_frm<0b1100010, 0b00000, GPR, FPR16, "fcvt.w.h">,
-               Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_W_H, "fcvt.w.h", GPR, FPR16>;
-
-def FCVT_WU_H : FPUnaryOp_r_frm<0b1100010, 0b00001, GPR, FPR16, "fcvt.wu.h">,
+defm FCVT_W_H : FPUnaryOp_r_frm_m<0b1100010, 0b00000, XHINX, "fcvt.w.h">,
                 Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_WU_H, "fcvt.wu.h", GPR, FPR16>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_W_H, "fcvt.w.h", XHINX>;
 
-def FCVT_H_W : FPUnaryOp_r_frm<0b1101010, 0b00000, FPR16, GPR, "fcvt.h.w">,
-               Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_H_W, "fcvt.h.w", FPR16, GPR>;
+defm FCVT_WU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00001, XHINX, "fcvt.wu.h">,
+                 Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_WU_H, "fcvt.wu.h", XHINX>;
 
-def FCVT_H_WU : FPUnaryOp_r_frm<0b1101010, 0b00001, FPR16, GPR, "fcvt.h.wu">,
+defm FCVT_H_W : FPUnaryOp_r_frm_m<0b1101010, 0b00000, HXINX, "fcvt.h.w">,
                 Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_H_WU, "fcvt.h.wu", FPR16, GPR>;
-} // Predicates = [HasStdExtZfh]
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_H_W, "fcvt.h.w", HXINX>;
 
-let Predicates = [HasStdExtZfhmin] in {
-def FCVT_H_S : FPUnaryOp_r_frm<0b0100010, 0b00000, FPR16, FPR32, "fcvt.h.s">,
-               Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_H_S, "fcvt.h.s", FPR16, FPR32>;
+defm FCVT_H_WU : FPUnaryOp_r_frm_m<0b1101010, 0b00001, HXINX, "fcvt.h.wu">,
+                 Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_H_WU, "fcvt.h.wu", HXINX>;
 
-def FCVT_S_H : FPUnaryOp_r<0b0100000, 0b00010, 0b000, FPR32, FPR16, "fcvt.s.h">,
+defm FCVT_H_S : FPUnaryOp_r_frm_m<0b0100010, 0b00000, HFINXmin, "fcvt.h.s">,
+                Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_H_S, "fcvt.h.s", HFINXmin>;
+
+defm FCVT_S_H : FPUnaryOp_r_m<0b0100000, 0b00010, 0b000, FHINXmin, "fcvt.s.h">,
                Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;
 
+let Predicates = [HasStdExtZfhmin] in {
 let mayRaiseFPException = 0 in
 def FMV_X_H : FPUnaryOp_r<0b1110010, 0b00000, 0b000, GPR, FPR16, "fmv.x.h">,
               Sched<[WriteFMovF16ToI16, ReadFMovF16ToI16]>;
@@ -117,45 +173,38 @@
               Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]>;
 } // Predicates = [HasStdExtZfhmin]
 
-let Predicates = [HasStdExtZfh] in {
-
 let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in {
-def FEQ_H : FPCmp_rr<0b1010010, 0b010, "feq.h", FPR16>;
-def FLT_H : FPCmp_rr<0b1010010, 0b001, "flt.h", FPR16>;
-def FLE_H : FPCmp_rr<0b1010010, 0b000, "fle.h", FPR16>;
+defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", HINX>;
+defm FLT_H : FPCmp_rr_m<0b1010010, 0b001, "flt.h", HINX>;
+defm FLE_H : FPCmp_rr_m<0b1010010, 0b000, "fle.h", HINX>;
 }
 
 let mayRaiseFPException = 0 in
-def FCLASS_H : FPUnaryOp_r<0b1110010, 0b00000, 0b001, GPR, FPR16, "fclass.h">,
-               Sched<[WriteFClass16, ReadFClass16]>;
-} // Predicates = [HasStdExtZfh]
-
-let Predicates = [HasStdExtZfh, IsRV64] in {
-def FCVT_L_H  : FPUnaryOp_r_frm<0b1100010, 0b00010, GPR, FPR16, "fcvt.l.h">,
-                Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_L_H, "fcvt.l.h", GPR, FPR16>;
+defm FCLASS_H : FPUnaryOp_r_m<0b1110010, 0b00000, 0b001, XHINX, "fclass.h">,
+                Sched<[WriteFClass16, ReadFClass16]>;
 
-def FCVT_LU_H  : FPUnaryOp_r_frm<0b1100010, 0b00011, GPR, FPR16, "fcvt.lu.h">,
+defm FCVT_L_H  : FPUnaryOp_r_frm_m<0b1100010, 0b00010, XHIN64X, "fcvt.l.h">,
                  Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
-def            : FPUnaryOpDynFrmAlias<FCVT_LU_H, "fcvt.lu.h", GPR, FPR16>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_L_H, "fcvt.l.h", XHIN64X>;
 
-def FCVT_H_L : FPUnaryOp_r_frm<0b1101010, 0b00010, FPR16, GPR, "fcvt.h.l">,
-               Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_H_L, "fcvt.h.l", FPR16, GPR>;
+defm FCVT_LU_H  : FPUnaryOp_r_frm_m<0b1100010, 0b00011, XHIN64X, "fcvt.lu.h">,
+                  Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
+defm            : FPUnaryOpDynFrmAlias_m<FCVT_LU_H, "fcvt.lu.h", XHIN64X>;
 
-def FCVT_H_LU : FPUnaryOp_r_frm<0b1101010, 0b00011, FPR16, GPR, "fcvt.h.lu">,
+defm FCVT_H_L : FPUnaryOp_r_frm_m<0b1101010, 0b00010, HXIN64X, "fcvt.h.l">,
                 Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_H_LU, "fcvt.h.lu", FPR16, GPR>;
-} // Predicates = [HasStdExtZfh, IsRV64]
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_H_L, "fcvt.h.l", HXIN64X>;
 
-let Predicates = [HasStdExtZfhmin, HasStdExtD] in {
-def FCVT_H_D : FPUnaryOp_r_frm<0b0100010, 0b00001, FPR16, FPR64, "fcvt.h.d">,
-               Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_H_D, "fcvt.h.d", FPR16, FPR64>;
+defm FCVT_H_LU : FPUnaryOp_r_frm_m<0b1101010, 0b00011, HXIN64X, "fcvt.h.lu">,
+                 Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_H_LU, "fcvt.h.lu", HXIN64X>;
 
-def FCVT_D_H : FPUnaryOp_r<0b0100001, 0b00010, 0b000, FPR64, FPR16, "fcvt.d.h">,
-               Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
-} // Predicates = [HasStdExtZfhmin, HasStdExtD]
+defm FCVT_H_D : FPUnaryOp_r_frm_m<0b0100010, 0b00001, HDINXmin, "fcvt.h.d">,
+                Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_H_D, "fcvt.h.d", HDINXmin>;
+
+defm FCVT_D_H : FPUnaryOp_r_m<0b0100001, 0b00010, 0b000, DHINXmin, "fcvt.d.h">,
+                Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
 
 //===----------------------------------------------------------------------===//
 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
@@ -188,6 +237,17 @@
 }
 } // Predicates = [HasStdExtZfhmin]
 
+let Predicates = [HasStdExtZhinx] in {
+def : InstAlias<"fmv.h $rd, $rs",  (FSGNJ_H_INX  FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
+def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
+def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
+
+def : InstAlias<"fgt.h $rd, $rs, $rt",
+                (FLT_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>;
+def : InstAlias<"fge.h $rd, $rs, $rt",
+                (FLE_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>;
+} // Predicates = [HasStdExtZhinx]
+
 //===----------------------------------------------------------------------===//
 // Pseudo-instructions and codegen patterns
 //===----------------------------------------------------------------------===//
Index: llvm/lib/Target/RISCV/RISCVInstrInfoF.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoF.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfoF.td
@@ -57,6 +57,73 @@
 // Operand and SDNode transformation definitions.
 //===----------------------------------------------------------------------===//
 
+// Zfinx
+
+def GPRAsFPR : AsmOperandClass {
+  let Name = "GPRAsFPR";
+  let ParserMethod = "parseGPRAsFPR";
+  let RenderMethod = "addRegOperands";
+}
+
+def FPR32INX : RegisterOperand<GPRF32> {
+  let ParserMatchClass = GPRAsFPR;
+  let DecoderMethod = "DecodeGPRRegisterClass";
+}
+
+// inx = 0 : f, d, zfh, zfhmin
+//     = 1 : zfinx, zdinx, zhinx, zhinxmin
+//     = 2 : zdinx_rv32
+class ExtInfo<bits<2> inx, list<Predicate> pres> {
+  string Suffix = !cond(!eq(inx, 0): "",
+                        !eq(inx, 1): "_INX",
+                        !eq(inx, 2): "_IN32X");
+  list<Predicate> Predicates = pres;
+  string Space = !cond(!eq(inx, 0): "",
+                       !eq(inx, 1): "RVZfinx",
+                       !eq(inx, 2): "RV32Zdinx");
+}
+
+class ExtInfo_r<ExtInfo ext, DAGOperand reg> {
+  string Suffix = ext.Suffix;
+  list<Predicate> Predicates = ext.Predicates;
+  string Space = ext.Space;
+  DAGOperand Reg = reg;
+}
+
+class ExtInfo_rr<ExtInfo ext, DAGOperand rdty, DAGOperand rs1ty> {
+  string Suffix = ext.Suffix;
+  list<Predicate> Predicates = ext.Predicates;
+  string Space = ext.Space;
+  DAGOperand RdTy = rdty;
+  DAGOperand Rs1Ty = rs1ty;
+}
+
+def FExt       : ExtInfo<0, [HasStdExtF]>;
+def F64Ext     : ExtInfo<0, [HasStdExtF, IsRV64]>;
+def ZfinxExt   : ExtInfo<1, [HasStdExtZfinx]>;
+def Zfinx64Ext : ExtInfo<1, [HasStdExtZfinx, IsRV64]>;
+
+def F      : ExtInfo_r<FExt,     FPR32>;
+def F_INX  : ExtInfo_r<ZfinxExt, FPR32INX>;
+
+def FF        : ExtInfo_rr<FExt,       FPR32,    FPR32>;
+def FF_INX    : ExtInfo_rr<ZfinxExt,   FPR32INX, FPR32INX>;
+def FX        : ExtInfo_rr<FExt,       FPR32,    GPR>;
+def FX_INX    : ExtInfo_rr<ZfinxExt,   FPR32INX, GPR>;
+def FX_64     : ExtInfo_rr<F64Ext,     FPR32,    GPR>;
+def FX_INX_64 : ExtInfo_rr<Zfinx64Ext, FPR32INX, GPR>;
+def XF        : ExtInfo_rr<FExt,       GPR,      FPR32>;
+def XF_64     : ExtInfo_rr<F64Ext,     GPR,      FPR32>;
+def XF_INX    : ExtInfo_rr<ZfinxExt,   GPR,      FPR32INX>;
+def XF_INX_64 : ExtInfo_rr<Zfinx64Ext, GPR,      FPR32INX>;
+
+defvar FINX    = [F,  F_INX];
+defvar FFINX   = [FF, FF_INX];
+defvar XFINX   = [XF, XF_INX];
+defvar FXINX   = [FX, FX_INX];
+defvar XFIN64X = [XF_64, XF_INX_64];
+defvar FXIN64X = [FX_64, FX_INX_64];
+
 // Floating-point rounding mode
 
 def FRMArg : AsmOperandClass {
@@ -94,62 +161,123 @@
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
     UseNamedOperandTable = 1, hasPostISelHook = 1 in
 class FPFMA_rrr_frm<RISCVOpcode opcode, bits<2> funct2, string opcodestr,
-                    RegisterClass rty>
+                    DAGOperand rty>
     : RVInstR4Frm<funct2, opcode, (outs rty:$rd),
                   (ins rty:$rs1, rty:$rs2, rty:$rs3, frmarg:$frm),
                   opcodestr, "$rd, $rs1, $rs2, $rs3, $frm">;
 
+multiclass FPFMA_rrr_frm_m<RISCVOpcode opcode, bits<2> funct2,
+                           string opcodestr, list<ExtInfo_r> Exts> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+    def Ext.Suffix : FPFMA_rrr_frm<opcode, funct2, opcodestr, Ext.Reg>;
+}
+
 class FPFMADynFrmAlias<FPFMA_rrr_frm Inst, string OpcodeStr,
-                       RegisterClass rty>
+                       DAGOperand rty>
     : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3",
                 (Inst rty:$rd, rty:$rs1, rty:$rs2, rty:$rs3, 0b111)>;
+multiclass FPFMADynFrmAlias_m<FPFMA_rrr_frm Inst, string OpcodeStr,
+                              list<ExtInfo_r> Exts> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates in
+    def : FPFMADynFrmAlias<!cast<FPFMA_rrr_frm>(Inst#Ext.Suffix), OpcodeStr,
+                           Ext.Reg>;
+}
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
 class FPALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
-               RegisterClass rty>
+               DAGOperand rty>
     : RVInstR<funct7, funct3, OPC_OP_FP, (outs rty:$rd),
               (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+multiclass FPALU_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr,
+                      list<ExtInfo_r> Exts> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+    def Ext.Suffix : FPALU_rr<funct7, funct3, opcodestr, Ext.Reg>;
+}
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
     UseNamedOperandTable = 1, hasPostISelHook = 1 in
-class FPALU_rr_frm<bits<7> funct7, string opcodestr, RegisterClass rty>
+class FPALU_rr_frm<bits<7> funct7, string opcodestr, DAGOperand rty>
     : RVInstRFrm<funct7, OPC_OP_FP, (outs rty:$rd),
                  (ins rty:$rs1, rty:$rs2, frmarg:$frm), opcodestr,
                   "$rd, $rs1, $rs2, $frm">;
 
+multiclass FPALU_rr_frm_m<bits<7> funct7, string opcodestr,
+                          list<ExtInfo_r> Exts> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+    def Ext.Suffix : FPALU_rr_frm<funct7, opcodestr, Ext.Reg>;
+}
+
 class FPALUDynFrmAlias<FPALU_rr_frm Inst, string OpcodeStr,
-                       RegisterClass rty>
+                       DAGOperand rty>
     : InstAlias<OpcodeStr#" $rd, $rs1, $rs2",
                 (Inst rty:$rd, rty:$rs1, rty:$rs2, 0b111)>;
+multiclass FPALUDynFrmAlias_m<FPALU_rr_frm Inst, string OpcodeStr,
+                              list<ExtInfo_r> Exts> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates in
+    def : FPALUDynFrmAlias<!cast<FPALU_rr_frm>(Inst#Ext.Suffix), OpcodeStr,
+                           Ext.Reg>;
+}
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
 class FPUnaryOp_r<bits<7> funct7, bits<5> rs2val, bits<3> funct3,
-                  RegisterClass rdty, RegisterClass rs1ty, string opcodestr>
+                  DAGOperand rdty, DAGOperand rs1ty, string opcodestr>
     : RVInstR<funct7, funct3, OPC_OP_FP, (outs rdty:$rd), (ins rs1ty:$rs1),
               opcodestr, "$rd, $rs1"> {
   let rs2 = rs2val;
 }
+multiclass FPUnaryOp_r_m<bits<7> funct7, bits<5> rs2val, bits<3> funct3,
+                         list<ExtInfo_rr> Exts, string opcodestr> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+    def Ext.Suffix : FPUnaryOp_r<funct7, rs2val, funct3, Ext.RdTy, Ext.Rs1Ty,
+                                 opcodestr>;
+}
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
     UseNamedOperandTable = 1, hasPostISelHook = 1 in
-class FPUnaryOp_r_frm<bits<7> funct7, bits<5> rs2val, RegisterClass rdty,
-                      RegisterClass rs1ty, string opcodestr>
+class FPUnaryOp_r_frm<bits<7> funct7, bits<5> rs2val, DAGOperand rdty,
+                      DAGOperand rs1ty, string opcodestr>
     : RVInstRFrm<funct7, OPC_OP_FP, (outs rdty:$rd),
                  (ins rs1ty:$rs1, frmarg:$frm), opcodestr,
                   "$rd, $rs1, $frm"> {
   let rs2 = rs2val;
 }
+multiclass FPUnaryOp_r_frm_m<bits<7> funct7, bits<5> rs2val,
+                             list<ExtInfo_rr> Exts, string opcodestr> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+    def Ext.Suffix : FPUnaryOp_r_frm<funct7, rs2val, Ext.RdTy, Ext.Rs1Ty,
+                                     opcodestr>;
+}
 
 class FPUnaryOpDynFrmAlias<FPUnaryOp_r_frm Inst, string OpcodeStr,
-                           RegisterClass rdty, RegisterClass rs1ty>
+                           DAGOperand rdty, DAGOperand rs1ty>
     : InstAlias<OpcodeStr#" $rd, $rs1",
                 (Inst rdty:$rd, rs1ty:$rs1, 0b111)>;
+multiclass FPUnaryOpDynFrmAlias_m<FPUnaryOp_r_frm Inst, string OpcodeStr,
+                                  list<ExtInfo_rr> Exts> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates in
+    def : FPUnaryOpDynFrmAlias<!cast<FPUnaryOp_r_frm>(Inst#Ext.Suffix),
+                               OpcodeStr, Ext.RdTy, Ext.Rs1Ty>;
+}
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
 class FPCmp_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
-               RegisterClass rty>
+               DAGOperand rty>
     : RVInstR<funct7, funct3, OPC_OP_FP, (outs GPR:$rd),
               (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+multiclass FPCmp_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr,
+                      list<ExtInfo_r> Exts> {
+  foreach Ext = Exts in
+    let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+    def Ext.Suffix : FPCmp_rr<funct7, funct3, opcodestr, Ext.Reg>;
+}
 
 //===----------------------------------------------------------------------===//
 // Instructions
@@ -162,101 +290,100 @@
 // reflecting the order these fields are specified in the instruction
 // encoding.
 def FSW : FPStore_r<0b010, "fsw", FPR32, WriteFST32>;
+} // Predicates = [HasStdExtF]
 
 let SchedRW = [WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32] in {
-def FMADD_S  : FPFMA_rrr_frm<OPC_MADD,  0b00, "fmadd.s",  FPR32>;
-def FMSUB_S  : FPFMA_rrr_frm<OPC_MSUB,  0b00, "fmsub.s",  FPR32>;
-def FNMSUB_S : FPFMA_rrr_frm<OPC_NMSUB, 0b00, "fnmsub.s", FPR32>;
-def FNMADD_S : FPFMA_rrr_frm<OPC_NMADD, 0b00, "fnmadd.s", FPR32>;
+defm FMADD_S  : FPFMA_rrr_frm_m<OPC_MADD,  0b00, "fmadd.s",  FINX>;
+defm FMSUB_S  : FPFMA_rrr_frm_m<OPC_MSUB,  0b00, "fmsub.s",  FINX>;
+defm FNMSUB_S : FPFMA_rrr_frm_m<OPC_NMSUB, 0b00, "fnmsub.s", FINX>;
+defm FNMADD_S : FPFMA_rrr_frm_m<OPC_NMADD, 0b00, "fnmadd.s", FINX>;
+}
+
+defm : FPFMADynFrmAlias_m<FMADD_S,  "fmadd.s",  FINX>;
+defm : FPFMADynFrmAlias_m<FMSUB_S,  "fmsub.s",  FINX>;
+defm : FPFMADynFrmAlias_m<FNMSUB_S, "fnmsub.s", FINX>;
+defm : FPFMADynFrmAlias_m<FNMADD_S, "fnmadd.s", FINX>;
+
+let SchedRW = [WriteFALU32, ReadFALU32, ReadFALU32] in {
+defm FADD_S : FPALU_rr_frm_m<0b0000000, "fadd.s", FINX>;
+defm FSUB_S : FPALU_rr_frm_m<0b0000100, "fsub.s", FINX>;
 }
+let SchedRW = [WriteFMul32, ReadFMul32, ReadFMul32] in
+defm FMUL_S : FPALU_rr_frm_m<0b0001000, "fmul.s", FINX>;
 
-def : FPFMADynFrmAlias<FMADD_S,  "fmadd.s",  FPR32>;
-def : FPFMADynFrmAlias<FMSUB_S,  "fmsub.s",  FPR32>;
-def : FPFMADynFrmAlias<FNMSUB_S, "fnmsub.s", FPR32>;
-def : FPFMADynFrmAlias<FNMADD_S, "fnmadd.s", FPR32>;
-
-def FADD_S : FPALU_rr_frm<0b0000000, "fadd.s", FPR32>,
-             Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>;
-def FSUB_S : FPALU_rr_frm<0b0000100, "fsub.s", FPR32>,
-             Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>;
-def FMUL_S : FPALU_rr_frm<0b0001000, "fmul.s", FPR32>,
-             Sched<[WriteFMul32, ReadFMul32, ReadFMul32]>;
-def FDIV_S : FPALU_rr_frm<0b0001100, "fdiv.s", FPR32>,
-             Sched<[WriteFDiv32, ReadFDiv32, ReadFDiv32]>;
-
-def        : FPALUDynFrmAlias<FADD_S, "fadd.s", FPR32>;
-def        : FPALUDynFrmAlias<FSUB_S, "fsub.s", FPR32>;
-def        : FPALUDynFrmAlias<FMUL_S, "fmul.s", FPR32>;
-def        : FPALUDynFrmAlias<FDIV_S, "fdiv.s", FPR32>;
-
-def FSQRT_S : FPUnaryOp_r_frm<0b0101100, 0b00000, FPR32, FPR32, "fsqrt.s">,
-              Sched<[WriteFSqrt32, ReadFSqrt32]>;
-def         : FPUnaryOpDynFrmAlias<FSQRT_S, "fsqrt.s", FPR32, FPR32>;
+let SchedRW = [WriteFDiv32, ReadFDiv32, ReadFDiv32] in
+defm FDIV_S : FPALU_rr_frm_m<0b0001100, "fdiv.s", FINX>;
+
+defm : FPALUDynFrmAlias_m<FADD_S, "fadd.s", FINX>;
+defm : FPALUDynFrmAlias_m<FSUB_S, "fsub.s", FINX>;
+defm : FPALUDynFrmAlias_m<FMUL_S, "fmul.s", FINX>;
+defm : FPALUDynFrmAlias_m<FDIV_S, "fdiv.s", FINX>;
+
+defm FSQRT_S : FPUnaryOp_r_frm_m<0b0101100, 0b00000, FFINX, "fsqrt.s">,
+               Sched<[WriteFSqrt32, ReadFSqrt32]>;
+defm         : FPUnaryOpDynFrmAlias_m<FSQRT_S, "fsqrt.s", FFINX>;
 
 let SchedRW = [WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32],
     mayRaiseFPException = 0 in {
-def FSGNJ_S  : FPALU_rr<0b0010000, 0b000, "fsgnj.s", FPR32>;
-def FSGNJN_S : FPALU_rr<0b0010000, 0b001, "fsgnjn.s", FPR32>;
-def FSGNJX_S : FPALU_rr<0b0010000, 0b010, "fsgnjx.s", FPR32>;
+defm FSGNJ_S  : FPALU_rr_m<0b0010000, 0b000, "fsgnj.s",  FINX>;
+defm FSGNJN_S : FPALU_rr_m<0b0010000, 0b001, "fsgnjn.s", FINX>;
+defm FSGNJX_S : FPALU_rr_m<0b0010000, 0b010, "fsgnjx.s", FINX>;
 }
 
 let SchedRW = [WriteFMinMax32, ReadFMinMax32, ReadFMinMax32] in {
-def FMIN_S   : FPALU_rr<0b0010100, 0b000, "fmin.s", FPR32>;
-def FMAX_S   : FPALU_rr<0b0010100, 0b001, "fmax.s", FPR32>;
+defm FMIN_S   : FPALU_rr_m<0b0010100, 0b000, "fmin.s", FINX>;
+defm FMAX_S   : FPALU_rr_m<0b0010100, 0b001, "fmax.s", FINX>;
 }
 
-def FCVT_W_S : FPUnaryOp_r_frm<0b1100000, 0b00000, GPR, FPR32, "fcvt.w.s">,
-               Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_W_S, "fcvt.w.s", GPR, FPR32>;
-
-def FCVT_WU_S : FPUnaryOp_r_frm<0b1100000, 0b00001, GPR, FPR32, "fcvt.wu.s">,
+defm FCVT_W_S : FPUnaryOp_r_frm_m<0b1100000, 0b00000, XFINX, "fcvt.w.s">,
                 Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_WU_S, "fcvt.wu.s", GPR, FPR32>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_W_S, "fcvt.w.s", XFINX>;
+
+defm FCVT_WU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00001, XFINX, "fcvt.wu.s">,
+                 Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_WU_S, "fcvt.wu.s", XFINX>;
 
 let mayRaiseFPException = 0 in
 def FMV_X_W : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR32, "fmv.x.w">,
               Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>;
 
 let SchedRW = [WriteFCmp32, ReadFCmp32, ReadFCmp32] in {
-def FEQ_S : FPCmp_rr<0b1010000, 0b010, "feq.s", FPR32>;
-def FLT_S : FPCmp_rr<0b1010000, 0b001, "flt.s", FPR32>;
-def FLE_S : FPCmp_rr<0b1010000, 0b000, "fle.s", FPR32>;
+defm FEQ_S : FPCmp_rr_m<0b1010000, 0b010, "feq.s", FINX>;
+defm FLT_S : FPCmp_rr_m<0b1010000, 0b001, "flt.s", FINX>;
+defm FLE_S : FPCmp_rr_m<0b1010000, 0b000, "fle.s", FINX>;
 }
 
 let mayRaiseFPException = 0 in
-def FCLASS_S : FPUnaryOp_r<0b1110000, 0b00000, 0b001, GPR, FPR32, "fclass.s">,
-               Sched<[WriteFClass32, ReadFClass32]>;
-
-def FCVT_S_W : FPUnaryOp_r_frm<0b1101000, 0b00000, FPR32, GPR, "fcvt.s.w">,
-               Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_S_W, "fcvt.s.w", FPR32, GPR>;
+defm FCLASS_S : FPUnaryOp_r_m<0b1110000, 0b00000, 0b001, XFINX, "fclass.s">,
+                Sched<[WriteFClass32, ReadFClass32]>;
 
-def FCVT_S_WU : FPUnaryOp_r_frm<0b1101000, 0b00001, FPR32, GPR, "fcvt.s.wu">,
+defm FCVT_S_W : FPUnaryOp_r_frm_m<0b1101000, 0b00000, FXINX, "fcvt.s.w">,
                 Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_S_WU, "fcvt.s.wu", FPR32, GPR>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_S_W, "fcvt.s.w", FXINX>;
+
+defm FCVT_S_WU : FPUnaryOp_r_frm_m<0b1101000, 0b00001, FXINX, "fcvt.s.wu">,
+                 Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_S_WU, "fcvt.s.wu", FXINX>;
 
 let mayRaiseFPException = 0 in
 def FMV_W_X : FPUnaryOp_r<0b1111000, 0b00000, 0b000, FPR32, GPR, "fmv.w.x">,
               Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>;
-} // Predicates = [HasStdExtF]
 
-let Predicates = [HasStdExtF, IsRV64] in {
-def FCVT_L_S  : FPUnaryOp_r_frm<0b1100000, 0b00010, GPR, FPR32, "fcvt.l.s">,
-                Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_L_S, "fcvt.l.s", GPR, FPR32>;
-
-def FCVT_LU_S  : FPUnaryOp_r_frm<0b1100000, 0b00011, GPR, FPR32, "fcvt.lu.s">,
+defm FCVT_L_S  : FPUnaryOp_r_frm_m<0b1100000, 0b00010, XFIN64X, "fcvt.l.s">,
                  Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>;
-def            : FPUnaryOpDynFrmAlias<FCVT_LU_S, "fcvt.lu.s", GPR, FPR32>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_L_S, "fcvt.l.s", XFIN64X>;
 
-def FCVT_S_L : FPUnaryOp_r_frm<0b1101000, 0b00010, FPR32, GPR, "fcvt.s.l">,
-               Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_S_L, "fcvt.s.l", FPR32, GPR>;
+defm FCVT_LU_S  : FPUnaryOp_r_frm_m<0b1100000, 0b00011, XFIN64X, "fcvt.lu.s">,
+                  Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>;
+defm            : FPUnaryOpDynFrmAlias_m<FCVT_LU_S, "fcvt.lu.s", XFIN64X>;
 
-def FCVT_S_LU : FPUnaryOp_r_frm<0b1101000, 0b00011, FPR32, GPR, "fcvt.s.lu">,
+defm FCVT_S_L : FPUnaryOp_r_frm_m<0b1101000, 0b00010, FXIN64X, "fcvt.s.l">,
                 Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_S_LU, "fcvt.s.lu", FPR32, GPR>;
-} // Predicates = [HasStdExtF, IsRV64]
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_S_L, "fcvt.s.l", FXIN64X>;
+
+defm FCVT_S_LU : FPUnaryOp_r_frm_m<0b1101000, 0b00011, FXIN64X, "fcvt.s.lu">,
+                 Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_S_LU, "fcvt.s.lu", FXIN64X>;
 
 //===----------------------------------------------------------------------===//
 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
@@ -315,6 +442,16 @@
 }
 } // Predicates = [HasStdExtF]
 
+let Predicates = [HasStdExtZfinx] in {
+def : InstAlias<"fabs.s $rd, $rs", (FSGNJX_S_INX FPR32INX:$rd, FPR32INX:$rs, FPR32INX:$rs)>;
+def : InstAlias<"fneg.s $rd, $rs", (FSGNJN_S_INX FPR32INX:$rd, FPR32INX:$rs, FPR32INX:$rs)>;
+
+def : InstAlias<"fgt.s $rd, $rs, $rt",
+                (FLT_S_INX GPR:$rd, FPR32INX:$rt, FPR32INX:$rs), 0>;
+def : InstAlias<"fge.s $rd, $rs, $rt",
+                (FLE_S_INX GPR:$rd, FPR32INX:$rt, FPR32INX:$rs), 0>;
+} // Predicates = [HasStdExtZfinx]
+
 //===----------------------------------------------------------------------===//
 // Pseudo-instructions and codegen patterns
 //===----------------------------------------------------------------------===//
Index: llvm/lib/Target/RISCV/RISCVInstrInfoD.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -25,6 +25,69 @@
 def RISCVBuildPairF64 : SDNode<"RISCVISD::BuildPairF64", SDT_RISCVBuildPairF64>;
 def RISCVSplitF64     : SDNode<"RISCVISD::SplitF64", SDT_RISCVSplitF64>;
 
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+// Zdinx
+
+def GPRPF64AsFPR : AsmOperandClass {
+  let Name = "GPRPF64AsFPR";
+  let ParserMethod = "parseGPRAsFPR";
+  let RenderMethod = "addRegOperands";
+}
+
+def GPRF64AsFPR : AsmOperandClass {
+  let Name = "GPRF64AsFPR";
+  let ParserMethod = "parseGPRAsFPR";
+  let RenderMethod = "addRegOperands";
+}
+
+def FPR64INX : RegisterOperand<GPRF64> {
+  let ParserMatchClass = GPRF64AsFPR;
+  let DecoderMethod = "DecodeGPRRegisterClass";
+}
+
+def FPR64IN32X : RegisterOperand<GPRPF64> {
+  let ParserMatchClass = GPRPF64AsFPR;
+}
+
+def DExt       : ExtInfo<0, [HasStdExtD]>;
+def D64Ext     : ExtInfo<0, [HasStdExtD, IsRV64]>;
+def ZdinxExt   : ExtInfo<1, [HasStdExtZdinx, IsRV64]>;
+def Zdinx32Ext : ExtInfo<2, [HasStdExtZdinx, IsRV32]>;
+
+def D       : ExtInfo_r<DExt,       FPR64>;
+def D_INX   : ExtInfo_r<ZdinxExt,   FPR64INX>;
+def D_IN32X : ExtInfo_r<Zdinx32Ext, FPR64IN32X>;
+
+def DD       : ExtInfo_rr<DExt,       FPR64,      FPR64>;
+def DD_INX   : ExtInfo_rr<ZdinxExt,   FPR64INX,   FPR64INX>;
+def DD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR64IN32X>;
+def DF       : ExtInfo_rr<DExt,       FPR64,      FPR32>;
+def DF_INX   : ExtInfo_rr<ZdinxExt,   FPR64INX,   FPR32INX>;
+def DF_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR32INX>;
+def DX       : ExtInfo_rr<DExt,       FPR64,      GPR>;
+def DX_INX   : ExtInfo_rr<ZdinxExt,   FPR64INX,   GPR>;
+def DX_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, GPR>;
+def DX_64    : ExtInfo_rr<D64Ext,     FPR64,      GPR>;
+def FD       : ExtInfo_rr<DExt,       FPR32,      FPR64>;
+def FD_INX   : ExtInfo_rr<ZdinxExt,   FPR32INX,   FPR64INX>;
+def FD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR32INX,   FPR64IN32X>;
+def XD       : ExtInfo_rr<DExt,       GPR,        FPR64>;
+def XD_INX   : ExtInfo_rr<ZdinxExt,   GPR,        FPR64INX>;
+def XD_IN32X : ExtInfo_rr<Zdinx32Ext, GPR,        FPR64IN32X>;
+def XD_64    : ExtInfo_rr<D64Ext,     GPR,        FPR64>;
+
+defvar DINX    = [D,  D_INX,  D_IN32X];
+defvar DDINX   = [DD, DD_INX, DD_IN32X];
+defvar DXINX   = [DX, DX_INX, DX_IN32X];
+defvar DFINX   = [DF, DF_INX, DF_IN32X];
+defvar FDINX   = [FD, FD_INX, FD_IN32X];
+defvar XDINX   = [XD, XD_INX, XD_IN32X];
+defvar DXIN64X = [DX_64, DX_INX];
+defvar XDIN64X = [XD_64, XD_INX];
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -36,106 +99,104 @@
 // reflecting the order these fields are specified in the instruction
 // encoding.
 def FSD : FPStore_r<0b011, "fsd", FPR64, WriteFST64>;
+} // Predicates = [HasStdExtD]
 
 let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in {
-def FMADD_D  : FPFMA_rrr_frm<OPC_MADD,  0b01, "fmadd.d",  FPR64>;
-def FMSUB_D  : FPFMA_rrr_frm<OPC_MSUB,  0b01, "fmsub.d",  FPR64>;
-def FNMSUB_D : FPFMA_rrr_frm<OPC_NMSUB, 0b01, "fnmsub.d", FPR64>;
-def FNMADD_D : FPFMA_rrr_frm<OPC_NMADD, 0b01, "fnmadd.d", FPR64>;
+defm FMADD_D  : FPFMA_rrr_frm_m<OPC_MADD,  0b01, "fmadd.d",  DINX>;
+defm FMSUB_D  : FPFMA_rrr_frm_m<OPC_MSUB,  0b01, "fmsub.d",  DINX>;
+defm FNMSUB_D : FPFMA_rrr_frm_m<OPC_NMSUB, 0b01, "fnmsub.d", DINX>;
+defm FNMADD_D : FPFMA_rrr_frm_m<OPC_NMADD, 0b01, "fnmadd.d", DINX>;
+}
+
+defm : FPFMADynFrmAlias_m<FMADD_D,  "fmadd.d",  DINX>;
+defm : FPFMADynFrmAlias_m<FMSUB_D,  "fmsub.d",  DINX>;
+defm : FPFMADynFrmAlias_m<FNMSUB_D, "fnmsub.d", DINX>;
+defm : FPFMADynFrmAlias_m<FNMADD_D, "fnmadd.d", DINX>;
+
+let SchedRW = [WriteFALU64, ReadFALU64, ReadFALU64] in {
+defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", DINX>;
+defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", DINX>;
 }
+let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in
+defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", DINX>;
 
-def : FPFMADynFrmAlias<FMADD_D,  "fmadd.d",  FPR64>;
-def : FPFMADynFrmAlias<FMSUB_D,  "fmsub.d",  FPR64>;
-def : FPFMADynFrmAlias<FNMSUB_D, "fnmsub.d", FPR64>;
-def : FPFMADynFrmAlias<FNMADD_D, "fnmadd.d", FPR64>;
-
-def FADD_D : FPALU_rr_frm<0b0000001, "fadd.d", FPR64>,
-             Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>;
-def FSUB_D : FPALU_rr_frm<0b0000101, "fsub.d", FPR64>,
-             Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>;
-def FMUL_D : FPALU_rr_frm<0b0001001, "fmul.d", FPR64>,
-             Sched<[WriteFMul64, ReadFMul64, ReadFMul64]>;
-def FDIV_D : FPALU_rr_frm<0b0001101, "fdiv.d", FPR64>,
-             Sched<[WriteFDiv64, ReadFDiv64, ReadFDiv64]>;
-
-def        : FPALUDynFrmAlias<FADD_D, "fadd.d", FPR64>;
-def        : FPALUDynFrmAlias<FSUB_D, "fsub.d", FPR64>;
-def        : FPALUDynFrmAlias<FMUL_D, "fmul.d", FPR64>;
-def        : FPALUDynFrmAlias<FDIV_D, "fdiv.d", FPR64>;
-
-def FSQRT_D : FPUnaryOp_r_frm<0b0101101, 0b00000, FPR64, FPR64, "fsqrt.d">,
-              Sched<[WriteFSqrt64, ReadFSqrt64]>;
-def         : FPUnaryOpDynFrmAlias<FSQRT_D, "fsqrt.d", FPR64, FPR64>;
+let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in
+defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", DINX>;
+
+defm : FPALUDynFrmAlias_m<FADD_D, "fadd.d", DINX>;
+defm : FPALUDynFrmAlias_m<FSUB_D, "fsub.d", DINX>;
+defm : FPALUDynFrmAlias_m<FMUL_D, "fmul.d", DINX>;
+defm : FPALUDynFrmAlias_m<FDIV_D, "fdiv.d", DINX>;
+
+defm FSQRT_D : FPUnaryOp_r_frm_m<0b0101101, 0b00000, DDINX, "fsqrt.d">,
+               Sched<[WriteFSqrt64, ReadFSqrt64]>;
+defm         : FPUnaryOpDynFrmAlias_m<FSQRT_D, "fsqrt.d", DDINX>;
 
 let SchedRW = [WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64],
     mayRaiseFPException = 0 in {
-def FSGNJ_D  : FPALU_rr<0b0010001, 0b000, "fsgnj.d", FPR64>;
-def FSGNJN_D : FPALU_rr<0b0010001, 0b001, "fsgnjn.d", FPR64>;
-def FSGNJX_D : FPALU_rr<0b0010001, 0b010, "fsgnjx.d", FPR64>;
+defm FSGNJ_D  : FPALU_rr_m<0b0010001, 0b000, "fsgnj.d",  DINX>;
+defm FSGNJN_D : FPALU_rr_m<0b0010001, 0b001, "fsgnjn.d", DINX>;
+defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", DINX>;
 }
 
 let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
-def FMIN_D   : FPALU_rr<0b0010101, 0b000, "fmin.d", FPR64>;
-def FMAX_D   : FPALU_rr<0b0010101, 0b001, "fmax.d", FPR64>;
+defm FMIN_D   : FPALU_rr_m<0b0010101, 0b000, "fmin.d", DINX>;
+defm FMAX_D   : FPALU_rr_m<0b0010101, 0b001, "fmax.d", DINX>;
 }
 
-def FCVT_S_D : FPUnaryOp_r_frm<0b0100000, 0b00001, FPR32, FPR64, "fcvt.s.d">,
-               Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_S_D, "fcvt.s.d", FPR32, FPR64>;
+defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, FDINX, "fcvt.s.d">,
+                Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_S_D, "fcvt.s.d", FDINX>;
 
-def FCVT_D_S : FPUnaryOp_r<0b0100001, 0b00000, 0b000, FPR64, FPR32, "fcvt.d.s">,
-               Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
+defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, DFINX, "fcvt.d.s">,
+                Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
 
 let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
-def FEQ_D : FPCmp_rr<0b1010001, 0b010, "feq.d", FPR64>;
-def FLT_D : FPCmp_rr<0b1010001, 0b001, "flt.d", FPR64>;
-def FLE_D : FPCmp_rr<0b1010001, 0b000, "fle.d", FPR64>;
+defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", DINX>;
+defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", DINX>;
+defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", DINX>;
 }
 
-let mayRaiseFPException = 0 in
-def FCLASS_D : FPUnaryOp_r<0b1110001, 0b00000, 0b001, GPR, FPR64, "fclass.d">,
-               Sched<[WriteFClass64, ReadFClass64]>;
+defm FCLASS_D : FPUnaryOp_r_m<0b1110001, 0b00000, 0b001, XDINX, "fclass.d">,
+                Sched<[WriteFClass64, ReadFClass64]>;
 
-def FCVT_W_D : FPUnaryOp_r_frm<0b1100001, 0b00000, GPR, FPR64, "fcvt.w.d">,
+defm FCVT_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b00000, XDINX, "fcvt.w.d">,
                Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_W_D, "fcvt.w.d", GPR, FPR64>;
-
-def FCVT_WU_D : FPUnaryOp_r_frm<0b1100001, 0b00001, GPR, FPR64, "fcvt.wu.d">,
-                Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_WU_D, "fcvt.wu.d", GPR, FPR64>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_W_D, "fcvt.w.d", XDINX>;
 
-def FCVT_D_W : FPUnaryOp_r<0b1101001, 0b00000, 0b000, FPR64, GPR, "fcvt.d.w">,
-               Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
+defm FCVT_WU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00001, XDINX, "fcvt.wu.d">,
+                 Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_WU_D, "fcvt.wu.d", XDINX>;
 
-def FCVT_D_WU : FPUnaryOp_r<0b1101001, 0b00001, 0b000, FPR64, GPR, "fcvt.d.wu">,
+defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, DXINX, "fcvt.d.w">,
                 Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
-} // Predicates = [HasStdExtD]
 
-let Predicates = [HasStdExtD, IsRV64] in {
-def FCVT_L_D : FPUnaryOp_r_frm<0b1100001, 0b00010, GPR, FPR64, "fcvt.l.d">,
-               Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_L_D, "fcvt.l.d", GPR, FPR64>;
+defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, DXINX, "fcvt.d.wu">,
+                 Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
 
-def FCVT_LU_D : FPUnaryOp_r_frm<0b1100001, 0b00011, GPR, FPR64, "fcvt.lu.d">,
+defm FCVT_L_D : FPUnaryOp_r_frm_m<0b1100001, 0b00010, XDIN64X, "fcvt.l.d">,
                 Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_LU_D, "fcvt.lu.d", GPR, FPR64>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_L_D, "fcvt.l.d", XDIN64X>;
 
-let mayRaiseFPException = 0 in
+defm FCVT_LU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00011, XDIN64X, "fcvt.lu.d">,
+                 Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_LU_D, "fcvt.lu.d", XDIN64X>;
+
+let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
 def FMV_X_D : FPUnaryOp_r<0b1110001, 0b00000, 0b000, GPR, FPR64, "fmv.x.d">,
               Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]>;
 
-def FCVT_D_L : FPUnaryOp_r_frm<0b1101001, 0b00010, FPR64, GPR, "fcvt.d.l">,
-               Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
-def          : FPUnaryOpDynFrmAlias<FCVT_D_L, "fcvt.d.l", FPR64, GPR>;
-
-def FCVT_D_LU : FPUnaryOp_r_frm<0b1101001, 0b00011, FPR64, GPR, "fcvt.d.lu">,
+defm FCVT_D_L : FPUnaryOp_r_frm_m<0b1101001, 0b00010, DXIN64X, "fcvt.d.l">,
                 Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
-def           : FPUnaryOpDynFrmAlias<FCVT_D_LU, "fcvt.d.lu", FPR64, GPR>;
+defm          : FPUnaryOpDynFrmAlias_m<FCVT_D_L, "fcvt.d.l", DXIN64X>;
 
-let mayRaiseFPException = 0 in
+defm FCVT_D_LU : FPUnaryOp_r_frm_m<0b1101001, 0b00011, DXIN64X, "fcvt.d.lu">,
+                 Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
+defm           : FPUnaryOpDynFrmAlias_m<FCVT_D_LU, "fcvt.d.lu", DXIN64X>;
+
+let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
 def FMV_D_X : FPUnaryOp_r<0b1111001, 0b00000, 0b000, FPR64, GPR, "fmv.d.x">,
               Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]>;
-} // Predicates = [HasStdExtD, IsRV64]
 
 //===----------------------------------------------------------------------===//
 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
@@ -164,6 +225,26 @@
 }
 } // Predicates = [HasStdExtD]
 
+let Predicates = [HasStdExtZdinx, IsRV64] in {
+def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_INX FPR64INX:$rd, FPR64INX:$rs, FPR64INX:$rs)>;
+def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_INX FPR64INX:$rd, FPR64INX:$rs, FPR64INX:$rs)>;
+
+def : InstAlias<"fgt.d $rd, $rs, $rt",
+                (FLT_D_INX GPR:$rd, FPR64INX:$rt, FPR64INX:$rs), 0>;
+def : InstAlias<"fge.d $rd, $rs, $rt",
+                (FLE_D_INX GPR:$rd, FPR64INX:$rt, FPR64INX:$rs), 0>;
+} // Predicates = [HasStdExtZdinx, IsRV64]
+
+let Predicates = [HasStdExtZdinx, IsRV32] in {
+def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_IN32X FPR64IN32X:$rd, FPR64IN32X:$rs, FPR64IN32X:$rs)>;
+def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_IN32X FPR64IN32X:$rd, FPR64IN32X:$rs, FPR64IN32X:$rs)>;
+
+def : InstAlias<"fgt.d $rd, $rs, $rt",
+                (FLT_D_IN32X GPR:$rd, FPR64IN32X:$rt, FPR64IN32X:$rs), 0>;
+def : InstAlias<"fge.d $rd, $rs, $rt",
+                (FLE_D_IN32X GPR:$rd, FPR64IN32X:$rt, FPR64IN32X:$rs), 0>;
+} // Predicates = [HasStdExtZdinx, IsRV32]
+
 //===----------------------------------------------------------------------===//
 // Pseudo-instructions and codegen patterns
 //===----------------------------------------------------------------------===//
Index: llvm/lib/Target/RISCV/RISCV.td
===================================================================
--- llvm/lib/Target/RISCV/RISCV.td
+++ llvm/lib/Target/RISCV/RISCV.td
@@ -57,6 +57,37 @@
                              AssemblerPredicate<(all_of FeatureStdExtZfh),
                              "'Zfh' (Half-Precision Floating-Point)">;
 
+def FeatureStdExtZfinx
+    : SubtargetFeature<"zfinx", "HasStdExtZfinx", "true",
+                       "'Zfinx' (Float in Integer)">;
+def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">,
+                               AssemblerPredicate<(all_of FeatureStdExtZfinx),
+                               "'Zfinx' (Float in Integer)">;
+
+def FeatureStdExtZdinx
+    : SubtargetFeature<"zdinx", "HasStdExtZdinx", "true",
+                       "'Zdinx' (Double in Integer)",
+                       [FeatureStdExtZfinx]>;
+def HasStdExtZdinx : Predicate<"Subtarget->hasStdExtZdinx()">,
+                               AssemblerPredicate<(all_of FeatureStdExtZdinx),
+                               "'Zdinx' (Double in Integer)">;
+
+def FeatureStdExtZhinxmin
+    : SubtargetFeature<"zhinxmin", "HasStdExtZhinxmin", "true",
+                       "'Zhinxmin' (Half Float in Integer Minimal)",
+                       [FeatureStdExtZfinx]>;
+def HasStdExtZhinxmin : Predicate<"Subtarget->hasStdExtZhinxmin()">,
+                                  AssemblerPredicate<(all_of FeatureStdExtZhinxmin),
+                                  "'Zhinxmin' (Half Float in Integer Minimal)">;
+
+def FeatureStdExtZhinx
+    : SubtargetFeature<"zhinx", "HasStdExtZhinx", "true",
+                       "'Zhinx' (Half Float in Integer)",
+                       [FeatureStdExtZhinxmin]>;
+def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">,
+                               AssemblerPredicate<(all_of FeatureStdExtZhinx),
+                               "'Zhinx' (Half Float in Integer)">;
+
 def FeatureStdExtC
     : SubtargetFeature<"c", "HasStdExtC", "true",
                        "'C' (Compressed Instructions)">;
Index: llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
===================================================================
--- llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -161,6 +161,17 @@
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo,
+                                               uint64_t Address,
+                                               const void *Decoder) {
+  if (RegNo >= 32 || RegNo & 1)
+    return MCDisassembler::Fail;
+
+  MCRegister Reg = RISCV::X0 + RegNo;
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
                                           uint64_t Address,
                                           const void *Decoder) {
@@ -427,6 +438,27 @@
       return MCDisassembler::Fail;
     }
     Insn = support::endian::read32le(Bytes.data());
+    if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] &&
+        !STI.getFeatureBits()[RISCV::Feature64Bit]) {
+      LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and"
+                           "rv32)\n");
+      Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address,
+                                 this, STI);
+      if (Result != MCDisassembler::Fail) {
+        Size = 4;
+        return Result;
+      }
+    }
+
+    if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) {
+      LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n");
+      Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this,
+                                 STI);
+      if (Result != MCDisassembler::Fail) {
+        Size = 4;
+        return Result;
+      }
+    }
     LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
     Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
     Size = 4;
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -170,6 +170,7 @@
   OperandMatchResultTy parseVTypeI(OperandVector &Operands);
   OperandMatchResultTy parseMaskReg(OperandVector &Operands);
   OperandMatchResultTy parseInsnDirectiveOpcode(OperandVector &Operands);
+  OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands);
 
   bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
 
@@ -273,6 +274,8 @@
 
   bool IsRV64;
 
+  bool IsGPRAsFPR;
+
   struct RegOp {
     MCRegister RegNum;
   };
@@ -343,6 +346,14 @@
            RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
   }
 
+  bool isGPRAsFPR() const { return isGPR() && IsGPRAsFPR; }
+
+  bool isGPRF64AsFPR() const { return isGPR() && IsGPRAsFPR && IsRV64; }
+
+  bool isGPRPF64AsFPR() const {
+    return isGPR() && IsGPRAsFPR && !IsRV64 && !((Reg.RegNum - RISCV::X0) & 1);
+  }
+
   static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
                                   RISCVMCExpr::VariantKind &VK) {
     if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
@@ -821,12 +832,14 @@
   }
 
   static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
-                                                 SMLoc E, bool IsRV64) {
+                                                 SMLoc E, bool IsRV64,
+                                                 bool IsGPRAsFPR = false) {
     auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
     Op->Reg.RegNum = RegNo;
     Op->StartLoc = S;
     Op->EndLoc = E;
     Op->IsRV64 = IsRV64;
+    Op->IsGPRAsFPR = IsGPRAsFPR;
     return Op;
   }
 
@@ -1767,6 +1780,26 @@
   return MatchOperand_Success;
 }
 
+OperandMatchResultTy RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
+  switch (getLexer().getKind()) {
+  default:
+    return MatchOperand_NoMatch;
+  case AsmToken::Identifier:
+    StringRef Name = getLexer().getTok().getIdentifier();
+    MCRegister RegNo;
+    matchRegisterNameHelper(isRV32E(), RegNo, Name);
+
+    if (RegNo == RISCV::NoRegister)
+      return MatchOperand_NoMatch;
+    SMLoc S = getLoc();
+    SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
+    getLexer().Lex();
+    Operands.push_back(RISCVOperand::createReg(
+        RegNo, S, E, isRV64(), !getSTI().hasFeature(RISCV::FeatureStdExtF)));
+  }
+  return MatchOperand_Success;
+}
+
 OperandMatchResultTy
 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
   if (getLexer().isNot(AsmToken::LParen)) {
Index: llvm/lib/Support/RISCVISAInfo.cpp
===================================================================
--- llvm/lib/Support/RISCVISAInfo.cpp
+++ llvm/lib/Support/RISCVISAInfo.cpp
@@ -51,6 +51,11 @@
     {"zbb", RISCVExtensionVersion{1, 0}},
     {"zbc", RISCVExtensionVersion{1, 0}},
     {"zbs", RISCVExtensionVersion{1, 0}},
+
+    {"zfinx", RISCVExtensionVersion{1, 0}},
+    {"zdinx", RISCVExtensionVersion{1, 0}},
+    {"zhinxmin", RISCVExtensionVersion{1, 0}},
+    {"zhinx", RISCVExtensionVersion{1, 0}},
 };
 
 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
@@ -670,6 +675,9 @@
   bool HasE = Exts.count("e") == 1;
   bool HasD = Exts.count("d") == 1;
   bool HasF = Exts.count("f") == 1;
+  bool HasZdinx = Exts.count("zdinx") == 1;
+  bool HasZfinx = Exts.count("zfinx") == 1;
+  bool HasZhinxmin = Exts.count("zhinxmin") == 1;
 
   if (HasE && !IsRv32)
     return createStringError(
@@ -684,6 +692,15 @@
     return createStringError(errc::invalid_argument,
                              "d requires f extension to also be specified");
 
+  if (HasZdinx && !HasZfinx)
+    return createStringError(
+        errc::invalid_argument,
+        "Zdinx requires Zfinx extension to also be specified");
+  if (HasZhinxmin && !HasZfinx)
+    return createStringError(
+        errc::invalid_argument,
+        "Zhinxmin requires Zfinx extension to also be specified");
+
   // Additional dependency checks.
   // TODO: The 'q' extension requires rv64.
   // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'.
@@ -693,6 +710,7 @@
 
 static const char *ImpliedExtsV[] = {"zvlsseg"};
 static const char *ImpliedExtsZfh[] = {"zfhmin"};
+static const char *ImpliedExtsZhinx[] = {"zhinxmin"};
 
 struct ImpliedExtsEntry {
   StringLiteral Name;
@@ -708,6 +726,7 @@
 static constexpr ImpliedExtsEntry ImpliedExts[] = {
     {{"v"}, {ImpliedExtsV}},
     {{"zfh"}, {ImpliedExtsZfh}},
+    {{"zhinx"}, {ImpliedExtsZhinx}},
 };
 
 void RISCVISAInfo::updateImplication() {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to