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