OSDN Git Service

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