OSDN Git Service

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