1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2004, 2005,
3 2006, 2007 Free Software Foundation, Inc.
4 Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
34 #include "insn-attr.h"
42 #include "target-def.h"
45 #define FPU_REG_P(X) ((X)>=8 && (X)<14)
46 #define CPU_REG_P(X) ((X)>=0 && (X)<8)
49 /* this is the current value returned by the macro FIRST_PARM_OFFSET
51 int current_first_parm_offset;
53 /* Routines to encode/decode pdp11 floats */
54 static void encode_pdp11_f (const struct real_format *fmt,
55 long *, const REAL_VALUE_TYPE *);
56 static void decode_pdp11_f (const struct real_format *,
57 REAL_VALUE_TYPE *, const long *);
58 static void encode_pdp11_d (const struct real_format *fmt,
59 long *, const REAL_VALUE_TYPE *);
60 static void decode_pdp11_d (const struct real_format *,
61 REAL_VALUE_TYPE *, const long *);
63 /* These two are taken from the corresponding vax descriptors
64 in real.c, changing only the encode/decode routine pointers. */
65 const struct real_format pdp11_f_format =
84 const struct real_format pdp11_d_format =
104 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
105 const REAL_VALUE_TYPE *r)
107 (*vax_f_format.encode) (fmt, buf, r);
108 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
112 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
113 REAL_VALUE_TYPE *r, const long *buf)
116 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
117 (*vax_f_format.decode) (fmt, r, &tbuf);
121 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
122 const REAL_VALUE_TYPE *r)
124 (*vax_d_format.encode) (fmt, buf, r);
125 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
126 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
130 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
131 REAL_VALUE_TYPE *r, const long *buf)
134 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
135 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
136 (*vax_d_format.decode) (fmt, r, tbuf);
139 /* This is where the condition code register lives. */
140 /* rtx cc0_reg_rtx; - no longer needed? */
142 static bool pdp11_handle_option (size_t, const char *, int);
143 static rtx find_addr_reg (rtx);
144 static const char *singlemove_string (rtx *);
145 static bool pdp11_assemble_integer (rtx, unsigned int, int);
146 static void pdp11_output_function_prologue (FILE *, HOST_WIDE_INT);
147 static void pdp11_output_function_epilogue (FILE *, HOST_WIDE_INT);
148 static bool pdp11_rtx_costs (rtx, int, int, int *);
149 static bool pdp11_return_in_memory (tree, tree);
151 /* Initialize the GCC target structure. */
152 #undef TARGET_ASM_BYTE_OP
153 #define TARGET_ASM_BYTE_OP NULL
154 #undef TARGET_ASM_ALIGNED_HI_OP
155 #define TARGET_ASM_ALIGNED_HI_OP NULL
156 #undef TARGET_ASM_ALIGNED_SI_OP
157 #define TARGET_ASM_ALIGNED_SI_OP NULL
158 #undef TARGET_ASM_INTEGER
159 #define TARGET_ASM_INTEGER pdp11_assemble_integer
161 #undef TARGET_ASM_FUNCTION_PROLOGUE
162 #define TARGET_ASM_FUNCTION_PROLOGUE pdp11_output_function_prologue
163 #undef TARGET_ASM_FUNCTION_EPILOGUE
164 #define TARGET_ASM_FUNCTION_EPILOGUE pdp11_output_function_epilogue
166 #undef TARGET_ASM_OPEN_PAREN
167 #define TARGET_ASM_OPEN_PAREN "["
168 #undef TARGET_ASM_CLOSE_PAREN
169 #define TARGET_ASM_CLOSE_PAREN "]"
171 #undef TARGET_DEFAULT_TARGET_FLAGS
172 #define TARGET_DEFAULT_TARGET_FLAGS \
173 (MASK_FPU | MASK_45 | MASK_ABSHI_BUILTIN | TARGET_UNIX_ASM_DEFAULT)
174 #undef TARGET_HANDLE_OPTION
175 #define TARGET_HANDLE_OPTION pdp11_handle_option
177 #undef TARGET_RTX_COSTS
178 #define TARGET_RTX_COSTS pdp11_rtx_costs
180 #undef TARGET_RETURN_IN_MEMORY
181 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
183 struct gcc_target targetm = TARGET_INITIALIZER;
185 /* Implement TARGET_HANDLE_OPTION. */
188 pdp11_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED,
189 int value ATTRIBUTE_UNUSED)
194 target_flags &= ~(MASK_40 | MASK_45);
202 /* Nonzero if OP is a valid second operand for an arithmetic insn. */
205 arith_operand (rtx op, enum machine_mode mode)
207 return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);
211 const_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
213 return (GET_CODE (op) == CONST_INT);
217 immediate15_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
219 return (GET_CODE (op) == CONST_INT && ((INTVAL (op) & 0x8000) == 0x0000));
223 expand_shift_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
225 return (GET_CODE (op) == CONST_INT
226 && abs (INTVAL(op)) > 1
227 && abs (INTVAL(op)) <= 4);
231 stream is a stdio stream to output the code to.
232 size is an int: how many units of temporary storage to allocate.
233 Refer to the array `regs_ever_live' to determine which registers
234 to save; `regs_ever_live[I]' is nonzero if register number I
235 is ever used in the function. This macro is responsible for
236 knowing which registers should not be saved even if used.
242 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
244 fprintf (stream, "\tjsr r5, csv\n");
247 fprintf (stream, "\t/*abuse empty parameter slot for locals!*/\n");
249 asm_fprintf (stream, "\tsub $%#wo, sp\n", size - 2);
257 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
259 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
264 "\n\t; /* function prologue %s*/\n",
265 current_function_name ());
267 /* if we are outputting code for main,
268 the switch FPU to right mode if TARGET_FPU */
269 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
272 "\t;/* switch cpu to double float, single integer */\n");
273 fprintf(stream, "\tsetd\n");
274 fprintf(stream, "\tseti\n\n");
277 if (frame_pointer_needed)
279 fprintf(stream, "\tmov r5, -(sp)\n");
280 fprintf(stream, "\tmov sp, r5\n");
289 asm_fprintf (stream, "\tsub $%#wo, sp\n", fsize);
291 /* save CPU registers */
292 for (regno = 0; regno < 8; regno++)
293 if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
294 if (! ((regno == FRAME_POINTER_REGNUM)
295 && frame_pointer_needed))
296 fprintf (stream, "\tmov %s, -(sp)\n", reg_names[regno]);
297 /* fpu regs saving */
299 /* via_ac specifies the ac to use for saving ac4, ac5 */
302 for (regno = 8; regno < FIRST_PSEUDO_REGISTER ; regno++)
305 if (LOAD_FPU_REG_P(regno)
306 && df_regs_ever_live_p (regno)
307 && ! call_used_regs[regno])
309 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[regno]);
313 /* maybe make ac4, ac5 call used regs?? */
315 if (NO_LOAD_FPU_REG_P(regno)
316 && df_regs_ever_live_p (regno)
317 && ! call_used_regs[regno])
319 gcc_assert (via_ac != -1);
320 fprintf (stream, "\tldd %s, %s\n",
321 reg_names[regno], reg_names[via_ac]);
322 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[via_ac]);
326 fprintf (stream, "\t;/* end of prologue */\n\n");
329 #endif /* !TWO_BSD */
332 The function epilogue should not depend on the current stack pointer!
333 It should use the frame pointer only. This is mandatory because
334 of alloca; we also take advantage of it to omit stack adjustments
337 /* maybe we can make leaf functions faster by switching to the
338 second register file - this way we don't have to save regs!
339 leaf functions are ~ 50% of all functions (dynamically!)
341 set/clear bit 11 (dec. 2048) of status word for switching register files -
342 but how can we do this? the pdp11/45 manual says bit may only
343 be set (p.24), but not cleared!
345 switching to kernel is probably more expensive, so we'll leave it
346 like this and not use the second set of registers...
348 maybe as option if you want to generate code for kernel mode? */
353 pdp11_output_function_epilogue (FILE *stream,
354 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
356 fprintf (stream, "\t/* SP ignored by cret? */\n");
357 fprintf (stream, "\tjmp cret\n");
363 pdp11_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
365 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
370 fprintf (stream, "\n\t; /*function epilogue */\n");
372 if (frame_pointer_needed)
374 /* hope this is safe - m68k does it also .... */
375 df_regs_ever_live_p (FRAME_POINTER_REGNUM) = 0;
377 for (i =7, j = 0 ; i >= 0 ; i--)
378 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
381 /* remember # of pushed bytes for CPU regs */
384 /* change fp -> r5 due to the compile error on libgcc2.c */
385 for (i =7 ; i >= 0 ; i--)
386 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
387 fprintf(stream, "\tmov %#o(r5), %s\n",(-fsize-2*j--)&0xffff, reg_names[i]);
390 via_ac = FIRST_PSEUDO_REGISTER -1;
392 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
393 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
399 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
401 if (LOAD_FPU_REG_P(i)
402 && df_regs_ever_live_p (i)
403 && ! call_used_regs[i])
405 fprintf(stream, "\tldd %#o(r5), %s\n", (-fsize-k)&0xffff, reg_names[i]);
409 if (NO_LOAD_FPU_REG_P(i)
410 && df_regs_ever_live_p (i)
411 && ! call_used_regs[i])
413 gcc_assert (LOAD_FPU_REG_P(via_ac));
415 fprintf(stream, "\tldd %#o(r5), %s\n", (-fsize-k)&0xffff, reg_names[via_ac]);
416 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
421 fprintf(stream, "\tmov r5, sp\n");
422 fprintf (stream, "\tmov (sp)+, r5\n");
426 via_ac = FIRST_PSEUDO_REGISTER -1;
429 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
430 if (df_regs_ever_live_p (i) && call_used_regs[i])
433 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
435 if (LOAD_FPU_REG_P(i)
436 && df_regs_ever_live_p (i)
437 && ! call_used_regs[i])
438 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[i]);
440 if (NO_LOAD_FPU_REG_P(i)
441 && df_regs_ever_live_p (i)
442 && ! call_used_regs[i])
444 gcc_assert (LOAD_FPU_REG_P(via_ac));
446 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[via_ac]);
447 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
451 for (i=7; i >= 0; i--)
452 if (df_regs_ever_live_p (i) && !call_used_regs[i])
453 fprintf(stream, "\tmov (sp)+, %s\n", reg_names[i]);
456 fprintf((stream), "\tadd $%#o, sp\n", (fsize)&0xffff);
459 fprintf (stream, "\trts pc\n");
460 fprintf (stream, "\t;/* end of epilogue*/\n\n\n");
463 #endif /* !TWO_BSD */
465 /* Return the best assembler insn template
466 for moving operands[1] into operands[0] as a fullword. */
468 singlemove_string (rtx *operands)
470 if (operands[1] != const0_rtx)
477 /* Output assembler code to perform a doubleword move insn
478 with operands OPERANDS. */
481 output_move_double (rtx *operands)
483 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
485 rtx addreg0 = 0, addreg1 = 0;
487 /* First classify both operands. */
489 if (REG_P (operands[0]))
491 else if (offsettable_memref_p (operands[0]))
493 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
495 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
497 else if (GET_CODE (operands[0]) == MEM)
502 if (REG_P (operands[1]))
504 else if (CONSTANT_P (operands[1])
506 || GET_CODE (operands[1]) == CONST_DOUBLE
510 else if (offsettable_memref_p (operands[1]))
512 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
514 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
516 else if (GET_CODE (operands[1]) == MEM)
521 /* Check for the cases that the operand constraints are not
522 supposed to allow to happen. Abort if we get one,
523 because generating code for these cases is painful. */
525 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
527 /* If one operand is decrementing and one is incrementing
528 decrement the former register explicitly
529 and change that operand into ordinary indexing. */
531 if (optype0 == PUSHOP && optype1 == POPOP)
533 operands[0] = XEXP (XEXP (operands[0], 0), 0);
534 output_asm_insn ("sub $4,%0", operands);
535 operands[0] = gen_rtx_MEM (SImode, operands[0]);
538 if (optype0 == POPOP && optype1 == PUSHOP)
540 operands[1] = XEXP (XEXP (operands[1], 0), 0);
541 output_asm_insn ("sub $4,%1", operands);
542 operands[1] = gen_rtx_MEM (SImode, operands[1]);
546 /* If an operand is an unoffsettable memory ref, find a register
547 we can increment temporarily to make it refer to the second word. */
549 if (optype0 == MEMOP)
550 addreg0 = find_addr_reg (XEXP (operands[0], 0));
552 if (optype1 == MEMOP)
553 addreg1 = find_addr_reg (XEXP (operands[1], 0));
555 /* Ok, we can do one word at a time.
556 Normally we do the low-numbered word first,
557 but if either operand is autodecrementing then we
558 do the high-numbered word first.
560 In either case, set up in LATEHALF the operands to use
561 for the high-numbered word and in some cases alter the
562 operands in OPERANDS to be suitable for the low-numbered word. */
564 if (optype0 == REGOP)
565 latehalf[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
566 else if (optype0 == OFFSOP)
567 latehalf[0] = adjust_address (operands[0], HImode, 2);
569 latehalf[0] = operands[0];
571 if (optype1 == REGOP)
572 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
573 else if (optype1 == OFFSOP)
574 latehalf[1] = adjust_address (operands[1], HImode, 2);
575 else if (optype1 == CNSTOP)
577 if (CONSTANT_P (operands[1]))
579 /* now the mess begins, high word is in lower word???
581 that's what ashc makes me think, but I don't remember :-( */
582 latehalf[1] = GEN_INT (INTVAL(operands[1]) >> 16);
583 operands[1] = GEN_INT (INTVAL(operands[1]) & 0xff);
586 /* immediate 32-bit values not allowed */
587 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE);
590 latehalf[1] = operands[1];
592 /* If insn is effectively movd N(sp),-(sp) then we will do the
593 high word first. We should use the adjusted operand 1 (which is N+4(sp))
594 for the low word as well, to compensate for the first decrement of sp. */
595 if (optype0 == PUSHOP
596 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
597 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
598 operands[1] = latehalf[1];
600 /* If one or both operands autodecrementing,
601 do the two words, high-numbered first. */
603 /* Likewise, the first move would clobber the source of the second one,
604 do them in the other order. This happens only for registers;
605 such overlap can't happen in memory unless the user explicitly
606 sets it up, and that is an undefined circumstance. */
608 if (optype0 == PUSHOP || optype1 == PUSHOP
609 || (optype0 == REGOP && optype1 == REGOP
610 && REGNO (operands[0]) == REGNO (latehalf[1])))
612 /* Make any unoffsettable addresses point at high-numbered word. */
614 output_asm_insn ("add $2,%0", &addreg0);
616 output_asm_insn ("add $2,%0", &addreg1);
619 output_asm_insn (singlemove_string (latehalf), latehalf);
621 /* Undo the adds we just did. */
623 output_asm_insn ("sub $2,%0", &addreg0);
625 output_asm_insn ("sub $2,%0", &addreg1);
627 /* Do low-numbered word. */
628 return singlemove_string (operands);
631 /* Normal case: do the two words, low-numbered first. */
633 output_asm_insn (singlemove_string (operands), operands);
635 /* Make any unoffsettable addresses point at high-numbered word. */
637 output_asm_insn ("add $2,%0", &addreg0);
639 output_asm_insn ("add $2,%0", &addreg1);
642 output_asm_insn (singlemove_string (latehalf), latehalf);
644 /* Undo the adds we just did. */
646 output_asm_insn ("sub $2,%0", &addreg0);
648 output_asm_insn ("sub $2,%0", &addreg1);
652 /* Output assembler code to perform a quadword move insn
653 with operands OPERANDS. */
656 output_move_quad (rtx *operands)
658 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
660 rtx addreg0 = 0, addreg1 = 0;
662 output_asm_insn(";/* movdi/df: %1 -> %0 */", operands);
664 if (REG_P (operands[0]))
666 else if (offsettable_memref_p (operands[0]))
668 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
670 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
672 else if (GET_CODE (operands[0]) == MEM)
677 if (REG_P (operands[1]))
679 else if (CONSTANT_P (operands[1])
680 || GET_CODE (operands[1]) == CONST_DOUBLE)
682 else if (offsettable_memref_p (operands[1]))
684 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
686 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
688 else if (GET_CODE (operands[1]) == MEM)
693 /* Check for the cases that the operand constraints are not
694 supposed to allow to happen. Abort if we get one,
695 because generating code for these cases is painful. */
697 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
699 /* check if we move a CPU reg to an FPU reg, or vice versa! */
700 if (optype0 == REGOP && optype1 == REGOP)
701 /* bogus - 64 bit cannot reside in CPU! */
702 gcc_assert (!CPU_REG_P(REGNO(operands[0]))
703 && !CPU_REG_P (REGNO(operands[1])));
705 if (optype0 == REGOP || optype1 == REGOP)
707 /* check for use of clrd????
708 if you ever allow ac4 and ac5 (now we require secondary load)
709 you must check whether
710 you want to load into them or store from them -
711 then dump ac0 into $help$ movce ac4/5 to ac0, do the
712 store from ac0, and restore ac0 - if you can find
713 an unused ac[0-3], use that and you save a store and a load!*/
715 if (FPU_REG_P(REGNO(operands[0])))
717 if (GET_CODE(operands[1]) == CONST_DOUBLE)
720 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
722 if (REAL_VALUES_EQUAL (r, dconst0))
723 return "{clrd|clrf} %0";
726 return "{ldd|movf} %1, %0";
729 if (FPU_REG_P(REGNO(operands[1])))
730 return "{std|movf} %1, %0";
733 /* If one operand is decrementing and one is incrementing
734 decrement the former register explicitly
735 and change that operand into ordinary indexing. */
737 if (optype0 == PUSHOP && optype1 == POPOP)
739 operands[0] = XEXP (XEXP (operands[0], 0), 0);
740 output_asm_insn ("sub $8,%0", operands);
741 operands[0] = gen_rtx_MEM (DImode, operands[0]);
744 if (optype0 == POPOP && optype1 == PUSHOP)
746 operands[1] = XEXP (XEXP (operands[1], 0), 0);
747 output_asm_insn ("sub $8,%1", operands);
748 operands[1] = gen_rtx_MEM (SImode, operands[1]);
752 /* If an operand is an unoffsettable memory ref, find a register
753 we can increment temporarily to make it refer to the second word. */
755 if (optype0 == MEMOP)
756 addreg0 = find_addr_reg (XEXP (operands[0], 0));
758 if (optype1 == MEMOP)
759 addreg1 = find_addr_reg (XEXP (operands[1], 0));
761 /* Ok, we can do one word at a time.
762 Normally we do the low-numbered word first,
763 but if either operand is autodecrementing then we
764 do the high-numbered word first.
766 In either case, set up in LATEHALF the operands to use
767 for the high-numbered word and in some cases alter the
768 operands in OPERANDS to be suitable for the low-numbered word. */
770 if (optype0 == REGOP)
771 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
772 else if (optype0 == OFFSOP)
773 latehalf[0] = adjust_address (operands[0], SImode, 4);
775 latehalf[0] = operands[0];
777 if (optype1 == REGOP)
778 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
779 else if (optype1 == OFFSOP)
780 latehalf[1] = adjust_address (operands[1], SImode, 4);
781 else if (optype1 == CNSTOP)
783 if (GET_CODE (operands[1]) == CONST_DOUBLE)
787 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
788 REAL_VALUE_TO_TARGET_DOUBLE (r, dval);
789 latehalf[1] = GEN_INT (dval[1]);
790 operands[1] = GEN_INT (dval[0]);
792 else if (GET_CODE(operands[1]) == CONST_INT)
794 latehalf[1] = const0_rtx;
800 latehalf[1] = operands[1];
802 /* If insn is effectively movd N(sp),-(sp) then we will do the
803 high word first. We should use the adjusted operand 1 (which is N+4(sp))
804 for the low word as well, to compensate for the first decrement of sp. */
805 if (optype0 == PUSHOP
806 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
807 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
808 operands[1] = latehalf[1];
810 /* If one or both operands autodecrementing,
811 do the two words, high-numbered first. */
813 /* Likewise, the first move would clobber the source of the second one,
814 do them in the other order. This happens only for registers;
815 such overlap can't happen in memory unless the user explicitly
816 sets it up, and that is an undefined circumstance. */
818 if (optype0 == PUSHOP || optype1 == PUSHOP
819 || (optype0 == REGOP && optype1 == REGOP
820 && REGNO (operands[0]) == REGNO (latehalf[1])))
822 /* Make any unoffsettable addresses point at high-numbered word. */
824 output_asm_insn ("add $4,%0", &addreg0);
826 output_asm_insn ("add $4,%0", &addreg1);
829 output_asm_insn(output_move_double(latehalf), latehalf);
831 /* Undo the adds we just did. */
833 output_asm_insn ("sub $4,%0", &addreg0);
835 output_asm_insn ("sub $4,%0", &addreg1);
837 /* Do low-numbered word. */
838 return output_move_double (operands);
841 /* Normal case: do the two words, low-numbered first. */
843 output_asm_insn (output_move_double (operands), operands);
845 /* Make any unoffsettable addresses point at high-numbered word. */
847 output_asm_insn ("add $4,%0", &addreg0);
849 output_asm_insn ("add $4,%0", &addreg1);
852 output_asm_insn (output_move_double (latehalf), latehalf);
854 /* Undo the adds we just did. */
856 output_asm_insn ("sub $4,%0", &addreg0);
858 output_asm_insn ("sub $4,%0", &addreg1);
864 /* Return a REG that occurs in ADDR with coefficient 1.
865 ADDR can be effectively incremented by incrementing REG. */
868 find_addr_reg (rtx addr)
870 while (GET_CODE (addr) == PLUS)
872 if (GET_CODE (XEXP (addr, 0)) == REG)
873 addr = XEXP (addr, 0);
874 if (GET_CODE (XEXP (addr, 1)) == REG)
875 addr = XEXP (addr, 1);
876 if (CONSTANT_P (XEXP (addr, 0)))
877 addr = XEXP (addr, 1);
878 if (CONSTANT_P (XEXP (addr, 1)))
879 addr = XEXP (addr, 0);
881 if (GET_CODE (addr) == REG)
886 /* Output an ascii string. */
888 output_ascii (FILE *file, const char *p, int size)
892 /* This used to output .byte "string", which doesn't work with the UNIX
893 assembler and I think not with DEC ones either. */
894 fprintf (file, "\t.byte ");
896 for (i = 0; i < size; i++)
898 register int c = p[i];
901 fprintf (file, "%#o", c);
909 /* --- stole from out-vax, needs changes */
912 print_operand_address (FILE *file, register rtx addr)
914 register rtx reg1, reg2, breg, ireg;
919 switch (GET_CODE (addr))
926 addr = XEXP (addr, 0);
930 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
935 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
940 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
947 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
948 || GET_CODE (XEXP (addr, 0)) == MEM)
950 offset = XEXP (addr, 0);
951 addr = XEXP (addr, 1);
953 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
954 || GET_CODE (XEXP (addr, 1)) == MEM)
956 offset = XEXP (addr, 1);
957 addr = XEXP (addr, 0);
959 if (GET_CODE (addr) != PLUS)
961 else if (GET_CODE (XEXP (addr, 0)) == MULT)
963 reg1 = XEXP (addr, 0);
964 addr = XEXP (addr, 1);
966 else if (GET_CODE (XEXP (addr, 1)) == MULT)
968 reg1 = XEXP (addr, 1);
969 addr = XEXP (addr, 0);
971 else if (GET_CODE (XEXP (addr, 0)) == REG)
973 reg1 = XEXP (addr, 0);
974 addr = XEXP (addr, 1);
976 else if (GET_CODE (XEXP (addr, 1)) == REG)
978 reg1 = XEXP (addr, 1);
979 addr = XEXP (addr, 0);
981 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
991 gcc_assert (addr == 0);
994 if (reg1 != 0 && GET_CODE (reg1) == MULT)
999 else if (reg2 != 0 && GET_CODE (reg2) == MULT)
1004 else if (reg2 != 0 || GET_CODE (addr) == MEM)
1015 output_address (addr);
1018 gcc_assert (GET_CODE (breg) == REG);
1019 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
1023 if (GET_CODE (ireg) == MULT)
1024 ireg = XEXP (ireg, 0);
1025 gcc_assert (GET_CODE (ireg) == REG);
1026 gcc_unreachable(); /* ??? */
1027 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
1032 output_addr_const_pdp11 (file, addr);
1036 /* Target hook to assemble integer objects. We need to use the
1037 pdp-specific version of output_addr_const. */
1040 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
1046 fprintf (asm_out_file, "\t.byte\t");
1047 output_addr_const_pdp11 (asm_out_file, x);
1048 fprintf (asm_out_file, " /* char */\n");
1052 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
1053 output_addr_const_pdp11 (asm_out_file, x);
1054 fprintf (asm_out_file, " /* short */\n");
1057 return default_assemble_integer (x, size, aligned_p);
1061 /* register move costs, indexed by regs */
1063 static const int move_costs[N_REG_CLASSES][N_REG_CLASSES] =
1065 /* NO MUL GEN LFPU NLFPU FPU ALL */
1067 /* NO */ { 0, 0, 0, 0, 0, 0, 0},
1068 /* MUL */ { 0, 2, 2, 10, 22, 22, 22},
1069 /* GEN */ { 0, 2, 2, 10, 22, 22, 22},
1070 /* LFPU */ { 0, 10, 10, 2, 2, 2, 10},
1071 /* NLFPU */ { 0, 22, 22, 2, 2, 2, 22},
1072 /* FPU */ { 0, 22, 22, 2, 2, 2, 22},
1073 /* ALL */ { 0, 22, 22, 10, 22, 22, 22}
1077 /* -- note that some moves are tremendously expensive,
1078 because they require lots of tricks! do we have to
1079 charge the costs incurred by secondary reload class
1080 -- as we do here with 22 -- or not ? */
1083 register_move_cost(c1, c2)
1084 enum reg_class c1, c2;
1086 return move_costs[(int)c1][(int)c2];
1090 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
1095 if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
1105 /* Twice as expensive as REG. */
1110 /* Twice (or 4 times) as expensive as 16 bit. */
1115 /* ??? There is something wrong in MULT because MULT is not
1116 as cheap as total = 2 even if we can shift! */
1117 /* If optimizing for size make mult etc cheap, but not 1, so when
1118 in doubt the faster insn is chosen. */
1120 *total = COSTS_N_INSNS (2);
1122 *total = COSTS_N_INSNS (11);
1127 *total = COSTS_N_INSNS (2);
1129 *total = COSTS_N_INSNS (25);
1134 *total = COSTS_N_INSNS (2);
1136 *total = COSTS_N_INSNS (26);
1140 /* Equivalent to length, so same for optimize_size. */
1141 *total = COSTS_N_INSNS (3);
1145 /* Only used for qi->hi. */
1146 *total = COSTS_N_INSNS (1);
1150 if (GET_MODE (x) == HImode)
1151 *total = COSTS_N_INSNS (1);
1152 else if (GET_MODE (x) == SImode)
1153 *total = COSTS_N_INSNS (6);
1155 *total = COSTS_N_INSNS (2);
1162 *total = COSTS_N_INSNS (1);
1163 else if (GET_MODE (x) == QImode)
1165 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
1166 *total = COSTS_N_INSNS (8); /* worst case */
1168 *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
1170 else if (GET_MODE (x) == HImode)
1172 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1174 if (abs (INTVAL (XEXP (x, 1))) == 1)
1175 *total = COSTS_N_INSNS (1);
1177 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1180 *total = COSTS_N_INSNS (10); /* worst case */
1182 else if (GET_MODE (x) == SImode)
1184 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1185 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1186 else /* worst case */
1187 *total = COSTS_N_INSNS (18);
1197 output_jump (const char *pos, const char *neg, int length)
1201 static char buf[1000];
1204 /* currently we don't need this, because the tstdf and cmpdf
1205 copy the condition code immediately, and other float operations are not
1206 yet recognized as changing the FCC - if so, then the length-cost of all
1207 jump insns increases by one, because we have to potentially copy the
1209 if (cc_status.flags & CC_IN_FPU)
1210 output_asm_insn("cfcc", NULL);
1218 strcat(buf, " %l0");
1224 sprintf(buf, "%s JMP_%d\n\tjmp %%l0\nJMP_%d:", neg, x, x);
1238 notice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED)
1240 if (GET_CODE (SET_DEST (exp)) == CC0)
1242 cc_status.flags = 0;
1243 cc_status.value1 = SET_DEST (exp);
1244 cc_status.value2 = SET_SRC (exp);
1247 if (GET_MODE(SET_SRC(exp)) == DFmode)
1248 cc_status.flags |= CC_IN_FPU;
1251 else if ((GET_CODE (SET_DEST (exp)) == REG
1252 || GET_CODE (SET_DEST (exp)) == MEM)
1253 && GET_CODE (SET_SRC (exp)) != PC
1254 && (GET_MODE (SET_DEST(exp)) == HImode
1255 || GET_MODE (SET_DEST(exp)) == QImode)
1256 && (GET_CODE (SET_SRC(exp)) == PLUS
1257 || GET_CODE (SET_SRC(exp)) == MINUS
1258 || GET_CODE (SET_SRC(exp)) == AND
1259 || GET_CODE (SET_SRC(exp)) == IOR
1260 || GET_CODE (SET_SRC(exp)) == XOR
1261 || GET_CODE (SET_SRC(exp)) == NOT
1262 || GET_CODE (SET_SRC(exp)) == NEG
1263 || GET_CODE (SET_SRC(exp)) == REG
1264 || GET_CODE (SET_SRC(exp)) == MEM))
1266 cc_status.flags = 0;
1267 cc_status.value1 = SET_SRC (exp);
1268 cc_status.value2 = SET_DEST (exp);
1270 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1272 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1273 cc_status.value2 = 0;
1274 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
1276 && GET_CODE (cc_status.value2) == MEM)
1277 cc_status.value2 = 0;
1279 else if (GET_CODE (SET_SRC (exp)) == CALL)
1283 else if (GET_CODE (SET_DEST (exp)) == REG)
1286 if ((cc_status.value1
1287 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)))
1288 cc_status.value1 = 0;
1289 if ((cc_status.value2
1290 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)))
1291 cc_status.value2 = 0;
1293 else if (SET_DEST(exp) == pc_rtx)
1297 else /* if (GET_CODE (SET_DEST (exp)) == MEM) */
1299 /* the last else is a bit paranoiac, but since nearly all instructions
1300 play with condition codes, it's reasonable! */
1302 CC_STATUS_INIT; /* paranoia*/
1308 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1312 /* Eliminate non-memory operations */
1313 if (GET_CODE (op) != MEM)
1317 /* dword operations really put out 2 instructions, so eliminate them. */
1318 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
1322 /* Decode the address now. */
1326 addr = XEXP (op, 0);
1328 switch (GET_CODE (addr))
1331 /* (R0) - no extra cost */
1336 /* -(R0), (R0)+ - cheap! */
1340 /* cheap - is encoded in addressing mode info!
1342 -- except for @(R0), which has to be @0(R0) !!! */
1344 if (GET_CODE (XEXP (addr, 0)) == REG)
1354 /* @#address - extra cost */
1358 /* X(R0) - extra cost */
1370 * output a block move:
1372 * operands[0] ... to
1373 * operands[1] ... from
1374 * operands[2] ... length
1375 * operands[3] ... alignment
1376 * operands[4] ... scratch register
1381 output_block_move(rtx *operands)
1383 static int count = 0;
1386 if (GET_CODE(operands[2]) == CONST_INT
1389 if (INTVAL(operands[2]) < 16
1390 && INTVAL(operands[3]) == 1)
1394 for (i = 1; i <= INTVAL(operands[2]); i++)
1395 output_asm_insn("movb (%1)+, (%0)+", operands);
1399 else if (INTVAL(operands[2]) < 32)
1403 for (i = 1; i <= INTVAL(operands[2])/2; i++)
1404 output_asm_insn("mov (%1)+, (%0)+", operands);
1406 /* may I assume that moved quantity is
1407 multiple of alignment ???
1416 /* can do other clever things, maybe... */
1419 if (CONSTANT_P(operands[2]) )
1421 /* just move count to scratch */
1422 output_asm_insn("mov %2, %4", operands);
1426 /* just clobber the register */
1427 operands[4] = operands[2];
1431 /* switch over alignment */
1432 switch (INTVAL(operands[3]))
1448 sprintf(buf, "\nmovestrhi%d:", count);
1449 output_asm_insn(buf, NULL);
1451 output_asm_insn("movb (%1)+, (%0)+", operands);
1455 sprintf(buf, "sob %%4, movestrhi%d", count);
1456 output_asm_insn(buf, operands);
1460 output_asm_insn("dec %4", operands);
1462 sprintf(buf, "bgt movestrhi%d", count);
1463 output_asm_insn(buf, NULL);
1485 generate_compact_code:
1487 output_asm_insn("asr %4", operands);
1489 sprintf(buf, "\nmovestrhi%d:", count);
1490 output_asm_insn(buf, NULL);
1492 output_asm_insn("mov (%1)+, (%0)+", operands);
1496 sprintf(buf, "sob %%4, movestrhi%d", count);
1497 output_asm_insn(buf, operands);
1501 output_asm_insn("dec %4", operands);
1503 sprintf(buf, "bgt movestrhi%d", count);
1504 output_asm_insn(buf, NULL);
1530 goto generate_compact_code;
1532 output_asm_insn("asr %4", operands);
1533 output_asm_insn("asr %4", operands);
1535 sprintf(buf, "\nmovestrhi%d:", count);
1536 output_asm_insn(buf, NULL);
1538 output_asm_insn("mov (%1)+, (%0)+", operands);
1539 output_asm_insn("mov (%1)+, (%0)+", operands);
1543 sprintf(buf, "sob %%4, movestrhi%d", count);
1544 output_asm_insn(buf, operands);
1548 output_asm_insn("dec %4", operands);
1550 sprintf(buf, "bgt movestrhi%d", count);
1551 output_asm_insn(buf, NULL);
1581 goto generate_compact_code;
1583 output_asm_insn("asr %4", operands);
1584 output_asm_insn("asr %4", operands);
1585 output_asm_insn("asr %4", operands);
1587 sprintf(buf, "\nmovestrhi%d:", count);
1588 output_asm_insn(buf, NULL);
1590 output_asm_insn("mov (%1)+, (%0)+", operands);
1591 output_asm_insn("mov (%1)+, (%0)+", operands);
1592 output_asm_insn("mov (%1)+, (%0)+", operands);
1593 output_asm_insn("mov (%1)+, (%0)+", operands);
1597 sprintf(buf, "sob %%4, movestrhi%d", count);
1598 output_asm_insn(buf, operands);
1602 output_asm_insn("dec %4", operands);
1604 sprintf(buf, "bgt movestrhi%d", count);
1605 output_asm_insn(buf, NULL);
1619 legitimate_address_p (enum machine_mode mode, rtx address)
1621 /* #define REG_OK_STRICT */
1622 GO_IF_LEGITIMATE_ADDRESS(mode, address, win);
1629 /* #undef REG_OK_STRICT */
1632 /* This function checks whether a real value can be encoded as
1633 a literal, i.e., addressing mode 27. In that mode, real values
1634 are one word values, so the remaining 48 bits have to be zero. */
1636 legitimate_const_double_p (rtx address)
1640 REAL_VALUE_FROM_CONST_DOUBLE (r, address);
1641 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
1642 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1647 /* A copy of output_addr_const modified for pdp11 expression syntax.
1648 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1649 use, and for debugging output, which we don't support with this port either.
1650 So this copy should get called whenever needed.
1653 output_addr_const_pdp11 (FILE *file, rtx x)
1658 switch (GET_CODE (x))
1661 gcc_assert (flag_pic);
1666 assemble_name (file, XSTR (x, 0));
1670 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1671 assemble_name (file, buf);
1675 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1676 assemble_name (file, buf);
1680 /* Should we check for constants which are too big? Maybe cutting
1681 them off to 16 bits is OK? */
1682 fprintf (file, "%#ho", (unsigned short) INTVAL (x));
1686 /* This used to output parentheses around the expression,
1687 but that does not work on the 386 (either ATT or BSD assembler). */
1688 output_addr_const_pdp11 (file, XEXP (x, 0));
1692 if (GET_MODE (x) == VOIDmode)
1694 /* We can use %o if the number is one word and positive. */
1695 gcc_assert (!CONST_DOUBLE_HIGH (x));
1696 fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
1699 /* We can't handle floating point constants;
1700 PRINT_OPERAND must handle them. */
1701 output_operand_lossage ("floating constant misused");
1705 /* Some assemblers need integer constants to appear last (e.g. masm). */
1706 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1708 output_addr_const_pdp11 (file, XEXP (x, 1));
1709 if (INTVAL (XEXP (x, 0)) >= 0)
1710 fprintf (file, "+");
1711 output_addr_const_pdp11 (file, XEXP (x, 0));
1715 output_addr_const_pdp11 (file, XEXP (x, 0));
1716 if (INTVAL (XEXP (x, 1)) >= 0)
1717 fprintf (file, "+");
1718 output_addr_const_pdp11 (file, XEXP (x, 1));
1723 /* Avoid outputting things like x-x or x+5-x,
1724 since some assemblers can't handle that. */
1725 x = simplify_subtraction (x);
1726 if (GET_CODE (x) != MINUS)
1729 output_addr_const_pdp11 (file, XEXP (x, 0));
1730 fprintf (file, "-");
1731 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1732 && INTVAL (XEXP (x, 1)) < 0)
1734 fprintf (file, targetm.asm_out.open_paren);
1735 output_addr_const_pdp11 (file, XEXP (x, 1));
1736 fprintf (file, targetm.asm_out.close_paren);
1739 output_addr_const_pdp11 (file, XEXP (x, 1));
1744 output_addr_const_pdp11 (file, XEXP (x, 0));
1748 output_operand_lossage ("invalid expression as operand");
1752 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1755 pdp11_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
1757 /* Should probably return DImode and DFmode in memory, lest
1758 we fill up all regs!
1760 have to, else we crash - exception: maybe return result in
1761 ac0 if DFmode and FPU present - compatibility problem with
1762 libraries for non-floating point.... */
1763 return (TYPE_MODE (type) == DImode
1764 || (TYPE_MODE (type) == DFmode && ! TARGET_AC0));