]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nds32/nds32-memory-manipulation.c
tree-core.h: Include symtab.h.
[thirdparty/gcc.git] / gcc / config / nds32 / nds32-memory-manipulation.c
CommitLineData
c0c935b5
CJW
1/* Auxiliary functions for expand movmem, setmem, cmpmem, load_multiple
2 and store_multiple pattern of Andes NDS32 cpu for GNU compiler
5624e564 3 Copyright (C) 2012-2015 Free Software Foundation, Inc.
c0c935b5
CJW
4 Contributed by Andes Technology Corporation.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published
10 by the Free Software Foundation; either version 3, or (at your
11 option) any later version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
f1fac1bc
CJW
21
22/* ------------------------------------------------------------------------ */
23
24#include "config.h"
25#include "system.h"
26#include "coretypes.h"
c7131fb2 27#include "backend.h"
f1fac1bc 28#include "tree.h"
c7131fb2
AM
29#include "rtl.h"
30#include "df.h"
31#include "alias.h"
f1fac1bc
CJW
32#include "stor-layout.h"
33#include "varasm.h"
34#include "calls.h"
f1fac1bc 35#include "regs.h"
f1fac1bc
CJW
36#include "insn-config.h" /* Required by recog.h. */
37#include "conditions.h"
38#include "output.h"
39#include "insn-attr.h" /* For DFA state_t. */
40#include "insn-codes.h" /* For CODE_FOR_xxx. */
41#include "reload.h" /* For push_reload(). */
42#include "flags.h"
36566b39
PK
43#include "insn-config.h"
44#include "expmed.h"
45#include "dojump.h"
46#include "explow.h"
47#include "emit-rtl.h"
48#include "stmt.h"
f1fac1bc
CJW
49#include "expr.h"
50#include "recog.h"
51#include "diagnostic-core.h"
60393bbc
AM
52#include "cfgrtl.h"
53#include "cfganal.h"
54#include "lcm.h"
55#include "cfgbuild.h"
56#include "cfgcleanup.h"
f1fac1bc
CJW
57#include "tm_p.h"
58#include "tm-constrs.h"
59#include "optabs.h" /* For GEN_FCN. */
60#include "target.h"
f1fac1bc 61#include "langhooks.h" /* For add_builtin_function(). */
f1fac1bc
CJW
62#include "builtins.h"
63
64/* ------------------------------------------------------------------------ */
65
66/* Functions to expand load_multiple and store_multiple.
67 They are auxiliary extern functions to help create rtx template.
68 Check nds32-multiple.md file for the patterns. */
69rtx
70nds32_expand_load_multiple (int base_regno, int count,
71 rtx base_addr, rtx basemem)
72{
73 int par_index;
74 int offset;
75 rtx result;
76 rtx new_addr, mem, reg;
77
78 /* Create the pattern that is presented in nds32-multiple.md. */
79
80 result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
81
82 for (par_index = 0; par_index < count; par_index++)
83 {
84 offset = par_index * 4;
85 /* 4-byte for loading data to each register. */
86 new_addr = plus_constant (Pmode, base_addr, offset);
87 mem = adjust_automodify_address_nv (basemem, SImode,
88 new_addr, offset);
89 reg = gen_rtx_REG (SImode, base_regno + par_index);
90
f7df4a84 91 XVECEXP (result, 0, par_index) = gen_rtx_SET (reg, mem);
f1fac1bc
CJW
92 }
93
94 return result;
95}
96
97rtx
98nds32_expand_store_multiple (int base_regno, int count,
99 rtx base_addr, rtx basemem)
100{
101 int par_index;
102 int offset;
103 rtx result;
104 rtx new_addr, mem, reg;
105
106 /* Create the pattern that is presented in nds32-multiple.md. */
107
108 result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
109
110 for (par_index = 0; par_index < count; par_index++)
111 {
112 offset = par_index * 4;
113 /* 4-byte for storing data to memory. */
114 new_addr = plus_constant (Pmode, base_addr, offset);
115 mem = adjust_automodify_address_nv (basemem, SImode,
116 new_addr, offset);
117 reg = gen_rtx_REG (SImode, base_regno + par_index);
118
f7df4a84 119 XVECEXP (result, 0, par_index) = gen_rtx_SET (mem, reg);
f1fac1bc
CJW
120 }
121
122 return result;
123}
124
125/* Function to move block memory content by
126 using load_multiple and store_multiple.
127 This is auxiliary extern function to help create rtx template.
128 Check nds32-multiple.md file for the patterns. */
129int
130nds32_expand_movmemqi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment)
131{
132 HOST_WIDE_INT in_words, out_words;
133 rtx dst_base_reg, src_base_reg;
134 int maximum_bytes;
135
136 /* Because reduced-set regsiters has few registers
137 (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31'
138 cannot be used for register allocation),
139 using 8 registers (32 bytes) for moving memory block
140 may easily consume all of them.
141 It makes register allocation/spilling hard to work.
142 So we only allow maximum=4 registers (16 bytes) for
143 moving memory block under reduced-set registers. */
144 if (TARGET_REDUCED_REGS)
145 maximum_bytes = 16;
146 else
147 maximum_bytes = 32;
148
149 /* 1. Total_bytes is integer for sure.
150 2. Alignment is integer for sure.
151 3. Maximum 4 or 8 registers, 4 * 4 = 16 bytes, 8 * 4 = 32 bytes.
152 4. Requires (n * 4) block size.
153 5. Requires 4-byte alignment. */
154 if (GET_CODE (total_bytes) != CONST_INT
155 || GET_CODE (alignment) != CONST_INT
156 || INTVAL (total_bytes) > maximum_bytes
157 || INTVAL (total_bytes) & 3
158 || INTVAL (alignment) & 3)
159 return 0;
160
161 dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0));
162 src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0));
163
164 out_words = in_words = INTVAL (total_bytes) / UNITS_PER_WORD;
165
166 emit_insn (nds32_expand_load_multiple (0, in_words, src_base_reg, srcmem));
167 emit_insn (nds32_expand_store_multiple (0, out_words, dst_base_reg, dstmem));
168
169 /* Successfully create patterns, return 1. */
170 return 1;
171}
172
173/* ------------------------------------------------------------------------ */