OSDN Git Service

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