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)
5 This file is part of GCC.
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)
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.
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/>. */
23 #include "coretypes.h"
29 #include "insn-config.h"
35 #include "cfgcleanup.h"
38 #include "stor-layout.h"
47 #include "diagnostic-core.h"
53 #include "tm-constrs.h"
56 /* This file should be included last. */
57 #include "target-def.h"
59 /* First some local helper definitions. */
60 #define MMIX_FIRST_GLOBAL_REGNUM 32
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
65 #define MMIX_CFUN_HAS_LANDING_PAD (cfun->machine->has_landing_pad != 0)
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
78 #define MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS \
80 && ((reload_completed && df_regs_ever_live_p (MMIX_rJ_REGNUM)) \
81 || !leaf_function_p ()))
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))
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) \
99 || (int) (N) < MMIX_RETURN_VALUE_REGNUM \
100 || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM \
102 || cfun->machine == NULL \
103 || cfun->machine->in_prologue \
104 ? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM \
105 + cfun->machine->highest_saved_stack_register + 1))
107 /* The %d in "POP %d,0". */
108 #define MMIX_POP_ARGUMENT() \
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) \
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
;
121 /* Declarations of locals. */
123 /* Intermediate for insn output. */
124 static int mmix_output_destination_register
;
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
,
158 int *, const_tree
, int);
159 static void mmix_function_arg_advance (cumulative_args_t
, machine_mode
,
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
,
165 static rtx
mmix_function_arg (cumulative_args_t
, machine_mode
,
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);
180 /* Target structure macros. Listed by node. See `Using and Porting GCC'
181 for a general description. */
183 /* Node: Function Entry */
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
196 #undef TARGET_ASM_FUNCTION_PROLOGUE
197 #define TARGET_ASM_FUNCTION_PROLOGUE mmix_target_asm_function_prologue
199 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
200 #define TARGET_ASM_FUNCTION_END_PROLOGUE mmix_target_asm_function_end_prologue
202 #undef TARGET_ASM_FUNCTION_EPILOGUE
203 #define TARGET_ASM_FUNCTION_EPILOGUE mmix_target_asm_function_epilogue
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
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
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
230 #undef TARGET_CONDITIONAL_REGISTER_USAGE
231 #define TARGET_CONDITIONAL_REGISTER_USAGE mmix_conditional_register_usage
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
238 #undef TARGET_REGISTER_MOVE_COST
239 #define TARGET_REGISTER_MOVE_COST mmix_register_move_cost
241 #undef TARGET_MACHINE_DEPENDENT_REORG
242 #define TARGET_MACHINE_DEPENDENT_REORG mmix_reorg
244 #undef TARGET_PROMOTE_FUNCTION_MODE
245 #define TARGET_PROMOTE_FUNCTION_MODE mmix_promote_function_mode
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
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
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
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
279 #undef TARGET_FRAME_POINTER_REQUIRED
280 #define TARGET_FRAME_POINTER_REQUIRED mmix_frame_pointer_required
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
287 #undef TARGET_OPTION_OVERRIDE
288 #define TARGET_OPTION_OVERRIDE mmix_option_override
290 struct gcc_target targetm
= TARGET_INITIALIZER
;
292 /* Functions that are expansions for target macros.
293 See Target Macros in `Using and Porting GCC'. */
295 /* TARGET_OPTION_OVERRIDE. */
298 mmix_option_override (void)
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
307 warning (0, "-f%s not supported: ignored", (flag_pic
> 1) ? "PIC" : "pic");
312 /* INIT_EXPANDERS. */
315 mmix_init_expanders (void)
317 init_machine_status
= mmix_init_machine_status
;
320 /* Set the per-function data. */
322 static struct machine_function
*
323 mmix_init_machine_status (void)
325 return ggc_cleared_alloc
<machine_function
> ();
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. */
334 mmix_data_alignment (tree type ATTRIBUTE_UNUSED
, int basic_align
)
336 if (basic_align
< 32)
342 /* CONSTANT_ALIGNMENT. */
345 mmix_constant_alignment (tree constant ATTRIBUTE_UNUSED
, int basic_align
)
347 if (basic_align
< 32)
353 /* LOCAL_ALIGNMENT. */
356 mmix_local_alignment (tree type ATTRIBUTE_UNUSED
, unsigned basic_align
)
358 if (basic_align
< 32)
364 /* TARGET_CONDITIONAL_REGISTER_USAGE. */
367 mmix_conditional_register_usage (void)
373 static const int gnu_abi_reg_alloc_order
[]
374 = MMIX_GNU_ABI_REG_ALLOC_ORDER
;
376 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
377 reg_alloc_order
[i
] = gnu_abi_reg_alloc_order
[i
];
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
386 for (i
= 15; i
<= 30; i
++)
387 call_used_regs
[i
] = 0;
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
;
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] == ':')
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
424 mmix_opposite_regno (int regno
, int incoming
)
426 if (incoming
&& regno
== MMIX_OUTGOING_RETURN_VALUE_REGNUM
)
427 return MMIX_RETURN_VALUE_REGNUM
;
429 if (!incoming
&& regno
== MMIX_RETURN_VALUE_REGNUM
)
430 return MMIX_OUTGOING_RETURN_VALUE_REGNUM
;
432 if (!mmix_function_arg_regno_p (regno
, incoming
))
437 ? MMIX_FIRST_INCOMING_ARG_REGNUM
- MMIX_FIRST_ARG_REGNUM
438 : MMIX_FIRST_ARG_REGNUM
- MMIX_FIRST_INCOMING_ARG_REGNUM
);
442 All registers that are part of the register stack and that will be
446 mmix_local_regno (int regno
)
448 return regno
<= MMIX_LAST_STACK_REGISTER_REGNUM
&& !call_used_regs
[regno
];
451 /* TARGET_PREFERRED_RELOAD_CLASS.
452 We need to extend the reload class of REMAINDER_REG and HIMULT_REG. */
455 mmix_preferred_reload_class (rtx x
, reg_class_t rclass
)
457 /* FIXME: Revisit. */
458 return GET_CODE (x
) == MOD
&& GET_MODE (x
) == DImode
459 ? REMAINDER_REG
: rclass
;
462 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS.
463 We need to extend the reload class of REMAINDER_REG and HIMULT_REG. */
466 mmix_preferred_output_reload_class (rtx x
, reg_class_t rclass
)
468 /* FIXME: Revisit. */
469 return GET_CODE (x
) == MOD
&& GET_MODE (x
) == DImode
470 ? REMAINDER_REG
: rclass
;
473 /* SECONDARY_RELOAD_CLASS.
474 We need to reload regs of REMAINDER_REG and HIMULT_REG elsewhere. */
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
)
482 if (rclass
== REMAINDER_REG
483 || rclass
== HIMULT_REG
484 || rclass
== SYSTEM_REGS
)
490 /* DYNAMIC_CHAIN_ADDRESS. */
493 mmix_dynamic_chain_address (rtx frame
)
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);
502 /* STARTING_FRAME_OFFSET. */
505 mmix_starting_frame_offset (void)
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. */
515 + (MMIX_CFUN_HAS_LANDING_PAD
516 ? -16 : (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
? -8 : 0)));
519 /* RETURN_ADDR_RTX. */
522 mmix_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
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
))
537 /* SETUP_FRAME_ADDRESSES. */
540 mmix_setup_frame_addresses (void)
542 /* Nothing needed at the moment. */
545 /* The difference between the (imaginary) frame pointer and the stack
546 pointer. Used to eliminate the frame pointer. */
549 mmix_initial_elimination_offset (int fromreg
, int toreg
)
553 = (get_frame_size () + crtl
->outgoing_args_size
+ 7) & ~7;
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
559 if (fromreg
== MMIX_ARG_POINTER_REGNUM
560 && toreg
== MMIX_FRAME_POINTER_REGNUM
)
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.
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.
572 Also add in the slot for the register stack pointer we save if we
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.
582 We have to do alignment here; get_frame_size will not return a
583 multiple of STACK_BOUNDARY. FIXME: Add note in manual. */
585 for (regno
= MMIX_FIRST_GLOBAL_REGNUM
;
588 if ((df_regs_ever_live_p (regno
) && ! call_used_regs
[regno
])
589 || IS_MMIX_EH_RETURN_DATA_REG (regno
))
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);
599 mmix_function_arg_advance (cumulative_args_t argsp_v
, machine_mode mode
,
600 const_tree type
, bool named ATTRIBUTE_UNUSED
)
602 CUMULATIVE_ARGS
*argsp
= get_cumulative_args (argsp_v
);
603 int arg_size
= MMIX_FUNCTION_ARG_SIZE (mode
, type
);
605 argsp
->regs
= ((targetm
.calls
.must_pass_in_stack (mode
, type
)
609 ? (MMIX_MAX_ARGS_IN_REGS
) + 1
610 : argsp
->regs
+ (7 + arg_size
) / 8);
613 /* Helper function for mmix_function_arg and mmix_function_incoming_arg. */
616 mmix_function_arg_1 (const cumulative_args_t argsp_v
,
619 bool named ATTRIBUTE_UNUSED
,
622 CUMULATIVE_ARGS
*argsp
= get_cumulative_args (argsp_v
);
624 /* Last-argument marker. */
625 if (type
== void_type_node
)
626 return (argsp
->regs
< MMIX_MAX_ARGS_IN_REGS
)
629 ? MMIX_FIRST_INCOMING_ARG_REGNUM
630 : MMIX_FIRST_ARG_REGNUM
) + argsp
->regs
)
633 return (argsp
->regs
< MMIX_MAX_ARGS_IN_REGS
634 && !targetm
.calls
.must_pass_in_stack (mode
, type
)
635 && (GET_MODE_BITSIZE (mode
) <= 64
640 ? MMIX_FIRST_INCOMING_ARG_REGNUM
641 : MMIX_FIRST_ARG_REGNUM
)
646 /* Return an rtx for a function argument to go in a register, and 0 for
647 one that must go on stack. */
650 mmix_function_arg (cumulative_args_t argsp
,
655 return mmix_function_arg_1 (argsp
, mode
, type
, named
, false);
659 mmix_function_incoming_arg (cumulative_args_t argsp
,
664 return mmix_function_arg_1 (argsp
, mode
, type
, named
, true);
667 /* Returns nonzero for everything that goes by reference, 0 for
668 everything that goes by value. */
671 mmix_pass_by_reference (cumulative_args_t argsp_v
, machine_mode mode
,
672 const_tree type
, bool named ATTRIBUTE_UNUSED
)
674 CUMULATIVE_ARGS
*argsp
= get_cumulative_args (argsp_v
);
676 /* FIXME: Check: I'm not sure the must_pass_in_stack check is
678 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
681 if (MMIX_FUNCTION_ARG_SIZE (mode
, type
) > 8
683 && (!argsp
|| !argsp
->lib
))
689 /* Return nonzero if regno is a register number where a parameter is
690 passed, and 0 otherwise. */
693 mmix_function_arg_regno_p (int regno
, int incoming
)
696 = incoming
? MMIX_FIRST_INCOMING_ARG_REGNUM
: MMIX_FIRST_ARG_REGNUM
;
698 return regno
>= first_arg_regnum
699 && regno
< first_arg_regnum
+ MMIX_MAX_ARGS_IN_REGS
;
702 /* Implements TARGET_FUNCTION_VALUE. */
705 mmix_function_value (const_tree valtype
,
706 const_tree func ATTRIBUTE_UNUSED
,
709 machine_mode mode
= TYPE_MODE (valtype
);
711 int first_val_regnum
= MMIX_OUTGOING_RETURN_VALUE_REGNUM
;
712 rtx vec
[MMIX_MAX_REGS_FOR_VALUE
];
717 return gen_rtx_REG (mode
, MMIX_RETURN_VALUE_REGNUM
);
719 /* Return values that fit in a register need no special handling.
720 There's no register hole when parameters are passed in global
723 || GET_MODE_BITSIZE (mode
) <= BITS_PER_WORD
)
725 gen_rtx_REG (mode
, MMIX_OUTGOING_RETURN_VALUE_REGNUM
);
727 if (COMPLEX_MODE_P (mode
))
728 /* A complex type, made up of components. */
729 cmode
= TYPE_MODE (TREE_TYPE (valtype
));
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
737 sorry ("support for mode %qs", GET_MODE_NAME (mode
));
739 /* In any case, we will fill registers to the natural size. */
743 nregs
= ((GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
);
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.) */
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
);
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
++)
758 = gen_rtx_EXPR_LIST (VOIDmode
,
759 gen_rtx_REG (cmode
, first_val_regnum
+ i
),
760 GEN_INT ((i
+ 1) * BITS_PER_UNIT
));
763 = gen_rtx_EXPR_LIST (VOIDmode
,
764 gen_rtx_REG (cmode
, first_val_regnum
+ nregs
- 1),
767 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (nregs
, vec
));
770 /* Implements TARGET_LIBCALL_VALUE. */
773 mmix_libcall_value (machine_mode mode
,
774 const_rtx fun ATTRIBUTE_UNUSED
)
776 return gen_rtx_REG (mode
, MMIX_RETURN_VALUE_REGNUM
);
779 /* Implements TARGET_FUNCTION_VALUE_REGNO_P. */
782 mmix_function_value_regno_p (const unsigned int regno
)
784 return regno
== MMIX_RETURN_VALUE_REGNUM
;
787 /* EH_RETURN_DATA_REGNO. */
790 mmix_eh_return_data_regno (int n
)
793 return MMIX_EH_RETURN_DATA_REGNO_START
+ n
;
795 return INVALID_REGNUM
;
798 /* EH_RETURN_STACKADJ_RTX. */
801 mmix_eh_return_stackadj_rtx (void)
803 return gen_rtx_REG (Pmode
, MMIX_EH_RETURN_STACKADJ_REGNUM
);
806 /* EH_RETURN_HANDLER_RTX. */
809 mmix_eh_return_handler_rtx (void)
811 return gen_rtx_REG (Pmode
, MMIX_INCOMING_RETURN_ADDRESS_REGNUM
);
814 /* ASM_PREFERRED_EH_DATA_FORMAT. */
817 mmix_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED
,
818 int global ATTRIBUTE_UNUSED
)
820 /* This is the default (was at 2001-07-20). Revisit when needed. */
821 return DW_EH_PE_absptr
;
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
829 mmix_target_asm_function_prologue (FILE *stream ATTRIBUTE_UNUSED
,
830 HOST_WIDE_INT framesize ATTRIBUTE_UNUSED
)
832 cfun
->machine
->in_prologue
= 1;
835 /* Make a note that we've seen the end of the prologue. */
838 mmix_target_asm_function_end_prologue (FILE *stream ATTRIBUTE_UNUSED
)
840 cfun
->machine
->in_prologue
= 0;
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. */
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
856 for (regno
= MMIX_LAST_STACK_REGISTER_REGNUM
;
859 if ((df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
860 || (regno
== MMIX_FRAME_POINTER_REGNUM
&& frame_pointer_needed
))
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)
872 regno
= crtl
->args
.info
.regs
- 1;
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;
882 cfun
->machine
->highest_saved_stack_register
= regno
;
885 /* TARGET_ASM_FUNCTION_EPILOGUE. */
888 mmix_target_asm_function_epilogue (FILE *stream
,
889 HOST_WIDE_INT locals_size ATTRIBUTE_UNUSED
)
891 /* Emit an \n for readability of the generated assembly. */
892 fputc ('\n', stream
);
895 /* TARGET_ASM_OUTPUT_MI_THUNK. */
898 mmix_asm_output_mi_thunk (FILE *stream
,
899 tree fndecl ATTRIBUTE_UNUSED
,
901 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
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
];
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
);
915 mmix_output_register_setting (stream
, 255, delta
, 1);
916 fprintf (stream
, "\tADDU %s,%s,$255\n", regname
, regname
);
919 fprintf (stream
, "\tJMP ");
920 assemble_name (stream
, XSTR (XEXP (DECL_RTL (func
), 0), 0));
921 fprintf (stream
, "\n");
924 /* FUNCTION_PROFILER. */
927 mmix_function_profiler (FILE *stream ATTRIBUTE_UNUSED
,
928 int labelno ATTRIBUTE_UNUSED
)
930 sorry ("function_profiler support for MMIX");
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. */
938 mmix_setup_incoming_varargs (cumulative_args_t args_so_farp_v
,
942 int second_time ATTRIBUTE_UNUSED
)
944 CUMULATIVE_ARGS
*args_so_farp
= get_cumulative_args (args_so_farp_v
);
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;
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");
957 /* TARGET_ASM_TRAMPOLINE_TEMPLATE. */
960 mmix_asm_trampoline_template (FILE *stream
)
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. */
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");
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). */
980 mmix_trampoline_init (rtx m_tramp
, tree fndecl
, rtx static_chain
)
982 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
985 emit_block_move (m_tramp
, assemble_trampoline_template (),
986 GEN_INT (2*UNITS_PER_WORD
), BLOCK_OP_NORMAL
);
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
);
993 mem
= adjust_address (m_tramp
, DImode
, 0);
994 emit_insn (gen_sync_icache (mem
, GEN_INT (TRAMPOLINE_SIZE
- 1)));
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. */
1002 mmix_constant_address_p (rtx x
)
1004 RTX_CODE code
= GET_CODE (x
);
1006 /* When using "base addresses", anything constant goes. */
1007 int constant_ok
= TARGET_BASE_ADDRESSES
!= 0;
1016 /* FIXME: Don't know how to dissect these. Avoid them for now,
1017 except we know they're constants. */
1021 addend
= INTVAL (x
);
1025 if (GET_MODE (x
) != VOIDmode
)
1026 /* Strange that we got here. FIXME: Check if we do. */
1028 addend
= CONST_DOUBLE_LOW (x
);
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
)
1037 rtx x0
= XEXP (XEXP (x
, 0), 0);
1038 rtx x1
= XEXP (XEXP (x
, 0), 1);
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
);
1057 return constant_ok
|| (addend
& 3) == 0;
1060 /* Return 1 if the address is OK, otherwise 0. */
1063 mmix_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
1065 bool strict_checking
)
1067 #define MMIX_REG_OK(X) \
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)))
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. */
1086 if (REG_P (x
) && MMIX_REG_OK (x
))
1089 if (GET_CODE(x
) == PLUS
)
1091 rtx x1
= XEXP (x
, 0);
1092 rtx x2
= XEXP (x
, 1);
1094 /* Try swapping the order. FIXME: Do we need this? */
1102 /* (mem (plus (reg?) (?))) */
1103 if (!REG_P (x1
) || !MMIX_REG_OK (x1
))
1104 return TARGET_BASE_ADDRESSES
&& mmix_constant_address_p (x
);
1106 /* (mem (plus (reg) (reg?))) */
1107 if (REG_P (x2
) && MMIX_REG_OK (x2
))
1110 /* (mem (plus (reg) (0..255?))) */
1111 if (satisfies_constraint_I (x2
))
1117 return TARGET_BASE_ADDRESSES
&& mmix_constant_address_p (x
);
1120 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1123 mmix_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1125 RTX_CODE code
= GET_CODE (x
);
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
)
1133 return CONSTANT_ADDRESS_P (x
);
1136 /* SELECT_CC_MODE. */
1139 mmix_select_cc_mode (RTX_CODE op
, rtx x
, rtx y ATTRIBUTE_UNUSED
)
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. */
1145 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
1147 if (op
== ORDERED
|| op
== UNORDERED
|| op
== UNGE
1148 || op
== UNGT
|| op
== UNLE
|| op
== UNLT
)
1151 if (op
== EQ
|| op
== NE
)
1157 if (op
== GTU
|| op
== LTU
|| op
== GEU
|| op
== LEU
)
1163 /* REVERSIBLE_CC_MODE. */
1166 mmix_reversible_cc_mode (machine_mode mode
)
1168 /* That is, all integer and the EQ, NE, ORDERED and UNORDERED float
1170 return mode
!= CC_FPmode
;
1173 /* TARGET_RTX_COSTS. */
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
)
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. */
1189 /* TARGET_REGISTER_MOVE_COST.
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. */
1195 mmix_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
1199 return (from
== GENERAL_REGS
&& from
== to
) ? 2 : 3;
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
1206 /* DATA_SECTION_ASM_OP. */
1209 mmix_data_section_asm_op (void)
1211 return "\t.data ! mmixal:= 8H LOC 9B";
1215 mmix_encode_section_info (tree decl
, rtx rtl
, int first
)
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
)))
1222 else if (first
&& DECL_P (decl
))
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.
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. */
1234 const char *str
= XSTR (XEXP (rtl
, 0), 0);
1235 int len
= strlen (str
);
1236 char *newstr
= XALLOCAVEC (char, len
+ 2);
1238 strcpy (newstr
+ 1, str
);
1239 XSTR (XEXP (rtl
, 0), 0) = ggc_alloc_string (newstr
, len
+ 1);
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;
1256 mmix_strip_name_encoding (const char *name
)
1258 for (; (*name
== '@' || *name
== '*'); name
++)
1264 /* TARGET_ASM_FILE_START.
1265 We just emit a little comment for the time being. */
1268 mmix_file_start (void)
1270 default_file_start ();
1272 fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file
);
1274 /* Make sure each file starts with the text section. */
1275 switch_to_section (text_section
);
1278 /* TARGET_ASM_FILE_END. */
1281 mmix_file_end (void)
1283 /* Make sure each file ends with the data section. */
1284 switch_to_section (data_section
);
1287 /* TARGET_ASM_OUTPUT_SOURCE_FILENAME. */
1290 mmix_asm_output_source_filename (FILE *stream
, const char *name
)
1292 fprintf (stream
, "# 1 ");
1293 OUTPUT_QUOTED_STRING (stream
, name
);
1294 fprintf (stream
, "\n");
1297 /* OUTPUT_QUOTED_STRING. */
1300 mmix_output_quoted_string (FILE *stream
, const char *string
, int length
)
1302 const char * string_end
= string
+ length
;
1303 static const char *const unwanted_chars
= "\"[]\\";
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
)
1313 && (unsigned char) *string
< 128
1314 && !ISCNTRL (*string
)
1315 && strchr (unwanted_chars
, *string
) == NULL
)
1317 fputc ('"', stream
);
1319 && (unsigned char) *string
< 128
1320 && !ISCNTRL (*string
)
1321 && strchr (unwanted_chars
, *string
) == NULL
1322 && string
< string_end
)
1324 fputc (*string
, stream
);
1327 fputc ('"', stream
);
1328 if (string
< string_end
)
1329 fprintf (stream
, ",");
1331 if (string
< string_end
)
1333 fprintf (stream
, "#%x", *string
& 255);
1335 if (string
< string_end
)
1336 fprintf (stream
, ",");
1341 /* Target hook for assembling integer objects. Use mmix_print_operand
1342 for WYDE and TETRA. Use mmix_output_octa to output 8-byte
1346 mmix_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
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). */
1360 if (GET_CODE (x
) != CONST_INT
)
1365 fputs ("\tBYTE\t", asm_out_file
);
1366 mmix_print_operand (asm_out_file
, x
, 'B');
1367 fputc ('\n', asm_out_file
);
1371 if (GET_CODE (x
) != CONST_INT
)
1376 fputs ("\tWYDE\t", asm_out_file
);
1377 mmix_print_operand (asm_out_file
, x
, 'W');
1378 fputc ('\n', asm_out_file
);
1382 if (GET_CODE (x
) != CONST_INT
)
1387 fputs ("\tTETRA\t", asm_out_file
);
1388 mmix_print_operand (asm_out_file
, x
, 'L');
1389 fputc ('\n', asm_out_file
);
1393 /* We don't get here anymore for CONST_DOUBLE, because DImode
1394 isn't expressed as CONST_DOUBLE, and DFmode is handled
1396 gcc_assert (GET_CODE (x
) != CONST_DOUBLE
);
1397 assemble_integer_with_op ("\tOCTA\t", x
);
1400 return default_assemble_integer (x
, size
, aligned_p
);
1403 /* ASM_OUTPUT_ASCII. */
1406 mmix_asm_output_ascii (FILE *stream
, const char *string
, int length
)
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");
1419 /* ASM_OUTPUT_ALIGNED_COMMON. */
1422 mmix_asm_output_aligned_common (FILE *stream
,
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
);
1435 /* ASM_OUTPUT_ALIGNED_LOCAL. */
1438 mmix_asm_output_aligned_local (FILE *stream
,
1443 switch_to_section (data_section
);
1445 ASM_OUTPUT_ALIGN (stream
, exact_log2 (align
/BITS_PER_UNIT
));
1446 assemble_name (stream
, name
);
1447 fprintf (stream
, "\tLOC @+%d\n", size
);
1450 /* ASM_OUTPUT_LABEL. */
1453 mmix_asm_output_label (FILE *stream
, const char *name
)
1455 assemble_name (stream
, name
);
1456 fprintf (stream
, "\tIS @\n");
1459 /* ASM_OUTPUT_INTERNAL_LABEL. */
1462 mmix_asm_output_internal_label (FILE *stream
, const char *name
)
1464 assemble_name_raw (stream
, name
);
1465 fprintf (stream
, "\tIS @\n");
1468 /* ASM_DECLARE_REGISTER_GLOBAL. */
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
)
1476 /* Nothing to do here, but there *will* be, therefore the framework is
1480 /* ASM_WEAKEN_LABEL. */
1483 mmix_asm_weaken_label (FILE *stream ATTRIBUTE_UNUSED
,
1484 const char *name ATTRIBUTE_UNUSED
)
1486 fprintf (stream
, "\t.weak ");
1487 assemble_name (stream
, name
);
1488 fprintf (stream
, " ! mmixal-incompatible\n");
1491 /* MAKE_DECL_ONE_ONLY. */
1494 mmix_make_decl_one_only (tree decl
)
1496 DECL_WEAK (decl
) = 1;
1499 /* ASM_OUTPUT_LABELREF.
1500 Strip GCC's '*' and our own '@'. No order is assumed. */
1503 mmix_asm_output_labelref (FILE *stream
, const char *name
)
1507 for (; (*name
== '@' || *name
== '*'); name
++)
1511 asm_fprintf (stream
, "%s%U%s",
1512 is_extern
&& TARGET_TOPLEVEL_SYMBOLS
? ":" : "",
1516 /* ASM_OUTPUT_DEF. */
1519 mmix_asm_output_def (FILE *stream
, const char *name
, const char *value
)
1521 assemble_name (stream
, name
);
1522 fprintf (stream
, "\tIS ");
1523 assemble_name (stream
, value
);
1524 fputc ('\n', stream
);
1527 /* TARGET_PRINT_OPERAND. */
1530 mmix_print_operand (FILE *stream
, rtx x
, int code
)
1532 /* When we add support for different codes later, we can, when needed,
1533 drop through to the main handler with a modified operand. */
1535 int regno
= x
!= NULL_RTX
&& REG_P (x
) ? REGNO (x
) : 0;
1539 /* Unrelated codes are in alphabetic order. */
1542 /* For conditional branches, output "P" for a probable branch. */
1543 if (TARGET_BRANCH_PREDICT
)
1545 x
= find_reg_note (current_output_insn
, REG_BR_PROB
, 0);
1546 if (x
&& XINT (x
, 0) > REG_BR_PROB_BASE
/ 2)
1552 /* For the %d in POP %d,0. */
1553 fprintf (stream
, "%d", MMIX_POP_ARGUMENT ());
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));
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
);
1568 /* This is big-endian, so the high-part is the first one. */
1569 fprintf (stream
, "%s", reg_names
[MMIX_OUTPUT_REGNO (regno
)]);
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
)
1577 fprintf (stream
, "#%lx",
1578 (unsigned long) (INTVAL (x
)
1579 & ((unsigned int) 0x7fffffff * 2 + 1)));
1583 if (GET_CODE (x
) == SYMBOL_REF
)
1585 output_addr_const (stream
, x
);
1589 if (regno
> MMIX_LAST_GENERAL_REGISTER
- 1)
1590 internal_error ("MMIX Internal: Bad register: %d", regno
);
1592 /* This is big-endian, so the low-part is + 1. */
1593 fprintf (stream
, "%s", reg_names
[MMIX_OUTPUT_REGNO (regno
) + 1]);
1596 /* Can't use 'a' because that's a generic modifier for address
1599 mmix_output_shiftvalue_op_from_str (stream
, "ANDN",
1605 mmix_output_shiftvalue_op_from_str (stream
, "INC",
1611 mmix_output_shiftvalue_op_from_str (stream
, "OR",
1617 mmix_output_shiftvalue_op_from_str (stream
, "SET",
1624 mmix_output_condition (stream
, x
, (code
== 'D'));
1628 /* Output an extra "e" to make fcmpe, fune. */
1629 if (TARGET_FCMP_EPSILON
)
1630 fprintf (stream
, "e");
1634 /* Output the number minus 1. */
1635 if (GET_CODE (x
) != CONST_INT
)
1637 fatal_insn ("MMIX Internal: Bad value for 'm', not a CONST_INT",
1640 fprintf (stream
, "%" PRId64
,
1641 (int64_t) (mmix_intval (x
) - 1));
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);
1654 /* Store the register to output a constant to. */
1656 fatal_insn ("MMIX Internal: Expected a register, not this", x
);
1657 mmix_output_destination_register
= MMIX_OUTPUT_REGNO (regno
);
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);
1673 /* An U for unsigned, if TARGET_ZERO_EXTEND. Ignore the operand. */
1674 if (TARGET_ZERO_EXTEND
)
1679 mmix_output_shifted_value (stream
, (int64_t) mmix_intval (x
));
1683 mmix_output_shifted_value (stream
, (int64_t) ~mmix_intval (x
));
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));
1693 /* Nothing to do. */
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
);
1701 switch (GET_CODE (modified_x
))
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
)]);
1711 output_address (XEXP (modified_x
, 0));
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.
1719 Print small constants +-255 using decimal. */
1721 if (INTVAL (modified_x
) > -256 && INTVAL (modified_x
) < 256)
1722 fprintf (stream
, "%d", (int) (INTVAL (modified_x
)));
1724 fprintf (stream
, "#%x",
1725 (int) (INTVAL (modified_x
)) & (unsigned int) ~0);
1729 /* Do somewhat as CONST_INT. */
1730 mmix_output_octa (stream
, mmix_intval (modified_x
), 0);
1734 output_addr_const (stream
, modified_x
);
1738 /* No need to test for all strange things. Let output_addr_const do
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
))
1745 output_addr_const (stream
, modified_x
);
1749 /* We need the original here. */
1750 fatal_insn ("MMIX Internal: Cannot decode this operand", x
);
1754 /* TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
1757 mmix_print_operand_punct_valid_p (unsigned char code
)
1759 /* A '+' is used for branch prediction, similar to other ports. */
1761 /* A '.' is used for the %d in the POP %d,0 return insn. */
1765 /* TARGET_PRINT_OPERAND_ADDRESS. */
1768 mmix_print_operand_address (FILE *stream
, rtx x
)
1772 /* I find the generated assembly code harder to read without
1774 fprintf (stream
, "%s,0", reg_names
[MMIX_OUTPUT_REGNO (REGNO (x
))]);
1777 else if (GET_CODE (x
) == PLUS
)
1779 rtx x1
= XEXP (x
, 0);
1780 rtx x2
= XEXP (x
, 1);
1784 fprintf (stream
, "%s,", reg_names
[MMIX_OUTPUT_REGNO (REGNO (x1
))]);
1788 fprintf (stream
, "%s",
1789 reg_names
[MMIX_OUTPUT_REGNO (REGNO (x2
))]);
1792 else if (satisfies_constraint_I (x2
))
1794 output_addr_const (stream
, x2
);
1800 if (TARGET_BASE_ADDRESSES
&& mmix_legitimate_constant_p (Pmode
, x
))
1802 output_addr_const (stream
, x
);
1806 fatal_insn ("MMIX Internal: This is not a recognized address", x
);
1809 /* ASM_OUTPUT_REG_PUSH. */
1812 mmix_asm_output_reg_push (FILE *stream
, int regno
)
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
]);
1821 /* ASM_OUTPUT_REG_POP. */
1824 mmix_asm_output_reg_pop (FILE *stream
, int regno
)
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
]);
1832 /* ASM_OUTPUT_ADDR_DIFF_ELT. */
1835 mmix_asm_output_addr_diff_elt (FILE *stream
,
1836 rtx body ATTRIBUTE_UNUSED
,
1840 fprintf (stream
, "\tTETRA L%d-L%d\n", value
, rel
);
1843 /* ASM_OUTPUT_ADDR_VEC_ELT. */
1846 mmix_asm_output_addr_vec_elt (FILE *stream
, int value
)
1848 fprintf (stream
, "\tOCTA L:%d\n", value
);
1851 /* ASM_OUTPUT_SKIP. */
1854 mmix_asm_output_skip (FILE *stream
, int nbytes
)
1856 fprintf (stream
, "\tLOC @+%d\n", nbytes
);
1859 /* ASM_OUTPUT_ALIGN. */
1862 mmix_asm_output_align (FILE *stream
, int power
)
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);
1874 /* DBX_REGISTER_NUMBER. */
1877 mmix_dbx_register_number (unsigned regno
)
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
);
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);
1893 /* End of target macro support functions.
1895 Now the MMIX port's own functions. First the exported ones. */
1897 /* Wrapper for get_hard_reg_initial_val since integrate.h isn't included
1898 from insn-emit.c. */
1901 mmix_get_hard_reg_initial_val (machine_mode mode
, int regno
)
1903 return get_hard_reg_initial_val (mode
, regno
);
1906 /* Nonzero when the function epilogue is simple enough that a single
1907 "POP %d,0" should be used even within the function. */
1910 mmix_use_simple_return (void)
1914 int stack_space_to_allocate
1915 = (crtl
->outgoing_args_size
1916 + crtl
->args
.pretend_args_size
1917 + get_frame_size () + 7) & ~7;
1919 if (!TARGET_USE_RETURN_INSN
|| !reload_completed
)
1923 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
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
))
1932 if (frame_pointer_needed
)
1933 stack_space_to_allocate
+= 8;
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;
1940 return stack_space_to_allocate
== 0;
1944 /* Expands the function prologue into RTX. */
1947 mmix_expand_prologue (void)
1949 HOST_WIDE_INT locals_size
= get_frame_size ();
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;
1957 /* Add room needed to save global non-register-stack registers. */
1959 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
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;
1968 /* If we do have a frame-pointer, add room for it. */
1969 if (frame_pointer_needed
)
1970 stack_space_to_allocate
+= 8;
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;
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
);
1986 if (crtl
->args
.pretend_args_size
)
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));
1994 = MMIX_FIRST_INCOMING_ARG_REGNUM
+ MMIX_MAX_ARGS_IN_REGS
- 1;
1995 regno
>= mmix_first_vararg_reg
;
2000 HOST_WIDE_INT stack_chunk
2001 = stack_space_to_allocate
> (256 - 8)
2002 ? (256 - 8) : stack_space_to_allocate
;
2004 mmix_emit_sp_add (-stack_chunk
);
2005 offset
+= stack_chunk
;
2006 stack_space_to_allocate
-= stack_chunk
;
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
,
2014 gen_rtx_REG (DImode
, regno
));
2019 /* Store the frame-pointer. */
2021 if (frame_pointer_needed
)
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
;
2032 mmix_emit_sp_add (-stack_chunk
);
2034 offset
+= stack_chunk
;
2035 stack_space_to_allocate
-= stack_chunk
;
2038 insn
= emit_move_insn (gen_rtx_MEM (DImode
,
2039 plus_constant (Pmode
,
2042 hard_frame_pointer_rtx
);
2043 RTX_FRAME_RELATED_P (insn
) = 1;
2044 insn
= emit_insn (gen_adddi3 (hard_frame_pointer_rtx
,
2046 GEN_INT (offset
+ 8)));
2047 RTX_FRAME_RELATED_P (insn
) = 1;
2051 if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
)
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. */
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
;
2067 mmix_emit_sp_add (-stack_chunk
);
2069 offset
+= stack_chunk
;
2070 stack_space_to_allocate
-= stack_chunk
;
2073 tmpreg
= gen_rtx_REG (DImode
, 255);
2074 retreg
= gen_rtx_REG (DImode
, MMIX_rJ_REGNUM
);
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
);
2081 insn
= emit_move_insn (gen_rtx_MEM (DImode
,
2082 plus_constant (Pmode
,
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
,
2096 else if (MMIX_CFUN_HAS_LANDING_PAD
)
2099 if (MMIX_CFUN_HAS_LANDING_PAD
)
2101 /* Store the register defining the numbering of local registers, so
2102 we know how long to unwind the register stack. */
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
;
2111 mmix_emit_sp_add (-stack_chunk
);
2113 offset
+= stack_chunk
;
2114 stack_space_to_allocate
-= stack_chunk
;
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. */
2126 emit_move_insn (gen_rtx_REG (DImode
, 255),
2127 gen_rtx_REG (DImode
,
2129 emit_move_insn (gen_rtx_MEM (DImode
,
2130 plus_constant (Pmode
, stack_pointer_rtx
,
2132 gen_rtx_REG (DImode
, 255));
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;
2140 /* Now store all registers that are global, i.e. not saved by the
2141 register file machinery.
2143 It is assumed that the frame-pointer is one of these registers, so it
2144 is explicitly excluded in the count. */
2147 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
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
))
2157 HOST_WIDE_INT stack_chunk
2158 = (stack_space_to_allocate
> (256 - offset
- 8)
2159 ? (256 - offset
- 8) : stack_space_to_allocate
);
2161 mmix_emit_sp_add (-stack_chunk
);
2162 offset
+= stack_chunk
;
2163 stack_space_to_allocate
-= stack_chunk
;
2166 insn
= emit_move_insn (gen_rtx_MEM (DImode
,
2167 plus_constant (Pmode
,
2170 gen_rtx_REG (DImode
, regno
));
2171 RTX_FRAME_RELATED_P (insn
) = 1;
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
);
2181 /* Expands the function epilogue into RTX. */
2184 mmix_expand_epilogue (void)
2186 HOST_WIDE_INT locals_size
= get_frame_size ();
2188 HOST_WIDE_INT stack_space_to_deallocate
2189 = (crtl
->outgoing_args_size
2190 + crtl
->args
.pretend_args_size
2191 + locals_size
+ 7) & ~7;
2193 /* The first address to access is beyond the outgoing_args area. */
2194 HOST_WIDE_INT offset
= crtl
->outgoing_args_size
;
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. */
2200 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
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;
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;
2215 /* Add in the frame-pointer. */
2216 if (frame_pointer_needed
)
2217 stack_space_to_deallocate
+= 8;
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
);
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. */
2228 for (regno
= MMIX_FIRST_GLOBAL_REGNUM
;
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
))
2237 mmix_emit_sp_add (offset
);
2238 stack_space_to_deallocate
-= offset
;
2242 emit_move_insn (gen_rtx_REG (DImode
, regno
),
2243 gen_rtx_MEM (DImode
,
2244 plus_constant (Pmode
, stack_pointer_rtx
,
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;
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
)
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. */
2263 /* Get back the old frame-pointer-value. */
2264 if (frame_pointer_needed
)
2268 mmix_emit_sp_add (offset
);
2270 stack_space_to_deallocate
-= offset
;
2274 emit_move_insn (hard_frame_pointer_rtx
,
2275 gen_rtx_MEM (DImode
,
2276 plus_constant (Pmode
, stack_pointer_rtx
,
2281 /* We do not need to restore pretended incoming args, just add back
2283 if (stack_space_to_deallocate
!= 0)
2284 mmix_emit_sp_add (stack_space_to_deallocate
);
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
)));
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.
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. */
2303 mmix_output_register_setting (FILE *stream
,
2309 fprintf (stream
, "\t");
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
))
2315 /* First, the one-insn cases. */
2316 mmix_output_shiftvalue_op_from_str (stream
, "SET",
2319 fprintf (stream
, " %s,", reg_names
[regno
]);
2320 mmix_output_shifted_value (stream
, (uint64_t) value
);
2322 else if (mmix_shiftable_wyde_value (-(uint64_t) value
))
2324 /* We do this to get a bit more legible assembly code. The next
2325 alternative is mostly redundant with this. */
2327 mmix_output_shiftvalue_op_from_str (stream
, "SET",
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
],
2335 else if (mmix_shiftable_wyde_value (~(uint64_t) value
))
2337 /* Slightly more expensive, the two-insn cases. */
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). */
2345 mmix_output_shiftvalue_op_from_str (stream
, "SET",
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
],
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
= "";
2361 int64_t tmpvalue
= value
;
2363 /* Compute the number of insns needed to output this constant. */
2364 for (i
= 0; i
< 4 && tmpvalue
!= 0; i
++)
2366 if (tmpvalue
& 65535)
2370 if (TARGET_BASE_ADDRESSES
&& insns
== 3)
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,
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
2382 fprintf (stream
, "LDA %s,", reg_names
[regno
]);
2383 mmix_output_octa (stream
, value
, 0);
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
++)
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. */
2400 line_begin
= "\n\t";
2409 fprintf (stream
, "\n");
2412 /* Return 1 if value is 0..65535*2**(16*N) for N=0..3.
2416 mmix_shiftable_wyde_value (uint64_t value
)
2418 /* Shift by 16 bits per group, stop when we've found two groups with
2421 int has_candidate
= 0;
2423 for (i
= 0; i
< 4; i
++)
2439 /* X and Y are two things to compare using CODE. Return the rtx for
2440 the cc-reg in the proper mode. */
2443 mmix_gen_compare_reg (RTX_CODE code
, rtx x
, rtx y
)
2445 machine_mode ccmode
= SELECT_CC_MODE (code
, x
, y
);
2446 return gen_reg_rtx (ccmode
);
2449 /* Local (static) helper functions. */
2452 mmix_emit_sp_add (HOST_WIDE_INT offset
)
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. */
2462 insn
= emit_insn (gen_adddi3 (stack_pointer_rtx
,
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
));
2472 RTX_FRAME_RELATED_P (insn
) = 1;
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
,
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
));
2492 /* Print operator suitable for doing something with a shiftable
2493 wyde. The type of operator is passed as an asm output modifier. */
2496 mmix_output_shiftvalue_op_from_str (FILE *stream
,
2500 static const char *const op_part
[] = {"L", "ML", "MH", "H"};
2503 if (! mmix_shiftable_wyde_value (value
))
2505 char s
[sizeof ("0xffffffffffffffff")];
2506 sprintf (s
, "%#" PRIx64
, value
);
2507 internal_error ("MMIX Internal: %s is not a shiftable int", s
);
2510 for (i
= 0; i
< 4; i
++)
2512 /* We know we're through when we find one-bits in the low
2516 fprintf (stream
, "%s%s", mainop
, op_part
[i
]);
2522 /* No bits set? Then it must have been zero. */
2523 fprintf (stream
, "%sL", mainop
);
2526 /* Print a 64-bit value, optionally prefixed by assembly pseudo. */
2529 mmix_output_octa (FILE *stream
, int64_t value
, int do_begin_end
)
2532 fprintf (stream
, "\tOCTA ");
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
);
2551 fprintf (stream
, "\n");
2554 /* Print the presumed shiftable wyde argument shifted into place (to
2555 be output with an operand). */
2558 mmix_output_shifted_value (FILE *stream
, int64_t value
)
2562 if (! mmix_shiftable_wyde_value (value
))
2565 sprintf (s
, "%#" PRIx64
, value
);
2566 internal_error ("MMIX Internal: %s is not a shiftable int", s
);
2569 for (i
= 0; i
< 4; i
++)
2571 /* We know we're through when we find one-bits in the low 16 bits. */
2574 fprintf (stream
, "#%x", (int) (value
& 0xffff));
2581 /* No bits set? Then it must have been zero. */
2582 fprintf (stream
, "0");
2585 /* Output an MMIX condition name corresponding to an operator
2587 (comparison_operator [(comparison_operator ...) (const_int 0)])
2588 which means we have to look at *two* operators.
2590 The argument "reversed" refers to reversal of the condition (not the
2591 same as swapping the arguments). */
2594 mmix_output_condition (FILE *stream
, const_rtx x
, int reversed
)
2600 /* The normal output cc-code. */
2601 const char *const normal
;
2603 /* The reversed cc-code, or NULL if invalid. */
2604 const char *const reversed
;
2609 machine_mode cc_mode
;
2611 /* Terminated with {UNKNOWN, NULL, NULL} */
2612 const struct cc_conv
*const convs
;
2616 #define CCEND {UNKNOWN, NULL, NULL}
2618 static const struct cc_conv cc_fun_convs
[]
2619 = {{ORDERED
, "Z", "P"},
2620 {UNORDERED
, "P", "Z"},
2622 static const struct cc_conv cc_fp_convs
[]
2626 static const struct cc_conv cc_fpeq_convs
[]
2630 static const struct cc_conv cc_uns_convs
[]
2631 = {{GEU
, "NN", "N"},
2636 static const struct cc_conv cc_signed_convs
[]
2644 static const struct cc_conv cc_di_convs
[]
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
}};
2667 machine_mode mode
= GET_MODE (XEXP (x
, 0));
2668 RTX_CODE cc
= GET_CODE (x
);
2670 for (i
= 0; i
< ARRAY_SIZE (cc_convs
); i
++)
2672 if (mode
== cc_convs
[i
].cc_mode
)
2674 for (j
= 0; cc_convs
[i
].convs
[j
].cc
!= UNKNOWN
; j
++)
2675 if (cc
== cc_convs
[i
].convs
[j
].cc
)
2678 = (reversed
? cc_convs
[i
].convs
[j
].reversed
2679 : cc_convs
[i
].convs
[j
].normal
);
2681 if (mmix_cc
== NULL
)
2682 fatal_insn ("MMIX Internal: Trying to output invalidly\
2683 reversed condition:", x
);
2685 fprintf (stream
, "%s", mmix_cc
);
2689 fatal_insn ("MMIX Internal: What's the CC of this?", x
);
2693 fatal_insn ("MMIX Internal: What is the CC of this?", x
);
2696 /* Return the bit-value for a const_int or const_double. */
2699 mmix_intval (const_rtx x
)
2701 if (GET_CODE (x
) == CONST_INT
)
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
);
2710 if (GET_CODE (x
) == CONST_DOUBLE
)
2712 REAL_VALUE_TYPE value
;
2714 /* FIXME: This macro is not in the manual but should be. */
2715 REAL_VALUE_FROM_CONST_DOUBLE (value
, x
);
2717 if (GET_MODE (x
) == DFmode
)
2721 REAL_VALUE_TO_TARGET_DOUBLE (value
, bits
);
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). */
2727 ((uint64_t) (unsigned long) bits
[0]
2729 | (uint64_t) (unsigned long) bits
[1];
2731 else if (GET_MODE (x
) == SFmode
)
2734 REAL_VALUE_TO_TARGET_SINGLE (value
, bits
);
2736 return (unsigned long) bits
;
2740 fatal_insn ("MMIX Internal: This is not a constant:", x
);
2743 /* Worker function for TARGET_PROMOTE_FUNCTION_MODE. */
2746 mmix_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
2748 int *punsignedp ATTRIBUTE_UNUSED
,
2749 const_tree fntype ATTRIBUTE_UNUSED
,
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)
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)
2765 /* Worker function for TARGET_STRUCT_VALUE_RTX. */
2768 mmix_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
2769 int incoming ATTRIBUTE_UNUSED
)
2771 return gen_rtx_REG (Pmode
, MMIX_STRUCT_VALUE_REGNUM
);
2774 /* Worker function for TARGET_FRAME_POINTER_REQUIRED.
2776 FIXME: Is this requirement built-in? Anyway, we should try to get rid
2777 of it; we can deduce the value. */
2780 mmix_frame_pointer_required (void)
2782 return (cfun
->has_nonlocal_label
);
2787 * eval: (c-set-style "gnu")
2788 * indent-tabs-mode: t