1 /* Target Code for moxie
2    Copyright (C) 2008-2019 Free Software Foundation, Inc.
3    Contributed by Anthony Green.
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 
44 /* This file should be included last.  */
45 #include "target-def.h"
46 
47 #define LOSE_AND_RETURN(msgid, x)		\
48   do						\
49     {						\
50       moxie_operand_lossage (msgid, x);		\
51       return;					\
52     } while (0)
53 
54 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
55 
56 static bool
moxie_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)57 moxie_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
58 {
59   const HOST_WIDE_INT size = int_size_in_bytes (type);
60   return (size == -1 || size > 2 * UNITS_PER_WORD);
61 }
62 
63 /* Define how to find the value returned by a function.
64    VALTYPE is the data type of the value (as a tree).
65    If the precise function being called is known, FUNC is its
66    FUNCTION_DECL; otherwise, FUNC is 0.
67 
68    We always return values in register $r0 for moxie.  */
69 
70 static rtx
moxie_function_value(const_tree valtype,const_tree fntype_or_decl ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)71 moxie_function_value (const_tree valtype,
72 		      const_tree fntype_or_decl ATTRIBUTE_UNUSED,
73 		      bool outgoing ATTRIBUTE_UNUSED)
74 {
75   return gen_rtx_REG (TYPE_MODE (valtype), MOXIE_R0);
76 }
77 
78 /* Define how to find the value returned by a library function.
79 
80    We always return values in register $r0 for moxie.  */
81 
82 static rtx
moxie_libcall_value(machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)83 moxie_libcall_value (machine_mode mode,
84                      const_rtx fun ATTRIBUTE_UNUSED)
85 {
86   return gen_rtx_REG (mode, MOXIE_R0);
87 }
88 
89 /* Handle TARGET_FUNCTION_VALUE_REGNO_P.
90 
91    We always return values in register $r0 for moxie.  */
92 
93 static bool
moxie_function_value_regno_p(const unsigned int regno)94 moxie_function_value_regno_p (const unsigned int regno)
95 {
96   return (regno == MOXIE_R0);
97 }
98 
99 /* Emit an error message when we're in an asm, and a fatal error for
100    "normal" insns.  Formatted output isn't easily implemented, since we
101    use output_operand_lossage to output the actual message and handle the
102    categorization of the error.  */
103 
104 static void
moxie_operand_lossage(const char * msgid,rtx op)105 moxie_operand_lossage (const char *msgid, rtx op)
106 {
107   debug_rtx (op);
108   output_operand_lossage ("%s", msgid);
109 }
110 
111 /* The PRINT_OPERAND_ADDRESS worker.  */
112 
113 static void
moxie_print_operand_address(FILE * file,machine_mode,rtx x)114 moxie_print_operand_address (FILE *file, machine_mode, rtx x)
115 {
116   switch (GET_CODE (x))
117     {
118     case REG:
119       fprintf (file, "(%s)", reg_names[REGNO (x)]);
120       break;
121 
122     case PLUS:
123       switch (GET_CODE (XEXP (x, 1)))
124 	{
125 	case CONST_INT:
126 	  fprintf (file, "%ld(%s)",
127 		   INTVAL(XEXP (x, 1)), reg_names[REGNO (XEXP (x, 0))]);
128 	  break;
129 	case SYMBOL_REF:
130 	  output_addr_const (file, XEXP (x, 1));
131 	  fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
132 	  break;
133 	case CONST:
134 	  {
135 	    rtx plus = XEXP (XEXP (x, 1), 0);
136 	    if (GET_CODE (XEXP (plus, 0)) == SYMBOL_REF
137 		&& CONST_INT_P (XEXP (plus, 1)))
138 	      {
139 		output_addr_const(file, XEXP (plus, 0));
140 		fprintf (file,"+%ld(%s)", INTVAL (XEXP (plus, 1)),
141 			 reg_names[REGNO (XEXP (x, 0))]);
142 	      }
143 	    else
144 	      abort();
145 	  }
146 	  break;
147 	default:
148 	  abort();
149 	}
150       break;
151 
152     default:
153       output_addr_const (file, x);
154       break;
155     }
156 }
157 
158 /* The PRINT_OPERAND worker.  */
159 
160 static void
moxie_print_operand(FILE * file,rtx x,int code)161 moxie_print_operand (FILE *file, rtx x, int code)
162 {
163   rtx operand = x;
164 
165   /* New code entries should just be added to the switch below.  If
166      handling is finished, just return.  If handling was just a
167      modification of the operand, the modified operand should be put in
168      "operand", and then do a break to let default handling
169      (zero-modifier) output the operand.  */
170 
171   switch (code)
172     {
173     case 0:
174       /* No code, print as usual.  */
175       break;
176 
177     default:
178       LOSE_AND_RETURN ("invalid operand modifier letter", x);
179     }
180 
181   /* Print an operand as without a modifier letter.  */
182   switch (GET_CODE (operand))
183     {
184     case REG:
185       if (REGNO (operand) > MOXIE_R13)
186 	internal_error ("internal error: bad register: %d", REGNO (operand));
187       fprintf (file, "%s", reg_names[REGNO (operand)]);
188       return;
189 
190     case MEM:
191       output_address (GET_MODE (XEXP (operand, 0)), XEXP (operand, 0));
192       return;
193 
194     default:
195       /* No need to handle all strange variants, let output_addr_const
196 	 do it for us.  */
197       if (CONSTANT_P (operand))
198 	{
199 	  output_addr_const (file, operand);
200 	  return;
201 	}
202 
203       LOSE_AND_RETURN ("unexpected operand", x);
204     }
205 }
206 
207 /* Per-function machine data.  */
208 struct GTY(()) machine_function
209  {
210    /* Number of bytes saved on the stack for callee saved registers.  */
211    int callee_saved_reg_size;
212 
213    /* Number of bytes saved on the stack for local variables.  */
214    int local_vars_size;
215 
216    /* The sum of 2 sizes: locals vars and padding byte for saving the
217     * registers.  Used in expand_prologue () and expand_epilogue().  */
218    int size_for_adjusting_sp;
219  };
220 
221 /* Zero initialization is OK for all current fields.  */
222 
223 static struct machine_function *
moxie_init_machine_status(void)224 moxie_init_machine_status (void)
225 {
226   return ggc_cleared_alloc<machine_function> ();
227 }
228 
229 
230 /* The TARGET_OPTION_OVERRIDE worker.  */
231 static void
moxie_option_override(void)232 moxie_option_override (void)
233 {
234   /* Set the per-function-data initializer.  */
235   init_machine_status = moxie_init_machine_status;
236 
237 #ifdef TARGET_MOXIEBOX
238   target_flags |= MASK_HAS_MULX;
239 #endif
240 }
241 
242 /* Compute the size of the local area and the size to be adjusted by the
243  * prologue and epilogue.  */
244 
245 static void
moxie_compute_frame(void)246 moxie_compute_frame (void)
247 {
248   /* For aligning the local variables.  */
249   int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
250   int padding_locals;
251   int regno;
252 
253   /* Padding needed for each element of the frame.  */
254   cfun->machine->local_vars_size = get_frame_size ();
255 
256   /* Align to the stack alignment.  */
257   padding_locals = cfun->machine->local_vars_size % stack_alignment;
258   if (padding_locals)
259     padding_locals = stack_alignment - padding_locals;
260 
261   cfun->machine->local_vars_size += padding_locals;
262 
263   cfun->machine->callee_saved_reg_size = 0;
264 
265   /* Save callee-saved registers.  */
266   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
267     if (df_regs_ever_live_p (regno) && (! call_used_regs[regno]))
268       cfun->machine->callee_saved_reg_size += 4;
269 
270   cfun->machine->size_for_adjusting_sp =
271     crtl->args.pretend_args_size
272     + cfun->machine->local_vars_size
273     + (ACCUMULATE_OUTGOING_ARGS
274        ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0);
275 }
276 
277 void
moxie_expand_prologue(void)278 moxie_expand_prologue (void)
279 {
280   int regno;
281   rtx insn;
282 
283   moxie_compute_frame ();
284 
285   if (flag_stack_usage_info)
286     current_function_static_stack_size = cfun->machine->size_for_adjusting_sp;
287 
288   /* Save callee-saved registers.  */
289   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
290     {
291       if (!fixed_regs[regno] && df_regs_ever_live_p (regno) && !call_used_regs[regno])
292 	{
293 	  insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
294 	  RTX_FRAME_RELATED_P (insn) = 1;
295 	}
296     }
297 
298   if (cfun->machine->size_for_adjusting_sp > 0)
299     {
300       int i = cfun->machine->size_for_adjusting_sp;
301       while ((i >= 255) && (i <= 510))
302 	{
303 	  insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
304 					stack_pointer_rtx,
305 					GEN_INT (255)));
306 	  RTX_FRAME_RELATED_P (insn) = 1;
307 	  i -= 255;
308 	}
309       if (i <= 255)
310 	{
311 	  insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
312 					stack_pointer_rtx,
313 					GEN_INT (i)));
314 	  RTX_FRAME_RELATED_P (insn) = 1;
315 	}
316       else
317 	{
318 	  rtx reg = gen_rtx_REG (SImode, MOXIE_R12);
319 	  insn = emit_move_insn (reg, GEN_INT (i));
320 	  RTX_FRAME_RELATED_P (insn) = 1;
321 	  insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
322 					stack_pointer_rtx,
323 					reg));
324 	  RTX_FRAME_RELATED_P (insn) = 1;
325 	}
326     }
327 }
328 
329 void
moxie_expand_epilogue(void)330 moxie_expand_epilogue (void)
331 {
332   int regno;
333   rtx reg;
334 
335   if (cfun->machine->callee_saved_reg_size != 0)
336     {
337       reg = gen_rtx_REG (Pmode, MOXIE_R12);
338       if (cfun->machine->callee_saved_reg_size <= 255)
339 	{
340 	  emit_move_insn (reg, hard_frame_pointer_rtx);
341 	  emit_insn (gen_subsi3
342 		     (reg, reg,
343 		      GEN_INT (cfun->machine->callee_saved_reg_size)));
344 	}
345       else
346 	{
347 	  emit_move_insn (reg,
348 			  GEN_INT (-cfun->machine->callee_saved_reg_size));
349 	  emit_insn (gen_addsi3 (reg, reg, hard_frame_pointer_rtx));
350 	}
351       for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0; )
352 	if (!fixed_regs[regno] && !call_used_regs[regno]
353 	    && df_regs_ever_live_p (regno))
354 	  {
355 	    rtx preg = gen_rtx_REG (Pmode, regno);
356 	    emit_insn (gen_movsi_pop (reg, preg));
357 	  }
358     }
359 
360   emit_jump_insn (gen_returner ());
361 }
362 
363 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET.  */
364 
365 int
moxie_initial_elimination_offset(int from,int to)366 moxie_initial_elimination_offset (int from, int to)
367 {
368   int ret;
369 
370   if ((from) == FRAME_POINTER_REGNUM && (to) == HARD_FRAME_POINTER_REGNUM)
371     {
372       /* Compute this since we need to use cfun->machine->local_vars_size.  */
373       moxie_compute_frame ();
374       ret = -cfun->machine->callee_saved_reg_size;
375     }
376   else if ((from) == ARG_POINTER_REGNUM && (to) == HARD_FRAME_POINTER_REGNUM)
377     ret = 0x00;
378   else
379     abort ();
380 
381   return ret;
382 }
383 
384 /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
385 
386 static void
moxie_setup_incoming_varargs(cumulative_args_t cum_v,machine_mode mode ATTRIBUTE_UNUSED,tree type ATTRIBUTE_UNUSED,int * pretend_size,int no_rtl)387 moxie_setup_incoming_varargs (cumulative_args_t cum_v,
388 			      machine_mode mode ATTRIBUTE_UNUSED,
389 			      tree type ATTRIBUTE_UNUSED,
390 			      int *pretend_size, int no_rtl)
391 {
392   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
393   int regno;
394   int regs = 8 - *cum;
395 
396   *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs;
397 
398   if (no_rtl)
399     return;
400 
401   for (regno = *cum; regno < 8; regno++)
402     {
403       rtx reg = gen_rtx_REG (SImode, regno);
404       rtx slot = gen_rtx_PLUS (Pmode,
405 			       gen_rtx_REG (SImode, ARG_POINTER_REGNUM),
406 			       GEN_INT (UNITS_PER_WORD * (3 + (regno-2))));
407 
408       emit_move_insn (gen_rtx_MEM (SImode, slot), reg);
409     }
410 }
411 
412 
413 /* Return the fixed registers used for condition codes.  */
414 
415 static bool
moxie_fixed_condition_code_regs(unsigned int * p1,unsigned int * p2)416 moxie_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
417 {
418   *p1 = CC_REG;
419   *p2 = INVALID_REGNUM;
420   return true;
421 }
422 
423 /* Return the next register to be used to hold a function argument or
424    NULL_RTX if there's no more space.  */
425 
426 static rtx
moxie_function_arg(cumulative_args_t cum_v,machine_mode mode,const_tree type ATTRIBUTE_UNUSED,bool named ATTRIBUTE_UNUSED)427 moxie_function_arg (cumulative_args_t cum_v, machine_mode mode,
428 		    const_tree type ATTRIBUTE_UNUSED,
429 		    bool named ATTRIBUTE_UNUSED)
430 {
431   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
432 
433   if (*cum < 8)
434     return gen_rtx_REG (mode, *cum);
435   else
436     return NULL_RTX;
437 }
438 
439 #define MOXIE_FUNCTION_ARG_SIZE(MODE, TYPE)	\
440   ((MODE) != BLKmode ? GET_MODE_SIZE (MODE)	\
441    : (unsigned) int_size_in_bytes (TYPE))
442 
443 static void
moxie_function_arg_advance(cumulative_args_t cum_v,machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)444 moxie_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
445 			    const_tree type, bool named ATTRIBUTE_UNUSED)
446 {
447   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
448 
449   *cum = (*cum < MOXIE_R6
450 	  ? *cum + ((3 + MOXIE_FUNCTION_ARG_SIZE (mode, type)) / 4)
451 	  : *cum);
452 }
453 
454 /* Return non-zero if the function argument described by TYPE is to be
455    passed by reference.  */
456 
457 static bool
moxie_pass_by_reference(cumulative_args_t cum ATTRIBUTE_UNUSED,machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)458 moxie_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
459 			 machine_mode mode, const_tree type,
460 			 bool named ATTRIBUTE_UNUSED)
461 {
462   unsigned HOST_WIDE_INT size;
463 
464   if (type)
465     {
466       if (AGGREGATE_TYPE_P (type))
467 	return true;
468       size = int_size_in_bytes (type);
469     }
470   else
471     size = GET_MODE_SIZE (mode);
472 
473   return size > 4*6;
474 }
475 
476 /* Some function arguments will only partially fit in the registers
477    that hold arguments.  Given a new arg, return the number of bytes
478    that fit in argument passing registers.  */
479 
480 static int
moxie_arg_partial_bytes(cumulative_args_t cum_v,machine_mode mode,tree type,bool named)481 moxie_arg_partial_bytes (cumulative_args_t cum_v,
482 			 machine_mode mode,
483 			 tree type, bool named)
484 {
485   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
486   int bytes_left, size;
487 
488   if (*cum >= 8)
489     return 0;
490 
491   if (moxie_pass_by_reference (cum_v, mode, type, named))
492     size = 4;
493   else if (type)
494     {
495       if (AGGREGATE_TYPE_P (type))
496 	return 0;
497       size = int_size_in_bytes (type);
498     }
499   else
500     size = GET_MODE_SIZE (mode);
501 
502   bytes_left = (4 * 6) - ((*cum - 2) * 4);
503 
504   if (size > bytes_left)
505     return bytes_left;
506   else
507     return 0;
508 }
509 
510 /* Worker function for TARGET_STATIC_CHAIN.  */
511 
512 static rtx
moxie_static_chain(const_tree ARG_UNUSED (fndecl_or_type),bool incoming_p)513 moxie_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
514 {
515   rtx addr, mem;
516 
517   if (incoming_p)
518     addr = plus_constant (Pmode, arg_pointer_rtx, 2 * UNITS_PER_WORD);
519   else
520     addr = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
521 
522   mem = gen_rtx_MEM (Pmode, addr);
523   MEM_NOTRAP_P (mem) = 1;
524 
525   return mem;
526 }
527 
528 /* Worker function for TARGET_ASM_TRAMPOLINE_TEMPLATE.  */
529 
530 static void
moxie_asm_trampoline_template(FILE * f)531 moxie_asm_trampoline_template (FILE *f)
532 {
533   fprintf (f, "\tpush  $sp, $r0\n");
534   fprintf (f, "\tldi.l $r0, 0x0\n");
535   fprintf (f, "\tsto.l 0x8($fp), $r0\n");
536   fprintf (f, "\tpop   $sp, $r0\n");
537   fprintf (f, "\tjmpa  0x0\n");
538 }
539 
540 /* Worker function for TARGET_TRAMPOLINE_INIT.  */
541 
542 static void
moxie_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)543 moxie_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
544 {
545   rtx mem, fnaddr = XEXP (DECL_RTL (fndecl), 0);
546 
547   emit_block_move (m_tramp, assemble_trampoline_template (),
548 		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
549 
550   mem = adjust_address (m_tramp, SImode, 4);
551   emit_move_insn (mem, chain_value);
552   mem = adjust_address (m_tramp, SImode, 16);
553   emit_move_insn (mem, fnaddr);
554 }
555 
556 /* Return true for memory offset addresses between -32768 and 32767.  */
557 bool
moxie_offset_address_p(rtx x)558 moxie_offset_address_p (rtx x)
559 {
560   x = XEXP (x, 0);
561 
562   if (GET_CODE (x) == PLUS)
563     {
564       x = XEXP (x, 1);
565       if (GET_CODE (x) == CONST_INT)
566 	{
567 	  unsigned int v = INTVAL (x) & 0xFFFF8000;
568 	  return (v == 0xFFFF8000 || v == 0x00000000);
569 	}
570     }
571   return 0;
572 }
573 
574 /* Helper function for `moxie_legitimate_address_p'.  */
575 
576 static bool
moxie_reg_ok_for_base_p(const_rtx reg,bool strict_p)577 moxie_reg_ok_for_base_p (const_rtx reg, bool strict_p)
578 {
579   int regno = REGNO (reg);
580 
581   if (strict_p)
582     return HARD_REGNO_OK_FOR_BASE_P (regno)
583 	   || HARD_REGNO_OK_FOR_BASE_P (reg_renumber[regno]);
584   else
585     return !HARD_REGISTER_NUM_P (regno)
586 	   || HARD_REGNO_OK_FOR_BASE_P (regno);
587 }
588 
589 /* Worker function for TARGET_LEGITIMATE_ADDRESS_P.  */
590 
591 static bool
moxie_legitimate_address_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x,bool strict_p,addr_space_t as)592 moxie_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
593 			    rtx x, bool strict_p,
594 			    addr_space_t as)
595 {
596   gcc_assert (ADDR_SPACE_GENERIC_P (as));
597 
598   if (GET_CODE(x) == PLUS
599       && REG_P (XEXP (x, 0))
600       && moxie_reg_ok_for_base_p (XEXP (x, 0), strict_p)
601       && CONST_INT_P (XEXP (x, 1))
602       && IN_RANGE (INTVAL (XEXP (x, 1)), -32768, 32767))
603     return true;
604   if (REG_P (x) && moxie_reg_ok_for_base_p (x, strict_p))
605     return true;
606   if (GET_CODE (x) == SYMBOL_REF
607       || GET_CODE (x) == LABEL_REF
608       || GET_CODE (x) == CONST)
609     return true;
610   return false;
611 }
612 
613 /* The Global `targetm' Variable.  */
614 
615 /* Initialize the GCC target structure.  */
616 
617 #undef  TARGET_PROMOTE_PROTOTYPES
618 #define TARGET_PROMOTE_PROTOTYPES	hook_bool_const_tree_true
619 
620 #undef  TARGET_RETURN_IN_MEMORY
621 #define TARGET_RETURN_IN_MEMORY		moxie_return_in_memory
622 #undef  TARGET_MUST_PASS_IN_STACK
623 #define TARGET_MUST_PASS_IN_STACK	must_pass_in_stack_var_size
624 #undef  TARGET_PASS_BY_REFERENCE
625 #define TARGET_PASS_BY_REFERENCE        moxie_pass_by_reference
626 #undef  TARGET_ARG_PARTIAL_BYTES
627 #define TARGET_ARG_PARTIAL_BYTES        moxie_arg_partial_bytes
628 #undef  TARGET_FUNCTION_ARG
629 #define TARGET_FUNCTION_ARG		moxie_function_arg
630 #undef  TARGET_FUNCTION_ARG_ADVANCE
631 #define TARGET_FUNCTION_ARG_ADVANCE	moxie_function_arg_advance
632 
633 #undef TARGET_LRA_P
634 #define TARGET_LRA_P hook_bool_void_false
635 
636 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
637 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P	moxie_legitimate_address_p
638 
639 #undef  TARGET_SETUP_INCOMING_VARARGS
640 #define TARGET_SETUP_INCOMING_VARARGS 	moxie_setup_incoming_varargs
641 
642 #undef	TARGET_FIXED_CONDITION_CODE_REGS
643 #define	TARGET_FIXED_CONDITION_CODE_REGS moxie_fixed_condition_code_regs
644 
645 /* Define this to return an RTX representing the place where a
646    function returns or receives a value of data type RET_TYPE, a tree
647    node representing a data type.  */
648 #undef TARGET_FUNCTION_VALUE
649 #define TARGET_FUNCTION_VALUE moxie_function_value
650 #undef TARGET_LIBCALL_VALUE
651 #define TARGET_LIBCALL_VALUE moxie_libcall_value
652 #undef TARGET_FUNCTION_VALUE_REGNO_P
653 #define TARGET_FUNCTION_VALUE_REGNO_P moxie_function_value_regno_p
654 
655 #undef TARGET_FRAME_POINTER_REQUIRED
656 #define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_true
657 
658 #undef TARGET_STATIC_CHAIN
659 #define TARGET_STATIC_CHAIN moxie_static_chain
660 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
661 #define TARGET_ASM_TRAMPOLINE_TEMPLATE moxie_asm_trampoline_template
662 #undef TARGET_TRAMPOLINE_INIT
663 #define TARGET_TRAMPOLINE_INIT moxie_trampoline_init
664 
665 #undef TARGET_OPTION_OVERRIDE
666 #define TARGET_OPTION_OVERRIDE moxie_option_override
667 
668 #undef  TARGET_PRINT_OPERAND
669 #define TARGET_PRINT_OPERAND moxie_print_operand
670 #undef  TARGET_PRINT_OPERAND_ADDRESS
671 #define TARGET_PRINT_OPERAND_ADDRESS moxie_print_operand_address
672 
673 #undef  TARGET_CONSTANT_ALIGNMENT
674 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
675 
676 struct gcc_target targetm = TARGET_INITIALIZER;
677 
678 #include "gt-moxie.h"
679