1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2004, 2005,
3 2006, 2007, 2008, 2009, 2010 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"
29 #include "insn-config.h"
30 #include "conditions.h"
33 #include "insn-attr.h"
38 #include "diagnostic-core.h"
41 #include "target-def.h"
44 /* this is the current value returned by the macro FIRST_PARM_OFFSET
46 int current_first_parm_offset
;
48 /* Routines to encode/decode pdp11 floats */
49 static void encode_pdp11_f (const struct real_format
*fmt
,
50 long *, const REAL_VALUE_TYPE
*);
51 static void decode_pdp11_f (const struct real_format
*,
52 REAL_VALUE_TYPE
*, const long *);
53 static void encode_pdp11_d (const struct real_format
*fmt
,
54 long *, const REAL_VALUE_TYPE
*);
55 static void decode_pdp11_d (const struct real_format
*,
56 REAL_VALUE_TYPE
*, const long *);
58 /* These two are taken from the corresponding vax descriptors
59 in real.c, changing only the encode/decode routine pointers. */
60 const struct real_format pdp11_f_format
=
81 const struct real_format pdp11_d_format
=
103 encode_pdp11_f (const struct real_format
*fmt ATTRIBUTE_UNUSED
, long *buf
,
104 const REAL_VALUE_TYPE
*r
)
106 (*vax_f_format
.encode
) (fmt
, buf
, r
);
107 buf
[0] = ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
111 decode_pdp11_f (const struct real_format
*fmt ATTRIBUTE_UNUSED
,
112 REAL_VALUE_TYPE
*r
, const long *buf
)
115 tbuf
= ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
116 (*vax_f_format
.decode
) (fmt
, r
, &tbuf
);
120 encode_pdp11_d (const struct real_format
*fmt ATTRIBUTE_UNUSED
, long *buf
,
121 const REAL_VALUE_TYPE
*r
)
123 (*vax_d_format
.encode
) (fmt
, buf
, r
);
124 buf
[0] = ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
125 buf
[1] = ((buf
[1] >> 16) & 0xffff) | ((buf
[1] & 0xffff) << 16);
129 decode_pdp11_d (const struct real_format
*fmt ATTRIBUTE_UNUSED
,
130 REAL_VALUE_TYPE
*r
, const long *buf
)
133 tbuf
[0] = ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
134 tbuf
[1] = ((buf
[1] >> 16) & 0xffff) | ((buf
[1] & 0xffff) << 16);
135 (*vax_d_format
.decode
) (fmt
, r
, tbuf
);
138 /* This is where the condition code register lives. */
139 /* rtx cc0_reg_rtx; - no longer needed? */
141 static bool pdp11_handle_option (size_t, const char *, int);
142 static void pdp11_option_init_struct (struct gcc_options
*);
143 static const char *singlemove_string (rtx
*);
144 static bool pdp11_assemble_integer (rtx
, unsigned int, int);
145 static void pdp11_output_function_prologue (FILE *, HOST_WIDE_INT
);
146 static void pdp11_output_function_epilogue (FILE *, HOST_WIDE_INT
);
147 static bool pdp11_rtx_costs (rtx
, int, int, int *, bool);
148 static bool pdp11_return_in_memory (const_tree
, const_tree
);
149 static rtx
pdp11_function_value (const_tree
, const_tree
, bool);
150 static rtx
pdp11_libcall_value (enum machine_mode
, const_rtx
);
151 static bool pdp11_function_value_regno_p (const unsigned int);
152 static void pdp11_trampoline_init (rtx
, tree
, rtx
);
153 static rtx
pdp11_function_arg (CUMULATIVE_ARGS
*, enum machine_mode
,
155 static void pdp11_function_arg_advance (CUMULATIVE_ARGS
*,
156 enum machine_mode
, const_tree
, bool);
157 static void pdp11_conditional_register_usage (void);
159 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
161 static const struct default_options pdp11_option_optimization_table
[] =
163 { OPT_LEVELS_3_PLUS
, OPT_fomit_frame_pointer
, NULL
, 1 },
164 { OPT_LEVELS_NONE
, 0, NULL
, 0 }
167 /* Initialize the GCC target structure. */
168 #undef TARGET_ASM_BYTE_OP
169 #define TARGET_ASM_BYTE_OP NULL
170 #undef TARGET_ASM_ALIGNED_HI_OP
171 #define TARGET_ASM_ALIGNED_HI_OP NULL
172 #undef TARGET_ASM_ALIGNED_SI_OP
173 #define TARGET_ASM_ALIGNED_SI_OP NULL
174 #undef TARGET_ASM_INTEGER
175 #define TARGET_ASM_INTEGER pdp11_assemble_integer
177 #undef TARGET_ASM_FUNCTION_PROLOGUE
178 #define TARGET_ASM_FUNCTION_PROLOGUE pdp11_output_function_prologue
179 #undef TARGET_ASM_FUNCTION_EPILOGUE
180 #define TARGET_ASM_FUNCTION_EPILOGUE pdp11_output_function_epilogue
182 #undef TARGET_ASM_OPEN_PAREN
183 #define TARGET_ASM_OPEN_PAREN "["
184 #undef TARGET_ASM_CLOSE_PAREN
185 #define TARGET_ASM_CLOSE_PAREN "]"
187 #undef TARGET_DEFAULT_TARGET_FLAGS
188 #define TARGET_DEFAULT_TARGET_FLAGS \
189 (MASK_FPU | MASK_45 | TARGET_UNIX_ASM_DEFAULT)
190 #undef TARGET_HANDLE_OPTION
191 #define TARGET_HANDLE_OPTION pdp11_handle_option
192 #undef TARGET_OPTION_OPTIMIZATION_TABLE
193 #define TARGET_OPTION_OPTIMIZATION_TABLE pdp11_option_optimization_table
194 #undef TARGET_OPTION_INIT_STRUCT
195 #define TARGET_OPTION_INIT_STRUCT pdp11_option_init_struct
197 #undef TARGET_RTX_COSTS
198 #define TARGET_RTX_COSTS pdp11_rtx_costs
200 #undef TARGET_FUNCTION_ARG
201 #define TARGET_FUNCTION_ARG pdp11_function_arg
202 #undef TARGET_FUNCTION_ARG_ADVANCE
203 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
205 #undef TARGET_RETURN_IN_MEMORY
206 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
208 #undef TARGET_FUNCTION_VALUE
209 #define TARGET_FUNCTION_VALUE pdp11_function_value
210 #undef TARGET_LIBCALL_VALUE
211 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
212 #undef TARGET_FUNCTION_VALUE_REGNO_P
213 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
215 #undef TARGET_TRAMPOLINE_INIT
216 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
218 #undef TARGET_SECONDARY_RELOAD
219 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
221 #undef TARGET_REGISTER_MOVE_COST
222 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
224 #undef TARGET_PREFERRED_RELOAD_CLASS
225 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
227 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
228 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
230 #undef TARGET_LEGITIMATE_ADDRESS_P
231 #define TARGET_LEGITIMATE_ADDRESS_P pdp11_legitimate_address_p
233 #undef TARGET_CONDITIONAL_REGISTER_USAGE
234 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
236 #undef TARGET_ASM_FUNCTION_SECTION
237 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
239 #undef TARGET_PRINT_OPERAND
240 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
242 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
243 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
245 /* Implement TARGET_HANDLE_OPTION. */
248 pdp11_handle_option (size_t code
, const char *arg ATTRIBUTE_UNUSED
,
249 int value ATTRIBUTE_UNUSED
)
254 target_flags
&= ~(MASK_40
| MASK_45
);
262 /* Implement TARGET_OPTION_INIT_STRUCT. */
265 pdp11_option_init_struct (struct gcc_options
*opts
)
267 opts
->x_flag_finite_math_only
= 0;
268 opts
->x_flag_trapping_math
= 0;
269 opts
->x_flag_signaling_nans
= 0;
273 stream is a stdio stream to output the code to.
274 size is an int: how many units of temporary storage to allocate.
275 Refer to the array `regs_ever_live' to determine which registers
276 to save; `regs_ever_live[I]' is nonzero if register number I
277 is ever used in the function. This macro is responsible for
278 knowing which registers should not be saved even if used.
282 pdp11_output_function_prologue (FILE *stream
, HOST_WIDE_INT size
)
284 HOST_WIDE_INT fsize
= ((size
) + 1) & ~1;
289 "\n\t; /* function prologue %s*/\n",
290 current_function_name ());
292 /* if we are outputting code for main,
293 the switch FPU to right mode if TARGET_FPU */
294 if (MAIN_NAME_P (DECL_NAME (current_function_decl
)) && TARGET_FPU
)
297 "\t;/* switch cpu to double float, single integer */\n");
298 fprintf(stream
, "\tsetd\n");
299 fprintf(stream
, "\tseti\n\n");
302 if (frame_pointer_needed
)
304 fprintf(stream
, "\tmov r5, -(sp)\n");
305 fprintf(stream
, "\tmov sp, r5\n");
314 asm_fprintf (stream
, "\tsub $%#wo, sp\n", fsize
);
316 /* save CPU registers */
317 for (regno
= R0_REGNUM
; regno
<= PC_REGNUM
; regno
++)
318 if (df_regs_ever_live_p (regno
) && ! call_used_regs
[regno
])
319 if (! ((regno
== FRAME_POINTER_REGNUM
)
320 && frame_pointer_needed
))
321 fprintf (stream
, "\tmov %s, -(sp)\n", reg_names
[regno
]);
322 /* fpu regs saving */
324 /* via_ac specifies the ac to use for saving ac4, ac5 */
327 for (regno
= AC0_REGNUM
; regno
<= AC5_REGNUM
; regno
++)
330 if (LOAD_FPU_REG_P(regno
)
331 && df_regs_ever_live_p (regno
)
332 && ! call_used_regs
[regno
])
334 fprintf (stream
, "\tstd %s, -(sp)\n", reg_names
[regno
]);
338 /* maybe make ac4, ac5 call used regs?? */
340 if (NO_LOAD_FPU_REG_P(regno
)
341 && df_regs_ever_live_p (regno
)
342 && ! call_used_regs
[regno
])
344 gcc_assert (via_ac
!= -1);
345 fprintf (stream
, "\tldd %s, %s\n",
346 reg_names
[regno
], reg_names
[via_ac
]);
347 fprintf (stream
, "\tstd %s, -(sp)\n", reg_names
[via_ac
]);
351 fprintf (stream
, "\t;/* end of prologue */\n\n");
355 The function epilogue should not depend on the current stack pointer!
356 It should use the frame pointer only. This is mandatory because
357 of alloca; we also take advantage of it to omit stack adjustments
360 /* maybe we can make leaf functions faster by switching to the
361 second register file - this way we don't have to save regs!
362 leaf functions are ~ 50% of all functions (dynamically!)
364 set/clear bit 11 (dec. 2048) of status word for switching register files -
365 but how can we do this? the pdp11/45 manual says bit may only
366 be set (p.24), but not cleared!
368 switching to kernel is probably more expensive, so we'll leave it
369 like this and not use the second set of registers...
371 maybe as option if you want to generate code for kernel mode? */
374 pdp11_output_function_epilogue (FILE *stream
, HOST_WIDE_INT size
)
376 HOST_WIDE_INT fsize
= ((size
) + 1) & ~1;
381 fprintf (stream
, "\n\t; /*function epilogue */\n");
383 if (frame_pointer_needed
)
385 /* hope this is safe - m68k does it also .... */
386 df_set_regs_ever_live (FRAME_POINTER_REGNUM
, false);
388 for (i
= PC_REGNUM
, j
= 0 ; i
>= 0 ; i
--)
389 if (df_regs_ever_live_p (i
) && ! call_used_regs
[i
])
392 /* remember # of pushed bytes for CPU regs */
395 /* change fp -> r5 due to the compile error on libgcc2.c */
396 for (i
= PC_REGNUM
; i
>= R0_REGNUM
; i
--)
397 if (df_regs_ever_live_p (i
) && ! call_used_regs
[i
])
398 fprintf(stream
, "\tmov %#" HOST_WIDE_INT_PRINT
"o(r5), %s\n",
399 (-fsize
-2*j
--)&0xffff, reg_names
[i
]);
404 for (i
= AC5_REGNUM
; i
>= AC0_REGNUM
; i
--)
405 if (df_regs_ever_live_p (i
) && ! call_used_regs
[i
])
411 for (i
= AC5_REGNUM
; i
>= AC0_REGNUM
; i
--)
413 if (LOAD_FPU_REG_P(i
)
414 && df_regs_ever_live_p (i
)
415 && ! call_used_regs
[i
])
417 fprintf(stream
, "\tldd %#" HOST_WIDE_INT_PRINT
"o(r5), %s\n",
418 (-fsize
-k
)&0xffff, reg_names
[i
]);
422 if (NO_LOAD_FPU_REG_P(i
)
423 && df_regs_ever_live_p (i
)
424 && ! call_used_regs
[i
])
426 gcc_assert (LOAD_FPU_REG_P(via_ac
));
428 fprintf(stream
, "\tldd %#" HOST_WIDE_INT_PRINT
"o(r5), %s\n",
429 (-fsize
-k
)&0xffff, reg_names
[via_ac
]);
430 fprintf(stream
, "\tstd %s, %s\n", reg_names
[via_ac
], reg_names
[i
]);
435 fprintf(stream
, "\tmov r5, sp\n");
436 fprintf (stream
, "\tmov (sp)+, r5\n");
443 for (i
= AC5_REGNUM
; i
>= AC0_REGNUM
; i
--)
444 if (df_regs_ever_live_p (i
) && ! call_used_regs
[i
])
447 for (i
= AC5_REGNUM
; i
>= AC0_REGNUM
; i
--)
449 if (LOAD_FPU_REG_P(i
)
450 && df_regs_ever_live_p (i
)
451 && ! call_used_regs
[i
])
452 fprintf(stream
, "\tldd (sp)+, %s\n", reg_names
[i
]);
454 if (NO_LOAD_FPU_REG_P(i
)
455 && df_regs_ever_live_p (i
)
456 && ! call_used_regs
[i
])
458 gcc_assert (LOAD_FPU_REG_P(via_ac
));
460 fprintf(stream
, "\tldd (sp)+, %s\n", reg_names
[via_ac
]);
461 fprintf(stream
, "\tstd %s, %s\n", reg_names
[via_ac
], reg_names
[i
]);
465 for (i
= PC_REGNUM
; i
>= 0; i
--)
466 if (df_regs_ever_live_p (i
) && !call_used_regs
[i
])
467 fprintf(stream
, "\tmov (sp)+, %s\n", reg_names
[i
]);
470 fprintf((stream
), "\tadd $%#" HOST_WIDE_INT_PRINT
"o, sp\n",
474 fprintf (stream
, "\trts pc\n");
475 fprintf (stream
, "\t;/* end of epilogue*/\n\n\n");
478 /* Return the best assembler insn template
479 for moving operands[1] into operands[0] as a fullword. */
481 singlemove_string (rtx
*operands
)
483 if (operands
[1] != const0_rtx
)
490 /* Expand multi-word operands (SImode or DImode) into the 2 or 4
491 corresponding HImode operands. The number of operands is given
492 as the third argument, and the required order of the parts as
493 the fourth argument. */
495 pdp11_expand_operands (rtx
*operands
, rtx exops
[][2], int opcount
,
496 pdp11_action
*action
, pdp11_partorder order
)
498 int words
, op
, w
, i
, sh
;
499 pdp11_partorder useorder
;
500 bool sameoff
= false;
501 enum { REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
} optype
;
505 words
= GET_MODE_BITSIZE (GET_MODE (operands
[0])) / 16;
507 /* If either piece order is accepted and one is pre-decrement
508 while the other is post-increment, set order to be high order
509 word first. That will force the pre-decrement to be turned
510 into a pointer adjust, then offset addressing.
511 Otherwise, if either operand uses pre-decrement, that means
512 the order is low order first.
513 Otherwise, if both operands are registers and destination is
514 higher than source and they overlap, do low order word (highest
515 register number) first. */
519 if (!REG_P (operands
[0]) && !REG_P (operands
[1]) &&
520 !(CONSTANT_P (operands
[1]) ||
521 GET_CODE (operands
[1]) == CONST_DOUBLE
) &&
522 ((GET_CODE (XEXP (operands
[0], 0)) == POST_INC
&&
523 GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
) ||
524 (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
&&
525 GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)))
527 else if ((!REG_P (operands
[0]) &&
528 GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
) ||
529 (!REG_P (operands
[1]) &&
530 !(CONSTANT_P (operands
[1]) ||
531 GET_CODE (operands
[1]) == CONST_DOUBLE
) &&
532 GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
))
534 else if (REG_P (operands
[0]) && REG_P (operands
[1]) &&
535 REGNO (operands
[0]) > REGNO (operands
[1]) &&
536 REGNO (operands
[0]) < REGNO (operands
[1]) + words
)
539 /* Check for source == offset from register and dest == push of
540 the same register. In that case, we have to use the same
541 offset (the one for the low order word) for all words, because
542 the push increases the offset to each source word.
543 In theory there are other cases like this, for example dest == pop,
544 but those don't occur in real life so ignore those. */
545 if (GET_CODE (operands
[0]) == MEM
546 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
547 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
548 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
552 /* If the caller didn't specify order, use the one we computed,
553 or high word first if we don't care either. If the caller did
554 specify, verify we don't have a problem with that order.
555 (If it matters to the caller, constraints need to be used to
556 ensure this case doesn't occur). */
558 order
= (useorder
== either
) ? big
: useorder
;
560 gcc_assert (useorder
== either
|| useorder
== order
);
563 for (op
= 0; op
< opcount
; op
++)
565 /* First classify the operand. */
566 if (REG_P (operands
[op
]))
568 else if (CONSTANT_P (operands
[op
])
569 || GET_CODE (operands
[op
]) == CONST_DOUBLE
)
571 else if (GET_CODE (XEXP (operands
[op
], 0)) == POST_INC
)
573 else if (GET_CODE (XEXP (operands
[op
], 0)) == PRE_DEC
)
575 else if (!reload_in_progress
|| offsettable_memref_p (operands
[op
]))
577 else if (GET_CODE (operands
[op
]) == MEM
)
582 /* Check for the cases that the operand constraints are not
583 supposed to allow to happen. Return failure for such cases. */
588 action
[op
] = no_action
;
590 /* If the operand uses pre-decrement addressing but we
591 want to get the parts high order first,
592 decrement the former register explicitly
593 and change the operand into ordinary indexing. */
594 if (optype
== PUSHOP
&& order
== big
)
596 gcc_assert (action
!= NULL
);
597 action
[op
] = dec_before
;
598 operands
[op
] = gen_rtx_MEM (GET_MODE (operands
[op
]),
599 XEXP (XEXP (operands
[op
], 0), 0));
602 /* If the operand uses post-increment mode but we want
603 to get the parts low order first, change the operand
604 into ordinary indexing and remember to increment
605 the register explicitly when we're done. */
606 else if (optype
== POPOP
&& order
== little
)
608 gcc_assert (action
!= NULL
);
609 action
[op
] = inc_after
;
610 operands
[op
] = gen_rtx_MEM (GET_MODE (operands
[op
]),
611 XEXP (XEXP (operands
[op
], 0), 0));
615 if (GET_CODE (operands
[op
]) == CONST_DOUBLE
)
617 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[op
]);
618 REAL_VALUE_TO_TARGET_DOUBLE (r
, sval
);
621 for (i
= 0; i
< words
; i
++)
630 /* Set the output operand to be word "w" of the input. */
632 exops
[i
][op
] = gen_rtx_REG (HImode
, REGNO (operands
[op
]) + w
);
633 else if (optype
== OFFSOP
)
634 exops
[i
][op
] = adjust_address (operands
[op
], HImode
, w
* 2);
635 else if (optype
== CNSTOP
)
637 if (GET_CODE (operands
[op
]) == CONST_DOUBLE
)
639 sh
= 16 - (w
& 1) * 16;
640 exops
[i
][op
] = gen_rtx_CONST_INT (HImode
, (sval
[w
/ 2] >> sh
) & 0xffff);
644 sh
= ((words
- 1 - w
) * 16);
645 exops
[i
][op
] = gen_rtx_CONST_INT (HImode
, trunc_int_for_mode (INTVAL(operands
[op
]) >> sh
, HImode
));
649 exops
[i
][op
] = operands
[op
];
655 /* Output assembler code to perform a multiple-word move insn
656 with operands OPERANDS. This moves 2 or 4 words depending
657 on the machine mode of the operands. */
660 output_move_multiple (rtx
*operands
)
663 pdp11_action action
[2];
666 words
= GET_MODE_BITSIZE (GET_MODE (operands
[0])) / 16;
668 pdp11_expand_operands (operands
, exops
, 2, action
, either
);
670 /* Check for explicit decrement before. */
671 if (action
[0] == dec_before
)
673 operands
[0] = XEXP (operands
[0], 0);
674 output_asm_insn ("sub $4,%0", operands
);
676 if (action
[1] == dec_before
)
678 operands
[1] = XEXP (operands
[1], 0);
679 output_asm_insn ("sub $4,%1", operands
);
683 for (i
= 0; i
< words
; i
++)
684 output_asm_insn (singlemove_string (exops
[i
]), exops
[i
]);
686 /* Check for increment after. */
687 if (action
[0] == inc_after
)
689 operands
[0] = XEXP (operands
[0], 0);
690 output_asm_insn ("add $4,%0", operands
);
692 if (action
[1] == inc_after
)
694 operands
[1] = XEXP (operands
[1], 0);
695 output_asm_insn ("add $4,%1", operands
);
701 /* Output an ascii string. */
703 output_ascii (FILE *file
, const char *p
, int size
)
707 /* This used to output .byte "string", which doesn't work with the UNIX
708 assembler and I think not with DEC ones either. */
709 fprintf (file
, "\t.byte ");
711 for (i
= 0; i
< size
; i
++)
713 register int c
= p
[i
];
716 fprintf (file
, "%#o", c
);
725 pdp11_asm_output_var (FILE *file
, const char *name
, int size
,
726 int align
, bool global
)
729 fprintf (file
, "\n\t.even\n");
732 fprintf (file
, ".globl ");
733 assemble_name (file
, name
);
735 fprintf (file
, "\n");
736 assemble_name (file
, name
);
737 fprintf (file
, ": .=.+ %#ho\n", (unsigned short)size
);
741 pdp11_asm_print_operand (FILE *file
, rtx x
, int code
)
748 else if (code
== '@')
755 else if (GET_CODE (x
) == REG
)
756 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
757 else if (GET_CODE (x
) == MEM
)
758 output_address (XEXP (x
, 0));
759 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) != SImode
)
761 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
762 REAL_VALUE_TO_TARGET_DOUBLE (r
, sval
);
763 fprintf (file
, "$%#lo", sval
[0] >> 16);
768 output_addr_const_pdp11 (file
, x
);
773 pdp11_asm_print_operand_punct_valid_p (unsigned char c
)
775 return (c
== '#' || c
== '@');
779 print_operand_address (FILE *file
, register rtx addr
)
787 switch (GET_CODE (addr
))
794 addr
= XEXP (addr
, 0);
799 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
804 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
809 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
815 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0))
816 || GET_CODE (XEXP (addr
, 0)) == MEM
)
818 offset
= XEXP (addr
, 0);
819 addr
= XEXP (addr
, 1);
821 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1))
822 || GET_CODE (XEXP (addr
, 1)) == MEM
)
824 offset
= XEXP (addr
, 1);
825 addr
= XEXP (addr
, 0);
827 if (GET_CODE (addr
) != PLUS
)
829 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
831 breg
= XEXP (addr
, 0);
832 addr
= XEXP (addr
, 1);
834 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
836 breg
= XEXP (addr
, 1);
837 addr
= XEXP (addr
, 0);
839 if (GET_CODE (addr
) == REG
)
841 gcc_assert (breg
== 0);
847 gcc_assert (addr
== 0);
851 output_addr_const_pdp11 (file
, addr
);
854 gcc_assert (GET_CODE (breg
) == REG
);
855 fprintf (file
, "(%s)", reg_names
[REGNO (breg
)]);
860 if (!again
&& GET_CODE (addr
) == CONST_INT
)
862 /* Absolute (integer number) address. */
863 if (!TARGET_UNIX_ASM
)
864 fprintf (file
, "@$");
866 output_addr_const_pdp11 (file
, addr
);
870 /* Target hook to assemble integer objects. We need to use the
871 pdp-specific version of output_addr_const. */
874 pdp11_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
880 fprintf (asm_out_file
, "\t.byte\t");
881 output_addr_const_pdp11 (asm_out_file
, GEN_INT (INTVAL (x
) & 0xff));
883 fprintf (asm_out_file
, " /* char */\n");
887 fprintf (asm_out_file
, TARGET_UNIX_ASM
? "\t" : "\t.word\t");
888 output_addr_const_pdp11 (asm_out_file
, x
);
889 fprintf (asm_out_file
, " /* short */\n");
892 return default_assemble_integer (x
, size
, aligned_p
);
896 /* register move costs, indexed by regs */
898 static const int move_costs
[N_REG_CLASSES
][N_REG_CLASSES
] =
900 /* NO MUL GEN LFPU NLFPU FPU ALL */
902 /* NO */ { 0, 0, 0, 0, 0, 0, 0},
903 /* MUL */ { 0, 2, 2, 22, 22, 22, 22},
904 /* GEN */ { 0, 2, 2, 22, 22, 22, 22},
905 /* LFPU */ { 0, 22, 22, 2, 2, 2, 22},
906 /* NLFPU */ { 0, 22, 22, 2, 10, 10, 22},
907 /* FPU */ { 0, 22, 22, 2, 10, 10, 22},
908 /* ALL */ { 0, 22, 22, 22, 22, 22, 22}
912 /* -- note that some moves are tremendously expensive,
913 because they require lots of tricks! do we have to
914 charge the costs incurred by secondary reload class
915 -- as we do here with 10 -- or not ? */
918 pdp11_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED
,
919 reg_class_t c1
, reg_class_t c2
)
921 return move_costs
[(int)c1
][(int)c2
];
925 pdp11_rtx_costs (rtx x
, int code
, int outer_code ATTRIBUTE_UNUSED
, int *total
,
926 bool speed ATTRIBUTE_UNUSED
)
931 if (INTVAL (x
) == 0 || INTVAL (x
) == -1 || INTVAL (x
) == 1)
941 /* Twice as expensive as REG. */
946 /* Twice (or 4 times) as expensive as 16 bit. */
951 /* ??? There is something wrong in MULT because MULT is not
952 as cheap as total = 2 even if we can shift! */
953 /* If optimizing for size make mult etc cheap, but not 1, so when
954 in doubt the faster insn is chosen. */
956 *total
= COSTS_N_INSNS (2);
958 *total
= COSTS_N_INSNS (11);
963 *total
= COSTS_N_INSNS (2);
965 *total
= COSTS_N_INSNS (25);
970 *total
= COSTS_N_INSNS (2);
972 *total
= COSTS_N_INSNS (26);
976 /* Equivalent to length, so same for optimize_size. */
977 *total
= COSTS_N_INSNS (3);
981 /* Only used for qi->hi. */
982 *total
= COSTS_N_INSNS (1);
986 if (GET_MODE (x
) == HImode
)
987 *total
= COSTS_N_INSNS (1);
988 else if (GET_MODE (x
) == SImode
)
989 *total
= COSTS_N_INSNS (6);
991 *total
= COSTS_N_INSNS (2);
998 *total
= COSTS_N_INSNS (1);
999 else if (GET_MODE (x
) == QImode
)
1001 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
1002 *total
= COSTS_N_INSNS (8); /* worst case */
1004 *total
= COSTS_N_INSNS (INTVAL (XEXP (x
, 1)));
1006 else if (GET_MODE (x
) == HImode
)
1008 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1010 if (abs (INTVAL (XEXP (x
, 1))) == 1)
1011 *total
= COSTS_N_INSNS (1);
1013 *total
= COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x
, 1)));
1016 *total
= COSTS_N_INSNS (10); /* worst case */
1018 else if (GET_MODE (x
) == SImode
)
1020 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1021 *total
= COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x
, 1)));
1022 else /* worst case */
1023 *total
= COSTS_N_INSNS (18);
1033 output_jump (enum rtx_code code
, int inv
, int length
)
1037 static char buf
[1000];
1038 const char *pos
, *neg
;
1040 if (cc_prev_status
.flags
& CC_NO_OVERFLOW
)
1044 case GTU
: code
= GT
; break;
1045 case LTU
: code
= LT
; break;
1046 case GEU
: code
= GE
; break;
1047 case LEU
: code
= LE
; break;
1053 case EQ
: pos
= "beq", neg
= "bne"; break;
1054 case NE
: pos
= "bne", neg
= "beq"; break;
1055 case GT
: pos
= "bgt", neg
= "ble"; break;
1056 case GTU
: pos
= "bhi", neg
= "blos"; break;
1057 case LT
: pos
= "blt", neg
= "bge"; break;
1058 case LTU
: pos
= "blo", neg
= "bhis"; break;
1059 case GE
: pos
= "bge", neg
= "blt"; break;
1060 case GEU
: pos
= "bhis", neg
= "blo"; break;
1061 case LE
: pos
= "ble", neg
= "bgt"; break;
1062 case LEU
: pos
= "blos", neg
= "bhi"; break;
1063 default: gcc_unreachable ();
1067 /* currently we don't need this, because the tstdf and cmpdf
1068 copy the condition code immediately, and other float operations are not
1069 yet recognized as changing the FCC - if so, then the length-cost of all
1070 jump insns increases by one, because we have to potentially copy the
1072 if (cc_status
.flags
& CC_IN_FPU
)
1073 output_asm_insn("cfcc", NULL
);
1080 sprintf(buf
, "%s %%l1", inv
? neg
: pos
);
1086 sprintf(buf
, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv
? pos
: neg
, x
, x
);
1100 notice_update_cc_on_set(rtx exp
, rtx insn ATTRIBUTE_UNUSED
)
1102 if (GET_CODE (SET_DEST (exp
)) == CC0
)
1104 cc_status
.flags
= 0;
1105 cc_status
.value1
= SET_DEST (exp
);
1106 cc_status
.value2
= SET_SRC (exp
);
1108 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
1112 else if (SET_DEST(exp
) == pc_rtx
)
1116 else if (GET_MODE (SET_DEST(exp
)) == HImode
1117 || GET_MODE (SET_DEST(exp
)) == QImode
)
1119 cc_status
.flags
= GET_CODE (SET_SRC(exp
)) == MINUS
? 0 : CC_NO_OVERFLOW
;
1120 cc_status
.value1
= SET_SRC (exp
);
1121 cc_status
.value2
= SET_DEST (exp
);
1123 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
1125 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
1126 cc_status
.value2
= 0;
1127 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == MEM
1129 && GET_CODE (cc_status
.value2
) == MEM
)
1130 cc_status
.value2
= 0;
1140 simple_memory_operand(rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1144 /* Eliminate non-memory operations */
1145 if (GET_CODE (op
) != MEM
)
1149 /* dword operations really put out 2 instructions, so eliminate them. */
1150 if (GET_MODE_SIZE (GET_MODE (op
)) > (HAVE_64BIT_P () ? 8 : 4))
1154 /* Decode the address now. */
1158 addr
= XEXP (op
, 0);
1160 switch (GET_CODE (addr
))
1163 /* (R0) - no extra cost */
1168 /* -(R0), (R0)+ - cheap! */
1172 /* cheap - is encoded in addressing mode info!
1174 -- except for @(R0), which has to be @0(R0) !!! */
1176 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1186 /* @#address - extra cost */
1190 /* X(R0) - extra cost */
1202 * output a block move:
1204 * operands[0] ... to
1205 * operands[1] ... from
1206 * operands[2] ... length
1207 * operands[3] ... alignment
1208 * operands[4] ... scratch register
1213 output_block_move(rtx
*operands
)
1215 static int count
= 0;
1220 /* Move of zero bytes is a NOP. */
1221 if (operands
[2] == const0_rtx
)
1224 /* Look for moves by small constant byte counts, those we'll
1225 expand to straight line code. */
1226 if (CONSTANT_P (operands
[2]))
1228 if (INTVAL (operands
[2]) < 16
1229 && (!optimize_size
|| INTVAL (operands
[2]) < 5)
1230 && INTVAL (operands
[3]) == 1)
1234 for (i
= 1; i
<= INTVAL (operands
[2]); i
++)
1235 output_asm_insn("movb (%1)+, (%0)+", operands
);
1239 else if (INTVAL(operands
[2]) < 32
1240 && (!optimize_size
|| INTVAL (operands
[2]) < 9)
1241 && INTVAL (operands
[3]) >= 2)
1245 for (i
= 1; i
<= INTVAL (operands
[2]) / 2; i
++)
1246 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1247 if (INTVAL (operands
[2]) & 1)
1248 output_asm_insn ("movb (%1), (%0)", operands
);
1254 /* Ideally we'd look for moves that are multiples of 4 or 8
1255 bytes and handle those by unrolling the move loop. That
1256 makes for a lot of code if done at run time, but it's ok
1257 for constant counts. Also, for variable counts we have
1258 to worry about odd byte count with even aligned pointers.
1259 On 11/40 and up we handle that case; on older machines
1260 we don't and just use byte-wise moves all the time. */
1262 if (CONSTANT_P (operands
[2]) )
1264 if (INTVAL (operands
[3]) < 2)
1268 lastbyte
= INTVAL (operands
[2]) & 1;
1270 if (optimize_size
|| INTVAL (operands
[2]) & 2)
1272 else if (INTVAL (operands
[2]) & 4)
1278 /* Loop count is byte count scaled by unroll. */
1279 operands
[2] = GEN_INT (INTVAL (operands
[2]) >> unroll
);
1280 output_asm_insn ("mov %2, %4", operands
);
1284 /* Variable byte count; use the input register
1286 operands
[4] = operands
[2];
1288 /* Decide whether to move by words, and check
1289 the byte count for zero. */
1290 if (TARGET_40_PLUS
&& INTVAL (operands
[3]) > 1)
1293 output_asm_insn ("asr %4", operands
);
1298 output_asm_insn ("tst %4", operands
);
1300 sprintf (buf
, "beq movestrhi%d", count
+ 1);
1301 output_asm_insn (buf
, NULL
);
1304 /* Output the loop label. */
1305 sprintf (buf
, "\nmovestrhi%d:", count
);
1306 output_asm_insn (buf
, NULL
);
1308 /* Output the appropriate move instructions. */
1312 output_asm_insn ("movb (%1)+, (%0)+", operands
);
1316 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1320 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1321 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1325 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1326 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1327 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1328 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1332 /* Output the decrement and test. */
1335 sprintf (buf
, "sob %%4, movestrhi%d", count
);
1336 output_asm_insn (buf
, operands
);
1340 output_asm_insn ("dec %4", operands
);
1341 sprintf (buf
, "bgt movestrhi%d", count
);
1342 output_asm_insn (buf
, NULL
);
1346 /* If constant odd byte count, move the last byte. */
1348 output_asm_insn ("movb (%1), (%0)", operands
);
1349 else if (!CONSTANT_P (operands
[2]))
1351 /* Output the destination label for the zero byte count check. */
1352 sprintf (buf
, "\nmovestrhi%d:", count
);
1353 output_asm_insn (buf
, NULL
);
1356 /* If we did word moves, check for trailing last byte. */
1359 sprintf (buf
, "bcc movestrhi%d", count
);
1360 output_asm_insn (buf
, NULL
);
1361 output_asm_insn ("movb (%1), (%0)", operands
);
1362 sprintf (buf
, "\nmovestrhi%d:", count
);
1363 output_asm_insn (buf
, NULL
);
1371 /* This function checks whether a real value can be encoded as
1372 a literal, i.e., addressing mode 27. In that mode, real values
1373 are one word values, so the remaining 48 bits have to be zero. */
1375 legitimate_const_double_p (rtx address
)
1379 REAL_VALUE_FROM_CONST_DOUBLE (r
, address
);
1380 REAL_VALUE_TO_TARGET_DOUBLE (r
, sval
);
1381 if ((sval
[0] & 0xffff) == 0 && sval
[1] == 0)
1386 /* Implement CANNOT_CHANGE_MODE_CLASS. */
1388 pdp11_cannot_change_mode_class (enum machine_mode from
,
1389 enum machine_mode to
,
1390 enum reg_class rclass
)
1392 /* Also, FPU registers contain a whole float value and the parts of
1393 it are not separately accessible.
1395 So we disallow all mode changes involving FPRs. */
1396 if (FLOAT_MODE_P (from
) != FLOAT_MODE_P (to
))
1399 return reg_classes_intersect_p (FPU_REGS
, rclass
);
1402 /* TARGET_PREFERRED_RELOAD_CLASS
1404 Given an rtx X being reloaded into a reg required to be
1405 in class CLASS, return the class of reg to actually use.
1406 In general this is just CLASS; but on some machines
1407 in some cases it is preferable to use a more restrictive class.
1409 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1412 pdp11_preferred_reload_class (rtx x
, reg_class_t rclass
)
1414 if (rclass
== FPU_REGS
)
1415 return LOAD_FPU_REGS
;
1416 if (rclass
== ALL_REGS
)
1418 if (FLOAT_MODE_P (GET_MODE (x
)))
1419 return LOAD_FPU_REGS
;
1421 return GENERAL_REGS
;
1426 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1428 Given an rtx X being reloaded into a reg required to be
1429 in class CLASS, return the class of reg to actually use.
1430 In general this is just CLASS; but on some machines
1431 in some cases it is preferable to use a more restrictive class.
1433 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1436 pdp11_preferred_output_reload_class (rtx x
, reg_class_t rclass
)
1438 if (rclass
== FPU_REGS
)
1439 return LOAD_FPU_REGS
;
1440 if (rclass
== ALL_REGS
)
1442 if (FLOAT_MODE_P (GET_MODE (x
)))
1443 return LOAD_FPU_REGS
;
1445 return GENERAL_REGS
;
1451 /* TARGET_SECONDARY_RELOAD.
1453 FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1454 intermediate register (AC0-AC3: LOAD_FPU_REGS). Everything else
1455 can be loade/stored directly. */
1457 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED
,
1459 reg_class_t reload_class
,
1460 enum machine_mode reload_mode ATTRIBUTE_UNUSED
,
1461 secondary_reload_info
*sri ATTRIBUTE_UNUSED
)
1463 if (reload_class
!= NO_LOAD_FPU_REGS
|| GET_CODE (x
) != REG
||
1464 REGNO_REG_CLASS (REGNO (x
)) == LOAD_FPU_REGS
)
1467 return LOAD_FPU_REGS
;
1470 /* Target routine to check if register to register move requires memory.
1472 The answer is yes if we're going between general register and FPU
1473 registers. The mode doesn't matter in making this check.
1476 pdp11_secondary_memory_needed (reg_class_t c1
, reg_class_t c2
,
1477 enum machine_mode mode ATTRIBUTE_UNUSED
)
1479 int fromfloat
= (c1
== LOAD_FPU_REGS
|| c1
== NO_LOAD_FPU_REGS
||
1481 int tofloat
= (c2
== LOAD_FPU_REGS
|| c2
== NO_LOAD_FPU_REGS
||
1484 return (fromfloat
!= tofloat
);
1487 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
1488 that is a valid memory address for an instruction.
1489 The MODE argument is the machine mode for the MEM expression
1490 that wants to use this address.
1495 pdp11_legitimate_address_p (enum machine_mode mode
,
1496 rtx operand
, bool strict
)
1500 /* accept @#address */
1501 if (CONSTANT_ADDRESS_P (operand
))
1504 switch (GET_CODE (operand
))
1508 return !strict
|| REGNO_OK_FOR_BASE_P (REGNO (operand
));
1512 return GET_CODE (XEXP (operand
, 0)) == REG
1513 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand
, 0))))
1514 && CONSTANT_ADDRESS_P (XEXP (operand
, 1));
1518 return GET_CODE (XEXP (operand
, 0)) == REG
1519 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand
, 0))));
1523 return GET_CODE (XEXP (operand
, 0)) == REG
1524 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand
, 0))));
1527 /* accept -(SP) -- which uses PRE_MODIFY for byte mode */
1528 return GET_CODE (XEXP (operand
, 0)) == REG
1529 && REGNO (XEXP (operand
, 0)) == STACK_POINTER_REGNUM
1530 && GET_CODE ((xfoob
= XEXP (operand
, 1))) == PLUS
1531 && GET_CODE (XEXP (xfoob
, 0)) == REG
1532 && REGNO (XEXP (xfoob
, 0)) == STACK_POINTER_REGNUM
1533 && CONSTANT_P (XEXP (xfoob
, 1))
1534 && INTVAL (XEXP (xfoob
,1)) == -2;
1537 /* accept (SP)+ -- which uses POST_MODIFY for byte mode */
1538 return GET_CODE (XEXP (operand
, 0)) == REG
1539 && REGNO (XEXP (operand
, 0)) == STACK_POINTER_REGNUM
1540 && GET_CODE ((xfoob
= XEXP (operand
, 1))) == PLUS
1541 && GET_CODE (XEXP (xfoob
, 0)) == REG
1542 && REGNO (XEXP (xfoob
, 0)) == STACK_POINTER_REGNUM
1543 && CONSTANT_P (XEXP (xfoob
, 1))
1544 && INTVAL (XEXP (xfoob
,1)) == 2;
1547 /* handle another level of indirection ! */
1548 xfoob
= XEXP (operand
, 0);
1550 /* (MEM:xx (MEM:xx ())) is not valid for SI, DI and currently
1551 also forbidden for float, because we have to handle this
1552 in output_move_double and/or output_move_quad() - we could
1553 do it, but currently it's not worth it!!!
1554 now that DFmode cannot go into CPU register file,
1555 maybe I should allow float ...
1556 but then I have to handle memory-to-memory moves in movdf ?? */
1557 if (GET_MODE_BITSIZE(mode
) > 16)
1560 /* accept @address */
1561 if (CONSTANT_ADDRESS_P (xfoob
))
1564 switch (GET_CODE (xfoob
))
1567 /* accept @(R0) - which is @0(R0) */
1568 return !strict
|| REGNO_OK_FOR_BASE_P(REGNO (xfoob
));
1572 return GET_CODE (XEXP (xfoob
, 0)) == REG
1573 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob
, 0))))
1574 && CONSTANT_ADDRESS_P (XEXP (xfoob
, 1));
1578 return GET_CODE (XEXP (xfoob
, 0)) == REG
1579 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob
, 0))));
1583 return GET_CODE (XEXP (xfoob
, 0)) == REG
1584 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob
, 0))));
1587 /* anything else is invalid */
1592 /* anything else is invalid */
1597 /* Return the class number of the smallest class containing
1598 reg number REGNO. */
1600 pdp11_regno_reg_class (int regno
)
1602 if (regno
== FRAME_POINTER_REGNUM
|| regno
== ARG_POINTER_REGNUM
)
1603 return GENERAL_REGS
;
1604 else if (regno
> AC3_REGNUM
)
1605 return NO_LOAD_FPU_REGS
;
1606 else if (regno
>= AC0_REGNUM
)
1607 return LOAD_FPU_REGS
;
1611 return GENERAL_REGS
;
1616 pdp11_sp_frame_offset (void)
1618 int offset
= 0, regno
;
1619 offset
= get_frame_size();
1620 for (regno
= 0; regno
<= PC_REGNUM
; regno
++)
1621 if (df_regs_ever_live_p (regno
) && ! call_used_regs
[regno
])
1623 for (regno
= AC0_REGNUM
; regno
<= AC5_REGNUM
; regno
++)
1624 if (df_regs_ever_live_p (regno
) && ! call_used_regs
[regno
])
1630 /* Return the offset between two registers, one to be eliminated, and the other
1631 its replacement, at the start of a routine. */
1634 pdp11_initial_elimination_offset (int from
, int to
)
1638 if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
1640 else if (from
== FRAME_POINTER_REGNUM
1641 && to
== HARD_FRAME_POINTER_REGNUM
)
1645 gcc_assert (to
== STACK_POINTER_REGNUM
);
1647 /* Get the size of the register save area. */
1648 spoff
= pdp11_sp_frame_offset ();
1649 if (from
== FRAME_POINTER_REGNUM
)
1652 gcc_assert (from
== ARG_POINTER_REGNUM
);
1654 /* If there is a frame pointer, that is saved too. */
1655 if (frame_pointer_needed
)
1658 /* Account for the saved PC in the function call. */
1663 /* A copy of output_addr_const modified for pdp11 expression syntax.
1664 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1665 use, and for debugging output, which we don't support with this port either.
1666 So this copy should get called whenever needed.
1669 output_addr_const_pdp11 (FILE *file
, rtx x
)
1675 switch (GET_CODE (x
))
1678 gcc_assert (flag_pic
);
1683 assemble_name (file
, XSTR (x
, 0));
1687 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
1688 assemble_name (file
, buf
);
1692 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
1693 assemble_name (file
, buf
);
1701 fprintf (file
, "-");
1703 fprintf (file
, "%#o", i
& 0xffff);
1707 /* This used to output parentheses around the expression,
1708 but that does not work on the 386 (either ATT or BSD assembler). */
1709 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1713 if (GET_MODE (x
) == VOIDmode
)
1715 /* We can use %o if the number is one word and positive. */
1716 gcc_assert (!CONST_DOUBLE_HIGH (x
));
1717 fprintf (file
, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x
));
1720 /* We can't handle floating point constants;
1721 PRINT_OPERAND must handle them. */
1722 output_operand_lossage ("floating constant misused");
1726 /* Some assemblers need integer constants to appear last (e.g. masm). */
1727 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
1729 output_addr_const_pdp11 (file
, XEXP (x
, 1));
1730 if (INTVAL (XEXP (x
, 0)) >= 0)
1731 fprintf (file
, "+");
1732 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1736 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1737 if (INTVAL (XEXP (x
, 1)) >= 0)
1738 fprintf (file
, "+");
1739 output_addr_const_pdp11 (file
, XEXP (x
, 1));
1744 /* Avoid outputting things like x-x or x+5-x,
1745 since some assemblers can't handle that. */
1746 x
= simplify_subtraction (x
);
1747 if (GET_CODE (x
) != MINUS
)
1750 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1751 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
1752 || INTVAL (XEXP (x
, 1)) >= 0)
1753 fprintf (file
, "-");
1754 output_addr_const_pdp11 (file
, XEXP (x
, 1));
1759 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1763 output_operand_lossage ("invalid expression as operand");
1767 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1770 pdp11_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
1772 /* Integers 32 bits and under, and scalar floats (if FPU), are returned
1773 in registers. The rest go into memory. */
1774 return (TYPE_MODE (type
) == DImode
1775 || (FLOAT_MODE_P (TYPE_MODE (type
)) && ! TARGET_AC0
)
1776 || TREE_CODE (type
) == VECTOR_TYPE
1777 || COMPLEX_MODE_P (TYPE_MODE (type
)));
1780 /* Worker function for TARGET_FUNCTION_VALUE.
1782 On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! ) */
1785 pdp11_function_value (const_tree valtype
,
1786 const_tree fntype_or_decl ATTRIBUTE_UNUSED
,
1787 bool outgoing ATTRIBUTE_UNUSED
)
1789 return gen_rtx_REG (TYPE_MODE (valtype
),
1790 BASE_RETURN_VALUE_REG(TYPE_MODE(valtype
)));
1793 /* Worker function for TARGET_LIBCALL_VALUE. */
1796 pdp11_libcall_value (enum machine_mode mode
,
1797 const_rtx fun ATTRIBUTE_UNUSED
)
1799 return gen_rtx_REG (mode
, BASE_RETURN_VALUE_REG(mode
));
1802 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1804 On the pdp, the first "output" reg is the only register thus used.
1806 maybe ac0 ? - as option someday! */
1809 pdp11_function_value_regno_p (const unsigned int regno
)
1811 return (regno
== RETVAL_REGNUM
) || (TARGET_AC0
&& (regno
== AC0_REGNUM
));
1814 /* Worker function for TARGET_TRAMPOLINE_INIT.
1816 trampoline - how should i do it in separate i+d ?
1817 have some allocate_trampoline magic???
1819 the following should work for shared I/D:
1821 MOV #STATIC, $4 01270Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
1822 JMP @#FUNCTION 000137 0x0000 <- FUNCTION
1826 pdp11_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
1828 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
1831 gcc_assert (!TARGET_SPLIT
);
1833 mem
= adjust_address (m_tramp
, HImode
, 0);
1834 emit_move_insn (mem
, GEN_INT (012700+STATIC_CHAIN_REGNUM
));
1835 mem
= adjust_address (m_tramp
, HImode
, 2);
1836 emit_move_insn (mem
, chain_value
);
1837 mem
= adjust_address (m_tramp
, HImode
, 4);
1838 emit_move_insn (mem
, GEN_INT (000137));
1839 emit_move_insn (mem
, fnaddr
);
1842 /* Worker function for TARGET_FUNCTION_ARG.
1844 Determine where to put an argument to a function.
1845 Value is zero to push the argument on the stack,
1846 or a hard register in which to store the argument.
1848 MODE is the argument's machine mode.
1849 TYPE is the data type of the argument (as a tree).
1850 This is null for libcalls where that information may
1852 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1853 the preceding args and about the function being called.
1854 NAMED is nonzero if this argument is a named parameter
1855 (otherwise it is an extra parameter matching an ellipsis). */
1858 pdp11_function_arg (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
1859 enum machine_mode mode ATTRIBUTE_UNUSED
,
1860 const_tree type ATTRIBUTE_UNUSED
,
1861 bool named ATTRIBUTE_UNUSED
)
1866 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
1868 Update the data in CUM to advance over an argument of mode MODE and
1869 data type TYPE. (TYPE is null for libcalls where that information
1870 may not be available.) */
1873 pdp11_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
1874 const_tree type
, bool named ATTRIBUTE_UNUSED
)
1876 *cum
+= (mode
!= BLKmode
1877 ? GET_MODE_SIZE (mode
)
1878 : int_size_in_bytes (type
));
1881 /* Make sure everything's fine if we *don't* have an FPU.
1882 This assumes that putting a register in fixed_regs will keep the
1883 compiler's mitts completely off it. We don't bother to zero it out
1884 of register classes. Also fix incompatible register naming with
1885 the UNIX assembler. */
1888 pdp11_conditional_register_usage (void)
1894 COPY_HARD_REG_SET (x
, reg_class_contents
[(int)FPU_REGS
]);
1895 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++ )
1896 if (TEST_HARD_REG_BIT (x
, i
))
1897 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1901 call_used_regs
[AC0_REGNUM
] = 1;
1902 if (TARGET_UNIX_ASM
)
1904 /* Change names of FPU registers for the UNIX assembler. */
1905 reg_names
[8] = "fr0";
1906 reg_names
[9] = "fr1";
1907 reg_names
[10] = "fr2";
1908 reg_names
[11] = "fr3";
1909 reg_names
[12] = "fr4";
1910 reg_names
[13] = "fr5";
1915 pdp11_function_section (tree decl ATTRIBUTE_UNUSED
,
1916 enum node_frequency freq ATTRIBUTE_UNUSED
,
1917 bool startup ATTRIBUTE_UNUSED
,
1918 bool exit ATTRIBUTE_UNUSED
)
1923 struct gcc_target targetm
= TARGET_INITIALIZER
;