1 /* Subroutines for insn-output.c for Motorola 88000.
2 Copyright (C) 1988, 92, 93, 94, 95, 16, 1997 Free Software Foundation, Inc.
3 Contributed by Michael Tiemann (tiemann@mcc.com)
4 Currently maintained by (gcc@dg-rtp.dg.com)
6 This file is part of GNU CC.
8 GNU CC 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 2, or (at your option)
13 GNU CC 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.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
26 #include <sys/types.h>
33 #include "hard-reg-set.h"
35 #include "insn-config.h"
36 #include "conditions.h"
37 #include "insn-flags.h"
39 #include "insn-attr.h"
45 extern char *version_string
;
46 extern time_t time ();
47 extern char *ctime ();
48 extern int flag_traditional
;
49 extern FILE *asm_out_file
;
51 static char out_rcs_id
[] = "$What: <@(#) m88k.c,v 1.8> $";
52 static char tm_rcs_id
[] = TM_RCS_ID
;
54 char *m88k_pound_sign
= ""; /* Either # for SVR4 or empty for SVR3 */
55 char *m88k_short_data
;
57 char m88k_volatile_code
;
59 unsigned m88k_gp_threshold
= 0;
60 int m88k_prologue_done
= 0; /* Ln directives can now be emitted */
61 int m88k_function_number
= 0; /* Counter unique to each function */
62 int m88k_fp_offset
= 0; /* offset of frame pointer if used */
63 int m88k_stack_size
= 0; /* size of allocated stack (including frame) */
66 rtx m88k_compare_reg
; /* cmp output pseudo register */
67 rtx m88k_compare_op0
; /* cmpsi operand 0 */
68 rtx m88k_compare_op1
; /* cmpsi operand 1 */
70 enum processor_type m88k_cpu
; /* target cpu */
72 /* Determine what instructions are needed to manufacture the integer VALUE
76 classify_integer (mode
, value
)
77 enum machine_mode mode
;
84 else if (SMALL_INTVAL (value
))
86 else if (SMALL_INTVAL (-value
))
88 else if (mode
== HImode
)
90 else if (mode
== QImode
)
92 else if ((value
& 0xffff) == 0)
94 else if (integer_ok_for_set (value
))
100 /* Return the bit number in a compare word corresponding to CONDITION. */
103 condition_value (condition
)
106 switch (GET_CODE (condition
))
123 integer_ok_for_set (value
)
124 register unsigned value
;
126 /* All the "one" bits must be contiguous. If so, MASK + 1 will be
127 a power of two or zero. */
128 register unsigned mask
= (value
| (value
- 1));
129 return (value
&& POWER_OF_2_or_0 (mask
+ 1));
133 output_load_const_int (mode
, operands
)
134 enum machine_mode mode
;
137 static char *patterns
[] =
145 "or.u %0,%#r0,%X1\n\tor %0,%0,%x1",
148 if (! REG_P (operands
[0])
149 || GET_CODE (operands
[1]) != CONST_INT
)
151 return patterns
[classify_integer (mode
, INTVAL (operands
[1]))];
154 /* These next two routines assume that floating point numbers are represented
155 in a manner which is consistent between host and target machines. */
158 output_load_const_float (operands
)
161 /* These can return 0 under some circumstances when cross-compiling. */
162 operands
[0] = operand_subword (operands
[0], 0, 0, SFmode
);
163 operands
[1] = operand_subword (operands
[1], 0, 0, SFmode
);
165 return output_load_const_int (SImode
, operands
);
169 output_load_const_double (operands
)
174 /* These can return zero on some cross-compilers, but there's nothing
175 we can do about it. */
176 latehalf
[0] = operand_subword (operands
[0], 1, 0, DFmode
);
177 latehalf
[1] = operand_subword (operands
[1], 1, 0, DFmode
);
179 operands
[0] = operand_subword (operands
[0], 0, 0, DFmode
);
180 operands
[1] = operand_subword (operands
[1], 0, 0, DFmode
);
182 output_asm_insn (output_load_const_int (SImode
, operands
), operands
);
184 operands
[0] = latehalf
[0];
185 operands
[1] = latehalf
[1];
187 return output_load_const_int (SImode
, operands
);
191 output_load_const_dimode (operands
)
196 latehalf
[0] = operand_subword (operands
[0], 1, 0, DImode
);
197 latehalf
[1] = operand_subword (operands
[1], 1, 0, DImode
);
199 operands
[0] = operand_subword (operands
[0], 0, 0, DImode
);
200 operands
[1] = operand_subword (operands
[1], 0, 0, DImode
);
202 output_asm_insn (output_load_const_int (SImode
, operands
), operands
);
204 operands
[0] = latehalf
[0];
205 operands
[1] = latehalf
[1];
207 return output_load_const_int (SImode
, operands
);
210 /* Emit insns to move operands[1] into operands[0].
212 Return 1 if we have written out everything that needs to be done to
213 do the move. Otherwise, return 0 and the caller will emit the move
216 SCRATCH if non zero can be used as a scratch register for the move
217 operation. It is provided by a SECONDARY_RELOAD_* macro if needed. */
220 emit_move_sequence (operands
, mode
, scratch
)
222 enum machine_mode mode
;
225 register rtx operand0
= operands
[0];
226 register rtx operand1
= operands
[1];
228 if (CONSTANT_P (operand1
) && flag_pic
229 && pic_address_needs_scratch (operand1
))
230 operands
[1] = operand1
= legitimize_address (1, operand1
, 0, 0);
232 /* Handle most common case first: storing into a register. */
233 if (register_operand (operand0
, mode
))
235 if (register_operand (operand1
, mode
)
236 || (GET_CODE (operand1
) == CONST_INT
&& SMALL_INT (operand1
))
237 || GET_CODE (operand1
) == HIGH
238 /* Only `general_operands' can come here, so MEM is ok. */
239 || GET_CODE (operand1
) == MEM
)
241 /* Run this case quickly. */
242 emit_insn (gen_rtx (SET
, VOIDmode
, operand0
, operand1
));
246 else if (GET_CODE (operand0
) == MEM
)
248 if (register_operand (operand1
, mode
)
249 || (operand1
== const0_rtx
&& GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
))
251 /* Run this case quickly. */
252 emit_insn (gen_rtx (SET
, VOIDmode
, operand0
, operand1
));
255 if (! reload_in_progress
&& ! reload_completed
)
257 operands
[0] = validize_mem (operand0
);
258 operands
[1] = operand1
= force_reg (mode
, operand1
);
262 /* Simplify the source if we need to. */
263 if (GET_CODE (operand1
) != HIGH
&& immediate_operand (operand1
, mode
))
265 if (GET_CODE (operand1
) != CONST_INT
266 && GET_CODE (operand1
) != CONST_DOUBLE
)
268 rtx temp
= ((reload_in_progress
|| reload_completed
)
270 operands
[1] = legitimize_address (flag_pic
271 && symbolic_address_p (operand1
),
272 operand1
, temp
, scratch
);
274 operands
[1] = gen_rtx (SUBREG
, mode
, operands
[1], 0);
278 /* Now have insn-emit do whatever it normally does. */
282 /* Return a legitimate reference for ORIG (either an address or a MEM)
283 using the register REG. If PIC and the address is already
284 position-independent, use ORIG. Newly generated position-independent
285 addresses go into a reg. This is REG if non zero, otherwise we
286 allocate register(s) as necessary. If this is called during reload,
287 and we need a second temp register, then we use SCRATCH, which is
288 provided via the SECONDARY_INPUT_RELOAD_CLASS mechanism. */
291 legitimize_address (pic
, orig
, reg
, scratch
)
297 rtx addr
= (GET_CODE (orig
) == MEM
? XEXP (orig
, 0) : orig
);
303 if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == LABEL_REF
)
307 if (reload_in_progress
|| reload_completed
)
310 reg
= gen_reg_rtx (Pmode
);
315 /* If not during reload, allocate another temp reg here for
316 loading in the address, so that these instructions can be
317 optimized properly. */
318 temp
= ((reload_in_progress
|| reload_completed
)
319 ? reg
: gen_reg_rtx (Pmode
));
321 emit_insn (gen_rtx (SET
, VOIDmode
, temp
,
322 gen_rtx (HIGH
, SImode
,
323 gen_rtx (UNSPEC
, SImode
,
326 emit_insn (gen_rtx (SET
, VOIDmode
, temp
,
327 gen_rtx (LO_SUM
, SImode
, temp
,
328 gen_rtx (UNSPEC
, SImode
,
333 new = gen_rtx (MEM
, Pmode
,
334 gen_rtx (PLUS
, SImode
,
335 pic_offset_table_rtx
, addr
));
336 current_function_uses_pic_offset_table
= 1;
337 RTX_UNCHANGING_P (new) = 1;
338 insn
= emit_move_insn (reg
, new);
339 /* Put a REG_EQUAL note on this insn, so that it can be optimized
341 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUAL
, orig
,
345 else if (GET_CODE (addr
) == CONST
)
349 if (GET_CODE (XEXP (addr
, 0)) == PLUS
350 && XEXP (XEXP (addr
, 0), 0) == pic_offset_table_rtx
)
355 if (reload_in_progress
|| reload_completed
)
358 reg
= gen_reg_rtx (Pmode
);
361 if (GET_CODE (XEXP (addr
, 0)) != PLUS
) abort ();
363 base
= legitimize_address (1, XEXP (XEXP (addr
, 0), 0), reg
, 0);
364 addr
= legitimize_address (1, XEXP (XEXP (addr
, 0), 1),
365 base
== reg
? 0 : reg
, 0);
367 if (GET_CODE (addr
) == CONST_INT
)
370 return plus_constant_for_output (base
, INTVAL (addr
));
371 else if (! reload_in_progress
&& ! reload_completed
)
372 addr
= force_reg (Pmode
, addr
);
373 /* We can't create any new registers during reload, so use the
374 SCRATCH reg provided by the reload_insi pattern. */
377 emit_move_insn (scratch
, addr
);
381 /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS
382 macro needs to be adjusted so that a scratch reg is provided
386 new = gen_rtx (PLUS
, SImode
, base
, addr
);
387 /* Should we set special REG_NOTEs here? */
390 else if (! SHORT_ADDRESS_P (addr
, temp
))
394 if (reload_in_progress
|| reload_completed
)
397 reg
= gen_reg_rtx (Pmode
);
400 emit_insn (gen_rtx (SET
, VOIDmode
,
401 reg
, gen_rtx (HIGH
, SImode
, addr
)));
402 new = gen_rtx (LO_SUM
, SImode
, reg
, addr
);
406 && GET_CODE (orig
) == MEM
)
408 new = gen_rtx (MEM
, GET_MODE (orig
), new);
409 RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (orig
);
410 MEM_VOLATILE_P (new) = MEM_VOLATILE_P (orig
);
411 MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (orig
);
416 /* Support functions for code to emit a block move. There are four methods
417 used to perform the block move:
419 + call the looping library function, e.g. __movstrSI64n8
420 + call a non-looping library function, e.g. __movstrHI15x11
421 + produce an inline sequence of ld/st instructions
423 The parameters below describe the library functions produced by
426 #define MOVSTR_LOOP 64 /* __movstrSI64n68 .. __movstrSI64n8 */
427 #define MOVSTR_QI 16 /* __movstrQI16x16 .. __movstrQI16x2 */
428 #define MOVSTR_HI 48 /* __movstrHI48x48 .. __movstrHI48x4 */
429 #define MOVSTR_SI 96 /* __movstrSI96x96 .. __movstrSI96x8 */
430 #define MOVSTR_DI 96 /* __movstrDI96x96 .. __movstrDI96x16 */
431 #define MOVSTR_ODD_HI 16 /* __movstrHI15x15 .. __movstrHI15x5 */
432 #define MOVSTR_ODD_SI 48 /* __movstrSI47x47 .. __movstrSI47x11,
433 __movstrSI46x46 .. __movstrSI46x10,
434 __movstrSI45x45 .. __movstrSI45x9 */
435 #define MOVSTR_ODD_DI 48 /* __movstrDI47x47 .. __movstrDI47x23,
436 __movstrDI46x46 .. __movstrDI46x22,
437 __movstrDI45x45 .. __movstrDI45x21,
438 __movstrDI44x44 .. __movstrDI44x20,
439 __movstrDI43x43 .. __movstrDI43x19,
440 __movstrDI42x42 .. __movstrDI42x18,
441 __movstrDI41x41 .. __movstrDI41x17 */
443 /* Limits for using the non-looping movstr functions. For the m88100
444 processor, we assume the source and destination are word aligned.
445 The QImode and HImode limits are the break even points where memcpy
446 does just as well and beyond which memcpy does better. For the
447 m88110, we tend to assume double word alignment, but also analyze
448 the word aligned cases. The analysis is complicated because memcpy
449 may use the cache control instructions for better performance. */
451 #define MOVSTR_QI_LIMIT_88100 13
452 #define MOVSTR_HI_LIMIT_88100 38
453 #define MOVSTR_SI_LIMIT_88100 MOVSTR_SI
454 #define MOVSTR_DI_LIMIT_88100 MOVSTR_SI
456 #define MOVSTR_QI_LIMIT_88000 16
457 #define MOVSTR_HI_LIMIT_88000 38
458 #define MOVSTR_SI_LIMIT_88000 72
459 #define MOVSTR_DI_LIMIT_88000 72
461 #define MOVSTR_QI_LIMIT_88110 16
462 #define MOVSTR_HI_LIMIT_88110 38
463 #define MOVSTR_SI_LIMIT_88110 72
464 #define MOVSTR_DI_LIMIT_88110 72
466 static enum machine_mode mode_from_align
[] =
467 {VOIDmode
, QImode
, HImode
, VOIDmode
, SImode
,
468 VOIDmode
, VOIDmode
, VOIDmode
, DImode
};
469 static int max_from_align
[] = {0, MOVSTR_QI
, MOVSTR_HI
, 0, MOVSTR_SI
,
471 static int all_from_align
[] = {0, MOVSTR_QI
, MOVSTR_ODD_HI
, 0, MOVSTR_ODD_SI
,
472 0, 0, 0, MOVSTR_ODD_DI
};
474 static int best_from_align
[3][9] =
475 {0, MOVSTR_QI_LIMIT_88100
, MOVSTR_HI_LIMIT_88100
, 0, MOVSTR_SI_LIMIT_88100
,
476 0, 0, 0, MOVSTR_DI_LIMIT_88100
,
477 0, MOVSTR_QI_LIMIT_88110
, MOVSTR_HI_LIMIT_88110
, 0, MOVSTR_SI_LIMIT_88110
,
478 0, 0, 0, MOVSTR_DI_LIMIT_88110
,
479 0, MOVSTR_QI_LIMIT_88000
, MOVSTR_HI_LIMIT_88000
, 0, MOVSTR_SI_LIMIT_88000
,
480 0, 0, 0, MOVSTR_DI_LIMIT_88000
};
482 static void block_move_loop ();
483 static void block_move_no_loop ();
484 static void block_move_sequence ();
486 /* Emit code to perform a block move. Choose the best method.
488 OPERANDS[0] is the destination.
489 OPERANDS[1] is the source.
490 OPERANDS[2] is the size.
491 OPERANDS[3] is the alignment safe to use. */
494 expand_block_move (dest_mem
, src_mem
, operands
)
499 int align
= INTVAL (operands
[3]);
500 int constp
= (GET_CODE (operands
[2]) == CONST_INT
);
501 int bytes
= (constp
? INTVAL (operands
[2]) : 0);
502 int target
= (int) m88k_cpu
;
504 assert (PROCESSOR_M88100
== 0);
505 assert (PROCESSOR_M88110
== 1);
506 assert (PROCESSOR_M88000
== 2);
508 if (constp
&& bytes
<= 0)
511 /* Determine machine mode to do move with. */
512 if (align
> 4 && !TARGET_88110
)
514 else if (align
<= 0 || align
== 3)
515 abort (); /* block move invalid alignment. */
517 if (constp
&& bytes
<= 3 * align
)
518 block_move_sequence (operands
[0], dest_mem
, operands
[1], src_mem
,
521 else if (constp
&& bytes
<= best_from_align
[target
][align
])
522 block_move_no_loop (operands
[0], dest_mem
, operands
[1], src_mem
,
525 else if (constp
&& align
== 4 && TARGET_88100
)
526 block_move_loop (operands
[0], dest_mem
, operands
[1], src_mem
,
531 #ifdef TARGET_MEM_FUNCTIONS
532 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "memcpy"), 0,
536 convert_to_mode (TYPE_MODE (sizetype
), operands
[2],
537 TREE_UNSIGNED (sizetype
)),
538 TYPE_MODE (sizetype
));
540 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "bcopy"), 0,
544 convert_to_mode (TYPE_MODE (integer_type_node
),
546 TREE_UNSIGNED (integer_type_node
)),
547 TYPE_MODE (integer_type_node
));
552 /* Emit code to perform a block move by calling a looping movstr library
553 function. SIZE and ALIGN are known constants. DEST and SRC are
557 block_move_loop (dest
, dest_mem
, src
, src_mem
, size
, align
)
563 enum machine_mode mode
;
572 /* Determine machine mode to do move with. */
576 /* Determine the structure of the loop. */
577 count
= size
/ MOVSTR_LOOP
;
578 units
= (size
- count
* MOVSTR_LOOP
) / align
;
583 units
+= MOVSTR_LOOP
/ align
;
588 block_move_no_loop (dest
, dest_mem
, src
, src_mem
, size
, align
);
592 remainder
= size
- count
* MOVSTR_LOOP
- units
* align
;
594 mode
= mode_from_align
[align
];
595 sprintf (entry
, "__movstr%s%dn%d",
596 GET_MODE_NAME (mode
), MOVSTR_LOOP
, units
* align
);
597 entry_name
= get_identifier (entry
);
599 offset_rtx
= gen_rtx (CONST_INT
, VOIDmode
,
600 MOVSTR_LOOP
+ (1 - units
) * align
);
602 value_rtx
= gen_rtx (MEM
, MEM_IN_STRUCT_P (src_mem
) ? mode
: BLKmode
,
603 gen_rtx (PLUS
, Pmode
,
604 gen_rtx (REG
, Pmode
, 3),
606 RTX_UNCHANGING_P (value_rtx
) = RTX_UNCHANGING_P (src_mem
);
607 MEM_VOLATILE_P (value_rtx
) = MEM_VOLATILE_P (src_mem
);
608 MEM_IN_STRUCT_P (value_rtx
) = MEM_IN_STRUCT_P (src_mem
);
610 emit_insn (gen_call_movstrsi_loop
611 (gen_rtx (SYMBOL_REF
, Pmode
, IDENTIFIER_POINTER (entry_name
)),
612 dest
, src
, offset_rtx
, value_rtx
,
613 gen_rtx (REG
, mode
, ((units
& 1) ? 4 : 5)),
614 gen_rtx (CONST_INT
, VOIDmode
, count
)));
617 block_move_sequence (gen_rtx (REG
, Pmode
, 2), dest_mem
,
618 gen_rtx (REG
, Pmode
, 3), src_mem
,
619 remainder
, align
, MOVSTR_LOOP
+ align
);
622 /* Emit code to perform a block move by calling a non-looping library
623 function. SIZE and ALIGN are known constants. DEST and SRC are
624 registers. OFFSET is the known starting point for the output pattern. */
627 block_move_no_loop (dest
, dest_mem
, src
, src_mem
, size
, align
)
633 enum machine_mode mode
= mode_from_align
[align
];
634 int units
= size
/ align
;
635 int remainder
= size
- units
* align
;
643 if (remainder
&& size
<= all_from_align
[align
])
645 most
= all_from_align
[align
] - (align
- remainder
);
650 most
= max_from_align
[align
];
653 sprintf (entry
, "__movstr%s%dx%d",
654 GET_MODE_NAME (mode
), most
, size
- remainder
);
655 entry_name
= get_identifier (entry
);
657 offset_rtx
= gen_rtx (CONST_INT
, VOIDmode
, most
- (size
- remainder
));
659 value_rtx
= gen_rtx (MEM
, MEM_IN_STRUCT_P (src_mem
) ? mode
: BLKmode
,
660 gen_rtx (PLUS
, Pmode
,
661 gen_rtx (REG
, Pmode
, 3),
663 RTX_UNCHANGING_P (value_rtx
) = RTX_UNCHANGING_P (src_mem
);
664 MEM_VOLATILE_P (value_rtx
) = MEM_VOLATILE_P (src_mem
);
665 MEM_IN_STRUCT_P (value_rtx
) = MEM_IN_STRUCT_P (src_mem
);
667 value_reg
= ((((most
- (size
- remainder
)) / align
) & 1) == 0
668 ? (align
== 8 ? 6 : 5) : 4);
670 emit_insn (gen_call_block_move
671 (gen_rtx (SYMBOL_REF
, Pmode
, IDENTIFIER_POINTER (entry_name
)),
672 dest
, src
, offset_rtx
, value_rtx
,
673 gen_rtx (REG
, mode
, value_reg
)));
676 block_move_sequence (gen_rtx (REG
, Pmode
, 2), dest_mem
,
677 gen_rtx (REG
, Pmode
, 3), src_mem
,
678 remainder
, align
, most
);
681 /* Emit code to perform a block move with an offset sequence of ld/st
682 instructions (..., ld 0, st 1, ld 1, st 0, ...). SIZE and ALIGN are
683 known constants. DEST and SRC are registers. OFFSET is the known
684 starting point for the output pattern. */
687 block_move_sequence (dest
, dest_mem
, src
, src_mem
, size
, align
, offset
)
695 enum machine_mode mode
[2];
700 int offset_ld
= offset
;
701 int offset_st
= offset
;
703 active
[0] = active
[1] = FALSE
;
705 /* Establish parameters for the first load and for the second load if
706 it is known to be the same mode as the first. */
707 amount
[0] = amount
[1] = align
;
708 mode
[0] = mode_from_align
[align
];
709 temp
[0] = gen_reg_rtx (mode
[0]);
710 if (size
>= 2 * align
)
713 temp
[1] = gen_reg_rtx (mode
[1]);
724 /* Change modes as the sequence tails off. */
725 if (size
< amount
[next
])
727 amount
[next
] = (size
>= 4 ? 4 : (size
>= 2 ? 2 : 1));
728 mode
[next
] = mode_from_align
[amount
[next
]];
729 temp
[next
] = gen_reg_rtx (mode
[next
]);
731 size
-= amount
[next
];
733 MEM_IN_STRUCT_P (src_mem
) ? mode
[next
] : BLKmode
,
734 gen_rtx (PLUS
, Pmode
, src
,
735 gen_rtx (CONST_INT
, SImode
, offset_ld
)));
736 RTX_UNCHANGING_P (srcp
) = RTX_UNCHANGING_P (src_mem
);
737 MEM_VOLATILE_P (srcp
) = MEM_VOLATILE_P (src_mem
);
738 MEM_IN_STRUCT_P (srcp
) = MEM_IN_STRUCT_P (src_mem
);
739 emit_insn (gen_rtx (SET
, VOIDmode
, temp
[next
], srcp
));
740 offset_ld
+= amount
[next
];
746 active
[phase
] = FALSE
;
748 MEM_IN_STRUCT_P (dest_mem
) ? mode
[phase
] : BLKmode
,
749 gen_rtx (PLUS
, Pmode
, dest
,
750 gen_rtx (CONST_INT
, SImode
, offset_st
)));
751 RTX_UNCHANGING_P (dstp
) = RTX_UNCHANGING_P (dest_mem
);
752 MEM_VOLATILE_P (dstp
) = MEM_VOLATILE_P (dest_mem
);
753 MEM_IN_STRUCT_P (dstp
) = MEM_IN_STRUCT_P (dest_mem
);
754 emit_insn (gen_rtx (SET
, VOIDmode
, dstp
, temp
[phase
]));
755 offset_st
+= amount
[phase
];
758 while (active
[next
]);
761 /* Emit the code to do an AND operation. */
764 output_and (operands
)
769 if (REG_P (operands
[2]))
770 return "and %0,%1,%2";
772 value
= INTVAL (operands
[2]);
773 if (SMALL_INTVAL (value
))
774 return "mask %0,%1,%2";
775 else if ((value
& 0xffff0000) == 0xffff0000)
776 return "and %0,%1,%x2";
777 else if ((value
& 0xffff) == 0xffff)
778 return "and.u %0,%1,%X2";
779 else if ((value
& 0xffff) == 0)
780 return "mask.u %0,%1,%X2";
781 else if (integer_ok_for_set (~value
))
782 return "clr %0,%1,%S2";
784 return "and.u %0,%1,%X2\n\tand %0,%0,%x2";
787 /* Emit the code to do an inclusive OR operation. */
790 output_ior (operands
)
795 if (REG_P (operands
[2]))
796 return "or %0,%1,%2";
798 value
= INTVAL (operands
[2]);
799 if (SMALL_INTVAL (value
))
800 return "or %0,%1,%2";
801 else if ((value
& 0xffff) == 0)
802 return "or.u %0,%1,%X2";
803 else if (integer_ok_for_set (value
))
804 return "set %0,%1,%s2";
806 return "or.u %0,%1,%X2\n\tor %0,%0,%x2";
809 /* Emit the instructions for doing an XOR. */
812 output_xor (operands
)
817 if (REG_P (operands
[2]))
818 return "xor %0,%1,%2";
820 value
= INTVAL (operands
[2]);
821 if (SMALL_INTVAL (value
))
822 return "xor %0,%1,%2";
823 else if ((value
& 0xffff) == 0)
824 return "xor.u %0,%1,%X2";
826 return "xor.u %0,%1,%X2\n\txor %0,%0,%x2";
829 /* Output a call. Normally this is just bsr or jsr, but this also deals with
830 accomplishing a branch after the call by incrementing r1. This requires
831 that various assembler bugs be accommodated. The 4.30 DG/UX assembler
832 requires that forward references not occur when computing the difference of
833 two labels. The [version?] Motorola assembler computes a word difference.
834 No doubt there's more to come!
836 It would seem the same idea could be used to tail call, but in this case,
837 the epilogue will be non-null. */
839 static rtx sb_name
= 0;
840 static rtx sb_high
= 0;
841 static rtx sb_low
= 0;
844 output_call (operands
, addr
)
854 /* This can be generalized, but there is currently no need. */
855 if (XVECLEN (final_sequence
, 0) != 2)
858 /* The address of interior insns is not computed, so use the sequence. */
859 seq_insn
= NEXT_INSN (PREV_INSN (XVECEXP (final_sequence
, 0, 0)));
860 jump
= XVECEXP (final_sequence
, 0, 1);
861 if (GET_CODE (jump
) == JUMP_INSN
)
865 rtx dest
= XEXP (SET_SRC (PATTERN (jump
)), 0);
866 int delta
= 4 * (insn_addresses
[INSN_UID (dest
)]
867 - insn_addresses
[INSN_UID (seq_insn
)]
869 #if (MONITOR_GCC & 0x2) /* How often do long branches happen? */
870 if ((unsigned) (delta
+ 0x8000) >= 0x10000)
871 warning ("Internal gcc monitor: short-branch(%x)", delta
);
874 /* Delete the jump. */
875 PUT_CODE (jump
, NOTE
);
876 NOTE_LINE_NUMBER (jump
) = NOTE_INSN_DELETED
;
877 NOTE_SOURCE_FILE (jump
) = 0;
879 /* We only do this optimization if -O2, modifying the value of
880 r1 in the delay slot confuses debuggers and profilers on some
883 If we loose, we must use the non-delay form. This is unlikely
884 to ever happen. If it becomes a problem, claim that a call
885 has two delay slots and only the second can be filled with
888 The 88110 can lose when a jsr.n r1 is issued and a page fault
889 occurs accessing the delay slot. So don't use jsr.n form when
892 #ifdef AS_BUG_IMMEDIATE_LABEL /* The assembler restricts immediate values. */
894 || ! ADD_INTVAL (delta
* 2)
897 || ! ADD_INTVAL (delta
)
899 || (REG_P (addr
) && REGNO (addr
) == 1))
905 ? "bsr %0#plt\n\tbr %l1"
906 : "bsr %0\n\tbr %l1"));
909 /* Output the short branch form. */
910 output_asm_insn ((REG_P (addr
)
912 : (flag_pic
? "bsr.n %0#plt" : "bsr.n %0")),
917 ? "subu %#r1,%#r1,.-%l0+4"
918 : "addu %#r1,%#r1,%l0-.-4");
921 operands
[0] = gen_label_rtx ();
922 operands
[1] = gen_label_rtx ();
927 last
= "subu %#r1,%#r1,%l0\n%l1:";
933 last
= "addu %#r1,%#r1,%l0\n%l1:";
936 /* Record the values to be computed later as "def name,high-low". */
937 sb_name
= gen_rtx (EXPR_LIST
, VOIDmode
, operands
[0], sb_name
);
938 sb_high
= gen_rtx (EXPR_LIST
, VOIDmode
, high
, sb_high
);
939 sb_low
= gen_rtx (EXPR_LIST
, VOIDmode
, low
, sb_low
);
940 #endif /* Don't USE_GAS */
947 : (flag_pic
? "bsr%. %0#plt" : "bsr%. %0"));
951 output_short_branch_defs (stream
)
954 char name
[256], high
[256], low
[256];
956 for (; sb_name
&& sb_high
&& sb_low
;
957 sb_name
= XEXP (sb_name
, 1),
958 sb_high
= XEXP (sb_high
, 1),
959 sb_low
= XEXP (sb_low
, 1))
961 ASM_GENERATE_INTERNAL_LABEL
962 (name
, "L", CODE_LABEL_NUMBER (XEXP (sb_name
, 0)));
963 ASM_GENERATE_INTERNAL_LABEL
964 (high
, "L", CODE_LABEL_NUMBER (XEXP (sb_high
, 0)));
965 ASM_GENERATE_INTERNAL_LABEL
966 (low
, "L", CODE_LABEL_NUMBER (XEXP (sb_low
, 0)));
967 /* This will change as the assembler requirements become known. */
968 fprintf (stream
, "\t%s\t %s,%s-%s\n",
969 SET_ASM_OP
, &name
[1], &high
[1], &low
[1]);
971 if (sb_name
|| sb_high
|| sb_low
)
975 /* Return truth value of the statement that this conditional branch is likely
976 to fall through. CONDITION, is the condition that JUMP_INSN is testing. */
979 mostly_false_jump (jump_insn
, condition
)
980 rtx jump_insn
, condition
;
982 rtx target_label
= JUMP_LABEL (jump_insn
);
985 /* Much of this isn't computed unless we're optimizing. */
989 /* Determine if one path or the other leads to a return. */
990 for (insnt
= NEXT_INSN (target_label
);
992 insnt
= NEXT_INSN (insnt
))
994 if (GET_CODE (insnt
) == JUMP_INSN
)
996 else if (GET_CODE (insnt
) == INSN
997 && GET_CODE (PATTERN (insnt
)) == SEQUENCE
998 && GET_CODE (XVECEXP (PATTERN (insnt
), 0, 0)) == JUMP_INSN
)
1000 insnt
= XVECEXP (PATTERN (insnt
), 0, 0);
1005 && (GET_CODE (PATTERN (insnt
)) == RETURN
1006 || (GET_CODE (PATTERN (insnt
)) == SET
1007 && GET_CODE (SET_SRC (PATTERN (insnt
))) == REG
1008 && REGNO (SET_SRC (PATTERN (insnt
))) == 1)))
1011 for (insnj
= NEXT_INSN (jump_insn
);
1013 insnj
= NEXT_INSN (insnj
))
1015 if (GET_CODE (insnj
) == JUMP_INSN
)
1017 else if (GET_CODE (insnj
) == INSN
1018 && GET_CODE (PATTERN (insnj
)) == SEQUENCE
1019 && GET_CODE (XVECEXP (PATTERN (insnj
), 0, 0)) == JUMP_INSN
)
1021 insnj
= XVECEXP (PATTERN (insnj
), 0, 0);
1026 && (GET_CODE (PATTERN (insnj
)) == RETURN
1027 || (GET_CODE (PATTERN (insnj
)) == SET
1028 && GET_CODE (SET_SRC (PATTERN (insnj
))) == REG
1029 && REGNO (SET_SRC (PATTERN (insnj
))) == 1)))
1032 /* Predict to not return. */
1033 if ((insnt
== 0) != (insnj
== 0))
1034 return (insnt
== 0);
1036 /* Predict loops to loop. */
1037 for (insnt
= PREV_INSN (target_label
);
1038 insnt
&& GET_CODE (insnt
) == NOTE
;
1039 insnt
= PREV_INSN (insnt
))
1040 if (NOTE_LINE_NUMBER (insnt
) == NOTE_INSN_LOOP_END
)
1042 else if (NOTE_LINE_NUMBER (insnt
) == NOTE_INSN_LOOP_BEG
)
1044 else if (NOTE_LINE_NUMBER (insnt
) == NOTE_INSN_LOOP_CONT
)
1047 /* Predict backward branches usually take. */
1049 insnj
= NEXT_INSN (PREV_INSN (XVECEXP (final_sequence
, 0, 0)));
1052 if (insn_addresses
[INSN_UID (insnj
)]
1053 > insn_addresses
[INSN_UID (target_label
)])
1056 /* EQ tests are usually false and NE tests are usually true. Also,
1057 most quantities are positive, so we can make the appropriate guesses
1058 about signed comparisons against zero. Consider unsigned comparisons
1059 to be a range check and assume quantities to be in range. */
1060 switch (GET_CODE (condition
))
1063 /* Unconditional branch. */
1072 case GTU
: /* Must get casesi right at least. */
1073 if (XEXP (condition
, 1) == const0_rtx
)
1080 if (XEXP (condition
, 1) == const0_rtx
)
1088 /* Return true if the operand is a power of two and is a floating
1089 point type (to optimize division by power of two into multiplication). */
1092 real_power_of_2_operand (op
, mode
)
1094 enum machine_mode mode
;
1098 int i
[sizeof (REAL_VALUE_TYPE
) / sizeof (int)];
1099 struct { /* IEEE double precision format */
1101 unsigned exponent
: 11;
1102 unsigned mantissa1
: 20;
1105 struct { /* IEEE double format to quick check */
1106 unsigned sign
: 1; /* if it fits in a float */
1107 unsigned exponent1
: 4;
1108 unsigned exponent2
: 7;
1109 unsigned mantissa1
: 20;
1114 if (GET_MODE (op
) != DFmode
&& GET_MODE (op
) != SFmode
)
1117 if (GET_CODE (op
) != CONST_DOUBLE
)
1120 u
.i
[0] = CONST_DOUBLE_LOW (op
);
1121 u
.i
[1] = CONST_DOUBLE_HIGH (op
);
1123 if (u
.s
.mantissa1
!= 0 || u
.s
.mantissa2
!= 0 /* not a power of two */
1124 || u
.s
.exponent
== 0 /* constant 0.0 */
1125 || u
.s
.exponent
== 0x7ff /* NAN */
1126 || (u
.s2
.exponent1
!= 0x8 && u
.s2
.exponent1
!= 0x7))
1127 return 0; /* const won't fit in float */
1132 /* Make OP legitimate for mode MODE. Currently this only deals with DFmode
1133 operands, putting them in registers and making CONST_DOUBLE values
1134 SFmode where possible. */
1137 legitimize_operand (op
, mode
)
1139 enum machine_mode mode
;
1143 union real_extract r
;
1144 struct { /* IEEE double precision format */
1146 unsigned exponent
: 11;
1147 unsigned mantissa1
: 20;
1150 struct { /* IEEE double format to quick check */
1151 unsigned sign
: 1; /* if it fits in a float */
1152 unsigned exponent1
: 4;
1153 unsigned exponent2
: 7;
1154 unsigned mantissa1
: 20;
1159 if (GET_CODE (op
) == REG
|| mode
!= DFmode
)
1162 if (GET_CODE (op
) == CONST_DOUBLE
)
1164 bcopy (&CONST_DOUBLE_LOW (op
), &u
.r
, sizeof u
);
1165 if (u
.d
.exponent
!= 0x7ff /* NaN */
1166 && u
.d
.mantissa2
== 0 /* Mantissa fits */
1167 && (u
.s
.exponent1
== 0x8 || u
.s
.exponent1
== 0x7) /* Exponent fits */
1168 && (temp
= simplify_unary_operation (FLOAT_TRUNCATE
, SFmode
,
1170 return gen_rtx (FLOAT_EXTEND
, mode
, force_reg (SFmode
, temp
));
1172 else if (register_operand (op
, mode
))
1175 return force_reg (mode
, op
);
1178 /* Return true if OP is a suitable input for a move insn. */
1181 move_operand (op
, mode
)
1183 enum machine_mode mode
;
1185 if (register_operand (op
, mode
))
1187 if (GET_CODE (op
) == CONST_INT
)
1188 return (classify_integer (mode
, INTVAL (op
)) < m88k_oru_hi16
);
1189 if (GET_MODE (op
) != mode
)
1191 if (GET_CODE (op
) == SUBREG
)
1192 op
= SUBREG_REG (op
);
1193 if (GET_CODE (op
) != MEM
)
1197 if (GET_CODE (op
) == LO_SUM
)
1198 return (REG_P (XEXP (op
, 0))
1199 && symbolic_address_p (XEXP (op
, 1)));
1200 return memory_address_p (mode
, op
);
1203 /* Return true if OP is suitable for a call insn. */
1206 call_address_operand (op
, mode
)
1208 enum machine_mode mode
;
1210 return (REG_P (op
) || symbolic_address_p (op
));
1213 /* Returns true if OP is either a symbol reference or a sum of a symbol
1214 reference and a constant. */
1217 symbolic_address_p (op
)
1220 switch (GET_CODE (op
))
1228 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1229 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1230 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1237 /* Return true if OP is a register or const0_rtx. */
1240 reg_or_0_operand (op
, mode
)
1242 enum machine_mode mode
;
1244 return (op
== const0_rtx
|| register_operand (op
, mode
));
1247 /* Nonzero if OP is a valid second operand for an arithmetic insn. */
1250 arith_operand (op
, mode
)
1252 enum machine_mode mode
;
1254 return (register_operand (op
, mode
)
1255 || (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
)));
1258 /* Return true if OP is a register or 5 bit integer. */
1261 arith5_operand (op
, mode
)
1263 enum machine_mode mode
;
1265 return (register_operand (op
, mode
)
1266 || (GET_CODE (op
) == CONST_INT
&& (unsigned) INTVAL (op
) < 32));
1270 arith32_operand (op
, mode
)
1272 enum machine_mode mode
;
1274 return (register_operand (op
, mode
) || GET_CODE (op
) == CONST_INT
);
1278 arith64_operand (op
, mode
)
1280 enum machine_mode mode
;
1282 return (register_operand (op
, mode
)
1283 || GET_CODE (op
) == CONST_INT
1284 || (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
));
1288 int5_operand (op
, mode
)
1290 enum machine_mode mode
;
1292 return (GET_CODE (op
) == CONST_INT
&& (unsigned) INTVAL (op
) < 32);
1296 int32_operand (op
, mode
)
1298 enum machine_mode mode
;
1300 return (GET_CODE (op
) == CONST_INT
);
1303 /* Return true if OP is a register or a valid immediate operand for
1307 add_operand (op
, mode
)
1309 enum machine_mode mode
;
1311 return (register_operand (op
, mode
)
1312 || (GET_CODE (op
) == CONST_INT
&& ADD_INT (op
)));
1315 /* Nonzero if this is a bitmask filling the bottom bits, for optimizing and +
1316 shift left combinations into a single mak instruction. */
1322 return (value
&& POWER_OF_2_or_0 (value
+ 1));
1326 reg_or_bbx_mask_operand (op
, mode
)
1328 enum machine_mode mode
;
1331 if (register_operand (op
, mode
))
1333 if (GET_CODE (op
) != CONST_INT
)
1336 value
= INTVAL (op
);
1337 if (POWER_OF_2 (value
))
1343 /* Return true if OP is valid to use in the context of a floating
1344 point operation. Special case 0.0, since we can use r0. */
1347 real_or_0_operand (op
, mode
)
1349 enum machine_mode mode
;
1351 if (mode
!= SFmode
&& mode
!= DFmode
)
1354 return (register_operand (op
, mode
)
1355 || (GET_CODE (op
) == CONST_DOUBLE
1356 && op
== CONST0_RTX (mode
)));
1359 /* Return true if OP is valid to use in the context of logic arithmetic
1360 on condition codes. */
1363 partial_ccmode_register_operand (op
, mode
)
1365 enum machine_mode mode
;
1367 return register_operand (op
, CCmode
) || register_operand (op
, CCEVENmode
);
1370 /* Return true if OP is a relational operator. */
1375 enum machine_mode mode
;
1377 switch (GET_CODE (op
))
1396 even_relop (op
, mode
)
1398 enum machine_mode mode
;
1400 switch (GET_CODE (op
))
1414 odd_relop (op
, mode
)
1416 enum machine_mode mode
;
1418 switch (GET_CODE (op
))
1431 /* Return true if OP is a relational operator, and is not an unsigned
1432 relational operator. */
1435 relop_no_unsigned (op
, mode
)
1437 enum machine_mode mode
;
1439 switch (GET_CODE (op
))
1447 /* @@ What is this test doing? Why not use `mode'? */
1448 if (GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
1449 || GET_MODE (op
) == DImode
1450 || GET_MODE_CLASS (GET_MODE (XEXP (op
, 0))) == MODE_FLOAT
1451 || GET_MODE (XEXP (op
, 0)) == DImode
1452 || GET_MODE_CLASS (GET_MODE (XEXP (op
, 1))) == MODE_FLOAT
1453 || GET_MODE (XEXP (op
, 1)) == DImode
)
1461 /* Return true if the code of this rtx pattern is EQ or NE. */
1464 equality_op (op
, mode
)
1466 enum machine_mode mode
;
1468 return (GET_CODE (op
) == EQ
|| GET_CODE (op
) == NE
);
1471 /* Return true if the code of this rtx pattern is pc or label_ref. */
1474 pc_or_label_ref (op
, mode
)
1476 enum machine_mode mode
;
1478 return (GET_CODE (op
) == PC
|| GET_CODE (op
) == LABEL_REF
);
1481 /* Output to FILE the start of the assembler file. */
1491 output_option (file
, sep
, type
, name
, indent
, pos
, max
)
1500 if (strlen (sep
) + strlen (type
) + strlen (name
) + pos
> max
)
1502 fprintf (file
, indent
);
1503 return fprintf (file
, "%s%s", type
, name
);
1505 return pos
+ fprintf (file
, "%s%s%s", sep
, type
, name
);
1508 static struct { char *name
; int value
; } m_options
[] = TARGET_SWITCHES
;
1511 output_options (file
, f_options
, f_len
, W_options
, W_len
,
1512 pos
, max
, sep
, indent
, term
)
1514 struct options
*f_options
;
1515 struct options
*W_options
;
1525 pos
= output_option (file
, sep
, "-O", "", indent
, pos
, max
);
1526 if (write_symbols
!= NO_DEBUG
)
1527 pos
= output_option (file
, sep
, "-g", "", indent
, pos
, max
);
1528 if (flag_traditional
)
1529 pos
= output_option (file
, sep
, "-traditional", "", indent
, pos
, max
);
1531 pos
= output_option (file
, sep
, "-p", "", indent
, pos
, max
);
1532 if (profile_block_flag
)
1533 pos
= output_option (file
, sep
, "-a", "", indent
, pos
, max
);
1535 for (j
= 0; j
< f_len
; j
++)
1536 if (*f_options
[j
].variable
== f_options
[j
].on_value
)
1537 pos
= output_option (file
, sep
, "-f", f_options
[j
].string
,
1540 for (j
= 0; j
< W_len
; j
++)
1541 if (*W_options
[j
].variable
== W_options
[j
].on_value
)
1542 pos
= output_option (file
, sep
, "-W", W_options
[j
].string
,
1545 for (j
= 0; j
< sizeof m_options
/ sizeof m_options
[0]; j
++)
1546 if (m_options
[j
].name
[0] != '\0'
1547 && m_options
[j
].value
> 0
1548 && ((m_options
[j
].value
& target_flags
)
1549 == m_options
[j
].value
))
1550 pos
= output_option (file
, sep
, "-m", m_options
[j
].name
,
1553 if (m88k_short_data
)
1554 pos
= output_option (file
, sep
, "-mshort-data-", m88k_short_data
,
1557 fprintf (file
, term
);
1561 output_file_start (file
, f_options
, f_len
, W_options
, W_len
)
1563 struct options
*f_options
;
1564 struct options
*W_options
;
1569 ASM_FIRST_LINE (file
);
1572 fprintf (file
, "\t%s\n", REQUIRES_88110_ASM_OP
);
1573 output_file_directive (file
, main_input_filename
);
1574 /* Switch to the data section so that the coffsem symbol and the
1575 gcc2_compiled. symbol aren't in the text section. */
1579 if (TARGET_IDENTIFY_REVISION
)
1583 time_t now
= time ((time_t *)0);
1584 sprintf (indent
, "]\"\n\t%s\t \"@(#)%s [", IDENT_ASM_OP
, main_input_filename
);
1585 fprintf (file
, indent
+3);
1586 pos
= fprintf (file
, "gcc %s, %.24s,", VERSION_STRING
, ctime (&now
));
1588 /* ??? It would be nice to call print_switch_values here (and thereby
1589 let us delete output_options) but this is kept in until it is known
1590 whether the change in content format matters. */
1591 output_options (file
, f_options
, f_len
, W_options
, W_len
,
1592 pos
, 150 - strlen (indent
), " ", indent
, "]\"\n\n");
1594 fprintf (file
, "]\"\n");
1595 print_switch_values (file
, 0, 150 - strlen (indent
),
1596 indent
+ 3, " ", "]\"\n");
1601 /* Output an ascii string. */
1604 output_ascii (file
, opcode
, max
, p
, size
)
1614 register int num
= 0;
1616 fprintf (file
, "\t%s\t \"", opcode
);
1617 for (i
= 0; i
< size
; i
++)
1619 register int c
= p
[i
];
1623 fprintf (file
, "\"\n\t%s\t \"", opcode
);
1627 if (c
== '\"' || c
== '\\')
1635 else if (in_escape
&& c
>= '0' && c
<= '9')
1637 /* If a digit follows an octal-escape, the Vax assembler fails
1638 to stop reading the escape after three digits. Continue to
1639 output the values as an octal-escape until a non-digit is
1641 fprintf (file
, "\\%03o", c
);
1644 else if ((c
>= ' ' && c
< 0177) || (c
== '\t'))
1654 /* Some assemblers can't handle \a, \v, or \?. */
1655 case '\f': c
= 'f'; goto escape
;
1656 case '\b': c
= 'b'; goto escape
;
1657 case '\r': c
= 'r'; goto escape
;
1658 case '\n': c
= 'n'; goto escape
;
1661 fprintf (file
, "\\%03o", c
);
1666 fprintf (file
, "\"\n");
1669 /* Output a label (allows insn-output.c to be compiled without including
1670 m88k.c or needing to include stdio.h). */
1673 output_label (label_number
)
1676 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L", label_number
);
1679 /* Generate the assembly code for function entry.
1681 The prologue is responsible for setting up the stack frame,
1682 initializing the frame pointer register, saving registers that must be
1683 saved, and allocating SIZE additional bytes of storage for the
1684 local variables. SIZE is an integer. FILE is a stdio
1685 stream to which the assembler code should be output.
1687 The label for the beginning of the function need not be output by this
1688 macro. That has already been done when the macro is run.
1690 To determine which registers to save, the macro can refer to the array
1691 `regs_ever_live': element R is nonzero if hard register
1692 R is used anywhere within the function. This implies the
1693 function prologue should save register R, but not if it is one
1694 of the call-used registers.
1696 On machines where functions may or may not have frame-pointers, the
1697 function entry code must vary accordingly; it must set up the frame
1698 pointer if one is wanted, and not otherwise. To determine whether a
1699 frame pointer is in wanted, the macro can refer to the variable
1700 `frame_pointer_needed'. The variable's value will be 1 at run
1701 time in a function that needs a frame pointer.
1703 On machines where an argument may be passed partly in registers and
1704 partly in memory, this macro must examine the variable
1705 `current_function_pretend_args_size', and allocate that many bytes
1706 of uninitialized space on the stack just underneath the first argument
1707 arriving on the stack. (This may not be at the very end of the stack,
1708 if the calling sequence has pushed anything else since pushing the stack
1709 arguments. But usually, on such machines, nothing else has been pushed
1710 yet, because the function prologue itself does all the pushing.)
1712 If `ACCUMULATE_OUTGOING_ARGS' is defined, the variable
1713 `current_function_outgoing_args_size' contains the size in bytes
1714 required for the outgoing arguments. This macro must add that
1715 amount of uninitialized space to very bottom of the stack.
1717 The stack frame we use looks like this:
1720 |==============================================|
1722 |==============================================|
1723 | [caller's outgoing memory arguments] |
1724 |==============================================|
1725 | caller's outgoing argument area (32 bytes) |
1726 sp -> |==============================================| <- ap
1727 | [local variable space] |
1728 |----------------------------------------------|
1729 | [return address (r1)] |
1730 |----------------------------------------------|
1731 | [previous frame pointer (r30)] |
1732 |==============================================| <- fp
1733 | [preserved registers (r25..r14)] |
1734 |----------------------------------------------|
1735 | [preserved registers (x29..x22)] |
1736 |==============================================|
1737 | [dynamically allocated space (alloca)] |
1738 |==============================================|
1739 | [callee's outgoing memory arguments] |
1740 |==============================================|
1741 | [callee's outgoing argument area (32 bytes)] |
1742 |==============================================| <- sp
1746 r1 and r30 must be saved if debugging.
1748 fp (if present) is located two words down from the local
1752 static void emit_add ();
1753 static void preserve_registers ();
1754 static void emit_ldst ();
1755 static void output_tdesc ();
1759 static char save_regs
[FIRST_PSEUDO_REGISTER
];
1760 static int frame_laid_out
;
1761 static int frame_size
;
1762 static int variable_args_p
;
1763 static int epilogue_marked
;
1764 static int prologue_marked
;
1766 extern char call_used_regs
[];
1767 extern int current_function_pretend_args_size
;
1768 extern int current_function_outgoing_args_size
;
1769 extern int frame_pointer_needed
;
1771 #define FIRST_OCS_PRESERVE_REGISTER 14
1772 #define LAST_OCS_PRESERVE_REGISTER 30
1774 #define FIRST_OCS_EXTENDED_PRESERVE_REGISTER (32 + 22)
1775 #define LAST_OCS_EXTENDED_PRESERVE_REGISTER (32 + 31)
1777 #define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
1778 #define ROUND_CALL_BLOCK_SIZE(BYTES) \
1779 (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
1781 /* Establish the position of the FP relative to the SP. This is done
1782 either during FUNCTION_PROLOGUE or by INITIAL_ELIMINATION_OFFSET. */
1785 m88k_layout_frame ()
1791 bzero ((char *) &save_regs
[0], sizeof (save_regs
));
1792 sp_size
= nregs
= nxregs
= 0;
1793 frame_size
= get_frame_size ();
1795 /* Since profiling requires a call, make sure r1 is saved. */
1796 if (profile_flag
|| profile_block_flag
)
1799 /* If we are producing debug information, store r1 and r30 where the
1800 debugger wants to find them (r30 at r30+0, r1 at r30+4). Space has
1801 already been reserved for r1/r30 in STARTING_FRAME_OFFSET. */
1802 if (write_symbols
!= NO_DEBUG
&& !TARGET_OCS_FRAME_POSITION
)
1805 /* If there is a call, alloca is used, __builtin_alloca is used, or
1806 a dynamic-sized object is defined, add the 8 additional words
1807 for the callee's argument area. The common denominator is that the
1808 FP is required. may_call_alloca only gets calls to alloca;
1809 current_function_calls_alloca gets alloca and __builtin_alloca. */
1810 if (regs_ever_live
[1] || frame_pointer_needed
)
1813 sp_size
+= REG_PARM_STACK_SPACE (0);
1816 /* If we are producing PIC, save the addressing base register and r1. */
1817 if (flag_pic
&& current_function_uses_pic_offset_table
)
1819 save_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
1823 /* If a frame is requested, save the previous FP, and the return
1824 address (r1), so that a traceback can be done without using tdesc
1825 information. Otherwise, simply save the FP if it is used as
1826 a preserve register. */
1827 if (frame_pointer_needed
)
1828 save_regs
[FRAME_POINTER_REGNUM
] = save_regs
[1] = 1;
1829 else if (regs_ever_live
[FRAME_POINTER_REGNUM
])
1830 save_regs
[FRAME_POINTER_REGNUM
] = 1;
1832 /* Figure out which extended register(s) needs to be saved. */
1833 for (regno
= FIRST_EXTENDED_REGISTER
+ 1; regno
< FIRST_PSEUDO_REGISTER
;
1835 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
1837 save_regs
[regno
] = 1;
1841 /* Figure out which normal register(s) needs to be saved. */
1842 for (regno
= 2; regno
< FRAME_POINTER_REGNUM
; regno
++)
1843 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
1845 save_regs
[regno
] = 1;
1849 /* Achieve greatest use of double memory ops. Either we end up saving
1850 r30 or we use that slot to align the registers we do save. */
1851 if (nregs
>= 2 && save_regs
[1] && !save_regs
[FRAME_POINTER_REGNUM
])
1854 nregs
+= save_regs
[1] + save_regs
[FRAME_POINTER_REGNUM
];
1855 /* if we need to align extended registers, add a word */
1856 if (nxregs
> 0 && (nregs
& 1) != 0)
1858 sp_size
+= 4 * nregs
;
1859 sp_size
+= 8 * nxregs
;
1860 sp_size
+= current_function_outgoing_args_size
;
1862 /* The first two saved registers are placed above the new frame pointer
1863 if any. In the only case this matters, they are r1 and r30. */
1864 if (frame_pointer_needed
|| sp_size
)
1865 m88k_fp_offset
= ROUND_CALL_BLOCK_SIZE (sp_size
- STARTING_FRAME_OFFSET
);
1867 m88k_fp_offset
= -STARTING_FRAME_OFFSET
;
1868 m88k_stack_size
= m88k_fp_offset
+ STARTING_FRAME_OFFSET
;
1870 /* First, combine m88k_stack_size and size. If m88k_stack_size is
1871 non-zero, align the frame size to 8 mod 16; otherwise align the
1872 frame size to 0 mod 16. (If stacks are 8 byte aligned, this ends
1876 = ((m88k_stack_size
? STACK_UNIT_BOUNDARY
- STARTING_FRAME_OFFSET
: 0)
1877 - (frame_size
% STACK_UNIT_BOUNDARY
));
1881 need
+= STACK_UNIT_BOUNDARY
;
1882 (void) assign_stack_local (BLKmode
, need
, BITS_PER_UNIT
);
1883 frame_size
= get_frame_size ();
1886 = ROUND_CALL_BLOCK_SIZE (m88k_stack_size
+ frame_size
1887 + current_function_pretend_args_size
);
1891 /* Return true if this function is known to have a null prologue. */
1896 if (! reload_completed
)
1898 if (! frame_laid_out
)
1899 m88k_layout_frame ();
1900 return (! frame_pointer_needed
1903 && m88k_stack_size
== 0);
1906 /* Determine if the current function has any references to the arg pointer.
1907 This is done indirectly by examining the DECL_ARGUMENTS' DECL_RTL.
1908 It is OK to return TRUE if there are no references, but FALSE must be
1916 if (current_function_decl
== 0
1917 || current_function_varargs
1921 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1923 parm
= TREE_CHAIN (parm
))
1925 if (DECL_RTL (parm
) == 0
1926 || GET_CODE (DECL_RTL (parm
)) == MEM
)
1929 if (DECL_INCOMING_RTL (parm
) == 0
1930 || GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
1937 m88k_begin_prologue (stream
, size
)
1941 if (TARGET_OMIT_LEAF_FRAME_POINTER
&& ! quiet_flag
&& leaf_function_p ())
1942 fprintf (stderr
, "$");
1944 m88k_prologue_done
= 1; /* it's ok now to put out ln directives */
1948 m88k_end_prologue (stream
)
1951 if (TARGET_OCS_DEBUG_INFO
&& !prologue_marked
)
1953 PUT_OCS_FUNCTION_START (stream
);
1954 prologue_marked
= 1;
1956 /* If we've already passed the start of the epilogue, say that
1957 it starts here. This marks the function as having a null body,
1958 but at a point where the return address is in a known location.
1960 Originally, I thought this couldn't happen, but the pic prologue
1961 for leaf functions ends with the instruction that restores the
1962 return address from the temporary register. If the temporary
1963 register is never used, that instruction can float all the way
1964 to the end of the function. */
1965 if (epilogue_marked
)
1966 PUT_OCS_FUNCTION_END (stream
);
1971 m88k_expand_prologue ()
1973 m88k_layout_frame ();
1975 if (TARGET_OPTIMIZE_ARG_AREA
1977 && ! uses_arg_area_p ())
1979 /* The incoming argument area is used for stack space if it is not
1980 used (or if -mno-optimize-arg-area is given). */
1981 if ((m88k_stack_size
-= REG_PARM_STACK_SPACE (0)) < 0)
1982 m88k_stack_size
= 0;
1985 if (m88k_stack_size
)
1986 emit_add (stack_pointer_rtx
, stack_pointer_rtx
, -m88k_stack_size
);
1988 if (nregs
|| nxregs
)
1989 preserve_registers (m88k_fp_offset
+ 4, 1);
1991 if (frame_pointer_needed
)
1992 emit_add (frame_pointer_rtx
, stack_pointer_rtx
, m88k_fp_offset
);
1994 if (flag_pic
&& save_regs
[PIC_OFFSET_TABLE_REGNUM
])
1996 rtx return_reg
= gen_rtx (REG
, SImode
, 1);
1997 rtx label
= gen_label_rtx ();
2002 temp_reg
= gen_rtx (REG
, SImode
, TEMP_REGNUM
);
2003 emit_move_insn (temp_reg
, return_reg
);
2005 emit_insn (gen_locate1 (pic_offset_table_rtx
, label
));
2006 emit_insn (gen_locate2 (pic_offset_table_rtx
, label
));
2007 emit_insn (gen_addsi3 (pic_offset_table_rtx
,
2008 pic_offset_table_rtx
, return_reg
));
2010 emit_move_insn (return_reg
, temp_reg
);
2012 if (profile_flag
|| profile_block_flag
)
2013 emit_insn (gen_blockage ());
2016 /* This function generates the assembly code for function exit,
2017 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
2019 The function epilogue should not depend on the current stack pointer!
2020 It should use the frame pointer only, if there is a frame pointer.
2021 This is mandatory because of alloca; we also take advantage of it to
2022 omit stack adjustments before returning. */
2025 m88k_begin_epilogue (stream
)
2028 if (TARGET_OCS_DEBUG_INFO
&& !epilogue_marked
&& prologue_marked
)
2030 PUT_OCS_FUNCTION_END (stream
);
2032 epilogue_marked
= 1;
2036 m88k_end_epilogue (stream
, size
)
2040 rtx insn
= get_last_insn ();
2042 if (TARGET_OCS_DEBUG_INFO
&& !epilogue_marked
)
2043 PUT_OCS_FUNCTION_END (stream
);
2045 /* If the last insn isn't a BARRIER, we must write a return insn. This
2046 should only happen if the function has no prologue and no body. */
2047 if (GET_CODE (insn
) == NOTE
)
2048 insn
= prev_nonnote_insn (insn
);
2049 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
2050 fprintf (stream
, "\tjmp\t %s\n", reg_names
[1]);
2052 /* If the last insn is a barrier, and the insn before that is a call,
2053 then add a nop instruction so that tdesc can walk the stack correctly
2054 even though there is no epilogue. (Otherwise, the label for the
2055 end of the tdesc region ends up at the start of the next function. */
2056 if (insn
&& GET_CODE (insn
) == BARRIER
)
2058 insn
= prev_nonnote_insn (insn
);
2059 if (insn
&& GET_CODE (insn
) == CALL_INSN
)
2060 fprintf (stream
, "\tor\t %s,%s,%s\n",reg_names
[0],reg_names
[0],reg_names
[0]);
2063 output_short_branch_defs (stream
);
2065 fprintf (stream
, "\n");
2067 if (TARGET_OCS_DEBUG_INFO
)
2068 output_tdesc (stream
, m88k_fp_offset
+ 4);
2070 m88k_function_number
++;
2071 m88k_prologue_done
= 0; /* don't put out ln directives */
2072 variable_args_p
= 0; /* has variable args */
2074 epilogue_marked
= 0;
2075 prologue_marked
= 0;
2079 m88k_expand_epilogue ()
2081 #if (MONITOR_GCC & 0x4) /* What are interesting prologue/epilogue values? */
2082 fprintf (stream
, "; size = %d, m88k_fp_offset = %d, m88k_stack_size = %d\n",
2083 size
, m88k_fp_offset
, m88k_stack_size
);
2086 if (frame_pointer_needed
)
2087 emit_add (stack_pointer_rtx
, frame_pointer_rtx
, -m88k_fp_offset
);
2089 if (nregs
|| nxregs
)
2090 preserve_registers (m88k_fp_offset
+ 4, 0);
2092 if (m88k_stack_size
)
2093 emit_add (stack_pointer_rtx
, stack_pointer_rtx
, m88k_stack_size
);
2096 /* Emit insns to set DSTREG to SRCREG + AMOUNT during the prologue or
2100 emit_add (dstreg
, srcreg
, amount
)
2105 rtx incr
= gen_rtx (CONST_INT
, VOIDmode
, abs (amount
));
2106 if (! ADD_INTVAL (amount
))
2108 rtx temp
= gen_rtx (REG
, SImode
, TEMP_REGNUM
);
2109 emit_move_insn (temp
, incr
);
2112 emit_insn ((amount
< 0 ? gen_subsi3
: gen_addsi3
) (dstreg
, srcreg
, incr
));
2115 /* Save/restore the preserve registers. base is the highest offset from
2116 r31 at which a register is stored. store_p is true if stores are to
2117 be done; otherwise loads. */
2120 preserve_registers (base
, store_p
)
2129 } mem_op
[FIRST_PSEUDO_REGISTER
];
2130 struct mem_op
*mo_ptr
= mem_op
;
2132 /* The 88open OCS mandates that preserved registers be stored in
2133 increasing order. For compatibility with current practice,
2134 the order is r1, r30, then the preserve registers. */
2139 /* An extra word is given in this case to make best use of double
2141 if (nregs
> 2 && !save_regs
[FRAME_POINTER_REGNUM
])
2143 emit_ldst (store_p
, 1, SImode
, offset
);
2148 /* Walk the registers to save recording all single memory operations. */
2149 for (regno
= FRAME_POINTER_REGNUM
; regno
> 1; regno
--)
2150 if (save_regs
[regno
])
2152 if ((offset
& 7) != 4 || (regno
& 1) != 1 || !save_regs
[regno
-1])
2155 mo_ptr
->regno
= regno
;
2156 mo_ptr
->offset
= offset
;
2167 /* Walk the registers to save recording all double memory operations.
2168 This avoids a delay in the epilogue (ld.d/ld). */
2170 for (regno
= FRAME_POINTER_REGNUM
; regno
> 1; regno
--)
2171 if (save_regs
[regno
])
2173 if ((offset
& 7) != 4 || (regno
& 1) != 1 || !save_regs
[regno
-1])
2180 mo_ptr
->regno
= regno
-1;
2181 mo_ptr
->offset
= offset
-4;
2188 /* Walk the extended registers to record all memory operations. */
2189 /* Be sure the offset is double word aligned. */
2190 offset
= (offset
- 1) & ~7;
2191 for (regno
= FIRST_PSEUDO_REGISTER
- 1; regno
> FIRST_EXTENDED_REGISTER
;
2193 if (save_regs
[regno
])
2196 mo_ptr
->regno
= regno
;
2197 mo_ptr
->offset
= offset
;
2204 /* Output the memory operations. */
2205 for (mo_ptr
= mem_op
; mo_ptr
->regno
; mo_ptr
++)
2208 emit_ldst (store_p
, mo_ptr
->regno
,
2209 (mo_ptr
->nregs
> 1 ? DImode
: SImode
),
2215 emit_ldst (store_p
, regno
, mode
, offset
)
2218 enum machine_mode mode
;
2221 rtx reg
= gen_rtx (REG
, mode
, regno
);
2224 if (SMALL_INTVAL (offset
))
2226 mem
= gen_rtx (MEM
, mode
, plus_constant (stack_pointer_rtx
, offset
));
2230 /* offset is too large for immediate index must use register */
2232 rtx disp
= gen_rtx (CONST_INT
, VOIDmode
, offset
);
2233 rtx temp
= gen_rtx (REG
, SImode
, TEMP_REGNUM
);
2234 rtx regi
= gen_rtx (PLUS
, SImode
, stack_pointer_rtx
, temp
);
2235 emit_move_insn (temp
, disp
);
2236 mem
= gen_rtx (MEM
, mode
, regi
);
2240 emit_move_insn (mem
, reg
);
2242 emit_move_insn (reg
, mem
);
2245 /* Convert the address expression REG to a CFA offset. */
2248 m88k_debugger_offset (reg
, offset
)
2250 register int offset
;
2252 if (GET_CODE (reg
) == PLUS
)
2254 offset
= INTVAL (XEXP (reg
, 1));
2255 reg
= XEXP (reg
, 0);
2258 /* Put the offset in terms of the CFA (arg pointer). */
2259 if (reg
== frame_pointer_rtx
)
2260 offset
+= m88k_fp_offset
- m88k_stack_size
;
2261 else if (reg
== stack_pointer_rtx
)
2262 offset
-= m88k_stack_size
;
2263 else if (reg
!= arg_pointer_rtx
)
2265 #if (MONITOR_GCC & 0x10) /* Watch for suspicious symbolic locations. */
2266 if (! (GET_CODE (reg
) == REG
2267 && REGNO (reg
) >= FIRST_PSEUDO_REGISTER
))
2268 warning ("Internal gcc error: Can't express symbolic location");
2276 /* Output the 88open OCS proscribed text description information.
2279 0 22: info-byte-length (16 or 20 bytes)
2280 0 2: info-alignment (word 2)
2281 1 32: info-protocol (version 1 or 2(pic))
2282 2 32: starting-address (inclusive, not counting prologue)
2283 3 32: ending-address (exclusive, not counting epilog)
2284 4 8: info-variant (version 1 or 3(extended registers))
2285 4 17: register-save-mask (from register 14 to 30)
2287 4 1: return-address-info-discriminant
2288 4 5: frame-address-register
2289 5 32: frame-address-offset
2290 6 32: return-address-info
2291 7 32: register-save-offset
2292 8 16: extended-register-save-mask (x16 - x31)
2293 8 16: extended-register-save-offset (WORDS from register-save-offset) */
2296 output_tdesc (file
, offset
)
2301 long mask
, return_address_info
, register_save_offset
;
2302 long xmask
, xregister_save_offset
;
2305 for (mask
= 0, i
= 0, regno
= FIRST_OCS_PRESERVE_REGISTER
;
2306 regno
<= LAST_OCS_PRESERVE_REGISTER
;
2310 if (save_regs
[regno
])
2317 for (xmask
= 0, j
= 0, regno
= FIRST_OCS_EXTENDED_PRESERVE_REGISTER
;
2318 regno
<= LAST_OCS_EXTENDED_PRESERVE_REGISTER
;
2322 if (save_regs
[regno
])
2331 if ((nxregs
> 0 || nregs
> 2) && !save_regs
[FRAME_POINTER_REGNUM
])
2333 return_address_info
= - m88k_stack_size
+ offset
;
2334 register_save_offset
= return_address_info
- i
*4;
2338 return_address_info
= 1;
2339 register_save_offset
= - m88k_stack_size
+ offset
+ 4 - i
*4;
2342 xregister_save_offset
= - (j
* 2 + ((register_save_offset
>> 2) & 1));
2346 fprintf (file
, "\t%s\t %d,%d", INT_ASM_OP
, /* 8:0,22:(20 or 16),2:2 */
2347 (((xmask
!= 0) ? 20 : 16) << 2) | 2,
2350 ASM_GENERATE_INTERNAL_LABEL (buf
, OCS_START_PREFIX
, m88k_function_number
);
2351 fprintf (file
, ",%s%s", buf
+1, flag_pic
? "#rel" : "");
2352 ASM_GENERATE_INTERNAL_LABEL (buf
, OCS_END_PREFIX
, m88k_function_number
);
2353 fprintf (file
, ",%s%s", buf
+1, flag_pic
? "#rel" : "");
2355 fprintf (file
, ",0x%x,0x%x,0x%x,0x%x",
2356 /* 8:1,17:0x%.3x,1:0,1:%d,5:%d */
2357 (((xmask
? 3 : 1) << (17+1+1+5))
2359 | ((!!save_regs
[1]) << 5)
2360 | (frame_pointer_needed
2361 ? FRAME_POINTER_REGNUM
2362 : STACK_POINTER_REGNUM
)),
2363 (m88k_stack_size
- (frame_pointer_needed
? m88k_fp_offset
: 0)),
2364 return_address_info
,
2365 register_save_offset
);
2367 fprintf (file
, ",0x%x%04x", xmask
, (0xffff & xregister_save_offset
));
2373 /* Output assembler code to FILE to increment profiler label # LABELNO
2374 for profiling a function entry. NAME is the mcount function name
2375 (varies), SAVEP indicates whether the parameter registers need to
2376 be saved and restored. */
2379 output_function_profiler (file
, labelno
, name
, savep
)
2387 char *temp
= (savep
? reg_names
[2] : reg_names
[10]);
2389 /* Remember to update FUNCTION_PROFILER_LENGTH. */
2393 fprintf (file
, "\tsubu\t %s,%s,64\n", reg_names
[31], reg_names
[31]);
2394 fprintf (file
, "\tst.d\t %s,%s,32\n", reg_names
[2], reg_names
[31]);
2395 fprintf (file
, "\tst.d\t %s,%s,40\n", reg_names
[4], reg_names
[31]);
2396 fprintf (file
, "\tst.d\t %s,%s,48\n", reg_names
[6], reg_names
[31]);
2397 fprintf (file
, "\tst.d\t %s,%s,56\n", reg_names
[8], reg_names
[31]);
2400 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
2403 fprintf (file
, "\tor.u\t %s,%s,%shi16(%s#got_rel)\n",
2404 temp
, reg_names
[0], m88k_pound_sign
, &label
[1]);
2405 fprintf (file
, "\tor\t %s,%s,%slo16(%s#got_rel)\n",
2406 temp
, temp
, m88k_pound_sign
, &label
[1]);
2407 sprintf (dbi
, "\tld\t %s,%s,%s\n", temp
,
2408 reg_names
[PIC_OFFSET_TABLE_REGNUM
], temp
);
2412 sprintf (dbi
, "\tld\t %s,%s,%s#got_rel\n", temp
,
2413 reg_names
[PIC_OFFSET_TABLE_REGNUM
], &label
[1]);
2417 fprintf (file
, "\tor.u\t %s,%s,%shi16(%s)\n",
2418 temp
, reg_names
[0], m88k_pound_sign
, &label
[1]);
2419 sprintf (dbi
, "\tor\t %s,%s,%slo16(%s)\n",
2420 temp
, temp
, m88k_pound_sign
, &label
[1]);
2424 fprintf (file
, "\tbsr.n\t %s#plt\n", name
);
2426 fprintf (file
, "\tbsr.n\t %s\n", name
);
2431 fprintf (file
, "\tld.d\t %s,%s,32\n", reg_names
[2], reg_names
[31]);
2432 fprintf (file
, "\tld.d\t %s,%s,40\n", reg_names
[4], reg_names
[31]);
2433 fprintf (file
, "\tld.d\t %s,%s,48\n", reg_names
[6], reg_names
[31]);
2434 fprintf (file
, "\tld.d\t %s,%s,56\n", reg_names
[8], reg_names
[31]);
2435 fprintf (file
, "\taddu\t %s,%s,64\n", reg_names
[31], reg_names
[31]);
2439 /* Output assembler code to FILE to initialize basic-block profiling for
2440 the current module. LABELNO is unique to each instance. */
2443 output_function_block_profiler (file
, labelno
)
2450 /* Remember to update FUNCTION_BLOCK_PROFILER_LENGTH. */
2452 ASM_GENERATE_INTERNAL_LABEL (block
, "LPBX", 0);
2453 ASM_GENERATE_INTERNAL_LABEL (label
, "LPY", labelno
);
2455 /* @@ Need to deal with PIC. I'm not sure what the requirements are on
2456 register usage, so I used r26/r27 to be safe. */
2457 fprintf (file
, "\tor.u\t %s,%s,%shi16(%s)\n", reg_names
[27], reg_names
[0],
2458 m88k_pound_sign
, &block
[1]);
2459 fprintf (file
, "\tld\t %s,%s,%slo16(%s)\n", reg_names
[26], reg_names
[27],
2460 m88k_pound_sign
, &block
[1]);
2461 fprintf (file
, "\tbcnd\t %sne0,%s,%s\n",
2462 m88k_pound_sign
, reg_names
[26], &label
[1]);
2463 fprintf (file
, "\tsubu\t %s,%s,64\n", reg_names
[31], reg_names
[31]);
2464 fprintf (file
, "\tst.d\t %s,%s,32\n", reg_names
[2], reg_names
[31]);
2465 fprintf (file
, "\tst.d\t %s,%s,40\n", reg_names
[4], reg_names
[31]);
2466 fprintf (file
, "\tst.d\t %s,%s,48\n", reg_names
[6], reg_names
[31]);
2467 fprintf (file
, "\tst.d\t %s,%s,56\n", reg_names
[8], reg_names
[31]);
2468 fputs ("\tbsr.n\t ", file
);
2469 ASM_OUTPUT_LABELREF (file
, "__bb_init_func");
2471 fprintf (file
, "\tor\t %s,%s,%slo16(%s)\n", reg_names
[2], reg_names
[27],
2472 m88k_pound_sign
, &block
[1]);
2473 fprintf (file
, "\tld.d\t %s,%s,32\n", reg_names
[2], reg_names
[31]);
2474 fprintf (file
, "\tld.d\t %s,%s,40\n", reg_names
[4], reg_names
[31]);
2475 fprintf (file
, "\tld.d\t %s,%s,48\n", reg_names
[6], reg_names
[31]);
2476 fprintf (file
, "\tld.d\t %s,%s,56\n", reg_names
[8], reg_names
[31]);
2477 fprintf (file
, "\taddu\t %s,%s,64\n", reg_names
[31], reg_names
[31]);
2478 ASM_OUTPUT_INTERNAL_LABEL (file
, "LPY", labelno
);
2481 /* Output assembler code to FILE to increment the count associated with
2482 the basic block number BLOCKNO. */
2485 output_block_profiler (file
, blockno
)
2491 /* Remember to update BLOCK_PROFILER_LENGTH. */
2493 ASM_GENERATE_INTERNAL_LABEL (block
, "LPBX", 2);
2495 /* @@ Need to deal with PIC. I'm not sure what the requirements are on
2496 register usage, so I used r26/r27 to be safe. */
2497 fprintf (file
, "\tor.u\t %s,%s,%shi16(%s+%d)\n", reg_names
[27], reg_names
[0],
2498 m88k_pound_sign
, &block
[1], 4 * blockno
);
2499 fprintf (file
, "\tld\t %s,%s,%slo16(%s+%d)\n", reg_names
[26], reg_names
[27],
2500 m88k_pound_sign
, &block
[1], 4 * blockno
);
2501 fprintf (file
, "\taddu\t %s,%s,1\n", reg_names
[26], reg_names
[26]);
2502 fprintf (file
, "\tst\t %s,%s,%slo16(%s+%d)\n", reg_names
[26], reg_names
[27],
2503 m88k_pound_sign
, &block
[1], 4 * blockno
);
2506 /* Determine whether a function argument is passed in a register, and
2509 The arguments are CUM, which summarizes all the previous
2510 arguments; MODE, the machine mode of the argument; TYPE,
2511 the data type of the argument as a tree node or 0 if that is not known
2512 (which happens for C support library functions); and NAMED,
2513 which is 1 for an ordinary argument and 0 for nameless arguments that
2514 correspond to `...' in the called function's prototype.
2516 The value of the expression should either be a `reg' RTX for the
2517 hard register in which to pass the argument, or zero to pass the
2518 argument on the stack.
2520 On the m88000 the first eight words of args are normally in registers
2521 and the rest are pushed. Double precision floating point must be
2522 double word aligned (and if in a register, starting on an even
2523 register). Structures and unions which are not 4 byte, and word
2524 aligned are passed in memory rather than registers, even if they
2525 would fit completely in the registers under OCS rules.
2527 Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
2528 For structures that are passed in memory, but could have been
2529 passed in registers, we first load the structure into the
2530 register, and then when the last argument is passed, we store
2531 the registers into the stack locations. This fixes some bugs
2532 where GCC did not expect to have register arguments, followed
2533 by stack arguments, followed by register arguments. */
2536 m88k_function_arg (args_so_far
, mode
, type
, named
)
2537 CUMULATIVE_ARGS args_so_far
;
2538 enum machine_mode mode
;
2544 if (type
!= 0 /* undo putting struct in register */
2545 && (TREE_CODE (type
) == RECORD_TYPE
|| TREE_CODE (type
) == UNION_TYPE
))
2548 if (mode
== BLKmode
&& TARGET_WARN_PASS_STRUCT
)
2549 warning ("argument #%d is a structure", args_so_far
+ 1);
2551 if ((args_so_far
& 1) != 0
2552 && (mode
== DImode
|| mode
== DFmode
2553 || (type
!= 0 && TYPE_ALIGN (type
) > 32)))
2558 return (rtx
) 0; /* don't put args in registers */
2561 if (type
== 0 && mode
== BLKmode
)
2562 abort (); /* m88k_function_arg argument `type' is NULL for BLKmode. */
2564 bytes
= (mode
!= BLKmode
) ? GET_MODE_SIZE (mode
) : int_size_in_bytes (type
);
2565 words
= (bytes
+ 3) / 4;
2567 if (args_so_far
+ words
> 8)
2568 return (rtx
) 0; /* args have exhausted registers */
2570 else if (mode
== BLKmode
2571 && (TYPE_ALIGN (type
) != BITS_PER_WORD
2572 || bytes
!= UNITS_PER_WORD
))
2575 return gen_rtx (REG
,
2576 ((mode
== BLKmode
) ? TYPE_MODE (type
) : mode
),
2580 /* Do what is necessary for `va_start'. The argument is ignored;
2581 We look at the current function to determine if stdargs or varargs
2582 is used and fill in an initial va_list. A pointer to this constructor
2586 m88k_builtin_saveregs (arglist
)
2589 rtx block
, addr
, argsize
, dest
;
2590 tree fntype
= TREE_TYPE (current_function_decl
);
2591 int argadj
= ((!(TYPE_ARG_TYPES (fntype
) != 0
2592 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
2593 != void_type_node
)))
2594 ? -UNITS_PER_WORD
: 0) + UNITS_PER_WORD
- 1;
2596 variable_args_p
= 1;
2598 if (CONSTANT_P (current_function_arg_offset_rtx
))
2600 fixed
= (XINT (current_function_arg_offset_rtx
, 0)
2601 + argadj
) / UNITS_PER_WORD
;
2602 argsize
= gen_rtx (CONST_INT
, VOIDmode
, fixed
);
2607 argsize
= plus_constant (current_function_arg_offset_rtx
, argadj
);
2608 argsize
= expand_shift (RSHIFT_EXPR
, Pmode
, argsize
,
2609 build_int_2 (2, 0), argsize
, 0);
2612 /* Allocate the va_list constructor */
2613 block
= assign_stack_local (BLKmode
, 3 * UNITS_PER_WORD
, BITS_PER_WORD
);
2614 MEM_IN_STRUCT_P (block
) = 1;
2615 RTX_UNCHANGING_P (block
) = 1;
2616 RTX_UNCHANGING_P (XEXP (block
, 0)) = 1;
2618 /* Store the argsize as the __va_arg member. */
2619 emit_move_insn (change_address (block
, SImode
, XEXP (block
, 0)),
2622 /* Store the arg pointer in the __va_stk member. */
2623 emit_move_insn (change_address (block
, Pmode
,
2624 plus_constant (XEXP (block
, 0),
2626 copy_to_reg (virtual_incoming_args_rtx
));
2628 /* Allocate the register space, and store it as the __va_reg member. */
2629 addr
= assign_stack_local (BLKmode
, 8 * UNITS_PER_WORD
, -1);
2630 MEM_IN_STRUCT_P (addr
) = 1;
2631 RTX_UNCHANGING_P (addr
) = 1;
2632 RTX_UNCHANGING_P (XEXP (addr
, 0)) = 1;
2633 emit_move_insn (change_address (block
, Pmode
,
2634 plus_constant (XEXP (block
, 0),
2635 2 * UNITS_PER_WORD
)),
2636 copy_to_reg (XEXP (addr
, 0)));
2638 /* Now store the incoming registers. */
2641 dest
= change_address (addr
, Pmode
,
2642 plus_constant (XEXP (addr
, 0),
2643 fixed
* UNITS_PER_WORD
));
2644 move_block_from_reg (2 + fixed
, dest
, 8 - fixed
,
2645 UNITS_PER_WORD
* (8 - fixed
));
2648 if (flag_check_memory_usage
)
2650 emit_library_call (chkr_set_right_libfunc
, 1, VOIDmode
, 3,
2652 GEN_INT (3 * UNITS_PER_WORD
), TYPE_MODE (sizetype
),
2653 GEN_INT (MEMORY_USE_RW
),
2654 TYPE_MODE (integer_type_node
));
2656 emit_library_call (chkr_set_right_libfunc
, 1, VOIDmode
, 3,
2658 GEN_INT (UNITS_PER_WORD
* (8 - fixed
)),
2659 TYPE_MODE (sizetype
),
2660 GEN_INT (MEMORY_USE_RW
),
2661 TYPE_MODE (integer_type_node
));
2664 /* Return the address of the va_list constructor, but don't put it in a
2665 register. This fails when not optimizing and produces worse code when
2667 return XEXP (block
, 0);
2670 /* If cmpsi has not been generated, emit code to do the test. Return the
2671 expression describing the test of operator OP. */
2674 emit_test (op
, mode
)
2676 enum machine_mode mode
;
2678 if (m88k_compare_reg
== 0)
2679 emit_insn (gen_test (m88k_compare_op0
, m88k_compare_op1
));
2680 return (gen_rtx (op
, mode
, m88k_compare_reg
, const0_rtx
));
2683 /* Determine how to best perform cmpsi/bxx, where cmpsi has a constant
2684 operand. All tests with zero (albeit swapped) and all equality tests
2685 with a constant are done with bcnd. The remaining cases are swapped
2689 emit_bcnd (op
, label
)
2693 if (m88k_compare_op1
== const0_rtx
)
2694 emit_jump_insn( gen_bcnd (
2695 gen_rtx (op
, VOIDmode
,m88k_compare_op0
, const0_rtx
),
2697 else if (m88k_compare_op0
== const0_rtx
)
2698 emit_jump_insn( gen_bcnd(
2700 swap_condition (op
),
2701 VOIDmode
, m88k_compare_op1
, const0_rtx
),
2703 else if (op
!= EQ
&& op
!= NE
)
2704 emit_jump_insn (gen_bxx (emit_test (op
, VOIDmode
), label
));
2707 rtx zero
= gen_reg_rtx (SImode
);
2711 if (GET_CODE (m88k_compare_op1
) == CONST_INT
)
2713 reg
= force_reg (SImode
, m88k_compare_op0
);
2714 constant
= m88k_compare_op1
;
2718 reg
= force_reg (SImode
, m88k_compare_op1
);
2719 constant
= m88k_compare_op0
;
2721 value
= INTVAL (constant
);
2723 /* Perform an arithmetic computation to make the compared-to value
2724 zero, but avoid loosing if the bcnd is later changed into sxx. */
2725 if (SMALL_INTVAL (value
))
2726 emit_jump_insn (gen_bxx (emit_test (op
, VOIDmode
), label
));
2729 if (SMALL_INTVAL (-value
))
2730 emit_insn (gen_addsi3 (zero
, reg
,
2731 gen_rtx (CONST_INT
, VOIDmode
, -value
)));
2733 emit_insn (gen_xorsi3 (zero
, reg
, constant
));
2735 emit_jump_insn (gen_bcnd (gen_rtx (op
, VOIDmode
,
2742 /* Print an operand. Recognize special options, documented below. */
2745 print_operand (file
, x
, code
)
2750 enum rtx_code xc
= (x
? GET_CODE (x
) : UNKNOWN
);
2751 register int value
= (xc
== CONST_INT
? INTVAL (x
) : 0);
2752 static int sequencep
;
2753 static int reversep
;
2757 if (code
< 'B' || code
> 'E')
2758 output_operand_lossage ("%R not followed by %B/C/D/E");
2760 xc
= reverse_condition (xc
);
2766 case '*': /* addressing base register for PIC */
2767 fputs (reg_names
[PIC_OFFSET_TABLE_REGNUM
], file
); return;
2769 case '#': /* SVR4 pound-sign syntax character (empty if SVR3) */
2770 fputs (m88k_pound_sign
, file
); return;
2772 case 'V': /* Output a serializing instruction as needed if the operand
2773 (assumed to be a MEM) is a volatile load. */
2774 case 'v': /* ditto for a volatile store. */
2775 if (MEM_VOLATILE_P (x
) && TARGET_SERIALIZE_VOLATILE
)
2777 /* The m88110 implements two FIFO queues, one for loads and
2778 one for stores. These queues mean that loads complete in
2779 their issue order as do stores. An interaction between the
2780 history buffer and the store reservation station ensures
2781 that a store will not bypass load. Finally, a load will not
2782 bypass store, but only when they reference the same address.
2784 To avoid this reordering (a load bypassing a store) for
2785 volatile references, a serializing instruction is output.
2786 We choose the fldcr instruction as it does not serialize on
2787 the m88100 so that -m88000 code will not be degraded.
2789 The mechanism below is completed by having CC_STATUS_INIT set
2790 the code to the unknown value. */
2794 A problem with 88110 4.1 & 4.2 makes the use of fldcr for
2795 this purpose undesirable. Instead we will use tb1, this will
2796 cause serialization on the 88100 but such is life.
2799 static rtx last_addr
= 0;
2800 if (code
== 'V' /* Only need to serialize before a load. */
2801 && m88k_volatile_code
!= 'V' /* Loads complete in FIFO order. */
2802 && !(m88k_volatile_code
== 'v'
2803 && GET_CODE (XEXP (x
, 0)) == LO_SUM
2804 && rtx_equal_p (XEXP (XEXP (x
, 0), 1), last_addr
)))
2808 "fldcr\t %s,%scr63\n\t",
2810 "fldcr\t %s,%sfcr63\n\t",
2812 reg_names
[0], m88k_pound_sign
);
2814 "tb1\t 1,%s,0xff\n\t", reg_names
[0]);
2816 m88k_volatile_code
= code
;
2817 last_addr
= (GET_CODE (XEXP (x
, 0)) == LO_SUM
2818 ? XEXP (XEXP (x
, 0), 1) : 0);
2822 case 'X': /* print the upper 16 bits... */
2824 case 'x': /* print the lower 16 bits of the integer constant in hex */
2825 if (xc
!= CONST_INT
)
2826 output_operand_lossage ("invalid %x/X value");
2827 fprintf (file
, "0x%x", value
& 0xffff); return;
2829 case 'H': /* print the low 16 bits of the negated integer constant */
2830 if (xc
!= CONST_INT
)
2831 output_operand_lossage ("invalid %H value");
2833 case 'h': /* print the register or low 16 bits of the integer constant */
2836 if (xc
!= CONST_INT
)
2837 output_operand_lossage ("invalid %h value");
2838 fprintf (file
, "%d", value
& 0xffff);
2841 case 'Q': /* print the low 8 bits of the negated integer constant */
2842 if (xc
!= CONST_INT
)
2843 output_operand_lossage ("invalid %Q value");
2845 case 'q': /* print the register or low 8 bits of the integer constant */
2848 if (xc
!= CONST_INT
)
2849 output_operand_lossage ("invalid %q value");
2850 fprintf (file
, "%d", value
& 0xff);
2853 case 'w': /* print the integer constant (X == 32 ? 0 : 32 - X) */
2854 if (xc
!= CONST_INT
)
2855 output_operand_lossage ("invalid %o value");
2856 fprintf (file
, "%d", value
== 32 ? 0 : 32 - value
);
2859 case 'p': /* print the logarithm of the integer constant */
2861 || (value
= exact_log2 (value
)) < 0)
2862 output_operand_lossage ("invalid %p value");
2863 fprintf (file
, "%d", value
);
2866 case 'S': /* compliment the value and then... */
2868 case 's': /* print the width and offset values forming the integer
2869 constant with a SET instruction. See integer_ok_for_set. */
2871 register unsigned mask
, uval
= value
;
2872 register int top
, bottom
;
2874 if (xc
!= CONST_INT
)
2875 output_operand_lossage ("invalid %s/S value");
2876 /* All the "one" bits must be contiguous. If so, MASK will be
2877 a power of two or zero. */
2878 mask
= (uval
| (uval
- 1)) + 1;
2879 if (!(uval
&& POWER_OF_2_or_0 (mask
)))
2880 output_operand_lossage ("invalid %s/S value");
2881 top
= mask
? exact_log2 (mask
) : 32;
2882 bottom
= exact_log2 (uval
& ~(uval
- 1));
2883 fprintf (file
,"%d<%d>", top
- bottom
, bottom
);
2887 case 'P': /* print nothing if pc_rtx; output label_ref */
2888 if (xc
== LABEL_REF
)
2889 output_addr_const (file
, x
);
2891 output_operand_lossage ("invalid %P operand");
2894 case 'L': /* print 0 or 1 if operand is label_ref and then... */
2895 fputc (xc
== LABEL_REF
? '1' : '0', file
);
2896 case '.': /* print .n if delay slot is used */
2897 fputs ((final_sequence
2898 && ! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence
, 0, 0)))
2899 ? ".n\t" : "\t", file
);
2902 case '!': /* Reverse the following condition. */
2906 case 'R': /* reverse the condition of the next print_operand
2907 if operand is a label_ref. */
2909 reversep
= (xc
== LABEL_REF
);
2912 case 'B': /* bcnd branch values */
2913 fputs (m88k_pound_sign
, file
);
2916 case EQ
: fputs ("eq0", file
); return;
2917 case NE
: fputs ("ne0", file
); return;
2918 case GT
: fputs ("gt0", file
); return;
2919 case LE
: fputs ("le0", file
); return;
2920 case LT
: fputs ("lt0", file
); return;
2921 case GE
: fputs ("ge0", file
); return;
2922 default: output_operand_lossage ("invalid %B value");
2925 case 'C': /* bb0/bb1 branch values for comparisons */
2926 fputs (m88k_pound_sign
, file
);
2929 case EQ
: fputs ("eq", file
); return;
2930 case NE
: fputs ("ne", file
); return;
2931 case GT
: fputs ("gt", file
); return;
2932 case LE
: fputs ("le", file
); return;
2933 case LT
: fputs ("lt", file
); return;
2934 case GE
: fputs ("ge", file
); return;
2935 case GTU
: fputs ("hi", file
); return;
2936 case LEU
: fputs ("ls", file
); return;
2937 case LTU
: fputs ("lo", file
); return;
2938 case GEU
: fputs ("hs", file
); return;
2939 default: output_operand_lossage ("invalid %C value");
2942 case 'D': /* bcnd branch values for float comparisons */
2945 case EQ
: fputs ("0xa", file
); return;
2946 case NE
: fputs ("0x5", file
); return;
2947 case GT
: fputs (m88k_pound_sign
, file
);
2948 fputs ("gt0", file
); return;
2949 case LE
: fputs ("0xe", file
); return;
2950 case LT
: fputs ("0x4", file
); return;
2951 case GE
: fputs ("0xb", file
); return;
2952 default: output_operand_lossage ("invalid %D value");
2955 case 'E': /* bcnd branch values for special integers */
2958 case EQ
: fputs ("0x8", file
); return;
2959 case NE
: fputs ("0x7", file
); return;
2960 default: output_operand_lossage ("invalid %E value");
2963 case 'd': /* second register of a two register pair */
2965 output_operand_lossage ("`%d' operand isn't a register");
2966 fputs (reg_names
[REGNO (x
) + 1], file
);
2969 case 'r': /* an immediate 0 should be represented as `r0' */
2970 if (x
== const0_rtx
)
2972 fputs (reg_names
[0], file
);
2976 output_operand_lossage ("invalid %r value");
2982 if (REGNO (x
) == ARG_POINTER_REGNUM
)
2983 output_operand_lossage ("operand is r0");
2985 fputs (reg_names
[REGNO (x
)], file
);
2987 else if (xc
== PLUS
)
2990 output_address (XEXP (x
, 0));
2991 else if (flag_pic
&& xc
== UNSPEC
)
2993 output_addr_const (file
, XVECEXP (x
, 0, 0));
2994 fputs ("#got_rel", file
);
2996 else if (xc
== CONST_DOUBLE
)
2997 output_operand_lossage ("operand is const_double");
2999 output_addr_const (file
, x
);
3002 case 'g': /* append #got_rel as needed */
3003 if (flag_pic
&& (xc
== SYMBOL_REF
|| xc
== LABEL_REF
))
3005 output_addr_const (file
, x
);
3006 fputs ("#got_rel", file
);
3011 case 'a': /* (standard), assume operand is an address */
3012 case 'c': /* (standard), assume operand is an immediate value */
3013 case 'l': /* (standard), assume operand is a label_ref */
3014 case 'n': /* (standard), like %c, except negate first */
3016 output_operand_lossage ("invalid code");
3021 print_operand_address (file
, addr
)
3025 register rtx reg0
, reg1
, temp
;
3027 switch (GET_CODE (addr
))
3030 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3033 fprintf (file
, "%s,%s", reg_names
[0], reg_names
[REGNO (addr
)]);
3037 fprintf (file
, "%s,%slo16(",
3038 reg_names
[REGNO (XEXP (addr
, 0))], m88k_pound_sign
);
3039 output_addr_const (file
, XEXP (addr
, 1));
3044 reg0
= XEXP (addr
, 0);
3045 reg1
= XEXP (addr
, 1);
3046 if (GET_CODE (reg0
) == MULT
|| GET_CODE (reg0
) == CONST_INT
)
3053 if ((REG_P (reg0
) && REGNO (reg0
) == ARG_POINTER_REGNUM
)
3054 || (REG_P (reg1
) && REGNO (reg1
) == ARG_POINTER_REGNUM
))
3057 else if (REG_P (reg0
))
3060 fprintf (file
, "%s,%s",
3061 reg_names
[REGNO (reg0
)], reg_names
[REGNO (reg1
)]);
3063 else if (GET_CODE (reg1
) == CONST_INT
)
3064 fprintf (file
, "%s,%d",
3065 reg_names
[REGNO (reg0
)], INTVAL (reg1
));
3067 else if (GET_CODE (reg1
) == MULT
)
3069 rtx mreg
= XEXP (reg1
, 0);
3070 if (REGNO (mreg
) == ARG_POINTER_REGNUM
)
3073 fprintf (file
, "%s[%s]", reg_names
[REGNO (reg0
)],
3074 reg_names
[REGNO (mreg
)]);
3077 else if (GET_CODE (reg1
) == ZERO_EXTRACT
)
3079 fprintf (file
, "%s,%slo16(",
3080 reg_names
[REGNO (reg0
)], m88k_pound_sign
);
3081 output_addr_const (file
, XEXP (reg1
, 0));
3087 fprintf (file
, "%s,", reg_names
[REGNO (reg0
)]);
3088 output_addr_const (file
, reg1
);
3089 fputs ("#got_rel", file
);
3099 if (REGNO (XEXP (addr
, 0)) == ARG_POINTER_REGNUM
)
3102 fprintf (file
, "%s[%s]",
3103 reg_names
[0], reg_names
[REGNO (XEXP (addr
, 0))]);
3107 fprintf (file
, "%s,%d", reg_names
[0], INTVAL (addr
));
3111 fprintf (file
, "%s,", reg_names
[0]);
3112 if (SHORT_ADDRESS_P (addr
, temp
))
3114 fprintf (file
, "%siw16(", m88k_pound_sign
);
3115 output_addr_const (file
, addr
);
3119 output_addr_const (file
, addr
);
3123 /* Return true if X is an address which needs a temporary register when
3124 reloaded while generating PIC code. */
3127 pic_address_needs_scratch (x
)
3130 /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
3131 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
3132 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
3133 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3134 && ! ADD_INT (XEXP (XEXP (x
, 0), 1)))
3140 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
3141 reference and a constant. */
3144 symbolic_operand (op
, mode
)
3146 enum machine_mode mode
;
3148 switch (GET_CODE (op
))
3156 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3157 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
3158 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
3160 /* ??? This clause seems to be irrelevant. */
3162 return GET_MODE (op
) == mode
;