blob: 411958e748d32efa949cf28e32039e23c7389fe3 [file] [log] [blame]
Brad Bishop26bdd442019-08-16 17:08:17 -04001From eee9b7f7423823b133d6a5e5382863502433bdc6 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Fri, 27 Jul 2018 15:23:41 +0530
4Subject: [PATCH 41/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 | 7 +-
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, 1232 insertions(+), 236 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 a06b4d8..867a7b5 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 ;; Define floating point constraints
43
44diff --git a/gcc/config/microblaze/microblaze-c.c b/gcc/config/microblaze/microblaze-c.c
45index 7b020b5..d8a1d13 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 2079ae9..ba7ade4 100644
61--- a/gcc/config/microblaze/microblaze.c
62+++ b/gcc/config/microblaze/microblaze.c
63@@ -382,10 +382,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@@ -433,7 +433,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@@ -680,7 +680,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@@ -698,7 +698,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@@ -1230,8 +1230,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@@ -1561,14 +1569,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@@ -2219,7 +2233,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@@ -2487,7 +2501,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@@ -2513,6 +2527,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@@ -2525,12 +2540,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@@ -2713,7 +2728,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@@ -2736,7 +2754,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@@ -2802,7 +2823,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@@ -2810,8 +2831,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@@ -2819,8 +2840,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@@ -2831,9 +2852,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@@ -2848,7 +2869,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@@ -2858,8 +2879,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@@ -2949,7 +2970,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@@ -3095,10 +3119,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@@ -3108,15 +3132,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@@ -3124,7 +3156,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@@ -3224,12 +3256,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@@ -3245,15 +3277,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@@ -3402,9 +3444,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@@ -3417,7 +3464,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@@ -3564,7 +3614,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@@ -3619,9 +3669,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@@ -3645,7 +3695,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@@ -3764,7 +3814,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@@ -3774,10 +3824,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@@ -3798,8 +3848,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@@ -3807,17 +3857,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@@ -3964,7 +4028,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@@ -3974,7 +4038,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@@ -4127,6 +4211,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@@ -4136,6 +4231,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 72fbee5..1e60513 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) microblaze_reg_parm_stack_space(FNDECL)
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@@ -533,13 +551,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@@ -549,7 +567,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@@ -711,6 +729,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 0cd0441..0f41ac6 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@@ -539,6 +540,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@@ -560,23 +562,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@@ -603,7 +620,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@@ -616,23 +633,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@@ -661,7 +688,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@@ -672,7 +699,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@@ -683,7 +710,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@@ -787,7 +814,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@@ -817,6 +844,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@@ -845,16 +881,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@@ -869,7 +913,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@@ -881,18 +926,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@@ -917,7 +961,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@@ -943,7 +987,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@@ -1016,26 +1060,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@@ -1058,6 +1082,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@@ -1088,68 +1133,117 @@
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 (define_insn "*movdi_internal"
1204 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o")
1205 (match_operand:DI 1 "general_operand" " d,i,J,R,o,d,d"))]
1206- ""
1207+ "!TARGET_MB_64"
1208 {
1209 switch (which_alternative)
1210 {
1211@@ -1181,7 +1275,8 @@
1212 "reload_completed
1213 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1214 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1215- && (REGNO(operands[0]) == (REGNO(operands[1]) + 1))"
1216+ && (REGNO(operands[0]) == (REGNO(operands[1]) + 1))
1217+ && !(TARGET_MB_64)"
1218
1219 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
1220 (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
1221@@ -1193,12 +1288,22 @@
1222 "reload_completed
1223 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1224 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1225- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
1226+ && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))
1227+ && !(TARGET_MB_64)"
1228
1229 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1230 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
1231 "")
1232
1233+(define_insn "movdi_long_int"
1234+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1235+ (match_operand:DI 1 "general_operand" "i"))]
1236+ ""
1237+ "addlik\t%0,r0,%h1\n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #li => la";
1238+ [(set_attr "type" "no_delay_arith")
1239+ (set_attr "mode" "DI")
1240+ (set_attr "length" "12")])
1241+
1242 ;; Unlike most other insns, the move insns can't be split with
1243 ;; different predicates, because register spilling and other parts of
1244 ;; the compiler, have memoized the insn number already.
1245@@ -1270,6 +1375,8 @@
1246 (set_attr "length" "4,4,8,4,8,4,8")])
1247
1248
1249+
1250+
1251 ;; 16-bit Integer moves
1252
1253 ;; Unlike most other insns, the move insns can't be split with
1254@@ -1302,8 +1409,8 @@
1255 "@
1256 addik\t%0,r0,%1\t# %X1
1257 addk\t%0,%1,r0
1258- lhui\t%0,%1
1259- lhui\t%0,%1
1260+ lhu%i1\t%0,%1
1261+ lhu%i1\t%0,%1
1262 sh%i0\t%z1,%0
1263 sh%i0\t%z1,%0"
1264 [(set_attr "type" "arith,move,load,no_delay_load,store,no_delay_store")
1265@@ -1346,7 +1453,7 @@
1266 lbu%i1\t%0,%1
1267 lbu%i1\t%0,%1
1268 sb%i0\t%z1,%0
1269- sbi\t%z1,%0"
1270+ sb%i0\t%z1,%0"
1271 [(set_attr "type" "arith,arith,move,load,no_delay_load,store,no_delay_store")
1272 (set_attr "mode" "QI")
1273 (set_attr "length" "4,4,8,4,8,4,8")])
1274@@ -1419,7 +1526,7 @@
1275 addik\t%0,r0,%F1
1276 lw%i1\t%0,%1
1277 sw%i0\t%z1,%0
1278- swi\t%z1,%0"
1279+ sw%i0\t%z1,%0"
1280 [(set_attr "type" "move,no_delay_load,load,no_delay_load,no_delay_load,store,no_delay_store")
1281 (set_attr "mode" "SF")
1282 (set_attr "length" "4,4,4,4,4,4,4")])
1283@@ -1458,6 +1565,33 @@
1284 ;; movdf_internal
1285 ;; Applies to both TARGET_SOFT_FLOAT and TARGET_HARD_FLOAT
1286 ;;
1287+(define_insn "*movdf_internal_64"
1288+ [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,d,d,m")
1289+ (match_operand:DF 1 "general_operand" "d,dG,m,F,T,d"))]
1290+ "TARGET_MB_64"
1291+ {
1292+ switch (which_alternative)
1293+ {
1294+ case 0:
1295+ return "addlk\t%0,%1,r0";
1296+ case 1:
1297+ return "addlk\t%0,r0,r0";
1298+ case 2:
1299+ case 4:
1300+ return "ll%i1\t%0,%1";
1301+ case 3:
1302+ {
1303+ return "addlik\t%0,r0,%h1 \n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #Xfer Lo";
1304+ }
1305+ case 5:
1306+ return "sl%i0\t%1,%0";
1307+ }
1308+ gcc_unreachable ();
1309+ }
1310+ [(set_attr "type" "no_delay_move,no_delay_move,no_delay_load,no_delay_load,no_delay_load,no_delay_store")
1311+ (set_attr "mode" "DF")
1312+ (set_attr "length" "4,4,4,16,4,4")])
1313+
1314 (define_insn "*movdf_internal"
1315 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,d,o")
1316 (match_operand:DF 1 "general_operand" "dG,o,F,T,d"))]
1317@@ -1492,7 +1626,8 @@
1318 "reload_completed
1319 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1320 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1321- && (REGNO (operands[0]) == (REGNO (operands[1]) + 1))"
1322+ && (REGNO (operands[0]) == (REGNO (operands[1]) + 1))
1323+ && !TARGET_MB_64"
1324 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
1325 (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
1326 "")
1327@@ -1503,7 +1638,8 @@
1328 "reload_completed
1329 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1330 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1331- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
1332+ && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))
1333+ && !TARGET_MB_64"
1334 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1335 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
1336 "")
1337@@ -2003,6 +2139,31 @@ else
1338 "
1339 )
1340
1341+
1342+(define_insn "seq_internal_pat_long"
1343+ [(set (match_operand:DI 0 "register_operand" "=d")
1344+ (eq:DI
1345+ (match_operand:DI 1 "register_operand" "d")
1346+ (match_operand:DI 2 "register_operand" "d")))]
1347+ "TARGET_MB_64"
1348+ "pcmpleq\t%0,%1,%2"
1349+ [(set_attr "type" "arith")
1350+ (set_attr "mode" "DI")
1351+ (set_attr "length" "4")]
1352+)
1353+
1354+(define_insn "sne_internal_pat_long"
1355+ [(set (match_operand:DI 0 "register_operand" "=d")
1356+ (ne:DI
1357+ (match_operand:DI 1 "register_operand" "d")
1358+ (match_operand:DI 2 "register_operand" "d")))]
1359+ "TARGET_MB_64"
1360+ "pcmplne\t%0,%1,%2"
1361+ [(set_attr "type" "arith")
1362+ (set_attr "mode" "DI")
1363+ (set_attr "length" "4")]
1364+)
1365+
1366 (define_insn "seq_internal_pat"
1367 [(set (match_operand:SI 0 "register_operand" "=d")
1368 (eq:SI
1369@@ -2063,8 +2224,8 @@ else
1370 (define_expand "cbranchsi4"
1371 [(set (pc)
1372 (if_then_else (match_operator 0 "ordered_comparison_operator"
1373- [(match_operand:SI 1 "register_operand")
1374- (match_operand:SI 2 "arith_operand" "I,i")])
1375+ [(match_operand 1 "register_operand")
1376+ (match_operand 2 "arith_operand" "I,i")])
1377 (label_ref (match_operand 3 ""))
1378 (pc)))]
1379 ""
1380@@ -2076,13 +2237,13 @@ else
1381 (define_expand "cbranchsi4_reg"
1382 [(set (pc)
1383 (if_then_else (match_operator 0 "ordered_comparison_operator"
1384- [(match_operand:SI 1 "register_operand")
1385- (match_operand:SI 2 "register_operand")])
1386+ [(match_operand 1 "register_operand")
1387+ (match_operand 2 "register_operand")])
1388 (label_ref (match_operand 3 ""))
1389 (pc)))]
1390 ""
1391 {
1392- microblaze_expand_conditional_branch_reg (SImode, operands);
1393+ microblaze_expand_conditional_branch_reg (Pmode, operands);
1394 DONE;
1395 })
1396
1397@@ -2107,6 +2268,26 @@ else
1398 (label_ref (match_operand 1))
1399 (pc)))])
1400
1401+(define_insn "branch_zero64"
1402+ [(set (pc)
1403+ (if_then_else (match_operator 0 "ordered_comparison_operator"
1404+ [(match_operand 1 "register_operand" "d")
1405+ (const_int 0)])
1406+ (match_operand 2 "pc_or_label_operand" "")
1407+ (match_operand 3 "pc_or_label_operand" "")))
1408+ ]
1409+ "TARGET_MB_64"
1410+ {
1411+ if (operands[3] == pc_rtx)
1412+ return "bea%C0i%?\t%z1,%2";
1413+ else
1414+ return "bea%N0i%?\t%z1,%3";
1415+ }
1416+ [(set_attr "type" "branch")
1417+ (set_attr "mode" "none")
1418+ (set_attr "length" "4")]
1419+)
1420+
1421 (define_insn "branch_zero"
1422 [(set (pc)
1423 (if_then_else (match_operator:SI 0 "ordered_comparison_operator"
1424@@ -2127,6 +2308,47 @@ else
1425 (set_attr "length" "4")]
1426 )
1427
1428+(define_insn "branch_compare64"
1429+ [(set (pc)
1430+ (if_then_else (match_operator 0 "cmp_op"
1431+ [(match_operand 1 "register_operand" "d")
1432+ (match_operand 2 "register_operand" "d")
1433+ ])
1434+ (label_ref (match_operand 3))
1435+ (pc)))
1436+ (clobber(reg:SI R_TMP))]
1437+ "TARGET_MB_64"
1438+ {
1439+ operands[4] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
1440+ enum rtx_code code = GET_CODE (operands[0]);
1441+
1442+ if (code == GT || code == LE)
1443+ {
1444+ output_asm_insn ("cmp\tr18,%z1,%z2", operands);
1445+ code = swap_condition (code);
1446+ }
1447+ else if (code == GTU || code == LEU)
1448+ {
1449+ output_asm_insn ("cmpu\tr18,%z1,%z2", operands);
1450+ code = swap_condition (code);
1451+ }
1452+ else if (code == GE || code == LT)
1453+ {
1454+ output_asm_insn ("cmp\tr18,%z2,%z1", operands);
1455+ }
1456+ else if (code == GEU || code == LTU)
1457+ {
1458+ output_asm_insn ("cmpu\tr18,%z2,%z1", operands);
1459+ }
1460+
1461+ operands[0] = gen_rtx_fmt_ee (signed_condition (code), SImode, operands[4], const0_rtx);
1462+ return "bea%C0i%?\tr18,%3";
1463+ }
1464+ [(set_attr "type" "branch")
1465+ (set_attr "mode" "none")
1466+ (set_attr "length" "12")]
1467+)
1468+
1469 (define_insn "branch_compare"
1470 [(set (pc)
1471 (if_then_else (match_operator:SI 0 "cmp_op"
1472@@ -2310,7 +2532,7 @@ else
1473 ;; Indirect jumps. Jump to register values. Assuming absolute jumps
1474
1475 (define_insn "indirect_jump_internal1"
1476- [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
1477+ [(set (pc) (match_operand 0 "register_operand" "d"))]
1478 ""
1479 "bra%?\t%0"
1480 [(set_attr "type" "jump")
1481@@ -2323,7 +2545,7 @@ else
1482 (use (label_ref (match_operand 1 "" "")))]
1483 ""
1484 {
1485- gcc_assert (GET_MODE (operands[0]) == Pmode);
1486+ //gcc_assert (GET_MODE (operands[0]) == Pmode);
1487
1488 if (!flag_pic)
1489 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
1490@@ -2335,7 +2557,7 @@ else
1491
1492 (define_insn "tablejump_internal1"
1493 [(set (pc)
1494- (match_operand:SI 0 "register_operand" "d"))
1495+ (match_operand 0 "register_operand" "d"))
1496 (use (label_ref (match_operand 1 "" "")))]
1497 ""
1498 "bra%?\t%0 "
1499@@ -2345,9 +2567,9 @@ else
1500
1501 (define_expand "tablejump_internal3"
1502 [(parallel [(set (pc)
1503- (plus:SI (match_operand:SI 0 "register_operand" "d")
1504- (label_ref:SI (match_operand:SI 1 "" ""))))
1505- (use (label_ref:SI (match_dup 1)))])]
1506+ (plus (match_operand 0 "register_operand" "d")
1507+ (label_ref (match_operand:SI 1 "" ""))))
1508+ (use (label_ref (match_dup 1)))])]
1509 ""
1510 ""
1511 )
1512@@ -2408,7 +2630,7 @@ else
1513 (minus (reg 1) (match_operand 1 "register_operand" "")))
1514 (set (reg 1)
1515 (minus (reg 1) (match_dup 1)))]
1516- ""
1517+ "!TARGET_MB_64"
1518 {
1519 rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1520 rtx reg = gen_reg_rtx (Pmode);
1521@@ -2433,7 +2655,7 @@ else
1522 (define_expand "save_stack_block"
1523 [(match_operand 0 "register_operand" "")
1524 (match_operand 1 "register_operand" "")]
1525- ""
1526+ "!TARGET_MB_64"
1527 {
1528 emit_move_insn (operands[0], operands[1]);
1529 DONE;
1530@@ -2443,7 +2665,7 @@ else
1531 (define_expand "restore_stack_block"
1532 [(match_operand 0 "register_operand" "")
1533 (match_operand 1 "register_operand" "")]
1534- ""
1535+ "!TARGET_MB_64"
1536 {
1537 rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1538 rtx rtmp = gen_rtx_REG (SImode, R_TMP);
1539@@ -2490,7 +2712,7 @@ else
1540
1541 (define_insn "<optab>_internal"
1542 [(any_return)
1543- (use (match_operand:SI 0 "register_operand" ""))]
1544+ (use (match_operand 0 "register_operand" ""))]
1545 ""
1546 {
1547 if (microblaze_is_break_handler ())
1548@@ -2523,7 +2745,7 @@ else
1549 (define_expand "call"
1550 [(parallel [(call (match_operand 0 "memory_operand" "m")
1551 (match_operand 1 "" "i"))
1552- (clobber (reg:SI R_SR))
1553+ (clobber (reg R_SR))
1554 (use (match_operand 2 "" ""))
1555 (use (match_operand 3 "" ""))])]
1556 ""
1557@@ -2543,12 +2765,12 @@ else
1558
1559 if (GET_CODE (XEXP (operands[0], 0)) == UNSPEC)
1560 emit_call_insn (gen_call_internal_plt0 (operands[0], operands[1],
1561- gen_rtx_REG (SImode,
1562+ gen_rtx_REG (Pmode,
1563 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
1564 pic_offset_table_rtx));
1565 else
1566 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
1567- gen_rtx_REG (SImode,
1568+ gen_rtx_REG (Pmode,
1569 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
1570
1571 DONE;
1572@@ -2558,7 +2780,7 @@ else
1573 (define_expand "call_internal0"
1574 [(parallel [(call (match_operand 0 "" "")
1575 (match_operand 1 "" ""))
1576- (clobber (match_operand:SI 2 "" ""))])]
1577+ (clobber (match_operand 2 "" ""))])]
1578 ""
1579 {
1580 }
1581@@ -2567,18 +2789,34 @@ else
1582 (define_expand "call_internal_plt0"
1583 [(parallel [(call (match_operand 0 "" "")
1584 (match_operand 1 "" ""))
1585- (clobber (match_operand:SI 2 "" ""))
1586- (use (match_operand:SI 3 "" ""))])]
1587+ (clobber (match_operand 2 "" ""))
1588+ (use (match_operand 3 "" ""))])]
1589 ""
1590 {
1591 }
1592 )
1593
1594+(define_insn "call_internal_plt_64"
1595+ [(call (mem (match_operand 0 "call_insn_plt_operand" ""))
1596+ (match_operand 1 "" "i"))
1597+ (clobber (reg R_SR))
1598+ (use (reg R_GOT))]
1599+ "flag_pic && TARGET_MB_64"
1600+ {
1601+ register rtx target2 = gen_rtx_REG (Pmode,
1602+ GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1603+ gen_rtx_CLOBBER (VOIDmode, target2);
1604+ return "brealid\tr15,%0\;%#";
1605+ }
1606+ [(set_attr "type" "call")
1607+ (set_attr "mode" "none")
1608+ (set_attr "length" "4")])
1609+
1610 (define_insn "call_internal_plt"
1611- [(call (mem (match_operand:SI 0 "call_insn_plt_operand" ""))
1612- (match_operand:SI 1 "" "i"))
1613- (clobber (reg:SI R_SR))
1614- (use (reg:SI R_GOT))]
1615+ [(call (mem (match_operand 0 "call_insn_plt_operand" ""))
1616+ (match_operand 1 "" "i"))
1617+ (clobber (reg R_SR))
1618+ (use (reg R_GOT))]
1619 "flag_pic"
1620 {
1621 register rtx target2 = gen_rtx_REG (Pmode,
1622@@ -2590,10 +2828,41 @@ else
1623 (set_attr "mode" "none")
1624 (set_attr "length" "4")])
1625
1626+(define_insn "call_internal1_64"
1627+ [(call (mem (match_operand:VOID 0 "call_insn_simple_operand" "ri"))
1628+ (match_operand 1 "" "i"))
1629+ (clobber (reg R_SR))]
1630+ "TARGET_MB_64"
1631+ {
1632+ register rtx target = operands[0];
1633+ register rtx target2 = gen_rtx_REG (Pmode,
1634+ GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1635+ if (GET_CODE (target) == SYMBOL_REF) {
1636+ if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
1637+ gen_rtx_CLOBBER (VOIDmode, target2);
1638+ return "breaki\tr16,%0\;%#";
1639+ }
1640+ else {
1641+ gen_rtx_CLOBBER (VOIDmode, target2);
1642+ return "brealid\tr15,%0\;%#";
1643+ }
1644+ } else if (GET_CODE (target) == CONST_INT)
1645+ return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
1646+ else if (GET_CODE (target) == REG)
1647+ return "brald\tr15,%0\;%#";
1648+ else {
1649+ fprintf (stderr,"Unsupported call insn\n");
1650+ return NULL;
1651+ }
1652+ }
1653+ [(set_attr "type" "call")
1654+ (set_attr "mode" "none")
1655+ (set_attr "length" "4")])
1656+
1657 (define_insn "call_internal1"
1658 [(call (mem (match_operand:VOID 0 "call_insn_simple_operand" "ri"))
1659- (match_operand:SI 1 "" "i"))
1660- (clobber (reg:SI R_SR))]
1661+ (match_operand 1 "" "i"))
1662+ (clobber (reg R_SR))]
1663 ""
1664 {
1665 register rtx target = operands[0];
1666@@ -2627,7 +2896,7 @@ else
1667 [(parallel [(set (match_operand 0 "register_operand" "=d")
1668 (call (match_operand 1 "memory_operand" "m")
1669 (match_operand 2 "" "i")))
1670- (clobber (reg:SI R_SR))
1671+ (clobber (reg R_SR))
1672 (use (match_operand 3 "" ""))])] ;; next_arg_reg
1673 ""
1674 {
1675@@ -2647,13 +2916,13 @@ else
1676 if (GET_CODE (XEXP (operands[1], 0)) == UNSPEC)
1677 emit_call_insn (gen_call_value_intern_plt0 (operands[0], operands[1],
1678 operands[2],
1679- gen_rtx_REG (SImode,
1680+ gen_rtx_REG (Pmode,
1681 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
1682 pic_offset_table_rtx));
1683 else
1684 emit_call_insn (gen_call_value_internal (operands[0], operands[1],
1685 operands[2],
1686- gen_rtx_REG (SImode,
1687+ gen_rtx_REG (Pmode,
1688 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
1689
1690 DONE;
1691@@ -2665,7 +2934,7 @@ else
1692 [(parallel [(set (match_operand 0 "" "")
1693 (call (match_operand 1 "" "")
1694 (match_operand 2 "" "")))
1695- (clobber (match_operand:SI 3 "" ""))
1696+ (clobber (match_operand 3 "" ""))
1697 ])]
1698 ""
1699 {}
1700@@ -2675,18 +2944,35 @@ else
1701 [(parallel[(set (match_operand 0 "" "")
1702 (call (match_operand 1 "" "")
1703 (match_operand 2 "" "")))
1704- (clobber (match_operand:SI 3 "" ""))
1705- (use (match_operand:SI 4 "" ""))])]
1706+ (clobber (match_operand 3 "" ""))
1707+ (use (match_operand 4 "" ""))])]
1708 "flag_pic"
1709 {}
1710 )
1711
1712+(define_insn "call_value_intern_plt_64"
1713+ [(set (match_operand:VOID 0 "register_operand" "=d")
1714+ (call (mem (match_operand 1 "call_insn_plt_operand" ""))
1715+ (match_operand 2 "" "i")))
1716+ (clobber (match_operand 3 "register_operand" "=d"))
1717+ (use (match_operand 4 "register_operand"))]
1718+ "flag_pic && TARGET_MB_64"
1719+ {
1720+ register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1721+
1722+ gen_rtx_CLOBBER (VOIDmode,target2);
1723+ return "brealid\tr15,%1\;%#";
1724+ }
1725+ [(set_attr "type" "call")
1726+ (set_attr "mode" "none")
1727+ (set_attr "length" "4")])
1728+
1729 (define_insn "call_value_intern_plt"
1730 [(set (match_operand:VOID 0 "register_operand" "=d")
1731- (call (mem (match_operand:SI 1 "call_insn_plt_operand" ""))
1732- (match_operand:SI 2 "" "i")))
1733- (clobber (match_operand:SI 3 "register_operand" "=d"))
1734- (use (match_operand:SI 4 "register_operand"))]
1735+ (call (mem (match_operand 1 "call_insn_plt_operand" ""))
1736+ (match_operand 2 "" "i")))
1737+ (clobber (match_operand 3 "register_operand" "=d"))
1738+ (use (match_operand 4 "register_operand"))]
1739 "flag_pic"
1740 {
1741 register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1742@@ -2698,11 +2984,46 @@ else
1743 (set_attr "mode" "none")
1744 (set_attr "length" "4")])
1745
1746+(define_insn "call_value_intern_64"
1747+ [(set (match_operand:VOID 0 "register_operand" "=d")
1748+ (call (mem (match_operand:VOID 1 "call_insn_operand" "ri"))
1749+ (match_operand 2 "" "i")))
1750+ (clobber (match_operand 3 "register_operand" "=d"))]
1751+ "TARGET_MB_64"
1752+ {
1753+ register rtx target = operands[1];
1754+ register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1755+
1756+ if (GET_CODE (target) == SYMBOL_REF)
1757+ {
1758+ gen_rtx_CLOBBER (VOIDmode,target2);
1759+ if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
1760+ return "breaki\tr16,%1\;%#";
1761+ else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
1762+ {
1763+ return "brealid\tr15,%1\;%#";
1764+ }
1765+ else
1766+ {
1767+ return "bralid\tr15,%1\;%#";
1768+ }
1769+ }
1770+ else if (GET_CODE (target) == CONST_INT)
1771+ return "la\t%@,r0,%1\;brald\tr15,%@\;%#";
1772+ else if (GET_CODE (target) == REG)
1773+ return "brald\tr15,%1\;%#";
1774+ else
1775+ return "Unsupported call insn\n";
1776+ }
1777+ [(set_attr "type" "call")
1778+ (set_attr "mode" "none")
1779+ (set_attr "length" "4")])
1780+
1781 (define_insn "call_value_intern"
1782 [(set (match_operand:VOID 0 "register_operand" "=d")
1783 (call (mem (match_operand:VOID 1 "call_insn_operand" "ri"))
1784- (match_operand:SI 2 "" "i")))
1785- (clobber (match_operand:SI 3 "register_operand" "=d"))]
1786+ (match_operand 2 "" "i")))
1787+ (clobber (match_operand 3 "register_operand" "=d"))]
1788 ""
1789 {
1790 register rtx target = operands[1];
1791@@ -2864,7 +3185,6 @@ else
1792
1793 ;;if (!register_operand (operands[0], VOIDmode))
1794 ;; FAIL;
1795-
1796 emit_insn (gen_insv_32 (operands[0], operands[1],
1797 operands[2], operands[3]));
1798 DONE;
1799diff --git a/gcc/config/microblaze/t-microblaze b/gcc/config/microblaze/t-microblaze
1800index 7671f63..9fc80b1 100644
1801--- a/gcc/config/microblaze/t-microblaze
1802+++ b/gcc/config/microblaze/t-microblaze
1803@@ -2,10 +2,11 @@ MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high mlittle-en
1804 MULTILIB_DIRNAMES = bs m mh le m64
1805 MULTILIB_EXCEPTIONS = *mxl-barrel-shift/mxl-multiply-high mxl-multiply-high
1806 MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian
1807-MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64
1808+MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian/m64
1809+MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64 mxl-multiply-high
1810 MULTILIB_EXCEPTIONS += mxl-multiply-high/mlittle-endian
1811-#MULTILIB_EXCEPTIONS += mxl-multiply-high/m64
1812-#MULTILIB_EXCEPTIONS += *mxl-multiply-high/mlittle-endian/m64
1813+MULTILIB_EXCEPTIONS += mxl-multiply-high/m64
1814+MULTILIB_EXCEPTIONS += *mxl-multiply-high/mlittle-endian/m64
1815
1816 # Extra files
1817 microblaze-c.o: $(srcdir)/config/microblaze/microblaze-c.c \
1818diff --git a/libgcc/config/microblaze/crti.S b/libgcc/config/microblaze/crti.S
1819index 2e15be4..3386520 100644
1820--- a/libgcc/config/microblaze/crti.S
1821+++ b/libgcc/config/microblaze/crti.S
1822@@ -40,7 +40,7 @@
1823
1824 .align 2
1825 __init:
1826- addik r1, r1, -8
1827+ addik r1, r1, -16
1828 sw r15, r0, r1
1829 la r11, r0, _stack
1830 mts rshr, r11
1831@@ -51,5 +51,5 @@ __init:
1832 .global __fini
1833 .align 2
1834 __fini:
1835- addik r1, r1, -8
1836+ addik r1, r1, -16
1837 sw r15, r0, r1
1838diff --git a/libgcc/config/microblaze/crtn.S b/libgcc/config/microblaze/crtn.S
1839index cd5fd9e..04e73d7 100644
1840--- a/libgcc/config/microblaze/crtn.S
1841+++ b/libgcc/config/microblaze/crtn.S
1842@@ -33,9 +33,9 @@
1843 .section .init, "ax"
1844 lw r15, r0, r1
1845 rtsd r15, 8
1846- addik r1, r1, 8
1847+ addik r1, r1, 16
1848
1849 .section .fini, "ax"
1850 lw r15, r0, r1
1851 rtsd r15, 8
1852- addik r1, r1, 8
1853+ addik r1, r1, 16
1854diff --git a/libgcc/config/microblaze/divdi3.S b/libgcc/config/microblaze/divdi3.S
1855new file mode 100644
1856index 0000000..d37bf51
1857--- /dev/null
1858+++ b/libgcc/config/microblaze/divdi3.S
1859@@ -0,0 +1,98 @@
1860+###################################-
1861+#
1862+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
1863+#
1864+# Contributed by Michael Eager <eager@eagercon.com>.
1865+#
1866+# This file is free software; you can redistribute it and/or modify it
1867+# under the terms of the GNU General Public License as published by the
1868+# Free Software Foundation; either version 3, or (at your option) any
1869+# later version.
1870+#
1871+# GCC is distributed in the hope that it will be useful, but WITHOUT
1872+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1873+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1874+# License for more details.
1875+#
1876+# Under Section 7 of GPL version 3, you are granted additional
1877+# permissions described in the GCC Runtime Library Exception, version
1878+# 3.1, as published by the Free Software Foundation.
1879+#
1880+# You should have received a copy of the GNU General Public License and
1881+# a copy of the GCC Runtime Library Exception along with this program;
1882+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1883+# <http://www.gnu.org/licenses/>.
1884+#
1885+# divdi3.S
1886+#
1887+# Divide operation for 32 bit integers.
1888+# Input : Dividend in Reg r5
1889+# Divisor in Reg r6
1890+# Output: Result in Reg r3
1891+#
1892+#######################################
1893+
1894+#ifdef __arch64__
1895+ .globl __divdi3
1896+ .ent __divdi3
1897+ .type __divdi3,@function
1898+__divdi3:
1899+ .frame r1,0,r15
1900+
1901+ ADDLIK r1,r1,-32
1902+ SLI r28,r1,0
1903+ SLI r29,r1,8
1904+ SLI r30,r1,16
1905+ SLI r31,r1,24
1906+
1907+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
1908+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
1909+ XORL r28,r5,r6 # Get the sign of the result
1910+ BEALGEI r5,$LaR5_Pos
1911+ RSUBLI r5,r5,0 # Make r5 positive
1912+$LaR5_Pos:
1913+ BEALGEI r6,$LaR6_Pos
1914+ RSUBLI r6,r6,0 # Make r6 positive
1915+$LaR6_Pos:
1916+ ADDLIK r30,r0,0 # Clear mod
1917+ ADDLIK r3,r0,0 # clear div
1918+ ADDLIK r29,r0,64 # Initialize the loop count
1919+
1920+ # First part try to find the first '1' in the r5
1921+$LaDIV0:
1922+ BEALLTI r5,$LaDIV2 # This traps r5 == 0x80000000
1923+$LaDIV1:
1924+ ADDL r5,r5,r5 # left shift logical r5
1925+ ADDLIK r29,r29,-1
1926+ BEALGTI r5,$LaDIV1
1927+$LaDIV2:
1928+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
1929+ ADDLC r30,r30,r30 # Move that bit into the Mod register
1930+ RSUBL r31,r6,r30 # Try to subtract (r30 a r6)
1931+ BEALLTI r31,$LaMOD_TOO_SMALL
1932+ ORL r30,r0,r31 # Move the r31 to mod since the result was positive
1933+ ADDLIK r3,r3,1
1934+$LaMOD_TOO_SMALL:
1935+ ADDLIK r29,r29,-1
1936+ BEALEQi r29,$LaLOOP_END
1937+ ADDL r3,r3,r3 # Shift in the '1' into div
1938+ BREAI $LaDIV2 # Div2
1939+$LaLOOP_END:
1940+ BEALGEI r28,$LaRETURN_HERE
1941+ RSUBLI r3,r3,0 # Negate the result
1942+ BREAI $LaRETURN_HERE
1943+$LaDiv_By_Zero:
1944+$LaResult_Is_Zero:
1945+ ORL r3,r0,r0 # set result to 0
1946+$LaRETURN_HERE:
1947+# Restore values of CSRs and that of r3 and the divisor and the dividend
1948+ LLI r28,r1,0
1949+ LLI r29,r1,8
1950+ LLI r30,r1,16
1951+ LLI r31,r1,24
1952+ ADDLIK r1,r1,32
1953+ RTSD r15,8
1954+ nop
1955+.end __divdi3
1956+ .size __divdi3, . - __divdi3
1957+#endif
1958diff --git a/libgcc/config/microblaze/divdi3_table.c b/libgcc/config/microblaze/divdi3_table.c
1959new file mode 100644
1960index 0000000..8096259
1961--- /dev/null
1962+++ b/libgcc/config/microblaze/divdi3_table.c
1963@@ -0,0 +1,62 @@
1964+/* Table for software lookup divide for Xilinx MicroBlaze.
1965+
1966+ Copyright (C) 2009-2017 Free Software Foundation, Inc.
1967+
1968+ Contributed by Michael Eager <eager@eagercon.com>.
1969+
1970+ This file is free software; you can redistribute it and/or modify it
1971+ under the terms of the GNU General Public License as published by the
1972+ Free Software Foundation; either version 3, or (at your option) any
1973+ later version.
1974+
1975+ GCC is distributed in the hope that it will be useful, but WITHOUT
1976+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1977+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1978+ License for more details.
1979+
1980+ Under Section 7 of GPL version 3, you are granted additional
1981+ permissions described in the GCC Runtime Library Exception, version
1982+ 3.1, as published by the Free Software Foundation.
1983+
1984+ You should have received a copy of the GNU General Public License and
1985+ a copy of the GCC Runtime Library Exception along with this program;
1986+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1987+ <http://www.gnu.org/licenses/>. */
1988+
1989+
1990+unsigned char _divdi3_table[] =
1991+{
1992+ 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7,
1993+ 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
1994+ 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7,
1995+ 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
1996+ 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7,
1997+ 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
1998+ 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7,
1999+ 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
2000+ 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7,
2001+ 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
2002+ 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7,
2003+ 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
2004+ 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7,
2005+ 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
2006+ 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7,
2007+ 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
2008+ 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7,
2009+ 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
2010+ 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7,
2011+ 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
2012+ 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7,
2013+ 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
2014+ 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7,
2015+ 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
2016+ 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7,
2017+ 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
2018+ 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7,
2019+ 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
2020+ 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7,
2021+ 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
2022+ 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7,
2023+ 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
2024+};
2025+
2026diff --git a/libgcc/config/microblaze/moddi3.S b/libgcc/config/microblaze/moddi3.S
2027new file mode 100644
2028index 0000000..5d3f7c0
2029--- /dev/null
2030+++ b/libgcc/config/microblaze/moddi3.S
2031@@ -0,0 +1,97 @@
2032+###################################
2033+#
2034+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2035+#
2036+# Contributed by Michael Eager <eager@eagercon.com>.
2037+#
2038+# This file is free software; you can redistribute it and/or modify it
2039+# under the terms of the GNU General Public License as published by the
2040+# Free Software Foundation; either version 3, or (at your option) any
2041+# later version.
2042+#
2043+# GCC is distributed in the hope that it will be useful, but WITHOUT
2044+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2045+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2046+# License for more details.
2047+#
2048+# Under Section 7 of GPL version 3, you are granted additional
2049+# permissions described in the GCC Runtime Library Exception, version
2050+# 3.1, as published by the Free Software Foundation.
2051+#
2052+# You should have received a copy of the GNU General Public License and
2053+# a copy of the GCC Runtime Library Exception along with this program;
2054+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2055+# <http://www.gnu.org/licenses/>.
2056+#
2057+# moddi3.S
2058+#
2059+# modulo operation for 32 bit integers.
2060+# Input : op1 in Reg r5
2061+# op2 in Reg r6
2062+# Output: op1 mod op2 in Reg r3
2063+#
2064+#######################################
2065+
2066+#ifdef __arch64__
2067+ .globl __moddi3
2068+ .ent __moddi3
2069+ .type __moddi3,@function
2070+__moddi3:
2071+ .frame r1,0,r15
2072+
2073+ addlik r1,r1,-32
2074+ sli r28,r1,0
2075+ sli r29,r1,8
2076+ sli r30,r1,16
2077+ sli r31,r1,32
2078+
2079+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2080+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2081+ ADDL r28,r5,r0 # Get the sign of the result [ Depends only on the first arg]
2082+ BEALGEI r5,$LaR5_Pos
2083+ RSUBLI r5,r5,0 # Make r5 positive
2084+$LaR5_Pos:
2085+ BEALGEI r6,$LaR6_Pos
2086+ RSUBLI r6,r6,0 # Make r6 positive
2087+$LaR6_Pos:
2088+ ADDLIK r3,r0,0 # Clear mod
2089+ ADDLIK r30,r0,0 # clear div
2090+ ADDLIK r29,r0,64 # Initialize the loop count
2091+ BEALLTI r5,$LaDIV2 # If r5 is still negative (0x80000000), skip
2092+ # the first bit search.
2093+ # First part try to find the first '1' in the r5
2094+$LaDIV1:
2095+ ADDL r5,r5,r5 # left shift logical r5
2096+ ADDLIK r29,r29,-1
2097+ BEALGEI r5,$LaDIV1 #
2098+$LaDIV2:
2099+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2100+ ADDLC r3,r3,r3 # Move that bit into the Mod register
2101+ rSUBL r31,r6,r3 # Try to subtract (r30 a r6)
2102+ BEALLTi r31,$LaMOD_TOO_SMALL
2103+ ORL r3,r0,r31 # Move the r31 to mod since the result was positive
2104+ ADDLIK r30,r30,1
2105+$LaMOD_TOO_SMALL:
2106+ ADDLIK r29,r29,-1
2107+ BEALEQi r29,$LaLOOP_END
2108+ ADDL r30,r30,r30 # Shift in the '1' into div
2109+ BREAI $LaDIV2 # Div2
2110+$LaLOOP_END:
2111+ BEALGEI r28,$LaRETURN_HERE
2112+ rsubli r3,r3,0 # Negate the result
2113+ BREAI $LaRETURN_HERE
2114+$LaDiv_By_Zero:
2115+$LaResult_Is_Zero:
2116+ orl r3,r0,r0 # set result to 0 [Both mod as well as div are 0]
2117+$LaRETURN_HERE:
2118+# Restore values of CSRs and that of r3 and the divisor and the dividend
2119+ lli r28,r1,0
2120+ lli r29,r1,8
2121+ lli r30,r1,16
2122+ lli r31,r1,24
2123+ addlik r1,r1,32
2124+ rtsd r15,8
2125+ nop
2126+ .end __moddi3
2127+ .size __moddi3, . - __moddi3
2128+#endif
2129diff --git a/libgcc/config/microblaze/muldi3.S b/libgcc/config/microblaze/muldi3.S
2130new file mode 100644
2131index 0000000..5677841
2132--- /dev/null
2133+++ b/libgcc/config/microblaze/muldi3.S
2134@@ -0,0 +1,73 @@
2135+/*###################################-*-asm*-
2136+#
2137+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2138+#
2139+# Contributed by Michael Eager <eager@eagercon.com>.
2140+#
2141+# This file is free software; you can redistribute it and/or modify it
2142+# under the terms of the GNU General Public License as published by the
2143+# Free Software Foundation; either version 3, or (at your option) any
2144+# later version.
2145+#
2146+# GCC is distributed in the hope that it will be useful, but WITHOUT
2147+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2148+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2149+# License for more details.
2150+#
2151+# Under Section 7 of GPL version 3, you are granted additional
2152+# permissions described in the GCC Runtime Library Exception, version
2153+# 3.1, as published by the Free Software Foundation.
2154+#
2155+# You should have received a copy of the GNU General Public License and
2156+# a copy of the GCC Runtime Library Exception along with this program;
2157+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2158+# <http://www.gnu.org/licenses/>.
2159+#
2160+# muldi3.S
2161+#
2162+# Multiply operation for 32 bit integers.
2163+# Input : Operand1 in Reg r5
2164+# Operand2 in Reg r6
2165+# Output: Result [op1 * op2] in Reg r3
2166+#
2167+#######################################*/
2168+
2169+#ifdef __arch64__
2170+ .globl __muldi3
2171+ .ent __muldi3
2172+ .type __muldi3,@function
2173+__muldi3:
2174+ .frame r1,0,r15
2175+ addl r3,r0,r0
2176+ BEALEQI r5,$L_Result_Is_Zero # Multiply by Zero
2177+ BEALEQI r6,$L_Result_Is_Zero # Multiply by Zero
2178+ XORL r4,r5,r6 # Get the sign of the result
2179+ BEALGEI r5,$L_R5_Pos
2180+ RSUBLI r5,r5,0 # Make r5 positive
2181+$L_R5_Pos:
2182+ BEALGEI r6,$L_R6_Pos
2183+ RSUBLI r6,r6,0 # Make r6 positive
2184+$L_R6_Pos:
2185+ breai $L1
2186+$L2:
2187+ addl r5,r5,r5
2188+$L1:
2189+ srll r6,r6
2190+ addlc r7,r0,r0
2191+ bealeqi r7,$L2
2192+ addl r3,r3,r5
2193+ bealnei r6,$L2
2194+ beallti r4,$L_NegateResult
2195+ rtsd r15,8
2196+ nop
2197+$L_NegateResult:
2198+ rsubl r3,r3,r0
2199+ rtsd r15,8
2200+ nop
2201+$L_Result_Is_Zero:
2202+ addli r3,r0,0
2203+ rtsd r15,8
2204+ nop
2205+ .end __muldi3
2206+ .size __muldi3, . - __muldi3
2207+#endif
2208diff --git a/libgcc/config/microblaze/t-microblaze b/libgcc/config/microblaze/t-microblaze
2209index 8d954a4..35021b2 100644
2210--- a/libgcc/config/microblaze/t-microblaze
2211+++ b/libgcc/config/microblaze/t-microblaze
2212@@ -1,11 +1,16 @@
2213-LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _mulsi3 _udivsi3 _umodsi3
2214+LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _mulsi3 _udivsi3 _umodsi3 \
2215+ _divdi3 _moddi3 _muldi3 _udivdi3 _umoddi3
2216
2217 LIB2ADD += \
2218 $(srcdir)/config/microblaze/divsi3.S \
2219+ $(srcdir)/config/microblaze/divdi3.S \
2220 $(srcdir)/config/microblaze/modsi3.S \
2221- $(srcdir)/config/microblaze/muldi3_hard.S \
2222+ $(srcdir)/config/microblaze/moddi3.S \
2223 $(srcdir)/config/microblaze/mulsi3.S \
2224+ $(srcdir)/config/microblaze/muldi3.S \
2225 $(srcdir)/config/microblaze/stack_overflow_exit.S \
2226 $(srcdir)/config/microblaze/udivsi3.S \
2227+ $(srcdir)/config/microblaze/udivdi3.S \
2228 $(srcdir)/config/microblaze/umodsi3.S \
2229- $(srcdir)/config/microblaze/divsi3_table.c
2230+ $(srcdir)/config/microblaze/umoddi3.S \
2231+ $(srcdir)/config/microblaze/divsi3_table.c \
2232diff --git a/libgcc/config/microblaze/udivdi3.S b/libgcc/config/microblaze/udivdi3.S
2233new file mode 100644
2234index 0000000..c210fbc
2235--- /dev/null
2236+++ b/libgcc/config/microblaze/udivdi3.S
2237@@ -0,0 +1,107 @@
2238+###################################-
2239+#
2240+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2241+#
2242+# Contributed by Michael Eager <eager@eagercon.com>.
2243+#
2244+# This file is free software; you can redistribute it and/or modify it
2245+# under the terms of the GNU General Public License as published by the
2246+# Free Software Foundation; either version 3, or (at your option) any
2247+# later version.
2248+#
2249+# GCC is distributed in the hope that it will be useful, but WITHOUT
2250+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2251+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2252+# License for more details.
2253+#
2254+# Under Section 7 of GPL version 3, you are granted additional
2255+# permissions described in the GCC Runtime Library Exception, version
2256+# 3.1, as published by the Free Software Foundation.
2257+#
2258+# You should have received a copy of the GNU General Public License and
2259+# a copy of the GCC Runtime Library Exception along with this program;
2260+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2261+# <http://www.gnu.org/licenses/>.
2262+#
2263+# udivdi3.S
2264+#
2265+# Unsigned divide operation.
2266+# Input : Divisor in Reg r5
2267+# Dividend in Reg r6
2268+# Output: Result in Reg r3
2269+#
2270+#######################################
2271+
2272+#ifdef __arch64__
2273+ .globl __udivdi3
2274+ .ent __udivdi3
2275+ .type __udivdi3,@function
2276+__udivdi3:
2277+ .frame r1,0,r15
2278+
2279+ ADDlIK r1,r1,-24
2280+ SLI r29,r1,0
2281+ SLI r30,r1,8
2282+ SLI r31,r1,16
2283+
2284+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2285+ ADDLIK r30,r0,0 # Clear mod
2286+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2287+ ADDLIK r29,r0,64 # Initialize the loop count
2288+
2289+ # Check if r6 and r5 are equal # if yes, return 1
2290+ RSUBL r18,r5,r6
2291+ ADDLIK r3,r0,1
2292+ BEALEQI r18,$LaRETURN_HERE
2293+
2294+ # Check if (uns)r6 is greater than (uns)r5. In that case, just return 0
2295+ XORL r18,r5,r6
2296+ ADDL r3,r0,r0 # We would anyways clear r3
2297+ BEALGEI r18,$LRSUBL
2298+ BEALLTI r6,$LaRETURN_HERE # r6[bit 31 = 1] hence is greater
2299+ BREAI $LCheckr6
2300+$LRSUBL:
2301+ RSUBL r18,r6,r5 # MICROBLAZEcmp
2302+ BEALLTI r18,$LaRETURN_HERE
2303+
2304+ # If r6 [bit 31] is set, then return result as 1
2305+$LCheckr6:
2306+ BEALGTI r6,$LaDIV0
2307+ ADDLIK r3,r0,1
2308+ BREAI $LaRETURN_HERE
2309+
2310+ # First part try to find the first '1' in the r5
2311+$LaDIV0:
2312+ BEALLTI r5,$LaDIV2
2313+$LaDIV1:
2314+ ADDL r5,r5,r5 # left shift logical r5
2315+ ADDLIK r29,r29,-1
2316+ BEALGTI r5,$LaDIV1
2317+$LaDIV2:
2318+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2319+ ADDLC r30,r30,r30 # Move that bit into the Mod register
2320+ RSUBL r31,r6,r30 # Try to subtract (r30 a r6)
2321+ BEALLTI r31,$LaMOD_TOO_SMALL
2322+ ORL r30,r0,r31 # Move the r31 to mod since the result was positive
2323+ ADDLIK r3,r3,1
2324+$LaMOD_TOO_SMALL:
2325+ ADDLIK r29,r29,-1
2326+ BEALEQi r29,$LaLOOP_END
2327+ ADDL r3,r3,r3 # Shift in the '1' into div
2328+ BREAI $LaDIV2 # Div2
2329+$LaLOOP_END:
2330+ BREAI $LaRETURN_HERE
2331+$LaDiv_By_Zero:
2332+$LaResult_Is_Zero:
2333+ ORL r3,r0,r0 # set result to 0
2334+$LaRETURN_HERE:
2335+ # Restore values of CSRs and that of r3 and the divisor and the dividend
2336+ LLI r29,r1,0
2337+ LLI r30,r1,8
2338+ LLI r31,r1,16
2339+ ADDLIK r1,r1,24
2340+ RTSD r15,8
2341+ NOP
2342+ .end __udivdi3
2343+ .size __udivdi3, . - __udivdi3
2344+#endif
2345diff --git a/libgcc/config/microblaze/umoddi3.S b/libgcc/config/microblaze/umoddi3.S
2346new file mode 100644
2347index 0000000..7f5cd23
2348--- /dev/null
2349+++ b/libgcc/config/microblaze/umoddi3.S
2350@@ -0,0 +1,110 @@
2351+###################################
2352+#
2353+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2354+#
2355+# Contributed by Michael Eager <eager@eagercon.com>.
2356+#
2357+# This file is free software; you can redistribute it and/or modify it
2358+# under the terms of the GNU General Public License as published by the
2359+# Free Software Foundation; either version 3, or (at your option) any
2360+# later version.
2361+#
2362+# GCC is distributed in the hope that it will be useful, but WITHOUT
2363+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2364+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2365+# License for more details.
2366+#
2367+# Under Section 7 of GPL version 3, you are granted additional
2368+# permissions described in the GCC Runtime Library Exception, version
2369+# 3.1, as published by the Free Software Foundation.
2370+#
2371+# You should have received a copy of the GNU General Public License and
2372+# a copy of the GCC Runtime Library Exception along with this program;
2373+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2374+# <http://www.gnu.org/licenses/>.
2375+#
2376+# umoddi3.S
2377+#
2378+# Unsigned modulo operation for 32 bit integers.
2379+# Input : op1 in Reg r5
2380+# op2 in Reg r6
2381+# Output: op1 mod op2 in Reg r3
2382+#
2383+#######################################
2384+
2385+#ifdef __arch64__
2386+ .globl __umoddi3
2387+ .ent __umoddi3
2388+ .type __umoddi3,@function
2389+__umoddi3:
2390+ .frame r1,0,r15
2391+
2392+ addlik r1,r1,-24
2393+ sli r29,r1,0
2394+ sli r30,r1,8
2395+ sli r31,r1,16
2396+
2397+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2398+ ADDLIK r3,r0,0 # Clear div
2399+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2400+ ADDLIK r30,r0,0 # clear mod
2401+ ADDLIK r29,r0,64 # Initialize the loop count
2402+
2403+# Check if r6 and r5 are equal # if yes, return 0
2404+ rsubl r18,r5,r6
2405+ bealeqi r18,$LaRETURN_HERE
2406+
2407+# Check if (uns)r6 is greater than (uns)r5. In that case, just return r5
2408+ xorl r18,r5,r6
2409+ addlik r3,r5,0
2410+ bealgei r18,$LRSUB
2411+ beallti r6,$LaRETURN_HERE
2412+ breai $LCheckr6
2413+$LRSUB:
2414+ rsubl r18,r5,r6 # MICROBLAZEcmp
2415+ bealgti r18,$LaRETURN_HERE
2416+
2417+# If r6 [bit 31] is set, then return result as r5-r6
2418+$LCheckr6:
2419+ addlik r3,r0,0
2420+ bealgti r6,$LaDIV0
2421+ addlik r18,r0,0x7fffffff
2422+ andl r5,r5,r18
2423+ andl r6,r6,r18
2424+ breaid $LaRETURN_HERE
2425+ rsubl r3,r6,r5
2426+# First part: try to find the first '1' in the r5
2427+$LaDIV0:
2428+ BEALLTI r5,$LaDIV2
2429+$LaDIV1:
2430+ ADDL r5,r5,r5 # left shift logical r5
2431+ ADDLIK r29,r29,-1
2432+ BEALGEI r5,$LaDIV1 #
2433+$LaDIV2:
2434+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2435+ ADDLC r3,r3,r3 # Move that bit into the Mod register
2436+ rSUBL r31,r6,r3 # Try to subtract (r3 a r6)
2437+ BEALLTi r31,$LaMOD_TOO_SMALL
2438+ ORL r3,r0,r31 # Move the r31 to mod since the result was positive
2439+ ADDLIK r30,r30,1
2440+$LaMOD_TOO_SMALL:
2441+ ADDLIK r29,r29,-1
2442+ BEALEQi r29,$LaLOOP_END
2443+ ADDL r30,r30,r30 # Shift in the '1' into div
2444+ BREAI $LaDIV2 # Div2
2445+$LaLOOP_END:
2446+ BREAI $LaRETURN_HERE
2447+$LaDiv_By_Zero:
2448+$LaResult_Is_Zero:
2449+ orl r3,r0,r0 # set result to 0
2450+$LaRETURN_HERE:
2451+# Restore values of CSRs and that of r3 and the divisor and the dividend
2452+ lli r29,r1,0
2453+ lli r30,r1,8
2454+ lli r31,r1,16
2455+ addlik r1,r1,24
2456+ rtsd r15,8
2457+ nop
2458+.end __umoddi3
2459+ .size __umoddi3, . - __umoddi3
2460+#endif
2461--
24622.7.4
2463