OSDN Git Service

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