]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/nds32/nds32-memory-manipulation.c
caa45f8e2fb5b2ff20b5f75d8d80b4f5d5cb51db
1 /* Auxiliary functions for expand movmem, setmem, cmpmem, load_multiple
2 and store_multiple pattern of Andes NDS32 cpu for GNU compiler
3 Copyright (C) 2012-2015 Free Software Foundation, Inc.
4 Contributed by Andes Technology Corporation.
6 This file is part of GCC.
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.
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.
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/>. */
22 /* ------------------------------------------------------------------------ */
26 #include "coretypes.h"
33 #include "stor-layout.h"
37 #include "insn-config.h" /* Required by recog.h. */
38 #include "conditions.h"
40 #include "insn-attr.h" /* For DFA state_t. */
41 #include "insn-codes.h" /* For CODE_FOR_xxx. */
42 #include "reload.h" /* For push_reload(). */
44 #include "insn-config.h"
52 #include "diagnostic-core.h"
57 #include "cfgcleanup.h"
59 #include "tm-constrs.h"
60 #include "optabs.h" /* For GEN_FCN. */
62 #include "langhooks.h" /* For add_builtin_function(). */
65 /* ------------------------------------------------------------------------ */
67 /* Functions to expand load_multiple and store_multiple.
68 They are auxiliary extern functions to help create rtx template.
69 Check nds32-multiple.md file for the patterns. */
71 nds32_expand_load_multiple (int base_regno
, int count
,
72 rtx base_addr
, rtx basemem
)
77 rtx new_addr
, mem
, reg
;
79 /* Create the pattern that is presented in nds32-multiple.md. */
81 result
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (count
));
83 for (par_index
= 0; par_index
< count
; par_index
++)
85 offset
= par_index
* 4;
86 /* 4-byte for loading data to each register. */
87 new_addr
= plus_constant (Pmode
, base_addr
, offset
);
88 mem
= adjust_automodify_address_nv (basemem
, SImode
,
90 reg
= gen_rtx_REG (SImode
, base_regno
+ par_index
);
92 XVECEXP (result
, 0, par_index
) = gen_rtx_SET (reg
, mem
);
99 nds32_expand_store_multiple (int base_regno
, int count
,
100 rtx base_addr
, rtx basemem
)
105 rtx new_addr
, mem
, reg
;
107 /* Create the pattern that is presented in nds32-multiple.md. */
109 result
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (count
));
111 for (par_index
= 0; par_index
< count
; par_index
++)
113 offset
= par_index
* 4;
114 /* 4-byte for storing data to memory. */
115 new_addr
= plus_constant (Pmode
, base_addr
, offset
);
116 mem
= adjust_automodify_address_nv (basemem
, SImode
,
118 reg
= gen_rtx_REG (SImode
, base_regno
+ par_index
);
120 XVECEXP (result
, 0, par_index
) = gen_rtx_SET (mem
, reg
);
126 /* Function to move block memory content by
127 using load_multiple and store_multiple.
128 This is auxiliary extern function to help create rtx template.
129 Check nds32-multiple.md file for the patterns. */
131 nds32_expand_movmemqi (rtx dstmem
, rtx srcmem
, rtx total_bytes
, rtx alignment
)
133 HOST_WIDE_INT in_words
, out_words
;
134 rtx dst_base_reg
, src_base_reg
;
137 /* Because reduced-set regsiters has few registers
138 (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31'
139 cannot be used for register allocation),
140 using 8 registers (32 bytes) for moving memory block
141 may easily consume all of them.
142 It makes register allocation/spilling hard to work.
143 So we only allow maximum=4 registers (16 bytes) for
144 moving memory block under reduced-set registers. */
145 if (TARGET_REDUCED_REGS
)
150 /* 1. Total_bytes is integer for sure.
151 2. Alignment is integer for sure.
152 3. Maximum 4 or 8 registers, 4 * 4 = 16 bytes, 8 * 4 = 32 bytes.
153 4. Requires (n * 4) block size.
154 5. Requires 4-byte alignment. */
155 if (GET_CODE (total_bytes
) != CONST_INT
156 || GET_CODE (alignment
) != CONST_INT
157 || INTVAL (total_bytes
) > maximum_bytes
158 || INTVAL (total_bytes
) & 3
159 || INTVAL (alignment
) & 3)
162 dst_base_reg
= copy_to_mode_reg (SImode
, XEXP (dstmem
, 0));
163 src_base_reg
= copy_to_mode_reg (SImode
, XEXP (srcmem
, 0));
165 out_words
= in_words
= INTVAL (total_bytes
) / UNITS_PER_WORD
;
167 emit_insn (nds32_expand_load_multiple (0, in_words
, src_base_reg
, srcmem
));
168 emit_insn (nds32_expand_store_multiple (0, out_words
, dst_base_reg
, dstmem
));
170 /* Successfully create patterns, return 1. */
174 /* ------------------------------------------------------------------------ */