1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2004, 2005,
3 2006, 2007, 2008, 2009 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"
46 #define FPU_REG_P(X) ((X)>=8 && (X)<14)
47 #define CPU_REG_P(X) ((X)>=0 && (X)<8)
50 /* this is the current value returned by the macro FIRST_PARM_OFFSET
52 int current_first_parm_offset;
54 /* Routines to encode/decode pdp11 floats */
55 static void encode_pdp11_f (const struct real_format *fmt,
56 long *, const REAL_VALUE_TYPE *);
57 static void decode_pdp11_f (const struct real_format *,
58 REAL_VALUE_TYPE *, const long *);
59 static void encode_pdp11_d (const struct real_format *fmt,
60 long *, const REAL_VALUE_TYPE *);
61 static void decode_pdp11_d (const struct real_format *,
62 REAL_VALUE_TYPE *, const long *);
64 /* These two are taken from the corresponding vax descriptors
65 in real.c, changing only the encode/decode routine pointers. */
66 const struct real_format pdp11_f_format =
87 const struct real_format pdp11_d_format =
109 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
110 const REAL_VALUE_TYPE *r)
112 (*vax_f_format.encode) (fmt, buf, r);
113 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
117 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
118 REAL_VALUE_TYPE *r, const long *buf)
121 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
122 (*vax_f_format.decode) (fmt, r, &tbuf);
126 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
127 const REAL_VALUE_TYPE *r)
129 (*vax_d_format.encode) (fmt, buf, r);
130 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
131 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
135 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
136 REAL_VALUE_TYPE *r, const long *buf)
139 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
140 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
141 (*vax_d_format.decode) (fmt, r, tbuf);
144 /* This is where the condition code register lives. */
145 /* rtx cc0_reg_rtx; - no longer needed? */
147 static bool pdp11_handle_option (size_t, const char *, int);
148 static rtx find_addr_reg (rtx);
149 static const char *singlemove_string (rtx *);
150 static bool pdp11_assemble_integer (rtx, unsigned int, int);
151 static void pdp11_output_function_prologue (FILE *, HOST_WIDE_INT);
152 static void pdp11_output_function_epilogue (FILE *, HOST_WIDE_INT);
153 static bool pdp11_rtx_costs (rtx, int, int, int *, bool);
154 static bool pdp11_return_in_memory (const_tree, const_tree);
155 static void pdp11_trampoline_init (rtx, tree, rtx);
157 /* Initialize the GCC target structure. */
158 #undef TARGET_ASM_BYTE_OP
159 #define TARGET_ASM_BYTE_OP NULL
160 #undef TARGET_ASM_ALIGNED_HI_OP
161 #define TARGET_ASM_ALIGNED_HI_OP NULL
162 #undef TARGET_ASM_ALIGNED_SI_OP
163 #define TARGET_ASM_ALIGNED_SI_OP NULL
164 #undef TARGET_ASM_INTEGER
165 #define TARGET_ASM_INTEGER pdp11_assemble_integer
167 #undef TARGET_ASM_FUNCTION_PROLOGUE
168 #define TARGET_ASM_FUNCTION_PROLOGUE pdp11_output_function_prologue
169 #undef TARGET_ASM_FUNCTION_EPILOGUE
170 #define TARGET_ASM_FUNCTION_EPILOGUE pdp11_output_function_epilogue
172 #undef TARGET_ASM_OPEN_PAREN
173 #define TARGET_ASM_OPEN_PAREN "["
174 #undef TARGET_ASM_CLOSE_PAREN
175 #define TARGET_ASM_CLOSE_PAREN "]"
177 #undef TARGET_DEFAULT_TARGET_FLAGS
178 #define TARGET_DEFAULT_TARGET_FLAGS \
179 (MASK_FPU | MASK_45 | MASK_ABSHI_BUILTIN | TARGET_UNIX_ASM_DEFAULT)
180 #undef TARGET_HANDLE_OPTION
181 #define TARGET_HANDLE_OPTION pdp11_handle_option
183 #undef TARGET_RTX_COSTS
184 #define TARGET_RTX_COSTS pdp11_rtx_costs
186 #undef TARGET_RETURN_IN_MEMORY
187 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
189 #undef TARGET_TRAMPOLINE_INIT
190 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
192 struct gcc_target targetm = TARGET_INITIALIZER;
194 /* Implement TARGET_HANDLE_OPTION. */
197 pdp11_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED,
198 int value ATTRIBUTE_UNUSED)
203 target_flags &= ~(MASK_40 | MASK_45);
211 /* Nonzero if OP is a valid second operand for an arithmetic insn. */
214 arith_operand (rtx op, enum machine_mode mode)
216 return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);
220 const_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
222 return (GET_CODE (op) == CONST_INT);
226 immediate15_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
228 return (GET_CODE (op) == CONST_INT && ((INTVAL (op) & 0x8000) == 0x0000));
232 expand_shift_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
234 return (GET_CODE (op) == CONST_INT
235 && abs (INTVAL(op)) > 1
236 && abs (INTVAL(op)) <= 4);
240 stream is a stdio stream to output the code to.
241 size is an int: how many units of temporary storage to allocate.
242 Refer to the array `regs_ever_live' to determine which registers
243 to save; `regs_ever_live[I]' is nonzero if register number I
244 is ever used in the function. This macro is responsible for
245 knowing which registers should not be saved even if used.
249 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
251 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
256 "\n\t; /* function prologue %s*/\n",
257 current_function_name ());
259 /* if we are outputting code for main,
260 the switch FPU to right mode if TARGET_FPU */
261 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
264 "\t;/* switch cpu to double float, single integer */\n");
265 fprintf(stream, "\tsetd\n");
266 fprintf(stream, "\tseti\n\n");
269 if (frame_pointer_needed)
271 fprintf(stream, "\tmov r5, -(sp)\n");
272 fprintf(stream, "\tmov sp, r5\n");
281 asm_fprintf (stream, "\tsub $%#wo, sp\n", fsize);
283 /* save CPU registers */
284 for (regno = 0; regno < 8; regno++)
285 if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
286 if (! ((regno == FRAME_POINTER_REGNUM)
287 && frame_pointer_needed))
288 fprintf (stream, "\tmov %s, -(sp)\n", reg_names[regno]);
289 /* fpu regs saving */
291 /* via_ac specifies the ac to use for saving ac4, ac5 */
294 for (regno = 8; regno < FIRST_PSEUDO_REGISTER ; regno++)
297 if (LOAD_FPU_REG_P(regno)
298 && df_regs_ever_live_p (regno)
299 && ! call_used_regs[regno])
301 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[regno]);
305 /* maybe make ac4, ac5 call used regs?? */
307 if (NO_LOAD_FPU_REG_P(regno)
308 && df_regs_ever_live_p (regno)
309 && ! call_used_regs[regno])
311 gcc_assert (via_ac != -1);
312 fprintf (stream, "\tldd %s, %s\n",
313 reg_names[regno], reg_names[via_ac]);
314 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[via_ac]);
318 fprintf (stream, "\t;/* end of prologue */\n\n");
322 The function epilogue should not depend on the current stack pointer!
323 It should use the frame pointer only. This is mandatory because
324 of alloca; we also take advantage of it to omit stack adjustments
327 /* maybe we can make leaf functions faster by switching to the
328 second register file - this way we don't have to save regs!
329 leaf functions are ~ 50% of all functions (dynamically!)
331 set/clear bit 11 (dec. 2048) of status word for switching register files -
332 but how can we do this? the pdp11/45 manual says bit may only
333 be set (p.24), but not cleared!
335 switching to kernel is probably more expensive, so we'll leave it
336 like this and not use the second set of registers...
338 maybe as option if you want to generate code for kernel mode? */
341 pdp11_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
343 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
348 fprintf (stream, "\n\t; /*function epilogue */\n");
350 if (frame_pointer_needed)
352 /* hope this is safe - m68k does it also .... */
353 df_set_regs_ever_live (FRAME_POINTER_REGNUM, false);
355 for (i =7, j = 0 ; i >= 0 ; i--)
356 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
359 /* remember # of pushed bytes for CPU regs */
362 /* change fp -> r5 due to the compile error on libgcc2.c */
363 for (i =7 ; i >= 0 ; i--)
364 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
365 fprintf(stream, "\tmov %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
366 (-fsize-2*j--)&0xffff, reg_names[i]);
369 via_ac = FIRST_PSEUDO_REGISTER -1;
371 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
372 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
378 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
380 if (LOAD_FPU_REG_P(i)
381 && df_regs_ever_live_p (i)
382 && ! call_used_regs[i])
384 fprintf(stream, "\tldd %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
385 (-fsize-k)&0xffff, reg_names[i]);
389 if (NO_LOAD_FPU_REG_P(i)
390 && df_regs_ever_live_p (i)
391 && ! call_used_regs[i])
393 gcc_assert (LOAD_FPU_REG_P(via_ac));
395 fprintf(stream, "\tldd %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
396 (-fsize-k)&0xffff, reg_names[via_ac]);
397 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
402 fprintf(stream, "\tmov r5, sp\n");
403 fprintf (stream, "\tmov (sp)+, r5\n");
407 via_ac = FIRST_PSEUDO_REGISTER -1;
410 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
411 if (df_regs_ever_live_p (i) && call_used_regs[i])
414 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
416 if (LOAD_FPU_REG_P(i)
417 && df_regs_ever_live_p (i)
418 && ! call_used_regs[i])
419 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[i]);
421 if (NO_LOAD_FPU_REG_P(i)
422 && df_regs_ever_live_p (i)
423 && ! call_used_regs[i])
425 gcc_assert (LOAD_FPU_REG_P(via_ac));
427 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[via_ac]);
428 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
432 for (i=7; i >= 0; i--)
433 if (df_regs_ever_live_p (i) && !call_used_regs[i])
434 fprintf(stream, "\tmov (sp)+, %s\n", reg_names[i]);
437 fprintf((stream), "\tadd $%#" HOST_WIDE_INT_PRINT "o, sp\n",
441 fprintf (stream, "\trts pc\n");
442 fprintf (stream, "\t;/* end of epilogue*/\n\n\n");
445 /* Return the best assembler insn template
446 for moving operands[1] into operands[0] as a fullword. */
448 singlemove_string (rtx *operands)
450 if (operands[1] != const0_rtx)
457 /* Output assembler code to perform a doubleword move insn
458 with operands OPERANDS. */
461 output_move_double (rtx *operands)
463 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
465 rtx addreg0 = 0, addreg1 = 0;
467 /* First classify both operands. */
469 if (REG_P (operands[0]))
471 else if (offsettable_memref_p (operands[0]))
473 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
475 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
477 else if (GET_CODE (operands[0]) == MEM)
482 if (REG_P (operands[1]))
484 else if (CONSTANT_P (operands[1])
486 || GET_CODE (operands[1]) == CONST_DOUBLE
490 else if (offsettable_memref_p (operands[1]))
492 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
494 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
496 else if (GET_CODE (operands[1]) == MEM)
501 /* Check for the cases that the operand constraints are not
502 supposed to allow to happen. Abort if we get one,
503 because generating code for these cases is painful. */
505 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
507 /* If one operand is decrementing and one is incrementing
508 decrement the former register explicitly
509 and change that operand into ordinary indexing. */
511 if (optype0 == PUSHOP && optype1 == POPOP)
513 operands[0] = XEXP (XEXP (operands[0], 0), 0);
514 output_asm_insn ("sub $4,%0", operands);
515 operands[0] = gen_rtx_MEM (SImode, operands[0]);
518 if (optype0 == POPOP && optype1 == PUSHOP)
520 operands[1] = XEXP (XEXP (operands[1], 0), 0);
521 output_asm_insn ("sub $4,%1", operands);
522 operands[1] = gen_rtx_MEM (SImode, operands[1]);
526 /* If an operand is an unoffsettable memory ref, find a register
527 we can increment temporarily to make it refer to the second word. */
529 if (optype0 == MEMOP)
530 addreg0 = find_addr_reg (XEXP (operands[0], 0));
532 if (optype1 == MEMOP)
533 addreg1 = find_addr_reg (XEXP (operands[1], 0));
535 /* Ok, we can do one word at a time.
536 Normally we do the low-numbered word first,
537 but if either operand is autodecrementing then we
538 do the high-numbered word first.
540 In either case, set up in LATEHALF the operands to use
541 for the high-numbered word and in some cases alter the
542 operands in OPERANDS to be suitable for the low-numbered word. */
544 if (optype0 == REGOP)
545 latehalf[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
546 else if (optype0 == OFFSOP)
547 latehalf[0] = adjust_address (operands[0], HImode, 2);
549 latehalf[0] = operands[0];
551 if (optype1 == REGOP)
552 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
553 else if (optype1 == OFFSOP)
554 latehalf[1] = adjust_address (operands[1], HImode, 2);
555 else if (optype1 == CNSTOP)
557 if (CONSTANT_P (operands[1]))
559 /* now the mess begins, high word is in lower word???
561 that's what ashc makes me think, but I don't remember :-( */
562 latehalf[1] = GEN_INT (INTVAL(operands[1]) >> 16);
563 operands[1] = GEN_INT (INTVAL(operands[1]) & 0xff);
566 /* immediate 32-bit values not allowed */
567 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE);
570 latehalf[1] = operands[1];
572 /* If insn is effectively movd N(sp),-(sp) then we will do the
573 high word first. We should use the adjusted operand 1 (which is N+4(sp))
574 for the low word as well, to compensate for the first decrement of sp. */
575 if (optype0 == PUSHOP
576 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
577 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
578 operands[1] = latehalf[1];
580 /* If one or both operands autodecrementing,
581 do the two words, high-numbered first. */
583 /* Likewise, the first move would clobber the source of the second one,
584 do them in the other order. This happens only for registers;
585 such overlap can't happen in memory unless the user explicitly
586 sets it up, and that is an undefined circumstance. */
588 if (optype0 == PUSHOP || optype1 == PUSHOP
589 || (optype0 == REGOP && optype1 == REGOP
590 && REGNO (operands[0]) == REGNO (latehalf[1])))
592 /* Make any unoffsettable addresses point at high-numbered word. */
594 output_asm_insn ("add $2,%0", &addreg0);
596 output_asm_insn ("add $2,%0", &addreg1);
599 output_asm_insn (singlemove_string (latehalf), latehalf);
601 /* Undo the adds we just did. */
603 output_asm_insn ("sub $2,%0", &addreg0);
605 output_asm_insn ("sub $2,%0", &addreg1);
607 /* Do low-numbered word. */
608 return singlemove_string (operands);
611 /* Normal case: do the two words, low-numbered first. */
613 output_asm_insn (singlemove_string (operands), operands);
615 /* Make any unoffsettable addresses point at high-numbered word. */
617 output_asm_insn ("add $2,%0", &addreg0);
619 output_asm_insn ("add $2,%0", &addreg1);
622 output_asm_insn (singlemove_string (latehalf), latehalf);
624 /* Undo the adds we just did. */
626 output_asm_insn ("sub $2,%0", &addreg0);
628 output_asm_insn ("sub $2,%0", &addreg1);
632 /* Output assembler code to perform a quadword move insn
633 with operands OPERANDS. */
636 output_move_quad (rtx *operands)
638 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
640 rtx addreg0 = 0, addreg1 = 0;
642 output_asm_insn(";/* movdi/df: %1 -> %0 */", operands);
644 if (REG_P (operands[0]))
646 else if (offsettable_memref_p (operands[0]))
648 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
650 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
652 else if (GET_CODE (operands[0]) == MEM)
657 if (REG_P (operands[1]))
659 else if (CONSTANT_P (operands[1])
660 || GET_CODE (operands[1]) == CONST_DOUBLE)
662 else if (offsettable_memref_p (operands[1]))
664 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
666 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
668 else if (GET_CODE (operands[1]) == MEM)
673 /* Check for the cases that the operand constraints are not
674 supposed to allow to happen. Abort if we get one,
675 because generating code for these cases is painful. */
677 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
679 /* check if we move a CPU reg to an FPU reg, or vice versa! */
680 if (optype0 == REGOP && optype1 == REGOP)
681 /* bogus - 64 bit cannot reside in CPU! */
682 gcc_assert (!CPU_REG_P(REGNO(operands[0]))
683 && !CPU_REG_P (REGNO(operands[1])));
685 if (optype0 == REGOP || optype1 == REGOP)
687 /* check for use of clrd????
688 if you ever allow ac4 and ac5 (now we require secondary load)
689 you must check whether
690 you want to load into them or store from them -
691 then dump ac0 into $help$ movce ac4/5 to ac0, do the
692 store from ac0, and restore ac0 - if you can find
693 an unused ac[0-3], use that and you save a store and a load!*/
695 if (FPU_REG_P(REGNO(operands[0])))
697 if (GET_CODE(operands[1]) == CONST_DOUBLE)
700 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
702 if (REAL_VALUES_EQUAL (r, dconst0))
703 return "{clrd|clrf} %0";
706 return "{ldd|movf} %1, %0";
709 if (FPU_REG_P(REGNO(operands[1])))
710 return "{std|movf} %1, %0";
713 /* If one operand is decrementing and one is incrementing
714 decrement the former register explicitly
715 and change that operand into ordinary indexing. */
717 if (optype0 == PUSHOP && optype1 == POPOP)
719 operands[0] = XEXP (XEXP (operands[0], 0), 0);
720 output_asm_insn ("sub $8,%0", operands);
721 operands[0] = gen_rtx_MEM (DImode, operands[0]);
724 if (optype0 == POPOP && optype1 == PUSHOP)
726 operands[1] = XEXP (XEXP (operands[1], 0), 0);
727 output_asm_insn ("sub $8,%1", operands);
728 operands[1] = gen_rtx_MEM (SImode, operands[1]);
732 /* If an operand is an unoffsettable memory ref, find a register
733 we can increment temporarily to make it refer to the second word. */
735 if (optype0 == MEMOP)
736 addreg0 = find_addr_reg (XEXP (operands[0], 0));
738 if (optype1 == MEMOP)
739 addreg1 = find_addr_reg (XEXP (operands[1], 0));
741 /* Ok, we can do one word at a time.
742 Normally we do the low-numbered word first,
743 but if either operand is autodecrementing then we
744 do the high-numbered word first.
746 In either case, set up in LATEHALF the operands to use
747 for the high-numbered word and in some cases alter the
748 operands in OPERANDS to be suitable for the low-numbered word. */
750 if (optype0 == REGOP)
751 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
752 else if (optype0 == OFFSOP)
753 latehalf[0] = adjust_address (operands[0], SImode, 4);
755 latehalf[0] = operands[0];
757 if (optype1 == REGOP)
758 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
759 else if (optype1 == OFFSOP)
760 latehalf[1] = adjust_address (operands[1], SImode, 4);
761 else if (optype1 == CNSTOP)
763 if (GET_CODE (operands[1]) == CONST_DOUBLE)
767 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
768 REAL_VALUE_TO_TARGET_DOUBLE (r, dval);
769 latehalf[1] = GEN_INT (dval[1]);
770 operands[1] = GEN_INT (dval[0]);
772 else if (GET_CODE(operands[1]) == CONST_INT)
774 latehalf[1] = const0_rtx;
780 latehalf[1] = operands[1];
782 /* If insn is effectively movd N(sp),-(sp) then we will do the
783 high word first. We should use the adjusted operand 1 (which is N+4(sp))
784 for the low word as well, to compensate for the first decrement of sp. */
785 if (optype0 == PUSHOP
786 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
787 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
788 operands[1] = latehalf[1];
790 /* If one or both operands autodecrementing,
791 do the two words, high-numbered first. */
793 /* Likewise, the first move would clobber the source of the second one,
794 do them in the other order. This happens only for registers;
795 such overlap can't happen in memory unless the user explicitly
796 sets it up, and that is an undefined circumstance. */
798 if (optype0 == PUSHOP || optype1 == PUSHOP
799 || (optype0 == REGOP && optype1 == REGOP
800 && REGNO (operands[0]) == REGNO (latehalf[1])))
802 /* Make any unoffsettable addresses point at high-numbered word. */
804 output_asm_insn ("add $4,%0", &addreg0);
806 output_asm_insn ("add $4,%0", &addreg1);
809 output_asm_insn(output_move_double(latehalf), latehalf);
811 /* Undo the adds we just did. */
813 output_asm_insn ("sub $4,%0", &addreg0);
815 output_asm_insn ("sub $4,%0", &addreg1);
817 /* Do low-numbered word. */
818 return output_move_double (operands);
821 /* Normal case: do the two words, low-numbered first. */
823 output_asm_insn (output_move_double (operands), operands);
825 /* Make any unoffsettable addresses point at high-numbered word. */
827 output_asm_insn ("add $4,%0", &addreg0);
829 output_asm_insn ("add $4,%0", &addreg1);
832 output_asm_insn (output_move_double (latehalf), latehalf);
834 /* Undo the adds we just did. */
836 output_asm_insn ("sub $4,%0", &addreg0);
838 output_asm_insn ("sub $4,%0", &addreg1);
844 /* Return a REG that occurs in ADDR with coefficient 1.
845 ADDR can be effectively incremented by incrementing REG. */
848 find_addr_reg (rtx addr)
850 while (GET_CODE (addr) == PLUS)
852 if (GET_CODE (XEXP (addr, 0)) == REG)
853 addr = XEXP (addr, 0);
854 if (GET_CODE (XEXP (addr, 1)) == REG)
855 addr = XEXP (addr, 1);
856 if (CONSTANT_P (XEXP (addr, 0)))
857 addr = XEXP (addr, 1);
858 if (CONSTANT_P (XEXP (addr, 1)))
859 addr = XEXP (addr, 0);
861 if (GET_CODE (addr) == REG)
866 /* Output an ascii string. */
868 output_ascii (FILE *file, const char *p, int size)
872 /* This used to output .byte "string", which doesn't work with the UNIX
873 assembler and I think not with DEC ones either. */
874 fprintf (file, "\t.byte ");
876 for (i = 0; i < size; i++)
878 register int c = p[i];
881 fprintf (file, "%#o", c);
889 /* --- stole from out-vax, needs changes */
892 print_operand_address (FILE *file, register rtx addr)
894 register rtx reg1, reg2, breg, ireg;
899 switch (GET_CODE (addr))
906 addr = XEXP (addr, 0);
910 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
915 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
920 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
927 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
928 || GET_CODE (XEXP (addr, 0)) == MEM)
930 offset = XEXP (addr, 0);
931 addr = XEXP (addr, 1);
933 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
934 || GET_CODE (XEXP (addr, 1)) == MEM)
936 offset = XEXP (addr, 1);
937 addr = XEXP (addr, 0);
939 if (GET_CODE (addr) != PLUS)
941 else if (GET_CODE (XEXP (addr, 0)) == MULT)
943 reg1 = XEXP (addr, 0);
944 addr = XEXP (addr, 1);
946 else if (GET_CODE (XEXP (addr, 1)) == MULT)
948 reg1 = XEXP (addr, 1);
949 addr = XEXP (addr, 0);
951 else if (GET_CODE (XEXP (addr, 0)) == REG)
953 reg1 = XEXP (addr, 0);
954 addr = XEXP (addr, 1);
956 else if (GET_CODE (XEXP (addr, 1)) == REG)
958 reg1 = XEXP (addr, 1);
959 addr = XEXP (addr, 0);
961 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
971 gcc_assert (addr == 0);
974 if (reg1 != 0 && GET_CODE (reg1) == MULT)
979 else if (reg2 != 0 && GET_CODE (reg2) == MULT)
984 else if (reg2 != 0 || GET_CODE (addr) == MEM)
995 output_address (addr);
998 gcc_assert (GET_CODE (breg) == REG);
999 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
1003 if (GET_CODE (ireg) == MULT)
1004 ireg = XEXP (ireg, 0);
1005 gcc_assert (GET_CODE (ireg) == REG);
1006 gcc_unreachable(); /* ??? */
1007 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
1012 output_addr_const_pdp11 (file, addr);
1016 /* Target hook to assemble integer objects. We need to use the
1017 pdp-specific version of output_addr_const. */
1020 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
1026 fprintf (asm_out_file, "\t.byte\t");
1027 output_addr_const_pdp11 (asm_out_file, x);
1028 fprintf (asm_out_file, " /* char */\n");
1032 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
1033 output_addr_const_pdp11 (asm_out_file, x);
1034 fprintf (asm_out_file, " /* short */\n");
1037 return default_assemble_integer (x, size, aligned_p);
1041 /* register move costs, indexed by regs */
1043 static const int move_costs[N_REG_CLASSES][N_REG_CLASSES] =
1045 /* NO MUL GEN LFPU NLFPU FPU ALL */
1047 /* NO */ { 0, 0, 0, 0, 0, 0, 0},
1048 /* MUL */ { 0, 2, 2, 10, 22, 22, 22},
1049 /* GEN */ { 0, 2, 2, 10, 22, 22, 22},
1050 /* LFPU */ { 0, 10, 10, 2, 2, 2, 10},
1051 /* NLFPU */ { 0, 22, 22, 2, 2, 2, 22},
1052 /* FPU */ { 0, 22, 22, 2, 2, 2, 22},
1053 /* ALL */ { 0, 22, 22, 10, 22, 22, 22}
1057 /* -- note that some moves are tremendously expensive,
1058 because they require lots of tricks! do we have to
1059 charge the costs incurred by secondary reload class
1060 -- as we do here with 22 -- or not ? */
1063 register_move_cost(enum reg_class c1, enum reg_class c2)
1065 return move_costs[(int)c1][(int)c2];
1069 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
1070 bool speed ATTRIBUTE_UNUSED)
1075 if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
1085 /* Twice as expensive as REG. */
1090 /* Twice (or 4 times) as expensive as 16 bit. */
1095 /* ??? There is something wrong in MULT because MULT is not
1096 as cheap as total = 2 even if we can shift! */
1097 /* If optimizing for size make mult etc cheap, but not 1, so when
1098 in doubt the faster insn is chosen. */
1100 *total = COSTS_N_INSNS (2);
1102 *total = COSTS_N_INSNS (11);
1107 *total = COSTS_N_INSNS (2);
1109 *total = COSTS_N_INSNS (25);
1114 *total = COSTS_N_INSNS (2);
1116 *total = COSTS_N_INSNS (26);
1120 /* Equivalent to length, so same for optimize_size. */
1121 *total = COSTS_N_INSNS (3);
1125 /* Only used for qi->hi. */
1126 *total = COSTS_N_INSNS (1);
1130 if (GET_MODE (x) == HImode)
1131 *total = COSTS_N_INSNS (1);
1132 else if (GET_MODE (x) == SImode)
1133 *total = COSTS_N_INSNS (6);
1135 *total = COSTS_N_INSNS (2);
1142 *total = COSTS_N_INSNS (1);
1143 else if (GET_MODE (x) == QImode)
1145 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
1146 *total = COSTS_N_INSNS (8); /* worst case */
1148 *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
1150 else if (GET_MODE (x) == HImode)
1152 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1154 if (abs (INTVAL (XEXP (x, 1))) == 1)
1155 *total = COSTS_N_INSNS (1);
1157 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1160 *total = COSTS_N_INSNS (10); /* worst case */
1162 else if (GET_MODE (x) == SImode)
1164 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1165 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1166 else /* worst case */
1167 *total = COSTS_N_INSNS (18);
1177 output_jump (enum rtx_code code, int inv, int length)
1181 static char buf[1000];
1182 const char *pos, *neg;
1186 case EQ: pos = "beq", neg = "bne"; break;
1187 case NE: pos = "bne", neg = "beq"; break;
1188 case GT: pos = "bgt", neg = "ble"; break;
1189 case GTU: pos = "bhi", neg = "blos"; break;
1190 case LT: pos = "blt", neg = "bge"; break;
1191 case LTU: pos = "blo", neg = "bhis"; break;
1192 case GE: pos = "bge", neg = "blt"; break;
1193 case GEU: pos = "bhis", neg = "blo"; break;
1194 case LE: pos = "ble", neg = "bgt"; break;
1195 case LEU: pos = "blos", neg = "bhi"; break;
1196 default: gcc_unreachable ();
1200 /* currently we don't need this, because the tstdf and cmpdf
1201 copy the condition code immediately, and other float operations are not
1202 yet recognized as changing the FCC - if so, then the length-cost of all
1203 jump insns increases by one, because we have to potentially copy the
1205 if (cc_status.flags & CC_IN_FPU)
1206 output_asm_insn("cfcc", NULL);
1213 sprintf(buf, "%s %%l1", inv ? neg : pos);
1219 sprintf(buf, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv ? pos : neg, x, x);
1233 notice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED)
1235 if (GET_CODE (SET_DEST (exp)) == CC0)
1237 cc_status.flags = 0;
1238 cc_status.value1 = SET_DEST (exp);
1239 cc_status.value2 = SET_SRC (exp);
1242 if (GET_MODE(SET_SRC(exp)) == DFmode)
1243 cc_status.flags |= CC_IN_FPU;
1246 else if ((GET_CODE (SET_DEST (exp)) == REG
1247 || GET_CODE (SET_DEST (exp)) == MEM)
1248 && GET_CODE (SET_SRC (exp)) != PC
1249 && (GET_MODE (SET_DEST(exp)) == HImode
1250 || GET_MODE (SET_DEST(exp)) == QImode)
1251 && (GET_CODE (SET_SRC(exp)) == PLUS
1252 || GET_CODE (SET_SRC(exp)) == MINUS
1253 || GET_CODE (SET_SRC(exp)) == AND
1254 || GET_CODE (SET_SRC(exp)) == IOR
1255 || GET_CODE (SET_SRC(exp)) == XOR
1256 || GET_CODE (SET_SRC(exp)) == NOT
1257 || GET_CODE (SET_SRC(exp)) == NEG
1258 || GET_CODE (SET_SRC(exp)) == REG
1259 || GET_CODE (SET_SRC(exp)) == MEM))
1261 cc_status.flags = 0;
1262 cc_status.value1 = SET_SRC (exp);
1263 cc_status.value2 = SET_DEST (exp);
1265 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1267 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1268 cc_status.value2 = 0;
1269 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
1271 && GET_CODE (cc_status.value2) == MEM)
1272 cc_status.value2 = 0;
1274 else if (GET_CODE (SET_SRC (exp)) == CALL)
1278 else if (GET_CODE (SET_DEST (exp)) == REG)
1281 if ((cc_status.value1
1282 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)))
1283 cc_status.value1 = 0;
1284 if ((cc_status.value2
1285 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)))
1286 cc_status.value2 = 0;
1288 else if (SET_DEST(exp) == pc_rtx)
1292 else /* if (GET_CODE (SET_DEST (exp)) == MEM) */
1294 /* the last else is a bit paranoiac, but since nearly all instructions
1295 play with condition codes, it's reasonable! */
1297 CC_STATUS_INIT; /* paranoia*/
1303 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1307 /* Eliminate non-memory operations */
1308 if (GET_CODE (op) != MEM)
1312 /* dword operations really put out 2 instructions, so eliminate them. */
1313 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
1317 /* Decode the address now. */
1321 addr = XEXP (op, 0);
1323 switch (GET_CODE (addr))
1326 /* (R0) - no extra cost */
1331 /* -(R0), (R0)+ - cheap! */
1335 /* cheap - is encoded in addressing mode info!
1337 -- except for @(R0), which has to be @0(R0) !!! */
1339 if (GET_CODE (XEXP (addr, 0)) == REG)
1349 /* @#address - extra cost */
1353 /* X(R0) - extra cost */
1365 * output a block move:
1367 * operands[0] ... to
1368 * operands[1] ... from
1369 * operands[2] ... length
1370 * operands[3] ... alignment
1371 * operands[4] ... scratch register
1376 output_block_move(rtx *operands)
1378 static int count = 0;
1381 if (GET_CODE(operands[2]) == CONST_INT
1384 if (INTVAL(operands[2]) < 16
1385 && INTVAL(operands[3]) == 1)
1389 for (i = 1; i <= INTVAL(operands[2]); i++)
1390 output_asm_insn("movb (%1)+, (%0)+", operands);
1394 else if (INTVAL(operands[2]) < 32)
1398 for (i = 1; i <= INTVAL(operands[2])/2; i++)
1399 output_asm_insn("mov (%1)+, (%0)+", operands);
1401 /* may I assume that moved quantity is
1402 multiple of alignment ???
1411 /* can do other clever things, maybe... */
1414 if (CONSTANT_P(operands[2]) )
1416 /* just move count to scratch */
1417 output_asm_insn("mov %2, %4", operands);
1421 /* just clobber the register */
1422 operands[4] = operands[2];
1426 /* switch over alignment */
1427 switch (INTVAL(operands[3]))
1443 sprintf(buf, "\nmovestrhi%d:", count);
1444 output_asm_insn(buf, NULL);
1446 output_asm_insn("movb (%1)+, (%0)+", operands);
1450 sprintf(buf, "sob %%4, movestrhi%d", count);
1451 output_asm_insn(buf, operands);
1455 output_asm_insn("dec %4", operands);
1457 sprintf(buf, "bgt movestrhi%d", count);
1458 output_asm_insn(buf, NULL);
1480 generate_compact_code:
1482 output_asm_insn("asr %4", operands);
1484 sprintf(buf, "\nmovestrhi%d:", count);
1485 output_asm_insn(buf, NULL);
1487 output_asm_insn("mov (%1)+, (%0)+", operands);
1491 sprintf(buf, "sob %%4, movestrhi%d", count);
1492 output_asm_insn(buf, operands);
1496 output_asm_insn("dec %4", operands);
1498 sprintf(buf, "bgt movestrhi%d", count);
1499 output_asm_insn(buf, NULL);
1525 goto generate_compact_code;
1527 output_asm_insn("asr %4", operands);
1528 output_asm_insn("asr %4", operands);
1530 sprintf(buf, "\nmovestrhi%d:", count);
1531 output_asm_insn(buf, NULL);
1533 output_asm_insn("mov (%1)+, (%0)+", operands);
1534 output_asm_insn("mov (%1)+, (%0)+", operands);
1538 sprintf(buf, "sob %%4, movestrhi%d", count);
1539 output_asm_insn(buf, operands);
1543 output_asm_insn("dec %4", operands);
1545 sprintf(buf, "bgt movestrhi%d", count);
1546 output_asm_insn(buf, NULL);
1576 goto generate_compact_code;
1578 output_asm_insn("asr %4", operands);
1579 output_asm_insn("asr %4", operands);
1580 output_asm_insn("asr %4", operands);
1582 sprintf(buf, "\nmovestrhi%d:", count);
1583 output_asm_insn(buf, NULL);
1585 output_asm_insn("mov (%1)+, (%0)+", operands);
1586 output_asm_insn("mov (%1)+, (%0)+", operands);
1587 output_asm_insn("mov (%1)+, (%0)+", operands);
1588 output_asm_insn("mov (%1)+, (%0)+", operands);
1592 sprintf(buf, "sob %%4, movestrhi%d", count);
1593 output_asm_insn(buf, operands);
1597 output_asm_insn("dec %4", operands);
1599 sprintf(buf, "bgt movestrhi%d", count);
1600 output_asm_insn(buf, NULL);
1613 /* This function checks whether a real value can be encoded as
1614 a literal, i.e., addressing mode 27. In that mode, real values
1615 are one word values, so the remaining 48 bits have to be zero. */
1617 legitimate_const_double_p (rtx address)
1621 REAL_VALUE_FROM_CONST_DOUBLE (r, address);
1622 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
1623 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1628 /* A copy of output_addr_const modified for pdp11 expression syntax.
1629 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1630 use, and for debugging output, which we don't support with this port either.
1631 So this copy should get called whenever needed.
1634 output_addr_const_pdp11 (FILE *file, rtx x)
1639 switch (GET_CODE (x))
1642 gcc_assert (flag_pic);
1647 assemble_name (file, XSTR (x, 0));
1651 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1652 assemble_name (file, buf);
1656 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1657 assemble_name (file, buf);
1661 /* Should we check for constants which are too big? Maybe cutting
1662 them off to 16 bits is OK? */
1663 fprintf (file, "%#ho", (unsigned short) INTVAL (x));
1667 /* This used to output parentheses around the expression,
1668 but that does not work on the 386 (either ATT or BSD assembler). */
1669 output_addr_const_pdp11 (file, XEXP (x, 0));
1673 if (GET_MODE (x) == VOIDmode)
1675 /* We can use %o if the number is one word and positive. */
1676 gcc_assert (!CONST_DOUBLE_HIGH (x));
1677 fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
1680 /* We can't handle floating point constants;
1681 PRINT_OPERAND must handle them. */
1682 output_operand_lossage ("floating constant misused");
1686 /* Some assemblers need integer constants to appear last (e.g. masm). */
1687 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1689 output_addr_const_pdp11 (file, XEXP (x, 1));
1690 if (INTVAL (XEXP (x, 0)) >= 0)
1691 fprintf (file, "+");
1692 output_addr_const_pdp11 (file, XEXP (x, 0));
1696 output_addr_const_pdp11 (file, XEXP (x, 0));
1697 if (INTVAL (XEXP (x, 1)) >= 0)
1698 fprintf (file, "+");
1699 output_addr_const_pdp11 (file, XEXP (x, 1));
1704 /* Avoid outputting things like x-x or x+5-x,
1705 since some assemblers can't handle that. */
1706 x = simplify_subtraction (x);
1707 if (GET_CODE (x) != MINUS)
1710 output_addr_const_pdp11 (file, XEXP (x, 0));
1711 fprintf (file, "-");
1712 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1713 && INTVAL (XEXP (x, 1)) < 0)
1715 fprintf (file, targetm.asm_out.open_paren);
1716 output_addr_const_pdp11 (file, XEXP (x, 1));
1717 fprintf (file, targetm.asm_out.close_paren);
1720 output_addr_const_pdp11 (file, XEXP (x, 1));
1725 output_addr_const_pdp11 (file, XEXP (x, 0));
1729 output_operand_lossage ("invalid expression as operand");
1733 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1736 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1738 /* Should probably return DImode and DFmode in memory, lest
1739 we fill up all regs!
1741 have to, else we crash - exception: maybe return result in
1742 ac0 if DFmode and FPU present - compatibility problem with
1743 libraries for non-floating point.... */
1744 return (TYPE_MODE (type) == DImode
1745 || (TYPE_MODE (type) == DFmode && ! TARGET_AC0));
1748 /* Worker function for TARGET_TRAMPOLINE_INIT.
1750 trampoline - how should i do it in separate i+d ?
1751 have some allocate_trampoline magic???
1753 the following should work for shared I/D:
1755 MV #STATIC, $4 0x940Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
1756 JMP FUNCTION 0x0058 0x0000 <- FUNCTION
1760 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1762 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
1765 gcc_assert (!TARGET_SPLIT);
1767 mem = adjust_address (m_tramp, HImode, 0);
1768 emit_move_insn (mem, GEN_INT (0x9400+STATIC_CHAIN_REGNUM));
1769 mem = adjust_address (m_tramp, HImode, 2);
1770 emit_move_insn (mem, chain_value);
1771 mem = adjust_address (m_tramp, HImode, 4);
1772 emit_move_insn (mem, GEN_INT (0x0058));
1773 emit_move_insn (mem, fnaddr);