OSDN Git Service

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