summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools/gcc/gcc-13/0028-Intial-commit-for-64bit-MB-sources.-Need-to-cleanup-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-microblaze/recipes-devtools/gcc/gcc-13/0028-Intial-commit-for-64bit-MB-sources.-Need-to-cleanup-.patch')
-rw-r--r--meta-microblaze/recipes-devtools/gcc/gcc-13/0028-Intial-commit-for-64bit-MB-sources.-Need-to-cleanup-.patch2442
1 files changed, 2442 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/gcc/gcc-13/0028-Intial-commit-for-64bit-MB-sources.-Need-to-cleanup-.patch b/meta-microblaze/recipes-devtools/gcc/gcc-13/0028-Intial-commit-for-64bit-MB-sources.-Need-to-cleanup-.patch
new file mode 100644
index 00000000..58bb6fd8
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/gcc/gcc-13/0028-Intial-commit-for-64bit-MB-sources.-Need-to-cleanup-.patch
@@ -0,0 +1,2442 @@
1From fcec4be11de1c646bdcd6dcfc3844b7deb42898e Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 13 Sep 2022 14:38:48 +0530
4Subject: [PATCH 28/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.cc | 6 +
10 gcc/config/microblaze/microblaze.cc | 216 ++++++---
11 gcc/config/microblaze/microblaze.h | 63 ++-
12 gcc/config/microblaze/microblaze.md | 605 ++++++++++++++++++------
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, 1229 insertions(+), 232 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 26742d34980..7bb1e0b4c8d 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.cc b/gcc/config/microblaze/microblaze-c.cc
45index 065351ad218..af73de0709c 100644
46--- a/gcc/config/microblaze/microblaze-c.cc
47+++ b/gcc/config/microblaze/microblaze-c.cc
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.cc b/gcc/config/microblaze/microblaze.cc
60index 7975bc182f2..46bbf8a21e7 100644
61--- a/gcc/config/microblaze/microblaze.cc
62+++ b/gcc/config/microblaze/microblaze.cc
63@@ -384,10 +384,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@@ -435,7 +435,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@@ -682,7 +682,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@@ -700,7 +700,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@@ -1308,8 +1308,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@@ -1639,14 +1647,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@@ -2161,7 +2175,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@@ -2430,7 +2444,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@@ -2456,6 +2470,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@@ -2468,12 +2483,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@@ -2667,7 +2682,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@@ -2690,7 +2708,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@@ -2756,7 +2777,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@@ -2764,8 +2785,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@@ -2773,8 +2794,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@@ -2785,9 +2806,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@@ -2802,7 +2823,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@@ -2812,8 +2833,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@@ -2903,7 +2924,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@@ -3047,10 +3071,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@@ -3059,15 +3083,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@@ -3075,7 +3107,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@@ -3185,12 +3217,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@@ -3206,15 +3238,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@@ -3381,9 +3423,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@@ -3396,7 +3443,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@@ -3631,9 +3681,9 @@ microblaze_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
410 emit_block_move (m_tramp, assemble_trampoline_template (),
411 GEN_INT (6*UNITS_PER_WORD), BLOCK_OP_NORMAL);
412
413- mem = adjust_address (m_tramp, SImode, 16);
414+ mem = adjust_address (m_tramp, Pmode, 16);
415 emit_move_insn (mem, chain_value);
416- mem = adjust_address (m_tramp, SImode, 20);
417+ mem = adjust_address (m_tramp, Pmode, 20);
418 emit_move_insn (mem, fnaddr);
419 }
420
421@@ -3657,7 +3707,7 @@ microblaze_expand_conditional_branch (machine_mode mode, rtx operands[])
422 {
423 comp_reg = cmp_op0;
424 condition = gen_rtx_fmt_ee (signed_condition (code), mode, comp_reg, const0_rtx);
425- if (mode == SImode)
426+ if (mode == Pmode)
427 emit_jump_insn (gen_condjump (condition, label1));
428 else
429 emit_jump_insn (gen_long_condjump (condition, label1));
430@@ -3776,7 +3826,7 @@ microblaze_expand_conditional_branch_sf (rtx operands[])
431 rtx comp_reg = gen_reg_rtx (SImode);
432
433 emit_insn (gen_cstoresf4 (comp_reg, operands[0], cmp_op0, cmp_op1));
434- condition = gen_rtx_NE (SImode, comp_reg, const0_rtx);
435+ condition = gen_rtx_NE (Pmode, comp_reg, const0_rtx);
436 emit_jump_insn (gen_condjump (condition, operands[3]));
437 }
438
439@@ -3786,10 +3836,10 @@ microblaze_expand_conditional_branch_df (rtx operands[])
440 rtx condition;
441 rtx cmp_op0 = XEXP (operands[0], 0);
442 rtx cmp_op1 = XEXP (operands[0], 1);
443- rtx comp_reg = gen_reg_rtx (DImode);
444+ rtx comp_reg = gen_reg_rtx (Pmode);
445
446 emit_insn (gen_cstoredf4 (comp_reg, operands[0], cmp_op0, cmp_op1));
447- condition = gen_rtx_NE (DImode, comp_reg, const0_rtx);
448+ condition = gen_rtx_NE (Pmode, comp_reg, const0_rtx);
449 emit_jump_insn (gen_long_condjump (condition, operands[3]));
450 }
451
452@@ -3810,8 +3860,8 @@ microblaze_expand_divide (rtx operands[])
453 {
454 /* Table lookup software divides. Works for all (nr/dr) where (0 <= nr,dr <= 15). */
455
456- rtx regt1 = gen_reg_rtx (SImode);
457- rtx reg18 = gen_rtx_REG (SImode, R_TMP);
458+ rtx regt1 = gen_reg_rtx (Pmode);
459+ rtx reg18 = gen_rtx_REG (Pmode, R_TMP);
460 rtx regqi = gen_reg_rtx (QImode);
461 rtx_code_label *div_label = gen_label_rtx ();
462 rtx_code_label *div_end_label = gen_label_rtx ();
463@@ -3819,17 +3869,31 @@ microblaze_expand_divide (rtx operands[])
464 rtx mem_rtx;
465 rtx ret;
466 rtx_insn *jump, *cjump, *insn;
467-
468- insn = emit_insn (gen_iorsi3 (regt1, operands[1], operands[2]));
469- cjump = emit_jump_insn_after (gen_cbranchsi4 (
470- gen_rtx_GTU (SImode, regt1, GEN_INT (15)),
471+
472+ if (TARGET_MB_64) {
473+ insn = emit_insn (gen_iordi3 (regt1, operands[1], operands[2]));
474+ cjump = emit_jump_insn_after (gen_cbranchdi4 (
475+ gen_rtx_GTU (Pmode, regt1, GEN_INT (15)),
476+ regt1, GEN_INT (15), div_label), insn);
477+ }
478+ else {
479+ insn = emit_insn (gen_iorsi3 (regt1, operands[1], operands[2]));
480+ cjump = emit_jump_insn_after (gen_cbranchsi4 (
481+ gen_rtx_GTU (Pmode, regt1, GEN_INT (15)),
482 regt1, GEN_INT (15), div_label), insn);
483+ }
484 LABEL_NUSES (div_label) = 1;
485 JUMP_LABEL (cjump) = div_label;
486- emit_insn (gen_rtx_CLOBBER (SImode, reg18));
487+ emit_insn (gen_rtx_CLOBBER (Pmode, reg18));
488
489- emit_insn (gen_ashlsi3_bshift (regt1, operands[1], GEN_INT(4)));
490- emit_insn (gen_addsi3 (regt1, regt1, operands[2]));
491+ if (TARGET_MB_64) {
492+ emit_insn (gen_ashldi3_long (regt1, operands[1], GEN_INT(4)));
493+ emit_insn (gen_adddi3 (regt1, regt1, operands[2]));
494+ }
495+ else {
496+ emit_insn (gen_ashlsi3_bshift (regt1, operands[1], GEN_INT(4)));
497+ emit_insn (gen_addsi3 (regt1, regt1, operands[2]));
498+ }
499 mem_rtx = gen_rtx_MEM (QImode,
500 gen_rtx_PLUS (QImode, regt1, div_table_rtx));
501
502@@ -3976,7 +4040,7 @@ insert_wic_for_ilb_runout (rtx_insn *first)
503 {
504 insn =
505 emit_insn_before (gen_iprefetch
506- (gen_int_mode (addr_offset, SImode)),
507+ (gen_int_mode (addr_offset, Pmode)),
508 before_4);
509 recog_memoized (insn);
510 INSN_LOCATION (insn) = INSN_LOCATION (before_4);
511@@ -3986,7 +4050,27 @@ insert_wic_for_ilb_runout (rtx_insn *first)
512 }
513 }
514 }
515-
516+
517+/* Set the names for various arithmetic operations according to the
518+ * MICROBLAZE ABI. */
519+static void
520+microblaze_init_libfuncs (void)
521+{
522+ set_optab_libfunc (smod_optab, SImode, "__modsi3");
523+ set_optab_libfunc (sdiv_optab, SImode, "__divsi3");
524+ set_optab_libfunc (smul_optab, SImode, "__mulsi3");
525+ set_optab_libfunc (umod_optab, SImode, "__umodsi3");
526+ set_optab_libfunc (udiv_optab, SImode, "__udivsi3");
527+
528+ if (TARGET_MB_64)
529+ {
530+ set_optab_libfunc (smod_optab, DImode, "__moddi3");
531+ set_optab_libfunc (sdiv_optab, DImode, "__divdi3");
532+ set_optab_libfunc (smul_optab, DImode, "__muldi3");
533+ set_optab_libfunc (umod_optab, DImode, "__umoddi3");
534+ set_optab_libfunc (udiv_optab, DImode, "__udivdi3");
535+ }
536+}
537 /* Insert instruction prefetch instruction at the fall
538 through path of the function call. */
539
540@@ -4139,6 +4223,17 @@ microblaze_starting_frame_offset (void)
541 #undef TARGET_LRA_P
542 #define TARGET_LRA_P hook_bool_void_false
543
544+#ifdef TARGET_MB_64
545+#undef TARGET_ASM_ALIGNED_DI_OP
546+#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
547+
548+#undef TARGET_ASM_ALIGNED_HI_OP
549+#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
550+
551+#undef TARGET_ASM_ALIGNED_SI_OP
552+#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
553+#endif
554+
555 #undef TARGET_FRAME_POINTER_REQUIRED
556 #define TARGET_FRAME_POINTER_REQUIRED microblaze_frame_pointer_required
557
558@@ -4148,6 +4243,9 @@ microblaze_starting_frame_offset (void)
559 #undef TARGET_TRAMPOLINE_INIT
560 #define TARGET_TRAMPOLINE_INIT microblaze_trampoline_init
561
562+#undef TARGET_INIT_LIBFUNCS
563+#define TARGET_INIT_LIBFUNCS microblaze_init_libfuncs
564+
565 #undef TARGET_PROMOTE_FUNCTION_MODE
566 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
567
568diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
569index f35f7075ce3..3aee003de0d 100644
570--- a/gcc/config/microblaze/microblaze.h
571+++ b/gcc/config/microblaze/microblaze.h
572@@ -173,7 +173,6 @@ extern enum pipeline_type microblaze_pipe;
573
574 /* Generate DWARF exception handling info. */
575 #define DWARF2_UNWIND_INFO 1
576-
577 /* Don't generate .loc operations. */
578 #define DWARF2_ASM_LINE_DEBUG_INFO 0
579
580@@ -206,38 +205,51 @@ extern enum pipeline_type microblaze_pipe;
581 ((flag_pic || GLOBAL) ? DW_EH_PE_aligned : DW_EH_PE_absptr)
582
583 /* Use DWARF 2 debugging information by default. */
584-#define DWARF2_DEBUGGING_INFO
585+#define DWARF2_DEBUGGING_INFO 1
586 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
587+#define DWARF2_ADDR_SIZE 4
588
589 /* Target machine storage layout */
590
591 #define BITS_BIG_ENDIAN 0
592 #define BYTES_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
593 #define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
594-#define BITS_PER_WORD 32
595-#define UNITS_PER_WORD 4
596+//#define BITS_PER_WORD 64
597+//Revisit
598+#define MAX_BITS_PER_WORD 64
599+#define UNITS_PER_WORD (TARGET_MB_64 ? 8 : 4)
600+//#define MIN_UNITS_PER_WORD (TARGET_MB_64 ? 8 : 4)
601+//#define UNITS_PER_WORD 4
602 #define MIN_UNITS_PER_WORD 4
603 #define INT_TYPE_SIZE 32
604 #define SHORT_TYPE_SIZE 16
605-#define LONG_TYPE_SIZE 64
606+#define LONG_TYPE_SIZE (TARGET_MB_64 ? 64 : 32)
607 #define LONG_LONG_TYPE_SIZE 64
608 #define FLOAT_TYPE_SIZE 32
609 #define DOUBLE_TYPE_SIZE 64
610 #define LONG_DOUBLE_TYPE_SIZE 64
611-#define POINTER_SIZE 32
612-#define PARM_BOUNDARY 32
613-#define FUNCTION_BOUNDARY 32
614-#define EMPTY_FIELD_BOUNDARY 32
615+#define POINTER_SIZE (TARGET_MB_64 ? 64 : 32)
616+//#define WIDEST_HARDWARE_FP_SIZE 64
617+//#define POINTERS_EXTEND_UNSIGNED 1
618+#define PARM_BOUNDARY (TARGET_MB_64 ? 64 : 32)
619+#define FUNCTION_BOUNDARY (TARGET_MB_64 ? 64 : 32)
620+#define EMPTY_FIELD_BOUNDARY (TARGET_MB_64 ? 64 : 32)
621 #define STRUCTURE_SIZE_BOUNDARY 8
622-#define BIGGEST_ALIGNMENT 32
623+#define BIGGEST_ALIGNMENT (TARGET_MB_64 ? 64 : 32)
624 #define STRICT_ALIGNMENT 1
625 #define PCC_BITFIELD_TYPE_MATTERS 1
626
627+//#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_MB_64 ? TImode : DImode)
628 #undef SIZE_TYPE
629-#define SIZE_TYPE "unsigned int"
630+#define SIZE_TYPE (TARGET_MB_64 ? "long unsigned int" : "unsigned int")
631
632 #undef PTRDIFF_TYPE
633-#define PTRDIFF_TYPE "int"
634+#define PTRDIFF_TYPE (TARGET_MB_64 ? "long int" : "int")
635+
636+/*#undef INTPTR_TYPE
637+#define INTPTR_TYPE (TARGET_MB_64 ? "long int" : "int")*/
638+#undef UINTPTR_TYPE
639+#define UINTPTR_TYPE (TARGET_MB_64 ? "long unsigned int" : "unsigned int")
640
641 #define DATA_ALIGNMENT(TYPE, ALIGN) \
642 ((((ALIGN) < BITS_PER_WORD) \
643@@ -253,12 +265,12 @@ extern enum pipeline_type microblaze_pipe;
644 #define WORD_REGISTER_OPERATIONS 1
645
646 #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
647-
648+/*
649 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
650 if (GET_MODE_CLASS (MODE) == MODE_INT \
651- && GET_MODE_SIZE (MODE) < 4) \
652- (MODE) = SImode;
653-
654+ && GET_MODE_SIZE (MODE) < (TARGET_MB_64 ? 8 : 4)) \
655+ (MODE) = TARGET_MB_64 ? DImode : SImode;
656+*/
657 /* Standard register usage. */
658
659 /* On the MicroBlaze, we have 32 integer registers */
660@@ -438,13 +450,16 @@ extern struct microblaze_frame_info current_frame_info;
661 #define FIRST_PARM_OFFSET(FNDECL) (UNITS_PER_WORD)
662
663 #define ARG_POINTER_CFA_OFFSET(FNDECL) 0
664+#define DWARF_CIE_DATA_ALIGNMENT -1
665
666 #define REG_PARM_STACK_SPACE(FNDECL) (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
667
668 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
669
670-#define STACK_BOUNDARY 32
671+#define STACK_BOUNDARY (TARGET_MB_64 ? 64 : 32)
672
673+#define PREFERRED_STACK_BOUNDARY (TARGET_MB_64 ? 64 : 32)
674+
675 #define NUM_OF_ARGS 6
676
677 #define GP_RETURN (GP_REG_FIRST + MB_ABI_INT_RETURN_VAL_REGNUM)
678@@ -455,12 +470,15 @@ extern struct microblaze_frame_info current_frame_info;
679 #define MAX_ARGS_IN_REGISTERS MB_ABI_MAX_ARG_REGS
680
681 #define LIBCALL_VALUE(MODE) \
682+ gen_rtx_REG (MODE,GP_RETURN)
683+
684+/*#define LIBCALL_VALUE(MODE) \
685 gen_rtx_REG ( \
686 ((GET_MODE_CLASS (MODE) != MODE_INT \
687 || GET_MODE_SIZE (MODE) >= 4) \
688 ? (MODE) \
689 : SImode), GP_RETURN)
690-
691+*/
692 /* 1 if N is a possible register number for a function value.
693 On the MicroBlaze, R2 R3 are the only register thus used.
694 Currently, R2 are only implemented here (C has no complex type) */
695@@ -500,7 +518,7 @@ typedef struct microblaze_args
696 /* 4 insns + 2 words of data. */
697 #define TRAMPOLINE_SIZE (6 * 4)
698
699-#define TRAMPOLINE_ALIGNMENT 32
700+#define TRAMPOLINE_ALIGNMENT 64
701
702 #define REGNO_OK_FOR_BASE_P(regno) microblaze_regno_ok_for_base_p ((regno), 1)
703
704@@ -529,13 +547,13 @@ typedef struct microblaze_args
705 addresses which require two reload registers. */
706 #define LEGITIMATE_PIC_OPERAND_P(X) microblaze_legitimate_pic_operand (X)
707
708-#define CASE_VECTOR_MODE (SImode)
709+#define CASE_VECTOR_MODE (TARGET_MB_64? DImode:SImode)
710
711 #ifndef DEFAULT_SIGNED_CHAR
712 #define DEFAULT_SIGNED_CHAR 1
713 #endif
714
715-#define MOVE_MAX 4
716+#define MOVE_MAX (TARGET_MB_64 ? 8 : 4)
717 #define MAX_MOVE_MAX 8
718
719 #define SLOW_BYTE_ACCESS 1
720@@ -545,7 +563,7 @@ typedef struct microblaze_args
721
722 #define SHIFT_COUNT_TRUNCATED 1
723
724-#define Pmode SImode
725+#define Pmode (TARGET_MB_64? DImode:SImode)
726
727 #define FUNCTION_MODE SImode
728
729@@ -707,6 +725,7 @@ do { \
730
731 #undef TARGET_ASM_OUTPUT_IDENT
732 #define TARGET_ASM_OUTPUT_IDENT microblaze_asm_output_ident
733+//#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive
734
735 /* Default to -G 8 */
736 #ifndef MICROBLAZE_DEFAULT_GVALUE
737diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
738index 3f572fe2351..97da9aad6fd 100644
739--- a/gcc/config/microblaze/microblaze.md
740+++ b/gcc/config/microblaze/microblaze.md
741@@ -26,6 +26,7 @@
742 ;; Constants
743 ;;----------------------------------------------------
744 (define_constants [
745+ (R_Z 0) ;; For reg r0
746 (R_SP 1) ;; Stack pointer reg
747 (R_SR 15) ;; Sub-routine return addr reg
748 (R_IR 14) ;; Interrupt return addr reg
749@@ -541,6 +542,7 @@
750
751 ;; Add 2 SImode integers [ src1 = reg ; src2 = arith ; dest = reg ]
752 ;; Leave carry as is
753+
754 (define_insn "addsi3"
755 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
756 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%dJ,dJ,dJ")
757@@ -562,23 +564,38 @@
758
759 ;; Adding 2 DI operands in register or reg/imm
760
761-(define_insn "adddi3_long"
762+(define_expand "adddi3"
763+ [(set (match_operand:DI 0 "register_operand" "")
764+ (plus:DI (match_operand:DI 1 "register_operand" "")
765+ (match_operand:DI 2 "arith_plus_operand" "")))]
766+""
767+{
768+ if (TARGET_MB_64)
769+ {
770+ if (GET_CODE (operands[2]) == CONST_INT &&
771+ INTVAL(operands[2]) < (long)-549755813888 &&
772+ INTVAL(operands[2]) > (long)549755813887)
773+ FAIL;
774+ }
775+})
776+
777+(define_insn "*adddi3_long"
778 [(set (match_operand:DI 0 "register_operand" "=d,d")
779- (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%dJ,dJ")
780+ (plus:DI (match_operand:DI 1 "register_operand" "%d,d")
781 (match_operand:DI 2 "arith_plus_operand" "d,K")))]
782 "TARGET_MB_64"
783 "@
784- addlk\t%0,%z1,%2
785- addlik\t%0,%z1,%2"
786- [(set_attr "type" "arith,arith")
787- (set_attr "mode" "DI,DI")
788+ addlk\t%0,%1,%2
789+ addlik\t%0,%1,%2 #N10"
790+ [(set_attr "type" "darith,no_delay_arith")
791+ (set_attr "mode" "DI")
792 (set_attr "length" "4,4")])
793
794-(define_insn "adddi3"
795+(define_insn "*adddi3_all"
796 [(set (match_operand:DI 0 "register_operand" "=d,d")
797 (plus:DI (match_operand:DI 1 "register_operand" "%d,d")
798 (match_operand:DI 2 "arith_operand" "d,i")))]
799- ""
800+ "!TARGET_MB_64"
801 "@
802 add\t%L0,%L1,%L2\;addc\t%M0,%M1,%M2
803 addi\t%L0,%L1,%j2\;addic\t%M0,%M1,%h2"
804@@ -605,7 +622,7 @@
805 (define_insn "iprefetch"
806 [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
807 (clobber (mem:BLK (scratch)))]
808- "TARGET_PREFETCH"
809+ "TARGET_PREFETCH && !TARGET_MB_64"
810 {
811 operands[2] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
812 return "mfs\t%2,rpc\n\twic\t%2,r0";
813@@ -618,23 +635,33 @@
814 ;; Double Precision Subtraction
815 ;;----------------------------------------------------------------
816
817-(define_insn "subdi3_long"
818- [(set (match_operand:DI 0 "register_operand" "=d,d")
819- (minus:DI (match_operand:DI 1 "register_operand" "d,d")
820- (match_operand:DI 2 "register_operand" "d,n")))]
821+(define_expand "subdi3"
822+ [(set (match_operand:DI 0 "register_operand" "")
823+ (minus:DI (match_operand:DI 1 "register_operand" "")
824+ (match_operand:DI 2 "arith_operand" "")))]
825+""
826+"
827+{
828+}")
829+
830+(define_insn "subsidi3"
831+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
832+ (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
833+ (match_operand:DI 2 "arith_operand" "d,K,n")))]
834 "TARGET_MB_64"
835 "@
836 rsubl\t%0,%2,%1
837- addlik\t%0,%z1,-%2"
838- [(set_attr "type" "darith")
839- (set_attr "mode" "DI,DI")
840- (set_attr "length" "4,4")])
841+ addik\t%0,%z1,-%2
842+ addik\t%0,%z1,-%2"
843+ [(set_attr "type" "arith,no_delay_arith,no_delay_arith")
844+ (set_attr "mode" "DI")
845+ (set_attr "length" "4,4,4")])
846
847-(define_insn "subdi3"
848+(define_insn "subdi3_small"
849 [(set (match_operand:DI 0 "register_operand" "=&d")
850 (minus:DI (match_operand:DI 1 "register_operand" "d")
851 (match_operand:DI 2 "register_operand" "d")))]
852- ""
853+ "!TARGET_MB_64"
854 "rsub\t%L0,%L2,%L1\;rsubc\t%M0,%M2,%M1"
855 [(set_attr "type" "darith")
856 (set_attr "mode" "DI")
857@@ -663,7 +690,7 @@
858 (mult:DI
859 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
860 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
861- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
862+ "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH && !TARGET_MB_64"
863 "mul\t%L0,%1,%2\;mulh\t%M0,%1,%2"
864 [(set_attr "type" "no_delay_arith")
865 (set_attr "mode" "DI")
866@@ -674,7 +701,7 @@
867 (mult:DI
868 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
869 (zero_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\;mulhu\t%M0,%1,%2"
873 [(set_attr "type" "no_delay_arith")
874 (set_attr "mode" "DI")
875@@ -685,7 +712,7 @@
876 (mult:DI
877 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
878 (sign_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\;mulhsu\t%M0,%2,%1"
882 [(set_attr "type" "no_delay_arith")
883 (set_attr "mode" "DI")
884@@ -789,7 +816,7 @@
885 (match_operand:SI 4 "arith_operand")])
886 (label_ref (match_operand 5))
887 (pc)))]
888- "TARGET_HARD_FLOAT"
889+ "TARGET_HARD_FLOAT && !TARGET_MB_64"
890 [(set (match_dup 1) (match_dup 3))]
891
892 {
893@@ -819,6 +846,15 @@
894 (set_attr "mode" "SI")
895 (set_attr "length" "4")])
896
897+(define_insn "negsi_long"
898+ [(set (match_operand:SI 0 "register_operand" "=d")
899+ (neg:SI (match_operand:DI 1 "register_operand" "d")))]
900+ ""
901+ "rsubk\t%0,%1,r0"
902+ [(set_attr "type" "arith")
903+ (set_attr "mode" "SI")
904+ (set_attr "length" "4")])
905+
906 (define_insn "negdi2_long"
907 [(set (match_operand:DI 0 "register_operand" "=d")
908 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
909@@ -847,16 +883,24 @@
910 (set_attr "mode" "SI")
911 (set_attr "length" "4")])
912
913-(define_insn "one_cmpldi2_long"
914+(define_expand "one_cmpldi2"
915+ [(set (match_operand:DI 0 "register_operand" "")
916+ (not:DI (match_operand:DI 1 "register_operand" "")))]
917+ ""
918+ "
919+{
920+}")
921+
922+(define_insn ""
923 [(set (match_operand:DI 0 "register_operand" "=d")
924- (not:DI (match_operand:DI 1 "register_operand" "d")))]
925+ (not:DI (match_operand:DI 1 "arith_operand" "d")))]
926 "TARGET_MB_64"
927 "xorli\t%0,%1,-1"
928- [(set_attr "type" "arith")
929+ [(set_attr "type" "no_delay_arith")
930 (set_attr "mode" "DI")
931 (set_attr "length" "4")])
932
933-(define_insn "*one_cmpldi2"
934+(define_insn ""
935 [(set (match_operand:DI 0 "register_operand" "=d")
936 (not:DI (match_operand:DI 1 "register_operand" "d")))]
937 ""
938@@ -871,7 +915,8 @@
939 (not:DI (match_operand:DI 1 "register_operand" "")))]
940 "reload_completed
941 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
942- && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
943+ && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
944+ && !TARGET_MB_64"
945
946 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
947 (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
948@@ -883,18 +928,17 @@
949 ;;----------------------------------------------------------------
950
951 (define_insn "anddi3"
952- [(set (match_operand:DI 0 "register_operand" "=d,d")
953- (and:DI (match_operand:DI 1 "arith_operand" "d,d")
954- (match_operand:DI 2 "arith_operand" "d,K")))]
955+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
956+ (and:DI (match_operand:DI 1 "arith_operand" "d,d,d")
957+ (match_operand:DI 2 "arith_operand" "d,K,I")))]
958 "TARGET_MB_64"
959 "@
960 andl\t%0,%1,%2
961- andli\t%0,%1,%2 #andl1"
962- ;; andli\t%0,%1,%2 #andl3
963- ;; andli\t%0,%1,%2 #andl2
964- [(set_attr "type" "arith,arith")
965- (set_attr "mode" "DI,DI")
966- (set_attr "length" "4,4")])
967+ andli\t%0,%1,%2 #andl2
968+ andli\t%0,%1,%2 #andl3"
969+ [(set_attr "type" "arith,no_delay_arith,no_delay_arith")
970+ (set_attr "mode" "DI,DI,DI")
971+ (set_attr "length" "4,4,4")])
972
973 (define_insn "andsi3"
974 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
975@@ -919,7 +963,7 @@
976 "@
977 orl\t%0,%1,%2
978 orli\t%0,%1,%2 #andl1"
979- [(set_attr "type" "arith,arith")
980+ [(set_attr "type" "arith,no_delay_arith")
981 (set_attr "mode" "DI,DI")
982 (set_attr "length" "4,4")])
983
984@@ -945,7 +989,7 @@
985 "@
986 xorl\t%0,%1,%2
987 xorli\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@@ -1018,26 +1062,6 @@
994 (set_attr "mode" "SI")
995 (set_attr "length" "4")])
996
997-;;(define_expand "extendqidi2"
998-;; [(set (match_operand:DI 0 "register_operand" "=d")
999-;; (sign_extend:DI (match_operand:QI 1 "general_operand" "d")))]
1000-;; "TARGET_MB_64"
1001-;; {
1002-;; if (GET_CODE (operands[1]) != REG)
1003-;; FAIL;
1004-;; }
1005-;;)
1006-
1007-
1008-;;(define_insn "extendqidi2"
1009-;; [(set (match_operand:DI 0 "register_operand" "=d")
1010-;; (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
1011-;; "TARGET_MB_64"
1012-;; "sextl8\t%0,%1"
1013-;; [(set_attr "type" "arith")
1014-;; (set_attr "mode" "DI")
1015-;; (set_attr "length" "4")])
1016-
1017 (define_insn "extendhisi2"
1018 [(set (match_operand:SI 0 "register_operand" "=d")
1019 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
1020@@ -1060,6 +1084,27 @@
1021 ;; Those for integer source operand are ordered
1022 ;; widest source type first.
1023
1024+(define_insn "extendsidi2_long"
1025+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1026+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1027+ "TARGET_MB_64"
1028+ {
1029+ switch (which_alternative)
1030+ {
1031+ case 0:
1032+ return "sextl32\t%0,%1";
1033+ case 1:
1034+ case 2:
1035+ {
1036+ output_asm_insn ("ll%i1\t%0,%1", operands);
1037+ return "sextl32\t%0,%0";
1038+ }
1039+ }
1040+ }
1041+ [(set_attr "type" "multi,multi,multi")
1042+ (set_attr "mode" "DI")
1043+ (set_attr "length" "4,8,8")])
1044+
1045 (define_insn "extendsidi2"
1046 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1047 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1048@@ -1088,69 +1133,118 @@
1049 ;; Unlike most other insns, the move insns can't be split with
1050 ;; different predicates, because register spilling and other parts of
1051 ;; the compiler, have memoized the insn number already.
1052+;; //}
1053
1054 (define_expand "movdi"
1055 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1056 (match_operand:DI 1 "general_operand" ""))]
1057 ""
1058 {
1059- /* If operands[1] is a constant address illegal for pic, then we need to
1060- handle it just like microblaze_legitimize_address does. */
1061- if (flag_pic && pic_address_needs_scratch (operands[1]))
1062+ if (TARGET_MB_64)
1063 {
1064+ if (microblaze_expand_move (DImode, operands)) DONE;
1065+ }
1066+ else
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+ {
1072 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
1073 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
1074 emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
1075 DONE;
1076- }
1077-
1078-
1079- if ((reload_in_progress | reload_completed) == 0
1080- && !register_operand (operands[0], DImode)
1081- && !register_operand (operands[1], DImode)
1082- && (((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
1083- && operands[1] != CONST0_RTX (DImode))))
1084- {
1085+ }
1086
1087- rtx temp = force_reg (DImode, operands[1]);
1088- emit_move_insn (operands[0], temp);
1089- DONE;
1090+ if ((reload_in_progress | reload_completed) == 0
1091+ && !register_operand (operands[0], DImode)
1092+ && !register_operand (operands[1], DImode)
1093+ && (((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
1094+ && operands[1] != CONST0_RTX (DImode))))
1095+ {
1096+ rtx temp = force_reg (DImode, operands[1]);
1097+ emit_move_insn (operands[0], temp);
1098+ DONE;
1099+ }
1100 }
1101 }
1102 )
1103
1104+;; Added for status registers
1105+(define_insn "movdi_status"
1106+ [(set (match_operand:DI 0 "register_operand" "=d,d,z")
1107+ (match_operand:DI 1 "register_operand" "z,d,d"))]
1108+ "microblaze_is_interrupt_variant () && TARGET_MB_64"
1109+ "@
1110+ mfs\t%0,%1 #mfs
1111+ addlk\t%0,%1,r0 #add movdi
1112+ mts\t%0,%1 #mts"
1113+ [(set_attr "type" "move")
1114+ (set_attr "mode" "DI")
1115+ (set_attr "length" "12")])
1116+
1117+;; This move will be not be moved to delay slot.
1118+(define_insn "*movdi_internal3"
1119+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d")
1120+ (match_operand:DI 1 "immediate_operand" "J,I,Mnis"))]
1121+ "TARGET_MB_64 && (register_operand (operands[0], DImode) &&
1122+ (GET_CODE (operands[1]) == CONST_INT &&
1123+ (INTVAL (operands[1]) <= (long)549755813887 && INTVAL (operands[1]) >= (long)-549755813888)))"
1124+ "@
1125+ addlk\t%0,r0,r0\t
1126+ addlik\t%0,r0,%1\t #N1 %X1
1127+ addlik\t%0,r0,%1\t #N2 %X1"
1128+ [(set_attr "type" "arith,no_delay_arith,no_delay_arith")
1129+ (set_attr "mode" "DI")
1130+ (set_attr "length" "4")])
1131
1132-(define_insn "*movdi_internal_64"
1133- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o")
1134- (match_operand:DI 1 "general_operand" " d,K,J,R,o,d,d"))]
1135- "TARGET_MB_64 && (INTVAL(operands[1]) < 0x7fffffffff) && (INTVAL(operands[1]) > 0xffffff8000000000)"
1136+;; This move may be used for PLT label operand
1137+(define_insn "*movdi_internal5_pltop"
1138+ [(set (match_operand:DI 0 "register_operand" "=d,d")
1139+ (match_operand:DI 1 "call_insn_operand" ""))]
1140+ "TARGET_MB_64 && (register_operand (operands[0], Pmode) &&
1141+ PLT_ADDR_P (operands[1]))"
1142+ {
1143+ gcc_unreachable ();
1144+ }
1145+ [(set_attr "type" "load")
1146+ (set_attr "mode" "DI")
1147+ (set_attr "length" "4")])
1148+
1149+(define_insn "*movdi_internal2"
1150+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d, d,d,R,m")
1151+ (match_operand:DI 1 "move_src_operand" " d,I,Mnis,R,m,dJ,dJ"))]
1152+ "TARGET_MB_64"
1153 {
1154 switch (which_alternative)
1155 {
1156 case 0:
1157- return "addlk\t%0,%1";
1158- case 1:
1159- return "addlik\t%0,r0,%1";
1160- case 2:
1161- return "addlk\t%0,r0,r0";
1162- case 3:
1163- case 4:
1164- return "lli\t%0,%1";
1165- case 5:
1166- case 6:
1167- return "sli\t%1,%0";
1168- }
1169- return "unreachable";
1170- }
1171- [(set_attr "type" "no_delay_move,no_delay_arith,no_delay_arith,no_delay_load,no_delay_load,no_delay_store,no_delay_store")
1172+ return "addlk\t%0,%1,r0";
1173+ case 1:
1174+ case 2:
1175+ if (GET_CODE (operands[1]) == CONST_INT &&
1176+ (INTVAL (operands[1]) > (long)549755813887 || INTVAL (operands[1]) < (long)-549755813888))
1177+ return "addlik\t%0,r0,%h1\n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #li => la";
1178+ else
1179+ return "addlik\t%0,r0,%1";
1180+ case 3:
1181+ case 4:
1182+ return "ll%i1\t%0,%1";
1183+ case 5:
1184+ case 6:
1185+ return "sl%i0\t%z1,%0";
1186+ }
1187+ }
1188+ [(set_attr "type" "load,no_delay_load,no_delay_load,no_delay_load,no_delay_load,no_delay_store,no_delay_store")
1189 (set_attr "mode" "DI")
1190- (set_attr "length" "8,8,8,8,12,8,12")])
1191+ (set_attr "length" "4,4,12,4,8,4,8")])
1192+
1193
1194
1195 (define_insn "*movdi_internal"
1196 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o")
1197 (match_operand:DI 1 "general_operand" " d,i,J,R,o,d,d"))]
1198- ""
1199+ "!TARGET_MB_64"
1200 {
1201 switch (which_alternative)
1202 {
1203@@ -1182,7 +1276,8 @@
1204 "reload_completed
1205 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1206 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1207- && (REGNO(operands[0]) == (REGNO(operands[1]) + 1))"
1208+ && (REGNO(operands[0]) == (REGNO(operands[1]) + 1))
1209+ && !(TARGET_MB_64)"
1210
1211 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
1212 (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
1213@@ -1194,12 +1289,22 @@
1214 "reload_completed
1215 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1216 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1217- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
1218+ && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))
1219+ && !(TARGET_MB_64)"
1220
1221 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1222 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
1223 "")
1224
1225+(define_insn "movdi_long_int"
1226+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1227+ (match_operand:DI 1 "general_operand" "i"))]
1228+ ""
1229+ "addlik\t%0,r0,%h1\n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #li => la";
1230+ [(set_attr "type" "no_delay_arith")
1231+ (set_attr "mode" "DI")
1232+ (set_attr "length" "12")])
1233+
1234 ;; Unlike most other insns, the move insns can't be split with
1235 ;; different predicates, because register spilling and other parts of
1236 ;; the compiler, have memoized the insn number already.
1237@@ -1271,6 +1376,8 @@
1238 (set_attr "length" "4,4,8,4,8,4,8")])
1239
1240
1241+
1242+
1243 ;; 16-bit Integer moves
1244
1245 ;; Unlike most other insns, the move insns can't be split with
1246@@ -1303,8 +1410,8 @@
1247 "@
1248 addik\t%0,r0,%1\t# %X1
1249 addk\t%0,%1,r0
1250- lhui\t%0,%1
1251- lhui\t%0,%1
1252+ lhu%i1\t%0,%1
1253+ lhu%i1\t%0,%1
1254 sh%i0\t%z1,%0
1255 sh%i0\t%z1,%0"
1256 [(set_attr "type" "arith,move,load,no_delay_load,store,no_delay_store")
1257@@ -1347,7 +1454,7 @@
1258 lbu%i1\t%0,%1
1259 lbu%i1\t%0,%1
1260 sb%i0\t%z1,%0
1261- sbi\t%z1,%0"
1262+ sb%i0\t%z1,%0"
1263 [(set_attr "type" "arith,arith,move,load,no_delay_load,store,no_delay_store")
1264 (set_attr "mode" "QI")
1265 (set_attr "length" "4,4,8,4,8,4,8")])
1266@@ -1420,7 +1527,7 @@
1267 addik\t%0,r0,%F1
1268 lw%i1\t%0,%1
1269 sw%i0\t%z1,%0
1270- swi\t%z1,%0"
1271+ sw%i0\t%z1,%0"
1272 [(set_attr "type" "move,no_delay_load,load,no_delay_load,no_delay_load,store,no_delay_store")
1273 (set_attr "mode" "SF")
1274 (set_attr "length" "4,4,4,4,4,4,4")])
1275@@ -1459,6 +1566,33 @@
1276 ;; movdf_internal
1277 ;; Applies to both TARGET_SOFT_FLOAT and TARGET_HARD_FLOAT
1278 ;;
1279+(define_insn "*movdf_internal_64"
1280+ [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,d,d,m")
1281+ (match_operand:DF 1 "general_operand" "d,dG,m,F,T,d"))]
1282+ "TARGET_MB_64"
1283+ {
1284+ switch (which_alternative)
1285+ {
1286+ case 0:
1287+ return "addlk\t%0,%1,r0";
1288+ case 1:
1289+ return "addlk\t%0,r0,r0";
1290+ case 2:
1291+ case 4:
1292+ return "ll%i1\t%0,%1";
1293+ case 3:
1294+ {
1295+ return "addlik\t%0,r0,%h1 \n\tbsllli\t%0,%0,32\n\taddlik\t%0,%0,%j1 #Xfer Lo";
1296+ }
1297+ case 5:
1298+ return "sl%i0\t%1,%0";
1299+ }
1300+ gcc_unreachable ();
1301+ }
1302+ [(set_attr "type" "no_delay_move,no_delay_move,no_delay_load,no_delay_load,no_delay_load,no_delay_store")
1303+ (set_attr "mode" "DF")
1304+ (set_attr "length" "4,4,4,16,4,4")])
1305+
1306 (define_insn "*movdf_internal"
1307 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,d,o")
1308 (match_operand:DF 1 "general_operand" "dG,o,F,T,d"))]
1309@@ -1493,7 +1627,8 @@
1310 "reload_completed
1311 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1312 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1313- && (REGNO (operands[0]) == (REGNO (operands[1]) + 1))"
1314+ && (REGNO (operands[0]) == (REGNO (operands[1]) + 1))
1315+ && !TARGET_MB_64"
1316 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
1317 (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
1318 "")
1319@@ -1504,7 +1639,8 @@
1320 "reload_completed
1321 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1322 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1323- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
1324+ && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))
1325+ && !TARGET_MB_64"
1326 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1327 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
1328 "")
1329@@ -2003,6 +2139,31 @@ else
1330 "
1331 )
1332
1333+
1334+(define_insn "seq_internal_pat_long"
1335+ [(set (match_operand:DI 0 "register_operand" "=d")
1336+ (eq:DI
1337+ (match_operand:DI 1 "register_operand" "d")
1338+ (match_operand:DI 2 "register_operand" "d")))]
1339+ "TARGET_MB_64"
1340+ "pcmpleq\t%0,%1,%2"
1341+ [(set_attr "type" "arith")
1342+ (set_attr "mode" "DI")
1343+ (set_attr "length" "4")]
1344+)
1345+
1346+(define_insn "sne_internal_pat_long"
1347+ [(set (match_operand:DI 0 "register_operand" "=d")
1348+ (ne:DI
1349+ (match_operand:DI 1 "register_operand" "d")
1350+ (match_operand:DI 2 "register_operand" "d")))]
1351+ "TARGET_MB_64"
1352+ "pcmplne\t%0,%1,%2"
1353+ [(set_attr "type" "arith")
1354+ (set_attr "mode" "DI")
1355+ (set_attr "length" "4")]
1356+)
1357+
1358 (define_insn "seq_internal_pat"
1359 [(set (match_operand:SI 0 "register_operand" "=d")
1360 (eq:SI
1361@@ -2063,8 +2224,8 @@ else
1362 (define_expand "cbranchsi4"
1363 [(set (pc)
1364 (if_then_else (match_operator 0 "ordered_comparison_operator"
1365- [(match_operand:SI 1 "register_operand")
1366- (match_operand:SI 2 "arith_operand" "I,i")])
1367+ [(match_operand 1 "register_operand")
1368+ (match_operand 2 "arith_operand" "I,i")])
1369 (label_ref (match_operand 3 ""))
1370 (pc)))]
1371 ""
1372@@ -2076,13 +2237,13 @@ else
1373 (define_expand "cbranchsi4_reg"
1374 [(set (pc)
1375 (if_then_else (match_operator 0 "ordered_comparison_operator"
1376- [(match_operand:SI 1 "register_operand")
1377- (match_operand:SI 2 "register_operand")])
1378+ [(match_operand 1 "register_operand")
1379+ (match_operand 2 "register_operand")])
1380 (label_ref (match_operand 3 ""))
1381 (pc)))]
1382 ""
1383 {
1384- microblaze_expand_conditional_branch_reg (SImode, operands);
1385+ microblaze_expand_conditional_branch_reg (Pmode, operands);
1386 DONE;
1387 })
1388
1389@@ -2107,6 +2268,26 @@ else
1390 (label_ref (match_operand 1))
1391 (pc)))])
1392
1393+(define_insn "branch_zero64"
1394+ [(set (pc)
1395+ (if_then_else (match_operator 0 "ordered_comparison_operator"
1396+ [(match_operand 1 "register_operand" "d")
1397+ (const_int 0)])
1398+ (match_operand 2 "pc_or_label_operand" "")
1399+ (match_operand 3 "pc_or_label_operand" "")))
1400+ ]
1401+ "TARGET_MB_64"
1402+ {
1403+ if (operands[3] == pc_rtx)
1404+ return "bea%C0i%?\t%z1,%2";
1405+ else
1406+ return "bea%N0i%?\t%z1,%3";
1407+ }
1408+ [(set_attr "type" "branch")
1409+ (set_attr "mode" "none")
1410+ (set_attr "length" "4")]
1411+)
1412+
1413 (define_insn "branch_zero"
1414 [(set (pc)
1415 (if_then_else (match_operator:SI 0 "ordered_comparison_operator"
1416@@ -2127,6 +2308,47 @@ else
1417 (set_attr "length" "4")]
1418 )
1419
1420+(define_insn "branch_compare64"
1421+ [(set (pc)
1422+ (if_then_else (match_operator 0 "cmp_op"
1423+ [(match_operand 1 "register_operand" "d")
1424+ (match_operand 2 "register_operand" "d")
1425+ ])
1426+ (label_ref (match_operand 3))
1427+ (pc)))
1428+ (clobber(reg:SI R_TMP))]
1429+ "TARGET_MB_64"
1430+ {
1431+ operands[4] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
1432+ enum rtx_code code = GET_CODE (operands[0]);
1433+
1434+ if (code == GT || code == LE)
1435+ {
1436+ output_asm_insn ("cmp\tr18,%z1,%z2", operands);
1437+ code = swap_condition (code);
1438+ }
1439+ else if (code == GTU || code == LEU)
1440+ {
1441+ output_asm_insn ("cmpu\tr18,%z1,%z2", operands);
1442+ code = swap_condition (code);
1443+ }
1444+ else if (code == GE || code == LT)
1445+ {
1446+ output_asm_insn ("cmp\tr18,%z2,%z1", operands);
1447+ }
1448+ else if (code == GEU || code == LTU)
1449+ {
1450+ output_asm_insn ("cmpu\tr18,%z2,%z1", operands);
1451+ }
1452+
1453+ operands[0] = gen_rtx_fmt_ee (signed_condition (code), SImode, operands[4], const0_rtx);
1454+ return "bea%C0i%?\tr18,%3";
1455+ }
1456+ [(set_attr "type" "branch")
1457+ (set_attr "mode" "none")
1458+ (set_attr "length" "12")]
1459+)
1460+
1461 (define_insn "branch_compare"
1462 [(set (pc)
1463 (if_then_else (match_operator:SI 0 "cmp_op"
1464@@ -2310,7 +2532,7 @@ else
1465 ;; Indirect jumps. Jump to register values. Assuming absolute jumps
1466
1467 (define_insn "indirect_jump_internal1"
1468- [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
1469+ [(set (pc) (match_operand 0 "register_operand" "d"))]
1470 ""
1471 "bra%?\t%0"
1472 [(set_attr "type" "jump")
1473@@ -2323,7 +2545,7 @@ else
1474 (use (label_ref (match_operand 1 "" "")))]
1475 ""
1476 {
1477- gcc_assert (GET_MODE (operands[0]) == Pmode);
1478+ //gcc_assert (GET_MODE (operands[0]) == Pmode);
1479
1480 if (!flag_pic || TARGET_PIC_DATA_TEXT_REL)
1481 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
1482@@ -2335,7 +2557,7 @@ else
1483
1484 (define_insn "tablejump_internal1"
1485 [(set (pc)
1486- (match_operand:SI 0 "register_operand" "d"))
1487+ (match_operand 0 "register_operand" "d"))
1488 (use (label_ref (match_operand 1 "" "")))]
1489 ""
1490 "bra%?\t%0 "
1491@@ -2345,9 +2567,9 @@ else
1492
1493 (define_expand "tablejump_internal3"
1494 [(parallel [(set (pc)
1495- (plus:SI (match_operand:SI 0 "register_operand" "d")
1496- (label_ref:SI (match_operand:SI 1 "" ""))))
1497- (use (label_ref:SI (match_dup 1)))])]
1498+ (plus (match_operand 0 "register_operand" "d")
1499+ (label_ref (match_operand:SI 1 "" ""))))
1500+ (use (label_ref (match_dup 1)))])]
1501 ""
1502 ""
1503 )
1504@@ -2408,7 +2630,7 @@ else
1505 (minus (reg 1) (match_operand 1 "register_operand" "")))
1506 (set (reg 1)
1507 (minus (reg 1) (match_dup 1)))]
1508- ""
1509+ "!TARGET_MB_64"
1510 {
1511 rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1512 rtx reg = gen_reg_rtx (Pmode);
1513@@ -2433,7 +2655,7 @@ else
1514 (define_expand "save_stack_block"
1515 [(match_operand 0 "register_operand" "")
1516 (match_operand 1 "register_operand" "")]
1517- ""
1518+ "!TARGET_MB_64"
1519 {
1520 emit_move_insn (operands[0], operands[1]);
1521 DONE;
1522@@ -2443,7 +2665,7 @@ else
1523 (define_expand "restore_stack_block"
1524 [(match_operand 0 "register_operand" "")
1525 (match_operand 1 "register_operand" "")]
1526- ""
1527+ "!TARGET_MB_64"
1528 {
1529 rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1530 rtx rtmp = gen_rtx_REG (SImode, R_TMP);
1531@@ -2490,7 +2712,7 @@ else
1532
1533 (define_insn "<optab>_internal"
1534 [(any_return)
1535- (use (match_operand:SI 0 "register_operand" ""))]
1536+ (use (match_operand 0 "register_operand" ""))]
1537 ""
1538 {
1539 if (microblaze_is_break_handler ())
1540@@ -2523,7 +2745,7 @@ else
1541 (define_expand "call"
1542 [(parallel [(call (match_operand 0 "memory_operand" "m")
1543 (match_operand 1 "" "i"))
1544- (clobber (reg:SI R_SR))
1545+ (clobber (reg R_SR))
1546 (use (match_operand 2 "" ""))
1547 (use (match_operand 3 "" ""))])]
1548 ""
1549@@ -2544,12 +2766,12 @@ else
1550
1551 if (GET_CODE (XEXP (operands[0], 0)) == UNSPEC)
1552 emit_call_insn (gen_call_internal_plt0 (operands[0], operands[1],
1553- gen_rtx_REG (SImode,
1554+ gen_rtx_REG (Pmode,
1555 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
1556 pic_offset_table_rtx));
1557 else
1558 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
1559- gen_rtx_REG (SImode,
1560+ gen_rtx_REG (Pmode,
1561 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
1562
1563 DONE;
1564@@ -2559,7 +2781,7 @@ else
1565 (define_expand "call_internal0"
1566 [(parallel [(call (match_operand 0 "" "")
1567 (match_operand 1 "" ""))
1568- (clobber (match_operand:SI 2 "" ""))])]
1569+ (clobber (match_operand 2 "" ""))])]
1570 ""
1571 {
1572 }
1573@@ -2568,18 +2790,34 @@ else
1574 (define_expand "call_internal_plt0"
1575 [(parallel [(call (match_operand 0 "" "")
1576 (match_operand 1 "" ""))
1577- (clobber (match_operand:SI 2 "" ""))
1578- (use (match_operand:SI 3 "" ""))])]
1579+ (clobber (match_operand 2 "" ""))
1580+ (use (match_operand 3 "" ""))])]
1581 ""
1582 {
1583 }
1584 )
1585
1586+(define_insn "call_internal_plt_64"
1587+ [(call (mem (match_operand 0 "call_insn_plt_operand" ""))
1588+ (match_operand 1 "" "i"))
1589+ (clobber (reg R_SR))
1590+ (use (reg R_GOT))]
1591+ "flag_pic && TARGET_MB_64"
1592+ {
1593+ register rtx target2 = gen_rtx_REG (Pmode,
1594+ GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1595+ gen_rtx_CLOBBER (VOIDmode, target2);
1596+ return "brealid\tr15,%0\;%#";
1597+ }
1598+ [(set_attr "type" "call")
1599+ (set_attr "mode" "none")
1600+ (set_attr "length" "4")])
1601+
1602 (define_insn "call_internal_plt"
1603- [(call (mem (match_operand:SI 0 "call_insn_plt_operand" ""))
1604- (match_operand:SI 1 "" "i"))
1605- (clobber (reg:SI R_SR))
1606- (use (reg:SI R_GOT))]
1607+ [(call (mem (match_operand 0 "call_insn_plt_operand" ""))
1608+ (match_operand 1 "" "i"))
1609+ (clobber (reg R_SR))
1610+ (use (reg R_GOT))]
1611 "flag_pic"
1612 {
1613 rtx target2
1614@@ -2591,10 +2829,41 @@ else
1615 (set_attr "mode" "none")
1616 (set_attr "length" "4")])
1617
1618+(define_insn "call_internal1_64"
1619+ [(call (mem (match_operand:VOID 0 "call_insn_simple_operand" "ri"))
1620+ (match_operand 1 "" "i"))
1621+ (clobber (reg R_SR))]
1622+ "TARGET_MB_64"
1623+ {
1624+ register rtx target = operands[0];
1625+ register rtx target2 = gen_rtx_REG (Pmode,
1626+ GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1627+ if (GET_CODE (target) == SYMBOL_REF) {
1628+ if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
1629+ gen_rtx_CLOBBER (VOIDmode, target2);
1630+ return "breaki\tr16,%0\;%#";
1631+ }
1632+ else {
1633+ gen_rtx_CLOBBER (VOIDmode, target2);
1634+ return "brealid\tr15,%0\;%#";
1635+ }
1636+ } else if (GET_CODE (target) == CONST_INT)
1637+ return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
1638+ else if (GET_CODE (target) == REG)
1639+ return "brald\tr15,%0\;%#";
1640+ else {
1641+ fprintf (stderr,"Unsupported call insn\n");
1642+ return NULL;
1643+ }
1644+ }
1645+ [(set_attr "type" "call")
1646+ (set_attr "mode" "none")
1647+ (set_attr "length" "4")])
1648+
1649 (define_insn "call_internal1"
1650 [(call (mem (match_operand:VOID 0 "call_insn_simple_operand" "ri"))
1651- (match_operand:SI 1 "" "i"))
1652- (clobber (reg:SI R_SR))]
1653+ (match_operand 1 "" "i"))
1654+ (clobber (reg R_SR))]
1655 ""
1656 {
1657 rtx target = operands[0];
1658@@ -2628,7 +2897,7 @@ else
1659 [(parallel [(set (match_operand 0 "register_operand" "=d")
1660 (call (match_operand 1 "memory_operand" "m")
1661 (match_operand 2 "" "i")))
1662- (clobber (reg:SI R_SR))
1663+ (clobber (reg R_SR))
1664 (use (match_operand 3 "" ""))])] ;; next_arg_reg
1665 ""
1666 {
1667@@ -2649,13 +2918,13 @@ else
1668 if (GET_CODE (XEXP (operands[1], 0)) == UNSPEC)
1669 emit_call_insn (gen_call_value_intern_plt0 (operands[0], operands[1],
1670 operands[2],
1671- gen_rtx_REG (SImode,
1672+ gen_rtx_REG (Pmode,
1673 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
1674 pic_offset_table_rtx));
1675 else
1676 emit_call_insn (gen_call_value_internal (operands[0], operands[1],
1677 operands[2],
1678- gen_rtx_REG (SImode,
1679+ gen_rtx_REG (Pmode,
1680 GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
1681
1682 DONE;
1683@@ -2667,7 +2936,7 @@ else
1684 [(parallel [(set (match_operand 0 "" "")
1685 (call (match_operand 1 "" "")
1686 (match_operand 2 "" "")))
1687- (clobber (match_operand:SI 3 "" ""))
1688+ (clobber (match_operand 3 "" ""))
1689 ])]
1690 ""
1691 {}
1692@@ -2677,18 +2946,35 @@ else
1693 [(parallel[(set (match_operand 0 "" "")
1694 (call (match_operand 1 "" "")
1695 (match_operand 2 "" "")))
1696- (clobber (match_operand:SI 3 "" ""))
1697- (use (match_operand:SI 4 "" ""))])]
1698+ (clobber (match_operand 3 "" ""))
1699+ (use (match_operand 4 "" ""))])]
1700 "flag_pic"
1701 {}
1702 )
1703
1704+(define_insn "call_value_intern_plt_64"
1705+ [(set (match_operand:VOID 0 "register_operand" "=d")
1706+ (call (mem (match_operand 1 "call_insn_plt_operand" ""))
1707+ (match_operand 2 "" "i")))
1708+ (clobber (match_operand 3 "register_operand" "=d"))
1709+ (use (match_operand 4 "register_operand"))]
1710+ "flag_pic && TARGET_MB_64"
1711+ {
1712+ register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1713+
1714+ gen_rtx_CLOBBER (VOIDmode,target2);
1715+ return "brealid\tr15,%1\;%#";
1716+ }
1717+ [(set_attr "type" "call")
1718+ (set_attr "mode" "none")
1719+ (set_attr "length" "4")])
1720+
1721 (define_insn "call_value_intern_plt"
1722 [(set (match_operand:VOID 0 "register_operand" "=d")
1723- (call (mem (match_operand:SI 1 "call_insn_plt_operand" ""))
1724- (match_operand:SI 2 "" "i")))
1725- (clobber (match_operand:SI 3 "register_operand" "=d"))
1726- (use (match_operand:SI 4 "register_operand"))]
1727+ (call (mem (match_operand 1 "call_insn_plt_operand" ""))
1728+ (match_operand 2 "" "i")))
1729+ (clobber (match_operand 3 "register_operand" "=d"))
1730+ (use (match_operand 4 "register_operand"))]
1731 "flag_pic"
1732 {
1733 rtx target2
1734@@ -2701,11 +2987,46 @@ else
1735 (set_attr "mode" "none")
1736 (set_attr "length" "4")])
1737
1738+(define_insn "call_value_intern_64"
1739+ [(set (match_operand:VOID 0 "register_operand" "=d")
1740+ (call (mem (match_operand:VOID 1 "call_insn_operand" "ri"))
1741+ (match_operand 2 "" "i")))
1742+ (clobber (match_operand 3 "register_operand" "=d"))]
1743+ "TARGET_MB_64"
1744+ {
1745+ register rtx target = operands[1];
1746+ register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
1747+
1748+ if (GET_CODE (target) == SYMBOL_REF)
1749+ {
1750+ gen_rtx_CLOBBER (VOIDmode,target2);
1751+ if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
1752+ return "breaki\tr16,%1\;%#";
1753+ else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
1754+ {
1755+ return "brealid\tr15,%1\;%#";
1756+ }
1757+ else
1758+ {
1759+ return "bralid\tr15,%1\;%#";
1760+ }
1761+ }
1762+ else if (GET_CODE (target) == CONST_INT)
1763+ return "la\t%@,r0,%1\;brald\tr15,%@\;%#";
1764+ else if (GET_CODE (target) == REG)
1765+ return "brald\tr15,%1\;%#";
1766+ else
1767+ return "Unsupported call insn\n";
1768+ }
1769+ [(set_attr "type" "call")
1770+ (set_attr "mode" "none")
1771+ (set_attr "length" "4")])
1772+
1773 (define_insn "call_value_intern"
1774 [(set (match_operand:VOID 0 "register_operand" "=d")
1775 (call (mem (match_operand:VOID 1 "call_insn_operand" "ri"))
1776- (match_operand:SI 2 "" "i")))
1777- (clobber (match_operand:SI 3 "register_operand" "=d"))]
1778+ (match_operand 2 "" "i")))
1779+ (clobber (match_operand 3 "register_operand" "=d"))]
1780 ""
1781 {
1782 rtx target = operands[1];
1783diff --git a/gcc/config/microblaze/t-microblaze b/gcc/config/microblaze/t-microblaze
1784index 4c25cfe15e7..965132b3513 100644
1785--- a/gcc/config/microblaze/t-microblaze
1786+++ b/gcc/config/microblaze/t-microblaze
1787@@ -2,7 +2,8 @@ MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high mlittle-en
1788 MULTILIB_DIRNAMES = bs m mh le m64
1789 MULTILIB_EXCEPTIONS = *mxl-barrel-shift/mxl-multiply-high mxl-multiply-high
1790 MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian
1791-MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64
1792+MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian/m64
1793+MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64 mxl-multiply-high
1794 MULTILIB_EXCEPTIONS += mxl-multiply-high/mlittle-endian
1795 MULTILIB_EXCEPTIONS += mxl-multiply-high/m64
1796 MULTILIB_EXCEPTIONS += *mxl-multiply-high/mlittle-endian/m64
1797diff --git a/libgcc/config/microblaze/crti.S b/libgcc/config/microblaze/crti.S
1798index 0f24adb750d..1a89a0a2ffa 100644
1799--- a/libgcc/config/microblaze/crti.S
1800+++ b/libgcc/config/microblaze/crti.S
1801@@ -40,7 +40,7 @@
1802
1803 .align 2
1804 __init:
1805- addik r1, r1, -8
1806+ addik r1, r1, -16
1807 sw r15, r0, r1
1808 la r11, r0, _stack
1809 mts rshr, r11
1810@@ -51,5 +51,5 @@ __init:
1811 .global __fini
1812 .align 2
1813 __fini:
1814- addik r1, r1, -8
1815+ addik r1, r1, -16
1816 sw r15, r0, r1
1817diff --git a/libgcc/config/microblaze/crtn.S b/libgcc/config/microblaze/crtn.S
1818index d38d7ab9f98..29a004973ae 100644
1819--- a/libgcc/config/microblaze/crtn.S
1820+++ b/libgcc/config/microblaze/crtn.S
1821@@ -33,9 +33,9 @@
1822 .section .init, "ax"
1823 lw r15, r0, r1
1824 rtsd r15, 8
1825- addik r1, r1, 8
1826+ addik r1, r1, 16
1827
1828 .section .fini, "ax"
1829 lw r15, r0, r1
1830 rtsd r15, 8
1831- addik r1, r1, 8
1832+ addik r1, r1, 16
1833diff --git a/libgcc/config/microblaze/divdi3.S b/libgcc/config/microblaze/divdi3.S
1834new file mode 100644
1835index 00000000000..d37bf5165c6
1836--- /dev/null
1837+++ b/libgcc/config/microblaze/divdi3.S
1838@@ -0,0 +1,98 @@
1839+###################################-
1840+#
1841+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
1842+#
1843+# Contributed by Michael Eager <eager@eagercon.com>.
1844+#
1845+# This file is free software; you can redistribute it and/or modify it
1846+# under the terms of the GNU General Public License as published by the
1847+# Free Software Foundation; either version 3, or (at your option) any
1848+# later version.
1849+#
1850+# GCC is distributed in the hope that it will be useful, but WITHOUT
1851+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1852+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1853+# License for more details.
1854+#
1855+# Under Section 7 of GPL version 3, you are granted additional
1856+# permissions described in the GCC Runtime Library Exception, version
1857+# 3.1, as published by the Free Software Foundation.
1858+#
1859+# You should have received a copy of the GNU General Public License and
1860+# a copy of the GCC Runtime Library Exception along with this program;
1861+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1862+# <http://www.gnu.org/licenses/>.
1863+#
1864+# divdi3.S
1865+#
1866+# Divide operation for 32 bit integers.
1867+# Input : Dividend in Reg r5
1868+# Divisor in Reg r6
1869+# Output: Result in Reg r3
1870+#
1871+#######################################
1872+
1873+#ifdef __arch64__
1874+ .globl __divdi3
1875+ .ent __divdi3
1876+ .type __divdi3,@function
1877+__divdi3:
1878+ .frame r1,0,r15
1879+
1880+ ADDLIK r1,r1,-32
1881+ SLI r28,r1,0
1882+ SLI r29,r1,8
1883+ SLI r30,r1,16
1884+ SLI r31,r1,24
1885+
1886+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
1887+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
1888+ XORL r28,r5,r6 # Get the sign of the result
1889+ BEALGEI r5,$LaR5_Pos
1890+ RSUBLI r5,r5,0 # Make r5 positive
1891+$LaR5_Pos:
1892+ BEALGEI r6,$LaR6_Pos
1893+ RSUBLI r6,r6,0 # Make r6 positive
1894+$LaR6_Pos:
1895+ ADDLIK r30,r0,0 # Clear mod
1896+ ADDLIK r3,r0,0 # clear div
1897+ ADDLIK r29,r0,64 # Initialize the loop count
1898+
1899+ # First part try to find the first '1' in the r5
1900+$LaDIV0:
1901+ BEALLTI r5,$LaDIV2 # This traps r5 == 0x80000000
1902+$LaDIV1:
1903+ ADDL r5,r5,r5 # left shift logical r5
1904+ ADDLIK r29,r29,-1
1905+ BEALGTI r5,$LaDIV1
1906+$LaDIV2:
1907+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
1908+ ADDLC r30,r30,r30 # Move that bit into the Mod register
1909+ RSUBL r31,r6,r30 # Try to subtract (r30 a r6)
1910+ BEALLTI r31,$LaMOD_TOO_SMALL
1911+ ORL r30,r0,r31 # Move the r31 to mod since the result was positive
1912+ ADDLIK r3,r3,1
1913+$LaMOD_TOO_SMALL:
1914+ ADDLIK r29,r29,-1
1915+ BEALEQi r29,$LaLOOP_END
1916+ ADDL r3,r3,r3 # Shift in the '1' into div
1917+ BREAI $LaDIV2 # Div2
1918+$LaLOOP_END:
1919+ BEALGEI r28,$LaRETURN_HERE
1920+ RSUBLI r3,r3,0 # Negate the result
1921+ BREAI $LaRETURN_HERE
1922+$LaDiv_By_Zero:
1923+$LaResult_Is_Zero:
1924+ ORL r3,r0,r0 # set result to 0
1925+$LaRETURN_HERE:
1926+# Restore values of CSRs and that of r3 and the divisor and the dividend
1927+ LLI r28,r1,0
1928+ LLI r29,r1,8
1929+ LLI r30,r1,16
1930+ LLI r31,r1,24
1931+ ADDLIK r1,r1,32
1932+ RTSD r15,8
1933+ nop
1934+.end __divdi3
1935+ .size __divdi3, . - __divdi3
1936+#endif
1937diff --git a/libgcc/config/microblaze/divdi3_table.c b/libgcc/config/microblaze/divdi3_table.c
1938new file mode 100644
1939index 00000000000..80962597ea5
1940--- /dev/null
1941+++ b/libgcc/config/microblaze/divdi3_table.c
1942@@ -0,0 +1,62 @@
1943+/* Table for software lookup divide for Xilinx MicroBlaze.
1944+
1945+ Copyright (C) 2009-2017 Free Software Foundation, Inc.
1946+
1947+ Contributed by Michael Eager <eager@eagercon.com>.
1948+
1949+ This file is free software; you can redistribute it and/or modify it
1950+ under the terms of the GNU General Public License as published by the
1951+ Free Software Foundation; either version 3, or (at your option) any
1952+ later version.
1953+
1954+ GCC is distributed in the hope that it will be useful, but WITHOUT
1955+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1956+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1957+ License for more details.
1958+
1959+ Under Section 7 of GPL version 3, you are granted additional
1960+ permissions described in the GCC Runtime Library Exception, version
1961+ 3.1, as published by the Free Software Foundation.
1962+
1963+ You should have received a copy of the GNU General Public License and
1964+ a copy of the GCC Runtime Library Exception along with this program;
1965+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1966+ <http://www.gnu.org/licenses/>. */
1967+
1968+
1969+unsigned char _divdi3_table[] =
1970+{
1971+ 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7,
1972+ 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
1973+ 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7,
1974+ 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
1975+ 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7,
1976+ 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
1977+ 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7,
1978+ 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
1979+ 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7,
1980+ 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
1981+ 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7,
1982+ 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
1983+ 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7,
1984+ 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
1985+ 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7,
1986+ 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
1987+ 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7,
1988+ 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
1989+ 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7,
1990+ 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
1991+ 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7,
1992+ 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
1993+ 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7,
1994+ 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
1995+ 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7,
1996+ 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
1997+ 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7,
1998+ 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
1999+ 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7,
2000+ 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
2001+ 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7,
2002+ 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
2003+};
2004+
2005diff --git a/libgcc/config/microblaze/moddi3.S b/libgcc/config/microblaze/moddi3.S
2006new file mode 100644
2007index 00000000000..5d3f7c03fc8
2008--- /dev/null
2009+++ b/libgcc/config/microblaze/moddi3.S
2010@@ -0,0 +1,97 @@
2011+###################################
2012+#
2013+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2014+#
2015+# Contributed by Michael Eager <eager@eagercon.com>.
2016+#
2017+# This file is free software; you can redistribute it and/or modify it
2018+# under the terms of the GNU General Public License as published by the
2019+# Free Software Foundation; either version 3, or (at your option) any
2020+# later version.
2021+#
2022+# GCC is distributed in the hope that it will be useful, but WITHOUT
2023+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2024+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2025+# License for more details.
2026+#
2027+# Under Section 7 of GPL version 3, you are granted additional
2028+# permissions described in the GCC Runtime Library Exception, version
2029+# 3.1, as published by the Free Software Foundation.
2030+#
2031+# You should have received a copy of the GNU General Public License and
2032+# a copy of the GCC Runtime Library Exception along with this program;
2033+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2034+# <http://www.gnu.org/licenses/>.
2035+#
2036+# moddi3.S
2037+#
2038+# modulo operation for 32 bit integers.
2039+# Input : op1 in Reg r5
2040+# op2 in Reg r6
2041+# Output: op1 mod op2 in Reg r3
2042+#
2043+#######################################
2044+
2045+#ifdef __arch64__
2046+ .globl __moddi3
2047+ .ent __moddi3
2048+ .type __moddi3,@function
2049+__moddi3:
2050+ .frame r1,0,r15
2051+
2052+ addlik r1,r1,-32
2053+ sli r28,r1,0
2054+ sli r29,r1,8
2055+ sli r30,r1,16
2056+ sli r31,r1,32
2057+
2058+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2059+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2060+ ADDL r28,r5,r0 # Get the sign of the result [ Depends only on the first arg]
2061+ BEALGEI r5,$LaR5_Pos
2062+ RSUBLI r5,r5,0 # Make r5 positive
2063+$LaR5_Pos:
2064+ BEALGEI r6,$LaR6_Pos
2065+ RSUBLI r6,r6,0 # Make r6 positive
2066+$LaR6_Pos:
2067+ ADDLIK r3,r0,0 # Clear mod
2068+ ADDLIK r30,r0,0 # clear div
2069+ ADDLIK r29,r0,64 # Initialize the loop count
2070+ BEALLTI r5,$LaDIV2 # If r5 is still negative (0x80000000), skip
2071+ # the first bit search.
2072+ # First part try to find the first '1' in the r5
2073+$LaDIV1:
2074+ ADDL r5,r5,r5 # left shift logical r5
2075+ ADDLIK r29,r29,-1
2076+ BEALGEI r5,$LaDIV1 #
2077+$LaDIV2:
2078+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2079+ ADDLC r3,r3,r3 # Move that bit into the Mod register
2080+ rSUBL r31,r6,r3 # Try to subtract (r30 a r6)
2081+ BEALLTi r31,$LaMOD_TOO_SMALL
2082+ ORL r3,r0,r31 # Move the r31 to mod since the result was positive
2083+ ADDLIK r30,r30,1
2084+$LaMOD_TOO_SMALL:
2085+ ADDLIK r29,r29,-1
2086+ BEALEQi r29,$LaLOOP_END
2087+ ADDL r30,r30,r30 # Shift in the '1' into div
2088+ BREAI $LaDIV2 # Div2
2089+$LaLOOP_END:
2090+ BEALGEI r28,$LaRETURN_HERE
2091+ rsubli r3,r3,0 # Negate the result
2092+ BREAI $LaRETURN_HERE
2093+$LaDiv_By_Zero:
2094+$LaResult_Is_Zero:
2095+ orl r3,r0,r0 # set result to 0 [Both mod as well as div are 0]
2096+$LaRETURN_HERE:
2097+# Restore values of CSRs and that of r3 and the divisor and the dividend
2098+ lli r28,r1,0
2099+ lli r29,r1,8
2100+ lli r30,r1,16
2101+ lli r31,r1,24
2102+ addlik r1,r1,32
2103+ rtsd r15,8
2104+ nop
2105+ .end __moddi3
2106+ .size __moddi3, . - __moddi3
2107+#endif
2108diff --git a/libgcc/config/microblaze/muldi3.S b/libgcc/config/microblaze/muldi3.S
2109new file mode 100644
2110index 00000000000..567784197d3
2111--- /dev/null
2112+++ b/libgcc/config/microblaze/muldi3.S
2113@@ -0,0 +1,73 @@
2114+/*###################################-*-asm*-
2115+#
2116+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2117+#
2118+# Contributed by Michael Eager <eager@eagercon.com>.
2119+#
2120+# This file is free software; you can redistribute it and/or modify it
2121+# under the terms of the GNU General Public License as published by the
2122+# Free Software Foundation; either version 3, or (at your option) any
2123+# later version.
2124+#
2125+# GCC is distributed in the hope that it will be useful, but WITHOUT
2126+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2127+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2128+# License for more details.
2129+#
2130+# Under Section 7 of GPL version 3, you are granted additional
2131+# permissions described in the GCC Runtime Library Exception, version
2132+# 3.1, as published by the Free Software Foundation.
2133+#
2134+# You should have received a copy of the GNU General Public License and
2135+# a copy of the GCC Runtime Library Exception along with this program;
2136+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2137+# <http://www.gnu.org/licenses/>.
2138+#
2139+# muldi3.S
2140+#
2141+# Multiply operation for 32 bit integers.
2142+# Input : Operand1 in Reg r5
2143+# Operand2 in Reg r6
2144+# Output: Result [op1 * op2] in Reg r3
2145+#
2146+#######################################*/
2147+
2148+#ifdef __arch64__
2149+ .globl __muldi3
2150+ .ent __muldi3
2151+ .type __muldi3,@function
2152+__muldi3:
2153+ .frame r1,0,r15
2154+ addl r3,r0,r0
2155+ BEALEQI r5,$L_Result_Is_Zero # Multiply by Zero
2156+ BEALEQI r6,$L_Result_Is_Zero # Multiply by Zero
2157+ XORL r4,r5,r6 # Get the sign of the result
2158+ BEALGEI r5,$L_R5_Pos
2159+ RSUBLI r5,r5,0 # Make r5 positive
2160+$L_R5_Pos:
2161+ BEALGEI r6,$L_R6_Pos
2162+ RSUBLI r6,r6,0 # Make r6 positive
2163+$L_R6_Pos:
2164+ breai $L1
2165+$L2:
2166+ addl r5,r5,r5
2167+$L1:
2168+ srll r6,r6
2169+ addlc r7,r0,r0
2170+ bealeqi r7,$L2
2171+ addl r3,r3,r5
2172+ bealnei r6,$L2
2173+ beallti r4,$L_NegateResult
2174+ rtsd r15,8
2175+ nop
2176+$L_NegateResult:
2177+ rsubl r3,r3,r0
2178+ rtsd r15,8
2179+ nop
2180+$L_Result_Is_Zero:
2181+ addli r3,r0,0
2182+ rtsd r15,8
2183+ nop
2184+ .end __muldi3
2185+ .size __muldi3, . - __muldi3
2186+#endif
2187diff --git a/libgcc/config/microblaze/t-microblaze b/libgcc/config/microblaze/t-microblaze
2188index 8d954a49575..35021b24b7d 100644
2189--- a/libgcc/config/microblaze/t-microblaze
2190+++ b/libgcc/config/microblaze/t-microblaze
2191@@ -1,11 +1,16 @@
2192-LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _mulsi3 _udivsi3 _umodsi3
2193+LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _mulsi3 _udivsi3 _umodsi3 \
2194+ _divdi3 _moddi3 _muldi3 _udivdi3 _umoddi3
2195
2196 LIB2ADD += \
2197 $(srcdir)/config/microblaze/divsi3.S \
2198+ $(srcdir)/config/microblaze/divdi3.S \
2199 $(srcdir)/config/microblaze/modsi3.S \
2200- $(srcdir)/config/microblaze/muldi3_hard.S \
2201+ $(srcdir)/config/microblaze/moddi3.S \
2202 $(srcdir)/config/microblaze/mulsi3.S \
2203+ $(srcdir)/config/microblaze/muldi3.S \
2204 $(srcdir)/config/microblaze/stack_overflow_exit.S \
2205 $(srcdir)/config/microblaze/udivsi3.S \
2206+ $(srcdir)/config/microblaze/udivdi3.S \
2207 $(srcdir)/config/microblaze/umodsi3.S \
2208- $(srcdir)/config/microblaze/divsi3_table.c
2209+ $(srcdir)/config/microblaze/umoddi3.S \
2210+ $(srcdir)/config/microblaze/divsi3_table.c \
2211diff --git a/libgcc/config/microblaze/udivdi3.S b/libgcc/config/microblaze/udivdi3.S
2212new file mode 100644
2213index 00000000000..c210fbc7128
2214--- /dev/null
2215+++ b/libgcc/config/microblaze/udivdi3.S
2216@@ -0,0 +1,107 @@
2217+###################################-
2218+#
2219+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2220+#
2221+# Contributed by Michael Eager <eager@eagercon.com>.
2222+#
2223+# This file is free software; you can redistribute it and/or modify it
2224+# under the terms of the GNU General Public License as published by the
2225+# Free Software Foundation; either version 3, or (at your option) any
2226+# later version.
2227+#
2228+# GCC is distributed in the hope that it will be useful, but WITHOUT
2229+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2230+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2231+# License for more details.
2232+#
2233+# Under Section 7 of GPL version 3, you are granted additional
2234+# permissions described in the GCC Runtime Library Exception, version
2235+# 3.1, as published by the Free Software Foundation.
2236+#
2237+# You should have received a copy of the GNU General Public License and
2238+# a copy of the GCC Runtime Library Exception along with this program;
2239+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2240+# <http://www.gnu.org/licenses/>.
2241+#
2242+# udivdi3.S
2243+#
2244+# Unsigned divide operation.
2245+# Input : Divisor in Reg r5
2246+# Dividend in Reg r6
2247+# Output: Result in Reg r3
2248+#
2249+#######################################
2250+
2251+#ifdef __arch64__
2252+ .globl __udivdi3
2253+ .ent __udivdi3
2254+ .type __udivdi3,@function
2255+__udivdi3:
2256+ .frame r1,0,r15
2257+
2258+ ADDlIK r1,r1,-24
2259+ SLI r29,r1,0
2260+ SLI r30,r1,8
2261+ SLI r31,r1,16
2262+
2263+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2264+ ADDLIK r30,r0,0 # Clear mod
2265+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2266+ ADDLIK r29,r0,64 # Initialize the loop count
2267+
2268+ # Check if r6 and r5 are equal # if yes, return 1
2269+ RSUBL r18,r5,r6
2270+ ADDLIK r3,r0,1
2271+ BEALEQI r18,$LaRETURN_HERE
2272+
2273+ # Check if (uns)r6 is greater than (uns)r5. In that case, just return 0
2274+ XORL r18,r5,r6
2275+ ADDL r3,r0,r0 # We would anyways clear r3
2276+ BEALGEI r18,$LRSUBL
2277+ BEALLTI r6,$LaRETURN_HERE # r6[bit 31 = 1] hence is greater
2278+ BREAI $LCheckr6
2279+$LRSUBL:
2280+ RSUBL r18,r6,r5 # MICROBLAZEcmp
2281+ BEALLTI r18,$LaRETURN_HERE
2282+
2283+ # If r6 [bit 31] is set, then return result as 1
2284+$LCheckr6:
2285+ BEALGTI r6,$LaDIV0
2286+ ADDLIK r3,r0,1
2287+ BREAI $LaRETURN_HERE
2288+
2289+ # First part try to find the first '1' in the r5
2290+$LaDIV0:
2291+ BEALLTI r5,$LaDIV2
2292+$LaDIV1:
2293+ ADDL r5,r5,r5 # left shift logical r5
2294+ ADDLIK r29,r29,-1
2295+ BEALGTI r5,$LaDIV1
2296+$LaDIV2:
2297+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2298+ ADDLC r30,r30,r30 # Move that bit into the Mod register
2299+ RSUBL r31,r6,r30 # Try to subtract (r30 a r6)
2300+ BEALLTI r31,$LaMOD_TOO_SMALL
2301+ ORL r30,r0,r31 # Move the r31 to mod since the result was positive
2302+ ADDLIK r3,r3,1
2303+$LaMOD_TOO_SMALL:
2304+ ADDLIK r29,r29,-1
2305+ BEALEQi r29,$LaLOOP_END
2306+ ADDL r3,r3,r3 # Shift in the '1' into div
2307+ BREAI $LaDIV2 # Div2
2308+$LaLOOP_END:
2309+ BREAI $LaRETURN_HERE
2310+$LaDiv_By_Zero:
2311+$LaResult_Is_Zero:
2312+ ORL r3,r0,r0 # set result to 0
2313+$LaRETURN_HERE:
2314+ # Restore values of CSRs and that of r3 and the divisor and the dividend
2315+ LLI r29,r1,0
2316+ LLI r30,r1,8
2317+ LLI r31,r1,16
2318+ ADDLIK r1,r1,24
2319+ RTSD r15,8
2320+ NOP
2321+ .end __udivdi3
2322+ .size __udivdi3, . - __udivdi3
2323+#endif
2324diff --git a/libgcc/config/microblaze/umoddi3.S b/libgcc/config/microblaze/umoddi3.S
2325new file mode 100644
2326index 00000000000..7f5cd23f9a1
2327--- /dev/null
2328+++ b/libgcc/config/microblaze/umoddi3.S
2329@@ -0,0 +1,110 @@
2330+###################################
2331+#
2332+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
2333+#
2334+# Contributed by Michael Eager <eager@eagercon.com>.
2335+#
2336+# This file is free software; you can redistribute it and/or modify it
2337+# under the terms of the GNU General Public License as published by the
2338+# Free Software Foundation; either version 3, or (at your option) any
2339+# later version.
2340+#
2341+# GCC is distributed in the hope that it will be useful, but WITHOUT
2342+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2343+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2344+# License for more details.
2345+#
2346+# Under Section 7 of GPL version 3, you are granted additional
2347+# permissions described in the GCC Runtime Library Exception, version
2348+# 3.1, as published by the Free Software Foundation.
2349+#
2350+# You should have received a copy of the GNU General Public License and
2351+# a copy of the GCC Runtime Library Exception along with this program;
2352+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2353+# <http://www.gnu.org/licenses/>.
2354+#
2355+# umoddi3.S
2356+#
2357+# Unsigned modulo operation for 32 bit integers.
2358+# Input : op1 in Reg r5
2359+# op2 in Reg r6
2360+# Output: op1 mod op2 in Reg r3
2361+#
2362+#######################################
2363+
2364+#ifdef __arch64__
2365+ .globl __umoddi3
2366+ .ent __umoddi3
2367+ .type __umoddi3,@function
2368+__umoddi3:
2369+ .frame r1,0,r15
2370+
2371+ addlik r1,r1,-24
2372+ sli r29,r1,0
2373+ sli r30,r1,8
2374+ sli r31,r1,16
2375+
2376+ BEALEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error
2377+ ADDLIK r3,r0,0 # Clear div
2378+ BEALEQI r5,$LaResult_Is_Zero # Result is Zero
2379+ ADDLIK r30,r0,0 # clear mod
2380+ ADDLIK r29,r0,64 # Initialize the loop count
2381+
2382+# Check if r6 and r5 are equal # if yes, return 0
2383+ rsubl r18,r5,r6
2384+ bealeqi r18,$LaRETURN_HERE
2385+
2386+# Check if (uns)r6 is greater than (uns)r5. In that case, just return r5
2387+ xorl r18,r5,r6
2388+ addlik r3,r5,0
2389+ bealgei r18,$LRSUB
2390+ beallti r6,$LaRETURN_HERE
2391+ breai $LCheckr6
2392+$LRSUB:
2393+ rsubl r18,r5,r6 # MICROBLAZEcmp
2394+ bealgti r18,$LaRETURN_HERE
2395+
2396+# If r6 [bit 31] is set, then return result as r5-r6
2397+$LCheckr6:
2398+ addlik r3,r0,0
2399+ bealgti r6,$LaDIV0
2400+ addlik r18,r0,0x7fffffff
2401+ andl r5,r5,r18
2402+ andl r6,r6,r18
2403+ breaid $LaRETURN_HERE
2404+ rsubl r3,r6,r5
2405+# First part: try to find the first '1' in the r5
2406+$LaDIV0:
2407+ BEALLTI r5,$LaDIV2
2408+$LaDIV1:
2409+ ADDL r5,r5,r5 # left shift logical r5
2410+ ADDLIK r29,r29,-1
2411+ BEALGEI r5,$LaDIV1 #
2412+$LaDIV2:
2413+ ADDL r5,r5,r5 # left shift logical r5 get the '1' into the Carry
2414+ ADDLC r3,r3,r3 # Move that bit into the Mod register
2415+ rSUBL r31,r6,r3 # Try to subtract (r3 a r6)
2416+ BEALLTi r31,$LaMOD_TOO_SMALL
2417+ ORL r3,r0,r31 # Move the r31 to mod since the result was positive
2418+ ADDLIK r30,r30,1
2419+$LaMOD_TOO_SMALL:
2420+ ADDLIK r29,r29,-1
2421+ BEALEQi r29,$LaLOOP_END
2422+ ADDL r30,r30,r30 # Shift in the '1' into div
2423+ BREAI $LaDIV2 # Div2
2424+$LaLOOP_END:
2425+ BREAI $LaRETURN_HERE
2426+$LaDiv_By_Zero:
2427+$LaResult_Is_Zero:
2428+ orl r3,r0,r0 # set result to 0
2429+$LaRETURN_HERE:
2430+# Restore values of CSRs and that of r3 and the divisor and the dividend
2431+ lli r29,r1,0
2432+ lli r30,r1,8
2433+ lli r31,r1,16
2434+ addlik r1,r1,24
2435+ rtsd r15,8
2436+ nop
2437+.end __umoddi3
2438+ .size __umoddi3, . - __umoddi3
2439+#endif
2440--
24412.34.1
2442