diff options
author | Kito Cheng <kito.cheng@gmail.com> | 2018-05-13 17:18:31 +0000 |
---|---|---|
committer | Chung-Ju Wu <jasonwucj@gcc.gnu.org> | 2018-05-13 17:18:31 +0000 |
commit | 628332f85dbcd0996f68afae47b2b6d134b7b268 (patch) | |
tree | a4bd00a917a25d12539d210f62bf9a352b0cd943 /gcc/config/nds32/nds32-utils.c | |
parent | 58148bb64960dc5b0e421de8f6d4a4a5cbed9fe2 (diff) | |
download | gcc-628332f85dbcd0996f68afae47b2b6d134b7b268.zip gcc-628332f85dbcd0996f68afae47b2b6d134b7b268.tar.gz gcc-628332f85dbcd0996f68afae47b2b6d134b7b268.tar.bz2 |
[NDS32] Implment n15 pipeline.
gcc/
* config.gcc (nds32*-*-*): Check that n15 is valid to --with-cpu.
* config/nds32/nds32-graywolf.md: New file.
* config/nds32/nds32-opts.h (nds32_cpu_type): Add CPU_GRAYWOLF.
* config/nds32/nds32-pipelines-auxiliary.c: Implementation for n15
pipeline.
* config/nds32/nds32-protos.h: More declarations for n15 pipeline.
* config/nds32/nds32-utils.c: More implementations for n15 pipeline.
* config/nds32/nds32.md (pipeline_model): Add graywolf.
* config/nds32/nds32.opt (mcpu): Support n15 pipeline cpus.
* config/nds32/pipelines.md: Include n15 settings.
Co-Authored-By: Chung-Ju Wu <jasonwucj@gmail.com>
From-SVN: r260214
Diffstat (limited to 'gcc/config/nds32/nds32-utils.c')
-rw-r--r-- | gcc/config/nds32/nds32-utils.c | 121 |
1 files changed, 115 insertions, 6 deletions
diff --git a/gcc/config/nds32/nds32-utils.c b/gcc/config/nds32/nds32-utils.c index 6c93774..7c93cd2 100644 --- a/gcc/config/nds32/nds32-utils.c +++ b/gcc/config/nds32/nds32-utils.c @@ -142,6 +142,23 @@ store_double_p (rtx_insn *insn) return true; } +bool +store_offset_reg_p (rtx_insn *insn) +{ + if (get_attr_type (insn) != TYPE_STORE) + return false; + + rtx offset_rtx = extract_offset_rtx (insn); + + if (offset_rtx == NULL_RTX) + return false; + + if (REG_P (offset_rtx)) + return true; + + return false; +} + /* Determine if INSN is a post update insn. */ bool post_update_insn_p (rtx_insn *insn) @@ -316,22 +333,114 @@ extract_base_reg (rtx_insn *insn) if (REG_P (XEXP (mem_rtx, 0))) return XEXP (mem_rtx, 0); + /* (mem (lo_sum (reg) (symbol_ref)) */ + if (GET_CODE (XEXP (mem_rtx, 0)) == LO_SUM) + return XEXP (XEXP (mem_rtx, 0), 0); + plus_rtx = XEXP (mem_rtx, 0); if (GET_CODE (plus_rtx) == SYMBOL_REF || GET_CODE (plus_rtx) == CONST) return NULL_RTX; - gcc_assert (GET_CODE (plus_rtx) == PLUS - || GET_CODE (plus_rtx) == POST_INC - || GET_CODE (plus_rtx) == POST_DEC - || GET_CODE (plus_rtx) == POST_MODIFY); - gcc_assert (REG_P (XEXP (plus_rtx, 0))); /* (mem (plus (reg) (const_int))) or + (mem (plus (mult (reg) (const_int 4)) (reg))) or (mem (post_inc (reg))) or (mem (post_dec (reg))) or (mem (post_modify (reg) (plus (reg) (reg)))) */ - return XEXP (plus_rtx, 0); + gcc_assert (GET_CODE (plus_rtx) == PLUS + || GET_CODE (plus_rtx) == POST_INC + || GET_CODE (plus_rtx) == POST_DEC + || GET_CODE (plus_rtx) == POST_MODIFY); + + if (REG_P (XEXP (plus_rtx, 0))) + return XEXP (plus_rtx, 0); + + gcc_assert (REG_P (XEXP (plus_rtx, 1))); + return XEXP (plus_rtx, 1); +} + +/* Extract the offset rtx from load/store insns. The function returns + NULL_RTX if offset is absent. */ +rtx +extract_offset_rtx (rtx_insn *insn) +{ + rtx mem_rtx; + rtx plus_rtx; + rtx offset_rtx; + + /* Find the MEM rtx. The multiple load/store insns doens't have + the offset field so we can return NULL_RTX here. */ + switch (get_attr_type (insn)) + { + case TYPE_LOAD_MULTIPLE: + case TYPE_STORE_MULTIPLE: + return NULL_RTX; + + case TYPE_LOAD: + case TYPE_FLOAD: + case TYPE_STORE: + case TYPE_FSTORE: + mem_rtx = extract_mem_rtx (insn); + break; + + default: + gcc_unreachable (); + } + + gcc_assert (MEM_P (mem_rtx)); + + /* (mem (reg)) */ + if (REG_P (XEXP (mem_rtx, 0))) + return NULL_RTX; + + plus_rtx = XEXP (mem_rtx, 0); + + switch (GET_CODE (plus_rtx)) + { + case SYMBOL_REF: + case CONST: + case POST_INC: + case POST_DEC: + return NULL_RTX; + + case PLUS: + /* (mem (plus (reg) (const_int))) or + (mem (plus (mult (reg) (const_int 4)) (reg))) */ + if (REG_P (XEXP (plus_rtx, 0))) + offset_rtx = XEXP (plus_rtx, 1); + else + { + gcc_assert (REG_P (XEXP (plus_rtx, 1))); + offset_rtx = XEXP (plus_rtx, 0); + } + + if (ARITHMETIC_P (offset_rtx)) + { + gcc_assert (GET_CODE (offset_rtx) == MULT); + gcc_assert (REG_P (XEXP (offset_rtx, 0))); + offset_rtx = XEXP (offset_rtx, 0); + } + break; + + case LO_SUM: + /* (mem (lo_sum (reg) (symbol_ref)) */ + offset_rtx = XEXP (plus_rtx, 1); + break; + + case POST_MODIFY: + /* (mem (post_modify (reg) (plus (reg) (reg / const_int)))) */ + gcc_assert (REG_P (XEXP (plus_rtx, 0))); + plus_rtx = XEXP (plus_rtx, 1); + gcc_assert (GET_CODE (plus_rtx) == PLUS); + offset_rtx = XEXP (plus_rtx, 0); + break; + + default: + gcc_unreachable (); + } + + return offset_rtx; } /* Extract the register of the shift operand from an ALU_SHIFT rtx. */ |