OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [mmix/] [mmix.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.