blob: 88a0d0ba10d85a27bb5b1ff5987a3899166de81f [file] [log] [blame]
Brad Bishopf6355e42020-12-08 14:30:50 -05001From 53799d63bd26a04265a55f68ca57e3462ed6eeb7 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Fri, 27 Jul 2018 15:23:41 +0530
4Subject: [PATCH 30/54] Intial commit for 64bit-MB sources. Need to cleanup the
5 code later.
6
7---
8 gcc/config/microblaze/constraints.md | 2 +-
9 gcc/config/microblaze/microblaze-c.c | 6 +
10 gcc/config/microblaze/microblaze.c | 218 ++++++---
11 gcc/config/microblaze/microblaze.h | 63 ++-
12 gcc/config/microblaze/microblaze.md | 606 ++++++++++++++++++------
13 gcc/config/microblaze/t-microblaze | 3 +-
14 libgcc/config/microblaze/crti.S | 4 +-
15 libgcc/config/microblaze/crtn.S | 4 +-
16 libgcc/config/microblaze/divdi3.S | 98 ++++
17 libgcc/config/microblaze/divdi3_table.c | 62 +++
18 libgcc/config/microblaze/moddi3.S | 97 ++++
19 libgcc/config/microblaze/muldi3.S | 73 +++
20 libgcc/config/microblaze/t-microblaze | 11 +-
21 libgcc/config/microblaze/udivdi3.S | 107 +++++
22 libgcc/config/microblaze/umoddi3.S | 110 +++++
23 15 files changed, 1230 insertions(+), 234 deletions(-)
24 create mode 100644 libgcc/config/microblaze/divdi3.S
25 create mode 100644 libgcc/config/microblaze/divdi3_table.c
26 create mode 100644 libgcc/config/microblaze/moddi3.S
27 create mode 100644 libgcc/config/microblaze/muldi3.S
28 create mode 100644 libgcc/config/microblaze/udivdi3.S
29 create mode 100644 libgcc/config/microblaze/umoddi3.S
30
31diff --git a/gcc/config/microblaze/constraints.md b/gcc/config/microblaze/constraints.md
32index 123395717e0..b8ef1650f92 100644
33--- a/gcc/config/microblaze/constraints.md
34+++ b/gcc/config/microblaze/constraints.md
35@@ -55,7 +55,7 @@
36 (define_constraint "K"
37 "A constant in the range 0xffffff8000000000L to 0x0000007fffffffffL (inclusive)."
38 (and (match_code "const_int")
39- (match_test "ival > (long)0xffffff8000000000L && ival < (long)0x0000007fffffffffL")))
40+ (match_test "ival > (long)-549755813888 && ival < (long)549755813887")))
41
42
43 ;; Define floating point constraints
44diff --git a/gcc/config/microblaze/microblaze-c.c b/gcc/config/microblaze/microblaze-c.c
45index d8c88e510e5..dbcd21fc6ee 100644
46--- a/gcc/config/microblaze/microblaze-c.c
47+++ b/gcc/config/microblaze/microblaze-c.c
48@@ -100,4 +100,10 @@ microblaze_cpp_define (cpp_reader *pfile)
49 builtin_define ("HAVE_HW_FPU_SQRT");
50 builtin_define ("__HAVE_HW_FPU_SQRT__");
51 }
52+ if (TARGET_MB_64)
53+ {
54+ builtin_define ("__arch64__");
55+ builtin_define ("__microblaze64__");
56+ builtin_define ("__MICROBLAZE64__");
57+ }
58 }
59diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
60index 99a1cd5c0be..3c815444574 100644
61--- a/gcc/config/microblaze/microblaze.c
62+++ b/gcc/config/microblaze/microblaze.c
63@@ -383,10 +383,10 @@ simple_memory_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
64 {
65 return 1;
66 }
67- else if (GET_CODE (plus0) == REG && GET_CODE (plus1) == REG)
68+ /*else if (GET_CODE (plus0) == REG && GET_CODE (plus1) == REG)
69 {
70 return 1;
71- }
72+ }*/
73 else
74 return 0;
75
76@@ -434,7 +434,7 @@ double_memory_operand (rtx op, machine_mode mode)
77 return 1;
78
79 return memory_address_p ((GET_MODE_CLASS (mode) == MODE_INT
80- ? E_SImode : E_SFmode),
81+ ? Pmode : E_SFmode),
82 plus_constant (Pmode, addr, 4));
83 }
84
85@@ -681,7 +681,7 @@ microblaze_legitimize_tls_address(rtx x, rtx reg)
86 /* Load the addend. */
87 addend = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (TLS_DTPREL)),
88 UNSPEC_TLS);
89- addend = force_reg (SImode, gen_rtx_CONST (SImode, addend));
90+ addend = force_reg (Pmode, gen_rtx_CONST (Pmode, addend));
91 dest = gen_rtx_PLUS (Pmode, dest, addend);
92 break;
93
94@@ -699,7 +699,7 @@ microblaze_classify_unspec (struct microblaze_address_info *info, rtx x)
95
96 if (XINT (x, 1) == UNSPEC_GOTOFF)
97 {
98- info->regA = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
99+ info->regA = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
100 info->type = ADDRESS_GOTOFF;
101 }
102 else if (XINT (x, 1) == UNSPEC_PLT)
103@@ -1302,8 +1302,16 @@ microblaze_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length)
104 emit_move_insn (dest_reg, plus_constant (Pmode, dest_reg, MAX_MOVE_BYTES));
105
106 /* Emit the test & branch. */
107- emit_insn (gen_cbranchsi4 (gen_rtx_NE (SImode, src_reg, final_src),
108+
109+ if (TARGET_MB_64) {
110+ emit_insn (gen_cbranchdi4 (gen_rtx_NE (Pmode, src_reg, final_src),
111+ src_reg, final_src, label));
112+ }
113+ else {
114+ emit_insn (gen_cbranchsi4 (gen_rtx_NE (Pmode, src_reg, final_src),
115 src_reg, final_src, label));
116+
117+ }
118
119 /* Mop up any left-over bytes. */
120 if (leftover)
121@@ -1633,14 +1641,20 @@ microblaze_function_arg_advance (cumulative_args_t cum_v,
122 break;
123
124 case E_DFmode:
125- cum->arg_words += 2;
126+ if (TARGET_MB_64)
127+ cum->arg_words++;
128+ else
129+ cum->arg_words += 2;
130 if (!cum->gp_reg_found && cum->arg_number <= 2)
131 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
132 break;
133
134 case E_DImode:
135 cum->gp_reg_found = 1;
136- cum->arg_words += 2;
137+ if (TARGET_MB_64)
138+ cum->arg_words++;
139+ else
140+ cum->arg_words += 2;
141 break;
142
143 case E_QImode:
144@@ -2155,7 +2169,7 @@ compute_frame_size (HOST_WIDE_INT size)
145
146 if (regno != MB_ABI_SUB_RETURN_ADDR_REGNUM)
147 /* Don't account for link register. It is accounted specially below. */
148- gp_reg_size += GET_MODE_SIZE (SImode);
149+ gp_reg_size += GET_MODE_SIZE (Pmode);
150
151 mask |= (1L << (regno - GP_REG_FIRST));
152 }
153@@ -2424,7 +2438,7 @@ print_operand (FILE * file, rtx op, int letter)
154
155 if ((letter == 'M' && !WORDS_BIG_ENDIAN)
156 || (letter == 'L' && WORDS_BIG_ENDIAN) || letter == 'D')
157- regnum++;
158+ regnum++;
159
160 fprintf (file, "%s", reg_names[regnum]);
161 }
162@@ -2450,6 +2464,7 @@ print_operand (FILE * file, rtx op, int letter)
163 else if (letter == 'h' || letter == 'j')
164 {
165 long val[2];
166+ int val1[2];
167 long l[2];
168 if (code == CONST_DOUBLE)
169 {
170@@ -2462,12 +2477,12 @@ print_operand (FILE * file, rtx op, int letter)
171 val[0] = l[WORDS_BIG_ENDIAN != 0];
172 }
173 }
174- else if (code == CONST_INT)
175+ else if (code == CONST_INT || code == CONST)// || code == SYMBOL_REF ||code == LABEL_REF)
176 {
177- val[0] = (INTVAL (op) & 0xffffffff00000000LL) >> 32;
178- val[1] = INTVAL (op) & 0x00000000ffffffffLL;
179+ val1[0] = (INTVAL (op) & 0xffffffff00000000LL) >> 32;
180+ val1[1] = INTVAL (op) & 0x00000000ffffffffLL;
181 }
182- fprintf (file, "0x%8.8lx", (letter == 'h') ? val[0] : val[1]);
183+ fprintf (file, "0x%8.8lx", (letter == 'h') ? val1[0] : val1[1]);
184 }
185 else if (code == CONST_DOUBLE)
186 {
187@@ -2661,7 +2676,10 @@ microblaze_asm_constructor (rtx symbol ATTRIBUTE_UNUSED, int priority)
188
189 switch_to_section (get_section (section, 0, NULL));
190 assemble_align (POINTER_SIZE);
191- fputs ("\t.word\t", asm_out_file);
192+ if (TARGET_MB_64)
193+ fputs ("\t.dword\t", asm_out_file);
194+ else
195+ fputs ("\t.word\t", asm_out_file);
196 output_addr_const (asm_out_file, symbol);
197 fputs ("\n", asm_out_file);
198 }
199@@ -2684,7 +2702,10 @@ microblaze_asm_destructor (rtx symbol, int priority)
200
201 switch_to_section (get_section (section, 0, NULL));
202 assemble_align (POINTER_SIZE);
203- fputs ("\t.word\t", asm_out_file);
204+ if (TARGET_MB_64)
205+ fputs ("\t.dword\t", asm_out_file);
206+ else
207+ fputs ("\t.word\t", asm_out_file);
208 output_addr_const (asm_out_file, symbol);
209 fputs ("\n", asm_out_file);
210 }
211@@ -2750,7 +2771,7 @@ save_restore_insns (int prologue)
212 /* For interrupt_handlers, need to save/restore the MSR. */
213 if (microblaze_is_interrupt_variant ())
214 {
215- isr_mem_rtx = gen_rtx_MEM (SImode,
216+ isr_mem_rtx = gen_rtx_MEM (Pmode,
217 gen_rtx_PLUS (Pmode, base_reg_rtx,
218 GEN_INT (current_frame_info.
219 gp_offset -
220@@ -2758,8 +2779,8 @@ save_restore_insns (int prologue)
221
222 /* Do not optimize in flow analysis. */
223 MEM_VOLATILE_P (isr_mem_rtx) = 1;
224- isr_reg_rtx = gen_rtx_REG (SImode, MB_ABI_MSR_SAVE_REG);
225- isr_msr_rtx = gen_rtx_REG (SImode, ST_REG);
226+ isr_reg_rtx = gen_rtx_REG (Pmode, MB_ABI_MSR_SAVE_REG);
227+ isr_msr_rtx = gen_rtx_REG (Pmode, ST_REG);
228 }
229
230 if (microblaze_is_interrupt_variant () && !prologue)
231@@ -2767,8 +2788,8 @@ save_restore_insns (int prologue)
232 emit_move_insn (isr_reg_rtx, isr_mem_rtx);
233 emit_move_insn (isr_msr_rtx, isr_reg_rtx);
234 /* Do not optimize in flow analysis. */
235- emit_insn (gen_rtx_USE (SImode, isr_reg_rtx));
236- emit_insn (gen_rtx_USE (SImode, isr_msr_rtx));
237+ emit_insn (gen_rtx_USE (Pmode, isr_reg_rtx));
238+ emit_insn (gen_rtx_USE (Pmode, isr_msr_rtx));
239 }
240
241 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
242@@ -2779,9 +2800,9 @@ save_restore_insns (int prologue)
243 /* Don't handle here. Already handled as the first register. */
244 continue;
245
246- reg_rtx = gen_rtx_REG (SImode, regno);
247+ reg_rtx = gen_rtx_REG (Pmode, regno);
248 insn = gen_rtx_PLUS (Pmode, base_reg_rtx, GEN_INT (gp_offset));
249- mem_rtx = gen_rtx_MEM (SImode, insn);
250+ mem_rtx = gen_rtx_MEM (Pmode, insn);
251 if (microblaze_is_interrupt_variant () || save_volatiles)
252 /* Do not optimize in flow analysis. */
253 MEM_VOLATILE_P (mem_rtx) = 1;
254@@ -2796,7 +2817,7 @@ save_restore_insns (int prologue)
255 insn = emit_move_insn (reg_rtx, mem_rtx);
256 }
257
258- gp_offset += GET_MODE_SIZE (SImode);
259+ gp_offset += GET_MODE_SIZE (Pmode);
260 }
261 }
262
263@@ -2806,8 +2827,8 @@ save_restore_insns (int prologue)
264 emit_move_insn (isr_mem_rtx, isr_reg_rtx);
265
266 /* Do not optimize in flow analysis. */
267- emit_insn (gen_rtx_USE (SImode, isr_reg_rtx));
268- emit_insn (gen_rtx_USE (SImode, isr_msr_rtx));
269+ emit_insn (gen_rtx_USE (Pmode, isr_reg_rtx));
270+ emit_insn (gen_rtx_USE (Pmode, isr_msr_rtx));
271 }
272
273 /* Done saving and restoring */
274@@ -2897,7 +2918,10 @@ microblaze_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
275
276 switch_to_section (s);
277 assemble_align (POINTER_SIZE);
278- fputs ("\t.word\t", asm_out_file);
279+ if (TARGET_MB_64)
280+ fputs ("\t.dword\t", asm_out_file);
281+ else
282+ fputs ("\t.word\t", asm_out_file);
283 output_addr_const (asm_out_file, symbol);
284 fputs ("\n", asm_out_file);
285 }
286@@ -3041,10 +3065,10 @@ microblaze_expand_prologue (void)
287 {
288 if (offset != 0)
289 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
290- emit_move_insn (gen_rtx_MEM (SImode, ptr),
291- gen_rtx_REG (SImode, regno));
292+ emit_move_insn (gen_rtx_MEM (Pmode, ptr),
293+ gen_rtx_REG (Pmode, regno));
294
295- offset += GET_MODE_SIZE (SImode);
296+ offset += GET_MODE_SIZE (Pmode);
297 }
298 }
299
300@@ -3053,15 +3077,23 @@ microblaze_expand_prologue (void)
301 rtx fsiz_rtx = GEN_INT (fsiz);
302
303 rtx_insn *insn = NULL;
304- insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
305+ if (TARGET_MB_64)
306+ {
307+
308+ insn = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
309 fsiz_rtx));
310+ }
311+ else {
312+ insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
313+ fsiz_rtx));
314+ }
315 if (insn)
316 RTX_FRAME_RELATED_P (insn) = 1;
317
318 /* Handle SUB_RETURN_ADDR_REGNUM specially at first. */
319 if (!crtl->is_leaf || interrupt_handler)
320 {
321- mem_rtx = gen_rtx_MEM (SImode,
322+ mem_rtx = gen_rtx_MEM (Pmode,
323 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
324 const0_rtx));
325
326@@ -3069,7 +3101,7 @@ microblaze_expand_prologue (void)
327 /* Do not optimize in flow analysis. */
328 MEM_VOLATILE_P (mem_rtx) = 1;
329
330- reg_rtx = gen_rtx_REG (SImode, MB_ABI_SUB_RETURN_ADDR_REGNUM);
331+ reg_rtx = gen_rtx_REG (Pmode, MB_ABI_SUB_RETURN_ADDR_REGNUM);
332 insn = emit_move_insn (mem_rtx, reg_rtx);
333 RTX_FRAME_RELATED_P (insn) = 1;
334 }
335@@ -3179,12 +3211,12 @@ microblaze_expand_epilogue (void)
336 if (!crtl->is_leaf || interrupt_handler)
337 {
338 mem_rtx =
339- gen_rtx_MEM (SImode,
340+ gen_rtx_MEM (Pmode,
341 gen_rtx_PLUS (Pmode, stack_pointer_rtx, const0_rtx));
342 if (interrupt_handler)
343 /* Do not optimize in flow analysis. */
344 MEM_VOLATILE_P (mem_rtx) = 1;
345- reg_rtx = gen_rtx_REG (SImode, MB_ABI_SUB_RETURN_ADDR_REGNUM);
346+ reg_rtx = gen_rtx_REG (Pmode, MB_ABI_SUB_RETURN_ADDR_REGNUM);
347 emit_move_insn (reg_rtx, mem_rtx);
348 }
349
350@@ -3200,15 +3232,25 @@ microblaze_expand_epilogue (void)
351 /* _restore_ registers for epilogue. */
352 save_restore_insns (0);
353 emit_insn (gen_blockage ());
354- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, fsiz_rtx));
355+ if (TARGET_MB_64)
356+ emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, fsiz_rtx));
357+ else
358+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, fsiz_rtx));
359 }
360
361 if (crtl->calls_eh_return)
362- emit_insn (gen_addsi3 (stack_pointer_rtx,
363+ if (TARGET_MB_64) {
364+ emit_insn (gen_adddi3 (stack_pointer_rtx,
365 stack_pointer_rtx,
366- gen_raw_REG (SImode,
367+ gen_raw_REG (Pmode,
368 MB_EH_STACKADJ_REGNUM)));
369-
370+ }
371+ else {
372+ emit_insn (gen_addsi3 (stack_pointer_rtx,
373+ stack_pointer_rtx,
374+ gen_raw_REG (Pmode,
375+ MB_EH_STACKADJ_REGNUM)));
376+ }
377 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, GP_REG_FIRST +
378 MB_ABI_SUB_RETURN_ADDR_REGNUM)));
379 }
380@@ -3375,9 +3417,14 @@ microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
381 else
382 this_rtx = gen_rtx_REG (Pmode, MB_ABI_FIRST_ARG_REGNUM);
383
384- /* Apply the constant offset, if required. */
385+ /* Apply the constant offset, if required. */
386 if (delta)
387- emit_insn (gen_addsi3 (this_rtx, this_rtx, GEN_INT (delta)));
388+ {
389+ if (TARGET_MB_64)
390+ emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (delta)));
391+ else
392+ emit_insn (gen_addsi3 (this_rtx, this_rtx, GEN_INT (delta)));
393+ }
394
395 /* Apply the offset from the vtable, if required. */
396 if (vcall_offset)
397@@ -3390,7 +3437,10 @@ microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
398 rtx loc = gen_rtx_PLUS (Pmode, temp1, vcall_offset_rtx);
399 emit_move_insn (temp1, gen_rtx_MEM (Pmode, loc));
400
401- emit_insn (gen_addsi3 (this_rtx, this_rtx, temp1));
402+ if (TARGET_MB_64)
403+ emit_insn (gen_adddi3 (this_rtx, this_rtx, temp1));
404+ else
405+ emit_insn (gen_addsi3 (this_rtx, this_rtx, temp1));
406 }
407
408 /* Generate a tail call to the target function. */
409@@ -3566,7 +3616,7 @@ microblaze_eh_return (rtx op0)
410 /* Queue an .ident string in the queue of top-level asm statements.
411 If the string size is below the threshold, put it into .sdata2.
412 If the front-end is done, we must be being called from toplev.c.
413- In that case, do nothing. */
414+ In that case, do nothing. */
415 void
416 microblaze_asm_output_ident (const char *string)
417 {
418@@ -3621,9 +3671,9 @@ microblaze_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
419 emit_block_move (m_tramp, assemble_trampoline_template (),
420 GEN_INT (6*UNITS_PER_WORD), BLOCK_OP_NORMAL);
421
422- mem = adjust_address (m_tramp, SImode, 16);
423+ mem = adjust_address (m_tramp, Pmode, 16);
424 emit_move_insn (mem, chain_value);
425- mem = adjust_address (m_tramp, SImode, 20);
426+ mem = adjust_address (m_tramp, Pmode, 20);
427 emit_move_insn (mem, fnaddr);
428 }
429
430@@ -3647,7 +3697,7 @@ microblaze_expand_conditional_branch (machine_mode mode, rtx operands[])
431 {
432 comp_reg = cmp_op0;
433 condition = gen_rtx_fmt_ee (signed_condition (code), mode, comp_reg, const0_rtx);
434- if (mode == SImode)
435+ if (mode == Pmode)
436 emit_jump_insn (gen_condjump (condition, label1));
437 else
438 emit_jump_insn (gen_long_condjump (condition, label1));
439@@ -3766,7 +3816,7 @@ microblaze_expand_conditional_branch_sf (rtx operands[])
440 rtx comp_reg = gen_reg_rtx (SImode);
441
442 emit_insn (gen_cstoresf4 (comp_reg, operands[0], cmp_op0, cmp_op1));
443- condition = gen_rtx_NE (SImode, comp_reg, const0_rtx);
444+ condition = gen_rtx_NE (Pmode, comp_reg, const0_rtx);
445 emit_jump_insn (gen_condjump (condition, operands[3]));
446 }
447
448@@ -3776,10 +3826,10 @@ microblaze_expand_conditional_branch_df (rtx operands[])
449 rtx condition;
450 rtx cmp_op0 = XEXP (operands[0], 0);
451 rtx cmp_op1 = XEXP (operands[0], 1);
452- rtx comp_reg = gen_reg_rtx (DImode);
453+ rtx comp_reg = gen_reg_rtx (Pmode);
454
455 emit_insn (gen_cstoredf4 (comp_reg, operands[0], cmp_op0, cmp_op1));
456- condition = gen_rtx_NE (DImode, comp_reg, const0_rtx);
457+ condition = gen_rtx_NE (Pmode, comp_reg, const0_rtx);
458 emit_jump_insn (gen_long_condjump (condition, operands[3]));
459 }
460
461@@ -3800,8 +3850,8 @@ microblaze_expand_divide (rtx operands[])
462 {
463 /* Table lookup software divides. Works for all (nr/dr) where (0 <= nr,dr <= 15). */
464
465- rtx regt1 = gen_reg_rtx (SImode);
466- rtx reg18 = gen_rtx_REG (SImode, R_TMP);
467+ rtx regt1 = gen_reg_rtx (Pmode);
468+ rtx reg18 = gen_rtx_REG (Pmode, R_TMP);
469 rtx regqi = gen_reg_rtx (QImode);
470 rtx_code_label *div_label = gen_label_rtx ();
471 rtx_code_label *div_end_label = gen_label_rtx ();
472@@ -3809,17 +3859,31 @@ microblaze_expand_divide (rtx operands[])
473 rtx mem_rtx;
474 rtx ret;
475 rtx_insn *jump, *cjump, *insn;
476-
477- insn = emit_insn (gen_iorsi3 (regt1, operands[1], operands[2]));
478- cjump = emit_jump_insn_after (gen_cbranchsi4 (
479- gen_rtx_GTU (SImode, regt1, GEN_INT (15)),
480+
481+ if (TARGET_MB_64) {
482+ insn = emit_insn (gen_iordi3 (regt1, operands[1], operands[2]));
483+ cjump = emit_jump_insn_after (gen_cbranchdi4 (
484+ gen_rtx_GTU (Pmode, regt1, GEN_INT (15)),
485+ regt1, GEN_INT (15), div_label), insn);
486+ }
487+ else {
488+ insn = emit_insn (gen_iorsi3 (regt1, operands[1], operands[2]));
489+ cjump = emit_jump_insn_after (gen_cbranchsi4 (
490+ gen_rtx_GTU (Pmode, regt1, GEN_INT (15)),
491 regt1, GEN_INT (15), div_label), insn);
492+ }
493 LABEL_NUSES (div_label) = 1;
494 JUMP_LABEL (cjump) = div_label;
495- emit_insn (gen_rtx_CLOBBER (SImode, reg18));
496+ emit_insn (gen_rtx_CLOBBER (Pmode, reg18));
497
498- emit_insn (gen_ashlsi3_bshift (regt1, operands[1], GEN_INT(4)));
499- emit_insn (gen_addsi3 (regt1, regt1, operands[2]));
500+ if (TARGET_MB_64) {
501+ emit_insn (gen_ashldi3_long (regt1, operands[1], GEN_INT(4)));
502+ emit_insn (gen_adddi3 (regt1, regt1, operands[2]));
503+ }
504+ else {
505+ emit_insn (gen_ashlsi3_bshift (regt1, operands[1], GEN_INT(4)));
506+ emit_insn (gen_addsi3 (regt1, regt1, operands[2]));
507+ }
508 mem_rtx = gen_rtx_MEM (QImode,
509 gen_rtx_PLUS (QImode, regt1, div_table_rtx));
510
511@@ -3966,7 +4030,7 @@ insert_wic_for_ilb_runout (rtx_insn *first)
512 {
513 insn =
514 emit_insn_before (gen_iprefetch
515- (gen_int_mode (addr_offset, SImode)),
516+ (gen_int_mode (addr_offset, Pmode)),
517 before_4);
518 recog_memoized (insn);
519 INSN_LOCATION (insn) = INSN_LOCATION (before_4);
520@@ -3976,7 +4040,27 @@ insert_wic_for_ilb_runout (rtx_insn *first)
521 }
522 }
523 }
524-
525+
526+/* Set the names for various arithmetic operations according to the
527+ * MICROBLAZE ABI. */
528+static void
529+microblaze_init_libfuncs (void)
530+{
531+ set_optab_libfunc (smod_optab, SImode, "__modsi3");
532+ set_optab_libfunc (sdiv_optab, SImode, "__divsi3");
533+ set_optab_libfunc (smul_optab, SImode, "__mulsi3");
534+ set_optab_libfunc (umod_optab, SImode, "__umodsi3");
535+ set_optab_libfunc (udiv_optab, SImode, "__udivsi3");
536+
537+ if (TARGET_MB_64)
538+ {
539+ set_optab_libfunc (smod_optab, DImode, "__moddi3");
540+ set_optab_libfunc (sdiv_optab, DImode, "__divdi3");
541+ set_optab_libfunc (smul_optab, DImode, "__muldi3");
542+ set_optab_libfunc (umod_optab, DImode, "__umoddi3");
543+ set_optab_libfunc (udiv_optab, DImode, "__udivdi3");
544+ }
545+}
546 /* Insert instruction prefetch instruction at the fall
547 through path of the function call. */
548
549@@ -4129,6 +4213,17 @@ microblaze_starting_frame_offset (void)
550 #undef TARGET_LRA_P
551 #define TARGET_LRA_P hook_bool_void_false
552
553+#ifdef TARGET_MB_64
554+#undef TARGET_ASM_ALIGNED_DI_OP
555+#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
556+
557+#undef TARGET_ASM_ALIGNED_HI_OP
558+#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
559+
560+#undef TARGET_ASM_ALIGNED_SI_OP
561+#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
562+#endif
563+
564 #undef TARGET_FRAME_POINTER_REQUIRED
565 #define TARGET_FRAME_POINTER_REQUIRED microblaze_frame_pointer_required
566
567@@ -4138,6 +4233,9 @@ microblaze_starting_frame_offset (void)
568 #undef TARGET_TRAMPOLINE_INIT
569 #define TARGET_TRAMPOLINE_INIT microblaze_trampoline_init
570
571+#undef TARGET_INIT_LIBFUNCS
572+#define TARGET_INIT_LIBFUNCS microblaze_init_libfuncs
573+
574 #undef TARGET_PROMOTE_FUNCTION_MODE
575 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
576
577diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
578index c0358603380..f6ad4d9fc21 100644
579--- a/gcc/config/microblaze/microblaze.h
580+++ b/gcc/config/microblaze/microblaze.h
581@@ -173,7 +173,6 @@ extern enum pipeline_type microblaze_pipe;
582
583 /* Generate DWARF exception handling info. */
584 #define DWARF2_UNWIND_INFO 1
585-
586 /* Don't generate .loc operations. */
587 #define DWARF2_ASM_LINE_DEBUG_INFO 0
588
589@@ -206,38 +205,51 @@ extern enum pipeline_type microblaze_pipe;
590 ((flag_pic || GLOBAL) ? DW_EH_PE_aligned : DW_EH_PE_absptr)
591
592 /* Use DWARF 2 debugging information by default. */
593-#define DWARF2_DEBUGGING_INFO
594+#define DWARF2_DEBUGGING_INFO 1
595 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
596+#define DWARF2_ADDR_SIZE 4
597
598 /* Target machine storage layout */
599
600 #define BITS_BIG_ENDIAN 0
601 #define BYTES_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
602 #define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
603-#define BITS_PER_WORD 32
604-#define UNITS_PER_WORD 4
605+//#define BITS_PER_WORD 64
606+//Revisit
607+#define MAX_BITS_PER_WORD 64
608+#define UNITS_PER_WORD (TARGET_MB_64 ? 8 : 4)
609+//#define MIN_UNITS_PER_WORD (TARGET_MB_64 ? 8 : 4)
610+//#define UNITS_PER_WORD 4
611 #define MIN_UNITS_PER_WORD 4
612 #define INT_TYPE_SIZE 32
613 #define SHORT_TYPE_SIZE 16
614-#define LONG_TYPE_SIZE 64
615+#define LONG_TYPE_SIZE (TARGET_MB_64 ? 64 : 32)
616 #define LONG_LONG_TYPE_SIZE 64
617 #define FLOAT_TYPE_SIZE 32
618 #define DOUBLE_TYPE_SIZE 64
619 #define LONG_DOUBLE_TYPE_SIZE 64
620-#define POINTER_SIZE 32
621-#define PARM_BOUNDARY 32
622-#define FUNCTION_BOUNDARY 32
623-#define EMPTY_FIELD_BOUNDARY 32
624+#define POINTER_SIZE (TARGET_MB_64 ? 64 : 32)
625+//#define WIDEST_HARDWARE_FP_SIZE 64
626+//#define POINTERS_EXTEND_UNSIGNED 1
627+#define PARM_BOUNDARY (TARGET_MB_64 ? 64 : 32)
628+#define FUNCTION_BOUNDARY (TARGET_MB_64 ? 64 : 32)
629+#define EMPTY_FIELD_BOUNDARY (TARGET_MB_64 ? 64 : 32)
630 #define STRUCTURE_SIZE_BOUNDARY 8
631-#define BIGGEST_ALIGNMENT 32
632+#define BIGGEST_ALIGNMENT (TARGET_MB_64 ? 64 : 32)
633 #define STRICT_ALIGNMENT 1
634 #define PCC_BITFIELD_TYPE_MATTERS 1
635
636+//#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_MB_64 ? TImode : DImode)
637 #undef SIZE_TYPE
638-#define SIZE_TYPE "unsigned int"
639+#define SIZE_TYPE (TARGET_MB_64 ? "long unsigned int" : "unsigned int")
640
641 #undef PTRDIFF_TYPE
642-#define PTRDIFF_TYPE "int"
643+#define PTRDIFF_TYPE (TARGET_MB_64 ? "long int" : "int")
644+
645+/*#undef INTPTR_TYPE
646+#define INTPTR_TYPE (TARGET_MB_64 ? "long int" : "int")*/
647+#undef UINTPTR_TYPE
648+#define UINTPTR_TYPE (TARGET_MB_64 ? "long unsigned int" : "unsigned int")
649
650 #define DATA_ALIGNMENT(TYPE, ALIGN) \
651 ((((ALIGN) < BITS_PER_WORD) \
652@@ -253,12 +265,12 @@ extern enum pipeline_type microblaze_pipe;
653 #define WORD_REGISTER_OPERATIONS 1
654
655 #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
656-
657+/*
658 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
659 if (GET_MODE_CLASS (MODE) == MODE_INT \
660- && GET_MODE_SIZE (MODE) < 4) \
661- (MODE) = SImode;
662-
663+ && GET_MODE_SIZE (MODE) < (TARGET_MB_64 ? 8 : 4)) \
664+ (MODE) = TARGET_MB_64 ? DImode : SImode;
665+*/
666 /* Standard register usage. */
667
668 /* On the MicroBlaze, we have 32 integer registers */
669@@ -438,13 +450,16 @@ extern struct microblaze_frame_info current_frame_info;
670 #define FIRST_PARM_OFFSET(FNDECL) (UNITS_PER_WORD)
671
672 #define ARG_POINTER_CFA_OFFSET(FNDECL) 0
673+#define DWARF_CIE_DATA_ALIGNMENT -1
674
675 #define REG_PARM_STACK_SPACE(FNDECL) (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
676
677 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
678
679-#define STACK_BOUNDARY 32
680+#define STACK_BOUNDARY (TARGET_MB_64 ? 64 : 32)
681
682+#define PREFERRED_STACK_BOUNDARY (TARGET_MB_64 ? 64 : 32)
683+
684 #define NUM_OF_ARGS 6
685
686 #define GP_RETURN (GP_REG_FIRST + MB_ABI_INT_RETURN_VAL_REGNUM)
687@@ -455,12 +470,15 @@ extern struct microblaze_frame_info current_frame_info;
688 #define MAX_ARGS_IN_REGISTERS MB_ABI_MAX_ARG_REGS
689
690 #define LIBCALL_VALUE(MODE) \
691+ gen_rtx_REG (MODE,GP_RETURN)
692+
693+/*#define LIBCALL_VALUE(MODE) \
694 gen_rtx_REG ( \
695 ((GET_MODE_CLASS (MODE) != MODE_INT \
696 || GET_MODE_SIZE (MODE) >= 4) \
697 ? (MODE) \
698 : SImode), GP_RETURN)
699-
700+*/
701 /* 1 if N is a possible register number for a function value.
702 On the MicroBlaze, R2 R3 are the only register thus used.
703 Currently, R2 are only implemented here (C has no complex type) */
704@@ -500,7 +518,7 @@ typedef struct microblaze_args
705 /* 4 insns + 2 words of data. */
706 #define TRAMPOLINE_SIZE (6 * 4)
707
708-#define TRAMPOLINE_ALIGNMENT 32
709+#define TRAMPOLINE_ALIGNMENT 64
710
711 #define REGNO_OK_FOR_BASE_P(regno) microblaze_regno_ok_for_base_p ((regno), 1)
712
713@@ -529,13 +547,13 @@ typedef struct microblaze_args
714 addresses which require two reload registers. */
715 #define LEGITIMATE_PIC_OPERAND_P(X) microblaze_legitimate_pic_operand (X)
716
717-#define CASE_VECTOR_MODE (SImode)
718+#define CASE_VECTOR_MODE (TARGET_MB_64? DImode:SImode)
719
720 #ifndef DEFAULT_SIGNED_CHAR
721 #define DEFAULT_SIGNED_CHAR 1
722 #endif
723
724-#define MOVE_MAX 4
725+#define MOVE_MAX (TARGET_MB_64 ? 8 : 4)
726 #define MAX_MOVE_MAX 8
727
728 #define SLOW_BYTE_ACCESS 1
729@@ -545,7 +563,7 @@ typedef struct microblaze_args
730
731 #define SHIFT_COUNT_TRUNCATED 1
732
733-#define Pmode SImode
734+#define Pmode (TARGET_MB_64? DImode:SImode)
735
736 #define FUNCTION_MODE SImode
737
738@@ -707,6 +725,7 @@ do { \
739
740 #undef TARGET_ASM_OUTPUT_IDENT
741 #define TARGET_ASM_OUTPUT_IDENT microblaze_asm_output_ident
742+//#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive
743
744 /* Default to -G 8 */
745 #ifndef MICROBLAZE_DEFAULT_GVALUE
746diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
747index 4d8429d9a90..33a8b12ef3b 100644
748--- a/gcc/config/microblaze/microblaze.md
749+++ b/gcc/config/microblaze/microblaze.md
750@@ -26,6 +26,7 @@
751 ;; Constants
752 ;;----------------------------------------------------
753 (define_constants [
754+ (R_Z 0) ;; For reg r0
755 (R_SP 1) ;; Stack pointer reg
756 (R_SR 15) ;; Sub-routine return addr reg
757 (R_IR 14) ;; Interrupt return addr reg
758@@ -541,6 +542,7 @@
759
760 ;; Add 2 SImode integers [ src1 = reg ; src2 = arith ; dest = reg ]
761 ;; Leave carry as is
762+
763 (define_insn "addsi3"
764 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
765 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%dJ,dJ,dJ")
766@@ -562,23 +564,38 @@
767
768 ;; Adding 2 DI operands in register or reg/imm
769
770-(define_insn "adddi3_long"
771+(define_expand "adddi3"
772+ [(set (match_operand:DI 0 "register_operand" "")
773+ (plus:DI (match_operand:DI 1 "register_operand" "")
774+ (match_operand:DI 2 "arith_plus_operand" "")))]
775+""
776+{
777+ if (TARGET_MB_64)
778+ {
779+ if (GET_CODE (operands[2]) == CONST_INT &&
780+ INTVAL(operands[2]) < (long)-549755813888 &&
781+ INTVAL(operands[2]) > (long)549755813887)
782+ FAIL;
783+ }
784+})
785+
786+(define_insn "*adddi3_long"
787 [(set (match_operand:DI 0 "register_operand" "=d,d")
788- (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%dJ,dJ")
789+ (plus:DI (match_operand:DI 1 "register_operand" "%d,d")
790 (match_operand:DI 2 "arith_plus_operand" "d,K")))]
791 "TARGET_MB_64"
792 "@
793- addlk\t%0,%z1,%2
794- addlik\t%0,%z1,%2"
795- [(set_attr "type" "arith,arith")
796- (set_attr "mode" "DI,DI")
797+ addlk\t%0,%1,%2
798+ addlik\t%0,%1,%2 #N10"
799+ [(set_attr "type" "darith,no_delay_arith")
800+ (set_attr "mode" "DI")
801 (set_attr "length" "4,4")])
802
803-(define_insn "adddi3"
804+(define_insn "*adddi3_all"
805 [(set (match_operand:DI 0 "register_operand" "=d,d")
806 (plus:DI (match_operand:DI 1 "register_operand" "%d,d")
807 (match_operand:DI 2 "arith_operand" "d,i")))]
808- ""
809+ "!TARGET_MB_64"
810 "@
811 add\t%L0,%L1,%L2\;addc\t%M0,%M1,%M2
812 addi\t%L0,%L1,%j2\;addic\t%M0,%M1,%h2"
813@@ -605,7 +622,7 @@
814 (define_insn "iprefetch"
815 [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
816 (clobber (mem:BLK (scratch)))]
817- "TARGET_PREFETCH"
818+ "TARGET_PREFETCH && !TARGET_MB_64"
819 {
820 operands[2] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
821 return "mfs\t%2,rpc\n\twic\t%2,r0";
822@@ -618,23 +635,33 @@
823 ;; Double Precision Subtraction
824 ;;----------------------------------------------------------------
825
826-(define_insn "subdi3_long"
827- [(set (match_operand:DI 0 "register_operand" "=d,d")
828- (minus:DI (match_operand:DI 1 "register_operand" "d,d")
829- (match_operand:DI 2 "register_operand" "d,n")))]
830+(define_expand "subdi3"
831+ [(set (match_operand:DI 0 "register_operand" "")
832+ (minus:DI (match_operand:DI 1 "register_operand" "")
833+ (match_operand:DI 2 "arith_operand" "")))]
834+""
835+"
836+{
837+}")
838+
839+(define_insn "subsidi3"
840+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
841+ (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
842+ (match_operand:DI 2 "arith_operand" "d,K,n")))]
843 "TARGET_MB_64"
844 "@
845 rsubl\t%0,%2,%1
846- addlik\t%0,%z1,-%2"
847- [(set_attr "type" "darith")
848- (set_attr "mode" "DI,DI")
849- (set_attr "length" "4,4")])
850+ addik\t%0,%z1,-%2
851+ addik\t%0,%z1,-%2"
852+ [(set_attr "type" "arith,no_delay_arith,no_delay_arith")
853+ (set_attr "mode" "DI")
854+ (set_attr "length" "4,4,4")])
855
856-(define_insn "subdi3"
857+(define_insn "subdi3_small"
858 [(set (match_operand:DI 0 "register_operand" "=&d")
859 (minus:DI (match_operand:DI 1 "register_operand" "d")
860 (match_operand:DI 2 "register_operand" "d")))]
861- ""
862+ "!TARGET_MB_64"
863 "rsub\t%L0,%L2,%L1\;rsubc\t%M0,%M2,%M1"
864 [(set_attr "type" "darith")
865 (set_attr "mode" "DI")
866@@ -663,7 +690,7 @@
867 (mult:DI
868 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
869 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
870- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
871+ "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH && !TARGET_MB_64"
872 "mul\t%L0,%1,%2\;mulh\t%M0,%1,%2"
873 [(set_attr "type" "no_delay_arith")
874 (set_attr "mode" "DI")
875@@ -674,7 +701,7 @@
876 (mult:DI
877 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
878 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
879- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
880+ "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH && !TARGET_MB_64"
881 "mul\t%L0,%1,%2\;mulhu\t%M0,%1,%2"
882 [(set_attr "type" "no_delay_arith")
883 (set_attr "mode" "DI")
884@@ -685,7 +712,7 @@
885 (mult:DI
886 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
887 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
888- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
889+ "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH && !TARGET_MB_64"
890 "mul\t%L0,%1,%2\;mulhsu\t%M0,%2,%1"
891 [(set_attr "type" "no_delay_arith")
892 (set_attr "mode" "DI")
893@@ -789,7 +816,7 @@
894 (match_operand:SI 4 "arith_operand")])
895 (label_ref (match_operand 5))
896 (pc)))]
897- "TARGET_HARD_FLOAT"
898+ "TARGET_HARD_FLOAT && !TARGET_MB_64"
899 [(set (match_dup 1) (match_dup 3))]
900
901 {
902@@ -819,6 +846,15 @@
903 (set_attr "mode" "SI")
904 (set_attr "length" "4")])
905
906+(define_insn "negsi_long"
907+ [(set (match_operand:SI 0 "register_operand" "=d")
908+ (neg:SI (match_operand:DI 1 "register_operand" "d")))]
909+ ""
910+ "rsubk\t%0,%1,r0"
911+ [(set_attr "type" "arith")
912+ (set_attr "mode" "SI")
913+ (set_attr "length" "4")])
914+
915 (define_insn "negdi2_long"
916 [(set (match_operand:DI 0 "register_operand" "=d")
917 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
918@@ -847,16 +883,24 @@
919 (set_attr "mode" "SI")
920 (set_attr "length" "4")])
921
922-(define_insn "one_cmpldi2_long"
923+(define_expand "one_cmpldi2"
924+ [(set (match_operand:DI 0 "register_operand" "")
925+ (not:DI (match_operand:DI 1 "register_operand" "")))]
926+ ""
927+ "
928+{
929+}")
930+
931+(define_insn ""
932 [(set (match_operand:DI 0 "register_operand" "=d")
933- (not:DI (match_operand:DI 1 "register_operand" "d")))]
934+ (not:DI (match_operand:DI 1 "arith_operand" "d")))]
935 "TARGET_MB_64"
936 "xorli\t%0,%1,-1"
937- [(set_attr "type" "arith")
938+ [(set_attr "type" "no_delay_arith")
939 (set_attr "mode" "DI")
940 (set_attr "length" "4")])
941
942-(define_insn "*one_cmpldi2"
943+(define_insn ""
944 [(set (match_operand:DI 0 "register_operand" "=d")
945 (not:DI (match_operand:DI 1 "register_operand" "d")))]
946 ""
947@@ -871,7 +915,8 @@
948 (not:DI (match_operand:DI 1 "register_operand" "")))]
949 "reload_completed
950 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
951- && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
952+ && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
953+ && !TARGET_MB_64"
954
955 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
956 (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
957@@ -883,18 +928,17 @@
958 ;;----------------------------------------------------------------
959
960 (define_insn "anddi3"
961- [(set (match_operand:DI 0 "register_operand" "=d,d")
962- (and:DI (match_operand:DI 1 "arith_operand" "d,d")
963- (match_operand:DI 2 "arith_operand" "d,K")))]
964+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
965+ (and:DI (match_operand:DI 1 "arith_operand" "d,d,d")
966+ (match_operand:DI 2 "arith_operand" "d,K,I")))]
967 "TARGET_MB_64"
968 "@
969 andl\t%0,%1,%2
970- andli\t%0,%1,%2 #andl1"
971- ;; andli\t%0,%1,%2 #andl3
972- ;; andli\t%0,%1,%2 #andl2
973- [(set_attr "type" "arith,arith")
974- (set_attr "mode" "DI,DI")
975- (set_attr "length" "4,4")])
976+ andli\t%0,%1,%2 #andl2
977+ andli\t%0,%1,%2 #andl3"
978+ [(set_attr "type" "arith,no_delay_arith,no_delay_arith")
979+ (set_attr "mode" "DI,DI,DI")
980+ (set_attr "length" "4,4,4")])
981
982 (define_insn "andsi3"
983 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
984@@ -919,7 +963,7 @@
985 "@
986 orl\t%0,%1,%2
987 orli\t%0,%1,%2 #andl1"
988- [(set_attr "type" "arith,arith")
989+ [(set_attr "type" "arith,no_delay_arith")
990 (set_attr "mode" "DI,DI")
991 (set_attr "length" "4,4")])
992
993@@ -945,7 +989,7 @@
994 "@
995 xorl\t%0,%1,%2
996 xorli\t%0,%1,%2 #andl1"
997- [(set_attr "type" "arith,arith")
998+ [(set_attr "type" "arith,no_delay_arith")
999 (set_attr "mode" "DI,DI")
1000 (set_attr "length" "4,4")])
1001
1002@@ -1018,26 +1062,6 @@
1003 (set_attr "mode" "SI")
1004 (set_attr "length" "4")])
1005
1006-;;(define_expand "extendqidi2"
1007-;; [(set (match_operand:DI 0 "register_operand" "=d")
1008-;; (sign_extend:DI (match_operand:QI 1 "general_operand" "d")))]
1009-;; "TARGET_MB_64"
1010-;; {
1011-;; if (GET_CODE (operands[1]) != REG)
1012-;; FAIL;
1013-;; }
1014-;;)
1015-
1016-
1017-;;(define_insn "extendqidi2"
1018-;; [(set (match_operand:DI 0 "register_operand" "=d")
1019-;; (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
1020-;; "TARGET_MB_64"
1021-;; "sextl8\t%0,%1"
1022-;; [(set_attr "type" "arith")
1023-;; (set_attr "mode" "DI")
1024-;; (set_attr "length" "4")])
1025-
1026 (define_insn "extendhisi2"
1027 [(set (match_operand:SI 0 "register_operand" "=d")
1028 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
1029@@ -1060,6 +1084,27 @@
1030 ;; Those for integer source operand are ordered
1031 ;; widest source type first.
1032
1033+(define_insn "extendsidi2_long"
1034+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1035+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1036+ "TARGET_MB_64"
1037+ {
1038+ switch (which_alternative)
1039+ {
1040+ case 0:
1041+ return "sextl32\t%0,%1";
1042+ case 1:
1043+ case 2:
1044+ {
1045+ output_asm_insn ("ll%i1\t%0,%1", operands);
1046+ return "sextl32\t%0,%0";
1047+ }
1048+ }
1049+ }
1050+ [(set_attr "type" "multi,multi,multi")
1051+ (set_attr "mode" "DI")
1052+ (set_attr "length" "4,8,8")])
1053+
1054 (define_insn "extendsidi2"
1055 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1056 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1057@@ -1090,69 +1135,118 @@
1058 ;; Unlike most other insns, the move insns can't be split with
1059 ;; different predicates, because register spilling and other parts of
1060 ;; the compiler, have memoized the insn number already.
1061+;; //}
1062
1063 (define_expand "movdi"
1064 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1065 (match_operand:DI 1 "general_operand" ""))]
1066 ""
1067 {
1068- /* If operands[1] is a constant address illegal for pic, then we need to
1069- handle it just like microblaze_legitimize_address does. */
1070- if (flag_pic && pic_address_needs_scratch (operands[1]))
1071+ if (TARGET_MB_64)
1072+ {
1073+ if (microblaze_expand_move (DImode, operands)) DONE;
1074+ }
1075+ else
1076 {
1077+ /* If operands[1] is a constant address illegal for pic, then we need to
1078+ handle it just like microblaze_legitimize_address does. */
1079+ if (flag_pic && pic_address_needs_scratch (operands[1]))
1080+ {
1081 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
1082 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
1083 emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
1084 DONE;
1085- }
1086-
1087-
1088- if ((reload_in_progress | reload_completed) == 0
1089- && !register_operand (operands[0], DImode)
1090- && !register_operand (operands[1], DImode)
1091- && (((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
1092- && operands[1] != CONST0_RTX (DImode))))
1093- {
1094+ }
1095
1096- rtx temp = force_reg (DImode, operands[1]);
1097- emit_move_insn (operands[0], temp);
1098- DONE;
1099+ if ((reload_in_progress | reload_completed) == 0
1100+ && !register_operand (operands[0], DImode)
1101+ && !register_operand (operands[1], DImode)
1102+ && (((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
1103+ && operands[1] != CONST0_RTX (DImode))))
1104+ {
1105+ rtx temp = force_reg (DImode, operands[1]);
1106+ emit_move_insn (operands[0], temp);
1107+ DONE;
1108+ }
1109 }
1110 }
1111 )
1112
1113+;; Added for status registers
1114+(define_insn "movdi_status"
1115+ [(set (match_operand:DI 0 "register_operand" "=d,d,z")
1116+ (match_operand:DI 1 "register_operand" "z,d,d"))]
1117+ "microblaze_is_interrupt_variant () && TARGET_MB_64"
1118+ "@
1119+ mfs\t%0,%1 #mfs
1120+ addlk\t%0,%1,r0 #add movdi
1121+ mts\t%0,%1 #mts"
1122+ [(set_attr "type" "move")
1123+ (set_attr "mode" "DI")
1124+ (set_attr "length" "12")])
1125
1126-(define_insn "*movdi_internal_64"
1127- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o")
1128- (match_operand:DI 1 "general_operand" " d,K,J,R,o,d,d"))]
1129- "TARGET_MB_64 && (INTVAL(operands[1]) < 0x7fffffffff) && (INTVAL(operands[1]) > 0xffffff8000000000)"
1130+;; This move will be not be moved to delay slot.
1131+(define_insn "*movdi_internal3"
1132+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d")
1133+ (match_operand:DI 1 "immediate_operand" "J,I,Mnis"))]
1134+ "TARGET_MB_64 && (register_operand (operands[0], DImode) &&
1135+ (GET_CODE (operands[1]) == CONST_INT &&
1136+ (INTVAL (operands[1]) <= (long)549755813887 && INTVAL (operands[1]) >= (long)-549755813888)))"
1137+ "@
1138+ addlk\t%0,r0,r0\t
1139+ addlik\t%0,r0,%1\t #N1 %X1
1140+ addlik\t%0,r0,%1\t #N2 %X1"
1141+ [(set_attr "type" "arith,no_delay_arith,no_delay_arith")
1142+ (set_attr "mode" "DI")
1143+ (set_attr "length" "4")])
1144+
1145+;; This move may be used for PLT label operand
1146+(define_insn "*movdi_internal5_pltop"
1147+ [(set (match_operand:DI 0 "register_operand" "=d,d")
1148+ (match_operand:DI 1 "call_insn_operand" ""))]
1149+ "TARGET_MB_64 && (register_operand (operands[0], Pmode) &&
1150+ PLT_ADDR_P (operands[1]))"
1151+ {
1152+ gcc_unreachable ();
1153+ }
1154+ [(set_attr "type" "load")
1155+ (set_attr "mode" "DI")
1156+ (set_attr "length" "4")])
1157+
1158+(define_insn "*movdi_internal2"
1159+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d, d,d,R,m")
1160+ (match_operand:DI 1 "move_src_operand" " d,I,Mnis,R,m,dJ,dJ"))]
1161+ "TARGET_MB_64"
1162 {
1163 switch (which_alternative)
1164 {
1165 case 0:
1166- return "addlk\t%0,%1";
1167- case 1:
1168- return "addlik\t%0,r0,%1";
1169- case 2:
1170- return "addlk\t%0,r0,r0";
1171- case 3:
1172- case 4:
1173- return "lli\t%0,%1";
1174- case 5:
1175- case 6:
1176- return "sli\t%1,%0";
1177- }
1178- return "unreachable";
1179- }
1180- [(set_attr "type" "no_delay_move,no_delay_arith,no_delay_arith,no_delay_load,no_delay_load,no_delay_store,no_delay_store")
1181+ return "addlk\t%0,%1,r0";
1182+ case 1:
1183+ case 2:
1184+ if (GET_CODE (operands[1]) == CONST_INT &&
1185+ (INTVAL (operands[1]) > (long)549755813887 || INTVAL (operands[1]) < (long)-549755813888))
1186+ return "addlik\t%0,r0,%h1\n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #li => la";
1187+ else
1188+ return "addlik\t%0,r0,%1";
1189+ case 3:
1190+ case 4:
1191+ return "ll%i1\t%0,%1";
1192+ case 5:
1193+ case 6:
1194+ return "sl%i0\t%z1,%0";
1195+ }
1196+ }
1197+ [(set_attr "type" "load,no_delay_load,no_delay_load,no_delay_load,no_delay_load,no_delay_store,no_delay_store")
1198 (set_attr "mode" "DI")
1199- (set_attr "length" "8,8,8,8,12,8,12")])
1200+ (set_attr "length" "4,4,12,4,8,4,8")])
1201+
1202
1203
1204 (define_insn "*movdi_internal"
1205 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o")
1206 (match_operand:DI 1 "general_operand" " d,i,J,R,o,d,d"))]
1207- ""
1208+ "!TARGET_MB_64"
1209 {
1210 switch (which_alternative)
1211 {
1212@@ -1184,7 +1278,8 @@
1213 "reload_completed
1214 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1215 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1216- && (REGNO(operands[0]) == (REGNO(operands[1]) + 1))"
1217+ && (REGNO(operands[0]) == (REGNO(operands[1]) + 1))
1218+ && !(TARGET_MB_64)"
1219
1220 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
1221 (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
1222@@ -1196,12 +1291,22 @@
1223 "reload_completed
1224 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1225 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1226- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
1227+ && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))
1228+ && !(TARGET_MB_64)"
1229
1230 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1231 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
1232 "")
1233
1234+(define_insn "movdi_long_int"
1235+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1236+ (match_operand:DI 1 "general_operand" "i"))]
1237+ ""
1238+ "addlik\t%0,r0,%h1\n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #li => la";
1239+ [(set_attr "type" "no_delay_arith")
1240+ (set_attr "mode" "DI")
1241+ (set_attr "length" "12")])
1242+
1243 ;; Unlike most other insns, the move insns can't be split with
1244 ;; different predicates, because register spilling and other parts of
1245 ;; the compiler, have memoized the insn number already.
1246@@ -1273,6 +1378,8 @@
1247 (set_attr "length" "4,4,8,4,8,4,8")])
1248
1249
1250+
1251+
1252 ;; 16-bit Integer moves
1253
1254 ;; Unlike most other insns, the move insns can't be split with
1255@@ -1305,8 +1412,8 @@
1256 "@
1257 addik\t%0,r0,%1\t# %X1
1258 addk\t%0,%1,r0
1259- lhui\t%0,%1
1260- lhui\t%0,%1
1261+ lhu%i1\t%0,%1
1262+ lhu%i1\t%0,%1
1263 sh%i0\t%z1,%0
1264 sh%i0\t%z1,%0"
1265 [(set_attr "type" "arith,move,load,no_delay_load,store,no_delay_store")
1266@@ -1349,7 +1456,7 @@
1267 lbu%i1\t%0,%1
1268 lbu%i1\t%0,%1
1269 sb%i0\t%z1,%0
1270- sbi\t%z1,%0"
1271+ sb%i0\t%z1,%0"
1272 [(set_attr "type" "arith,arith,move,load,no_delay_load,store,no_delay_store")
1273 (set_attr "mode" "QI")
1274 (set_attr "length" "4,4,8,4,8,4,8")])
1275@@ -1422,7 +1529,7 @@
1276 addik\t%0,r0,%F1
1277 lw%i1\t%0,%1
1278 sw%i0\t%z1,%0
1279- swi\t%z1,%0"
1280+ sw%i0\t%z1,%0"
1281 [(set_attr "type" "move,no_delay_load,load,no_delay_load,no_delay_load,store,no_delay_store")
1282 (set_attr "mode" "SF")
1283 (set_attr "length" "4,4,4,4,4,4,4")])
1284@@ -1461,6 +1568,33 @@
1285 ;; movdf_internal
1286 ;; Applies to both TARGET_SOFT_FLOAT and TARGET_HARD_FLOAT
1287 ;;
1288+(define_insn "*movdf_internal_64"
1289+ [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,d,d,m")
1290+ (match_operand:DF 1 "general_operand" "d,dG,m,F,T,d"))]
1291+ "TARGET_MB_64"
1292+ {
1293+ switch (which_alternative)
1294+ {
1295+ case 0:
1296+ return "addlk\t%0,%1,r0";
1297+ case 1:
1298+ return "addlk\t%0,r0,r0";
1299+ case 2:
1300+ case 4:
1301+ return "ll%i1\t%0,%1";
1302+ case 3:
1303+ {
1304+ return "addlik\t%0,r0,%h1 \n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #Xfer Lo";
1305+ }
1306+ case 5:
1307+ return "sl%i0\t%1,%0";
1308+ }
1309+ gcc_unreachable ();
1310+ }
1311+ [(set_attr "type" "no_delay_move,no_delay_move,no_delay_load,no_delay_load,no_delay_load,no_delay_store")
1312+ (set_attr "mode" "DF")
1313+ (set_attr "length" "4,4,4,16,4,4")])
1314+
1315 (define_insn "*movdf_internal"
1316 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,d,o")
1317 (match_operand:DF 1 "general_operand" "dG,o,F,T,d"))]
1318@@ -1495,7 +1629,8 @@
1319 "reload_completed
1320 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1321 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1322- && (REGNO (operands[0]) == (REGNO (operands[1]) + 1))"
1323+ && (REGNO (operands[0]) == (REGNO (operands[1]) + 1))
1324+ && !TARGET_MB_64"
1325 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
1326 (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
1327 "")
1328@@ -1506,7 +1641,8 @@
1329 "reload_completed
1330 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1331 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1332- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
1333+ && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))
1334+ && !TARGET_MB_64"
1335 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1336 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
1337 "")
1338@@ -2006,6 +2142,31 @@ else
1339 "
1340 )
1341
1342+
1343+(define_insn "seq_internal_pat_long"
1344+ [(set (match_operand:DI 0 "register_operand" "=d")
1345+ (eq:DI
1346+ (match_operand:DI 1 "register_operand" "d")
1347+ (match_operand:DI 2 "register_operand" "d")))]
1348+ "TARGET_MB_64"
1349+ "pcmpleq\t%0,%1,%2"
1350+ [(set_attr "type" "arith")
1351+ (set_attr "mode" "DI")
1352+ (set_attr "length" "4")]
1353+)
1354+
1355+(define_insn "sne_internal_pat_long"
1356+ [(set (match_operand:DI 0 "register_operand" "=d")
1357+ (ne:DI
1358+ (match_operand:DI 1 "register_operand" "d")
1359+ (match_operand:DI 2 "register_operand" "d")))]
1360+ "TARGET_MB_64"
1361+ "pcmplne\t%0,%1,%2"
1362+ [(set_attr "type" "arith")
1363+ (set_attr "mode" "DI")
1364+ (set_attr "length" "4")]
1365+)
1366+
1367 (define_insn "seq_internal_pat"
1368 [(set (match_operand:SI 0 "register_operand" "=d")
1369 (eq:SI
1370@@ -2066,8 +2227,8 @@ else
1371 (define_expand "cbranchsi4"
1372 [(set (pc)
1373 (if_then_else (match_operator 0 "ordered_comparison_operator"
1374- [(match_operand:SI 1 "register_operand")
1375- (match_operand:SI 2 "arith_operand" "I,i")])
1376+ [(match_operand 1 "register_operand")
1377+ (match_operand 2 "arith_operand" "I,i")])
1378 (label_ref (match_operand 3 ""))
1379 (pc)))]
1380 ""
1381@@ -2079,13 +2240,13 @@ else
1382 (define_expand "cbranchsi4_reg"
1383 [(set (pc)
1384 (if_then_else (match_operator 0 "ordered_comparison_operator"
1385- [(match_operand:SI 1 "register_operand")
1386- (match_operand:SI 2 "register_operand")])
1387+ [(match_operand 1 "register_operand")
1388+ (match_operand 2 "register_operand")])
1389 (label_ref (match_operand 3 ""))
1390 (pc)))]
1391 ""
1392 {
1393- microblaze_expand_conditional_branch_reg (SImode, operands);
1394+ microblaze_expand_conditional_branch_reg (Pmode, operands);
1395 DONE;
1396 })
1397
1398@@ -2110,6 +2271,26 @@ else
1399 (label_ref (match_operand 1))
1400 (pc)))])
1401
1402+(define_insn "branch_zero64"
1403+ [(set (pc)
1404+ (if_then_else (match_operator 0 "ordered_comparison_operator"
1405+ [(match_operand 1 "register_operand" "d")
1406+ (const_int 0)])
1407+ (match_operand 2 "pc_or_label_operand" "")
1408+ (match_operand 3 "pc_or_label_operand" "")))
1409+ ]
1410+ "TARGET_MB_64"
1411+ {
1412+ if (operands[3] == pc_rtx)
1413+ return "bea%C0i%?\t%z1,%2";
1414+ else
1415+ return "bea%N0i%?\t%z1,%3";
1416+ }
1417+ [(set_attr "type" "branch")
1418+ (set_attr "mode" "none")
1419+ (set_attr "length" "4")]
1420+)
1421+
1422 (define_insn "branch_zero"
1423 [(set (pc)
1424 (if_then_else (match_operator:SI 0 "ordered_comparison_operator"
1425@@ -2130,6 +2311,47 @@ else
1426 (set_attr "length" "4")]
1427 )
1428
1429+(define_insn "branch_compare64"
1430+ [(set (pc)
1431+ (if_then_else (match_operator 0 "cmp_op"
1432+ [(match_operand 1 "register_operand" "d")
1433+ (match_operand 2 "register_operand" "d")
1434+ ])
1435+ (label_ref (match_operand 3))
1436+ (pc)))
1437+ (clobber(reg:SI R_TMP))]
1438+ "TARGET_MB_64"
1439+ {
1440+ operands[4] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
1441+ enum rtx_code code = GET_CODE (operands[0]);
1442+
1443+ if (code == GT || code == LE)
1444+ {
1445+ output_asm_insn ("cmp\tr18,%z1,%z2", operands);
1446+ code = swap_condition (code);
1447+ }
1448+ else if (code == GTU || code == LEU)
1449+ {
1450+ output_asm_insn ("cmpu\tr18,%z1,%z2", operands);
1451+ code = swap_condition (code);
1452+ }
1453+ else if (code == GE || code == LT)
1454+ {
1455+ output_asm_insn ("cmp\tr18,%z2,%z1", operands);
1456+ }
1457+ else if (code == GEU || code == LTU)
1458+ {
1459+ output_asm_insn ("cmpu\tr18,%z2,%z1", operands);
1460+ }
1461+
1462+ operands[0] = gen_rtx_fmt_ee (signed_condition (code), SImode, operands[4], const0_rtx);
1463+ return "bea%C0i%?\tr18,%3";
1464+ }
1465+ [(set_attr "type" "branch")
1466+ (set_attr "mode" "none")
1467+ (set_attr "length" "12")]
1468+)
1469+
1470 (define_insn "branch_compare"
1471 [(set (pc)
1472 (if_then_else (match_operator:SI 0 "cmp_op"
1473@@ -2313,7 +2535,7 @@ else
1474 ;; Indirect jumps. Jump to register values. Assuming absolute jumps
1475
1476 (define_insn "indirect_jump_internal1"
1477- [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
1478+ [(set (pc) (match_operand 0 "register_operand" "d"))]
1479 ""
1480 "bra%?\t%0"
1481 [(set_attr "type" "jump")
1482@@ -2326,7 +2548,7 @@ else
1483 (use (label_ref (match_operand 1 "" "")))]
1484 ""
1485 {
1486- gcc_assert (GET_MODE (operands[0]) == Pmode);
1487+ //gcc_assert (GET_MODE (operands[0]) == Pmode);
1488
1489 if (!flag_pic || TARGET_PIC_DATA_TEXT_REL)
1490 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
1491@@ -2338,7 +2560,7 @@ else
1492
1493 (define_insn "tablejump_internal1"
1494 [(set (pc)
1495- (match_operand:SI 0 "register_operand" "d"))
1496+ (match_operand 0 "register_operand" "d"))
1497 (use (label_ref (match_operand 1 "" "")))]
1498 ""
1499 "bra%?\t%0 "
1500@@ -2348,9 +2570,9 @@ else
1501
1502 (define_expand "tablejump_internal3"
1503 [(parallel [(set (pc)
1504- (plus:SI (match_operand:SI 0 "register_operand" "d")
1505- (label_ref:SI (match_operand:SI 1 "" ""))))
1506- (use (label_ref:SI (match_dup 1)))])]
1507+ (plus (match_operand 0 "register_operand" "d")
1508+ (label_ref (match_operand:SI 1 "" ""))))
1509+ (use (label_ref (match_dup 1)))])]
1510 ""
1511 ""
1512 )
1513@@ -2411,7 +2633,7 @@ else
1514 (minus (reg 1) (match_operand 1 "register_operand" "")))
1515 (set (reg 1)
1516 (minus (reg 1) (match_dup 1)))]
1517- ""
1518+ "!TARGET_MB_64"
1519 {
1520 rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1521 rtx reg = gen_reg_rtx (Pmode);
1522@@ -2436,7 +2658,7 @@ else
1523 (define_expand "save_stack_block"
1524 [(match_operand 0 "register_operand" "")
1525 (match_operand 1 "register_operand" "")]
1526- ""
1527+ "!TARGET_MB_64"
1528 {
1529 emit_move_insn (operands[0], operands[1]);
1530 DONE;
1531@@ -2446,7 +2668,7 @@ else
1532 (define_expand "restore_stack_block"
1533 [(match_operand 0 "register_operand" "")
1534 (match_operand 1 "register_operand" "")]
1535- ""
1536+ "!TARGET_MB_64"
1537 {
1538 rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1539 rtx rtmp = gen_rtx_REG (SImode, R_TMP);
1540@@ -2493,7 +2715,7 @@ else
1541
1542 (define_insn "<optab>_internal"
1543 [(any_return)
1544- (use (match_operand:SI 0 "register_operand" ""))]
1545+ (use (match_operand 0 "register_operand" ""))]
1546 ""
1547 {
1548 if (microblaze_is_break_handler ())
1549@@ -2526,7 +2748,7 @@ else
1550 (define_expand "call"
1551 [(parallel [(call (match_operand 0 "memory_operand" "m")
1552 (match_operand 1 "" "i"))
1553- (clobber (reg:SI R_SR))
1554+ (clobber (reg R_SR))
1555 (use (match_operand 2 "" ""))
1556 (use (match_operand 3 "" ""))])]
1557 ""
1558@@ -2547,12 +2769,12 @@ else
1559
1560 if (GET_CODE (XEXP (operands[0], 0)) == UNSPEC)
1561 emit_call_insn (gen_call_internal_plt0 (operands[0], operands[1],
1562- gen_rtx_REG (SImode,
1563+ gen_rtx_REG (Pmode,
1564 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
1565 pic_offset_table_rtx));
1566 else
1567 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
1568- gen_rtx_REG (SImode,
1569+ gen_rtx_REG (Pmode,
1570 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
1571
1572 DONE;
1573@@ -2562,7 +2784,7 @@ else
1574 (define_expand "call_internal0"
1575 [(parallel [(call (match_operand 0 "" "")
1576 (match_operand 1 "" ""))
1577- (clobber (match_operand:SI 2 "" ""))])]
1578+ (clobber (match_operand 2 "" ""))])]
1579 ""
1580 {
1581 }
1582@@ -2571,18 +2793,34 @@ else
1583 (define_expand "call_internal_plt0"
1584 [(parallel [(call (match_operand 0 "" "")
1585 (match_operand 1 "" ""))
1586- (clobber (match_operand:SI 2 "" ""))
1587- (use (match_operand:SI 3 "" ""))])]
1588+ (clobber (match_operand 2 "" ""))
1589+ (use (match_operand 3 "" ""))])]
1590 ""
1591 {
1592 }
1593 )
1594
1595+(define_insn "call_internal_plt_64"
1596+ [(call (mem (match_operand 0 "call_insn_plt_operand" ""))
1597+ (match_operand 1 "" "i"))
1598+ (clobber (reg R_SR))
1599+ (use (reg R_GOT))]
1600+ "flag_pic && TARGET_MB_64"
1601+ {
1602+ register rtx target2 = gen_rtx_REG (Pmode,
1603+ GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1604+ gen_rtx_CLOBBER (VOIDmode, target2);
1605+ return "brealid\tr15,%0\;%#";
1606+ }
1607+ [(set_attr "type" "call")
1608+ (set_attr "mode" "none")
1609+ (set_attr "length" "4")])
1610+
1611 (define_insn "call_internal_plt"
1612- [(call (mem (match_operand:SI 0 "call_insn_plt_operand" ""))
1613- (match_operand:SI 1 "" "i"))
1614- (clobber (reg:SI R_SR))
1615- (use (reg:SI R_GOT))]
1616+ [(call (mem (match_operand 0 "call_insn_plt_operand" ""))
1617+ (match_operand 1 "" "i"))
1618+ (clobber (reg R_SR))
1619+ (use (reg R_GOT))]
1620 "flag_pic"
1621 {
1622 register rtx target2 = gen_rtx_REG (Pmode,
1623@@ -2594,10 +2832,41 @@ else
1624 (set_attr "mode" "none")
1625 (set_attr "length" "4")])
1626
1627+(define_insn "call_internal1_64"
1628+ [(call (mem (match_operand:VOID 0 "call_insn_simple_operand" "ri"))
1629+ (match_operand 1 "" "i"))
1630+ (clobber (reg R_SR))]
1631+ "TARGET_MB_64"
1632+ {
1633+ register rtx target = operands[0];
1634+ register rtx target2 = gen_rtx_REG (Pmode,
1635+ GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1636+ if (GET_CODE (target) == SYMBOL_REF) {
1637+ if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
1638+ gen_rtx_CLOBBER (VOIDmode, target2);
1639+ return "breaki\tr16,%0\;%#";
1640+ }
1641+ else {
1642+ gen_rtx_CLOBBER (VOIDmode, target2);
1643+ return "brealid\tr15,%0\;%#";
1644+ }
1645+ } else if (GET_CODE (target) == CONST_INT)
1646+ return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
1647+ else if (GET_CODE (target) == REG)
1648+ return "brald\tr15,%0\;%#";
1649+ else {
1650+ fprintf (stderr,"Unsupported call insn\n");
1651+ return NULL;
1652+ }
1653+ }
1654+ [(set_attr "type" "call")
1655+ (set_attr "mode" "none")
1656+ (set_attr "length" "4")])
1657+
1658 (define_insn "call_internal1"
1659 [(call (mem (match_operand:VOID 0 "call_insn_simple_operand" "ri"))
1660- (match_operand:SI 1 "" "i"))
1661- (clobber (reg:SI R_SR))]
1662+ (match_operand 1 "" "i"))
1663+ (clobber (reg R_SR))]
1664 ""
1665 {
1666 register rtx target = operands[0];
1667@@ -2631,7 +2900,7 @@ else
1668 [(parallel [(set (match_operand 0 "register_operand" "=d")
1669 (call (match_operand 1 "memory_operand" "m")
1670 (match_operand 2 "" "i")))
1671- (clobber (reg:SI R_SR))
1672+ (clobber (reg R_SR))
1673 (use (match_operand 3 "" ""))])] ;; next_arg_reg
1674 ""
1675 {
1676@@ -2652,13 +2921,13 @@ else
1677 if (GET_CODE (XEXP (operands[1], 0)) == UNSPEC)
1678 emit_call_insn (gen_call_value_intern_plt0 (operands[0], operands[1],
1679 operands[2],
1680- gen_rtx_REG (SImode,
1681+ gen_rtx_REG (Pmode,
1682 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
1683 pic_offset_table_rtx));
1684 else
1685 emit_call_insn (gen_call_value_internal (operands[0], operands[1],
1686 operands[2],
1687- gen_rtx_REG (SImode,
1688+ gen_rtx_REG (Pmode,
1689 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
1690
1691 DONE;
1692@@ -2670,7 +2939,7 @@ else
1693 [(parallel [(set (match_operand 0 "" "")
1694 (call (match_operand 1 "" "")
1695 (match_operand 2 "" "")))
1696- (clobber (match_operand:SI 3 "" ""))
1697+ (clobber (match_operand 3 "" ""))
1698 ])]
1699 ""
1700 {}
1701@@ -2680,18 +2949,35 @@ else
1702 [(parallel[(set (match_operand 0 "" "")
1703 (call (match_operand 1 "" "")
1704 (match_operand 2 "" "")))
1705- (clobber (match_operand:SI 3 "" ""))
1706- (use (match_operand:SI 4 "" ""))])]
1707+ (clobber (match_operand 3 "" ""))
1708+ (use (match_operand 4 "" ""))])]
1709 "flag_pic"
1710 {}
1711 )
1712
1713+(define_insn "call_value_intern_plt_64"
1714+ [(set (match_operand:VOID 0 "register_operand" "=d")
1715+ (call (mem (match_operand 1 "call_insn_plt_operand" ""))
1716+ (match_operand 2 "" "i")))
1717+ (clobber (match_operand 3 "register_operand" "=d"))
1718+ (use (match_operand 4 "register_operand"))]
1719+ "flag_pic && TARGET_MB_64"
1720+ {
1721+ register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1722+
1723+ gen_rtx_CLOBBER (VOIDmode,target2);
1724+ return "brealid\tr15,%1\;%#";
1725+ }
1726+ [(set_attr "type" "call")
1727+ (set_attr "mode" "none")
1728+ (set_attr "length" "4")])
1729+
1730 (define_insn "call_value_intern_plt"
1731 [(set (match_operand:VOID 0 "register_operand" "=d")
1732- (call (mem (match_operand:SI 1 "call_insn_plt_operand" ""))
1733- (match_operand:SI 2 "" "i")))
1734- (clobber (match_operand:SI 3 "register_operand" "=d"))
1735- (use (match_operand:SI 4 "register_operand"))]
1736+ (call (mem (match_operand 1 "call_insn_plt_operand" ""))
1737+ (match_operand 2 "" "i")))
1738+ (clobber (match_operand 3 "register_operand" "=d"))
1739+ (use (match_operand 4 "register_operand"))]
1740 "flag_pic"
1741 {
1742 register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1743@@ -2703,11 +2989,46 @@ else
1744 (set_attr "mode" "none")
1745 (set_attr "length" "4")])
1746
1747+(define_insn "call_value_intern_64"
1748+ [(set (match_operand:VOID 0 "register_operand" "=d")
1749+ (call (mem (match_operand:VOID 1 "call_insn_operand" "ri"))
1750+ (match_operand 2 "" "i")))
1751+ (clobber (match_operand 3 "register_operand" "=d"))]
1752+ "TARGET_MB_64"
1753+ {
1754+ register rtx target = operands[1];
1755+ register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1756+
1757+ if (GET_CODE (target) == SYMBOL_REF)
1758+ {
1759+ gen_rtx_CLOBBER (VOIDmode,target2);
1760+ if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
1761+ return "breaki\tr16,%1\;%#";
1762+ else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
1763+ {
1764+ return "brealid\tr15,%1\;%#";
1765+ }
1766+ else
1767+ {
1768+ return "bralid\tr15,%1\;%#";
1769+ }
1770+ }
1771+ else if (GET_CODE (target) == CONST_INT)
1772+ return "la\t%@,r0,%1\;brald\tr15,%@\;%#";
1773+ else if (GET_CODE (target) == REG)
1774+ return "brald\tr15,%1\;%#";
1775+ else
1776+ return "Unsupported call insn\n";
1777+ }
1778+ [(set_attr "type" "call")
1779+ (set_attr "mode" "none")
1780+ (set_attr "length" "4")])
1781+
1782 (define_insn "call_value_intern"
1783 [(set (match_operand:VOID 0 "register_operand" "=d")
1784 (call (mem (match_operand:VOID 1 "call_insn_operand" "ri"))
1785- (match_operand:SI 2 "" "i")))
1786- (clobber (match_operand:SI 3 "register_operand" "=d"))]
1787+ (match_operand 2 "" "i")))
1788+ (clobber (match_operand 3 "register_operand" "=d"))]
1789 ""
1790 {
1791 register rtx target = operands[1];
1792@@ -2881,7 +3202,6 @@ else
1793
1794 ;;if (!register_operand (operands[0], VOIDmode))
1795 ;; FAIL;
1796-
1797 emit_insn (gen_insv_32 (operands[0], operands[1],
1798 operands[2], operands[3]));
1799 DONE;
1800diff --git a/gcc/config/microblaze/t-microblaze b/gcc/config/microblaze/t-microblaze
1801index e9a1921ae26..9fc80b142ce 100644
1802--- a/gcc/config/microblaze/t-microblaze
1803+++ b/gcc/config/microblaze/t-microblaze
1804@@ -2,7 +2,8 @@ MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high mlittle-en
1805 MULTILIB_DIRNAMES = bs m mh le m64
1806 MULTILIB_EXCEPTIONS = *mxl-barrel-shift/mxl-multiply-high mxl-multiply-high
1807 MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian
1808-MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64
1809+MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian/m64
1810+MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64 mxl-multiply-high
1811 MULTILIB_EXCEPTIONS += mxl-multiply-high/mlittle-endian
1812 MULTILIB_EXCEPTIONS += mxl-multiply-high/m64
1813 MULTILIB_EXCEPTIONS += *mxl-multiply-high/mlittle-endian/m64
1814diff --git a/libgcc/config/microblaze/crti.S b/libgcc/config/microblaze/crti.S
1815index d0146083db6..005825f1ec5 100644
1816--- a/libgcc/config/microblaze/crti.S
1817+++ b/libgcc/config/microblaze/crti.S
1818@@ -40,7 +40,7 @@
1819
1820 .align 2
1821 __init:
1822- addik r1, r1, -8
1823+ addik r1, r1, -16
1824 sw r15, r0, r1
1825 la r11, r0, _stack
1826 mts rshr, r11
1827@@ -51,5 +51,5 @@ __init:
1828 .global __fini
1829 .align 2
1830 __fini:
1831- addik r1, r1, -8
1832+ addik r1, r1, -16
1833 sw r15, r0, r1
1834diff --git a/libgcc/config/microblaze/crtn.S b/libgcc/config/microblaze/crtn.S
1835index 2fff5ac04c7..5705eff9a4a 100644
1836--- a/libgcc/config/microblaze/crtn.S
1837+++ b/libgcc/config/microblaze/crtn.S
1838@@ -33,9 +33,9 @@
1839 .section .init, "ax"
1840 lw r15, r0, r1
1841 rtsd r15, 8
1842- addik r1, r1, 8
1843+ addik r1, r1, 16
1844
1845 .section .fini, "ax"
1846 lw r15, r0, r1
1847 rtsd r15, 8
1848- addik r1, r1, 8
1849+ addik r1, r1, 16
1850diff --git a/libgcc/config/microblaze/divdi3.S b/libgcc/config/microblaze/divdi3.S
1851new file mode 100644
1852index 00000000000..d37bf5165c6
1853--- /dev/null
1854+++ b/libgcc/config/microblaze/divdi3.S
1855@@ -0,0 +1,98 @@
1856+###################################-
1857+#
1858+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
1859+#
1860+# Contributed by Michael Eager <eager@eagercon.com>.
1861+#
1862+# This file is free software; you can redistribute it and/or modify it
1863+# under the terms of the GNU General Public License as published by the
1864+# Free Software Foundation; either version 3, or (at your option) any
1865+# later version.
1866+#
1867+# GCC is distributed in the hope that it will be useful, but WITHOUT
1868+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1869+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1870+# License for more details.
1871+#
1872+# Under Section 7 of GPL version 3, you are granted additional
1873+# permissions described in the GCC Runtime Library Exception, version
1874+# 3.1, as published by the Free Software Foundation.
1875+#
1876+# You should have received a copy of the GNU General Public License and
1877+# a copy of the GCC Runtime Library Exception along with this program;
1878+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1879+# <http://www.gnu.org/licenses/>.
1880+#
1881+# divdi3.S
1882+#
1883+# Divide operation for 32 bit integers.
1884+# Input : Dividend in Reg r5
1885+# Divisor in Reg r6
1886+# Output: Result in Reg r3
1887+#
1888+#######################################
1889+
1890+#ifdef __arch64__
1891+ .globl __divdi3
1892+ .ent __divdi3
1893+ .type __divdi3,@function
1894+__divdi3:
1895+ .frame r1,0,r15
1896+
1897+ ADDLIK r1,r1,-32
1898+ SLI r28,r1,0
1899+ SLI r29,r1,8
1900+ SLI r30,r1,16
1901+ SLI r31,r1,24
1902+
1903+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
1904+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
1905+ XORL r28,r5,r6 # Get the sign of the result
1906+ BEALGEI r5,$LaR5_Pos
1907+ RSUBLI r5,r5,0 # Make r5 positive
1908+$LaR5_Pos:
1909+ BEALGEI r6,$LaR6_Pos
1910+ RSUBLI r6,r6,0 # Make r6 positive
1911+$LaR6_Pos:
1912+ ADDLIK r30,r0,0 # Clear mod
1913+ ADDLIK r3,r0,0 # clear div
1914+ ADDLIK r29,r0,64 # Initialize the loop count
1915+
1916+ # First part try to find the first '1' in the r5
1917+$LaDIV0:
1918+ BEALLTI r5,$LaDIV2 # This traps r5 == 0x80000000
1919+$LaDIV1:
1920+ ADDL r5,r5,r5 # left shift logical r5
1921+ ADDLIK r29,r29,-1
1922+ BEALGTI r5,$LaDIV1
1923+$LaDIV2:
1924+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
1925+ ADDLC r30,r30,r30 # Move that bit into the Mod register
1926+ RSUBL r31,r6,r30 # Try to subtract (r30 a r6)
1927+ BEALLTI r31,$LaMOD_TOO_SMALL
1928+ ORL r30,r0,r31 # Move the r31 to mod since the result was positive
1929+ ADDLIK r3,r3,1
1930+$LaMOD_TOO_SMALL:
1931+ ADDLIK r29,r29,-1
1932+ BEALEQi r29,$LaLOOP_END
1933+ ADDL r3,r3,r3 # Shift in the '1' into div
1934+ BREAI $LaDIV2 # Div2
1935+$LaLOOP_END:
1936+ BEALGEI r28,$LaRETURN_HERE
1937+ RSUBLI r3,r3,0 # Negate the result
1938+ BREAI $LaRETURN_HERE
1939+$LaDiv_By_Zero:
1940+$LaResult_Is_Zero:
1941+ ORL r3,r0,r0 # set result to 0
1942+$LaRETURN_HERE:
1943+# Restore values of CSRs and that of r3 and the divisor and the dividend
1944+ LLI r28,r1,0
1945+ LLI r29,r1,8
1946+ LLI r30,r1,16
1947+ LLI r31,r1,24
1948+ ADDLIK r1,r1,32
1949+ RTSD r15,8
1950+ nop
1951+.end __divdi3
1952+ .size __divdi3, . - __divdi3
1953+#endif
1954diff --git a/libgcc/config/microblaze/divdi3_table.c b/libgcc/config/microblaze/divdi3_table.c
1955new file mode 100644
1956index 00000000000..80962597ea5
1957--- /dev/null
1958+++ b/libgcc/config/microblaze/divdi3_table.c
1959@@ -0,0 +1,62 @@
1960+/* Table for software lookup divide for Xilinx MicroBlaze.
1961+
1962+ Copyright (C) 2009-2017 Free Software Foundation, Inc.
1963+
1964+ Contributed by Michael Eager <eager@eagercon.com>.
1965+
1966+ This file is free software; you can redistribute it and/or modify it
1967+ under the terms of the GNU General Public License as published by the
1968+ Free Software Foundation; either version 3, or (at your option) any
1969+ later version.
1970+
1971+ GCC is distributed in the hope that it will be useful, but WITHOUT
1972+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1973+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1974+ License for more details.
1975+
1976+ Under Section 7 of GPL version 3, you are granted additional
1977+ permissions described in the GCC Runtime Library Exception, version
1978+ 3.1, as published by the Free Software Foundation.
1979+
1980+ You should have received a copy of the GNU General Public License and
1981+ a copy of the GCC Runtime Library Exception along with this program;
1982+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1983+ <http://www.gnu.org/licenses/>. */
1984+
1985+
1986+unsigned char _divdi3_table[] =
1987+{
1988+ 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7,
1989+ 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
1990+ 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7,
1991+ 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
1992+ 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7,
1993+ 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
1994+ 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7,
1995+ 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
1996+ 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7,
1997+ 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
1998+ 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7,
1999+ 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
2000+ 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7,
2001+ 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
2002+ 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7,
2003+ 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
2004+ 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7,
2005+ 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
2006+ 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7,
2007+ 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
2008+ 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7,
2009+ 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
2010+ 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7,
2011+ 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
2012+ 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7,
2013+ 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
2014+ 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7,
2015+ 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
2016+ 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7,
2017+ 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
2018+ 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7,
2019+ 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
2020+};
2021+
2022diff --git a/libgcc/config/microblaze/moddi3.S b/libgcc/config/microblaze/moddi3.S
2023new file mode 100644
2024index 00000000000..5d3f7c03fc8
2025--- /dev/null
2026+++ b/libgcc/config/microblaze/moddi3.S
2027@@ -0,0 +1,97 @@
2028+###################################
2029+#
2030+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2031+#
2032+# Contributed by Michael Eager <eager@eagercon.com>.
2033+#
2034+# This file is free software; you can redistribute it and/or modify it
2035+# under the terms of the GNU General Public License as published by the
2036+# Free Software Foundation; either version 3, or (at your option) any
2037+# later version.
2038+#
2039+# GCC is distributed in the hope that it will be useful, but WITHOUT
2040+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2041+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2042+# License for more details.
2043+#
2044+# Under Section 7 of GPL version 3, you are granted additional
2045+# permissions described in the GCC Runtime Library Exception, version
2046+# 3.1, as published by the Free Software Foundation.
2047+#
2048+# You should have received a copy of the GNU General Public License and
2049+# a copy of the GCC Runtime Library Exception along with this program;
2050+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2051+# <http://www.gnu.org/licenses/>.
2052+#
2053+# moddi3.S
2054+#
2055+# modulo operation for 32 bit integers.
2056+# Input : op1 in Reg r5
2057+# op2 in Reg r6
2058+# Output: op1 mod op2 in Reg r3
2059+#
2060+#######################################
2061+
2062+#ifdef __arch64__
2063+ .globl __moddi3
2064+ .ent __moddi3
2065+ .type __moddi3,@function
2066+__moddi3:
2067+ .frame r1,0,r15
2068+
2069+ addlik r1,r1,-32
2070+ sli r28,r1,0
2071+ sli r29,r1,8
2072+ sli r30,r1,16
2073+ sli r31,r1,32
2074+
2075+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2076+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2077+ ADDL r28,r5,r0 # Get the sign of the result [ Depends only on the first arg]
2078+ BEALGEI r5,$LaR5_Pos
2079+ RSUBLI r5,r5,0 # Make r5 positive
2080+$LaR5_Pos:
2081+ BEALGEI r6,$LaR6_Pos
2082+ RSUBLI r6,r6,0 # Make r6 positive
2083+$LaR6_Pos:
2084+ ADDLIK r3,r0,0 # Clear mod
2085+ ADDLIK r30,r0,0 # clear div
2086+ ADDLIK r29,r0,64 # Initialize the loop count
2087+ BEALLTI r5,$LaDIV2 # If r5 is still negative (0x80000000), skip
2088+ # the first bit search.
2089+ # First part try to find the first '1' in the r5
2090+$LaDIV1:
2091+ ADDL r5,r5,r5 # left shift logical r5
2092+ ADDLIK r29,r29,-1
2093+ BEALGEI r5,$LaDIV1 #
2094+$LaDIV2:
2095+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2096+ ADDLC r3,r3,r3 # Move that bit into the Mod register
2097+ rSUBL r31,r6,r3 # Try to subtract (r30 a r6)
2098+ BEALLTi r31,$LaMOD_TOO_SMALL
2099+ ORL r3,r0,r31 # Move the r31 to mod since the result was positive
2100+ ADDLIK r30,r30,1
2101+$LaMOD_TOO_SMALL:
2102+ ADDLIK r29,r29,-1
2103+ BEALEQi r29,$LaLOOP_END
2104+ ADDL r30,r30,r30 # Shift in the '1' into div
2105+ BREAI $LaDIV2 # Div2
2106+$LaLOOP_END:
2107+ BEALGEI r28,$LaRETURN_HERE
2108+ rsubli r3,r3,0 # Negate the result
2109+ BREAI $LaRETURN_HERE
2110+$LaDiv_By_Zero:
2111+$LaResult_Is_Zero:
2112+ orl r3,r0,r0 # set result to 0 [Both mod as well as div are 0]
2113+$LaRETURN_HERE:
2114+# Restore values of CSRs and that of r3 and the divisor and the dividend
2115+ lli r28,r1,0
2116+ lli r29,r1,8
2117+ lli r30,r1,16
2118+ lli r31,r1,24
2119+ addlik r1,r1,32
2120+ rtsd r15,8
2121+ nop
2122+ .end __moddi3
2123+ .size __moddi3, . - __moddi3
2124+#endif
2125diff --git a/libgcc/config/microblaze/muldi3.S b/libgcc/config/microblaze/muldi3.S
2126new file mode 100644
2127index 00000000000..567784197d3
2128--- /dev/null
2129+++ b/libgcc/config/microblaze/muldi3.S
2130@@ -0,0 +1,73 @@
2131+/*###################################-*-asm*-
2132+#
2133+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2134+#
2135+# Contributed by Michael Eager <eager@eagercon.com>.
2136+#
2137+# This file is free software; you can redistribute it and/or modify it
2138+# under the terms of the GNU General Public License as published by the
2139+# Free Software Foundation; either version 3, or (at your option) any
2140+# later version.
2141+#
2142+# GCC is distributed in the hope that it will be useful, but WITHOUT
2143+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2144+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2145+# License for more details.
2146+#
2147+# Under Section 7 of GPL version 3, you are granted additional
2148+# permissions described in the GCC Runtime Library Exception, version
2149+# 3.1, as published by the Free Software Foundation.
2150+#
2151+# You should have received a copy of the GNU General Public License and
2152+# a copy of the GCC Runtime Library Exception along with this program;
2153+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2154+# <http://www.gnu.org/licenses/>.
2155+#
2156+# muldi3.S
2157+#
2158+# Multiply operation for 32 bit integers.
2159+# Input : Operand1 in Reg r5
2160+# Operand2 in Reg r6
2161+# Output: Result [op1 * op2] in Reg r3
2162+#
2163+#######################################*/
2164+
2165+#ifdef __arch64__
2166+ .globl __muldi3
2167+ .ent __muldi3
2168+ .type __muldi3,@function
2169+__muldi3:
2170+ .frame r1,0,r15
2171+ addl r3,r0,r0
2172+ BEALEQI r5,$L_Result_Is_Zero # Multiply by Zero
2173+ BEALEQI r6,$L_Result_Is_Zero # Multiply by Zero
2174+ XORL r4,r5,r6 # Get the sign of the result
2175+ BEALGEI r5,$L_R5_Pos
2176+ RSUBLI r5,r5,0 # Make r5 positive
2177+$L_R5_Pos:
2178+ BEALGEI r6,$L_R6_Pos
2179+ RSUBLI r6,r6,0 # Make r6 positive
2180+$L_R6_Pos:
2181+ breai $L1
2182+$L2:
2183+ addl r5,r5,r5
2184+$L1:
2185+ srll r6,r6
2186+ addlc r7,r0,r0
2187+ bealeqi r7,$L2
2188+ addl r3,r3,r5
2189+ bealnei r6,$L2
2190+ beallti r4,$L_NegateResult
2191+ rtsd r15,8
2192+ nop
2193+$L_NegateResult:
2194+ rsubl r3,r3,r0
2195+ rtsd r15,8
2196+ nop
2197+$L_Result_Is_Zero:
2198+ addli r3,r0,0
2199+ rtsd r15,8
2200+ nop
2201+ .end __muldi3
2202+ .size __muldi3, . - __muldi3
2203+#endif
2204diff --git a/libgcc/config/microblaze/t-microblaze b/libgcc/config/microblaze/t-microblaze
2205index 8d954a49575..35021b24b7d 100644
2206--- a/libgcc/config/microblaze/t-microblaze
2207+++ b/libgcc/config/microblaze/t-microblaze
2208@@ -1,11 +1,16 @@
2209-LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _mulsi3 _udivsi3 _umodsi3
2210+LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _mulsi3 _udivsi3 _umodsi3 \
2211+ _divdi3 _moddi3 _muldi3 _udivdi3 _umoddi3
2212
2213 LIB2ADD += \
2214 $(srcdir)/config/microblaze/divsi3.S \
2215+ $(srcdir)/config/microblaze/divdi3.S \
2216 $(srcdir)/config/microblaze/modsi3.S \
2217- $(srcdir)/config/microblaze/muldi3_hard.S \
2218+ $(srcdir)/config/microblaze/moddi3.S \
2219 $(srcdir)/config/microblaze/mulsi3.S \
2220+ $(srcdir)/config/microblaze/muldi3.S \
2221 $(srcdir)/config/microblaze/stack_overflow_exit.S \
2222 $(srcdir)/config/microblaze/udivsi3.S \
2223+ $(srcdir)/config/microblaze/udivdi3.S \
2224 $(srcdir)/config/microblaze/umodsi3.S \
2225- $(srcdir)/config/microblaze/divsi3_table.c
2226+ $(srcdir)/config/microblaze/umoddi3.S \
2227+ $(srcdir)/config/microblaze/divsi3_table.c \
2228diff --git a/libgcc/config/microblaze/udivdi3.S b/libgcc/config/microblaze/udivdi3.S
2229new file mode 100644
2230index 00000000000..c210fbc7128
2231--- /dev/null
2232+++ b/libgcc/config/microblaze/udivdi3.S
2233@@ -0,0 +1,107 @@
2234+###################################-
2235+#
2236+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2237+#
2238+# Contributed by Michael Eager <eager@eagercon.com>.
2239+#
2240+# This file is free software; you can redistribute it and/or modify it
2241+# under the terms of the GNU General Public License as published by the
2242+# Free Software Foundation; either version 3, or (at your option) any
2243+# later version.
2244+#
2245+# GCC is distributed in the hope that it will be useful, but WITHOUT
2246+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2247+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2248+# License for more details.
2249+#
2250+# Under Section 7 of GPL version 3, you are granted additional
2251+# permissions described in the GCC Runtime Library Exception, version
2252+# 3.1, as published by the Free Software Foundation.
2253+#
2254+# You should have received a copy of the GNU General Public License and
2255+# a copy of the GCC Runtime Library Exception along with this program;
2256+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2257+# <http://www.gnu.org/licenses/>.
2258+#
2259+# udivdi3.S
2260+#
2261+# Unsigned divide operation.
2262+# Input : Divisor in Reg r5
2263+# Dividend in Reg r6
2264+# Output: Result in Reg r3
2265+#
2266+#######################################
2267+
2268+#ifdef __arch64__
2269+ .globl __udivdi3
2270+ .ent __udivdi3
2271+ .type __udivdi3,@function
2272+__udivdi3:
2273+ .frame r1,0,r15
2274+
2275+ ADDlIK r1,r1,-24
2276+ SLI r29,r1,0
2277+ SLI r30,r1,8
2278+ SLI r31,r1,16
2279+
2280+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2281+ ADDLIK r30,r0,0 # Clear mod
2282+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2283+ ADDLIK r29,r0,64 # Initialize the loop count
2284+
2285+ # Check if r6 and r5 are equal # if yes, return 1
2286+ RSUBL r18,r5,r6
2287+ ADDLIK r3,r0,1
2288+ BEALEQI r18,$LaRETURN_HERE
2289+
2290+ # Check if (uns)r6 is greater than (uns)r5. In that case, just return 0
2291+ XORL r18,r5,r6
2292+ ADDL r3,r0,r0 # We would anyways clear r3
2293+ BEALGEI r18,$LRSUBL
2294+ BEALLTI r6,$LaRETURN_HERE # r6[bit 31 = 1] hence is greater
2295+ BREAI $LCheckr6
2296+$LRSUBL:
2297+ RSUBL r18,r6,r5 # MICROBLAZEcmp
2298+ BEALLTI r18,$LaRETURN_HERE
2299+
2300+ # If r6 [bit 31] is set, then return result as 1
2301+$LCheckr6:
2302+ BEALGTI r6,$LaDIV0
2303+ ADDLIK r3,r0,1
2304+ BREAI $LaRETURN_HERE
2305+
2306+ # First part try to find the first '1' in the r5
2307+$LaDIV0:
2308+ BEALLTI r5,$LaDIV2
2309+$LaDIV1:
2310+ ADDL r5,r5,r5 # left shift logical r5
2311+ ADDLIK r29,r29,-1
2312+ BEALGTI r5,$LaDIV1
2313+$LaDIV2:
2314+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2315+ ADDLC r30,r30,r30 # Move that bit into the Mod register
2316+ RSUBL r31,r6,r30 # Try to subtract (r30 a r6)
2317+ BEALLTI r31,$LaMOD_TOO_SMALL
2318+ ORL r30,r0,r31 # Move the r31 to mod since the result was positive
2319+ ADDLIK r3,r3,1
2320+$LaMOD_TOO_SMALL:
2321+ ADDLIK r29,r29,-1
2322+ BEALEQi r29,$LaLOOP_END
2323+ ADDL r3,r3,r3 # Shift in the '1' into div
2324+ BREAI $LaDIV2 # Div2
2325+$LaLOOP_END:
2326+ BREAI $LaRETURN_HERE
2327+$LaDiv_By_Zero:
2328+$LaResult_Is_Zero:
2329+ ORL r3,r0,r0 # set result to 0
2330+$LaRETURN_HERE:
2331+ # Restore values of CSRs and that of r3 and the divisor and the dividend
2332+ LLI r29,r1,0
2333+ LLI r30,r1,8
2334+ LLI r31,r1,16
2335+ ADDLIK r1,r1,24
2336+ RTSD r15,8
2337+ NOP
2338+ .end __udivdi3
2339+ .size __udivdi3, . - __udivdi3
2340+#endif
2341diff --git a/libgcc/config/microblaze/umoddi3.S b/libgcc/config/microblaze/umoddi3.S
2342new file mode 100644
2343index 00000000000..7f5cd23f9a1
2344--- /dev/null
2345+++ b/libgcc/config/microblaze/umoddi3.S
2346@@ -0,0 +1,110 @@
2347+###################################
2348+#
2349+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2350+#
2351+# Contributed by Michael Eager <eager@eagercon.com>.
2352+#
2353+# This file is free software; you can redistribute it and/or modify it
2354+# under the terms of the GNU General Public License as published by the
2355+# Free Software Foundation; either version 3, or (at your option) any
2356+# later version.
2357+#
2358+# GCC is distributed in the hope that it will be useful, but WITHOUT
2359+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2360+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2361+# License for more details.
2362+#
2363+# Under Section 7 of GPL version 3, you are granted additional
2364+# permissions described in the GCC Runtime Library Exception, version
2365+# 3.1, as published by the Free Software Foundation.
2366+#
2367+# You should have received a copy of the GNU General Public License and
2368+# a copy of the GCC Runtime Library Exception along with this program;
2369+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2370+# <http://www.gnu.org/licenses/>.
2371+#
2372+# umoddi3.S
2373+#
2374+# Unsigned modulo operation for 32 bit integers.
2375+# Input : op1 in Reg r5
2376+# op2 in Reg r6
2377+# Output: op1 mod op2 in Reg r3
2378+#
2379+#######################################
2380+
2381+#ifdef __arch64__
2382+ .globl __umoddi3
2383+ .ent __umoddi3
2384+ .type __umoddi3,@function
2385+__umoddi3:
2386+ .frame r1,0,r15
2387+
2388+ addlik r1,r1,-24
2389+ sli r29,r1,0
2390+ sli r30,r1,8
2391+ sli r31,r1,16
2392+
2393+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2394+ ADDLIK r3,r0,0 # Clear div
2395+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2396+ ADDLIK r30,r0,0 # clear mod
2397+ ADDLIK r29,r0,64 # Initialize the loop count
2398+
2399+# Check if r6 and r5 are equal # if yes, return 0
2400+ rsubl r18,r5,r6
2401+ bealeqi r18,$LaRETURN_HERE
2402+
2403+# Check if (uns)r6 is greater than (uns)r5. In that case, just return r5
2404+ xorl r18,r5,r6
2405+ addlik r3,r5,0
2406+ bealgei r18,$LRSUB
2407+ beallti r6,$LaRETURN_HERE
2408+ breai $LCheckr6
2409+$LRSUB:
2410+ rsubl r18,r5,r6 # MICROBLAZEcmp
2411+ bealgti r18,$LaRETURN_HERE
2412+
2413+# If r6 [bit 31] is set, then return result as r5-r6
2414+$LCheckr6:
2415+ addlik r3,r0,0
2416+ bealgti r6,$LaDIV0
2417+ addlik r18,r0,0x7fffffff
2418+ andl r5,r5,r18
2419+ andl r6,r6,r18
2420+ breaid $LaRETURN_HERE
2421+ rsubl r3,r6,r5
2422+# First part: try to find the first '1' in the r5
2423+$LaDIV0:
2424+ BEALLTI r5,$LaDIV2
2425+$LaDIV1:
2426+ ADDL r5,r5,r5 # left shift logical r5
2427+ ADDLIK r29,r29,-1
2428+ BEALGEI r5,$LaDIV1 #
2429+$LaDIV2:
2430+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2431+ ADDLC r3,r3,r3 # Move that bit into the Mod register
2432+ rSUBL r31,r6,r3 # Try to subtract (r3 a r6)
2433+ BEALLTi r31,$LaMOD_TOO_SMALL
2434+ ORL r3,r0,r31 # Move the r31 to mod since the result was positive
2435+ ADDLIK r30,r30,1
2436+$LaMOD_TOO_SMALL:
2437+ ADDLIK r29,r29,-1
2438+ BEALEQi r29,$LaLOOP_END
2439+ ADDL r30,r30,r30 # Shift in the '1' into div
2440+ BREAI $LaDIV2 # Div2
2441+$LaLOOP_END:
2442+ BREAI $LaRETURN_HERE
2443+$LaDiv_By_Zero:
2444+$LaResult_Is_Zero:
2445+ orl r3,r0,r0 # set result to 0
2446+$LaRETURN_HERE:
2447+# Restore values of CSRs and that of r3 and the divisor and the dividend
2448+ lli r29,r1,0
2449+ lli r30,r1,8
2450+ lli r31,r1,16
2451+ addlik r1,r1,24
2452+ rtsd r15,8
2453+ nop
2454+.end __umoddi3
2455+ .size __umoddi3, . - __umoddi3
2456+#endif
2457--
24582.17.1
2459