From 1766d186b66ee37ba1814c380fb98508b6df1ed8 Mon Sep 17 00:00:00 2001
From: wangtao <wangtao42@huawei.com>
Date: Mon, 27 Jul 2020 10:17:11 +0800
Subject: [PATCH] RISC-V: Add zfinx support.

	Tao Wang <wangtao42@huawei.com>
	Yingying Liu <liuyingying19@huawei.com>

	* common/config/riscv/riscv-common.c (riscv_parse_arch_string):
	  Add support to parse zfinx. Clear MASK_ZFINX for non-zfinx.
	* config/riscv/constraints.md: Add TARGET_ZFINX constraints.
	* config/riscv/riscv.c (riscv_compute_frame_info): When TARGET_ZFINX,
	  don't save FPRs.
	  (riscv_option_override): Call error when the abi doesn't match zfinx.
	  (riscv_conditional_register_usage): When TARGET_ZFINX, mark the FPRs
	  as fixed_regs.
	* config/riscv/riscv.opt: Add ZFINX mask.
---
 gcc/common/config/riscv/riscv-common.c | 4 ++++
 gcc/config/riscv/constraints.md        | 3 ++-
 gcc/config/riscv/riscv.c               | 9 +++++++--
 gcc/config/riscv/riscv.opt             | 2 ++
 4 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c
index 82c5154b6..7c980fd51 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -647,6 +647,10 @@ riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
   if (subset_list->lookup ("c"))
     *flags |= MASK_RVC;
 
+  *flags &= ~MASK_ZFINX;
+  if (subset_list->lookup ("zfinx"))
+    *flags |= MASK_ZFINX;
+
   if (current_subset_list)
     delete current_subset_list;
 
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index ef9c81e42..16e4e43bd 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -21,7 +21,8 @@
 
 ;; Register constraints
 
-(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
+(define_register_constraint "f"
+    "TARGET_HARD_FLOAT ? (TARGET_ZFINX ? GR_REGS : FP_REGS) : NO_REGS"
   "A floating-point register (if available).")
 
 (define_register_constraint "j" "SIBCALL_REGS"
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index bfb3885ed..78204d3da 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3734,7 +3734,7 @@ riscv_compute_frame_info (void)
 
       /* Find out which FPRs we need to save.  This loop must iterate over
 	 the same space as its companion in riscv_for_each_saved_reg.  */
-      if (TARGET_HARD_FLOAT)
+      if (TARGET_HARD_FLOAT && !TARGET_ZFINX)
 	for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
 	  if (riscv_save_reg_p (regno))
 	    frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++;
@@ -4746,6 +4746,11 @@ riscv_option_override (void)
   if (TARGET_RVE && riscv_abi != ABI_ILP32E)
     error ("rv32e requires ilp32e ABI");
 
+  /* Zfinx only supports floating-point arguments in X-registers.  */
+  if (TARGET_ZFINX && riscv_abi != ABI_ILP32 && riscv_abi != ABI_LP64
+      && riscv_abi != ABI_ILP32E)
+    error ("zfinx requires ilp32, lp64 or ilp32e ABI");
+
   /* We do not yet support ILP32 on RV64.  */
   if (BITS_PER_WORD != POINTER_SIZE)
     error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
@@ -4795,7 +4800,7 @@ riscv_conditional_register_usage (void)
 	call_used_regs[r] = 1;
     }
 
-  if (!TARGET_HARD_FLOAT)
+  if (!TARGET_HARD_FLOAT || TARGET_ZFINX)
     {
       for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
 	fixed_regs[regno] = call_used_regs[regno] = 1;
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index e4bfcb86f..3dce072d6 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -134,6 +134,8 @@ Mask(RVC)
 
 Mask(RVE)
 
+Mask(ZFINX)
+
 mriscv-attribute
 Target Report Var(riscv_emit_attribute_p) Init(-1)
 Emit RISC-V ELF attribute.
-- 
2.26.2

