[NDS32] Refine functions that deal with lwm and smw operations.
authorChung-Ju Wu <jasonwucj@gmail.com>
Sat, 19 May 2018 12:01:11 +0000 (12:01 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Sat, 19 May 2018 12:01:11 +0000 (12:01 +0000)
gcc/
* config/nds32/nds32-md-auxiliary.c
(nds32_valid_smw_lwm_base_p): Refine.
(nds32_output_smw_single_word): Refine.
(nds32_output_smw_double_word): New.
* config/nds32/nds32-protos.h (nds32_output_smw_double_word): New.

From-SVN: r260396

gcc/ChangeLog
gcc/config/nds32/nds32-md-auxiliary.c
gcc/config/nds32/nds32-protos.h

index 876a9568420fd71999092196b0f177db05c31010..6312e0282a48231ad5168de7166c387e0327d2a9 100644 (file)
@@ -1,3 +1,11 @@
+2018-05-19  Chung-Ju Wu  <jasonwucj@gmail.com>
+
+       * config/nds32/nds32-md-auxiliary.c
+       (nds32_valid_smw_lwm_base_p): Refine.
+       (nds32_output_smw_single_word): Refine.
+       (nds32_output_smw_double_word): New.
+       * config/nds32/nds32-protos.h (nds32_output_smw_double_word): New.
+
 2018-05-19  Chung-Ju Wu  <jasonwucj@gmail.com>
 
        * config/nds32/nds32-md-auxiliary.c (nds32_output_stack_push): Refine.
index 78079c6c868b51d03e40e3efac03fa4b2912a94c..3040bde9423ae3483b013100ad98f6325ba5da3d 100644 (file)
@@ -2446,33 +2446,51 @@ nds32_output_float_store (rtx *operands)
   return "";
 }
 
-
-/* Auxiliary functions for lwm/smw.  */
-bool
-nds32_valid_smw_lwm_base_p (rtx op)
+const char *
+nds32_output_smw_single_word (rtx *operands)
 {
-  rtx base_addr;
+  char buff[100];
+  unsigned regno;
+  int enable4;
+  bool update_base_p;
+  rtx base_addr = operands[0];
+  rtx base_reg;
+  rtx otherops[2];
 
-  if (!MEM_P (op))
-    return false;
+  if (REG_P (XEXP (base_addr, 0)))
+    {
+      update_base_p = false;
+      base_reg = XEXP (base_addr, 0);
+    }
+  else
+    {
+      update_base_p = true;
+      base_reg = XEXP (XEXP (base_addr, 0), 0);
+    }
 
-  base_addr = XEXP (op, 0);
+  const char *update_base = update_base_p ? "m" : "";
 
-  if (REG_P (base_addr))
-    return true;
+  regno = REGNO (operands[1]);
+
+  otherops[0] = base_reg;
+  otherops[1] = operands[1];
+
+  if (regno >= 28)
+    {
+      enable4 = nds32_regno_to_enable4 (regno);
+      sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4);
+    }
   else
     {
-      if (GET_CODE (base_addr) == POST_INC
-         && REG_P (XEXP (base_addr, 0)))
-        return true;
+      sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1", update_base);
     }
-
-  return false;
+  output_asm_insn (buff, otherops);
+  return "";
 }
 
 /* ------------------------------------------------------------------------ */
 const char *
-nds32_output_smw_single_word (rtx *operands)
+nds32_output_smw_double_word (rtx *operands)
 {
   char buff[100];
   unsigned regno;
@@ -2480,7 +2498,7 @@ nds32_output_smw_single_word (rtx *operands)
   bool update_base_p;
   rtx base_addr = operands[0];
   rtx base_reg;
-  rtx otherops[2];
+  rtx otherops[3];
 
   if (REG_P (XEXP (base_addr, 0)))
     {
@@ -2499,15 +2517,22 @@ nds32_output_smw_single_word (rtx *operands)
 
   otherops[0] = base_reg;
   otherops[1] = operands[1];
+  otherops[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);;
 
   if (regno >= 28)
     {
-      enable4 = nds32_regno_to_enable4 (regno);
+      enable4 = nds32_regno_to_enable4 (regno)
+               | nds32_regno_to_enable4 (regno + 1);
       sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4);
     }
+  else if (regno == 27)
+    {
+      enable4 = nds32_regno_to_enable4 (regno + 1);
+      sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1, %x", update_base, enable4);
+    }
   else
     {
-      sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1", update_base);
+      sprintf (buff, "smw.bi%s\t%%1, [%%0], %%2", update_base);
     }
   output_asm_insn (buff, otherops);
   return "";
@@ -3774,6 +3799,29 @@ nds32_expand_constant (machine_mode mode, HOST_WIDE_INT val,
     }
 }
 
+/* Auxiliary functions for lwm/smw.  */
+bool
+nds32_valid_smw_lwm_base_p (rtx op)
+{
+  rtx base_addr;
+
+  if (!MEM_P (op))
+    return false;
+
+  base_addr = XEXP (op, 0);
+
+  if (REG_P (base_addr))
+    return true;
+  else
+    {
+      if (GET_CODE (base_addr) == POST_INC
+         && REG_P (XEXP (base_addr, 0)))
+       return true;
+    }
+
+  return false;
+}
+
 /* Auxiliary functions for manipulation DI mode.  */
 rtx nds32_di_high_part_subreg(rtx reg)
 {
index 55988d5910f0e34d86aa37809d6ea75fa8af3b0a..9b8b8fa09a54a0ec15aad7113fb1fca885b44099 100644 (file)
@@ -69,10 +69,6 @@ extern unsigned int nds32_dbx_register_number (unsigned int);
 
 /* ------------------------------------------------------------------------ */
 
-/* Auxiliary functions for lwm/smw.  */
-
-extern bool nds32_valid_smw_lwm_base_p (rtx);
-
 /* Auxiliary functions for manipulation DI mode.  */
 
 extern rtx nds32_di_high_part_subreg(rtx);
@@ -246,6 +242,7 @@ extern const char *nds32_output_32bit_load_s (rtx *, int);
 extern const char *nds32_output_float_load(rtx *);
 extern const char *nds32_output_float_store(rtx *);
 extern const char *nds32_output_smw_single_word (rtx *);
+extern const char *nds32_output_smw_double_word (rtx *);
 extern const char *nds32_output_lmw_single_word (rtx *);
 extern const char *nds32_output_double (rtx *, bool);
 extern const char *nds32_output_cbranchsi4_equality_zero (rtx_insn *, rtx *);
@@ -328,6 +325,10 @@ extern bool nds32_valid_CVs5_p (rtx);
 extern bool nds32_valid_CVs2_p (rtx);
 extern bool nds32_valid_CVhi_p (rtx);
 
+/* Auxiliary functions for lwm/smw.  */
+
+extern bool nds32_valid_smw_lwm_base_p (rtx);
+
 extern bool nds32_split_double_word_load_store_p (rtx *,bool);
 
 namespace nds32 {