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