aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/nds32/nds32-md-auxiliary.c86
-rw-r--r--gcc/config/nds32/nds32-protos.h9
2 files changed, 72 insertions, 23 deletions
diff --git a/gcc/config/nds32/nds32-md-auxiliary.c b/gcc/config/nds32/nds32-md-auxiliary.c
index 78079c6..3040bde 100644
--- a/gcc/config/nds32/nds32-md-auxiliary.c
+++ b/gcc/config/nds32/nds32-md-auxiliary.c
@@ -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)
{
diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h
index 55988d5..9b8b8fa 100644
--- a/gcc/config/nds32/nds32-protos.h
+++ b/gcc/config/nds32/nds32-protos.h
@@ -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 {