Commit f1fac1bc by Chung-Ju Wu Committed by Chung-Ju Wu

Move memory related implementation to nds32-memory-manipulation.c module.

gcc/
	* config/nds32/nds32.c (nds32_expand_load_multiple): Move to ...
	(nds32_expand_store_multiple): Move to ...
	(nds32_expand_movmemqi): Move to ...
	* config/nds32/nds32-memory-manipulation.c: ... here.

Co-Authored-By: Kito Cheng <kito@0xlab.org>
Co-Authored-By: Monk Chiang <sh.chiang04@gmail.com>

From-SVN: r212287
parent 9e9dbc42
......@@ -2,6 +2,15 @@
Kito Cheng <kito@0xlab.org>
Monk Chiang <sh.chiang04@gmail.com>
* config/nds32/nds32.c (nds32_expand_load_multiple): Move to ...
(nds32_expand_store_multiple): Move to ...
(nds32_expand_movmemqi): Move to ...
* config/nds32/nds32-memory-manipulation.c: ... here.
2014-07-04 Chung-Ju Wu <jasonwucj@gmail.com>
Kito Cheng <kito@0xlab.org>
Monk Chiang <sh.chiang04@gmail.com>
* config/nds32/nds32.c (nds32_byte_to_size): Move to ...
(nds32_output_casesi_pc_relative): Move to ...
(nds32_output_casesi): Move to ...
......
......@@ -18,3 +18,148 @@
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------------ */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "stor-layout.h"
#include "varasm.h"
#include "calls.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "insn-config.h" /* Required by recog.h. */
#include "conditions.h"
#include "output.h"
#include "insn-attr.h" /* For DFA state_t. */
#include "insn-codes.h" /* For CODE_FOR_xxx. */
#include "reload.h" /* For push_reload(). */
#include "flags.h"
#include "function.h"
#include "expr.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "df.h"
#include "tm_p.h"
#include "tm-constrs.h"
#include "optabs.h" /* For GEN_FCN. */
#include "target.h"
#include "target-def.h"
#include "langhooks.h" /* For add_builtin_function(). */
#include "ggc.h"
#include "builtins.h"
/* ------------------------------------------------------------------------ */
/* Functions to expand load_multiple and store_multiple.
They are auxiliary extern functions to help create rtx template.
Check nds32-multiple.md file for the patterns. */
rtx
nds32_expand_load_multiple (int base_regno, int count,
rtx base_addr, rtx basemem)
{
int par_index;
int offset;
rtx result;
rtx new_addr, mem, reg;
/* Create the pattern that is presented in nds32-multiple.md. */
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
for (par_index = 0; par_index < count; par_index++)
{
offset = par_index * 4;
/* 4-byte for loading data to each register. */
new_addr = plus_constant (Pmode, base_addr, offset);
mem = adjust_automodify_address_nv (basemem, SImode,
new_addr, offset);
reg = gen_rtx_REG (SImode, base_regno + par_index);
XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, reg, mem);
}
return result;
}
rtx
nds32_expand_store_multiple (int base_regno, int count,
rtx base_addr, rtx basemem)
{
int par_index;
int offset;
rtx result;
rtx new_addr, mem, reg;
/* Create the pattern that is presented in nds32-multiple.md. */
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
for (par_index = 0; par_index < count; par_index++)
{
offset = par_index * 4;
/* 4-byte for storing data to memory. */
new_addr = plus_constant (Pmode, base_addr, offset);
mem = adjust_automodify_address_nv (basemem, SImode,
new_addr, offset);
reg = gen_rtx_REG (SImode, base_regno + par_index);
XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, mem, reg);
}
return result;
}
/* Function to move block memory content by
using load_multiple and store_multiple.
This is auxiliary extern function to help create rtx template.
Check nds32-multiple.md file for the patterns. */
int
nds32_expand_movmemqi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment)
{
HOST_WIDE_INT in_words, out_words;
rtx dst_base_reg, src_base_reg;
int maximum_bytes;
/* Because reduced-set regsiters has few registers
(r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31'
cannot be used for register allocation),
using 8 registers (32 bytes) for moving memory block
may easily consume all of them.
It makes register allocation/spilling hard to work.
So we only allow maximum=4 registers (16 bytes) for
moving memory block under reduced-set registers. */
if (TARGET_REDUCED_REGS)
maximum_bytes = 16;
else
maximum_bytes = 32;
/* 1. Total_bytes is integer for sure.
2. Alignment is integer for sure.
3. Maximum 4 or 8 registers, 4 * 4 = 16 bytes, 8 * 4 = 32 bytes.
4. Requires (n * 4) block size.
5. Requires 4-byte alignment. */
if (GET_CODE (total_bytes) != CONST_INT
|| GET_CODE (alignment) != CONST_INT
|| INTVAL (total_bytes) > maximum_bytes
|| INTVAL (total_bytes) & 3
|| INTVAL (alignment) & 3)
return 0;
dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0));
src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0));
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));
/* Successfully create patterns, return 1. */
return 1;
}
/* ------------------------------------------------------------------------ */
......@@ -3133,113 +3133,6 @@ nds32_ls_333_p (rtx rt, rtx ra, rtx imm, enum machine_mode mode)
}
/* Functions to expand load_multiple and store_multiple.
They are auxiliary extern functions to help create rtx template.
Check nds32-multiple.md file for the patterns. */
rtx
nds32_expand_load_multiple (int base_regno, int count,
rtx base_addr, rtx basemem)
{
int par_index;
int offset;
rtx result;
rtx new_addr, mem, reg;
/* Create the pattern that is presented in nds32-multiple.md. */
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
for (par_index = 0; par_index < count; par_index++)
{
offset = par_index * 4;
/* 4-byte for loading data to each register. */
new_addr = plus_constant (Pmode, base_addr, offset);
mem = adjust_automodify_address_nv (basemem, SImode,
new_addr, offset);
reg = gen_rtx_REG (SImode, base_regno + par_index);
XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, reg, mem);
}
return result;
}
rtx
nds32_expand_store_multiple (int base_regno, int count,
rtx base_addr, rtx basemem)
{
int par_index;
int offset;
rtx result;
rtx new_addr, mem, reg;
/* Create the pattern that is presented in nds32-multiple.md. */
result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
for (par_index = 0; par_index < count; par_index++)
{
offset = par_index * 4;
/* 4-byte for storing data to memory. */
new_addr = plus_constant (Pmode, base_addr, offset);
mem = adjust_automodify_address_nv (basemem, SImode,
new_addr, offset);
reg = gen_rtx_REG (SImode, base_regno + par_index);
XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, mem, reg);
}
return result;
}
/* Function to move block memory content by
using load_multiple and store_multiple.
This is auxiliary extern function to help create rtx template.
Check nds32-multiple.md file for the patterns. */
int
nds32_expand_movmemqi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment)
{
HOST_WIDE_INT in_words, out_words;
rtx dst_base_reg, src_base_reg;
int maximum_bytes;
/* Because reduced-set regsiters has few registers
(r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31'
cannot be used for register allocation),
using 8 registers (32 bytes) for moving memory block
may easily consume all of them.
It makes register allocation/spilling hard to work.
So we only allow maximum=4 registers (16 bytes) for
moving memory block under reduced-set registers. */
if (TARGET_REDUCED_REGS)
maximum_bytes = 16;
else
maximum_bytes = 32;
/* 1. Total_bytes is integer for sure.
2. Alignment is integer for sure.
3. Maximum 4 or 8 registers, 4 * 4 = 16 bytes, 8 * 4 = 32 bytes.
4. Requires (n * 4) block size.
5. Requires 4-byte alignment. */
if (GET_CODE (total_bytes) != CONST_INT
|| GET_CODE (alignment) != CONST_INT
|| INTVAL (total_bytes) > maximum_bytes
|| INTVAL (total_bytes) & 3
|| INTVAL (alignment) & 3)
return 0;
dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0));
src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0));
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));
/* Successfully create patterns, return 1. */
return 1;
}
/* Computing the Length of an Insn.
Modifies the length assigned to instruction INSN.
LEN is the initially computed length of the insn. */
......
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