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

Subversion Repositories openrisc

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Subroutines for insn-output.c for Motorola 68000 family.
2
   Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2003, 2004, 2005, 2006, 2007
4
   Free Software Foundation, Inc.
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 "tree.h"
27
#include "rtl.h"
28
#include "function.h"
29
#include "regs.h"
30
#include "hard-reg-set.h"
31
#include "real.h"
32
#include "insn-config.h"
33
#include "conditions.h"
34
#include "output.h"
35
#include "insn-attr.h"
36
#include "recog.h"
37
#include "toplev.h"
38
#include "expr.h"
39
#include "reload.h"
40
#include "tm_p.h"
41
#include "target.h"
42
#include "target-def.h"
43
#include "debug.h"
44
#include "flags.h"
45
 
46
enum reg_class regno_reg_class[] =
47
{
48
  DATA_REGS, DATA_REGS, DATA_REGS, DATA_REGS,
49
  DATA_REGS, DATA_REGS, DATA_REGS, DATA_REGS,
50
  ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
51
  ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
52
  FP_REGS, FP_REGS, FP_REGS, FP_REGS,
53
  FP_REGS, FP_REGS, FP_REGS, FP_REGS,
54
  ADDR_REGS
55
};
56
 
57
 
58
/* The ASM_DOT macro allows easy string pasting to handle the differences
59
   between MOTOROLA and MIT syntaxes in asm_fprintf(), which doesn't
60
   support the %. option.  */
61
#if MOTOROLA
62
# define ASM_DOT "."
63
# define ASM_DOTW ".w"
64
# define ASM_DOTL ".l"
65
#else
66
# define ASM_DOT ""
67
# define ASM_DOTW ""
68
# define ASM_DOTL ""
69
#endif
70
 
71
 
72
/* Structure describing stack frame layout.  */
73
struct m68k_frame
74
{
75
  /* Stack pointer to frame pointer offset.  */
76
  HOST_WIDE_INT offset;
77
 
78
  /* Offset of FPU registers.  */
79
  HOST_WIDE_INT foffset;
80
 
81
  /* Frame size in bytes (rounded up).  */
82
  HOST_WIDE_INT size;
83
 
84
  /* Data and address register.  */
85
  int reg_no;
86
  unsigned int reg_mask;
87
  unsigned int reg_rev_mask;
88
 
89
  /* FPU registers.  */
90
  int fpu_no;
91
  unsigned int fpu_mask;
92
  unsigned int fpu_rev_mask;
93
 
94
  /* Offsets relative to ARG_POINTER.  */
95
  HOST_WIDE_INT frame_pointer_offset;
96
  HOST_WIDE_INT stack_pointer_offset;
97
 
98
  /* Function which the above information refers to.  */
99
  int funcdef_no;
100
};
101
 
102
/* Current frame information calculated by m68k_compute_frame_layout().  */
103
static struct m68k_frame current_frame;
104
 
105
static bool m68k_handle_option (size_t, const char *, int);
106
static rtx find_addr_reg (rtx);
107
static const char *singlemove_string (rtx *);
108
static void m68k_output_function_prologue (FILE *, HOST_WIDE_INT);
109
static void m68k_output_function_epilogue (FILE *, HOST_WIDE_INT);
110
#ifdef M68K_TARGET_COFF
111
static void m68k_coff_asm_named_section (const char *, unsigned int, tree);
112
#endif /* M68K_TARGET_COFF */
113
static void m68k_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
114
                                          HOST_WIDE_INT, tree);
115
static rtx m68k_struct_value_rtx (tree, int);
116
static bool m68k_interrupt_function_p (tree func);
117
static tree m68k_handle_fndecl_attribute (tree *node, tree name,
118
                                          tree args, int flags,
119
                                          bool *no_add_attrs);
120
static void m68k_compute_frame_layout (void);
121
static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
122
static int const_int_cost (rtx);
123
static bool m68k_rtx_costs (rtx, int, int, int *);
124
 
125
 
126
/* Specify the identification number of the library being built */
127
const char *m68k_library_id_string = "_current_shared_library_a5_offset_";
128
 
129
/* Nonzero if the last compare/test insn had FP operands.  The
130
   sCC expanders peek at this to determine what to do for the
131
   68060, which has no fsCC instructions.  */
132
int m68k_last_compare_had_fp_operands;
133
 
134
/* Initialize the GCC target structure.  */
135
 
136
#if INT_OP_GROUP == INT_OP_DOT_WORD
137
#undef TARGET_ASM_ALIGNED_HI_OP
138
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
139
#endif
140
 
141
#if INT_OP_GROUP == INT_OP_NO_DOT
142
#undef TARGET_ASM_BYTE_OP
143
#define TARGET_ASM_BYTE_OP "\tbyte\t"
144
#undef TARGET_ASM_ALIGNED_HI_OP
145
#define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
146
#undef TARGET_ASM_ALIGNED_SI_OP
147
#define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
148
#endif
149
 
150
#if INT_OP_GROUP == INT_OP_DC
151
#undef TARGET_ASM_BYTE_OP
152
#define TARGET_ASM_BYTE_OP "\tdc.b\t"
153
#undef TARGET_ASM_ALIGNED_HI_OP
154
#define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
155
#undef TARGET_ASM_ALIGNED_SI_OP
156
#define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
157
#endif
158
 
159
#undef TARGET_ASM_UNALIGNED_HI_OP
160
#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
161
#undef TARGET_ASM_UNALIGNED_SI_OP
162
#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
163
 
164
#undef TARGET_ASM_FUNCTION_PROLOGUE
165
#define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
166
#undef TARGET_ASM_FUNCTION_EPILOGUE
167
#define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
168
 
169
#undef TARGET_ASM_OUTPUT_MI_THUNK
170
#define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
171
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
172
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
173
 
174
#undef TARGET_ASM_FILE_START_APP_OFF
175
#define TARGET_ASM_FILE_START_APP_OFF true
176
 
177
#undef TARGET_DEFAULT_TARGET_FLAGS
178
#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_STRICT_ALIGNMENT)
179
#undef TARGET_HANDLE_OPTION
180
#define TARGET_HANDLE_OPTION m68k_handle_option
181
 
182
#undef TARGET_RTX_COSTS
183
#define TARGET_RTX_COSTS m68k_rtx_costs
184
 
185
#undef TARGET_ATTRIBUTE_TABLE
186
#define TARGET_ATTRIBUTE_TABLE m68k_attribute_table
187
 
188
#undef TARGET_PROMOTE_PROTOTYPES
189
#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
190
 
191
#undef TARGET_STRUCT_VALUE_RTX
192
#define TARGET_STRUCT_VALUE_RTX m68k_struct_value_rtx
193
 
194
static const struct attribute_spec m68k_attribute_table[] =
195
{
196
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
197
  { "interrupt_handler", 0, 0, true,  false, false, m68k_handle_fndecl_attribute },
198
  { NULL,                0, 0, false, false, false, NULL }
199
};
200
 
201
struct gcc_target targetm = TARGET_INITIALIZER;
202
 
203
/* These bits are controlled by all CPU selection options.  Many options
204
   also control MASK_68881, but some (notably -m68020) leave it alone.  */
205
 
206
#define MASK_ALL_CPU_BITS \
207
  (MASK_COLDFIRE | MASK_CF_HWDIV | MASK_68060 | MASK_68040 \
208
   | MASK_68040_ONLY | MASK_68030 | MASK_68020 | MASK_BITFIELD)
209
 
210
/* Implement TARGET_HANDLE_OPTION.  */
211
 
212
static bool
213
m68k_handle_option (size_t code, const char *arg, int value)
214
{
215
  switch (code)
216
    {
217
    case OPT_m5200:
218
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
219
      target_flags |= MASK_5200;
220
      return true;
221
 
222
    case OPT_m5206e:
223
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
224
      target_flags |= MASK_5200 | MASK_CF_HWDIV;
225
      return true;
226
 
227
    case OPT_m528x:
228
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
229
      target_flags |= MASK_528x | MASK_CF_HWDIV;
230
      return true;
231
 
232
    case OPT_m5307:
233
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
234
      target_flags |= MASK_CFV3 | MASK_CF_HWDIV;
235
      return true;
236
 
237
    case OPT_m5407:
238
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
239
      target_flags |= MASK_CFV4 | MASK_CF_HWDIV;
240
      return true;
241
 
242
    case OPT_mcfv4e:
243
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
244
      target_flags |= MASK_CFV4 | MASK_CF_HWDIV | MASK_CFV4E;
245
      return true;
246
 
247
    case OPT_m68000:
248
    case OPT_mc68000:
249
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
250
      return true;
251
 
252
    case OPT_m68020:
253
    case OPT_mc68020:
254
      target_flags &= ~MASK_ALL_CPU_BITS;
255
      target_flags |= MASK_68020 | MASK_BITFIELD;
256
      return true;
257
 
258
    case OPT_m68020_40:
259
      target_flags &= ~MASK_ALL_CPU_BITS;
260
      target_flags |= MASK_BITFIELD | MASK_68881 | MASK_68020 | MASK_68040;
261
      return true;
262
 
263
    case OPT_m68020_60:
264
      target_flags &= ~MASK_ALL_CPU_BITS;
265
      target_flags |= (MASK_BITFIELD | MASK_68881 | MASK_68020
266
                       | MASK_68040 | MASK_68060);
267
      return true;
268
 
269
    case OPT_m68030:
270
      target_flags &= ~MASK_ALL_CPU_BITS;
271
      target_flags |= MASK_68020 | MASK_68030 | MASK_BITFIELD;
272
      return true;
273
 
274
    case OPT_m68040:
275
      target_flags &= ~MASK_ALL_CPU_BITS;
276
      target_flags |= (MASK_68020 | MASK_68881 | MASK_BITFIELD
277
                       | MASK_68040_ONLY | MASK_68040);
278
      return true;
279
 
280
    case OPT_m68060:
281
      target_flags &= ~MASK_ALL_CPU_BITS;
282
      target_flags |= (MASK_68020 | MASK_68881 | MASK_BITFIELD
283
                       | MASK_68040_ONLY | MASK_68060);
284
      return true;
285
 
286
    case OPT_m68302:
287
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
288
      return true;
289
 
290
    case OPT_m68332:
291
    case OPT_mcpu32:
292
      target_flags &= ~(MASK_ALL_CPU_BITS | MASK_68881);
293
      target_flags |= MASK_68020;
294
      return true;
295
 
296
    case OPT_mshared_library_id_:
297
      if (value > MAX_LIBRARY_ID)
298
        error ("-mshared-library-id=%s is not between 0 and %d",
299
               arg, MAX_LIBRARY_ID);
300
      else
301
        asprintf ((char **) &m68k_library_id_string, "%d", (value * -4) - 4);
302
      return true;
303
 
304
    default:
305
      return true;
306
    }
307
}
308
 
309
/* Sometimes certain combinations of command options do not make
310
   sense on a particular target machine.  You can define a macro
311
   `OVERRIDE_OPTIONS' to take account of this.  This macro, if
312
   defined, is executed once just after all the command options have
313
   been parsed.
314
 
315
   Don't use this macro to turn on various extra optimizations for
316
   `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
317
 
318
void
319
override_options (void)
320
{
321
  /* Sanity check to ensure that msep-data and mid-sahred-library are not
322
   * both specified together.  Doing so simply doesn't make sense.
323
   */
324
  if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
325
    error ("cannot specify both -msep-data and -mid-shared-library");
326
 
327
  /* If we're generating code for a separate A5 relative data segment,
328
   * we've got to enable -fPIC as well.  This might be relaxable to
329
   * -fpic but it hasn't been tested properly.
330
   */
331
  if (TARGET_SEP_DATA || TARGET_ID_SHARED_LIBRARY)
332
    flag_pic = 2;
333
 
334
  /* -fPIC uses 32-bit pc-relative displacements, which don't exist
335
     until the 68020.  */
336
  if (!TARGET_68020 && !TARGET_COLDFIRE && (flag_pic == 2))
337
    error ("-fPIC is not currently supported on the 68000 or 68010");
338
 
339
  /* ??? A historic way of turning on pic, or is this intended to
340
     be an embedded thing that doesn't have the same name binding
341
     significance that it does on hosted ELF systems?  */
342
  if (TARGET_PCREL && flag_pic == 0)
343
    flag_pic = 1;
344
 
345
  /* Turn off function cse if we are doing PIC.  We always want function call
346
     to be done as `bsr foo@PLTPC', so it will force the assembler to create
347
     the PLT entry for `foo'. Doing function cse will cause the address of
348
     `foo' to be loaded into a register, which is exactly what we want to
349
     avoid when we are doing PIC on svr4 m68k.  */
350
  if (flag_pic)
351
    flag_no_function_cse = 1;
352
 
353
  SUBTARGET_OVERRIDE_OPTIONS;
354
}
355
 
356
/* Return nonzero if FUNC is an interrupt function as specified by the
357
   "interrupt_handler" attribute.  */
358
static bool
359
m68k_interrupt_function_p(tree func)
360
{
361
  tree a;
362
 
363
  if (TREE_CODE (func) != FUNCTION_DECL)
364
    return false;
365
 
366
  a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
367
  return (a != NULL_TREE);
368
}
369
 
370
/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
371
   struct attribute_spec.handler.  */
372
static tree
373
m68k_handle_fndecl_attribute (tree *node, tree name,
374
                              tree args ATTRIBUTE_UNUSED,
375
                              int flags ATTRIBUTE_UNUSED,
376
                              bool *no_add_attrs)
377
{
378
  if (TREE_CODE (*node) != FUNCTION_DECL)
379
    {
380
      warning (OPT_Wattributes, "%qs attribute only applies to functions",
381
               IDENTIFIER_POINTER (name));
382
      *no_add_attrs = true;
383
    }
384
 
385
  return NULL_TREE;
386
}
387
 
388
static void
389
m68k_compute_frame_layout (void)
390
{
391
  int regno, saved;
392
  unsigned int mask, rmask;
393
  bool interrupt_handler = m68k_interrupt_function_p (current_function_decl);
394
 
395
  /* Only compute the frame once per function.
396
     Don't cache information until reload has been completed.  */
397
  if (current_frame.funcdef_no == current_function_funcdef_no
398
      && reload_completed)
399
    return;
400
 
401
  current_frame.size = (get_frame_size () + 3) & -4;
402
 
403
  mask = rmask = saved = 0;
404
  for (regno = 0; regno < 16; regno++)
405
    if (m68k_save_reg (regno, interrupt_handler))
406
      {
407
        mask |= 1 << regno;
408
        rmask |= 1 << (15 - regno);
409
        saved++;
410
      }
411
  current_frame.offset = saved * 4;
412
  current_frame.reg_no = saved;
413
  current_frame.reg_mask = mask;
414
  current_frame.reg_rev_mask = rmask;
415
 
416
  current_frame.foffset = 0;
417
  mask = rmask = saved = 0;
418
  if (TARGET_HARD_FLOAT)
419
    {
420
      for (regno = 16; regno < 24; regno++)
421
        if (m68k_save_reg (regno, interrupt_handler))
422
          {
423
            mask |= 1 << (regno - 16);
424
            rmask |= 1 << (23 - regno);
425
            saved++;
426
          }
427
      current_frame.foffset = saved * TARGET_FP_REG_SIZE;
428
      current_frame.offset += current_frame.foffset;
429
    }
430
  current_frame.fpu_no = saved;
431
  current_frame.fpu_mask = mask;
432
  current_frame.fpu_rev_mask = rmask;
433
 
434
  /* Remember what function this frame refers to.  */
435
  current_frame.funcdef_no = current_function_funcdef_no;
436
}
437
 
438
HOST_WIDE_INT
439
m68k_initial_elimination_offset (int from, int to)
440
{
441
  int argptr_offset;
442
  /* The arg pointer points 8 bytes before the start of the arguments,
443
     as defined by FIRST_PARM_OFFSET.  This makes it coincident with the
444
     frame pointer in most frames.  */
445
  argptr_offset = frame_pointer_needed ? 0 : UNITS_PER_WORD;
446
  if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
447
    return argptr_offset;
448
 
449
  m68k_compute_frame_layout ();
450
 
451
  gcc_assert (to == STACK_POINTER_REGNUM);
452
  switch (from)
453
    {
454
    case ARG_POINTER_REGNUM:
455
      return current_frame.offset + current_frame.size - argptr_offset;
456
    case FRAME_POINTER_REGNUM:
457
      return current_frame.offset + current_frame.size;
458
    default:
459
      gcc_unreachable ();
460
    }
461
}
462
 
463
/* Refer to the array `regs_ever_live' to determine which registers
464
   to save; `regs_ever_live[I]' is nonzero if register number I
465
   is ever used in the function.  This function is responsible for
466
   knowing which registers should not be saved even if used.
467
   Return true if we need to save REGNO.  */
468
 
469
static bool
470
m68k_save_reg (unsigned int regno, bool interrupt_handler)
471
{
472
  if (flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
473
    {
474
      if (current_function_uses_pic_offset_table)
475
        return true;
476
      if (!current_function_is_leaf && TARGET_ID_SHARED_LIBRARY)
477
        return true;
478
    }
479
 
480
  if (current_function_calls_eh_return)
481
    {
482
      unsigned int i;
483
      for (i = 0; ; i++)
484
        {
485
          unsigned int test = EH_RETURN_DATA_REGNO (i);
486
          if (test == INVALID_REGNUM)
487
            break;
488
          if (test == regno)
489
            return true;
490
        }
491
    }
492
 
493
  /* Fixed regs we never touch.  */
494
  if (fixed_regs[regno])
495
    return false;
496
 
497
  /* The frame pointer (if it is such) is handled specially.  */
498
  if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
499
    return false;
500
 
501
  /* Interrupt handlers must also save call_used_regs
502
     if they are live or when calling nested functions.  */
503
  if (interrupt_handler)
504
    {
505
      if (regs_ever_live[regno])
506
        return true;
507
 
508
      if (!current_function_is_leaf && call_used_regs[regno])
509
        return true;
510
    }
511
 
512
  /* Never need to save registers that aren't touched.  */
513
  if (!regs_ever_live[regno])
514
    return false;
515
 
516
  /* Otherwise save everything that isn't call-clobbered.  */
517
  return !call_used_regs[regno];
518
}
519
 
520
/* This function generates the assembly code for function entry.
521
   STREAM is a stdio stream to output the code to.
522
   SIZE is an int: how many units of temporary storage to allocate.  */
523
 
524
static void
525
m68k_output_function_prologue (FILE *stream,
526
                               HOST_WIDE_INT size ATTRIBUTE_UNUSED)
527
{
528
  HOST_WIDE_INT fsize_with_regs;
529
  HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
530
 
531
  m68k_compute_frame_layout();
532
 
533
  /* If the stack limit is a symbol, we can check it here,
534
     before actually allocating the space.  */
535
  if (current_function_limit_stack
536
      && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
537
    asm_fprintf (stream, "\tcmp" ASM_DOT "l %I%s+%wd,%Rsp\n\ttrapcs\n",
538
                 XSTR (stack_limit_rtx, 0), current_frame.size + 4);
539
 
540
  /* On ColdFire add register save into initial stack frame setup, if possible.  */
541
  fsize_with_regs = current_frame.size;
542
  if (TARGET_COLDFIRE)
543
    {
544
      if (current_frame.reg_no > 2)
545
        fsize_with_regs += current_frame.reg_no * 4;
546
      if (current_frame.fpu_no)
547
        fsize_with_regs += current_frame.fpu_no * 8;
548
    }
549
 
550
  if (frame_pointer_needed)
551
    {
552
      if (current_frame.size == 0 && TARGET_68040)
553
        /* on the 68040, pea + move is faster than link.w 0 */
554
        fprintf (stream, (MOTOROLA
555
                          ? "\tpea (%s)\n\tmove.l %s,%s\n"
556
                          : "\tpea %s@\n\tmovel %s,%s\n"),
557
                 M68K_REGNAME (FRAME_POINTER_REGNUM),
558
                 M68K_REGNAME (STACK_POINTER_REGNUM),
559
                 M68K_REGNAME (FRAME_POINTER_REGNUM));
560
      else if (fsize_with_regs < 0x8000)
561
        asm_fprintf (stream, "\tlink" ASM_DOTW " %s,%I%wd\n",
562
                     M68K_REGNAME (FRAME_POINTER_REGNUM), -fsize_with_regs);
563
      else if (TARGET_68020)
564
        asm_fprintf (stream, "\tlink" ASM_DOTL " %s,%I%wd\n",
565
                     M68K_REGNAME (FRAME_POINTER_REGNUM), -fsize_with_regs);
566
      else
567
        /* Adding negative number is faster on the 68040.  */
568
        asm_fprintf (stream,
569
                     "\tlink" ASM_DOTW " %s,%I0\n"
570
                     "\tadd" ASM_DOT "l %I%wd,%Rsp\n",
571
                     M68K_REGNAME (FRAME_POINTER_REGNUM), -fsize_with_regs);
572
    }
573
  else if (fsize_with_regs) /* !frame_pointer_needed */
574
    {
575
      if (fsize_with_regs < 0x8000)
576
        {
577
          if (fsize_with_regs <= 8)
578
            {
579
              if (!TARGET_COLDFIRE)
580
                asm_fprintf (stream, "\tsubq" ASM_DOT "w %I%wd,%Rsp\n",
581
                             fsize_with_regs);
582
              else
583
                asm_fprintf (stream, "\tsubq" ASM_DOT "l %I%wd,%Rsp\n",
584
                             fsize_with_regs);
585
            }
586
          else if (fsize_with_regs <= 16 && TARGET_CPU32)
587
            /* On the CPU32 it is faster to use two subqw instructions to
588
               subtract a small integer (8 < N <= 16) to a register.  */
589
            asm_fprintf (stream,
590
                         "\tsubq" ASM_DOT "w %I8,%Rsp\n"
591
                         "\tsubq" ASM_DOT "w %I%wd,%Rsp\n",
592
                         fsize_with_regs - 8);
593
          else if (TARGET_68040)
594
            /* Adding negative number is faster on the 68040.  */
595
            asm_fprintf (stream, "\tadd" ASM_DOT "w %I%wd,%Rsp\n",
596
                         -fsize_with_regs);
597
          else
598
            asm_fprintf (stream, (MOTOROLA
599
                                  ? "\tlea (%wd,%Rsp),%Rsp\n"
600
                                  : "\tlea %Rsp@(%wd),%Rsp\n"),
601
                         -fsize_with_regs);
602
        }
603
      else /* fsize_with_regs >= 0x8000 */
604
        asm_fprintf (stream, "\tadd" ASM_DOT "l %I%wd,%Rsp\n",
605
                     -fsize_with_regs);
606
    } /* !frame_pointer_needed */
607
 
608
  if (dwarf2out_do_frame ())
609
    {
610
      if (frame_pointer_needed)
611
        {
612
          char *l;
613
          l = (char *) dwarf2out_cfi_label ();
614
          cfa_offset += 4;
615
          dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, -cfa_offset);
616
          dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
617
          cfa_offset += current_frame.size;
618
        }
619
      else
620
        {
621
          cfa_offset += current_frame.size;
622
          dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
623
        }
624
    }
625
 
626
  if (current_frame.fpu_mask)
627
    {
628
      if (TARGET_68881)
629
        {
630
          asm_fprintf (stream, (MOTOROLA
631
                                ? "\tfmovm %I0x%x,-(%Rsp)\n"
632
                                : "\tfmovem %I0x%x,%Rsp@-\n"),
633
                       current_frame.fpu_mask);
634
        }
635
      else
636
        {
637
          int offset;
638
 
639
          /* stack already has registers in it.  Find the offset from
640
             the bottom of stack to where the FP registers go */
641
          if (current_frame.reg_no <= 2)
642
            offset = 0;
643
          else
644
            offset = current_frame.reg_no * 4;
645
          if (offset)
646
            asm_fprintf (stream,
647
                         "\tfmovem %I0x%x,%d(%Rsp)\n",
648
                         current_frame.fpu_rev_mask,
649
                         offset);
650
          else
651
            asm_fprintf (stream,
652
                         "\tfmovem %I0x%x,(%Rsp)\n",
653
                         current_frame.fpu_rev_mask);
654
        }
655
 
656
      if (dwarf2out_do_frame ())
657
        {
658
          char *l = (char *) dwarf2out_cfi_label ();
659
          int n_regs, regno;
660
 
661
          cfa_offset += current_frame.fpu_no * TARGET_FP_REG_SIZE;
662
          if (! frame_pointer_needed)
663
            dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
664
          for (regno = 16, n_regs = 0; regno < 24; regno++)
665
            if (current_frame.fpu_mask & (1 << (regno - 16)))
666
              dwarf2out_reg_save (l, regno, -cfa_offset
667
                                  + n_regs++ * TARGET_FP_REG_SIZE);
668
        }
669
    }
670
 
671
  /* If the stack limit is not a symbol, check it here.
672
     This has the disadvantage that it may be too late...  */
673
  if (current_function_limit_stack)
674
    {
675
      if (REG_P (stack_limit_rtx))
676
        asm_fprintf (stream, "\tcmp" ASM_DOT "l %s,%Rsp\n\ttrapcs\n",
677
                     M68K_REGNAME (REGNO (stack_limit_rtx)));
678
      else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
679
        warning (0, "stack limit expression is not supported");
680
    }
681
 
682
  if (current_frame.reg_no <= 2)
683
    {
684
      /* Store each separately in the same order moveml uses.
685
         Using two movel instructions instead of a single moveml
686
         is about 15% faster for the 68020 and 68030 at no expense
687
         in code size.  */
688
 
689
      int i;
690
 
691
      for (i = 0; i < 16; i++)
692
        if (current_frame.reg_rev_mask & (1 << i))
693
          {
694
            asm_fprintf (stream, (MOTOROLA
695
                                  ? "\t%Omove.l %s,-(%Rsp)\n"
696
                                  : "\tmovel %s,%Rsp@-\n"),
697
                         M68K_REGNAME (15 - i));
698
            if (dwarf2out_do_frame ())
699
              {
700
                char *l = (char *) dwarf2out_cfi_label ();
701
 
702
                cfa_offset += 4;
703
                if (! frame_pointer_needed)
704
                  dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
705
                dwarf2out_reg_save (l, 15 - i, -cfa_offset);
706
              }
707
          }
708
    }
709
  else if (current_frame.reg_rev_mask)
710
    {
711
      if (TARGET_COLDFIRE)
712
        /* The ColdFire does not support the predecrement form of the
713
           MOVEM instruction, so we must adjust the stack pointer and
714
           then use the plain address register indirect mode.
715
           The required register save space was combined earlier with
716
           the fsize_with_regs amount.  */
717
 
718
        asm_fprintf (stream, (MOTOROLA
719
                              ? "\tmovm.l %I0x%x,(%Rsp)\n"
720
                              : "\tmoveml %I0x%x,%Rsp@\n"),
721
                     current_frame.reg_mask);
722
      else
723
        asm_fprintf (stream, (MOTOROLA
724
                              ? "\tmovm.l %I0x%x,-(%Rsp)\n"
725
                              : "\tmoveml %I0x%x,%Rsp@-\n"),
726
                     current_frame.reg_rev_mask);
727
      if (dwarf2out_do_frame ())
728
        {
729
          char *l = (char *) dwarf2out_cfi_label ();
730
          int n_regs, regno;
731
 
732
          cfa_offset += current_frame.reg_no * 4;
733
          if (! frame_pointer_needed)
734
            dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
735
          for (regno = 0, n_regs = 0; regno < 16; regno++)
736
            if (current_frame.reg_mask & (1 << regno))
737
              dwarf2out_reg_save (l, regno, -cfa_offset + n_regs++ * 4);
738
        }
739
    }
740
  if (!TARGET_SEP_DATA && flag_pic
741
      && (current_function_uses_pic_offset_table
742
          || (!current_function_is_leaf && TARGET_ID_SHARED_LIBRARY)))
743
    {
744
      if (TARGET_ID_SHARED_LIBRARY)
745
        {
746
          asm_fprintf (stream, "\tmovel %s@(%s), %s\n",
747
                       M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM),
748
                       m68k_library_id_string,
749
                       M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM));
750
        }
751
      else
752
        {
753
          if (MOTOROLA)
754
            asm_fprintf (stream,
755
                         "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
756
                         M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM));
757
          else
758
            {
759
              asm_fprintf (stream, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n",
760
                           M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM));
761
              asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
762
                           M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM),
763
                           M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM));
764
            }
765
        }
766
    }
767
}
768
 
769
/* Return true if this function's epilogue can be output as RTL.  */
770
 
771
bool
772
use_return_insn (void)
773
{
774
  if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
775
    return false;
776
 
777
  /* We can output the epilogue as RTL only if no registers need to be
778
     restored.  */
779
  m68k_compute_frame_layout ();
780
  return current_frame.reg_no ? false : true;
781
}
782
 
783
/* This function generates the assembly code for function exit,
784
   on machines that need it.
785
 
786
   The function epilogue should not depend on the current stack pointer!
787
   It should use the frame pointer only, if there is a frame pointer.
788
   This is mandatory because of alloca; we also take advantage of it to
789
   omit stack adjustments before returning.  */
790
 
791
static void
792
m68k_output_function_epilogue (FILE *stream,
793
                               HOST_WIDE_INT size ATTRIBUTE_UNUSED)
794
{
795
  HOST_WIDE_INT fsize, fsize_with_regs;
796
  bool big = false;
797
  bool restore_from_sp = false;
798
  rtx insn = get_last_insn ();
799
 
800
  m68k_compute_frame_layout ();
801
 
802
  /* If the last insn was a BARRIER, we don't have to write any code.  */
803
  if (GET_CODE (insn) == NOTE)
804
    insn = prev_nonnote_insn (insn);
805
  if (insn && GET_CODE (insn) == BARRIER)
806
    {
807
      /* Output just a no-op so that debuggers don't get confused
808
         about which function the pc is in at this address.  */
809
      fprintf (stream, "\tnop\n");
810
      return;
811
    }
812
 
813
#ifdef FUNCTION_EXTRA_EPILOGUE
814
  FUNCTION_EXTRA_EPILOGUE (stream, size);
815
#endif
816
 
817
  fsize = current_frame.size;
818
 
819
  /* FIXME: leaf_function_p below is too strong.
820
     What we really need to know there is if there could be pending
821
     stack adjustment needed at that point.  */
822
  restore_from_sp
823
    = (! frame_pointer_needed
824
       || (! current_function_calls_alloca && leaf_function_p ()));
825
 
826
  /* fsize_with_regs is the size we need to adjust the sp when
827
     popping the frame.  */
828
  fsize_with_regs = fsize;
829
 
830
  /* Because the ColdFire doesn't support moveml with
831
     complex address modes, we must adjust the stack manually
832
     after restoring registers. When the frame pointer isn't used,
833
     we can merge movem adjustment into frame unlinking
834
     made immediately after it.  */
835
  if (TARGET_COLDFIRE && restore_from_sp)
836
    {
837
      if (current_frame.reg_no > 2)
838
        fsize_with_regs += current_frame.reg_no * 4;
839
      if (current_frame.fpu_no)
840
        fsize_with_regs += current_frame.fpu_no * 8;
841
    }
842
 
843
  if (current_frame.offset + fsize >= 0x8000
844
      && ! restore_from_sp
845
      && (current_frame.reg_mask || current_frame.fpu_mask))
846
    {
847
      /* Because the ColdFire doesn't support moveml with
848
         complex address modes we make an extra correction here.  */
849
      if (TARGET_COLDFIRE)
850
        fsize += current_frame.offset;
851
 
852
      asm_fprintf (stream, "\t%Omove" ASM_DOT "l %I%wd,%Ra1\n", -fsize);
853
      fsize = 0, big = true;
854
    }
855
  if (current_frame.reg_no <= 2)
856
    {
857
      /* Restore each separately in the same order moveml does.
858
         Using two movel instructions instead of a single moveml
859
         is about 15% faster for the 68020 and 68030 at no expense
860
         in code size.  */
861
 
862
      int i;
863
      HOST_WIDE_INT offset = current_frame.offset + fsize;
864
 
865
      for (i = 0; i < 16; i++)
866
        if (current_frame.reg_mask & (1 << i))
867
          {
868
            if (big)
869
              {
870
                if (MOTOROLA)
871
                  asm_fprintf (stream, "\t%Omove.l -%wd(%s,%Ra1.l),%s\n",
872
                               offset,
873
                               M68K_REGNAME (FRAME_POINTER_REGNUM),
874
                               M68K_REGNAME (i));
875
                else
876
                  asm_fprintf (stream, "\tmovel %s@(-%wd,%Ra1:l),%s\n",
877
                               M68K_REGNAME (FRAME_POINTER_REGNUM),
878
                               offset,
879
                               M68K_REGNAME (i));
880
              }
881
            else if (restore_from_sp)
882
              asm_fprintf (stream, (MOTOROLA
883
                                    ? "\t%Omove.l (%Rsp)+,%s\n"
884
                                    : "\tmovel %Rsp@+,%s\n"),
885
                           M68K_REGNAME (i));
886
            else
887
              {
888
                if (MOTOROLA)
889
                  asm_fprintf (stream, "\t%Omove.l -%wd(%s),%s\n",
890
                               offset,
891
                               M68K_REGNAME (FRAME_POINTER_REGNUM),
892
                               M68K_REGNAME (i));
893
                else
894
                  asm_fprintf (stream, "\tmovel %s@(-%wd),%s\n",
895
                               M68K_REGNAME (FRAME_POINTER_REGNUM),
896
                               offset,
897
                               M68K_REGNAME (i));
898
              }
899
            offset -= 4;
900
          }
901
    }
902
  else if (current_frame.reg_mask)
903
    {
904
      /* The ColdFire requires special handling due to its limited moveml
905
         insn.  */
906
      if (TARGET_COLDFIRE)
907
        {
908
          if (big)
909
            {
910
              asm_fprintf (stream, "\tadd" ASM_DOT "l %s,%Ra1\n",
911
                           M68K_REGNAME (FRAME_POINTER_REGNUM));
912
              asm_fprintf (stream, (MOTOROLA
913
                                    ? "\tmovm.l (%Ra1),%I0x%x\n"
914
                                    : "\tmoveml %Ra1@,%I0x%x\n"),
915
                           current_frame.reg_mask);
916
             }
917
           else if (restore_from_sp)
918
             asm_fprintf (stream, (MOTOROLA
919
                                   ? "\tmovm.l (%Rsp),%I0x%x\n"
920
                                   : "\tmoveml %Rsp@,%I0x%x\n"),
921
                          current_frame.reg_mask);
922
          else
923
            {
924
              if (MOTOROLA)
925
                asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
926
                             current_frame.offset + fsize,
927
                             M68K_REGNAME (FRAME_POINTER_REGNUM),
928
                             current_frame.reg_mask);
929
              else
930
                asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
931
                             M68K_REGNAME (FRAME_POINTER_REGNUM),
932
                             current_frame.offset + fsize,
933
                             current_frame.reg_mask);
934
            }
935
        }
936
      else /* !TARGET_COLDFIRE */
937
        {
938
          if (big)
939
            {
940
              if (MOTOROLA)
941
                asm_fprintf (stream, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
942
                             current_frame.offset + fsize,
943
                             M68K_REGNAME (FRAME_POINTER_REGNUM),
944
                             current_frame.reg_mask);
945
              else
946
                asm_fprintf (stream, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
947
                             M68K_REGNAME (FRAME_POINTER_REGNUM),
948
                             current_frame.offset + fsize,
949
                             current_frame.reg_mask);
950
            }
951
          else if (restore_from_sp)
952
            {
953
              asm_fprintf (stream, (MOTOROLA
954
                                    ? "\tmovm.l (%Rsp)+,%I0x%x\n"
955
                                    : "\tmoveml %Rsp@+,%I0x%x\n"),
956
                           current_frame.reg_mask);
957
            }
958
          else
959
            {
960
              if (MOTOROLA)
961
                asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
962
                             current_frame.offset + fsize,
963
                             M68K_REGNAME (FRAME_POINTER_REGNUM),
964
                             current_frame.reg_mask);
965
              else
966
                asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
967
                             M68K_REGNAME (FRAME_POINTER_REGNUM),
968
                             current_frame.offset + fsize,
969
                             current_frame.reg_mask);
970
            }
971
        }
972
    }
973
  if (current_frame.fpu_rev_mask)
974
    {
975
      if (big)
976
        {
977
          if (TARGET_COLDFIRE)
978
            {
979
              if (current_frame.reg_no)
980
                asm_fprintf (stream, MOTOROLA ?
981
                             "\tfmovem.d %d(%Ra1),%I0x%x\n" :
982
                             "\tfmovmd (%d,%Ra1),%I0x%x\n",
983
                             current_frame.reg_no * 4,
984
                             current_frame.fpu_rev_mask);
985
              else
986
                asm_fprintf (stream, MOTOROLA ?
987
                             "\tfmovem.d (%Ra1),%I0x%x\n" :
988
                             "\tfmovmd (%Ra1),%I0x%x\n",
989
                             current_frame.fpu_rev_mask);
990
            }
991
          else if (MOTOROLA)
992
            asm_fprintf (stream, "\tfmovm -%wd(%s,%Ra1.l),%I0x%x\n",
993
                         current_frame.foffset + fsize,
994
                         M68K_REGNAME (FRAME_POINTER_REGNUM),
995
                         current_frame.fpu_rev_mask);
996
          else
997
            asm_fprintf (stream, "\tfmovem %s@(-%wd,%Ra1:l),%I0x%x\n",
998
                         M68K_REGNAME (FRAME_POINTER_REGNUM),
999
                         current_frame.foffset + fsize,
1000
                         current_frame.fpu_rev_mask);
1001
        }
1002
      else if (restore_from_sp)
1003
        {
1004
          if (TARGET_COLDFIRE)
1005
            {
1006
              int offset;
1007
 
1008
              /* Stack already has registers in it.  Find the offset from
1009
                 the bottom of stack to where the FP registers go.  */
1010
              if (current_frame.reg_no <= 2)
1011
                offset = 0;
1012
              else
1013
                offset = current_frame.reg_no * 4;
1014
              if (offset)
1015
                asm_fprintf (stream,
1016
                             "\tfmovem %Rsp@(%d), %I0x%x\n",
1017
                             offset, current_frame.fpu_rev_mask);
1018
              else
1019
                asm_fprintf (stream,
1020
                             "\tfmovem %Rsp@, %I0x%x\n",
1021
                             current_frame.fpu_rev_mask);
1022
            }
1023
          else
1024
            asm_fprintf (stream, MOTOROLA ?
1025
                         "\tfmovm (%Rsp)+,%I0x%x\n" :
1026
                         "\tfmovem %Rsp@+,%I0x%x\n",
1027
                         current_frame.fpu_rev_mask);
1028
        }
1029
      else
1030
        {
1031
          if (MOTOROLA && !TARGET_COLDFIRE)
1032
            asm_fprintf (stream, "\tfmovm -%wd(%s),%I0x%x\n",
1033
                         current_frame.foffset + fsize,
1034
                         M68K_REGNAME (FRAME_POINTER_REGNUM),
1035
                         current_frame.fpu_rev_mask);
1036
          else
1037
            asm_fprintf (stream, "\tfmovem %s@(-%wd),%I0x%x\n",
1038
                         M68K_REGNAME (FRAME_POINTER_REGNUM),
1039
                         current_frame.foffset + fsize,
1040
                         current_frame.fpu_rev_mask);
1041
        }
1042
    }
1043
  if (frame_pointer_needed)
1044
    fprintf (stream, "\tunlk %s\n", M68K_REGNAME (FRAME_POINTER_REGNUM));
1045
  else if (fsize_with_regs)
1046
    {
1047
      if (fsize_with_regs <= 8)
1048
        {
1049
          if (!TARGET_COLDFIRE)
1050
            asm_fprintf (stream, "\taddq" ASM_DOT "w %I%wd,%Rsp\n",
1051
                         fsize_with_regs);
1052
          else
1053
            asm_fprintf (stream, "\taddq" ASM_DOT "l %I%wd,%Rsp\n",
1054
                         fsize_with_regs);
1055
        }
1056
      else if (fsize_with_regs <= 16 && TARGET_CPU32)
1057
        {
1058
          /* On the CPU32 it is faster to use two addqw instructions to
1059
             add a small integer (8 < N <= 16) to a register.  */
1060
          asm_fprintf (stream,
1061
                       "\taddq" ASM_DOT "w %I8,%Rsp\n"
1062
                       "\taddq" ASM_DOT "w %I%wd,%Rsp\n",
1063
                       fsize_with_regs - 8);
1064
        }
1065
      else if (fsize_with_regs < 0x8000)
1066
        {
1067
          if (TARGET_68040)
1068
            asm_fprintf (stream, "\tadd" ASM_DOT "w %I%wd,%Rsp\n",
1069
                         fsize_with_regs);
1070
          else
1071
            asm_fprintf (stream, (MOTOROLA
1072
                                  ? "\tlea (%wd,%Rsp),%Rsp\n"
1073
                                  : "\tlea %Rsp@(%wd),%Rsp\n"),
1074
                         fsize_with_regs);
1075
        }
1076
      else
1077
        asm_fprintf (stream, "\tadd" ASM_DOT "l %I%wd,%Rsp\n", fsize_with_regs);
1078
    }
1079
  if (current_function_calls_eh_return)
1080
    asm_fprintf (stream, "\tadd" ASM_DOT "l %Ra0,%Rsp\n");
1081
  if (m68k_interrupt_function_p (current_function_decl))
1082
    fprintf (stream, "\trte\n");
1083
  else if (current_function_pops_args)
1084
    asm_fprintf (stream, "\trtd %I%d\n", current_function_pops_args);
1085
  else
1086
    fprintf (stream, "\trts\n");
1087
}
1088
 
1089
/* Return true if X is a valid comparison operator for the dbcc
1090
   instruction.
1091
 
1092
   Note it rejects floating point comparison operators.
1093
   (In the future we could use Fdbcc).
1094
 
1095
   It also rejects some comparisons when CC_NO_OVERFLOW is set.  */
1096
 
1097
int
1098
valid_dbcc_comparison_p_2 (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
1099
{
1100
  switch (GET_CODE (x))
1101
    {
1102
      case EQ: case NE: case GTU: case LTU:
1103
      case GEU: case LEU:
1104
        return 1;
1105
 
1106
      /* Reject some when CC_NO_OVERFLOW is set.  This may be over
1107
         conservative */
1108
      case GT: case LT: case GE: case LE:
1109
        return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
1110
      default:
1111
        return 0;
1112
    }
1113
}
1114
 
1115
/* Return nonzero if flags are currently in the 68881 flag register.  */
1116
int
1117
flags_in_68881 (void)
1118
{
1119
  /* We could add support for these in the future */
1120
  return cc_status.flags & CC_IN_68881;
1121
}
1122
 
1123
/* Output a BSR instruction suitable for PIC code.  */
1124
void
1125
m68k_output_pic_call (rtx dest)
1126
{
1127
  const char *out;
1128
 
1129
  if (!(GET_CODE (dest) == MEM && GET_CODE (XEXP (dest, 0)) == SYMBOL_REF))
1130
    out = "jsr %0";
1131
      /* We output a BSR instruction if we're building for a target that
1132
         supports long branches.  Otherwise we generate one of two sequences:
1133
         a shorter one that uses a GOT entry or a longer one that doesn't.
1134
         We'll use the -Os command-line flag to decide which to generate.
1135
         Both sequences take the same time to execute on the ColdFire.  */
1136
  else if (TARGET_PCREL)
1137
    out = "bsr.l %o0";
1138
  else if (TARGET_68020)
1139
#if defined(USE_GAS)
1140
    out = "bsr.l %0@PLTPC";
1141
#else
1142
    out = "bsr %0@PLTPC";
1143
#endif
1144
  else if (optimize_size || TARGET_ID_SHARED_LIBRARY)
1145
    out = "move.l %0@GOT(%%a5), %%a1\n\tjsr (%%a1)";
1146
  else
1147
    out = "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";
1148
 
1149
  output_asm_insn (out, &dest);
1150
}
1151
 
1152
/* Output a dbCC; jCC sequence.  Note we do not handle the
1153
   floating point version of this sequence (Fdbcc).  We also
1154
   do not handle alternative conditions when CC_NO_OVERFLOW is
1155
   set.  It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
1156
   kick those out before we get here.  */
1157
 
1158
void
1159
output_dbcc_and_branch (rtx *operands)
1160
{
1161
  switch (GET_CODE (operands[3]))
1162
    {
1163
      case EQ:
1164
        output_asm_insn (MOTOROLA
1165
                         ? "dbeq %0,%l1\n\tjbeq %l2"
1166
                         : "dbeq %0,%l1\n\tjeq %l2",
1167
                         operands);
1168
        break;
1169
 
1170
      case NE:
1171
        output_asm_insn (MOTOROLA
1172
                         ? "dbne %0,%l1\n\tjbne %l2"
1173
                         : "dbne %0,%l1\n\tjne %l2",
1174
                         operands);
1175
        break;
1176
 
1177
      case GT:
1178
        output_asm_insn (MOTOROLA
1179
                         ? "dbgt %0,%l1\n\tjbgt %l2"
1180
                         : "dbgt %0,%l1\n\tjgt %l2",
1181
                         operands);
1182
        break;
1183
 
1184
      case GTU:
1185
        output_asm_insn (MOTOROLA
1186
                         ? "dbhi %0,%l1\n\tjbhi %l2"
1187
                         : "dbhi %0,%l1\n\tjhi %l2",
1188
                         operands);
1189
        break;
1190
 
1191
      case LT:
1192
        output_asm_insn (MOTOROLA
1193
                         ? "dblt %0,%l1\n\tjblt %l2"
1194
                         : "dblt %0,%l1\n\tjlt %l2",
1195
                         operands);
1196
        break;
1197
 
1198
      case LTU:
1199
        output_asm_insn (MOTOROLA
1200
                         ? "dbcs %0,%l1\n\tjbcs %l2"
1201
                         : "dbcs %0,%l1\n\tjcs %l2",
1202
                         operands);
1203
        break;
1204
 
1205
      case GE:
1206
        output_asm_insn (MOTOROLA
1207
                         ? "dbge %0,%l1\n\tjbge %l2"
1208
                         : "dbge %0,%l1\n\tjge %l2",
1209
                         operands);
1210
        break;
1211
 
1212
      case GEU:
1213
        output_asm_insn (MOTOROLA
1214
                         ? "dbcc %0,%l1\n\tjbcc %l2"
1215
                         : "dbcc %0,%l1\n\tjcc %l2",
1216
                         operands);
1217
        break;
1218
 
1219
      case LE:
1220
        output_asm_insn (MOTOROLA
1221
                         ? "dble %0,%l1\n\tjble %l2"
1222
                         : "dble %0,%l1\n\tjle %l2",
1223
                         operands);
1224
        break;
1225
 
1226
      case LEU:
1227
        output_asm_insn (MOTOROLA
1228
                         ? "dbls %0,%l1\n\tjbls %l2"
1229
                         : "dbls %0,%l1\n\tjls %l2",
1230
                         operands);
1231
        break;
1232
 
1233
      default:
1234
        gcc_unreachable ();
1235
    }
1236
 
1237
  /* If the decrement is to be done in SImode, then we have
1238
     to compensate for the fact that dbcc decrements in HImode.  */
1239
  switch (GET_MODE (operands[0]))
1240
    {
1241
      case SImode:
1242
        output_asm_insn (MOTOROLA
1243
                         ? "clr%.w %0\n\tsubq%.l #1,%0\n\tjbpl %l1"
1244
                         : "clr%.w %0\n\tsubq%.l #1,%0\n\tjpl %l1",
1245
                         operands);
1246
        break;
1247
 
1248
      case HImode:
1249
        break;
1250
 
1251
      default:
1252
        gcc_unreachable ();
1253
    }
1254
}
1255
 
1256
const char *
1257
output_scc_di (rtx op, rtx operand1, rtx operand2, rtx dest)
1258
{
1259
  rtx loperands[7];
1260
  enum rtx_code op_code = GET_CODE (op);
1261
 
1262
  /* This does not produce a useful cc.  */
1263
  CC_STATUS_INIT;
1264
 
1265
  /* The m68k cmp.l instruction requires operand1 to be a reg as used
1266
     below.  Swap the operands and change the op if these requirements
1267
     are not fulfilled.  */
1268
  if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
1269
    {
1270
      rtx tmp = operand1;
1271
 
1272
      operand1 = operand2;
1273
      operand2 = tmp;
1274
      op_code = swap_condition (op_code);
1275
    }
1276
  loperands[0] = operand1;
1277
  if (GET_CODE (operand1) == REG)
1278
    loperands[1] = gen_rtx_REG (SImode, REGNO (operand1) + 1);
1279
  else
1280
    loperands[1] = adjust_address (operand1, SImode, 4);
1281
  if (operand2 != const0_rtx)
1282
    {
1283
      loperands[2] = operand2;
1284
      if (GET_CODE (operand2) == REG)
1285
        loperands[3] = gen_rtx_REG (SImode, REGNO (operand2) + 1);
1286
      else
1287
        loperands[3] = adjust_address (operand2, SImode, 4);
1288
    }
1289
  loperands[4] = gen_label_rtx ();
1290
  if (operand2 != const0_rtx)
1291
    {
1292
      output_asm_insn (MOTOROLA
1293
                       ? "cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1"
1294
                       : "cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1",
1295
                       loperands);
1296
    }
1297
  else
1298
    {
1299
      if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (loperands[0]))
1300
        output_asm_insn ("tst%.l %0", loperands);
1301
      else
1302
        output_asm_insn ("cmp%.w #0,%0", loperands);
1303
 
1304
      output_asm_insn (MOTOROLA ? "jbne %l4" : "jne %l4", loperands);
1305
 
1306
      if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (loperands[1]))
1307
        output_asm_insn ("tst%.l %1", loperands);
1308
      else
1309
        output_asm_insn ("cmp%.w #0,%1", loperands);
1310
    }
1311
 
1312
  loperands[5] = dest;
1313
 
1314
  switch (op_code)
1315
    {
1316
      case EQ:
1317
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1318
                                           CODE_LABEL_NUMBER (loperands[4]));
1319
        output_asm_insn ("seq %5", loperands);
1320
        break;
1321
 
1322
      case NE:
1323
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1324
                                           CODE_LABEL_NUMBER (loperands[4]));
1325
        output_asm_insn ("sne %5", loperands);
1326
        break;
1327
 
1328
      case GT:
1329
        loperands[6] = gen_label_rtx ();
1330
        output_asm_insn (MOTOROLA ? "shi %5\n\tjbra %l6" : "shi %5\n\tjra %l6",
1331
                         loperands);
1332
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1333
                                           CODE_LABEL_NUMBER (loperands[4]));
1334
        output_asm_insn ("sgt %5", loperands);
1335
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1336
                                           CODE_LABEL_NUMBER (loperands[6]));
1337
        break;
1338
 
1339
      case GTU:
1340
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1341
                                           CODE_LABEL_NUMBER (loperands[4]));
1342
        output_asm_insn ("shi %5", loperands);
1343
        break;
1344
 
1345
      case LT:
1346
        loperands[6] = gen_label_rtx ();
1347
        output_asm_insn (MOTOROLA ? "scs %5\n\tjbra %l6" : "scs %5\n\tjra %l6",
1348
                         loperands);
1349
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1350
                                           CODE_LABEL_NUMBER (loperands[4]));
1351
        output_asm_insn ("slt %5", loperands);
1352
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1353
                                           CODE_LABEL_NUMBER (loperands[6]));
1354
        break;
1355
 
1356
      case LTU:
1357
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1358
                                           CODE_LABEL_NUMBER (loperands[4]));
1359
        output_asm_insn ("scs %5", loperands);
1360
        break;
1361
 
1362
      case GE:
1363
        loperands[6] = gen_label_rtx ();
1364
        output_asm_insn (MOTOROLA ? "scc %5\n\tjbra %l6" : "scc %5\n\tjra %l6",
1365
                         loperands);
1366
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1367
                                           CODE_LABEL_NUMBER (loperands[4]));
1368
        output_asm_insn ("sge %5", loperands);
1369
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1370
                                           CODE_LABEL_NUMBER (loperands[6]));
1371
        break;
1372
 
1373
      case GEU:
1374
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1375
                                           CODE_LABEL_NUMBER (loperands[4]));
1376
        output_asm_insn ("scc %5", loperands);
1377
        break;
1378
 
1379
      case LE:
1380
        loperands[6] = gen_label_rtx ();
1381
        output_asm_insn (MOTOROLA ? "sls %5\n\tjbra %l6" : "sls %5\n\tjra %l6",
1382
                         loperands);
1383
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1384
                                           CODE_LABEL_NUMBER (loperands[4]));
1385
        output_asm_insn ("sle %5", loperands);
1386
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1387
                                           CODE_LABEL_NUMBER (loperands[6]));
1388
        break;
1389
 
1390
      case LEU:
1391
        (*targetm.asm_out.internal_label) (asm_out_file, "L",
1392
                                           CODE_LABEL_NUMBER (loperands[4]));
1393
        output_asm_insn ("sls %5", loperands);
1394
        break;
1395
 
1396
      default:
1397
        gcc_unreachable ();
1398
    }
1399
  return "";
1400
}
1401
 
1402
const char *
1403
output_btst (rtx *operands, rtx countop, rtx dataop, rtx insn, int signpos)
1404
{
1405
  operands[0] = countop;
1406
  operands[1] = dataop;
1407
 
1408
  if (GET_CODE (countop) == CONST_INT)
1409
    {
1410
      register int count = INTVAL (countop);
1411
      /* If COUNT is bigger than size of storage unit in use,
1412
         advance to the containing unit of same size.  */
1413
      if (count > signpos)
1414
        {
1415
          int offset = (count & ~signpos) / 8;
1416
          count = count & signpos;
1417
          operands[1] = dataop = adjust_address (dataop, QImode, offset);
1418
        }
1419
      if (count == signpos)
1420
        cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
1421
      else
1422
        cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
1423
 
1424
      /* These three statements used to use next_insns_test_no...
1425
         but it appears that this should do the same job.  */
1426
      if (count == 31
1427
          && next_insn_tests_no_inequality (insn))
1428
        return "tst%.l %1";
1429
      if (count == 15
1430
          && next_insn_tests_no_inequality (insn))
1431
        return "tst%.w %1";
1432
      if (count == 7
1433
          && next_insn_tests_no_inequality (insn))
1434
        return "tst%.b %1";
1435
 
1436
      cc_status.flags = CC_NOT_NEGATIVE;
1437
    }
1438
  return "btst %0,%1";
1439
}
1440
 
1441
/* Legitimize PIC addresses.  If the address is already
1442
   position-independent, we return ORIG.  Newly generated
1443
   position-independent addresses go to REG.  If we need more
1444
   than one register, we lose.
1445
 
1446
   An address is legitimized by making an indirect reference
1447
   through the Global Offset Table with the name of the symbol
1448
   used as an offset.
1449
 
1450
   The assembler and linker are responsible for placing the
1451
   address of the symbol in the GOT.  The function prologue
1452
   is responsible for initializing a5 to the starting address
1453
   of the GOT.
1454
 
1455
   The assembler is also responsible for translating a symbol name
1456
   into a constant displacement from the start of the GOT.
1457
 
1458
   A quick example may make things a little clearer:
1459
 
1460
   When not generating PIC code to store the value 12345 into _foo
1461
   we would generate the following code:
1462
 
1463
        movel #12345, _foo
1464
 
1465
   When generating PIC two transformations are made.  First, the compiler
1466
   loads the address of foo into a register.  So the first transformation makes:
1467
 
1468
        lea     _foo, a0
1469
        movel   #12345, a0@
1470
 
1471
   The code in movsi will intercept the lea instruction and call this
1472
   routine which will transform the instructions into:
1473
 
1474
        movel   a5@(_foo:w), a0
1475
        movel   #12345, a0@
1476
 
1477
 
1478
   That (in a nutshell) is how *all* symbol and label references are
1479
   handled.  */
1480
 
1481
rtx
1482
legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
1483
                        rtx reg)
1484
{
1485
  rtx pic_ref = orig;
1486
 
1487
  /* First handle a simple SYMBOL_REF or LABEL_REF */
1488
  if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1489
    {
1490
      gcc_assert (reg);
1491
 
1492
      pic_ref = gen_rtx_MEM (Pmode,
1493
                             gen_rtx_PLUS (Pmode,
1494
                                           pic_offset_table_rtx, orig));
1495
      current_function_uses_pic_offset_table = 1;
1496
      MEM_READONLY_P (pic_ref) = 1;
1497
      emit_move_insn (reg, pic_ref);
1498
      return reg;
1499
    }
1500
  else if (GET_CODE (orig) == CONST)
1501
    {
1502
      rtx base;
1503
 
1504
      /* Make sure this has not already been legitimized.  */
1505
      if (GET_CODE (XEXP (orig, 0)) == PLUS
1506
          && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1507
        return orig;
1508
 
1509
      gcc_assert (reg);
1510
 
1511
      /* legitimize both operands of the PLUS */
1512
      gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
1513
 
1514
      base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1515
      orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1516
                                     base == reg ? 0 : reg);
1517
 
1518
      if (GET_CODE (orig) == CONST_INT)
1519
        return plus_constant (base, INTVAL (orig));
1520
      pic_ref = gen_rtx_PLUS (Pmode, base, orig);
1521
      /* Likewise, should we set special REG_NOTEs here?  */
1522
    }
1523
  return pic_ref;
1524
}
1525
 
1526
 
1527
typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ, MVS, MVZ } CONST_METHOD;
1528
 
1529
static CONST_METHOD const_method (rtx);
1530
 
1531
#define USE_MOVQ(i)     ((unsigned) ((i) + 128) <= 255)
1532
 
1533
static CONST_METHOD
1534
const_method (rtx constant)
1535
{
1536
  int i;
1537
  unsigned u;
1538
 
1539
  i = INTVAL (constant);
1540
  if (USE_MOVQ (i))
1541
    return MOVQ;
1542
 
1543
  /* The ColdFire doesn't have byte or word operations.  */
1544
  /* FIXME: This may not be useful for the m68060 either.  */
1545
  if (!TARGET_COLDFIRE)
1546
    {
1547
      /* if -256 < N < 256 but N is not in range for a moveq
1548
         N^ff will be, so use moveq #N^ff, dreg; not.b dreg.  */
1549
      if (USE_MOVQ (i ^ 0xff))
1550
        return NOTB;
1551
      /* Likewise, try with not.w */
1552
      if (USE_MOVQ (i ^ 0xffff))
1553
        return NOTW;
1554
      /* This is the only value where neg.w is useful */
1555
      if (i == -65408)
1556
        return NEGW;
1557
    }
1558
 
1559
  /* Try also with swap.  */
1560
  u = i;
1561
  if (USE_MOVQ ((u >> 16) | (u << 16)))
1562
    return SWAP;
1563
 
1564
  if (TARGET_CFV4)
1565
    {
1566
      /* Try using MVZ/MVS with an immediate value to load constants.  */
1567
      if (i >= 0 && i <= 65535)
1568
        return MVZ;
1569
      if (i >= -32768 && i <= 32767)
1570
        return MVS;
1571
    }
1572
 
1573
  /* Otherwise, use move.l */
1574
  return MOVL;
1575
}
1576
 
1577
static int
1578
const_int_cost (rtx constant)
1579
{
1580
  switch (const_method (constant))
1581
    {
1582
    case MOVQ:
1583
      /* Constants between -128 and 127 are cheap due to moveq.  */
1584
      return 0;
1585
    case MVZ:
1586
    case MVS:
1587
    case NOTB:
1588
    case NOTW:
1589
    case NEGW:
1590
    case SWAP:
1591
      /* Constants easily generated by moveq + not.b/not.w/neg.w/swap.  */
1592
      return 1;
1593
    case MOVL:
1594
      return 2;
1595
    default:
1596
      gcc_unreachable ();
1597
    }
1598
}
1599
 
1600
static bool
1601
m68k_rtx_costs (rtx x, int code, int outer_code, int *total)
1602
{
1603
  switch (code)
1604
    {
1605
    case CONST_INT:
1606
      /* Constant zero is super cheap due to clr instruction.  */
1607
      if (x == const0_rtx)
1608
        *total = 0;
1609
      else
1610
        *total = const_int_cost (x);
1611
      return true;
1612
 
1613
    case CONST:
1614
    case LABEL_REF:
1615
    case SYMBOL_REF:
1616
      *total = 3;
1617
      return true;
1618
 
1619
    case CONST_DOUBLE:
1620
      /* Make 0.0 cheaper than other floating constants to
1621
         encourage creating tstsf and tstdf insns.  */
1622
      if (outer_code == COMPARE
1623
          && (x == CONST0_RTX (SFmode) || x == CONST0_RTX (DFmode)))
1624
        *total = 4;
1625
      else
1626
        *total = 5;
1627
      return true;
1628
 
1629
    /* These are vaguely right for a 68020.  */
1630
    /* The costs for long multiply have been adjusted to work properly
1631
       in synth_mult on the 68020, relative to an average of the time
1632
       for add and the time for shift, taking away a little more because
1633
       sometimes move insns are needed.  */
1634
    /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS
1635
       terms.  */
1636
#define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5          \
1637
                   : (TARGET_COLDFIRE && !TARGET_5200) ? 3      \
1638
                   : TARGET_COLDFIRE ? 10 : 13)
1639
#define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 \
1640
                   : (TARGET_COLDFIRE && !TARGET_5200) ? 2 : 5)
1641
#define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12)
1642
 
1643
    case PLUS:
1644
      /* An lea costs about three times as much as a simple add.  */
1645
      if (GET_MODE (x) == SImode
1646
          && GET_CODE (XEXP (x, 1)) == REG
1647
          && GET_CODE (XEXP (x, 0)) == MULT
1648
          && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1649
          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1650
          && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
1651
              || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
1652
              || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
1653
        {
1654
            /* lea an@(dx:l:i),am */
1655
            *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);
1656
            return true;
1657
        }
1658
      return false;
1659
 
1660
    case ASHIFT:
1661
    case ASHIFTRT:
1662
    case LSHIFTRT:
1663
      if (TARGET_68060)
1664
        {
1665
          *total = COSTS_N_INSNS(1);
1666
          return true;
1667
        }
1668
      if (! TARGET_68020 && ! TARGET_COLDFIRE)
1669
        {
1670
          if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1671
            {
1672
              if (INTVAL (XEXP (x, 1)) < 16)
1673
                *total = COSTS_N_INSNS (2) + INTVAL (XEXP (x, 1)) / 2;
1674
              else
1675
                /* We're using clrw + swap for these cases.  */
1676
                *total = COSTS_N_INSNS (4) + (INTVAL (XEXP (x, 1)) - 16) / 2;
1677
            }
1678
          else
1679
            *total = COSTS_N_INSNS (10); /* Worst case.  */
1680
          return true;
1681
        }
1682
      /* A shift by a big integer takes an extra instruction.  */
1683
      if (GET_CODE (XEXP (x, 1)) == CONST_INT
1684
          && (INTVAL (XEXP (x, 1)) == 16))
1685
        {
1686
          *total = COSTS_N_INSNS (2);    /* clrw;swap */
1687
          return true;
1688
        }
1689
      if (GET_CODE (XEXP (x, 1)) == CONST_INT
1690
          && !(INTVAL (XEXP (x, 1)) > 0
1691
               && INTVAL (XEXP (x, 1)) <= 8))
1692
        {
1693
          *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 1 : 3);      /* lsr #i,dn */
1694
          return true;
1695
        }
1696
      return false;
1697
 
1698
    case MULT:
1699
      if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
1700
           || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
1701
          && GET_MODE (x) == SImode)
1702
        *total = COSTS_N_INSNS (MULW_COST);
1703
      else if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
1704
        *total = COSTS_N_INSNS (MULW_COST);
1705
      else
1706
        *total = COSTS_N_INSNS (MULL_COST);
1707
      return true;
1708
 
1709
    case DIV:
1710
    case UDIV:
1711
    case MOD:
1712
    case UMOD:
1713
      if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
1714
        *total = COSTS_N_INSNS (DIVW_COST);     /* div.w */
1715
      else if (TARGET_CF_HWDIV)
1716
        *total = COSTS_N_INSNS (18);
1717
      else
1718
        *total = COSTS_N_INSNS (43);            /* div.l */
1719
      return true;
1720
 
1721
    default:
1722
      return false;
1723
    }
1724
}
1725
 
1726
const char *
1727
output_move_const_into_data_reg (rtx *operands)
1728
{
1729
  int i;
1730
 
1731
  i = INTVAL (operands[1]);
1732
  switch (const_method (operands[1]))
1733
    {
1734
    case MVZ:
1735
      return "mvzw %1,%0";
1736
    case MVS:
1737
      return "mvsw %1,%0";
1738
    case MOVQ:
1739
      return "moveq %1,%0";
1740
    case NOTB:
1741
      CC_STATUS_INIT;
1742
      operands[1] = GEN_INT (i ^ 0xff);
1743
      return "moveq %1,%0\n\tnot%.b %0";
1744
    case NOTW:
1745
      CC_STATUS_INIT;
1746
      operands[1] = GEN_INT (i ^ 0xffff);
1747
      return "moveq %1,%0\n\tnot%.w %0";
1748
    case NEGW:
1749
      CC_STATUS_INIT;
1750
      return "moveq #-128,%0\n\tneg%.w %0";
1751
    case SWAP:
1752
      {
1753
        unsigned u = i;
1754
 
1755
        operands[1] = GEN_INT ((u << 16) | (u >> 16));
1756
        return "moveq %1,%0\n\tswap %0";
1757
      }
1758
    case MOVL:
1759
        return "move%.l %1,%0";
1760
    default:
1761
        gcc_unreachable ();
1762
    }
1763
}
1764
 
1765
/* Return 1 if 'constant' can be represented by
1766
   mov3q on a ColdFire V4 core.  */
1767
int
1768
valid_mov3q_const (rtx constant)
1769
{
1770
  int i;
1771
 
1772
  if (TARGET_CFV4 && GET_CODE (constant) == CONST_INT)
1773
    {
1774
      i = INTVAL (constant);
1775
      if (i == -1 || (i >= 1 && i <= 7))
1776
        return 1;
1777
    }
1778
  return 0;
1779
}
1780
 
1781
 
1782
const char *
1783
output_move_simode_const (rtx *operands)
1784
{
1785
  if (operands[1] == const0_rtx
1786
      && (DATA_REG_P (operands[0])
1787
          || GET_CODE (operands[0]) == MEM)
1788
      /* clr insns on 68000 read before writing.
1789
         This isn't so on the 68010, but we have no TARGET_68010.  */
1790
      && ((TARGET_68020 || TARGET_COLDFIRE)
1791
          || !(GET_CODE (operands[0]) == MEM
1792
               && MEM_VOLATILE_P (operands[0]))))
1793
    return "clr%.l %0";
1794
  else if ((GET_MODE (operands[0]) == SImode)
1795
           && valid_mov3q_const (operands[1]))
1796
    return "mov3q%.l %1,%0";
1797
  else if (operands[1] == const0_rtx
1798
           && ADDRESS_REG_P (operands[0]))
1799
    return "sub%.l %0,%0";
1800
  else if (DATA_REG_P (operands[0]))
1801
    return output_move_const_into_data_reg (operands);
1802
  else if (ADDRESS_REG_P (operands[0])
1803
           && INTVAL (operands[1]) < 0x8000
1804
           && INTVAL (operands[1]) >= -0x8000)
1805
    {
1806
      if (valid_mov3q_const (operands[1]))
1807
        return "mov3q%.l %1,%0";
1808
      return "move%.w %1,%0";
1809
    }
1810
  else if (GET_CODE (operands[0]) == MEM
1811
           && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1812
           && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1813
           && INTVAL (operands[1]) < 0x8000
1814
           && INTVAL (operands[1]) >= -0x8000)
1815
    {
1816
      if (valid_mov3q_const (operands[1]))
1817
        return "mov3q%.l %1,%-";
1818
      return "pea %a1";
1819
    }
1820
  return "move%.l %1,%0";
1821
}
1822
 
1823
const char *
1824
output_move_simode (rtx *operands)
1825
{
1826
  if (GET_CODE (operands[1]) == CONST_INT)
1827
    return output_move_simode_const (operands);
1828
  else if ((GET_CODE (operands[1]) == SYMBOL_REF
1829
            || GET_CODE (operands[1]) == CONST)
1830
           && push_operand (operands[0], SImode))
1831
    return "pea %a1";
1832
  else if ((GET_CODE (operands[1]) == SYMBOL_REF
1833
            || GET_CODE (operands[1]) == CONST)
1834
           && ADDRESS_REG_P (operands[0]))
1835
    return "lea %a1,%0";
1836
  return "move%.l %1,%0";
1837
}
1838
 
1839
const char *
1840
output_move_himode (rtx *operands)
1841
{
1842
 if (GET_CODE (operands[1]) == CONST_INT)
1843
    {
1844
      if (operands[1] == const0_rtx
1845
          && (DATA_REG_P (operands[0])
1846
              || GET_CODE (operands[0]) == MEM)
1847
          /* clr insns on 68000 read before writing.
1848
             This isn't so on the 68010, but we have no TARGET_68010.  */
1849
          && ((TARGET_68020 || TARGET_COLDFIRE)
1850
              || !(GET_CODE (operands[0]) == MEM
1851
                   && MEM_VOLATILE_P (operands[0]))))
1852
        return "clr%.w %0";
1853
      else if (operands[1] == const0_rtx
1854
               && ADDRESS_REG_P (operands[0]))
1855
        return "sub%.l %0,%0";
1856
      else if (DATA_REG_P (operands[0])
1857
               && INTVAL (operands[1]) < 128
1858
               && INTVAL (operands[1]) >= -128)
1859
        return "moveq %1,%0";
1860
      else if (INTVAL (operands[1]) < 0x8000
1861
               && INTVAL (operands[1]) >= -0x8000)
1862
        return "move%.w %1,%0";
1863
    }
1864
  else if (CONSTANT_P (operands[1]))
1865
    return "move%.l %1,%0";
1866
  /* Recognize the insn before a tablejump, one that refers
1867
     to a table of offsets.  Such an insn will need to refer
1868
     to a label on the insn.  So output one.  Use the label-number
1869
     of the table of offsets to generate this label.  This code,
1870
     and similar code below, assumes that there will be at most one
1871
     reference to each table.  */
1872
  if (GET_CODE (operands[1]) == MEM
1873
      && GET_CODE (XEXP (operands[1], 0)) == PLUS
1874
      && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
1875
      && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
1876
    {
1877
      rtx labelref = XEXP (XEXP (operands[1], 0), 1);
1878
      if (MOTOROLA)
1879
        asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
1880
                     CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1881
      else
1882
        (*targetm.asm_out.internal_label) (asm_out_file, "LI",
1883
                                           CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1884
    }
1885
  return "move%.w %1,%0";
1886
}
1887
 
1888
const char *
1889
output_move_qimode (rtx *operands)
1890
{
1891
  /* 68k family always modifies the stack pointer by at least 2, even for
1892
     byte pushes.  The 5200 (ColdFire) does not do this.  */
1893
 
1894
  /* This case is generated by pushqi1 pattern now.  */
1895
  gcc_assert (!(GET_CODE (operands[0]) == MEM
1896
                && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1897
                && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
1898
                && ! ADDRESS_REG_P (operands[1])
1899
                && ! TARGET_COLDFIRE));
1900
 
1901
  /* clr and st insns on 68000 read before writing.
1902
     This isn't so on the 68010, but we have no TARGET_68010.  */
1903
  if (!ADDRESS_REG_P (operands[0])
1904
      && ((TARGET_68020 || TARGET_COLDFIRE)
1905
          || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1906
    {
1907
      if (operands[1] == const0_rtx)
1908
        return "clr%.b %0";
1909
      if ((!TARGET_COLDFIRE || DATA_REG_P (operands[0]))
1910
          && GET_CODE (operands[1]) == CONST_INT
1911
          && (INTVAL (operands[1]) & 255) == 255)
1912
        {
1913
          CC_STATUS_INIT;
1914
          return "st %0";
1915
        }
1916
    }
1917
  if (GET_CODE (operands[1]) == CONST_INT
1918
      && DATA_REG_P (operands[0])
1919
      && INTVAL (operands[1]) < 128
1920
      && INTVAL (operands[1]) >= -128)
1921
    return "moveq %1,%0";
1922
  if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
1923
    return "sub%.l %0,%0";
1924
  if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
1925
    return "move%.l %1,%0";
1926
  /* 68k family (including the 5200 ColdFire) does not support byte moves to
1927
     from address registers.  */
1928
  if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
1929
    return "move%.w %1,%0";
1930
  return "move%.b %1,%0";
1931
}
1932
 
1933
const char *
1934
output_move_stricthi (rtx *operands)
1935
{
1936
  if (operands[1] == const0_rtx
1937
      /* clr insns on 68000 read before writing.
1938
         This isn't so on the 68010, but we have no TARGET_68010.  */
1939
      && ((TARGET_68020 || TARGET_COLDFIRE)
1940
          || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1941
    return "clr%.w %0";
1942
  return "move%.w %1,%0";
1943
}
1944
 
1945
const char *
1946
output_move_strictqi (rtx *operands)
1947
{
1948
  if (operands[1] == const0_rtx
1949
      /* clr insns on 68000 read before writing.
1950
         This isn't so on the 68010, but we have no TARGET_68010.  */
1951
      && ((TARGET_68020 || TARGET_COLDFIRE)
1952
          || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1953
    return "clr%.b %0";
1954
  return "move%.b %1,%0";
1955
}
1956
 
1957
/* Return the best assembler insn template
1958
   for moving operands[1] into operands[0] as a fullword.  */
1959
 
1960
static const char *
1961
singlemove_string (rtx *operands)
1962
{
1963
  if (GET_CODE (operands[1]) == CONST_INT)
1964
    return output_move_simode_const (operands);
1965
  return "move%.l %1,%0";
1966
}
1967
 
1968
 
1969
/* Output assembler code to perform a doubleword move insn
1970
   with operands OPERANDS.  */
1971
 
1972
const char *
1973
output_move_double (rtx *operands)
1974
{
1975
  enum
1976
    {
1977
      REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
1978
    } optype0, optype1;
1979
  rtx latehalf[2];
1980
  rtx middlehalf[2];
1981
  rtx xops[2];
1982
  rtx addreg0 = 0, addreg1 = 0;
1983
  int dest_overlapped_low = 0;
1984
  int size = GET_MODE_SIZE (GET_MODE (operands[0]));
1985
 
1986
  middlehalf[0] = 0;
1987
  middlehalf[1] = 0;
1988
 
1989
  /* First classify both operands.  */
1990
 
1991
  if (REG_P (operands[0]))
1992
    optype0 = REGOP;
1993
  else if (offsettable_memref_p (operands[0]))
1994
    optype0 = OFFSOP;
1995
  else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1996
    optype0 = POPOP;
1997
  else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1998
    optype0 = PUSHOP;
1999
  else if (GET_CODE (operands[0]) == MEM)
2000
    optype0 = MEMOP;
2001
  else
2002
    optype0 = RNDOP;
2003
 
2004
  if (REG_P (operands[1]))
2005
    optype1 = REGOP;
2006
  else if (CONSTANT_P (operands[1]))
2007
    optype1 = CNSTOP;
2008
  else if (offsettable_memref_p (operands[1]))
2009
    optype1 = OFFSOP;
2010
  else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
2011
    optype1 = POPOP;
2012
  else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2013
    optype1 = PUSHOP;
2014
  else if (GET_CODE (operands[1]) == MEM)
2015
    optype1 = MEMOP;
2016
  else
2017
    optype1 = RNDOP;
2018
 
2019
  /* Check for the cases that the operand constraints are not supposed
2020
     to allow to happen.  Generating code for these cases is
2021
     painful.  */
2022
  gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
2023
 
2024
  /* If one operand is decrementing and one is incrementing
2025
     decrement the former register explicitly
2026
     and change that operand into ordinary indexing.  */
2027
 
2028
  if (optype0 == PUSHOP && optype1 == POPOP)
2029
    {
2030
      operands[0] = XEXP (XEXP (operands[0], 0), 0);
2031
      if (size == 12)
2032
        output_asm_insn ("sub%.l #12,%0", operands);
2033
      else
2034
        output_asm_insn ("subq%.l #8,%0", operands);
2035
      if (GET_MODE (operands[1]) == XFmode)
2036
        operands[0] = gen_rtx_MEM (XFmode, operands[0]);
2037
      else if (GET_MODE (operands[0]) == DFmode)
2038
        operands[0] = gen_rtx_MEM (DFmode, operands[0]);
2039
      else
2040
        operands[0] = gen_rtx_MEM (DImode, operands[0]);
2041
      optype0 = OFFSOP;
2042
    }
2043
  if (optype0 == POPOP && optype1 == PUSHOP)
2044
    {
2045
      operands[1] = XEXP (XEXP (operands[1], 0), 0);
2046
      if (size == 12)
2047
        output_asm_insn ("sub%.l #12,%1", operands);
2048
      else
2049
        output_asm_insn ("subq%.l #8,%1", operands);
2050
      if (GET_MODE (operands[1]) == XFmode)
2051
        operands[1] = gen_rtx_MEM (XFmode, operands[1]);
2052
      else if (GET_MODE (operands[1]) == DFmode)
2053
        operands[1] = gen_rtx_MEM (DFmode, operands[1]);
2054
      else
2055
        operands[1] = gen_rtx_MEM (DImode, operands[1]);
2056
      optype1 = OFFSOP;
2057
    }
2058
 
2059
  /* If an operand is an unoffsettable memory ref, find a register
2060
     we can increment temporarily to make it refer to the second word.  */
2061
 
2062
  if (optype0 == MEMOP)
2063
    addreg0 = find_addr_reg (XEXP (operands[0], 0));
2064
 
2065
  if (optype1 == MEMOP)
2066
    addreg1 = find_addr_reg (XEXP (operands[1], 0));
2067
 
2068
  /* Ok, we can do one word at a time.
2069
     Normally we do the low-numbered word first,
2070
     but if either operand is autodecrementing then we
2071
     do the high-numbered word first.
2072
 
2073
     In either case, set up in LATEHALF the operands to use
2074
     for the high-numbered word and in some cases alter the
2075
     operands in OPERANDS to be suitable for the low-numbered word.  */
2076
 
2077
  if (size == 12)
2078
    {
2079
      if (optype0 == REGOP)
2080
        {
2081
          latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2082
          middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2083
        }
2084
      else if (optype0 == OFFSOP)
2085
        {
2086
          middlehalf[0] = adjust_address (operands[0], SImode, 4);
2087
          latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2088
        }
2089
      else
2090
        {
2091
          middlehalf[0] = operands[0];
2092
          latehalf[0] = operands[0];
2093
        }
2094
 
2095
      if (optype1 == REGOP)
2096
        {
2097
          latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2098
          middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2099
        }
2100
      else if (optype1 == OFFSOP)
2101
        {
2102
          middlehalf[1] = adjust_address (operands[1], SImode, 4);
2103
          latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2104
        }
2105
      else if (optype1 == CNSTOP)
2106
        {
2107
          if (GET_CODE (operands[1]) == CONST_DOUBLE)
2108
            {
2109
              REAL_VALUE_TYPE r;
2110
              long l[3];
2111
 
2112
              REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2113
              REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
2114
              operands[1] = GEN_INT (l[0]);
2115
              middlehalf[1] = GEN_INT (l[1]);
2116
              latehalf[1] = GEN_INT (l[2]);
2117
            }
2118
          else
2119
            {
2120
              /* No non-CONST_DOUBLE constant should ever appear
2121
                 here.  */
2122
              gcc_assert (!CONSTANT_P (operands[1]));
2123
            }
2124
        }
2125
      else
2126
        {
2127
          middlehalf[1] = operands[1];
2128
          latehalf[1] = operands[1];
2129
        }
2130
    }
2131
  else
2132
    /* size is not 12: */
2133
    {
2134
      if (optype0 == REGOP)
2135
        latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2136
      else if (optype0 == OFFSOP)
2137
        latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2138
      else
2139
        latehalf[0] = operands[0];
2140
 
2141
      if (optype1 == REGOP)
2142
        latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2143
      else if (optype1 == OFFSOP)
2144
        latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2145
      else if (optype1 == CNSTOP)
2146
        split_double (operands[1], &operands[1], &latehalf[1]);
2147
      else
2148
        latehalf[1] = operands[1];
2149
    }
2150
 
2151
  /* If insn is effectively movd N(sp),-(sp) then we will do the
2152
     high word first.  We should use the adjusted operand 1 (which is N+4(sp))
2153
     for the low word as well, to compensate for the first decrement of sp.  */
2154
  if (optype0 == PUSHOP
2155
      && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
2156
      && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
2157
    operands[1] = middlehalf[1] = latehalf[1];
2158
 
2159
  /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2160
     if the upper part of reg N does not appear in the MEM, arrange to
2161
     emit the move late-half first.  Otherwise, compute the MEM address
2162
     into the upper part of N and use that as a pointer to the memory
2163
     operand.  */
2164
  if (optype0 == REGOP
2165
      && (optype1 == OFFSOP || optype1 == MEMOP))
2166
    {
2167
      rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
2168
 
2169
      if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2170
          && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2171
        {
2172
          /* If both halves of dest are used in the src memory address,
2173
             compute the address into latehalf of dest.
2174
             Note that this can't happen if the dest is two data regs.  */
2175
        compadr:
2176
          xops[0] = latehalf[0];
2177
          xops[1] = XEXP (operands[1], 0);
2178
          output_asm_insn ("lea %a1,%0", xops);
2179
          if (GET_MODE (operands[1]) == XFmode )
2180
            {
2181
              operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
2182
              middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
2183
              latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2184
            }
2185
          else
2186
            {
2187
              operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
2188
              latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2189
            }
2190
        }
2191
      else if (size == 12
2192
               && reg_overlap_mentioned_p (middlehalf[0],
2193
                                           XEXP (operands[1], 0)))
2194
        {
2195
          /* Check for two regs used by both source and dest.
2196
             Note that this can't happen if the dest is all data regs.
2197
             It can happen if the dest is d6, d7, a0.
2198
             But in that case, latehalf is an addr reg, so
2199
             the code at compadr does ok.  */
2200
 
2201
          if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2202
              || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2203
            goto compadr;
2204
 
2205
          /* JRV says this can't happen: */
2206
          gcc_assert (!addreg0 && !addreg1);
2207
 
2208
          /* Only the middle reg conflicts; simply put it last.  */
2209
          output_asm_insn (singlemove_string (operands), operands);
2210
          output_asm_insn (singlemove_string (latehalf), latehalf);
2211
          output_asm_insn (singlemove_string (middlehalf), middlehalf);
2212
          return "";
2213
        }
2214
      else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
2215
        /* If the low half of dest is mentioned in the source memory
2216
           address, the arrange to emit the move late half first.  */
2217
        dest_overlapped_low = 1;
2218
    }
2219
 
2220
  /* If one or both operands autodecrementing,
2221
     do the two words, high-numbered first.  */
2222
 
2223
  /* Likewise,  the first move would clobber the source of the second one,
2224
     do them in the other order.  This happens only for registers;
2225
     such overlap can't happen in memory unless the user explicitly
2226
     sets it up, and that is an undefined circumstance.  */
2227
 
2228
  if (optype0 == PUSHOP || optype1 == PUSHOP
2229
      || (optype0 == REGOP && optype1 == REGOP
2230
          && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
2231
              || REGNO (operands[0]) == REGNO (latehalf[1])))
2232
      || dest_overlapped_low)
2233
    {
2234
      /* Make any unoffsettable addresses point at high-numbered word.  */
2235
      if (addreg0)
2236
        {
2237
          if (size == 12)
2238
            output_asm_insn ("addq%.l #8,%0", &addreg0);
2239
          else
2240
            output_asm_insn ("addq%.l #4,%0", &addreg0);
2241
        }
2242
      if (addreg1)
2243
        {
2244
          if (size == 12)
2245
            output_asm_insn ("addq%.l #8,%0", &addreg1);
2246
          else
2247
            output_asm_insn ("addq%.l #4,%0", &addreg1);
2248
        }
2249
 
2250
      /* Do that word.  */
2251
      output_asm_insn (singlemove_string (latehalf), latehalf);
2252
 
2253
      /* Undo the adds we just did.  */
2254
      if (addreg0)
2255
        output_asm_insn ("subq%.l #4,%0", &addreg0);
2256
      if (addreg1)
2257
        output_asm_insn ("subq%.l #4,%0", &addreg1);
2258
 
2259
      if (size == 12)
2260
        {
2261
          output_asm_insn (singlemove_string (middlehalf), middlehalf);
2262
          if (addreg0)
2263
            output_asm_insn ("subq%.l #4,%0", &addreg0);
2264
          if (addreg1)
2265
            output_asm_insn ("subq%.l #4,%0", &addreg1);
2266
        }
2267
 
2268
      /* Do low-numbered word.  */
2269
      return singlemove_string (operands);
2270
    }
2271
 
2272
  /* Normal case: do the two words, low-numbered first.  */
2273
 
2274
  output_asm_insn (singlemove_string (operands), operands);
2275
 
2276
  /* Do the middle one of the three words for long double */
2277
  if (size == 12)
2278
    {
2279
      if (addreg0)
2280
        output_asm_insn ("addq%.l #4,%0", &addreg0);
2281
      if (addreg1)
2282
        output_asm_insn ("addq%.l #4,%0", &addreg1);
2283
 
2284
      output_asm_insn (singlemove_string (middlehalf), middlehalf);
2285
    }
2286
 
2287
  /* Make any unoffsettable addresses point at high-numbered word.  */
2288
  if (addreg0)
2289
    output_asm_insn ("addq%.l #4,%0", &addreg0);
2290
  if (addreg1)
2291
    output_asm_insn ("addq%.l #4,%0", &addreg1);
2292
 
2293
  /* Do that word.  */
2294
  output_asm_insn (singlemove_string (latehalf), latehalf);
2295
 
2296
  /* Undo the adds we just did.  */
2297
  if (addreg0)
2298
    {
2299
      if (size == 12)
2300
        output_asm_insn ("subq%.l #8,%0", &addreg0);
2301
      else
2302
        output_asm_insn ("subq%.l #4,%0", &addreg0);
2303
    }
2304
  if (addreg1)
2305
    {
2306
      if (size == 12)
2307
        output_asm_insn ("subq%.l #8,%0", &addreg1);
2308
      else
2309
        output_asm_insn ("subq%.l #4,%0", &addreg1);
2310
    }
2311
 
2312
  return "";
2313
}
2314
 
2315
 
2316
/* Ensure mode of ORIG, a REG rtx, is MODE.  Returns either ORIG or a
2317
   new rtx with the correct mode.  */
2318
 
2319
static rtx
2320
force_mode (enum machine_mode mode, rtx orig)
2321
{
2322
  if (mode == GET_MODE (orig))
2323
    return orig;
2324
 
2325
  if (REGNO (orig) >= FIRST_PSEUDO_REGISTER)
2326
    abort ();
2327
 
2328
  return gen_rtx_REG (mode, REGNO (orig));
2329
}
2330
 
2331
static int
2332
fp_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2333
{
2334
  return reg_renumber && FP_REG_P (op);
2335
}
2336
 
2337
/* Emit insns to move operands[1] into operands[0].
2338
 
2339
   Return 1 if we have written out everything that needs to be done to
2340
   do the move.  Otherwise, return 0 and the caller will emit the move
2341
   normally.
2342
 
2343
   Note SCRATCH_REG may not be in the proper mode depending on how it
2344
   will be used.  This routine is responsible for creating a new copy
2345
   of SCRATCH_REG in the proper mode.  */
2346
 
2347
int
2348
emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
2349
{
2350
  register rtx operand0 = operands[0];
2351
  register rtx operand1 = operands[1];
2352
  register rtx tem;
2353
 
2354
  if (scratch_reg
2355
      && reload_in_progress && GET_CODE (operand0) == REG
2356
      && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
2357
    operand0 = reg_equiv_mem[REGNO (operand0)];
2358
  else if (scratch_reg
2359
           && reload_in_progress && GET_CODE (operand0) == SUBREG
2360
           && GET_CODE (SUBREG_REG (operand0)) == REG
2361
           && REGNO (SUBREG_REG (operand0)) >= FIRST_PSEUDO_REGISTER)
2362
    {
2363
     /* We must not alter SUBREG_BYTE (operand0) since that would confuse
2364
        the code which tracks sets/uses for delete_output_reload.  */
2365
      rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
2366
                                 reg_equiv_mem [REGNO (SUBREG_REG (operand0))],
2367
                                 SUBREG_BYTE (operand0));
2368
      operand0 = alter_subreg (&temp);
2369
    }
2370
 
2371
  if (scratch_reg
2372
      && reload_in_progress && GET_CODE (operand1) == REG
2373
      && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
2374
    operand1 = reg_equiv_mem[REGNO (operand1)];
2375
  else if (scratch_reg
2376
           && reload_in_progress && GET_CODE (operand1) == SUBREG
2377
           && GET_CODE (SUBREG_REG (operand1)) == REG
2378
           && REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)
2379
    {
2380
     /* We must not alter SUBREG_BYTE (operand0) since that would confuse
2381
        the code which tracks sets/uses for delete_output_reload.  */
2382
      rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
2383
                                 reg_equiv_mem [REGNO (SUBREG_REG (operand1))],
2384
                                 SUBREG_BYTE (operand1));
2385
      operand1 = alter_subreg (&temp);
2386
    }
2387
 
2388
  if (scratch_reg && reload_in_progress && GET_CODE (operand0) == MEM
2389
      && ((tem = find_replacement (&XEXP (operand0, 0)))
2390
          != XEXP (operand0, 0)))
2391
    operand0 = gen_rtx_MEM (GET_MODE (operand0), tem);
2392
  if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM
2393
      && ((tem = find_replacement (&XEXP (operand1, 0)))
2394
          != XEXP (operand1, 0)))
2395
    operand1 = gen_rtx_MEM (GET_MODE (operand1), tem);
2396
 
2397
  /* Handle secondary reloads for loads/stores of FP registers where
2398
     the address is symbolic by using the scratch register */
2399
  if (fp_reg_operand (operand0, mode)
2400
      && ((GET_CODE (operand1) == MEM
2401
           && ! memory_address_p (DFmode, XEXP (operand1, 0)))
2402
          || ((GET_CODE (operand1) == SUBREG
2403
               && GET_CODE (XEXP (operand1, 0)) == MEM
2404
               && !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
2405
      && scratch_reg)
2406
    {
2407
      if (GET_CODE (operand1) == SUBREG)
2408
        operand1 = XEXP (operand1, 0);
2409
 
2410
      /* SCRATCH_REG will hold an address.  We want
2411
         it in SImode regardless of what mode it was originally given
2412
         to us.  */
2413
      scratch_reg = force_mode (SImode, scratch_reg);
2414
 
2415
      /* D might not fit in 14 bits either; for such cases load D into
2416
         scratch reg.  */
2417
      if (!memory_address_p (Pmode, XEXP (operand1, 0)))
2418
        {
2419
          emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
2420
          emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1, 0)),
2421
                                                       Pmode,
2422
                                                       XEXP (XEXP (operand1, 0), 0),
2423
                                                       scratch_reg));
2424
        }
2425
      else
2426
        emit_move_insn (scratch_reg, XEXP (operand1, 0));
2427
      emit_insn (gen_rtx_SET (VOIDmode, operand0,
2428
                              gen_rtx_MEM (mode, scratch_reg)));
2429
      return 1;
2430
    }
2431
  else if (fp_reg_operand (operand1, mode)
2432
           && ((GET_CODE (operand0) == MEM
2433
                && ! memory_address_p (DFmode, XEXP (operand0, 0)))
2434
               || ((GET_CODE (operand0) == SUBREG)
2435
                   && GET_CODE (XEXP (operand0, 0)) == MEM
2436
                   && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
2437
           && scratch_reg)
2438
    {
2439
      if (GET_CODE (operand0) == SUBREG)
2440
        operand0 = XEXP (operand0, 0);
2441
 
2442
      /* SCRATCH_REG will hold an address and maybe the actual data.  We want
2443
         it in SIMODE regardless of what mode it was originally given
2444
         to us.  */
2445
      scratch_reg = force_mode (SImode, scratch_reg);
2446
 
2447
      /* D might not fit in 14 bits either; for such cases load D into
2448
         scratch reg.  */
2449
      if (!memory_address_p (Pmode, XEXP (operand0, 0)))
2450
        {
2451
          emit_move_insn (scratch_reg, XEXP (XEXP (operand0, 0), 1));
2452
          emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand0,
2453
                                                                        0)),
2454
                                                       Pmode,
2455
                                                       XEXP (XEXP (operand0, 0),
2456
                                                                   0),
2457
                                                       scratch_reg));
2458
        }
2459
      else
2460
        emit_move_insn (scratch_reg, XEXP (operand0, 0));
2461
      emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (mode, scratch_reg),
2462
                              operand1));
2463
      return 1;
2464
    }
2465
  /* Handle secondary reloads for loads of FP registers from constant
2466
     expressions by forcing the constant into memory.
2467
 
2468
     use scratch_reg to hold the address of the memory location.
2469
 
2470
     The proper fix is to change PREFERRED_RELOAD_CLASS to return
2471
     NO_REGS when presented with a const_int and an register class
2472
     containing only FP registers.  Doing so unfortunately creates
2473
     more problems than it solves.   Fix this for 2.5.  */
2474
  else if (fp_reg_operand (operand0, mode)
2475
           && CONSTANT_P (operand1)
2476
           && scratch_reg)
2477
    {
2478
      rtx xoperands[2];
2479
 
2480
      /* SCRATCH_REG will hold an address and maybe the actual data.  We want
2481
         it in SIMODE regardless of what mode it was originally given
2482
         to us.  */
2483
      scratch_reg = force_mode (SImode, scratch_reg);
2484
 
2485
      /* Force the constant into memory and put the address of the
2486
         memory location into scratch_reg.  */
2487
      xoperands[0] = scratch_reg;
2488
      xoperands[1] = XEXP (force_const_mem (mode, operand1), 0);
2489
      emit_insn (gen_rtx_SET (mode, scratch_reg, xoperands[1]));
2490
 
2491
      /* Now load the destination register.  */
2492
      emit_insn (gen_rtx_SET (mode, operand0,
2493
                              gen_rtx_MEM (mode, scratch_reg)));
2494
      return 1;
2495
    }
2496
 
2497
  /* Now have insn-emit do whatever it normally does.  */
2498
  return 0;
2499
}
2500
 
2501
/* Return a REG that occurs in ADDR with coefficient 1.
2502
   ADDR can be effectively incremented by incrementing REG.  */
2503
 
2504
static rtx
2505
find_addr_reg (rtx addr)
2506
{
2507
  while (GET_CODE (addr) == PLUS)
2508
    {
2509
      if (GET_CODE (XEXP (addr, 0)) == REG)
2510
        addr = XEXP (addr, 0);
2511
      else if (GET_CODE (XEXP (addr, 1)) == REG)
2512
        addr = XEXP (addr, 1);
2513
      else if (CONSTANT_P (XEXP (addr, 0)))
2514
        addr = XEXP (addr, 1);
2515
      else if (CONSTANT_P (XEXP (addr, 1)))
2516
        addr = XEXP (addr, 0);
2517
      else
2518
        gcc_unreachable ();
2519
    }
2520
  gcc_assert (GET_CODE (addr) == REG);
2521
  return addr;
2522
}
2523
 
2524
/* Output assembler code to perform a 32-bit 3-operand add.  */
2525
 
2526
const char *
2527
output_addsi3 (rtx *operands)
2528
{
2529
  if (! operands_match_p (operands[0], operands[1]))
2530
    {
2531
      if (!ADDRESS_REG_P (operands[1]))
2532
        {
2533
          rtx tmp = operands[1];
2534
 
2535
          operands[1] = operands[2];
2536
          operands[2] = tmp;
2537
        }
2538
 
2539
      /* These insns can result from reloads to access
2540
         stack slots over 64k from the frame pointer.  */
2541
      if (GET_CODE (operands[2]) == CONST_INT
2542
          && (INTVAL (operands[2]) < -32768 || INTVAL (operands[2]) > 32767))
2543
        return "move%.l %2,%0\n\tadd%.l %1,%0";
2544
      if (GET_CODE (operands[2]) == REG)
2545
        return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
2546
      return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
2547
    }
2548
  if (GET_CODE (operands[2]) == CONST_INT)
2549
    {
2550
      if (INTVAL (operands[2]) > 0
2551
          && INTVAL (operands[2]) <= 8)
2552
        return "addq%.l %2,%0";
2553
      if (INTVAL (operands[2]) < 0
2554
          && INTVAL (operands[2]) >= -8)
2555
        {
2556
          operands[2] = GEN_INT (- INTVAL (operands[2]));
2557
          return "subq%.l %2,%0";
2558
        }
2559
      /* On the CPU32 it is faster to use two addql instructions to
2560
         add a small integer (8 < N <= 16) to a register.
2561
         Likewise for subql.  */
2562
      if (TARGET_CPU32 && REG_P (operands[0]))
2563
        {
2564
          if (INTVAL (operands[2]) > 8
2565
              && INTVAL (operands[2]) <= 16)
2566
            {
2567
              operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2568
              return "addq%.l #8,%0\n\taddq%.l %2,%0";
2569
            }
2570
          if (INTVAL (operands[2]) < -8
2571
              && INTVAL (operands[2]) >= -16)
2572
            {
2573
              operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2574
              return "subq%.l #8,%0\n\tsubq%.l %2,%0";
2575
            }
2576
        }
2577
      if (ADDRESS_REG_P (operands[0])
2578
          && INTVAL (operands[2]) >= -0x8000
2579
          && INTVAL (operands[2]) < 0x8000)
2580
        {
2581
          if (TARGET_68040)
2582
            return "add%.w %2,%0";
2583
          else
2584
            return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
2585
        }
2586
    }
2587
  return "add%.l %2,%0";
2588
}
2589
 
2590
/* Store in cc_status the expressions that the condition codes will
2591
   describe after execution of an instruction whose pattern is EXP.
2592
   Do not alter them if the instruction would not alter the cc's.  */
2593
 
2594
/* On the 68000, all the insns to store in an address register fail to
2595
   set the cc's.  However, in some cases these instructions can make it
2596
   possibly invalid to use the saved cc's.  In those cases we clear out
2597
   some or all of the saved cc's so they won't be used.  */
2598
 
2599
void
2600
notice_update_cc (rtx exp, rtx insn)
2601
{
2602
  if (GET_CODE (exp) == SET)
2603
    {
2604
      if (GET_CODE (SET_SRC (exp)) == CALL)
2605
        CC_STATUS_INIT;
2606
      else if (ADDRESS_REG_P (SET_DEST (exp)))
2607
        {
2608
          if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
2609
            cc_status.value1 = 0;
2610
          if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
2611
            cc_status.value2 = 0;
2612
        }
2613
      else if (!FP_REG_P (SET_DEST (exp))
2614
               && SET_DEST (exp) != cc0_rtx
2615
               && (FP_REG_P (SET_SRC (exp))
2616
                   || GET_CODE (SET_SRC (exp)) == FIX
2617
                   || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
2618
                   || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
2619
        CC_STATUS_INIT;
2620
      /* A pair of move insns doesn't produce a useful overall cc.  */
2621
      else if (!FP_REG_P (SET_DEST (exp))
2622
               && !FP_REG_P (SET_SRC (exp))
2623
               && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
2624
               && (GET_CODE (SET_SRC (exp)) == REG
2625
                   || GET_CODE (SET_SRC (exp)) == MEM
2626
                   || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
2627
        CC_STATUS_INIT;
2628
      else if (SET_DEST (exp) != pc_rtx)
2629
        {
2630
          cc_status.flags = 0;
2631
          cc_status.value1 = SET_DEST (exp);
2632
          cc_status.value2 = SET_SRC (exp);
2633
        }
2634
    }
2635
  else if (GET_CODE (exp) == PARALLEL
2636
           && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2637
    {
2638
      rtx dest = SET_DEST (XVECEXP (exp, 0, 0));
2639
      rtx src  = SET_SRC  (XVECEXP (exp, 0, 0));
2640
 
2641
      if (ADDRESS_REG_P (dest))
2642
        CC_STATUS_INIT;
2643
      else if (dest != pc_rtx)
2644
        {
2645
          cc_status.flags = 0;
2646
          cc_status.value1 = dest;
2647
          cc_status.value2 = src;
2648
        }
2649
    }
2650
  else
2651
    CC_STATUS_INIT;
2652
  if (cc_status.value2 != 0
2653
      && ADDRESS_REG_P (cc_status.value2)
2654
      && GET_MODE (cc_status.value2) == QImode)
2655
    CC_STATUS_INIT;
2656
  if (cc_status.value2 != 0)
2657
    switch (GET_CODE (cc_status.value2))
2658
      {
2659
      case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2660
      case ROTATE: case ROTATERT:
2661
        /* These instructions always clear the overflow bit, and set
2662
           the carry to the bit shifted out.  */
2663
        /* ??? We don't currently have a way to signal carry not valid,
2664
           nor do we check for it in the branch insns.  */
2665
        CC_STATUS_INIT;
2666
        break;
2667
 
2668
      case PLUS: case MINUS: case MULT:
2669
      case DIV: case UDIV: case MOD: case UMOD: case NEG:
2670
        if (GET_MODE (cc_status.value2) != VOIDmode)
2671
          cc_status.flags |= CC_NO_OVERFLOW;
2672
        break;
2673
      case ZERO_EXTEND:
2674
        /* (SET r1 (ZERO_EXTEND r2)) on this machine
2675
           ends with a move insn moving r2 in r2's mode.
2676
           Thus, the cc's are set for r2.
2677
           This can set N bit spuriously.  */
2678
        cc_status.flags |= CC_NOT_NEGATIVE;
2679
 
2680
      default:
2681
        break;
2682
      }
2683
  if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
2684
      && cc_status.value2
2685
      && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
2686
    cc_status.value2 = 0;
2687
  if (((cc_status.value1 && FP_REG_P (cc_status.value1))
2688
       || (cc_status.value2 && FP_REG_P (cc_status.value2))))
2689
    cc_status.flags = CC_IN_68881;
2690
}
2691
 
2692
const char *
2693
output_move_const_double (rtx *operands)
2694
{
2695
  int code = standard_68881_constant_p (operands[1]);
2696
 
2697
  if (code != 0)
2698
    {
2699
      static char buf[40];
2700
 
2701
      sprintf (buf, "fmovecr #0x%x,%%0", code & 0xff);
2702
      return buf;
2703
    }
2704
  return "fmove%.d %1,%0";
2705
}
2706
 
2707
const char *
2708
output_move_const_single (rtx *operands)
2709
{
2710
  int code = standard_68881_constant_p (operands[1]);
2711
 
2712
  if (code != 0)
2713
    {
2714
      static char buf[40];
2715
 
2716
      sprintf (buf, "fmovecr #0x%x,%%0", code & 0xff);
2717
      return buf;
2718
    }
2719
  return "fmove%.s %f1,%0";
2720
}
2721
 
2722
/* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2723
   from the "fmovecr" instruction.
2724
   The value, anded with 0xff, gives the code to use in fmovecr
2725
   to get the desired constant.  */
2726
 
2727
/* This code has been fixed for cross-compilation.  */
2728
 
2729
static int inited_68881_table = 0;
2730
 
2731
static const char *const strings_68881[7] = {
2732
  "0.0",
2733
  "1.0",
2734
  "10.0",
2735
  "100.0",
2736
  "10000.0",
2737
  "1e8",
2738
  "1e16"
2739
};
2740
 
2741
static const int codes_68881[7] = {
2742
  0x0f,
2743
  0x32,
2744
  0x33,
2745
  0x34,
2746
  0x35,
2747
  0x36,
2748
  0x37
2749
};
2750
 
2751
REAL_VALUE_TYPE values_68881[7];
2752
 
2753
/* Set up values_68881 array by converting the decimal values
2754
   strings_68881 to binary.  */
2755
 
2756
void
2757
init_68881_table (void)
2758
{
2759
  int i;
2760
  REAL_VALUE_TYPE r;
2761
  enum machine_mode mode;
2762
 
2763
  mode = SFmode;
2764
  for (i = 0; i < 7; i++)
2765
    {
2766
      if (i == 6)
2767
        mode = DFmode;
2768
      r = REAL_VALUE_ATOF (strings_68881[i], mode);
2769
      values_68881[i] = r;
2770
    }
2771
  inited_68881_table = 1;
2772
}
2773
 
2774
int
2775
standard_68881_constant_p (rtx x)
2776
{
2777
  REAL_VALUE_TYPE r;
2778
  int i;
2779
 
2780
  /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2781
     used at all on those chips.  */
2782
  if (TARGET_68040 || TARGET_68060)
2783
    return 0;
2784
 
2785
  if (! inited_68881_table)
2786
    init_68881_table ();
2787
 
2788
  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2789
 
2790
  /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2791
     is rejected.  */
2792
  for (i = 0; i < 6; i++)
2793
    {
2794
      if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
2795
        return (codes_68881[i]);
2796
    }
2797
 
2798
  if (GET_MODE (x) == SFmode)
2799
    return 0;
2800
 
2801
  if (REAL_VALUES_EQUAL (r, values_68881[6]))
2802
    return (codes_68881[6]);
2803
 
2804
  /* larger powers of ten in the constants ram are not used
2805
     because they are not equal to a `double' C constant.  */
2806
  return 0;
2807
}
2808
 
2809
/* If X is a floating-point constant, return the logarithm of X base 2,
2810
   or 0 if X is not a power of 2.  */
2811
 
2812
int
2813
floating_exact_log2 (rtx x)
2814
{
2815
  REAL_VALUE_TYPE r, r1;
2816
  int exp;
2817
 
2818
  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2819
 
2820
  if (REAL_VALUES_LESS (r, dconst1))
2821
    return 0;
2822
 
2823
  exp = real_exponent (&r);
2824
  real_2expN (&r1, exp);
2825
  if (REAL_VALUES_EQUAL (r1, r))
2826
    return exp;
2827
 
2828
  return 0;
2829
}
2830
 
2831
/* A C compound statement to output to stdio stream STREAM the
2832
   assembler syntax for an instruction operand X.  X is an RTL
2833
   expression.
2834
 
2835
   CODE is a value that can be used to specify one of several ways
2836
   of printing the operand.  It is used when identical operands
2837
   must be printed differently depending on the context.  CODE
2838
   comes from the `%' specification that was used to request
2839
   printing of the operand.  If the specification was just `%DIGIT'
2840
   then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2841
   is the ASCII code for LTR.
2842
 
2843
   If X is a register, this macro should print the register's name.
2844
   The names can be found in an array `reg_names' whose type is
2845
   `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
2846
 
2847
   When the machine description has a specification `%PUNCT' (a `%'
2848
   followed by a punctuation character), this macro is called with
2849
   a null pointer for X and the punctuation character for CODE.
2850
 
2851
   The m68k specific codes are:
2852
 
2853
   '.' for dot needed in Motorola-style opcode names.
2854
   '-' for an operand pushing on the stack:
2855
       sp@-, -(sp) or -(%sp) depending on the style of syntax.
2856
   '+' for an operand pushing on the stack:
2857
       sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2858
   '@' for a reference to the top word on the stack:
2859
       sp@, (sp) or (%sp) depending on the style of syntax.
2860
   '#' for an immediate operand prefix (# in MIT and Motorola syntax
2861
       but & in SGS syntax).
2862
   '!' for the cc register (used in an `and to cc' insn).
2863
   '$' for the letter `s' in an op code, but only on the 68040.
2864
   '&' for the letter `d' in an op code, but only on the 68040.
2865
   '/' for register prefix needed by longlong.h.
2866
 
2867
   'b' for byte insn (no effect, on the Sun; this is for the ISI).
2868
   'd' to force memory addressing to be absolute, not relative.
2869
   'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2870
   'o' for operands to go directly to output_operand_address (bypassing
2871
       print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2872
   'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2873
       or print pair of registers as rx:ry.
2874
 
2875
   */
2876
 
2877
void
2878
print_operand (FILE *file, rtx op, int letter)
2879
{
2880
  if (letter == '.')
2881
    {
2882
      if (MOTOROLA)
2883
        fprintf (file, ".");
2884
    }
2885
  else if (letter == '#')
2886
    asm_fprintf (file, "%I");
2887
  else if (letter == '-')
2888
    asm_fprintf (file, MOTOROLA ? "-(%Rsp)" : "%Rsp@-");
2889
  else if (letter == '+')
2890
    asm_fprintf (file, MOTOROLA ? "(%Rsp)+" : "%Rsp@+");
2891
  else if (letter == '@')
2892
    asm_fprintf (file, MOTOROLA ? "(%Rsp)" : "%Rsp@");
2893
  else if (letter == '!')
2894
    asm_fprintf (file, "%Rfpcr");
2895
  else if (letter == '$')
2896
    {
2897
      if (TARGET_68040_ONLY)
2898
        fprintf (file, "s");
2899
    }
2900
  else if (letter == '&')
2901
    {
2902
      if (TARGET_68040_ONLY)
2903
        fprintf (file, "d");
2904
    }
2905
  else if (letter == '/')
2906
    asm_fprintf (file, "%R");
2907
  else if (letter == 'o')
2908
    {
2909
      /* This is only for direct addresses with TARGET_PCREL */
2910
      gcc_assert (GET_CODE (op) == MEM
2911
                  && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
2912
                  && TARGET_PCREL);
2913
      output_addr_const (file, XEXP (op, 0));
2914
    }
2915
  else if (GET_CODE (op) == REG)
2916
    {
2917
      if (letter == 'R')
2918
        /* Print out the second register name of a register pair.
2919
           I.e., R (6) => 7.  */
2920
        fputs (M68K_REGNAME(REGNO (op) + 1), file);
2921
      else
2922
        fputs (M68K_REGNAME(REGNO (op)), file);
2923
    }
2924
  else if (GET_CODE (op) == MEM)
2925
    {
2926
      output_address (XEXP (op, 0));
2927
      if (letter == 'd' && ! TARGET_68020
2928
          && CONSTANT_ADDRESS_P (XEXP (op, 0))
2929
          && !(GET_CODE (XEXP (op, 0)) == CONST_INT
2930
               && INTVAL (XEXP (op, 0)) < 0x8000
2931
               && INTVAL (XEXP (op, 0)) >= -0x8000))
2932
        fprintf (file, MOTOROLA ? ".l" : ":l");
2933
    }
2934
  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
2935
    {
2936
      REAL_VALUE_TYPE r;
2937
      REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2938
      ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
2939
    }
2940
  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
2941
    {
2942
      REAL_VALUE_TYPE r;
2943
      REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2944
      ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
2945
    }
2946
  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
2947
    {
2948
      REAL_VALUE_TYPE r;
2949
      REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2950
      ASM_OUTPUT_DOUBLE_OPERAND (file, r);
2951
    }
2952
  else
2953
    {
2954
      /* Use `print_operand_address' instead of `output_addr_const'
2955
         to ensure that we print relevant PIC stuff.  */
2956
      asm_fprintf (file, "%I");
2957
      if (TARGET_PCREL
2958
          && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
2959
        print_operand_address (file, op);
2960
      else
2961
        output_addr_const (file, op);
2962
    }
2963
}
2964
 
2965
 
2966
/* A C compound statement to output to stdio stream STREAM the
2967
   assembler syntax for an instruction operand that is a memory
2968
   reference whose address is ADDR.  ADDR is an RTL expression.
2969
 
2970
   Note that this contains a kludge that knows that the only reason
2971
   we have an address (plus (label_ref...) (reg...)) when not generating
2972
   PIC code is in the insn before a tablejump, and we know that m68k.md
2973
   generates a label LInnn: on such an insn.
2974
 
2975
   It is possible for PIC to generate a (plus (label_ref...) (reg...))
2976
   and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2977
 
2978
   Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2979
   fails to assemble.  Luckily "Lnnn(pc,d0.l*2)" produces the results
2980
   we want.  This difference can be accommodated by using an assembler
2981
   define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2982
   string, as necessary.  This is accomplished via the ASM_OUTPUT_CASE_END
2983
   macro.  See m68k/sgs.h for an example; for versions without the bug.
2984
   Some assemblers refuse all the above solutions.  The workaround is to
2985
   emit "K(pc,d0.l*2)" with K being a small constant known to give the
2986
   right behavior.
2987
 
2988
   They also do not like things like "pea 1.w", so we simple leave off
2989
   the .w on small constants.
2990
 
2991
   This routine is responsible for distinguishing between -fpic and -fPIC
2992
   style relocations in an address.  When generating -fpic code the
2993
   offset is output in word mode (e.g. movel a5@(_foo:w), a0).  When generating
2994
   -fPIC code the offset is output in long mode (e.g. movel a5@(_foo:l), a0) */
2995
 
2996
#if MOTOROLA
2997
#  define ASM_OUTPUT_CASE_FETCH(file, labelno, regname) \
2998
  asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2999
#else /* !MOTOROLA */
3000
# define ASM_OUTPUT_CASE_FETCH(file, labelno, regname) \
3001
  asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
3002
#endif /* !MOTOROLA */
3003
 
3004
void
3005
print_operand_address (FILE *file, rtx addr)
3006
{
3007
  register rtx reg1, reg2, breg, ireg;
3008
  rtx offset;
3009
 
3010
  switch (GET_CODE (addr))
3011
    {
3012
    case REG:
3013
      fprintf (file, MOTOROLA ? "(%s)" : "%s@", M68K_REGNAME (REGNO (addr)));
3014
      break;
3015
    case PRE_DEC:
3016
      fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
3017
               M68K_REGNAME (REGNO (XEXP (addr, 0))));
3018
      break;
3019
    case POST_INC:
3020
      fprintf (file, MOTOROLA ? "(%s)+" : "%s@+",
3021
               M68K_REGNAME (REGNO (XEXP (addr, 0))));
3022
      break;
3023
    case PLUS:
3024
      reg1 = reg2 = ireg = breg = offset = 0;
3025
      if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3026
        {
3027
          offset = XEXP (addr, 0);
3028
          addr = XEXP (addr, 1);
3029
        }
3030
      else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3031
        {
3032
          offset = XEXP (addr, 1);
3033
          addr = XEXP (addr, 0);
3034
        }
3035
      if (GET_CODE (addr) != PLUS)
3036
        {
3037
          ;
3038
        }
3039
      else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
3040
        {
3041
          reg1 = XEXP (addr, 0);
3042
          addr = XEXP (addr, 1);
3043
        }
3044
      else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
3045
        {
3046
          reg1 = XEXP (addr, 1);
3047
          addr = XEXP (addr, 0);
3048
        }
3049
      else if (GET_CODE (XEXP (addr, 0)) == MULT)
3050
        {
3051
          reg1 = XEXP (addr, 0);
3052
          addr = XEXP (addr, 1);
3053
        }
3054
      else if (GET_CODE (XEXP (addr, 1)) == MULT)
3055
        {
3056
          reg1 = XEXP (addr, 1);
3057
          addr = XEXP (addr, 0);
3058
        }
3059
      else if (GET_CODE (XEXP (addr, 0)) == REG)
3060
        {
3061
          reg1 = XEXP (addr, 0);
3062
          addr = XEXP (addr, 1);
3063
        }
3064
      else if (GET_CODE (XEXP (addr, 1)) == REG)
3065
        {
3066
          reg1 = XEXP (addr, 1);
3067
          addr = XEXP (addr, 0);
3068
        }
3069
      if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
3070
          || GET_CODE (addr) == SIGN_EXTEND)
3071
        {
3072
          if (reg1 == 0)
3073
            reg1 = addr;
3074
          else
3075
            reg2 = addr;
3076
          addr = 0;
3077
        }
3078
#if 0   /* for OLD_INDEXING */
3079
      else if (GET_CODE (addr) == PLUS)
3080
        {
3081
          if (GET_CODE (XEXP (addr, 0)) == REG)
3082
            {
3083
              reg2 = XEXP (addr, 0);
3084
              addr = XEXP (addr, 1);
3085
            }
3086
          else if (GET_CODE (XEXP (addr, 1)) == REG)
3087
            {
3088
              reg2 = XEXP (addr, 1);
3089
              addr = XEXP (addr, 0);
3090
            }
3091
        }
3092
#endif
3093
      if (offset != 0)
3094
        {
3095
          gcc_assert (!addr);
3096
          addr = offset;
3097
        }
3098
      if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
3099
                    || GET_CODE (reg1) == MULT))
3100
          || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3101
        {
3102
          breg = reg2;
3103
          ireg = reg1;
3104
        }
3105
      else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3106
        {
3107
          breg = reg1;
3108
          ireg = reg2;
3109
        }
3110
      if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
3111
          && ! (flag_pic && ireg == pic_offset_table_rtx))
3112
        {
3113
          int scale = 1;
3114
          if (GET_CODE (ireg) == MULT)
3115
            {
3116
              scale = INTVAL (XEXP (ireg, 1));
3117
              ireg = XEXP (ireg, 0);
3118
            }
3119
          if (GET_CODE (ireg) == SIGN_EXTEND)
3120
            {
3121
              ASM_OUTPUT_CASE_FETCH (file,
3122
                                     CODE_LABEL_NUMBER (XEXP (addr, 0)),
3123
                                     M68K_REGNAME (REGNO (XEXP (ireg, 0))));
3124
              fprintf (file, "w");
3125
            }
3126
          else
3127
            {
3128
              ASM_OUTPUT_CASE_FETCH (file,
3129
                                     CODE_LABEL_NUMBER (XEXP (addr, 0)),
3130
                                     M68K_REGNAME (REGNO (ireg)));
3131
              fprintf (file, "l");
3132
            }
3133
          if (scale != 1)
3134
            fprintf (file, MOTOROLA ? "*%d" : ":%d", scale);
3135
          putc (')', file);
3136
          break;
3137
        }
3138
      if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
3139
          && ! (flag_pic && breg == pic_offset_table_rtx))
3140
        {
3141
          ASM_OUTPUT_CASE_FETCH (file,
3142
                                 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3143
                                 M68K_REGNAME (REGNO (breg)));
3144
          fprintf (file, "l)");
3145
          break;
3146
        }
3147
      if (ireg != 0 || breg != 0)
3148
        {
3149
          int scale = 1;
3150
 
3151
          gcc_assert (breg);
3152
          gcc_assert (flag_pic || !addr || GET_CODE (addr) != LABEL_REF);
3153
 
3154
          if (MOTOROLA)
3155
            {
3156
              if (addr != 0)
3157
                {
3158
                  output_addr_const (file, addr);
3159
                  if (flag_pic && (breg == pic_offset_table_rtx))
3160
                    {
3161
                      fprintf (file, "@GOT");
3162
                      if (flag_pic == 1)
3163
                        fprintf (file, ".w");
3164
                    }
3165
                }
3166
              fprintf (file, "(%s", M68K_REGNAME (REGNO (breg)));
3167
              if (ireg != 0)
3168
                putc (',', file);
3169
            }
3170
          else /* !MOTOROLA */
3171
            {
3172
              fprintf (file, "%s@(", M68K_REGNAME (REGNO (breg)));
3173
              if (addr != 0)
3174
                {
3175
                  output_addr_const (file, addr);
3176
                  if (breg == pic_offset_table_rtx)
3177
                    switch (flag_pic)
3178
                      {
3179
                      case 1:
3180
                        fprintf (file, ":w");
3181
                        break;
3182
                      case 2:
3183
                        fprintf (file, ":l");
3184
                        break;
3185
                      default:
3186
                        break;
3187
                      }
3188
                  if (ireg != 0)
3189
                    putc (',', file);
3190
                }
3191
            } /* !MOTOROLA */
3192
          if (ireg != 0 && GET_CODE (ireg) == MULT)
3193
            {
3194
              scale = INTVAL (XEXP (ireg, 1));
3195
              ireg = XEXP (ireg, 0);
3196
            }
3197
          if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
3198
            fprintf (file, MOTOROLA ? "%s.w" : "%s:w",
3199
                     M68K_REGNAME (REGNO (XEXP (ireg, 0))));
3200
          else if (ireg != 0)
3201
            fprintf (file, MOTOROLA ? "%s.l" : "%s:l",
3202
                     M68K_REGNAME (REGNO (ireg)));
3203
          if (scale != 1)
3204
            fprintf (file, MOTOROLA ? "*%d" : ":%d", scale);
3205
          putc (')', file);
3206
          break;
3207
        }
3208
      else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3209
               && ! (flag_pic && reg1 == pic_offset_table_rtx))
3210
        {
3211
          ASM_OUTPUT_CASE_FETCH (file,
3212
                                 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3213
                                 M68K_REGNAME (REGNO (reg1)));
3214
          fprintf (file, "l)");
3215
          break;
3216
        }
3217
      /* FALL-THROUGH (is this really what we want?)  */
3218
    default:
3219
      if (GET_CODE (addr) == CONST_INT
3220
          && INTVAL (addr) < 0x8000
3221
          && INTVAL (addr) >= -0x8000)
3222
        {
3223
          fprintf (file, MOTOROLA ? "%d.w" : "%d:w", (int) INTVAL (addr));
3224
        }
3225
      else if (GET_CODE (addr) == CONST_INT)
3226
        {
3227
          fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
3228
        }
3229
      else if (TARGET_PCREL)
3230
        {
3231
          fputc ('(', file);
3232
          output_addr_const (file, addr);
3233
          if (flag_pic == 1)
3234
            asm_fprintf (file, ":w,%Rpc)");
3235
          else
3236
            asm_fprintf (file, ":l,%Rpc)");
3237
        }
3238
      else
3239
        {
3240
          /* Special case for SYMBOL_REF if the symbol name ends in
3241
             `.<letter>', this can be mistaken as a size suffix.  Put
3242
             the name in parentheses.  */
3243
          if (GET_CODE (addr) == SYMBOL_REF
3244
              && strlen (XSTR (addr, 0)) > 2
3245
              && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
3246
            {
3247
              putc ('(', file);
3248
              output_addr_const (file, addr);
3249
              putc (')', file);
3250
            }
3251
          else
3252
            output_addr_const (file, addr);
3253
        }
3254
      break;
3255
    }
3256
}
3257
 
3258
/* Check for cases where a clr insns can be omitted from code using
3259
   strict_low_part sets.  For example, the second clrl here is not needed:
3260
   clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3261
 
3262
   MODE is the mode of this STRICT_LOW_PART set.  FIRST_INSN is the clear
3263
   insn we are checking for redundancy.  TARGET is the register set by the
3264
   clear insn.  */
3265
 
3266
bool
3267
strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
3268
                             rtx target)
3269
{
3270
  rtx p;
3271
 
3272
  p = prev_nonnote_insn (first_insn);
3273
 
3274
  while (p)
3275
    {
3276
      /* If it isn't an insn, then give up.  */
3277
      if (GET_CODE (p) != INSN)
3278
        return false;
3279
 
3280
      if (reg_set_p (target, p))
3281
        {
3282
          rtx set = single_set (p);
3283
          rtx dest;
3284
 
3285
          /* If it isn't an easy to recognize insn, then give up.  */
3286
          if (! set)
3287
            return false;
3288
 
3289
          dest = SET_DEST (set);
3290
 
3291
          /* If this sets the entire target register to zero, then our
3292
             first_insn is redundant.  */
3293
          if (rtx_equal_p (dest, target)
3294
              && SET_SRC (set) == const0_rtx)
3295
            return true;
3296
          else if (GET_CODE (dest) == STRICT_LOW_PART
3297
                   && GET_CODE (XEXP (dest, 0)) == REG
3298
                   && REGNO (XEXP (dest, 0)) == REGNO (target)
3299
                   && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3300
                       <= GET_MODE_SIZE (mode)))
3301
            /* This is a strict low part set which modifies less than
3302
               we are using, so it is safe.  */
3303
            ;
3304
          else
3305
            return false;
3306
        }
3307
 
3308
      p = prev_nonnote_insn (p);
3309
    }
3310
 
3311
  return false;
3312
}
3313
 
3314
/* Operand predicates for implementing asymmetric pc-relative addressing
3315
   on m68k.  The m68k supports pc-relative addressing (mode 7, register 2)
3316
   when used as a source operand, but not as a destination operand.
3317
 
3318
   We model this by restricting the meaning of the basic predicates
3319
   (general_operand, memory_operand, etc) to forbid the use of this
3320
   addressing mode, and then define the following predicates that permit
3321
   this addressing mode.  These predicates can then be used for the
3322
   source operands of the appropriate instructions.
3323
 
3324
   n.b.  While it is theoretically possible to change all machine patterns
3325
   to use this addressing more where permitted by the architecture,
3326
   it has only been implemented for "common" cases: SImode, HImode, and
3327
   QImode operands, and only for the principle operations that would
3328
   require this addressing mode: data movement and simple integer operations.
3329
 
3330
   In parallel with these new predicates, two new constraint letters
3331
   were defined: 'S' and 'T'.  'S' is the -mpcrel analog of 'm'.
3332
   'T' replaces 's' in the non-pcrel case.  It is a no-op in the pcrel case.
3333
   In the pcrel case 's' is only valid in combination with 'a' registers.
3334
   See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3335
   of how these constraints are used.
3336
 
3337
   The use of these predicates is strictly optional, though patterns that
3338
   don't will cause an extra reload register to be allocated where one
3339
   was not necessary:
3340
 
3341
        lea (abc:w,%pc),%a0     ; need to reload address
3342
        moveq &1,%d1            ; since write to pc-relative space
3343
        movel %d1,%a0@          ; is not allowed
3344
        ...
3345
        lea (abc:w,%pc),%a1     ; no need to reload address here
3346
        movel %a1@,%d0          ; since "movel (abc:w,%pc),%d0" is ok
3347
 
3348
   For more info, consult tiemann@cygnus.com.
3349
 
3350
 
3351
   All of the ugliness with predicates and constraints is due to the
3352
   simple fact that the m68k does not allow a pc-relative addressing
3353
   mode as a destination.  gcc does not distinguish between source and
3354
   destination addresses.  Hence, if we claim that pc-relative address
3355
   modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3356
   end up with invalid code.  To get around this problem, we left
3357
   pc-relative modes as invalid addresses, and then added special
3358
   predicates and constraints to accept them.
3359
 
3360
   A cleaner way to handle this is to modify gcc to distinguish
3361
   between source and destination addresses.  We can then say that
3362
   pc-relative is a valid source address but not a valid destination
3363
   address, and hopefully avoid a lot of the predicate and constraint
3364
   hackery.  Unfortunately, this would be a pretty big change.  It would
3365
   be a useful change for a number of ports, but there aren't any current
3366
   plans to undertake this.
3367
 
3368
   ***************************************************************************/
3369
 
3370
 
3371
const char *
3372
output_andsi3 (rtx *operands)
3373
{
3374
  int logval;
3375
  if (GET_CODE (operands[2]) == CONST_INT
3376
      && (INTVAL (operands[2]) | 0xffff) == -1
3377
      && (DATA_REG_P (operands[0])
3378
          || offsettable_memref_p (operands[0]))
3379
      && !TARGET_COLDFIRE)
3380
    {
3381
      if (GET_CODE (operands[0]) != REG)
3382
        operands[0] = adjust_address (operands[0], HImode, 2);
3383
      operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3384
      /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3385
      CC_STATUS_INIT;
3386
      if (operands[2] == const0_rtx)
3387
        return "clr%.w %0";
3388
      return "and%.w %2,%0";
3389
    }
3390
  if (GET_CODE (operands[2]) == CONST_INT
3391
      && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3392
      && (DATA_REG_P (operands[0])
3393
          || offsettable_memref_p (operands[0])))
3394
    {
3395
      if (DATA_REG_P (operands[0]))
3396
        operands[1] = GEN_INT (logval);
3397
      else
3398
        {
3399
          operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3400
          operands[1] = GEN_INT (logval % 8);
3401
        }
3402
      /* This does not set condition codes in a standard way.  */
3403
      CC_STATUS_INIT;
3404
      return "bclr %1,%0";
3405
    }
3406
  return "and%.l %2,%0";
3407
}
3408
 
3409
const char *
3410
output_iorsi3 (rtx *operands)
3411
{
3412
  register int logval;
3413
  if (GET_CODE (operands[2]) == CONST_INT
3414
      && INTVAL (operands[2]) >> 16 == 0
3415
      && (DATA_REG_P (operands[0])
3416
          || offsettable_memref_p (operands[0]))
3417
      && !TARGET_COLDFIRE)
3418
    {
3419
      if (GET_CODE (operands[0]) != REG)
3420
        operands[0] = adjust_address (operands[0], HImode, 2);
3421
      /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3422
      CC_STATUS_INIT;
3423
      if (INTVAL (operands[2]) == 0xffff)
3424
        return "mov%.w %2,%0";
3425
      return "or%.w %2,%0";
3426
    }
3427
  if (GET_CODE (operands[2]) == CONST_INT
3428
      && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3429
      && (DATA_REG_P (operands[0])
3430
          || offsettable_memref_p (operands[0])))
3431
    {
3432
      if (DATA_REG_P (operands[0]))
3433
        operands[1] = GEN_INT (logval);
3434
      else
3435
        {
3436
          operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3437
          operands[1] = GEN_INT (logval % 8);
3438
        }
3439
      CC_STATUS_INIT;
3440
      return "bset %1,%0";
3441
    }
3442
  return "or%.l %2,%0";
3443
}
3444
 
3445
const char *
3446
output_xorsi3 (rtx *operands)
3447
{
3448
  register int logval;
3449
  if (GET_CODE (operands[2]) == CONST_INT
3450
      && INTVAL (operands[2]) >> 16 == 0
3451
      && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3452
      && !TARGET_COLDFIRE)
3453
    {
3454
      if (! DATA_REG_P (operands[0]))
3455
        operands[0] = adjust_address (operands[0], HImode, 2);
3456
      /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3457
      CC_STATUS_INIT;
3458
      if (INTVAL (operands[2]) == 0xffff)
3459
        return "not%.w %0";
3460
      return "eor%.w %2,%0";
3461
    }
3462
  if (GET_CODE (operands[2]) == CONST_INT
3463
      && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3464
      && (DATA_REG_P (operands[0])
3465
          || offsettable_memref_p (operands[0])))
3466
    {
3467
      if (DATA_REG_P (operands[0]))
3468
        operands[1] = GEN_INT (logval);
3469
      else
3470
        {
3471
          operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3472
          operands[1] = GEN_INT (logval % 8);
3473
        }
3474
      CC_STATUS_INIT;
3475
      return "bchg %1,%0";
3476
    }
3477
  return "eor%.l %2,%0";
3478
}
3479
 
3480
#ifdef M68K_TARGET_COFF
3481
 
3482
/* Output assembly to switch to section NAME with attribute FLAGS.  */
3483
 
3484
static void
3485
m68k_coff_asm_named_section (const char *name, unsigned int flags,
3486
                             tree decl ATTRIBUTE_UNUSED)
3487
{
3488
  char flagchar;
3489
 
3490
  if (flags & SECTION_WRITE)
3491
    flagchar = 'd';
3492
  else
3493
    flagchar = 'x';
3494
 
3495
  fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
3496
}
3497
 
3498
#endif /* M68K_TARGET_COFF */
3499
 
3500
static void
3501
m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
3502
                      HOST_WIDE_INT delta,
3503
                      HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
3504
                      tree function)
3505
{
3506
  rtx xops[1];
3507
  const char *fmt;
3508
 
3509
  if (delta > 0 && delta <= 8)
3510
    asm_fprintf (file, (MOTOROLA
3511
                        ? "\taddq.l %I%d,4(%Rsp)\n"
3512
                        : "\taddql %I%d,%Rsp@(4)\n"),
3513
                 (int) delta);
3514
  else if (delta < 0 && delta >= -8)
3515
    asm_fprintf (file, (MOTOROLA
3516
                        ? "\tsubq.l %I%d,4(%Rsp)\n"
3517
                        : "\tsubql %I%d,%Rsp@(4)\n"),
3518
                 (int) -delta);
3519
  else if (TARGET_COLDFIRE)
3520
    {
3521
      /* ColdFire can't add/sub a constant to memory unless it is in
3522
         the range of addq/subq.  So load the value into %d0 and
3523
         then add it to 4(%sp). */
3524
      if (delta >= -128 && delta <= 127)
3525
        asm_fprintf (file, (MOTOROLA
3526
                            ? "\tmoveq.l %I%wd,%Rd0\n"
3527
                            : "\tmoveql %I%wd,%Rd0\n"),
3528
                     delta);
3529
      else
3530
        asm_fprintf (file, (MOTOROLA
3531
                            ? "\tmove.l %I%wd,%Rd0\n"
3532
                            : "\tmovel %I%wd,%Rd0\n"),
3533
                     delta);
3534
      asm_fprintf (file, (MOTOROLA
3535
                          ? "\tadd.l %Rd0,4(%Rsp)\n"
3536
                          : "\taddl %Rd0,%Rsp@(4)\n"));
3537
    }
3538
  else
3539
    asm_fprintf (file, (MOTOROLA
3540
                        ? "\tadd.l %I%wd,4(%Rsp)\n"
3541
                        : "\taddl %I%wd,%Rsp@(4)\n"),
3542
                 delta);
3543
 
3544
  xops[0] = DECL_RTL (function);
3545
 
3546
  /* Logic taken from call patterns in m68k.md.  */
3547
  if (flag_pic)
3548
    {
3549
      if (TARGET_PCREL)
3550
        fmt = "bra.l %o0";
3551
      else if (flag_pic == 1 || TARGET_68020)
3552
        {
3553
          if (MOTOROLA)
3554
            {
3555
#if defined (USE_GAS)
3556
              fmt = "bra.l %0@PLTPC";
3557
#else
3558
              fmt = "bra %0@PLTPC";
3559
#endif
3560
            }
3561
          else /* !MOTOROLA */
3562
            {
3563
#ifdef USE_GAS
3564
              fmt = "bra.l %0";
3565
#else
3566
              fmt = "jra %0,a1";
3567
#endif
3568
            }
3569
        }
3570
      else if (optimize_size || TARGET_ID_SHARED_LIBRARY)
3571
        fmt = "move.l %0@GOT(%%a5), %%a1\n\tjmp (%%a1)";
3572
      else
3573
        fmt = "lea %0-.-8,%%a1\n\tjmp 0(%%pc,%%a1)";
3574
    }
3575
  else
3576
    {
3577
#if MOTOROLA && !defined (USE_GAS)
3578
      fmt = "jmp %0";
3579
#else
3580
      fmt = "jra %0";
3581
#endif
3582
    }
3583
 
3584
  output_asm_insn (fmt, xops);
3585
}
3586
 
3587
/* Worker function for TARGET_STRUCT_VALUE_RTX.  */
3588
 
3589
static rtx
3590
m68k_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
3591
                       int incoming ATTRIBUTE_UNUSED)
3592
{
3593
  return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
3594
}
3595
 
3596
/* Return nonzero if register old_reg can be renamed to register new_reg.  */
3597
int
3598
m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
3599
                           unsigned int new_reg)
3600
{
3601
 
3602
  /* Interrupt functions can only use registers that have already been
3603
     saved by the prologue, even if they would normally be
3604
     call-clobbered.  */
3605
 
3606
  if (m68k_interrupt_function_p (current_function_decl)
3607
      && !regs_ever_live[new_reg])
3608
    return 0;
3609
 
3610
  return 1;
3611
}
3612
 
3613
/* Value is true if hard register REGNO can hold a value of machine-mode MODE.
3614
   On the 68000, the cpu registers can hold any mode except bytes in address
3615
   registers, but the 68881 registers can hold only SFmode or DFmode.  */
3616
bool
3617
m68k_regno_mode_ok (int regno, enum machine_mode mode)
3618
{
3619
  if (regno < 8)
3620
    {
3621
      /* Data Registers, can hold aggregate if fits in.  */
3622
      if (regno + GET_MODE_SIZE (mode) / 4 <= 8)
3623
        return true;
3624
    }
3625
  else if (regno < 16)
3626
    {
3627
      /* Address Registers, can't hold bytes, can hold aggregate if
3628
         fits in.  */
3629
      if (GET_MODE_SIZE (mode) == 1)
3630
        return false;
3631
      if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
3632
        return true;
3633
    }
3634
  else if (regno < 24)
3635
    {
3636
      /* FPU registers, hold float or complex float of long double or
3637
         smaller.  */
3638
      if ((GET_MODE_CLASS (mode) == MODE_FLOAT
3639
           || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
3640
          && GET_MODE_UNIT_SIZE (mode) <= TARGET_FP_REG_SIZE)
3641
        return true;
3642
    }
3643
  return false;
3644
}
3645
 
3646
/* Return floating point values in a 68881 register.  This makes 68881 code
3647
   a little bit faster.  It also makes -msoft-float code incompatible with
3648
   hard-float code, so people have to be careful not to mix the two.
3649
   For ColdFire it was decided the ABI incompatibility is undesirable.
3650
   If there is need for a hard-float ABI it is probably worth doing it
3651
   properly and also passing function arguments in FP registers.  */
3652
rtx
3653
m68k_libcall_value (enum machine_mode mode)
3654
{
3655
  switch (mode) {
3656
  case SFmode:
3657
  case DFmode:
3658
  case XFmode:
3659
    if (TARGET_68881)
3660
      return gen_rtx_REG (mode, 16);
3661
    break;
3662
  default:
3663
    break;
3664
  }
3665
  return gen_rtx_REG (mode, 0);
3666
}
3667
 
3668
rtx
3669
m68k_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
3670
{
3671
  enum machine_mode mode;
3672
 
3673
  mode = TYPE_MODE (valtype);
3674
  switch (mode) {
3675
  case SFmode:
3676
  case DFmode:
3677
  case XFmode:
3678
    if (TARGET_68881)
3679
      return gen_rtx_REG (mode, 16);
3680
    break;
3681
  default:
3682
    break;
3683
  }
3684
 
3685
  /* If the function returns a pointer, push that into %a0 */
3686
  if (POINTER_TYPE_P (valtype))
3687
    return gen_rtx_REG (mode, 8);
3688
  else
3689
    return gen_rtx_REG (mode, 0);
3690
}

powered by: WebSVN 2.1.0

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