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