summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools/gcc/gcc-11/0029-Patch-MicroBlaze-Intial-commit-of-64-bit-Microblaze.patch
diff options
context:
space:
mode:
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.patch845
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 @@
1From 1a7fda96cb247bad0a4df61cd8fd3e65c0e6f35d Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 10 Nov 2020 12:52:54 +0530
4Subject: [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
16diff --git a/gcc/config/microblaze/constraints.md b/gcc/config/microblaze/constraints.md
17index 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"
33diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
34index 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);
45diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
46index 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
236diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
237index 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
265diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
266index 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")
810diff --git a/gcc/config/microblaze/microblaze.opt b/gcc/config/microblaze/microblaze.opt
811index 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+
825diff --git a/gcc/config/microblaze/t-microblaze b/gcc/config/microblaze/t-microblaze
826index 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--
8442.17.1
845