OSDN Git Service

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