1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* Some output-actions in m68k.md need these. */
26 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
32 #include "insn-attr.h"
34 /* Needed for use_return_insn. */
37 #ifdef SUPPORT_SUN_FPA
39 /* Index into this array by (register number >> 3) to find the
40 smallest class which contains that register. */
41 enum reg_class regno_reg_class
[]
42 = { DATA_REGS
, ADDR_REGS
, FP_REGS
,
43 LO_FPA_REGS
, LO_FPA_REGS
, FPA_REGS
, FPA_REGS
};
45 #endif /* defined SUPPORT_SUN_FPA */
47 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
48 if SGS_SWITCH_TABLE. */
49 int switch_table_difference_label_flag
;
51 static rtx
find_addr_reg ();
52 rtx
legitimize_pic_address ();
55 /* Emit a (use pic_offset_table_rtx) if we used PIC relocation in the
56 function at any time during the compilation process. In the future
57 we should try and eliminate the USE if we can easily determine that
58 all PIC references were deleted from the current function. That would
59 save an address register */
64 if (flag_pic
&& current_function_uses_pic_offset_table
)
65 emit_insn (gen_rtx (USE
, VOIDmode
, pic_offset_table_rtx
));
69 /* This function generates the assembly code for function entry.
70 STREAM is a stdio stream to output the code to.
71 SIZE is an int: how many units of temporary storage to allocate.
72 Refer to the array `regs_ever_live' to determine which registers
73 to save; `regs_ever_live[I]' is nonzero if register number I
74 is ever used in the function. This function is responsible for
75 knowing which registers should not be saved even if used. */
78 /* Note that the order of the bit mask for fmovem is the opposite
79 of the order for movem! */
83 output_function_prologue (stream
, size
)
88 register int mask
= 0;
89 int num_saved_regs
= 0;
90 extern char call_used_regs
[];
91 int fsize
= (size
+ 3) & -4;
94 if (frame_pointer_needed
)
96 if (fsize
== 0 && TARGET_68040
)
98 /* on the 68040, pea + move is faster than link.w 0 */
100 asm_fprintf (stream
, "\tpea (%s)\n\tmove.l %s,%s\n",
101 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
102 reg_names
[FRAME_POINTER_REGNUM
]);
104 asm_fprintf (stream
, "\tpea %s@\n\tmovel %s,%s\n",
105 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
106 reg_names
[FRAME_POINTER_REGNUM
]);
109 else if (fsize
< 0x8000)
112 asm_fprintf (stream
, "\tlink.w %s,%0I%d\n",
113 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
115 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
116 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
119 else if (TARGET_68020
)
122 asm_fprintf (stream
, "\tlink.l %s,%0I%d\n",
123 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
125 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
126 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
131 /* Adding negative number is faster on the 68040. */
133 asm_fprintf (stream
, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
134 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
136 asm_fprintf (stream
, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
137 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
143 /* Adding negative number is faster on the 68040. */
144 if (fsize
+ 4 < 0x8000)
146 /* asm_fprintf() cannot handle %. */
148 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", - (fsize
+ 4));
150 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", - (fsize
+ 4));
155 /* asm_fprintf() cannot handle %. */
157 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", - (fsize
+ 4));
159 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", - (fsize
+ 4));
163 #ifdef SUPPORT_SUN_FPA
164 for (regno
= 24; regno
< 56; regno
++)
165 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
168 asm_fprintf (stream
, "\tfpmovd %s,-(%Rsp)\n",
171 asm_fprintf (stream
, "\tfpmoved %s,%Rsp@-\n",
176 for (regno
= 16; regno
< 24; regno
++)
177 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
178 mask
|= 1 << (regno
- 16);
179 if ((mask
& 0xff) != 0)
182 asm_fprintf (stream
, "\tfmovm %0I0x%x,-(%Rsp)\n", mask
& 0xff);
184 asm_fprintf (stream
, "\tfmovem %0I0x%x,%Rsp@-\n", mask
& 0xff);
188 for (regno
= 0; regno
< 16; regno
++)
189 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
191 mask
|= 1 << (15 - regno
);
194 if (frame_pointer_needed
)
196 mask
&= ~ (1 << (15 - FRAME_POINTER_REGNUM
));
201 fprintf (stream
, "\ttstl sp@(%d)\n", NEED_PROBE
- num_saved_regs
* 4);
204 if (num_saved_regs
<= 2)
206 /* Store each separately in the same order moveml uses.
207 Using two movel instructions instead of a single moveml
208 is about 15% faster for the 68020 and 68030 at no expense
213 /* Undo the work from above. */
214 for (i
= 0; i
< 16; i
++)
218 "\t%Omove.l %s,-(%Rsp)\n",
220 "\tmovel %s,%Rsp@-\n",
227 asm_fprintf (stream
, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask
);
229 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@-\n", mask
);
232 if (flag_pic
&& current_function_uses_pic_offset_table
)
235 asm_fprintf (stream
, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
236 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
238 asm_fprintf (stream
, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
239 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
240 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
241 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
242 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
247 /* Return true if this function's epilogue can be output as RTL. */
254 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
257 /* Copied from output_function_epilogue (). We should probably create a
258 separate layout routine to perform the common work. */
260 for (regno
= 0 ; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
261 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
267 /* This function generates the assembly code for function exit,
268 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
270 The function epilogue should not depend on the current stack pointer!
271 It should use the frame pointer only, if there is a frame pointer.
272 This is mandatory because of alloca; we also take advantage of it to
273 omit stack adjustments before returning. */
276 output_function_epilogue (stream
, size
)
281 register int mask
, fmask
;
283 int offset
, foffset
, fpoffset
;
284 extern char call_used_regs
[];
285 int fsize
= (size
+ 3) & -4;
287 rtx insn
= get_last_insn ();
289 /* If the last insn was a BARRIER, we don't have to write any code. */
290 if (GET_CODE (insn
) == NOTE
)
291 insn
= prev_nonnote_insn (insn
);
292 if (insn
&& GET_CODE (insn
) == BARRIER
)
294 /* Output just a no-op so that debuggers don't get confused
295 about which function the pc is in at this address. */
296 asm_fprintf (stream
, "\tnop\n");
300 #ifdef FUNCTION_EXTRA_EPILOGUE
301 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
303 nregs
= 0; fmask
= 0; fpoffset
= 0;
304 #ifdef SUPPORT_SUN_FPA
305 for (regno
= 24 ; regno
< 56 ; regno
++)
306 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
308 fpoffset
= nregs
* 8;
311 for (regno
= 16; regno
< 24; regno
++)
312 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
315 fmask
|= 1 << (23 - regno
);
317 foffset
= fpoffset
+ nregs
* 12;
319 if (frame_pointer_needed
)
320 regs_ever_live
[FRAME_POINTER_REGNUM
] = 0;
321 for (regno
= 0; regno
< 16; regno
++)
322 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
327 offset
= foffset
+ nregs
* 4;
328 if (offset
+ fsize
>= 0x8000
329 && frame_pointer_needed
330 && (mask
|| fmask
|| fpoffset
))
333 asm_fprintf (stream
, "\t%Omove.l %0I%d,%Ra1\n", -fsize
);
335 asm_fprintf (stream
, "\tmovel %0I%d,%Ra1\n", -fsize
);
341 /* Restore each separately in the same order moveml does.
342 Using two movel instructions instead of a single moveml
343 is about 15% faster for the 68020 and 68030 at no expense
348 /* Undo the work from above. */
349 for (i
= 0; i
< 16; i
++)
355 asm_fprintf (stream
, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
357 reg_names
[FRAME_POINTER_REGNUM
],
360 asm_fprintf (stream
, "\tmovel %s@(-%d,%Ra1:l),%s\n",
361 reg_names
[FRAME_POINTER_REGNUM
],
362 offset
+ fsize
, reg_names
[i
]);
365 else if (! frame_pointer_needed
)
368 asm_fprintf (stream
, "\t%Omove.l (%Rsp)+,%s\n",
371 asm_fprintf (stream
, "\tmovel %Rsp@+,%s\n",
378 asm_fprintf (stream
, "\t%Omove.l -%d(%s),%s\n",
380 reg_names
[FRAME_POINTER_REGNUM
],
383 asm_fprintf (stream
, "\tmovel %s@(-%d),%s\n",
384 reg_names
[FRAME_POINTER_REGNUM
],
385 offset
+ fsize
, reg_names
[i
]);
396 asm_fprintf (stream
, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
398 reg_names
[FRAME_POINTER_REGNUM
],
401 asm_fprintf (stream
, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
402 reg_names
[FRAME_POINTER_REGNUM
],
403 offset
+ fsize
, mask
);
406 else if (! frame_pointer_needed
)
409 asm_fprintf (stream
, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask
);
411 asm_fprintf (stream
, "\tmoveml %Rsp@+,%0I0x%x\n", mask
);
417 asm_fprintf (stream
, "\tmovm.l -%d(%s),%0I0x%x\n",
419 reg_names
[FRAME_POINTER_REGNUM
],
422 asm_fprintf (stream
, "\tmoveml %s@(-%d),%0I0x%x\n",
423 reg_names
[FRAME_POINTER_REGNUM
],
424 offset
+ fsize
, mask
);
433 asm_fprintf (stream
, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
435 reg_names
[FRAME_POINTER_REGNUM
],
438 asm_fprintf (stream
, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
439 reg_names
[FRAME_POINTER_REGNUM
],
440 foffset
+ fsize
, fmask
);
443 else if (! frame_pointer_needed
)
446 asm_fprintf (stream
, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask
);
448 asm_fprintf (stream
, "\tfmovem %Rsp@+,%0I0x%x\n", fmask
);
454 asm_fprintf (stream
, "\tfmovm -%d(%s),%0I0x%x\n",
456 reg_names
[FRAME_POINTER_REGNUM
],
459 asm_fprintf (stream
, "\tfmovem %s@(-%d),%0I0x%x\n",
460 reg_names
[FRAME_POINTER_REGNUM
],
461 foffset
+ fsize
, fmask
);
466 for (regno
= 55; regno
>= 24; regno
--)
467 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
472 asm_fprintf (stream
, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
474 reg_names
[FRAME_POINTER_REGNUM
],
477 asm_fprintf (stream
, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
478 reg_names
[FRAME_POINTER_REGNUM
],
479 fpoffset
+ fsize
, reg_names
[regno
]);
482 else if (! frame_pointer_needed
)
485 asm_fprintf (stream
, "\tfpmovd (%Rsp)+,%s\n",
488 asm_fprintf (stream
, "\tfpmoved %Rsp@+, %s\n",
495 asm_fprintf (stream
, "\tfpmovd -%d(%s), %s\n",
497 reg_names
[FRAME_POINTER_REGNUM
],
500 asm_fprintf (stream
, "\tfpmoved %s@(-%d), %s\n",
501 reg_names
[FRAME_POINTER_REGNUM
],
502 fpoffset
+ fsize
, reg_names
[regno
]);
507 if (frame_pointer_needed
)
508 fprintf (stream
, "\tunlk %s\n",
509 reg_names
[FRAME_POINTER_REGNUM
]);
512 if (fsize
+ 4 < 0x8000)
514 /* asm_fprintf() cannot handle %. */
516 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", fsize
+ 4);
518 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", fsize
+ 4);
523 /* asm_fprintf() cannot handle %. */
525 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", fsize
+ 4);
527 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", fsize
+ 4);
531 if (current_function_pops_args
)
532 asm_fprintf (stream
, "\trtd %0I%d\n", current_function_pops_args
);
534 fprintf (stream
, "\trts\n");
537 /* Similar to general_operand, but exclude stack_pointer_rtx. */
540 not_sp_operand (op
, mode
)
542 enum machine_mode mode
;
544 return op
!= stack_pointer_rtx
&& general_operand (op
, mode
);
547 /* Return TRUE if X is a valid comparison operator for the dbcc
550 Note it rejects floating point comparison operators.
551 (In the future we could use Fdbcc).
553 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
556 valid_dbcc_comparison_p (x
, mode
)
558 enum machine_mode mode
;
560 /* We could add support for these in the future */
561 if (cc_prev_status
.flags
& CC_IN_68881
)
564 switch (GET_CODE (x
))
567 case EQ
: case NE
: case GTU
: case LTU
:
571 /* Reject some when CC_NO_OVERFLOW is set. This may be over
573 case GT
: case LT
: case GE
: case LE
:
574 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
580 /* Output a dbCC; jCC sequence. Note we do not handle the
581 floating point version of this sequence (Fdbcc). We also
582 do not handle alternative conditions when CC_NO_OVERFLOW is
583 set. It is assumed that valid_dbcc_comparison_p will kick
584 those out before we get here. */
586 output_dbcc_and_branch (operands
)
590 switch (GET_CODE (operands
[3]))
594 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands
);
596 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands
);
602 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands
);
604 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands
);
610 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands
);
612 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands
);
618 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands
);
620 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands
);
626 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands
);
628 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands
);
634 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands
);
636 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands
);
642 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands
);
644 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands
);
650 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands
);
652 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands
);
658 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands
);
660 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands
);
666 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands
);
668 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands
);
676 /* If the decrement is to be done in SImode, then we have
677 to compensate for the fact that dbcc decrements in HImode. */
678 switch (GET_MODE (operands
[0]))
682 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands
);
684 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands
);
697 output_btst (operands
, countop
, dataop
, insn
, signpos
)
703 operands
[0] = countop
;
704 operands
[1] = dataop
;
706 if (GET_CODE (countop
) == CONST_INT
)
708 register int count
= INTVAL (countop
);
709 /* If COUNT is bigger than size of storage unit in use,
710 advance to the containing unit of same size. */
713 int offset
= (count
& ~signpos
) / 8;
714 count
= count
& signpos
;
715 operands
[1] = dataop
= adj_offsettable_operand (dataop
, offset
);
717 if (count
== signpos
)
718 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
720 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
722 /* These three statements used to use next_insns_test_no...
723 but it appears that this should do the same job. */
725 && next_insn_tests_no_inequality (insn
))
728 && next_insn_tests_no_inequality (insn
))
731 && next_insn_tests_no_inequality (insn
))
734 cc_status
.flags
= CC_NOT_NEGATIVE
;
739 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
740 reference and a constant. */
743 symbolic_operand (op
, mode
)
745 enum machine_mode mode
;
747 switch (GET_CODE (op
))
755 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
756 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
757 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
759 #if 0 /* Deleted, with corresponding change in m68k.h,
760 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
762 return GET_MODE (op
) == mode
;
770 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
773 extend_operator(x
, mode
)
775 enum machine_mode mode
;
777 if (GET_MODE(x
) != SImode
)
787 switch (GET_MODE(XEXP(x
, 0)))
798 /* Legitimize PIC addresses. If the address is already
799 position-independent, we return ORIG. Newly generated
800 position-independent addresses go to REG. If we need more
801 than one register, we lose.
803 An address is legitimized by making an indirect reference
804 through the Global Offset Table with the name of the symbol
807 The assembler and linker are responsible for placing the
808 address of the symbol in the GOT. The function prologue
809 is responsible for initializing a5 to the starting address
812 The assembler is also responsible for translating a symbol name
813 into a constant displacement from the start of the GOT.
815 A quick example may make things a little clearer:
817 When not generating PIC code to store the value 12345 into _foo
818 we would generate the following code:
822 When generating PIC two transformations are made. First, the compiler
823 loads the address of foo into a register. So the first transformation makes:
828 The code in movsi will intercept the lea instruction and call this
829 routine which will transform the instructions into:
831 movel a5@(_foo:w), a0
835 That (in a nutshell) is how *all* symbol and label references are
839 legitimize_pic_address (orig
, mode
, reg
)
841 enum machine_mode mode
;
845 /* First handle a simple SYMBOL_REF or LABEL_REF */
846 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
851 pic_ref
= gen_rtx (MEM
, Pmode
,
852 gen_rtx (PLUS
, Pmode
,
853 pic_offset_table_rtx
, orig
));
854 current_function_uses_pic_offset_table
= 1;
855 RTX_UNCHANGING_P (pic_ref
) = 1;
856 emit_move_insn (reg
, pic_ref
);
859 else if (GET_CODE (orig
) == CONST
)
863 /* Make sure this is CONST has not already been legitimized */
864 if (GET_CODE (XEXP (orig
, 0)) == PLUS
865 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
871 /* legitimize both operands of the PLUS */
872 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
874 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
875 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
876 base
== reg
? 0 : reg
);
880 if (GET_CODE (orig
) == CONST_INT
)
881 return plus_constant_for_output (base
, INTVAL (orig
));
882 pic_ref
= gen_rtx (PLUS
, Pmode
, base
, orig
);
883 /* Likewise, should we set special REG_NOTEs here? */
889 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
} CONST_METHOD
;
894 return (i
>= -128 && i
<= 127);
898 const_method (constant
)
904 i
= INTVAL (constant
);
907 /* if -256 < N < 256 but N is not in range for a moveq
908 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
909 if (use_movq (i
^ 0xff))
911 /* Likewise, try with not.w */
912 if (use_movq (i
^ 0xffff))
914 /* This is the only value where neg.w is usefull */
917 /* Try also with swap */
919 if (use_movq ((u
>> 16) | (u
<< 16)))
921 /* Otherwise, use move.l */
925 const_int_cost (constant
)
928 switch (const_method (constant
))
931 /* Constants between -128 and 127 are cheap due to moveq */
937 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
947 output_move_const_into_data_reg (operands
)
952 i
= INTVAL (operands
[1]);
953 switch (const_method (operands
[1]))
956 #if defined (MOTOROLA) && !defined (CRDS)
957 return "moveq%.l %1,%0";
959 return "moveq %1,%0";
962 operands
[1] = gen_rtx (CONST_INT
, VOIDmode
, i
^ 0xff);
963 #if defined (MOTOROLA) && !defined (CRDS)
964 return "moveq%.l %1,%0\n\tnot%.b %0";
966 return "moveq %1,%0\n\tnot%.b %0";
969 operands
[1] = gen_rtx (CONST_INT
, VOIDmode
, i
^ 0xffff);
970 #if defined (MOTOROLA) && !defined (CRDS)
971 return "moveq%.l %1,%0\n\tnot%.w %0";
973 return "moveq %1,%0\n\tnot%.w %0";
976 #if defined (MOTOROLA) && !defined (CRDS)
977 return "moveq%.l %#-128,%0\n\tneg%.w %0";
979 return "moveq %#-128,%0\n\tneg%.w %0";
985 operands
[1] = gen_rtx (CONST_INT
, VOIDmode
, (u
<< 16) | (u
>> 16));
986 #if defined (MOTOROLA) && !defined (CRDS)
987 return "moveq%.l %1,%0\n\tswap %0";
989 return "moveq %1,%0\n\tswap %0";
993 return "move%.l %1,%0";
999 /* Return the best assembler insn template
1000 for moving operands[1] into operands[0] as a fullword. */
1003 singlemove_string (operands
)
1006 #ifdef SUPPORT_SUN_FPA
1007 if (FPA_REG_P (operands
[0]) || FPA_REG_P (operands
[1]))
1008 return "fpmoves %1,%0";
1010 if (DATA_REG_P (operands
[0])
1011 && GET_CODE (operands
[1]) == CONST_INT
)
1012 return output_move_const_into_data_reg (operands
);
1013 if (operands
[1] != const0_rtx
)
1014 return "move%.l %1,%0";
1015 if (! ADDRESS_REG_P (operands
[0]))
1017 return "sub%.l %0,%0";
1021 /* Output assembler code to perform a doubleword move insn
1022 with operands OPERANDS. */
1025 output_move_double (operands
)
1030 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
1035 rtx addreg0
= 0, addreg1
= 0;
1036 int dest_overlapped_low
= 0;
1037 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
1042 /* First classify both operands. */
1044 if (REG_P (operands
[0]))
1046 else if (offsettable_memref_p (operands
[0]))
1048 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
1050 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
1052 else if (GET_CODE (operands
[0]) == MEM
)
1057 if (REG_P (operands
[1]))
1059 else if (CONSTANT_P (operands
[1]))
1061 else if (offsettable_memref_p (operands
[1]))
1063 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
1065 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
1067 else if (GET_CODE (operands
[1]) == MEM
)
1072 /* Check for the cases that the operand constraints are not
1073 supposed to allow to happen. Abort if we get one,
1074 because generating code for these cases is painful. */
1076 if (optype0
== RNDOP
|| optype1
== RNDOP
)
1079 /* If one operand is decrementing and one is incrementing
1080 decrement the former register explicitly
1081 and change that operand into ordinary indexing. */
1083 if (optype0
== PUSHOP
&& optype1
== POPOP
)
1085 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
1087 output_asm_insn ("sub%.l %#12,%0", operands
);
1089 output_asm_insn ("subq%.l %#8,%0", operands
);
1090 if (GET_MODE (operands
[1]) == XFmode
)
1091 operands
[0] = gen_rtx (MEM
, XFmode
, operands
[0]);
1092 else if (GET_MODE (operands
[0]) == DFmode
)
1093 operands
[0] = gen_rtx (MEM
, DFmode
, operands
[0]);
1095 operands
[0] = gen_rtx (MEM
, DImode
, operands
[0]);
1098 if (optype0
== POPOP
&& optype1
== PUSHOP
)
1100 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
1102 output_asm_insn ("sub%.l %#12,%1", operands
);
1104 output_asm_insn ("subq%.l %#8,%1", operands
);
1105 if (GET_MODE (operands
[1]) == XFmode
)
1106 operands
[1] = gen_rtx (MEM
, XFmode
, operands
[1]);
1107 else if (GET_MODE (operands
[1]) == DFmode
)
1108 operands
[1] = gen_rtx (MEM
, DFmode
, operands
[1]);
1110 operands
[1] = gen_rtx (MEM
, DImode
, operands
[1]);
1114 /* If an operand is an unoffsettable memory ref, find a register
1115 we can increment temporarily to make it refer to the second word. */
1117 if (optype0
== MEMOP
)
1118 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1120 if (optype1
== MEMOP
)
1121 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1123 /* Ok, we can do one word at a time.
1124 Normally we do the low-numbered word first,
1125 but if either operand is autodecrementing then we
1126 do the high-numbered word first.
1128 In either case, set up in LATEHALF the operands to use
1129 for the high-numbered word and in some cases alter the
1130 operands in OPERANDS to be suitable for the low-numbered word. */
1134 if (optype0
== REGOP
)
1136 latehalf
[0] = gen_rtx (REG
, SImode
, REGNO (operands
[0]) + 2);
1137 middlehalf
[0] = gen_rtx (REG
, SImode
, REGNO (operands
[0]) + 1);
1139 else if (optype0
== OFFSOP
)
1141 middlehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1142 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1146 middlehalf
[0] = operands
[0];
1147 latehalf
[0] = operands
[0];
1150 if (optype1
== REGOP
)
1152 latehalf
[1] = gen_rtx (REG
, SImode
, REGNO (operands
[1]) + 2);
1153 middlehalf
[1] = gen_rtx (REG
, SImode
, REGNO (operands
[1]) + 1);
1155 else if (optype1
== OFFSOP
)
1157 middlehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1158 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1160 else if (optype1
== CNSTOP
)
1162 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
1167 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
1168 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
1169 operands
[1] = GEN_INT (l
[0]);
1170 middlehalf
[1] = GEN_INT (l
[1]);
1171 latehalf
[1] = GEN_INT (l
[2]);
1173 else if (CONSTANT_P (operands
[1]))
1175 /* actually, no non-CONST_DOUBLE constant should ever
1178 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
1179 latehalf
[1] = constm1_rtx
;
1181 latehalf
[1] = const0_rtx
;
1186 middlehalf
[1] = operands
[1];
1187 latehalf
[1] = operands
[1];
1191 /* size is not 12: */
1193 if (optype0
== REGOP
)
1194 latehalf
[0] = gen_rtx (REG
, SImode
, REGNO (operands
[0]) + 1);
1195 else if (optype0
== OFFSOP
)
1196 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1198 latehalf
[0] = operands
[0];
1200 if (optype1
== REGOP
)
1201 latehalf
[1] = gen_rtx (REG
, SImode
, REGNO (operands
[1]) + 1);
1202 else if (optype1
== OFFSOP
)
1203 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1204 else if (optype1
== CNSTOP
)
1205 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1207 latehalf
[1] = operands
[1];
1210 /* If insn is effectively movd N(sp),-(sp) then we will do the
1211 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1212 for the low word as well, to compensate for the first decrement of sp. */
1213 if (optype0
== PUSHOP
1214 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1215 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
1216 operands
[1] = middlehalf
[1] = latehalf
[1];
1218 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1219 if the upper part of reg N does not appear in the MEM, arrange to
1220 emit the move late-half first. Otherwise, compute the MEM address
1221 into the upper part of N and use that as a pointer to the memory
1223 if (optype0
== REGOP
1224 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
1226 rtx testlow
= gen_rtx (REG
, SImode
, REGNO (operands
[0]));
1228 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1229 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1231 /* If both halves of dest are used in the src memory address,
1232 compute the address into latehalf of dest.
1233 Note that this can't happen if the dest is two data regs. */
1235 xops
[0] = latehalf
[0];
1236 xops
[1] = XEXP (operands
[1], 0);
1237 output_asm_insn ("lea %a1,%0", xops
);
1238 if( GET_MODE (operands
[1]) == XFmode
)
1240 operands
[1] = gen_rtx (MEM
, XFmode
, latehalf
[0]);
1241 middlehalf
[1] = adj_offsettable_operand (operands
[1], size
-8);
1242 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1246 operands
[1] = gen_rtx (MEM
, DImode
, latehalf
[0]);
1247 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1251 && reg_overlap_mentioned_p (middlehalf
[0],
1252 XEXP (operands
[1], 0)))
1254 /* Check for two regs used by both source and dest.
1255 Note that this can't happen if the dest is all data regs.
1256 It can happen if the dest is d6, d7, a0.
1257 But in that case, latehalf is an addr reg, so
1258 the code at compadr does ok. */
1260 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1261 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1264 /* JRV says this can't happen: */
1265 if (addreg0
|| addreg1
)
1268 /* Only the middle reg conflicts; simply put it last. */
1269 output_asm_insn (singlemove_string (operands
), operands
);
1270 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1271 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
1274 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
1275 /* If the low half of dest is mentioned in the source memory
1276 address, the arrange to emit the move late half first. */
1277 dest_overlapped_low
= 1;
1280 /* If one or both operands autodecrementing,
1281 do the two words, high-numbered first. */
1283 /* Likewise, the first move would clobber the source of the second one,
1284 do them in the other order. This happens only for registers;
1285 such overlap can't happen in memory unless the user explicitly
1286 sets it up, and that is an undefined circumstance. */
1288 if (optype0
== PUSHOP
|| optype1
== PUSHOP
1289 || (optype0
== REGOP
&& optype1
== REGOP
1290 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
1291 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
1292 || dest_overlapped_low
)
1294 /* Make any unoffsettable addresses point at high-numbered word. */
1298 output_asm_insn ("addq%.l %#8,%0", &addreg0
);
1300 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
1305 output_asm_insn ("addq%.l %#8,%0", &addreg1
);
1307 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
1311 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1313 /* Undo the adds we just did. */
1315 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
1317 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
1321 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
1323 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
1325 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
1328 /* Do low-numbered word. */
1329 return singlemove_string (operands
);
1332 /* Normal case: do the two words, low-numbered first. */
1334 output_asm_insn (singlemove_string (operands
), operands
);
1336 /* Do the middle one of the three words for long double */
1340 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
1342 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
1344 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
1347 /* Make any unoffsettable addresses point at high-numbered word. */
1349 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
1351 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
1354 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1356 /* Undo the adds we just did. */
1360 output_asm_insn ("subq%.l %#8,%0", &addreg0
);
1362 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
1367 output_asm_insn ("subq%.l %#8,%0", &addreg1
);
1369 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
1375 /* Return a REG that occurs in ADDR with coefficient 1.
1376 ADDR can be effectively incremented by incrementing REG. */
1379 find_addr_reg (addr
)
1382 while (GET_CODE (addr
) == PLUS
)
1384 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1385 addr
= XEXP (addr
, 0);
1386 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
1387 addr
= XEXP (addr
, 1);
1388 else if (CONSTANT_P (XEXP (addr
, 0)))
1389 addr
= XEXP (addr
, 1);
1390 else if (CONSTANT_P (XEXP (addr
, 1)))
1391 addr
= XEXP (addr
, 0);
1395 if (GET_CODE (addr
) == REG
)
1400 /* Store in cc_status the expressions that the condition codes will
1401 describe after execution of an instruction whose pattern is EXP.
1402 Do not alter them if the instruction would not alter the cc's. */
1404 /* On the 68000, all the insns to store in an address register fail to
1405 set the cc's. However, in some cases these instructions can make it
1406 possibly invalid to use the saved cc's. In those cases we clear out
1407 some or all of the saved cc's so they won't be used. */
1409 notice_update_cc (exp
, insn
)
1413 /* If the cc is being set from the fpa and the expression is not an
1414 explicit floating point test instruction (which has code to deal with
1415 this), reinit the CC. */
1416 if (((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
1417 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
)))
1418 && !(GET_CODE (exp
) == PARALLEL
1419 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
1420 && XEXP (XVECEXP (exp
, 0, 0), 0) == cc0_rtx
))
1424 else if (GET_CODE (exp
) == SET
)
1426 if (GET_CODE (SET_SRC (exp
)) == CALL
)
1430 else if (ADDRESS_REG_P (SET_DEST (exp
)))
1432 if (cc_status
.value1
1433 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value1
))
1434 cc_status
.value1
= 0;
1435 if (cc_status
.value2
1436 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value2
))
1437 cc_status
.value2
= 0;
1439 else if (!FP_REG_P (SET_DEST (exp
))
1440 && SET_DEST (exp
) != cc0_rtx
1441 && (FP_REG_P (SET_SRC (exp
))
1442 || GET_CODE (SET_SRC (exp
)) == FIX
1443 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
1444 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
1448 /* A pair of move insns doesn't produce a useful overall cc. */
1449 else if (!FP_REG_P (SET_DEST (exp
))
1450 && !FP_REG_P (SET_SRC (exp
))
1451 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
1452 && (GET_CODE (SET_SRC (exp
)) == REG
1453 || GET_CODE (SET_SRC (exp
)) == MEM
1454 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
1458 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
1462 else if (XEXP (exp
, 0) != pc_rtx
)
1464 cc_status
.flags
= 0;
1465 cc_status
.value1
= XEXP (exp
, 0);
1466 cc_status
.value2
= XEXP (exp
, 1);
1469 else if (GET_CODE (exp
) == PARALLEL
1470 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
1472 if (ADDRESS_REG_P (XEXP (XVECEXP (exp
, 0, 0), 0)))
1474 else if (XEXP (XVECEXP (exp
, 0, 0), 0) != pc_rtx
)
1476 cc_status
.flags
= 0;
1477 cc_status
.value1
= XEXP (XVECEXP (exp
, 0, 0), 0);
1478 cc_status
.value2
= XEXP (XVECEXP (exp
, 0, 0), 1);
1483 if (cc_status
.value2
!= 0
1484 && ADDRESS_REG_P (cc_status
.value2
)
1485 && GET_MODE (cc_status
.value2
) == QImode
)
1487 if (cc_status
.value2
!= 0
1488 && !(cc_status
.value1
&& FPA_REG_P (cc_status
.value1
)))
1489 switch (GET_CODE (cc_status
.value2
))
1491 case PLUS
: case MINUS
: case MULT
:
1492 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
1493 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
1494 case ROTATE
: case ROTATERT
:
1495 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
1496 cc_status
.flags
|= CC_NO_OVERFLOW
;
1499 /* (SET r1 (ZERO_EXTEND r2)) on this machine
1500 ends with a move insn moving r2 in r2's mode.
1501 Thus, the cc's are set for r2.
1502 This can set N bit spuriously. */
1503 cc_status
.flags
|= CC_NOT_NEGATIVE
;
1505 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
1507 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
1508 cc_status
.value2
= 0;
1509 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
1510 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
)))
1511 && !((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
1512 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
))))
1513 cc_status
.flags
= CC_IN_68881
;
1517 output_move_const_double (operands
)
1520 #ifdef SUPPORT_SUN_FPA
1521 if (TARGET_FPA
&& FPA_REG_P (operands
[0]))
1523 int code
= standard_sun_fpa_constant_p (operands
[1]);
1527 static char buf
[40];
1529 sprintf (buf
, "fpmove%%.d %%%%%d,%%0", code
& 0x1ff);
1532 return "fpmove%.d %1,%0";
1537 int code
= standard_68881_constant_p (operands
[1]);
1541 static char buf
[40];
1543 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
1546 return "fmove%.d %1,%0";
1551 output_move_const_single (operands
)
1554 #ifdef SUPPORT_SUN_FPA
1557 int code
= standard_sun_fpa_constant_p (operands
[1]);
1561 static char buf
[40];
1563 sprintf (buf
, "fpmove%%.s %%%%%d,%%0", code
& 0x1ff);
1566 return "fpmove%.s %1,%0";
1569 #endif /* defined SUPPORT_SUN_FPA */
1571 int code
= standard_68881_constant_p (operands
[1]);
1575 static char buf
[40];
1577 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
1580 return "fmove%.s %f1,%0";
1584 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1585 from the "fmovecr" instruction.
1586 The value, anded with 0xff, gives the code to use in fmovecr
1587 to get the desired constant. */
1589 /* This code has been fixed for cross-compilation. */
1591 static int inited_68881_table
= 0;
1593 char *strings_68881
[7] = {
1603 int codes_68881
[7] = {
1613 REAL_VALUE_TYPE values_68881
[7];
1615 /* Set up values_68881 array by converting the decimal values
1616 strings_68881 to binary. */
1623 enum machine_mode mode
;
1626 for (i
= 0; i
< 7; i
++)
1630 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
1631 values_68881
[i
] = r
;
1633 inited_68881_table
= 1;
1637 standard_68881_constant_p (x
)
1642 enum machine_mode mode
;
1644 #ifdef NO_ASM_FMOVECR
1648 /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */
1652 #ifndef REAL_ARITHMETIC
1653 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1654 if (! flag_pretend_float
)
1659 if (! inited_68881_table
)
1660 init_68881_table ();
1662 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
1664 for (i
= 0; i
< 6; i
++)
1666 if (REAL_VALUES_EQUAL (r
, values_68881
[i
]))
1667 return (codes_68881
[i
]);
1670 if (GET_MODE (x
) == SFmode
)
1673 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
1674 return (codes_68881
[6]);
1676 /* larger powers of ten in the constants ram are not used
1677 because they are not equal to a `double' C constant. */
1681 /* If X is a floating-point constant, return the logarithm of X base 2,
1682 or 0 if X is not a power of 2. */
1685 floating_exact_log2 (x
)
1688 REAL_VALUE_TYPE r
, r1
;
1691 #ifndef REAL_ARITHMETIC
1692 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1693 if (! flag_pretend_float
)
1698 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
1700 if (REAL_VALUES_LESS (r
, dconst0
))
1705 while (REAL_VALUES_LESS (r1
, r
))
1707 r1
= REAL_VALUE_LDEXP (dconst1
, i
);
1708 if (REAL_VALUES_EQUAL (r1
, r
))
1715 #ifdef SUPPORT_SUN_FPA
1716 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1717 from the Sun FPA's constant RAM.
1718 The value returned, anded with 0x1ff, gives the code to use in fpmove
1719 to get the desired constant. */
1721 static int inited_FPA_table
= 0;
1723 char *strings_FPA
[38] = {
1724 /* small rationals */
1737 /* Decimal equivalents of double precision values */
1738 "2.718281828459045091", /* D_E */
1739 "6.283185307179586477", /* 2 pi */
1740 "3.141592653589793116", /* D_PI */
1741 "1.570796326794896619", /* pi/2 */
1742 "1.414213562373095145", /* D_SQRT2 */
1743 "0.7071067811865475244", /* 1/sqrt(2) */
1744 "-1.570796326794896619", /* -pi/2 */
1745 "1.442695040888963387", /* D_LOG2ofE */
1746 "3.321928024887362182", /* D_LOG2of10 */
1747 "0.6931471805599452862", /* D_LOGEof2 */
1748 "2.302585092994045901", /* D_LOGEof10 */
1749 "0.3010299956639811980", /* D_LOG10of2 */
1750 "0.4342944819032518167", /* D_LOG10ofE */
1751 /* Decimal equivalents of single precision values */
1752 "2.718281745910644531", /* S_E */
1753 "6.283185307179586477", /* 2 pi */
1754 "3.141592741012573242", /* S_PI */
1755 "1.570796326794896619", /* pi/2 */
1756 "1.414213538169860840", /* S_SQRT2 */
1757 "0.7071067811865475244", /* 1/sqrt(2) */
1758 "-1.570796326794896619", /* -pi/2 */
1759 "1.442695021629333496", /* S_LOG2ofE */
1760 "3.321928024291992188", /* S_LOG2of10 */
1761 "0.6931471824645996094", /* S_LOGEof2 */
1762 "2.302585124969482442", /* S_LOGEof10 */
1763 "0.3010300099849700928", /* S_LOG10of2 */
1764 "0.4342944920063018799", /* S_LOG10ofE */
1768 int codes_FPA
[38] = {
1769 /* small rationals */
1782 /* double precision */
1796 /* single precision */
1812 REAL_VALUE_TYPE values_FPA
[38];
1814 /* This code has been fixed for cross-compilation. */
1819 enum machine_mode mode
;
1824 for (i
= 0; i
< 38; i
++)
1828 r
= REAL_VALUE_ATOF (strings_FPA
[i
], mode
);
1831 inited_FPA_table
= 1;
1836 standard_sun_fpa_constant_p (x
)
1842 #ifndef REAL_ARITHMETIC
1843 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1844 if (! flag_pretend_float
)
1849 if (! inited_FPA_table
)
1852 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
1854 for (i
=0; i
<12; i
++)
1856 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
1857 return (codes_FPA
[i
]);
1860 if (GET_MODE (x
) == SFmode
)
1862 for (i
=25; i
<38; i
++)
1864 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
1865 return (codes_FPA
[i
]);
1870 for (i
=12; i
<25; i
++)
1872 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
1873 return (codes_FPA
[i
]);
1878 #endif /* define SUPPORT_SUN_FPA */
1880 /* A C compound statement to output to stdio stream STREAM the
1881 assembler syntax for an instruction operand X. X is an RTL
1884 CODE is a value that can be used to specify one of several ways
1885 of printing the operand. It is used when identical operands
1886 must be printed differently depending on the context. CODE
1887 comes from the `%' specification that was used to request
1888 printing of the operand. If the specification was just `%DIGIT'
1889 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
1890 is the ASCII code for LTR.
1892 If X is a register, this macro should print the register's name.
1893 The names can be found in an array `reg_names' whose type is
1894 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
1896 When the machine description has a specification `%PUNCT' (a `%'
1897 followed by a punctuation character), this macro is called with
1898 a null pointer for X and the punctuation character for CODE.
1900 The m68k specific codes are:
1902 '.' for dot needed in Motorola-style opcode names.
1903 '-' for an operand pushing on the stack:
1904 sp@-, -(sp) or -(%sp) depending on the style of syntax.
1905 '+' for an operand pushing on the stack:
1906 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
1907 '@' for a reference to the top word on the stack:
1908 sp@, (sp) or (%sp) depending on the style of syntax.
1909 '#' for an immediate operand prefix (# in MIT and Motorola syntax
1910 but & in SGS syntax).
1911 '!' for the cc register (used in an `and to cc' insn).
1912 '$' for the letter `s' in an op code, but only on the 68040.
1913 '&' for the letter `d' in an op code, but only on the 68040.
1914 '/' for register prefix needed by longlong.h.
1916 'b' for byte insn (no effect, on the Sun; this is for the ISI).
1917 'd' to force memory addressing to be absolute, not relative.
1918 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
1919 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
1920 than directly). Second part of 'y' below.
1921 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
1922 or print pair of registers as rx:ry.
1923 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
1924 CONST_DOUBLE's as SunFPA constant RAM registers if
1925 possible, so it should not be used except for the SunFPA.
1930 print_operand (file
, op
, letter
)
1931 FILE *file
; /* file to write to */
1932 rtx op
; /* operand to print */
1933 int letter
; /* %<letter> or 0 */
1940 asm_fprintf (file
, ".");
1943 else if (letter
== '#')
1945 asm_fprintf (file
, "%0I");
1947 else if (letter
== '-')
1950 asm_fprintf (file
, "-(%Rsp)");
1952 asm_fprintf (file
, "%Rsp@-");
1955 else if (letter
== '+')
1958 asm_fprintf (file
, "(%Rsp)+");
1960 asm_fprintf (file
, "%Rsp@+");
1963 else if (letter
== '@')
1966 asm_fprintf (file
, "(%Rsp)");
1968 asm_fprintf (file
, "%Rsp@");
1971 else if (letter
== '!')
1973 asm_fprintf (file
, "%Rfpcr");
1975 else if (letter
== '$')
1977 if (TARGET_68040_ONLY
)
1979 fprintf (file
, "s");
1982 else if (letter
== '&')
1984 if (TARGET_68040_ONLY
)
1986 fprintf (file
, "d");
1989 else if (letter
== '/')
1991 asm_fprintf (file
, "%R");
1993 else if (GET_CODE (op
) == REG
)
1995 #ifdef SUPPORT_SUN_FPA
1997 && (letter
== 'y' || letter
== 'x')
1998 && GET_MODE (op
) == DFmode
)
2000 fprintf (file
, "%s:%s", reg_names
[REGNO (op
)],
2001 reg_names
[REGNO (op
)+1]);
2006 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
2009 else if (GET_CODE (op
) == MEM
)
2011 output_address (XEXP (op
, 0));
2012 if (letter
== 'd' && ! TARGET_68020
2013 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
2014 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
2015 && INTVAL (XEXP (op
, 0)) < 0x8000
2016 && INTVAL (XEXP (op
, 0)) >= -0x8000))
2018 fprintf (file
, ":l");
2021 #ifdef SUPPORT_SUN_FPA
2022 else if ((letter
== 'y' || letter
== 'w')
2023 && GET_CODE (op
) == CONST_DOUBLE
2024 && (i
= standard_sun_fpa_constant_p (op
)))
2026 fprintf (file
, "%%%d", i
& 0x1ff);
2029 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
2032 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2033 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
2035 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
2038 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2039 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
2041 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
2044 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2045 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
2049 asm_fprintf (file
, "%0I"); output_addr_const (file
, op
);
2054 /* A C compound statement to output to stdio stream STREAM the
2055 assembler syntax for an instruction operand that is a memory
2056 reference whose address is ADDR. ADDR is an RTL expression.
2058 Note that this contains a kludge that knows that the only reason
2059 we have an address (plus (label_ref...) (reg...)) when not generating
2060 PIC code is in the insn before a tablejump, and we know that m68k.md
2061 generates a label LInnn: on such an insn.
2063 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2064 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2066 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2067 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2068 we want. This difference can be accommodated by using an assembler
2069 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2070 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2071 macro. See m68k/sgs.h for an example; for versions without the bug.
2072 Some assemblers refuse all the above solutions. The workaround is to
2073 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2076 They also do not like things like "pea 1.w", so we simple leave off
2077 the .w on small constants.
2079 This routine is responsible for distinguishing between -fpic and -fPIC
2080 style relocations in an address. When generating -fpic code the
2081 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2082 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2084 #ifndef ASM_OUTPUT_CASE_FETCH
2087 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2088 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2090 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2091 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2094 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2095 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2097 #endif /* ASM_OUTPUT_CASE_FETCH */
2100 print_operand_address (file
, addr
)
2104 register rtx reg1
, reg2
, breg
, ireg
;
2107 switch (GET_CODE (addr
))
2111 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
2113 fprintf (file
, "%s@", reg_names
[REGNO (addr
)]);
2118 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
2120 fprintf (file
, "%s@-", reg_names
[REGNO (XEXP (addr
, 0))]);
2125 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
2127 fprintf (file
, "%s@+", reg_names
[REGNO (XEXP (addr
, 0))]);
2131 reg1
= reg2
= ireg
= breg
= offset
= 0;
2132 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
2134 offset
= XEXP (addr
, 0);
2135 addr
= XEXP (addr
, 1);
2137 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
2139 offset
= XEXP (addr
, 1);
2140 addr
= XEXP (addr
, 0);
2142 if (GET_CODE (addr
) != PLUS
)
2146 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
2148 reg1
= XEXP (addr
, 0);
2149 addr
= XEXP (addr
, 1);
2151 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
2153 reg1
= XEXP (addr
, 1);
2154 addr
= XEXP (addr
, 0);
2156 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
2158 reg1
= XEXP (addr
, 0);
2159 addr
= XEXP (addr
, 1);
2161 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
2163 reg1
= XEXP (addr
, 1);
2164 addr
= XEXP (addr
, 0);
2166 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
2168 reg1
= XEXP (addr
, 0);
2169 addr
= XEXP (addr
, 1);
2171 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2173 reg1
= XEXP (addr
, 1);
2174 addr
= XEXP (addr
, 0);
2176 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
2177 || GET_CODE (addr
) == SIGN_EXTEND
)
2189 #if 0 /* for OLD_INDEXING */
2190 else if (GET_CODE (addr
) == PLUS
)
2192 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2194 reg2
= XEXP (addr
, 0);
2195 addr
= XEXP (addr
, 1);
2197 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2199 reg2
= XEXP (addr
, 1);
2200 addr
= XEXP (addr
, 0);
2212 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
2213 || GET_CODE (reg1
) == MULT
))
2214 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
2219 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
2224 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
2225 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
2228 if (GET_CODE (ireg
) == MULT
)
2230 scale
= INTVAL (XEXP (ireg
, 1));
2231 ireg
= XEXP (ireg
, 0);
2233 if (GET_CODE (ireg
) == SIGN_EXTEND
)
2235 ASM_OUTPUT_CASE_FETCH (file
,
2236 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
2237 reg_names
[REGNO (XEXP (ireg
, 0))]);
2238 fprintf (file
, "w");
2242 ASM_OUTPUT_CASE_FETCH (file
,
2243 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
2244 reg_names
[REGNO (ireg
)]);
2245 fprintf (file
, "l");
2250 fprintf (file
, "*%d", scale
);
2252 fprintf (file
, ":%d", scale
);
2258 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
2259 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
2261 ASM_OUTPUT_CASE_FETCH (file
,
2262 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
2263 reg_names
[REGNO (breg
)]);
2264 fprintf (file
, "l)");
2267 if (ireg
!= 0 || breg
!= 0)
2274 if (! flag_pic
&& addr
&& GET_CODE (addr
) == LABEL_REF
)
2281 output_addr_const (file
, addr
);
2282 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
2283 fprintf (file
, "@GOT");
2285 fprintf (file
, "(%s", reg_names
[REGNO (breg
)]);
2291 fprintf (file
, "%s@(", reg_names
[REGNO (breg
)]);
2294 output_addr_const (file
, addr
);
2295 if ((flag_pic
== 1) && (breg
== pic_offset_table_rtx
))
2296 fprintf (file
, ":w");
2297 if ((flag_pic
== 2) && (breg
== pic_offset_table_rtx
))
2298 fprintf (file
, ":l");
2300 if (addr
!= 0 && ireg
!= 0)
2305 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
2307 scale
= INTVAL (XEXP (ireg
, 1));
2308 ireg
= XEXP (ireg
, 0);
2310 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
2313 fprintf (file
, "%s.w", reg_names
[REGNO (XEXP (ireg
, 0))]);
2315 fprintf (file
, "%s:w", reg_names
[REGNO (XEXP (ireg
, 0))]);
2321 fprintf (file
, "%s.l", reg_names
[REGNO (ireg
)]);
2323 fprintf (file
, "%s:l", reg_names
[REGNO (ireg
)]);
2329 fprintf (file
, "*%d", scale
);
2331 fprintf (file
, ":%d", scale
);
2337 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
2338 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
2340 ASM_OUTPUT_CASE_FETCH (file
,
2341 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
2342 reg_names
[REGNO (reg1
)]);
2343 fprintf (file
, "l)");
2346 /* FALL-THROUGH (is this really what we want? */
2348 if (GET_CODE (addr
) == CONST_INT
2349 && INTVAL (addr
) < 0x8000
2350 && INTVAL (addr
) >= -0x8000)
2354 /* Many SGS assemblers croak on size specifiers for constants. */
2355 fprintf (file
, "%d", INTVAL (addr
));
2357 fprintf (file
, "%d.w", INTVAL (addr
));
2360 fprintf (file
, "%d:w", INTVAL (addr
));
2365 output_addr_const (file
, addr
);
2371 /* Check for cases where a clr insns can be omitted from code using
2372 strict_low_part sets. For example, the second clrl here is not needed:
2373 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
2375 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
2376 insn we are checking for redundancy. TARGET is the register set by the
2380 strict_low_part_peephole_ok (mode
, first_insn
, target
)
2381 enum machine_mode mode
;
2387 p
= prev_nonnote_insn (first_insn
);
2391 /* If it isn't an insn, then give up. */
2392 if (GET_CODE (p
) != INSN
)
2395 if (reg_set_p (target
, p
))
2397 rtx set
= single_set (p
);
2400 /* If it isn't an easy to recognize insn, then give up. */
2404 dest
= SET_DEST (set
);
2406 /* If this sets the entire target register to zero, then our
2407 first_insn is redundant. */
2408 if (rtx_equal_p (dest
, target
)
2409 && SET_SRC (set
) == const0_rtx
)
2411 else if (GET_CODE (dest
) == STRICT_LOW_PART
2412 && GET_CODE (XEXP (dest
, 0)) == REG
2413 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
2414 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
2415 <= GET_MODE_SIZE (mode
)))
2416 /* This is a strict low part set which modifies less than
2417 we are using, so it is safe. */
2423 p
= prev_nonnote_insn (p
);
2430 /* Accept integer operands in the range 0..0xffffffff. We have to check the
2431 range carefully since this predicate is used in DImode contexts. Also, we
2432 need some extra crud to make it work when hosted on 64-bit machines. */
2435 const_uint32_operand (op
, mode
)
2437 enum machine_mode mode
;
2439 #if HOST_BITS_PER_WIDE_INT > 32
2440 /* All allowed constants will fit a CONST_INT. */
2441 return (GET_CODE (op
) == CONST_INT
2442 && (INTVAL (op
) >= 0 && INTVAL (op
) <= 0xffffffffL
));
2444 return (GET_CODE (op
) == CONST_INT
2445 || (GET_CODE (op
) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op
) == 0));
2449 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
2450 to check the range carefully since this predicate is used in DImode
2454 const_sint32_operand (op
, mode
)
2456 enum machine_mode mode
;
2458 /* All allowed constants will fit a CONST_INT. */
2459 return (GET_CODE (op
) == CONST_INT
2460 && (INTVAL (op
) >= (-0x7fffffff - 1) && INTVAL (op
) <= 0x7fffffff));