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
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along 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.  */
106rtx mmix_compare_op0;
107rtx mmix_compare_op1;
108
109/* Declarations of locals.  */
110
111/* Intermediate for insn output.  */
112static int mmix_output_destination_register;
113
114static void mmix_output_shiftvalue_op_from_str
115  (FILE *, const char *, HOST_WIDEST_INT);
116static void mmix_output_shifted_value (FILE *, HOST_WIDEST_INT);
117static void mmix_output_condition (FILE *, rtx, int);
118static HOST_WIDEST_INT mmix_intval (rtx);
119static void mmix_output_octa (FILE *, HOST_WIDEST_INT, int);
120static bool mmix_assemble_integer (rtx, unsigned int, int);
121static struct machine_function *mmix_init_machine_status (void);
122static void mmix_encode_section_info (tree, rtx, int);
123static const char *mmix_strip_name_encoding (const char *);
124static void mmix_emit_sp_add (HOST_WIDE_INT offset);
125static void mmix_target_asm_function_prologue (FILE *, HOST_WIDE_INT);
126static void mmix_target_asm_function_end_prologue (FILE *);
127static void mmix_target_asm_function_epilogue (FILE *, HOST_WIDE_INT);
128static bool mmix_legitimate_address_p (enum machine_mode, rtx, bool);
129static void mmix_reorg (void);
130static void mmix_asm_output_mi_thunk
131  (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
132static void mmix_setup_incoming_varargs
133  (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
134static void mmix_file_start (void);
135static void mmix_file_end (void);
136static bool mmix_rtx_costs (rtx, int, int, int *, bool);
137static rtx mmix_struct_value_rtx (tree, int);
138static enum machine_mode mmix_promote_function_mode (const_tree,
139						     enum machine_mode,
140	                                             int *, const_tree, int);
141static bool mmix_pass_by_reference (CUMULATIVE_ARGS *,
142				    enum machine_mode, const_tree, bool);
143static bool mmix_frame_pointer_required (void);
144static void mmix_asm_trampoline_template (FILE *);
145static 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
222struct 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
229void
230mmix_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
246void
247mmix_init_expanders (void)
248{
249  init_machine_status = mmix_init_machine_status;
250}
251
252/* Set the per-function data.  */
253
254static struct machine_function *
255mmix_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
265int
266mmix_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
276int
277mmix_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
287int
288mmix_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
298void
299mmix_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
343int
344mmix_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
359int
360mmix_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
368enum reg_class
369mmix_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
379enum reg_class
380mmix_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
391enum reg_class
392mmix_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
407int
408mmix_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
424int
425mmix_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
436int
437mmix_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
488rtx
489mmix_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
500int
501mmix_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
517rtx
518mmix_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
533void
534mmix_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
542int
543mmix_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
595rtx
596mmix_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
627static bool
628mmix_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
647int
648mmix_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
659rtx
660mmix_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
722int
723mmix_function_value_regno_p (int regno)
724{
725  return regno == MMIX_RETURN_VALUE_REGNUM;
726}
727
728/* EH_RETURN_DATA_REGNO. */
729
730int
731mmix_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
741rtx
742mmix_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
749rtx
750mmix_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
757int
758mmix_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
769static void
770mmix_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
778static void
779mmix_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
788static void
789mmix_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
828static void
829mmix_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
838static void
839mmix_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
867void
868mmix_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
878static void
879mmix_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
898static void
899mmix_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
918static void
919mmix_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
940int
941mmix_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
1001bool
1002mmix_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
1062int
1063mmix_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
1078enum machine_mode
1079mmix_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
1105int
1106mmix_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
1115static bool
1116mmix_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
1130int
1131mmix_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
1144const char *
1145mmix_data_section_asm_op (void)
1146{
1147  return "\t.data ! mmixal:= 8H LOC 9B";
1148}
1149
1150static void
1151mmix_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
1191static const char *
1192mmix_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
1203static void
1204mmix_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
1216static void
1217mmix_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
1225void
1226mmix_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
1235void
1236mmix_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
1281static bool
1282mmix_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
1341void
1342mmix_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
1357void
1358mmix_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
1373void
1374mmix_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
1388void
1389mmix_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
1397void
1398mmix_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
1406void
1407mmix_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
1418void
1419mmix_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
1429void
1430mmix_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
1438void
1439mmix_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
1454void
1455mmix_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
1465void
1466mmix_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
1692int
1693mmix_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
1703void
1704mmix_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
1748void
1749mmix_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
1760void
1761mmix_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
1771void
1772mmix_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
1782void
1783mmix_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
1790void
1791mmix_asm_output_skip (FILE *stream, int nbytes)
1792{
1793  fprintf (stream, "\tLOC @+%d\n", nbytes);
1794}
1795
1796/* ASM_OUTPUT_ALIGN.  */
1797
1798void
1799mmix_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
1813int
1814mmix_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
1837rtx
1838mmix_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
1846int
1847mmix_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
1883void
1884mmix_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
2118void
2119mmix_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
2237void
2238mmix_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
2348int
2349mmix_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
2375rtx
2376mmix_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
2384static void
2385mmix_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
2428static void
2429mmix_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
2461static void
2462mmix_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
2495static void
2496mmix_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
2531static void
2532mmix_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
2636static HOST_WIDEST_INT
2637mmix_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
2700enum machine_mode
2701mmix_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
2722static rtx
2723mmix_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
2734bool
2735mmix_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