xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/mmix/mmix.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1 /* Definitions of target machine for GNU compiler, for MMIX.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3    Free Software Foundation, Inc.
4    Contributed by Hans-Peter Nilsson (hp@bitrange.com)
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12 
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "hashtab.h"
30 #include "insn-config.h"
31 #include "output.h"
32 #include "flags.h"
33 #include "tree.h"
34 #include "function.h"
35 #include "expr.h"
36 #include "toplev.h"
37 #include "recog.h"
38 #include "ggc.h"
39 #include "dwarf2.h"
40 #include "debug.h"
41 #include "tm_p.h"
42 #include "integrate.h"
43 #include "target.h"
44 #include "target-def.h"
45 #include "real.h"
46 
47 /* First some local helper definitions.  */
48 #define MMIX_FIRST_GLOBAL_REGNUM 32
49 
50 /* We'd need a current_function_has_landing_pad.  It's marked as such when
51    a nonlocal_goto_receiver is expanded.  Not just a C++ thing, but
52    mostly.  */
53 #define MMIX_CFUN_HAS_LANDING_PAD (cfun->machine->has_landing_pad != 0)
54 
55 /* We have no means to tell DWARF 2 about the register stack, so we need
56    to store the return address on the stack if an exception can get into
57    this function.  FIXME: Narrow condition.  Before any whole-function
58    analysis, df_regs_ever_live_p () isn't initialized.  We know it's up-to-date
59    after reload_completed; it may contain incorrect information some time
60    before that.  Within a RTL sequence (after a call to start_sequence,
61    such as in RTL expanders), leaf_function_p doesn't see all insns
62    (perhaps any insn).  But regs_ever_live is up-to-date when
63    leaf_function_p () isn't, so we "or" them together to get accurate
64    information.  FIXME: Some tweak to leaf_function_p might be
65    preferable.  */
66 #define MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS			\
67  (flag_exceptions						\
68   && ((reload_completed && df_regs_ever_live_p (MMIX_rJ_REGNUM))	\
69       || !leaf_function_p ()))
70 
71 #define IS_MMIX_EH_RETURN_DATA_REG(REGNO)	\
72  (crtl->calls_eh_return		\
73   && (EH_RETURN_DATA_REGNO (0) == REGNO		\
74       || EH_RETURN_DATA_REGNO (1) == REGNO	\
75       || EH_RETURN_DATA_REGNO (2) == REGNO	\
76       || EH_RETURN_DATA_REGNO (3) == REGNO))
77 
78 /* For the default ABI, we rename registers at output-time to fill the gap
79    between the (statically partitioned) saved registers and call-clobbered
80    registers.  In effect this makes unused call-saved registers to be used
81    as call-clobbered registers.  The benefit comes from keeping the number
82    of local registers (value of rL) low, since there's a cost of
83    increasing rL and clearing unused (unset) registers with lower numbers.
84    Don't translate while outputting the prologue.  */
85 #define MMIX_OUTPUT_REGNO(N)					\
86  (TARGET_ABI_GNU 						\
87   || (int) (N) < MMIX_RETURN_VALUE_REGNUM			\
88   || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM		\
89   || cfun == NULL 						\
90   || cfun->machine == NULL 					\
91   || cfun->machine->in_prologue					\
92   ? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM			\
93 	   + cfun->machine->highest_saved_stack_register + 1))
94 
95 /* The %d in "POP %d,0".  */
96 #define MMIX_POP_ARGUMENT()						\
97  ((! TARGET_ABI_GNU							\
98    && crtl->return_rtx != NULL				\
99    && ! cfun->returns_struct)				\
100   ? (GET_CODE (crtl->return_rtx) == PARALLEL			\
101      ? GET_NUM_ELEM (XVEC (crtl->return_rtx, 0)) : 1)	\
102   : 0)
103 
104 /* The canonical saved comparison operands for non-cc0 machines, set in
105    the compare expander.  */
106 rtx mmix_compare_op0;
107 rtx mmix_compare_op1;
108 
109 /* Declarations of locals.  */
110 
111 /* Intermediate for insn output.  */
112 static int mmix_output_destination_register;
113 
114 static void mmix_output_shiftvalue_op_from_str
115   (FILE *, const char *, HOST_WIDEST_INT);
116 static void mmix_output_shifted_value (FILE *, HOST_WIDEST_INT);
117 static void mmix_output_condition (FILE *, rtx, int);
118 static HOST_WIDEST_INT mmix_intval (rtx);
119 static void mmix_output_octa (FILE *, HOST_WIDEST_INT, int);
120 static bool mmix_assemble_integer (rtx, unsigned int, int);
121 static struct machine_function *mmix_init_machine_status (void);
122 static void mmix_encode_section_info (tree, rtx, int);
123 static const char *mmix_strip_name_encoding (const char *);
124 static void mmix_emit_sp_add (HOST_WIDE_INT offset);
125 static void mmix_target_asm_function_prologue (FILE *, HOST_WIDE_INT);
126 static void mmix_target_asm_function_end_prologue (FILE *);
127 static void mmix_target_asm_function_epilogue (FILE *, HOST_WIDE_INT);
128 static bool mmix_legitimate_address_p (enum machine_mode, rtx, bool);
129 static void mmix_reorg (void);
130 static void mmix_asm_output_mi_thunk
131   (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
132 static void mmix_setup_incoming_varargs
133   (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
134 static void mmix_file_start (void);
135 static void mmix_file_end (void);
136 static bool mmix_rtx_costs (rtx, int, int, int *, bool);
137 static rtx mmix_struct_value_rtx (tree, int);
138 static enum machine_mode mmix_promote_function_mode (const_tree,
139 						     enum machine_mode,
140 	                                             int *, const_tree, int);
141 static bool mmix_pass_by_reference (CUMULATIVE_ARGS *,
142 				    enum machine_mode, const_tree, bool);
143 static bool mmix_frame_pointer_required (void);
144 static void mmix_asm_trampoline_template (FILE *);
145 static void mmix_trampoline_init (rtx, tree, rtx);
146 
147 /* Target structure macros.  Listed by node.  See `Using and Porting GCC'
148    for a general description.  */
149 
150 /* Node: Function Entry */
151 
152 #undef TARGET_ASM_BYTE_OP
153 #define TARGET_ASM_BYTE_OP NULL
154 #undef TARGET_ASM_ALIGNED_HI_OP
155 #define TARGET_ASM_ALIGNED_HI_OP NULL
156 #undef TARGET_ASM_ALIGNED_SI_OP
157 #define TARGET_ASM_ALIGNED_SI_OP NULL
158 #undef TARGET_ASM_ALIGNED_DI_OP
159 #define TARGET_ASM_ALIGNED_DI_OP NULL
160 #undef TARGET_ASM_INTEGER
161 #define TARGET_ASM_INTEGER mmix_assemble_integer
162 
163 #undef TARGET_ASM_FUNCTION_PROLOGUE
164 #define TARGET_ASM_FUNCTION_PROLOGUE mmix_target_asm_function_prologue
165 
166 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
167 #define TARGET_ASM_FUNCTION_END_PROLOGUE mmix_target_asm_function_end_prologue
168 
169 #undef TARGET_ASM_FUNCTION_EPILOGUE
170 #define TARGET_ASM_FUNCTION_EPILOGUE mmix_target_asm_function_epilogue
171 
172 #undef TARGET_ENCODE_SECTION_INFO
173 #define TARGET_ENCODE_SECTION_INFO  mmix_encode_section_info
174 #undef TARGET_STRIP_NAME_ENCODING
175 #define TARGET_STRIP_NAME_ENCODING  mmix_strip_name_encoding
176 
177 #undef TARGET_ASM_OUTPUT_MI_THUNK
178 #define TARGET_ASM_OUTPUT_MI_THUNK mmix_asm_output_mi_thunk
179 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
180 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
181 #undef TARGET_ASM_FILE_START
182 #define TARGET_ASM_FILE_START mmix_file_start
183 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
184 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
185 #undef TARGET_ASM_FILE_END
186 #define TARGET_ASM_FILE_END mmix_file_end
187 
188 #undef TARGET_RTX_COSTS
189 #define TARGET_RTX_COSTS mmix_rtx_costs
190 #undef TARGET_ADDRESS_COST
191 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
192 
193 #undef TARGET_MACHINE_DEPENDENT_REORG
194 #define TARGET_MACHINE_DEPENDENT_REORG mmix_reorg
195 
196 #undef TARGET_PROMOTE_FUNCTION_MODE
197 #define TARGET_PROMOTE_FUNCTION_MODE mmix_promote_function_mode
198 
199 
200 #undef TARGET_STRUCT_VALUE_RTX
201 #define TARGET_STRUCT_VALUE_RTX mmix_struct_value_rtx
202 #undef TARGET_SETUP_INCOMING_VARARGS
203 #define TARGET_SETUP_INCOMING_VARARGS mmix_setup_incoming_varargs
204 #undef TARGET_PASS_BY_REFERENCE
205 #define TARGET_PASS_BY_REFERENCE mmix_pass_by_reference
206 #undef TARGET_CALLEE_COPIES
207 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
208 #undef TARGET_DEFAULT_TARGET_FLAGS
209 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
210 
211 #undef TARGET_LEGITIMATE_ADDRESS_P
212 #define TARGET_LEGITIMATE_ADDRESS_P	mmix_legitimate_address_p
213 
214 #undef TARGET_FRAME_POINTER_REQUIRED
215 #define TARGET_FRAME_POINTER_REQUIRED mmix_frame_pointer_required
216 
217 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
218 #define TARGET_ASM_TRAMPOLINE_TEMPLATE mmix_asm_trampoline_template
219 #undef TARGET_TRAMPOLINE_INIT
220 #define TARGET_TRAMPOLINE_INIT mmix_trampoline_init
221 
222 struct gcc_target targetm = TARGET_INITIALIZER;
223 
224 /* Functions that are expansions for target macros.
225    See Target Macros in `Using and Porting GCC'.  */
226 
227 /* OVERRIDE_OPTIONS.  */
228 
229 void
230 mmix_override_options (void)
231 {
232   /* Should we err or should we warn?  Hmm.  At least we must neutralize
233      it.  For example the wrong kind of case-tables will be generated with
234      PIC; we use absolute address items for mmixal compatibility.  FIXME:
235      They could be relative if we just elide them to after all pertinent
236      labels.  */
237   if (flag_pic)
238     {
239       warning (0, "-f%s not supported: ignored", (flag_pic > 1) ? "PIC" : "pic");
240       flag_pic = 0;
241     }
242 }
243 
244 /* INIT_EXPANDERS.  */
245 
246 void
247 mmix_init_expanders (void)
248 {
249   init_machine_status = mmix_init_machine_status;
250 }
251 
252 /* Set the per-function data.  */
253 
254 static struct machine_function *
255 mmix_init_machine_status (void)
256 {
257   return GGC_CNEW (struct machine_function);
258 }
259 
260 /* DATA_ALIGNMENT.
261    We have trouble getting the address of stuff that is located at other
262    than 32-bit alignments (GETA requirements), so try to give everything
263    at least 32-bit alignment.  */
264 
265 int
266 mmix_data_alignment (tree type ATTRIBUTE_UNUSED, int basic_align)
267 {
268   if (basic_align < 32)
269     return 32;
270 
271   return basic_align;
272 }
273 
274 /* CONSTANT_ALIGNMENT.  */
275 
276 int
277 mmix_constant_alignment (tree constant ATTRIBUTE_UNUSED, int basic_align)
278 {
279   if (basic_align < 32)
280     return 32;
281 
282   return basic_align;
283 }
284 
285 /* LOCAL_ALIGNMENT.  */
286 
287 int
288 mmix_local_alignment (tree type ATTRIBUTE_UNUSED, int basic_align)
289 {
290   if (basic_align < 32)
291     return 32;
292 
293   return basic_align;
294 }
295 
296 /* CONDITIONAL_REGISTER_USAGE.  */
297 
298 void
299 mmix_conditional_register_usage (void)
300 {
301   int i;
302 
303   if (TARGET_ABI_GNU)
304     {
305       static const int gnu_abi_reg_alloc_order[]
306 	= MMIX_GNU_ABI_REG_ALLOC_ORDER;
307 
308       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
309 	reg_alloc_order[i] = gnu_abi_reg_alloc_order[i];
310 
311       /* Change the default from the mmixware ABI.  For the GNU ABI,
312 	 $15..$30 are call-saved just as $0..$14.  There must be one
313 	 call-clobbered local register for the "hole" that holds the
314 	 number of saved local registers saved by PUSHJ/PUSHGO during the
315 	 function call, receiving the return value at return.  So best is
316 	 to use the highest, $31.  It's already marked call-clobbered for
317 	 the mmixware ABI.  */
318       for (i = 15; i <= 30; i++)
319 	call_used_regs[i] = 0;
320 
321       /* "Unfix" the parameter registers.  */
322       for (i = MMIX_RESERVED_GNU_ARG_0_REGNUM;
323 	   i < MMIX_RESERVED_GNU_ARG_0_REGNUM + MMIX_MAX_ARGS_IN_REGS;
324 	   i++)
325 	fixed_regs[i] = 0;
326     }
327 
328   /* Step over the ":" in special register names.  */
329   if (! TARGET_TOPLEVEL_SYMBOLS)
330     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
331       if (reg_names[i][0] == ':')
332 	reg_names[i]++;
333 }
334 
335 /* INCOMING_REGNO and OUTGOING_REGNO worker function.
336    Those two macros must only be applied to function argument
337    registers.  FIXME: for their current use in gcc, it'd be better
338    with an explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P
339    a'la FUNCTION_ARG / FUNCTION_INCOMING_ARG instead of forcing the
340    target to commit to a fixed mapping and for any unspecified
341    register use.  */
342 
343 int
344 mmix_opposite_regno (int regno, int incoming)
345 {
346   if (!mmix_function_arg_regno_p (regno, incoming))
347     return regno;
348 
349   return
350     regno - (incoming
351 	     ? MMIX_FIRST_INCOMING_ARG_REGNUM - MMIX_FIRST_ARG_REGNUM
352 	     : MMIX_FIRST_ARG_REGNUM - MMIX_FIRST_INCOMING_ARG_REGNUM);
353 }
354 
355 /* LOCAL_REGNO.
356    All registers that are part of the register stack and that will be
357    saved are local.  */
358 
359 int
360 mmix_local_regno (int regno)
361 {
362   return regno <= MMIX_LAST_STACK_REGISTER_REGNUM && !call_used_regs[regno];
363 }
364 
365 /* PREFERRED_RELOAD_CLASS.
366    We need to extend the reload class of REMAINDER_REG and HIMULT_REG.  */
367 
368 enum reg_class
369 mmix_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class rclass)
370 {
371   /* FIXME: Revisit.  */
372   return GET_CODE (x) == MOD && GET_MODE (x) == DImode
373     ? REMAINDER_REG : rclass;
374 }
375 
376 /* PREFERRED_OUTPUT_RELOAD_CLASS.
377    We need to extend the reload class of REMAINDER_REG and HIMULT_REG.  */
378 
379 enum reg_class
380 mmix_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED,
381 				    enum reg_class rclass)
382 {
383   /* FIXME: Revisit.  */
384   return GET_CODE (x) == MOD && GET_MODE (x) == DImode
385     ? REMAINDER_REG : rclass;
386 }
387 
388 /* SECONDARY_RELOAD_CLASS.
389    We need to reload regs of REMAINDER_REG and HIMULT_REG elsewhere.  */
390 
391 enum reg_class
392 mmix_secondary_reload_class (enum reg_class rclass,
393 			     enum machine_mode mode ATTRIBUTE_UNUSED,
394 			     rtx x ATTRIBUTE_UNUSED,
395 			     int in_p ATTRIBUTE_UNUSED)
396 {
397   if (rclass == REMAINDER_REG
398       || rclass == HIMULT_REG
399       || rclass == SYSTEM_REGS)
400     return GENERAL_REGS;
401 
402   return NO_REGS;
403 }
404 
405 /* CONST_OK_FOR_LETTER_P.  */
406 
407 int
408 mmix_const_ok_for_letter_p (HOST_WIDE_INT value, int c)
409 {
410   return
411     (c == 'I' ? value >= 0 && value <= 255
412      : c == 'J' ? value >= 0 && value <= 65535
413      : c == 'K' ? value <= 0 && value >= -255
414      : c == 'L' ? mmix_shiftable_wyde_value (value)
415      : c == 'M' ? value == 0
416      : c == 'N' ? mmix_shiftable_wyde_value (~value)
417      : c == 'O' ? (value == 3 || value == 5 || value == 9
418 		   || value == 17)
419      : 0);
420 }
421 
422 /* CONST_DOUBLE_OK_FOR_LETTER_P.  */
423 
424 int
425 mmix_const_double_ok_for_letter_p (rtx value, int c)
426 {
427   return
428     (c == 'G' ? value == CONST0_RTX (GET_MODE (value))
429      : 0);
430 }
431 
432 /* EXTRA_CONSTRAINT.
433    We need this since our constants are not always expressible as
434    CONST_INT:s, but rather often as CONST_DOUBLE:s.  */
435 
436 int
437 mmix_extra_constraint (rtx x, int c, int strict)
438 {
439   HOST_WIDEST_INT value;
440 
441   /* When checking for an address, we need to handle strict vs. non-strict
442      register checks.  Don't use address_operand, but instead its
443      equivalent (its callee, which it is just a wrapper for),
444      memory_operand_p and the strict-equivalent strict_memory_address_p.  */
445   if (c == 'U')
446     return
447       strict
448       ? strict_memory_address_p (Pmode, x)
449       : memory_address_p (Pmode, x);
450 
451   /* R asks whether x is to be loaded with GETA or something else.  Right
452      now, only a SYMBOL_REF and LABEL_REF can fit for
453      TARGET_BASE_ADDRESSES.
454 
455      Only constant symbolic addresses apply.  With TARGET_BASE_ADDRESSES,
456      we just allow straight LABEL_REF or SYMBOL_REFs with SYMBOL_REF_FLAG
457      set right now; only function addresses and code labels.  If we change
458      to let SYMBOL_REF_FLAG be set on other symbols, we have to check
459      inside CONST expressions.  When TARGET_BASE_ADDRESSES is not in
460      effect, a "raw" constant check together with mmix_constant_address_p
461      is all that's needed; we want all constant addresses to be loaded
462      with GETA then.  */
463   if (c == 'R')
464     return
465       GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_DOUBLE
466       && mmix_constant_address_p (x)
467       && (! TARGET_BASE_ADDRESSES
468 	  || (GET_CODE (x) == LABEL_REF
469 	      || (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))));
470 
471   if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode)
472     return 0;
473 
474   value = mmix_intval (x);
475 
476   /* We used to map Q->J, R->K, S->L, T->N, U->O, but we don't have to any
477      more ('U' taken for address_operand, 'R' similarly).  Some letters map
478      outside of CONST_INT, though; we still use 'S' and 'T'.  */
479   if (c == 'S')
480     return mmix_shiftable_wyde_value (value);
481   else if (c == 'T')
482     return mmix_shiftable_wyde_value (~value);
483   return 0;
484 }
485 
486 /* DYNAMIC_CHAIN_ADDRESS.  */
487 
488 rtx
489 mmix_dynamic_chain_address (rtx frame)
490 {
491   /* FIXME: the frame-pointer is stored at offset -8 from the current
492      frame-pointer.  Unfortunately, the caller assumes that a
493      frame-pointer is present for *all* previous frames.  There should be
494      a way to say that that cannot be done, like for RETURN_ADDR_RTX.  */
495   return plus_constant (frame, -8);
496 }
497 
498 /* STARTING_FRAME_OFFSET.  */
499 
500 int
501 mmix_starting_frame_offset (void)
502 {
503   /* The old frame pointer is in the slot below the new one, so
504      FIRST_PARM_OFFSET does not need to depend on whether the
505      frame-pointer is needed or not.  We have to adjust for the register
506      stack pointer being located below the saved frame pointer.
507      Similarly, we store the return address on the stack too, for
508      exception handling, and always if we save the register stack pointer.  */
509   return
510     (-8
511      + (MMIX_CFUN_HAS_LANDING_PAD
512 	? -16 : (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS ? -8 : 0)));
513 }
514 
515 /* RETURN_ADDR_RTX.  */
516 
517 rtx
518 mmix_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
519 {
520   return count == 0
521     ? (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
522        /* FIXME: Set frame_alias_set on the following.  (Why?)
523 	  See mmix_initial_elimination_offset for the reason we can't use
524 	  get_hard_reg_initial_val for both.  Always using a stack slot
525 	  and not a register would be suboptimal.  */
526        ? validize_mem (gen_rtx_MEM (Pmode, plus_constant (frame_pointer_rtx, -16)))
527        : get_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM))
528     : NULL_RTX;
529 }
530 
531 /* SETUP_FRAME_ADDRESSES.  */
532 
533 void
534 mmix_setup_frame_addresses (void)
535 {
536   /* Nothing needed at the moment.  */
537 }
538 
539 /* The difference between the (imaginary) frame pointer and the stack
540    pointer.  Used to eliminate the frame pointer.  */
541 
542 int
543 mmix_initial_elimination_offset (int fromreg, int toreg)
544 {
545   int regno;
546   int fp_sp_offset
547     = (get_frame_size () + crtl->outgoing_args_size + 7) & ~7;
548 
549   /* There is no actual offset between these two virtual values, but for
550      the frame-pointer, we have the old one in the stack position below
551      it, so the offset for the frame-pointer to the stack-pointer is one
552      octabyte larger.  */
553   if (fromreg == MMIX_ARG_POINTER_REGNUM
554       && toreg == MMIX_FRAME_POINTER_REGNUM)
555     return 0;
556 
557   /* The difference is the size of local variables plus the size of
558      outgoing function arguments that would normally be passed as
559      registers but must be passed on stack because we're out of
560      function-argument registers.  Only global saved registers are
561      counted; the others go on the register stack.
562 
563      The frame-pointer is counted too if it is what is eliminated, as we
564      need to balance the offset for it from STARTING_FRAME_OFFSET.
565 
566      Also add in the slot for the register stack pointer we save if we
567      have a landing pad.
568 
569      Unfortunately, we can't access $0..$14, from unwinder code easily, so
570      store the return address in a frame slot too.  FIXME: Only for
571      non-leaf functions.  FIXME: Always with a landing pad, because it's
572      hard to know whether we need the other at the time we know we need
573      the offset for one (and have to state it).  It's a kludge until we
574      can express the register stack in the EH frame info.
575 
576      We have to do alignment here; get_frame_size will not return a
577      multiple of STACK_BOUNDARY.  FIXME: Add note in manual.  */
578 
579   for (regno = MMIX_FIRST_GLOBAL_REGNUM;
580        regno <= 255;
581        regno++)
582     if ((df_regs_ever_live_p (regno) && ! call_used_regs[regno])
583 	|| IS_MMIX_EH_RETURN_DATA_REG (regno))
584       fp_sp_offset += 8;
585 
586   return fp_sp_offset
587     + (MMIX_CFUN_HAS_LANDING_PAD
588        ? 16 : (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS ? 8 : 0))
589     + (fromreg == MMIX_ARG_POINTER_REGNUM ? 0 : 8);
590 }
591 
592 /* Return an rtx for a function argument to go in a register, and 0 for
593    one that must go on stack.  */
594 
595 rtx
596 mmix_function_arg (const CUMULATIVE_ARGS *argsp,
597 		   enum machine_mode mode,
598 		   tree type,
599 		   int named ATTRIBUTE_UNUSED,
600 		   int incoming)
601 {
602   /* Last-argument marker.  */
603   if (type == void_type_node)
604     return (argsp->regs < MMIX_MAX_ARGS_IN_REGS)
605       ? gen_rtx_REG (mode,
606 		     (incoming
607 		      ? MMIX_FIRST_INCOMING_ARG_REGNUM
608 		      : MMIX_FIRST_ARG_REGNUM) + argsp->regs)
609       : NULL_RTX;
610 
611   return (argsp->regs < MMIX_MAX_ARGS_IN_REGS
612 	  && !targetm.calls.must_pass_in_stack (mode, type)
613 	  && (GET_MODE_BITSIZE (mode) <= 64
614 	      || argsp->lib
615 	      || TARGET_LIBFUNC))
616     ? gen_rtx_REG (mode,
617 		   (incoming
618 		    ? MMIX_FIRST_INCOMING_ARG_REGNUM
619 		    : MMIX_FIRST_ARG_REGNUM)
620 		   + argsp->regs)
621     : NULL_RTX;
622 }
623 
624 /* Returns nonzero for everything that goes by reference, 0 for
625    everything that goes by value.  */
626 
627 static bool
628 mmix_pass_by_reference (CUMULATIVE_ARGS *argsp, enum machine_mode mode,
629 			const_tree type, bool named ATTRIBUTE_UNUSED)
630 {
631   /* FIXME: Check: I'm not sure the must_pass_in_stack check is
632      necessary.  */
633   if (targetm.calls.must_pass_in_stack (mode, type))
634     return true;
635 
636   if (MMIX_FUNCTION_ARG_SIZE (mode, type) > 8
637       && !TARGET_LIBFUNC
638       && (!argsp || !argsp->lib))
639     return true;
640 
641   return false;
642 }
643 
644 /* Return nonzero if regno is a register number where a parameter is
645    passed, and 0 otherwise.  */
646 
647 int
648 mmix_function_arg_regno_p (int regno, int incoming)
649 {
650   int first_arg_regnum
651     = incoming ? MMIX_FIRST_INCOMING_ARG_REGNUM : MMIX_FIRST_ARG_REGNUM;
652 
653   return regno >= first_arg_regnum
654     && regno < first_arg_regnum + MMIX_MAX_ARGS_IN_REGS;
655 }
656 
657 /* FUNCTION_OUTGOING_VALUE.  */
658 
659 rtx
660 mmix_function_outgoing_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
661 {
662   enum machine_mode mode = TYPE_MODE (valtype);
663   enum machine_mode cmode;
664   int first_val_regnum = MMIX_OUTGOING_RETURN_VALUE_REGNUM;
665   rtx vec[MMIX_MAX_REGS_FOR_VALUE];
666   int i;
667   int nregs;
668 
669   /* Return values that fit in a register need no special handling.
670      There's no register hole when parameters are passed in global
671      registers.  */
672   if (TARGET_ABI_GNU
673       || GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
674     return
675       gen_rtx_REG (mode, MMIX_OUTGOING_RETURN_VALUE_REGNUM);
676 
677   if (COMPLEX_MODE_P (mode))
678     /* A complex type, made up of components.  */
679     cmode = TYPE_MODE (TREE_TYPE (valtype));
680   else
681     {
682       /* Of the other larger-than-register modes, we only support
683 	 scalar mode TImode.  (At least, that's the only one that's
684 	 been rudimentally tested.)  Make sure we're alerted for
685 	 unexpected cases.  */
686       if (mode != TImode)
687 	sorry ("support for mode %qs", GET_MODE_NAME (mode));
688 
689       /* In any case, we will fill registers to the natural size.  */
690       cmode = DImode;
691     }
692 
693   nregs = ((GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD);
694 
695   /* We need to take care of the effect of the register hole on return
696      values of large sizes; the last register will appear as the first
697      register, with the rest shifted.  (For complex modes, this is just
698      swapped registers.)  */
699 
700   if (nregs > MMIX_MAX_REGS_FOR_VALUE)
701     internal_error ("too large function value type, needs %d registers,\
702  have only %d registers for this", nregs, MMIX_MAX_REGS_FOR_VALUE);
703 
704   /* FIXME: Maybe we should handle structure values like this too
705      (adjusted for BLKmode), perhaps for both ABI:s.  */
706   for (i = 0; i < nregs - 1; i++)
707     vec[i]
708       = gen_rtx_EXPR_LIST (VOIDmode,
709 			   gen_rtx_REG (cmode, first_val_regnum + i),
710 			   GEN_INT ((i + 1) * BITS_PER_UNIT));
711 
712   vec[nregs - 1]
713     = gen_rtx_EXPR_LIST (VOIDmode,
714 			 gen_rtx_REG (cmode, first_val_regnum + nregs - 1),
715 			 const0_rtx);
716 
717   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nregs, vec));
718 }
719 
720 /* FUNCTION_VALUE_REGNO_P.  */
721 
722 int
723 mmix_function_value_regno_p (int regno)
724 {
725   return regno == MMIX_RETURN_VALUE_REGNUM;
726 }
727 
728 /* EH_RETURN_DATA_REGNO. */
729 
730 int
731 mmix_eh_return_data_regno (int n)
732 {
733   if (n >= 0 && n < 4)
734     return MMIX_EH_RETURN_DATA_REGNO_START + n;
735 
736   return INVALID_REGNUM;
737 }
738 
739 /* EH_RETURN_STACKADJ_RTX. */
740 
741 rtx
742 mmix_eh_return_stackadj_rtx (void)
743 {
744   return gen_rtx_REG (Pmode, MMIX_EH_RETURN_STACKADJ_REGNUM);
745 }
746 
747 /* EH_RETURN_HANDLER_RTX.  */
748 
749 rtx
750 mmix_eh_return_handler_rtx (void)
751 {
752   return gen_rtx_REG (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
753 }
754 
755 /* ASM_PREFERRED_EH_DATA_FORMAT. */
756 
757 int
758 mmix_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED,
759 				   int global ATTRIBUTE_UNUSED)
760 {
761   /* This is the default (was at 2001-07-20).  Revisit when needed.  */
762   return DW_EH_PE_absptr;
763 }
764 
765 /* Make a note that we've seen the beginning of the prologue.  This
766    matters to whether we'll translate register numbers as calculated by
767    mmix_reorg.  */
768 
769 static void
770 mmix_target_asm_function_prologue (FILE *stream ATTRIBUTE_UNUSED,
771 				   HOST_WIDE_INT framesize ATTRIBUTE_UNUSED)
772 {
773   cfun->machine->in_prologue = 1;
774 }
775 
776 /* Make a note that we've seen the end of the prologue.  */
777 
778 static void
779 mmix_target_asm_function_end_prologue (FILE *stream ATTRIBUTE_UNUSED)
780 {
781   cfun->machine->in_prologue = 0;
782 }
783 
784 /* Implement TARGET_MACHINE_DEPENDENT_REORG.  No actual rearrangements
785    done here; just virtually by calculating the highest saved stack
786    register number used to modify the register numbers at output time.  */
787 
788 static void
789 mmix_reorg (void)
790 {
791   int regno;
792 
793   /* We put the number of the highest saved register-file register in a
794      location convenient for the call-patterns to output.  Note that we
795      don't tell dwarf2 about these registers, since it can't restore them
796      anyway.  */
797   for (regno = MMIX_LAST_STACK_REGISTER_REGNUM;
798        regno >= 0;
799        regno--)
800     if ((df_regs_ever_live_p (regno) && !call_used_regs[regno])
801 	|| (regno == MMIX_FRAME_POINTER_REGNUM && frame_pointer_needed))
802       break;
803 
804   /* Regardless of whether they're saved (they might be just read), we
805      mustn't include registers that carry parameters.  We could scan the
806      insns to see whether they're actually used (and indeed do other less
807      trivial register usage analysis and transformations), but it seems
808      wasteful to optimize for unused parameter registers.  As of
809      2002-04-30, df_regs_ever_live_p (n) seems to be set for only-reads too, but
810      that might change.  */
811   if (!TARGET_ABI_GNU && regno < crtl->args.info.regs - 1)
812     {
813       regno = crtl->args.info.regs - 1;
814 
815       /* We don't want to let this cause us to go over the limit and make
816 	 incoming parameter registers be misnumbered and treating the last
817 	 parameter register and incoming return value register call-saved.
818 	 Stop things at the unmodified scheme.  */
819       if (regno > MMIX_RETURN_VALUE_REGNUM - 1)
820 	regno = MMIX_RETURN_VALUE_REGNUM - 1;
821     }
822 
823   cfun->machine->highest_saved_stack_register = regno;
824 }
825 
826 /* TARGET_ASM_FUNCTION_EPILOGUE.  */
827 
828 static void
829 mmix_target_asm_function_epilogue (FILE *stream,
830 				   HOST_WIDE_INT locals_size ATTRIBUTE_UNUSED)
831 {
832   /* Emit an \n for readability of the generated assembly.  */
833   fputc ('\n', stream);
834 }
835 
836 /* TARGET_ASM_OUTPUT_MI_THUNK.  */
837 
838 static void
839 mmix_asm_output_mi_thunk (FILE *stream,
840 			  tree fndecl ATTRIBUTE_UNUSED,
841 			  HOST_WIDE_INT delta,
842 			  HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
843 			  tree func)
844 {
845   /* If you define TARGET_STRUCT_VALUE_RTX that returns 0 (i.e. pass
846      location of structure to return as invisible first argument), you
847      need to tweak this code too.  */
848   const char *regname = reg_names[MMIX_FIRST_INCOMING_ARG_REGNUM];
849 
850   if (delta >= 0 && delta < 65536)
851     fprintf (stream, "\tINCL %s,%d\n", regname, (int)delta);
852   else if (delta < 0 && delta >= -255)
853     fprintf (stream, "\tSUBU %s,%s,%d\n", regname, regname, (int)-delta);
854   else
855     {
856       mmix_output_register_setting (stream, 255, delta, 1);
857       fprintf (stream, "\tADDU %s,%s,$255\n", regname, regname);
858     }
859 
860   fprintf (stream, "\tJMP ");
861   assemble_name (stream, XSTR (XEXP (DECL_RTL (func), 0), 0));
862   fprintf (stream, "\n");
863 }
864 
865 /* FUNCTION_PROFILER.  */
866 
867 void
868 mmix_function_profiler (FILE *stream ATTRIBUTE_UNUSED,
869 			int labelno ATTRIBUTE_UNUSED)
870 {
871   sorry ("function_profiler support for MMIX");
872 }
873 
874 /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  For the moment,
875    let's stick to pushing argument registers on the stack.  Later, we
876    can parse all arguments in registers, to improve performance.  */
877 
878 static void
879 mmix_setup_incoming_varargs (CUMULATIVE_ARGS *args_so_farp,
880 			     enum machine_mode mode,
881 			     tree vartype,
882 			     int *pretend_sizep,
883 			     int second_time ATTRIBUTE_UNUSED)
884 {
885   /* The last named variable has been handled, but
886      args_so_farp has not been advanced for it.  */
887   if (args_so_farp->regs + 1 < MMIX_MAX_ARGS_IN_REGS)
888     *pretend_sizep = (MMIX_MAX_ARGS_IN_REGS - (args_so_farp->regs + 1)) * 8;
889 
890   /* We assume that one argument takes up one register here.  That should
891      be true until we start messing with multi-reg parameters.  */
892   if ((7 + (MMIX_FUNCTION_ARG_SIZE (mode, vartype))) / 8 != 1)
893     internal_error ("MMIX Internal: Last named vararg would not fit in a register");
894 }
895 
896 /* TARGET_ASM_TRAMPOLINE_TEMPLATE.  */
897 
898 static void
899 mmix_asm_trampoline_template (FILE *stream)
900 {
901   /* Read a value into the static-chain register and jump somewhere.  The
902      static chain is stored at offset 16, and the function address is
903      stored at offset 24.  */
904 
905   fprintf (stream, "\tGETA $255,1F\n\t");
906   fprintf (stream, "LDOU %s,$255,0\n\t", reg_names[MMIX_STATIC_CHAIN_REGNUM]);
907   fprintf (stream, "LDOU $255,$255,8\n\t");
908   fprintf (stream, "GO $255,$255,0\n");
909   fprintf (stream, "1H\tOCTA 0\n\t");
910   fprintf (stream, "OCTA 0\n");
911 }
912 
913 /* TARGET_TRAMPOLINE_INIT.  */
914 /* Set the static chain and function pointer field in the trampoline.
915    We also SYNCID here to be sure (doesn't matter in the simulator, but
916    some day it will).  */
917 
918 static void
919 mmix_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
920 {
921   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
922   rtx mem;
923 
924   emit_block_move (m_tramp, assemble_trampoline_template (),
925 		   GEN_INT (2*UNITS_PER_WORD), BLOCK_OP_NORMAL);
926 
927   mem = adjust_address (m_tramp, DImode, 2*UNITS_PER_WORD);
928   emit_move_insn (mem, static_chain);
929   mem = adjust_address (m_tramp, DImode, 3*UNITS_PER_WORD);
930   emit_move_insn (mem, fnaddr);
931 
932   mem = adjust_address (m_tramp, DImode, 0);
933   emit_insn (gen_sync_icache (mem, GEN_INT (TRAMPOLINE_SIZE - 1)));
934 }
935 
936 /* We must exclude constant addresses that have an increment that is not a
937    multiple of four bytes because of restrictions of the GETA
938    instruction, unless TARGET_BASE_ADDRESSES.  */
939 
940 int
941 mmix_constant_address_p (rtx x)
942 {
943   RTX_CODE code = GET_CODE (x);
944   int addend = 0;
945   /* When using "base addresses", anything constant goes.  */
946   int constant_ok = TARGET_BASE_ADDRESSES != 0;
947 
948   switch (code)
949     {
950     case LABEL_REF:
951     case SYMBOL_REF:
952       return 1;
953 
954     case HIGH:
955       /* FIXME: Don't know how to dissect these.  Avoid them for now,
956 	 except we know they're constants.  */
957       return constant_ok;
958 
959     case CONST_INT:
960       addend = INTVAL (x);
961       break;
962 
963     case CONST_DOUBLE:
964       if (GET_MODE (x) != VOIDmode)
965 	/* Strange that we got here.  FIXME: Check if we do.  */
966 	return constant_ok;
967       addend = CONST_DOUBLE_LOW (x);
968       break;
969 
970     case CONST:
971       /* Note that expressions with arithmetic on forward references don't
972 	 work in mmixal.  People using gcc assembly code with mmixal might
973 	 need to move arrays and such to before the point of use.  */
974       if (GET_CODE (XEXP (x, 0)) == PLUS)
975 	{
976 	  rtx x0 = XEXP (XEXP (x, 0), 0);
977 	  rtx x1 = XEXP (XEXP (x, 0), 1);
978 
979 	  if ((GET_CODE (x0) == SYMBOL_REF
980 	       || GET_CODE (x0) == LABEL_REF)
981 	      && (GET_CODE (x1) == CONST_INT
982 		  || (GET_CODE (x1) == CONST_DOUBLE
983 		      && GET_MODE (x1) == VOIDmode)))
984 	    addend = mmix_intval (x1);
985 	  else
986 	    return constant_ok;
987 	}
988       else
989 	return constant_ok;
990       break;
991 
992     default:
993       return 0;
994     }
995 
996   return constant_ok || (addend & 3) == 0;
997 }
998 
999 /* Return 1 if the address is OK, otherwise 0.  */
1000 
1001 bool
1002 mmix_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
1003 			   rtx x,
1004 			   bool strict_checking)
1005 {
1006 #define MMIX_REG_OK(X)							\
1007   ((strict_checking							\
1008     && (REGNO (X) <= MMIX_LAST_GENERAL_REGISTER				\
1009 	|| (reg_renumber[REGNO (X)] > 0					\
1010 	    && reg_renumber[REGNO (X)] <= MMIX_LAST_GENERAL_REGISTER)))	\
1011    || (!strict_checking							\
1012        && (REGNO (X) <= MMIX_LAST_GENERAL_REGISTER			\
1013 	   || REGNO (X) >= FIRST_PSEUDO_REGISTER			\
1014 	   || REGNO (X) == ARG_POINTER_REGNUM)))
1015 
1016   /* We only accept:
1017      (mem reg)
1018      (mem (plus reg reg))
1019      (mem (plus reg 0..255)).
1020      unless TARGET_BASE_ADDRESSES, in which case we accept all
1021      (mem constant_address) too.  */
1022 
1023 
1024     /* (mem reg) */
1025   if (REG_P (x) && MMIX_REG_OK (x))
1026     return 1;
1027 
1028   if (GET_CODE(x) == PLUS)
1029     {
1030       rtx x1 = XEXP (x, 0);
1031       rtx x2 = XEXP (x, 1);
1032 
1033       /* Try swapping the order.  FIXME: Do we need this?  */
1034       if (! REG_P (x1))
1035 	{
1036 	  rtx tem = x1;
1037 	  x1 = x2;
1038 	  x2 = tem;
1039 	}
1040 
1041       /* (mem (plus (reg?) (?))) */
1042       if (!REG_P (x1) || !MMIX_REG_OK (x1))
1043 	return TARGET_BASE_ADDRESSES && mmix_constant_address_p (x);
1044 
1045       /* (mem (plus (reg) (reg?))) */
1046       if (REG_P (x2) && MMIX_REG_OK (x2))
1047 	return 1;
1048 
1049       /* (mem (plus (reg) (0..255?))) */
1050       if (GET_CODE (x2) == CONST_INT
1051 	  && CONST_OK_FOR_LETTER_P (INTVAL (x2), 'I'))
1052 	return 1;
1053 
1054       return 0;
1055     }
1056 
1057   return TARGET_BASE_ADDRESSES && mmix_constant_address_p (x);
1058 }
1059 
1060 /* LEGITIMATE_CONSTANT_P.  */
1061 
1062 int
1063 mmix_legitimate_constant_p (rtx x)
1064 {
1065   RTX_CODE code = GET_CODE (x);
1066 
1067   /* We must allow any number due to the way the cse passes works; if we
1068      do not allow any number here, general_operand will fail, and insns
1069      will fatally fail recognition instead of "softly".  */
1070   if (code == CONST_INT || code == CONST_DOUBLE)
1071     return 1;
1072 
1073   return CONSTANT_ADDRESS_P (x);
1074 }
1075 
1076 /* SELECT_CC_MODE.  */
1077 
1078 enum machine_mode
1079 mmix_select_cc_mode (RTX_CODE op, rtx x, rtx y ATTRIBUTE_UNUSED)
1080 {
1081   /* We use CCmode, CC_UNSmode, CC_FPmode, CC_FPEQmode and CC_FUNmode to
1082      output different compare insns.  Note that we do not check the
1083      validity of the comparison here.  */
1084 
1085   if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
1086     {
1087       if (op == ORDERED || op == UNORDERED || op == UNGE
1088 	  || op == UNGT || op == UNLE || op == UNLT)
1089 	return CC_FUNmode;
1090 
1091       if (op == EQ || op == NE)
1092 	return CC_FPEQmode;
1093 
1094       return CC_FPmode;
1095     }
1096 
1097   if (op == GTU || op == LTU || op == GEU || op == LEU)
1098     return CC_UNSmode;
1099 
1100   return CCmode;
1101 }
1102 
1103 /* REVERSIBLE_CC_MODE.  */
1104 
1105 int
1106 mmix_reversible_cc_mode (enum machine_mode mode)
1107 {
1108   /* That is, all integer and the EQ, NE, ORDERED and UNORDERED float
1109      compares.  */
1110   return mode != CC_FPmode;
1111 }
1112 
1113 /* TARGET_RTX_COSTS.  */
1114 
1115 static bool
1116 mmix_rtx_costs (rtx x ATTRIBUTE_UNUSED,
1117 		int code ATTRIBUTE_UNUSED,
1118 		int outer_code ATTRIBUTE_UNUSED,
1119 		int *total ATTRIBUTE_UNUSED,
1120 		bool speed ATTRIBUTE_UNUSED)
1121 {
1122   /* For the time being, this is just a stub and we'll accept the
1123      generic calculations, until we can do measurements, at least.
1124      Say we did not modify any calculated costs.  */
1125   return false;
1126 }
1127 
1128 /* REGISTER_MOVE_COST.  */
1129 
1130 int
1131 mmix_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1132 			 enum reg_class from,
1133 			 enum reg_class to)
1134 {
1135   return (from == GENERAL_REGS && from == to) ? 2 : 3;
1136 }
1137 
1138 /* Note that we don't have a TEXT_SECTION_ASM_OP, because it has to be a
1139    compile-time constant; it's used in an asm in crtstuff.c, compiled for
1140    the target.  */
1141 
1142 /* DATA_SECTION_ASM_OP.  */
1143 
1144 const char *
1145 mmix_data_section_asm_op (void)
1146 {
1147   return "\t.data ! mmixal:= 8H LOC 9B";
1148 }
1149 
1150 static void
1151 mmix_encode_section_info (tree decl, rtx rtl, int first)
1152 {
1153   /* Test for an external declaration, and do nothing if it is one.  */
1154   if ((TREE_CODE (decl) == VAR_DECL
1155        && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl)))
1156       || (TREE_CODE (decl) == FUNCTION_DECL && TREE_PUBLIC (decl)))
1157     ;
1158   else if (first && DECL_P (decl))
1159     {
1160       /* For non-visible declarations, add a "@" prefix, which we skip
1161 	 when the label is output.  If the label does not have this
1162 	 prefix, a ":" is output if -mtoplevel-symbols.
1163 
1164 	 Note that this does not work for data that is declared extern and
1165 	 later defined as static.  If there's code in between, that code
1166 	 will refer to the extern declaration, and vice versa.  This just
1167 	 means that when -mtoplevel-symbols is in use, we can just handle
1168 	 well-behaved ISO-compliant code.  */
1169 
1170       const char *str = XSTR (XEXP (rtl, 0), 0);
1171       int len = strlen (str);
1172       char *newstr = XALLOCAVEC (char, len + 2);
1173       newstr[0] = '@';
1174       strcpy (newstr + 1, str);
1175       XSTR (XEXP (rtl, 0), 0) = ggc_alloc_string (newstr, len + 1);
1176     }
1177 
1178   /* Set SYMBOL_REF_FLAG for things that we want to access with GETA.  We
1179      may need different options to reach for different things with GETA.
1180      For now, functions and things we know or have been told are constant.  */
1181   if (TREE_CODE (decl) == FUNCTION_DECL
1182       || TREE_CONSTANT (decl)
1183       || (TREE_CODE (decl) == VAR_DECL
1184 	  && TREE_READONLY (decl)
1185 	  && !TREE_SIDE_EFFECTS (decl)
1186 	  && (!DECL_INITIAL (decl)
1187 	      || TREE_CONSTANT (DECL_INITIAL (decl)))))
1188     SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
1189 }
1190 
1191 static const char *
1192 mmix_strip_name_encoding (const char *name)
1193 {
1194   for (; (*name == '@' || *name == '*'); name++)
1195     ;
1196 
1197   return name;
1198 }
1199 
1200 /* TARGET_ASM_FILE_START.
1201    We just emit a little comment for the time being.  */
1202 
1203 static void
1204 mmix_file_start (void)
1205 {
1206   default_file_start ();
1207 
1208   fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file);
1209 
1210   /* Make sure each file starts with the text section.  */
1211   switch_to_section (text_section);
1212 }
1213 
1214 /* TARGET_ASM_FILE_END.  */
1215 
1216 static void
1217 mmix_file_end (void)
1218 {
1219   /* Make sure each file ends with the data section.  */
1220   switch_to_section (data_section);
1221 }
1222 
1223 /* ASM_OUTPUT_SOURCE_FILENAME.  */
1224 
1225 void
1226 mmix_asm_output_source_filename (FILE *stream, const char *name)
1227 {
1228   fprintf (stream, "# 1 ");
1229   OUTPUT_QUOTED_STRING (stream, name);
1230   fprintf (stream, "\n");
1231 }
1232 
1233 /* OUTPUT_QUOTED_STRING.  */
1234 
1235 void
1236 mmix_output_quoted_string (FILE *stream, const char *string, int length)
1237 {
1238   const char * string_end = string + length;
1239   static const char *const unwanted_chars = "\"[]\\";
1240 
1241   /* Output "any character except newline and double quote character".  We
1242      play it safe and avoid all control characters too.  We also do not
1243      want [] as characters, should input be passed through m4 with [] as
1244      quotes.  Further, we avoid "\", because the GAS port handles it as a
1245      quoting character.  */
1246   while (string < string_end)
1247     {
1248       if (*string
1249 	  && (unsigned char) *string < 128
1250 	  && !ISCNTRL (*string)
1251 	  && strchr (unwanted_chars, *string) == NULL)
1252 	{
1253 	  fputc ('"', stream);
1254 	  while (*string
1255 		 && (unsigned char) *string < 128
1256 		 && !ISCNTRL (*string)
1257 		 && strchr (unwanted_chars, *string) == NULL
1258 		 && string < string_end)
1259 	    {
1260 	      fputc (*string, stream);
1261 	      string++;
1262 	    }
1263 	  fputc ('"', stream);
1264 	  if (string < string_end)
1265 	    fprintf (stream, ",");
1266 	}
1267       if (string < string_end)
1268 	{
1269 	  fprintf (stream, "#%x", *string & 255);
1270 	  string++;
1271 	  if (string < string_end)
1272 	    fprintf (stream, ",");
1273 	}
1274     }
1275 }
1276 
1277 /* Target hook for assembling integer objects.  Use mmix_print_operand
1278    for WYDE and TETRA.  Use mmix_output_octa to output 8-byte
1279    CONST_DOUBLEs.  */
1280 
1281 static bool
1282 mmix_assemble_integer (rtx x, unsigned int size, int aligned_p)
1283 {
1284   if (aligned_p)
1285     switch (size)
1286       {
1287 	/* We handle a limited number of types of operands in here.  But
1288 	   that's ok, because we can punt to generic functions.  We then
1289 	   pretend that aligned data isn't needed, so the usual .<pseudo>
1290 	   syntax is used (which works for aligned data too).  We actually
1291 	   *must* do that, since we say we don't have simple aligned
1292 	   pseudos, causing this function to be called.  We just try and
1293 	   keep as much compatibility as possible with mmixal syntax for
1294 	   normal cases (i.e. without GNU extensions and C only).  */
1295       case 1:
1296 	if (GET_CODE (x) != CONST_INT)
1297 	  {
1298 	    aligned_p = 0;
1299 	    break;
1300 	  }
1301 	fputs ("\tBYTE\t", asm_out_file);
1302 	mmix_print_operand (asm_out_file, x, 'B');
1303 	fputc ('\n', asm_out_file);
1304 	return true;
1305 
1306       case 2:
1307 	if (GET_CODE (x) != CONST_INT)
1308 	  {
1309 	    aligned_p = 0;
1310 	    break;
1311 	  }
1312 	fputs ("\tWYDE\t", asm_out_file);
1313 	mmix_print_operand (asm_out_file, x, 'W');
1314 	fputc ('\n', asm_out_file);
1315 	return true;
1316 
1317       case 4:
1318 	if (GET_CODE (x) != CONST_INT)
1319 	  {
1320 	    aligned_p = 0;
1321 	    break;
1322 	  }
1323 	fputs ("\tTETRA\t", asm_out_file);
1324 	mmix_print_operand (asm_out_file, x, 'L');
1325 	fputc ('\n', asm_out_file);
1326 	return true;
1327 
1328       case 8:
1329 	/* We don't get here anymore for CONST_DOUBLE, because DImode
1330 	   isn't expressed as CONST_DOUBLE, and DFmode is handled
1331 	   elsewhere.  */
1332 	gcc_assert (GET_CODE (x) != CONST_DOUBLE);
1333 	assemble_integer_with_op ("\tOCTA\t", x);
1334 	return true;
1335       }
1336   return default_assemble_integer (x, size, aligned_p);
1337 }
1338 
1339 /* ASM_OUTPUT_ASCII.  */
1340 
1341 void
1342 mmix_asm_output_ascii (FILE *stream, const char *string, int length)
1343 {
1344   while (length > 0)
1345     {
1346       int chunk_size = length > 60 ? 60 : length;
1347       fprintf (stream, "\tBYTE ");
1348       mmix_output_quoted_string (stream, string, chunk_size);
1349       string += chunk_size;
1350       length -= chunk_size;
1351       fprintf (stream, "\n");
1352     }
1353 }
1354 
1355 /* ASM_OUTPUT_ALIGNED_COMMON.  */
1356 
1357 void
1358 mmix_asm_output_aligned_common (FILE *stream,
1359 				const char *name,
1360 				int size,
1361 				int align)
1362 {
1363   /* This is mostly the elfos.h one.  There doesn't seem to be a way to
1364      express this in a mmixal-compatible way.  */
1365   fprintf (stream, "\t.comm\t");
1366   assemble_name (stream, name);
1367   fprintf (stream, ",%u,%u ! mmixal-incompatible COMMON\n",
1368 	   size, align / BITS_PER_UNIT);
1369 }
1370 
1371 /* ASM_OUTPUT_ALIGNED_LOCAL.  */
1372 
1373 void
1374 mmix_asm_output_aligned_local (FILE *stream,
1375 			       const char *name,
1376 			       int size,
1377 			       int align)
1378 {
1379   switch_to_section (data_section);
1380 
1381   ASM_OUTPUT_ALIGN (stream, exact_log2 (align/BITS_PER_UNIT));
1382   assemble_name (stream, name);
1383   fprintf (stream, "\tLOC @+%d\n", size);
1384 }
1385 
1386 /* ASM_OUTPUT_LABEL.  */
1387 
1388 void
1389 mmix_asm_output_label (FILE *stream, const char *name)
1390 {
1391   assemble_name (stream, name);
1392   fprintf (stream, "\tIS @\n");
1393 }
1394 
1395 /* ASM_OUTPUT_INTERNAL_LABEL.  */
1396 
1397 void
1398 mmix_asm_output_internal_label (FILE *stream, const char *name)
1399 {
1400   assemble_name_raw (stream, name);
1401   fprintf (stream, "\tIS @\n");
1402 }
1403 
1404 /* ASM_DECLARE_REGISTER_GLOBAL.  */
1405 
1406 void
1407 mmix_asm_declare_register_global (FILE *stream ATTRIBUTE_UNUSED,
1408 				  tree decl ATTRIBUTE_UNUSED,
1409 				  int regno ATTRIBUTE_UNUSED,
1410 				  const char *name ATTRIBUTE_UNUSED)
1411 {
1412   /* Nothing to do here, but there *will* be, therefore the framework is
1413      here.  */
1414 }
1415 
1416 /* ASM_WEAKEN_LABEL.  */
1417 
1418 void
1419 mmix_asm_weaken_label (FILE *stream ATTRIBUTE_UNUSED,
1420 		       const char *name ATTRIBUTE_UNUSED)
1421 {
1422   fprintf (stream, "\t.weak ");
1423   assemble_name (stream, name);
1424   fprintf (stream, " ! mmixal-incompatible\n");
1425 }
1426 
1427 /* MAKE_DECL_ONE_ONLY.  */
1428 
1429 void
1430 mmix_make_decl_one_only (tree decl)
1431 {
1432   DECL_WEAK (decl) = 1;
1433 }
1434 
1435 /* ASM_OUTPUT_LABELREF.
1436    Strip GCC's '*' and our own '@'.  No order is assumed.  */
1437 
1438 void
1439 mmix_asm_output_labelref (FILE *stream, const char *name)
1440 {
1441   int is_extern = 1;
1442 
1443   for (; (*name == '@' || *name == '*'); name++)
1444     if (*name == '@')
1445       is_extern = 0;
1446 
1447   asm_fprintf (stream, "%s%U%s",
1448 	       is_extern && TARGET_TOPLEVEL_SYMBOLS ? ":" : "",
1449 	       name);
1450 }
1451 
1452 /* ASM_OUTPUT_DEF.  */
1453 
1454 void
1455 mmix_asm_output_def (FILE *stream, const char *name, const char *value)
1456 {
1457   assemble_name (stream, name);
1458   fprintf (stream, "\tIS ");
1459   assemble_name (stream, value);
1460   fputc ('\n', stream);
1461 }
1462 
1463 /* PRINT_OPERAND.  */
1464 
1465 void
1466 mmix_print_operand (FILE *stream, rtx x, int code)
1467 {
1468   /* When we add support for different codes later, we can, when needed,
1469      drop through to the main handler with a modified operand.  */
1470   rtx modified_x = x;
1471   int regno = x != NULL_RTX && REG_P (x) ? REGNO (x) : 0;
1472 
1473   switch (code)
1474     {
1475       /* Unrelated codes are in alphabetic order.  */
1476 
1477     case '+':
1478       /* For conditional branches, output "P" for a probable branch.  */
1479       if (TARGET_BRANCH_PREDICT)
1480 	{
1481 	  x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
1482 	  if (x && INTVAL (XEXP (x, 0)) > REG_BR_PROB_BASE / 2)
1483 	    putc ('P', stream);
1484 	}
1485       return;
1486 
1487     case '.':
1488       /* For the %d in POP %d,0.  */
1489       fprintf (stream, "%d", MMIX_POP_ARGUMENT ());
1490       return;
1491 
1492     case 'B':
1493       if (GET_CODE (x) != CONST_INT)
1494 	fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x);
1495       fprintf (stream, "%d", (int) (INTVAL (x) & 0xff));
1496       return;
1497 
1498     case 'H':
1499       /* Highpart.  Must be general register, and not the last one, as
1500 	 that one cannot be part of a consecutive register pair.  */
1501       if (regno > MMIX_LAST_GENERAL_REGISTER - 1)
1502 	internal_error ("MMIX Internal: Bad register: %d", regno);
1503 
1504       /* This is big-endian, so the high-part is the first one.  */
1505       fprintf (stream, "%s", reg_names[MMIX_OUTPUT_REGNO (regno)]);
1506       return;
1507 
1508     case 'L':
1509       /* Lowpart.  Must be CONST_INT or general register, and not the last
1510 	 one, as that one cannot be part of a consecutive register pair.  */
1511       if (GET_CODE (x) == CONST_INT)
1512 	{
1513 	  fprintf (stream, "#%lx",
1514 		   (unsigned long) (INTVAL (x)
1515 				    & ((unsigned int) 0x7fffffff * 2 + 1)));
1516 	  return;
1517 	}
1518 
1519       if (GET_CODE (x) == SYMBOL_REF)
1520 	{
1521 	  output_addr_const (stream, x);
1522 	  return;
1523 	}
1524 
1525       if (regno > MMIX_LAST_GENERAL_REGISTER - 1)
1526 	internal_error ("MMIX Internal: Bad register: %d", regno);
1527 
1528       /* This is big-endian, so the low-part is + 1.  */
1529       fprintf (stream, "%s", reg_names[MMIX_OUTPUT_REGNO (regno) + 1]);
1530       return;
1531 
1532       /* Can't use 'a' because that's a generic modifier for address
1533 	 output.  */
1534     case 'A':
1535       mmix_output_shiftvalue_op_from_str (stream, "ANDN",
1536 					  ~(unsigned HOST_WIDEST_INT)
1537 					  mmix_intval (x));
1538       return;
1539 
1540     case 'i':
1541       mmix_output_shiftvalue_op_from_str (stream, "INC",
1542 					  (unsigned HOST_WIDEST_INT)
1543 					  mmix_intval (x));
1544       return;
1545 
1546     case 'o':
1547       mmix_output_shiftvalue_op_from_str (stream, "OR",
1548 					  (unsigned HOST_WIDEST_INT)
1549 					  mmix_intval (x));
1550       return;
1551 
1552     case 's':
1553       mmix_output_shiftvalue_op_from_str (stream, "SET",
1554 					  (unsigned HOST_WIDEST_INT)
1555 					  mmix_intval (x));
1556       return;
1557 
1558     case 'd':
1559     case 'D':
1560       mmix_output_condition (stream, x, (code == 'D'));
1561       return;
1562 
1563     case 'e':
1564       /* Output an extra "e" to make fcmpe, fune.  */
1565       if (TARGET_FCMP_EPSILON)
1566 	fprintf (stream, "e");
1567       return;
1568 
1569     case 'm':
1570       /* Output the number minus 1.  */
1571       if (GET_CODE (x) != CONST_INT)
1572 	{
1573 	  fatal_insn ("MMIX Internal: Bad value for 'm', not a CONST_INT",
1574 		      x);
1575 	}
1576       fprintf (stream, HOST_WIDEST_INT_PRINT_DEC,
1577 	       (HOST_WIDEST_INT) (mmix_intval (x) - 1));
1578       return;
1579 
1580     case 'p':
1581       /* Store the number of registers we want to save.  This was setup
1582 	 by the prologue.  The actual operand contains the number of
1583 	 registers to pass, but we don't use it currently.  Anyway, we
1584 	 need to output the number of saved registers here.  */
1585       fprintf (stream, "%d",
1586 	       cfun->machine->highest_saved_stack_register + 1);
1587       return;
1588 
1589     case 'r':
1590       /* Store the register to output a constant to.  */
1591       if (! REG_P (x))
1592 	fatal_insn ("MMIX Internal: Expected a register, not this", x);
1593       mmix_output_destination_register = MMIX_OUTPUT_REGNO (regno);
1594       return;
1595 
1596     case 'I':
1597       /* Output the constant.  Note that we use this for floats as well.  */
1598       if (GET_CODE (x) != CONST_INT
1599 	  && (GET_CODE (x) != CONST_DOUBLE
1600 	      || (GET_MODE (x) != VOIDmode && GET_MODE (x) != DFmode
1601 		  && GET_MODE (x) != SFmode)))
1602 	fatal_insn ("MMIX Internal: Expected a constant, not this", x);
1603       mmix_output_register_setting (stream,
1604 				    mmix_output_destination_register,
1605 				    mmix_intval (x), 0);
1606       return;
1607 
1608     case 'U':
1609       /* An U for unsigned, if TARGET_ZERO_EXTEND.  Ignore the operand.  */
1610       if (TARGET_ZERO_EXTEND)
1611 	putc ('U', stream);
1612       return;
1613 
1614     case 'v':
1615       mmix_output_shifted_value (stream, (HOST_WIDEST_INT) mmix_intval (x));
1616       return;
1617 
1618     case 'V':
1619       mmix_output_shifted_value (stream, (HOST_WIDEST_INT) ~mmix_intval (x));
1620       return;
1621 
1622     case 'W':
1623       if (GET_CODE (x) != CONST_INT)
1624 	fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x);
1625       fprintf (stream, "#%x", (int) (INTVAL (x) & 0xffff));
1626       return;
1627 
1628     case 0:
1629       /* Nothing to do.  */
1630       break;
1631 
1632     default:
1633       /* Presumably there's a missing case above if we get here.  */
1634       internal_error ("MMIX Internal: Missing %qc case in mmix_print_operand", code);
1635     }
1636 
1637   switch (GET_CODE (modified_x))
1638     {
1639     case REG:
1640       regno = REGNO (modified_x);
1641       if (regno >= FIRST_PSEUDO_REGISTER)
1642 	internal_error ("MMIX Internal: Bad register: %d", regno);
1643       fprintf (stream, "%s", reg_names[MMIX_OUTPUT_REGNO (regno)]);
1644       return;
1645 
1646     case MEM:
1647       output_address (XEXP (modified_x, 0));
1648       return;
1649 
1650     case CONST_INT:
1651       /* For -2147483648, mmixal complains that the constant does not fit
1652 	 in 4 bytes, so let's output it as hex.  Take care to handle hosts
1653 	 where HOST_WIDE_INT is longer than an int.
1654 
1655 	 Print small constants +-255 using decimal.  */
1656 
1657       if (INTVAL (modified_x) > -256 && INTVAL (modified_x) < 256)
1658 	fprintf (stream, "%d", (int) (INTVAL (modified_x)));
1659       else
1660 	fprintf (stream, "#%x",
1661 		 (int) (INTVAL (modified_x)) & (unsigned int) ~0);
1662       return;
1663 
1664     case CONST_DOUBLE:
1665       /* Do somewhat as CONST_INT.  */
1666       mmix_output_octa (stream, mmix_intval (modified_x), 0);
1667       return;
1668 
1669     case CONST:
1670       output_addr_const (stream, modified_x);
1671       return;
1672 
1673     default:
1674       /* No need to test for all strange things.  Let output_addr_const do
1675 	 it for us.  */
1676       if (CONSTANT_P (modified_x)
1677 	  /* Strangely enough, this is not included in CONSTANT_P.
1678 	     FIXME: Ask/check about sanity here.  */
1679 	  || GET_CODE (modified_x) == CODE_LABEL)
1680 	{
1681 	  output_addr_const (stream, modified_x);
1682 	  return;
1683 	}
1684 
1685       /* We need the original here.  */
1686       fatal_insn ("MMIX Internal: Cannot decode this operand", x);
1687     }
1688 }
1689 
1690 /* PRINT_OPERAND_PUNCT_VALID_P.  */
1691 
1692 int
1693 mmix_print_operand_punct_valid_p (int code ATTRIBUTE_UNUSED)
1694 {
1695   /* A '+' is used for branch prediction, similar to other ports.  */
1696   return code == '+'
1697     /* A '.' is used for the %d in the POP %d,0 return insn.  */
1698     || code == '.';
1699 }
1700 
1701 /* PRINT_OPERAND_ADDRESS.  */
1702 
1703 void
1704 mmix_print_operand_address (FILE *stream, rtx x)
1705 {
1706   if (REG_P (x))
1707     {
1708       /* I find the generated assembly code harder to read without
1709 	 the ",0".  */
1710       fprintf (stream, "%s,0", reg_names[MMIX_OUTPUT_REGNO (REGNO (x))]);
1711       return;
1712     }
1713   else if (GET_CODE (x) == PLUS)
1714     {
1715       rtx x1 = XEXP (x, 0);
1716       rtx x2 = XEXP (x, 1);
1717 
1718       if (REG_P (x1))
1719 	{
1720 	  fprintf (stream, "%s,", reg_names[MMIX_OUTPUT_REGNO (REGNO (x1))]);
1721 
1722 	  if (REG_P (x2))
1723 	    {
1724 	      fprintf (stream, "%s",
1725 		       reg_names[MMIX_OUTPUT_REGNO (REGNO (x2))]);
1726 	      return;
1727 	    }
1728 	  else if (GET_CODE (x2) == CONST_INT
1729 		   && CONST_OK_FOR_LETTER_P (INTVAL (x2), 'I'))
1730 	    {
1731 	      output_addr_const (stream, x2);
1732 	      return;
1733 	    }
1734 	}
1735     }
1736 
1737   if (TARGET_BASE_ADDRESSES && mmix_legitimate_constant_p (x))
1738     {
1739       output_addr_const (stream, x);
1740       return;
1741     }
1742 
1743   fatal_insn ("MMIX Internal: This is not a recognized address", x);
1744 }
1745 
1746 /* ASM_OUTPUT_REG_PUSH.  */
1747 
1748 void
1749 mmix_asm_output_reg_push (FILE *stream, int regno)
1750 {
1751   fprintf (stream, "\tSUBU %s,%s,8\n\tSTOU %s,%s,0\n",
1752 	   reg_names[MMIX_STACK_POINTER_REGNUM],
1753 	   reg_names[MMIX_STACK_POINTER_REGNUM],
1754 	   reg_names[MMIX_OUTPUT_REGNO (regno)],
1755 	   reg_names[MMIX_STACK_POINTER_REGNUM]);
1756 }
1757 
1758 /* ASM_OUTPUT_REG_POP.  */
1759 
1760 void
1761 mmix_asm_output_reg_pop (FILE *stream, int regno)
1762 {
1763   fprintf (stream, "\tLDOU %s,%s,0\n\tINCL %s,8\n",
1764 	   reg_names[MMIX_OUTPUT_REGNO (regno)],
1765 	   reg_names[MMIX_STACK_POINTER_REGNUM],
1766 	   reg_names[MMIX_STACK_POINTER_REGNUM]);
1767 }
1768 
1769 /* ASM_OUTPUT_ADDR_DIFF_ELT.  */
1770 
1771 void
1772 mmix_asm_output_addr_diff_elt (FILE *stream,
1773 			       rtx body ATTRIBUTE_UNUSED,
1774 			       int value,
1775 			       int rel)
1776 {
1777   fprintf (stream, "\tTETRA L%d-L%d\n", value, rel);
1778 }
1779 
1780 /* ASM_OUTPUT_ADDR_VEC_ELT.  */
1781 
1782 void
1783 mmix_asm_output_addr_vec_elt (FILE *stream, int value)
1784 {
1785   fprintf (stream, "\tOCTA L:%d\n", value);
1786 }
1787 
1788 /* ASM_OUTPUT_SKIP.  */
1789 
1790 void
1791 mmix_asm_output_skip (FILE *stream, int nbytes)
1792 {
1793   fprintf (stream, "\tLOC @+%d\n", nbytes);
1794 }
1795 
1796 /* ASM_OUTPUT_ALIGN.  */
1797 
1798 void
1799 mmix_asm_output_align (FILE *stream, int power)
1800 {
1801   /* We need to record the needed alignment of this section in the object,
1802      so we have to output an alignment directive.  Use a .p2align (not
1803      .align) so people will never have to wonder about whether the
1804      argument is in number of bytes or the log2 thereof.  We do it in
1805      addition to the LOC directive, so nothing needs tweaking when
1806      copy-pasting assembly into mmixal.  */
1807  fprintf (stream, "\t.p2align %d\n", power);
1808  fprintf (stream, "\tLOC @+(%d-@)&%d\n", 1 << power, (1 << power) - 1);
1809 }
1810 
1811 /* DBX_REGISTER_NUMBER.  */
1812 
1813 int
1814 mmix_dbx_register_number (int regno)
1815 {
1816   /* Adjust the register number to the one it will be output as, dammit.
1817      It'd be nice if we could check the assumption that we're filling a
1818      gap, but every register between the last saved register and parameter
1819      registers might be a valid parameter register.  */
1820   regno = MMIX_OUTPUT_REGNO (regno);
1821 
1822   /* We need to renumber registers to get the number of the return address
1823      register in the range 0..255.  It is also space-saving if registers
1824      mentioned in the call-frame information (which uses this function by
1825      defaulting DWARF_FRAME_REGNUM to DBX_REGISTER_NUMBER) are numbered
1826      0 .. 63.  So map 224 .. 256+15 -> 0 .. 47 and 0 .. 223 -> 48..223+48.  */
1827   return regno >= 224 ? (regno - 224) : (regno + 48);
1828 }
1829 
1830 /* End of target macro support functions.
1831 
1832    Now the MMIX port's own functions.  First the exported ones.  */
1833 
1834 /* Wrapper for get_hard_reg_initial_val since integrate.h isn't included
1835    from insn-emit.c.  */
1836 
1837 rtx
1838 mmix_get_hard_reg_initial_val (enum machine_mode mode, int regno)
1839 {
1840   return get_hard_reg_initial_val (mode, regno);
1841 }
1842 
1843 /* Nonzero when the function epilogue is simple enough that a single
1844    "POP %d,0" should be used even within the function.  */
1845 
1846 int
1847 mmix_use_simple_return (void)
1848 {
1849   int regno;
1850 
1851   int stack_space_to_allocate
1852     = (crtl->outgoing_args_size
1853        + crtl->args.pretend_args_size
1854        + get_frame_size () + 7) & ~7;
1855 
1856   if (!TARGET_USE_RETURN_INSN || !reload_completed)
1857     return 0;
1858 
1859   for (regno = 255;
1860        regno >= MMIX_FIRST_GLOBAL_REGNUM;
1861        regno--)
1862     /* Note that we assume that the frame-pointer-register is one of these
1863        registers, in which case we don't count it here.  */
1864     if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
1865 	  && df_regs_ever_live_p (regno) && !call_used_regs[regno]))
1866 	|| IS_MMIX_EH_RETURN_DATA_REG (regno))
1867       return 0;
1868 
1869   if (frame_pointer_needed)
1870     stack_space_to_allocate += 8;
1871 
1872   if (MMIX_CFUN_HAS_LANDING_PAD)
1873     stack_space_to_allocate += 16;
1874   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
1875     stack_space_to_allocate += 8;
1876 
1877   return stack_space_to_allocate == 0;
1878 }
1879 
1880 
1881 /* Expands the function prologue into RTX.  */
1882 
1883 void
1884 mmix_expand_prologue (void)
1885 {
1886   HOST_WIDE_INT locals_size = get_frame_size ();
1887   int regno;
1888   HOST_WIDE_INT stack_space_to_allocate
1889     = (crtl->outgoing_args_size
1890        + crtl->args.pretend_args_size
1891        + locals_size + 7) & ~7;
1892   HOST_WIDE_INT offset = -8;
1893 
1894   /* Add room needed to save global non-register-stack registers.  */
1895   for (regno = 255;
1896        regno >= MMIX_FIRST_GLOBAL_REGNUM;
1897        regno--)
1898     /* Note that we assume that the frame-pointer-register is one of these
1899        registers, in which case we don't count it here.  */
1900     if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
1901 	  && df_regs_ever_live_p (regno) && !call_used_regs[regno]))
1902 	|| IS_MMIX_EH_RETURN_DATA_REG (regno))
1903       stack_space_to_allocate += 8;
1904 
1905   /* If we do have a frame-pointer, add room for it.  */
1906   if (frame_pointer_needed)
1907     stack_space_to_allocate += 8;
1908 
1909   /* If we have a non-local label, we need to be able to unwind to it, so
1910      store the current register stack pointer.  Also store the return
1911      address if we do that.  */
1912   if (MMIX_CFUN_HAS_LANDING_PAD)
1913     stack_space_to_allocate += 16;
1914   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
1915     /* If we do have a saved return-address slot, add room for it.  */
1916     stack_space_to_allocate += 8;
1917 
1918   /* Make sure we don't get an unaligned stack.  */
1919   if ((stack_space_to_allocate % 8) != 0)
1920     internal_error ("stack frame not a multiple of 8 bytes: %wd",
1921 		    stack_space_to_allocate);
1922 
1923   if (crtl->args.pretend_args_size)
1924     {
1925       int mmix_first_vararg_reg
1926 	= (MMIX_FIRST_INCOMING_ARG_REGNUM
1927 	   + (MMIX_MAX_ARGS_IN_REGS
1928 	      - crtl->args.pretend_args_size / 8));
1929 
1930       for (regno
1931 	     = MMIX_FIRST_INCOMING_ARG_REGNUM + MMIX_MAX_ARGS_IN_REGS - 1;
1932 	   regno >= mmix_first_vararg_reg;
1933 	   regno--)
1934 	{
1935 	  if (offset < 0)
1936 	    {
1937 	      HOST_WIDE_INT stack_chunk
1938 		= stack_space_to_allocate > (256 - 8)
1939 		? (256 - 8) : stack_space_to_allocate;
1940 
1941 	      mmix_emit_sp_add (-stack_chunk);
1942 	      offset += stack_chunk;
1943 	      stack_space_to_allocate -= stack_chunk;
1944 	    }
1945 
1946 	  /* These registers aren't actually saved (as in "will be
1947 	     restored"), so don't tell DWARF2 they're saved.  */
1948 	  emit_move_insn (gen_rtx_MEM (DImode,
1949 				       plus_constant (stack_pointer_rtx,
1950 						      offset)),
1951 			  gen_rtx_REG (DImode, regno));
1952 	  offset -= 8;
1953 	}
1954     }
1955 
1956   /* Store the frame-pointer.  */
1957 
1958   if (frame_pointer_needed)
1959     {
1960       rtx insn;
1961 
1962       if (offset < 0)
1963 	{
1964 	  /* Get 8 less than otherwise, since we need to reach offset + 8.  */
1965 	  HOST_WIDE_INT stack_chunk
1966 	    = stack_space_to_allocate > (256 - 8 - 8)
1967 	    ? (256 - 8 - 8) : stack_space_to_allocate;
1968 
1969 	  mmix_emit_sp_add (-stack_chunk);
1970 
1971 	  offset += stack_chunk;
1972 	  stack_space_to_allocate -= stack_chunk;
1973 	}
1974 
1975       insn = emit_move_insn (gen_rtx_MEM (DImode,
1976 					  plus_constant (stack_pointer_rtx,
1977 							 offset)),
1978 			     hard_frame_pointer_rtx);
1979       RTX_FRAME_RELATED_P (insn) = 1;
1980       insn = emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
1981 				    stack_pointer_rtx,
1982 				    GEN_INT (offset + 8)));
1983       RTX_FRAME_RELATED_P (insn) = 1;
1984       offset -= 8;
1985     }
1986 
1987   if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
1988     {
1989       rtx tmpreg, retreg;
1990       rtx insn;
1991 
1992       /* Store the return-address, if one is needed on the stack.  We
1993 	 usually store it in a register when needed, but that doesn't work
1994 	 with -fexceptions.  */
1995 
1996       if (offset < 0)
1997 	{
1998 	  /* Get 8 less than otherwise, since we need to reach offset + 8.  */
1999 	  HOST_WIDE_INT stack_chunk
2000 	    = stack_space_to_allocate > (256 - 8 - 8)
2001 	    ? (256 - 8 - 8) : stack_space_to_allocate;
2002 
2003 	  mmix_emit_sp_add (-stack_chunk);
2004 
2005 	  offset += stack_chunk;
2006 	  stack_space_to_allocate -= stack_chunk;
2007 	}
2008 
2009       tmpreg = gen_rtx_REG (DImode, 255);
2010       retreg = gen_rtx_REG (DImode, MMIX_rJ_REGNUM);
2011 
2012       /* Dwarf2 code is confused by the use of a temporary register for
2013 	 storing the return address, so we have to express it as a note,
2014 	 which we attach to the actual store insn.  */
2015       emit_move_insn (tmpreg, retreg);
2016 
2017       insn = emit_move_insn (gen_rtx_MEM (DImode,
2018 					  plus_constant (stack_pointer_rtx,
2019 							 offset)),
2020 			     tmpreg);
2021       RTX_FRAME_RELATED_P (insn) = 1;
2022       REG_NOTES (insn)
2023 	= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2024 			     gen_rtx_SET (VOIDmode,
2025 					  gen_rtx_MEM (DImode,
2026 						       plus_constant (stack_pointer_rtx,
2027 								      offset)),
2028 					  retreg),
2029 			     REG_NOTES (insn));
2030 
2031       offset -= 8;
2032     }
2033   else if (MMIX_CFUN_HAS_LANDING_PAD)
2034     offset -= 8;
2035 
2036   if (MMIX_CFUN_HAS_LANDING_PAD)
2037     {
2038       /* Store the register defining the numbering of local registers, so
2039 	 we know how long to unwind the register stack.  */
2040 
2041       if (offset < 0)
2042 	{
2043 	  /* Get 8 less than otherwise, since we need to reach offset + 8.  */
2044 	  HOST_WIDE_INT stack_chunk
2045 	    = stack_space_to_allocate > (256 - 8 - 8)
2046 	    ? (256 - 8 - 8) : stack_space_to_allocate;
2047 
2048 	  mmix_emit_sp_add (-stack_chunk);
2049 
2050 	  offset += stack_chunk;
2051 	  stack_space_to_allocate -= stack_chunk;
2052 	}
2053 
2054       /* We don't tell dwarf2 about this one; we just have it to unwind
2055 	 the register stack at landing pads.  FIXME: It's a kludge because
2056 	 we can't describe the effect of the PUSHJ and PUSHGO insns on the
2057 	 register stack at the moment.  Best thing would be to handle it
2058 	 like stack-pointer offsets.  Better: some hook into dwarf2out.c
2059 	 to produce DW_CFA_expression:s that specify the increment of rO,
2060 	 and unwind it at eh_return (preferred) or at the landing pad.
2061 	 Then saves to $0..$G-1 could be specified through that register.  */
2062 
2063       emit_move_insn (gen_rtx_REG (DImode, 255),
2064 		      gen_rtx_REG (DImode,
2065 				   MMIX_rO_REGNUM));
2066       emit_move_insn (gen_rtx_MEM (DImode,
2067 				   plus_constant (stack_pointer_rtx, offset)),
2068 		      gen_rtx_REG (DImode, 255));
2069       offset -= 8;
2070     }
2071 
2072   /* After the return-address and the frame-pointer, we have the local
2073      variables.  They're the ones that may have an "unaligned" size.  */
2074   offset -= (locals_size + 7) & ~7;
2075 
2076   /* Now store all registers that are global, i.e. not saved by the
2077      register file machinery.
2078 
2079      It is assumed that the frame-pointer is one of these registers, so it
2080      is explicitly excluded in the count.  */
2081 
2082   for (regno = 255;
2083        regno >= MMIX_FIRST_GLOBAL_REGNUM;
2084        regno--)
2085     if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
2086 	 && df_regs_ever_live_p (regno) && ! call_used_regs[regno])
2087 	|| IS_MMIX_EH_RETURN_DATA_REG (regno))
2088       {
2089 	rtx insn;
2090 
2091 	if (offset < 0)
2092 	  {
2093 	    HOST_WIDE_INT stack_chunk
2094 	      = (stack_space_to_allocate > (256 - offset - 8)
2095 		 ? (256 - offset - 8) : stack_space_to_allocate);
2096 
2097 	    mmix_emit_sp_add (-stack_chunk);
2098 	    offset += stack_chunk;
2099 	    stack_space_to_allocate -= stack_chunk;
2100 	  }
2101 
2102 	insn = emit_move_insn (gen_rtx_MEM (DImode,
2103 					    plus_constant (stack_pointer_rtx,
2104 							   offset)),
2105 			       gen_rtx_REG (DImode, regno));
2106 	RTX_FRAME_RELATED_P (insn) = 1;
2107 	offset -= 8;
2108       }
2109 
2110   /* Finally, allocate room for outgoing args and local vars if room
2111      wasn't allocated above.  */
2112   if (stack_space_to_allocate)
2113     mmix_emit_sp_add (-stack_space_to_allocate);
2114 }
2115 
2116 /* Expands the function epilogue into RTX.  */
2117 
2118 void
2119 mmix_expand_epilogue (void)
2120 {
2121   HOST_WIDE_INT locals_size = get_frame_size ();
2122   int regno;
2123   HOST_WIDE_INT stack_space_to_deallocate
2124     = (crtl->outgoing_args_size
2125        + crtl->args.pretend_args_size
2126        + locals_size + 7) & ~7;
2127 
2128   /* The first address to access is beyond the outgoing_args area.  */
2129   HOST_WIDE_INT offset = crtl->outgoing_args_size;
2130 
2131   /* Add the space for global non-register-stack registers.
2132      It is assumed that the frame-pointer register can be one of these
2133      registers, in which case it is excluded from the count when needed.  */
2134   for (regno = 255;
2135        regno >= MMIX_FIRST_GLOBAL_REGNUM;
2136        regno--)
2137     if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
2138 	 && df_regs_ever_live_p (regno) && !call_used_regs[regno])
2139 	|| IS_MMIX_EH_RETURN_DATA_REG (regno))
2140       stack_space_to_deallocate += 8;
2141 
2142   /* Add in the space for register stack-pointer.  If so, always add room
2143      for the saved PC.  */
2144   if (MMIX_CFUN_HAS_LANDING_PAD)
2145     stack_space_to_deallocate += 16;
2146   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
2147     /* If we have a saved return-address slot, add it in.  */
2148     stack_space_to_deallocate += 8;
2149 
2150   /* Add in the frame-pointer.  */
2151   if (frame_pointer_needed)
2152     stack_space_to_deallocate += 8;
2153 
2154   /* Make sure we don't get an unaligned stack.  */
2155   if ((stack_space_to_deallocate % 8) != 0)
2156     internal_error ("stack frame not a multiple of octabyte: %wd",
2157 		    stack_space_to_deallocate);
2158 
2159   /* We will add back small offsets to the stack pointer as we go.
2160      First, we restore all registers that are global, i.e. not saved by
2161      the register file machinery.  */
2162 
2163   for (regno = MMIX_FIRST_GLOBAL_REGNUM;
2164        regno <= 255;
2165        regno++)
2166     if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
2167 	 && df_regs_ever_live_p (regno) && !call_used_regs[regno])
2168 	|| IS_MMIX_EH_RETURN_DATA_REG (regno))
2169       {
2170 	if (offset > 255)
2171 	  {
2172 	    mmix_emit_sp_add (offset);
2173 	    stack_space_to_deallocate -= offset;
2174 	    offset = 0;
2175 	  }
2176 
2177 	emit_move_insn (gen_rtx_REG (DImode, regno),
2178 			gen_rtx_MEM (DImode,
2179 				     plus_constant (stack_pointer_rtx,
2180 						    offset)));
2181 	offset += 8;
2182       }
2183 
2184   /* Here is where the local variables were.  As in the prologue, they
2185      might be of an unaligned size.  */
2186   offset += (locals_size + 7) & ~7;
2187 
2188   /* The saved register stack pointer is just below the frame-pointer
2189      register.  We don't need to restore it "manually"; the POP
2190      instruction does that.  */
2191   if (MMIX_CFUN_HAS_LANDING_PAD)
2192     offset += 16;
2193   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
2194     /* The return-address slot is just below the frame-pointer register.
2195        We don't need to restore it because we don't really use it.  */
2196     offset += 8;
2197 
2198   /* Get back the old frame-pointer-value.  */
2199   if (frame_pointer_needed)
2200     {
2201       if (offset > 255)
2202 	{
2203 	  mmix_emit_sp_add (offset);
2204 
2205 	  stack_space_to_deallocate -= offset;
2206 	  offset = 0;
2207 	}
2208 
2209       emit_move_insn (hard_frame_pointer_rtx,
2210 		      gen_rtx_MEM (DImode,
2211 				   plus_constant (stack_pointer_rtx,
2212 						  offset)));
2213       offset += 8;
2214     }
2215 
2216   /* We do not need to restore pretended incoming args, just add back
2217      offset to sp.  */
2218   if (stack_space_to_deallocate != 0)
2219     mmix_emit_sp_add (stack_space_to_deallocate);
2220 
2221   if (crtl->calls_eh_return)
2222     /* Adjust the (normal) stack-pointer to that of the receiver.
2223        FIXME: It would be nice if we could also adjust the register stack
2224        here, but we need to express it through DWARF 2 too.  */
2225     emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
2226 			   gen_rtx_REG (DImode,
2227 					MMIX_EH_RETURN_STACKADJ_REGNUM)));
2228 }
2229 
2230 /* Output an optimal sequence for setting a register to a specific
2231    constant.  Used in an alternative for const_ints in movdi, and when
2232    using large stack-frame offsets.
2233 
2234    Use do_begin_end to say if a line-starting TAB and newline before the
2235    first insn and after the last insn is wanted.  */
2236 
2237 void
2238 mmix_output_register_setting (FILE *stream,
2239 			      int regno,
2240 			      HOST_WIDEST_INT value,
2241 			      int do_begin_end)
2242 {
2243   if (do_begin_end)
2244     fprintf (stream, "\t");
2245 
2246   if (mmix_shiftable_wyde_value ((unsigned HOST_WIDEST_INT) value))
2247     {
2248       /* First, the one-insn cases.  */
2249       mmix_output_shiftvalue_op_from_str (stream, "SET",
2250 					  (unsigned HOST_WIDEST_INT)
2251 					  value);
2252       fprintf (stream, " %s,", reg_names[regno]);
2253       mmix_output_shifted_value (stream, (unsigned HOST_WIDEST_INT) value);
2254     }
2255   else if (mmix_shiftable_wyde_value (-(unsigned HOST_WIDEST_INT) value))
2256     {
2257       /* We do this to get a bit more legible assembly code.  The next
2258 	 alternative is mostly redundant with this.  */
2259 
2260       mmix_output_shiftvalue_op_from_str (stream, "SET",
2261 					  -(unsigned HOST_WIDEST_INT)
2262 					  value);
2263       fprintf (stream, " %s,", reg_names[regno]);
2264       mmix_output_shifted_value (stream, -(unsigned HOST_WIDEST_INT) value);
2265       fprintf (stream, "\n\tNEGU %s,0,%s", reg_names[regno],
2266 	       reg_names[regno]);
2267     }
2268   else if (mmix_shiftable_wyde_value (~(unsigned HOST_WIDEST_INT) value))
2269     {
2270       /* Slightly more expensive, the two-insn cases.  */
2271 
2272       /* FIXME: We could of course also test if 0..255-N or ~(N | 1..255)
2273 	 is shiftable, or any other one-insn transformation of the value.
2274 	 FIXME: Check first if the value is "shiftable" by two loading
2275 	 with two insns, since it makes more readable assembly code (if
2276 	 anyone else cares).  */
2277 
2278       mmix_output_shiftvalue_op_from_str (stream, "SET",
2279 					  ~(unsigned HOST_WIDEST_INT)
2280 					  value);
2281       fprintf (stream, " %s,", reg_names[regno]);
2282       mmix_output_shifted_value (stream, ~(unsigned HOST_WIDEST_INT) value);
2283       fprintf (stream, "\n\tNOR %s,%s,0", reg_names[regno],
2284 	       reg_names[regno]);
2285     }
2286   else
2287     {
2288       /* The generic case.  2..4 insns.  */
2289       static const char *const higher_parts[] = {"L", "ML", "MH", "H"};
2290       const char *op = "SET";
2291       const char *line_begin = "";
2292       int insns = 0;
2293       int i;
2294       HOST_WIDEST_INT tmpvalue = value;
2295 
2296       /* Compute the number of insns needed to output this constant.  */
2297       for (i = 0; i < 4 && tmpvalue != 0; i++)
2298 	{
2299 	  if (tmpvalue & 65535)
2300 	    insns++;
2301 	  tmpvalue >>= 16;
2302 	}
2303       if (TARGET_BASE_ADDRESSES && insns == 3)
2304 	{
2305 	  /* The number three is based on a static observation on
2306 	     ghostscript-6.52.  Two and four are excluded because there
2307 	     are too many such constants, and each unique constant (maybe
2308 	     offset by 1..255) were used few times compared to other uses,
2309 	     e.g. addresses.
2310 
2311 	     We use base-plus-offset addressing to force it into a global
2312 	     register; we just use a "LDA reg,VALUE", which will cause the
2313 	     assembler and linker to DTRT (for constants as well as
2314 	     addresses).  */
2315 	  fprintf (stream, "LDA %s,", reg_names[regno]);
2316 	  mmix_output_octa (stream, value, 0);
2317 	}
2318       else
2319 	{
2320 	  /* Output pertinent parts of the 4-wyde sequence.
2321 	     Still more to do if we want this to be optimal, but hey...
2322 	     Note that the zero case has been handled above.  */
2323 	  for (i = 0; i < 4 && value != 0; i++)
2324 	    {
2325 	      if (value & 65535)
2326 		{
2327 		  fprintf (stream, "%s%s%s %s,#%x", line_begin, op,
2328 			   higher_parts[i], reg_names[regno],
2329 			   (int) (value & 65535));
2330 		  /* The first one sets the rest of the bits to 0, the next
2331 		     ones add set bits.  */
2332 		  op = "INC";
2333 		  line_begin = "\n\t";
2334 		}
2335 
2336 	      value >>= 16;
2337 	    }
2338 	}
2339     }
2340 
2341   if (do_begin_end)
2342     fprintf (stream, "\n");
2343 }
2344 
2345 /* Return 1 if value is 0..65535*2**(16*N) for N=0..3.
2346    else return 0.  */
2347 
2348 int
2349 mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT value)
2350 {
2351   /* Shift by 16 bits per group, stop when we've found two groups with
2352      nonzero bits.  */
2353   int i;
2354   int has_candidate = 0;
2355 
2356   for (i = 0; i < 4; i++)
2357     {
2358       if (value & 65535)
2359 	{
2360 	  if (has_candidate)
2361 	    return 0;
2362 	  else
2363 	    has_candidate = 1;
2364 	}
2365 
2366       value >>= 16;
2367     }
2368 
2369   return 1;
2370 }
2371 
2372 /* X and Y are two things to compare using CODE.  Return the rtx for
2373    the cc-reg in the proper mode.  */
2374 
2375 rtx
2376 mmix_gen_compare_reg (RTX_CODE code, rtx x, rtx y)
2377 {
2378   enum machine_mode ccmode = SELECT_CC_MODE (code, x, y);
2379   return gen_reg_rtx (ccmode);
2380 }
2381 
2382 /* Local (static) helper functions.  */
2383 
2384 static void
2385 mmix_emit_sp_add (HOST_WIDE_INT offset)
2386 {
2387   rtx insn;
2388 
2389   if (offset < 0)
2390     {
2391       /* Negative stack-pointer adjustments are allocations and appear in
2392 	 the prologue only.  We mark them as frame-related so unwind and
2393 	 debug info is properly emitted for them.  */
2394       if (offset > -255)
2395 	insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
2396 				      stack_pointer_rtx,
2397 				      GEN_INT (offset)));
2398       else
2399 	{
2400 	  rtx tmpr = gen_rtx_REG (DImode, 255);
2401 	  RTX_FRAME_RELATED_P (emit_move_insn (tmpr, GEN_INT (offset))) = 1;
2402 	  insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
2403 					stack_pointer_rtx, tmpr));
2404 	}
2405       RTX_FRAME_RELATED_P (insn) = 1;
2406     }
2407   else
2408     {
2409       /* Positive adjustments are in the epilogue only.  Don't mark them
2410 	 as "frame-related" for unwind info.  */
2411       if (CONST_OK_FOR_LETTER_P (offset, 'L'))
2412 	emit_insn (gen_adddi3 (stack_pointer_rtx,
2413 			       stack_pointer_rtx,
2414 			       GEN_INT (offset)));
2415       else
2416 	{
2417 	  rtx tmpr = gen_rtx_REG (DImode, 255);
2418 	  emit_move_insn (tmpr, GEN_INT (offset));
2419 	  insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
2420 					stack_pointer_rtx, tmpr));
2421 	}
2422     }
2423 }
2424 
2425 /* Print operator suitable for doing something with a shiftable
2426    wyde.  The type of operator is passed as an asm output modifier.  */
2427 
2428 static void
2429 mmix_output_shiftvalue_op_from_str (FILE *stream,
2430 				    const char *mainop,
2431 				    HOST_WIDEST_INT value)
2432 {
2433   static const char *const op_part[] = {"L", "ML", "MH", "H"};
2434   int i;
2435 
2436   if (! mmix_shiftable_wyde_value (value))
2437     {
2438       char s[sizeof ("0xffffffffffffffff")];
2439       sprintf (s, HOST_WIDEST_INT_PRINT_HEX, value);
2440       internal_error ("MMIX Internal: %s is not a shiftable int", s);
2441     }
2442 
2443   for (i = 0; i < 4; i++)
2444     {
2445       /* We know we're through when we find one-bits in the low
2446 	 16 bits.  */
2447       if (value & 0xffff)
2448 	{
2449 	  fprintf (stream, "%s%s", mainop, op_part[i]);
2450 	  return;
2451 	}
2452       value >>= 16;
2453     }
2454 
2455   /* No bits set?  Then it must have been zero.  */
2456   fprintf (stream, "%sL", mainop);
2457 }
2458 
2459 /* Print a 64-bit value, optionally prefixed by assembly pseudo.  */
2460 
2461 static void
2462 mmix_output_octa (FILE *stream, HOST_WIDEST_INT value, int do_begin_end)
2463 {
2464   /* Snipped from final.c:output_addr_const.  We need to avoid the
2465      presumed universal "0x" prefix.  We can do it by replacing "0x" with
2466      "#0" here; we must avoid a space in the operands and no, the zero
2467      won't cause the number to be assumed in octal format.  */
2468   char hex_format[sizeof (HOST_WIDEST_INT_PRINT_HEX)];
2469 
2470   if (do_begin_end)
2471     fprintf (stream, "\tOCTA ");
2472 
2473   strcpy (hex_format, HOST_WIDEST_INT_PRINT_HEX);
2474   hex_format[0] = '#';
2475   hex_format[1] = '0';
2476 
2477   /* Provide a few alternative output formats depending on the number, to
2478      improve legibility of assembler output.  */
2479   if ((value < (HOST_WIDEST_INT) 0 && value > (HOST_WIDEST_INT) -10000)
2480       || (value >= (HOST_WIDEST_INT) 0 && value <= (HOST_WIDEST_INT) 16384))
2481     fprintf (stream, "%d", (int) value);
2482   else if (value > (HOST_WIDEST_INT) 0
2483 	   && value < ((HOST_WIDEST_INT) 1 << 31) * 2)
2484     fprintf (stream, "#%x", (unsigned int) value);
2485   else
2486     fprintf (stream, hex_format, value);
2487 
2488   if (do_begin_end)
2489     fprintf (stream, "\n");
2490 }
2491 
2492 /* Print the presumed shiftable wyde argument shifted into place (to
2493    be output with an operand).  */
2494 
2495 static void
2496 mmix_output_shifted_value (FILE *stream, HOST_WIDEST_INT value)
2497 {
2498   int i;
2499 
2500   if (! mmix_shiftable_wyde_value (value))
2501     {
2502       char s[16+2+1];
2503       sprintf (s, HOST_WIDEST_INT_PRINT_HEX, value);
2504       internal_error ("MMIX Internal: %s is not a shiftable int", s);
2505     }
2506 
2507   for (i = 0; i < 4; i++)
2508     {
2509       /* We know we're through when we find one-bits in the low 16 bits.  */
2510       if (value & 0xffff)
2511 	{
2512 	  fprintf (stream, "#%x", (int) (value & 0xffff));
2513 	  return;
2514 	}
2515 
2516     value >>= 16;
2517   }
2518 
2519   /* No bits set?  Then it must have been zero.  */
2520   fprintf (stream, "0");
2521 }
2522 
2523 /* Output an MMIX condition name corresponding to an operator
2524    and operands:
2525    (comparison_operator [(comparison_operator ...) (const_int 0)])
2526    which means we have to look at *two* operators.
2527 
2528    The argument "reversed" refers to reversal of the condition (not the
2529    same as swapping the arguments).  */
2530 
2531 static void
2532 mmix_output_condition (FILE *stream, rtx x, int reversed)
2533 {
2534   struct cc_conv
2535   {
2536     RTX_CODE cc;
2537 
2538     /* The normal output cc-code.  */
2539     const char *const normal;
2540 
2541     /* The reversed cc-code, or NULL if invalid.  */
2542     const char *const reversed;
2543   };
2544 
2545   struct cc_type_conv
2546   {
2547     enum machine_mode cc_mode;
2548 
2549     /* Terminated with {UNKNOWN, NULL, NULL} */
2550     const struct cc_conv *const convs;
2551   };
2552 
2553 #undef CCEND
2554 #define CCEND {UNKNOWN, NULL, NULL}
2555 
2556   static const struct cc_conv cc_fun_convs[]
2557     = {{ORDERED, "Z", "P"},
2558        {UNORDERED, "P", "Z"},
2559        CCEND};
2560   static const struct cc_conv cc_fp_convs[]
2561     = {{GT, "P", NULL},
2562        {LT, "N", NULL},
2563        CCEND};
2564   static const struct cc_conv cc_fpeq_convs[]
2565     = {{NE, "Z", "P"},
2566        {EQ, "P", "Z"},
2567        CCEND};
2568   static const struct cc_conv cc_uns_convs[]
2569     = {{GEU, "NN", "N"},
2570        {GTU, "P", "NP"},
2571        {LEU, "NP", "P"},
2572        {LTU, "N", "NN"},
2573        CCEND};
2574   static const struct cc_conv cc_signed_convs[]
2575     = {{NE, "NZ", "Z"},
2576        {EQ, "Z", "NZ"},
2577        {GE, "NN", "N"},
2578        {GT, "P", "NP"},
2579        {LE, "NP", "P"},
2580        {LT, "N", "NN"},
2581        CCEND};
2582   static const struct cc_conv cc_di_convs[]
2583     = {{NE, "NZ", "Z"},
2584        {EQ, "Z", "NZ"},
2585        {GE, "NN", "N"},
2586        {GT, "P", "NP"},
2587        {LE, "NP", "P"},
2588        {LT, "N", "NN"},
2589        {GTU, "NZ", "Z"},
2590        {LEU, "Z", "NZ"},
2591        CCEND};
2592 #undef CCEND
2593 
2594   static const struct cc_type_conv cc_convs[]
2595     = {{CC_FUNmode, cc_fun_convs},
2596        {CC_FPmode, cc_fp_convs},
2597        {CC_FPEQmode, cc_fpeq_convs},
2598        {CC_UNSmode, cc_uns_convs},
2599        {CCmode, cc_signed_convs},
2600        {DImode, cc_di_convs}};
2601 
2602   size_t i;
2603   int j;
2604 
2605   enum machine_mode mode = GET_MODE (XEXP (x, 0));
2606   RTX_CODE cc = GET_CODE (x);
2607 
2608   for (i = 0; i < ARRAY_SIZE (cc_convs); i++)
2609     {
2610       if (mode == cc_convs[i].cc_mode)
2611 	{
2612 	  for (j = 0; cc_convs[i].convs[j].cc != UNKNOWN; j++)
2613 	    if (cc == cc_convs[i].convs[j].cc)
2614 	      {
2615 		const char *mmix_cc
2616 		  = (reversed ? cc_convs[i].convs[j].reversed
2617 		     : cc_convs[i].convs[j].normal);
2618 
2619 		if (mmix_cc == NULL)
2620 		  fatal_insn ("MMIX Internal: Trying to output invalidly\
2621  reversed condition:", x);
2622 
2623 		fprintf (stream, "%s", mmix_cc);
2624 		return;
2625 	      }
2626 
2627 	  fatal_insn ("MMIX Internal: What's the CC of this?", x);
2628 	}
2629     }
2630 
2631   fatal_insn ("MMIX Internal: What is the CC of this?", x);
2632 }
2633 
2634 /* Return the bit-value for a const_int or const_double.  */
2635 
2636 static HOST_WIDEST_INT
2637 mmix_intval (rtx x)
2638 {
2639   unsigned HOST_WIDEST_INT retval;
2640 
2641   if (GET_CODE (x) == CONST_INT)
2642     return INTVAL (x);
2643 
2644   /* We make a little song and dance because converting to long long in
2645      gcc-2.7.2 is broken.  I still want people to be able to use it for
2646      cross-compilation to MMIX.  */
2647   if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == VOIDmode)
2648     {
2649       if (sizeof (HOST_WIDE_INT) < sizeof (HOST_WIDEST_INT))
2650 	{
2651 	  retval = (unsigned) CONST_DOUBLE_LOW (x) / 2;
2652 	  retval *= 2;
2653 	  retval |= CONST_DOUBLE_LOW (x) & 1;
2654 
2655 	  retval |=
2656 	    (unsigned HOST_WIDEST_INT) CONST_DOUBLE_HIGH (x)
2657 	      << (HOST_BITS_PER_LONG);
2658 	}
2659       else
2660 	retval = CONST_DOUBLE_HIGH (x);
2661 
2662       return retval;
2663     }
2664 
2665   if (GET_CODE (x) == CONST_DOUBLE)
2666     {
2667       REAL_VALUE_TYPE value;
2668 
2669       /* FIXME:  This macro is not in the manual but should be.  */
2670       REAL_VALUE_FROM_CONST_DOUBLE (value, x);
2671 
2672       if (GET_MODE (x) == DFmode)
2673 	{
2674 	  long bits[2];
2675 
2676 	  REAL_VALUE_TO_TARGET_DOUBLE (value, bits);
2677 
2678 	  /* The double cast is necessary to avoid getting the long
2679 	     sign-extended to unsigned long long(!) when they're of
2680 	     different size (usually 32-bit hosts).  */
2681 	  return
2682 	    ((unsigned HOST_WIDEST_INT) (unsigned long) bits[0]
2683 	     << (unsigned HOST_WIDEST_INT) 32U)
2684 	    | (unsigned HOST_WIDEST_INT) (unsigned long) bits[1];
2685 	}
2686       else if (GET_MODE (x) == SFmode)
2687 	{
2688 	  long bits;
2689 	  REAL_VALUE_TO_TARGET_SINGLE (value, bits);
2690 
2691 	  return (unsigned long) bits;
2692 	}
2693     }
2694 
2695   fatal_insn ("MMIX Internal: This is not a constant:", x);
2696 }
2697 
2698 /* Worker function for TARGET_PROMOTE_FUNCTION_MODE.  */
2699 
2700 enum machine_mode
2701 mmix_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
2702                             enum machine_mode mode,
2703                             int *punsignedp ATTRIBUTE_UNUSED,
2704                             const_tree fntype ATTRIBUTE_UNUSED,
2705                             int for_return)
2706 {
2707   /* Apparently not doing TRT if int < register-size.  FIXME: Perhaps
2708      FUNCTION_VALUE and LIBCALL_VALUE needs tweaking as some ports say.  */
2709   if (for_return == 1)
2710     return mode;
2711 
2712   /* Promotion of modes currently generates slow code, extending before
2713      operation, so we do it only for arguments.  */
2714   if (GET_MODE_CLASS (mode) == MODE_INT
2715       && GET_MODE_SIZE (mode) < 8)
2716     return DImode;
2717   else
2718     return mode;
2719 }
2720 /* Worker function for TARGET_STRUCT_VALUE_RTX.  */
2721 
2722 static rtx
2723 mmix_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
2724 		       int incoming ATTRIBUTE_UNUSED)
2725 {
2726   return gen_rtx_REG (Pmode, MMIX_STRUCT_VALUE_REGNUM);
2727 }
2728 
2729 /* Worker function for TARGET_FRAME_POINTER_REQUIRED.
2730 
2731    FIXME: Is this requirement built-in?  Anyway, we should try to get rid
2732    of it; we can deduce the value.  */
2733 
2734 bool
2735 mmix_frame_pointer_required (void)
2736 {
2737   return (cfun->has_nonlocal_label);
2738 }
2739 
2740 /*
2741  * Local variables:
2742  * eval: (c-set-style "gnu")
2743  * indent-tabs-mode: t
2744  * End:
2745  */
2746