PR target/47135
[official-gcc.git] / gcc / config / pdp11 / pdp11.c
blobb6ed97989fcf5bba480f40fb1cca56402272fd81
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)
11 any later version.
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/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "function.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "tree.h"
37 #include "expr.h"
38 #include "diagnostic-core.h"
39 #include "tm_p.h"
40 #include "target.h"
41 #include "target-def.h"
42 #include "df.h"
44 /* this is the current value returned by the macro FIRST_PARM_OFFSET
45 defined in tm.h */
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 =
62 encode_pdp11_f,
63 decode_pdp11_f,
65 24,
66 24,
67 -127,
68 127,
69 15,
70 15,
71 false,
72 false,
73 false,
74 false,
75 false,
76 false,
77 false,
78 false
81 const struct real_format pdp11_d_format =
83 encode_pdp11_d,
84 decode_pdp11_d,
86 56,
87 56,
88 -127,
89 127,
90 15,
91 15,
92 false,
93 false,
94 false,
95 false,
96 false,
97 false,
98 false,
99 false
102 static void
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);
110 static void
111 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
112 REAL_VALUE_TYPE *r, const long *buf)
114 long tbuf;
115 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
116 (*vax_f_format.decode) (fmt, r, &tbuf);
119 static void
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);
128 static void
129 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
130 REAL_VALUE_TYPE *r, const long *buf)
132 long tbuf[2];
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,
154 const_tree, bool);
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. */
247 static bool
248 pdp11_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED,
249 int value ATTRIBUTE_UNUSED)
251 switch (code)
253 case OPT_m10:
254 target_flags &= ~(MASK_40 | MASK_45);
255 return true;
257 default:
258 return true;
262 /* Implement TARGET_OPTION_INIT_STRUCT. */
264 static void
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.
281 static void
282 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
284 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
285 int regno;
286 int via_ac = -1;
288 fprintf (stream,
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)
296 fprintf(stream,
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");
307 else
309 /* DON'T SAVE FP */
312 /* make frame */
313 if (fsize)
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 */
325 via_ac = -1;
327 for (regno = AC0_REGNUM; regno <= AC5_REGNUM ; regno++)
329 /* ac0 - ac3 */
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]);
335 via_ac = regno;
338 /* maybe make ac4, ac5 call used regs?? */
339 /* ac4 - ac5 */
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
358 before returning. */
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? */
373 static void
374 pdp11_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
376 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
377 int i, j, k;
379 int via_ac;
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])
390 j++;
392 /* remember # of pushed bytes for CPU regs */
393 k = 2*j;
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]);
401 /* get ACs */
402 via_ac = AC5_REGNUM;
404 for (i = AC5_REGNUM; i >= AC0_REGNUM; i--)
405 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
407 via_ac = i;
408 k += 8;
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]);
419 k -= 8;
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]);
431 k -= 8;
435 fprintf(stream, "\tmov r5, sp\n");
436 fprintf (stream, "\tmov (sp)+, r5\n");
438 else
440 via_ac = AC5_REGNUM;
442 /* get ACs */
443 for (i = AC5_REGNUM; i >= AC0_REGNUM; i--)
444 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
445 via_ac = 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]);
469 if (fsize)
470 fprintf((stream), "\tadd $%#" HOST_WIDE_INT_PRINT "o, sp\n",
471 (fsize)&0xffff);
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. */
480 static const char *
481 singlemove_string (rtx *operands)
483 if (operands[1] != const0_rtx)
484 return "mov %1,%0";
486 return "clr %0";
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. */
494 bool
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;
502 REAL_VALUE_TYPE r;
503 long sval[2];
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. */
516 useorder = either;
517 if (opcount == 2)
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)))
526 useorder = big;
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))
533 useorder = little;
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)
537 useorder = little;
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]))
549 sameoff = true;
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). */
557 if (order == either)
558 order = (useorder == either) ? big : useorder;
559 else
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]))
567 optype = REGOP;
568 else if (CONSTANT_P (operands[op])
569 || GET_CODE (operands[op]) == CONST_DOUBLE)
570 optype = CNSTOP;
571 else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
572 optype = POPOP;
573 else if (GET_CODE (XEXP (operands[op], 0)) == PRE_DEC)
574 optype = PUSHOP;
575 else if (!reload_in_progress || offsettable_memref_p (operands[op]))
576 optype = OFFSOP;
577 else if (GET_CODE (operands[op]) == MEM)
578 optype = MEMOP;
579 else
580 optype = RNDOP;
582 /* Check for the cases that the operand constraints are not
583 supposed to allow to happen. Return failure for such cases. */
584 if (optype == RNDOP)
585 return false;
587 if (action != NULL)
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));
600 optype = OFFSOP;
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));
612 optype = OFFSOP;
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++)
623 if (order == big)
624 w = i;
625 else if (sameoff)
626 w = words - 1;
627 else
628 w = words - 1 - i;
630 /* Set the output operand to be word "w" of the input. */
631 if (optype == REGOP)
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);
642 else
644 sh = ((words - 1 - w) * 16);
645 exops[i][op] = gen_rtx_CONST_INT (HImode, trunc_int_for_mode (INTVAL(operands[op]) >> sh, HImode));
648 else
649 exops[i][op] = operands[op];
652 return true;
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. */
659 const char *
660 output_move_multiple (rtx *operands)
662 rtx exops[4][2];
663 pdp11_action action[2];
664 int i, words;
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);
682 /* Do the words. */
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);
698 return "";
701 /* Output an ascii string. */
702 void
703 output_ascii (FILE *file, const char *p, int size)
705 int i;
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];
714 if (c < 0)
715 c += 256;
716 fprintf (file, "%#o", c);
717 if (i < size - 1)
718 putc (',', file);
720 putc ('\n', file);
724 void
725 pdp11_asm_output_var (FILE *file, const char *name, int size,
726 int align, bool global)
728 if (align > 8)
729 fprintf (file, "\n\t.even\n");
730 if (global)
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);
740 static void
741 pdp11_asm_print_operand (FILE *file, rtx x, int code)
743 REAL_VALUE_TYPE r;
744 long sval[2];
746 if (code == '#')
747 fprintf (file, "#");
748 else if (code == '@')
750 if (TARGET_UNIX_ASM)
751 fprintf (file, "*");
752 else
753 fprintf (file, "@");
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);
765 else
767 putc ('$', file);
768 output_addr_const_pdp11 (file, x);
772 static bool
773 pdp11_asm_print_operand_punct_valid_p (unsigned char c)
775 return (c == '#' || c == '@');
778 void
779 print_operand_address (FILE *file, register rtx addr)
781 register rtx breg;
782 rtx offset;
783 int again = 0;
785 retry:
787 switch (GET_CODE (addr))
789 case MEM:
790 if (TARGET_UNIX_ASM)
791 fprintf (file, "*");
792 else
793 fprintf (file, "@");
794 addr = XEXP (addr, 0);
795 again = 1;
796 goto retry;
798 case REG:
799 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
800 break;
802 case PRE_MODIFY:
803 case PRE_DEC:
804 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
805 break;
807 case POST_MODIFY:
808 case POST_INC:
809 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
810 break;
812 case PLUS:
813 breg = 0;
814 offset = 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);
842 breg = addr;
843 addr = 0;
845 if (offset != 0)
847 gcc_assert (addr == 0);
848 addr = offset;
850 if (addr != 0)
851 output_addr_const_pdp11 (file, addr);
852 if (breg != 0)
854 gcc_assert (GET_CODE (breg) == REG);
855 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
857 break;
859 default:
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. */
873 static bool
874 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
876 if (aligned_p)
877 switch (size)
879 case 1:
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");
884 return true;
886 case 2:
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");
890 return true;
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 ? */
917 static int
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];
924 static bool
925 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
926 bool speed ATTRIBUTE_UNUSED)
928 switch (code)
930 case CONST_INT:
931 if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
933 *total = 0;
934 return true;
936 /* FALLTHRU */
938 case CONST:
939 case LABEL_REF:
940 case SYMBOL_REF:
941 /* Twice as expensive as REG. */
942 *total = 2;
943 return true;
945 case CONST_DOUBLE:
946 /* Twice (or 4 times) as expensive as 16 bit. */
947 *total = 4;
948 return true;
950 case MULT:
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. */
955 if (optimize_size)
956 *total = COSTS_N_INSNS (2);
957 else
958 *total = COSTS_N_INSNS (11);
959 return false;
961 case DIV:
962 if (optimize_size)
963 *total = COSTS_N_INSNS (2);
964 else
965 *total = COSTS_N_INSNS (25);
966 return false;
968 case MOD:
969 if (optimize_size)
970 *total = COSTS_N_INSNS (2);
971 else
972 *total = COSTS_N_INSNS (26);
973 return false;
975 case ABS:
976 /* Equivalent to length, so same for optimize_size. */
977 *total = COSTS_N_INSNS (3);
978 return false;
980 case ZERO_EXTEND:
981 /* Only used for qi->hi. */
982 *total = COSTS_N_INSNS (1);
983 return false;
985 case SIGN_EXTEND:
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);
990 else
991 *total = COSTS_N_INSNS (2);
992 return false;
994 case ASHIFT:
995 case LSHIFTRT:
996 case ASHIFTRT:
997 if (optimize_size)
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 */
1003 else
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);
1012 else
1013 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1015 else
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);
1025 return false;
1027 default:
1028 return false;
1032 const char *
1033 output_jump (enum rtx_code code, int inv, int length)
1035 static int x = 0;
1037 static char buf[1000];
1038 const char *pos, *neg;
1040 if (cc_prev_status.flags & CC_NO_OVERFLOW)
1042 switch (code)
1044 case GTU: code = GT; break;
1045 case LTU: code = LT; break;
1046 case GEU: code = GE; break;
1047 case LEU: code = LE; break;
1048 default: ;
1051 switch (code)
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 ();
1066 #if 0
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
1071 FCC! */
1072 if (cc_status.flags & CC_IN_FPU)
1073 output_asm_insn("cfcc", NULL);
1074 #endif
1076 switch (length)
1078 case 2:
1080 sprintf(buf, "%s %%l1", inv ? neg : pos);
1082 return buf;
1084 case 6:
1086 sprintf(buf, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv ? pos : neg, x, x);
1088 x++;
1090 return buf;
1092 default:
1094 gcc_unreachable ();
1099 void
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)
1110 CC_STATUS_INIT;
1112 else if (SET_DEST(exp) == pc_rtx)
1114 /* jump */
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
1124 && cc_status.value2
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
1128 && cc_status.value2
1129 && GET_CODE (cc_status.value2) == MEM)
1130 cc_status.value2 = 0;
1132 else
1134 CC_STATUS_INIT;
1140 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1142 rtx addr;
1144 /* Eliminate non-memory operations */
1145 if (GET_CODE (op) != MEM)
1146 return FALSE;
1148 #if 0
1149 /* dword operations really put out 2 instructions, so eliminate them. */
1150 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
1151 return FALSE;
1152 #endif
1154 /* Decode the address now. */
1156 indirection:
1158 addr = XEXP (op, 0);
1160 switch (GET_CODE (addr))
1162 case REG:
1163 /* (R0) - no extra cost */
1164 return 1;
1166 case PRE_DEC:
1167 case POST_INC:
1168 /* -(R0), (R0)+ - cheap! */
1169 return 0;
1171 case MEM:
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)
1177 return 0;
1179 op=addr;
1180 goto indirection;
1182 case CONST_INT:
1183 case LABEL_REF:
1184 case CONST:
1185 case SYMBOL_REF:
1186 /* @#address - extra cost */
1187 return 0;
1189 case PLUS:
1190 /* X(R0) - extra cost */
1191 return 0;
1193 default:
1194 break;
1197 return FALSE;
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
1212 const char *
1213 output_block_move(rtx *operands)
1215 static int count = 0;
1216 char buf[200];
1217 int unroll;
1218 int lastbyte = 0;
1220 /* Move of zero bytes is a NOP. */
1221 if (operands[2] == const0_rtx)
1222 return "";
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)
1232 register int i;
1234 for (i = 1; i <= INTVAL (operands[2]); i++)
1235 output_asm_insn("movb (%1)+, (%0)+", operands);
1237 return "";
1239 else if (INTVAL(operands[2]) < 32
1240 && (!optimize_size || INTVAL (operands[2]) < 9)
1241 && INTVAL (operands[3]) >= 2)
1243 register int i;
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);
1250 return "";
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)
1265 unroll = 0;
1266 else
1268 lastbyte = INTVAL (operands[2]) & 1;
1270 if (optimize_size || INTVAL (operands[2]) & 2)
1271 unroll = 1;
1272 else if (INTVAL (operands[2]) & 4)
1273 unroll = 2;
1274 else
1275 unroll = 3;
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);
1282 else
1284 /* Variable byte count; use the input register
1285 as the scratch. */
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)
1292 unroll = 1;
1293 output_asm_insn ("asr %4", operands);
1295 else
1297 unroll = 0;
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. */
1309 switch (unroll)
1311 case 0:
1312 output_asm_insn ("movb (%1)+, (%0)+", operands);
1313 break;
1315 case 1:
1316 output_asm_insn ("mov (%1)+, (%0)+", operands);
1317 break;
1319 case 2:
1320 output_asm_insn ("mov (%1)+, (%0)+", operands);
1321 output_asm_insn ("mov (%1)+, (%0)+", operands);
1322 break;
1324 default:
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);
1329 break;
1332 /* Output the decrement and test. */
1333 if (TARGET_40_PLUS)
1335 sprintf (buf, "sob %%4, movestrhi%d", count);
1336 output_asm_insn (buf, operands);
1338 else
1340 output_asm_insn ("dec %4", operands);
1341 sprintf (buf, "bgt movestrhi%d", count);
1342 output_asm_insn (buf, NULL);
1344 count ++;
1346 /* If constant odd byte count, move the last byte. */
1347 if (lastbyte)
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);
1354 count++;
1356 /* If we did word moves, check for trailing last byte. */
1357 if (unroll)
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);
1364 count++;
1368 return "";
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)
1377 REAL_VALUE_TYPE r;
1378 long sval[2];
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)
1382 return 1;
1383 return 0;
1386 /* Implement CANNOT_CHANGE_MODE_CLASS. */
1387 bool
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))
1397 return true;
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! */
1411 static reg_class_t
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;
1420 else
1421 return GENERAL_REGS;
1423 return rclass;
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! */
1435 static reg_class_t
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;
1444 else
1445 return GENERAL_REGS;
1447 return rclass;
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. */
1456 static reg_class_t
1457 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED,
1458 rtx x,
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)
1465 return NO_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.
1475 bool
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 ||
1480 c1 == FPU_REGS);
1481 int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS ||
1482 c2 == 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.
1494 static bool
1495 pdp11_legitimate_address_p (enum machine_mode mode,
1496 rtx operand, bool strict)
1498 rtx xfoob;
1500 /* accept @#address */
1501 if (CONSTANT_ADDRESS_P (operand))
1502 return true;
1504 switch (GET_CODE (operand))
1506 case REG:
1507 /* accept (R0) */
1508 return !strict || REGNO_OK_FOR_BASE_P (REGNO (operand));
1510 case PLUS:
1511 /* accept X(R0) */
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));
1516 case PRE_DEC:
1517 /* accept -(R0) */
1518 return GET_CODE (XEXP (operand, 0)) == REG
1519 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1521 case POST_INC:
1522 /* accept (R0)+ */
1523 return GET_CODE (XEXP (operand, 0)) == REG
1524 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1526 case PRE_MODIFY:
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;
1536 case POST_MODIFY:
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;
1546 case MEM:
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)
1558 return false;
1560 /* accept @address */
1561 if (CONSTANT_ADDRESS_P (xfoob))
1562 return true;
1564 switch (GET_CODE (xfoob))
1566 case REG:
1567 /* accept @(R0) - which is @0(R0) */
1568 return !strict || REGNO_OK_FOR_BASE_P(REGNO (xfoob));
1570 case PLUS:
1571 /* accept @X(R0) */
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));
1576 case PRE_DEC:
1577 /* accept @-(R0) */
1578 return GET_CODE (XEXP (xfoob, 0)) == REG
1579 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1581 case POST_INC:
1582 /* accept @(R0)+ */
1583 return GET_CODE (XEXP (xfoob, 0)) == REG
1584 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1586 default:
1587 /* anything else is invalid */
1588 return false;
1591 default:
1592 /* anything else is invalid */
1593 return false;
1597 /* Return the class number of the smallest class containing
1598 reg number REGNO. */
1599 enum reg_class
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;
1608 else if (regno & 1)
1609 return MUL_REGS;
1610 else
1611 return GENERAL_REGS;
1615 static int
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])
1622 offset += 2;
1623 for (regno = AC0_REGNUM; regno <= AC5_REGNUM; regno++)
1624 if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
1625 offset += 8;
1627 return offset;
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)
1636 int spoff;
1638 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
1639 return 4;
1640 else if (from == FRAME_POINTER_REGNUM
1641 && to == HARD_FRAME_POINTER_REGNUM)
1642 return 0;
1643 else
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)
1650 return spoff;
1652 gcc_assert (from == ARG_POINTER_REGNUM);
1654 /* If there is a frame pointer, that is saved too. */
1655 if (frame_pointer_needed)
1656 spoff += 2;
1658 /* Account for the saved PC in the function call. */
1659 return spoff + 2;
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.
1668 void
1669 output_addr_const_pdp11 (FILE *file, rtx x)
1671 char buf[256];
1672 int i;
1674 restart:
1675 switch (GET_CODE (x))
1677 case PC:
1678 gcc_assert (flag_pic);
1679 putc ('.', file);
1680 break;
1682 case SYMBOL_REF:
1683 assemble_name (file, XSTR (x, 0));
1684 break;
1686 case LABEL_REF:
1687 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1688 assemble_name (file, buf);
1689 break;
1691 case CODE_LABEL:
1692 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1693 assemble_name (file, buf);
1694 break;
1696 case CONST_INT:
1697 i = INTVAL (x);
1698 if (i < 0)
1700 i = -i;
1701 fprintf (file, "-");
1703 fprintf (file, "%#o", i & 0xffff);
1704 break;
1706 case CONST:
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));
1710 break;
1712 case CONST_DOUBLE:
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));
1719 else
1720 /* We can't handle floating point constants;
1721 PRINT_OPERAND must handle them. */
1722 output_operand_lossage ("floating constant misused");
1723 break;
1725 case PLUS:
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));
1734 else
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));
1741 break;
1743 case MINUS:
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)
1748 goto restart;
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));
1755 break;
1757 case ZERO_EXTEND:
1758 case SIGN_EXTEND:
1759 output_addr_const_pdp11 (file, XEXP (x, 0));
1760 break;
1762 default:
1763 output_operand_lossage ("invalid expression as operand");
1767 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1769 static bool
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!!!! ) */
1784 static rtx
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. */
1795 static rtx
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! */
1808 static bool
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
1825 static void
1826 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1828 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
1829 rtx mem;
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
1851 not be available.
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). */
1857 static rtx
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)
1863 return NULL_RTX;
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.) */
1872 static void
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. */
1887 static void
1888 pdp11_conditional_register_usage (void)
1890 int i;
1891 HARD_REG_SET x;
1892 if (!TARGET_FPU)
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;
1900 if (TARGET_AC0)
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";
1914 static section *
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)
1920 return NULL;
1923 struct gcc_target targetm = TARGET_INITIALIZER;