]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/or1k/or1k.c
Use function_arg_info for TARGET_ARG_PARTIAL_BYTES
[thirdparty/gcc.git] / gcc / config / or1k / or1k.c
CommitLineData
3965b35f 1/* Target Code for OpenRISC
a5544970 2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
3965b35f
SH
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. */
58struct 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
80static struct machine_function *
81or1k_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
90static void
91or1k_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
99static bool
100callee_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
156static void
157or1k_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
181static void
182or1k_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
194static rtx
195or1k_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
206void
207or1k_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
317void
318or1k_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
423static void
424or1k_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
447rtx
448or1k_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
459rtx
460or1k_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
469rtx
470or1k_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
478static bool
479or1k_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
493void
494or1k_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
513HOST_WIDE_INT
514or1k_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
544static bool
545or1k_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
622static tls_model
623or1k_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
634static GTY(()) rtx gen_tls_tga;
635
636static rtx
637gen_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
646static void
647or1k_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
655static rtx
656gen_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
666static bool
667or1k_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
707static rtx
708or1k_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
840static rtx
841or1k_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
854static rtx
855or1k_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
888static bool
889or1k_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
905static bool
906or1k_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 of TYPE in MODE should be passed by reference
932 as required by the OpenRISC ABI. On OpenRISC structures, unions and
933 arguments larger than 64-bits are passed by reference. */
934
935static bool
936or1k_pass_by_reference (cumulative_args_t, machine_mode mode,
937 const_tree type, bool)
938{
939 HOST_WIDE_INT size;
940 if (type)
941 {
942 if (AGGREGATE_TYPE_P (type))
943 return true;
944 size = int_size_in_bytes (type);
945 }
946 else
947 size = GET_MODE_SIZE (mode);
948 return size < 0 || size > 8;
949}
950
951/* Worker for TARGET_FUNCTION_VALUE.
952 Returns an RTX representing the location where function return values will
953 be stored. On OpenRISC this is the register r11. 64-bit return value's
954 upper 32-bits are returned in r12, this is automatically done by GCC. */
955
956static rtx
957or1k_function_value (const_tree valtype,
958 const_tree /* fn_decl_or_type */,
959 bool /* outgoing */)
960{
961 return gen_rtx_REG (TYPE_MODE (valtype), RV_REGNUM);
962}
963
964/* Worker for TARGET_LIBCALL_VALUE.
965 Returns an RTX representing the location where function return values to
966 external libraries will be stored. On OpenRISC this the same as local
967 function calls. */
968
969static rtx
970or1k_libcall_value (machine_mode mode,
971 const_rtx /* fun */)
972{
973 return gen_rtx_REG (mode, RV_REGNUM);
974}
975
976
977/* Worker for TARGET_FUNCTION_VALUE_REGNO_P.
978 Returns true if REGNO is a valid register for storing a function return
979 value. */
980
981static bool
982or1k_function_value_regno_p (const unsigned int regno)
983{
984 return (regno == RV_REGNUM);
985}
986
987/* Worker for TARGET_STRICT_ARGUMENT_NAMING.
988 Return true always as on OpenRISC the last argument in a variatic function
989 is named. */
990
991static bool
992or1k_strict_argument_naming (cumulative_args_t /* ca */)
993{
994 return true;
995}
996
997#undef TARGET_STRICT_ARGUMENT_NAMING
998#define TARGET_STRICT_ARGUMENT_NAMING or1k_strict_argument_naming
999
1000/* Worker for TARGET_FUNCTION_ARG.
1001 Return the next register to be used to hold a function argument or NULL_RTX
1002 if there's no more space. Arugment CUM_V represents the current argument
1003 offset, zero for the first function argument. OpenRISC function arguments
1004 maybe be passed in registers r3 to r8. */
1005
1006static rtx
1007or1k_function_arg (cumulative_args_t cum_v, machine_mode mode,
1008 const_tree /* type */, bool named)
1009{
1010 /* VOIDmode is passed as a special flag for "last argument". */
1011 if (mode == VOIDmode)
1012 return NULL_RTX;
1013
1014 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1015 int nreg = CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
1016
1017 /* Note that all large arguments are passed by reference. */
1018 gcc_assert (nreg <= 2);
1019 if (named && *cum + nreg <= 6)
1020 return gen_rtx_REG (mode, *cum + 3);
1021 else
1022 return NULL_RTX;
1023}
1024
1025/* Worker for TARGET_FUNCTION_ARG_ADVANCE.
1026 Update the cumulative args descriptor CUM_V to advance past the next function
1027 argument. Note, this is not called for arguments passed on the stack. */
1028
1029static void
1030or1k_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
1031 const_tree /* type */, bool named)
1032{
1033 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1034 int nreg = CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
1035
1036 /* Note that all large arguments are passed by reference. */
1037 gcc_assert (nreg <= 2);
1038 if (named)
1039 *cum += nreg;
1040}
1041
1042/* worker function for TARGET_RETURN_IN_MEMORY.
1043 Returns true if the argument of TYPE should be returned in memory. On
1044 OpenRISC this is any value larger than 64-bits. */
1045
1046static bool
1047or1k_return_in_memory (const_tree type, const_tree /* fntype */)
1048{
1049 const HOST_WIDE_INT size = int_size_in_bytes (type);
1050 return (size == -1 || size > (2 * UNITS_PER_WORD));
1051}
1052
1053/* Print reloc (x + add). */
1054
1055static void
1056output_addr_reloc (FILE *stream, rtx x, HOST_WIDE_INT add, const char *reloc)
1057{
1058 if (*reloc)
1059 {
1060 fputs (reloc, stream);
1061 fputc ('(', stream);
1062 }
1063 output_addr_const (stream, x);
1064 if (add)
1065 {
1066 if (add > 0)
1067 fputc ('+', stream);
1068 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, add);
1069 }
1070 if (*reloc)
1071 fputc (')', stream);
1072}
1073
1074enum reloc_kind
1075{
1076 RKIND_LO,
1077 RKIND_HI,
1078 RKIND_MAX
1079};
1080
1081enum reloc_type
1082{
1083 RTYPE_DIRECT,
1084 RTYPE_GOT,
1085 RTYPE_GOTOFF,
1086 RTYPE_TPOFF,
1087 RTYPE_GOTTPOFF,
1088 RTYPE_TLSGD,
1089 RTYPE_MAX
1090};
1091
1092static void
1093print_reloc (FILE *stream, rtx x, HOST_WIDE_INT add, reloc_kind kind)
1094{
1095 /* All data relocations. A NULL in this table indicates a form that
1096 we expect to never generate, while "" indicates a form that requires
1097 no special markup. */
1098 static const char * const relocs[RKIND_MAX][RTYPE_MAX] = {
1099 { "lo", "got", "gotofflo", "tpofflo", "gottpofflo", "tlsgdlo" },
1100 { "ha", NULL, "gotoffha", "tpoffha", "gottpoffha", "tlsgdhi" },
1101 };
1102 reloc_type type = RTYPE_DIRECT;
1103
1104 if (GET_CODE (x) == UNSPEC)
1105 {
1106 switch (XINT (x, 1))
1107 {
1108 case UNSPEC_GOT:
1109 type = RTYPE_GOT;
1110 break;
1111 case UNSPEC_GOTOFF:
1112 type = RTYPE_GOTOFF;
1113 break;
1114 case UNSPEC_TPOFF:
1115 type = RTYPE_TPOFF;
1116 break;
1117 case UNSPEC_GOTTPOFF:
1118 type = RTYPE_GOTTPOFF;
1119 break;
1120 case UNSPEC_TLSGD:
1121 type = RTYPE_TLSGD;
1122 break;
1123 default:
1124 output_operand_lossage ("invalid relocation");
1125 return;
1126 }
1127 x = XVECEXP (x, 0, 0);
1128 }
1129
1130 const char *reloc = relocs[kind][type];
1131 if (reloc == NULL)
1132 output_operand_lossage ("invalid relocation");
1133 else
1134 output_addr_reloc (stream, x, add, reloc);
1135}
1136
1137/* Worker for TARGET_PRINT_OPERAND_ADDRESS.
1138 Prints the argument ADDR, an address RTX, to the file FILE. The output is
1139 formed as expected by the OpenRISC assembler. Examples:
1140
1141 RTX OUTPUT
1142 (reg:SI 3) 0(r3)
1143 (plus:SI (reg:SI 3) (const_int 4)) 0x4(r3)
1144 (lo_sum:SI (reg:SI 3) (symbol_ref:SI ("x")))) lo(x)(r3) */
1145
1146static void
1147or1k_print_operand_address (FILE *file, machine_mode, rtx addr)
1148{
1149 rtx offset;
1150
1151 switch (GET_CODE (addr))
1152 {
1153 case REG:
1154 fputc ('0', file);
1155 break;
1156
1157 case PLUS:
1158 offset = XEXP (addr, 1);
1159 addr = XEXP (addr, 0);
1160 gcc_assert (CONST_INT_P (offset));
1161 if (GET_CODE (addr) == LO_SUM)
1162 {
1163 print_reloc (file, XEXP (addr, 1), INTVAL (offset), RKIND_LO);
1164 addr = XEXP (addr, 0);
1165 }
1166 else
1167 output_addr_const (file, offset);
1168 break;
1169
1170 case LO_SUM:
1171 offset = XEXP (addr, 1);
1172 addr = XEXP (addr, 0);
1173 print_reloc (file, offset, 0, RKIND_LO);
1174 break;
1175
1176 default:
1177 output_addr_const (file, addr);
1178 return;
1179 }
1180
1181 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
1182}
1183
1184/* Worker for TARGET_PRINT_OPERAND.
1185 Print operand X, an RTX, to the file FILE. The output is formed as expected
1186 by the OpenRISC assember. CODE is the letter following a '%' in an
1187 instrunction template used to control the RTX output. Example(s):
1188
1189 CODE RTX OUTPUT COMMENT
1190 0 (reg:SI 3) r3 output an operand
1191 r (reg:SI 3) r3 output a register or const zero
1192 H (reg:SI 3) r4 output the high pair register
1193 h (symbol_ref:SI ("x")) ha(x) output a signed high relocation
1194 L (symbol_ref:SI ("x")) lo(x) output a low relocation
1195
1196 Note, '#' is a special code used to fill the branch delay slot with an l.nop
1197 instruction. The l.nop (no-op) instruction is only outputted when the delay
1198 slot has not been filled. */
1199
1200static void
1201or1k_print_operand (FILE *file, rtx x, int code)
1202{
1203 rtx operand = x;
1204
1205 switch (code)
1206 {
1207 case '#':
1208 /* Conditionally add a nop in unfilled delay slot. */
1209 if (final_sequence == NULL)
1210 fputs ("\n\t l.nop\n", file);
1211 break;
1212
1213 case 'r':
1214 if (REG_P (x))
1215 fprintf (file, "%s", reg_names[REGNO (operand)]);
1216 else if (x == CONST0_RTX (GET_MODE (x)))
1217 fprintf (file, "r0");
1218 else
1219 output_operand_lossage ("invalid %%r value");
1220 break;
1221
1222 case 'H':
1223 if (REG_P (x))
1224 fprintf (file, "%s", reg_names[REGNO (operand) + 1]);
1225 else
1226 output_operand_lossage ("invalid %%H value");
1227 break;
1228
44080af9
SH
1229 case 'd':
1230 if (REG_P (x))
1231 {
1232 if (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
1233 fprintf (file, "%s,%s", reg_names[REGNO (operand)],
1234 reg_names[REGNO (operand) + 1]);
1235 else
1236 fprintf (file, "%s", reg_names[REGNO (operand)]);
1237 }
1238 else
1239 output_operand_lossage ("invalid %%d value");
1240 break;
1241
3965b35f
SH
1242 case 'h':
1243 print_reloc (file, x, 0, RKIND_HI);
1244 break;
1245 case 'L':
1246 print_reloc (file, x, 0, RKIND_LO);
1247 break;
1248 case 'P':
1249 if (!flag_pic || SYMBOL_REF_LOCAL_P (x))
1250 output_addr_const (file, x);
1251 else
1252 output_addr_reloc (file, x, 0, "plt");
1253 break;
1254
1255 case 0:
1256 /* Print an operand as without a modifier letter. */
1257 switch (GET_CODE (operand))
1258 {
1259 case REG:
1260 if (REGNO (operand) > 31)
1261 internal_error ("internal error: bad register: %d",
1262 REGNO (operand));
1263 fprintf (file, "%s", reg_names[REGNO (operand)]);
1264 break;
1265
1266 case MEM:
1267 output_address (GET_MODE (XEXP (operand, 0)), XEXP (operand, 0));
1268 break;
1269
1270 case CODE_LABEL:
1271 case LABEL_REF:
1272 output_asm_label (operand);
1273 break;
1274
1275 default:
1276 /* No need to handle all strange variants, let output_addr_const
1277 do it for us. */
1278 if (CONSTANT_P (operand))
1279 output_addr_const (file, operand);
1280 else
1281 internal_error ("unexpected operand: %d", GET_CODE (operand));
1282 break;
1283 }
1284 break;
1285
1286 default:
1287 output_operand_lossage ("unknown operand letter: '%c'", code);
1288 break;
1289 }
1290}
1291
1292/* Worker for TARGET_TRAMPOLINE_INIT.
1293 This is called to initialize a trampoline. The argument M_TRAMP is an RTX
1294 for the memory block to be initialized with trampoline code. The argument
1295 FNDECL contains the definition of the nested function to be called, we use
1296 this to get the function's address. The argument CHAIN is an RTX for the
1297 static chain value to be passed to the nested function. */
1298
1299static void
1300or1k_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
1301{
1302 const unsigned movhi_r13 = (0x06u << 26) | (13 << 21);
1303 const unsigned movhi_r11 = (0x06u << 26) | (11 << 21);
1304 const unsigned ori_r13_r13 = (0x2a << 26) | (13 << 21) | (13 << 16);
1305 const unsigned ori_r11_r11 = (0x2a << 26) | (11 << 21) | (11 << 16);
1306 const unsigned jr_r13 = (0x11 << 26) | (13 << 11);
1307 rtx tramp[5], fnaddr, f_hi, f_lo, c_hi, c_lo;
1308
1309 fnaddr = force_operand (XEXP (DECL_RTL (fndecl), 0), NULL);
1310 f_hi = expand_binop (SImode, lshr_optab, fnaddr, GEN_INT (16),
1311 NULL, true, OPTAB_DIRECT);
1312 f_lo = expand_binop (SImode, and_optab, fnaddr, GEN_INT (0xffff),
1313 NULL, true, OPTAB_DIRECT);
1314
1315 chain = force_operand (chain, NULL);
1316 c_hi = expand_binop (SImode, lshr_optab, chain, GEN_INT (16),
1317 NULL, true, OPTAB_DIRECT);
1318 c_lo = expand_binop (SImode, and_optab, chain, GEN_INT (0xffff),
1319 NULL, true, OPTAB_DIRECT);
1320
1321 /* We want to generate
1322
1323 l.movhi r13,hi(nested_func)
1324 l.movhi r11,hi(static_chain)
1325 l.ori r13,r13,lo(nested_func)
1326 l.jr r13
1327 l.ori r11,r11,lo(static_chain)
1328 */
1329 tramp[0] = expand_binop (SImode, ior_optab, f_hi,
1330 gen_int_mode (movhi_r13, SImode),
1331 f_hi, true, OPTAB_DIRECT);
1332 tramp[1] = expand_binop (SImode, ior_optab, c_hi,
1333 gen_int_mode (movhi_r11, SImode),
1334 c_hi, true, OPTAB_DIRECT);
1335 tramp[2] = expand_binop (SImode, ior_optab, f_lo,
1336 gen_int_mode (ori_r13_r13, SImode),
1337 f_lo, true, OPTAB_DIRECT);
1338 tramp[4] = expand_binop (SImode, ior_optab, c_lo,
1339 gen_int_mode (ori_r11_r11, SImode),
1340 c_lo, true, OPTAB_DIRECT);
1341 tramp[3] = gen_int_mode (jr_r13, SImode);
1342
1343 for (int i = 0; i < 5; ++i)
1344 {
1345 rtx mem = adjust_address (m_tramp, SImode, i * 4);
1346 emit_move_insn (mem, tramp[i]);
1347 }
1348
1349 /* Flushing the trampoline from the instruction cache needs
1350 to be done here. */
1351}
1352
1353/* Worker for TARGET_HARD_REGNO_MODE_OK.
1354 Returns true if the hard register REGNO is ok for storing values of mode
1355 MODE. */
1356
1357static bool
1358or1k_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
1359{
1360 /* For OpenRISC, GENERAL_REGS can hold anything, while
1361 FLAG_REGS are really single bits within SP[SR]. */
1362 if (REGNO_REG_CLASS (regno) == FLAG_REGS)
1363 return mode == BImode;
1364 return true;
1365}
1366
1367#undef TARGET_HARD_REGNO_MODE_OK
1368#define TARGET_HARD_REGNO_MODE_OK or1k_hard_regno_mode_ok
1369
1370/* Worker for TARGET_CAN_CHANGE_MODE_CLASS.
1371 Returns true if its ok to change a register in class RCLASS from mode FROM to
1372 mode TO. In general OpenRISC registers, other than special flags, handle all
1373 supported classes. */
1374
1375static bool
1376or1k_can_change_mode_class (machine_mode from, machine_mode to,
1377 reg_class_t rclass)
1378{
1379 if (rclass == FLAG_REGS)
1380 return from == to;
1381 return true;
1382}
1383
1384#undef TARGET_CAN_CHANGE_MODE_CLASS
1385#define TARGET_CAN_CHANGE_MODE_CLASS or1k_can_change_mode_class
1386
1387/* Expand the patterns "movqi", "movqi" and "movsi". The argument OP0 is the
1388 destination and OP1 is the source. This expands to set OP0 to OP1. OpenRISC
1389 cannot do memory to memory assignments so for those cases we force one
1390 argument to a register. Constants that can't fit into a 16-bit immediate are
1391 split. Symbols are legitimized using split relocations. */
1392
1393void
1394or1k_expand_move (machine_mode mode, rtx op0, rtx op1)
1395{
1396 if (MEM_P (op0))
1397 {
1398 if (!const0_operand (op1, mode))
1399 op1 = force_reg (mode, op1);
1400 }
1401 else if (mode == QImode || mode == HImode)
1402 {
1403 /* ??? Maybe promote MEMs and CONST_INT to SImode,
1404 and then squish back with gen_lowpart. */
1405 }
1406 else
1407 {
1408 switch (GET_CODE (op1))
1409 {
1410 case CONST_INT:
1411 if (!input_operand (op1, mode))
1412 {
1413 HOST_WIDE_INT i = INTVAL (op1);
1414 HOST_WIDE_INT lo = i & 0xffff;
1415 HOST_WIDE_INT hi = i ^ lo;
1416 rtx subtarget = op0;
1417
1418 if (!cse_not_expected && can_create_pseudo_p ())
1419 subtarget = gen_reg_rtx (SImode);
1420 emit_insn (gen_rtx_SET (subtarget, GEN_INT (hi)));
1421 emit_insn (gen_iorsi3 (op0, subtarget, GEN_INT (lo)));
1422 return;
1423 }
1424 break;
1425
1426 case CONST:
1427 case SYMBOL_REF:
1428 case LABEL_REF:
1429 op1 = or1k_legitimize_address_1 (op1, op0);
1430 break;
1431
1432 default:
1433 break;
1434 }
1435 }
1436 emit_insn (gen_rtx_SET (op0, op1));
1437}
1438
1439/* Used to expand patterns "movsicc", "movqicc", "movhicc", "cstoresi4" and
1440 "cbranchsi4".
1441 Expands a comparison where OPERANDS is an array of RTX describing the
1442 comparison. The first argument OPERANDS[0] is the operator and OPERANDS[1]
1443 and OPERANDS[2] are the operands. Split out the compare into SR[F] and
1444 return a new operation in OPERANDS[0]. The inputs OPERANDS[1] and
1445 OPERANDS[2] are not directly used, only overridden. */
1446
1447void
1448or1k_expand_compare (rtx *operands)
1449{
1450 rtx sr_f = gen_rtx_REG (BImode, SR_F_REGNUM);
575ce893 1451 rtx righthand_op = XEXP (operands[0], 1);
44080af9
SH
1452 rtx_code cmp_code = GET_CODE (operands[0]);
1453 bool flag_check_ne = true;
3965b35f 1454
575ce893
SH
1455 /* Integer RTL may receive an immediate in argument 1 of the compare, this is
1456 not supported unless we have l.sf*i instructions, force them into
1457 registers. */
1458 if (!TARGET_SFIMM && CONST_INT_P (righthand_op))
1459 XEXP (operands[0], 1) = force_reg (SImode, righthand_op);
3965b35f 1460
44080af9
SH
1461 /* Normalize comparison operators to ones OpenRISC support. */
1462 switch (cmp_code)
1463 {
1464 case LTGT:
1465 cmp_code = UNEQ;
1466 flag_check_ne = false;
1467 break;
1468
1469 case ORDERED:
1470 cmp_code = UNORDERED;
1471 flag_check_ne = false;
1472 break;
1473
1474 default:
1475 break;
1476 }
1477
3965b35f
SH
1478 /* Emit the given comparison into the Flag bit. */
1479 PUT_MODE (operands[0], BImode);
44080af9 1480 PUT_CODE (operands[0], cmp_code);
3965b35f
SH
1481 emit_insn (gen_rtx_SET (sr_f, operands[0]));
1482
1483 /* Adjust the operands for use in the caller. */
44080af9
SH
1484 operands[0] = flag_check_ne ? gen_rtx_NE (VOIDmode, sr_f, const0_rtx)
1485 : gen_rtx_EQ (VOIDmode, sr_f, const0_rtx);
3965b35f
SH
1486 operands[1] = sr_f;
1487 operands[2] = const0_rtx;
44080af9 1488 }
3965b35f
SH
1489
1490/* Expand the patterns "call", "sibcall", "call_value" and "sibcall_value".
1491 Expands a function call where argument RETVAL is an optional RTX providing
1492 return value storage, the argument FNADDR is and RTX describing the function
1493 to call, the argument CALLARG1 is the number or registers used as operands
1494 and the argument SIBCALL should be true if this is a nested function call.
1495 If FNADDR is a non local symbol and FLAG_PIC is enabled this will generate
1496 a PLT call. */
1497
1498void
1499or1k_expand_call (rtx retval, rtx fnaddr, rtx callarg1, bool sibcall)
1500{
1501 rtx call, use = NULL;
1502
1503 /* Calls via the PLT require the PIC register. */
1504 if (flag_pic
1505 && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
1506 && !SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
1507 {
1508 crtl->uses_pic_offset_table = 1;
1509 rtx hard_pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
1510 emit_move_insn (hard_pic, pic_offset_table_rtx);
1511 use_reg (&use, hard_pic);
1512 }
1513
1514 if (!call_insn_operand (XEXP (fnaddr, 0), Pmode))
1515 {
1516 fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
1517 fnaddr = gen_rtx_MEM (SImode, fnaddr);
1518 }
1519
1520 call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
1521 if (retval)
1522 call = gen_rtx_SET (retval, call);
1523
1524 /* Normal calls clobber LR. This is required in order to
1525 prevent e.g. a prologue store of LR being placed into
1526 the delay slot of the call, after it has been updated. */
1527 if (!sibcall)
1528 {
1529 rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNUM));
1530 call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, clob));
1531 }
1532 call = emit_call_insn (call);
1533
1534 CALL_INSN_FUNCTION_USAGE (call) = use;
1535}
1536
1537/* Worker for TARGET_FUNCTION_OK_FOR_SIBCALL.
1538 Returns true if the function declared by DECL is ok for calling as a nested
1539 function. */
1540
1541static bool
1542or1k_function_ok_for_sibcall (tree decl, tree /* exp */)
1543{
1544 /* We can sibcall to any function if not PIC. */
1545 if (!flag_pic)
1546 return true;
1547
1548 /* We can sibcall any indirect function. */
1549 if (decl == NULL)
1550 return true;
1551
1552 /* If the call may go through the PLT, we need r16 live. */
1553 return targetm.binds_local_p (decl);
1554}
1555
1556#undef TARGET_FUNCTION_OK_FOR_SIBCALL
1557#define TARGET_FUNCTION_OK_FOR_SIBCALL or1k_function_ok_for_sibcall
1558
1559/* Worker for TARGET_RTX_COSTS. */
1560
1561static bool
1562or1k_rtx_costs (rtx x, machine_mode mode, int outer_code, int /* opno */,
1563 int *total, bool /* speed */)
1564{
1565 switch (GET_CODE (x))
1566 {
1567 case CONST_INT:
1568 if (x == const0_rtx)
1569 *total = 0;
1570 else if ((outer_code == PLUS || outer_code == XOR || outer_code == MULT)
1571 && satisfies_constraint_I (x))
1572 *total = 0;
1573 else if ((outer_code == AND || outer_code == IOR)
1574 && satisfies_constraint_K (x))
1575 *total = 0;
1576 else if (satisfies_constraint_I (x)
1577 || satisfies_constraint_K (x)
1578 || satisfies_constraint_M (x))
1579 *total = 2;
1580 else
1581 *total = COSTS_N_INSNS (2);
1582 return true;
1583
1584 case CONST_DOUBLE:
1585 *total = (x == CONST0_RTX (mode) ? 0 : COSTS_N_INSNS (2));
1586 return true;
1587
1588 case HIGH:
1589 /* This is effectively an 'M' constraint. */
1590 *total = 2;
1591 return true;
1592
1593 case LO_SUM:
1594 /* This is effectively an 'I' constraint. */
1595 *total = (outer_code == MEM ? 0 : 2);
1596 return true;
1597
1598 case CONST:
1599 case SYMBOL_REF:
1600 case LABEL_REF:
1601 if (outer_code == LO_SUM || outer_code == HIGH)
1602 *total = 0;
1603 else
1604 {
1605 /* ??? Extra cost for GOT or TLS symbols. */
1606 *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1607 }
1608 return true;
1609
1610 case PLUS:
1611 if (outer_code == MEM)
1612 *total = 0;
1613 break;
1614
1615 default:
1616 break;
1617 }
1618 return false;
1619}
1620
1621#undef TARGET_RTX_COSTS
1622#define TARGET_RTX_COSTS or1k_rtx_costs
1623
1624
1625/* A subroutine of the atomic operation splitters. Jump to LABEL if
1626 COND is true. Mark the jump as unlikely to be taken. */
1627
1628static void
1629emit_unlikely_jump (rtx_code code, rtx label)
1630{
1631 rtx x;
1632
1633 x = gen_rtx_REG (BImode, SR_F_REGNUM);
1634 x = gen_rtx_fmt_ee (code, VOIDmode, x, const0_rtx);
1635 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx);
1636 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
1637
1638 // Disable this for now -- producing verify_cfg failures on probabilities.
1639 // int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
1640 // add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
1641}
1642
1643/* A subroutine of the atomic operation splitters.
1644 Emit a raw comparison for A CODE B. */
1645
1646static void
1647emit_compare (rtx_code code, rtx a, rtx b)
1648{
1649 emit_insn (gen_rtx_SET (gen_rtx_REG (BImode, SR_F_REGNUM),
1650 gen_rtx_fmt_ee (code, BImode, a, b)));
1651}
1652
1653/* A subroutine of the atomic operation splitters.
1654 Emit a load-locked instruction in MODE. */
1655
1656static void
1657emit_load_locked (machine_mode mode, rtx reg, rtx mem)
1658{
1659 gcc_assert (mode == SImode);
1660 emit_insn (gen_load_locked_si (reg, mem));
1661}
1662
1663/* A subroutine of the atomic operation splitters.
1664 Emit a store-conditional instruction in MODE. */
1665
1666static void
1667emit_store_conditional (machine_mode mode, rtx mem, rtx val)
1668{
1669 gcc_assert (mode == SImode);
1670 emit_insn (gen_store_conditional_si (mem, val));
1671}
1672
1673/* A subroutine of the various atomic expanders. For sub-word operations,
1674 we must adjust things to operate on SImode. Given the original MEM,
1675 return a new aligned memory. Also build and return the quantities by
1676 which to shift and mask. */
1677
1678static rtx
1679or1k_adjust_atomic_subword (rtx orig_mem, rtx *pshift, rtx *pmask)
1680{
1681 rtx addr, align, shift, mask, mem;
1682 machine_mode mode = GET_MODE (orig_mem);
1683
1684 addr = XEXP (orig_mem, 0);
1685 addr = force_reg (Pmode, addr);
1686
1687 /* Aligned memory containing subword. Generate a new memory. We
1688 do not want any of the existing MEM_ATTR data, as we're now
1689 accessing memory outside the original object. */
1690 align = expand_binop (Pmode, and_optab, addr, GEN_INT (-4),
1691 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1692 mem = gen_rtx_MEM (SImode, align);
1693 MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
1694 if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
1695 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
1696
1697 /* Shift amount for subword relative to aligned word. */
1698 rtx mode_mask = GEN_INT (mode == QImode ? 3 : 2);
1699 shift = expand_binop (SImode, and_optab, gen_lowpart (SImode, addr),
1700 mode_mask, NULL_RTX, 1, OPTAB_LIB_WIDEN);
1701 if (BYTES_BIG_ENDIAN)
1702 shift = expand_binop (SImode, xor_optab, shift, mode_mask,
1703 shift, 1, OPTAB_LIB_WIDEN);
1704 shift = expand_binop (SImode, ashl_optab, shift, GEN_INT (3),
1705 shift, 1, OPTAB_LIB_WIDEN);
1706 *pshift = shift;
1707
1708 /* Mask for insertion. */
1709 mask = expand_binop (SImode, ashl_optab, GEN_INT (GET_MODE_MASK (mode)),
1710 shift, NULL_RTX, 1, OPTAB_LIB_WIDEN);
1711 *pmask = mask;
1712
1713 return mem;
1714}
1715
1716/* A subroutine of the various atomic expanders. For sub-word operations,
1717 complete the operation by shifting result to the lsb of the SImode
1718 temporary and then extracting the result in MODE with a SUBREG. */
1719
1720static void
1721or1k_finish_atomic_subword (machine_mode mode, rtx o, rtx n, rtx shift)
1722{
1723 n = expand_binop (SImode, lshr_optab, n, shift,
1724 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1725 emit_move_insn (o, gen_lowpart (mode, n));
1726}
1727
1728/* Expand an atomic compare and swap operation.
1729 Emits the RTX to perform a compare and swap operation. This function takes
1730 8 RTX arguments in the OPERANDS array. The compare and swap operation
1731 loads a value from memory (OPERANDS[2]) and compares it with an expected
1732 value (OPERANDS[3]), if the values are equal it stores a new value
1733 (OPERANDS[4]) to memory. The argument OPERANDS[0] represents a boolean
1734 result which will be set to true if the operation succeeds. A return value
1735 (OPERANDS[1]) will be set to what was loaded from memory. The argument
1736 OPERAND[5] is used to indicate if the compare and swap is to be treated as
1737 weak. OpenRISC does not use OPERANDS[5] or OPERANDS[6] which provide memory
1738 model details.
1739 For OpenRISC this emits RTX which will translate to assembly using the
1740 'l.lwa' (load word atomic) and 'l.swa' (store word atomic) instructions. */
1741
1742void
1743or1k_expand_atomic_compare_and_swap (rtx operands[])
1744{
1745 rtx boolval, retval, mem, oldval, newval;
1746 rtx label1, label2;
1747 machine_mode mode;
1748 bool is_weak;
1749
1750 boolval = operands[0];
1751 retval = operands[1];
1752 mem = operands[2];
1753 oldval = operands[3];
1754 newval = operands[4];
1755 is_weak = (INTVAL (operands[5]) != 0);
1756 mode = GET_MODE (mem);
1757
1758 if (reg_overlap_mentioned_p (retval, oldval))
1759 oldval = copy_to_reg (oldval);
1760
1761 label1 = NULL_RTX;
1762 /* If strong, create a label to try again. */
1763 if (!is_weak)
1764 {
1765 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1766 emit_label (XEXP (label1, 0));
1767 }
1768 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1769
1770 emit_load_locked (mode, retval, mem);
1771 emit_compare (EQ, retval, oldval);
1772 emit_unlikely_jump (EQ, label2);
1773 emit_store_conditional (mode, mem, newval);
1774
1775 /* If strong, jump back to try again on fails. */
1776 if (!is_weak)
1777 emit_unlikely_jump (EQ, label1);
1778 emit_label (XEXP (label2, 0));
1779
1780 /* In all cases, SR_F contains 1 on success, and 0 on failure. */
1781 emit_insn (gen_sne_sr_f (boolval));
1782}
1783
1784void
1785or1k_expand_atomic_compare_and_swap_qihi (rtx operands[])
1786{
1787 rtx boolval, orig_retval, retval, scratch, mem, oldval, newval;
1788 rtx label1, label2, mask, shift;
1789 machine_mode mode;
1790 bool is_weak;
1791
1792 boolval = operands[0];
1793 orig_retval = operands[1];
1794 mem = operands[2];
1795 oldval = operands[3];
1796 newval = operands[4];
1797 is_weak = (INTVAL (operands[5]) != 0);
1798 mode = GET_MODE (mem);
1799
1800 mem = or1k_adjust_atomic_subword (mem, &shift, &mask);
1801
1802 /* Shift and mask OLDVAL and NEWVAL into position with the word. */
1803 if (oldval != const0_rtx)
1804 {
1805 oldval = convert_modes (SImode, mode, oldval, 1);
1806 oldval = expand_binop (SImode, ashl_optab, oldval, shift,
1807 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1808 }
1809 if (newval != const0_rtx)
1810 {
1811 newval = convert_modes (SImode, mode, newval, 1);
1812 newval = expand_binop (SImode, ashl_optab, newval, shift,
1813 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1814 }
1815
1816 label1 = NULL_RTX;
1817 if (!is_weak)
1818 {
1819 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1820 emit_label (XEXP (label1, 0));
1821 }
1822 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1823
1824 scratch = gen_reg_rtx (SImode);
1825 emit_load_locked (SImode, scratch, mem);
1826
1827 retval = expand_binop (SImode, and_optab, scratch, mask,
1828 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1829 scratch = expand_binop (SImode, xor_optab, scratch, retval,
1830 scratch, 1, OPTAB_LIB_WIDEN);
1831
1832 emit_compare (EQ, retval, oldval);
1833 emit_unlikely_jump (EQ, label2);
1834
1835 if (newval != const0_rtx)
1836 scratch = expand_binop (SImode, ior_optab, scratch, newval,
1837 scratch, 1, OPTAB_LIB_WIDEN);
1838
1839 emit_store_conditional (SImode, mem, scratch);
1840
1841 if (!is_weak)
1842 emit_unlikely_jump (EQ, label1);
1843 emit_label (XEXP (label2, 0));
1844
1845 or1k_finish_atomic_subword (mode, orig_retval, retval, shift);
1846
1847 /* In all cases, SR_F contains 1 on success, and 0 on failure. */
1848 emit_insn (gen_sne_sr_f (boolval));
1849}
1850
1851/* Expand an atomic exchange operation.
1852 Emits the RTX to perform an exchange operation. This function takes 4 RTX
1853 arguments in the OPERANDS array. The exchange operation atomically loads a
1854 value from memory (OPERANDS[1]) to a return value (OPERANDS[0]) and stores a
1855 new value (OPERANDS[2]) back to the memory location.
1856 Another argument (OPERANDS[3]) is used to indicate the memory model and
1857 is not used by OpenRISC.
1858 For OpenRISC this emits RTX which will translate to assembly using the
1859 'l.lwa' (load word atomic) and 'l.swa' (store word atomic) instructions. */
1860
1861void
1862or1k_expand_atomic_exchange (rtx operands[])
1863{
1864 rtx retval, mem, val, label;
1865 machine_mode mode;
1866
1867 retval = operands[0];
1868 mem = operands[1];
1869 val = operands[2];
1870 mode = GET_MODE (mem);
1871
1872 if (reg_overlap_mentioned_p (retval, val))
1873 val = copy_to_reg (val);
1874
1875 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1876 emit_label (XEXP (label, 0));
1877
1878 emit_load_locked (mode, retval, mem);
1879 emit_store_conditional (mode, mem, val);
1880 emit_unlikely_jump (EQ, label);
1881}
1882
1883void
1884or1k_expand_atomic_exchange_qihi (rtx operands[])
1885{
1886 rtx orig_retval, retval, mem, val, scratch;
1887 rtx label, mask, shift;
1888 machine_mode mode;
1889
1890 orig_retval = operands[0];
1891 mem = operands[1];
1892 val = operands[2];
1893 mode = GET_MODE (mem);
1894
1895 mem = or1k_adjust_atomic_subword (mem, &shift, &mask);
1896
1897 /* Shift and mask VAL into position with the word. */
1898 if (val != const0_rtx)
1899 {
1900 val = convert_modes (SImode, mode, val, 1);
1901 val = expand_binop (SImode, ashl_optab, val, shift,
1902 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1903 }
1904
1905 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1906 emit_label (XEXP (label, 0));
1907
1908 scratch = gen_reg_rtx (SImode);
1909 emit_load_locked (SImode, scratch, mem);
1910
1911 retval = expand_binop (SImode, and_optab, scratch, mask,
1912 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1913 scratch = expand_binop (SImode, xor_optab, scratch, retval,
1914 scratch, 1, OPTAB_LIB_WIDEN);
1915 if (val != const0_rtx)
1916 scratch = expand_binop (SImode, ior_optab, scratch, val,
1917 scratch, 1, OPTAB_LIB_WIDEN);
1918
1919 emit_store_conditional (SImode, mem, scratch);
1920 emit_unlikely_jump (EQ, label);
1921
1922 or1k_finish_atomic_subword (mode, orig_retval, retval, shift);
1923}
1924
1925/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
1926 to perform (with MULT as a stand-in for NAND). MEM is the memory on which
1927 to operate. VAL is the second operand of the binary operator. BEFORE and
1928 AFTER are optional locations to return the value of MEM either before of
1929 after the operation. */
1930
1931void
1932or1k_expand_atomic_op (rtx_code code, rtx mem, rtx val,
1933 rtx orig_before, rtx orig_after)
1934{
1935 machine_mode mode = GET_MODE (mem);
1936 rtx before = orig_before, after = orig_after;
1937 rtx label;
1938
1939 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1940 emit_label (XEXP (label, 0));
1941
1942 if (before == NULL_RTX)
1943 before = gen_reg_rtx (mode);
1944
1945 emit_load_locked (mode, before, mem);
1946
1947 if (code == MULT)
1948 {
1949 after = expand_binop (mode, and_optab, before, val,
1950 after, 1, OPTAB_LIB_WIDEN);
1951 after = expand_unop (mode, one_cmpl_optab, after, after, 1);
1952 }
1953 else
1954 after = expand_simple_binop (mode, code, before, val,
1955 after, 1, OPTAB_LIB_WIDEN);
1956
1957 emit_store_conditional (mode, mem, after);
1958 emit_unlikely_jump (EQ, label);
1959
1960 if (orig_before)
1961 emit_move_insn (orig_before, before);
1962 if (orig_after)
1963 emit_move_insn (orig_after, after);
1964}
1965
1966void
1967or1k_expand_atomic_op_qihi (rtx_code code, rtx mem, rtx val,
1968 rtx orig_before, rtx orig_after)
1969{
1970 machine_mode mode = GET_MODE (mem);
1971 rtx label, mask, shift, x;
1972 rtx before, after, scratch;
1973
1974 mem = or1k_adjust_atomic_subword (mem, &shift, &mask);
1975
1976 /* Shift and mask VAL into position with the word. */
1977 val = convert_modes (SImode, mode, val, 1);
1978 val = expand_binop (SImode, ashl_optab, val, shift,
1979 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1980
1981 switch (code)
1982 {
1983 case IOR:
1984 case XOR:
1985 /* We've already zero-extended VAL. That is sufficient to
1986 make certain that it does not affect other bits. */
1987 break;
1988
1989 case AND:
1990 case MULT: /* NAND */
1991 /* If we make certain that all of the other bits in VAL are
1992 set, that will be sufficient to not affect other bits. */
1993 x = expand_unop (SImode, one_cmpl_optab, mask, NULL_RTX, 1);
1994 val = expand_binop (SImode, ior_optab, val, x,
1995 val, 1, OPTAB_LIB_WIDEN);
1996 break;
1997
1998 case PLUS:
1999 case MINUS:
2000 /* These will all affect bits outside the field and need
2001 adjustment via MASK within the loop. */
2002 break;
2003
2004 default:
2005 gcc_unreachable ();
2006 }
2007
2008 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
2009 emit_label (XEXP (label, 0));
2010
2011 before = scratch = gen_reg_rtx (SImode);
2012 emit_load_locked (SImode, before, mem);
2013
2014 switch (code)
2015 {
2016 case IOR:
2017 case XOR:
2018 case AND:
2019 after = expand_simple_binop (SImode, code, before, val,
2020 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2021 scratch = after;
2022 break;
2023
2024 case PLUS:
2025 case MINUS:
2026 before = expand_binop (SImode, and_optab, scratch, mask,
2027 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2028 scratch = expand_binop (SImode, xor_optab, scratch, before,
2029 scratch, 1, OPTAB_LIB_WIDEN);
2030 after = expand_simple_binop (SImode, code, before, val,
2031 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2032 after = expand_binop (SImode, and_optab, after, mask,
2033 after, 1, OPTAB_LIB_WIDEN);
2034 scratch = expand_binop (SImode, ior_optab, scratch, after,
2035 scratch, 1, OPTAB_LIB_WIDEN);
2036 break;
2037
2038 case MULT: /* NAND */
2039 after = expand_binop (SImode, and_optab, before, val,
2040 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2041 after = expand_binop (SImode, xor_optab, after, mask,
2042 after, 1, OPTAB_LIB_WIDEN);
2043 scratch = after;
2044 break;
2045
2046 default:
2047 gcc_unreachable ();
2048 }
2049
2050 emit_store_conditional (SImode, mem, scratch);
2051 emit_unlikely_jump (EQ, label);
2052
2053 if (orig_before)
2054 or1k_finish_atomic_subword (mode, orig_before, before, shift);
2055 if (orig_after)
2056 or1k_finish_atomic_subword (mode, orig_after, after, shift);
2057}
2058
2059/* Worker for TARGET_ASM_OUTPUT_MI_THUNK.
2060 Output the assembler code for a thunk function. THUNK_DECL is the
2061 declaration for the thunk function itself, FUNCTION is the decl for
2062 the target function. DELTA is an immediate constant offset to be
2063 added to THIS. If VCALL_OFFSET is nonzero, the word at address
2064 (*THIS + VCALL_OFFSET) should be additionally added to THIS. */
2065
2066static void
f7430263 2067or1k_output_mi_thunk (FILE *file, tree thunk_fndecl,
3965b35f
SH
2068 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
2069 tree function)
2070{
f7430263 2071 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
3965b35f
SH
2072 rtx this_rtx, funexp;
2073 rtx_insn *insn;
2074
2075 reload_completed = 1;
2076 epilogue_completed = 1;
2077
2078 emit_note (NOTE_INSN_PROLOGUE_END);
2079
2080 /* Find the "this" pointer. Normally in r3, but if the function
2081 returns a structure, the structure return pointer is in r3 and
2082 the "this" pointer is in r4 instead. */
2083 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
2084 this_rtx = gen_rtx_REG (Pmode, 4);
2085 else
2086 this_rtx = gen_rtx_REG (Pmode, 3);
2087
2088 /* Add DELTA. When possible use a plain add, otherwise load it
2089 into a register first. */
2090 if (delta)
2091 {
2092 rtx delta_rtx = GEN_INT (delta);
2093
2094 if (!satisfies_constraint_I (delta_rtx))
2095 {
2096 rtx scratch = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
2097 emit_move_insn (scratch, delta_rtx);
2098 delta_rtx = scratch;
2099 }
2100
2101 /* THIS_RTX += DELTA. */
2102 emit_insn (gen_add2_insn (this_rtx, delta_rtx));
2103 }
2104
2105 /* Add the word at address (*THIS_RTX + VCALL_OFFSET). */
2106 if (vcall_offset)
2107 {
2108 rtx scratch = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
2109 HOST_WIDE_INT lo = sext_hwi (vcall_offset, 16);
2110 HOST_WIDE_INT hi = vcall_offset - lo;
2111 rtx tmp;
2112
2113 /* SCRATCH = *THIS_RTX. */
2114 tmp = gen_rtx_MEM (Pmode, this_rtx);
2115 emit_move_insn (scratch, tmp);
2116
2117 if (hi != 0)
2118 {
2119 rtx scratch2 = gen_rtx_REG (Pmode, RV_REGNUM);
2120 emit_move_insn (scratch2, GEN_INT (hi));
2121 emit_insn (gen_add2_insn (scratch, scratch2));
2122 }
2123
2124 /* SCRATCH = *(*THIS_RTX + VCALL_OFFSET). */
2125 tmp = plus_constant (Pmode, scratch, lo);
2126 tmp = gen_rtx_MEM (Pmode, tmp);
2127 emit_move_insn (scratch, tmp);
2128
2129 /* THIS_RTX += *(*THIS_RTX + VCALL_OFFSET). */
2130 emit_insn (gen_add2_insn (this_rtx, scratch));
2131 }
2132
2133 /* Generate a tail call to the target function. */
2134 if (!TREE_USED (function))
2135 {
2136 assemble_external (function);
2137 TREE_USED (function) = 1;
2138 }
2139 funexp = XEXP (DECL_RTL (function), 0);
2140
2141 /* The symbol will be a local alias and therefore always binds local. */
2142 gcc_assert (SYMBOL_REF_LOCAL_P (funexp));
2143
2144 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
2145 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
2146 SIBLING_CALL_P (insn) = 1;
2147 emit_barrier ();
2148
2149 /* Run just enough of rest_of_compilation to get the insns emitted.
2150 There's not really enough bulk here to make other passes such as
8b4e7143 2151 instruction scheduling worth while. */
3965b35f
SH
2152 insn = get_insns ();
2153 shorten_branches (insn);
f7430263 2154 assemble_start_function (thunk_fndecl, fnname);
3965b35f
SH
2155 final_start_function (insn, file, 1);
2156 final (insn, file, 1);
2157 final_end_function ();
f7430263 2158 assemble_end_function (thunk_fndecl, fnname);
3965b35f
SH
2159
2160 reload_completed = 0;
2161 epilogue_completed = 0;
2162}
2163
2164#undef TARGET_ASM_OUTPUT_MI_THUNK
2165#define TARGET_ASM_OUTPUT_MI_THUNK or1k_output_mi_thunk
2166#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
2167#define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
2168 hook_bool_const_tree_hwi_hwi_const_tree_true
2169
2170#undef TARGET_OPTION_OVERRIDE
2171#define TARGET_OPTION_OVERRIDE or1k_option_override
2172
2173#undef TARGET_COMPUTE_FRAME_LAYOUT
2174#define TARGET_COMPUTE_FRAME_LAYOUT or1k_compute_frame_layout
2175
2176#undef TARGET_LEGITIMATE_ADDRESS_P
2177#define TARGET_LEGITIMATE_ADDRESS_P or1k_legitimate_address_p
2178
2179#undef TARGET_HAVE_TLS
2180#define TARGET_HAVE_TLS true
2181
2182#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
2183#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
2184
2185/* Calling Conventions. */
2186#undef TARGET_FUNCTION_VALUE
2187#define TARGET_FUNCTION_VALUE or1k_function_value
2188#undef TARGET_LIBCALL_VALUE
2189#define TARGET_LIBCALL_VALUE or1k_libcall_value
2190#undef TARGET_FUNCTION_VALUE_REGNO_P
2191#define TARGET_FUNCTION_VALUE_REGNO_P or1k_function_value_regno_p
2192#undef TARGET_FUNCTION_ARG
2193#define TARGET_FUNCTION_ARG or1k_function_arg
2194#undef TARGET_FUNCTION_ARG_ADVANCE
2195#define TARGET_FUNCTION_ARG_ADVANCE or1k_function_arg_advance
2196#undef TARGET_RETURN_IN_MEMORY
2197#define TARGET_RETURN_IN_MEMORY or1k_return_in_memory
2198#undef TARGET_PASS_BY_REFERENCE
2199#define TARGET_PASS_BY_REFERENCE or1k_pass_by_reference
2200#undef TARGET_TRAMPOLINE_INIT
2201#define TARGET_TRAMPOLINE_INIT or1k_trampoline_init
2202#undef TARGET_FRAME_POINTER_REQUIRED
2203#define TARGET_FRAME_POINTER_REQUIRED or1k_frame_pointer_required
2204#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
2205#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
2206
2207/* Assembly generation. */
2208#undef TARGET_PRINT_OPERAND
2209#define TARGET_PRINT_OPERAND or1k_print_operand
2210#undef TARGET_PRINT_OPERAND_ADDRESS
2211#define TARGET_PRINT_OPERAND_ADDRESS or1k_print_operand_address
2212
2213/* Section anchor support. */
2214#undef TARGET_MIN_ANCHOR_OFFSET
2215#define TARGET_MIN_ANCHOR_OFFSET -32768
2216#undef TARGET_MAX_ANCHOR_OFFSET
2217#define TARGET_MAX_ANCHOR_OFFSET 32767
2218
2219struct gcc_target targetm = TARGET_INITIALIZER;
2220
2221#include "gt-or1k.h"