OSDN Git Service

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