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;
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)))
{
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 "";
}
}
+/* 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)
{
/* ------------------------------------------------------------------------ */
-/* 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);
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 *);
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 {