* config/pdp11/pdp11.c (output_move_quad): Fix ICE for CPU
[official-gcc.git] / gcc / config / pdp11 / pdp11.c
blob946d7ed973b8b2af6e4973f8bf75bc0e522601be
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 "toplev.h"
40 #include "tm_p.h"
41 #include "target.h"
42 #include "target-def.h"
43 #include "df.h"
45 /* this is the current value returned by the macro FIRST_PARM_OFFSET
46 defined in tm.h */
47 int current_first_parm_offset;
49 /* Routines to encode/decode pdp11 floats */
50 static void encode_pdp11_f (const struct real_format *fmt,
51 long *, const REAL_VALUE_TYPE *);
52 static void decode_pdp11_f (const struct real_format *,
53 REAL_VALUE_TYPE *, const long *);
54 static void encode_pdp11_d (const struct real_format *fmt,
55 long *, const REAL_VALUE_TYPE *);
56 static void decode_pdp11_d (const struct real_format *,
57 REAL_VALUE_TYPE *, const long *);
59 /* These two are taken from the corresponding vax descriptors
60 in real.c, changing only the encode/decode routine pointers. */
61 const struct real_format pdp11_f_format =
63 encode_pdp11_f,
64 decode_pdp11_f,
66 24,
67 24,
68 -127,
69 127,
70 15,
71 15,
72 false,
73 false,
74 false,
75 false,
76 false,
77 false,
78 false,
79 false
82 const struct real_format pdp11_d_format =
84 encode_pdp11_d,
85 decode_pdp11_d,
87 56,
88 56,
89 -127,
90 127,
91 15,
92 15,
93 false,
94 false,
95 false,
96 false,
97 false,
98 false,
99 false,
100 false
103 static void
104 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
105 const REAL_VALUE_TYPE *r)
107 (*vax_f_format.encode) (fmt, buf, r);
108 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
111 static void
112 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
113 REAL_VALUE_TYPE *r, const long *buf)
115 long tbuf;
116 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
117 (*vax_f_format.decode) (fmt, r, &tbuf);
120 static void
121 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
122 const REAL_VALUE_TYPE *r)
124 (*vax_d_format.encode) (fmt, buf, r);
125 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
126 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
129 static void
130 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
131 REAL_VALUE_TYPE *r, const long *buf)
133 long tbuf[2];
134 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
135 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
136 (*vax_d_format.decode) (fmt, r, tbuf);
139 /* This is where the condition code register lives. */
140 /* rtx cc0_reg_rtx; - no longer needed? */
142 static bool pdp11_handle_option (size_t, const char *, int);
143 static void pdp11_option_init_struct (struct gcc_options *);
144 static rtx find_addr_reg (rtx);
145 static const char *singlemove_string (rtx *);
146 static bool pdp11_assemble_integer (rtx, unsigned int, int);
147 static void pdp11_output_function_prologue (FILE *, HOST_WIDE_INT);
148 static void pdp11_output_function_epilogue (FILE *, HOST_WIDE_INT);
149 static bool pdp11_rtx_costs (rtx, int, int, int *, bool);
150 static bool pdp11_return_in_memory (const_tree, const_tree);
151 static rtx pdp11_function_value (const_tree, const_tree, bool);
152 static rtx pdp11_libcall_value (enum machine_mode, const_rtx);
153 static bool pdp11_function_value_regno_p (const unsigned int);
154 static void pdp11_trampoline_init (rtx, tree, rtx);
155 static rtx pdp11_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
156 const_tree, bool);
157 static void pdp11_function_arg_advance (CUMULATIVE_ARGS *,
158 enum machine_mode, const_tree, bool);
160 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
162 static const struct default_options pdp11_option_optimization_table[] =
164 { OPT_LEVELS_3_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
165 { OPT_LEVELS_NONE, 0, NULL, 0 }
168 /* Initialize the GCC target structure. */
169 #undef TARGET_ASM_BYTE_OP
170 #define TARGET_ASM_BYTE_OP NULL
171 #undef TARGET_ASM_ALIGNED_HI_OP
172 #define TARGET_ASM_ALIGNED_HI_OP NULL
173 #undef TARGET_ASM_ALIGNED_SI_OP
174 #define TARGET_ASM_ALIGNED_SI_OP NULL
175 #undef TARGET_ASM_INTEGER
176 #define TARGET_ASM_INTEGER pdp11_assemble_integer
178 #undef TARGET_ASM_FUNCTION_PROLOGUE
179 #define TARGET_ASM_FUNCTION_PROLOGUE pdp11_output_function_prologue
180 #undef TARGET_ASM_FUNCTION_EPILOGUE
181 #define TARGET_ASM_FUNCTION_EPILOGUE pdp11_output_function_epilogue
183 #undef TARGET_ASM_OPEN_PAREN
184 #define TARGET_ASM_OPEN_PAREN "["
185 #undef TARGET_ASM_CLOSE_PAREN
186 #define TARGET_ASM_CLOSE_PAREN "]"
188 #undef TARGET_DEFAULT_TARGET_FLAGS
189 #define TARGET_DEFAULT_TARGET_FLAGS \
190 (MASK_FPU | MASK_45 | MASK_ABSHI_BUILTIN | TARGET_UNIX_ASM_DEFAULT)
191 #undef TARGET_HANDLE_OPTION
192 #define TARGET_HANDLE_OPTION pdp11_handle_option
193 #undef TARGET_OPTION_OPTIMIZATION_TABLE
194 #define TARGET_OPTION_OPTIMIZATION_TABLE pdp11_option_optimization_table
195 #undef TARGET_OPTION_INIT_STRUCT
196 #define TARGET_OPTION_INIT_STRUCT pdp11_option_init_struct
198 #undef TARGET_RTX_COSTS
199 #define TARGET_RTX_COSTS pdp11_rtx_costs
201 #undef TARGET_FUNCTION_ARG
202 #define TARGET_FUNCTION_ARG pdp11_function_arg
203 #undef TARGET_FUNCTION_ARG_ADVANCE
204 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
206 #undef TARGET_RETURN_IN_MEMORY
207 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
209 #undef TARGET_FUNCTION_VALUE
210 #define TARGET_FUNCTION_VALUE pdp11_function_value
211 #undef TARGET_LIBCALL_VALUE
212 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
213 #undef TARGET_FUNCTION_VALUE_REGNO_P
214 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
216 #undef TARGET_TRAMPOLINE_INIT
217 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
219 #undef TARGET_SECONDARY_RELOAD
220 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
222 #undef TARGET_REGISTER_MOVE_COST
223 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
225 #undef TARGET_PREFERRED_RELOAD_CLASS
226 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
228 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
229 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
231 /* Implement TARGET_HANDLE_OPTION. */
233 static bool
234 pdp11_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED,
235 int value ATTRIBUTE_UNUSED)
237 switch (code)
239 case OPT_m10:
240 target_flags &= ~(MASK_40 | MASK_45);
241 return true;
243 default:
244 return true;
248 /* Implement TARGET_OPTION_INIT_STRUCT. */
250 static void
251 pdp11_option_init_struct (struct gcc_options *opts)
253 opts->x_flag_finite_math_only = 0;
254 opts->x_flag_trapping_math = 0;
255 opts->x_flag_signaling_nans = 0;
259 stream is a stdio stream to output the code to.
260 size is an int: how many units of temporary storage to allocate.
261 Refer to the array `regs_ever_live' to determine which registers
262 to save; `regs_ever_live[I]' is nonzero if register number I
263 is ever used in the function. This macro is responsible for
264 knowing which registers should not be saved even if used.
267 static void
268 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
270 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
271 int regno;
272 int via_ac = -1;
274 fprintf (stream,
275 "\n\t; /* function prologue %s*/\n",
276 current_function_name ());
278 /* if we are outputting code for main,
279 the switch FPU to right mode if TARGET_FPU */
280 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
282 fprintf(stream,
283 "\t;/* switch cpu to double float, single integer */\n");
284 fprintf(stream, "\tsetd\n");
285 fprintf(stream, "\tseti\n\n");
288 if (frame_pointer_needed)
290 fprintf(stream, "\tmov r5, -(sp)\n");
291 fprintf(stream, "\tmov sp, r5\n");
293 else
295 /* DON'T SAVE FP */
298 /* make frame */
299 if (fsize)
300 asm_fprintf (stream, "\tsub $%#wo, sp\n", fsize);
302 /* save CPU registers */
303 for (regno = 0; regno <= PC_REGNUM; regno++)
304 if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
305 if (! ((regno == FRAME_POINTER_REGNUM)
306 && frame_pointer_needed))
307 fprintf (stream, "\tmov %s, -(sp)\n", reg_names[regno]);
308 /* fpu regs saving */
310 /* via_ac specifies the ac to use for saving ac4, ac5 */
311 via_ac = -1;
313 for (regno = AC0_REGNUM; regno <= AC5_REGNUM ; regno++)
315 /* ac0 - ac3 */
316 if (LOAD_FPU_REG_P(regno)
317 && df_regs_ever_live_p (regno)
318 && ! call_used_regs[regno])
320 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[regno]);
321 via_ac = regno;
324 /* maybe make ac4, ac5 call used regs?? */
325 /* ac4 - ac5 */
326 if (NO_LOAD_FPU_REG_P(regno)
327 && df_regs_ever_live_p (regno)
328 && ! call_used_regs[regno])
330 gcc_assert (via_ac != -1);
331 fprintf (stream, "\tldd %s, %s\n",
332 reg_names[regno], reg_names[via_ac]);
333 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[via_ac]);
337 fprintf (stream, "\t;/* end of prologue */\n\n");
341 The function epilogue should not depend on the current stack pointer!
342 It should use the frame pointer only. This is mandatory because
343 of alloca; we also take advantage of it to omit stack adjustments
344 before returning. */
346 /* maybe we can make leaf functions faster by switching to the
347 second register file - this way we don't have to save regs!
348 leaf functions are ~ 50% of all functions (dynamically!)
350 set/clear bit 11 (dec. 2048) of status word for switching register files -
351 but how can we do this? the pdp11/45 manual says bit may only
352 be set (p.24), but not cleared!
354 switching to kernel is probably more expensive, so we'll leave it
355 like this and not use the second set of registers...
357 maybe as option if you want to generate code for kernel mode? */
359 static void
360 pdp11_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
362 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
363 int i, j, k;
365 int via_ac;
367 fprintf (stream, "\n\t; /*function epilogue */\n");
369 if (frame_pointer_needed)
371 /* hope this is safe - m68k does it also .... */
372 df_set_regs_ever_live (FRAME_POINTER_REGNUM, false);
374 for (i = PC_REGNUM, j = 0 ; i >= 0 ; i--)
375 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
376 j++;
378 /* remember # of pushed bytes for CPU regs */
379 k = 2*j;
381 /* change fp -> r5 due to the compile error on libgcc2.c */
382 for (i = PC_REGNUM ; i >= 0 ; i--)
383 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
384 fprintf(stream, "\tmov %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
385 (-fsize-2*j--)&0xffff, reg_names[i]);
387 /* get ACs */
388 via_ac = AC5_REGNUM;
390 for (i = AC5_REGNUM; i >= AC0_REGNUM; i--)
391 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
393 via_ac = i;
394 k += 8;
397 for (i = AC5_REGNUM; i >= AC0_REGNUM; i--)
399 if (LOAD_FPU_REG_P(i)
400 && df_regs_ever_live_p (i)
401 && ! call_used_regs[i])
403 fprintf(stream, "\tldd %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
404 (-fsize-k)&0xffff, reg_names[i]);
405 k -= 8;
408 if (NO_LOAD_FPU_REG_P(i)
409 && df_regs_ever_live_p (i)
410 && ! call_used_regs[i])
412 gcc_assert (LOAD_FPU_REG_P(via_ac));
414 fprintf(stream, "\tldd %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
415 (-fsize-k)&0xffff, reg_names[via_ac]);
416 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
417 k -= 8;
421 fprintf(stream, "\tmov r5, sp\n");
422 fprintf (stream, "\tmov (sp)+, r5\n");
424 else
426 via_ac = AC5_REGNUM;
428 /* get ACs */
429 for (i = AC5_REGNUM; i >= AC0_REGNUM; i--)
430 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
431 via_ac = i;
433 for (i = AC5_REGNUM; i >= AC0_REGNUM; i--)
435 if (LOAD_FPU_REG_P(i)
436 && df_regs_ever_live_p (i)
437 && ! call_used_regs[i])
438 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[i]);
440 if (NO_LOAD_FPU_REG_P(i)
441 && df_regs_ever_live_p (i)
442 && ! call_used_regs[i])
444 gcc_assert (LOAD_FPU_REG_P(via_ac));
446 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[via_ac]);
447 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
451 for (i = PC_REGNUM; i >= 0; i--)
452 if (df_regs_ever_live_p (i) && !call_used_regs[i])
453 fprintf(stream, "\tmov (sp)+, %s\n", reg_names[i]);
455 if (fsize)
456 fprintf((stream), "\tadd $%#" HOST_WIDE_INT_PRINT "o, sp\n",
457 (fsize)&0xffff);
460 fprintf (stream, "\trts pc\n");
461 fprintf (stream, "\t;/* end of epilogue*/\n\n\n");
464 /* Return the best assembler insn template
465 for moving operands[1] into operands[0] as a fullword. */
466 static const char *
467 singlemove_string (rtx *operands)
469 if (operands[1] != const0_rtx)
470 return "mov %1,%0";
472 return "clr %0";
476 /* Output assembler code to perform a doubleword move insn
477 with operands OPERANDS. */
479 const char *
480 output_move_double (rtx *operands)
482 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
483 rtx latehalf[2];
484 rtx addreg0 = 0, addreg1 = 0;
486 /* First classify both operands. */
488 if (REG_P (operands[0]))
489 optype0 = REGOP;
490 else if (offsettable_memref_p (operands[0]))
491 optype0 = OFFSOP;
492 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
493 optype0 = POPOP;
494 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
495 optype0 = PUSHOP;
496 else if (GET_CODE (operands[0]) == MEM)
497 optype0 = MEMOP;
498 else
499 optype0 = RNDOP;
501 if (REG_P (operands[1]))
502 optype1 = REGOP;
503 else if (CONSTANT_P (operands[1])
504 #if 0
505 || GET_CODE (operands[1]) == CONST_DOUBLE
506 #endif
508 optype1 = CNSTOP;
509 else if (offsettable_memref_p (operands[1]))
510 optype1 = OFFSOP;
511 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
512 optype1 = POPOP;
513 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
514 optype1 = PUSHOP;
515 else if (GET_CODE (operands[1]) == MEM)
516 optype1 = MEMOP;
517 else
518 optype1 = RNDOP;
520 /* Check for the cases that the operand constraints are not
521 supposed to allow to happen. Abort if we get one,
522 because generating code for these cases is painful. */
524 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
526 /* If one operand is decrementing and one is incrementing
527 decrement the former register explicitly
528 and change that operand into ordinary indexing. */
530 if (optype0 == PUSHOP && optype1 == POPOP)
532 operands[0] = XEXP (XEXP (operands[0], 0), 0);
533 output_asm_insn ("sub $4,%0", operands);
534 operands[0] = gen_rtx_MEM (SImode, operands[0]);
535 optype0 = OFFSOP;
537 if (optype0 == POPOP && optype1 == PUSHOP)
539 operands[1] = XEXP (XEXP (operands[1], 0), 0);
540 output_asm_insn ("sub $4,%1", operands);
541 operands[1] = gen_rtx_MEM (SImode, operands[1]);
542 optype1 = OFFSOP;
545 /* If an operand is an unoffsettable memory ref, find a register
546 we can increment temporarily to make it refer to the second word. */
548 if (optype0 == MEMOP)
549 addreg0 = find_addr_reg (XEXP (operands[0], 0));
551 if (optype1 == MEMOP)
552 addreg1 = find_addr_reg (XEXP (operands[1], 0));
554 /* Ok, we can do one word at a time.
555 Normally we do the low-numbered word first,
556 but if either operand is autodecrementing then we
557 do the high-numbered word first.
559 In either case, set up in LATEHALF the operands to use
560 for the high-numbered word and in some cases alter the
561 operands in OPERANDS to be suitable for the low-numbered word. */
563 if (optype0 == REGOP)
564 latehalf[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
565 else if (optype0 == OFFSOP)
566 latehalf[0] = adjust_address (operands[0], HImode, 2);
567 else
568 latehalf[0] = operands[0];
570 if (optype1 == REGOP)
571 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
572 else if (optype1 == OFFSOP)
573 latehalf[1] = adjust_address (operands[1], HImode, 2);
574 else if (optype1 == CNSTOP)
576 if (CONSTANT_P (operands[1]))
578 /* now the mess begins, high word is in lower word???
580 that's what ashc makes me think, but I don't remember :-( */
581 latehalf[1] = GEN_INT (INTVAL(operands[1]) >> 16);
582 operands[1] = GEN_INT (INTVAL(operands[1]) & 0xff);
584 else
585 /* immediate 32-bit values not allowed */
586 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE);
588 else
589 latehalf[1] = operands[1];
591 /* If insn is effectively movd N(sp),-(sp) then we will do the
592 high word first. We should use the adjusted operand 1 (which is N+4(sp))
593 for the low word as well, to compensate for the first decrement of sp. */
594 if (optype0 == PUSHOP
595 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
596 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
597 operands[1] = latehalf[1];
599 /* If one or both operands autodecrementing,
600 do the two words, high-numbered first. */
602 /* Likewise, the first move would clobber the source of the second one,
603 do them in the other order. This happens only for registers;
604 such overlap can't happen in memory unless the user explicitly
605 sets it up, and that is an undefined circumstance. */
607 if (optype0 == PUSHOP || optype1 == PUSHOP
608 || (optype0 == REGOP && optype1 == REGOP
609 && REGNO (operands[0]) == REGNO (latehalf[1])))
611 /* Make any unoffsettable addresses point at high-numbered word. */
612 if (addreg0)
613 output_asm_insn ("add $2,%0", &addreg0);
614 if (addreg1)
615 output_asm_insn ("add $2,%0", &addreg1);
617 /* Do that word. */
618 output_asm_insn (singlemove_string (latehalf), latehalf);
620 /* Undo the adds we just did. */
621 if (addreg0)
622 output_asm_insn ("sub $2,%0", &addreg0);
623 if (addreg1)
624 output_asm_insn ("sub $2,%0", &addreg1);
626 /* Do low-numbered word. */
627 return singlemove_string (operands);
630 /* Normal case: do the two words, low-numbered first. */
632 output_asm_insn (singlemove_string (operands), operands);
634 /* Make any unoffsettable addresses point at high-numbered word. */
635 if (addreg0)
636 output_asm_insn ("add $2,%0", &addreg0);
637 if (addreg1)
638 output_asm_insn ("add $2,%0", &addreg1);
640 /* Do that word. */
641 output_asm_insn (singlemove_string (latehalf), latehalf);
643 /* Undo the adds we just did. */
644 if (addreg0)
645 output_asm_insn ("sub $2,%0", &addreg0);
646 if (addreg1)
647 output_asm_insn ("sub $2,%0", &addreg1);
649 return "";
651 /* Output assembler code to perform a quadword move insn
652 with operands OPERANDS. */
654 const char *
655 output_move_quad (rtx *operands)
657 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
658 rtx latehalf[2];
659 rtx addreg0 = 0, addreg1 = 0;
661 output_asm_insn(";/* movdi/df: %1 -> %0 */", operands);
663 if (REG_P (operands[0]))
664 optype0 = REGOP;
665 else if (offsettable_memref_p (operands[0]))
666 optype0 = OFFSOP;
667 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
668 optype0 = POPOP;
669 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
670 optype0 = PUSHOP;
671 else if (GET_CODE (operands[0]) == MEM)
672 optype0 = MEMOP;
673 else
674 optype0 = RNDOP;
676 if (REG_P (operands[1]))
677 optype1 = REGOP;
678 else if (CONSTANT_P (operands[1])
679 || GET_CODE (operands[1]) == CONST_DOUBLE)
680 optype1 = CNSTOP;
681 else if (offsettable_memref_p (operands[1]))
682 optype1 = OFFSOP;
683 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
684 optype1 = POPOP;
685 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
686 optype1 = PUSHOP;
687 else if (GET_CODE (operands[1]) == MEM)
688 optype1 = MEMOP;
689 else
690 optype1 = RNDOP;
692 /* Check for the cases that the operand constraints are not
693 supposed to allow to happen. Abort if we get one,
694 because generating code for these cases is painful. */
696 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
698 if (optype0 == REGOP || optype1 == REGOP)
700 /* check for use of clrd????
701 if you ever allow ac4 and ac5 (now we require secondary load)
702 you must check whether
703 you want to load into them or store from them -
704 then dump ac0 into $help$ movce ac4/5 to ac0, do the
705 store from ac0, and restore ac0 - if you can find
706 an unused ac[0-3], use that and you save a store and a load!*/
708 if (FPU_REG_P(REGNO(operands[0])))
710 if (GET_CODE(operands[1]) == CONST_DOUBLE)
712 REAL_VALUE_TYPE r;
713 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
715 if (REAL_VALUES_EQUAL (r, dconst0))
716 return "{clrd|clrf} %0";
719 return "{ldd|movf} %1, %0";
722 if (FPU_REG_P(REGNO(operands[1])))
723 return "{std|movf} %1, %0";
726 /* If one operand is decrementing and one is incrementing
727 decrement the former register explicitly
728 and change that operand into ordinary indexing. */
730 if (optype0 == PUSHOP && optype1 == POPOP)
732 operands[0] = XEXP (XEXP (operands[0], 0), 0);
733 output_asm_insn ("sub $8,%0", operands);
734 operands[0] = gen_rtx_MEM (DImode, operands[0]);
735 optype0 = OFFSOP;
737 if (optype0 == POPOP && optype1 == PUSHOP)
739 operands[1] = XEXP (XEXP (operands[1], 0), 0);
740 output_asm_insn ("sub $8,%1", operands);
741 operands[1] = gen_rtx_MEM (SImode, operands[1]);
742 optype1 = OFFSOP;
745 /* If an operand is an unoffsettable memory ref, find a register
746 we can increment temporarily to make it refer to the second word. */
748 if (optype0 == MEMOP)
749 addreg0 = find_addr_reg (XEXP (operands[0], 0));
751 if (optype1 == MEMOP)
752 addreg1 = find_addr_reg (XEXP (operands[1], 0));
754 /* Ok, we can do one word at a time.
755 Normally we do the low-numbered word first,
756 but if either operand is autodecrementing then we
757 do the high-numbered word first.
759 In either case, set up in LATEHALF the operands to use
760 for the high-numbered word and in some cases alter the
761 operands in OPERANDS to be suitable for the low-numbered word. */
763 if (optype0 == REGOP)
764 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
765 else if (optype0 == OFFSOP)
766 latehalf[0] = adjust_address (operands[0], SImode, 4);
767 else
768 latehalf[0] = operands[0];
770 if (optype1 == REGOP)
771 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
772 else if (optype1 == OFFSOP)
773 latehalf[1] = adjust_address (operands[1], SImode, 4);
774 else if (optype1 == CNSTOP)
776 if (GET_CODE (operands[1]) == CONST_DOUBLE)
778 REAL_VALUE_TYPE r;
779 long dval[2];
780 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
781 REAL_VALUE_TO_TARGET_DOUBLE (r, dval);
782 latehalf[1] = GEN_INT (dval[1]);
783 operands[1] = GEN_INT (dval[0]);
785 else if (GET_CODE(operands[1]) == CONST_INT)
787 latehalf[1] = const0_rtx;
789 else
790 gcc_unreachable ();
792 else
793 latehalf[1] = operands[1];
795 /* If insn is effectively movd N(sp),-(sp) then we will do the
796 high word first. We should use the adjusted operand 1 (which is N+4(sp))
797 for the low word as well, to compensate for the first decrement of sp. */
798 if (optype0 == PUSHOP
799 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
800 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
801 operands[1] = latehalf[1];
803 /* If one or both operands autodecrementing,
804 do the two words, high-numbered first. */
806 /* Likewise, the first move would clobber the source of the second one,
807 do them in the other order. This happens only for registers;
808 such overlap can't happen in memory unless the user explicitly
809 sets it up, and that is an undefined circumstance. */
811 if (optype0 == PUSHOP || optype1 == PUSHOP
812 || (optype0 == REGOP && optype1 == REGOP
813 && REGNO (operands[0]) == REGNO (latehalf[1])))
815 /* Make any unoffsettable addresses point at high-numbered word. */
816 if (addreg0)
817 output_asm_insn ("add $4,%0", &addreg0);
818 if (addreg1)
819 output_asm_insn ("add $4,%0", &addreg1);
821 /* Do that word. */
822 output_asm_insn(output_move_double(latehalf), latehalf);
824 /* Undo the adds we just did. */
825 if (addreg0)
826 output_asm_insn ("sub $4,%0", &addreg0);
827 if (addreg1)
828 output_asm_insn ("sub $4,%0", &addreg1);
830 /* Do low-numbered word. */
831 return output_move_double (operands);
834 /* Normal case: do the two words, low-numbered first. */
836 output_asm_insn (output_move_double (operands), operands);
838 /* Make any unoffsettable addresses point at high-numbered word. */
839 if (addreg0)
840 output_asm_insn ("add $4,%0", &addreg0);
841 if (addreg1)
842 output_asm_insn ("add $4,%0", &addreg1);
844 /* Do that word. */
845 output_asm_insn (output_move_double (latehalf), latehalf);
847 /* Undo the adds we just did. */
848 if (addreg0)
849 output_asm_insn ("sub $4,%0", &addreg0);
850 if (addreg1)
851 output_asm_insn ("sub $4,%0", &addreg1);
853 return "";
857 /* Return a REG that occurs in ADDR with coefficient 1.
858 ADDR can be effectively incremented by incrementing REG. */
860 static rtx
861 find_addr_reg (rtx addr)
863 while (GET_CODE (addr) == PLUS)
865 if (GET_CODE (XEXP (addr, 0)) == REG)
866 addr = XEXP (addr, 0);
867 if (GET_CODE (XEXP (addr, 1)) == REG)
868 addr = XEXP (addr, 1);
869 if (CONSTANT_P (XEXP (addr, 0)))
870 addr = XEXP (addr, 1);
871 if (CONSTANT_P (XEXP (addr, 1)))
872 addr = XEXP (addr, 0);
874 if (GET_CODE (addr) == REG)
875 return addr;
876 return 0;
879 /* Output an ascii string. */
880 void
881 output_ascii (FILE *file, const char *p, int size)
883 int i;
885 /* This used to output .byte "string", which doesn't work with the UNIX
886 assembler and I think not with DEC ones either. */
887 fprintf (file, "\t.byte ");
889 for (i = 0; i < size; i++)
891 register int c = p[i];
892 if (c < 0)
893 c += 256;
894 fprintf (file, "%#o", c);
895 if (i < size - 1)
896 putc (',', file);
898 putc ('\n', file);
902 void
903 print_operand_address (FILE *file, register rtx addr)
905 register rtx breg;
906 rtx offset;
907 int again = 0;
909 retry:
911 switch (GET_CODE (addr))
913 case MEM:
914 if (TARGET_UNIX_ASM)
915 fprintf (file, "*");
916 else
917 fprintf (file, "@");
918 addr = XEXP (addr, 0);
919 again = 1;
920 goto retry;
922 case REG:
923 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
924 break;
926 case PRE_MODIFY:
927 case PRE_DEC:
928 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
929 break;
931 case POST_MODIFY:
932 case POST_INC:
933 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
934 break;
936 case PLUS:
937 breg = 0;
938 offset = 0;
939 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
940 || GET_CODE (XEXP (addr, 0)) == MEM)
942 offset = XEXP (addr, 0);
943 addr = XEXP (addr, 1);
945 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
946 || GET_CODE (XEXP (addr, 1)) == MEM)
948 offset = XEXP (addr, 1);
949 addr = XEXP (addr, 0);
951 if (GET_CODE (addr) != PLUS)
953 else if (GET_CODE (XEXP (addr, 0)) == REG)
955 breg = XEXP (addr, 0);
956 addr = XEXP (addr, 1);
958 else if (GET_CODE (XEXP (addr, 1)) == REG)
960 breg = XEXP (addr, 1);
961 addr = XEXP (addr, 0);
963 if (GET_CODE (addr) == REG)
965 gcc_assert (breg == 0);
966 breg = addr;
967 addr = 0;
969 if (offset != 0)
971 gcc_assert (addr == 0);
972 addr = offset;
974 if (addr != 0)
975 output_addr_const_pdp11 (file, addr);
976 if (breg != 0)
978 gcc_assert (GET_CODE (breg) == REG);
979 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
981 break;
983 default:
984 if (!again && GET_CODE (addr) == CONST_INT)
986 /* Absolute (integer number) address. */
987 if (!TARGET_UNIX_ASM)
988 fprintf (file, "@$");
990 output_addr_const_pdp11 (file, addr);
994 /* Target hook to assemble integer objects. We need to use the
995 pdp-specific version of output_addr_const. */
997 static bool
998 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
1000 if (aligned_p)
1001 switch (size)
1003 case 1:
1004 fprintf (asm_out_file, "\t.byte\t");
1005 output_addr_const_pdp11 (asm_out_file, x);
1006 fprintf (asm_out_file, " /* char */\n");
1007 return true;
1009 case 2:
1010 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
1011 output_addr_const_pdp11 (asm_out_file, x);
1012 fprintf (asm_out_file, " /* short */\n");
1013 return true;
1015 return default_assemble_integer (x, size, aligned_p);
1019 /* register move costs, indexed by regs */
1021 static const int move_costs[N_REG_CLASSES][N_REG_CLASSES] =
1023 /* NO MUL GEN LFPU NLFPU FPU ALL */
1025 /* NO */ { 0, 0, 0, 0, 0, 0, 0},
1026 /* MUL */ { 0, 2, 2, 22, 22, 22, 22},
1027 /* GEN */ { 0, 2, 2, 22, 22, 22, 22},
1028 /* LFPU */ { 0, 22, 22, 2, 2, 2, 22},
1029 /* NLFPU */ { 0, 22, 22, 2, 10, 10, 22},
1030 /* FPU */ { 0, 22, 22, 2, 10, 10, 22},
1031 /* ALL */ { 0, 22, 22, 22, 22, 22, 22}
1035 /* -- note that some moves are tremendously expensive,
1036 because they require lots of tricks! do we have to
1037 charge the costs incurred by secondary reload class
1038 -- as we do here with 10 -- or not ? */
1040 static int
1041 pdp11_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1042 reg_class_t c1, reg_class_t c2)
1044 return move_costs[(int)c1][(int)c2];
1047 static bool
1048 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
1049 bool speed ATTRIBUTE_UNUSED)
1051 switch (code)
1053 case CONST_INT:
1054 if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
1056 *total = 0;
1057 return true;
1059 /* FALLTHRU */
1061 case CONST:
1062 case LABEL_REF:
1063 case SYMBOL_REF:
1064 /* Twice as expensive as REG. */
1065 *total = 2;
1066 return true;
1068 case CONST_DOUBLE:
1069 /* Twice (or 4 times) as expensive as 16 bit. */
1070 *total = 4;
1071 return true;
1073 case MULT:
1074 /* ??? There is something wrong in MULT because MULT is not
1075 as cheap as total = 2 even if we can shift! */
1076 /* If optimizing for size make mult etc cheap, but not 1, so when
1077 in doubt the faster insn is chosen. */
1078 if (optimize_size)
1079 *total = COSTS_N_INSNS (2);
1080 else
1081 *total = COSTS_N_INSNS (11);
1082 return false;
1084 case DIV:
1085 if (optimize_size)
1086 *total = COSTS_N_INSNS (2);
1087 else
1088 *total = COSTS_N_INSNS (25);
1089 return false;
1091 case MOD:
1092 if (optimize_size)
1093 *total = COSTS_N_INSNS (2);
1094 else
1095 *total = COSTS_N_INSNS (26);
1096 return false;
1098 case ABS:
1099 /* Equivalent to length, so same for optimize_size. */
1100 *total = COSTS_N_INSNS (3);
1101 return false;
1103 case ZERO_EXTEND:
1104 /* Only used for qi->hi. */
1105 *total = COSTS_N_INSNS (1);
1106 return false;
1108 case SIGN_EXTEND:
1109 if (GET_MODE (x) == HImode)
1110 *total = COSTS_N_INSNS (1);
1111 else if (GET_MODE (x) == SImode)
1112 *total = COSTS_N_INSNS (6);
1113 else
1114 *total = COSTS_N_INSNS (2);
1115 return false;
1117 case ASHIFT:
1118 case LSHIFTRT:
1119 case ASHIFTRT:
1120 if (optimize_size)
1121 *total = COSTS_N_INSNS (1);
1122 else if (GET_MODE (x) == QImode)
1124 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
1125 *total = COSTS_N_INSNS (8); /* worst case */
1126 else
1127 *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
1129 else if (GET_MODE (x) == HImode)
1131 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1133 if (abs (INTVAL (XEXP (x, 1))) == 1)
1134 *total = COSTS_N_INSNS (1);
1135 else
1136 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1138 else
1139 *total = COSTS_N_INSNS (10); /* worst case */
1141 else if (GET_MODE (x) == SImode)
1143 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1144 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1145 else /* worst case */
1146 *total = COSTS_N_INSNS (18);
1148 return false;
1150 default:
1151 return false;
1155 const char *
1156 output_jump (enum rtx_code code, int inv, int length)
1158 static int x = 0;
1160 static char buf[1000];
1161 const char *pos, *neg;
1163 switch (code)
1165 case EQ: pos = "beq", neg = "bne"; break;
1166 case NE: pos = "bne", neg = "beq"; break;
1167 case GT: pos = "bgt", neg = "ble"; break;
1168 case GTU: pos = "bhi", neg = "blos"; break;
1169 case LT: pos = "blt", neg = "bge"; break;
1170 case LTU: pos = "blo", neg = "bhis"; break;
1171 case GE: pos = "bge", neg = "blt"; break;
1172 case GEU: pos = "bhis", neg = "blo"; break;
1173 case LE: pos = "ble", neg = "bgt"; break;
1174 case LEU: pos = "blos", neg = "bhi"; break;
1175 default: gcc_unreachable ();
1178 #if 0
1179 /* currently we don't need this, because the tstdf and cmpdf
1180 copy the condition code immediately, and other float operations are not
1181 yet recognized as changing the FCC - if so, then the length-cost of all
1182 jump insns increases by one, because we have to potentially copy the
1183 FCC! */
1184 if (cc_status.flags & CC_IN_FPU)
1185 output_asm_insn("cfcc", NULL);
1186 #endif
1188 switch (length)
1190 case 2:
1192 sprintf(buf, "%s %%l1", inv ? neg : pos);
1194 return buf;
1196 case 6:
1198 sprintf(buf, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv ? pos : neg, x, x);
1200 x++;
1202 return buf;
1204 default:
1206 gcc_unreachable ();
1211 void
1212 notice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED)
1214 if (GET_CODE (SET_DEST (exp)) == CC0)
1216 cc_status.flags = 0;
1217 cc_status.value1 = SET_DEST (exp);
1218 cc_status.value2 = SET_SRC (exp);
1221 if (GET_MODE(SET_SRC(exp)) == DFmode)
1222 cc_status.flags |= CC_IN_FPU;
1225 else if ((GET_CODE (SET_DEST (exp)) == REG
1226 || GET_CODE (SET_DEST (exp)) == MEM)
1227 && GET_CODE (SET_SRC (exp)) != PC
1228 && (GET_MODE (SET_DEST(exp)) == HImode
1229 || GET_MODE (SET_DEST(exp)) == QImode)
1230 && (GET_CODE (SET_SRC(exp)) == PLUS
1231 || GET_CODE (SET_SRC(exp)) == MINUS
1232 || GET_CODE (SET_SRC(exp)) == AND
1233 || GET_CODE (SET_SRC(exp)) == IOR
1234 || GET_CODE (SET_SRC(exp)) == XOR
1235 || GET_CODE (SET_SRC(exp)) == NOT
1236 || GET_CODE (SET_SRC(exp)) == NEG
1237 || GET_CODE (SET_SRC(exp)) == REG
1238 || GET_CODE (SET_SRC(exp)) == MEM))
1240 cc_status.flags = 0;
1241 cc_status.value1 = SET_SRC (exp);
1242 cc_status.value2 = SET_DEST (exp);
1244 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1245 && cc_status.value2
1246 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1247 cc_status.value2 = 0;
1248 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
1249 && cc_status.value2
1250 && GET_CODE (cc_status.value2) == MEM)
1251 cc_status.value2 = 0;
1253 else if (GET_CODE (SET_SRC (exp)) == CALL)
1255 CC_STATUS_INIT;
1257 else if (GET_CODE (SET_DEST (exp)) == REG)
1258 /* what's this ? */
1260 if ((cc_status.value1
1261 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)))
1262 cc_status.value1 = 0;
1263 if ((cc_status.value2
1264 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)))
1265 cc_status.value2 = 0;
1267 else if (SET_DEST(exp) == pc_rtx)
1269 /* jump */
1271 else /* if (GET_CODE (SET_DEST (exp)) == MEM) */
1273 /* the last else is a bit paranoiac, but since nearly all instructions
1274 play with condition codes, it's reasonable! */
1276 CC_STATUS_INIT; /* paranoia*/
1282 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1284 rtx addr;
1286 /* Eliminate non-memory operations */
1287 if (GET_CODE (op) != MEM)
1288 return FALSE;
1290 #if 0
1291 /* dword operations really put out 2 instructions, so eliminate them. */
1292 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
1293 return FALSE;
1294 #endif
1296 /* Decode the address now. */
1298 indirection:
1300 addr = XEXP (op, 0);
1302 switch (GET_CODE (addr))
1304 case REG:
1305 /* (R0) - no extra cost */
1306 return 1;
1308 case PRE_DEC:
1309 case POST_INC:
1310 /* -(R0), (R0)+ - cheap! */
1311 return 0;
1313 case MEM:
1314 /* cheap - is encoded in addressing mode info!
1316 -- except for @(R0), which has to be @0(R0) !!! */
1318 if (GET_CODE (XEXP (addr, 0)) == REG)
1319 return 0;
1321 op=addr;
1322 goto indirection;
1324 case CONST_INT:
1325 case LABEL_REF:
1326 case CONST:
1327 case SYMBOL_REF:
1328 /* @#address - extra cost */
1329 return 0;
1331 case PLUS:
1332 /* X(R0) - extra cost */
1333 return 0;
1335 default:
1336 break;
1339 return FALSE;
1344 * output a block move:
1346 * operands[0] ... to
1347 * operands[1] ... from
1348 * operands[2] ... length
1349 * operands[3] ... alignment
1350 * operands[4] ... scratch register
1354 const char *
1355 output_block_move(rtx *operands)
1357 static int count = 0;
1358 char buf[200];
1360 if (GET_CODE(operands[2]) == CONST_INT
1361 && ! optimize_size)
1363 if (INTVAL(operands[2]) < 16
1364 && INTVAL(operands[3]) == 1)
1366 register int i;
1368 for (i = 1; i <= INTVAL(operands[2]); i++)
1369 output_asm_insn("movb (%1)+, (%0)+", operands);
1371 return "";
1373 else if (INTVAL(operands[2]) < 32)
1375 register int i;
1377 for (i = 1; i <= INTVAL(operands[2])/2; i++)
1378 output_asm_insn("mov (%1)+, (%0)+", operands);
1380 /* may I assume that moved quantity is
1381 multiple of alignment ???
1383 I HOPE SO !
1386 return "";
1390 /* can do other clever things, maybe... */
1393 if (CONSTANT_P(operands[2]) )
1395 /* just move count to scratch */
1396 output_asm_insn("mov %2, %4", operands);
1398 else
1400 /* just clobber the register */
1401 operands[4] = operands[2];
1405 /* switch over alignment */
1406 switch (INTVAL(operands[3]))
1408 case 1:
1412 movb (%1)+, (%0)+
1414 if (TARGET_45)
1415 sob %4,x
1416 else
1417 dec %4
1418 bgt x
1422 sprintf(buf, "\nmovestrhi%d:", count);
1423 output_asm_insn(buf, NULL);
1425 output_asm_insn("movb (%1)+, (%0)+", operands);
1427 if (TARGET_45)
1429 sprintf(buf, "sob %%4, movestrhi%d", count);
1430 output_asm_insn(buf, operands);
1432 else
1434 output_asm_insn("dec %4", operands);
1436 sprintf(buf, "bgt movestrhi%d", count);
1437 output_asm_insn(buf, NULL);
1440 count ++;
1441 break;
1443 case 2:
1446 asr %4
1450 mov (%1)+, (%0)+
1452 if (TARGET_45)
1453 sob %4, x
1454 else
1455 dec %4
1456 bgt x
1459 generate_compact_code:
1461 output_asm_insn("asr %4", operands);
1463 sprintf(buf, "\nmovestrhi%d:", count);
1464 output_asm_insn(buf, NULL);
1466 output_asm_insn("mov (%1)+, (%0)+", operands);
1468 if (TARGET_45)
1470 sprintf(buf, "sob %%4, movestrhi%d", count);
1471 output_asm_insn(buf, operands);
1473 else
1475 output_asm_insn("dec %4", operands);
1477 sprintf(buf, "bgt movestrhi%d", count);
1478 output_asm_insn(buf, NULL);
1481 count ++;
1482 break;
1484 case 4:
1488 asr %4
1489 asr %4
1493 mov (%1)+, (%0)+
1494 mov (%1)+, (%0)+
1496 if (TARGET_45)
1497 sob %4, x
1498 else
1499 dec %4
1500 bgt x
1503 if (optimize_size)
1504 goto generate_compact_code;
1506 output_asm_insn("asr %4", operands);
1507 output_asm_insn("asr %4", operands);
1509 sprintf(buf, "\nmovestrhi%d:", count);
1510 output_asm_insn(buf, NULL);
1512 output_asm_insn("mov (%1)+, (%0)+", operands);
1513 output_asm_insn("mov (%1)+, (%0)+", operands);
1515 if (TARGET_45)
1517 sprintf(buf, "sob %%4, movestrhi%d", count);
1518 output_asm_insn(buf, operands);
1520 else
1522 output_asm_insn("dec %4", operands);
1524 sprintf(buf, "bgt movestrhi%d", count);
1525 output_asm_insn(buf, NULL);
1528 count ++;
1529 break;
1531 default:
1535 asr %4
1536 asr %4
1537 asr %4
1541 mov (%1)+, (%0)+
1542 mov (%1)+, (%0)+
1543 mov (%1)+, (%0)+
1544 mov (%1)+, (%0)+
1546 if (TARGET_45)
1547 sob %4, x
1548 else
1549 dec %4
1550 bgt x
1554 if (optimize_size)
1555 goto generate_compact_code;
1557 output_asm_insn("asr %4", operands);
1558 output_asm_insn("asr %4", operands);
1559 output_asm_insn("asr %4", operands);
1561 sprintf(buf, "\nmovestrhi%d:", count);
1562 output_asm_insn(buf, NULL);
1564 output_asm_insn("mov (%1)+, (%0)+", operands);
1565 output_asm_insn("mov (%1)+, (%0)+", operands);
1566 output_asm_insn("mov (%1)+, (%0)+", operands);
1567 output_asm_insn("mov (%1)+, (%0)+", operands);
1569 if (TARGET_45)
1571 sprintf(buf, "sob %%4, movestrhi%d", count);
1572 output_asm_insn(buf, operands);
1574 else
1576 output_asm_insn("dec %4", operands);
1578 sprintf(buf, "bgt movestrhi%d", count);
1579 output_asm_insn(buf, NULL);
1582 count ++;
1583 break;
1589 return "";
1592 /* This function checks whether a real value can be encoded as
1593 a literal, i.e., addressing mode 27. In that mode, real values
1594 are one word values, so the remaining 48 bits have to be zero. */
1596 legitimate_const_double_p (rtx address)
1598 REAL_VALUE_TYPE r;
1599 long sval[2];
1600 REAL_VALUE_FROM_CONST_DOUBLE (r, address);
1601 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
1602 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1603 return 1;
1604 return 0;
1607 /* Implement CANNOT_CHANGE_MODE_CLASS. */
1608 bool
1609 pdp11_cannot_change_mode_class (enum machine_mode from,
1610 enum machine_mode to,
1611 enum reg_class rclass)
1613 /* Also, FPU registers contain a whole float value and the parts of
1614 it are not separately accessible.
1616 So we disallow all mode changes involving FPRs. */
1617 if (FLOAT_MODE_P (from) != FLOAT_MODE_P (to))
1618 return true;
1620 return reg_classes_intersect_p (FPU_REGS, rclass);
1623 /* TARGET_PREFERRED_RELOAD_CLASS
1625 Given an rtx X being reloaded into a reg required to be
1626 in class CLASS, return the class of reg to actually use.
1627 In general this is just CLASS; but on some machines
1628 in some cases it is preferable to use a more restrictive class.
1630 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1632 static reg_class_t
1633 pdp11_preferred_reload_class (rtx x, reg_class_t class)
1635 if (class == FPU_REGS)
1636 return LOAD_FPU_REGS;
1637 if (class == ALL_REGS)
1639 if (FLOAT_MODE_P (GET_MODE (x)))
1640 return LOAD_FPU_REGS;
1641 else
1642 return GENERAL_REGS;
1644 return class;
1647 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1649 Given an rtx X being reloaded into a reg required to be
1650 in class CLASS, return the class of reg to actually use.
1651 In general this is just CLASS; but on some machines
1652 in some cases it is preferable to use a more restrictive class.
1654 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1656 static reg_class_t
1657 pdp11_preferred_output_reload_class (rtx x, reg_class_t class)
1659 if (class == FPU_REGS)
1660 return LOAD_FPU_REGS;
1661 if (class == ALL_REGS)
1663 if (FLOAT_MODE_P (GET_MODE (x)))
1664 return LOAD_FPU_REGS;
1665 else
1666 return GENERAL_REGS;
1668 return class;
1672 /* TARGET_SECONDARY_RELOAD.
1674 FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1675 intermediate register (AC0-AC3: LOAD_FPU_REGS). Everything else
1676 can be loade/stored directly. */
1677 reg_class_t
1678 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED,
1679 rtx x,
1680 reg_class_t reload_class,
1681 enum machine_mode reload_mode ATTRIBUTE_UNUSED,
1682 secondary_reload_info *sri ATTRIBUTE_UNUSED)
1684 if (reload_class != NO_LOAD_FPU_REGS || GET_CODE (x) != REG ||
1685 REGNO_REG_CLASS (REGNO (x)) == LOAD_FPU_REGS)
1686 return NO_REGS;
1688 return LOAD_FPU_REGS;
1691 /* Target routine to check if register to register move requires memory.
1693 The answer is yes if we're going between general register and FPU
1694 registers. The mode doesn't matter in making this check.
1696 bool
1697 pdp11_secondary_memory_needed (reg_class_t c1, reg_class_t c2,
1698 enum machine_mode mode ATTRIBUTE_UNUSED)
1700 int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS ||
1701 c1 == FPU_REGS);
1702 int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS ||
1703 c2 == FPU_REGS);
1705 return (fromfloat != tofloat);
1709 /* A copy of output_addr_const modified for pdp11 expression syntax.
1710 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1711 use, and for debugging output, which we don't support with this port either.
1712 So this copy should get called whenever needed.
1714 void
1715 output_addr_const_pdp11 (FILE *file, rtx x)
1717 char buf[256];
1719 restart:
1720 switch (GET_CODE (x))
1722 case PC:
1723 gcc_assert (flag_pic);
1724 putc ('.', file);
1725 break;
1727 case SYMBOL_REF:
1728 assemble_name (file, XSTR (x, 0));
1729 break;
1731 case LABEL_REF:
1732 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1733 assemble_name (file, buf);
1734 break;
1736 case CODE_LABEL:
1737 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1738 assemble_name (file, buf);
1739 break;
1741 case CONST_INT:
1742 /* Should we check for constants which are too big? Maybe cutting
1743 them off to 16 bits is OK? */
1744 fprintf (file, "%#ho", (unsigned short) INTVAL (x));
1745 break;
1747 case CONST:
1748 /* This used to output parentheses around the expression,
1749 but that does not work on the 386 (either ATT or BSD assembler). */
1750 output_addr_const_pdp11 (file, XEXP (x, 0));
1751 break;
1753 case CONST_DOUBLE:
1754 if (GET_MODE (x) == VOIDmode)
1756 /* We can use %o if the number is one word and positive. */
1757 gcc_assert (!CONST_DOUBLE_HIGH (x));
1758 fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
1760 else
1761 /* We can't handle floating point constants;
1762 PRINT_OPERAND must handle them. */
1763 output_operand_lossage ("floating constant misused");
1764 break;
1766 case PLUS:
1767 /* Some assemblers need integer constants to appear last (e.g. masm). */
1768 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1770 output_addr_const_pdp11 (file, XEXP (x, 1));
1771 if (INTVAL (XEXP (x, 0)) >= 0)
1772 fprintf (file, "+");
1773 output_addr_const_pdp11 (file, XEXP (x, 0));
1775 else
1777 output_addr_const_pdp11 (file, XEXP (x, 0));
1778 if (INTVAL (XEXP (x, 1)) >= 0)
1779 fprintf (file, "+");
1780 output_addr_const_pdp11 (file, XEXP (x, 1));
1782 break;
1784 case MINUS:
1785 /* Avoid outputting things like x-x or x+5-x,
1786 since some assemblers can't handle that. */
1787 x = simplify_subtraction (x);
1788 if (GET_CODE (x) != MINUS)
1789 goto restart;
1791 output_addr_const_pdp11 (file, XEXP (x, 0));
1792 fprintf (file, "-");
1793 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1794 && INTVAL (XEXP (x, 1)) < 0)
1796 fprintf (file, targetm.asm_out.open_paren);
1797 output_addr_const_pdp11 (file, XEXP (x, 1));
1798 fprintf (file, targetm.asm_out.close_paren);
1800 else
1801 output_addr_const_pdp11 (file, XEXP (x, 1));
1802 break;
1804 case ZERO_EXTEND:
1805 case SIGN_EXTEND:
1806 output_addr_const_pdp11 (file, XEXP (x, 0));
1807 break;
1809 default:
1810 output_operand_lossage ("invalid expression as operand");
1814 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1816 static bool
1817 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1819 /* Should probably return DImode and DFmode in memory, lest
1820 we fill up all regs!
1822 have to, else we crash - exception: maybe return result in
1823 ac0 if DFmode and FPU present - compatibility problem with
1824 libraries for non-floating point.... */
1825 return (TYPE_MODE (type) == DImode
1826 || (FLOAT_MODE_P (TYPE_MODE (type)) && ! TARGET_AC0));
1829 /* Worker function for TARGET_FUNCTION_VALUE.
1831 On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! ) */
1833 static rtx
1834 pdp11_function_value (const_tree valtype,
1835 const_tree fntype_or_decl ATTRIBUTE_UNUSED,
1836 bool outgoing ATTRIBUTE_UNUSED)
1838 return gen_rtx_REG (TYPE_MODE (valtype),
1839 BASE_RETURN_VALUE_REG(TYPE_MODE(valtype)));
1842 /* Worker function for TARGET_LIBCALL_VALUE. */
1844 static rtx
1845 pdp11_libcall_value (enum machine_mode mode,
1846 const_rtx fun ATTRIBUTE_UNUSED)
1848 return gen_rtx_REG (mode, BASE_RETURN_VALUE_REG(mode));
1851 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1853 On the pdp, the first "output" reg is the only register thus used.
1855 maybe ac0 ? - as option someday! */
1857 static bool
1858 pdp11_function_value_regno_p (const unsigned int regno)
1860 return (regno == 0) || (TARGET_AC0 && (regno == 8));
1863 /* Worker function for TARGET_TRAMPOLINE_INIT.
1865 trampoline - how should i do it in separate i+d ?
1866 have some allocate_trampoline magic???
1868 the following should work for shared I/D:
1870 MOV #STATIC, $4 01270Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
1871 JMP @#FUNCTION 000137 0x0000 <- FUNCTION
1874 static void
1875 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1877 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
1878 rtx mem;
1880 gcc_assert (!TARGET_SPLIT);
1882 mem = adjust_address (m_tramp, HImode, 0);
1883 emit_move_insn (mem, GEN_INT (012700+STATIC_CHAIN_REGNUM));
1884 mem = adjust_address (m_tramp, HImode, 2);
1885 emit_move_insn (mem, chain_value);
1886 mem = adjust_address (m_tramp, HImode, 4);
1887 emit_move_insn (mem, GEN_INT (000137));
1888 emit_move_insn (mem, fnaddr);
1891 /* Worker function for TARGET_FUNCTION_ARG.
1893 Determine where to put an argument to a function.
1894 Value is zero to push the argument on the stack,
1895 or a hard register in which to store the argument.
1897 MODE is the argument's machine mode.
1898 TYPE is the data type of the argument (as a tree).
1899 This is null for libcalls where that information may
1900 not be available.
1901 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1902 the preceding args and about the function being called.
1903 NAMED is nonzero if this argument is a named parameter
1904 (otherwise it is an extra parameter matching an ellipsis). */
1906 static rtx
1907 pdp11_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
1908 enum machine_mode mode ATTRIBUTE_UNUSED,
1909 const_tree type ATTRIBUTE_UNUSED,
1910 bool named ATTRIBUTE_UNUSED)
1912 return NULL_RTX;
1915 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
1917 Update the data in CUM to advance over an argument of mode MODE and
1918 data type TYPE. (TYPE is null for libcalls where that information
1919 may not be available.) */
1921 static void
1922 pdp11_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1923 const_tree type, bool named ATTRIBUTE_UNUSED)
1925 *cum += (mode != BLKmode
1926 ? GET_MODE_SIZE (mode)
1927 : int_size_in_bytes (type));
1930 struct gcc_target targetm = TARGET_INITIALIZER;