Commit 32a6f4f4 by Kito Cheng Committed by Chung-Ju Wu

[NDS32] Refine load_multiple and store_multiple.

gcc/
	* config/nds32/nds32-protos.h
	(nds32_expand_load_multiple): New arguments.
	(nds32_expand_store_multiple): Ditto.
	(nds32_valid_multiple_load_store): Rename ...
	(nds32_valid_multiple_load_store_p): ... to this.
	* config/nds32/nds32-memory-manipulation.c
	(nds32_expand_load_multiple): Refine implementation.
	(nds32_expand_store_multiple): Ditto.
	* config/nds32/nds32-multiple.md
	(load_multiple): Update nds32_expand_load_multiple interface.
	(store_multiple): Update nds32_expand_store_multiple interface.
	* config/nds32/nds32-predicates.c
	(nds32_valid_multiple_load_store): Rename ...
	(nds32_valid_multiple_load_store_p): ... to this and refine
	implementation.
	* config/nds32/predicates.md
	(nds32_load_multiple_and_update_address_operation): New predicate.
	(nds32_store_multiple_and_update_address_operation): New predicate.

Co-Authored-By: Chung-Ju Wu <jasonwucj@gmail.com>
Co-Authored-By: Monk Chiang <sh.chiang04@gmail.com>

From-SVN: r258234
parent 264159d2
2018-03-04 Kito Cheng <kito.cheng@gmail.com>
Monk Chiang <sh.chiang04@gmail.com>
Chung-Ju Wu <jasonwucj@gmail.com>
* config/nds32/nds32-protos.h
(nds32_expand_load_multiple): New arguments.
(nds32_expand_store_multiple): Ditto.
(nds32_valid_multiple_load_store): Rename ...
(nds32_valid_multiple_load_store_p): ... to this.
* config/nds32/nds32-memory-manipulation.c
(nds32_expand_load_multiple): Refine implementation.
(nds32_expand_store_multiple): Ditto.
* config/nds32/nds32-multiple.md
(load_multiple): Update nds32_expand_load_multiple interface.
(store_multiple): Update nds32_expand_store_multiple interface.
* config/nds32/nds32-predicates.c
(nds32_valid_multiple_load_store): Rename ...
(nds32_valid_multiple_load_store_p): ... to this and refine
implementation.
* config/nds32/predicates.md
(nds32_load_multiple_and_update_address_operation): New predicate.
(nds32_store_multiple_and_update_address_operation): New predicate.
2018-03-04 Kito Cheng <kito.cheng@gmail.com>
Chung-Ju Wu <jasonwucj@gmail.com>
* config/nds32/nds32.md (type): Add load_multiple and store_multiple.
......
......@@ -40,16 +40,50 @@
Check nds32-multiple.md file for the patterns. */
rtx
nds32_expand_load_multiple (int base_regno, int count,
rtx base_addr, rtx basemem)
rtx base_addr, rtx basemem,
bool update_base_reg_p,
rtx *update_base_reg)
{
int par_index;
int offset;
int start_idx;
rtx result;
rtx new_addr, mem, reg;
/* Generate a unaligned load to prevent load instruction pull out from
parallel, and then it will generate lwi, and lose unaligned acces */
if (count == 1)
{
reg = gen_rtx_REG (SImode, base_regno);
if (update_base_reg_p)
{
*update_base_reg = gen_reg_rtx (SImode);
return gen_unaligned_load_update_base_w (*update_base_reg, reg, base_addr);
}
else
return gen_unaligned_load_w (reg, gen_rtx_MEM (SImode, base_addr));
}
/* Create the pattern that is presented in nds32-multiple.md. */
if (update_base_reg_p)
{
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
start_idx = 1;
}
else
{
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
start_idx = 0;
}
if (update_base_reg_p)
{
offset = count * 4;
new_addr = plus_constant (Pmode, base_addr, offset);
*update_base_reg = gen_reg_rtx (SImode);
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
XVECEXP (result, 0, 0) = gen_rtx_SET (*update_base_reg, new_addr);
}
for (par_index = 0; par_index < count; par_index++)
{
......@@ -60,7 +94,7 @@ nds32_expand_load_multiple (int base_regno, int count,
new_addr, offset);
reg = gen_rtx_REG (SImode, base_regno + par_index);
XVECEXP (result, 0, par_index) = gen_rtx_SET (reg, mem);
XVECEXP (result, 0, (par_index + start_idx)) = gen_rtx_SET (reg, mem);
}
return result;
......@@ -68,16 +102,49 @@ nds32_expand_load_multiple (int base_regno, int count,
rtx
nds32_expand_store_multiple (int base_regno, int count,
rtx base_addr, rtx basemem)
rtx base_addr, rtx basemem,
bool update_base_reg_p,
rtx *update_base_reg)
{
int par_index;
int offset;
int start_idx;
rtx result;
rtx new_addr, mem, reg;
if (count == 1)
{
reg = gen_rtx_REG (SImode, base_regno);
if (update_base_reg_p)
{
*update_base_reg = gen_reg_rtx (SImode);
return gen_unaligned_store_update_base_w (*update_base_reg, base_addr, reg);
}
else
return gen_unaligned_store_w (gen_rtx_MEM (SImode, base_addr), reg);
}
/* Create the pattern that is presented in nds32-multiple.md. */
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
if (update_base_reg_p)
{
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
start_idx = 1;
}
else
{
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
start_idx = 0;
}
if (update_base_reg_p)
{
offset = count * 4;
new_addr = plus_constant (Pmode, base_addr, offset);
*update_base_reg = gen_reg_rtx (SImode);
XVECEXP (result, 0, 0) = gen_rtx_SET (*update_base_reg, new_addr);
}
for (par_index = 0; par_index < count; par_index++)
{
......@@ -88,7 +155,7 @@ nds32_expand_store_multiple (int base_regno, int count,
new_addr, offset);
reg = gen_rtx_REG (SImode, base_regno + par_index);
XVECEXP (result, 0, par_index) = gen_rtx_SET (mem, reg);
XVECEXP (result, 0, par_index + start_idx) = gen_rtx_SET (mem, reg);
}
return result;
......@@ -135,8 +202,12 @@ nds32_expand_movmemqi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment)
out_words = in_words = INTVAL (total_bytes) / UNITS_PER_WORD;
emit_insn (nds32_expand_load_multiple (0, in_words, src_base_reg, srcmem));
emit_insn (nds32_expand_store_multiple (0, out_words, dst_base_reg, dstmem));
emit_insn (
nds32_expand_load_multiple (0, in_words, src_base_reg,
srcmem, false, NULL));
emit_insn (
nds32_expand_store_multiple (0, out_words, dst_base_reg,
dstmem, false, NULL));
/* Successfully create patterns, return 1. */
return 1;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -101,21 +101,33 @@ nds32_consecutive_registers_load_store_p (rtx op,
We have to extract reg and mem of every element and
check if the information is valid for multiple load/store operation. */
bool
nds32_valid_multiple_load_store (rtx op, bool load_p)
nds32_valid_multiple_load_store_p (rtx op, bool load_p, bool bim_p)
{
int count;
int first_elt_regno;
int update_base_elt_idx;
int offset;
rtx elt;
rtx update_base;
/* Get the counts of elements in the parallel rtx. */
count = XVECLEN (op, 0);
/* Pick up the first element. */
elt = XVECEXP (op, 0, 0);
/* Get the counts of elements in the parallel rtx.
Last one is update base register if bim_p.
and pick up the first element. */
if (bim_p)
{
count = XVECLEN (op, 0) - 1;
elt = XVECEXP (op, 0, 1);
}
else
{
count = XVECLEN (op, 0);
elt = XVECEXP (op, 0, 0);
}
/* Perform some quick check for the first element in the parallel rtx. */
if (GET_CODE (elt) != SET
|| count <= 1
|| count > 8)
|| count > 25)
return false;
/* Pick up regno of first element for further detail checking.
......@@ -141,11 +153,29 @@ nds32_valid_multiple_load_store (rtx op, bool load_p)
Refer to nds32-multiple.md for more information
about following checking.
The starting element of parallel rtx is index 0. */
if (!nds32_consecutive_registers_load_store_p (op, load_p, 0,
if (!nds32_consecutive_registers_load_store_p (op, load_p, bim_p ? 1 : 0,
first_elt_regno,
count))
return false;
if (bim_p)
{
update_base_elt_idx = 0;
update_base = XVECEXP (op, 0, update_base_elt_idx);
if (!REG_P (SET_DEST (update_base)))
return false;
if (GET_CODE (SET_SRC (update_base)) != PLUS)
return false;
else
{
offset = count * UNITS_PER_WORD;
elt = XEXP (SET_SRC (update_base), 1);
if (GET_CODE (elt) != CONST_INT
|| (INTVAL (elt) != offset))
return false;
}
}
/* Pass all test, this is a valid rtx. */
return true;
}
......
......@@ -66,8 +66,8 @@ extern bool nds32_valid_smw_lwm_base_p (rtx);
/* Auxiliary functions for expanding rtl used in nds32-multiple.md. */
extern rtx nds32_expand_load_multiple (int, int, rtx, rtx);
extern rtx nds32_expand_store_multiple (int, int, rtx, rtx);
extern rtx nds32_expand_load_multiple (int, int, rtx, rtx, bool, rtx *);
extern rtx nds32_expand_store_multiple (int, int, rtx, rtx, bool, rtx *);
extern int nds32_expand_movmemqi (rtx, rtx, rtx, rtx);
/* Auxiliary functions for expand unalign load instruction. */
......@@ -80,7 +80,7 @@ extern void nds32_expand_unaligned_store (rtx *, enum machine_mode);
/* Auxiliary functions for multiple load/store predicate checking. */
extern bool nds32_valid_multiple_load_store (rtx, bool);
extern bool nds32_valid_multiple_load_store_p (rtx, bool, bool);
/* Auxiliary functions for stack operation predicate checking. */
......
......@@ -66,7 +66,16 @@
{
/* To verify 'load' operation, pass 'true' for the second argument.
See the implementation in nds32.c for details. */
return nds32_valid_multiple_load_store (op, true);
return nds32_valid_multiple_load_store_p (op, true, false);
})
(define_special_predicate "nds32_load_multiple_and_update_address_operation"
(match_code "parallel")
{
/* To verify 'load' operation, pass 'true' for the second argument.
to verify 'update address' operation, pass 'true' for the third argument
See the implementation in nds32.c for details. */
return nds32_valid_multiple_load_store_p (op, true, true);
})
(define_special_predicate "nds32_store_multiple_operation"
......@@ -74,7 +83,16 @@
{
/* To verify 'store' operation, pass 'false' for the second argument.
See the implementation in nds32.c for details. */
return nds32_valid_multiple_load_store (op, false);
return nds32_valid_multiple_load_store_p (op, false, false);
})
(define_special_predicate "nds32_store_multiple_and_update_address_operation"
(match_code "parallel")
{
/* To verify 'store' operation, pass 'false' for the second argument,
to verify 'update address' operation, pass 'true' for the third argument
See the implementation in nds32.c for details. */
return nds32_valid_multiple_load_store_p (op, false, true);
})
(define_special_predicate "nds32_stack_push_operation"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment