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