OSDN Git Service

* config/mmix/mmix.h (FUNCTION_INCOMING_ARG_REGNO_P): Don't define
[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  (current_function_calls_eh_return              \
73   && (EH_RETURN_DATA_REGNO (0) == REGNO         \
74       || EH_RETURN_DATA_REGNO (1) == REGNO      \
75       || EH_RETURN_DATA_REGNO (2) == REGNO      \
76       || EH_RETURN_DATA_REGNO (3) == REGNO))
77
78 /* For the default ABI, we rename registers at output-time to fill the gap
79    between the (statically partitioned) saved registers and call-clobbered
80    registers.  In effect this makes unused call-saved registers to be used
81    as call-clobbered registers.  The benefit comes from keeping the number
82    of local registers (value of rL) low, since there's a cost of
83    increasing rL and clearing unused (unset) registers with lower numbers.
84    Don't translate while outputting the prologue.  */
85 #define MMIX_OUTPUT_REGNO(N)                                    \
86  (TARGET_ABI_GNU                                                \
87   || (int) (N) < MMIX_RETURN_VALUE_REGNUM                       \
88   || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM                \
89   || cfun == NULL                                               \
90   || cfun->machine == NULL                                      \
91   || cfun->machine->in_prologue                                 \
92   ? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM                       \
93            + cfun->machine->highest_saved_stack_register + 1))
94
95 /* The %d in "POP %d,0".  */
96 #define MMIX_POP_ARGUMENT()                                             \
97  ((! TARGET_ABI_GNU                                                     \
98    && current_function_return_rtx != NULL                               \
99    && ! current_function_returns_struct)                                \
100   ? (GET_CODE (current_function_return_rtx) == PARALLEL                 \
101      ? GET_NUM_ELEM (XVEC (current_function_return_rtx, 0)) : 1)        \
102   : 0)
103
104 /* The canonical saved comparison operands for non-cc0 machines, set in
105    the compare expander.  */
106 rtx mmix_compare_op0;
107 rtx mmix_compare_op1;
108
109 /* 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 *);
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_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_alloc_cleared (sizeof (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 class)
357 {
358   /* FIXME: Revisit.  */
359   return GET_CODE (x) == MOD && GET_MODE (x) == DImode
360     ? REMAINDER_REG : class;
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 class)
369 {
370   /* FIXME: Revisit.  */
371   return GET_CODE (x) == MOD && GET_MODE (x) == DImode
372     ? REMAINDER_REG : class;
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 class,
380                              enum machine_mode mode ATTRIBUTE_UNUSED,
381                              rtx x ATTRIBUTE_UNUSED,
382                              int in_p ATTRIBUTE_UNUSED)
383 {
384   if (class == REMAINDER_REG
385       || class == HIMULT_REG
386       || class == 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 () + current_function_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 < current_function_args_info.regs - 1)
799     {
800       regno = current_function_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 {
1111   /* For the time being, this is just a stub and we'll accept the
1112      generic calculations, until we can do measurements, at least.
1113      Say we did not modify any calculated costs.  */
1114   return false;
1115 }
1116
1117 /* REGISTER_MOVE_COST.  */
1118
1119 int
1120 mmix_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1121                          enum reg_class from,
1122                          enum reg_class to)
1123 {
1124   return (from == GENERAL_REGS && from == to) ? 2 : 3;
1125 }
1126
1127 /* Note that we don't have a TEXT_SECTION_ASM_OP, because it has to be a
1128    compile-time constant; it's used in an asm in crtstuff.c, compiled for
1129    the target.  */
1130
1131 /* DATA_SECTION_ASM_OP.  */
1132
1133 const char *
1134 mmix_data_section_asm_op (void)
1135 {
1136   return "\t.data ! mmixal:= 8H LOC 9B";
1137 }
1138
1139 static void
1140 mmix_encode_section_info (tree decl, rtx rtl, int first)
1141 {
1142   /* Test for an external declaration, and do nothing if it is one.  */
1143   if ((TREE_CODE (decl) == VAR_DECL
1144        && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl)))
1145       || (TREE_CODE (decl) == FUNCTION_DECL && TREE_PUBLIC (decl)))
1146     ;
1147   else if (first && DECL_P (decl))
1148     {
1149       /* For non-visible declarations, add a "@" prefix, which we skip
1150          when the label is output.  If the label does not have this
1151          prefix, a ":" is output if -mtoplevel-symbols.
1152
1153          Note that this does not work for data that is declared extern and
1154          later defined as static.  If there's code in between, that code
1155          will refer to the extern declaration, and vice versa.  This just
1156          means that when -mtoplevel-symbols is in use, we can just handle
1157          well-behaved ISO-compliant code.  */
1158
1159       const char *str = XSTR (XEXP (rtl, 0), 0);
1160       int len = strlen (str);
1161       char *newstr;
1162
1163       /* Why is the return type of ggc_alloc_string const?  */
1164       newstr = CONST_CAST (char *, ggc_alloc_string ("", len + 1));
1165
1166       strcpy (newstr + 1, str);
1167       *newstr = '@';
1168       XSTR (XEXP (rtl, 0), 0) = newstr;
1169     }
1170
1171   /* Set SYMBOL_REF_FLAG for things that we want to access with GETA.  We
1172      may need different options to reach for different things with GETA.
1173      For now, functions and things we know or have been told are constant.  */
1174   if (TREE_CODE (decl) == FUNCTION_DECL
1175       || TREE_CONSTANT (decl)
1176       || (TREE_CODE (decl) == VAR_DECL
1177           && TREE_READONLY (decl)
1178           && !TREE_SIDE_EFFECTS (decl)
1179           && (!DECL_INITIAL (decl)
1180               || TREE_CONSTANT (DECL_INITIAL (decl)))))
1181     SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
1182 }
1183
1184 static const char *
1185 mmix_strip_name_encoding (const char *name)
1186 {
1187   for (; (*name == '@' || *name == '*'); name++)
1188     ;
1189
1190   return name;
1191 }
1192
1193 /* TARGET_ASM_FILE_START.
1194    We just emit a little comment for the time being.  */
1195
1196 static void
1197 mmix_file_start (void)
1198 {
1199   default_file_start ();
1200
1201   fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file);
1202
1203   /* Make sure each file starts with the text section.  */
1204   switch_to_section (text_section);
1205 }
1206
1207 /* TARGET_ASM_FILE_END.  */
1208
1209 static void
1210 mmix_file_end (void)
1211 {
1212   /* Make sure each file ends with the data section.  */
1213   switch_to_section (data_section);
1214 }
1215
1216 /* ASM_OUTPUT_SOURCE_FILENAME.  */
1217
1218 void
1219 mmix_asm_output_source_filename (FILE *stream, const char *name)
1220 {
1221   fprintf (stream, "# 1 ");
1222   OUTPUT_QUOTED_STRING (stream, name);
1223   fprintf (stream, "\n");
1224 }
1225
1226 /* OUTPUT_QUOTED_STRING.  */
1227
1228 void
1229 mmix_output_quoted_string (FILE *stream, const char *string, int length)
1230 {
1231   const char * string_end = string + length;
1232   static const char *const unwanted_chars = "\"[]\\";
1233
1234   /* Output "any character except newline and double quote character".  We
1235      play it safe and avoid all control characters too.  We also do not
1236      want [] as characters, should input be passed through m4 with [] as
1237      quotes.  Further, we avoid "\", because the GAS port handles it as a
1238      quoting character.  */
1239   while (string < string_end)
1240     {
1241       if (*string
1242           && (unsigned char) *string < 128
1243           && !ISCNTRL (*string)
1244           && strchr (unwanted_chars, *string) == NULL)
1245         {
1246           fputc ('"', stream);
1247           while (*string
1248                  && (unsigned char) *string < 128
1249                  && !ISCNTRL (*string)
1250                  && strchr (unwanted_chars, *string) == NULL
1251                  && string < string_end)
1252             {
1253               fputc (*string, stream);
1254               string++;
1255             }
1256           fputc ('"', stream);
1257           if (string < string_end)
1258             fprintf (stream, ",");
1259         }
1260       if (string < string_end)
1261         {
1262           fprintf (stream, "#%x", *string & 255);
1263           string++;
1264           if (string < string_end)
1265             fprintf (stream, ",");
1266         }
1267     }
1268 }
1269
1270 /* Target hook for assembling integer objects.  Use mmix_print_operand
1271    for WYDE and TETRA.  Use mmix_output_octa to output 8-byte
1272    CONST_DOUBLEs.  */
1273
1274 static bool
1275 mmix_assemble_integer (rtx x, unsigned int size, int aligned_p)
1276 {
1277   if (aligned_p)
1278     switch (size)
1279       {
1280         /* We handle a limited number of types of operands in here.  But
1281            that's ok, because we can punt to generic functions.  We then
1282            pretend that aligned data isn't needed, so the usual .<pseudo>
1283            syntax is used (which works for aligned data too).  We actually
1284            *must* do that, since we say we don't have simple aligned
1285            pseudos, causing this function to be called.  We just try and
1286            keep as much compatibility as possible with mmixal syntax for
1287            normal cases (i.e. without GNU extensions and C only).  */
1288       case 1:
1289         if (GET_CODE (x) != CONST_INT)
1290           {
1291             aligned_p = 0;
1292             break;
1293           }
1294         fputs ("\tBYTE\t", asm_out_file);
1295         mmix_print_operand (asm_out_file, x, 'B');
1296         fputc ('\n', asm_out_file);
1297         return true;
1298
1299       case 2:
1300         if (GET_CODE (x) != CONST_INT)
1301           {
1302             aligned_p = 0;
1303             break;
1304           }
1305         fputs ("\tWYDE\t", asm_out_file);
1306         mmix_print_operand (asm_out_file, x, 'W');
1307         fputc ('\n', asm_out_file);
1308         return true;
1309
1310       case 4:
1311         if (GET_CODE (x) != CONST_INT)
1312           {
1313             aligned_p = 0;
1314             break;
1315           }
1316         fputs ("\tTETRA\t", asm_out_file);
1317         mmix_print_operand (asm_out_file, x, 'L');
1318         fputc ('\n', asm_out_file);
1319         return true;
1320
1321       case 8:
1322         /* We don't get here anymore for CONST_DOUBLE, because DImode
1323            isn't expressed as CONST_DOUBLE, and DFmode is handled
1324            elsewhere.  */
1325         gcc_assert (GET_CODE (x) != CONST_DOUBLE);
1326         assemble_integer_with_op ("\tOCTA\t", x);
1327         return true;
1328       }
1329   return default_assemble_integer (x, size, aligned_p);
1330 }
1331
1332 /* ASM_OUTPUT_ASCII.  */
1333
1334 void
1335 mmix_asm_output_ascii (FILE *stream, const char *string, int length)
1336 {
1337   while (length > 0)
1338     {
1339       int chunk_size = length > 60 ? 60 : length;
1340       fprintf (stream, "\tBYTE ");
1341       mmix_output_quoted_string (stream, string, chunk_size);
1342       string += chunk_size;
1343       length -= chunk_size;
1344       fprintf (stream, "\n");
1345     }
1346 }
1347
1348 /* ASM_OUTPUT_ALIGNED_COMMON.  */
1349
1350 void
1351 mmix_asm_output_aligned_common (FILE *stream,
1352                                 const char *name,
1353                                 int size,
1354                                 int align)
1355 {
1356   /* This is mostly the elfos.h one.  There doesn't seem to be a way to
1357      express this in a mmixal-compatible way.  */
1358   fprintf (stream, "\t.comm\t");
1359   assemble_name (stream, name);
1360   fprintf (stream, ",%u,%u ! mmixal-incompatible COMMON\n",
1361            size, align / BITS_PER_UNIT);
1362 }
1363
1364 /* ASM_OUTPUT_ALIGNED_LOCAL.  */
1365
1366 void
1367 mmix_asm_output_aligned_local (FILE *stream,
1368                                const char *name,
1369                                int size,
1370                                int align)
1371 {
1372   switch_to_section (data_section);
1373
1374   ASM_OUTPUT_ALIGN (stream, exact_log2 (align/BITS_PER_UNIT));
1375   assemble_name (stream, name);
1376   fprintf (stream, "\tLOC @+%d\n", size);
1377 }
1378
1379 /* ASM_OUTPUT_LABEL.  */
1380
1381 void
1382 mmix_asm_output_label (FILE *stream, const char *name)
1383 {
1384   assemble_name (stream, name);
1385   fprintf (stream, "\tIS @\n");
1386 }
1387
1388 /* ASM_OUTPUT_INTERNAL_LABEL.  */
1389
1390 void
1391 mmix_asm_output_internal_label (FILE *stream, const char *name)
1392 {
1393   assemble_name_raw (stream, name);
1394   fprintf (stream, "\tIS @\n");
1395 }
1396
1397 /* ASM_DECLARE_REGISTER_GLOBAL.  */
1398
1399 void
1400 mmix_asm_declare_register_global (FILE *stream ATTRIBUTE_UNUSED,
1401                                   tree decl ATTRIBUTE_UNUSED,
1402                                   int regno ATTRIBUTE_UNUSED,
1403                                   const char *name ATTRIBUTE_UNUSED)
1404 {
1405   /* Nothing to do here, but there *will* be, therefore the framework is
1406      here.  */
1407 }
1408
1409 /* ASM_WEAKEN_LABEL.  */
1410
1411 void
1412 mmix_asm_weaken_label (FILE *stream ATTRIBUTE_UNUSED,
1413                        const char *name ATTRIBUTE_UNUSED)
1414 {
1415   fprintf (stream, "\t.weak ");
1416   assemble_name (stream, name);
1417   fprintf (stream, " ! mmixal-incompatible\n");
1418 }
1419
1420 /* MAKE_DECL_ONE_ONLY.  */
1421
1422 void
1423 mmix_make_decl_one_only (tree decl)
1424 {
1425   DECL_WEAK (decl) = 1;
1426 }
1427
1428 /* ASM_OUTPUT_LABELREF.
1429    Strip GCC's '*' and our own '@'.  No order is assumed.  */
1430
1431 void
1432 mmix_asm_output_labelref (FILE *stream, const char *name)
1433 {
1434   int is_extern = 1;
1435
1436   for (; (*name == '@' || *name == '*'); name++)
1437     if (*name == '@')
1438       is_extern = 0;
1439
1440   asm_fprintf (stream, "%s%U%s",
1441                is_extern && TARGET_TOPLEVEL_SYMBOLS ? ":" : "",
1442                name);
1443 }
1444
1445 /* ASM_OUTPUT_DEF.  */
1446
1447 void
1448 mmix_asm_output_def (FILE *stream, const char *name, const char *value)
1449 {
1450   assemble_name (stream, name);
1451   fprintf (stream, "\tIS ");
1452   assemble_name (stream, value);
1453   fputc ('\n', stream);
1454 }
1455
1456 /* PRINT_OPERAND.  */
1457
1458 void
1459 mmix_print_operand (FILE *stream, rtx x, int code)
1460 {
1461   /* When we add support for different codes later, we can, when needed,
1462      drop through to the main handler with a modified operand.  */
1463   rtx modified_x = x;
1464   int regno = x != NULL_RTX && REG_P (x) ? REGNO (x) : 0;
1465
1466   switch (code)
1467     {
1468       /* Unrelated codes are in alphabetic order.  */
1469
1470     case '+':
1471       /* For conditional branches, output "P" for a probable branch.  */
1472       if (TARGET_BRANCH_PREDICT)
1473         {
1474           x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
1475           if (x && INTVAL (XEXP (x, 0)) > REG_BR_PROB_BASE / 2)
1476             putc ('P', stream);
1477         }
1478       return;
1479
1480     case '.':
1481       /* For the %d in POP %d,0.  */
1482       fprintf (stream, "%d", MMIX_POP_ARGUMENT ());
1483       return;
1484
1485     case 'B':
1486       if (GET_CODE (x) != CONST_INT)
1487         fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x);
1488       fprintf (stream, "%d", (int) (INTVAL (x) & 0xff));
1489       return;
1490
1491     case 'H':
1492       /* Highpart.  Must be general register, and not the last one, as
1493          that one cannot be part of a consecutive register pair.  */
1494       if (regno > MMIX_LAST_GENERAL_REGISTER - 1)
1495         internal_error ("MMIX Internal: Bad register: %d", regno);
1496
1497       /* This is big-endian, so the high-part is the first one.  */
1498       fprintf (stream, "%s", reg_names[MMIX_OUTPUT_REGNO (regno)]);
1499       return;
1500
1501     case 'L':
1502       /* Lowpart.  Must be CONST_INT or general register, and not the last
1503          one, as that one cannot be part of a consecutive register pair.  */
1504       if (GET_CODE (x) == CONST_INT)
1505         {
1506           fprintf (stream, "#%lx",
1507                    (unsigned long) (INTVAL (x)
1508                                     & ((unsigned int) 0x7fffffff * 2 + 1)));
1509           return;
1510         }
1511
1512       if (GET_CODE (x) == SYMBOL_REF)
1513         {
1514           output_addr_const (stream, x);
1515           return;
1516         }
1517
1518       if (regno > MMIX_LAST_GENERAL_REGISTER - 1)
1519         internal_error ("MMIX Internal: Bad register: %d", regno);
1520
1521       /* This is big-endian, so the low-part is + 1.  */
1522       fprintf (stream, "%s", reg_names[MMIX_OUTPUT_REGNO (regno) + 1]);
1523       return;
1524
1525       /* Can't use 'a' because that's a generic modifier for address
1526          output.  */
1527     case 'A':
1528       mmix_output_shiftvalue_op_from_str (stream, "ANDN",
1529                                           ~(unsigned HOST_WIDEST_INT)
1530                                           mmix_intval (x));
1531       return;
1532
1533     case 'i':
1534       mmix_output_shiftvalue_op_from_str (stream, "INC",
1535                                           (unsigned HOST_WIDEST_INT)
1536                                           mmix_intval (x));
1537       return;
1538
1539     case 'o':
1540       mmix_output_shiftvalue_op_from_str (stream, "OR",
1541                                           (unsigned HOST_WIDEST_INT)
1542                                           mmix_intval (x));
1543       return;
1544
1545     case 's':
1546       mmix_output_shiftvalue_op_from_str (stream, "SET",
1547                                           (unsigned HOST_WIDEST_INT)
1548                                           mmix_intval (x));
1549       return;
1550
1551     case 'd':
1552     case 'D':
1553       mmix_output_condition (stream, x, (code == 'D'));
1554       return;
1555
1556     case 'e':
1557       /* Output an extra "e" to make fcmpe, fune.  */
1558       if (TARGET_FCMP_EPSILON)
1559         fprintf (stream, "e");
1560       return;
1561
1562     case 'm':
1563       /* Output the number minus 1.  */
1564       if (GET_CODE (x) != CONST_INT)
1565         {
1566           fatal_insn ("MMIX Internal: Bad value for 'm', not a CONST_INT",
1567                       x);
1568         }
1569       fprintf (stream, HOST_WIDEST_INT_PRINT_DEC,
1570                (HOST_WIDEST_INT) (mmix_intval (x) - 1));
1571       return;
1572
1573     case 'p':
1574       /* Store the number of registers we want to save.  This was setup
1575          by the prologue.  The actual operand contains the number of
1576          registers to pass, but we don't use it currently.  Anyway, we
1577          need to output the number of saved registers here.  */
1578       fprintf (stream, "%d",
1579                cfun->machine->highest_saved_stack_register + 1);
1580       return;
1581
1582     case 'r':
1583       /* Store the register to output a constant to.  */
1584       if (! REG_P (x))
1585         fatal_insn ("MMIX Internal: Expected a register, not this", x);
1586       mmix_output_destination_register = MMIX_OUTPUT_REGNO (regno);
1587       return;
1588
1589     case 'I':
1590       /* Output the constant.  Note that we use this for floats as well.  */
1591       if (GET_CODE (x) != CONST_INT
1592           && (GET_CODE (x) != CONST_DOUBLE
1593               || (GET_MODE (x) != VOIDmode && GET_MODE (x) != DFmode
1594                   && GET_MODE (x) != SFmode)))
1595         fatal_insn ("MMIX Internal: Expected a constant, not this", x);
1596       mmix_output_register_setting (stream,
1597                                     mmix_output_destination_register,
1598                                     mmix_intval (x), 0);
1599       return;
1600
1601     case 'U':
1602       /* An U for unsigned, if TARGET_ZERO_EXTEND.  Ignore the operand.  */
1603       if (TARGET_ZERO_EXTEND)
1604         putc ('U', stream);
1605       return;
1606
1607     case 'v':
1608       mmix_output_shifted_value (stream, (HOST_WIDEST_INT) mmix_intval (x));
1609       return;
1610
1611     case 'V':
1612       mmix_output_shifted_value (stream, (HOST_WIDEST_INT) ~mmix_intval (x));
1613       return;
1614
1615     case 'W':
1616       if (GET_CODE (x) != CONST_INT)
1617         fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x);
1618       fprintf (stream, "#%x", (int) (INTVAL (x) & 0xffff));
1619       return;
1620
1621     case 0:
1622       /* Nothing to do.  */
1623       break;
1624
1625     default:
1626       /* Presumably there's a missing case above if we get here.  */
1627       internal_error ("MMIX Internal: Missing %qc case in mmix_print_operand", code);
1628     }
1629
1630   switch (GET_CODE (modified_x))
1631     {
1632     case REG:
1633       regno = REGNO (modified_x);
1634       if (regno >= FIRST_PSEUDO_REGISTER)
1635         internal_error ("MMIX Internal: Bad register: %d", regno);
1636       fprintf (stream, "%s", reg_names[MMIX_OUTPUT_REGNO (regno)]);
1637       return;
1638
1639     case MEM:
1640       output_address (XEXP (modified_x, 0));
1641       return;
1642
1643     case CONST_INT:
1644       /* For -2147483648, mmixal complains that the constant does not fit
1645          in 4 bytes, so let's output it as hex.  Take care to handle hosts
1646          where HOST_WIDE_INT is longer than an int.
1647
1648          Print small constants +-255 using decimal.  */
1649
1650       if (INTVAL (modified_x) > -256 && INTVAL (modified_x) < 256)
1651         fprintf (stream, "%d", (int) (INTVAL (modified_x)));
1652       else
1653         fprintf (stream, "#%x",
1654                  (int) (INTVAL (modified_x)) & (unsigned int) ~0);
1655       return;
1656
1657     case CONST_DOUBLE:
1658       /* Do somewhat as CONST_INT.  */
1659       mmix_output_octa (stream, mmix_intval (modified_x), 0);
1660       return;
1661
1662     case CONST:
1663       output_addr_const (stream, modified_x);
1664       return;
1665
1666     default:
1667       /* No need to test for all strange things.  Let output_addr_const do
1668          it for us.  */
1669       if (CONSTANT_P (modified_x)
1670           /* Strangely enough, this is not included in CONSTANT_P.
1671              FIXME: Ask/check about sanity here.  */
1672           || GET_CODE (modified_x) == CODE_LABEL)
1673         {
1674           output_addr_const (stream, modified_x);
1675           return;
1676         }
1677
1678       /* We need the original here.  */
1679       fatal_insn ("MMIX Internal: Cannot decode this operand", x);
1680     }
1681 }
1682
1683 /* PRINT_OPERAND_PUNCT_VALID_P.  */
1684
1685 int
1686 mmix_print_operand_punct_valid_p (int code ATTRIBUTE_UNUSED)
1687 {
1688   /* A '+' is used for branch prediction, similar to other ports.  */
1689   return code == '+'
1690     /* A '.' is used for the %d in the POP %d,0 return insn.  */
1691     || code == '.';
1692 }
1693
1694 /* PRINT_OPERAND_ADDRESS.  */
1695
1696 void
1697 mmix_print_operand_address (FILE *stream, rtx x)
1698 {
1699   if (REG_P (x))
1700     {
1701       /* I find the generated assembly code harder to read without
1702          the ",0".  */
1703       fprintf (stream, "%s,0", reg_names[MMIX_OUTPUT_REGNO (REGNO (x))]);
1704       return;
1705     }
1706   else if (GET_CODE (x) == PLUS)
1707     {
1708       rtx x1 = XEXP (x, 0);
1709       rtx x2 = XEXP (x, 1);
1710
1711       if (REG_P (x1))
1712         {
1713           fprintf (stream, "%s,", reg_names[MMIX_OUTPUT_REGNO (REGNO (x1))]);
1714
1715           if (REG_P (x2))
1716             {
1717               fprintf (stream, "%s",
1718                        reg_names[MMIX_OUTPUT_REGNO (REGNO (x2))]);
1719               return;
1720             }
1721           else if (GET_CODE (x2) == CONST_INT
1722                    && CONST_OK_FOR_LETTER_P (INTVAL (x2), 'I'))
1723             {
1724               output_addr_const (stream, x2);
1725               return;
1726             }
1727         }
1728     }
1729
1730   if (TARGET_BASE_ADDRESSES && mmix_legitimate_constant_p (x))
1731     {
1732       output_addr_const (stream, x);
1733       return;
1734     }
1735
1736   fatal_insn ("MMIX Internal: This is not a recognized address", x);
1737 }
1738
1739 /* ASM_OUTPUT_REG_PUSH.  */
1740
1741 void
1742 mmix_asm_output_reg_push (FILE *stream, int regno)
1743 {
1744   fprintf (stream, "\tSUBU %s,%s,8\n\tSTOU %s,%s,0\n",
1745            reg_names[MMIX_STACK_POINTER_REGNUM],
1746            reg_names[MMIX_STACK_POINTER_REGNUM],
1747            reg_names[MMIX_OUTPUT_REGNO (regno)],
1748            reg_names[MMIX_STACK_POINTER_REGNUM]);
1749 }
1750
1751 /* ASM_OUTPUT_REG_POP.  */
1752
1753 void
1754 mmix_asm_output_reg_pop (FILE *stream, int regno)
1755 {
1756   fprintf (stream, "\tLDOU %s,%s,0\n\tINCL %s,8\n",
1757            reg_names[MMIX_OUTPUT_REGNO (regno)],
1758            reg_names[MMIX_STACK_POINTER_REGNUM],
1759            reg_names[MMIX_STACK_POINTER_REGNUM]);
1760 }
1761
1762 /* ASM_OUTPUT_ADDR_DIFF_ELT.  */
1763
1764 void
1765 mmix_asm_output_addr_diff_elt (FILE *stream,
1766                                rtx body ATTRIBUTE_UNUSED,
1767                                int value,
1768                                int rel)
1769 {
1770   fprintf (stream, "\tTETRA L%d-L%d\n", value, rel);
1771 }
1772
1773 /* ASM_OUTPUT_ADDR_VEC_ELT.  */
1774
1775 void
1776 mmix_asm_output_addr_vec_elt (FILE *stream, int value)
1777 {
1778   fprintf (stream, "\tOCTA L:%d\n", value);
1779 }
1780
1781 /* ASM_OUTPUT_SKIP.  */
1782
1783 void
1784 mmix_asm_output_skip (FILE *stream, int nbytes)
1785 {
1786   fprintf (stream, "\tLOC @+%d\n", nbytes);
1787 }
1788
1789 /* ASM_OUTPUT_ALIGN.  */
1790
1791 void
1792 mmix_asm_output_align (FILE *stream, int power)
1793 {
1794   /* We need to record the needed alignment of this section in the object,
1795      so we have to output an alignment directive.  Use a .p2align (not
1796      .align) so people will never have to wonder about whether the
1797      argument is in number of bytes or the log2 thereof.  We do it in
1798      addition to the LOC directive, so nothing needs tweaking when
1799      copy-pasting assembly into mmixal.  */
1800  fprintf (stream, "\t.p2align %d\n", power);
1801  fprintf (stream, "\tLOC @+(%d-@)&%d\n", 1 << power, (1 << power) - 1);
1802 }
1803
1804 /* DBX_REGISTER_NUMBER.  */
1805
1806 int
1807 mmix_dbx_register_number (int regno)
1808 {
1809   /* Adjust the register number to the one it will be output as, dammit.
1810      It'd be nice if we could check the assumption that we're filling a
1811      gap, but every register between the last saved register and parameter
1812      registers might be a valid parameter register.  */
1813   regno = MMIX_OUTPUT_REGNO (regno);
1814
1815   /* We need to renumber registers to get the number of the return address
1816      register in the range 0..255.  It is also space-saving if registers
1817      mentioned in the call-frame information (which uses this function by
1818      defaulting DWARF_FRAME_REGNUM to DBX_REGISTER_NUMBER) are numbered
1819      0 .. 63.  So map 224 .. 256+15 -> 0 .. 47 and 0 .. 223 -> 48..223+48.  */
1820   return regno >= 224 ? (regno - 224) : (regno + 48);
1821 }
1822
1823 /* End of target macro support functions.
1824
1825    Now the MMIX port's own functions.  First the exported ones.  */
1826
1827 /* Wrapper for get_hard_reg_initial_val since integrate.h isn't included
1828    from insn-emit.c.  */
1829
1830 rtx
1831 mmix_get_hard_reg_initial_val (enum machine_mode mode, int regno)
1832 {
1833   return get_hard_reg_initial_val (mode, regno);
1834 }
1835
1836 /* Nonzero when the function epilogue is simple enough that a single
1837    "POP %d,0" should be used even within the function.  */
1838
1839 int
1840 mmix_use_simple_return (void)
1841 {
1842   int regno;
1843
1844   int stack_space_to_allocate
1845     = (current_function_outgoing_args_size
1846        + current_function_pretend_args_size
1847        + get_frame_size () + 7) & ~7;
1848
1849   if (!TARGET_USE_RETURN_INSN || !reload_completed)
1850     return 0;
1851
1852   for (regno = 255;
1853        regno >= MMIX_FIRST_GLOBAL_REGNUM;
1854        regno--)
1855     /* Note that we assume that the frame-pointer-register is one of these
1856        registers, in which case we don't count it here.  */
1857     if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
1858           && df_regs_ever_live_p (regno) && !call_used_regs[regno]))
1859         || IS_MMIX_EH_RETURN_DATA_REG (regno))
1860       return 0;
1861
1862   if (frame_pointer_needed)
1863     stack_space_to_allocate += 8;
1864
1865   if (MMIX_CFUN_HAS_LANDING_PAD)
1866     stack_space_to_allocate += 16;
1867   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
1868     stack_space_to_allocate += 8;
1869
1870   return stack_space_to_allocate == 0;
1871 }
1872
1873
1874 /* Expands the function prologue into RTX.  */
1875
1876 void
1877 mmix_expand_prologue (void)
1878 {
1879   HOST_WIDE_INT locals_size = get_frame_size ();
1880   int regno;
1881   HOST_WIDE_INT stack_space_to_allocate
1882     = (current_function_outgoing_args_size
1883        + current_function_pretend_args_size
1884        + locals_size + 7) & ~7;
1885   HOST_WIDE_INT offset = -8;
1886
1887   /* Add room needed to save global non-register-stack registers.  */
1888   for (regno = 255;
1889        regno >= MMIX_FIRST_GLOBAL_REGNUM;
1890        regno--)
1891     /* Note that we assume that the frame-pointer-register is one of these
1892        registers, in which case we don't count it here.  */
1893     if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
1894           && df_regs_ever_live_p (regno) && !call_used_regs[regno]))
1895         || IS_MMIX_EH_RETURN_DATA_REG (regno))
1896       stack_space_to_allocate += 8;
1897
1898   /* If we do have a frame-pointer, add room for it.  */
1899   if (frame_pointer_needed)
1900     stack_space_to_allocate += 8;
1901
1902   /* If we have a non-local label, we need to be able to unwind to it, so
1903      store the current register stack pointer.  Also store the return
1904      address if we do that.  */
1905   if (MMIX_CFUN_HAS_LANDING_PAD)
1906     stack_space_to_allocate += 16;
1907   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
1908     /* If we do have a saved return-address slot, add room for it.  */
1909     stack_space_to_allocate += 8;
1910
1911   /* Make sure we don't get an unaligned stack.  */
1912   if ((stack_space_to_allocate % 8) != 0)
1913     internal_error ("stack frame not a multiple of 8 bytes: %wd",
1914                     stack_space_to_allocate);
1915
1916   if (current_function_pretend_args_size)
1917     {
1918       int mmix_first_vararg_reg
1919         = (MMIX_FIRST_INCOMING_ARG_REGNUM
1920            + (MMIX_MAX_ARGS_IN_REGS
1921               - current_function_pretend_args_size / 8));
1922
1923       for (regno
1924              = MMIX_FIRST_INCOMING_ARG_REGNUM + MMIX_MAX_ARGS_IN_REGS - 1;
1925            regno >= mmix_first_vararg_reg;
1926            regno--)
1927         {
1928           if (offset < 0)
1929             {
1930               HOST_WIDE_INT stack_chunk
1931                 = stack_space_to_allocate > (256 - 8)
1932                 ? (256 - 8) : stack_space_to_allocate;
1933
1934               mmix_emit_sp_add (-stack_chunk);
1935               offset += stack_chunk;
1936               stack_space_to_allocate -= stack_chunk;
1937             }
1938
1939           /* These registers aren't actually saved (as in "will be
1940              restored"), so don't tell DWARF2 they're saved.  */
1941           emit_move_insn (gen_rtx_MEM (DImode,
1942                                        plus_constant (stack_pointer_rtx,
1943                                                       offset)),
1944                           gen_rtx_REG (DImode, regno));
1945           offset -= 8;
1946         }
1947     }
1948
1949   /* Store the frame-pointer.  */
1950
1951   if (frame_pointer_needed)
1952     {
1953       rtx insn;
1954
1955       if (offset < 0)
1956         {
1957           /* Get 8 less than otherwise, since we need to reach offset + 8.  */
1958           HOST_WIDE_INT stack_chunk
1959             = stack_space_to_allocate > (256 - 8 - 8)
1960             ? (256 - 8 - 8) : stack_space_to_allocate;
1961
1962           mmix_emit_sp_add (-stack_chunk);
1963
1964           offset += stack_chunk;
1965           stack_space_to_allocate -= stack_chunk;
1966         }
1967
1968       insn = emit_move_insn (gen_rtx_MEM (DImode,
1969                                           plus_constant (stack_pointer_rtx,
1970                                                          offset)),
1971                              hard_frame_pointer_rtx);
1972       RTX_FRAME_RELATED_P (insn) = 1;
1973       insn = emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
1974                                     stack_pointer_rtx,
1975                                     GEN_INT (offset + 8)));
1976       RTX_FRAME_RELATED_P (insn) = 1;
1977       offset -= 8;
1978     }
1979
1980   if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
1981     {
1982       rtx tmpreg, retreg;
1983       rtx insn;
1984
1985       /* Store the return-address, if one is needed on the stack.  We
1986          usually store it in a register when needed, but that doesn't work
1987          with -fexceptions.  */
1988
1989       if (offset < 0)
1990         {
1991           /* Get 8 less than otherwise, since we need to reach offset + 8.  */
1992           HOST_WIDE_INT stack_chunk
1993             = stack_space_to_allocate > (256 - 8 - 8)
1994             ? (256 - 8 - 8) : stack_space_to_allocate;
1995
1996           mmix_emit_sp_add (-stack_chunk);
1997
1998           offset += stack_chunk;
1999           stack_space_to_allocate -= stack_chunk;
2000         }
2001
2002       tmpreg = gen_rtx_REG (DImode, 255);
2003       retreg = gen_rtx_REG (DImode, MMIX_rJ_REGNUM);
2004
2005       /* Dwarf2 code is confused by the use of a temporary register for
2006          storing the return address, so we have to express it as a note,
2007          which we attach to the actual store insn.  */
2008       emit_move_insn (tmpreg, retreg);
2009
2010       insn = emit_move_insn (gen_rtx_MEM (DImode,
2011                                           plus_constant (stack_pointer_rtx,
2012                                                          offset)),
2013                              tmpreg);
2014       RTX_FRAME_RELATED_P (insn) = 1;
2015       REG_NOTES (insn)
2016         = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2017                              gen_rtx_SET (VOIDmode,
2018                                           gen_rtx_MEM (DImode,
2019                                                        plus_constant (stack_pointer_rtx,
2020                                                                       offset)),
2021                                           retreg),
2022                              REG_NOTES (insn));
2023
2024       offset -= 8;
2025     }
2026   else if (MMIX_CFUN_HAS_LANDING_PAD)
2027     offset -= 8;
2028
2029   if (MMIX_CFUN_HAS_LANDING_PAD)
2030     {
2031       /* Store the register defining the numbering of local registers, so
2032          we know how long to unwind the register stack.  */
2033
2034       if (offset < 0)
2035         {
2036           /* Get 8 less than otherwise, since we need to reach offset + 8.  */
2037           HOST_WIDE_INT stack_chunk
2038             = stack_space_to_allocate > (256 - 8 - 8)
2039             ? (256 - 8 - 8) : stack_space_to_allocate;
2040
2041           mmix_emit_sp_add (-stack_chunk);
2042
2043           offset += stack_chunk;
2044           stack_space_to_allocate -= stack_chunk;
2045         }
2046
2047       /* We don't tell dwarf2 about this one; we just have it to unwind
2048          the register stack at landing pads.  FIXME: It's a kludge because
2049          we can't describe the effect of the PUSHJ and PUSHGO insns on the
2050          register stack at the moment.  Best thing would be to handle it
2051          like stack-pointer offsets.  Better: some hook into dwarf2out.c
2052          to produce DW_CFA_expression:s that specify the increment of rO,
2053          and unwind it at eh_return (preferred) or at the landing pad.
2054          Then saves to $0..$G-1 could be specified through that register.  */
2055
2056       emit_move_insn (gen_rtx_REG (DImode, 255),
2057                       gen_rtx_REG (DImode,
2058                                    MMIX_rO_REGNUM));
2059       emit_move_insn (gen_rtx_MEM (DImode,
2060                                    plus_constant (stack_pointer_rtx, offset)),
2061                       gen_rtx_REG (DImode, 255));
2062       offset -= 8;
2063     }
2064
2065   /* After the return-address and the frame-pointer, we have the local
2066      variables.  They're the ones that may have an "unaligned" size.  */
2067   offset -= (locals_size + 7) & ~7;
2068
2069   /* Now store all registers that are global, i.e. not saved by the
2070      register file machinery.
2071
2072      It is assumed that the frame-pointer is one of these registers, so it
2073      is explicitly excluded in the count.  */
2074
2075   for (regno = 255;
2076        regno >= MMIX_FIRST_GLOBAL_REGNUM;
2077        regno--)
2078     if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
2079          && df_regs_ever_live_p (regno) && ! call_used_regs[regno])
2080         || IS_MMIX_EH_RETURN_DATA_REG (regno))
2081       {
2082         rtx insn;
2083
2084         if (offset < 0)
2085           {
2086             HOST_WIDE_INT stack_chunk
2087               = (stack_space_to_allocate > (256 - offset - 8)
2088                  ? (256 - offset - 8) : stack_space_to_allocate);
2089
2090             mmix_emit_sp_add (-stack_chunk);
2091             offset += stack_chunk;
2092             stack_space_to_allocate -= stack_chunk;
2093           }
2094
2095         insn = emit_move_insn (gen_rtx_MEM (DImode,
2096                                             plus_constant (stack_pointer_rtx,
2097                                                            offset)),
2098                                gen_rtx_REG (DImode, regno));
2099         RTX_FRAME_RELATED_P (insn) = 1;
2100         offset -= 8;
2101       }
2102
2103   /* Finally, allocate room for outgoing args and local vars if room
2104      wasn't allocated above.  */
2105   if (stack_space_to_allocate)
2106     mmix_emit_sp_add (-stack_space_to_allocate);
2107 }
2108
2109 /* Expands the function epilogue into RTX.  */
2110
2111 void
2112 mmix_expand_epilogue (void)
2113 {
2114   HOST_WIDE_INT locals_size = get_frame_size ();
2115   int regno;
2116   HOST_WIDE_INT stack_space_to_deallocate
2117     = (current_function_outgoing_args_size
2118        + current_function_pretend_args_size
2119        + locals_size + 7) & ~7;
2120
2121   /* The first address to access is beyond the outgoing_args area.  */
2122   HOST_WIDE_INT offset = current_function_outgoing_args_size;
2123
2124   /* Add the space for global non-register-stack registers.
2125      It is assumed that the frame-pointer register can be one of these
2126      registers, in which case it is excluded from the count when needed.  */
2127   for (regno = 255;
2128        regno >= MMIX_FIRST_GLOBAL_REGNUM;
2129        regno--)
2130     if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
2131          && df_regs_ever_live_p (regno) && !call_used_regs[regno])
2132         || IS_MMIX_EH_RETURN_DATA_REG (regno))
2133       stack_space_to_deallocate += 8;
2134
2135   /* Add in the space for register stack-pointer.  If so, always add room
2136      for the saved PC.  */
2137   if (MMIX_CFUN_HAS_LANDING_PAD)
2138     stack_space_to_deallocate += 16;
2139   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
2140     /* If we have a saved return-address slot, add it in.  */
2141     stack_space_to_deallocate += 8;
2142
2143   /* Add in the frame-pointer.  */
2144   if (frame_pointer_needed)
2145     stack_space_to_deallocate += 8;
2146
2147   /* Make sure we don't get an unaligned stack.  */
2148   if ((stack_space_to_deallocate % 8) != 0)
2149     internal_error ("stack frame not a multiple of octabyte: %wd",
2150                     stack_space_to_deallocate);
2151
2152   /* We will add back small offsets to the stack pointer as we go.
2153      First, we restore all registers that are global, i.e. not saved by
2154      the register file machinery.  */
2155
2156   for (regno = MMIX_FIRST_GLOBAL_REGNUM;
2157        regno <= 255;
2158        regno++)
2159     if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
2160          && df_regs_ever_live_p (regno) && !call_used_regs[regno])
2161         || IS_MMIX_EH_RETURN_DATA_REG (regno))
2162       {
2163         if (offset > 255)
2164           {
2165             mmix_emit_sp_add (offset);
2166             stack_space_to_deallocate -= offset;
2167             offset = 0;
2168           }
2169
2170         emit_move_insn (gen_rtx_REG (DImode, regno),
2171                         gen_rtx_MEM (DImode,
2172                                      plus_constant (stack_pointer_rtx,
2173                                                     offset)));
2174         offset += 8;
2175       }
2176
2177   /* Here is where the local variables were.  As in the prologue, they
2178      might be of an unaligned size.  */
2179   offset += (locals_size + 7) & ~7;
2180
2181   /* The saved register stack pointer is just below the frame-pointer
2182      register.  We don't need to restore it "manually"; the POP
2183      instruction does that.  */
2184   if (MMIX_CFUN_HAS_LANDING_PAD)
2185     offset += 16;
2186   else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
2187     /* The return-address slot is just below the frame-pointer register.
2188        We don't need to restore it because we don't really use it.  */
2189     offset += 8;
2190
2191   /* Get back the old frame-pointer-value.  */
2192   if (frame_pointer_needed)
2193     {
2194       if (offset > 255)
2195         {
2196           mmix_emit_sp_add (offset);
2197
2198           stack_space_to_deallocate -= offset;
2199           offset = 0;
2200         }
2201
2202       emit_move_insn (hard_frame_pointer_rtx,
2203                       gen_rtx_MEM (DImode,
2204                                    plus_constant (stack_pointer_rtx,
2205                                                   offset)));
2206       offset += 8;
2207     }
2208
2209   /* We do not need to restore pretended incoming args, just add back
2210      offset to sp.  */
2211   if (stack_space_to_deallocate != 0)
2212     mmix_emit_sp_add (stack_space_to_deallocate);
2213
2214   if (current_function_calls_eh_return)
2215     /* Adjust the (normal) stack-pointer to that of the receiver.
2216        FIXME: It would be nice if we could also adjust the register stack
2217        here, but we need to express it through DWARF 2 too.  */
2218     emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
2219                            gen_rtx_REG (DImode,
2220                                         MMIX_EH_RETURN_STACKADJ_REGNUM)));
2221 }
2222
2223 /* Output an optimal sequence for setting a register to a specific
2224    constant.  Used in an alternative for const_ints in movdi, and when
2225    using large stack-frame offsets.
2226
2227    Use do_begin_end to say if a line-starting TAB and newline before the
2228    first insn and after the last insn is wanted.  */
2229
2230 void
2231 mmix_output_register_setting (FILE *stream,
2232                               int regno,
2233                               HOST_WIDEST_INT value,
2234                               int do_begin_end)
2235 {
2236   if (do_begin_end)
2237     fprintf (stream, "\t");
2238
2239   if (mmix_shiftable_wyde_value ((unsigned HOST_WIDEST_INT) value))
2240     {
2241       /* First, the one-insn cases.  */
2242       mmix_output_shiftvalue_op_from_str (stream, "SET",
2243                                           (unsigned HOST_WIDEST_INT)
2244                                           value);
2245       fprintf (stream, " %s,", reg_names[regno]);
2246       mmix_output_shifted_value (stream, (unsigned HOST_WIDEST_INT) value);
2247     }
2248   else if (mmix_shiftable_wyde_value (-(unsigned HOST_WIDEST_INT) value))
2249     {
2250       /* We do this to get a bit more legible assembly code.  The next
2251          alternative is mostly redundant with this.  */
2252
2253       mmix_output_shiftvalue_op_from_str (stream, "SET",
2254                                           -(unsigned HOST_WIDEST_INT)
2255                                           value);
2256       fprintf (stream, " %s,", reg_names[regno]);
2257       mmix_output_shifted_value (stream, -(unsigned HOST_WIDEST_INT) value);
2258       fprintf (stream, "\n\tNEGU %s,0,%s", reg_names[regno],
2259                reg_names[regno]);
2260     }
2261   else if (mmix_shiftable_wyde_value (~(unsigned HOST_WIDEST_INT) value))
2262     {
2263       /* Slightly more expensive, the two-insn cases.  */
2264
2265       /* FIXME: We could of course also test if 0..255-N or ~(N | 1..255)
2266          is shiftable, or any other one-insn transformation of the value.
2267          FIXME: Check first if the value is "shiftable" by two loading
2268          with two insns, since it makes more readable assembly code (if
2269          anyone else cares).  */
2270
2271       mmix_output_shiftvalue_op_from_str (stream, "SET",
2272                                           ~(unsigned HOST_WIDEST_INT)
2273                                           value);
2274       fprintf (stream, " %s,", reg_names[regno]);
2275       mmix_output_shifted_value (stream, ~(unsigned HOST_WIDEST_INT) value);
2276       fprintf (stream, "\n\tNOR %s,%s,0", reg_names[regno],
2277                reg_names[regno]);
2278     }
2279   else
2280     {
2281       /* The generic case.  2..4 insns.  */
2282       static const char *const higher_parts[] = {"L", "ML", "MH", "H"};
2283       const char *op = "SET";
2284       const char *line_begin = "";
2285       int insns = 0;
2286       int i;
2287       HOST_WIDEST_INT tmpvalue = value;
2288
2289       /* Compute the number of insns needed to output this constant.  */
2290       for (i = 0; i < 4 && tmpvalue != 0; i++)
2291         {
2292           if (tmpvalue & 65535)
2293             insns++;
2294           tmpvalue >>= 16;
2295         }
2296       if (TARGET_BASE_ADDRESSES && insns == 3)
2297         {
2298           /* The number three is based on a static observation on
2299              ghostscript-6.52.  Two and four are excluded because there
2300              are too many such constants, and each unique constant (maybe
2301              offset by 1..255) were used few times compared to other uses,
2302              e.g. addresses.
2303
2304              We use base-plus-offset addressing to force it into a global
2305              register; we just use a "LDA reg,VALUE", which will cause the
2306              assembler and linker to DTRT (for constants as well as
2307              addresses).  */
2308           fprintf (stream, "LDA %s,", reg_names[regno]);
2309           mmix_output_octa (stream, value, 0);
2310         }
2311       else
2312         {
2313           /* Output pertinent parts of the 4-wyde sequence.
2314              Still more to do if we want this to be optimal, but hey...
2315              Note that the zero case has been handled above.  */
2316           for (i = 0; i < 4 && value != 0; i++)
2317             {
2318               if (value & 65535)
2319                 {
2320                   fprintf (stream, "%s%s%s %s,#%x", line_begin, op,
2321                            higher_parts[i], reg_names[regno],
2322                            (int) (value & 65535));
2323                   /* The first one sets the rest of the bits to 0, the next
2324                      ones add set bits.  */
2325                   op = "INC";
2326                   line_begin = "\n\t";
2327                 }
2328
2329               value >>= 16;
2330             }
2331         }
2332     }
2333
2334   if (do_begin_end)
2335     fprintf (stream, "\n");
2336 }
2337
2338 /* Return 1 if value is 0..65535*2**(16*N) for N=0..3.
2339    else return 0.  */
2340
2341 int
2342 mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT value)
2343 {
2344   /* Shift by 16 bits per group, stop when we've found two groups with
2345      nonzero bits.  */
2346   int i;
2347   int has_candidate = 0;
2348
2349   for (i = 0; i < 4; i++)
2350     {
2351       if (value & 65535)
2352         {
2353           if (has_candidate)
2354             return 0;
2355           else
2356             has_candidate = 1;
2357         }
2358
2359       value >>= 16;
2360     }
2361
2362   return 1;
2363 }
2364
2365 /* Returns zero if code and mode is not a valid condition from a
2366    compare-type insn.  Nonzero if it is.  The parameter op, if non-NULL,
2367    is the comparison of mode is CC-somethingmode.  */
2368
2369 int
2370 mmix_valid_comparison (RTX_CODE code, enum machine_mode mode, rtx op)
2371 {
2372   if (mode == VOIDmode && op != NULL_RTX)
2373     mode = GET_MODE (op);
2374
2375   /* We don't care to look at these, they should always be valid.  */
2376   if (mode == CCmode || mode == CC_UNSmode || mode == DImode)
2377     return 1;
2378
2379   if ((mode == CC_FPmode || mode == DFmode)
2380       && (code == GT || code == LT))
2381     return 1;
2382
2383   if ((mode == CC_FPEQmode || mode == DFmode)
2384       && (code == EQ || code == NE))
2385     return 1;
2386
2387   if ((mode == CC_FUNmode || mode == DFmode)
2388       && (code == ORDERED || code == UNORDERED))
2389     return 1;
2390
2391   return 0;
2392 }
2393
2394 /* X and Y are two things to compare using CODE.  Emit a compare insn if
2395    possible and return the rtx for the cc-reg in the proper mode, or
2396    NULL_RTX if this is not a valid comparison.  */
2397
2398 rtx
2399 mmix_gen_compare_reg (RTX_CODE code, rtx x, rtx y)
2400 {
2401   enum machine_mode ccmode = SELECT_CC_MODE (code, x, y);
2402   rtx cc_reg;
2403
2404   /* FIXME: Do we get constants here?  Of double mode?  */
2405   enum machine_mode mode
2406     = GET_MODE (x) == VOIDmode
2407     ? GET_MODE (y)
2408     : GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT ? DFmode : DImode;
2409
2410   if (! mmix_valid_comparison (code, mode, x))
2411     return NULL_RTX;
2412
2413   cc_reg = gen_reg_rtx (ccmode);
2414
2415   /* FIXME:  Can we avoid emitting a compare insn here?  */
2416   if (! REG_P (x) && ! REG_P (y))
2417     x = force_reg (mode, x);
2418
2419   /* If it's not quite right yet, put y in a register.  */
2420   if (! REG_P (y)
2421       && (GET_CODE (y) != CONST_INT
2422           || ! CONST_OK_FOR_LETTER_P (INTVAL (y), 'I')))
2423     y = force_reg (mode, y);
2424
2425   emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
2426                           gen_rtx_COMPARE (ccmode, x, y)));
2427
2428   return cc_reg;
2429 }
2430
2431 /* Local (static) helper functions.  */
2432
2433 static void
2434 mmix_emit_sp_add (HOST_WIDE_INT offset)
2435 {
2436   rtx insn;
2437
2438   if (offset < 0)
2439     {
2440       /* Negative stack-pointer adjustments are allocations and appear in
2441          the prologue only.  We mark them as frame-related so unwind and
2442          debug info is properly emitted for them.  */
2443       if (offset > -255)
2444         insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
2445                                       stack_pointer_rtx,
2446                                       GEN_INT (offset)));
2447       else
2448         {
2449           rtx tmpr = gen_rtx_REG (DImode, 255);
2450           RTX_FRAME_RELATED_P (emit_move_insn (tmpr, GEN_INT (offset))) = 1;
2451           insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
2452                                         stack_pointer_rtx, tmpr));
2453         }
2454       RTX_FRAME_RELATED_P (insn) = 1;
2455     }
2456   else
2457     {
2458       /* Positive adjustments are in the epilogue only.  Don't mark them
2459          as "frame-related" for unwind info.  */
2460       if (CONST_OK_FOR_LETTER_P (offset, 'L'))
2461         emit_insn (gen_adddi3 (stack_pointer_rtx,
2462                                stack_pointer_rtx,
2463                                GEN_INT (offset)));
2464       else
2465         {
2466           rtx tmpr = gen_rtx_REG (DImode, 255);
2467           emit_move_insn (tmpr, GEN_INT (offset));
2468           insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
2469                                         stack_pointer_rtx, tmpr));
2470         }
2471     }
2472 }
2473
2474 /* Print operator suitable for doing something with a shiftable
2475    wyde.  The type of operator is passed as an asm output modifier.  */
2476
2477 static void
2478 mmix_output_shiftvalue_op_from_str (FILE *stream,
2479                                     const char *mainop,
2480                                     HOST_WIDEST_INT value)
2481 {
2482   static const char *const op_part[] = {"L", "ML", "MH", "H"};
2483   int i;
2484
2485   if (! mmix_shiftable_wyde_value (value))
2486     {
2487       char s[sizeof ("0xffffffffffffffff")];
2488       sprintf (s, HOST_WIDEST_INT_PRINT_HEX, value);
2489       internal_error ("MMIX Internal: %s is not a shiftable int", s);
2490     }
2491
2492   for (i = 0; i < 4; i++)
2493     {
2494       /* We know we're through when we find one-bits in the low
2495          16 bits.  */
2496       if (value & 0xffff)
2497         {
2498           fprintf (stream, "%s%s", mainop, op_part[i]);
2499           return;
2500         }
2501       value >>= 16;
2502     }
2503
2504   /* No bits set?  Then it must have been zero.  */
2505   fprintf (stream, "%sL", mainop);
2506 }
2507
2508 /* Print a 64-bit value, optionally prefixed by assembly pseudo.  */
2509
2510 static void
2511 mmix_output_octa (FILE *stream, HOST_WIDEST_INT value, int do_begin_end)
2512 {
2513   /* Snipped from final.c:output_addr_const.  We need to avoid the
2514      presumed universal "0x" prefix.  We can do it by replacing "0x" with
2515      "#0" here; we must avoid a space in the operands and no, the zero
2516      won't cause the number to be assumed in octal format.  */
2517   char hex_format[sizeof (HOST_WIDEST_INT_PRINT_HEX)];
2518
2519   if (do_begin_end)
2520     fprintf (stream, "\tOCTA ");
2521
2522   strcpy (hex_format, HOST_WIDEST_INT_PRINT_HEX);
2523   hex_format[0] = '#';
2524   hex_format[1] = '0';
2525
2526   /* Provide a few alternative output formats depending on the number, to
2527      improve legibility of assembler output.  */
2528   if ((value < (HOST_WIDEST_INT) 0 && value > (HOST_WIDEST_INT) -10000)
2529       || (value >= (HOST_WIDEST_INT) 0 && value <= (HOST_WIDEST_INT) 16384))
2530     fprintf (stream, "%d", (int) value);
2531   else if (value > (HOST_WIDEST_INT) 0
2532            && value < ((HOST_WIDEST_INT) 1 << 31) * 2)
2533     fprintf (stream, "#%x", (unsigned int) value);
2534   else
2535     fprintf (stream, hex_format, value);
2536
2537   if (do_begin_end)
2538     fprintf (stream, "\n");
2539 }
2540
2541 /* Print the presumed shiftable wyde argument shifted into place (to
2542    be output with an operand).  */
2543
2544 static void
2545 mmix_output_shifted_value (FILE *stream, HOST_WIDEST_INT value)
2546 {
2547   int i;
2548
2549   if (! mmix_shiftable_wyde_value (value))
2550     {
2551       char s[16+2+1];
2552       sprintf (s, HOST_WIDEST_INT_PRINT_HEX, value);
2553       internal_error ("MMIX Internal: %s is not a shiftable int", s);
2554     }
2555
2556   for (i = 0; i < 4; i++)
2557     {
2558       /* We know we're through when we find one-bits in the low 16 bits.  */
2559       if (value & 0xffff)
2560         {
2561           fprintf (stream, "#%x", (int) (value & 0xffff));
2562           return;
2563         }
2564
2565     value >>= 16;
2566   }
2567
2568   /* No bits set?  Then it must have been zero.  */
2569   fprintf (stream, "0");
2570 }
2571
2572 /* Output an MMIX condition name corresponding to an operator
2573    and operands:
2574    (comparison_operator [(comparison_operator ...) (const_int 0)])
2575    which means we have to look at *two* operators.
2576
2577    The argument "reversed" refers to reversal of the condition (not the
2578    same as swapping the arguments).  */
2579
2580 static void
2581 mmix_output_condition (FILE *stream, rtx x, int reversed)
2582 {
2583   struct cc_conv
2584   {
2585     RTX_CODE cc;
2586
2587     /* The normal output cc-code.  */
2588     const char *const normal;
2589
2590     /* The reversed cc-code, or NULL if invalid.  */
2591     const char *const reversed;
2592   };
2593
2594   struct cc_type_conv
2595   {
2596     enum machine_mode cc_mode;
2597
2598     /* Terminated with {UNKNOWN, NULL, NULL} */
2599     const struct cc_conv *const convs;
2600   };
2601
2602 #undef CCEND
2603 #define CCEND {UNKNOWN, NULL, NULL}
2604
2605   static const struct cc_conv cc_fun_convs[]
2606     = {{ORDERED, "Z", "P"},
2607        {UNORDERED, "P", "Z"},
2608        CCEND};
2609   static const struct cc_conv cc_fp_convs[]
2610     = {{GT, "P", NULL},
2611        {LT, "N", NULL},
2612        CCEND};
2613   static const struct cc_conv cc_fpeq_convs[]
2614     = {{NE, "Z", "P"},
2615        {EQ, "P", "Z"},
2616        CCEND};
2617   static const struct cc_conv cc_uns_convs[]
2618     = {{GEU, "NN", "N"},
2619        {GTU, "P", "NP"},
2620        {LEU, "NP", "P"},
2621        {LTU, "N", "NN"},
2622        CCEND};
2623   static const struct cc_conv cc_signed_convs[]
2624     = {{NE, "NZ", "Z"},
2625        {EQ, "Z", "NZ"},
2626        {GE, "NN", "N"},
2627        {GT, "P", "NP"},
2628        {LE, "NP", "P"},
2629        {LT, "N", "NN"},
2630        CCEND};
2631   static const struct cc_conv cc_di_convs[]
2632     = {{NE, "NZ", "Z"},
2633        {EQ, "Z", "NZ"},
2634        {GE, "NN", "N"},
2635        {GT, "P", "NP"},
2636        {LE, "NP", "P"},
2637        {LT, "N", "NN"},
2638        {GTU, "NZ", "Z"},
2639        {LEU, "Z", "NZ"},
2640        CCEND};
2641 #undef CCEND
2642
2643   static const struct cc_type_conv cc_convs[]
2644     = {{CC_FUNmode, cc_fun_convs},
2645        {CC_FPmode, cc_fp_convs},
2646        {CC_FPEQmode, cc_fpeq_convs},
2647        {CC_UNSmode, cc_uns_convs},
2648        {CCmode, cc_signed_convs},
2649        {DImode, cc_di_convs}};
2650
2651   size_t i;
2652   int j;
2653
2654   enum machine_mode mode = GET_MODE (XEXP (x, 0));
2655   RTX_CODE cc = GET_CODE (x);
2656
2657   for (i = 0; i < ARRAY_SIZE (cc_convs); i++)
2658     {
2659       if (mode == cc_convs[i].cc_mode)
2660         {
2661           for (j = 0; cc_convs[i].convs[j].cc != UNKNOWN; j++)
2662             if (cc == cc_convs[i].convs[j].cc)
2663               {
2664                 const char *mmix_cc
2665                   = (reversed ? cc_convs[i].convs[j].reversed
2666                      : cc_convs[i].convs[j].normal);
2667
2668                 if (mmix_cc == NULL)
2669                   fatal_insn ("MMIX Internal: Trying to output invalidly\
2670  reversed condition:", x);
2671
2672                 fprintf (stream, "%s", mmix_cc);
2673                 return;
2674               }
2675
2676           fatal_insn ("MMIX Internal: What's the CC of this?", x);
2677         }
2678     }
2679
2680   fatal_insn ("MMIX Internal: What is the CC of this?", x);
2681 }
2682
2683 /* Return the bit-value for a const_int or const_double.  */
2684
2685 static HOST_WIDEST_INT
2686 mmix_intval (rtx x)
2687 {
2688   unsigned HOST_WIDEST_INT retval;
2689
2690   if (GET_CODE (x) == CONST_INT)
2691     return INTVAL (x);
2692
2693   /* We make a little song and dance because converting to long long in
2694      gcc-2.7.2 is broken.  I still want people to be able to use it for
2695      cross-compilation to MMIX.  */
2696   if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == VOIDmode)
2697     {
2698       if (sizeof (HOST_WIDE_INT) < sizeof (HOST_WIDEST_INT))
2699         {
2700           retval = (unsigned) CONST_DOUBLE_LOW (x) / 2;
2701           retval *= 2;
2702           retval |= CONST_DOUBLE_LOW (x) & 1;
2703
2704           retval |=
2705             (unsigned HOST_WIDEST_INT) CONST_DOUBLE_HIGH (x)
2706               << (HOST_BITS_PER_LONG);
2707         }
2708       else
2709         retval = CONST_DOUBLE_HIGH (x);
2710
2711       return retval;
2712     }
2713
2714   if (GET_CODE (x) == CONST_DOUBLE)
2715     {
2716       REAL_VALUE_TYPE value;
2717
2718       /* FIXME:  This macro is not in the manual but should be.  */
2719       REAL_VALUE_FROM_CONST_DOUBLE (value, x);
2720
2721       if (GET_MODE (x) == DFmode)
2722         {
2723           long bits[2];
2724
2725           REAL_VALUE_TO_TARGET_DOUBLE (value, bits);
2726
2727           /* The double cast is necessary to avoid getting the long
2728              sign-extended to unsigned long long(!) when they're of
2729              different size (usually 32-bit hosts).  */
2730           return
2731             ((unsigned HOST_WIDEST_INT) (unsigned long) bits[0]
2732              << (unsigned HOST_WIDEST_INT) 32U)
2733             | (unsigned HOST_WIDEST_INT) (unsigned long) bits[1];
2734         }
2735       else if (GET_MODE (x) == SFmode)
2736         {
2737           long bits;
2738           REAL_VALUE_TO_TARGET_SINGLE (value, bits);
2739
2740           return (unsigned long) bits;
2741         }
2742     }
2743
2744   fatal_insn ("MMIX Internal: This is not a constant:", x);
2745 }
2746
2747 /* Worker function for TARGET_STRUCT_VALUE_RTX.  */
2748
2749 static rtx
2750 mmix_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
2751                        int incoming ATTRIBUTE_UNUSED)
2752 {
2753   return gen_rtx_REG (Pmode, MMIX_STRUCT_VALUE_REGNUM);
2754 }
2755
2756 /*
2757  * Local variables:
2758  * eval: (c-set-style "gnu")
2759  * indent-tabs-mode: t
2760  * End:
2761  */