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