]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/or1k/or1k.c
Use function_arg_info for TARGET_FUNCTION_(INCOMING_)ARG
[thirdparty/gcc.git] / gcc / config / or1k / or1k.c
1 /* Target Code for OpenRISC
2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
3 Contributed by Stafford Horne based on other ports.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #define IN_TARGET_CODE 1
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32 #include "df.h"
33 #include "regs.h"
34 #include "memmodel.h"
35 #include "emit-rtl.h"
36 #include "diagnostic-core.h"
37 #include "output.h"
38 #include "stor-layout.h"
39 #include "varasm.h"
40 #include "calls.h"
41 #include "expr.h"
42 #include "builtins.h"
43 #include "optabs.h"
44 #include "explow.h"
45 #include "cfgrtl.h"
46 #include "alias.h"
47
48 /* These 4 are needed to allow using satisfies_constraint_J. */
49 #include "insn-config.h"
50 #include "recog.h"
51 #include "tm_p.h"
52 #include "tm-constrs.h"
53
54 /* This file should be included last. */
55 #include "target-def.h"
56
57 /* Per-function machine data. */
58 struct GTY(()) machine_function
59 {
60 /* Number of bytes saved on the stack for callee saved registers. */
61 HOST_WIDE_INT callee_saved_reg_size;
62
63 /* Number of bytes saved on the stack for local variables. */
64 HOST_WIDE_INT local_vars_size;
65
66 /* Number of bytes saved on the stack for outgoing/sub-function args. */
67 HOST_WIDE_INT args_size;
68
69 /* The sum of sizes: locals vars, called saved regs, stack pointer
70 and an optional frame pointer.
71 Used in expand_prologue () and expand_epilogue (). */
72 HOST_WIDE_INT total_size;
73
74 /* Remember where the set_got_placeholder is located. */
75 rtx_insn *set_got_insn;
76 };
77
78 /* Zero initialization is OK for all current fields. */
79
80 static struct machine_function *
81 or1k_init_machine_status (void)
82 {
83 return ggc_cleared_alloc<machine_function> ();
84 }
85
86
87 /* Worker for TARGET_OPTION_OVERRIDE.
88 We currently only use this to setup init_machine_status. */
89
90 static void
91 or1k_option_override (void)
92 {
93 /* Set the per-function-data initializer. */
94 init_machine_status = or1k_init_machine_status;
95 }
96
97 /* Returns true if REGNO must be saved for the current function. */
98
99 static bool
100 callee_saved_regno_p (int regno)
101 {
102 /* Check call-saved registers. */
103 if (!call_used_regs[regno] && df_regs_ever_live_p (regno))
104 return true;
105
106 switch (regno)
107 {
108 case HARD_FRAME_POINTER_REGNUM:
109 return frame_pointer_needed;
110
111 case LR_REGNUM:
112 /* Always save LR if we are saving HFP, producing a walkable
113 stack chain with -fno-omit-frame-pointer. */
114 return (frame_pointer_needed
115 || !crtl->is_leaf
116 || crtl->uses_pic_offset_table
117 || df_regs_ever_live_p (regno));
118
119 case HW_TO_GCC_REGNO (25):
120 case HW_TO_GCC_REGNO (27):
121 case HW_TO_GCC_REGNO (29):
122 case HW_TO_GCC_REGNO (31):
123 /* See EH_RETURN_DATA_REGNO. */
124 return crtl->calls_eh_return;
125
126 default:
127 return false;
128 }
129 }
130
131 /* Worker for TARGET_COMPUTE_FRAME_LAYOUT.
132 Compute and populate machine specific function attributes which are globally
133 accessible via cfun->machine. These include the sizes needed for
134 stack stored local variables, callee saved registers and space for stack
135 arguments which may be passed to a next function. The values are used for
136 the epilogue, prologue and eliminations.
137
138 OpenRISC stack grows downwards and contains:
139
140 ---- previous frame --------
141 current func arg[n]
142 current func arg[0] <-- r2 [HFP,AP]
143 ---- current stack frame --- ^ ---\
144 return address r9 | |
145 old frame pointer r2 (+) |-- machine->total_size
146 callee saved regs | | > machine->callee_saved_reg_size
147 local variables | | > machine->local_vars_size <-FP
148 next function args <-- r1 [SP]---/ > machine->args_size
149 ---------------------------- |
150 (-)
151 (future) |
152 V
153
154 All of these contents are optional. */
155
156 static void
157 or1k_compute_frame_layout (void)
158 {
159 HOST_WIDE_INT local_vars_size, args_size, save_reg_size;
160
161 local_vars_size = get_frame_size ();
162 local_vars_size = ROUND_UP (local_vars_size, UNITS_PER_WORD);
163
164 args_size = crtl->outgoing_args_size;
165 args_size = ROUND_UP (args_size, UNITS_PER_WORD);
166
167 save_reg_size = 0;
168 for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
169 if (callee_saved_regno_p (regno))
170 save_reg_size += UNITS_PER_WORD;
171
172 cfun->machine->local_vars_size = local_vars_size;
173 cfun->machine->args_size = args_size;
174 cfun->machine->callee_saved_reg_size = save_reg_size;
175 cfun->machine->total_size = save_reg_size + local_vars_size + args_size;
176 }
177
178 /* Emit rtl to save register REGNO contents to stack memory at the given OFFSET
179 from the current stack pointer. */
180
181 static void
182 or1k_save_reg (int regno, HOST_WIDE_INT offset)
183 {
184 rtx reg = gen_rtx_REG (Pmode, regno);
185 rtx mem = gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx,
186 offset));
187 rtx insn = emit_move_insn (mem, reg);
188 RTX_FRAME_RELATED_P (insn) = 1;
189 }
190
191 /* Emit rtl to restore register REGNO contents from stack memory at the given
192 OFFSET from the current stack pointer. */
193
194 static rtx
195 or1k_restore_reg (int regno, HOST_WIDE_INT offset, rtx cfa_restores)
196 {
197 rtx reg = gen_rtx_REG (Pmode, regno);
198 rtx mem = gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx,
199 offset));
200 emit_move_insn (reg, mem);
201 return alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
202 }
203
204 /* Expand the "prologue" pattern. */
205
206 void
207 or1k_expand_prologue (void)
208 {
209 HOST_WIDE_INT sp_offset = -cfun->machine->total_size;
210 HOST_WIDE_INT reg_offset, this_offset;
211 rtx insn;
212
213 if (flag_stack_usage_info)
214 current_function_static_stack_size = -sp_offset;
215
216 /* Early exit for frameless functions. */
217 if (sp_offset == 0)
218 goto fini;
219
220 /* Adjust the stack pointer. For large stack offsets we will
221 do this in multiple parts, before and after saving registers. */
222 reg_offset = (sp_offset + cfun->machine->local_vars_size
223 + cfun->machine->args_size);
224 this_offset = MAX (sp_offset, -32764);
225 reg_offset -= this_offset;
226 sp_offset -= this_offset;
227
228 insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
229 GEN_INT (this_offset)));
230 RTX_FRAME_RELATED_P (insn) = 1;
231
232 /* Save callee-saved registers. */
233 for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
234 if (regno != HARD_FRAME_POINTER_REGNUM
235 && regno != LR_REGNUM
236 && callee_saved_regno_p (regno))
237 {
238 or1k_save_reg (regno, reg_offset);
239 reg_offset += UNITS_PER_WORD;
240 }
241
242 /* Save and update frame pointer. */
243 if (callee_saved_regno_p (HARD_FRAME_POINTER_REGNUM))
244 {
245 or1k_save_reg (HARD_FRAME_POINTER_REGNUM, reg_offset);
246 if (frame_pointer_needed)
247 {
248 insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
249 stack_pointer_rtx,
250 GEN_INT (-this_offset)));
251 RTX_FRAME_RELATED_P (insn) = 1;
252 }
253 reg_offset += UNITS_PER_WORD;
254 }
255
256 /* Save the link register. */
257 if (callee_saved_regno_p (LR_REGNUM))
258 {
259 or1k_save_reg (LR_REGNUM, reg_offset);
260 reg_offset += UNITS_PER_WORD;
261 }
262 gcc_assert (reg_offset + this_offset == 0);
263
264 /* Allocate the rest of the stack frame, if any. */
265 if (sp_offset != 0)
266 {
267 if (sp_offset < 2 * -32768)
268 {
269 /* For very large offsets, we need a temporary register. */
270 rtx tmp = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
271 emit_move_insn (tmp, GEN_INT (sp_offset));
272 insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
273 stack_pointer_rtx, tmp));
274 if (!frame_pointer_needed)
275 {
276 RTX_FRAME_RELATED_P (insn) = 1;
277 add_reg_note (insn, REG_CFA_ADJUST_CFA,
278 gen_rtx_SET (stack_pointer_rtx,
279 plus_constant (Pmode,
280 stack_pointer_rtx,
281 sp_offset)));
282 }
283 }
284 else
285 {
286 /* Otherwise, emit one or two sequential subtracts. */
287 do
288 {
289 this_offset = MAX (sp_offset, -32768);
290 sp_offset -= this_offset;
291
292 insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
293 stack_pointer_rtx,
294 GEN_INT (this_offset)));
295 if (!frame_pointer_needed)
296 RTX_FRAME_RELATED_P (insn) = 1;
297 }
298 while (sp_offset != 0);
299 }
300 }
301
302 fini:
303 /* Fix up, or remove, the insn that initialized the pic register. */
304 rtx_insn *set_got_insn = cfun->machine->set_got_insn;
305 if (crtl->uses_pic_offset_table)
306 {
307 rtx reg = SET_DEST (PATTERN (set_got_insn));
308 rtx_insn *insn = emit_insn_before (gen_set_got (reg), set_got_insn);
309 RTX_FRAME_RELATED_P (insn) = 1;
310 add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
311 }
312 delete_insn (set_got_insn);
313 }
314
315 /* Expand the "epilogue" pattern. */
316
317 void
318 or1k_expand_epilogue (void)
319 {
320 HOST_WIDE_INT reg_offset, sp_offset;
321 rtx insn, cfa_restores = NULL;
322
323 sp_offset = cfun->machine->total_size;
324 if (sp_offset == 0)
325 return;
326
327 reg_offset = cfun->machine->local_vars_size + cfun->machine->args_size;
328
329 if (sp_offset >= 32768 || cfun->calls_alloca)
330 {
331 /* The saved registers are out of range of the stack pointer.
332 We need to partially deallocate the stack frame now. */
333 if (frame_pointer_needed)
334 {
335 /* Reset the stack pointer to the bottom of the saved regs. */
336 sp_offset -= reg_offset;
337 reg_offset = 0;
338 insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
339 hard_frame_pointer_rtx,
340 GEN_INT (-sp_offset)));
341 RTX_FRAME_RELATED_P (insn) = 1;
342 add_reg_note (insn, REG_CFA_DEF_CFA,
343 plus_constant (Pmode, stack_pointer_rtx, sp_offset));
344 }
345 else if (sp_offset >= 3 * 32768)
346 {
347 /* For very large offsets, we need a temporary register. */
348 rtx tmp = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
349 emit_move_insn (tmp, GEN_INT (reg_offset));
350 insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
351 stack_pointer_rtx, tmp));
352 sp_offset -= reg_offset;
353 reg_offset = 0;
354 RTX_FRAME_RELATED_P (insn) = 1;
355 add_reg_note (insn, REG_CFA_DEF_CFA,
356 plus_constant (Pmode, stack_pointer_rtx, sp_offset));
357 }
358 else
359 {
360 /* Otherwise, emit one or two sequential additions. */
361 do
362 {
363 HOST_WIDE_INT this_offset = MIN (reg_offset, 32764);
364 reg_offset -= this_offset;
365 sp_offset -= this_offset;
366
367 insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
368 stack_pointer_rtx,
369 GEN_INT (this_offset)));
370 RTX_FRAME_RELATED_P (insn) = 1;
371 add_reg_note (insn, REG_CFA_DEF_CFA,
372 plus_constant (Pmode, stack_pointer_rtx,
373 sp_offset));
374 }
375 while (sp_offset >= 32768);
376 }
377 }
378
379 /* Restore callee-saved registers. */
380 for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
381 if (regno != HARD_FRAME_POINTER_REGNUM
382 && regno != LR_REGNUM
383 && callee_saved_regno_p (regno))
384 {
385 cfa_restores = or1k_restore_reg (regno, reg_offset, cfa_restores);
386 reg_offset += UNITS_PER_WORD;
387 }
388
389 /* Restore frame pointer. */
390 if (callee_saved_regno_p (HARD_FRAME_POINTER_REGNUM))
391 {
392 cfa_restores = or1k_restore_reg (HARD_FRAME_POINTER_REGNUM,
393 reg_offset, cfa_restores);
394 reg_offset += UNITS_PER_WORD;
395 }
396
397 /* Restore link register. */
398 if (callee_saved_regno_p (LR_REGNUM))
399 {
400 cfa_restores = or1k_restore_reg (LR_REGNUM, reg_offset, cfa_restores);
401 reg_offset += UNITS_PER_WORD;
402 }
403 gcc_assert (reg_offset == sp_offset);
404
405 /* Restore stack pointer. */
406 insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
407 GEN_INT (sp_offset)));
408 RTX_FRAME_RELATED_P (insn) = 1;
409 REG_NOTES (insn) = cfa_restores;
410 add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
411
412 /* Move up to the stack frame of an exception handler. */
413 if (crtl->calls_eh_return)
414 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
415 EH_RETURN_STACKADJ_RTX));
416 }
417
418 /* Worker for TARGET_INIT_PIC_REG.
419 Initialize the cfun->machine->set_got_insn rtx and insert it at the entry
420 of the current function. The rtx is just a temporary placeholder for
421 the GOT and will be replaced or removed during or1k_expand_prologue. */
422
423 static void
424 or1k_init_pic_reg (void)
425 {
426 start_sequence ();
427
428 cfun->machine->set_got_insn
429 = emit_insn (gen_set_got_tmp (pic_offset_table_rtx));
430
431 rtx_insn *seq = get_insns ();
432 end_sequence ();
433
434 edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
435 insert_insn_on_edge (seq, entry_edge);
436 commit_one_edge_insertion (entry_edge);
437 }
438
439 #undef TARGET_INIT_PIC_REG
440 #define TARGET_INIT_PIC_REG or1k_init_pic_reg
441 #undef TARGET_USE_PSEUDO_PIC_REG
442 #define TARGET_USE_PSEUDO_PIC_REG hook_bool_void_true
443
444 /* Worker for INITIAL_FRAME_ADDRESS_RTX.
445 Returns the RTX representing the address of the initial stack frame. */
446
447 rtx
448 or1k_initial_frame_addr ()
449 {
450 /* Use this to force a stack frame for the current function. */
451 crtl->accesses_prior_frames = 1;
452 return arg_pointer_rtx;
453 }
454
455 /* Worker for DYNAMIC_CHAIN_ADDRESS.
456 Returns the RTX representing the address of where the caller's frame pointer
457 may be stored on the stack. */
458
459 rtx
460 or1k_dynamic_chain_addr (rtx frame)
461 {
462 return plus_constant (Pmode, frame, -2 * UNITS_PER_WORD);
463 }
464
465 /* Worker for RETURN_ADDR_RTX.
466 Returns the RTX representing the address of where the link register may be
467 stored on the stack. */
468
469 rtx
470 or1k_return_addr (int, rtx frame)
471 {
472 return gen_frame_mem (Pmode, plus_constant (Pmode, frame, -UNITS_PER_WORD));
473 }
474
475 /* Worker for TARGET_FRAME_POINTER_REQUIRED.
476 Returns true if the current function must use a frame pointer. */
477
478 static bool
479 or1k_frame_pointer_required ()
480 {
481 /* ??? While IRA checks accesses_prior_frames, reload does not.
482 We do want the frame pointer for this case. */
483 return (crtl->accesses_prior_frames || crtl->profile);
484 }
485
486 /* Expand the "eh_return" pattern.
487 Used for defining __builtin_eh_return, this will emit RTX to override the
488 current function's return address stored on the stack. The emitted RTX is
489 inserted before the epilogue so we can't just update the link register.
490 This is used when handling exceptions to jump into the exception handler
491 catch block upon return from _Unwind_RaiseException. */
492
493 void
494 or1k_expand_eh_return (rtx eh_addr)
495 {
496 rtx lraddr;
497
498 lraddr = gen_frame_mem (Pmode, plus_constant (Pmode,
499 arg_pointer_rtx,
500 -UNITS_PER_WORD));
501 /* Set address to volatile to ensure the store doesn't get optimized out. */
502 MEM_VOLATILE_P (lraddr) = true;
503 emit_move_insn (lraddr, eh_addr);
504 }
505
506 /* Helper for defining INITIAL_ELIMINATION_OFFSET.
507 We allow the following eliminiations:
508 FP -> HARD_FP or SP
509 AP -> HARD_FP or SP
510
511 HARD_FP and AP are the same which is handled below. */
512
513 HOST_WIDE_INT
514 or1k_initial_elimination_offset (int from, int to)
515 {
516 HOST_WIDE_INT offset;
517
518 /* Set OFFSET to the offset from the stack pointer. */
519 switch (from)
520 {
521 /* Incoming args are all the way up at the previous frame. */
522 case ARG_POINTER_REGNUM:
523 offset = cfun->machine->total_size;
524 break;
525
526 /* Local args grow downward from the saved registers. */
527 case FRAME_POINTER_REGNUM:
528 offset = cfun->machine->args_size + cfun->machine->local_vars_size;
529 break;
530
531 default:
532 gcc_unreachable ();
533 }
534
535 if (to == HARD_FRAME_POINTER_REGNUM)
536 offset -= cfun->machine->total_size;
537
538 return offset;
539 }
540
541 /* Worker for TARGET_LEGITIMATE_ADDRESS_P.
542 Returns true if X is a legitimate address RTX on OpenRISC. */
543
544 static bool
545 or1k_legitimate_address_p (machine_mode, rtx x, bool strict_p)
546 {
547 rtx base, addend;
548
549 switch (GET_CODE (x))
550 {
551 case REG:
552 base = x;
553 break;
554
555 case PLUS:
556 base = XEXP (x, 0);
557 addend = XEXP (x, 1);
558 if (!REG_P (base))
559 return false;
560 /* Register elimination is going to adjust all of these offsets.
561 We might as well keep them as a unit until then. */
562 if (!strict_p && virtual_frame_reg_operand (base, VOIDmode))
563 return CONST_INT_P (addend);
564 if (!satisfies_constraint_I (addend))
565 return false;
566 break;
567
568 case LO_SUM:
569 base = XEXP (x, 0);
570 if (!REG_P (base))
571 return false;
572 x = XEXP (x, 1);
573 switch (GET_CODE (x))
574 {
575 case CONST:
576 case SYMBOL_REF:
577 case LABEL_REF:
578 /* Assume legitimize_address properly categorized
579 the symbol. Continue to check the base. */
580 break;
581
582 case UNSPEC:
583 switch (XINT (x, 1))
584 {
585 case UNSPEC_GOT:
586 case UNSPEC_GOTOFF:
587 case UNSPEC_TPOFF:
588 case UNSPEC_GOTTPOFF:
589 /* Assume legitimize_address properly categorized
590 the symbol. Continue to check the base. */
591 break;
592 default:
593 return false;
594 }
595 break;
596
597 default:
598 return false;
599 }
600 break;
601
602 default:
603 return false;
604 }
605
606 unsigned regno = REGNO (base);
607 if (regno >= FIRST_PSEUDO_REGISTER)
608 {
609 if (strict_p)
610 regno = reg_renumber[regno];
611 else
612 return true;
613 }
614 if (strict_p)
615 return regno <= 31;
616 else
617 return REGNO_OK_FOR_BASE_P (regno);
618 }
619
620 /* Return the TLS type for TLS symbols, 0 otherwise. */
621
622 static tls_model
623 or1k_tls_symbolic_operand (rtx op)
624 {
625 rtx sym, addend;
626 split_const (op, &sym, &addend);
627 if (SYMBOL_REF_P (sym))
628 return SYMBOL_REF_TLS_MODEL (sym);
629 return TLS_MODEL_NONE;
630 }
631
632 /* Get a reference to the '__tls_get_addr' symbol. */
633
634 static GTY(()) rtx gen_tls_tga;
635
636 static rtx
637 gen_tls_get_addr (void)
638 {
639 if (!gen_tls_tga)
640 gen_tls_tga = init_one_libfunc ("__tls_get_addr");
641 return gen_tls_tga;
642 }
643
644 /* Emit a call to '__tls_get_addr'. */
645
646 static void
647 or1k_tls_call (rtx dest, rtx arg)
648 {
649 emit_library_call_value (gen_tls_get_addr (), dest, LCT_CONST,
650 Pmode, arg, Pmode);
651 }
652
653 /* Helper for or1k_legitimize_address_1. Wrap X in an unspec. */
654
655 static rtx
656 gen_sym_unspec (rtx x, int kind)
657 {
658 return gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), kind);
659 }
660
661 /* Worker for TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT.
662 Split an out-of-range address displacement into hi and lo parts.
663 The hi part will have to be loaded into a register separately,
664 but the low part will be folded into the memory operand. */
665
666 static bool
667 or1k_legitimize_address_displacement (rtx *off1, rtx *off2,
668 poly_int64 poly_offset, machine_mode)
669 {
670 HOST_WIDE_INT orig_offset = poly_offset;
671 HOST_WIDE_INT lo, hi;
672
673 /* If the displacement is within range of 2 addi insns, prefer that.
674 Otherwise split as per normal, at which point the register allocator
675 will see that OFF1 is not a valid add3 operand and load it into
676 a register, as desired. */
677 if (orig_offset >= 0 && orig_offset < 2 * 32767)
678 {
679 hi = 32767;
680 lo = orig_offset - hi;
681 }
682 else if (orig_offset < 0 && orig_offset >= 2 * -32768)
683 {
684 hi = -32768;
685 lo = orig_offset - hi;
686 }
687 else
688 {
689 lo = sext_hwi (orig_offset, 16);
690 hi = orig_offset - lo;
691 }
692
693 *off1 = GEN_INT (hi);
694 *off2 = GEN_INT (lo);
695 return true;
696 }
697
698 #undef TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT
699 #define TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT \
700 or1k_legitimize_address_displacement
701
702 /* Helper function to implement both TARGET_LEGITIMIZE_ADDRESS and expand the
703 patterns "movqi", "movqi" and "movsi". Returns an valid OpenRISC RTX that
704 represents the argument X which is an invalid address RTX. The argument
705 SCRATCH may be used as a temporary when building addresses. */
706
707 static rtx
708 or1k_legitimize_address_1 (rtx x, rtx scratch)
709 {
710 rtx base, addend, t1, t2;
711 tls_model tls_kind = TLS_MODEL_NONE;
712 bool is_local = true;
713
714 split_const (x, &base, &addend);
715 switch (GET_CODE (base))
716 {
717 default:
718 gcc_assert (can_create_pseudo_p ());
719 base = force_reg (Pmode, base);
720 break;
721
722 case REG:
723 case SUBREG:
724 break;
725
726 case SYMBOL_REF:
727 tls_kind = SYMBOL_REF_TLS_MODEL (base);
728 is_local = SYMBOL_REF_LOCAL_P (base);
729 /* FALLTHRU */
730
731 case LABEL_REF:
732 switch (tls_kind)
733 {
734 case TLS_MODEL_NONE:
735 t1 = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : scratch;
736 if (!flag_pic)
737 {
738 emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, x)));
739 return gen_rtx_LO_SUM (Pmode, t1, x);
740 }
741 else if (is_local)
742 {
743 crtl->uses_pic_offset_table = 1;
744 t2 = gen_sym_unspec (x, UNSPEC_GOTOFF);
745 emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, t2)));
746 emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
747 return gen_rtx_LO_SUM (Pmode, t1, copy_rtx (t2));
748 }
749 else
750 {
751 base = gen_sym_unspec (base, UNSPEC_GOT);
752 crtl->uses_pic_offset_table = 1;
753 t2 = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, base);
754 t2 = gen_const_mem (Pmode, t2);
755 emit_insn (gen_rtx_SET (t1, t2));
756 base = t1;
757 }
758 break;
759
760 case TLS_MODEL_GLOBAL_DYNAMIC:
761 case TLS_MODEL_LOCAL_DYNAMIC:
762 /* TODO: For now, treat LD as GD. */
763 t1 = gen_reg_rtx (Pmode);
764 base = gen_sym_unspec (base, UNSPEC_TLSGD);
765 emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
766 emit_insn (gen_rtx_SET (t1, gen_rtx_LO_SUM (Pmode, t1, base)));
767 crtl->uses_pic_offset_table = 1;
768 emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
769 base = gen_reg_rtx (Pmode);
770 or1k_tls_call (base, t1);
771 break;
772
773 case TLS_MODEL_INITIAL_EXEC:
774 t1 = gen_reg_rtx (Pmode);
775 t2 = gen_reg_rtx (Pmode);
776 base = gen_sym_unspec (base, UNSPEC_GOTTPOFF);
777 emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
778 crtl->uses_pic_offset_table = 1;
779 emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
780 t1 = gen_rtx_LO_SUM (Pmode, t1, base);
781 emit_move_insn (t2, gen_const_mem (Pmode, t1));
782 t1 = gen_rtx_REG (Pmode, TLS_REGNUM);
783 emit_insn (gen_add3_insn (t2, t2, t1));
784 base = t2;
785 break;
786
787 case TLS_MODEL_LOCAL_EXEC:
788 x = gen_sym_unspec (x, UNSPEC_TPOFF);
789 t1 = gen_reg_rtx (Pmode);
790 emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, x)));
791 t2 = gen_rtx_REG (Pmode, TLS_REGNUM);
792 emit_insn (gen_add3_insn (t1, t1, t2));
793 return gen_rtx_LO_SUM (Pmode, t1, x);
794
795 default:
796 gcc_unreachable ();
797 }
798 break;
799
800 /* Accept what we may have already emitted. */
801
802 case LO_SUM:
803 case UNSPEC:
804 return x;
805 }
806
807 /* If we get here, we still have addend outstanding. */
808 gcc_checking_assert (register_operand (base, Pmode));
809 if (addend == const0_rtx)
810 return base;
811 if (satisfies_constraint_I (addend)
812 || virtual_frame_reg_operand (base, VOIDmode))
813 return gen_rtx_PLUS (Pmode, base, addend);
814 else
815 {
816 rtx hi, lo;
817 bool ok = (or1k_legitimize_address_displacement
818 (&hi, &lo, INTVAL (addend), SImode));
819 gcc_assert (ok);
820
821 t2 = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : scratch;
822 if (satisfies_constraint_I (hi))
823 emit_insn (gen_addsi3 (t2, base, hi));
824 else
825 {
826 t1 = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : scratch;
827 emit_move_insn (t1, hi);
828 emit_insn (gen_add3_insn (t2, base, t1));
829 }
830 if (lo == const0_rtx)
831 return t2;
832 else
833 return gen_rtx_PLUS (Pmode, t2, lo);
834 }
835 }
836
837 /* Worker for TARGET_LEGITIMIZE_ADDRESS.
838 This delegates implementation to or1k_legitimize_address_1. */
839
840 static rtx
841 or1k_legitimize_address (rtx x, rtx /* oldx */, machine_mode)
842 {
843 return or1k_legitimize_address_1 (x, NULL_RTX);
844 }
845
846 #undef TARGET_LEGITIMIZE_ADDRESS
847 #define TARGET_LEGITIMIZE_ADDRESS or1k_legitimize_address
848
849 /* Worker for TARGET_DELEGITIMIZE_ADDRESS.
850 In the name of slightly smaller debug output, and to cater to
851 general assembler lossage, recognize PIC+GOTOFF and turn it back
852 into a direct symbol reference. */
853
854 static rtx
855 or1k_delegitimize_address (rtx x)
856 {
857 if (GET_CODE (x) == UNSPEC)
858 {
859 /* The LO_SUM to which X was attached has been stripped.
860 Since the only legitimate address we could have been computing
861 is that of the symbol, assume that's what we've done. */
862 if (XINT (x, 1) == UNSPEC_GOTOFF)
863 return XVECEXP (x, 0, 0);
864 }
865 else if (MEM_P (x))
866 {
867 rtx addr = XEXP (x, 0);
868 if (GET_CODE (addr) == LO_SUM
869 && XEXP (addr, 0) == pic_offset_table_rtx)
870 {
871 rtx inner = XEXP (addr, 1);
872 if (GET_CODE (inner) == UNSPEC
873 && XINT (inner, 1) == UNSPEC_GOT)
874 return XVECEXP (inner, 0, 0);
875 }
876 }
877 return delegitimize_mem_from_attrs (x);
878 }
879
880 #undef TARGET_DELEGITIMIZE_ADDRESS
881 #define TARGET_DELEGITIMIZE_ADDRESS or1k_delegitimize_address
882
883 /* Worker for TARGET_CANNOT_FORCE_CONST_MEM.
884 Primarily this is required for TLS symbols, but given that our move
885 patterns *ought* to be able to handle any symbol at any time, we
886 should never be spilling symbolic operands to the constant pool, ever. */
887
888 static bool
889 or1k_cannot_force_const_mem (machine_mode, rtx x)
890 {
891 rtx_code code = GET_CODE (x);
892 return (code == SYMBOL_REF
893 || code == LABEL_REF
894 || code == CONST
895 || code == HIGH);
896 }
897
898 #undef TARGET_CANNOT_FORCE_CONST_MEM
899 #define TARGET_CANNOT_FORCE_CONST_MEM or1k_cannot_force_const_mem
900
901 /* Worker for TARGET_LEGITIMATE_CONSTANT_P.
902 Returns true is the RTX X represents a constant that can be used as an
903 immediate operand in OpenRISC. */
904
905 static bool
906 or1k_legitimate_constant_p (machine_mode, rtx x)
907 {
908 switch (GET_CODE (x))
909 {
910 case CONST_INT:
911 case CONST_WIDE_INT:
912 case HIGH:
913 /* We construct these, rather than spilling to memory. */
914 return true;
915
916 case CONST:
917 case SYMBOL_REF:
918 case LABEL_REF:
919 /* These may need to be split and not reconstructed. */
920 return or1k_tls_symbolic_operand (x) == TLS_MODEL_NONE;
921
922 default:
923 return false;
924 }
925 }
926
927 #undef TARGET_LEGITIMATE_CONSTANT_P
928 #define TARGET_LEGITIMATE_CONSTANT_P or1k_legitimate_constant_p
929
930 /* Worker for TARGET_PASS_BY_REFERENCE.
931 Returns true if an argument ARG should be passed by reference as
932 required by the OpenRISC ABI. On OpenRISC structures, unions and
933 arguments larger than 64-bits are passed by reference. */
934
935 static bool
936 or1k_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
937 {
938 if (arg.aggregate_type_p ())
939 return true;
940 HOST_WIDE_INT size = arg.type_size_in_bytes ();
941 return size < 0 || size > 8;
942 }
943
944 /* Worker for TARGET_FUNCTION_VALUE.
945 Returns an RTX representing the location where function return values will
946 be stored. On OpenRISC this is the register r11. 64-bit return value's
947 upper 32-bits are returned in r12, this is automatically done by GCC. */
948
949 static rtx
950 or1k_function_value (const_tree valtype,
951 const_tree /* fn_decl_or_type */,
952 bool /* outgoing */)
953 {
954 return gen_rtx_REG (TYPE_MODE (valtype), RV_REGNUM);
955 }
956
957 /* Worker for TARGET_LIBCALL_VALUE.
958 Returns an RTX representing the location where function return values to
959 external libraries will be stored. On OpenRISC this the same as local
960 function calls. */
961
962 static rtx
963 or1k_libcall_value (machine_mode mode,
964 const_rtx /* fun */)
965 {
966 return gen_rtx_REG (mode, RV_REGNUM);
967 }
968
969
970 /* Worker for TARGET_FUNCTION_VALUE_REGNO_P.
971 Returns true if REGNO is a valid register for storing a function return
972 value. */
973
974 static bool
975 or1k_function_value_regno_p (const unsigned int regno)
976 {
977 return (regno == RV_REGNUM);
978 }
979
980 /* Worker for TARGET_STRICT_ARGUMENT_NAMING.
981 Return true always as on OpenRISC the last argument in a variatic function
982 is named. */
983
984 static bool
985 or1k_strict_argument_naming (cumulative_args_t /* ca */)
986 {
987 return true;
988 }
989
990 #undef TARGET_STRICT_ARGUMENT_NAMING
991 #define TARGET_STRICT_ARGUMENT_NAMING or1k_strict_argument_naming
992
993 /* Worker for TARGET_FUNCTION_ARG.
994 Return the next register to be used to hold a function argument or NULL_RTX
995 if there's no more space. Arugment CUM_V represents the current argument
996 offset, zero for the first function argument. OpenRISC function arguments
997 maybe be passed in registers r3 to r8. */
998
999 static rtx
1000 or1k_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
1001 {
1002 /* Handle the special marker for the end of the arguments. */
1003 if (arg.end_marker_p ())
1004 return NULL_RTX;
1005
1006 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1007 int nreg = CEIL (GET_MODE_SIZE (arg.mode), UNITS_PER_WORD);
1008
1009 /* Note that all large arguments are passed by reference. */
1010 gcc_assert (nreg <= 2);
1011 if (arg.named && *cum + nreg <= 6)
1012 return gen_rtx_REG (arg.mode, *cum + 3);
1013 else
1014 return NULL_RTX;
1015 }
1016
1017 /* Worker for TARGET_FUNCTION_ARG_ADVANCE.
1018 Update the cumulative args descriptor CUM_V to advance past the next function
1019 argument. Note, this is not called for arguments passed on the stack. */
1020
1021 static void
1022 or1k_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
1023 const_tree /* type */, bool named)
1024 {
1025 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1026 int nreg = CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
1027
1028 /* Note that all large arguments are passed by reference. */
1029 gcc_assert (nreg <= 2);
1030 if (named)
1031 *cum += nreg;
1032 }
1033
1034 /* worker function for TARGET_RETURN_IN_MEMORY.
1035 Returns true if the argument of TYPE should be returned in memory. On
1036 OpenRISC this is any value larger than 64-bits. */
1037
1038 static bool
1039 or1k_return_in_memory (const_tree type, const_tree /* fntype */)
1040 {
1041 const HOST_WIDE_INT size = int_size_in_bytes (type);
1042 return (size == -1 || size > (2 * UNITS_PER_WORD));
1043 }
1044
1045 /* Print reloc (x + add). */
1046
1047 static void
1048 output_addr_reloc (FILE *stream, rtx x, HOST_WIDE_INT add, const char *reloc)
1049 {
1050 if (*reloc)
1051 {
1052 fputs (reloc, stream);
1053 fputc ('(', stream);
1054 }
1055 output_addr_const (stream, x);
1056 if (add)
1057 {
1058 if (add > 0)
1059 fputc ('+', stream);
1060 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, add);
1061 }
1062 if (*reloc)
1063 fputc (')', stream);
1064 }
1065
1066 enum reloc_kind
1067 {
1068 RKIND_LO,
1069 RKIND_HI,
1070 RKIND_MAX
1071 };
1072
1073 enum reloc_type
1074 {
1075 RTYPE_DIRECT,
1076 RTYPE_GOT,
1077 RTYPE_GOTOFF,
1078 RTYPE_TPOFF,
1079 RTYPE_GOTTPOFF,
1080 RTYPE_TLSGD,
1081 RTYPE_MAX
1082 };
1083
1084 static void
1085 print_reloc (FILE *stream, rtx x, HOST_WIDE_INT add, reloc_kind kind)
1086 {
1087 /* All data relocations. A NULL in this table indicates a form that
1088 we expect to never generate, while "" indicates a form that requires
1089 no special markup. */
1090 static const char * const relocs[RKIND_MAX][RTYPE_MAX] = {
1091 { "lo", "got", "gotofflo", "tpofflo", "gottpofflo", "tlsgdlo" },
1092 { "ha", NULL, "gotoffha", "tpoffha", "gottpoffha", "tlsgdhi" },
1093 };
1094 reloc_type type = RTYPE_DIRECT;
1095
1096 if (GET_CODE (x) == UNSPEC)
1097 {
1098 switch (XINT (x, 1))
1099 {
1100 case UNSPEC_GOT:
1101 type = RTYPE_GOT;
1102 break;
1103 case UNSPEC_GOTOFF:
1104 type = RTYPE_GOTOFF;
1105 break;
1106 case UNSPEC_TPOFF:
1107 type = RTYPE_TPOFF;
1108 break;
1109 case UNSPEC_GOTTPOFF:
1110 type = RTYPE_GOTTPOFF;
1111 break;
1112 case UNSPEC_TLSGD:
1113 type = RTYPE_TLSGD;
1114 break;
1115 default:
1116 output_operand_lossage ("invalid relocation");
1117 return;
1118 }
1119 x = XVECEXP (x, 0, 0);
1120 }
1121
1122 const char *reloc = relocs[kind][type];
1123 if (reloc == NULL)
1124 output_operand_lossage ("invalid relocation");
1125 else
1126 output_addr_reloc (stream, x, add, reloc);
1127 }
1128
1129 /* Worker for TARGET_PRINT_OPERAND_ADDRESS.
1130 Prints the argument ADDR, an address RTX, to the file FILE. The output is
1131 formed as expected by the OpenRISC assembler. Examples:
1132
1133 RTX OUTPUT
1134 (reg:SI 3) 0(r3)
1135 (plus:SI (reg:SI 3) (const_int 4)) 0x4(r3)
1136 (lo_sum:SI (reg:SI 3) (symbol_ref:SI ("x")))) lo(x)(r3) */
1137
1138 static void
1139 or1k_print_operand_address (FILE *file, machine_mode, rtx addr)
1140 {
1141 rtx offset;
1142
1143 switch (GET_CODE (addr))
1144 {
1145 case REG:
1146 fputc ('0', file);
1147 break;
1148
1149 case PLUS:
1150 offset = XEXP (addr, 1);
1151 addr = XEXP (addr, 0);
1152 gcc_assert (CONST_INT_P (offset));
1153 if (GET_CODE (addr) == LO_SUM)
1154 {
1155 print_reloc (file, XEXP (addr, 1), INTVAL (offset), RKIND_LO);
1156 addr = XEXP (addr, 0);
1157 }
1158 else
1159 output_addr_const (file, offset);
1160 break;
1161
1162 case LO_SUM:
1163 offset = XEXP (addr, 1);
1164 addr = XEXP (addr, 0);
1165 print_reloc (file, offset, 0, RKIND_LO);
1166 break;
1167
1168 default:
1169 output_addr_const (file, addr);
1170 return;
1171 }
1172
1173 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
1174 }
1175
1176 /* Worker for TARGET_PRINT_OPERAND.
1177 Print operand X, an RTX, to the file FILE. The output is formed as expected
1178 by the OpenRISC assember. CODE is the letter following a '%' in an
1179 instrunction template used to control the RTX output. Example(s):
1180
1181 CODE RTX OUTPUT COMMENT
1182 0 (reg:SI 3) r3 output an operand
1183 r (reg:SI 3) r3 output a register or const zero
1184 H (reg:SI 3) r4 output the high pair register
1185 h (symbol_ref:SI ("x")) ha(x) output a signed high relocation
1186 L (symbol_ref:SI ("x")) lo(x) output a low relocation
1187
1188 Note, '#' is a special code used to fill the branch delay slot with an l.nop
1189 instruction. The l.nop (no-op) instruction is only outputted when the delay
1190 slot has not been filled. */
1191
1192 static void
1193 or1k_print_operand (FILE *file, rtx x, int code)
1194 {
1195 rtx operand = x;
1196
1197 switch (code)
1198 {
1199 case '#':
1200 /* Conditionally add a nop in unfilled delay slot. */
1201 if (final_sequence == NULL)
1202 fputs ("\n\t l.nop\n", file);
1203 break;
1204
1205 case 'r':
1206 if (REG_P (x))
1207 fprintf (file, "%s", reg_names[REGNO (operand)]);
1208 else if (x == CONST0_RTX (GET_MODE (x)))
1209 fprintf (file, "r0");
1210 else
1211 output_operand_lossage ("invalid %%r value");
1212 break;
1213
1214 case 'H':
1215 if (REG_P (x))
1216 fprintf (file, "%s", reg_names[REGNO (operand) + 1]);
1217 else
1218 output_operand_lossage ("invalid %%H value");
1219 break;
1220
1221 case 'd':
1222 if (REG_P (x))
1223 {
1224 if (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
1225 fprintf (file, "%s,%s", reg_names[REGNO (operand)],
1226 reg_names[REGNO (operand) + 1]);
1227 else
1228 fprintf (file, "%s", reg_names[REGNO (operand)]);
1229 }
1230 else
1231 output_operand_lossage ("invalid %%d value");
1232 break;
1233
1234 case 'h':
1235 print_reloc (file, x, 0, RKIND_HI);
1236 break;
1237 case 'L':
1238 print_reloc (file, x, 0, RKIND_LO);
1239 break;
1240 case 'P':
1241 if (!flag_pic || SYMBOL_REF_LOCAL_P (x))
1242 output_addr_const (file, x);
1243 else
1244 output_addr_reloc (file, x, 0, "plt");
1245 break;
1246
1247 case 0:
1248 /* Print an operand as without a modifier letter. */
1249 switch (GET_CODE (operand))
1250 {
1251 case REG:
1252 if (REGNO (operand) > 31)
1253 internal_error ("internal error: bad register: %d",
1254 REGNO (operand));
1255 fprintf (file, "%s", reg_names[REGNO (operand)]);
1256 break;
1257
1258 case MEM:
1259 output_address (GET_MODE (XEXP (operand, 0)), XEXP (operand, 0));
1260 break;
1261
1262 case CODE_LABEL:
1263 case LABEL_REF:
1264 output_asm_label (operand);
1265 break;
1266
1267 default:
1268 /* No need to handle all strange variants, let output_addr_const
1269 do it for us. */
1270 if (CONSTANT_P (operand))
1271 output_addr_const (file, operand);
1272 else
1273 internal_error ("unexpected operand: %d", GET_CODE (operand));
1274 break;
1275 }
1276 break;
1277
1278 default:
1279 output_operand_lossage ("unknown operand letter: '%c'", code);
1280 break;
1281 }
1282 }
1283
1284 /* Worker for TARGET_TRAMPOLINE_INIT.
1285 This is called to initialize a trampoline. The argument M_TRAMP is an RTX
1286 for the memory block to be initialized with trampoline code. The argument
1287 FNDECL contains the definition of the nested function to be called, we use
1288 this to get the function's address. The argument CHAIN is an RTX for the
1289 static chain value to be passed to the nested function. */
1290
1291 static void
1292 or1k_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
1293 {
1294 const unsigned movhi_r13 = (0x06u << 26) | (13 << 21);
1295 const unsigned movhi_r11 = (0x06u << 26) | (11 << 21);
1296 const unsigned ori_r13_r13 = (0x2a << 26) | (13 << 21) | (13 << 16);
1297 const unsigned ori_r11_r11 = (0x2a << 26) | (11 << 21) | (11 << 16);
1298 const unsigned jr_r13 = (0x11 << 26) | (13 << 11);
1299 rtx tramp[5], fnaddr, f_hi, f_lo, c_hi, c_lo;
1300
1301 fnaddr = force_operand (XEXP (DECL_RTL (fndecl), 0), NULL);
1302 f_hi = expand_binop (SImode, lshr_optab, fnaddr, GEN_INT (16),
1303 NULL, true, OPTAB_DIRECT);
1304 f_lo = expand_binop (SImode, and_optab, fnaddr, GEN_INT (0xffff),
1305 NULL, true, OPTAB_DIRECT);
1306
1307 chain = force_operand (chain, NULL);
1308 c_hi = expand_binop (SImode, lshr_optab, chain, GEN_INT (16),
1309 NULL, true, OPTAB_DIRECT);
1310 c_lo = expand_binop (SImode, and_optab, chain, GEN_INT (0xffff),
1311 NULL, true, OPTAB_DIRECT);
1312
1313 /* We want to generate
1314
1315 l.movhi r13,hi(nested_func)
1316 l.movhi r11,hi(static_chain)
1317 l.ori r13,r13,lo(nested_func)
1318 l.jr r13
1319 l.ori r11,r11,lo(static_chain)
1320 */
1321 tramp[0] = expand_binop (SImode, ior_optab, f_hi,
1322 gen_int_mode (movhi_r13, SImode),
1323 f_hi, true, OPTAB_DIRECT);
1324 tramp[1] = expand_binop (SImode, ior_optab, c_hi,
1325 gen_int_mode (movhi_r11, SImode),
1326 c_hi, true, OPTAB_DIRECT);
1327 tramp[2] = expand_binop (SImode, ior_optab, f_lo,
1328 gen_int_mode (ori_r13_r13, SImode),
1329 f_lo, true, OPTAB_DIRECT);
1330 tramp[4] = expand_binop (SImode, ior_optab, c_lo,
1331 gen_int_mode (ori_r11_r11, SImode),
1332 c_lo, true, OPTAB_DIRECT);
1333 tramp[3] = gen_int_mode (jr_r13, SImode);
1334
1335 for (int i = 0; i < 5; ++i)
1336 {
1337 rtx mem = adjust_address (m_tramp, SImode, i * 4);
1338 emit_move_insn (mem, tramp[i]);
1339 }
1340
1341 /* Flushing the trampoline from the instruction cache needs
1342 to be done here. */
1343 }
1344
1345 /* Worker for TARGET_HARD_REGNO_MODE_OK.
1346 Returns true if the hard register REGNO is ok for storing values of mode
1347 MODE. */
1348
1349 static bool
1350 or1k_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
1351 {
1352 /* For OpenRISC, GENERAL_REGS can hold anything, while
1353 FLAG_REGS are really single bits within SP[SR]. */
1354 if (REGNO_REG_CLASS (regno) == FLAG_REGS)
1355 return mode == BImode;
1356 return true;
1357 }
1358
1359 #undef TARGET_HARD_REGNO_MODE_OK
1360 #define TARGET_HARD_REGNO_MODE_OK or1k_hard_regno_mode_ok
1361
1362 /* Worker for TARGET_CAN_CHANGE_MODE_CLASS.
1363 Returns true if its ok to change a register in class RCLASS from mode FROM to
1364 mode TO. In general OpenRISC registers, other than special flags, handle all
1365 supported classes. */
1366
1367 static bool
1368 or1k_can_change_mode_class (machine_mode from, machine_mode to,
1369 reg_class_t rclass)
1370 {
1371 if (rclass == FLAG_REGS)
1372 return from == to;
1373 return true;
1374 }
1375
1376 #undef TARGET_CAN_CHANGE_MODE_CLASS
1377 #define TARGET_CAN_CHANGE_MODE_CLASS or1k_can_change_mode_class
1378
1379 /* Expand the patterns "movqi", "movqi" and "movsi". The argument OP0 is the
1380 destination and OP1 is the source. This expands to set OP0 to OP1. OpenRISC
1381 cannot do memory to memory assignments so for those cases we force one
1382 argument to a register. Constants that can't fit into a 16-bit immediate are
1383 split. Symbols are legitimized using split relocations. */
1384
1385 void
1386 or1k_expand_move (machine_mode mode, rtx op0, rtx op1)
1387 {
1388 if (MEM_P (op0))
1389 {
1390 if (!const0_operand (op1, mode))
1391 op1 = force_reg (mode, op1);
1392 }
1393 else if (mode == QImode || mode == HImode)
1394 {
1395 /* ??? Maybe promote MEMs and CONST_INT to SImode,
1396 and then squish back with gen_lowpart. */
1397 }
1398 else
1399 {
1400 switch (GET_CODE (op1))
1401 {
1402 case CONST_INT:
1403 if (!input_operand (op1, mode))
1404 {
1405 HOST_WIDE_INT i = INTVAL (op1);
1406 HOST_WIDE_INT lo = i & 0xffff;
1407 HOST_WIDE_INT hi = i ^ lo;
1408 rtx subtarget = op0;
1409
1410 if (!cse_not_expected && can_create_pseudo_p ())
1411 subtarget = gen_reg_rtx (SImode);
1412 emit_insn (gen_rtx_SET (subtarget, GEN_INT (hi)));
1413 emit_insn (gen_iorsi3 (op0, subtarget, GEN_INT (lo)));
1414 return;
1415 }
1416 break;
1417
1418 case CONST:
1419 case SYMBOL_REF:
1420 case LABEL_REF:
1421 op1 = or1k_legitimize_address_1 (op1, op0);
1422 break;
1423
1424 default:
1425 break;
1426 }
1427 }
1428 emit_insn (gen_rtx_SET (op0, op1));
1429 }
1430
1431 /* Used to expand patterns "movsicc", "movqicc", "movhicc", "cstoresi4" and
1432 "cbranchsi4".
1433 Expands a comparison where OPERANDS is an array of RTX describing the
1434 comparison. The first argument OPERANDS[0] is the operator and OPERANDS[1]
1435 and OPERANDS[2] are the operands. Split out the compare into SR[F] and
1436 return a new operation in OPERANDS[0]. The inputs OPERANDS[1] and
1437 OPERANDS[2] are not directly used, only overridden. */
1438
1439 void
1440 or1k_expand_compare (rtx *operands)
1441 {
1442 rtx sr_f = gen_rtx_REG (BImode, SR_F_REGNUM);
1443 rtx righthand_op = XEXP (operands[0], 1);
1444 rtx_code cmp_code = GET_CODE (operands[0]);
1445 bool flag_check_ne = true;
1446
1447 /* Integer RTL may receive an immediate in argument 1 of the compare, this is
1448 not supported unless we have l.sf*i instructions, force them into
1449 registers. */
1450 if (!TARGET_SFIMM && CONST_INT_P (righthand_op))
1451 XEXP (operands[0], 1) = force_reg (SImode, righthand_op);
1452
1453 /* Normalize comparison operators to ones OpenRISC support. */
1454 switch (cmp_code)
1455 {
1456 case LTGT:
1457 cmp_code = UNEQ;
1458 flag_check_ne = false;
1459 break;
1460
1461 case ORDERED:
1462 cmp_code = UNORDERED;
1463 flag_check_ne = false;
1464 break;
1465
1466 default:
1467 break;
1468 }
1469
1470 /* Emit the given comparison into the Flag bit. */
1471 PUT_MODE (operands[0], BImode);
1472 PUT_CODE (operands[0], cmp_code);
1473 emit_insn (gen_rtx_SET (sr_f, operands[0]));
1474
1475 /* Adjust the operands for use in the caller. */
1476 operands[0] = flag_check_ne ? gen_rtx_NE (VOIDmode, sr_f, const0_rtx)
1477 : gen_rtx_EQ (VOIDmode, sr_f, const0_rtx);
1478 operands[1] = sr_f;
1479 operands[2] = const0_rtx;
1480 }
1481
1482 /* Expand the patterns "call", "sibcall", "call_value" and "sibcall_value".
1483 Expands a function call where argument RETVAL is an optional RTX providing
1484 return value storage, the argument FNADDR is and RTX describing the function
1485 to call, the argument CALLARG1 is the number or registers used as operands
1486 and the argument SIBCALL should be true if this is a nested function call.
1487 If FNADDR is a non local symbol and FLAG_PIC is enabled this will generate
1488 a PLT call. */
1489
1490 void
1491 or1k_expand_call (rtx retval, rtx fnaddr, rtx callarg1, bool sibcall)
1492 {
1493 rtx call, use = NULL;
1494
1495 /* Calls via the PLT require the PIC register. */
1496 if (flag_pic
1497 && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
1498 && !SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
1499 {
1500 crtl->uses_pic_offset_table = 1;
1501 rtx hard_pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
1502 emit_move_insn (hard_pic, pic_offset_table_rtx);
1503 use_reg (&use, hard_pic);
1504 }
1505
1506 if (!call_insn_operand (XEXP (fnaddr, 0), Pmode))
1507 {
1508 fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
1509 fnaddr = gen_rtx_MEM (SImode, fnaddr);
1510 }
1511
1512 call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
1513 if (retval)
1514 call = gen_rtx_SET (retval, call);
1515
1516 /* Normal calls clobber LR. This is required in order to
1517 prevent e.g. a prologue store of LR being placed into
1518 the delay slot of the call, after it has been updated. */
1519 if (!sibcall)
1520 {
1521 rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNUM));
1522 call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, clob));
1523 }
1524 call = emit_call_insn (call);
1525
1526 CALL_INSN_FUNCTION_USAGE (call) = use;
1527 }
1528
1529 /* Worker for TARGET_FUNCTION_OK_FOR_SIBCALL.
1530 Returns true if the function declared by DECL is ok for calling as a nested
1531 function. */
1532
1533 static bool
1534 or1k_function_ok_for_sibcall (tree decl, tree /* exp */)
1535 {
1536 /* We can sibcall to any function if not PIC. */
1537 if (!flag_pic)
1538 return true;
1539
1540 /* We can sibcall any indirect function. */
1541 if (decl == NULL)
1542 return true;
1543
1544 /* If the call may go through the PLT, we need r16 live. */
1545 return targetm.binds_local_p (decl);
1546 }
1547
1548 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1549 #define TARGET_FUNCTION_OK_FOR_SIBCALL or1k_function_ok_for_sibcall
1550
1551 /* Worker for TARGET_RTX_COSTS. */
1552
1553 static bool
1554 or1k_rtx_costs (rtx x, machine_mode mode, int outer_code, int /* opno */,
1555 int *total, bool /* speed */)
1556 {
1557 switch (GET_CODE (x))
1558 {
1559 case CONST_INT:
1560 if (x == const0_rtx)
1561 *total = 0;
1562 else if ((outer_code == PLUS || outer_code == XOR || outer_code == MULT)
1563 && satisfies_constraint_I (x))
1564 *total = 0;
1565 else if ((outer_code == AND || outer_code == IOR)
1566 && satisfies_constraint_K (x))
1567 *total = 0;
1568 else if (satisfies_constraint_I (x)
1569 || satisfies_constraint_K (x)
1570 || satisfies_constraint_M (x))
1571 *total = 2;
1572 else
1573 *total = COSTS_N_INSNS (2);
1574 return true;
1575
1576 case CONST_DOUBLE:
1577 *total = (x == CONST0_RTX (mode) ? 0 : COSTS_N_INSNS (2));
1578 return true;
1579
1580 case HIGH:
1581 /* This is effectively an 'M' constraint. */
1582 *total = 2;
1583 return true;
1584
1585 case LO_SUM:
1586 /* This is effectively an 'I' constraint. */
1587 *total = (outer_code == MEM ? 0 : 2);
1588 return true;
1589
1590 case CONST:
1591 case SYMBOL_REF:
1592 case LABEL_REF:
1593 if (outer_code == LO_SUM || outer_code == HIGH)
1594 *total = 0;
1595 else
1596 {
1597 /* ??? Extra cost for GOT or TLS symbols. */
1598 *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1599 }
1600 return true;
1601
1602 case PLUS:
1603 if (outer_code == MEM)
1604 *total = 0;
1605 break;
1606
1607 default:
1608 break;
1609 }
1610 return false;
1611 }
1612
1613 #undef TARGET_RTX_COSTS
1614 #define TARGET_RTX_COSTS or1k_rtx_costs
1615
1616
1617 /* A subroutine of the atomic operation splitters. Jump to LABEL if
1618 COND is true. Mark the jump as unlikely to be taken. */
1619
1620 static void
1621 emit_unlikely_jump (rtx_code code, rtx label)
1622 {
1623 rtx x;
1624
1625 x = gen_rtx_REG (BImode, SR_F_REGNUM);
1626 x = gen_rtx_fmt_ee (code, VOIDmode, x, const0_rtx);
1627 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx);
1628 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
1629
1630 // Disable this for now -- producing verify_cfg failures on probabilities.
1631 // int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
1632 // add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
1633 }
1634
1635 /* A subroutine of the atomic operation splitters.
1636 Emit a raw comparison for A CODE B. */
1637
1638 static void
1639 emit_compare (rtx_code code, rtx a, rtx b)
1640 {
1641 emit_insn (gen_rtx_SET (gen_rtx_REG (BImode, SR_F_REGNUM),
1642 gen_rtx_fmt_ee (code, BImode, a, b)));
1643 }
1644
1645 /* A subroutine of the atomic operation splitters.
1646 Emit a load-locked instruction in MODE. */
1647
1648 static void
1649 emit_load_locked (machine_mode mode, rtx reg, rtx mem)
1650 {
1651 gcc_assert (mode == SImode);
1652 emit_insn (gen_load_locked_si (reg, mem));
1653 }
1654
1655 /* A subroutine of the atomic operation splitters.
1656 Emit a store-conditional instruction in MODE. */
1657
1658 static void
1659 emit_store_conditional (machine_mode mode, rtx mem, rtx val)
1660 {
1661 gcc_assert (mode == SImode);
1662 emit_insn (gen_store_conditional_si (mem, val));
1663 }
1664
1665 /* A subroutine of the various atomic expanders. For sub-word operations,
1666 we must adjust things to operate on SImode. Given the original MEM,
1667 return a new aligned memory. Also build and return the quantities by
1668 which to shift and mask. */
1669
1670 static rtx
1671 or1k_adjust_atomic_subword (rtx orig_mem, rtx *pshift, rtx *pmask)
1672 {
1673 rtx addr, align, shift, mask, mem;
1674 machine_mode mode = GET_MODE (orig_mem);
1675
1676 addr = XEXP (orig_mem, 0);
1677 addr = force_reg (Pmode, addr);
1678
1679 /* Aligned memory containing subword. Generate a new memory. We
1680 do not want any of the existing MEM_ATTR data, as we're now
1681 accessing memory outside the original object. */
1682 align = expand_binop (Pmode, and_optab, addr, GEN_INT (-4),
1683 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1684 mem = gen_rtx_MEM (SImode, align);
1685 MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
1686 if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
1687 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
1688
1689 /* Shift amount for subword relative to aligned word. */
1690 rtx mode_mask = GEN_INT (mode == QImode ? 3 : 2);
1691 shift = expand_binop (SImode, and_optab, gen_lowpart (SImode, addr),
1692 mode_mask, NULL_RTX, 1, OPTAB_LIB_WIDEN);
1693 if (BYTES_BIG_ENDIAN)
1694 shift = expand_binop (SImode, xor_optab, shift, mode_mask,
1695 shift, 1, OPTAB_LIB_WIDEN);
1696 shift = expand_binop (SImode, ashl_optab, shift, GEN_INT (3),
1697 shift, 1, OPTAB_LIB_WIDEN);
1698 *pshift = shift;
1699
1700 /* Mask for insertion. */
1701 mask = expand_binop (SImode, ashl_optab, GEN_INT (GET_MODE_MASK (mode)),
1702 shift, NULL_RTX, 1, OPTAB_LIB_WIDEN);
1703 *pmask = mask;
1704
1705 return mem;
1706 }
1707
1708 /* A subroutine of the various atomic expanders. For sub-word operations,
1709 complete the operation by shifting result to the lsb of the SImode
1710 temporary and then extracting the result in MODE with a SUBREG. */
1711
1712 static void
1713 or1k_finish_atomic_subword (machine_mode mode, rtx o, rtx n, rtx shift)
1714 {
1715 n = expand_binop (SImode, lshr_optab, n, shift,
1716 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1717 emit_move_insn (o, gen_lowpart (mode, n));
1718 }
1719
1720 /* Expand an atomic compare and swap operation.
1721 Emits the RTX to perform a compare and swap operation. This function takes
1722 8 RTX arguments in the OPERANDS array. The compare and swap operation
1723 loads a value from memory (OPERANDS[2]) and compares it with an expected
1724 value (OPERANDS[3]), if the values are equal it stores a new value
1725 (OPERANDS[4]) to memory. The argument OPERANDS[0] represents a boolean
1726 result which will be set to true if the operation succeeds. A return value
1727 (OPERANDS[1]) will be set to what was loaded from memory. The argument
1728 OPERAND[5] is used to indicate if the compare and swap is to be treated as
1729 weak. OpenRISC does not use OPERANDS[5] or OPERANDS[6] which provide memory
1730 model details.
1731 For OpenRISC this emits RTX which will translate to assembly using the
1732 'l.lwa' (load word atomic) and 'l.swa' (store word atomic) instructions. */
1733
1734 void
1735 or1k_expand_atomic_compare_and_swap (rtx operands[])
1736 {
1737 rtx boolval, retval, mem, oldval, newval;
1738 rtx label1, label2;
1739 machine_mode mode;
1740 bool is_weak;
1741
1742 boolval = operands[0];
1743 retval = operands[1];
1744 mem = operands[2];
1745 oldval = operands[3];
1746 newval = operands[4];
1747 is_weak = (INTVAL (operands[5]) != 0);
1748 mode = GET_MODE (mem);
1749
1750 if (reg_overlap_mentioned_p (retval, oldval))
1751 oldval = copy_to_reg (oldval);
1752
1753 label1 = NULL_RTX;
1754 /* If strong, create a label to try again. */
1755 if (!is_weak)
1756 {
1757 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1758 emit_label (XEXP (label1, 0));
1759 }
1760 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1761
1762 emit_load_locked (mode, retval, mem);
1763 emit_compare (EQ, retval, oldval);
1764 emit_unlikely_jump (EQ, label2);
1765 emit_store_conditional (mode, mem, newval);
1766
1767 /* If strong, jump back to try again on fails. */
1768 if (!is_weak)
1769 emit_unlikely_jump (EQ, label1);
1770 emit_label (XEXP (label2, 0));
1771
1772 /* In all cases, SR_F contains 1 on success, and 0 on failure. */
1773 emit_insn (gen_sne_sr_f (boolval));
1774 }
1775
1776 void
1777 or1k_expand_atomic_compare_and_swap_qihi (rtx operands[])
1778 {
1779 rtx boolval, orig_retval, retval, scratch, mem, oldval, newval;
1780 rtx label1, label2, mask, shift;
1781 machine_mode mode;
1782 bool is_weak;
1783
1784 boolval = operands[0];
1785 orig_retval = operands[1];
1786 mem = operands[2];
1787 oldval = operands[3];
1788 newval = operands[4];
1789 is_weak = (INTVAL (operands[5]) != 0);
1790 mode = GET_MODE (mem);
1791
1792 mem = or1k_adjust_atomic_subword (mem, &shift, &mask);
1793
1794 /* Shift and mask OLDVAL and NEWVAL into position with the word. */
1795 if (oldval != const0_rtx)
1796 {
1797 oldval = convert_modes (SImode, mode, oldval, 1);
1798 oldval = expand_binop (SImode, ashl_optab, oldval, shift,
1799 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1800 }
1801 if (newval != const0_rtx)
1802 {
1803 newval = convert_modes (SImode, mode, newval, 1);
1804 newval = expand_binop (SImode, ashl_optab, newval, shift,
1805 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1806 }
1807
1808 label1 = NULL_RTX;
1809 if (!is_weak)
1810 {
1811 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1812 emit_label (XEXP (label1, 0));
1813 }
1814 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1815
1816 scratch = gen_reg_rtx (SImode);
1817 emit_load_locked (SImode, scratch, mem);
1818
1819 retval = expand_binop (SImode, and_optab, scratch, mask,
1820 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1821 scratch = expand_binop (SImode, xor_optab, scratch, retval,
1822 scratch, 1, OPTAB_LIB_WIDEN);
1823
1824 emit_compare (EQ, retval, oldval);
1825 emit_unlikely_jump (EQ, label2);
1826
1827 if (newval != const0_rtx)
1828 scratch = expand_binop (SImode, ior_optab, scratch, newval,
1829 scratch, 1, OPTAB_LIB_WIDEN);
1830
1831 emit_store_conditional (SImode, mem, scratch);
1832
1833 if (!is_weak)
1834 emit_unlikely_jump (EQ, label1);
1835 emit_label (XEXP (label2, 0));
1836
1837 or1k_finish_atomic_subword (mode, orig_retval, retval, shift);
1838
1839 /* In all cases, SR_F contains 1 on success, and 0 on failure. */
1840 emit_insn (gen_sne_sr_f (boolval));
1841 }
1842
1843 /* Expand an atomic exchange operation.
1844 Emits the RTX to perform an exchange operation. This function takes 4 RTX
1845 arguments in the OPERANDS array. The exchange operation atomically loads a
1846 value from memory (OPERANDS[1]) to a return value (OPERANDS[0]) and stores a
1847 new value (OPERANDS[2]) back to the memory location.
1848 Another argument (OPERANDS[3]) is used to indicate the memory model and
1849 is not used by OpenRISC.
1850 For OpenRISC this emits RTX which will translate to assembly using the
1851 'l.lwa' (load word atomic) and 'l.swa' (store word atomic) instructions. */
1852
1853 void
1854 or1k_expand_atomic_exchange (rtx operands[])
1855 {
1856 rtx retval, mem, val, label;
1857 machine_mode mode;
1858
1859 retval = operands[0];
1860 mem = operands[1];
1861 val = operands[2];
1862 mode = GET_MODE (mem);
1863
1864 if (reg_overlap_mentioned_p (retval, val))
1865 val = copy_to_reg (val);
1866
1867 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1868 emit_label (XEXP (label, 0));
1869
1870 emit_load_locked (mode, retval, mem);
1871 emit_store_conditional (mode, mem, val);
1872 emit_unlikely_jump (EQ, label);
1873 }
1874
1875 void
1876 or1k_expand_atomic_exchange_qihi (rtx operands[])
1877 {
1878 rtx orig_retval, retval, mem, val, scratch;
1879 rtx label, mask, shift;
1880 machine_mode mode;
1881
1882 orig_retval = operands[0];
1883 mem = operands[1];
1884 val = operands[2];
1885 mode = GET_MODE (mem);
1886
1887 mem = or1k_adjust_atomic_subword (mem, &shift, &mask);
1888
1889 /* Shift and mask VAL into position with the word. */
1890 if (val != const0_rtx)
1891 {
1892 val = convert_modes (SImode, mode, val, 1);
1893 val = expand_binop (SImode, ashl_optab, val, shift,
1894 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1895 }
1896
1897 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1898 emit_label (XEXP (label, 0));
1899
1900 scratch = gen_reg_rtx (SImode);
1901 emit_load_locked (SImode, scratch, mem);
1902
1903 retval = expand_binop (SImode, and_optab, scratch, mask,
1904 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1905 scratch = expand_binop (SImode, xor_optab, scratch, retval,
1906 scratch, 1, OPTAB_LIB_WIDEN);
1907 if (val != const0_rtx)
1908 scratch = expand_binop (SImode, ior_optab, scratch, val,
1909 scratch, 1, OPTAB_LIB_WIDEN);
1910
1911 emit_store_conditional (SImode, mem, scratch);
1912 emit_unlikely_jump (EQ, label);
1913
1914 or1k_finish_atomic_subword (mode, orig_retval, retval, shift);
1915 }
1916
1917 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
1918 to perform (with MULT as a stand-in for NAND). MEM is the memory on which
1919 to operate. VAL is the second operand of the binary operator. BEFORE and
1920 AFTER are optional locations to return the value of MEM either before of
1921 after the operation. */
1922
1923 void
1924 or1k_expand_atomic_op (rtx_code code, rtx mem, rtx val,
1925 rtx orig_before, rtx orig_after)
1926 {
1927 machine_mode mode = GET_MODE (mem);
1928 rtx before = orig_before, after = orig_after;
1929 rtx label;
1930
1931 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1932 emit_label (XEXP (label, 0));
1933
1934 if (before == NULL_RTX)
1935 before = gen_reg_rtx (mode);
1936
1937 emit_load_locked (mode, before, mem);
1938
1939 if (code == MULT)
1940 {
1941 after = expand_binop (mode, and_optab, before, val,
1942 after, 1, OPTAB_LIB_WIDEN);
1943 after = expand_unop (mode, one_cmpl_optab, after, after, 1);
1944 }
1945 else
1946 after = expand_simple_binop (mode, code, before, val,
1947 after, 1, OPTAB_LIB_WIDEN);
1948
1949 emit_store_conditional (mode, mem, after);
1950 emit_unlikely_jump (EQ, label);
1951
1952 if (orig_before)
1953 emit_move_insn (orig_before, before);
1954 if (orig_after)
1955 emit_move_insn (orig_after, after);
1956 }
1957
1958 void
1959 or1k_expand_atomic_op_qihi (rtx_code code, rtx mem, rtx val,
1960 rtx orig_before, rtx orig_after)
1961 {
1962 machine_mode mode = GET_MODE (mem);
1963 rtx label, mask, shift, x;
1964 rtx before, after, scratch;
1965
1966 mem = or1k_adjust_atomic_subword (mem, &shift, &mask);
1967
1968 /* Shift and mask VAL into position with the word. */
1969 val = convert_modes (SImode, mode, val, 1);
1970 val = expand_binop (SImode, ashl_optab, val, shift,
1971 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1972
1973 switch (code)
1974 {
1975 case IOR:
1976 case XOR:
1977 /* We've already zero-extended VAL. That is sufficient to
1978 make certain that it does not affect other bits. */
1979 break;
1980
1981 case AND:
1982 case MULT: /* NAND */
1983 /* If we make certain that all of the other bits in VAL are
1984 set, that will be sufficient to not affect other bits. */
1985 x = expand_unop (SImode, one_cmpl_optab, mask, NULL_RTX, 1);
1986 val = expand_binop (SImode, ior_optab, val, x,
1987 val, 1, OPTAB_LIB_WIDEN);
1988 break;
1989
1990 case PLUS:
1991 case MINUS:
1992 /* These will all affect bits outside the field and need
1993 adjustment via MASK within the loop. */
1994 break;
1995
1996 default:
1997 gcc_unreachable ();
1998 }
1999
2000 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
2001 emit_label (XEXP (label, 0));
2002
2003 before = scratch = gen_reg_rtx (SImode);
2004 emit_load_locked (SImode, before, mem);
2005
2006 switch (code)
2007 {
2008 case IOR:
2009 case XOR:
2010 case AND:
2011 after = expand_simple_binop (SImode, code, before, val,
2012 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2013 scratch = after;
2014 break;
2015
2016 case PLUS:
2017 case MINUS:
2018 before = expand_binop (SImode, and_optab, scratch, mask,
2019 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2020 scratch = expand_binop (SImode, xor_optab, scratch, before,
2021 scratch, 1, OPTAB_LIB_WIDEN);
2022 after = expand_simple_binop (SImode, code, before, val,
2023 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2024 after = expand_binop (SImode, and_optab, after, mask,
2025 after, 1, OPTAB_LIB_WIDEN);
2026 scratch = expand_binop (SImode, ior_optab, scratch, after,
2027 scratch, 1, OPTAB_LIB_WIDEN);
2028 break;
2029
2030 case MULT: /* NAND */
2031 after = expand_binop (SImode, and_optab, before, val,
2032 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2033 after = expand_binop (SImode, xor_optab, after, mask,
2034 after, 1, OPTAB_LIB_WIDEN);
2035 scratch = after;
2036 break;
2037
2038 default:
2039 gcc_unreachable ();
2040 }
2041
2042 emit_store_conditional (SImode, mem, scratch);
2043 emit_unlikely_jump (EQ, label);
2044
2045 if (orig_before)
2046 or1k_finish_atomic_subword (mode, orig_before, before, shift);
2047 if (orig_after)
2048 or1k_finish_atomic_subword (mode, orig_after, after, shift);
2049 }
2050
2051 /* Worker for TARGET_ASM_OUTPUT_MI_THUNK.
2052 Output the assembler code for a thunk function. THUNK_DECL is the
2053 declaration for the thunk function itself, FUNCTION is the decl for
2054 the target function. DELTA is an immediate constant offset to be
2055 added to THIS. If VCALL_OFFSET is nonzero, the word at address
2056 (*THIS + VCALL_OFFSET) should be additionally added to THIS. */
2057
2058 static void
2059 or1k_output_mi_thunk (FILE *file, tree thunk_fndecl,
2060 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
2061 tree function)
2062 {
2063 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
2064 rtx this_rtx, funexp;
2065 rtx_insn *insn;
2066
2067 reload_completed = 1;
2068 epilogue_completed = 1;
2069
2070 emit_note (NOTE_INSN_PROLOGUE_END);
2071
2072 /* Find the "this" pointer. Normally in r3, but if the function
2073 returns a structure, the structure return pointer is in r3 and
2074 the "this" pointer is in r4 instead. */
2075 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
2076 this_rtx = gen_rtx_REG (Pmode, 4);
2077 else
2078 this_rtx = gen_rtx_REG (Pmode, 3);
2079
2080 /* Add DELTA. When possible use a plain add, otherwise load it
2081 into a register first. */
2082 if (delta)
2083 {
2084 rtx delta_rtx = GEN_INT (delta);
2085
2086 if (!satisfies_constraint_I (delta_rtx))
2087 {
2088 rtx scratch = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
2089 emit_move_insn (scratch, delta_rtx);
2090 delta_rtx = scratch;
2091 }
2092
2093 /* THIS_RTX += DELTA. */
2094 emit_insn (gen_add2_insn (this_rtx, delta_rtx));
2095 }
2096
2097 /* Add the word at address (*THIS_RTX + VCALL_OFFSET). */
2098 if (vcall_offset)
2099 {
2100 rtx scratch = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
2101 HOST_WIDE_INT lo = sext_hwi (vcall_offset, 16);
2102 HOST_WIDE_INT hi = vcall_offset - lo;
2103 rtx tmp;
2104
2105 /* SCRATCH = *THIS_RTX. */
2106 tmp = gen_rtx_MEM (Pmode, this_rtx);
2107 emit_move_insn (scratch, tmp);
2108
2109 if (hi != 0)
2110 {
2111 rtx scratch2 = gen_rtx_REG (Pmode, RV_REGNUM);
2112 emit_move_insn (scratch2, GEN_INT (hi));
2113 emit_insn (gen_add2_insn (scratch, scratch2));
2114 }
2115
2116 /* SCRATCH = *(*THIS_RTX + VCALL_OFFSET). */
2117 tmp = plus_constant (Pmode, scratch, lo);
2118 tmp = gen_rtx_MEM (Pmode, tmp);
2119 emit_move_insn (scratch, tmp);
2120
2121 /* THIS_RTX += *(*THIS_RTX + VCALL_OFFSET). */
2122 emit_insn (gen_add2_insn (this_rtx, scratch));
2123 }
2124
2125 /* Generate a tail call to the target function. */
2126 if (!TREE_USED (function))
2127 {
2128 assemble_external (function);
2129 TREE_USED (function) = 1;
2130 }
2131 funexp = XEXP (DECL_RTL (function), 0);
2132
2133 /* The symbol will be a local alias and therefore always binds local. */
2134 gcc_assert (SYMBOL_REF_LOCAL_P (funexp));
2135
2136 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
2137 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
2138 SIBLING_CALL_P (insn) = 1;
2139 emit_barrier ();
2140
2141 /* Run just enough of rest_of_compilation to get the insns emitted.
2142 There's not really enough bulk here to make other passes such as
2143 instruction scheduling worth while. */
2144 insn = get_insns ();
2145 shorten_branches (insn);
2146 assemble_start_function (thunk_fndecl, fnname);
2147 final_start_function (insn, file, 1);
2148 final (insn, file, 1);
2149 final_end_function ();
2150 assemble_end_function (thunk_fndecl, fnname);
2151
2152 reload_completed = 0;
2153 epilogue_completed = 0;
2154 }
2155
2156 #undef TARGET_ASM_OUTPUT_MI_THUNK
2157 #define TARGET_ASM_OUTPUT_MI_THUNK or1k_output_mi_thunk
2158 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
2159 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
2160 hook_bool_const_tree_hwi_hwi_const_tree_true
2161
2162 #undef TARGET_OPTION_OVERRIDE
2163 #define TARGET_OPTION_OVERRIDE or1k_option_override
2164
2165 #undef TARGET_COMPUTE_FRAME_LAYOUT
2166 #define TARGET_COMPUTE_FRAME_LAYOUT or1k_compute_frame_layout
2167
2168 #undef TARGET_LEGITIMATE_ADDRESS_P
2169 #define TARGET_LEGITIMATE_ADDRESS_P or1k_legitimate_address_p
2170
2171 #undef TARGET_HAVE_TLS
2172 #define TARGET_HAVE_TLS true
2173
2174 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
2175 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
2176
2177 /* Calling Conventions. */
2178 #undef TARGET_FUNCTION_VALUE
2179 #define TARGET_FUNCTION_VALUE or1k_function_value
2180 #undef TARGET_LIBCALL_VALUE
2181 #define TARGET_LIBCALL_VALUE or1k_libcall_value
2182 #undef TARGET_FUNCTION_VALUE_REGNO_P
2183 #define TARGET_FUNCTION_VALUE_REGNO_P or1k_function_value_regno_p
2184 #undef TARGET_FUNCTION_ARG
2185 #define TARGET_FUNCTION_ARG or1k_function_arg
2186 #undef TARGET_FUNCTION_ARG_ADVANCE
2187 #define TARGET_FUNCTION_ARG_ADVANCE or1k_function_arg_advance
2188 #undef TARGET_RETURN_IN_MEMORY
2189 #define TARGET_RETURN_IN_MEMORY or1k_return_in_memory
2190 #undef TARGET_PASS_BY_REFERENCE
2191 #define TARGET_PASS_BY_REFERENCE or1k_pass_by_reference
2192 #undef TARGET_TRAMPOLINE_INIT
2193 #define TARGET_TRAMPOLINE_INIT or1k_trampoline_init
2194 #undef TARGET_FRAME_POINTER_REQUIRED
2195 #define TARGET_FRAME_POINTER_REQUIRED or1k_frame_pointer_required
2196 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
2197 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
2198
2199 /* Assembly generation. */
2200 #undef TARGET_PRINT_OPERAND
2201 #define TARGET_PRINT_OPERAND or1k_print_operand
2202 #undef TARGET_PRINT_OPERAND_ADDRESS
2203 #define TARGET_PRINT_OPERAND_ADDRESS or1k_print_operand_address
2204
2205 /* Section anchor support. */
2206 #undef TARGET_MIN_ANCHOR_OFFSET
2207 #define TARGET_MIN_ANCHOR_OFFSET -32768
2208 #undef TARGET_MAX_ANCHOR_OFFSET
2209 #define TARGET_MAX_ANCHOR_OFFSET 32767
2210
2211 struct gcc_target targetm = TARGET_INITIALIZER;
2212
2213 #include "gt-or1k.h"