diff options
Diffstat (limited to 'meta-xilinx-bsp/recipes-microblaze/gcc/gcc-10/0039-Intial-commit-of-64-bit-Microblaze.patch')
-rw-r--r-- | meta-xilinx-bsp/recipes-microblaze/gcc/gcc-10/0039-Intial-commit-of-64-bit-Microblaze.patch | 804 |
1 files changed, 804 insertions, 0 deletions
diff --git a/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-10/0039-Intial-commit-of-64-bit-Microblaze.patch b/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-10/0039-Intial-commit-of-64-bit-Microblaze.patch new file mode 100644 index 00000000..f524cba2 --- /dev/null +++ b/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-10/0039-Intial-commit-of-64-bit-Microblaze.patch | |||
@@ -0,0 +1,804 @@ | |||
1 | From 68359cc8e82f63d01a77c39c68e782e6757cd71e Mon Sep 17 00:00:00 2001 | ||
2 | From: Nagaraju Mekala <nmekala@xilix.com> | ||
3 | Date: Tue, 3 Apr 2018 16:48:39 +0530 | ||
4 | Subject: [PATCH 39/63] Intial commit of 64-bit Microblaze | ||
5 | |||
6 | Conflicts: | ||
7 | gcc/config/microblaze/microblaze.opt | ||
8 | --- | ||
9 | gcc/config/microblaze/microblaze-protos.h | 1 + | ||
10 | gcc/config/microblaze/microblaze.c | 109 +++++++-- | ||
11 | gcc/config/microblaze/microblaze.h | 4 +- | ||
12 | gcc/config/microblaze/microblaze.md | 370 +++++++++++++++++++++++++++++- | ||
13 | gcc/config/microblaze/microblaze.opt | 7 +- | ||
14 | gcc/config/microblaze/t-microblaze | 7 +- | ||
15 | 6 files changed, 460 insertions(+), 38 deletions(-) | ||
16 | |||
17 | diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h | ||
18 | index bdc9b69..7d6c189 100644 | ||
19 | --- a/gcc/config/microblaze/microblaze-protos.h | ||
20 | +++ b/gcc/config/microblaze/microblaze-protos.h | ||
21 | @@ -36,6 +36,7 @@ extern void microblaze_expand_divide (rtx *); | ||
22 | extern void microblaze_expand_conditional_branch (enum machine_mode, rtx *); | ||
23 | extern void microblaze_expand_conditional_branch_reg (machine_mode, rtx *); | ||
24 | extern void microblaze_expand_conditional_branch_sf (rtx *); | ||
25 | +extern void microblaze_expand_conditional_branch_df (rtx *); | ||
26 | extern int microblaze_can_use_return_insn (void); | ||
27 | extern void print_operand (FILE *, rtx, int); | ||
28 | extern void print_operand_address (FILE *, rtx); | ||
29 | diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c | ||
30 | index 71640e5..f740f5c 100644 | ||
31 | --- a/gcc/config/microblaze/microblaze.c | ||
32 | +++ b/gcc/config/microblaze/microblaze.c | ||
33 | @@ -3570,11 +3570,11 @@ microblaze_expand_move (machine_mode mode, rtx operands[]) | ||
34 | op0 = operands[0]; | ||
35 | op1 = operands[1]; | ||
36 | |||
37 | - if (!register_operand (op0, SImode) | ||
38 | - && !register_operand (op1, SImode) | ||
39 | + if (!register_operand (op0, mode) | ||
40 | + && !register_operand (op1, mode) | ||
41 | && (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0)) | ||
42 | { | ||
43 | - rtx temp = force_reg (SImode, op1); | ||
44 | + rtx temp = force_reg (mode, op1); | ||
45 | emit_move_insn (op0, temp); | ||
46 | return true; | ||
47 | } | ||
48 | @@ -3639,12 +3639,12 @@ microblaze_expand_move (machine_mode mode, rtx operands[]) | ||
49 | && (flag_pic == 2 || microblaze_tls_symbol_p (p0) | ||
50 | || !SMALL_INT (p1))))) | ||
51 | { | ||
52 | - rtx temp = force_reg (SImode, p0); | ||
53 | + rtx temp = force_reg (mode, p0); | ||
54 | rtx temp2 = p1; | ||
55 | |||
56 | if (flag_pic && reload_in_progress) | ||
57 | df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true); | ||
58 | - emit_move_insn (op0, gen_rtx_PLUS (SImode, temp, temp2)); | ||
59 | + emit_move_insn (op0, gen_rtx_PLUS (mode, temp, temp2)); | ||
60 | return true; | ||
61 | } | ||
62 | } | ||
63 | @@ -3775,7 +3775,7 @@ microblaze_expand_conditional_branch (machine_mode mode, rtx operands[]) | ||
64 | rtx cmp_op0 = operands[1]; | ||
65 | rtx cmp_op1 = operands[2]; | ||
66 | rtx label1 = operands[3]; | ||
67 | - rtx comp_reg = gen_reg_rtx (SImode); | ||
68 | + rtx comp_reg = gen_reg_rtx (mode); | ||
69 | rtx condition; | ||
70 | |||
71 | gcc_assert ((GET_CODE (cmp_op0) == REG) || (GET_CODE (cmp_op0) == SUBREG)); | ||
72 | @@ -3784,23 +3784,36 @@ microblaze_expand_conditional_branch (machine_mode mode, rtx operands[]) | ||
73 | if (cmp_op1 == const0_rtx) | ||
74 | { | ||
75 | comp_reg = cmp_op0; | ||
76 | - condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx); | ||
77 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
78 | + condition = gen_rtx_fmt_ee (signed_condition (code), mode, comp_reg, const0_rtx); | ||
79 | + if (mode == SImode) | ||
80 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
81 | + else | ||
82 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
83 | + | ||
84 | } | ||
85 | |||
86 | else if (code == EQ || code == NE) | ||
87 | { | ||
88 | /* Use xor for equal/not-equal comparison. */ | ||
89 | - emit_insn (gen_xorsi3 (comp_reg, cmp_op0, cmp_op1)); | ||
90 | - condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx); | ||
91 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
92 | + if (mode == SImode) | ||
93 | + emit_insn (gen_xorsi3 (comp_reg, cmp_op0, cmp_op1)); | ||
94 | + else | ||
95 | + emit_insn (gen_xordi3 (comp_reg, cmp_op0, cmp_op1)); | ||
96 | + condition = gen_rtx_fmt_ee (signed_condition (code), mode, comp_reg, const0_rtx); | ||
97 | + if (mode == SImode) | ||
98 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
99 | + else | ||
100 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | /* Generate compare and branch in single instruction. */ | ||
105 | cmp_op1 = force_reg (mode, cmp_op1); | ||
106 | condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1); | ||
107 | - emit_jump_insn (gen_branch_compare(condition, cmp_op0, cmp_op1, label1)); | ||
108 | + if (mode == SImode) | ||
109 | + emit_jump_insn (gen_branch_compare(condition, cmp_op0, cmp_op1, label1)); | ||
110 | + else | ||
111 | + emit_jump_insn (gen_long_branch_compare(condition, cmp_op0, cmp_op1, label1)); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | @@ -3811,7 +3824,7 @@ microblaze_expand_conditional_branch_reg (machine_mode mode, rtx operands[]) | ||
116 | rtx cmp_op0 = operands[1]; | ||
117 | rtx cmp_op1 = operands[2]; | ||
118 | rtx label1 = operands[3]; | ||
119 | - rtx comp_reg = gen_reg_rtx (SImode); | ||
120 | + rtx comp_reg = gen_reg_rtx (mode); | ||
121 | rtx condition; | ||
122 | |||
123 | gcc_assert ((GET_CODE (cmp_op0) == REG) | ||
124 | @@ -3822,30 +3835,63 @@ microblaze_expand_conditional_branch_reg (machine_mode mode, rtx operands[]) | ||
125 | { | ||
126 | comp_reg = cmp_op0; | ||
127 | condition = gen_rtx_fmt_ee (signed_condition (code), | ||
128 | - SImode, comp_reg, const0_rtx); | ||
129 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
130 | + mode, comp_reg, const0_rtx); | ||
131 | + if (mode == SImode) | ||
132 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
133 | + else | ||
134 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
135 | } | ||
136 | else if (code == EQ) | ||
137 | { | ||
138 | - emit_insn (gen_seq_internal_pat (comp_reg, | ||
139 | - cmp_op0, cmp_op1)); | ||
140 | - condition = gen_rtx_EQ (SImode, comp_reg, const0_rtx); | ||
141 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
142 | + if (mode == SImode) | ||
143 | + { | ||
144 | + emit_insn (gen_seq_internal_pat (comp_reg, cmp_op0, | ||
145 | + cmp_op1)); | ||
146 | + } | ||
147 | + else | ||
148 | + { | ||
149 | + emit_insn (gen_seq_internal_pat (comp_reg, cmp_op0, | ||
150 | + cmp_op1)); | ||
151 | + } | ||
152 | + condition = gen_rtx_EQ (mode, comp_reg, const0_rtx); | ||
153 | + if (mode == SImode) | ||
154 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
155 | + else | ||
156 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
157 | + | ||
158 | } | ||
159 | else if (code == NE) | ||
160 | { | ||
161 | - emit_insn (gen_sne_internal_pat (comp_reg, cmp_op0, | ||
162 | - cmp_op1)); | ||
163 | - condition = gen_rtx_NE (SImode, comp_reg, const0_rtx); | ||
164 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
165 | + if (mode == SImode) | ||
166 | + { | ||
167 | + emit_insn (gen_sne_internal_pat (comp_reg, cmp_op0, | ||
168 | + cmp_op1)); | ||
169 | + } | ||
170 | + else | ||
171 | + { | ||
172 | + emit_insn (gen_sne_internal_pat (comp_reg, cmp_op0, | ||
173 | + cmp_op1)); | ||
174 | + } | ||
175 | + condition = gen_rtx_NE (mode, comp_reg, const0_rtx); | ||
176 | + if (mode == SImode) | ||
177 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
178 | + else | ||
179 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | /* Generate compare and branch in single instruction. */ | ||
184 | cmp_op1 = force_reg (mode, cmp_op1); | ||
185 | condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1); | ||
186 | - emit_jump_insn (gen_branch_compare (condition, cmp_op0, | ||
187 | - cmp_op1, label1)); | ||
188 | + if (mode == SImode) | ||
189 | + emit_jump_insn (gen_branch_compare (condition, cmp_op0, | ||
190 | + cmp_op1, label1)); | ||
191 | + else | ||
192 | + { | ||
193 | + emit_jump_insn (gen_long_branch_compare (condition, cmp_op0, | ||
194 | + cmp_op1, label1)); | ||
195 | + } | ||
196 | + | ||
197 | } | ||
198 | } | ||
199 | |||
200 | @@ -3862,6 +3908,19 @@ microblaze_expand_conditional_branch_sf (rtx operands[]) | ||
201 | emit_jump_insn (gen_condjump (condition, operands[3])); | ||
202 | } | ||
203 | |||
204 | +void | ||
205 | +microblaze_expand_conditional_branch_df (rtx operands[]) | ||
206 | +{ | ||
207 | + rtx condition; | ||
208 | + rtx cmp_op0 = XEXP (operands[0], 0); | ||
209 | + rtx cmp_op1 = XEXP (operands[0], 1); | ||
210 | + rtx comp_reg = gen_reg_rtx (DImode); | ||
211 | + | ||
212 | + emit_insn (gen_cstoredf4 (comp_reg, operands[0], cmp_op0, cmp_op1)); | ||
213 | + condition = gen_rtx_NE (DImode, comp_reg, const0_rtx); | ||
214 | + emit_jump_insn (gen_long_condjump (condition, operands[3])); | ||
215 | +} | ||
216 | + | ||
217 | /* Implement TARGET_FRAME_POINTER_REQUIRED. */ | ||
218 | |||
219 | static bool | ||
220 | diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h | ||
221 | index 1d05e6e..2ca44f5 100644 | ||
222 | --- a/gcc/config/microblaze/microblaze.h | ||
223 | +++ b/gcc/config/microblaze/microblaze.h | ||
224 | @@ -102,6 +102,7 @@ extern enum pipeline_type microblaze_pipe; | ||
225 | #define ASM_SPEC "\ | ||
226 | %(target_asm_spec) \ | ||
227 | %{mbig-endian:-EB} \ | ||
228 | +%{m64:-m64} \ | ||
229 | %{mlittle-endian:-EL}" | ||
230 | |||
231 | /* Extra switches sometimes passed to the linker. */ | ||
232 | @@ -110,6 +111,7 @@ extern enum pipeline_type microblaze_pipe; | ||
233 | #define LINK_SPEC "%{shared:-shared} -N -relax \ | ||
234 | %{mbig-endian:-EB --oformat=elf32-microblaze} \ | ||
235 | %{mlittle-endian:-EL --oformat=elf32-microblazeel} \ | ||
236 | + %{m64:-EL --oformat=elf64-microblazeel} \ | ||
237 | %{Zxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \ | ||
238 | %{mxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \ | ||
239 | %{mxl-gp-opt:%{G*}} %{!mxl-gp-opt: -G 0} \ | ||
240 | @@ -217,7 +219,7 @@ extern enum pipeline_type microblaze_pipe; | ||
241 | #define MIN_UNITS_PER_WORD 4 | ||
242 | #define INT_TYPE_SIZE 32 | ||
243 | #define SHORT_TYPE_SIZE 16 | ||
244 | -#define LONG_TYPE_SIZE 32 | ||
245 | +#define LONG_TYPE_SIZE 64 | ||
246 | #define LONG_LONG_TYPE_SIZE 64 | ||
247 | #define FLOAT_TYPE_SIZE 32 | ||
248 | #define DOUBLE_TYPE_SIZE 64 | ||
249 | diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md | ||
250 | index eb01221..dbb592e 100644 | ||
251 | --- a/gcc/config/microblaze/microblaze.md | ||
252 | +++ b/gcc/config/microblaze/microblaze.md | ||
253 | @@ -497,7 +497,6 @@ | ||
254 | (set_attr "mode" "SF") | ||
255 | (set_attr "length" "4")]) | ||
256 | |||
257 | - | ||
258 | (define_insn "divsf3" | ||
259 | [(set (match_operand:SF 0 "register_operand" "=d") | ||
260 | (div:SF (match_operand:SF 1 "register_operand" "d") | ||
261 | @@ -508,6 +507,7 @@ | ||
262 | (set_attr "mode" "SF") | ||
263 | (set_attr "length" "4")]) | ||
264 | |||
265 | + | ||
266 | (define_insn "sqrtsf2" | ||
267 | [(set (match_operand:SF 0 "register_operand" "=d") | ||
268 | (sqrt:SF (match_operand:SF 1 "register_operand" "d")))] | ||
269 | @@ -562,6 +562,18 @@ | ||
270 | |||
271 | ;; Adding 2 DI operands in register or reg/imm | ||
272 | |||
273 | +(define_insn "adddi3_long" | ||
274 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
275 | + (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%dJ,dJ") | ||
276 | + (match_operand:DI 2 "arith_plus_operand" "d,K")))] | ||
277 | + "TARGET_MB_64" | ||
278 | + "@ | ||
279 | + addlk\t%0,%z1,%2 | ||
280 | + addlik\t%0,%z1,%2" | ||
281 | + [(set_attr "type" "arith,arith") | ||
282 | + (set_attr "mode" "DI,DI") | ||
283 | + (set_attr "length" "4,4")]) | ||
284 | + | ||
285 | (define_insn "adddi3" | ||
286 | [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
287 | (plus:DI (match_operand:DI 1 "register_operand" "%d,d") | ||
288 | @@ -606,6 +618,18 @@ | ||
289 | ;; Double Precision Subtraction | ||
290 | ;;---------------------------------------------------------------- | ||
291 | |||
292 | +(define_insn "subdi3_long" | ||
293 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
294 | + (minus:DI (match_operand:DI 1 "register_operand" "d,d") | ||
295 | + (match_operand:DI 2 "register_operand" "d,n")))] | ||
296 | + "TARGET_MB_64" | ||
297 | + "@ | ||
298 | + rsubl\t%0,%2,%1 | ||
299 | + addlik\t%0,%z1,-%2" | ||
300 | + [(set_attr "type" "darith") | ||
301 | + (set_attr "mode" "DI,DI") | ||
302 | + (set_attr "length" "4,4")]) | ||
303 | + | ||
304 | (define_insn "subdi3" | ||
305 | [(set (match_operand:DI 0 "register_operand" "=&d") | ||
306 | (minus:DI (match_operand:DI 1 "register_operand" "d") | ||
307 | @@ -795,6 +819,15 @@ | ||
308 | (set_attr "mode" "SI") | ||
309 | (set_attr "length" "4")]) | ||
310 | |||
311 | +(define_insn "negdi2_long" | ||
312 | + [(set (match_operand:DI 0 "register_operand" "=d") | ||
313 | + (neg:DI (match_operand:DI 1 "register_operand" "d")))] | ||
314 | + "TARGET_MB_64" | ||
315 | + "rsubl\t%0,%1,r0" | ||
316 | + [(set_attr "type" "darith") | ||
317 | + (set_attr "mode" "DI") | ||
318 | + (set_attr "length" "4")]) | ||
319 | + | ||
320 | (define_insn "negdi2" | ||
321 | [(set (match_operand:DI 0 "register_operand" "=d") | ||
322 | (neg:DI (match_operand:DI 1 "register_operand" "d")))] | ||
323 | @@ -814,6 +847,15 @@ | ||
324 | (set_attr "mode" "SI") | ||
325 | (set_attr "length" "4")]) | ||
326 | |||
327 | +(define_insn "one_cmpldi2_long" | ||
328 | + [(set (match_operand:DI 0 "register_operand" "=d") | ||
329 | + (not:DI (match_operand:DI 1 "register_operand" "d")))] | ||
330 | + "TARGET_MB_64" | ||
331 | + "xorli\t%0,%1,-1" | ||
332 | + [(set_attr "type" "arith") | ||
333 | + (set_attr "mode" "DI") | ||
334 | + (set_attr "length" "4")]) | ||
335 | + | ||
336 | (define_insn "*one_cmpldi2" | ||
337 | [(set (match_operand:DI 0 "register_operand" "=d") | ||
338 | (not:DI (match_operand:DI 1 "register_operand" "d")))] | ||
339 | @@ -840,6 +882,20 @@ | ||
340 | ;; Logical | ||
341 | ;;---------------------------------------------------------------- | ||
342 | |||
343 | +(define_insn "anddi3" | ||
344 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
345 | + (and:DI (match_operand:DI 1 "arith_operand" "d,d") | ||
346 | + (match_operand:DI 2 "arith_operand" "d,K")))] | ||
347 | + "TARGET_MB_64" | ||
348 | + "@ | ||
349 | + andl\t%0,%1,%2 | ||
350 | + andli\t%0,%1,%2 #andl1" | ||
351 | + ;; andli\t%0,%1,%2 #andl3 | ||
352 | + ;; andli\t%0,%1,%2 #andl2 | ||
353 | + [(set_attr "type" "arith,arith") | ||
354 | + (set_attr "mode" "DI,DI") | ||
355 | + (set_attr "length" "4,4")]) | ||
356 | + | ||
357 | (define_insn "andsi3" | ||
358 | [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") | ||
359 | (and:SI (match_operand:SI 1 "arith_operand" "%d,d,d,d") | ||
360 | @@ -855,6 +911,18 @@ | ||
361 | (set_attr "length" "4,8,8,8")]) | ||
362 | |||
363 | |||
364 | +(define_insn "iordi3" | ||
365 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
366 | + (ior:DI (match_operand:DI 1 "arith_operand" "d,d") | ||
367 | + (match_operand:DI 2 "arith_operand" "d,K")))] | ||
368 | + "TARGET_MB_64" | ||
369 | + "@ | ||
370 | + orl\t%0,%1,%2 | ||
371 | + orli\t%0,%1,%2 #andl1" | ||
372 | + [(set_attr "type" "arith,arith") | ||
373 | + (set_attr "mode" "DI,DI") | ||
374 | + (set_attr "length" "4,4")]) | ||
375 | + | ||
376 | (define_insn "iorsi3" | ||
377 | [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") | ||
378 | (ior:SI (match_operand:SI 1 "arith_operand" "%d,d,d,d") | ||
379 | @@ -869,6 +937,19 @@ | ||
380 | (set_attr "mode" "SI,SI,SI,SI") | ||
381 | (set_attr "length" "4,8,8,8")]) | ||
382 | |||
383 | +(define_insn "xordi3" | ||
384 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
385 | + (xor:DI (match_operand:DI 1 "arith_operand" "%d,d") | ||
386 | + (match_operand:DI 2 "arith_operand" "d,K")))] | ||
387 | + "TARGET_MB_64" | ||
388 | + "@ | ||
389 | + xorl\t%0,%1,%2 | ||
390 | + xorli\t%0,%1,%2 #andl1" | ||
391 | + [(set_attr "type" "arith,arith") | ||
392 | + (set_attr "mode" "DI,DI") | ||
393 | + (set_attr "length" "4,4")]) | ||
394 | + | ||
395 | + | ||
396 | (define_insn "xorsi3" | ||
397 | [(set (match_operand:SI 0 "register_operand" "=d,d,d") | ||
398 | (xor:SI (match_operand:SI 1 "arith_operand" "%d,d,d") | ||
399 | @@ -937,6 +1018,26 @@ | ||
400 | (set_attr "mode" "SI") | ||
401 | (set_attr "length" "4")]) | ||
402 | |||
403 | +;;(define_expand "extendqidi2" | ||
404 | +;; [(set (match_operand:DI 0 "register_operand" "=d") | ||
405 | +;; (sign_extend:DI (match_operand:QI 1 "general_operand" "d")))] | ||
406 | +;; "TARGET_MB_64" | ||
407 | +;; { | ||
408 | +;; if (GET_CODE (operands[1]) != REG) | ||
409 | +;; FAIL; | ||
410 | +;; } | ||
411 | +;;) | ||
412 | + | ||
413 | + | ||
414 | +;;(define_insn "extendqidi2" | ||
415 | +;; [(set (match_operand:DI 0 "register_operand" "=d") | ||
416 | +;; (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))] | ||
417 | +;; "TARGET_MB_64" | ||
418 | +;; "sextl8\t%0,%1" | ||
419 | +;; [(set_attr "type" "arith") | ||
420 | +;; (set_attr "mode" "DI") | ||
421 | +;; (set_attr "length" "4")]) | ||
422 | + | ||
423 | (define_insn "extendhisi2" | ||
424 | [(set (match_operand:SI 0 "register_operand" "=d") | ||
425 | (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))] | ||
426 | @@ -946,6 +1047,16 @@ | ||
427 | (set_attr "mode" "SI") | ||
428 | (set_attr "length" "4")]) | ||
429 | |||
430 | +(define_insn "extendhidi2" | ||
431 | + [(set (match_operand:DI 0 "register_operand" "=d") | ||
432 | + (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))] | ||
433 | + "TARGET_MB_64" | ||
434 | + "sextl16\t%0,%1" | ||
435 | + [(set_attr "type" "arith") | ||
436 | + (set_attr "mode" "DI") | ||
437 | + (set_attr "length" "4")]) | ||
438 | + | ||
439 | + | ||
440 | ;; Those for integer source operand are ordered | ||
441 | ;; widest source type first. | ||
442 | |||
443 | @@ -1011,7 +1122,6 @@ | ||
444 | ) | ||
445 | |||
446 | |||
447 | - | ||
448 | (define_insn "*movdi_internal" | ||
449 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o") | ||
450 | (match_operand:DI 1 "general_operand" " d,i,J,R,o,d,d"))] | ||
451 | @@ -1423,6 +1533,36 @@ | ||
452 | (set_attr "length" "4,4")] | ||
453 | ) | ||
454 | |||
455 | +;; Barrel shift left | ||
456 | +(define_expand "ashldi3" | ||
457 | + [(set (match_operand:DI 0 "register_operand" "=&d") | ||
458 | + (ashift:DI (match_operand:DI 1 "register_operand" "d") | ||
459 | + (match_operand:DI 2 "arith_operand" "")))] | ||
460 | +"TARGET_MB_64" | ||
461 | +{ | ||
462 | +;;if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
463 | +if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
464 | + { | ||
465 | + emit_insn(gen_ashldi3_long (operands[0], operands[1],operands[2])); | ||
466 | + DONE; | ||
467 | + } | ||
468 | +else | ||
469 | + FAIL; | ||
470 | +} | ||
471 | +) | ||
472 | + | ||
473 | +(define_insn "ashldi3_long" | ||
474 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
475 | + (ashift:DI (match_operand:DI 1 "register_operand" "d,d") | ||
476 | + (match_operand:DI 2 "arith_operand" "I,d")))] | ||
477 | + "TARGET_MB_64" | ||
478 | + "@ | ||
479 | + bsllli\t%0,%1,%2 | ||
480 | + bslll\t%0,%1,%2" | ||
481 | + [(set_attr "type" "bshift,bshift") | ||
482 | + (set_attr "mode" "DI,DI") | ||
483 | + (set_attr "length" "4,4")] | ||
484 | +) | ||
485 | ;; The following patterns apply when there is no barrel shifter present | ||
486 | |||
487 | (define_insn "*ashlsi3_with_mul_delay" | ||
488 | @@ -1548,6 +1688,36 @@ | ||
489 | ;;---------------------------------------------------------------- | ||
490 | ;; 32-bit right shifts | ||
491 | ;;---------------------------------------------------------------- | ||
492 | +;; Barrel shift left | ||
493 | +(define_expand "ashrdi3" | ||
494 | + [(set (match_operand:DI 0 "register_operand" "=&d") | ||
495 | + (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") | ||
496 | + (match_operand:DI 2 "arith_operand" "")))] | ||
497 | +"TARGET_MB_64" | ||
498 | +{ | ||
499 | +;;if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
500 | +if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
501 | + { | ||
502 | + emit_insn(gen_ashrdi3_long (operands[0], operands[1],operands[2])); | ||
503 | + DONE; | ||
504 | + } | ||
505 | +else | ||
506 | + FAIL; | ||
507 | +} | ||
508 | +) | ||
509 | + | ||
510 | +(define_insn "ashrdi3_long" | ||
511 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
512 | + (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d") | ||
513 | + (match_operand:DI 2 "arith_operand" "I,d")))] | ||
514 | + "TARGET_MB_64" | ||
515 | + "@ | ||
516 | + bslrai\t%0,%1,%2 | ||
517 | + bslra\t%0,%1,%2" | ||
518 | + [(set_attr "type" "bshift,bshift") | ||
519 | + (set_attr "mode" "DI,DI") | ||
520 | + (set_attr "length" "4,4")] | ||
521 | + ) | ||
522 | (define_expand "ashrsi3" | ||
523 | [(set (match_operand:SI 0 "register_operand" "=&d") | ||
524 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") | ||
525 | @@ -1657,6 +1827,36 @@ | ||
526 | ;;---------------------------------------------------------------- | ||
527 | ;; 32-bit right shifts (logical) | ||
528 | ;;---------------------------------------------------------------- | ||
529 | +;; Barrel shift left | ||
530 | +(define_expand "lshrdi3" | ||
531 | + [(set (match_operand:DI 0 "register_operand" "=&d") | ||
532 | + (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | ||
533 | + (match_operand:DI 2 "arith_operand" "")))] | ||
534 | +"TARGET_MB_64" | ||
535 | +{ | ||
536 | +;;if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
537 | +if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
538 | + { | ||
539 | + emit_insn(gen_lshrdi3_long (operands[0], operands[1],operands[2])); | ||
540 | + DONE; | ||
541 | + } | ||
542 | +else | ||
543 | + FAIL; | ||
544 | +} | ||
545 | +) | ||
546 | + | ||
547 | +(define_insn "lshrdi3_long" | ||
548 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
549 | + (lshiftrt:DI (match_operand:DI 1 "register_operand" "d,d") | ||
550 | + (match_operand:DI 2 "arith_operand" "I,d")))] | ||
551 | + "TARGET_MB_64" | ||
552 | + "@ | ||
553 | + bslrli\t%0,%1,%2 | ||
554 | + bslrl\t%0,%1,%2" | ||
555 | + [(set_attr "type" "bshift,bshift") | ||
556 | + (set_attr "mode" "DI,DI") | ||
557 | + (set_attr "length" "4,4")] | ||
558 | + ) | ||
559 | |||
560 | (define_expand "lshrsi3" | ||
561 | [(set (match_operand:SI 0 "register_operand" "=&d") | ||
562 | @@ -1803,6 +2003,8 @@ | ||
563 | (set_attr "length" "4")] | ||
564 | ) | ||
565 | |||
566 | + | ||
567 | + | ||
568 | ;;---------------------------------------------------------------- | ||
569 | ;; Setting a register from an floating point comparison. | ||
570 | ;;---------------------------------------------------------------- | ||
571 | @@ -1818,6 +2020,18 @@ | ||
572 | (set_attr "length" "4")] | ||
573 | ) | ||
574 | |||
575 | +(define_insn "cstoredf4" | ||
576 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
577 | + (match_operator:DI 1 "ordered_comparison_operator" | ||
578 | + [(match_operand:DF 2 "register_operand" "r") | ||
579 | + (match_operand:DF 3 "register_operand" "r")]))] | ||
580 | + "TARGET_MB_64" | ||
581 | + "dcmp.%C1\t%0,%3,%2" | ||
582 | + [(set_attr "type" "fcmp") | ||
583 | + (set_attr "mode" "DF") | ||
584 | + (set_attr "length" "4")] | ||
585 | +) | ||
586 | + | ||
587 | ;;---------------------------------------------------------------- | ||
588 | ;; Conditional branches | ||
589 | ;;---------------------------------------------------------------- | ||
590 | @@ -1930,6 +2144,115 @@ | ||
591 | (set_attr "length" "12")] | ||
592 | ) | ||
593 | |||
594 | + | ||
595 | +(define_expand "cbranchdi4" | ||
596 | + [(set (pc) | ||
597 | + (if_then_else (match_operator 0 "ordered_comparison_operator" | ||
598 | + [(match_operand:DI 1 "register_operand") | ||
599 | + (match_operand:DI 2 "arith_operand" "I,i")]) | ||
600 | + (label_ref (match_operand 3 "")) | ||
601 | + (pc)))] | ||
602 | + "TARGET_MB_64" | ||
603 | +{ | ||
604 | + microblaze_expand_conditional_branch (DImode, operands); | ||
605 | + DONE; | ||
606 | +}) | ||
607 | + | ||
608 | +(define_expand "cbranchdi4_reg" | ||
609 | + [(set (pc) | ||
610 | + (if_then_else (match_operator 0 "ordered_comparison_operator" | ||
611 | + [(match_operand:DI 1 "register_operand") | ||
612 | + (match_operand:DI 2 "register_operand")]) | ||
613 | + (label_ref (match_operand 3 "")) | ||
614 | + (pc)))] | ||
615 | + "TARGET_MB_64" | ||
616 | +{ | ||
617 | + microblaze_expand_conditional_branch_reg (DImode, operands); | ||
618 | + DONE; | ||
619 | +}) | ||
620 | + | ||
621 | +(define_expand "cbranchdf4" | ||
622 | + [(set (pc) | ||
623 | + (if_then_else (match_operator 0 "ordered_comparison_operator" | ||
624 | + [(match_operand:DF 1 "register_operand") | ||
625 | + (match_operand:DF 2 "register_operand")]) | ||
626 | + (label_ref (match_operand 3 "")) | ||
627 | + (pc)))] | ||
628 | + "TARGET_MB_64" | ||
629 | +{ | ||
630 | + microblaze_expand_conditional_branch_df (operands); | ||
631 | + DONE; | ||
632 | + | ||
633 | +}) | ||
634 | + | ||
635 | +;; Used to implement comparison instructions | ||
636 | +(define_expand "long_condjump" | ||
637 | + [(set (pc) | ||
638 | + (if_then_else (match_operand 0) | ||
639 | + (label_ref (match_operand 1)) | ||
640 | + (pc)))]) | ||
641 | + | ||
642 | +(define_insn "long_branch_zero" | ||
643 | + [(set (pc) | ||
644 | + (if_then_else (match_operator:DI 0 "ordered_comparison_operator" | ||
645 | + [(match_operand:DI 1 "register_operand" "d") | ||
646 | + (const_int 0)]) | ||
647 | + (match_operand:DI 2 "pc_or_label_operand" "") | ||
648 | + (match_operand:DI 3 "pc_or_label_operand" ""))) | ||
649 | + ] | ||
650 | + "TARGET_MB_64" | ||
651 | + { | ||
652 | + if (operands[3] == pc_rtx) | ||
653 | + return "beal%C0i%?\t%z1,%2"; | ||
654 | + else | ||
655 | + return "beal%N0i%?\t%z1,%3"; | ||
656 | + } | ||
657 | + [(set_attr "type" "branch") | ||
658 | + (set_attr "mode" "none") | ||
659 | + (set_attr "length" "4")] | ||
660 | +) | ||
661 | + | ||
662 | +(define_insn "long_branch_compare" | ||
663 | + [(set (pc) | ||
664 | + (if_then_else (match_operator:DI 0 "cmp_op" | ||
665 | + [(match_operand:DI 1 "register_operand" "d") | ||
666 | + (match_operand:DI 2 "register_operand" "d") | ||
667 | + ]) | ||
668 | + (label_ref (match_operand 3)) | ||
669 | + (pc))) | ||
670 | + (clobber(reg:DI R_TMP))] | ||
671 | + "TARGET_MB_64" | ||
672 | + { | ||
673 | + operands[4] = gen_rtx_REG (DImode, MB_ABI_ASM_TEMP_REGNUM); | ||
674 | + enum rtx_code code = GET_CODE (operands[0]); | ||
675 | + | ||
676 | + if (code == GT || code == LE) | ||
677 | + { | ||
678 | + output_asm_insn ("cmpl\tr18,%z1,%z2", operands); | ||
679 | + code = swap_condition (code); | ||
680 | + } | ||
681 | + else if (code == GTU || code == LEU) | ||
682 | + { | ||
683 | + output_asm_insn ("cmplu\tr18,%z1,%z2", operands); | ||
684 | + code = swap_condition (code); | ||
685 | + } | ||
686 | + else if (code == GE || code == LT) | ||
687 | + { | ||
688 | + output_asm_insn ("cmpl\tr18,%z2,%z1", operands); | ||
689 | + } | ||
690 | + else if (code == GEU || code == LTU) | ||
691 | + { | ||
692 | + output_asm_insn ("cmplu\tr18,%z2,%z1", operands); | ||
693 | + } | ||
694 | + | ||
695 | + operands[0] = gen_rtx_fmt_ee (signed_condition (code), DImode, operands[4], const0_rtx); | ||
696 | + return "beal%C0i%?\tr18,%3"; | ||
697 | + } | ||
698 | + [(set_attr "type" "branch") | ||
699 | + (set_attr "mode" "none") | ||
700 | + (set_attr "length" "12")] | ||
701 | +) | ||
702 | + | ||
703 | ;;---------------------------------------------------------------- | ||
704 | ;; Unconditional branches | ||
705 | ;;---------------------------------------------------------------- | ||
706 | @@ -2478,17 +2801,33 @@ | ||
707 | DONE; | ||
708 | }") | ||
709 | |||
710 | -(define_expand "extzvsi" | ||
711 | +(define_expand "extvsi" | ||
712 | [(set (match_operand:SI 0 "register_operand" "r") | ||
713 | (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | ||
714 | (match_operand:SI 2 "immediate_operand" "I") | ||
715 | (match_operand:SI 3 "immediate_operand" "I")))] | ||
716 | "TARGET_HAS_BITFIELD" | ||
717 | -"" | ||
718 | -) | ||
719 | - | ||
720 | +" | ||
721 | +{ | ||
722 | + unsigned HOST_WIDE_INT len = UINTVAL (operands[2]); | ||
723 | + unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]); | ||
724 | + | ||
725 | + if ((len == 0) || (pos + len > 32) ) | ||
726 | + FAIL; | ||
727 | + | ||
728 | + ;;if (!register_operand (operands[1], VOIDmode)) | ||
729 | + ;; FAIL; | ||
730 | + if (operands[0] == operands[1]) | ||
731 | + FAIL; | ||
732 | + if (GET_CODE (operands[1]) == ASHIFT) | ||
733 | + FAIL; | ||
734 | +;; operands[2] = GEN_INT(INTVAL(operands[2])+1 ); | ||
735 | + emit_insn (gen_extv_32 (operands[0], operands[1], | ||
736 | + operands[2], operands[3])); | ||
737 | + DONE; | ||
738 | +}") | ||
739 | |||
740 | -(define_insn "extzv_32" | ||
741 | +(define_insn "extv_32" | ||
742 | [(set (match_operand:SI 0 "register_operand" "=r") | ||
743 | (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | ||
744 | (match_operand:SI 2 "immediate_operand" "I") | ||
745 | @@ -2505,8 +2844,21 @@ | ||
746 | (match_operand:SI 2 "immediate_operand" "I")) | ||
747 | (match_operand:SI 3 "register_operand" "r"))] | ||
748 | "TARGET_HAS_BITFIELD" | ||
749 | -"" | ||
750 | -) | ||
751 | + " | ||
752 | +{ | ||
753 | + unsigned HOST_WIDE_INT len = UINTVAL (operands[1]); | ||
754 | + unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]); | ||
755 | + | ||
756 | + if (len <= 0 || pos + len > 32) | ||
757 | + FAIL; | ||
758 | + | ||
759 | + ;;if (!register_operand (operands[0], VOIDmode)) | ||
760 | + ;; FAIL; | ||
761 | + | ||
762 | + emit_insn (gen_insv_32 (operands[0], operands[1], | ||
763 | + operands[2], operands[3])); | ||
764 | + DONE; | ||
765 | +}") | ||
766 | |||
767 | (define_insn "insv_32" | ||
768 | [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") | ||
769 | diff --git a/gcc/config/microblaze/microblaze.opt b/gcc/config/microblaze/microblaze.opt | ||
770 | index d23f376..f316e27 100644 | ||
771 | --- a/gcc/config/microblaze/microblaze.opt | ||
772 | +++ b/gcc/config/microblaze/microblaze.opt | ||
773 | @@ -136,4 +136,9 @@ Target | ||
774 | |||
775 | mxl-frequency | ||
776 | Target Mask(AREA_OPTIMIZED_2) | ||
777 | -Use 8 stage pipeline (frequency optimization) | ||
778 | +Use 8 stage pipeline (frequency optimization). | ||
779 | + | ||
780 | +m64 | ||
781 | +Target Mask(MB_64) | ||
782 | +MicroBlaze 64-bit mode. | ||
783 | + | ||
784 | diff --git a/gcc/config/microblaze/t-microblaze b/gcc/config/microblaze/t-microblaze | ||
785 | index 41fa9a9..e9a1921 100644 | ||
786 | --- a/gcc/config/microblaze/t-microblaze | ||
787 | +++ b/gcc/config/microblaze/t-microblaze | ||
788 | @@ -1,8 +1,11 @@ | ||
789 | -MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high mlittle-endian | ||
790 | -MULTILIB_DIRNAMES = bs m mh le | ||
791 | +MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high mlittle-endian m64 | ||
792 | +MULTILIB_DIRNAMES = bs m mh le m64 | ||
793 | MULTILIB_EXCEPTIONS = *mxl-barrel-shift/mxl-multiply-high mxl-multiply-high | ||
794 | MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian | ||
795 | +MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64 | ||
796 | MULTILIB_EXCEPTIONS += mxl-multiply-high/mlittle-endian | ||
797 | +MULTILIB_EXCEPTIONS += mxl-multiply-high/m64 | ||
798 | +MULTILIB_EXCEPTIONS += *mxl-multiply-high/mlittle-endian/m64 | ||
799 | |||
800 | # Extra files | ||
801 | microblaze-c.o: $(srcdir)/config/microblaze/microblaze-c.c \ | ||
802 | -- | ||
803 | 2.7.4 | ||
804 | |||