1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994-2014 Free Software Foundation, Inc.
3 Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
27 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
32 #include "insn-attr.h"
36 #include "stor-layout.h"
40 #include "diagnostic-core.h"
43 #include "target-def.h"
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
=
86 const struct real_format pdp11_d_format
=
108 encode_pdp11_f (const struct real_format
*fmt ATTRIBUTE_UNUSED
, long *buf
,
109 const REAL_VALUE_TYPE
*r
)
111 (*vax_f_format
.encode
) (fmt
, buf
, r
);
112 buf
[0] = ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
116 decode_pdp11_f (const struct real_format
*fmt ATTRIBUTE_UNUSED
,
117 REAL_VALUE_TYPE
*r
, const long *buf
)
120 tbuf
= ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
121 (*vax_f_format
.decode
) (fmt
, r
, &tbuf
);
125 encode_pdp11_d (const struct real_format
*fmt ATTRIBUTE_UNUSED
, long *buf
,
126 const REAL_VALUE_TYPE
*r
)
128 (*vax_d_format
.encode
) (fmt
, buf
, r
);
129 buf
[0] = ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
130 buf
[1] = ((buf
[1] >> 16) & 0xffff) | ((buf
[1] & 0xffff) << 16);
134 decode_pdp11_d (const struct real_format
*fmt ATTRIBUTE_UNUSED
,
135 REAL_VALUE_TYPE
*r
, const long *buf
)
138 tbuf
[0] = ((buf
[0] >> 16) & 0xffff) | ((buf
[0] & 0xffff) << 16);
139 tbuf
[1] = ((buf
[1] >> 16) & 0xffff) | ((buf
[1] & 0xffff) << 16);
140 (*vax_d_format
.decode
) (fmt
, r
, tbuf
);
143 /* This is where the condition code register lives. */
144 /* rtx cc0_reg_rtx; - no longer needed? */
146 static const char *singlemove_string (rtx
*);
147 static bool pdp11_assemble_integer (rtx
, unsigned int, int);
148 static bool pdp11_rtx_costs (rtx
, int, int, int, int *, bool);
149 static bool pdp11_return_in_memory (const_tree
, const_tree
);
150 static rtx
pdp11_function_value (const_tree
, const_tree
, bool);
151 static rtx
pdp11_libcall_value (enum machine_mode
, const_rtx
);
152 static bool pdp11_function_value_regno_p (const unsigned int);
153 static void pdp11_trampoline_init (rtx
, tree
, rtx
);
154 static rtx
pdp11_function_arg (cumulative_args_t
, enum machine_mode
,
156 static void pdp11_function_arg_advance (cumulative_args_t
,
157 enum machine_mode
, const_tree
, bool);
158 static void pdp11_conditional_register_usage (void);
159 static bool pdp11_legitimate_constant_p (enum machine_mode
, rtx
);
161 /* Initialize the GCC target structure. */
162 #undef TARGET_ASM_BYTE_OP
163 #define TARGET_ASM_BYTE_OP NULL
164 #undef TARGET_ASM_ALIGNED_HI_OP
165 #define TARGET_ASM_ALIGNED_HI_OP NULL
166 #undef TARGET_ASM_ALIGNED_SI_OP
167 #define TARGET_ASM_ALIGNED_SI_OP NULL
168 #undef TARGET_ASM_INTEGER
169 #define TARGET_ASM_INTEGER pdp11_assemble_integer
171 #undef TARGET_ASM_OPEN_PAREN
172 #define TARGET_ASM_OPEN_PAREN "["
173 #undef TARGET_ASM_CLOSE_PAREN
174 #define TARGET_ASM_CLOSE_PAREN "]"
176 #undef TARGET_RTX_COSTS
177 #define TARGET_RTX_COSTS pdp11_rtx_costs
179 #undef TARGET_FUNCTION_ARG
180 #define TARGET_FUNCTION_ARG pdp11_function_arg
181 #undef TARGET_FUNCTION_ARG_ADVANCE
182 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
184 #undef TARGET_RETURN_IN_MEMORY
185 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
187 #undef TARGET_FUNCTION_VALUE
188 #define TARGET_FUNCTION_VALUE pdp11_function_value
189 #undef TARGET_LIBCALL_VALUE
190 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
191 #undef TARGET_FUNCTION_VALUE_REGNO_P
192 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
194 #undef TARGET_TRAMPOLINE_INIT
195 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
197 #undef TARGET_SECONDARY_RELOAD
198 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
200 #undef TARGET_REGISTER_MOVE_COST
201 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
203 #undef TARGET_PREFERRED_RELOAD_CLASS
204 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
206 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
207 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
209 #undef TARGET_LEGITIMATE_ADDRESS_P
210 #define TARGET_LEGITIMATE_ADDRESS_P pdp11_legitimate_address_p
212 #undef TARGET_CONDITIONAL_REGISTER_USAGE
213 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
215 #undef TARGET_ASM_FUNCTION_SECTION
216 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
218 #undef TARGET_PRINT_OPERAND
219 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
221 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
222 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
224 #undef TARGET_LEGITIMATE_CONSTANT_P
225 #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
227 /* A helper function to determine if REGNO should be saved in the
228 current function's stack frame. */
231 pdp11_saved_regno (unsigned regno
)
233 return !call_used_regs
[regno
] && df_regs_ever_live_p (regno
);
236 /* Expand the function prologue. */
239 pdp11_expand_prologue (void)
241 HOST_WIDE_INT fsize
= get_frame_size ();
243 rtx x
, via_ac
= NULL
;
245 /* If we are outputting code for main, the switch FPU to the
246 right mode if TARGET_FPU. */
247 if (MAIN_NAME_P (DECL_NAME (current_function_decl
)) && TARGET_FPU
)
249 emit_insn (gen_setd ());
250 emit_insn (gen_seti ());
253 if (frame_pointer_needed
)
255 x
= gen_rtx_PRE_DEC (Pmode
, stack_pointer_rtx
);
256 x
= gen_frame_mem (Pmode
, x
);
257 emit_move_insn (x
, hard_frame_pointer_rtx
);
259 emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
265 emit_insn (gen_addhi3 (stack_pointer_rtx
, stack_pointer_rtx
,
268 /* Prevent frame references via the frame pointer from being
269 scheduled before the frame is allocated. */
270 if (frame_pointer_needed
)
271 emit_insn (gen_blockage ());
274 /* Save CPU registers. */
275 for (regno
= R0_REGNUM
; regno
<= PC_REGNUM
; regno
++)
276 if (pdp11_saved_regno (regno
)
277 && (regno
!= HARD_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
))
279 x
= gen_rtx_PRE_DEC (Pmode
, stack_pointer_rtx
);
280 x
= gen_frame_mem (Pmode
, x
);
281 emit_move_insn (x
, gen_rtx_REG (Pmode
, regno
));
284 /* Save FPU registers. */
285 for (regno
= AC0_REGNUM
; regno
<= AC3_REGNUM
; regno
++)
286 if (pdp11_saved_regno (regno
))
288 x
= gen_rtx_PRE_DEC (Pmode
, stack_pointer_rtx
);
289 x
= gen_frame_mem (DFmode
, x
);
290 via_ac
= gen_rtx_REG (DFmode
, regno
);
291 emit_move_insn (x
, via_ac
);
294 /* ??? Maybe make ac4, ac5 call used regs?? */
295 for (regno
= AC4_REGNUM
; regno
<= AC5_REGNUM
; regno
++)
296 if (pdp11_saved_regno (regno
))
298 gcc_assert (via_ac
!= NULL
);
299 emit_move_insn (via_ac
, gen_rtx_REG (DFmode
, regno
));
301 x
= gen_rtx_PRE_DEC (Pmode
, stack_pointer_rtx
);
302 x
= gen_frame_mem (DFmode
, x
);
303 emit_move_insn (x
, via_ac
);
307 /* The function epilogue should not depend on the current stack pointer!
308 It should use the frame pointer only. This is mandatory because
309 of alloca; we also take advantage of it to omit stack adjustments
312 /* Maybe we can make leaf functions faster by switching to the
313 second register file - this way we don't have to save regs!
314 leaf functions are ~ 50% of all functions (dynamically!)
316 set/clear bit 11 (dec. 2048) of status word for switching register files -
317 but how can we do this? the pdp11/45 manual says bit may only
318 be set (p.24), but not cleared!
320 switching to kernel is probably more expensive, so we'll leave it
321 like this and not use the second set of registers...
323 maybe as option if you want to generate code for kernel mode? */
326 pdp11_expand_epilogue (void)
328 HOST_WIDE_INT fsize
= get_frame_size ();
330 rtx x
, reg
, via_ac
= NULL
;
332 if (pdp11_saved_regno (AC4_REGNUM
) || pdp11_saved_regno (AC5_REGNUM
))
334 /* Find a temporary with which to restore AC4/5. */
335 for (regno
= AC0_REGNUM
; regno
<= AC3_REGNUM
; regno
++)
336 if (pdp11_saved_regno (regno
))
338 via_ac
= gen_rtx_REG (DFmode
, regno
);
343 /* If possible, restore registers via pops. */
344 if (!frame_pointer_needed
|| crtl
->sp_is_unchanging
)
346 /* Restore registers via pops. */
348 for (regno
= AC5_REGNUM
; regno
>= AC0_REGNUM
; regno
--)
349 if (pdp11_saved_regno (regno
))
351 x
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
352 x
= gen_frame_mem (DFmode
, x
);
353 reg
= gen_rtx_REG (DFmode
, regno
);
355 if (LOAD_FPU_REG_P (regno
))
356 emit_move_insn (reg
, x
);
359 emit_move_insn (via_ac
, x
);
360 emit_move_insn (reg
, via_ac
);
364 for (regno
= PC_REGNUM
; regno
>= R0_REGNUM
+ 2; regno
--)
365 if (pdp11_saved_regno (regno
)
366 && (regno
!= HARD_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
))
368 x
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
369 x
= gen_frame_mem (Pmode
, x
);
370 emit_move_insn (gen_rtx_REG (Pmode
, regno
), x
);
375 /* Restore registers via moves. */
376 /* ??? If more than a few registers need to be restored, it's smaller
377 to generate a pointer through which we can emit pops. Consider
378 that moves cost 2*NREG words and pops cost NREG+3 words. This
379 means that the crossover is NREG=3.
381 Possible registers to use are:
382 (1) The first call-saved general register. This register will
383 be restored with the last pop.
384 (2) R1, if it's not used as a return register.
385 (3) FP itself. This option may result in +4 words, since we
386 may need two add imm,rn instructions instead of just one.
387 This also has the downside that we're not representing
388 the unwind info in any way, so during the epilogue the
389 debugger may get lost. */
391 HOST_WIDE_INT ofs
= -pdp11_sp_frame_offset ();
393 for (regno
= AC5_REGNUM
; regno
>= AC0_REGNUM
; regno
--)
394 if (pdp11_saved_regno (regno
))
396 x
= plus_constant (Pmode
, hard_frame_pointer_rtx
, ofs
);
397 x
= gen_frame_mem (DFmode
, x
);
398 reg
= gen_rtx_REG (DFmode
, regno
);
400 if (LOAD_FPU_REG_P (regno
))
401 emit_move_insn (reg
, x
);
404 emit_move_insn (via_ac
, x
);
405 emit_move_insn (reg
, via_ac
);
410 for (regno
= PC_REGNUM
; regno
>= R0_REGNUM
+ 2; regno
--)
411 if (pdp11_saved_regno (regno
)
412 && (regno
!= HARD_FRAME_POINTER_REGNUM
|| !frame_pointer_needed
))
414 x
= plus_constant (Pmode
, hard_frame_pointer_rtx
, ofs
);
415 x
= gen_frame_mem (Pmode
, x
);
416 emit_move_insn (gen_rtx_REG (Pmode
, regno
), x
);
421 /* Deallocate the stack frame. */
424 /* Prevent frame references via any pointer from being
425 scheduled after the frame is deallocated. */
426 emit_insn (gen_blockage ());
428 if (frame_pointer_needed
)
430 /* We can deallocate the frame with a single move. */
431 emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
);
434 emit_insn (gen_addhi3 (stack_pointer_rtx
, stack_pointer_rtx
,
438 if (frame_pointer_needed
)
440 x
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
441 x
= gen_frame_mem (Pmode
, x
);
442 emit_move_insn (hard_frame_pointer_rtx
, x
);
445 emit_jump_insn (gen_return ());
448 /* Return the best assembler insn template
449 for moving operands[1] into operands[0] as a fullword. */
451 singlemove_string (rtx
*operands
)
453 if (operands
[1] != const0_rtx
)
460 /* Expand multi-word operands (SImode or DImode) into the 2 or 4
461 corresponding HImode operands. The number of operands is given
462 as the third argument, and the required order of the parts as
463 the fourth argument. */
465 pdp11_expand_operands (rtx
*operands
, rtx exops
[][2], int opcount
,
466 pdp11_action
*action
, pdp11_partorder order
)
468 int words
, op
, w
, i
, sh
;
469 pdp11_partorder useorder
;
470 bool sameoff
= false;
471 enum { REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
} optype
;
475 words
= GET_MODE_BITSIZE (GET_MODE (operands
[0])) / 16;
477 /* If either piece order is accepted and one is pre-decrement
478 while the other is post-increment, set order to be high order
479 word first. That will force the pre-decrement to be turned
480 into a pointer adjust, then offset addressing.
481 Otherwise, if either operand uses pre-decrement, that means
482 the order is low order first.
483 Otherwise, if both operands are registers and destination is
484 higher than source and they overlap, do low order word (highest
485 register number) first. */
489 if (!REG_P (operands
[0]) && !REG_P (operands
[1]) &&
490 !(CONSTANT_P (operands
[1]) ||
491 GET_CODE (operands
[1]) == CONST_DOUBLE
) &&
492 ((GET_CODE (XEXP (operands
[0], 0)) == POST_INC
&&
493 GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
) ||
494 (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
&&
495 GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)))
497 else if ((!REG_P (operands
[0]) &&
498 GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
) ||
499 (!REG_P (operands
[1]) &&
500 !(CONSTANT_P (operands
[1]) ||
501 GET_CODE (operands
[1]) == CONST_DOUBLE
) &&
502 GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
))
504 else if (REG_P (operands
[0]) && REG_P (operands
[1]) &&
505 REGNO (operands
[0]) > REGNO (operands
[1]) &&
506 REGNO (operands
[0]) < REGNO (operands
[1]) + words
)
509 /* Check for source == offset from register and dest == push of
510 the same register. In that case, we have to use the same
511 offset (the one for the low order word) for all words, because
512 the push increases the offset to each source word.
513 In theory there are other cases like this, for example dest == pop,
514 but those don't occur in real life so ignore those. */
515 if (GET_CODE (operands
[0]) == MEM
516 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
517 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
518 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
522 /* If the caller didn't specify order, use the one we computed,
523 or high word first if we don't care either. If the caller did
524 specify, verify we don't have a problem with that order.
525 (If it matters to the caller, constraints need to be used to
526 ensure this case doesn't occur). */
528 order
= (useorder
== either
) ? big
: useorder
;
530 gcc_assert (useorder
== either
|| useorder
== order
);
533 for (op
= 0; op
< opcount
; op
++)
535 /* First classify the operand. */
536 if (REG_P (operands
[op
]))
538 else if (CONSTANT_P (operands
[op
])
539 || GET_CODE (operands
[op
]) == CONST_DOUBLE
)
541 else if (GET_CODE (XEXP (operands
[op
], 0)) == POST_INC
)
543 else if (GET_CODE (XEXP (operands
[op
], 0)) == PRE_DEC
)
545 else if (!reload_in_progress
|| offsettable_memref_p (operands
[op
]))
547 else if (GET_CODE (operands
[op
]) == MEM
)
552 /* Check for the cases that the operand constraints are not
553 supposed to allow to happen. Return failure for such cases. */
558 action
[op
] = no_action
;
560 /* If the operand uses pre-decrement addressing but we
561 want to get the parts high order first,
562 decrement the former register explicitly
563 and change the operand into ordinary indexing. */
564 if (optype
== PUSHOP
&& order
== big
)
566 gcc_assert (action
!= NULL
);
567 action
[op
] = dec_before
;
568 operands
[op
] = gen_rtx_MEM (GET_MODE (operands
[op
]),
569 XEXP (XEXP (operands
[op
], 0), 0));
572 /* If the operand uses post-increment mode but we want
573 to get the parts low order first, change the operand
574 into ordinary indexing and remember to increment
575 the register explicitly when we're done. */
576 else if (optype
== POPOP
&& order
== little
)
578 gcc_assert (action
!= NULL
);
579 action
[op
] = inc_after
;
580 operands
[op
] = gen_rtx_MEM (GET_MODE (operands
[op
]),
581 XEXP (XEXP (operands
[op
], 0), 0));
585 if (GET_CODE (operands
[op
]) == CONST_DOUBLE
)
587 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[op
]);
588 REAL_VALUE_TO_TARGET_DOUBLE (r
, sval
);
591 for (i
= 0; i
< words
; i
++)
600 /* Set the output operand to be word "w" of the input. */
602 exops
[i
][op
] = gen_rtx_REG (HImode
, REGNO (operands
[op
]) + w
);
603 else if (optype
== OFFSOP
)
604 exops
[i
][op
] = adjust_address (operands
[op
], HImode
, w
* 2);
605 else if (optype
== CNSTOP
)
607 if (GET_CODE (operands
[op
]) == CONST_DOUBLE
)
609 sh
= 16 - (w
& 1) * 16;
610 exops
[i
][op
] = gen_rtx_CONST_INT (HImode
, (sval
[w
/ 2] >> sh
) & 0xffff);
614 sh
= ((words
- 1 - w
) * 16);
615 exops
[i
][op
] = gen_rtx_CONST_INT (HImode
, trunc_int_for_mode (INTVAL(operands
[op
]) >> sh
, HImode
));
619 exops
[i
][op
] = operands
[op
];
625 /* Output assembler code to perform a multiple-word move insn
626 with operands OPERANDS. This moves 2 or 4 words depending
627 on the machine mode of the operands. */
630 output_move_multiple (rtx
*operands
)
633 pdp11_action action
[2];
636 words
= GET_MODE_BITSIZE (GET_MODE (operands
[0])) / 16;
638 pdp11_expand_operands (operands
, exops
, 2, action
, either
);
640 /* Check for explicit decrement before. */
641 if (action
[0] == dec_before
)
643 operands
[0] = XEXP (operands
[0], 0);
644 output_asm_insn ("sub $4,%0", operands
);
646 if (action
[1] == dec_before
)
648 operands
[1] = XEXP (operands
[1], 0);
649 output_asm_insn ("sub $4,%1", operands
);
653 for (i
= 0; i
< words
; i
++)
654 output_asm_insn (singlemove_string (exops
[i
]), exops
[i
]);
656 /* Check for increment after. */
657 if (action
[0] == inc_after
)
659 operands
[0] = XEXP (operands
[0], 0);
660 output_asm_insn ("add $4,%0", operands
);
662 if (action
[1] == inc_after
)
664 operands
[1] = XEXP (operands
[1], 0);
665 output_asm_insn ("add $4,%1", operands
);
671 /* Output an ascii string. */
673 output_ascii (FILE *file
, const char *p
, int size
)
677 /* This used to output .byte "string", which doesn't work with the UNIX
678 assembler and I think not with DEC ones either. */
679 fprintf (file
, "\t.byte ");
681 for (i
= 0; i
< size
; i
++)
683 register int c
= p
[i
];
686 fprintf (file
, "%#o", c
);
695 pdp11_asm_output_var (FILE *file
, const char *name
, int size
,
696 int align
, bool global
)
699 fprintf (file
, "\n\t.even\n");
702 fprintf (file
, ".globl ");
703 assemble_name (file
, name
);
705 fprintf (file
, "\n");
706 assemble_name (file
, name
);
707 fprintf (file
, ": .=.+ %#ho\n", (unsigned short)size
);
711 pdp11_asm_print_operand (FILE *file
, rtx x
, int code
)
718 else if (code
== '@')
725 else if (GET_CODE (x
) == REG
)
726 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
727 else if (GET_CODE (x
) == MEM
)
728 output_address (XEXP (x
, 0));
729 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) != SImode
)
731 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
732 REAL_VALUE_TO_TARGET_DOUBLE (r
, sval
);
733 fprintf (file
, "$%#lo", sval
[0] >> 16);
738 output_addr_const_pdp11 (file
, x
);
743 pdp11_asm_print_operand_punct_valid_p (unsigned char c
)
745 return (c
== '#' || c
== '@');
749 print_operand_address (FILE *file
, register rtx addr
)
757 switch (GET_CODE (addr
))
764 addr
= XEXP (addr
, 0);
769 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
774 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
779 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
785 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0))
786 || GET_CODE (XEXP (addr
, 0)) == MEM
)
788 offset
= XEXP (addr
, 0);
789 addr
= XEXP (addr
, 1);
791 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1))
792 || GET_CODE (XEXP (addr
, 1)) == MEM
)
794 offset
= XEXP (addr
, 1);
795 addr
= XEXP (addr
, 0);
797 if (GET_CODE (addr
) != PLUS
)
799 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
801 breg
= XEXP (addr
, 0);
802 addr
= XEXP (addr
, 1);
804 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
806 breg
= XEXP (addr
, 1);
807 addr
= XEXP (addr
, 0);
809 if (GET_CODE (addr
) == REG
)
811 gcc_assert (breg
== 0);
817 gcc_assert (addr
== 0);
821 output_addr_const_pdp11 (file
, addr
);
824 gcc_assert (GET_CODE (breg
) == REG
);
825 fprintf (file
, "(%s)", reg_names
[REGNO (breg
)]);
830 if (!again
&& GET_CODE (addr
) == CONST_INT
)
832 /* Absolute (integer number) address. */
833 if (!TARGET_UNIX_ASM
)
834 fprintf (file
, "@$");
836 output_addr_const_pdp11 (file
, addr
);
840 /* Target hook to assemble integer objects. We need to use the
841 pdp-specific version of output_addr_const. */
844 pdp11_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
850 fprintf (asm_out_file
, "\t.byte\t");
851 output_addr_const_pdp11 (asm_out_file
, GEN_INT (INTVAL (x
) & 0xff));
853 fprintf (asm_out_file
, " /* char */\n");
857 fprintf (asm_out_file
, TARGET_UNIX_ASM
? "\t" : "\t.word\t");
858 output_addr_const_pdp11 (asm_out_file
, x
);
859 fprintf (asm_out_file
, " /* short */\n");
862 return default_assemble_integer (x
, size
, aligned_p
);
866 /* register move costs, indexed by regs */
868 static const int move_costs
[N_REG_CLASSES
][N_REG_CLASSES
] =
870 /* NO MUL GEN LFPU NLFPU FPU ALL */
872 /* NO */ { 0, 0, 0, 0, 0, 0, 0},
873 /* MUL */ { 0, 2, 2, 22, 22, 22, 22},
874 /* GEN */ { 0, 2, 2, 22, 22, 22, 22},
875 /* LFPU */ { 0, 22, 22, 2, 2, 2, 22},
876 /* NLFPU */ { 0, 22, 22, 2, 10, 10, 22},
877 /* FPU */ { 0, 22, 22, 2, 10, 10, 22},
878 /* ALL */ { 0, 22, 22, 22, 22, 22, 22}
882 /* -- note that some moves are tremendously expensive,
883 because they require lots of tricks! do we have to
884 charge the costs incurred by secondary reload class
885 -- as we do here with 10 -- or not ? */
888 pdp11_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED
,
889 reg_class_t c1
, reg_class_t c2
)
891 return move_costs
[(int)c1
][(int)c2
];
895 pdp11_rtx_costs (rtx x
, int code
, int outer_code ATTRIBUTE_UNUSED
,
896 int opno ATTRIBUTE_UNUSED
, int *total
,
897 bool speed ATTRIBUTE_UNUSED
)
902 if (INTVAL (x
) == 0 || INTVAL (x
) == -1 || INTVAL (x
) == 1)
912 /* Twice as expensive as REG. */
917 /* Twice (or 4 times) as expensive as 16 bit. */
922 /* ??? There is something wrong in MULT because MULT is not
923 as cheap as total = 2 even if we can shift! */
924 /* If optimizing for size make mult etc cheap, but not 1, so when
925 in doubt the faster insn is chosen. */
927 *total
= COSTS_N_INSNS (2);
929 *total
= COSTS_N_INSNS (11);
934 *total
= COSTS_N_INSNS (2);
936 *total
= COSTS_N_INSNS (25);
941 *total
= COSTS_N_INSNS (2);
943 *total
= COSTS_N_INSNS (26);
947 /* Equivalent to length, so same for optimize_size. */
948 *total
= COSTS_N_INSNS (3);
952 /* Only used for qi->hi. */
953 *total
= COSTS_N_INSNS (1);
957 if (GET_MODE (x
) == HImode
)
958 *total
= COSTS_N_INSNS (1);
959 else if (GET_MODE (x
) == SImode
)
960 *total
= COSTS_N_INSNS (6);
962 *total
= COSTS_N_INSNS (2);
969 *total
= COSTS_N_INSNS (1);
970 else if (GET_MODE (x
) == QImode
)
972 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
973 *total
= COSTS_N_INSNS (8); /* worst case */
975 *total
= COSTS_N_INSNS (INTVAL (XEXP (x
, 1)));
977 else if (GET_MODE (x
) == HImode
)
979 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
981 if (abs (INTVAL (XEXP (x
, 1))) == 1)
982 *total
= COSTS_N_INSNS (1);
984 *total
= COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x
, 1)));
987 *total
= COSTS_N_INSNS (10); /* worst case */
989 else if (GET_MODE (x
) == SImode
)
991 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
992 *total
= COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x
, 1)));
993 else /* worst case */
994 *total
= COSTS_N_INSNS (18);
1004 output_jump (enum rtx_code code
, int inv
, int length
)
1008 static char buf
[1000];
1009 const char *pos
, *neg
;
1011 if (cc_prev_status
.flags
& CC_NO_OVERFLOW
)
1015 case GTU
: code
= GT
; break;
1016 case LTU
: code
= LT
; break;
1017 case GEU
: code
= GE
; break;
1018 case LEU
: code
= LE
; break;
1024 case EQ
: pos
= "beq", neg
= "bne"; break;
1025 case NE
: pos
= "bne", neg
= "beq"; break;
1026 case GT
: pos
= "bgt", neg
= "ble"; break;
1027 case GTU
: pos
= "bhi", neg
= "blos"; break;
1028 case LT
: pos
= "blt", neg
= "bge"; break;
1029 case LTU
: pos
= "blo", neg
= "bhis"; break;
1030 case GE
: pos
= "bge", neg
= "blt"; break;
1031 case GEU
: pos
= "bhis", neg
= "blo"; break;
1032 case LE
: pos
= "ble", neg
= "bgt"; break;
1033 case LEU
: pos
= "blos", neg
= "bhi"; break;
1034 default: gcc_unreachable ();
1038 /* currently we don't need this, because the tstdf and cmpdf
1039 copy the condition code immediately, and other float operations are not
1040 yet recognized as changing the FCC - if so, then the length-cost of all
1041 jump insns increases by one, because we have to potentially copy the
1043 if (cc_status
.flags
& CC_IN_FPU
)
1044 output_asm_insn("cfcc", NULL
);
1051 sprintf(buf
, "%s %%l1", inv
? neg
: pos
);
1057 sprintf(buf
, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv
? pos
: neg
, x
, x
);
1071 notice_update_cc_on_set(rtx exp
, rtx insn ATTRIBUTE_UNUSED
)
1073 if (GET_CODE (SET_DEST (exp
)) == CC0
)
1075 cc_status
.flags
= 0;
1076 cc_status
.value1
= SET_DEST (exp
);
1077 cc_status
.value2
= SET_SRC (exp
);
1079 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
1083 else if (SET_DEST(exp
) == pc_rtx
)
1087 else if (GET_MODE (SET_DEST(exp
)) == HImode
1088 || GET_MODE (SET_DEST(exp
)) == QImode
)
1090 cc_status
.flags
= GET_CODE (SET_SRC(exp
)) == MINUS
? 0 : CC_NO_OVERFLOW
;
1091 cc_status
.value1
= SET_SRC (exp
);
1092 cc_status
.value2
= SET_DEST (exp
);
1094 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
1096 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
1097 cc_status
.value2
= 0;
1098 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == MEM
1100 && GET_CODE (cc_status
.value2
) == MEM
)
1101 cc_status
.value2
= 0;
1111 simple_memory_operand(rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1115 /* Eliminate non-memory operations */
1116 if (GET_CODE (op
) != MEM
)
1120 /* dword operations really put out 2 instructions, so eliminate them. */
1121 if (GET_MODE_SIZE (GET_MODE (op
)) > (HAVE_64BIT_P () ? 8 : 4))
1125 /* Decode the address now. */
1129 addr
= XEXP (op
, 0);
1131 switch (GET_CODE (addr
))
1134 /* (R0) - no extra cost */
1139 /* -(R0), (R0)+ - cheap! */
1143 /* cheap - is encoded in addressing mode info!
1145 -- except for @(R0), which has to be @0(R0) !!! */
1147 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1157 /* @#address - extra cost */
1161 /* X(R0) - extra cost */
1173 * output a block move:
1175 * operands[0] ... to
1176 * operands[1] ... from
1177 * operands[2] ... length
1178 * operands[3] ... alignment
1179 * operands[4] ... scratch register
1184 output_block_move(rtx
*operands
)
1186 static int count
= 0;
1191 /* Move of zero bytes is a NOP. */
1192 if (operands
[2] == const0_rtx
)
1195 /* Look for moves by small constant byte counts, those we'll
1196 expand to straight line code. */
1197 if (CONSTANT_P (operands
[2]))
1199 if (INTVAL (operands
[2]) < 16
1200 && (!optimize_size
|| INTVAL (operands
[2]) < 5)
1201 && INTVAL (operands
[3]) == 1)
1205 for (i
= 1; i
<= INTVAL (operands
[2]); i
++)
1206 output_asm_insn("movb (%1)+, (%0)+", operands
);
1210 else if (INTVAL(operands
[2]) < 32
1211 && (!optimize_size
|| INTVAL (operands
[2]) < 9)
1212 && INTVAL (operands
[3]) >= 2)
1216 for (i
= 1; i
<= INTVAL (operands
[2]) / 2; i
++)
1217 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1218 if (INTVAL (operands
[2]) & 1)
1219 output_asm_insn ("movb (%1), (%0)", operands
);
1225 /* Ideally we'd look for moves that are multiples of 4 or 8
1226 bytes and handle those by unrolling the move loop. That
1227 makes for a lot of code if done at run time, but it's ok
1228 for constant counts. Also, for variable counts we have
1229 to worry about odd byte count with even aligned pointers.
1230 On 11/40 and up we handle that case; on older machines
1231 we don't and just use byte-wise moves all the time. */
1233 if (CONSTANT_P (operands
[2]) )
1235 if (INTVAL (operands
[3]) < 2)
1239 lastbyte
= INTVAL (operands
[2]) & 1;
1241 if (optimize_size
|| INTVAL (operands
[2]) & 2)
1243 else if (INTVAL (operands
[2]) & 4)
1249 /* Loop count is byte count scaled by unroll. */
1250 operands
[2] = GEN_INT (INTVAL (operands
[2]) >> unroll
);
1251 output_asm_insn ("mov %2, %4", operands
);
1255 /* Variable byte count; use the input register
1257 operands
[4] = operands
[2];
1259 /* Decide whether to move by words, and check
1260 the byte count for zero. */
1261 if (TARGET_40_PLUS
&& INTVAL (operands
[3]) > 1)
1264 output_asm_insn ("asr %4", operands
);
1269 output_asm_insn ("tst %4", operands
);
1271 sprintf (buf
, "beq movestrhi%d", count
+ 1);
1272 output_asm_insn (buf
, NULL
);
1275 /* Output the loop label. */
1276 sprintf (buf
, "\nmovestrhi%d:", count
);
1277 output_asm_insn (buf
, NULL
);
1279 /* Output the appropriate move instructions. */
1283 output_asm_insn ("movb (%1)+, (%0)+", operands
);
1287 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1291 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1292 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1296 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1297 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1298 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1299 output_asm_insn ("mov (%1)+, (%0)+", operands
);
1303 /* Output the decrement and test. */
1306 sprintf (buf
, "sob %%4, movestrhi%d", count
);
1307 output_asm_insn (buf
, operands
);
1311 output_asm_insn ("dec %4", operands
);
1312 sprintf (buf
, "bgt movestrhi%d", count
);
1313 output_asm_insn (buf
, NULL
);
1317 /* If constant odd byte count, move the last byte. */
1319 output_asm_insn ("movb (%1), (%0)", operands
);
1320 else if (!CONSTANT_P (operands
[2]))
1322 /* Output the destination label for the zero byte count check. */
1323 sprintf (buf
, "\nmovestrhi%d:", count
);
1324 output_asm_insn (buf
, NULL
);
1327 /* If we did word moves, check for trailing last byte. */
1330 sprintf (buf
, "bcc movestrhi%d", count
);
1331 output_asm_insn (buf
, NULL
);
1332 output_asm_insn ("movb (%1), (%0)", operands
);
1333 sprintf (buf
, "\nmovestrhi%d:", count
);
1334 output_asm_insn (buf
, NULL
);
1342 /* This function checks whether a real value can be encoded as
1343 a literal, i.e., addressing mode 27. In that mode, real values
1344 are one word values, so the remaining 48 bits have to be zero. */
1346 legitimate_const_double_p (rtx address
)
1350 REAL_VALUE_FROM_CONST_DOUBLE (r
, address
);
1351 REAL_VALUE_TO_TARGET_DOUBLE (r
, sval
);
1352 if ((sval
[0] & 0xffff) == 0 && sval
[1] == 0)
1357 /* Implement CANNOT_CHANGE_MODE_CLASS. */
1359 pdp11_cannot_change_mode_class (enum machine_mode from
,
1360 enum machine_mode to
,
1361 enum reg_class rclass
)
1363 /* Also, FPU registers contain a whole float value and the parts of
1364 it are not separately accessible.
1366 So we disallow all mode changes involving FPRs. */
1367 if (FLOAT_MODE_P (from
) != FLOAT_MODE_P (to
))
1370 return reg_classes_intersect_p (FPU_REGS
, rclass
);
1373 /* TARGET_PREFERRED_RELOAD_CLASS
1375 Given an rtx X being reloaded into a reg required to be
1376 in class CLASS, return the class of reg to actually use.
1377 In general this is just CLASS; but on some machines
1378 in some cases it is preferable to use a more restrictive class.
1380 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1383 pdp11_preferred_reload_class (rtx x
, reg_class_t rclass
)
1385 if (rclass
== FPU_REGS
)
1386 return LOAD_FPU_REGS
;
1387 if (rclass
== ALL_REGS
)
1389 if (FLOAT_MODE_P (GET_MODE (x
)))
1390 return LOAD_FPU_REGS
;
1392 return GENERAL_REGS
;
1397 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1399 Given an rtx X being reloaded into a reg required to be
1400 in class CLASS, return the class of reg to actually use.
1401 In general this is just CLASS; but on some machines
1402 in some cases it is preferable to use a more restrictive class.
1404 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1407 pdp11_preferred_output_reload_class (rtx x
, reg_class_t rclass
)
1409 if (rclass
== FPU_REGS
)
1410 return LOAD_FPU_REGS
;
1411 if (rclass
== ALL_REGS
)
1413 if (FLOAT_MODE_P (GET_MODE (x
)))
1414 return LOAD_FPU_REGS
;
1416 return GENERAL_REGS
;
1422 /* TARGET_SECONDARY_RELOAD.
1424 FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1425 intermediate register (AC0-AC3: LOAD_FPU_REGS). Everything else
1426 can be loade/stored directly. */
1428 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED
,
1430 reg_class_t reload_class
,
1431 enum machine_mode reload_mode ATTRIBUTE_UNUSED
,
1432 secondary_reload_info
*sri ATTRIBUTE_UNUSED
)
1434 if (reload_class
!= NO_LOAD_FPU_REGS
|| GET_CODE (x
) != REG
||
1435 REGNO_REG_CLASS (REGNO (x
)) == LOAD_FPU_REGS
)
1438 return LOAD_FPU_REGS
;
1441 /* Target routine to check if register to register move requires memory.
1443 The answer is yes if we're going between general register and FPU
1444 registers. The mode doesn't matter in making this check.
1447 pdp11_secondary_memory_needed (reg_class_t c1
, reg_class_t c2
,
1448 enum machine_mode mode ATTRIBUTE_UNUSED
)
1450 int fromfloat
= (c1
== LOAD_FPU_REGS
|| c1
== NO_LOAD_FPU_REGS
||
1452 int tofloat
= (c2
== LOAD_FPU_REGS
|| c2
== NO_LOAD_FPU_REGS
||
1455 return (fromfloat
!= tofloat
);
1458 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
1459 that is a valid memory address for an instruction.
1460 The MODE argument is the machine mode for the MEM expression
1461 that wants to use this address.
1466 pdp11_legitimate_address_p (enum machine_mode mode
,
1467 rtx operand
, bool strict
)
1471 /* accept @#address */
1472 if (CONSTANT_ADDRESS_P (operand
))
1475 switch (GET_CODE (operand
))
1479 return !strict
|| REGNO_OK_FOR_BASE_P (REGNO (operand
));
1483 return GET_CODE (XEXP (operand
, 0)) == REG
1484 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand
, 0))))
1485 && CONSTANT_ADDRESS_P (XEXP (operand
, 1));
1489 return GET_CODE (XEXP (operand
, 0)) == REG
1490 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand
, 0))));
1494 return GET_CODE (XEXP (operand
, 0)) == REG
1495 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand
, 0))));
1498 /* accept -(SP) -- which uses PRE_MODIFY for byte mode */
1499 return GET_CODE (XEXP (operand
, 0)) == REG
1500 && REGNO (XEXP (operand
, 0)) == STACK_POINTER_REGNUM
1501 && GET_CODE ((xfoob
= XEXP (operand
, 1))) == PLUS
1502 && GET_CODE (XEXP (xfoob
, 0)) == REG
1503 && REGNO (XEXP (xfoob
, 0)) == STACK_POINTER_REGNUM
1504 && CONSTANT_P (XEXP (xfoob
, 1))
1505 && INTVAL (XEXP (xfoob
,1)) == -2;
1508 /* accept (SP)+ -- which uses POST_MODIFY for byte mode */
1509 return GET_CODE (XEXP (operand
, 0)) == REG
1510 && REGNO (XEXP (operand
, 0)) == STACK_POINTER_REGNUM
1511 && GET_CODE ((xfoob
= XEXP (operand
, 1))) == PLUS
1512 && GET_CODE (XEXP (xfoob
, 0)) == REG
1513 && REGNO (XEXP (xfoob
, 0)) == STACK_POINTER_REGNUM
1514 && CONSTANT_P (XEXP (xfoob
, 1))
1515 && INTVAL (XEXP (xfoob
,1)) == 2;
1518 /* handle another level of indirection ! */
1519 xfoob
= XEXP (operand
, 0);
1521 /* (MEM:xx (MEM:xx ())) is not valid for SI, DI and currently
1522 also forbidden for float, because we have to handle this
1523 in output_move_double and/or output_move_quad() - we could
1524 do it, but currently it's not worth it!!!
1525 now that DFmode cannot go into CPU register file,
1526 maybe I should allow float ...
1527 but then I have to handle memory-to-memory moves in movdf ?? */
1528 if (GET_MODE_BITSIZE(mode
) > 16)
1531 /* accept @address */
1532 if (CONSTANT_ADDRESS_P (xfoob
))
1535 switch (GET_CODE (xfoob
))
1538 /* accept @(R0) - which is @0(R0) */
1539 return !strict
|| REGNO_OK_FOR_BASE_P(REGNO (xfoob
));
1543 return GET_CODE (XEXP (xfoob
, 0)) == REG
1544 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob
, 0))))
1545 && CONSTANT_ADDRESS_P (XEXP (xfoob
, 1));
1549 return GET_CODE (XEXP (xfoob
, 0)) == REG
1550 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob
, 0))));
1554 return GET_CODE (XEXP (xfoob
, 0)) == REG
1555 && (!strict
|| REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob
, 0))));
1558 /* anything else is invalid */
1563 /* anything else is invalid */
1568 /* Return the class number of the smallest class containing
1569 reg number REGNO. */
1571 pdp11_regno_reg_class (int regno
)
1573 if (regno
== FRAME_POINTER_REGNUM
|| regno
== ARG_POINTER_REGNUM
)
1574 return GENERAL_REGS
;
1575 else if (regno
> AC3_REGNUM
)
1576 return NO_LOAD_FPU_REGS
;
1577 else if (regno
>= AC0_REGNUM
)
1578 return LOAD_FPU_REGS
;
1582 return GENERAL_REGS
;
1587 pdp11_sp_frame_offset (void)
1589 int offset
= 0, regno
;
1590 offset
= get_frame_size();
1591 for (regno
= 0; regno
<= PC_REGNUM
; regno
++)
1592 if (pdp11_saved_regno (regno
))
1594 for (regno
= AC0_REGNUM
; regno
<= AC5_REGNUM
; regno
++)
1595 if (pdp11_saved_regno (regno
))
1601 /* Return the offset between two registers, one to be eliminated, and the other
1602 its replacement, at the start of a routine. */
1605 pdp11_initial_elimination_offset (int from
, int to
)
1609 if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
1611 else if (from
== FRAME_POINTER_REGNUM
1612 && to
== HARD_FRAME_POINTER_REGNUM
)
1616 gcc_assert (to
== STACK_POINTER_REGNUM
);
1618 /* Get the size of the register save area. */
1619 spoff
= pdp11_sp_frame_offset ();
1620 if (from
== FRAME_POINTER_REGNUM
)
1623 gcc_assert (from
== ARG_POINTER_REGNUM
);
1625 /* If there is a frame pointer, that is saved too. */
1626 if (frame_pointer_needed
)
1629 /* Account for the saved PC in the function call. */
1634 /* A copy of output_addr_const modified for pdp11 expression syntax.
1635 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1636 use, and for debugging output, which we don't support with this port either.
1637 So this copy should get called whenever needed.
1640 output_addr_const_pdp11 (FILE *file
, rtx x
)
1646 switch (GET_CODE (x
))
1649 gcc_assert (flag_pic
);
1654 assemble_name (file
, XSTR (x
, 0));
1658 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
1659 assemble_name (file
, buf
);
1663 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
1664 assemble_name (file
, buf
);
1672 fprintf (file
, "-");
1674 fprintf (file
, "%#o", i
& 0xffff);
1678 /* This used to output parentheses around the expression,
1679 but that does not work on the 386 (either ATT or BSD assembler). */
1680 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1684 if (GET_MODE (x
) == VOIDmode
)
1686 /* We can use %o if the number is one word and positive. */
1687 gcc_assert (!CONST_DOUBLE_HIGH (x
));
1688 fprintf (file
, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x
));
1691 /* We can't handle floating point constants;
1692 PRINT_OPERAND must handle them. */
1693 output_operand_lossage ("floating constant misused");
1697 /* Some assemblers need integer constants to appear last (e.g. masm). */
1698 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
1700 output_addr_const_pdp11 (file
, XEXP (x
, 1));
1701 if (INTVAL (XEXP (x
, 0)) >= 0)
1702 fprintf (file
, "+");
1703 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1707 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1708 if (INTVAL (XEXP (x
, 1)) >= 0)
1709 fprintf (file
, "+");
1710 output_addr_const_pdp11 (file
, XEXP (x
, 1));
1715 /* Avoid outputting things like x-x or x+5-x,
1716 since some assemblers can't handle that. */
1717 x
= simplify_subtraction (x
);
1718 if (GET_CODE (x
) != MINUS
)
1721 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1722 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
1723 || INTVAL (XEXP (x
, 1)) >= 0)
1724 fprintf (file
, "-");
1725 output_addr_const_pdp11 (file
, XEXP (x
, 1));
1730 output_addr_const_pdp11 (file
, XEXP (x
, 0));
1734 output_operand_lossage ("invalid expression as operand");
1738 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1741 pdp11_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
1743 /* Integers 32 bits and under, and scalar floats (if FPU), are returned
1744 in registers. The rest go into memory. */
1745 return (TYPE_MODE (type
) == DImode
1746 || (FLOAT_MODE_P (TYPE_MODE (type
)) && ! TARGET_AC0
)
1747 || TREE_CODE (type
) == VECTOR_TYPE
1748 || COMPLEX_MODE_P (TYPE_MODE (type
)));
1751 /* Worker function for TARGET_FUNCTION_VALUE.
1753 On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! ) */
1756 pdp11_function_value (const_tree valtype
,
1757 const_tree fntype_or_decl ATTRIBUTE_UNUSED
,
1758 bool outgoing ATTRIBUTE_UNUSED
)
1760 return gen_rtx_REG (TYPE_MODE (valtype
),
1761 BASE_RETURN_VALUE_REG(TYPE_MODE(valtype
)));
1764 /* Worker function for TARGET_LIBCALL_VALUE. */
1767 pdp11_libcall_value (enum machine_mode mode
,
1768 const_rtx fun ATTRIBUTE_UNUSED
)
1770 return gen_rtx_REG (mode
, BASE_RETURN_VALUE_REG(mode
));
1773 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1775 On the pdp, the first "output" reg is the only register thus used.
1777 maybe ac0 ? - as option someday! */
1780 pdp11_function_value_regno_p (const unsigned int regno
)
1782 return (regno
== RETVAL_REGNUM
) || (TARGET_AC0
&& (regno
== AC0_REGNUM
));
1785 /* Worker function for TARGET_TRAMPOLINE_INIT.
1787 trampoline - how should i do it in separate i+d ?
1788 have some allocate_trampoline magic???
1790 the following should work for shared I/D:
1792 MOV #STATIC, $4 01270Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
1793 JMP @#FUNCTION 000137 0x0000 <- FUNCTION
1797 pdp11_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
1799 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
1802 gcc_assert (!TARGET_SPLIT
);
1804 mem
= adjust_address (m_tramp
, HImode
, 0);
1805 emit_move_insn (mem
, GEN_INT (012700+STATIC_CHAIN_REGNUM
));
1806 mem
= adjust_address (m_tramp
, HImode
, 2);
1807 emit_move_insn (mem
, chain_value
);
1808 mem
= adjust_address (m_tramp
, HImode
, 4);
1809 emit_move_insn (mem
, GEN_INT (000137));
1810 emit_move_insn (mem
, fnaddr
);
1813 /* Worker function for TARGET_FUNCTION_ARG.
1815 Determine where to put an argument to a function.
1816 Value is zero to push the argument on the stack,
1817 or a hard register in which to store the argument.
1819 MODE is the argument's machine mode.
1820 TYPE is the data type of the argument (as a tree).
1821 This is null for libcalls where that information may
1823 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1824 the preceding args and about the function being called.
1825 NAMED is nonzero if this argument is a named parameter
1826 (otherwise it is an extra parameter matching an ellipsis). */
1829 pdp11_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED
,
1830 enum machine_mode mode ATTRIBUTE_UNUSED
,
1831 const_tree type ATTRIBUTE_UNUSED
,
1832 bool named ATTRIBUTE_UNUSED
)
1837 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
1839 Update the data in CUM to advance over an argument of mode MODE and
1840 data type TYPE. (TYPE is null for libcalls where that information
1841 may not be available.) */
1844 pdp11_function_arg_advance (cumulative_args_t cum_v
, enum machine_mode mode
,
1845 const_tree type
, bool named ATTRIBUTE_UNUSED
)
1847 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1849 *cum
+= (mode
!= BLKmode
1850 ? GET_MODE_SIZE (mode
)
1851 : int_size_in_bytes (type
));
1854 /* Make sure everything's fine if we *don't* have an FPU.
1855 This assumes that putting a register in fixed_regs will keep the
1856 compiler's mitts completely off it. We don't bother to zero it out
1857 of register classes. Also fix incompatible register naming with
1858 the UNIX assembler. */
1861 pdp11_conditional_register_usage (void)
1867 COPY_HARD_REG_SET (x
, reg_class_contents
[(int)FPU_REGS
]);
1868 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++ )
1869 if (TEST_HARD_REG_BIT (x
, i
))
1870 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1874 call_used_regs
[AC0_REGNUM
] = 1;
1875 if (TARGET_UNIX_ASM
)
1877 /* Change names of FPU registers for the UNIX assembler. */
1878 reg_names
[8] = "fr0";
1879 reg_names
[9] = "fr1";
1880 reg_names
[10] = "fr2";
1881 reg_names
[11] = "fr3";
1882 reg_names
[12] = "fr4";
1883 reg_names
[13] = "fr5";
1888 pdp11_function_section (tree decl ATTRIBUTE_UNUSED
,
1889 enum node_frequency freq ATTRIBUTE_UNUSED
,
1890 bool startup ATTRIBUTE_UNUSED
,
1891 bool exit ATTRIBUTE_UNUSED
)
1896 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1899 pdp11_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1901 return GET_CODE (x
) != CONST_DOUBLE
|| legitimate_const_double_p (x
);
1904 struct gcc_target targetm
= TARGET_INITIALIZER
;