OSDN Git Service

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