diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/nds32/nds32-md-auxiliary.c | 86 | ||||
-rw-r--r-- | gcc/config/nds32/nds32-protos.h | 9 |
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 { |