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