Fix version check for ATTRIBUTE_GCC_DUMP_PRINTF
[official-gcc.git] / gcc / config / pdp11 / pdp11.c
blob62c653fd8a114256dba7f5bae64a9c4a002e65ac
1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #define IN_TARGET_CODE 1
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32 #include "df.h"
33 #include "memmodel.h"
34 #include "tm_p.h"
35 #include "insn-config.h"
36 #include "insn-attr.h"
37 #include "regs.h"
38 #include "emit-rtl.h"
39 #include "recog.h"
40 #include "conditions.h"
41 #include "output.h"
42 #include "stor-layout.h"
43 #include "varasm.h"
44 #include "calls.h"
45 #include "expr.h"
46 #include "builtins.h"
47 #include "dbxout.h"
48 #include "expmed.h"
50 /* This file should be included last. */
51 #include "target-def.h"
53 /* this is the current value returned by the macro FIRST_PARM_OFFSET
54 defined in tm.h */
55 int current_first_parm_offset;
57 /* Routines to encode/decode pdp11 floats */
58 static void encode_pdp11_f (const struct real_format *fmt,
59 long *, const REAL_VALUE_TYPE *);
60 static void decode_pdp11_f (const struct real_format *,
61 REAL_VALUE_TYPE *, const long *);
62 static void encode_pdp11_d (const struct real_format *fmt,
63 long *, const REAL_VALUE_TYPE *);
64 static void decode_pdp11_d (const struct real_format *,
65 REAL_VALUE_TYPE *, const long *);
67 /* These two are taken from the corresponding vax descriptors
68 in real.c, changing only the encode/decode routine pointers. */
69 const struct real_format pdp11_f_format =
71 encode_pdp11_f,
72 decode_pdp11_f,
74 24,
75 24,
76 -127,
77 127,
78 15,
79 15,
81 false,
82 false,
83 false,
84 false,
85 false,
86 false,
87 false,
88 false,
89 "pdp11_f"
92 const struct real_format pdp11_d_format =
94 encode_pdp11_d,
95 decode_pdp11_d,
97 56,
98 56,
99 -127,
100 127,
104 false,
105 false,
106 false,
107 false,
108 false,
109 false,
110 false,
111 false,
112 "pdp11_d"
115 static void
116 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
117 const REAL_VALUE_TYPE *r)
119 (*vax_f_format.encode) (fmt, buf, r);
120 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
123 static void
124 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
125 REAL_VALUE_TYPE *r, const long *buf)
127 long tbuf;
128 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
129 (*vax_f_format.decode) (fmt, r, &tbuf);
132 static void
133 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
134 const REAL_VALUE_TYPE *r)
136 (*vax_d_format.encode) (fmt, buf, r);
137 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
138 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
141 static void
142 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
143 REAL_VALUE_TYPE *r, const long *buf)
145 long tbuf[2];
146 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
147 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
148 (*vax_d_format.decode) (fmt, r, tbuf);
151 static const char *singlemove_string (rtx *);
152 static bool pdp11_assemble_integer (rtx, unsigned int, int);
153 static bool pdp11_rtx_costs (rtx, machine_mode, int, int, int *, bool);
154 static int pdp11_addr_cost (rtx, machine_mode, addr_space_t, bool);
155 static int pdp11_insn_cost (rtx_insn *insn, bool speed);
156 static rtx_insn *pdp11_md_asm_adjust (vec<rtx> &, vec<rtx> &,
157 vec<const char *> &,
158 vec<rtx> &, HARD_REG_SET &);
159 static bool pdp11_return_in_memory (const_tree, const_tree);
160 static rtx pdp11_function_value (const_tree, const_tree, bool);
161 static rtx pdp11_libcall_value (machine_mode, const_rtx);
162 static bool pdp11_function_value_regno_p (const unsigned int);
163 static void pdp11_trampoline_init (rtx, tree, rtx);
164 static rtx pdp11_function_arg (cumulative_args_t, machine_mode,
165 const_tree, bool);
166 static void pdp11_function_arg_advance (cumulative_args_t,
167 machine_mode, const_tree, bool);
168 static void pdp11_conditional_register_usage (void);
169 static bool pdp11_legitimate_constant_p (machine_mode, rtx);
171 static bool pdp11_scalar_mode_supported_p (scalar_mode);
173 /* Initialize the GCC target structure. */
174 #undef TARGET_ASM_BYTE_OP
175 #define TARGET_ASM_BYTE_OP NULL
176 #undef TARGET_ASM_ALIGNED_HI_OP
177 #define TARGET_ASM_ALIGNED_HI_OP NULL
178 #undef TARGET_ASM_ALIGNED_SI_OP
179 #define TARGET_ASM_ALIGNED_SI_OP NULL
180 #undef TARGET_ASM_INTEGER
181 #define TARGET_ASM_INTEGER pdp11_assemble_integer
183 /* These two apply to Unix and GNU assembler; for DEC, they are
184 overridden during option processing. */
185 #undef TARGET_ASM_OPEN_PAREN
186 #define TARGET_ASM_OPEN_PAREN "["
187 #undef TARGET_ASM_CLOSE_PAREN
188 #define TARGET_ASM_CLOSE_PAREN "]"
190 #undef TARGET_RTX_COSTS
191 #define TARGET_RTX_COSTS pdp11_rtx_costs
193 #undef TARGET_ADDRESS_COST
194 #define TARGET_ADDRESS_COST pdp11_addr_cost
196 #undef TARGET_INSN_COST
197 #define TARGET_INSN_COST pdp11_insn_cost
199 #undef TARGET_MD_ASM_ADJUST
200 #define TARGET_MD_ASM_ADJUST pdp11_md_asm_adjust
202 #undef TARGET_FUNCTION_ARG
203 #define TARGET_FUNCTION_ARG pdp11_function_arg
204 #undef TARGET_FUNCTION_ARG_ADVANCE
205 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
207 #undef TARGET_RETURN_IN_MEMORY
208 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
210 #undef TARGET_FUNCTION_VALUE
211 #define TARGET_FUNCTION_VALUE pdp11_function_value
212 #undef TARGET_LIBCALL_VALUE
213 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
214 #undef TARGET_FUNCTION_VALUE_REGNO_P
215 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
217 #undef TARGET_TRAMPOLINE_INIT
218 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
220 #undef TARGET_SECONDARY_RELOAD
221 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
223 #undef TARGET_REGISTER_MOVE_COST
224 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
226 #undef TARGET_PREFERRED_RELOAD_CLASS
227 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
229 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
230 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
232 #undef TARGET_LRA_P
233 #define TARGET_LRA_P hook_bool_void_false
235 #undef TARGET_LEGITIMATE_ADDRESS_P
236 #define TARGET_LEGITIMATE_ADDRESS_P pdp11_legitimate_address_p
238 #undef TARGET_CONDITIONAL_REGISTER_USAGE
239 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
241 #undef TARGET_OPTION_OVERRIDE
242 #define TARGET_OPTION_OVERRIDE pdp11_option_override
244 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
245 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
247 #undef TARGET_ASM_OUTPUT_IDENT
248 #define TARGET_ASM_OUTPUT_IDENT pdp11_output_ident
250 #undef TARGET_ASM_FUNCTION_SECTION
251 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
253 #undef TARGET_ASM_NAMED_SECTION
254 #define TARGET_ASM_NAMED_SECTION pdp11_asm_named_section
256 #undef TARGET_ASM_INIT_SECTIONS
257 #define TARGET_ASM_INIT_SECTIONS pdp11_asm_init_sections
259 #undef TARGET_ASM_FILE_START
260 #define TARGET_ASM_FILE_START pdp11_file_start
262 #undef TARGET_ASM_FILE_END
263 #define TARGET_ASM_FILE_END pdp11_file_end
265 #undef TARGET_PRINT_OPERAND
266 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
268 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
269 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
271 #undef TARGET_LEGITIMATE_CONSTANT_P
272 #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
274 #undef TARGET_SCALAR_MODE_SUPPORTED_P
275 #define TARGET_SCALAR_MODE_SUPPORTED_P pdp11_scalar_mode_supported_p
277 #undef TARGET_HARD_REGNO_NREGS
278 #define TARGET_HARD_REGNO_NREGS pdp11_hard_regno_nregs
280 #undef TARGET_HARD_REGNO_MODE_OK
281 #define TARGET_HARD_REGNO_MODE_OK pdp11_hard_regno_mode_ok
283 #undef TARGET_MODES_TIEABLE_P
284 #define TARGET_MODES_TIEABLE_P pdp11_modes_tieable_p
286 #undef TARGET_SECONDARY_MEMORY_NEEDED
287 #define TARGET_SECONDARY_MEMORY_NEEDED pdp11_secondary_memory_needed
289 #undef TARGET_CAN_CHANGE_MODE_CLASS
290 #define TARGET_CAN_CHANGE_MODE_CLASS pdp11_can_change_mode_class
292 #undef TARGET_INVALID_WITHIN_DOLOOP
293 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
295 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
296 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
298 /* A helper function to determine if REGNO should be saved in the
299 current function's stack frame. */
301 static inline bool
302 pdp11_saved_regno (unsigned regno)
304 return !call_used_regs[regno] && df_regs_ever_live_p (regno);
307 /* Expand the function prologue. */
309 void
310 pdp11_expand_prologue (void)
312 HOST_WIDE_INT fsize = get_frame_size ();
313 unsigned regno;
314 rtx x, via_ac = NULL;
316 /* If we are outputting code for main, the switch FPU to the
317 right mode if TARGET_FPU. */
318 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
320 emit_insn (gen_setd ());
321 emit_insn (gen_seti ());
324 if (frame_pointer_needed)
326 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
327 x = gen_frame_mem (Pmode, x);
328 emit_move_insn (x, hard_frame_pointer_rtx);
330 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
333 /* Make frame. */
334 if (fsize)
336 emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
337 GEN_INT (-fsize)));
339 /* Prevent frame references via the frame pointer from being
340 scheduled before the frame is allocated. */
341 if (frame_pointer_needed)
342 emit_insn (gen_blockage ());
345 /* Save CPU registers. */
346 for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++)
347 if (pdp11_saved_regno (regno)
348 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
350 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
351 x = gen_frame_mem (Pmode, x);
352 emit_move_insn (x, gen_rtx_REG (Pmode, regno));
355 /* Save FPU registers. */
356 for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
357 if (pdp11_saved_regno (regno))
359 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
360 x = gen_frame_mem (DFmode, x);
361 via_ac = gen_rtx_REG (DFmode, regno);
362 emit_move_insn (x, via_ac);
365 /* ??? Maybe make ac4, ac5 call used regs?? */
366 for (regno = AC4_REGNUM; regno <= AC5_REGNUM; regno++)
367 if (pdp11_saved_regno (regno))
369 gcc_assert (via_ac != NULL);
370 emit_move_insn (via_ac, gen_rtx_REG (DFmode, regno));
372 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
373 x = gen_frame_mem (DFmode, x);
374 emit_move_insn (x, via_ac);
378 /* The function epilogue should not depend on the current stack pointer!
379 It should use the frame pointer only. This is mandatory because
380 of alloca; we also take advantage of it to omit stack adjustments
381 before returning. */
383 /* Maybe we can make leaf functions faster by switching to the
384 second register file - this way we don't have to save regs!
385 leaf functions are ~ 50% of all functions (dynamically!)
387 set/clear bit 11 (dec. 2048) of status word for switching register files -
388 but how can we do this? the pdp11/45 manual says bit may only
389 be set (p.24), but not cleared!
391 switching to kernel is probably more expensive, so we'll leave it
392 like this and not use the second set of registers...
394 maybe as option if you want to generate code for kernel mode? */
396 void
397 pdp11_expand_epilogue (void)
399 HOST_WIDE_INT fsize = get_frame_size ();
400 unsigned regno;
401 rtx x, reg, via_ac = NULL;
403 if (pdp11_saved_regno (AC4_REGNUM) || pdp11_saved_regno (AC5_REGNUM))
405 /* Find a temporary with which to restore AC4/5. */
406 for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
407 if (pdp11_saved_regno (regno))
409 via_ac = gen_rtx_REG (DFmode, regno);
410 break;
414 /* If possible, restore registers via pops. */
415 if (!frame_pointer_needed || crtl->sp_is_unchanging)
417 /* Restore registers via pops. */
419 for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
420 if (pdp11_saved_regno (regno))
422 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
423 x = gen_frame_mem (DFmode, x);
424 reg = gen_rtx_REG (DFmode, regno);
426 if (LOAD_FPU_REG_P (regno))
427 emit_move_insn (reg, x);
428 else
430 emit_move_insn (via_ac, x);
431 emit_move_insn (reg, via_ac);
435 for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
436 if (pdp11_saved_regno (regno)
437 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
439 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
440 x = gen_frame_mem (Pmode, x);
441 emit_move_insn (gen_rtx_REG (Pmode, regno), x);
444 else
446 /* Restore registers via moves. */
447 /* ??? If more than a few registers need to be restored, it's smaller
448 to generate a pointer through which we can emit pops. Consider
449 that moves cost 2*NREG words and pops cost NREG+3 words. This
450 means that the crossover is NREG=3.
452 Possible registers to use are:
453 (1) The first call-saved general register. This register will
454 be restored with the last pop.
455 (2) R1, if it's not used as a return register.
456 (3) FP itself. This option may result in +4 words, since we
457 may need two add imm,rn instructions instead of just one.
458 This also has the downside that we're not representing
459 the unwind info in any way, so during the epilogue the
460 debugger may get lost. */
462 HOST_WIDE_INT ofs = -pdp11_sp_frame_offset ();
464 for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
465 if (pdp11_saved_regno (regno))
467 x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
468 x = gen_frame_mem (DFmode, x);
469 reg = gen_rtx_REG (DFmode, regno);
471 if (LOAD_FPU_REG_P (regno))
472 emit_move_insn (reg, x);
473 else
475 emit_move_insn (via_ac, x);
476 emit_move_insn (reg, via_ac);
478 ofs += 8;
481 for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
482 if (pdp11_saved_regno (regno)
483 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
485 x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
486 x = gen_frame_mem (Pmode, x);
487 emit_move_insn (gen_rtx_REG (Pmode, regno), x);
488 ofs += 2;
492 /* Deallocate the stack frame. */
493 if (fsize)
495 /* Prevent frame references via any pointer from being
496 scheduled after the frame is deallocated. */
497 emit_insn (gen_blockage ());
499 if (frame_pointer_needed)
501 /* We can deallocate the frame with a single move. */
502 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
504 else
505 emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
506 GEN_INT (fsize)));
509 if (frame_pointer_needed)
511 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
512 x = gen_frame_mem (Pmode, x);
513 emit_move_insn (hard_frame_pointer_rtx, x);
516 emit_jump_insn (gen_return ());
519 /* Return the best assembler insn template
520 for moving operands[1] into operands[0] as a fullword. */
521 static const char *
522 singlemove_string (rtx *operands)
524 if (operands[1] != const0_rtx)
525 return "mov\t%1,%0";
527 return "clr\t%0";
531 /* Expand multi-word operands (SImode or DImode) into the 2 or 4
532 corresponding HImode operands. The number of operands is given
533 as the third argument, and the required order of the parts as
534 the fourth argument. */
535 bool
536 pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
537 pdp11_action *action, pdp11_partorder order)
539 int words, op, w, i, sh;
540 pdp11_partorder useorder;
541 bool sameoff = false;
542 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype;
543 long sval[2];
545 words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
547 /* If either piece order is accepted and one is pre-decrement
548 while the other is post-increment, set order to be high order
549 word first. That will force the pre-decrement to be turned
550 into a pointer adjust, then offset addressing.
551 Otherwise, if either operand uses pre-decrement, that means
552 the order is low order first.
553 Otherwise, if both operands are registers and destination is
554 higher than source and they overlap, do low order word (highest
555 register number) first. */
556 useorder = either;
557 if (opcount == 2)
559 if (!REG_P (operands[0]) && !REG_P (operands[1]) &&
560 !(CONSTANT_P (operands[1]) ||
561 GET_CODE (operands[1]) == CONST_DOUBLE) &&
562 ((GET_CODE (XEXP (operands[0], 0)) == POST_INC &&
563 GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ||
564 (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC &&
565 GET_CODE (XEXP (operands[1], 0)) == POST_INC)))
566 useorder = big;
567 else if ((!REG_P (operands[0]) &&
568 GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ||
569 (!REG_P (operands[1]) &&
570 !(CONSTANT_P (operands[1]) ||
571 GET_CODE (operands[1]) == CONST_DOUBLE) &&
572 GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
573 useorder = little;
574 else if (REG_P (operands[0]) && REG_P (operands[1]) &&
575 REGNO (operands[0]) > REGNO (operands[1]) &&
576 REGNO (operands[0]) < REGNO (operands[1]) + words)
577 useorder = little;
579 /* Check for source == offset from register and dest == push of
580 the same register. In that case, we have to use the same
581 offset (the one for the low order word) for all words, because
582 the push increases the offset to each source word.
583 In theory there are other cases like this, for example dest == pop,
584 but those don't occur in real life so ignore those. */
585 if (GET_CODE (operands[0]) == MEM
586 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
587 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
588 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
589 sameoff = true;
592 /* If the caller didn't specify order, use the one we computed,
593 or high word first if we don't care either. If the caller did
594 specify, verify we don't have a problem with that order.
595 (If it matters to the caller, constraints need to be used to
596 ensure this case doesn't occur). */
597 if (order == either)
598 order = (useorder == either) ? big : useorder;
599 else
600 gcc_assert (useorder == either || useorder == order);
603 for (op = 0; op < opcount; op++)
605 /* First classify the operand. */
606 if (REG_P (operands[op]))
607 optype = REGOP;
608 else if (CONSTANT_P (operands[op])
609 || GET_CODE (operands[op]) == CONST_DOUBLE)
610 optype = CNSTOP;
611 else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
612 optype = POPOP;
613 else if (GET_CODE (XEXP (operands[op], 0)) == PRE_DEC)
614 optype = PUSHOP;
615 else if (!reload_in_progress || offsettable_memref_p (operands[op]))
616 optype = OFFSOP;
617 else if (GET_CODE (operands[op]) == MEM)
618 optype = MEMOP;
619 else
620 optype = RNDOP;
622 /* Check for the cases that the operand constraints are not
623 supposed to allow to happen. Return failure for such cases. */
624 if (optype == RNDOP)
625 return false;
627 if (action != NULL)
628 action[op] = no_action;
630 /* If the operand uses pre-decrement addressing but we
631 want to get the parts high order first,
632 decrement the former register explicitly
633 and change the operand into ordinary indexing. */
634 if (optype == PUSHOP && order == big)
636 gcc_assert (action != NULL);
637 action[op] = dec_before;
638 operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
639 XEXP (XEXP (operands[op], 0), 0));
640 optype = OFFSOP;
642 /* If the operand uses post-increment mode but we want
643 to get the parts low order first, change the operand
644 into ordinary indexing and remember to increment
645 the register explicitly when we're done. */
646 else if (optype == POPOP && order == little)
648 gcc_assert (action != NULL);
649 action[op] = inc_after;
650 operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
651 XEXP (XEXP (operands[op], 0), 0));
652 optype = OFFSOP;
655 if (GET_CODE (operands[op]) == CONST_DOUBLE)
656 REAL_VALUE_TO_TARGET_DOUBLE
657 (*CONST_DOUBLE_REAL_VALUE (operands[op]), sval);
659 for (i = 0; i < words; i++)
661 if (order == big)
662 w = i;
663 else if (sameoff)
664 w = words - 1;
665 else
666 w = words - 1 - i;
668 /* Set the output operand to be word "w" of the input. */
669 if (optype == REGOP)
670 exops[i][op] = gen_rtx_REG (HImode, REGNO (operands[op]) + w);
671 else if (optype == OFFSOP)
672 exops[i][op] = adjust_address (operands[op], HImode, w * 2);
673 else if (optype == CNSTOP)
675 if (GET_CODE (operands[op]) == CONST_DOUBLE)
677 sh = 16 - (w & 1) * 16;
678 exops[i][op] = gen_rtx_CONST_INT (HImode, (sval[w / 2] >> sh) & 0xffff);
680 else
682 sh = ((words - 1 - w) * 16);
683 exops[i][op] = gen_rtx_CONST_INT (HImode, trunc_int_for_mode (INTVAL(operands[op]) >> sh, HImode));
686 else
687 exops[i][op] = operands[op];
690 return true;
693 /* Output assembler code to perform a multiple-word move insn
694 with operands OPERANDS. This moves 2 or 4 words depending
695 on the machine mode of the operands. */
697 const char *
698 output_move_multiple (rtx *operands)
700 rtx exops[4][2];
701 pdp11_action action[2];
702 int i, words;
704 words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
706 pdp11_expand_operands (operands, exops, 2, action, either);
708 /* Check for explicit decrement before. */
709 if (action[0] == dec_before)
711 operands[0] = XEXP (operands[0], 0);
712 output_asm_insn ("sub\t%#4,%0", operands);
714 if (action[1] == dec_before)
716 operands[1] = XEXP (operands[1], 0);
717 output_asm_insn ("sub\t%#4,%1", operands);
720 /* Do the words. */
721 for (i = 0; i < words; i++)
722 output_asm_insn (singlemove_string (exops[i]), exops[i]);
724 /* Check for increment after. */
725 if (action[0] == inc_after)
727 operands[0] = XEXP (operands[0], 0);
728 output_asm_insn ("add\t%#4,%0", operands);
730 if (action[1] == inc_after)
732 operands[1] = XEXP (operands[1], 0);
733 output_asm_insn ("add\t%#4,%1", operands);
736 return "";
739 /* Build an internal label. */
740 void
741 pdp11_gen_int_label (char *label, const char *prefix, int num)
743 if (TARGET_DEC_ASM)
744 /* +1 because GCC numbers labels starting at zero. */
745 sprintf (label, "*%lu$", num + 1);
746 else
747 sprintf (label, "*%s_%lu", prefix, num);
750 /* Output an ascii string. */
751 void
752 output_ascii (FILE *file, const char *p, int size)
754 int i, c;
755 const char *pseudo = "\t.ascii\t";
756 bool delim = false;
758 if (TARGET_DEC_ASM)
760 if (p[size - 1] == '\0')
762 pseudo = "\t.asciz\t";
763 size--;
765 fputs (pseudo, file);
766 for (i = 0; i < size; i++)
768 c = *p++ & 0xff;
769 if (c < 32 || c == '"' || c > 126)
771 if (delim)
772 putc ('"', file);
773 fprintf (file, "<%o%>", c);
774 delim = false;
776 else
778 if (!delim)
779 putc ('"', file);
780 delim = true;
781 putc (c, file);
784 if (delim)
785 putc ('"', file);
786 putc ('\n', file);
788 else
790 fprintf (file, "\t.byte ");
792 for (i = 0; i < size; i++)
794 fprintf (file, "%#o", *p++ & 0xff);
795 if (i < size - 1)
796 putc (',', file);
798 putc ('\n', file);
802 void
803 pdp11_asm_output_var (FILE *file, const char *name, int size,
804 int align, bool global)
806 if (align > 8)
807 fprintf (file, "\t.even\n");
808 if (global)
810 fprintf (file, ".globl ");
811 assemble_name (file, name);
813 fprintf (file, "\n");
814 assemble_name (file, name);
815 fputs (":", file);
816 ASM_OUTPUT_SKIP (file, size);
819 /* Special format operators handled here:
820 # -- output the correct immediate operand marker for the assembler
821 dialect.
822 @ -- output the correct indirect marker for the assembler dialect.
823 o -- emit a constant value as a number (not an immediate operand)
824 in octal. */
825 static void
826 pdp11_asm_print_operand (FILE *file, rtx x, int code)
828 long sval[2];
830 if (code == '#')
832 if (TARGET_DEC_ASM)
833 putc ('#', file);
834 else
835 putc ('$', file);
837 else if (code == '@')
839 if (TARGET_UNIX_ASM)
840 fprintf (file, "*");
841 else
842 fprintf (file, "@");
844 else if (GET_CODE (x) == REG)
845 fprintf (file, "%s", reg_names[REGNO (x)]);
846 else if (GET_CODE (x) == MEM)
847 output_address (GET_MODE (x), XEXP (x, 0));
848 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != SImode)
850 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), sval);
851 if (TARGET_DEC_ASM)
852 fprintf (file, "#%lo", (sval[0] >> 16) & 0xffff);
853 else
854 fprintf (file, "$%#lo", (sval[0] >> 16) & 0xffff);
856 else
858 if (code != 'o')
860 if (TARGET_DEC_ASM)
861 putc ('#', file);
862 else
863 putc ('$', file);
865 output_addr_const_pdp11 (file, x);
869 static bool
870 pdp11_asm_print_operand_punct_valid_p (unsigned char c)
872 return (c == '#' || c == '@');
875 void
876 print_operand_address (FILE *file, register rtx addr)
878 register rtx breg;
879 rtx offset;
880 int again = 0;
882 retry:
884 switch (GET_CODE (addr))
886 case MEM:
887 if (TARGET_UNIX_ASM)
888 fprintf (file, "*");
889 else
890 fprintf (file, "@");
891 addr = XEXP (addr, 0);
892 again = 1;
893 goto retry;
895 case REG:
896 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
897 break;
899 case PRE_MODIFY:
900 case PRE_DEC:
901 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
902 break;
904 case POST_MODIFY:
905 case POST_INC:
906 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
907 break;
909 case PLUS:
910 breg = 0;
911 offset = 0;
912 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
913 || GET_CODE (XEXP (addr, 0)) == MEM)
915 offset = XEXP (addr, 0);
916 addr = XEXP (addr, 1);
918 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
919 || GET_CODE (XEXP (addr, 1)) == MEM)
921 offset = XEXP (addr, 1);
922 addr = XEXP (addr, 0);
924 if (GET_CODE (addr) != PLUS)
926 else if (GET_CODE (XEXP (addr, 0)) == REG)
928 breg = XEXP (addr, 0);
929 addr = XEXP (addr, 1);
931 else if (GET_CODE (XEXP (addr, 1)) == REG)
933 breg = XEXP (addr, 1);
934 addr = XEXP (addr, 0);
936 if (GET_CODE (addr) == REG)
938 gcc_assert (breg == 0);
939 breg = addr;
940 addr = 0;
942 if (offset != 0)
944 gcc_assert (addr == 0);
945 addr = offset;
947 if (addr != 0)
948 output_addr_const_pdp11 (file, addr);
949 if (breg != 0)
951 gcc_assert (GET_CODE (breg) == REG);
952 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
954 break;
956 default:
957 if (!again && GET_CODE (addr) == CONST_INT)
959 /* Absolute (integer number) address. */
960 if (TARGET_DEC_ASM)
961 fprintf (file, "@#");
962 else if (!TARGET_UNIX_ASM)
963 fprintf (file, "@$");
965 output_addr_const_pdp11 (file, addr);
969 /* Target hook to assemble integer objects. We need to use the
970 pdp-specific version of output_addr_const. */
972 static bool
973 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
975 if (aligned_p)
976 switch (size)
978 case 1:
979 fprintf (asm_out_file, "\t.byte\t");
980 output_addr_const_pdp11 (asm_out_file, GEN_INT (INTVAL (x) & 0xff));
981 fputs ("\n", asm_out_file);
982 return true;
984 case 2:
985 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
986 output_addr_const_pdp11 (asm_out_file, x);
987 fputs ("\n", asm_out_file);
988 return true;
990 return default_assemble_integer (x, size, aligned_p);
994 /* Register to register moves are cheap if both are general
995 registers. */
996 static int
997 pdp11_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
998 reg_class_t c1, reg_class_t c2)
1000 if (((c1 == MUL_REGS || c1 == GENERAL_REGS) &&
1001 (c2 == MUL_REGS || c2 == GENERAL_REGS)))
1002 return 2;
1003 else if ((c1 >= LOAD_FPU_REGS && c1 <= FPU_REGS && c2 == LOAD_FPU_REGS) ||
1004 (c2 >= LOAD_FPU_REGS && c2 <= FPU_REGS && c1 == LOAD_FPU_REGS))
1005 return 2;
1006 else
1007 return 22;
1010 /* This tries to approximate what pdp11_insn_cost would do, but
1011 without visibility into the actual instruction being generated it's
1012 inevitably a rough approximation. */
1013 static bool
1014 pdp11_rtx_costs (rtx x, machine_mode mode, int outer_code,
1015 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
1017 const int code = GET_CODE (x);
1018 const int asize = (mode == QImode) ? 2 : GET_MODE_SIZE (mode);
1019 rtx src, dest;
1020 const char *fmt;
1022 switch (code)
1024 case CONST_INT:
1025 /* Treat -1, 0, 1 as things that are optimized as clr or dec
1026 etc. though that doesn't apply to every case. */
1027 if (INTVAL (x) >= -1 && INTVAL (x) <= 1)
1029 *total = 0;
1030 return true;
1032 /* FALL THROUGH. */
1033 case REG:
1034 case MEM:
1035 case CONST:
1036 case LABEL_REF:
1037 case SYMBOL_REF:
1038 case CONST_DOUBLE:
1039 *total = pdp11_addr_cost (x, mode, ADDR_SPACE_GENERIC, speed);
1040 return true;
1042 if (GET_RTX_LENGTH (code) == 0)
1044 if (speed)
1045 *total = 0;
1046 else
1047 *total = 2;
1048 return true;
1051 /* Pick up source and dest. We don't necessarily use the standard
1052 recursion in rtx_costs to figure the cost, because that would
1053 count the destination operand twice for three-operand insns.
1054 Also, this way we can catch special cases like move of zero, or
1055 add one. */
1056 fmt = GET_RTX_FORMAT (code);
1057 if (fmt[0] != 'e' || (GET_RTX_LENGTH (code) > 1 && fmt[1] != 'e'))
1059 if (speed)
1060 *total = 0;
1061 else
1062 *total = 2;
1063 return true;
1065 if (GET_RTX_LENGTH (code) > 1)
1066 src = XEXP (x, 1);
1067 dest = XEXP (x, 0);
1069 /* If optimizing for size, claim everything costs 2 per word, plus
1070 whatever the operands require. */
1071 if (!speed)
1072 *total = asize;
1073 else
1075 if (FLOAT_MODE_P (mode))
1077 switch (code)
1079 case MULT:
1080 case DIV:
1081 case MOD:
1082 *total = 20;
1083 break;
1085 case COMPARE:
1086 *total = 4;
1087 break;
1089 case PLUS:
1090 case MINUS:
1091 *total = 6;
1092 break;
1094 default:
1095 *total = 2;
1096 break;
1099 else
1101 /* Integer operations are scaled for SI and DI modes, though the
1102 scaling is not exactly accurate. */
1103 switch (code)
1105 case MULT:
1106 *total = 5 * asize * asize;
1107 break;
1109 case DIV:
1110 *total = 10 * asize * asize;
1111 break;
1113 case MOD:
1114 /* Fake value because it's accounted for under DIV, since we
1115 use a divmod pattern. */
1116 total = 0;
1117 break;
1119 case ASHIFT:
1120 case ASHIFTRT:
1121 case LSHIFTRT:
1122 /* This is a bit problematic because the cost depends on the
1123 shift amount. Make it <asize> for now, which is for the
1124 case of a one bit shift. */
1125 *total = asize;
1126 break;
1128 default:
1129 *total = asize;
1130 break;
1135 /* Now see if we're looking at a SET. If yes, then look at the
1136 source to see if this is a move or an arithmetic operation, and
1137 continue accordingly to handle the operands. */
1138 if (code == SET)
1140 switch (GET_CODE (src))
1142 case REG:
1143 case MEM:
1144 case CONST_INT:
1145 case CONST:
1146 case LABEL_REF:
1147 case SYMBOL_REF:
1148 case CONST_DOUBLE:
1149 /* It's a move. */
1150 *total += pdp11_addr_cost (dest, mode, ADDR_SPACE_GENERIC, speed);
1151 if (src != const0_rtx)
1152 *total += pdp11_addr_cost (src, mode, ADDR_SPACE_GENERIC, speed);
1153 return true;
1154 default:
1155 /* Not a move. Get the cost of the source operand and add
1156 that in, but not the destination operand since we're
1157 dealing with read/modify/write operands. */
1158 *total += rtx_cost (src, mode, (enum rtx_code) outer_code, 1, speed);
1159 return true;
1162 else if (code == PLUS || code == MINUS)
1164 if (GET_CODE (src) == CONST_INT &&
1165 (INTVAL (src) == 1 || INTVAL (src) == -1))
1167 *total += rtx_cost (dest, mode, (enum rtx_code) outer_code, 0, speed);
1168 return true;
1171 return false;
1174 /* Return cost of accessing the supplied operand. Registers are free.
1175 Anything else starts with a cost of two. Add to that for memory
1176 references the memory accesses of the addressing mode (if any) plus
1177 the data reference; for other operands just the memory access (if
1178 any) for the mode. */
1179 static int
1180 pdp11_addr_cost (rtx addr, machine_mode mode, addr_space_t as ATTRIBUTE_UNUSED,
1181 bool speed)
1183 int cost = 0;
1185 if (GET_CODE (addr) != REG)
1187 if (!simple_memory_operand (addr, mode))
1188 cost = 2;
1190 /* If optimizing for speed, account for the memory reference if
1191 any. */
1192 if (speed && !CONSTANT_P (addr))
1193 cost += (mode == QImode) ? 2 : GET_MODE_SIZE (mode);
1195 return cost;
1199 static int
1200 pdp11_insn_cost (rtx_insn *insn, bool speed)
1202 int base_cost, i;
1203 rtx pat, set, dest, src, src2;
1204 machine_mode mode;
1205 const char *fmt;
1206 enum rtx_code op;
1208 if (recog_memoized (insn) < 0)
1209 return 0;
1211 /* If optimizing for size, we want the insn size. */
1212 if (!speed)
1213 return get_attr_length (insn);
1214 else
1216 /* Optimizing for speed. Get the base cost of the insn, then
1217 adjust for the cost of accessing operands. Zero means use
1218 the length as the cost even when optimizing for speed. */
1219 base_cost = get_attr_base_cost (insn);
1220 if (base_cost <= 0)
1221 base_cost = get_attr_length (insn);
1223 /* Look for the operands. Often we have a PARALLEL that's either
1224 the actual operation plus a clobber, or the implicit compare plus
1225 the actual operation. Find the actual operation. */
1226 pat = PATTERN (insn);
1228 if (GET_CODE (pat) == PARALLEL)
1230 set = XVECEXP (pat, 0, 0);
1231 if (GET_CODE (set) != SET || GET_CODE (XEXP (set, 1)) == COMPARE)
1232 set = XVECEXP (pat, 0, 1);
1233 if (GET_CODE (set) != SET || GET_CODE (XEXP (set, 1)) == COMPARE)
1234 return 0;
1236 else
1238 set = pat;
1239 if (GET_CODE (set) != SET)
1240 return 0;
1243 /* Pick up the SET source and destination RTL. */
1244 dest = XEXP (set, 0);
1245 src = XEXP (set, 1);
1246 mode = GET_MODE (dest);
1248 /* See if we have a move, or some arithmetic operation. If a move,
1249 account for source and destination operand costs. Otherwise,
1250 account for the destination and for the second operand of the
1251 operation -- the first is also destination and we don't want to
1252 double-count it. */
1253 base_cost += pdp11_addr_cost (dest, mode, ADDR_SPACE_GENERIC, speed);
1254 op = GET_CODE (src);
1255 switch (op)
1257 case REG:
1258 case MEM:
1259 case CONST_INT:
1260 case CONST:
1261 case LABEL_REF:
1262 case SYMBOL_REF:
1263 case CONST_DOUBLE:
1264 /* It's a move. */
1265 if (src != const0_rtx)
1266 base_cost += pdp11_addr_cost (src, mode, ADDR_SPACE_GENERIC, speed);
1267 return base_cost;
1268 default:
1269 break;
1271 /* There are some other cases where souce and dest are distinct. */
1272 if (FLOAT_MODE_P (mode) &&
1273 (op == FLOAT_TRUNCATE || op == FLOAT_EXTEND || op == FIX || op == FLOAT))
1275 src2 = XEXP (src, 0);
1276 base_cost += pdp11_addr_cost (src2, mode, ADDR_SPACE_GENERIC, speed);
1278 /* Otherwise, pick up the second operand of the arithmetic
1279 operation, if it has two operands. */
1280 else if (op != SUBREG && op != UNSPEC && GET_RTX_LENGTH (op) > 1)
1282 src2 = XEXP (src, 1);
1283 base_cost += pdp11_addr_cost (src2, mode, ADDR_SPACE_GENERIC, speed);
1286 return base_cost;
1289 const char *
1290 output_jump (rtx *operands, int ccnz, int length)
1292 rtx tmpop[1];
1293 static char buf[100];
1294 const char *pos, *neg;
1295 enum rtx_code code = GET_CODE (operands[0]);
1297 if (ccnz)
1299 /* These are the branches valid for CCNZmode, i.e., a comparison
1300 with zero where the V bit is not set to zero. These cases
1301 occur when CC or FCC are set as a side effect of some data
1302 manipulation, such as the ADD instruction. */
1303 switch (code)
1305 case EQ: pos = "beq", neg = "bne"; break;
1306 case NE: pos = "bne", neg = "beq"; break;
1307 case LT: pos = "bmi", neg = "bpl"; break;
1308 case GE: pos = "bpl", neg = "bmi"; break;
1309 default: gcc_unreachable ();
1312 else
1314 switch (code)
1316 case EQ: pos = "beq", neg = "bne"; break;
1317 case NE: pos = "bne", neg = "beq"; break;
1318 case GT: pos = "bgt", neg = "ble"; break;
1319 case GTU: pos = "bhi", neg = "blos"; break;
1320 case LT: pos = "blt", neg = "bge"; break;
1321 case LTU: pos = "blo", neg = "bhis"; break;
1322 case GE: pos = "bge", neg = "blt"; break;
1323 case GEU: pos = "bhis", neg = "blo"; break;
1324 case LE: pos = "ble", neg = "bgt"; break;
1325 case LEU: pos = "blos", neg = "bhi"; break;
1326 default: gcc_unreachable ();
1329 switch (length)
1331 case 2:
1332 sprintf (buf, "%s\t%%l1", pos);
1333 return buf;
1334 case 6:
1335 tmpop[0] = gen_label_rtx ();
1336 sprintf (buf, "%s\t%%l0", neg);
1337 output_asm_insn (buf, tmpop);
1338 output_asm_insn ("jmp\t%l1", operands);
1339 output_asm_label (tmpop[0]);
1340 fputs (":\n", asm_out_file);
1341 return "";
1342 default:
1343 gcc_unreachable ();
1347 /* Select the CC mode to be used for the side effect compare with
1348 zero, given the compare operation code in op and the compare
1349 operands in x in and y. */
1350 machine_mode
1351 pdp11_cc_mode (enum rtx_code op ATTRIBUTE_UNUSED, rtx x, rtx y ATTRIBUTE_UNUSED)
1353 if (FLOAT_MODE_P (GET_MODE (x)))
1355 switch (GET_CODE (x))
1357 case ABS:
1358 case NEG:
1359 case REG:
1360 case MEM:
1361 return CCmode;
1362 default:
1363 return CCNZmode;
1366 else
1368 switch (GET_CODE (x))
1370 case XOR:
1371 case AND:
1372 case IOR:
1373 case MULT:
1374 case NOT:
1375 case REG:
1376 case MEM:
1377 return CCmode;
1378 default:
1379 return CCNZmode;
1386 simple_memory_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1388 rtx addr;
1390 /* Eliminate non-memory operations */
1391 if (GET_CODE (op) != MEM)
1392 return FALSE;
1394 /* Decode the address now. */
1396 indirection:
1398 addr = XEXP (op, 0);
1400 switch (GET_CODE (addr))
1402 case REG:
1403 /* (R0) - no extra cost */
1404 return 1;
1406 case PRE_DEC:
1407 case POST_INC:
1408 case PRE_MODIFY:
1409 case POST_MODIFY:
1410 /* -(R0), (R0)+ - cheap! */
1411 return 1;
1413 case MEM:
1414 /* cheap - is encoded in addressing mode info!
1416 -- except for @(R0), which has to be @0(R0) !!! */
1418 if (GET_CODE (XEXP (addr, 0)) == REG)
1419 return 0;
1421 op=addr;
1422 goto indirection;
1424 case CONST_INT:
1425 case LABEL_REF:
1426 case CONST:
1427 case SYMBOL_REF:
1428 /* @#address - extra cost */
1429 return 0;
1431 case PLUS:
1432 /* X(R0) - extra cost */
1433 return 0;
1435 default:
1436 break;
1439 return FALSE;
1442 /* Similar to simple_memory_operand but doesn't match push/pop. */
1444 no_side_effect_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1446 rtx addr;
1448 /* Eliminate non-memory operations */
1449 if (GET_CODE (op) != MEM)
1450 return FALSE;
1452 /* Decode the address now. */
1454 indirection:
1456 addr = XEXP (op, 0);
1458 switch (GET_CODE (addr))
1460 case REG:
1461 /* (R0) - no extra cost */
1462 return 1;
1464 case PRE_DEC:
1465 case POST_INC:
1466 case PRE_MODIFY:
1467 case POST_MODIFY:
1468 return 0;
1470 case MEM:
1471 /* cheap - is encoded in addressing mode info!
1473 -- except for @(R0), which has to be @0(R0) !!! */
1475 if (GET_CODE (XEXP (addr, 0)) == REG)
1476 return 0;
1478 op=addr;
1479 goto indirection;
1481 case CONST_INT:
1482 case LABEL_REF:
1483 case CONST:
1484 case SYMBOL_REF:
1485 /* @#address - extra cost */
1486 return 0;
1488 case PLUS:
1489 /* X(R0) - extra cost */
1490 return 0;
1492 default:
1493 break;
1496 return FALSE;
1501 * output a block move:
1503 * operands[0] ... to
1504 * operands[1] ... from
1505 * operands[2] ... length
1506 * operands[3] ... alignment
1507 * operands[4] ... scratch register
1511 const char *
1512 output_block_move(rtx *operands)
1514 static int count = 0;
1515 char buf[200];
1516 int unroll;
1517 int lastbyte = 0;
1519 /* Move of zero bytes is a NOP. */
1520 if (operands[2] == const0_rtx)
1521 return "";
1523 /* Look for moves by small constant byte counts, those we'll
1524 expand to straight line code. */
1525 if (CONSTANT_P (operands[2]))
1527 if (INTVAL (operands[2]) < 16
1528 && (!optimize_size || INTVAL (operands[2]) < 5)
1529 && INTVAL (operands[3]) == 1)
1531 register int i;
1533 for (i = 1; i <= INTVAL (operands[2]); i++)
1534 output_asm_insn("movb\t(%1)+,(%0)+", operands);
1536 return "";
1538 else if (INTVAL(operands[2]) < 32
1539 && (!optimize_size || INTVAL (operands[2]) < 9)
1540 && INTVAL (operands[3]) >= 2)
1542 register int i;
1544 for (i = 1; i <= INTVAL (operands[2]) / 2; i++)
1545 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1546 if (INTVAL (operands[2]) & 1)
1547 output_asm_insn ("movb\t(%1),(%0)", operands);
1549 return "";
1553 /* Ideally we'd look for moves that are multiples of 4 or 8
1554 bytes and handle those by unrolling the move loop. That
1555 makes for a lot of code if done at run time, but it's ok
1556 for constant counts. Also, for variable counts we have
1557 to worry about odd byte count with even aligned pointers.
1558 On 11/40 and up we handle that case; on older machines
1559 we don't and just use byte-wise moves all the time. */
1561 if (CONSTANT_P (operands[2]) )
1563 if (INTVAL (operands[3]) < 2)
1564 unroll = 0;
1565 else
1567 lastbyte = INTVAL (operands[2]) & 1;
1569 if (optimize_size || INTVAL (operands[2]) & 2)
1570 unroll = 1;
1571 else if (INTVAL (operands[2]) & 4)
1572 unroll = 2;
1573 else
1574 unroll = 3;
1577 /* Loop count is byte count scaled by unroll. */
1578 operands[2] = GEN_INT (INTVAL (operands[2]) >> unroll);
1579 output_asm_insn ("mov\t%2,%4", operands);
1581 else
1583 /* Variable byte count; use the input register
1584 as the scratch. */
1585 operands[4] = operands[2];
1587 /* Decide whether to move by words, and check
1588 the byte count for zero. */
1589 if (TARGET_40_PLUS && INTVAL (operands[3]) > 1)
1591 unroll = 1;
1592 output_asm_insn ("asr\t%4", operands);
1594 else
1596 unroll = 0;
1597 output_asm_insn ("tst\t%4", operands);
1599 sprintf (buf, "beq movestrhi%d", count + 1);
1600 output_asm_insn (buf, NULL);
1603 /* Output the loop label. */
1604 sprintf (buf, "\nmovestrhi%d:", count);
1605 output_asm_insn (buf, NULL);
1607 /* Output the appropriate move instructions. */
1608 switch (unroll)
1610 case 0:
1611 output_asm_insn ("movb\t(%1)+,(%0)+", operands);
1612 break;
1614 case 1:
1615 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1616 break;
1618 case 2:
1619 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1620 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1621 break;
1623 default:
1624 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1625 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1626 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1627 output_asm_insn ("mov\t(%1)+,(%0)+", operands);
1628 break;
1631 /* Output the decrement and test. */
1632 if (TARGET_40_PLUS)
1634 sprintf (buf, "sob\t%%4, movestrhi%d", count);
1635 output_asm_insn (buf, operands);
1637 else
1639 output_asm_insn ("dec\t%4", operands);
1640 sprintf (buf, "bgt movestrhi%d", count);
1641 output_asm_insn (buf, NULL);
1643 count ++;
1645 /* If constant odd byte count, move the last byte. */
1646 if (lastbyte)
1647 output_asm_insn ("movb\t(%1),(%0)", operands);
1648 else if (!CONSTANT_P (operands[2]))
1650 /* Output the destination label for the zero byte count check. */
1651 sprintf (buf, "\nmovestrhi%d:", count);
1652 output_asm_insn (buf, NULL);
1653 count++;
1655 /* If we did word moves, check for trailing last byte. */
1656 if (unroll)
1658 sprintf (buf, "bcc movestrhi%d", count);
1659 output_asm_insn (buf, NULL);
1660 output_asm_insn ("movb\t(%1),(%0)", operands);
1661 sprintf (buf, "\nmovestrhi%d:", count);
1662 output_asm_insn (buf, NULL);
1663 count++;
1667 return "";
1670 /* This function checks whether a real value can be encoded as
1671 a literal, i.e., addressing mode 27. In that mode, real values
1672 are one word values, so the remaining 48 bits have to be zero. */
1674 legitimate_const_double_p (rtx address)
1676 long sval[2];
1677 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (address), sval);
1678 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1679 return 1;
1680 return 0;
1683 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
1684 static bool
1685 pdp11_can_change_mode_class (machine_mode from,
1686 machine_mode to,
1687 reg_class_t rclass)
1689 /* Also, FPU registers contain a whole float value and the parts of
1690 it are not separately accessible.
1692 So we disallow all mode changes involving FPRs. */
1693 if (FLOAT_MODE_P (from) != FLOAT_MODE_P (to))
1694 return false;
1696 return !reg_classes_intersect_p (FPU_REGS, rclass);
1699 /* TARGET_PREFERRED_RELOAD_CLASS
1701 Given an rtx X being reloaded into a reg required to be
1702 in class CLASS, return the class of reg to actually use.
1703 In general this is just CLASS; but on some machines
1704 in some cases it is preferable to use a more restrictive class.
1706 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1708 static reg_class_t
1709 pdp11_preferred_reload_class (rtx x, reg_class_t rclass)
1711 if (rclass == FPU_REGS)
1712 return LOAD_FPU_REGS;
1713 if (rclass == ALL_REGS)
1715 if (FLOAT_MODE_P (GET_MODE (x)))
1716 return LOAD_FPU_REGS;
1717 else
1718 return GENERAL_REGS;
1720 return rclass;
1723 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1725 Given an rtx X being reloaded into a reg required to be
1726 in class CLASS, return the class of reg to actually use.
1727 In general this is just CLASS; but on some machines
1728 in some cases it is preferable to use a more restrictive class.
1730 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1732 static reg_class_t
1733 pdp11_preferred_output_reload_class (rtx x, reg_class_t rclass)
1735 if (rclass == FPU_REGS)
1736 return LOAD_FPU_REGS;
1737 if (rclass == ALL_REGS)
1739 if (FLOAT_MODE_P (GET_MODE (x)))
1740 return LOAD_FPU_REGS;
1741 else
1742 return GENERAL_REGS;
1744 return rclass;
1748 /* TARGET_SECONDARY_RELOAD.
1750 FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1751 intermediate register (AC0-AC3: LOAD_FPU_REGS). Everything else
1752 can be loaded/stored directly. */
1753 static reg_class_t
1754 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED,
1755 rtx x,
1756 reg_class_t reload_class,
1757 machine_mode reload_mode ATTRIBUTE_UNUSED,
1758 secondary_reload_info *sri ATTRIBUTE_UNUSED)
1760 if (reload_class != NO_LOAD_FPU_REGS || GET_CODE (x) != REG ||
1761 REGNO_REG_CLASS (REGNO (x)) == LOAD_FPU_REGS)
1762 return NO_REGS;
1764 return LOAD_FPU_REGS;
1767 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
1769 The answer is yes if we're going between general register and FPU
1770 registers. The mode doesn't matter in making this check. */
1771 static bool
1772 pdp11_secondary_memory_needed (machine_mode, reg_class_t c1, reg_class_t c2)
1774 int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS ||
1775 c1 == FPU_REGS);
1776 int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS ||
1777 c2 == FPU_REGS);
1779 return (fromfloat != tofloat);
1782 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
1783 that is a valid memory address for an instruction.
1784 The MODE argument is the machine mode for the MEM expression
1785 that wants to use this address.
1789 static bool
1790 pdp11_legitimate_address_p (machine_mode mode,
1791 rtx operand, bool strict)
1793 rtx xfoob;
1795 /* accept @#address */
1796 if (CONSTANT_ADDRESS_P (operand))
1797 return true;
1799 switch (GET_CODE (operand))
1801 case REG:
1802 /* accept (R0) */
1803 return !strict || REGNO_OK_FOR_BASE_P (REGNO (operand));
1805 case PLUS:
1806 /* accept X(R0) */
1807 return GET_CODE (XEXP (operand, 0)) == REG
1808 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))))
1809 && CONSTANT_ADDRESS_P (XEXP (operand, 1));
1811 case PRE_DEC:
1812 /* accept -(R0) */
1813 return GET_CODE (XEXP (operand, 0)) == REG
1814 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1816 case POST_INC:
1817 /* accept (R0)+ */
1818 return GET_CODE (XEXP (operand, 0)) == REG
1819 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1821 case PRE_MODIFY:
1822 /* accept -(SP) -- which uses PRE_MODIFY for byte mode */
1823 return GET_CODE (XEXP (operand, 0)) == REG
1824 && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1825 && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1826 && GET_CODE (XEXP (xfoob, 0)) == REG
1827 && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1828 && CONSTANT_P (XEXP (xfoob, 1))
1829 && INTVAL (XEXP (xfoob,1)) == -2;
1831 case POST_MODIFY:
1832 /* accept (SP)+ -- which uses POST_MODIFY for byte mode */
1833 return GET_CODE (XEXP (operand, 0)) == REG
1834 && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1835 && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1836 && GET_CODE (XEXP (xfoob, 0)) == REG
1837 && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1838 && CONSTANT_P (XEXP (xfoob, 1))
1839 && INTVAL (XEXP (xfoob,1)) == 2;
1841 case MEM:
1842 /* handle another level of indirection ! */
1843 xfoob = XEXP (operand, 0);
1845 /* (MEM:xx (MEM:xx ())) is not valid for SI, DI and currently
1846 also forbidden for float, because we have to handle this
1847 in output_move_double and/or output_move_quad() - we could
1848 do it, but currently it's not worth it!!!
1849 now that DFmode cannot go into CPU register file,
1850 maybe I should allow float ...
1851 but then I have to handle memory-to-memory moves in movdf ?? */
1852 if (GET_MODE_BITSIZE(mode) > 16)
1853 return false;
1855 /* accept @address */
1856 if (CONSTANT_ADDRESS_P (xfoob))
1857 return true;
1859 switch (GET_CODE (xfoob))
1861 case REG:
1862 /* accept @(R0) - which is @0(R0) */
1863 return !strict || REGNO_OK_FOR_BASE_P(REGNO (xfoob));
1865 case PLUS:
1866 /* accept @X(R0) */
1867 return GET_CODE (XEXP (xfoob, 0)) == REG
1868 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))))
1869 && CONSTANT_ADDRESS_P (XEXP (xfoob, 1));
1871 case PRE_DEC:
1872 /* accept @-(R0) */
1873 return GET_CODE (XEXP (xfoob, 0)) == REG
1874 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1876 case POST_INC:
1877 /* accept @(R0)+ */
1878 return GET_CODE (XEXP (xfoob, 0)) == REG
1879 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1881 default:
1882 /* anything else is invalid */
1883 return false;
1886 default:
1887 /* anything else is invalid */
1888 return false;
1892 /* Return the class number of the smallest class containing
1893 reg number REGNO. */
1894 enum reg_class
1895 pdp11_regno_reg_class (int regno)
1897 if (regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM)
1898 return GENERAL_REGS;
1899 else if (regno == CC_REGNUM || regno == FCC_REGNUM)
1900 return CC_REGS;
1901 else if (regno > AC3_REGNUM)
1902 return NO_LOAD_FPU_REGS;
1903 else if (regno >= AC0_REGNUM)
1904 return LOAD_FPU_REGS;
1905 else if (regno & 1)
1906 return MUL_REGS;
1907 else
1908 return GENERAL_REGS;
1911 /* Return the regnums of the CC registers. */
1912 bool
1913 pdp11_fixed_cc_regs (unsigned int *p1, unsigned int *p2)
1915 *p1 = CC_REGNUM;
1916 *p2 = FCC_REGNUM;
1917 return true;
1921 pdp11_sp_frame_offset (void)
1923 int offset = 0, regno;
1924 offset = get_frame_size();
1925 for (regno = 0; regno <= PC_REGNUM; regno++)
1926 if (pdp11_saved_regno (regno))
1927 offset += 2;
1928 for (regno = AC0_REGNUM; regno <= AC5_REGNUM; regno++)
1929 if (pdp11_saved_regno (regno))
1930 offset += 8;
1932 return offset;
1935 /* Return the offset between two registers, one to be eliminated, and the other
1936 its replacement, at the start of a routine. */
1939 pdp11_initial_elimination_offset (int from, int to)
1941 int spoff;
1943 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
1944 return 4;
1945 else if (from == FRAME_POINTER_REGNUM
1946 && to == HARD_FRAME_POINTER_REGNUM)
1947 return 0;
1948 else
1950 gcc_assert (to == STACK_POINTER_REGNUM);
1952 /* Get the size of the register save area. */
1953 spoff = pdp11_sp_frame_offset ();
1954 if (from == FRAME_POINTER_REGNUM)
1955 return spoff;
1957 gcc_assert (from == ARG_POINTER_REGNUM);
1959 /* If there is a frame pointer, that is saved too. */
1960 if (frame_pointer_needed)
1961 spoff += 2;
1963 /* Account for the saved PC in the function call. */
1964 return spoff + 2;
1968 /* A copy of output_addr_const modified for pdp11 expression syntax.
1969 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1970 use, and for debugging output, which we don't support with this port either.
1971 So this copy should get called whenever needed.
1973 void
1974 output_addr_const_pdp11 (FILE *file, rtx x)
1976 char buf[256];
1977 int i;
1979 restart:
1980 switch (GET_CODE (x))
1982 case PC:
1983 gcc_assert (flag_pic);
1984 putc ('.', file);
1985 break;
1987 case SYMBOL_REF:
1988 assemble_name (file, XSTR (x, 0));
1989 break;
1991 case LABEL_REF:
1992 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1993 assemble_name (file, buf);
1994 break;
1996 case CODE_LABEL:
1997 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1998 assemble_name (file, buf);
1999 break;
2001 case CONST_INT:
2002 i = INTVAL (x);
2003 if (i < 0)
2005 i = -i;
2006 fprintf (file, "-");
2008 if (TARGET_DEC_ASM)
2009 fprintf (file, "%o", i & 0xffff);
2010 else
2011 fprintf (file, "%#o", i & 0xffff);
2012 break;
2014 case CONST:
2015 output_addr_const_pdp11 (file, XEXP (x, 0));
2016 break;
2018 case CONST_DOUBLE:
2019 if (GET_MODE (x) == VOIDmode)
2021 /* We can use %o if the number is one word and positive. */
2022 if (TARGET_DEC_ASM)
2023 fprintf (file, "%o", (int) CONST_DOUBLE_LOW (x) & 0xffff);
2024 else
2025 fprintf (file, "%#o", (int) CONST_DOUBLE_LOW (x) & 0xffff);
2027 else
2028 /* We can't handle floating point constants;
2029 PRINT_OPERAND must handle them. */
2030 output_operand_lossage ("floating constant misused");
2031 break;
2033 case PLUS:
2034 /* Some assemblers need integer constants to appear last (e.g. masm). */
2035 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2037 output_addr_const_pdp11 (file, XEXP (x, 1));
2038 if (INTVAL (XEXP (x, 0)) >= 0)
2039 fprintf (file, "+");
2040 output_addr_const_pdp11 (file, XEXP (x, 0));
2042 else
2044 output_addr_const_pdp11 (file, XEXP (x, 0));
2045 if (INTVAL (XEXP (x, 1)) >= 0)
2046 fprintf (file, "+");
2047 output_addr_const_pdp11 (file, XEXP (x, 1));
2049 break;
2051 case MINUS:
2052 /* Avoid outputting things like x-x or x+5-x,
2053 since some assemblers can't handle that. */
2054 x = simplify_subtraction (x);
2055 if (GET_CODE (x) != MINUS)
2056 goto restart;
2058 output_addr_const_pdp11 (file, XEXP (x, 0));
2059 if (GET_CODE (XEXP (x, 1)) != CONST_INT
2060 || INTVAL (XEXP (x, 1)) >= 0)
2061 fprintf (file, "-");
2062 output_addr_const_pdp11 (file, XEXP (x, 1));
2063 break;
2065 case ZERO_EXTEND:
2066 case SIGN_EXTEND:
2067 output_addr_const_pdp11 (file, XEXP (x, 0));
2068 break;
2070 default:
2071 output_operand_lossage ("invalid expression as operand");
2075 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2077 static bool
2078 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2080 /* Integers 32 bits and under, and scalar floats (if FPU), are returned
2081 in registers. The rest go into memory. */
2082 return (TYPE_MODE (type) == DImode
2083 || (FLOAT_MODE_P (TYPE_MODE (type)) && ! TARGET_AC0)
2084 || TREE_CODE (type) == VECTOR_TYPE
2085 || COMPLEX_MODE_P (TYPE_MODE (type)));
2088 /* Worker function for TARGET_FUNCTION_VALUE.
2090 On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! ) */
2092 static rtx
2093 pdp11_function_value (const_tree valtype,
2094 const_tree fntype_or_decl ATTRIBUTE_UNUSED,
2095 bool outgoing ATTRIBUTE_UNUSED)
2097 return gen_rtx_REG (TYPE_MODE (valtype),
2098 BASE_RETURN_VALUE_REG(TYPE_MODE(valtype)));
2101 /* Worker function for TARGET_LIBCALL_VALUE. */
2103 static rtx
2104 pdp11_libcall_value (machine_mode mode,
2105 const_rtx fun ATTRIBUTE_UNUSED)
2107 return gen_rtx_REG (mode, BASE_RETURN_VALUE_REG(mode));
2110 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
2112 On the pdp, the first "output" reg is the only register thus used.
2114 maybe ac0 ? - as option someday! */
2116 static bool
2117 pdp11_function_value_regno_p (const unsigned int regno)
2119 return (regno == RETVAL_REGNUM) || (TARGET_AC0 && (regno == AC0_REGNUM));
2122 /* Used for O constraint, matches if shift count is "small". */
2123 bool
2124 pdp11_small_shift (int n)
2126 return (unsigned) n < 4;
2129 /* Expand a shift insn. Returns true if the expansion was done,
2130 false if it needs to be handled by the caller. */
2131 bool
2132 pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
2133 rtx (*shift_base) (rtx, rtx, rtx))
2135 rtx r, test;
2136 rtx_code_label *lb;
2138 if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
2139 emit_insn ((*shift_sc) (operands[0], operands[1], operands[2]));
2140 else if (TARGET_40_PLUS)
2141 return false;
2142 else
2144 lb = gen_label_rtx ();
2145 r = gen_reg_rtx (HImode);
2146 emit_move_insn (operands[0], operands[1]);
2147 emit_move_insn (r, operands[2]);
2148 if (!CONSTANT_P (operands[2]))
2150 test = gen_rtx_LE (HImode, r, const0_rtx);
2151 emit_jump_insn (gen_cbranchhi4 (test, r, const0_rtx, lb));
2153 /* It would be nice to expand the loop here, but that's not
2154 possible because shifts may be generated by the loop unroll
2155 optimizer and it doesn't appreciate flow changes happening
2156 while it's doing things. */
2157 emit_insn ((*shift_base) (operands[0], operands[1], r));
2158 if (!CONSTANT_P (operands[2]))
2160 emit_label (lb);
2162 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2163 fields, and can't be used for REG_NOTES anyway). */
2164 emit_use (stack_pointer_rtx);
2167 return true;
2170 /* Emit the instructions needed to produce a shift by a small constant
2171 amount (unrolled), or a shift made from a loop for the base machine
2172 case. */
2173 const char *
2174 pdp11_assemble_shift (rtx *operands, machine_mode m, int code)
2176 int i, n;
2177 rtx exops[4][2];
2178 rtx lb[1];
2179 pdp11_action action[2];
2180 const bool small = CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]));
2182 gcc_assert (small || !TARGET_40_PLUS);
2184 if (m == E_SImode)
2185 pdp11_expand_operands (operands, exops, 1, action, either);
2187 if (!small)
2189 /* Loop case, generate the top of loop label. */
2190 lb[0] = gen_label_rtx ();
2191 output_asm_label (lb[0]);
2192 fputs (":\n", asm_out_file);
2193 n = 1;
2195 else
2196 n = INTVAL (operands[2]);
2197 if (code == LSHIFTRT)
2199 output_asm_insn ("clc", NULL);
2200 switch (m)
2202 case E_QImode:
2203 output_asm_insn ("rorb\t%0", operands);
2204 break;
2205 case E_HImode:
2206 output_asm_insn ("ror\t%0", operands);
2207 break;
2208 case E_SImode:
2209 output_asm_insn ("ror\t%0", exops[0]);
2210 output_asm_insn ("ror\t%0", exops[1]);
2211 break;
2212 default:
2213 gcc_unreachable ();
2215 n--;
2217 for (i = 0; i < n; i++)
2219 switch (code)
2221 case LSHIFTRT:
2222 case ASHIFTRT:
2223 switch (m)
2225 case E_QImode:
2226 output_asm_insn ("asrb\t%0", operands);
2227 break;
2228 case E_HImode:
2229 output_asm_insn ("asr\t%0", operands);
2230 break;
2231 case E_SImode:
2232 output_asm_insn ("asr\t%0", exops[0]);
2233 output_asm_insn ("ror\t%0", exops[1]);
2234 break;
2235 default:
2236 gcc_unreachable ();
2238 break;
2239 case ASHIFT:
2240 switch (m)
2242 case E_QImode:
2243 output_asm_insn ("aslb\t%0", operands);
2244 break;
2245 case E_HImode:
2246 output_asm_insn ("asl\t%0", operands);
2247 break;
2248 case E_SImode:
2249 output_asm_insn ("asl\t%0", exops[1]);
2250 output_asm_insn ("rol\t%0", exops[0]);
2251 break;
2252 default:
2253 gcc_unreachable ();
2255 break;
2258 if (!small)
2260 /* Loop case, emit the count-down and branch if not done. */
2261 output_asm_insn ("dec\t%2", operands);
2262 output_asm_insn ("bne\t%l0", lb);
2264 return "";
2267 /* Figure out the length of the instructions that will be produced for
2268 the given operands by pdp11_assemble_shift above. */
2270 pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand_p)
2272 int shift_size;
2274 /* Shift by 1 is 2 bytes if simple operand, 4 bytes if 2-word addressing mode. */
2275 shift_size = simple_operand_p ? 2 : 4;
2277 /* In SImode, two shifts are needed per data item. */
2278 if (m == E_SImode)
2279 shift_size *= 2;
2281 /* If shifting by a small constant, the loop is unrolled by the
2282 shift count. Otherwise, account for the size of the decrement
2283 and branch. */
2284 if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
2285 shift_size *= INTVAL (operands[2]);
2286 else
2287 shift_size += 4;
2289 /* Logical right shift takes one more instruction (CLC). */
2290 if (code == LSHIFTRT)
2291 shift_size += 2;
2293 return shift_size;
2296 /* Prepend to CLOBBERS hard registers that are automatically clobbered
2297 for an asm We do this for CC_REGNUM and FCC_REGNUM (on FPU target)
2298 to maintain source compatibility with the original cc0-based
2299 compiler. */
2301 static rtx_insn *
2302 pdp11_md_asm_adjust (vec<rtx> &/*outputs*/, vec<rtx> &/*inputs*/,
2303 vec<const char *> &/*constraints*/,
2304 vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs)
2306 clobbers.safe_push (gen_rtx_REG (CCmode, CC_REGNUM));
2307 SET_HARD_REG_BIT (clobbered_regs, CC_REGNUM);
2308 if (TARGET_FPU)
2310 clobbers.safe_push (gen_rtx_REG (CCmode, FCC_REGNUM));
2311 SET_HARD_REG_BIT (clobbered_regs, FCC_REGNUM);
2313 return NULL;
2316 /* Worker function for TARGET_TRAMPOLINE_INIT.
2318 trampoline - how should i do it in separate i+d ?
2319 have some allocate_trampoline magic???
2321 the following should work for shared I/D:
2323 MOV #STATIC, $4 01270Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
2324 JMP @#FUNCTION 000137 0x0000 <- FUNCTION
2326 static void
2327 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
2329 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2330 rtx mem;
2332 gcc_assert (!TARGET_SPLIT);
2334 mem = adjust_address (m_tramp, HImode, 0);
2335 emit_move_insn (mem, GEN_INT (012700+STATIC_CHAIN_REGNUM));
2336 mem = adjust_address (m_tramp, HImode, 2);
2337 emit_move_insn (mem, chain_value);
2338 mem = adjust_address (m_tramp, HImode, 4);
2339 emit_move_insn (mem, GEN_INT (000137));
2340 emit_move_insn (mem, fnaddr);
2343 /* Worker function for TARGET_FUNCTION_ARG.
2345 Determine where to put an argument to a function.
2346 Value is zero to push the argument on the stack,
2347 or a hard register in which to store the argument.
2349 MODE is the argument's machine mode.
2350 TYPE is the data type of the argument (as a tree).
2351 This is null for libcalls where that information may
2352 not be available.
2353 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2354 the preceding args and about the function being called.
2355 NAMED is nonzero if this argument is a named parameter
2356 (otherwise it is an extra parameter matching an ellipsis). */
2358 static rtx
2359 pdp11_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED,
2360 machine_mode mode ATTRIBUTE_UNUSED,
2361 const_tree type ATTRIBUTE_UNUSED,
2362 bool named ATTRIBUTE_UNUSED)
2364 return NULL_RTX;
2367 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
2369 Update the data in CUM to advance over an argument of mode MODE and
2370 data type TYPE. (TYPE is null for libcalls where that information
2371 may not be available.) */
2373 static void
2374 pdp11_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2375 const_tree type, bool named ATTRIBUTE_UNUSED)
2377 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2379 *cum += (mode != BLKmode
2380 ? GET_MODE_SIZE (mode)
2381 : int_size_in_bytes (type));
2384 /* Make sure everything's fine if we *don't* have an FPU.
2385 This assumes that putting a register in fixed_regs will keep the
2386 compiler's mitts completely off it. We don't bother to zero it out
2387 of register classes. Also fix incompatible register naming with
2388 the UNIX assembler. */
2390 static void
2391 pdp11_conditional_register_usage (void)
2393 int i;
2394 HARD_REG_SET x;
2395 if (!TARGET_FPU)
2397 COPY_HARD_REG_SET (x, reg_class_contents[(int)FPU_REGS]);
2398 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ )
2399 if (TEST_HARD_REG_BIT (x, i))
2400 fixed_regs[i] = call_used_regs[i] = 1;
2403 if (TARGET_AC0)
2404 call_used_regs[AC0_REGNUM] = 1;
2405 if (TARGET_UNIX_ASM)
2407 /* Change names of FPU registers for the UNIX assembler. */
2408 reg_names[8] = "fr0";
2409 reg_names[9] = "fr1";
2410 reg_names[10] = "fr2";
2411 reg_names[11] = "fr3";
2412 reg_names[12] = "fr4";
2413 reg_names[13] = "fr5";
2417 static section *
2418 pdp11_function_section (tree decl ATTRIBUTE_UNUSED,
2419 enum node_frequency freq ATTRIBUTE_UNUSED,
2420 bool startup ATTRIBUTE_UNUSED,
2421 bool exit ATTRIBUTE_UNUSED)
2423 return NULL;
2426 /* Support #ident for DEC assembler, but don't process the
2427 auto-generated ident string that names the compiler (since its
2428 syntax is not correct for DEC .ident). */
2429 static void pdp11_output_ident (const char *ident)
2431 if (TARGET_DEC_ASM)
2433 if (strncmp (ident, "GCC:", 4) != 0)
2434 fprintf (asm_out_file, "\t.ident\t\"%s\"\n", ident);
2439 /* This emits a (user) label, which gets a "_" prefix except for DEC
2440 assembler output. */
2441 void
2442 pdp11_output_labelref (FILE *file, const char *name)
2444 if (!TARGET_DEC_ASM)
2445 fputs (USER_LABEL_PREFIX, file);
2446 fputs (name, file);
2449 /* This equates name with value. */
2450 void
2451 pdp11_output_def (FILE *file, const char *label1, const char *label2)
2453 if (TARGET_DEC_ASM)
2455 assemble_name (file, label1);
2456 putc ('=', file);
2457 assemble_name (file, label2);
2459 else
2461 fputs ("\t.set\t", file);
2462 assemble_name (file, label1);
2463 putc (',', file);
2464 assemble_name (file, label2);
2466 putc ('\n', file);
2469 void
2470 pdp11_output_addr_vec_elt (FILE *file, int value)
2472 char buf[256];
2474 pdp11_gen_int_label (buf, "L", value);
2475 if (!TARGET_UNIX_ASM)
2476 fprintf (file, "\t.word");
2477 fprintf (file, "\t%s\n", buf + 1);
2480 /* This overrides some target hooks that are initializer elements so
2481 they can't be variables in the #define. */
2482 static void
2483 pdp11_option_override (void)
2485 if (TARGET_DEC_ASM)
2487 targetm.asm_out.open_paren = "<";
2488 targetm.asm_out.close_paren = ">";
2492 static void
2493 pdp11_asm_named_section (const char *name, unsigned int flags,
2494 tree decl ATTRIBUTE_UNUSED)
2496 const char *rwro = (flags & SECTION_WRITE) ? "rw" : "ro";
2497 const char *insdat = (flags & SECTION_CODE) ? "i" : "d";
2499 gcc_assert (TARGET_DEC_ASM);
2500 fprintf (asm_out_file, "\t.psect\t%s,con,%s,%s\n", name, insdat, rwro);
2503 static void
2504 pdp11_asm_init_sections (void)
2506 if (TARGET_DEC_ASM)
2508 bss_section = data_section;
2510 else if (TARGET_GNU_ASM)
2512 bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
2513 output_section_asm_op,
2514 ".bss");
2518 static void
2519 pdp11_file_start (void)
2521 default_file_start ();
2523 if (TARGET_DEC_ASM)
2524 fprintf (asm_out_file, "\t.enabl\tlsb,reg\n\n");
2527 static void
2528 pdp11_file_end (void)
2530 if (TARGET_DEC_ASM)
2531 fprintf (asm_out_file, "\t.end\n");
2534 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
2536 static bool
2537 pdp11_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2539 return GET_CODE (x) != CONST_DOUBLE || legitimate_const_double_p (x);
2542 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
2544 static bool
2545 pdp11_scalar_mode_supported_p (scalar_mode mode)
2547 /* Support SFmode even with -mfloat64. */
2548 if (mode == SFmode)
2549 return true;
2550 return default_scalar_mode_supported_p (mode);
2553 /* Implement TARGET_HARD_REGNO_NREGS. */
2555 static unsigned int
2556 pdp11_hard_regno_nregs (unsigned int regno, machine_mode mode)
2558 if (regno <= PC_REGNUM)
2559 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
2560 return 1;
2563 /* Implement TARGET_HARD_REGNO_MODE_OK. On the pdp, the cpu registers
2564 can hold any mode other than float (because otherwise we may end up
2565 being asked to move from CPU to FPU register, which isn't a valid
2566 operation on the PDP11). For CPU registers, check alignment.
2568 FPU accepts SF and DF but actually holds a DF - simplifies life! */
2570 static bool
2571 pdp11_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2573 if (regno <= PC_REGNUM)
2574 return (GET_MODE_BITSIZE (mode) <= 16
2575 || (GET_MODE_BITSIZE (mode) >= 32
2576 && !(regno & 1)
2577 && !FLOAT_MODE_P (mode)));
2579 return FLOAT_MODE_P (mode);
2582 /* Implement TARGET_MODES_TIEABLE_P. */
2584 static bool
2585 pdp11_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2587 return mode1 == HImode && mode2 == QImode;
2590 /* Implement PUSH_ROUNDING. On the pdp11, the stack is on an even
2591 boundary. */
2593 poly_int64
2594 pdp11_push_rounding (poly_int64 bytes)
2596 return (bytes + 1) & ~1;
2599 struct gcc_target targetm = TARGET_INITIALIZER;