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