1 /* Definitions of target machine for GNU compiler, for MMIX.
2 Copyright (C) 2000-2017 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"
28 #include "stringpool.h"
33 #include "insn-config.h"
37 #include "diagnostic-core.h"
40 #include "stor-layout.h"
45 #include "tm-constrs.h"
48 /* This file should be included last. */
49 #include "target-def.h"
51 /* First some local helper definitions. */
52 #define MMIX_FIRST_GLOBAL_REGNUM 32
54 /* We'd need a current_function_has_landing_pad. It's marked as such when
55 a nonlocal_goto_receiver is expanded. Not just a C++ thing, but
57 #define MMIX_CFUN_HAS_LANDING_PAD (cfun->machine->has_landing_pad != 0)
59 /* We have no means to tell DWARF 2 about the register stack, so we need
60 to store the return address on the stack if an exception can get into
61 this function. FIXME: Narrow condition. Before any whole-function
62 analysis, df_regs_ever_live_p () isn't initialized. We know it's up-to-date
63 after reload_completed; it may contain incorrect information some time
64 before that. Within a RTL sequence (after a call to start_sequence,
65 such as in RTL expanders), leaf_function_p doesn't see all insns
66 (perhaps any insn). But regs_ever_live is up-to-date when
67 leaf_function_p () isn't, so we "or" them together to get accurate
68 information. FIXME: Some tweak to leaf_function_p might be
70 #define MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS \
72 && ((reload_completed && df_regs_ever_live_p (MMIX_rJ_REGNUM)) \
73 || !leaf_function_p ()))
75 #define IS_MMIX_EH_RETURN_DATA_REG(REGNO) \
76 (crtl->calls_eh_return \
77 && (EH_RETURN_DATA_REGNO (0) == REGNO \
78 || EH_RETURN_DATA_REGNO (1) == REGNO \
79 || EH_RETURN_DATA_REGNO (2) == REGNO \
80 || EH_RETURN_DATA_REGNO (3) == REGNO))
82 /* For the default ABI, we rename registers at output-time to fill the gap
83 between the (statically partitioned) saved registers and call-clobbered
84 registers. In effect this makes unused call-saved registers to be used
85 as call-clobbered registers. The benefit comes from keeping the number
86 of local registers (value of rL) low, since there's a cost of
87 increasing rL and clearing unused (unset) registers with lower numbers.
88 Don't translate while outputting the prologue. */
89 #define MMIX_OUTPUT_REGNO(N) \
91 || (int) (N) < MMIX_RETURN_VALUE_REGNUM \
92 || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM \
94 || cfun->machine == NULL \
95 || cfun->machine->in_prologue \
96 ? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM \
97 + cfun->machine->highest_saved_stack_register + 1))
99 /* The %d in "POP %d,0". */
100 #define MMIX_POP_ARGUMENT() \
102 && crtl->return_rtx != NULL \
103 && ! cfun->returns_struct) \
104 ? (GET_CODE (crtl->return_rtx) == PARALLEL \
105 ? GET_NUM_ELEM (XVEC (crtl->return_rtx, 0)) : 1) \
108 /* The canonical saved comparison operands for non-cc0 machines, set in
109 the compare expander. */
110 rtx mmix_compare_op0
;
111 rtx mmix_compare_op1
;
113 /* Declarations of locals. */
115 /* Intermediate for insn output. */
116 static int mmix_output_destination_register
;
118 static void mmix_option_override (void);
119 static void mmix_asm_output_source_filename (FILE *, const char *);
120 static void mmix_output_shiftvalue_op_from_str
121 (FILE *, const char *, int64_t);
122 static void mmix_output_shifted_value (FILE *, int64_t);
123 static void mmix_output_condition (FILE *, const_rtx
, int);
124 static void mmix_output_octa (FILE *, int64_t, int);
125 static bool mmix_assemble_integer (rtx
, unsigned int, int);
126 static struct machine_function
*mmix_init_machine_status (void);
127 static void mmix_encode_section_info (tree
, rtx
, int);
128 static const char *mmix_strip_name_encoding (const char *);
129 static void mmix_emit_sp_add (HOST_WIDE_INT offset
);
130 static void mmix_target_asm_function_prologue (FILE *);
131 static void mmix_target_asm_function_end_prologue (FILE *);
132 static void mmix_target_asm_function_epilogue (FILE *);
133 static reg_class_t
mmix_preferred_reload_class (rtx
, reg_class_t
);
134 static reg_class_t
mmix_preferred_output_reload_class (rtx
, reg_class_t
);
135 static bool mmix_legitimate_address_p (machine_mode
, rtx
, bool);
136 static bool mmix_legitimate_constant_p (machine_mode
, rtx
);
137 static void mmix_reorg (void);
138 static void mmix_asm_output_mi_thunk
139 (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
, tree
);
140 static void mmix_setup_incoming_varargs
141 (cumulative_args_t
, machine_mode
, tree
, int *, int);
142 static void mmix_file_start (void);
143 static void mmix_file_end (void);
144 static bool mmix_rtx_costs (rtx
, machine_mode
, int, int, int *, bool);
145 static int mmix_register_move_cost (machine_mode
,
146 reg_class_t
, reg_class_t
);
147 static rtx
mmix_struct_value_rtx (tree
, int);
148 static machine_mode
mmix_promote_function_mode (const_tree
,
150 int *, const_tree
, int);
151 static void mmix_function_arg_advance (cumulative_args_t
, machine_mode
,
153 static rtx
mmix_function_arg_1 (const cumulative_args_t
, machine_mode
,
154 const_tree
, bool, bool);
155 static rtx
mmix_function_incoming_arg (cumulative_args_t
, machine_mode
,
157 static rtx
mmix_function_arg (cumulative_args_t
, machine_mode
,
159 static rtx
mmix_function_value (const_tree
, const_tree
, bool);
160 static rtx
mmix_libcall_value (machine_mode
, const_rtx
);
161 static bool mmix_function_value_regno_p (const unsigned int);
162 static bool mmix_pass_by_reference (cumulative_args_t
,
163 machine_mode
, const_tree
, bool);
164 static bool mmix_frame_pointer_required (void);
165 static void mmix_asm_trampoline_template (FILE *);
166 static void mmix_trampoline_init (rtx
, tree
, rtx
);
167 static void mmix_print_operand (FILE *, rtx
, int);
168 static void mmix_print_operand_address (FILE *, machine_mode
, rtx
);
169 static bool mmix_print_operand_punct_valid_p (unsigned char);
170 static void mmix_conditional_register_usage (void);
171 static HOST_WIDE_INT
mmix_static_rtx_alignment (machine_mode
);
172 static HOST_WIDE_INT
mmix_constant_alignment (const_tree
, HOST_WIDE_INT
);
173 static HOST_WIDE_INT
mmix_starting_frame_offset (void);
175 /* Target structure macros. Listed by node. See `Using and Porting GCC'
176 for a general description. */
178 /* Node: Function Entry */
180 #undef TARGET_ASM_BYTE_OP
181 #define TARGET_ASM_BYTE_OP NULL
182 #undef TARGET_ASM_ALIGNED_HI_OP
183 #define TARGET_ASM_ALIGNED_HI_OP NULL
184 #undef TARGET_ASM_ALIGNED_SI_OP
185 #define TARGET_ASM_ALIGNED_SI_OP NULL
186 #undef TARGET_ASM_ALIGNED_DI_OP
187 #define TARGET_ASM_ALIGNED_DI_OP NULL
188 #undef TARGET_ASM_INTEGER
189 #define TARGET_ASM_INTEGER mmix_assemble_integer
191 #undef TARGET_ASM_FUNCTION_PROLOGUE
192 #define TARGET_ASM_FUNCTION_PROLOGUE mmix_target_asm_function_prologue
194 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
195 #define TARGET_ASM_FUNCTION_END_PROLOGUE mmix_target_asm_function_end_prologue
197 #undef TARGET_ASM_FUNCTION_EPILOGUE
198 #define TARGET_ASM_FUNCTION_EPILOGUE mmix_target_asm_function_epilogue
200 #undef TARGET_PRINT_OPERAND
201 #define TARGET_PRINT_OPERAND mmix_print_operand
202 #undef TARGET_PRINT_OPERAND_ADDRESS
203 #define TARGET_PRINT_OPERAND_ADDRESS mmix_print_operand_address
204 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
205 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P mmix_print_operand_punct_valid_p
207 #undef TARGET_ENCODE_SECTION_INFO
208 #define TARGET_ENCODE_SECTION_INFO mmix_encode_section_info
209 #undef TARGET_STRIP_NAME_ENCODING
210 #define TARGET_STRIP_NAME_ENCODING mmix_strip_name_encoding
212 #undef TARGET_ASM_OUTPUT_MI_THUNK
213 #define TARGET_ASM_OUTPUT_MI_THUNK mmix_asm_output_mi_thunk
214 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
215 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
216 #undef TARGET_ASM_FILE_START
217 #define TARGET_ASM_FILE_START mmix_file_start
218 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
219 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
220 #undef TARGET_ASM_FILE_END
221 #define TARGET_ASM_FILE_END mmix_file_end
222 #undef TARGET_ASM_OUTPUT_SOURCE_FILENAME
223 #define TARGET_ASM_OUTPUT_SOURCE_FILENAME mmix_asm_output_source_filename
225 #undef TARGET_CONDITIONAL_REGISTER_USAGE
226 #define TARGET_CONDITIONAL_REGISTER_USAGE mmix_conditional_register_usage
228 #undef TARGET_RTX_COSTS
229 #define TARGET_RTX_COSTS mmix_rtx_costs
230 #undef TARGET_ADDRESS_COST
231 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
233 #undef TARGET_REGISTER_MOVE_COST
234 #define TARGET_REGISTER_MOVE_COST mmix_register_move_cost
236 #undef TARGET_MACHINE_DEPENDENT_REORG
237 #define TARGET_MACHINE_DEPENDENT_REORG mmix_reorg
239 #undef TARGET_PROMOTE_FUNCTION_MODE
240 #define TARGET_PROMOTE_FUNCTION_MODE mmix_promote_function_mode
242 #undef TARGET_FUNCTION_VALUE
243 #define TARGET_FUNCTION_VALUE mmix_function_value
244 #undef TARGET_LIBCALL_VALUE
245 #define TARGET_LIBCALL_VALUE mmix_libcall_value
246 #undef TARGET_FUNCTION_VALUE_REGNO_P
247 #define TARGET_FUNCTION_VALUE_REGNO_P mmix_function_value_regno_p
249 #undef TARGET_FUNCTION_ARG
250 #define TARGET_FUNCTION_ARG mmix_function_arg
251 #undef TARGET_FUNCTION_INCOMING_ARG
252 #define TARGET_FUNCTION_INCOMING_ARG mmix_function_incoming_arg
253 #undef TARGET_FUNCTION_ARG_ADVANCE
254 #define TARGET_FUNCTION_ARG_ADVANCE mmix_function_arg_advance
255 #undef TARGET_STRUCT_VALUE_RTX
256 #define TARGET_STRUCT_VALUE_RTX mmix_struct_value_rtx
257 #undef TARGET_SETUP_INCOMING_VARARGS
258 #define TARGET_SETUP_INCOMING_VARARGS mmix_setup_incoming_varargs
259 #undef TARGET_PASS_BY_REFERENCE
260 #define TARGET_PASS_BY_REFERENCE mmix_pass_by_reference
261 #undef TARGET_CALLEE_COPIES
262 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
264 #undef TARGET_PREFERRED_RELOAD_CLASS
265 #define TARGET_PREFERRED_RELOAD_CLASS mmix_preferred_reload_class
266 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
267 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS mmix_preferred_output_reload_class
270 #define TARGET_LRA_P hook_bool_void_false
272 #undef TARGET_LEGITIMATE_ADDRESS_P
273 #define TARGET_LEGITIMATE_ADDRESS_P mmix_legitimate_address_p
274 #undef TARGET_LEGITIMATE_CONSTANT_P
275 #define TARGET_LEGITIMATE_CONSTANT_P mmix_legitimate_constant_p
277 #undef TARGET_FRAME_POINTER_REQUIRED
278 #define TARGET_FRAME_POINTER_REQUIRED mmix_frame_pointer_required
280 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
281 #define TARGET_ASM_TRAMPOLINE_TEMPLATE mmix_asm_trampoline_template
282 #undef TARGET_TRAMPOLINE_INIT
283 #define TARGET_TRAMPOLINE_INIT mmix_trampoline_init
285 #undef TARGET_OPTION_OVERRIDE
286 #define TARGET_OPTION_OVERRIDE mmix_option_override
288 #undef TARGET_STATIC_RTX_ALIGNMENT
289 #define TARGET_STATIC_RTX_ALIGNMENT mmix_static_rtx_alignment
290 #undef TARGET_CONSTANT_ALIGNMENT
291 #define TARGET_CONSTANT_ALIGNMENT mmix_constant_alignment
293 #undef TARGET_STARTING_FRAME_OFFSET
294 #define TARGET_STARTING_FRAME_OFFSET mmix_starting_frame_offset
296 struct gcc_target targetm
= TARGET_INITIALIZER
;
298 /* Functions that are expansions for target macros.
299 See Target Macros in `Using and Porting GCC'. */
301 /* TARGET_OPTION_OVERRIDE. */
304 mmix_option_override (void)
306 /* Should we err or should we warn? Hmm. At least we must neutralize
307 it. For example the wrong kind of case-tables will be generated with
308 PIC; we use absolute address items for mmixal compatibility. FIXME:
309 They could be relative if we just elide them to after all pertinent
313 warning (0, "-f%s not supported: ignored", (flag_pic
> 1) ? "PIC" : "pic");
318 /* INIT_EXPANDERS. */
321 mmix_init_expanders (void)
323 init_machine_status
= mmix_init_machine_status
;
326 /* Set the per-function data. */
328 static struct machine_function
*
329 mmix_init_machine_status (void)
331 return ggc_cleared_alloc
<machine_function
> ();
334 /* DATA_ABI_ALIGNMENT.
335 We have trouble getting the address of stuff that is located at other
336 than 32-bit alignments (GETA requirements), so try to give everything
337 at least 32-bit alignment. */
340 mmix_data_alignment (tree type ATTRIBUTE_UNUSED
, int basic_align
)
342 if (basic_align
< 32)
348 /* Implement TARGET_STATIC_RTX_ALIGNMENT. */
351 mmix_static_rtx_alignment (machine_mode mode
)
353 return MAX (GET_MODE_ALIGNMENT (mode
), 32);
356 /* Implement tARGET_CONSTANT_ALIGNMENT. */
359 mmix_constant_alignment (const_tree
, HOST_WIDE_INT basic_align
)
361 if (basic_align
< 32)
367 /* LOCAL_ALIGNMENT. */
370 mmix_local_alignment (tree type ATTRIBUTE_UNUSED
, unsigned basic_align
)
372 if (basic_align
< 32)
378 /* TARGET_CONDITIONAL_REGISTER_USAGE. */
381 mmix_conditional_register_usage (void)
387 static const int gnu_abi_reg_alloc_order
[]
388 = MMIX_GNU_ABI_REG_ALLOC_ORDER
;
390 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
391 reg_alloc_order
[i
] = gnu_abi_reg_alloc_order
[i
];
393 /* Change the default from the mmixware ABI. For the GNU ABI,
394 $15..$30 are call-saved just as $0..$14. There must be one
395 call-clobbered local register for the "hole" that holds the
396 number of saved local registers saved by PUSHJ/PUSHGO during the
397 function call, receiving the return value at return. So best is
398 to use the highest, $31. It's already marked call-clobbered for
400 for (i
= 15; i
<= 30; i
++)
401 call_used_regs
[i
] = 0;
403 /* "Unfix" the parameter registers. */
404 for (i
= MMIX_RESERVED_GNU_ARG_0_REGNUM
;
405 i
< MMIX_RESERVED_GNU_ARG_0_REGNUM
+ MMIX_MAX_ARGS_IN_REGS
;
410 /* Step over the ":" in special register names. */
411 if (! TARGET_TOPLEVEL_SYMBOLS
)
412 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
413 if (reg_names
[i
][0] == ':')
417 /* INCOMING_REGNO and OUTGOING_REGNO worker function.
418 Those two macros must only be applied to function argument
419 registers and the function return value register for the opposite
420 use. FIXME: for their current use in gcc, it'd be better with an
421 explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P a'la
422 TARGET_FUNCTION_ARG / TARGET_FUNCTION_INCOMING_ARG instead of
423 forcing the target to commit to a fixed mapping and for any
424 unspecified register use. Particularly when thinking about the
425 return-value, it is better to imagine INCOMING_REGNO and
426 OUTGOING_REGNO as named CALLEE_TO_CALLER_REGNO and INNER_REGNO as
427 named CALLER_TO_CALLEE_REGNO because the direction. The "incoming"
428 and "outgoing" is from the perspective of the parameter-registers,
429 but the same macro is (must be, lacking an alternative like
430 suggested above) used to map the return-value-register from the
431 same perspective. To make directions even more confusing, the macro
432 MMIX_OUTGOING_RETURN_VALUE_REGNUM holds the number of the register
433 in which to return a value, i.e. INCOMING_REGNO for the return-value-
434 register as received from a called function; the return-value on the
438 mmix_opposite_regno (int regno
, int incoming
)
440 if (incoming
&& regno
== MMIX_OUTGOING_RETURN_VALUE_REGNUM
)
441 return MMIX_RETURN_VALUE_REGNUM
;
443 if (!incoming
&& regno
== MMIX_RETURN_VALUE_REGNUM
)
444 return MMIX_OUTGOING_RETURN_VALUE_REGNUM
;
446 if (!mmix_function_arg_regno_p (regno
, incoming
))
451 ? MMIX_FIRST_INCOMING_ARG_REGNUM
- MMIX_FIRST_ARG_REGNUM
452 : MMIX_FIRST_ARG_REGNUM
- MMIX_FIRST_INCOMING_ARG_REGNUM
);
456 All registers that are part of the register stack and that will be
460 mmix_local_regno (int regno
)
462 return regno
<= MMIX_LAST_STACK_REGISTER_REGNUM
&& !call_used_regs
[regno
];
465 /* TARGET_PREFERRED_RELOAD_CLASS.
466 We need to extend the reload class of REMAINDER_REG and HIMULT_REG. */
469 mmix_preferred_reload_class (rtx x
, reg_class_t rclass
)
471 /* FIXME: Revisit. */
472 return GET_CODE (x
) == MOD
&& GET_MODE (x
) == DImode
473 ? REMAINDER_REG
: rclass
;
476 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS.
477 We need to extend the reload class of REMAINDER_REG and HIMULT_REG. */
480 mmix_preferred_output_reload_class (rtx x
, reg_class_t rclass
)
482 /* FIXME: Revisit. */
483 return GET_CODE (x
) == MOD
&& GET_MODE (x
) == DImode
484 ? REMAINDER_REG
: rclass
;
487 /* SECONDARY_RELOAD_CLASS.
488 We need to reload regs of REMAINDER_REG and HIMULT_REG elsewhere. */
491 mmix_secondary_reload_class (enum reg_class rclass
,
492 machine_mode mode ATTRIBUTE_UNUSED
,
493 rtx x ATTRIBUTE_UNUSED
,
494 int in_p ATTRIBUTE_UNUSED
)
496 if (rclass
== REMAINDER_REG
497 || rclass
== HIMULT_REG
498 || rclass
== SYSTEM_REGS
)
504 /* DYNAMIC_CHAIN_ADDRESS. */
507 mmix_dynamic_chain_address (rtx frame
)
509 /* FIXME: the frame-pointer is stored at offset -8 from the current
510 frame-pointer. Unfortunately, the caller assumes that a
511 frame-pointer is present for *all* previous frames. There should be
512 a way to say that that cannot be done, like for RETURN_ADDR_RTX. */
513 return plus_constant (Pmode
, frame
, -8);
516 /* Implement TARGET_STARTING_FRAME_OFFSET. */
519 mmix_starting_frame_offset (void)
521 /* The old frame pointer is in the slot below the new one, so
522 FIRST_PARM_OFFSET does not need to depend on whether the
523 frame-pointer is needed or not. We have to adjust for the register
524 stack pointer being located below the saved frame pointer.
525 Similarly, we store the return address on the stack too, for
526 exception handling, and always if we save the register stack pointer. */
529 + (MMIX_CFUN_HAS_LANDING_PAD
530 ? -16 : (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
? -8 : 0)));
533 /* RETURN_ADDR_RTX. */
536 mmix_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
539 ? (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
540 /* FIXME: Set frame_alias_set on the following. (Why?)
541 See mmix_initial_elimination_offset for the reason we can't use
542 get_hard_reg_initial_val for both. Always using a stack slot
543 and not a register would be suboptimal. */
544 ? validize_mem (gen_rtx_MEM (Pmode
,
545 plus_constant (Pmode
,
546 frame_pointer_rtx
, -16)))
547 : get_hard_reg_initial_val (Pmode
, MMIX_INCOMING_RETURN_ADDRESS_REGNUM
))
551 /* SETUP_FRAME_ADDRESSES. */
554 mmix_setup_frame_addresses (void)
556 /* Nothing needed at the moment. */
559 /* The difference between the (imaginary) frame pointer and the stack
560 pointer. Used to eliminate the frame pointer. */
563 mmix_initial_elimination_offset (int fromreg
, int toreg
)
567 = (get_frame_size () + crtl
->outgoing_args_size
+ 7) & ~7;
569 /* There is no actual offset between these two virtual values, but for
570 the frame-pointer, we have the old one in the stack position below
571 it, so the offset for the frame-pointer to the stack-pointer is one
573 if (fromreg
== MMIX_ARG_POINTER_REGNUM
574 && toreg
== MMIX_FRAME_POINTER_REGNUM
)
577 /* The difference is the size of local variables plus the size of
578 outgoing function arguments that would normally be passed as
579 registers but must be passed on stack because we're out of
580 function-argument registers. Only global saved registers are
581 counted; the others go on the register stack.
583 The frame-pointer is counted too if it is what is eliminated, as we
584 need to balance the offset for it from TARGET_STARTING_FRAME_OFFSET.
586 Also add in the slot for the register stack pointer we save if we
589 Unfortunately, we can't access $0..$14, from unwinder code easily, so
590 store the return address in a frame slot too. FIXME: Only for
591 non-leaf functions. FIXME: Always with a landing pad, because it's
592 hard to know whether we need the other at the time we know we need
593 the offset for one (and have to state it). It's a kludge until we
594 can express the register stack in the EH frame info.
596 We have to do alignment here; get_frame_size will not return a
597 multiple of STACK_BOUNDARY. FIXME: Add note in manual. */
599 for (regno
= MMIX_FIRST_GLOBAL_REGNUM
;
602 if ((df_regs_ever_live_p (regno
) && ! call_used_regs
[regno
])
603 || IS_MMIX_EH_RETURN_DATA_REG (regno
))
607 + (MMIX_CFUN_HAS_LANDING_PAD
608 ? 16 : (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
? 8 : 0))
609 + (fromreg
== MMIX_ARG_POINTER_REGNUM
? 0 : 8);
613 mmix_function_arg_advance (cumulative_args_t argsp_v
, machine_mode mode
,
614 const_tree type
, bool named ATTRIBUTE_UNUSED
)
616 CUMULATIVE_ARGS
*argsp
= get_cumulative_args (argsp_v
);
617 int arg_size
= MMIX_FUNCTION_ARG_SIZE (mode
, type
);
619 argsp
->regs
= ((targetm
.calls
.must_pass_in_stack (mode
, type
)
623 ? (MMIX_MAX_ARGS_IN_REGS
) + 1
624 : argsp
->regs
+ (7 + arg_size
) / 8);
627 /* Helper function for mmix_function_arg and mmix_function_incoming_arg. */
630 mmix_function_arg_1 (const cumulative_args_t argsp_v
,
633 bool named ATTRIBUTE_UNUSED
,
636 CUMULATIVE_ARGS
*argsp
= get_cumulative_args (argsp_v
);
638 /* Last-argument marker. */
639 if (type
== void_type_node
)
640 return (argsp
->regs
< MMIX_MAX_ARGS_IN_REGS
)
643 ? MMIX_FIRST_INCOMING_ARG_REGNUM
644 : MMIX_FIRST_ARG_REGNUM
) + argsp
->regs
)
647 return (argsp
->regs
< MMIX_MAX_ARGS_IN_REGS
648 && !targetm
.calls
.must_pass_in_stack (mode
, type
)
649 && (GET_MODE_BITSIZE (mode
) <= 64
654 ? MMIX_FIRST_INCOMING_ARG_REGNUM
655 : MMIX_FIRST_ARG_REGNUM
)
660 /* Return an rtx for a function argument to go in a register, and 0 for
661 one that must go on stack. */
664 mmix_function_arg (cumulative_args_t argsp
,
669 return mmix_function_arg_1 (argsp
, mode
, type
, named
, false);
673 mmix_function_incoming_arg (cumulative_args_t argsp
,
678 return mmix_function_arg_1 (argsp
, mode
, type
, named
, true);
681 /* Returns nonzero for everything that goes by reference, 0 for
682 everything that goes by value. */
685 mmix_pass_by_reference (cumulative_args_t argsp_v
, machine_mode mode
,
686 const_tree type
, bool named ATTRIBUTE_UNUSED
)
688 CUMULATIVE_ARGS
*argsp
= get_cumulative_args (argsp_v
);
690 /* FIXME: Check: I'm not sure the must_pass_in_stack check is
692 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
695 if (MMIX_FUNCTION_ARG_SIZE (mode
, type
) > 8
697 && (!argsp
|| !argsp
->lib
))
703 /* Return nonzero if regno is a register number where a parameter is
704 passed, and 0 otherwise. */
707 mmix_function_arg_regno_p (int regno
, int incoming
)
710 = incoming
? MMIX_FIRST_INCOMING_ARG_REGNUM
: MMIX_FIRST_ARG_REGNUM
;
712 return regno
>= first_arg_regnum
713 && regno
< first_arg_regnum
+ MMIX_MAX_ARGS_IN_REGS
;
716 /* Implements TARGET_FUNCTION_VALUE. */
719 mmix_function_value (const_tree valtype
,
720 const_tree func ATTRIBUTE_UNUSED
,
723 machine_mode mode
= TYPE_MODE (valtype
);
725 int first_val_regnum
= MMIX_OUTGOING_RETURN_VALUE_REGNUM
;
726 rtx vec
[MMIX_MAX_REGS_FOR_VALUE
];
731 return gen_rtx_REG (mode
, MMIX_RETURN_VALUE_REGNUM
);
733 /* Return values that fit in a register need no special handling.
734 There's no register hole when parameters are passed in global
737 || GET_MODE_BITSIZE (mode
) <= BITS_PER_WORD
)
739 gen_rtx_REG (mode
, MMIX_OUTGOING_RETURN_VALUE_REGNUM
);
741 if (COMPLEX_MODE_P (mode
))
742 /* A complex type, made up of components. */
743 cmode
= TYPE_MODE (TREE_TYPE (valtype
));
746 /* Of the other larger-than-register modes, we only support
747 scalar mode TImode. (At least, that's the only one that's
748 been rudimentally tested.) Make sure we're alerted for
751 sorry ("support for mode %qs", GET_MODE_NAME (mode
));
753 /* In any case, we will fill registers to the natural size. */
757 nregs
= ((GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
);
759 /* We need to take care of the effect of the register hole on return
760 values of large sizes; the last register will appear as the first
761 register, with the rest shifted. (For complex modes, this is just
762 swapped registers.) */
764 if (nregs
> MMIX_MAX_REGS_FOR_VALUE
)
765 internal_error ("too large function value type, needs %d registers,\
766 have only %d registers for this", nregs
, MMIX_MAX_REGS_FOR_VALUE
);
768 /* FIXME: Maybe we should handle structure values like this too
769 (adjusted for BLKmode), perhaps for both ABI:s. */
770 for (i
= 0; i
< nregs
- 1; i
++)
772 = gen_rtx_EXPR_LIST (VOIDmode
,
773 gen_rtx_REG (cmode
, first_val_regnum
+ i
),
774 GEN_INT ((i
+ 1) * BITS_PER_UNIT
));
777 = gen_rtx_EXPR_LIST (VOIDmode
,
778 gen_rtx_REG (cmode
, first_val_regnum
+ nregs
- 1),
781 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (nregs
, vec
));
784 /* Implements TARGET_LIBCALL_VALUE. */
787 mmix_libcall_value (machine_mode mode
,
788 const_rtx fun ATTRIBUTE_UNUSED
)
790 return gen_rtx_REG (mode
, MMIX_RETURN_VALUE_REGNUM
);
793 /* Implements TARGET_FUNCTION_VALUE_REGNO_P. */
796 mmix_function_value_regno_p (const unsigned int regno
)
798 return regno
== MMIX_RETURN_VALUE_REGNUM
;
801 /* EH_RETURN_DATA_REGNO. */
804 mmix_eh_return_data_regno (int n
)
807 return MMIX_EH_RETURN_DATA_REGNO_START
+ n
;
809 return INVALID_REGNUM
;
812 /* EH_RETURN_STACKADJ_RTX. */
815 mmix_eh_return_stackadj_rtx (void)
817 return gen_rtx_REG (Pmode
, MMIX_EH_RETURN_STACKADJ_REGNUM
);
820 /* EH_RETURN_HANDLER_RTX. */
823 mmix_eh_return_handler_rtx (void)
825 return gen_rtx_REG (Pmode
, MMIX_INCOMING_RETURN_ADDRESS_REGNUM
);
828 /* ASM_PREFERRED_EH_DATA_FORMAT. */
831 mmix_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED
,
832 int global ATTRIBUTE_UNUSED
)
834 /* This is the default (was at 2001-07-20). Revisit when needed. */
835 return DW_EH_PE_absptr
;
838 /* Make a note that we've seen the beginning of the prologue. This
839 matters to whether we'll translate register numbers as calculated by
843 mmix_target_asm_function_prologue (FILE *)
845 cfun
->machine
->in_prologue
= 1;
848 /* Make a note that we've seen the end of the prologue. */
851 mmix_target_asm_function_end_prologue (FILE *stream ATTRIBUTE_UNUSED
)
853 cfun
->machine
->in_prologue
= 0;
856 /* Implement TARGET_MACHINE_DEPENDENT_REORG. No actual rearrangements
857 done here; just virtually by calculating the highest saved stack
858 register number used to modify the register numbers at output time. */
865 /* We put the number of the highest saved register-file register in a
866 location convenient for the call-patterns to output. Note that we
867 don't tell dwarf2 about these registers, since it can't restore them
869 for (regno
= MMIX_LAST_STACK_REGISTER_REGNUM
;
872 if ((df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
873 || (regno
== MMIX_FRAME_POINTER_REGNUM
&& frame_pointer_needed
))
876 /* Regardless of whether they're saved (they might be just read), we
877 mustn't include registers that carry parameters. We could scan the
878 insns to see whether they're actually used (and indeed do other less
879 trivial register usage analysis and transformations), but it seems
880 wasteful to optimize for unused parameter registers. As of
881 2002-04-30, df_regs_ever_live_p (n) seems to be set for only-reads too, but
882 that might change. */
883 if (!TARGET_ABI_GNU
&& regno
< crtl
->args
.info
.regs
- 1)
885 regno
= crtl
->args
.info
.regs
- 1;
887 /* We don't want to let this cause us to go over the limit and make
888 incoming parameter registers be misnumbered and treating the last
889 parameter register and incoming return value register call-saved.
890 Stop things at the unmodified scheme. */
891 if (regno
> MMIX_RETURN_VALUE_REGNUM
- 1)
892 regno
= MMIX_RETURN_VALUE_REGNUM
- 1;
895 cfun
->machine
->highest_saved_stack_register
= regno
;
898 /* TARGET_ASM_FUNCTION_EPILOGUE. */
901 mmix_target_asm_function_epilogue (FILE *stream
)
903 /* Emit an \n for readability of the generated assembly. */
904 fputc ('\n', stream
);
907 /* TARGET_ASM_OUTPUT_MI_THUNK. */
910 mmix_asm_output_mi_thunk (FILE *stream
,
911 tree fndecl ATTRIBUTE_UNUSED
,
913 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
916 /* If you define TARGET_STRUCT_VALUE_RTX that returns 0 (i.e. pass
917 location of structure to return as invisible first argument), you
918 need to tweak this code too. */
919 const char *regname
= reg_names
[MMIX_FIRST_INCOMING_ARG_REGNUM
];
921 if (delta
>= 0 && delta
< 65536)
922 fprintf (stream
, "\tINCL %s,%d\n", regname
, (int)delta
);
923 else if (delta
< 0 && delta
>= -255)
924 fprintf (stream
, "\tSUBU %s,%s,%d\n", regname
, regname
, (int)-delta
);
927 mmix_output_register_setting (stream
, 255, delta
, 1);
928 fprintf (stream
, "\tADDU %s,%s,$255\n", regname
, regname
);
931 fprintf (stream
, "\tJMP ");
932 assemble_name (stream
, XSTR (XEXP (DECL_RTL (func
), 0), 0));
933 fprintf (stream
, "\n");
936 /* FUNCTION_PROFILER. */
939 mmix_function_profiler (FILE *stream ATTRIBUTE_UNUSED
,
940 int labelno ATTRIBUTE_UNUSED
)
942 sorry ("function_profiler support for MMIX");
945 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. For the moment,
946 let's stick to pushing argument registers on the stack. Later, we
947 can parse all arguments in registers, to improve performance. */
950 mmix_setup_incoming_varargs (cumulative_args_t args_so_farp_v
,
954 int second_time ATTRIBUTE_UNUSED
)
956 CUMULATIVE_ARGS
*args_so_farp
= get_cumulative_args (args_so_farp_v
);
958 /* The last named variable has been handled, but
959 args_so_farp has not been advanced for it. */
960 if (args_so_farp
->regs
+ 1 < MMIX_MAX_ARGS_IN_REGS
)
961 *pretend_sizep
= (MMIX_MAX_ARGS_IN_REGS
- (args_so_farp
->regs
+ 1)) * 8;
963 /* We assume that one argument takes up one register here. That should
964 be true until we start messing with multi-reg parameters. */
965 if ((7 + (MMIX_FUNCTION_ARG_SIZE (mode
, vartype
))) / 8 != 1)
966 internal_error ("MMIX Internal: Last named vararg would not fit in a register");
969 /* TARGET_ASM_TRAMPOLINE_TEMPLATE. */
972 mmix_asm_trampoline_template (FILE *stream
)
974 /* Read a value into the static-chain register and jump somewhere. The
975 static chain is stored at offset 16, and the function address is
976 stored at offset 24. */
978 fprintf (stream
, "\tGETA $255,1F\n\t");
979 fprintf (stream
, "LDOU %s,$255,0\n\t", reg_names
[MMIX_STATIC_CHAIN_REGNUM
]);
980 fprintf (stream
, "LDOU $255,$255,8\n\t");
981 fprintf (stream
, "GO $255,$255,0\n");
982 fprintf (stream
, "1H\tOCTA 0\n\t");
983 fprintf (stream
, "OCTA 0\n");
986 /* TARGET_TRAMPOLINE_INIT. */
987 /* Set the static chain and function pointer field in the trampoline.
988 We also SYNCID here to be sure (doesn't matter in the simulator, but
989 some day it will). */
992 mmix_trampoline_init (rtx m_tramp
, tree fndecl
, rtx static_chain
)
994 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
997 emit_block_move (m_tramp
, assemble_trampoline_template (),
998 GEN_INT (2*UNITS_PER_WORD
), BLOCK_OP_NORMAL
);
1000 mem
= adjust_address (m_tramp
, DImode
, 2*UNITS_PER_WORD
);
1001 emit_move_insn (mem
, static_chain
);
1002 mem
= adjust_address (m_tramp
, DImode
, 3*UNITS_PER_WORD
);
1003 emit_move_insn (mem
, fnaddr
);
1005 mem
= adjust_address (m_tramp
, DImode
, 0);
1006 emit_insn (gen_sync_icache (mem
, GEN_INT (TRAMPOLINE_SIZE
- 1)));
1009 /* We must exclude constant addresses that have an increment that is not a
1010 multiple of four bytes because of restrictions of the GETA
1011 instruction, unless TARGET_BASE_ADDRESSES. */
1014 mmix_constant_address_p (rtx x
)
1016 RTX_CODE code
= GET_CODE (x
);
1018 /* When using "base addresses", anything constant goes. */
1019 int constant_ok
= TARGET_BASE_ADDRESSES
!= 0;
1028 /* FIXME: Don't know how to dissect these. Avoid them for now,
1029 except we know they're constants. */
1033 addend
= INTVAL (x
);
1037 if (GET_MODE (x
) != VOIDmode
)
1038 /* Strange that we got here. FIXME: Check if we do. */
1040 addend
= CONST_DOUBLE_LOW (x
);
1044 /* Note that expressions with arithmetic on forward references don't
1045 work in mmixal. People using gcc assembly code with mmixal might
1046 need to move arrays and such to before the point of use. */
1047 if (GET_CODE (XEXP (x
, 0)) == PLUS
)
1049 rtx x0
= XEXP (XEXP (x
, 0), 0);
1050 rtx x1
= XEXP (XEXP (x
, 0), 1);
1052 if ((GET_CODE (x0
) == SYMBOL_REF
1053 || GET_CODE (x0
) == LABEL_REF
)
1054 && (GET_CODE (x1
) == CONST_INT
1055 || (GET_CODE (x1
) == CONST_DOUBLE
1056 && GET_MODE (x1
) == VOIDmode
)))
1057 addend
= mmix_intval (x1
);
1069 return constant_ok
|| (addend
& 3) == 0;
1072 /* Return 1 if the address is OK, otherwise 0. */
1075 mmix_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
1077 bool strict_checking
)
1079 #define MMIX_REG_OK(X) \
1081 && (REGNO (X) <= MMIX_LAST_GENERAL_REGISTER \
1082 || (reg_renumber[REGNO (X)] > 0 \
1083 && reg_renumber[REGNO (X)] <= MMIX_LAST_GENERAL_REGISTER))) \
1084 || (!strict_checking \
1085 && (REGNO (X) <= MMIX_LAST_GENERAL_REGISTER \
1086 || REGNO (X) >= FIRST_PSEUDO_REGISTER \
1087 || REGNO (X) == ARG_POINTER_REGNUM)))
1091 (mem (plus reg reg))
1092 (mem (plus reg 0..255)).
1093 unless TARGET_BASE_ADDRESSES, in which case we accept all
1094 (mem constant_address) too. */
1098 if (REG_P (x
) && MMIX_REG_OK (x
))
1101 if (GET_CODE(x
) == PLUS
)
1103 rtx x1
= XEXP (x
, 0);
1104 rtx x2
= XEXP (x
, 1);
1106 /* Try swapping the order. FIXME: Do we need this? */
1114 /* (mem (plus (reg?) (?))) */
1115 if (!REG_P (x1
) || !MMIX_REG_OK (x1
))
1116 return TARGET_BASE_ADDRESSES
&& mmix_constant_address_p (x
);
1118 /* (mem (plus (reg) (reg?))) */
1119 if (REG_P (x2
) && MMIX_REG_OK (x2
))
1122 /* (mem (plus (reg) (0..255?))) */
1123 if (satisfies_constraint_I (x2
))
1129 return TARGET_BASE_ADDRESSES
&& mmix_constant_address_p (x
);
1132 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1135 mmix_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1137 RTX_CODE code
= GET_CODE (x
);
1139 /* We must allow any number due to the way the cse passes works; if we
1140 do not allow any number here, general_operand will fail, and insns
1141 will fatally fail recognition instead of "softly". */
1142 if (code
== CONST_INT
|| code
== CONST_DOUBLE
)
1145 return CONSTANT_ADDRESS_P (x
);
1148 /* SELECT_CC_MODE. */
1151 mmix_select_cc_mode (RTX_CODE op
, rtx x
, rtx y ATTRIBUTE_UNUSED
)
1153 /* We use CCmode, CC_UNSmode, CC_FPmode, CC_FPEQmode and CC_FUNmode to
1154 output different compare insns. Note that we do not check the
1155 validity of the comparison here. */
1157 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
1159 if (op
== ORDERED
|| op
== UNORDERED
|| op
== UNGE
1160 || op
== UNGT
|| op
== UNLE
|| op
== UNLT
)
1163 if (op
== EQ
|| op
== NE
)
1169 if (op
== GTU
|| op
== LTU
|| op
== GEU
|| op
== LEU
)
1175 /* REVERSIBLE_CC_MODE. */
1178 mmix_reversible_cc_mode (machine_mode mode
)
1180 /* That is, all integer and the EQ, NE, ORDERED and UNORDERED float
1182 return mode
!= CC_FPmode
;
1185 /* TARGET_RTX_COSTS. */
1188 mmix_rtx_costs (rtx x ATTRIBUTE_UNUSED
,
1189 machine_mode mode ATTRIBUTE_UNUSED
,
1190 int outer_code ATTRIBUTE_UNUSED
,
1191 int opno ATTRIBUTE_UNUSED
,
1192 int *total ATTRIBUTE_UNUSED
,
1193 bool speed ATTRIBUTE_UNUSED
)
1195 /* For the time being, this is just a stub and we'll accept the
1196 generic calculations, until we can do measurements, at least.
1197 Say we did not modify any calculated costs. */
1201 /* TARGET_REGISTER_MOVE_COST.
1203 The special registers can only move to and from general regs, and we
1204 need to check that their constraints match, so say 3 for them. */
1207 mmix_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
1211 return (from
== GENERAL_REGS
&& from
== to
) ? 2 : 3;
1214 /* Note that we don't have a TEXT_SECTION_ASM_OP, because it has to be a
1215 compile-time constant; it's used in an asm in crtstuff.c, compiled for
1218 /* DATA_SECTION_ASM_OP. */
1221 mmix_data_section_asm_op (void)
1223 return "\t.data ! mmixal:= 8H LOC 9B";
1227 mmix_encode_section_info (tree decl
, rtx rtl
, int first
)
1229 /* Test for an external declaration, and do nothing if it is one. */
1230 if ((TREE_CODE (decl
) == VAR_DECL
1231 && (DECL_EXTERNAL (decl
) || TREE_PUBLIC (decl
)))
1232 || (TREE_CODE (decl
) == FUNCTION_DECL
&& TREE_PUBLIC (decl
)))
1234 else if (first
&& DECL_P (decl
))
1236 /* For non-visible declarations, add a "@" prefix, which we skip
1237 when the label is output. If the label does not have this
1238 prefix, a ":" is output if -mtoplevel-symbols.
1240 Note that this does not work for data that is declared extern and
1241 later defined as static. If there's code in between, that code
1242 will refer to the extern declaration, and vice versa. This just
1243 means that when -mtoplevel-symbols is in use, we can just handle
1244 well-behaved ISO-compliant code. */
1246 const char *str
= XSTR (XEXP (rtl
, 0), 0);
1247 int len
= strlen (str
);
1248 char *newstr
= XALLOCAVEC (char, len
+ 2);
1250 strcpy (newstr
+ 1, str
);
1251 XSTR (XEXP (rtl
, 0), 0) = ggc_alloc_string (newstr
, len
+ 1);
1254 /* Set SYMBOL_REF_FLAG for things that we want to access with GETA. We
1255 may need different options to reach for different things with GETA.
1256 For now, functions and things we know or have been told are constant. */
1257 if (TREE_CODE (decl
) == FUNCTION_DECL
1258 || TREE_CONSTANT (decl
)
1259 || (TREE_CODE (decl
) == VAR_DECL
1260 && TREE_READONLY (decl
)
1261 && !TREE_SIDE_EFFECTS (decl
)
1262 && (!DECL_INITIAL (decl
)
1263 || TREE_CONSTANT (DECL_INITIAL (decl
)))))
1264 SYMBOL_REF_FLAG (XEXP (rtl
, 0)) = 1;
1268 mmix_strip_name_encoding (const char *name
)
1270 for (; (*name
== '@' || *name
== '*'); name
++)
1276 /* TARGET_ASM_FILE_START.
1277 We just emit a little comment for the time being. */
1280 mmix_file_start (void)
1282 default_file_start ();
1284 fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file
);
1286 /* Make sure each file starts with the text section. */
1287 switch_to_section (text_section
);
1290 /* TARGET_ASM_FILE_END. */
1293 mmix_file_end (void)
1295 /* Make sure each file ends with the data section. */
1296 switch_to_section (data_section
);
1299 /* TARGET_ASM_OUTPUT_SOURCE_FILENAME. */
1302 mmix_asm_output_source_filename (FILE *stream
, const char *name
)
1304 fprintf (stream
, "# 1 ");
1305 OUTPUT_QUOTED_STRING (stream
, name
);
1306 fprintf (stream
, "\n");
1309 /* OUTPUT_QUOTED_STRING. */
1312 mmix_output_quoted_string (FILE *stream
, const char *string
, int length
)
1314 const char * string_end
= string
+ length
;
1315 static const char *const unwanted_chars
= "\"[]\\";
1317 /* Output "any character except newline and double quote character". We
1318 play it safe and avoid all control characters too. We also do not
1319 want [] as characters, should input be passed through m4 with [] as
1320 quotes. Further, we avoid "\", because the GAS port handles it as a
1321 quoting character. */
1322 while (string
< string_end
)
1325 && (unsigned char) *string
< 128
1326 && !ISCNTRL (*string
)
1327 && strchr (unwanted_chars
, *string
) == NULL
)
1329 fputc ('"', stream
);
1331 && (unsigned char) *string
< 128
1332 && !ISCNTRL (*string
)
1333 && strchr (unwanted_chars
, *string
) == NULL
1334 && string
< string_end
)
1336 fputc (*string
, stream
);
1339 fputc ('"', stream
);
1340 if (string
< string_end
)
1341 fprintf (stream
, ",");
1343 if (string
< string_end
)
1345 fprintf (stream
, "#%x", *string
& 255);
1347 if (string
< string_end
)
1348 fprintf (stream
, ",");
1353 /* Target hook for assembling integer objects. Use mmix_print_operand
1354 for WYDE and TETRA. Use mmix_output_octa to output 8-byte
1358 mmix_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
1363 /* We handle a limited number of types of operands in here. But
1364 that's ok, because we can punt to generic functions. We then
1365 pretend that aligned data isn't needed, so the usual .<pseudo>
1366 syntax is used (which works for aligned data too). We actually
1367 *must* do that, since we say we don't have simple aligned
1368 pseudos, causing this function to be called. We just try and
1369 keep as much compatibility as possible with mmixal syntax for
1370 normal cases (i.e. without GNU extensions and C only). */
1372 if (GET_CODE (x
) != CONST_INT
)
1377 fputs ("\tBYTE\t", asm_out_file
);
1378 mmix_print_operand (asm_out_file
, x
, 'B');
1379 fputc ('\n', asm_out_file
);
1383 if (GET_CODE (x
) != CONST_INT
)
1388 fputs ("\tWYDE\t", asm_out_file
);
1389 mmix_print_operand (asm_out_file
, x
, 'W');
1390 fputc ('\n', asm_out_file
);
1394 if (GET_CODE (x
) != CONST_INT
)
1399 fputs ("\tTETRA\t", asm_out_file
);
1400 mmix_print_operand (asm_out_file
, x
, 'L');
1401 fputc ('\n', asm_out_file
);
1405 /* We don't get here anymore for CONST_DOUBLE, because DImode
1406 isn't expressed as CONST_DOUBLE, and DFmode is handled
1408 gcc_assert (GET_CODE (x
) != CONST_DOUBLE
);
1409 assemble_integer_with_op ("\tOCTA\t", x
);
1412 return default_assemble_integer (x
, size
, aligned_p
);
1415 /* ASM_OUTPUT_ASCII. */
1418 mmix_asm_output_ascii (FILE *stream
, const char *string
, int length
)
1422 int chunk_size
= length
> 60 ? 60 : length
;
1423 fprintf (stream
, "\tBYTE ");
1424 mmix_output_quoted_string (stream
, string
, chunk_size
);
1425 string
+= chunk_size
;
1426 length
-= chunk_size
;
1427 fprintf (stream
, "\n");
1431 /* ASM_OUTPUT_ALIGNED_COMMON. */
1434 mmix_asm_output_aligned_common (FILE *stream
,
1439 /* This is mostly the elfos.h one. There doesn't seem to be a way to
1440 express this in a mmixal-compatible way. */
1441 fprintf (stream
, "\t.comm\t");
1442 assemble_name (stream
, name
);
1443 fprintf (stream
, ",%u,%u ! mmixal-incompatible COMMON\n",
1444 size
, align
/ BITS_PER_UNIT
);
1447 /* ASM_OUTPUT_ALIGNED_LOCAL. */
1450 mmix_asm_output_aligned_local (FILE *stream
,
1455 switch_to_section (data_section
);
1457 ASM_OUTPUT_ALIGN (stream
, exact_log2 (align
/BITS_PER_UNIT
));
1458 assemble_name (stream
, name
);
1459 fprintf (stream
, "\tLOC @+%d\n", size
);
1462 /* ASM_OUTPUT_LABEL. */
1465 mmix_asm_output_label (FILE *stream
, const char *name
)
1467 assemble_name (stream
, name
);
1468 fprintf (stream
, "\tIS @\n");
1471 /* ASM_OUTPUT_INTERNAL_LABEL. */
1474 mmix_asm_output_internal_label (FILE *stream
, const char *name
)
1476 assemble_name_raw (stream
, name
);
1477 fprintf (stream
, "\tIS @\n");
1480 /* ASM_DECLARE_REGISTER_GLOBAL. */
1483 mmix_asm_declare_register_global (FILE *stream ATTRIBUTE_UNUSED
,
1484 tree decl ATTRIBUTE_UNUSED
,
1485 int regno ATTRIBUTE_UNUSED
,
1486 const char *name ATTRIBUTE_UNUSED
)
1488 /* Nothing to do here, but there *will* be, therefore the framework is
1492 /* ASM_WEAKEN_LABEL. */
1495 mmix_asm_weaken_label (FILE *stream ATTRIBUTE_UNUSED
,
1496 const char *name ATTRIBUTE_UNUSED
)
1498 fprintf (stream
, "\t.weak ");
1499 assemble_name (stream
, name
);
1500 fprintf (stream
, " ! mmixal-incompatible\n");
1503 /* MAKE_DECL_ONE_ONLY. */
1506 mmix_make_decl_one_only (tree decl
)
1508 DECL_WEAK (decl
) = 1;
1511 /* ASM_OUTPUT_LABELREF.
1512 Strip GCC's '*' and our own '@'. No order is assumed. */
1515 mmix_asm_output_labelref (FILE *stream
, const char *name
)
1519 for (; (*name
== '@' || *name
== '*'); name
++)
1523 asm_fprintf (stream
, "%s%U%s",
1524 is_extern
&& TARGET_TOPLEVEL_SYMBOLS
? ":" : "",
1528 /* ASM_OUTPUT_DEF. */
1531 mmix_asm_output_def (FILE *stream
, const char *name
, const char *value
)
1533 assemble_name (stream
, name
);
1534 fprintf (stream
, "\tIS ");
1535 assemble_name (stream
, value
);
1536 fputc ('\n', stream
);
1539 /* TARGET_PRINT_OPERAND. */
1542 mmix_print_operand (FILE *stream
, rtx x
, int code
)
1544 /* When we add support for different codes later, we can, when needed,
1545 drop through to the main handler with a modified operand. */
1547 int regno
= x
!= NULL_RTX
&& REG_P (x
) ? REGNO (x
) : 0;
1551 /* Unrelated codes are in alphabetic order. */
1554 /* For conditional branches, output "P" for a probable branch. */
1555 if (TARGET_BRANCH_PREDICT
)
1557 x
= find_reg_note (current_output_insn
, REG_BR_PROB
, 0);
1558 if (x
&& profile_probability::from_reg_br_prob_note (XINT (x
, 0))
1559 > profile_probability::even ())
1565 /* For the %d in POP %d,0. */
1566 fprintf (stream
, "%d", MMIX_POP_ARGUMENT ());
1570 if (GET_CODE (x
) != CONST_INT
)
1571 fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x
);
1572 fprintf (stream
, "%d", (int) (INTVAL (x
) & 0xff));
1576 /* Highpart. Must be general register, and not the last one, as
1577 that one cannot be part of a consecutive register pair. */
1578 if (regno
> MMIX_LAST_GENERAL_REGISTER
- 1)
1579 internal_error ("MMIX Internal: Bad register: %d", regno
);
1581 /* This is big-endian, so the high-part is the first one. */
1582 fprintf (stream
, "%s", reg_names
[MMIX_OUTPUT_REGNO (regno
)]);
1586 /* Lowpart. Must be CONST_INT or general register, and not the last
1587 one, as that one cannot be part of a consecutive register pair. */
1588 if (GET_CODE (x
) == CONST_INT
)
1590 fprintf (stream
, "#%lx",
1591 (unsigned long) (INTVAL (x
)
1592 & ((unsigned int) 0x7fffffff * 2 + 1)));
1596 if (GET_CODE (x
) == SYMBOL_REF
)
1598 output_addr_const (stream
, x
);
1602 if (regno
> MMIX_LAST_GENERAL_REGISTER
- 1)
1603 internal_error ("MMIX Internal: Bad register: %d", regno
);
1605 /* This is big-endian, so the low-part is + 1. */
1606 fprintf (stream
, "%s", reg_names
[MMIX_OUTPUT_REGNO (regno
) + 1]);
1609 /* Can't use 'a' because that's a generic modifier for address
1612 mmix_output_shiftvalue_op_from_str (stream
, "ANDN",
1618 mmix_output_shiftvalue_op_from_str (stream
, "INC",
1624 mmix_output_shiftvalue_op_from_str (stream
, "OR",
1630 mmix_output_shiftvalue_op_from_str (stream
, "SET",
1637 mmix_output_condition (stream
, x
, (code
== 'D'));
1641 /* Output an extra "e" to make fcmpe, fune. */
1642 if (TARGET_FCMP_EPSILON
)
1643 fprintf (stream
, "e");
1647 /* Output the number minus 1. */
1648 if (GET_CODE (x
) != CONST_INT
)
1650 fatal_insn ("MMIX Internal: Bad value for 'm', not a CONST_INT",
1653 fprintf (stream
, "%" PRId64
,
1654 (int64_t) (mmix_intval (x
) - 1));
1658 /* Store the number of registers we want to save. This was setup
1659 by the prologue. The actual operand contains the number of
1660 registers to pass, but we don't use it currently. Anyway, we
1661 need to output the number of saved registers here. */
1662 fprintf (stream
, "%d",
1663 cfun
->machine
->highest_saved_stack_register
+ 1);
1667 /* Store the register to output a constant to. */
1669 fatal_insn ("MMIX Internal: Expected a register, not this", x
);
1670 mmix_output_destination_register
= MMIX_OUTPUT_REGNO (regno
);
1674 /* Output the constant. Note that we use this for floats as well. */
1675 if (GET_CODE (x
) != CONST_INT
1676 && (GET_CODE (x
) != CONST_DOUBLE
1677 || (GET_MODE (x
) != VOIDmode
&& GET_MODE (x
) != DFmode
1678 && GET_MODE (x
) != SFmode
)))
1679 fatal_insn ("MMIX Internal: Expected a constant, not this", x
);
1680 mmix_output_register_setting (stream
,
1681 mmix_output_destination_register
,
1682 mmix_intval (x
), 0);
1686 /* An U for unsigned, if TARGET_ZERO_EXTEND. Ignore the operand. */
1687 if (TARGET_ZERO_EXTEND
)
1692 mmix_output_shifted_value (stream
, (int64_t) mmix_intval (x
));
1696 mmix_output_shifted_value (stream
, (int64_t) ~mmix_intval (x
));
1700 if (GET_CODE (x
) != CONST_INT
)
1701 fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x
);
1702 fprintf (stream
, "#%x", (int) (INTVAL (x
) & 0xffff));
1706 /* Nothing to do. */
1710 /* Presumably there's a missing case above if we get here. */
1711 internal_error ("MMIX Internal: Missing %qc case in mmix_print_operand", code
);
1714 switch (GET_CODE (modified_x
))
1717 regno
= REGNO (modified_x
);
1718 if (regno
>= FIRST_PSEUDO_REGISTER
)
1719 internal_error ("MMIX Internal: Bad register: %d", regno
);
1720 fprintf (stream
, "%s", reg_names
[MMIX_OUTPUT_REGNO (regno
)]);
1724 output_address (GET_MODE (modified_x
), XEXP (modified_x
, 0));
1728 /* For -2147483648, mmixal complains that the constant does not fit
1729 in 4 bytes, so let's output it as hex. Take care to handle hosts
1730 where HOST_WIDE_INT is longer than an int.
1732 Print small constants +-255 using decimal. */
1734 if (INTVAL (modified_x
) > -256 && INTVAL (modified_x
) < 256)
1735 fprintf (stream
, "%d", (int) (INTVAL (modified_x
)));
1737 fprintf (stream
, "#%x",
1738 (int) (INTVAL (modified_x
)) & (unsigned int) ~0);
1742 /* Do somewhat as CONST_INT. */
1743 mmix_output_octa (stream
, mmix_intval (modified_x
), 0);
1747 output_addr_const (stream
, modified_x
);
1751 /* No need to test for all strange things. Let output_addr_const do
1753 if (CONSTANT_P (modified_x
)
1754 /* Strangely enough, this is not included in CONSTANT_P.
1755 FIXME: Ask/check about sanity here. */
1756 || LABEL_P (modified_x
))
1758 output_addr_const (stream
, modified_x
);
1762 /* We need the original here. */
1763 fatal_insn ("MMIX Internal: Cannot decode this operand", x
);
1767 /* TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
1770 mmix_print_operand_punct_valid_p (unsigned char code
)
1772 /* A '+' is used for branch prediction, similar to other ports. */
1774 /* A '.' is used for the %d in the POP %d,0 return insn. */
1778 /* TARGET_PRINT_OPERAND_ADDRESS. */
1781 mmix_print_operand_address (FILE *stream
, machine_mode
/*mode*/, rtx x
)
1785 /* I find the generated assembly code harder to read without
1787 fprintf (stream
, "%s,0", reg_names
[MMIX_OUTPUT_REGNO (REGNO (x
))]);
1790 else if (GET_CODE (x
) == PLUS
)
1792 rtx x1
= XEXP (x
, 0);
1793 rtx x2
= XEXP (x
, 1);
1797 fprintf (stream
, "%s,", reg_names
[MMIX_OUTPUT_REGNO (REGNO (x1
))]);
1801 fprintf (stream
, "%s",
1802 reg_names
[MMIX_OUTPUT_REGNO (REGNO (x2
))]);
1805 else if (satisfies_constraint_I (x2
))
1807 output_addr_const (stream
, x2
);
1813 if (TARGET_BASE_ADDRESSES
&& mmix_legitimate_constant_p (Pmode
, x
))
1815 output_addr_const (stream
, x
);
1819 fatal_insn ("MMIX Internal: This is not a recognized address", x
);
1822 /* ASM_OUTPUT_REG_PUSH. */
1825 mmix_asm_output_reg_push (FILE *stream
, int regno
)
1827 fprintf (stream
, "\tSUBU %s,%s,8\n\tSTOU %s,%s,0\n",
1828 reg_names
[MMIX_STACK_POINTER_REGNUM
],
1829 reg_names
[MMIX_STACK_POINTER_REGNUM
],
1830 reg_names
[MMIX_OUTPUT_REGNO (regno
)],
1831 reg_names
[MMIX_STACK_POINTER_REGNUM
]);
1834 /* ASM_OUTPUT_REG_POP. */
1837 mmix_asm_output_reg_pop (FILE *stream
, int regno
)
1839 fprintf (stream
, "\tLDOU %s,%s,0\n\tINCL %s,8\n",
1840 reg_names
[MMIX_OUTPUT_REGNO (regno
)],
1841 reg_names
[MMIX_STACK_POINTER_REGNUM
],
1842 reg_names
[MMIX_STACK_POINTER_REGNUM
]);
1845 /* ASM_OUTPUT_ADDR_DIFF_ELT. */
1848 mmix_asm_output_addr_diff_elt (FILE *stream
,
1849 rtx body ATTRIBUTE_UNUSED
,
1853 fprintf (stream
, "\tTETRA L%d-L%d\n", value
, rel
);
1856 /* ASM_OUTPUT_ADDR_VEC_ELT. */
1859 mmix_asm_output_addr_vec_elt (FILE *stream
, int value
)
1861 fprintf (stream
, "\tOCTA L:%d\n", value
);
1864 /* ASM_OUTPUT_SKIP. */
1867 mmix_asm_output_skip (FILE *stream
, int nbytes
)
1869 fprintf (stream
, "\tLOC @+%d\n", nbytes
);
1872 /* ASM_OUTPUT_ALIGN. */
1875 mmix_asm_output_align (FILE *stream
, int power
)
1877 /* We need to record the needed alignment of this section in the object,
1878 so we have to output an alignment directive. Use a .p2align (not
1879 .align) so people will never have to wonder about whether the
1880 argument is in number of bytes or the log2 thereof. We do it in
1881 addition to the LOC directive, so nothing needs tweaking when
1882 copy-pasting assembly into mmixal. */
1883 fprintf (stream
, "\t.p2align %d\n", power
);
1884 fprintf (stream
, "\tLOC @+(%d-@)&%d\n", 1 << power
, (1 << power
) - 1);
1887 /* DBX_REGISTER_NUMBER. */
1890 mmix_dbx_register_number (unsigned regno
)
1892 /* Adjust the register number to the one it will be output as, dammit.
1893 It'd be nice if we could check the assumption that we're filling a
1894 gap, but every register between the last saved register and parameter
1895 registers might be a valid parameter register. */
1896 regno
= MMIX_OUTPUT_REGNO (regno
);
1898 /* We need to renumber registers to get the number of the return address
1899 register in the range 0..255. It is also space-saving if registers
1900 mentioned in the call-frame information (which uses this function by
1901 defaulting DWARF_FRAME_REGNUM to DBX_REGISTER_NUMBER) are numbered
1902 0 .. 63. So map 224 .. 256+15 -> 0 .. 47 and 0 .. 223 -> 48..223+48. */
1903 return regno
>= 224 ? (regno
- 224) : (regno
+ 48);
1906 /* End of target macro support functions.
1908 Now the MMIX port's own functions. First the exported ones. */
1910 /* Wrapper for get_hard_reg_initial_val since integrate.h isn't included
1911 from insn-emit.c. */
1914 mmix_get_hard_reg_initial_val (machine_mode mode
, int regno
)
1916 return get_hard_reg_initial_val (mode
, regno
);
1919 /* Nonzero when the function epilogue is simple enough that a single
1920 "POP %d,0" should be used even within the function. */
1923 mmix_use_simple_return (void)
1927 int stack_space_to_allocate
1928 = (crtl
->outgoing_args_size
1929 + crtl
->args
.pretend_args_size
1930 + get_frame_size () + 7) & ~7;
1932 if (!TARGET_USE_RETURN_INSN
|| !reload_completed
)
1936 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
1938 /* Note that we assume that the frame-pointer-register is one of these
1939 registers, in which case we don't count it here. */
1940 if ((((regno
!= MMIX_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
)
1941 && df_regs_ever_live_p (regno
) && !call_used_regs
[regno
]))
1942 || IS_MMIX_EH_RETURN_DATA_REG (regno
))
1945 if (frame_pointer_needed
)
1946 stack_space_to_allocate
+= 8;
1948 if (MMIX_CFUN_HAS_LANDING_PAD
)
1949 stack_space_to_allocate
+= 16;
1950 else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
)
1951 stack_space_to_allocate
+= 8;
1953 return stack_space_to_allocate
== 0;
1957 /* Expands the function prologue into RTX. */
1960 mmix_expand_prologue (void)
1962 HOST_WIDE_INT locals_size
= get_frame_size ();
1964 HOST_WIDE_INT stack_space_to_allocate
1965 = (crtl
->outgoing_args_size
1966 + crtl
->args
.pretend_args_size
1967 + locals_size
+ 7) & ~7;
1968 HOST_WIDE_INT offset
= -8;
1970 /* Add room needed to save global non-register-stack registers. */
1972 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
1974 /* Note that we assume that the frame-pointer-register is one of these
1975 registers, in which case we don't count it here. */
1976 if ((((regno
!= MMIX_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
)
1977 && df_regs_ever_live_p (regno
) && !call_used_regs
[regno
]))
1978 || IS_MMIX_EH_RETURN_DATA_REG (regno
))
1979 stack_space_to_allocate
+= 8;
1981 /* If we do have a frame-pointer, add room for it. */
1982 if (frame_pointer_needed
)
1983 stack_space_to_allocate
+= 8;
1985 /* If we have a non-local label, we need to be able to unwind to it, so
1986 store the current register stack pointer. Also store the return
1987 address if we do that. */
1988 if (MMIX_CFUN_HAS_LANDING_PAD
)
1989 stack_space_to_allocate
+= 16;
1990 else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
)
1991 /* If we do have a saved return-address slot, add room for it. */
1992 stack_space_to_allocate
+= 8;
1994 /* Make sure we don't get an unaligned stack. */
1995 if ((stack_space_to_allocate
% 8) != 0)
1996 internal_error ("stack frame not a multiple of 8 bytes: %wd",
1997 stack_space_to_allocate
);
1999 if (crtl
->args
.pretend_args_size
)
2001 int mmix_first_vararg_reg
2002 = (MMIX_FIRST_INCOMING_ARG_REGNUM
2003 + (MMIX_MAX_ARGS_IN_REGS
2004 - crtl
->args
.pretend_args_size
/ 8));
2007 = MMIX_FIRST_INCOMING_ARG_REGNUM
+ MMIX_MAX_ARGS_IN_REGS
- 1;
2008 regno
>= mmix_first_vararg_reg
;
2013 HOST_WIDE_INT stack_chunk
2014 = stack_space_to_allocate
> (256 - 8)
2015 ? (256 - 8) : stack_space_to_allocate
;
2017 mmix_emit_sp_add (-stack_chunk
);
2018 offset
+= stack_chunk
;
2019 stack_space_to_allocate
-= stack_chunk
;
2022 /* These registers aren't actually saved (as in "will be
2023 restored"), so don't tell DWARF2 they're saved. */
2024 emit_move_insn (gen_rtx_MEM (DImode
,
2025 plus_constant (Pmode
, stack_pointer_rtx
,
2027 gen_rtx_REG (DImode
, regno
));
2032 /* Store the frame-pointer. */
2034 if (frame_pointer_needed
)
2040 /* Get 8 less than otherwise, since we need to reach offset + 8. */
2041 HOST_WIDE_INT stack_chunk
2042 = stack_space_to_allocate
> (256 - 8 - 8)
2043 ? (256 - 8 - 8) : stack_space_to_allocate
;
2045 mmix_emit_sp_add (-stack_chunk
);
2047 offset
+= stack_chunk
;
2048 stack_space_to_allocate
-= stack_chunk
;
2051 insn
= emit_move_insn (gen_rtx_MEM (DImode
,
2052 plus_constant (Pmode
,
2055 hard_frame_pointer_rtx
);
2056 RTX_FRAME_RELATED_P (insn
) = 1;
2057 insn
= emit_insn (gen_adddi3 (hard_frame_pointer_rtx
,
2059 GEN_INT (offset
+ 8)));
2060 RTX_FRAME_RELATED_P (insn
) = 1;
2064 if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
)
2069 /* Store the return-address, if one is needed on the stack. We
2070 usually store it in a register when needed, but that doesn't work
2071 with -fexceptions. */
2075 /* Get 8 less than otherwise, since we need to reach offset + 8. */
2076 HOST_WIDE_INT stack_chunk
2077 = stack_space_to_allocate
> (256 - 8 - 8)
2078 ? (256 - 8 - 8) : stack_space_to_allocate
;
2080 mmix_emit_sp_add (-stack_chunk
);
2082 offset
+= stack_chunk
;
2083 stack_space_to_allocate
-= stack_chunk
;
2086 tmpreg
= gen_rtx_REG (DImode
, 255);
2087 retreg
= gen_rtx_REG (DImode
, MMIX_rJ_REGNUM
);
2089 /* Dwarf2 code is confused by the use of a temporary register for
2090 storing the return address, so we have to express it as a note,
2091 which we attach to the actual store insn. */
2092 emit_move_insn (tmpreg
, retreg
);
2094 insn
= emit_move_insn (gen_rtx_MEM (DImode
,
2095 plus_constant (Pmode
,
2099 RTX_FRAME_RELATED_P (insn
) = 1;
2100 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
2101 gen_rtx_SET (gen_rtx_MEM (DImode
,
2102 plus_constant (Pmode
,
2109 else if (MMIX_CFUN_HAS_LANDING_PAD
)
2112 if (MMIX_CFUN_HAS_LANDING_PAD
)
2114 /* Store the register defining the numbering of local registers, so
2115 we know how long to unwind the register stack. */
2119 /* Get 8 less than otherwise, since we need to reach offset + 8. */
2120 HOST_WIDE_INT stack_chunk
2121 = stack_space_to_allocate
> (256 - 8 - 8)
2122 ? (256 - 8 - 8) : stack_space_to_allocate
;
2124 mmix_emit_sp_add (-stack_chunk
);
2126 offset
+= stack_chunk
;
2127 stack_space_to_allocate
-= stack_chunk
;
2130 /* We don't tell dwarf2 about this one; we just have it to unwind
2131 the register stack at landing pads. FIXME: It's a kludge because
2132 we can't describe the effect of the PUSHJ and PUSHGO insns on the
2133 register stack at the moment. Best thing would be to handle it
2134 like stack-pointer offsets. Better: some hook into dwarf2out.c
2135 to produce DW_CFA_expression:s that specify the increment of rO,
2136 and unwind it at eh_return (preferred) or at the landing pad.
2137 Then saves to $0..$G-1 could be specified through that register. */
2139 emit_move_insn (gen_rtx_REG (DImode
, 255),
2140 gen_rtx_REG (DImode
,
2142 emit_move_insn (gen_rtx_MEM (DImode
,
2143 plus_constant (Pmode
, stack_pointer_rtx
,
2145 gen_rtx_REG (DImode
, 255));
2149 /* After the return-address and the frame-pointer, we have the local
2150 variables. They're the ones that may have an "unaligned" size. */
2151 offset
-= (locals_size
+ 7) & ~7;
2153 /* Now store all registers that are global, i.e. not saved by the
2154 register file machinery.
2156 It is assumed that the frame-pointer is one of these registers, so it
2157 is explicitly excluded in the count. */
2160 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
2162 if (((regno
!= MMIX_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
)
2163 && df_regs_ever_live_p (regno
) && ! call_used_regs
[regno
])
2164 || IS_MMIX_EH_RETURN_DATA_REG (regno
))
2170 HOST_WIDE_INT stack_chunk
2171 = (stack_space_to_allocate
> (256 - offset
- 8)
2172 ? (256 - offset
- 8) : stack_space_to_allocate
);
2174 mmix_emit_sp_add (-stack_chunk
);
2175 offset
+= stack_chunk
;
2176 stack_space_to_allocate
-= stack_chunk
;
2179 insn
= emit_move_insn (gen_rtx_MEM (DImode
,
2180 plus_constant (Pmode
,
2183 gen_rtx_REG (DImode
, regno
));
2184 RTX_FRAME_RELATED_P (insn
) = 1;
2188 /* Finally, allocate room for outgoing args and local vars if room
2189 wasn't allocated above. */
2190 if (stack_space_to_allocate
)
2191 mmix_emit_sp_add (-stack_space_to_allocate
);
2194 /* Expands the function epilogue into RTX. */
2197 mmix_expand_epilogue (void)
2199 HOST_WIDE_INT locals_size
= get_frame_size ();
2201 HOST_WIDE_INT stack_space_to_deallocate
2202 = (crtl
->outgoing_args_size
2203 + crtl
->args
.pretend_args_size
2204 + locals_size
+ 7) & ~7;
2206 /* The first address to access is beyond the outgoing_args area. */
2207 HOST_WIDE_INT offset
= crtl
->outgoing_args_size
;
2209 /* Add the space for global non-register-stack registers.
2210 It is assumed that the frame-pointer register can be one of these
2211 registers, in which case it is excluded from the count when needed. */
2213 regno
>= MMIX_FIRST_GLOBAL_REGNUM
;
2215 if (((regno
!= MMIX_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
)
2216 && df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
2217 || IS_MMIX_EH_RETURN_DATA_REG (regno
))
2218 stack_space_to_deallocate
+= 8;
2220 /* Add in the space for register stack-pointer. If so, always add room
2221 for the saved PC. */
2222 if (MMIX_CFUN_HAS_LANDING_PAD
)
2223 stack_space_to_deallocate
+= 16;
2224 else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
)
2225 /* If we have a saved return-address slot, add it in. */
2226 stack_space_to_deallocate
+= 8;
2228 /* Add in the frame-pointer. */
2229 if (frame_pointer_needed
)
2230 stack_space_to_deallocate
+= 8;
2232 /* Make sure we don't get an unaligned stack. */
2233 if ((stack_space_to_deallocate
% 8) != 0)
2234 internal_error ("stack frame not a multiple of octabyte: %wd",
2235 stack_space_to_deallocate
);
2237 /* We will add back small offsets to the stack pointer as we go.
2238 First, we restore all registers that are global, i.e. not saved by
2239 the register file machinery. */
2241 for (regno
= MMIX_FIRST_GLOBAL_REGNUM
;
2244 if (((regno
!= MMIX_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
)
2245 && df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
2246 || IS_MMIX_EH_RETURN_DATA_REG (regno
))
2250 mmix_emit_sp_add (offset
);
2251 stack_space_to_deallocate
-= offset
;
2255 emit_move_insn (gen_rtx_REG (DImode
, regno
),
2256 gen_rtx_MEM (DImode
,
2257 plus_constant (Pmode
, stack_pointer_rtx
,
2262 /* Here is where the local variables were. As in the prologue, they
2263 might be of an unaligned size. */
2264 offset
+= (locals_size
+ 7) & ~7;
2266 /* The saved register stack pointer is just below the frame-pointer
2267 register. We don't need to restore it "manually"; the POP
2268 instruction does that. */
2269 if (MMIX_CFUN_HAS_LANDING_PAD
)
2271 else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS
)
2272 /* The return-address slot is just below the frame-pointer register.
2273 We don't need to restore it because we don't really use it. */
2276 /* Get back the old frame-pointer-value. */
2277 if (frame_pointer_needed
)
2281 mmix_emit_sp_add (offset
);
2283 stack_space_to_deallocate
-= offset
;
2287 emit_move_insn (hard_frame_pointer_rtx
,
2288 gen_rtx_MEM (DImode
,
2289 plus_constant (Pmode
, stack_pointer_rtx
,
2294 /* We do not need to restore pretended incoming args, just add back
2296 if (stack_space_to_deallocate
!= 0)
2297 mmix_emit_sp_add (stack_space_to_deallocate
);
2299 if (crtl
->calls_eh_return
)
2300 /* Adjust the (normal) stack-pointer to that of the receiver.
2301 FIXME: It would be nice if we could also adjust the register stack
2302 here, but we need to express it through DWARF 2 too. */
2303 emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2304 gen_rtx_REG (DImode
,
2305 MMIX_EH_RETURN_STACKADJ_REGNUM
)));
2308 /* Output an optimal sequence for setting a register to a specific
2309 constant. Used in an alternative for const_ints in movdi, and when
2310 using large stack-frame offsets.
2312 Use do_begin_end to say if a line-starting TAB and newline before the
2313 first insn and after the last insn is wanted. */
2316 mmix_output_register_setting (FILE *stream
,
2322 fprintf (stream
, "\t");
2324 if (insn_const_int_ok_for_constraint (value
, CONSTRAINT_K
))
2325 fprintf (stream
, "NEGU %s,0,%" PRId64
, reg_names
[regno
], -value
);
2326 else if (mmix_shiftable_wyde_value ((uint64_t) value
))
2328 /* First, the one-insn cases. */
2329 mmix_output_shiftvalue_op_from_str (stream
, "SET",
2332 fprintf (stream
, " %s,", reg_names
[regno
]);
2333 mmix_output_shifted_value (stream
, (uint64_t) value
);
2335 else if (mmix_shiftable_wyde_value (-(uint64_t) value
))
2337 /* We do this to get a bit more legible assembly code. The next
2338 alternative is mostly redundant with this. */
2340 mmix_output_shiftvalue_op_from_str (stream
, "SET",
2343 fprintf (stream
, " %s,", reg_names
[regno
]);
2344 mmix_output_shifted_value (stream
, -(uint64_t) value
);
2345 fprintf (stream
, "\n\tNEGU %s,0,%s", reg_names
[regno
],
2348 else if (mmix_shiftable_wyde_value (~(uint64_t) value
))
2350 /* Slightly more expensive, the two-insn cases. */
2352 /* FIXME: We could of course also test if 0..255-N or ~(N | 1..255)
2353 is shiftable, or any other one-insn transformation of the value.
2354 FIXME: Check first if the value is "shiftable" by two loading
2355 with two insns, since it makes more readable assembly code (if
2356 anyone else cares). */
2358 mmix_output_shiftvalue_op_from_str (stream
, "SET",
2361 fprintf (stream
, " %s,", reg_names
[regno
]);
2362 mmix_output_shifted_value (stream
, ~(uint64_t) value
);
2363 fprintf (stream
, "\n\tNOR %s,%s,0", reg_names
[regno
],
2368 /* The generic case. 2..4 insns. */
2369 static const char *const higher_parts
[] = {"L", "ML", "MH", "H"};
2370 const char *op
= "SET";
2371 const char *line_begin
= "";
2374 int64_t tmpvalue
= value
;
2376 /* Compute the number of insns needed to output this constant. */
2377 for (i
= 0; i
< 4 && tmpvalue
!= 0; i
++)
2379 if (tmpvalue
& 65535)
2383 if (TARGET_BASE_ADDRESSES
&& insns
== 3)
2385 /* The number three is based on a static observation on
2386 ghostscript-6.52. Two and four are excluded because there
2387 are too many such constants, and each unique constant (maybe
2388 offset by 1..255) were used few times compared to other uses,
2391 We use base-plus-offset addressing to force it into a global
2392 register; we just use a "LDA reg,VALUE", which will cause the
2393 assembler and linker to DTRT (for constants as well as
2395 fprintf (stream
, "LDA %s,", reg_names
[regno
]);
2396 mmix_output_octa (stream
, value
, 0);
2400 /* Output pertinent parts of the 4-wyde sequence.
2401 Still more to do if we want this to be optimal, but hey...
2402 Note that the zero case has been handled above. */
2403 for (i
= 0; i
< 4 && value
!= 0; i
++)
2407 fprintf (stream
, "%s%s%s %s,#%x", line_begin
, op
,
2408 higher_parts
[i
], reg_names
[regno
],
2409 (int) (value
& 65535));
2410 /* The first one sets the rest of the bits to 0, the next
2411 ones add set bits. */
2413 line_begin
= "\n\t";
2422 fprintf (stream
, "\n");
2425 /* Return 1 if value is 0..65535*2**(16*N) for N=0..3.
2429 mmix_shiftable_wyde_value (uint64_t value
)
2431 /* Shift by 16 bits per group, stop when we've found two groups with
2434 int has_candidate
= 0;
2436 for (i
= 0; i
< 4; i
++)
2452 /* X and Y are two things to compare using CODE. Return the rtx for
2453 the cc-reg in the proper mode. */
2456 mmix_gen_compare_reg (RTX_CODE code
, rtx x
, rtx y
)
2458 machine_mode ccmode
= SELECT_CC_MODE (code
, x
, y
);
2459 return gen_reg_rtx (ccmode
);
2462 /* Local (static) helper functions. */
2465 mmix_emit_sp_add (HOST_WIDE_INT offset
)
2471 /* Negative stack-pointer adjustments are allocations and appear in
2472 the prologue only. We mark them as frame-related so unwind and
2473 debug info is properly emitted for them. */
2475 insn
= emit_insn (gen_adddi3 (stack_pointer_rtx
,
2480 rtx tmpr
= gen_rtx_REG (DImode
, 255);
2481 RTX_FRAME_RELATED_P (emit_move_insn (tmpr
, GEN_INT (offset
))) = 1;
2482 insn
= emit_insn (gen_adddi3 (stack_pointer_rtx
,
2483 stack_pointer_rtx
, tmpr
));
2485 RTX_FRAME_RELATED_P (insn
) = 1;
2489 /* Positive adjustments are in the epilogue only. Don't mark them
2490 as "frame-related" for unwind info. */
2491 if (insn_const_int_ok_for_constraint (offset
, CONSTRAINT_L
))
2492 emit_insn (gen_adddi3 (stack_pointer_rtx
,
2497 rtx tmpr
= gen_rtx_REG (DImode
, 255);
2498 emit_move_insn (tmpr
, GEN_INT (offset
));
2499 insn
= emit_insn (gen_adddi3 (stack_pointer_rtx
,
2500 stack_pointer_rtx
, tmpr
));
2505 /* Print operator suitable for doing something with a shiftable
2506 wyde. The type of operator is passed as an asm output modifier. */
2509 mmix_output_shiftvalue_op_from_str (FILE *stream
,
2513 static const char *const op_part
[] = {"L", "ML", "MH", "H"};
2516 if (! mmix_shiftable_wyde_value (value
))
2518 char s
[sizeof ("0xffffffffffffffff")];
2519 sprintf (s
, "%#" PRIx64
, value
);
2520 internal_error ("MMIX Internal: %s is not a shiftable int", s
);
2523 for (i
= 0; i
< 4; i
++)
2525 /* We know we're through when we find one-bits in the low
2529 fprintf (stream
, "%s%s", mainop
, op_part
[i
]);
2535 /* No bits set? Then it must have been zero. */
2536 fprintf (stream
, "%sL", mainop
);
2539 /* Print a 64-bit value, optionally prefixed by assembly pseudo. */
2542 mmix_output_octa (FILE *stream
, int64_t value
, int do_begin_end
)
2545 fprintf (stream
, "\tOCTA ");
2547 /* Provide a few alternative output formats depending on the number, to
2548 improve legibility of assembler output. */
2549 if ((value
< (int64_t) 0 && value
> (int64_t) -10000)
2550 || (value
>= (int64_t) 0 && value
<= (int64_t) 16384))
2551 fprintf (stream
, "%d", (int) value
);
2552 else if (value
> (int64_t) 0
2553 && value
< ((int64_t) 1 << 31) * 2)
2554 fprintf (stream
, "#%x", (unsigned int) value
);
2555 else if (sizeof (HOST_WIDE_INT
) == sizeof (int64_t))
2556 /* We need to avoid the not-so-universal "0x" prefix; we need the
2557 pure hex-digits together with the mmixal "#" hex prefix. */
2558 fprintf (stream
, "#" HOST_WIDE_INT_PRINT_HEX_PURE
,
2559 (HOST_WIDE_INT
) value
);
2560 else /* Need to avoid the hex output; there's no ...WIDEST...HEX_PURE. */
2561 fprintf (stream
, "%" PRIu64
, value
);
2564 fprintf (stream
, "\n");
2567 /* Print the presumed shiftable wyde argument shifted into place (to
2568 be output with an operand). */
2571 mmix_output_shifted_value (FILE *stream
, int64_t value
)
2575 if (! mmix_shiftable_wyde_value (value
))
2578 sprintf (s
, "%#" PRIx64
, value
);
2579 internal_error ("MMIX Internal: %s is not a shiftable int", s
);
2582 for (i
= 0; i
< 4; i
++)
2584 /* We know we're through when we find one-bits in the low 16 bits. */
2587 fprintf (stream
, "#%x", (int) (value
& 0xffff));
2594 /* No bits set? Then it must have been zero. */
2595 fprintf (stream
, "0");
2598 /* Output an MMIX condition name corresponding to an operator
2600 (comparison_operator [(comparison_operator ...) (const_int 0)])
2601 which means we have to look at *two* operators.
2603 The argument "reversed" refers to reversal of the condition (not the
2604 same as swapping the arguments). */
2607 mmix_output_condition (FILE *stream
, const_rtx x
, int reversed
)
2613 /* The normal output cc-code. */
2614 const char *const normal
;
2616 /* The reversed cc-code, or NULL if invalid. */
2617 const char *const reversed
;
2622 machine_mode cc_mode
;
2624 /* Terminated with {UNKNOWN, NULL, NULL} */
2625 const struct cc_conv
*const convs
;
2629 #define CCEND {UNKNOWN, NULL, NULL}
2631 static const struct cc_conv cc_fun_convs
[]
2632 = {{ORDERED
, "Z", "P"},
2633 {UNORDERED
, "P", "Z"},
2635 static const struct cc_conv cc_fp_convs
[]
2639 static const struct cc_conv cc_fpeq_convs
[]
2643 static const struct cc_conv cc_uns_convs
[]
2644 = {{GEU
, "NN", "N"},
2649 static const struct cc_conv cc_signed_convs
[]
2657 static const struct cc_conv cc_di_convs
[]
2669 static const struct cc_type_conv cc_convs
[]
2670 = {{E_CC_FUNmode
, cc_fun_convs
},
2671 {E_CC_FPmode
, cc_fp_convs
},
2672 {E_CC_FPEQmode
, cc_fpeq_convs
},
2673 {E_CC_UNSmode
, cc_uns_convs
},
2674 {E_CCmode
, cc_signed_convs
},
2675 {E_DImode
, cc_di_convs
}};
2680 machine_mode mode
= GET_MODE (XEXP (x
, 0));
2681 RTX_CODE cc
= GET_CODE (x
);
2683 for (i
= 0; i
< ARRAY_SIZE (cc_convs
); i
++)
2685 if (mode
== cc_convs
[i
].cc_mode
)
2687 for (j
= 0; cc_convs
[i
].convs
[j
].cc
!= UNKNOWN
; j
++)
2688 if (cc
== cc_convs
[i
].convs
[j
].cc
)
2691 = (reversed
? cc_convs
[i
].convs
[j
].reversed
2692 : cc_convs
[i
].convs
[j
].normal
);
2694 if (mmix_cc
== NULL
)
2695 fatal_insn ("MMIX Internal: Trying to output invalidly\
2696 reversed condition:", x
);
2698 fprintf (stream
, "%s", mmix_cc
);
2702 fatal_insn ("MMIX Internal: What's the CC of this?", x
);
2706 fatal_insn ("MMIX Internal: What is the CC of this?", x
);
2709 /* Return the bit-value for a const_int or const_double. */
2712 mmix_intval (const_rtx x
)
2714 if (GET_CODE (x
) == CONST_INT
)
2717 /* We make a little song and dance because converting to long long in
2718 gcc-2.7.2 is broken. I still want people to be able to use it for
2719 cross-compilation to MMIX. */
2720 if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == VOIDmode
)
2721 return CONST_DOUBLE_HIGH (x
);
2723 if (GET_CODE (x
) == CONST_DOUBLE
)
2725 if (GET_MODE (x
) == DFmode
)
2729 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x
), bits
);
2731 /* The double cast is necessary to avoid getting the long
2732 sign-extended to unsigned long long(!) when they're of
2733 different size (usually 32-bit hosts). */
2735 ((uint64_t) (unsigned long) bits
[0]
2737 | (uint64_t) (unsigned long) bits
[1];
2739 else if (GET_MODE (x
) == SFmode
)
2742 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), bits
);
2744 return (unsigned long) bits
;
2748 fatal_insn ("MMIX Internal: This is not a constant:", x
);
2751 /* Worker function for TARGET_PROMOTE_FUNCTION_MODE. */
2754 mmix_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
2756 int *punsignedp ATTRIBUTE_UNUSED
,
2757 const_tree fntype ATTRIBUTE_UNUSED
,
2760 /* Apparently not doing TRT if int < register-size. FIXME: Perhaps
2761 FUNCTION_VALUE and LIBCALL_VALUE needs tweaking as some ports say. */
2762 if (for_return
== 1)
2765 /* Promotion of modes currently generates slow code, extending before
2766 operation, so we do it only for arguments. */
2767 if (GET_MODE_CLASS (mode
) == MODE_INT
2768 && GET_MODE_SIZE (mode
) < 8)
2773 /* Worker function for TARGET_STRUCT_VALUE_RTX. */
2776 mmix_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
2777 int incoming ATTRIBUTE_UNUSED
)
2779 return gen_rtx_REG (Pmode
, MMIX_STRUCT_VALUE_REGNUM
);
2782 /* Worker function for TARGET_FRAME_POINTER_REQUIRED.
2784 FIXME: Is this requirement built-in? Anyway, we should try to get rid
2785 of it; we can deduce the value. */
2788 mmix_frame_pointer_required (void)
2790 return (cfun
->has_nonlocal_label
);
2795 * eval: (c-set-style "gnu")
2796 * indent-tabs-mode: t