OSDN Git Service

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