1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993 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 */
63 if (flag_pic && current_function_uses_pic_offset_table)
64 emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
68 /* This function generates the assembly code for function entry.
69 STREAM is a stdio stream to output the code to.
70 SIZE is an int: how many units of temporary storage to allocate.
71 Refer to the array `regs_ever_live' to determine which registers
72 to save; `regs_ever_live[I]' is nonzero if register number I
73 is ever used in the function. This function is responsible for
74 knowing which registers should not be saved even if used. */
77 /* Note that the order of the bit mask for fmovem is the opposite
78 of the order for movem! */
82 output_function_prologue (stream, size)
87 register int mask = 0;
88 int num_saved_regs = 0;
89 extern char call_used_regs[];
90 int fsize = (size + 3) & -4;
93 if (frame_pointer_needed)
95 /* Adding negative number is faster on the 68040. */
96 if (fsize < 0x8000 && !TARGET_68040)
99 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
100 reg_names[FRAME_POINTER_REGNUM], -fsize);
102 asm_fprintf (stream, "\tlink %s,%0I%d\n",
103 reg_names[FRAME_POINTER_REGNUM], -fsize);
106 else if (TARGET_68020)
109 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
110 reg_names[FRAME_POINTER_REGNUM], -fsize);
112 asm_fprintf (stream, "\tlink %s,%0I%d\n",
113 reg_names[FRAME_POINTER_REGNUM], -fsize);
119 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
120 reg_names[FRAME_POINTER_REGNUM], -fsize);
122 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
123 reg_names[FRAME_POINTER_REGNUM], -fsize);
129 /* Adding negative number is faster on the 68040. */
130 if (fsize + 4 < 0x8000)
133 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
135 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
141 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
143 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
147 #ifdef SUPPORT_SUN_FPA
148 for (regno = 24; regno < 56; regno++)
149 if (regs_ever_live[regno] && ! call_used_regs[regno])
152 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
155 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
160 for (regno = 16; regno < 24; regno++)
161 if (regs_ever_live[regno] && ! call_used_regs[regno])
162 mask |= 1 << (regno - 16);
163 if ((mask & 0xff) != 0)
166 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
168 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
172 for (regno = 0; regno < 16; regno++)
173 if (regs_ever_live[regno] && ! call_used_regs[regno])
175 mask |= 1 << (15 - regno);
178 if (frame_pointer_needed)
180 mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
185 fprintf (stream, "\ttstl sp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
188 if (num_saved_regs <= 2)
190 /* Store each separately in the same order moveml uses.
191 Using two movel instructions instead of a single moveml
192 is about 15% faster for the 68020 and 68030 at no expense
197 /* Undo the work from above. */
198 for (i = 0; i< 16; i++)
202 "\t%Omove.l %s,-(%Rsp)\n",
204 "\tmovel %s,%Rsp@-\n",
211 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
213 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
216 if (flag_pic && current_function_uses_pic_offset_table)
219 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
220 reg_names[PIC_OFFSET_TABLE_REGNUM]);
222 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
223 reg_names[PIC_OFFSET_TABLE_REGNUM]);
224 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
225 reg_names[PIC_OFFSET_TABLE_REGNUM],
226 reg_names[PIC_OFFSET_TABLE_REGNUM]);
231 /* Return true if this function's epilogue can be output as RTL. */
238 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
241 /* Copied from output_function_epilogue (). We should probably create a
242 separate layout routine to perform the common work. */
244 for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
245 if (regs_ever_live[regno] && ! call_used_regs[regno])
251 /* This function generates the assembly code for function exit,
252 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
254 The function epilogue should not depend on the current stack pointer!
255 It should use the frame pointer only, if there is a frame pointer.
256 This is mandatory because of alloca; we also take advantage of it to
257 omit stack adjustments before returning. */
260 output_function_epilogue (stream, size)
265 register int mask, fmask;
267 int offset, foffset, fpoffset;
268 extern char call_used_regs[];
269 int fsize = (size + 3) & -4;
271 rtx insn = get_last_insn ();
273 /* If the last insn was a BARRIER, we don't have to write any code. */
274 if (GET_CODE (insn) == NOTE)
275 insn = prev_nonnote_insn (insn);
276 if (insn && GET_CODE (insn) == BARRIER)
278 /* Output just a no-op so that debuggers don't get confused
279 about which function the pc is in at this address. */
280 asm_fprintf (stream, "\tnop\n");
284 #ifdef FUNCTION_EXTRA_EPILOGUE
285 FUNCTION_EXTRA_EPILOGUE (stream, size);
287 nregs = 0; fmask = 0; fpoffset = 0;
288 #ifdef SUPPORT_SUN_FPA
289 for (regno = 24 ; regno < 56 ; regno++)
290 if (regs_ever_live[regno] && ! call_used_regs[regno])
292 fpoffset = nregs * 8;
295 for (regno = 16; regno < 24; regno++)
296 if (regs_ever_live[regno] && ! call_used_regs[regno])
299 fmask |= 1 << (23 - regno);
301 foffset = fpoffset + nregs * 12;
303 if (frame_pointer_needed)
304 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
305 for (regno = 0; regno < 16; regno++)
306 if (regs_ever_live[regno] && ! call_used_regs[regno])
311 offset = foffset + nregs * 4;
312 if (offset + fsize >= 0x8000
313 && frame_pointer_needed
314 && (mask || fmask || fpoffset))
317 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra0\n", -fsize);
319 asm_fprintf (stream, "\tmovel %0I%d,%Ra0\n", -fsize);
325 /* Restore each separately in the same order moveml does.
326 Using two movel instructions instead of a single moveml
327 is about 15% faster for the 68020 and 68030 at no expense
332 /* Undo the work from above. */
333 for (i = 0; i< 16; i++)
339 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra0.l),%s\n",
341 reg_names[FRAME_POINTER_REGNUM],
344 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra0:l),%s\n",
345 reg_names[FRAME_POINTER_REGNUM],
346 offset + fsize, reg_names[i]);
349 else if (! frame_pointer_needed)
352 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
355 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
362 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
364 reg_names[FRAME_POINTER_REGNUM],
367 asm_fprintf (stream, "\tmovel %s@(-%d),%s\n",
368 reg_names[FRAME_POINTER_REGNUM],
369 offset + fsize, reg_names[i]);
380 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra0.l),%0I0x%x\n",
382 reg_names[FRAME_POINTER_REGNUM],
385 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra0:l),%0I0x%x\n",
386 reg_names[FRAME_POINTER_REGNUM],
387 offset + fsize, mask);
390 else if (! frame_pointer_needed)
393 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
395 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
401 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
403 reg_names[FRAME_POINTER_REGNUM],
406 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
407 reg_names[FRAME_POINTER_REGNUM],
408 offset + fsize, mask);
417 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra0.l),%0I0x%x\n",
419 reg_names[FRAME_POINTER_REGNUM],
422 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra0:l),%0I0x%x\n",
423 reg_names[FRAME_POINTER_REGNUM],
424 foffset + fsize, fmask);
427 else if (! frame_pointer_needed)
430 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
432 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
438 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
440 reg_names[FRAME_POINTER_REGNUM],
443 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
444 reg_names[FRAME_POINTER_REGNUM],
445 foffset + fsize, fmask);
450 for (regno = 55; regno >= 24; regno--)
451 if (regs_ever_live[regno] && ! call_used_regs[regno])
456 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra0.l), %s\n",
458 reg_names[FRAME_POINTER_REGNUM],
461 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra0:l), %s\n",
462 reg_names[FRAME_POINTER_REGNUM],
463 fpoffset + fsize, reg_names[regno]);
466 else if (! frame_pointer_needed)
469 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
472 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
479 asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n",
481 reg_names[FRAME_POINTER_REGNUM],
484 asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
485 reg_names[FRAME_POINTER_REGNUM],
486 fpoffset + fsize, reg_names[regno]);
491 if (frame_pointer_needed)
492 fprintf (stream, "\tunlk %s\n",
493 reg_names[FRAME_POINTER_REGNUM]);
496 if (fsize + 4 < 0x8000)
499 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
501 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
507 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
509 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
513 if (current_function_pops_args)
514 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
516 fprintf (stream, "\trts\n");
519 /* Similar to general_operand, but exclude stack_pointer_rtx. */
522 not_sp_operand (op, mode)
524 enum machine_mode mode;
526 return op != stack_pointer_rtx && general_operand (op, mode);
529 /* Return TRUE if X is a valid comparison operator for the dbcc
532 Note it rejects floating point comparison operators.
533 (In the future we could use Fdbcc).
535 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
538 valid_dbcc_comparison_p (x, mode)
540 enum machine_mode mode;
542 /* We could add support for these in the future */
543 if (cc_prev_status.flags & CC_IN_68881)
546 switch (GET_CODE (x))
549 case EQ: case NE: case GTU: case LTU:
553 /* Reject some when CC_NO_OVERFLOW is set. This may be over
555 case GT: case LT: case GE: case LE:
556 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
562 /* Output a dbCC; jCC sequence. Note we do not handle the
563 floating point version of this sequence (Fdbcc). We also
564 do not handle alternative conditions when CC_NO_OVERFLOW is
565 set. It is assumed that valid_dbcc_comparison_p will kick
566 those out before we get here. */
568 output_dbcc_and_branch (operands)
572 switch (GET_CODE (operands[3]))
576 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
578 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
584 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
586 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
592 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
594 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
600 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
602 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
608 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
610 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
616 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
618 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
624 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
626 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
632 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
634 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
640 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
642 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
648 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
650 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
658 /* If the decrement is to be done in SImode, then we have
659 to compensate for the fact that dbcc decrements in HImode. */
660 switch (GET_MODE (operands[0]))
664 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
666 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
679 output_btst (operands, countop, dataop, insn, signpos)
685 operands[0] = countop;
686 operands[1] = dataop;
688 if (GET_CODE (countop) == CONST_INT)
690 register int count = INTVAL (countop);
691 /* If COUNT is bigger than size of storage unit in use,
692 advance to the containing unit of same size. */
695 int offset = (count & ~signpos) / 8;
696 count = count & signpos;
697 operands[1] = dataop = adj_offsettable_operand (dataop, offset);
699 if (count == signpos)
700 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
702 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
704 /* These three statements used to use next_insns_test_no...
705 but it appears that this should do the same job. */
707 && next_insn_tests_no_inequality (insn))
710 && next_insn_tests_no_inequality (insn))
713 && next_insn_tests_no_inequality (insn))
716 cc_status.flags = CC_NOT_NEGATIVE;
721 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
722 reference and a constant. */
725 symbolic_operand (op, mode)
727 enum machine_mode mode;
729 switch (GET_CODE (op))
737 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
738 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
739 && GET_CODE (XEXP (op, 1)) == CONST_INT);
741 #if 0 /* Deleted, with corresponding change in m68k.h,
742 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
744 return GET_MODE (op) == mode;
753 /* Legitimize PIC addresses. If the address is already
754 position-independent, we return ORIG. Newly generated
755 position-independent addresses go to REG. If we need more
756 than one register, we lose.
758 An address is legitimized by making an indirect reference
759 through the Global Offset Table with the name of the symbol
762 The assembler and linker are responsible for placing the
763 address of the symbol in the GOT. The function prologue
764 is responsible for initializing a5 to the starting address
767 The assembler is also responsible for translating a symbol name
768 into a constant displacement from the start of the GOT.
770 A quick example may make things a little clearer:
772 When not generating PIC code to store the value 12345 into _foo
773 we would generate the following code:
777 When generating PIC two transformations are made. First, the compiler
778 loads the address of foo into a register. So the first transformation makes:
783 The code in movsi will intercept the lea instruction and call this
784 routine which will transform the instructions into:
786 movel a5@(_foo:w), a0
790 That (in a nutshell) is how *all* symbol and label references are
794 legitimize_pic_address (orig, mode, reg)
796 enum machine_mode mode;
800 /* First handle a simple SYMBOL_REF or LABEL_REF */
801 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
806 pic_ref = gen_rtx (MEM, Pmode,
807 gen_rtx (PLUS, Pmode,
808 pic_offset_table_rtx, orig));
809 current_function_uses_pic_offset_table = 1;
810 RTX_UNCHANGING_P (pic_ref) = 1;
811 emit_move_insn (reg, pic_ref);
814 else if (GET_CODE (orig) == CONST)
818 /* Make sure this is CONST has not already been legitimized */
819 if (GET_CODE (XEXP (orig, 0)) == PLUS
820 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
826 /* legitimize both operands of the PLUS */
827 if (GET_CODE (XEXP (orig, 0)) == PLUS)
829 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
830 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
831 base == reg ? 0 : reg);
835 if (GET_CODE (orig) == CONST_INT)
836 return plus_constant_for_output (base, INTVAL (orig));
837 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
838 /* Likewise, should we set special REG_NOTEs here? */
844 /* Return the best assembler insn template
845 for moving operands[1] into operands[0] as a fullword. */
848 singlemove_string (operands)
851 #ifdef SUPPORT_SUN_FPA
852 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
853 return "fpmoves %1,%0";
855 if (DATA_REG_P (operands[0])
856 && GET_CODE (operands[1]) == CONST_INT
857 && INTVAL (operands[1]) < 128
858 && INTVAL (operands[1]) >= -128)
860 #if defined (MOTOROLA) && !defined (CRDS)
861 return "moveq%.l %1,%0";
863 return "moveq %1,%0";
866 if (operands[1] != const0_rtx)
867 return "move%.l %1,%0";
868 if (! ADDRESS_REG_P (operands[0]))
870 return "sub%.l %0,%0";
874 /* Output assembler code to perform a doubleword move insn
875 with operands OPERANDS. */
878 output_move_double (operands)
883 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
887 rtx addreg0 = 0, addreg1 = 0;
888 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
893 /* First classify both operands. */
895 if (REG_P (operands[0]))
897 else if (offsettable_memref_p (operands[0]))
899 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
901 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
903 else if (GET_CODE (operands[0]) == MEM)
908 if (REG_P (operands[1]))
910 else if (CONSTANT_P (operands[1]))
912 else if (offsettable_memref_p (operands[1]))
914 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
916 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
918 else if (GET_CODE (operands[1]) == MEM)
923 /* Check for the cases that the operand constraints are not
924 supposed to allow to happen. Abort if we get one,
925 because generating code for these cases is painful. */
927 if (optype0 == RNDOP || optype1 == RNDOP)
930 /* If one operand is decrementing and one is incrementing
931 decrement the former register explicitly
932 and change that operand into ordinary indexing. */
934 if (optype0 == PUSHOP && optype1 == POPOP)
936 operands[0] = XEXP (XEXP (operands[0], 0), 0);
938 output_asm_insn ("sub%.l %#12,%0", operands);
940 output_asm_insn ("subq%.l %#8,%0", operands);
941 if (GET_MODE (operands[1]) == XFmode)
942 operands[0] = gen_rtx (MEM, XFmode, operands[0]);
943 else if (GET_MODE (operands[0]) == DFmode)
944 operands[0] = gen_rtx (MEM, DFmode, operands[0]);
946 operands[0] = gen_rtx (MEM, DImode, operands[0]);
949 if (optype0 == POPOP && optype1 == PUSHOP)
951 operands[1] = XEXP (XEXP (operands[1], 0), 0);
953 output_asm_insn ("sub%.l %#12,%1", operands);
955 output_asm_insn ("subq%.l %#8,%1", operands);
956 if (GET_MODE (operands[1]) == XFmode)
957 operands[1] = gen_rtx (MEM, XFmode, operands[1]);
958 else if (GET_MODE (operands[1]) == DFmode)
959 operands[1] = gen_rtx (MEM, DFmode, operands[1]);
961 operands[1] = gen_rtx (MEM, DImode, operands[1]);
965 /* If an operand is an unoffsettable memory ref, find a register
966 we can increment temporarily to make it refer to the second word. */
968 if (optype0 == MEMOP)
969 addreg0 = find_addr_reg (XEXP (operands[0], 0));
971 if (optype1 == MEMOP)
972 addreg1 = find_addr_reg (XEXP (operands[1], 0));
974 /* Ok, we can do one word at a time.
975 Normally we do the low-numbered word first,
976 but if either operand is autodecrementing then we
977 do the high-numbered word first.
979 In either case, set up in LATEHALF the operands to use
980 for the high-numbered word and in some cases alter the
981 operands in OPERANDS to be suitable for the low-numbered word. */
985 if (optype0 == REGOP)
987 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
988 middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
990 else if (optype0 == OFFSOP)
992 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
993 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
997 middlehalf[0] = operands[0];
998 latehalf[0] = operands[0];
1001 if (optype1 == REGOP)
1003 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
1004 middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1006 else if (optype1 == OFFSOP)
1008 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
1009 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1011 else if (optype1 == CNSTOP)
1013 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1018 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1019 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
1020 operands[1] = GEN_INT (l[0]);
1021 middlehalf[1] = GEN_INT (l[1]);
1022 latehalf[1] = GEN_INT (l[2]);
1024 else if (CONSTANT_P (operands[1]))
1026 /* actually, no non-CONST_DOUBLE constant should ever
1029 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
1030 latehalf[1] = constm1_rtx;
1032 latehalf[1] = const0_rtx;
1037 middlehalf[1] = operands[1];
1038 latehalf[1] = operands[1];
1042 /* size is not 12: */
1044 if (optype0 == REGOP)
1045 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1046 else if (optype0 == OFFSOP)
1047 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
1049 latehalf[0] = operands[0];
1051 if (optype1 == REGOP)
1052 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1053 else if (optype1 == OFFSOP)
1054 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1055 else if (optype1 == CNSTOP)
1056 split_double (operands[1], &operands[1], &latehalf[1]);
1058 latehalf[1] = operands[1];
1061 /* If insn is effectively movd N(sp),-(sp) then we will do the
1062 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1063 for the low word as well, to compensate for the first decrement of sp. */
1064 if (optype0 == PUSHOP
1065 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1066 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
1067 operands[1] = latehalf[1];
1069 /* If one or both operands autodecrementing,
1070 do the two words, high-numbered first. */
1072 /* Likewise, the first move would clobber the source of the second one,
1073 do them in the other order. This happens only for registers;
1074 such overlap can't happen in memory unless the user explicitly
1075 sets it up, and that is an undefined circumstance. */
1077 if (optype0 == PUSHOP || optype1 == PUSHOP
1078 || (optype0 == REGOP && optype1 == REGOP
1079 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1080 || REGNO (operands[0]) == REGNO (latehalf[1]))))
1082 /* Make any unoffsettable addresses point at high-numbered word. */
1086 output_asm_insn ("addql %#8,%0", &addreg0);
1088 output_asm_insn ("addql %#4,%0", &addreg0);
1093 output_asm_insn ("addql %#8,%0", &addreg1);
1095 output_asm_insn ("addql %#4,%0", &addreg1);
1099 output_asm_insn (singlemove_string (latehalf), latehalf);
1101 /* Undo the adds we just did. */
1103 output_asm_insn ("subql %#4,%0", &addreg0);
1105 output_asm_insn ("subql %#4,%0", &addreg1);
1109 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1111 output_asm_insn ("subql %#4,%0", &addreg0);
1113 output_asm_insn ("subql %#4,%0", &addreg1);
1116 /* Do low-numbered word. */
1117 return singlemove_string (operands);
1120 /* Normal case: do the two words, low-numbered first. */
1122 output_asm_insn (singlemove_string (operands), operands);
1124 /* Do the middle one of the three words for long double */
1128 output_asm_insn ("addql %#4,%0", &addreg0);
1130 output_asm_insn ("addql %#4,%0", &addreg1);
1132 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1135 /* Make any unoffsettable addresses point at high-numbered word. */
1137 output_asm_insn ("addql %#4,%0", &addreg0);
1139 output_asm_insn ("addql %#4,%0", &addreg1);
1142 output_asm_insn (singlemove_string (latehalf), latehalf);
1144 /* Undo the adds we just did. */
1148 output_asm_insn ("subql %#8,%0", &addreg0);
1150 output_asm_insn ("subql %#4,%0", &addreg0);
1155 output_asm_insn ("subql %#8,%0", &addreg1);
1157 output_asm_insn ("subql %#4,%0", &addreg1);
1163 /* Return a REG that occurs in ADDR with coefficient 1.
1164 ADDR can be effectively incremented by incrementing REG. */
1167 find_addr_reg (addr)
1170 while (GET_CODE (addr) == PLUS)
1172 if (GET_CODE (XEXP (addr, 0)) == REG)
1173 addr = XEXP (addr, 0);
1174 else if (GET_CODE (XEXP (addr, 1)) == REG)
1175 addr = XEXP (addr, 1);
1176 else if (CONSTANT_P (XEXP (addr, 0)))
1177 addr = XEXP (addr, 1);
1178 else if (CONSTANT_P (XEXP (addr, 1)))
1179 addr = XEXP (addr, 0);
1183 if (GET_CODE (addr) == REG)
1188 /* Store in cc_status the expressions that the condition codes will
1189 describe after execution of an instruction whose pattern is EXP.
1190 Do not alter them if the instruction would not alter the cc's. */
1192 /* On the 68000, all the insns to store in an address register fail to
1193 set the cc's. However, in some cases these instructions can make it
1194 possibly invalid to use the saved cc's. In those cases we clear out
1195 some or all of the saved cc's so they won't be used. */
1197 notice_update_cc (exp, insn)
1201 /* If the cc is being set from the fpa and the expression is not an
1202 explicit floating point test instruction (which has code to deal with
1203 this), reinit the CC. */
1204 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
1205 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
1206 && !(GET_CODE (exp) == PARALLEL
1207 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
1208 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
1212 else if (GET_CODE (exp) == SET)
1214 if (GET_CODE (SET_SRC (exp)) == CALL)
1218 else if (ADDRESS_REG_P (SET_DEST (exp)))
1220 if (cc_status.value1
1221 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1222 cc_status.value1 = 0;
1223 if (cc_status.value2
1224 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1225 cc_status.value2 = 0;
1227 else if (!FP_REG_P (SET_DEST (exp))
1228 && SET_DEST (exp) != cc0_rtx
1229 && (FP_REG_P (SET_SRC (exp))
1230 || GET_CODE (SET_SRC (exp)) == FIX
1231 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
1232 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
1236 /* A pair of move insns doesn't produce a useful overall cc. */
1237 else if (!FP_REG_P (SET_DEST (exp))
1238 && !FP_REG_P (SET_SRC (exp))
1239 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
1240 && (GET_CODE (SET_SRC (exp)) == REG
1241 || GET_CODE (SET_SRC (exp)) == MEM
1242 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
1246 else if (GET_CODE (SET_SRC (exp)) == CALL)
1250 else if (XEXP (exp, 0) != pc_rtx)
1252 cc_status.flags = 0;
1253 cc_status.value1 = XEXP (exp, 0);
1254 cc_status.value2 = XEXP (exp, 1);
1257 else if (GET_CODE (exp) == PARALLEL
1258 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1260 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
1262 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
1264 cc_status.flags = 0;
1265 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
1266 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
1271 if (cc_status.value2 != 0
1272 && ADDRESS_REG_P (cc_status.value2)
1273 && GET_MODE (cc_status.value2) == QImode)
1275 if (cc_status.value2 != 0
1276 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
1277 switch (GET_CODE (cc_status.value2))
1279 case PLUS: case MINUS: case MULT:
1280 case DIV: case UDIV: case MOD: case UMOD: case NEG:
1281 case ASHIFT: case LSHIFT: case ASHIFTRT: case LSHIFTRT:
1282 case ROTATE: case ROTATERT:
1283 if (GET_MODE (cc_status.value2) != VOIDmode)
1284 cc_status.flags |= CC_NO_OVERFLOW;
1287 /* (SET r1 (ZERO_EXTEND r2)) on this machine
1288 ends with a move insn moving r2 in r2's mode.
1289 Thus, the cc's are set for r2.
1290 This can set N bit spuriously. */
1291 cc_status.flags |= CC_NOT_NEGATIVE;
1293 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1295 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1296 cc_status.value2 = 0;
1297 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
1298 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
1299 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
1300 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
1301 cc_status.flags = CC_IN_68881;
1305 output_move_const_double (operands)
1308 #ifdef SUPPORT_SUN_FPA
1309 if (TARGET_FPA && FPA_REG_P (operands[0]))
1311 int code = standard_sun_fpa_constant_p (operands[1]);
1315 static char buf[40];
1317 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
1320 return "fpmove%.d %1,%0";
1325 int code = standard_68881_constant_p (operands[1]);
1329 static char buf[40];
1331 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1334 return "fmove%.d %1,%0";
1339 output_move_const_single (operands)
1342 #ifdef SUPPORT_SUN_FPA
1345 int code = standard_sun_fpa_constant_p (operands[1]);
1349 static char buf[40];
1351 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
1354 return "fpmove%.s %1,%0";
1357 #endif /* defined SUPPORT_SUN_FPA */
1359 int code = standard_68881_constant_p (operands[1]);
1363 static char buf[40];
1365 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1368 return "fmove%.s %f1,%0";
1372 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1373 from the "fmovecr" instruction.
1374 The value, anded with 0xff, gives the code to use in fmovecr
1375 to get the desired constant. */
1377 /* This code has been fixed for cross-compilation. */
1379 static int inited_68881_table = 0;
1381 char *strings_68881[7] = {
1391 int codes_68881[7] = {
1401 REAL_VALUE_TYPE values_68881[7];
1403 /* Set up values_68881 array by converting the decimal values
1404 strings_68881 to binary. */
1411 enum machine_mode mode;
1414 for (i = 0; i < 7; i++)
1418 r = REAL_VALUE_ATOF (strings_68881[i], mode);
1419 values_68881[i] = r;
1421 inited_68881_table = 1;
1425 standard_68881_constant_p (x)
1430 enum machine_mode mode;
1432 /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */
1436 #ifndef REAL_ARITHMETIC
1437 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1438 if (! flag_pretend_float)
1443 if (! inited_68881_table)
1444 init_68881_table ();
1446 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1448 for (i = 0; i < 6; i++)
1450 if (REAL_VALUES_EQUAL (r, values_68881[i]))
1451 return (codes_68881[i]);
1454 if (GET_MODE (x) == SFmode)
1457 if (REAL_VALUES_EQUAL (r, values_68881[6]))
1458 return (codes_68881[6]);
1460 /* larger powers of ten in the constants ram are not used
1461 because they are not equal to a `double' C constant. */
1465 /* If X is a floating-point constant, return the logarithm of X base 2,
1466 or 0 if X is not a power of 2. */
1469 floating_exact_log2 (x)
1472 REAL_VALUE_TYPE r, r1;
1475 #ifndef REAL_ARITHMETIC
1476 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1477 if (! flag_pretend_float)
1482 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1484 if (REAL_VALUES_LESS (r, dconst0))
1489 while (REAL_VALUES_LESS (r1, r))
1491 r1 = REAL_VALUE_LDEXP (dconst1, i);
1492 if (REAL_VALUES_EQUAL (r1, r))
1499 #ifdef SUPPORT_SUN_FPA
1500 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1501 from the Sun FPA's constant RAM.
1502 The value returned, anded with 0x1ff, gives the code to use in fpmove
1503 to get the desired constant. */
1505 static int inited_FPA_table = 0;
1507 char *strings_FPA[38] = {
1508 /* small rationals */
1521 /* Decimal equivalents of double precision values */
1522 "2.718281828459045091", /* D_E */
1523 "6.283185307179586477", /* 2 pi */
1524 "3.141592653589793116", /* D_PI */
1525 "1.570796326794896619", /* pi/2 */
1526 "1.414213562373095145", /* D_SQRT2 */
1527 "0.7071067811865475244", /* 1/sqrt(2) */
1528 "-1.570796326794896619", /* -pi/2 */
1529 "1.442695040888963387", /* D_LOG2ofE */
1530 "3.321928024887362182", /* D_LOG2of10 */
1531 "0.6931471805599452862", /* D_LOGEof2 */
1532 "2.302585092994045901", /* D_LOGEof10 */
1533 "0.3010299956639811980", /* D_LOG10of2 */
1534 "0.4342944819032518167", /* D_LOG10ofE */
1535 /* Decimal equivalents of single precision values */
1536 "2.718281745910644531", /* S_E */
1537 "6.283185307179586477", /* 2 pi */
1538 "3.141592741012573242", /* S_PI */
1539 "1.570796326794896619", /* pi/2 */
1540 "1.414213538169860840", /* S_SQRT2 */
1541 "0.7071067811865475244", /* 1/sqrt(2) */
1542 "-1.570796326794896619", /* -pi/2 */
1543 "1.442695021629333496", /* S_LOG2ofE */
1544 "3.321928024291992188", /* S_LOG2of10 */
1545 "0.6931471824645996094", /* S_LOGEof2 */
1546 "2.302585124969482442", /* S_LOGEof10 */
1547 "0.3010300099849700928", /* S_LOG10of2 */
1548 "0.4342944920063018799", /* S_LOG10ofE */
1552 int codes_FPA[38] = {
1553 /* small rationals */
1566 /* double precision */
1580 /* single precision */
1596 REAL_VALUE_TYPE values_FPA[38];
1598 /* This code has been fixed for cross-compilation. */
1603 enum machine_mode mode;
1608 for (i = 0; i < 38; i++)
1612 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
1615 inited_FPA_table = 1;
1620 standard_sun_fpa_constant_p (x)
1626 #ifndef REAL_ARITHMETIC
1627 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1628 if (! flag_pretend_float)
1633 if (! inited_FPA_table)
1636 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1638 for (i=0; i<12; i++)
1640 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
1641 return (codes_FPA[i]);
1644 if (GET_MODE (x) == SFmode)
1646 for (i=25; i<38; i++)
1648 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
1649 return (codes_FPA[i]);
1654 for (i=12; i<25; i++)
1656 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
1657 return (codes_FPA[i]);
1662 #endif /* define SUPPORT_SUN_FPA */
1664 /* A C compound statement to output to stdio stream STREAM the
1665 assembler syntax for an instruction operand X. X is an RTL
1668 CODE is a value that can be used to specify one of several ways
1669 of printing the operand. It is used when identical operands
1670 must be printed differently depending on the context. CODE
1671 comes from the `%' specification that was used to request
1672 printing of the operand. If the specification was just `%DIGIT'
1673 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
1674 is the ASCII code for LTR.
1676 If X is a register, this macro should print the register's name.
1677 The names can be found in an array `reg_names' whose type is
1678 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
1680 When the machine description has a specification `%PUNCT' (a `%'
1681 followed by a punctuation character), this macro is called with
1682 a null pointer for X and the punctuation character for CODE.
1684 The m68k specific codes are:
1686 '.' for dot needed in Motorola-style opcode names.
1687 '-' for an operand pushing on the stack:
1688 sp@-, -(sp) or -(%sp) depending on the style of syntax.
1689 '+' for an operand pushing on the stack:
1690 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
1691 '@' for a reference to the top word on the stack:
1692 sp@, (sp) or (%sp) depending on the style of syntax.
1693 '#' for an immediate operand prefix (# in MIT and Motorola syntax
1694 but & in SGS syntax).
1695 '!' for the cc register (used in an `and to cc' insn).
1696 '$' for the letter `s' in an op code, but only on the 68040.
1697 '&' for the letter `d' in an op code, but only on the 68040.
1698 '/' for register prefix needed by longlong.h.
1700 'b' for byte insn (no effect, on the Sun; this is for the ISI).
1701 'd' to force memory addressing to be absolute, not relative.
1702 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
1703 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
1704 than directly). Second part of 'y' below.
1705 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
1706 or print pair of registers as rx:ry.
1707 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
1708 CONST_DOUBLE's as SunFPA constant RAM registers if
1709 possible, so it should not be used except for the SunFPA.
1714 print_operand (file, op, letter)
1715 FILE *file; /* file to write to */
1716 rtx op; /* operand to print */
1717 int letter; /* %<letter> or 0 */
1724 asm_fprintf (file, ".");
1727 else if (letter == '#')
1729 asm_fprintf (file, "%0I");
1731 else if (letter == '-')
1734 asm_fprintf (file, "-(%Rsp)");
1736 asm_fprintf (file, "%Rsp@-");
1739 else if (letter == '+')
1742 asm_fprintf (file, "(%Rsp)+");
1744 asm_fprintf (file, "%Rsp@+");
1747 else if (letter == '@')
1750 asm_fprintf (file, "(%Rsp)");
1752 asm_fprintf (file, "%Rsp@");
1755 else if (letter == '!')
1757 asm_fprintf (file, "%Rfpcr");
1759 else if (letter == '$')
1761 if (TARGET_68040_ONLY)
1763 fprintf (file, "s");
1766 else if (letter == '&')
1768 if (TARGET_68040_ONLY)
1770 fprintf (file, "d");
1773 else if (letter == '/')
1775 asm_fprintf (file, "%R");
1777 else if (GET_CODE (op) == REG)
1780 && (letter == 'y' || letter == 'x')
1781 && GET_MODE (op) == DFmode)
1783 fprintf (file, "%s:%s", reg_names[REGNO (op)],
1784 reg_names[REGNO (op)+1]);
1788 fprintf (file, "%s", reg_names[REGNO (op)]);
1791 else if (GET_CODE (op) == MEM)
1793 output_address (XEXP (op, 0));
1794 if (letter == 'd' && ! TARGET_68020
1795 && CONSTANT_ADDRESS_P (XEXP (op, 0))
1796 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
1797 && INTVAL (XEXP (op, 0)) < 0x8000
1798 && INTVAL (XEXP (op, 0)) >= -0x8000))
1800 fprintf (file, ":l");
1803 #ifdef SUPPORT_SUN_FPA
1804 else if ((letter == 'y' || letter == 'w')
1805 && GET_CODE (op) == CONST_DOUBLE
1806 && (i = standard_sun_fpa_constant_p (op)))
1808 fprintf (file, "%%%d", i & 0x1ff);
1811 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
1814 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1815 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
1817 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
1820 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1821 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
1823 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) != DImode)
1826 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1827 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
1831 asm_fprintf (file, "%0I"); output_addr_const (file, op);
1836 /* A C compound statement to output to stdio stream STREAM the
1837 assembler syntax for an instruction operand that is a memory
1838 reference whose address is ADDR. ADDR is an RTL expression.
1840 Note that this contains a kludge that knows that the only reason
1841 we have an address (plus (label_ref...) (reg...)) when not generating
1842 PIC code is in the insn before a tablejump, and we know that m68k.md
1843 generates a label LInnn: on such an insn.
1845 It is possible for PIC to generate a (plus (label_ref...) (reg...))
1846 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
1848 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
1849 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
1850 we want. This difference can be accommodated by using an assembler
1851 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
1852 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
1853 macro. See m68k/sgs.h for an example; for versions without the bug.
1855 They also do not like things like "pea 1.w", so we simple leave off
1856 the .w on small constants.
1858 This routine is responsible for distinguishing between -fpic and -fPIC
1859 style relocations in an address. When generating -fpic code the
1860 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
1861 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
1864 print_operand_address (file, addr)
1868 register rtx reg1, reg2, breg, ireg;
1871 switch (GET_CODE (addr))
1875 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
1877 fprintf (file, "%s@", reg_names[REGNO (addr)]);
1882 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
1884 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
1889 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
1891 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
1895 reg1 = reg2 = ireg = breg = offset = 0;
1896 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
1898 offset = XEXP (addr, 0);
1899 addr = XEXP (addr, 1);
1901 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
1903 offset = XEXP (addr, 1);
1904 addr = XEXP (addr, 0);
1906 if (GET_CODE (addr) != PLUS)
1910 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
1912 reg1 = XEXP (addr, 0);
1913 addr = XEXP (addr, 1);
1915 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
1917 reg1 = XEXP (addr, 1);
1918 addr = XEXP (addr, 0);
1920 else if (GET_CODE (XEXP (addr, 0)) == MULT)
1922 reg1 = XEXP (addr, 0);
1923 addr = XEXP (addr, 1);
1925 else if (GET_CODE (XEXP (addr, 1)) == MULT)
1927 reg1 = XEXP (addr, 1);
1928 addr = XEXP (addr, 0);
1930 else if (GET_CODE (XEXP (addr, 0)) == REG)
1932 reg1 = XEXP (addr, 0);
1933 addr = XEXP (addr, 1);
1935 else if (GET_CODE (XEXP (addr, 1)) == REG)
1937 reg1 = XEXP (addr, 1);
1938 addr = XEXP (addr, 0);
1940 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
1941 || GET_CODE (addr) == SIGN_EXTEND)
1953 #if 0 /* for OLD_INDEXING */
1954 else if (GET_CODE (addr) == PLUS)
1956 if (GET_CODE (XEXP (addr, 0)) == REG)
1958 reg2 = XEXP (addr, 0);
1959 addr = XEXP (addr, 1);
1961 else if (GET_CODE (XEXP (addr, 1)) == REG)
1963 reg2 = XEXP (addr, 1);
1964 addr = XEXP (addr, 0);
1976 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
1977 || GET_CODE (reg1) == MULT))
1978 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
1983 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
1988 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
1989 && ! (flag_pic && ireg == pic_offset_table_rtx))
1992 if (GET_CODE (ireg) == MULT)
1994 scale = INTVAL (XEXP (ireg, 1));
1995 ireg = XEXP (ireg, 0);
1997 if (GET_CODE (ireg) == SIGN_EXTEND)
2001 asm_fprintf (file, "%LLD%d(%Rpc,%s.w",
2002 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2003 reg_names[REGNO (XEXP (ireg, 0))]);
2005 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.w",
2006 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2007 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2008 reg_names[REGNO (XEXP (ireg, 0))]);
2011 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:w",
2012 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2013 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2014 reg_names[REGNO (XEXP (ireg, 0))]);
2021 asm_fprintf (file, "%LLD%d(%Rpc,%s.l",
2022 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2023 reg_names[REGNO (ireg)]);
2025 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l",
2026 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2027 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2028 reg_names[REGNO (ireg)]);
2031 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l",
2032 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2033 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2034 reg_names[REGNO (ireg)]);
2040 fprintf (file, "*%d", scale);
2042 fprintf (file, ":%d", scale);
2048 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
2049 && ! (flag_pic && breg == pic_offset_table_rtx))
2053 asm_fprintf (file, "%LLD%d(%Rpc,%s.l",
2054 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2055 reg_names[REGNO (breg)]);
2057 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l",
2058 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2059 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2060 reg_names[REGNO (breg)]);
2063 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l",
2064 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2065 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2066 reg_names[REGNO (breg)]);
2071 if (ireg != 0 || breg != 0)
2078 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
2085 output_addr_const (file, addr);
2086 if (flag_pic && (breg == pic_offset_table_rtx))
2087 fprintf (file, "@GOT");
2089 fprintf (file, "(%s", reg_names[REGNO (breg)]);
2095 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
2098 output_addr_const (file, addr);
2099 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
2100 fprintf (file, ":w");
2101 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
2102 fprintf (file, ":l");
2104 if (addr != 0 && ireg != 0)
2109 if (ireg != 0 && GET_CODE (ireg) == MULT)
2111 scale = INTVAL (XEXP (ireg, 1));
2112 ireg = XEXP (ireg, 0);
2114 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
2117 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
2119 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
2125 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
2127 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
2133 fprintf (file, "*%d", scale);
2135 fprintf (file, ":%d", scale);
2141 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
2142 && ! (flag_pic && reg1 == pic_offset_table_rtx))
2146 asm_fprintf (file, "%LLD%d(%Rpc,%s.l)",
2147 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2148 reg_names[REGNO (reg1)]);
2150 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l)",
2151 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2152 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2153 reg_names[REGNO (reg1)]);
2156 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l)",
2157 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2158 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2159 reg_names[REGNO (reg1)]);
2163 /* FALL-THROUGH (is this really what we want? */
2165 if (GET_CODE (addr) == CONST_INT
2166 && INTVAL (addr) < 0x8000
2167 && INTVAL (addr) >= -0x8000)
2171 /* Many SGS assemblers croak on size specifiers for constants. */
2172 fprintf (file, "%d", INTVAL (addr));
2174 fprintf (file, "%d.w", INTVAL (addr));
2177 fprintf (file, "%d:w", INTVAL (addr));
2182 output_addr_const (file, addr);
2188 /* Check for cases where a clr insns can be omitted from code using
2189 strict_low_part sets. For example, the second clrl here is not needed:
2190 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
2192 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
2193 insn we are checking for redundancy. TARGET is the register set by the
2197 strict_low_part_peephole_ok (mode, first_insn, target)
2198 enum machine_mode mode;
2204 p = prev_nonnote_insn (first_insn);
2208 /* If it isn't an insn, then give up. */
2209 if (GET_CODE (p) != INSN)
2212 if (reg_set_p (target, p))
2214 rtx set = single_set (p);
2217 /* If it isn't an easy to recognize insn, then give up. */
2221 dest = SET_DEST (set);
2223 /* If this sets the entire target register to zero, then our
2224 first_insn is redundant. */
2225 if (rtx_equal_p (dest, target)
2226 && SET_SRC (set) == const0_rtx)
2228 else if (GET_CODE (dest) == STRICT_LOW_PART
2229 && GET_CODE (XEXP (dest, 0)) == REG
2230 && REGNO (XEXP (dest, 0)) == REGNO (target)
2231 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
2232 <= GET_MODE_SIZE (mode)))
2233 /* This is a strict low part set which modifies less than
2234 we are using, so it is safe. */
2240 p = prev_nonnote_insn (p);