1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994-2014 Free Software Foundation, Inc.
3 Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "function.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "tree.h"
36 #include "stor-layout.h"
37 #include "varasm.h"
38 #include "calls.h"
39 #include "expr.h"
40 #include "diagnostic-core.h"
41 #include "tm_p.h"
42 #include "target.h"
43 #include "target-def.h"
44 #include "df.h"
45 #include "opts.h"
46 #include "dbxout.h"
47
48 /* this is the current value returned by the macro FIRST_PARM_OFFSET
49 defined in tm.h */
50 int current_first_parm_offset;
51
52 /* Routines to encode/decode pdp11 floats */
53 static void encode_pdp11_f (const struct real_format *fmt,
54 long *, const REAL_VALUE_TYPE *);
55 static void decode_pdp11_f (const struct real_format *,
56 REAL_VALUE_TYPE *, const long *);
57 static void encode_pdp11_d (const struct real_format *fmt,
58 long *, const REAL_VALUE_TYPE *);
59 static void decode_pdp11_d (const struct real_format *,
60 REAL_VALUE_TYPE *, const long *);
61
62 /* These two are taken from the corresponding vax descriptors
63 in real.c, changing only the encode/decode routine pointers. */
64 const struct real_format pdp11_f_format =
65 {
66 encode_pdp11_f,
67 decode_pdp11_f,
68 2,
69 24,
70 24,
71 -127,
72 127,
73 15,
74 15,
75 false,
76 false,
77 false,
78 false,
79 false,
80 false,
81 false,
82 false
83 };
84
85 const struct real_format pdp11_d_format =
86 {
87 encode_pdp11_d,
88 decode_pdp11_d,
89 2,
90 56,
91 56,
92 -127,
93 127,
94 15,
95 15,
96 false,
97 false,
98 false,
99 false,
100 false,
101 false,
102 false,
103 false
104 };
105
106 static void
encode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)107 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
108 const REAL_VALUE_TYPE *r)
109 {
110 (*vax_f_format.encode) (fmt, buf, r);
111 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
112 }
113
114 static void
decode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)115 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
116 REAL_VALUE_TYPE *r, const long *buf)
117 {
118 long tbuf;
119 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
120 (*vax_f_format.decode) (fmt, r, &tbuf);
121 }
122
123 static void
encode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)124 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
125 const REAL_VALUE_TYPE *r)
126 {
127 (*vax_d_format.encode) (fmt, buf, r);
128 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
129 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
130 }
131
132 static void
decode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)133 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
134 REAL_VALUE_TYPE *r, const long *buf)
135 {
136 long tbuf[2];
137 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
138 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
139 (*vax_d_format.decode) (fmt, r, tbuf);
140 }
141
142 /* This is where the condition code register lives. */
143 /* rtx cc0_reg_rtx; - no longer needed? */
144
145 static const char *singlemove_string (rtx *);
146 static bool pdp11_assemble_integer (rtx, unsigned int, int);
147 static bool pdp11_rtx_costs (rtx, int, int, int, int *, bool);
148 static bool pdp11_return_in_memory (const_tree, const_tree);
149 static rtx pdp11_function_value (const_tree, const_tree, bool);
150 static rtx pdp11_libcall_value (enum machine_mode, const_rtx);
151 static bool pdp11_function_value_regno_p (const unsigned int);
152 static void pdp11_trampoline_init (rtx, tree, rtx);
153 static rtx pdp11_function_arg (cumulative_args_t, enum machine_mode,
154 const_tree, bool);
155 static void pdp11_function_arg_advance (cumulative_args_t,
156 enum machine_mode, const_tree, bool);
157 static void pdp11_conditional_register_usage (void);
158 static bool pdp11_legitimate_constant_p (enum machine_mode, rtx);
159
160 /* Initialize the GCC target structure. */
161 #undef TARGET_ASM_BYTE_OP
162 #define TARGET_ASM_BYTE_OP NULL
163 #undef TARGET_ASM_ALIGNED_HI_OP
164 #define TARGET_ASM_ALIGNED_HI_OP NULL
165 #undef TARGET_ASM_ALIGNED_SI_OP
166 #define TARGET_ASM_ALIGNED_SI_OP NULL
167 #undef TARGET_ASM_INTEGER
168 #define TARGET_ASM_INTEGER pdp11_assemble_integer
169
170 #undef TARGET_ASM_OPEN_PAREN
171 #define TARGET_ASM_OPEN_PAREN "["
172 #undef TARGET_ASM_CLOSE_PAREN
173 #define TARGET_ASM_CLOSE_PAREN "]"
174
175 #undef TARGET_RTX_COSTS
176 #define TARGET_RTX_COSTS pdp11_rtx_costs
177
178 #undef TARGET_FUNCTION_ARG
179 #define TARGET_FUNCTION_ARG pdp11_function_arg
180 #undef TARGET_FUNCTION_ARG_ADVANCE
181 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
182
183 #undef TARGET_RETURN_IN_MEMORY
184 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
185
186 #undef TARGET_FUNCTION_VALUE
187 #define TARGET_FUNCTION_VALUE pdp11_function_value
188 #undef TARGET_LIBCALL_VALUE
189 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
190 #undef TARGET_FUNCTION_VALUE_REGNO_P
191 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
192
193 #undef TARGET_TRAMPOLINE_INIT
194 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
195
196 #undef TARGET_SECONDARY_RELOAD
197 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
198
199 #undef TARGET_REGISTER_MOVE_COST
200 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
201
202 #undef TARGET_PREFERRED_RELOAD_CLASS
203 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
204
205 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
206 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
207
208 #undef TARGET_LEGITIMATE_ADDRESS_P
209 #define TARGET_LEGITIMATE_ADDRESS_P pdp11_legitimate_address_p
210
211 #undef TARGET_CONDITIONAL_REGISTER_USAGE
212 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
213
214 #undef TARGET_ASM_FUNCTION_SECTION
215 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
216
217 #undef TARGET_PRINT_OPERAND
218 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
219
220 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
221 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
222
223 #undef TARGET_LEGITIMATE_CONSTANT_P
224 #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
225
226 /* A helper function to determine if REGNO should be saved in the
227 current function's stack frame. */
228
229 static inline bool
pdp11_saved_regno(unsigned regno)230 pdp11_saved_regno (unsigned regno)
231 {
232 return !call_used_regs[regno] && df_regs_ever_live_p (regno);
233 }
234
235 /* Expand the function prologue. */
236
237 void
pdp11_expand_prologue(void)238 pdp11_expand_prologue (void)
239 {
240 HOST_WIDE_INT fsize = get_frame_size ();
241 unsigned regno;
242 rtx x, via_ac = NULL;
243
244 /* If we are outputting code for main, the switch FPU to the
245 right mode if TARGET_FPU. */
246 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
247 {
248 emit_insn (gen_setd ());
249 emit_insn (gen_seti ());
250 }
251
252 if (frame_pointer_needed)
253 {
254 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
255 x = gen_frame_mem (Pmode, x);
256 emit_move_insn (x, hard_frame_pointer_rtx);
257
258 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
259 }
260
261 /* Make frame. */
262 if (fsize)
263 {
264 emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
265 GEN_INT (-fsize)));
266
267 /* Prevent frame references via the frame pointer from being
268 scheduled before the frame is allocated. */
269 if (frame_pointer_needed)
270 emit_insn (gen_blockage ());
271 }
272
273 /* Save CPU registers. */
274 for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++)
275 if (pdp11_saved_regno (regno)
276 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
277 {
278 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
279 x = gen_frame_mem (Pmode, x);
280 emit_move_insn (x, gen_rtx_REG (Pmode, regno));
281 }
282
283 /* Save FPU registers. */
284 for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
285 if (pdp11_saved_regno (regno))
286 {
287 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
288 x = gen_frame_mem (DFmode, x);
289 via_ac = gen_rtx_REG (DFmode, regno);
290 emit_move_insn (x, via_ac);
291 }
292
293 /* ??? Maybe make ac4, ac5 call used regs?? */
294 for (regno = AC4_REGNUM; regno <= AC5_REGNUM; regno++)
295 if (pdp11_saved_regno (regno))
296 {
297 gcc_assert (via_ac != NULL);
298 emit_move_insn (via_ac, gen_rtx_REG (DFmode, regno));
299
300 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
301 x = gen_frame_mem (DFmode, x);
302 emit_move_insn (x, via_ac);
303 }
304 }
305
306 /* The function epilogue should not depend on the current stack pointer!
307 It should use the frame pointer only. This is mandatory because
308 of alloca; we also take advantage of it to omit stack adjustments
309 before returning. */
310
311 /* Maybe we can make leaf functions faster by switching to the
312 second register file - this way we don't have to save regs!
313 leaf functions are ~ 50% of all functions (dynamically!)
314
315 set/clear bit 11 (dec. 2048) of status word for switching register files -
316 but how can we do this? the pdp11/45 manual says bit may only
317 be set (p.24), but not cleared!
318
319 switching to kernel is probably more expensive, so we'll leave it
320 like this and not use the second set of registers...
321
322 maybe as option if you want to generate code for kernel mode? */
323
324 void
pdp11_expand_epilogue(void)325 pdp11_expand_epilogue (void)
326 {
327 HOST_WIDE_INT fsize = get_frame_size ();
328 unsigned regno;
329 rtx x, reg, via_ac = NULL;
330
331 if (pdp11_saved_regno (AC4_REGNUM) || pdp11_saved_regno (AC5_REGNUM))
332 {
333 /* Find a temporary with which to restore AC4/5. */
334 for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
335 if (pdp11_saved_regno (regno))
336 {
337 via_ac = gen_rtx_REG (DFmode, regno);
338 break;
339 }
340 }
341
342 /* If possible, restore registers via pops. */
343 if (!frame_pointer_needed || crtl->sp_is_unchanging)
344 {
345 /* Restore registers via pops. */
346
347 for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
348 if (pdp11_saved_regno (regno))
349 {
350 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
351 x = gen_frame_mem (DFmode, x);
352 reg = gen_rtx_REG (DFmode, regno);
353
354 if (LOAD_FPU_REG_P (regno))
355 emit_move_insn (reg, x);
356 else
357 {
358 emit_move_insn (via_ac, x);
359 emit_move_insn (reg, via_ac);
360 }
361 }
362
363 for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
364 if (pdp11_saved_regno (regno)
365 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
366 {
367 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
368 x = gen_frame_mem (Pmode, x);
369 emit_move_insn (gen_rtx_REG (Pmode, regno), x);
370 }
371 }
372 else
373 {
374 /* Restore registers via moves. */
375 /* ??? If more than a few registers need to be restored, it's smaller
376 to generate a pointer through which we can emit pops. Consider
377 that moves cost 2*NREG words and pops cost NREG+3 words. This
378 means that the crossover is NREG=3.
379
380 Possible registers to use are:
381 (1) The first call-saved general register. This register will
382 be restored with the last pop.
383 (2) R1, if it's not used as a return register.
384 (3) FP itself. This option may result in +4 words, since we
385 may need two add imm,rn instructions instead of just one.
386 This also has the downside that we're not representing
387 the unwind info in any way, so during the epilogue the
388 debugger may get lost. */
389
390 HOST_WIDE_INT ofs = -pdp11_sp_frame_offset ();
391
392 for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
393 if (pdp11_saved_regno (regno))
394 {
395 x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
396 x = gen_frame_mem (DFmode, x);
397 reg = gen_rtx_REG (DFmode, regno);
398
399 if (LOAD_FPU_REG_P (regno))
400 emit_move_insn (reg, x);
401 else
402 {
403 emit_move_insn (via_ac, x);
404 emit_move_insn (reg, via_ac);
405 }
406 ofs += 8;
407 }
408
409 for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
410 if (pdp11_saved_regno (regno)
411 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
412 {
413 x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
414 x = gen_frame_mem (Pmode, x);
415 emit_move_insn (gen_rtx_REG (Pmode, regno), x);
416 ofs += 2;
417 }
418 }
419
420 /* Deallocate the stack frame. */
421 if (fsize)
422 {
423 /* Prevent frame references via any pointer from being
424 scheduled after the frame is deallocated. */
425 emit_insn (gen_blockage ());
426
427 if (frame_pointer_needed)
428 {
429 /* We can deallocate the frame with a single move. */
430 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
431 }
432 else
433 emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
434 GEN_INT (fsize)));
435 }
436
437 if (frame_pointer_needed)
438 {
439 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
440 x = gen_frame_mem (Pmode, x);
441 emit_move_insn (hard_frame_pointer_rtx, x);
442 }
443
444 emit_jump_insn (gen_return ());
445 }
446
447 /* Return the best assembler insn template
448 for moving operands[1] into operands[0] as a fullword. */
449 static const char *
singlemove_string(rtx * operands)450 singlemove_string (rtx *operands)
451 {
452 if (operands[1] != const0_rtx)
453 return "mov %1,%0";
454
455 return "clr %0";
456 }
457
458
459 /* Expand multi-word operands (SImode or DImode) into the 2 or 4
460 corresponding HImode operands. The number of operands is given
461 as the third argument, and the required order of the parts as
462 the fourth argument. */
463 bool
pdp11_expand_operands(rtx * operands,rtx exops[][2],int opcount,pdp11_action * action,pdp11_partorder order)464 pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
465 pdp11_action *action, pdp11_partorder order)
466 {
467 int words, op, w, i, sh;
468 pdp11_partorder useorder;
469 bool sameoff = false;
470 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype;
471 REAL_VALUE_TYPE r;
472 long sval[2];
473
474 words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
475
476 /* If either piece order is accepted and one is pre-decrement
477 while the other is post-increment, set order to be high order
478 word first. That will force the pre-decrement to be turned
479 into a pointer adjust, then offset addressing.
480 Otherwise, if either operand uses pre-decrement, that means
481 the order is low order first.
482 Otherwise, if both operands are registers and destination is
483 higher than source and they overlap, do low order word (highest
484 register number) first. */
485 useorder = either;
486 if (opcount == 2)
487 {
488 if (!REG_P (operands[0]) && !REG_P (operands[1]) &&
489 !(CONSTANT_P (operands[1]) ||
490 GET_CODE (operands[1]) == CONST_DOUBLE) &&
491 ((GET_CODE (XEXP (operands[0], 0)) == POST_INC &&
492 GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ||
493 (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC &&
494 GET_CODE (XEXP (operands[1], 0)) == POST_INC)))
495 useorder = big;
496 else if ((!REG_P (operands[0]) &&
497 GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ||
498 (!REG_P (operands[1]) &&
499 !(CONSTANT_P (operands[1]) ||
500 GET_CODE (operands[1]) == CONST_DOUBLE) &&
501 GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
502 useorder = little;
503 else if (REG_P (operands[0]) && REG_P (operands[1]) &&
504 REGNO (operands[0]) > REGNO (operands[1]) &&
505 REGNO (operands[0]) < REGNO (operands[1]) + words)
506 useorder = little;
507
508 /* Check for source == offset from register and dest == push of
509 the same register. In that case, we have to use the same
510 offset (the one for the low order word) for all words, because
511 the push increases the offset to each source word.
512 In theory there are other cases like this, for example dest == pop,
513 but those don't occur in real life so ignore those. */
514 if (GET_CODE (operands[0]) == MEM
515 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
516 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
517 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
518 sameoff = true;
519 }
520
521 /* If the caller didn't specify order, use the one we computed,
522 or high word first if we don't care either. If the caller did
523 specify, verify we don't have a problem with that order.
524 (If it matters to the caller, constraints need to be used to
525 ensure this case doesn't occur). */
526 if (order == either)
527 order = (useorder == either) ? big : useorder;
528 else
529 gcc_assert (useorder == either || useorder == order);
530
531
532 for (op = 0; op < opcount; op++)
533 {
534 /* First classify the operand. */
535 if (REG_P (operands[op]))
536 optype = REGOP;
537 else if (CONSTANT_P (operands[op])
538 || GET_CODE (operands[op]) == CONST_DOUBLE)
539 optype = CNSTOP;
540 else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
541 optype = POPOP;
542 else if (GET_CODE (XEXP (operands[op], 0)) == PRE_DEC)
543 optype = PUSHOP;
544 else if (!reload_in_progress || offsettable_memref_p (operands[op]))
545 optype = OFFSOP;
546 else if (GET_CODE (operands[op]) == MEM)
547 optype = MEMOP;
548 else
549 optype = RNDOP;
550
551 /* Check for the cases that the operand constraints are not
552 supposed to allow to happen. Return failure for such cases. */
553 if (optype == RNDOP)
554 return false;
555
556 if (action != NULL)
557 action[op] = no_action;
558
559 /* If the operand uses pre-decrement addressing but we
560 want to get the parts high order first,
561 decrement the former register explicitly
562 and change the operand into ordinary indexing. */
563 if (optype == PUSHOP && order == big)
564 {
565 gcc_assert (action != NULL);
566 action[op] = dec_before;
567 operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
568 XEXP (XEXP (operands[op], 0), 0));
569 optype = OFFSOP;
570 }
571 /* If the operand uses post-increment mode but we want
572 to get the parts low order first, change the operand
573 into ordinary indexing and remember to increment
574 the register explicitly when we're done. */
575 else if (optype == POPOP && order == little)
576 {
577 gcc_assert (action != NULL);
578 action[op] = inc_after;
579 operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
580 XEXP (XEXP (operands[op], 0), 0));
581 optype = OFFSOP;
582 }
583
584 if (GET_CODE (operands[op]) == CONST_DOUBLE)
585 {
586 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[op]);
587 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
588 }
589
590 for (i = 0; i < words; i++)
591 {
592 if (order == big)
593 w = i;
594 else if (sameoff)
595 w = words - 1;
596 else
597 w = words - 1 - i;
598
599 /* Set the output operand to be word "w" of the input. */
600 if (optype == REGOP)
601 exops[i][op] = gen_rtx_REG (HImode, REGNO (operands[op]) + w);
602 else if (optype == OFFSOP)
603 exops[i][op] = adjust_address (operands[op], HImode, w * 2);
604 else if (optype == CNSTOP)
605 {
606 if (GET_CODE (operands[op]) == CONST_DOUBLE)
607 {
608 sh = 16 - (w & 1) * 16;
609 exops[i][op] = gen_rtx_CONST_INT (HImode, (sval[w / 2] >> sh) & 0xffff);
610 }
611 else
612 {
613 sh = ((words - 1 - w) * 16);
614 exops[i][op] = gen_rtx_CONST_INT (HImode, trunc_int_for_mode (INTVAL(operands[op]) >> sh, HImode));
615 }
616 }
617 else
618 exops[i][op] = operands[op];
619 }
620 }
621 return true;
622 }
623
624 /* Output assembler code to perform a multiple-word move insn
625 with operands OPERANDS. This moves 2 or 4 words depending
626 on the machine mode of the operands. */
627
628 const char *
output_move_multiple(rtx * operands)629 output_move_multiple (rtx *operands)
630 {
631 rtx exops[4][2];
632 pdp11_action action[2];
633 int i, words;
634
635 words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
636
637 pdp11_expand_operands (operands, exops, 2, action, either);
638
639 /* Check for explicit decrement before. */
640 if (action[0] == dec_before)
641 {
642 operands[0] = XEXP (operands[0], 0);
643 output_asm_insn ("sub $4,%0", operands);
644 }
645 if (action[1] == dec_before)
646 {
647 operands[1] = XEXP (operands[1], 0);
648 output_asm_insn ("sub $4,%1", operands);
649 }
650
651 /* Do the words. */
652 for (i = 0; i < words; i++)
653 output_asm_insn (singlemove_string (exops[i]), exops[i]);
654
655 /* Check for increment after. */
656 if (action[0] == inc_after)
657 {
658 operands[0] = XEXP (operands[0], 0);
659 output_asm_insn ("add $4,%0", operands);
660 }
661 if (action[1] == inc_after)
662 {
663 operands[1] = XEXP (operands[1], 0);
664 output_asm_insn ("add $4,%1", operands);
665 }
666
667 return "";
668 }
669
670 /* Output an ascii string. */
671 void
output_ascii(FILE * file,const char * p,int size)672 output_ascii (FILE *file, const char *p, int size)
673 {
674 int i;
675
676 /* This used to output .byte "string", which doesn't work with the UNIX
677 assembler and I think not with DEC ones either. */
678 fprintf (file, "\t.byte ");
679
680 for (i = 0; i < size; i++)
681 {
682 register int c = p[i];
683 if (c < 0)
684 c += 256;
685 fprintf (file, "%#o", c);
686 if (i < size - 1)
687 putc (',', file);
688 }
689 putc ('\n', file);
690 }
691
692
693 void
pdp11_asm_output_var(FILE * file,const char * name,int size,int align,bool global)694 pdp11_asm_output_var (FILE *file, const char *name, int size,
695 int align, bool global)
696 {
697 if (align > 8)
698 fprintf (file, "\n\t.even\n");
699 if (global)
700 {
701 fprintf (file, ".globl ");
702 assemble_name (file, name);
703 }
704 fprintf (file, "\n");
705 assemble_name (file, name);
706 fprintf (file, ": .=.+ %#ho\n", (unsigned short)size);
707 }
708
709 static void
pdp11_asm_print_operand(FILE * file,rtx x,int code)710 pdp11_asm_print_operand (FILE *file, rtx x, int code)
711 {
712 REAL_VALUE_TYPE r;
713 long sval[2];
714
715 if (code == '#')
716 fprintf (file, "#");
717 else if (code == '@')
718 {
719 if (TARGET_UNIX_ASM)
720 fprintf (file, "*");
721 else
722 fprintf (file, "@");
723 }
724 else if (GET_CODE (x) == REG)
725 fprintf (file, "%s", reg_names[REGNO (x)]);
726 else if (GET_CODE (x) == MEM)
727 output_address (XEXP (x, 0));
728 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != SImode)
729 {
730 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
731 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
732 fprintf (file, "$%#lo", sval[0] >> 16);
733 }
734 else
735 {
736 putc ('$', file);
737 output_addr_const_pdp11 (file, x);
738 }
739 }
740
741 static bool
pdp11_asm_print_operand_punct_valid_p(unsigned char c)742 pdp11_asm_print_operand_punct_valid_p (unsigned char c)
743 {
744 return (c == '#' || c == '@');
745 }
746
747 void
print_operand_address(FILE * file,register rtx addr)748 print_operand_address (FILE *file, register rtx addr)
749 {
750 register rtx breg;
751 rtx offset;
752 int again = 0;
753
754 retry:
755
756 switch (GET_CODE (addr))
757 {
758 case MEM:
759 if (TARGET_UNIX_ASM)
760 fprintf (file, "*");
761 else
762 fprintf (file, "@");
763 addr = XEXP (addr, 0);
764 again = 1;
765 goto retry;
766
767 case REG:
768 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
769 break;
770
771 case PRE_MODIFY:
772 case PRE_DEC:
773 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
774 break;
775
776 case POST_MODIFY:
777 case POST_INC:
778 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
779 break;
780
781 case PLUS:
782 breg = 0;
783 offset = 0;
784 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
785 || GET_CODE (XEXP (addr, 0)) == MEM)
786 {
787 offset = XEXP (addr, 0);
788 addr = XEXP (addr, 1);
789 }
790 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
791 || GET_CODE (XEXP (addr, 1)) == MEM)
792 {
793 offset = XEXP (addr, 1);
794 addr = XEXP (addr, 0);
795 }
796 if (GET_CODE (addr) != PLUS)
797 ;
798 else if (GET_CODE (XEXP (addr, 0)) == REG)
799 {
800 breg = XEXP (addr, 0);
801 addr = XEXP (addr, 1);
802 }
803 else if (GET_CODE (XEXP (addr, 1)) == REG)
804 {
805 breg = XEXP (addr, 1);
806 addr = XEXP (addr, 0);
807 }
808 if (GET_CODE (addr) == REG)
809 {
810 gcc_assert (breg == 0);
811 breg = addr;
812 addr = 0;
813 }
814 if (offset != 0)
815 {
816 gcc_assert (addr == 0);
817 addr = offset;
818 }
819 if (addr != 0)
820 output_addr_const_pdp11 (file, addr);
821 if (breg != 0)
822 {
823 gcc_assert (GET_CODE (breg) == REG);
824 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
825 }
826 break;
827
828 default:
829 if (!again && GET_CODE (addr) == CONST_INT)
830 {
831 /* Absolute (integer number) address. */
832 if (!TARGET_UNIX_ASM)
833 fprintf (file, "@$");
834 }
835 output_addr_const_pdp11 (file, addr);
836 }
837 }
838
839 /* Target hook to assemble integer objects. We need to use the
840 pdp-specific version of output_addr_const. */
841
842 static bool
pdp11_assemble_integer(rtx x,unsigned int size,int aligned_p)843 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
844 {
845 if (aligned_p)
846 switch (size)
847 {
848 case 1:
849 fprintf (asm_out_file, "\t.byte\t");
850 output_addr_const_pdp11 (asm_out_file, GEN_INT (INTVAL (x) & 0xff));
851 ;
852 fprintf (asm_out_file, " /* char */\n");
853 return true;
854
855 case 2:
856 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
857 output_addr_const_pdp11 (asm_out_file, x);
858 fprintf (asm_out_file, " /* short */\n");
859 return true;
860 }
861 return default_assemble_integer (x, size, aligned_p);
862 }
863
864
865 /* register move costs, indexed by regs */
866
867 static const int move_costs[N_REG_CLASSES][N_REG_CLASSES] =
868 {
869 /* NO MUL GEN LFPU NLFPU FPU ALL */
870
871 /* NO */ { 0, 0, 0, 0, 0, 0, 0},
872 /* MUL */ { 0, 2, 2, 22, 22, 22, 22},
873 /* GEN */ { 0, 2, 2, 22, 22, 22, 22},
874 /* LFPU */ { 0, 22, 22, 2, 2, 2, 22},
875 /* NLFPU */ { 0, 22, 22, 2, 10, 10, 22},
876 /* FPU */ { 0, 22, 22, 2, 10, 10, 22},
877 /* ALL */ { 0, 22, 22, 22, 22, 22, 22}
878 } ;
879
880
881 /* -- note that some moves are tremendously expensive,
882 because they require lots of tricks! do we have to
883 charge the costs incurred by secondary reload class
884 -- as we do here with 10 -- or not ? */
885
886 static int
pdp11_register_move_cost(enum machine_mode mode ATTRIBUTE_UNUSED,reg_class_t c1,reg_class_t c2)887 pdp11_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
888 reg_class_t c1, reg_class_t c2)
889 {
890 return move_costs[(int)c1][(int)c2];
891 }
892
893 static bool
pdp11_rtx_costs(rtx x,int code,int outer_code ATTRIBUTE_UNUSED,int opno ATTRIBUTE_UNUSED,int * total,bool speed ATTRIBUTE_UNUSED)894 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
895 int opno ATTRIBUTE_UNUSED, int *total,
896 bool speed ATTRIBUTE_UNUSED)
897 {
898 switch (code)
899 {
900 case CONST_INT:
901 if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
902 {
903 *total = 0;
904 return true;
905 }
906 /* FALLTHRU */
907
908 case CONST:
909 case LABEL_REF:
910 case SYMBOL_REF:
911 /* Twice as expensive as REG. */
912 *total = 2;
913 return true;
914
915 case CONST_DOUBLE:
916 /* Twice (or 4 times) as expensive as 16 bit. */
917 *total = 4;
918 return true;
919
920 case MULT:
921 /* ??? There is something wrong in MULT because MULT is not
922 as cheap as total = 2 even if we can shift! */
923 /* If optimizing for size make mult etc cheap, but not 1, so when
924 in doubt the faster insn is chosen. */
925 if (optimize_size)
926 *total = COSTS_N_INSNS (2);
927 else
928 *total = COSTS_N_INSNS (11);
929 return false;
930
931 case DIV:
932 if (optimize_size)
933 *total = COSTS_N_INSNS (2);
934 else
935 *total = COSTS_N_INSNS (25);
936 return false;
937
938 case MOD:
939 if (optimize_size)
940 *total = COSTS_N_INSNS (2);
941 else
942 *total = COSTS_N_INSNS (26);
943 return false;
944
945 case ABS:
946 /* Equivalent to length, so same for optimize_size. */
947 *total = COSTS_N_INSNS (3);
948 return false;
949
950 case ZERO_EXTEND:
951 /* Only used for qi->hi. */
952 *total = COSTS_N_INSNS (1);
953 return false;
954
955 case SIGN_EXTEND:
956 if (GET_MODE (x) == HImode)
957 *total = COSTS_N_INSNS (1);
958 else if (GET_MODE (x) == SImode)
959 *total = COSTS_N_INSNS (6);
960 else
961 *total = COSTS_N_INSNS (2);
962 return false;
963
964 case ASHIFT:
965 case LSHIFTRT:
966 case ASHIFTRT:
967 if (optimize_size)
968 *total = COSTS_N_INSNS (1);
969 else if (GET_MODE (x) == QImode)
970 {
971 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
972 *total = COSTS_N_INSNS (8); /* worst case */
973 else
974 *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
975 }
976 else if (GET_MODE (x) == HImode)
977 {
978 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
979 {
980 if (abs (INTVAL (XEXP (x, 1))) == 1)
981 *total = COSTS_N_INSNS (1);
982 else
983 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
984 }
985 else
986 *total = COSTS_N_INSNS (10); /* worst case */
987 }
988 else if (GET_MODE (x) == SImode)
989 {
990 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
991 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
992 else /* worst case */
993 *total = COSTS_N_INSNS (18);
994 }
995 return false;
996
997 default:
998 return false;
999 }
1000 }
1001
1002 const char *
output_jump(enum rtx_code code,int inv,int length)1003 output_jump (enum rtx_code code, int inv, int length)
1004 {
1005 static int x = 0;
1006
1007 static char buf[1000];
1008 const char *pos, *neg;
1009
1010 if (cc_prev_status.flags & CC_NO_OVERFLOW)
1011 {
1012 switch (code)
1013 {
1014 case GTU: code = GT; break;
1015 case LTU: code = LT; break;
1016 case GEU: code = GE; break;
1017 case LEU: code = LE; break;
1018 default: ;
1019 }
1020 }
1021 switch (code)
1022 {
1023 case EQ: pos = "beq", neg = "bne"; break;
1024 case NE: pos = "bne", neg = "beq"; break;
1025 case GT: pos = "bgt", neg = "ble"; break;
1026 case GTU: pos = "bhi", neg = "blos"; break;
1027 case LT: pos = "blt", neg = "bge"; break;
1028 case LTU: pos = "blo", neg = "bhis"; break;
1029 case GE: pos = "bge", neg = "blt"; break;
1030 case GEU: pos = "bhis", neg = "blo"; break;
1031 case LE: pos = "ble", neg = "bgt"; break;
1032 case LEU: pos = "blos", neg = "bhi"; break;
1033 default: gcc_unreachable ();
1034 }
1035
1036 #if 0
1037 /* currently we don't need this, because the tstdf and cmpdf
1038 copy the condition code immediately, and other float operations are not
1039 yet recognized as changing the FCC - if so, then the length-cost of all
1040 jump insns increases by one, because we have to potentially copy the
1041 FCC! */
1042 if (cc_status.flags & CC_IN_FPU)
1043 output_asm_insn("cfcc", NULL);
1044 #endif
1045
1046 switch (length)
1047 {
1048 case 2:
1049
1050 sprintf(buf, "%s %%l1", inv ? neg : pos);
1051
1052 return buf;
1053
1054 case 6:
1055
1056 sprintf(buf, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv ? pos : neg, x, x);
1057
1058 x++;
1059
1060 return buf;
1061
1062 default:
1063
1064 gcc_unreachable ();
1065 }
1066
1067 }
1068
1069 void
notice_update_cc_on_set(rtx exp,rtx insn ATTRIBUTE_UNUSED)1070 notice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED)
1071 {
1072 if (GET_CODE (SET_DEST (exp)) == CC0)
1073 {
1074 cc_status.flags = 0;
1075 cc_status.value1 = SET_DEST (exp);
1076 cc_status.value2 = SET_SRC (exp);
1077 }
1078 else if (GET_CODE (SET_SRC (exp)) == CALL)
1079 {
1080 CC_STATUS_INIT;
1081 }
1082 else if (SET_DEST(exp) == pc_rtx)
1083 {
1084 /* jump */
1085 }
1086 else if (GET_MODE (SET_DEST(exp)) == HImode
1087 || GET_MODE (SET_DEST(exp)) == QImode)
1088 {
1089 cc_status.flags = GET_CODE (SET_SRC(exp)) == MINUS ? 0 : CC_NO_OVERFLOW;
1090 cc_status.value1 = SET_SRC (exp);
1091 cc_status.value2 = SET_DEST (exp);
1092
1093 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1094 && cc_status.value2
1095 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1096 cc_status.value2 = 0;
1097 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
1098 && cc_status.value2
1099 && GET_CODE (cc_status.value2) == MEM)
1100 cc_status.value2 = 0;
1101 }
1102 else
1103 {
1104 CC_STATUS_INIT;
1105 }
1106 }
1107
1108
1109 int
simple_memory_operand(rtx op,enum machine_mode mode ATTRIBUTE_UNUSED)1110 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1111 {
1112 rtx addr;
1113
1114 /* Eliminate non-memory operations */
1115 if (GET_CODE (op) != MEM)
1116 return FALSE;
1117
1118 #if 0
1119 /* dword operations really put out 2 instructions, so eliminate them. */
1120 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
1121 return FALSE;
1122 #endif
1123
1124 /* Decode the address now. */
1125
1126 indirection:
1127
1128 addr = XEXP (op, 0);
1129
1130 switch (GET_CODE (addr))
1131 {
1132 case REG:
1133 /* (R0) - no extra cost */
1134 return 1;
1135
1136 case PRE_DEC:
1137 case POST_INC:
1138 /* -(R0), (R0)+ - cheap! */
1139 return 0;
1140
1141 case MEM:
1142 /* cheap - is encoded in addressing mode info!
1143
1144 -- except for @(R0), which has to be @0(R0) !!! */
1145
1146 if (GET_CODE (XEXP (addr, 0)) == REG)
1147 return 0;
1148
1149 op=addr;
1150 goto indirection;
1151
1152 case CONST_INT:
1153 case LABEL_REF:
1154 case CONST:
1155 case SYMBOL_REF:
1156 /* @#address - extra cost */
1157 return 0;
1158
1159 case PLUS:
1160 /* X(R0) - extra cost */
1161 return 0;
1162
1163 default:
1164 break;
1165 }
1166
1167 return FALSE;
1168 }
1169
1170
1171 /*
1172 * output a block move:
1173 *
1174 * operands[0] ... to
1175 * operands[1] ... from
1176 * operands[2] ... length
1177 * operands[3] ... alignment
1178 * operands[4] ... scratch register
1179 */
1180
1181
1182 const char *
output_block_move(rtx * operands)1183 output_block_move(rtx *operands)
1184 {
1185 static int count = 0;
1186 char buf[200];
1187 int unroll;
1188 int lastbyte = 0;
1189
1190 /* Move of zero bytes is a NOP. */
1191 if (operands[2] == const0_rtx)
1192 return "";
1193
1194 /* Look for moves by small constant byte counts, those we'll
1195 expand to straight line code. */
1196 if (CONSTANT_P (operands[2]))
1197 {
1198 if (INTVAL (operands[2]) < 16
1199 && (!optimize_size || INTVAL (operands[2]) < 5)
1200 && INTVAL (operands[3]) == 1)
1201 {
1202 register int i;
1203
1204 for (i = 1; i <= INTVAL (operands[2]); i++)
1205 output_asm_insn("movb (%1)+, (%0)+", operands);
1206
1207 return "";
1208 }
1209 else if (INTVAL(operands[2]) < 32
1210 && (!optimize_size || INTVAL (operands[2]) < 9)
1211 && INTVAL (operands[3]) >= 2)
1212 {
1213 register int i;
1214
1215 for (i = 1; i <= INTVAL (operands[2]) / 2; i++)
1216 output_asm_insn ("mov (%1)+, (%0)+", operands);
1217 if (INTVAL (operands[2]) & 1)
1218 output_asm_insn ("movb (%1), (%0)", operands);
1219
1220 return "";
1221 }
1222 }
1223
1224 /* Ideally we'd look for moves that are multiples of 4 or 8
1225 bytes and handle those by unrolling the move loop. That
1226 makes for a lot of code if done at run time, but it's ok
1227 for constant counts. Also, for variable counts we have
1228 to worry about odd byte count with even aligned pointers.
1229 On 11/40 and up we handle that case; on older machines
1230 we don't and just use byte-wise moves all the time. */
1231
1232 if (CONSTANT_P (operands[2]) )
1233 {
1234 if (INTVAL (operands[3]) < 2)
1235 unroll = 0;
1236 else
1237 {
1238 lastbyte = INTVAL (operands[2]) & 1;
1239
1240 if (optimize_size || INTVAL (operands[2]) & 2)
1241 unroll = 1;
1242 else if (INTVAL (operands[2]) & 4)
1243 unroll = 2;
1244 else
1245 unroll = 3;
1246 }
1247
1248 /* Loop count is byte count scaled by unroll. */
1249 operands[2] = GEN_INT (INTVAL (operands[2]) >> unroll);
1250 output_asm_insn ("mov %2, %4", operands);
1251 }
1252 else
1253 {
1254 /* Variable byte count; use the input register
1255 as the scratch. */
1256 operands[4] = operands[2];
1257
1258 /* Decide whether to move by words, and check
1259 the byte count for zero. */
1260 if (TARGET_40_PLUS && INTVAL (operands[3]) > 1)
1261 {
1262 unroll = 1;
1263 output_asm_insn ("asr %4", operands);
1264 }
1265 else
1266 {
1267 unroll = 0;
1268 output_asm_insn ("tst %4", operands);
1269 }
1270 sprintf (buf, "beq movestrhi%d", count + 1);
1271 output_asm_insn (buf, NULL);
1272 }
1273
1274 /* Output the loop label. */
1275 sprintf (buf, "\nmovestrhi%d:", count);
1276 output_asm_insn (buf, NULL);
1277
1278 /* Output the appropriate move instructions. */
1279 switch (unroll)
1280 {
1281 case 0:
1282 output_asm_insn ("movb (%1)+, (%0)+", operands);
1283 break;
1284
1285 case 1:
1286 output_asm_insn ("mov (%1)+, (%0)+", operands);
1287 break;
1288
1289 case 2:
1290 output_asm_insn ("mov (%1)+, (%0)+", operands);
1291 output_asm_insn ("mov (%1)+, (%0)+", operands);
1292 break;
1293
1294 default:
1295 output_asm_insn ("mov (%1)+, (%0)+", operands);
1296 output_asm_insn ("mov (%1)+, (%0)+", operands);
1297 output_asm_insn ("mov (%1)+, (%0)+", operands);
1298 output_asm_insn ("mov (%1)+, (%0)+", operands);
1299 break;
1300 }
1301
1302 /* Output the decrement and test. */
1303 if (TARGET_40_PLUS)
1304 {
1305 sprintf (buf, "sob %%4, movestrhi%d", count);
1306 output_asm_insn (buf, operands);
1307 }
1308 else
1309 {
1310 output_asm_insn ("dec %4", operands);
1311 sprintf (buf, "bgt movestrhi%d", count);
1312 output_asm_insn (buf, NULL);
1313 }
1314 count ++;
1315
1316 /* If constant odd byte count, move the last byte. */
1317 if (lastbyte)
1318 output_asm_insn ("movb (%1), (%0)", operands);
1319 else if (!CONSTANT_P (operands[2]))
1320 {
1321 /* Output the destination label for the zero byte count check. */
1322 sprintf (buf, "\nmovestrhi%d:", count);
1323 output_asm_insn (buf, NULL);
1324 count++;
1325
1326 /* If we did word moves, check for trailing last byte. */
1327 if (unroll)
1328 {
1329 sprintf (buf, "bcc movestrhi%d", count);
1330 output_asm_insn (buf, NULL);
1331 output_asm_insn ("movb (%1), (%0)", operands);
1332 sprintf (buf, "\nmovestrhi%d:", count);
1333 output_asm_insn (buf, NULL);
1334 count++;
1335 }
1336 }
1337
1338 return "";
1339 }
1340
1341 /* This function checks whether a real value can be encoded as
1342 a literal, i.e., addressing mode 27. In that mode, real values
1343 are one word values, so the remaining 48 bits have to be zero. */
1344 int
legitimate_const_double_p(rtx address)1345 legitimate_const_double_p (rtx address)
1346 {
1347 REAL_VALUE_TYPE r;
1348 long sval[2];
1349 REAL_VALUE_FROM_CONST_DOUBLE (r, address);
1350 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
1351 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1352 return 1;
1353 return 0;
1354 }
1355
1356 /* Implement CANNOT_CHANGE_MODE_CLASS. */
1357 bool
pdp11_cannot_change_mode_class(enum machine_mode from,enum machine_mode to,enum reg_class rclass)1358 pdp11_cannot_change_mode_class (enum machine_mode from,
1359 enum machine_mode to,
1360 enum reg_class rclass)
1361 {
1362 /* Also, FPU registers contain a whole float value and the parts of
1363 it are not separately accessible.
1364
1365 So we disallow all mode changes involving FPRs. */
1366 if (FLOAT_MODE_P (from) != FLOAT_MODE_P (to))
1367 return true;
1368
1369 return reg_classes_intersect_p (FPU_REGS, rclass);
1370 }
1371
1372 /* TARGET_PREFERRED_RELOAD_CLASS
1373
1374 Given an rtx X being reloaded into a reg required to be
1375 in class CLASS, return the class of reg to actually use.
1376 In general this is just CLASS; but on some machines
1377 in some cases it is preferable to use a more restrictive class.
1378
1379 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1380
1381 static reg_class_t
pdp11_preferred_reload_class(rtx x,reg_class_t rclass)1382 pdp11_preferred_reload_class (rtx x, reg_class_t rclass)
1383 {
1384 if (rclass == FPU_REGS)
1385 return LOAD_FPU_REGS;
1386 if (rclass == ALL_REGS)
1387 {
1388 if (FLOAT_MODE_P (GET_MODE (x)))
1389 return LOAD_FPU_REGS;
1390 else
1391 return GENERAL_REGS;
1392 }
1393 return rclass;
1394 }
1395
1396 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1397
1398 Given an rtx X being reloaded into a reg required to be
1399 in class CLASS, return the class of reg to actually use.
1400 In general this is just CLASS; but on some machines
1401 in some cases it is preferable to use a more restrictive class.
1402
1403 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1404
1405 static reg_class_t
pdp11_preferred_output_reload_class(rtx x,reg_class_t rclass)1406 pdp11_preferred_output_reload_class (rtx x, reg_class_t rclass)
1407 {
1408 if (rclass == FPU_REGS)
1409 return LOAD_FPU_REGS;
1410 if (rclass == ALL_REGS)
1411 {
1412 if (FLOAT_MODE_P (GET_MODE (x)))
1413 return LOAD_FPU_REGS;
1414 else
1415 return GENERAL_REGS;
1416 }
1417 return rclass;
1418 }
1419
1420
1421 /* TARGET_SECONDARY_RELOAD.
1422
1423 FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1424 intermediate register (AC0-AC3: LOAD_FPU_REGS). Everything else
1425 can be loade/stored directly. */
1426 static reg_class_t
pdp11_secondary_reload(bool in_p ATTRIBUTE_UNUSED,rtx x,reg_class_t reload_class,enum machine_mode reload_mode ATTRIBUTE_UNUSED,secondary_reload_info * sri ATTRIBUTE_UNUSED)1427 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED,
1428 rtx x,
1429 reg_class_t reload_class,
1430 enum machine_mode reload_mode ATTRIBUTE_UNUSED,
1431 secondary_reload_info *sri ATTRIBUTE_UNUSED)
1432 {
1433 if (reload_class != NO_LOAD_FPU_REGS || GET_CODE (x) != REG ||
1434 REGNO_REG_CLASS (REGNO (x)) == LOAD_FPU_REGS)
1435 return NO_REGS;
1436
1437 return LOAD_FPU_REGS;
1438 }
1439
1440 /* Target routine to check if register to register move requires memory.
1441
1442 The answer is yes if we're going between general register and FPU
1443 registers. The mode doesn't matter in making this check.
1444 */
1445 bool
pdp11_secondary_memory_needed(reg_class_t c1,reg_class_t c2,enum machine_mode mode ATTRIBUTE_UNUSED)1446 pdp11_secondary_memory_needed (reg_class_t c1, reg_class_t c2,
1447 enum machine_mode mode ATTRIBUTE_UNUSED)
1448 {
1449 int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS ||
1450 c1 == FPU_REGS);
1451 int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS ||
1452 c2 == FPU_REGS);
1453
1454 return (fromfloat != tofloat);
1455 }
1456
1457 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
1458 that is a valid memory address for an instruction.
1459 The MODE argument is the machine mode for the MEM expression
1460 that wants to use this address.
1461
1462 */
1463
1464 static bool
pdp11_legitimate_address_p(enum machine_mode mode,rtx operand,bool strict)1465 pdp11_legitimate_address_p (enum machine_mode mode,
1466 rtx operand, bool strict)
1467 {
1468 rtx xfoob;
1469
1470 /* accept @#address */
1471 if (CONSTANT_ADDRESS_P (operand))
1472 return true;
1473
1474 switch (GET_CODE (operand))
1475 {
1476 case REG:
1477 /* accept (R0) */
1478 return !strict || REGNO_OK_FOR_BASE_P (REGNO (operand));
1479
1480 case PLUS:
1481 /* accept X(R0) */
1482 return GET_CODE (XEXP (operand, 0)) == REG
1483 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))))
1484 && CONSTANT_ADDRESS_P (XEXP (operand, 1));
1485
1486 case PRE_DEC:
1487 /* accept -(R0) */
1488 return GET_CODE (XEXP (operand, 0)) == REG
1489 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1490
1491 case POST_INC:
1492 /* accept (R0)+ */
1493 return GET_CODE (XEXP (operand, 0)) == REG
1494 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1495
1496 case PRE_MODIFY:
1497 /* accept -(SP) -- which uses PRE_MODIFY for byte mode */
1498 return GET_CODE (XEXP (operand, 0)) == REG
1499 && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1500 && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1501 && GET_CODE (XEXP (xfoob, 0)) == REG
1502 && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1503 && CONSTANT_P (XEXP (xfoob, 1))
1504 && INTVAL (XEXP (xfoob,1)) == -2;
1505
1506 case POST_MODIFY:
1507 /* accept (SP)+ -- which uses POST_MODIFY for byte mode */
1508 return GET_CODE (XEXP (operand, 0)) == REG
1509 && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1510 && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1511 && GET_CODE (XEXP (xfoob, 0)) == REG
1512 && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1513 && CONSTANT_P (XEXP (xfoob, 1))
1514 && INTVAL (XEXP (xfoob,1)) == 2;
1515
1516 case MEM:
1517 /* handle another level of indirection ! */
1518 xfoob = XEXP (operand, 0);
1519
1520 /* (MEM:xx (MEM:xx ())) is not valid for SI, DI and currently
1521 also forbidden for float, because we have to handle this
1522 in output_move_double and/or output_move_quad() - we could
1523 do it, but currently it's not worth it!!!
1524 now that DFmode cannot go into CPU register file,
1525 maybe I should allow float ...
1526 but then I have to handle memory-to-memory moves in movdf ?? */
1527 if (GET_MODE_BITSIZE(mode) > 16)
1528 return false;
1529
1530 /* accept @address */
1531 if (CONSTANT_ADDRESS_P (xfoob))
1532 return true;
1533
1534 switch (GET_CODE (xfoob))
1535 {
1536 case REG:
1537 /* accept @(R0) - which is @0(R0) */
1538 return !strict || REGNO_OK_FOR_BASE_P(REGNO (xfoob));
1539
1540 case PLUS:
1541 /* accept @X(R0) */
1542 return GET_CODE (XEXP (xfoob, 0)) == REG
1543 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))))
1544 && CONSTANT_ADDRESS_P (XEXP (xfoob, 1));
1545
1546 case PRE_DEC:
1547 /* accept @-(R0) */
1548 return GET_CODE (XEXP (xfoob, 0)) == REG
1549 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1550
1551 case POST_INC:
1552 /* accept @(R0)+ */
1553 return GET_CODE (XEXP (xfoob, 0)) == REG
1554 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1555
1556 default:
1557 /* anything else is invalid */
1558 return false;
1559 }
1560
1561 default:
1562 /* anything else is invalid */
1563 return false;
1564 }
1565 }
1566
1567 /* Return the class number of the smallest class containing
1568 reg number REGNO. */
1569 enum reg_class
pdp11_regno_reg_class(int regno)1570 pdp11_regno_reg_class (int regno)
1571 {
1572 if (regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM)
1573 return GENERAL_REGS;
1574 else if (regno > AC3_REGNUM)
1575 return NO_LOAD_FPU_REGS;
1576 else if (regno >= AC0_REGNUM)
1577 return LOAD_FPU_REGS;
1578 else if (regno & 1)
1579 return MUL_REGS;
1580 else
1581 return GENERAL_REGS;
1582 }
1583
1584
1585 int
pdp11_sp_frame_offset(void)1586 pdp11_sp_frame_offset (void)
1587 {
1588 int offset = 0, regno;
1589 offset = get_frame_size();
1590 for (regno = 0; regno <= PC_REGNUM; regno++)
1591 if (pdp11_saved_regno (regno))
1592 offset += 2;
1593 for (regno = AC0_REGNUM; regno <= AC5_REGNUM; regno++)
1594 if (pdp11_saved_regno (regno))
1595 offset += 8;
1596
1597 return offset;
1598 }
1599
1600 /* Return the offset between two registers, one to be eliminated, and the other
1601 its replacement, at the start of a routine. */
1602
1603 int
pdp11_initial_elimination_offset(int from,int to)1604 pdp11_initial_elimination_offset (int from, int to)
1605 {
1606 int spoff;
1607
1608 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
1609 return 4;
1610 else if (from == FRAME_POINTER_REGNUM
1611 && to == HARD_FRAME_POINTER_REGNUM)
1612 return 0;
1613 else
1614 {
1615 gcc_assert (to == STACK_POINTER_REGNUM);
1616
1617 /* Get the size of the register save area. */
1618 spoff = pdp11_sp_frame_offset ();
1619 if (from == FRAME_POINTER_REGNUM)
1620 return spoff;
1621
1622 gcc_assert (from == ARG_POINTER_REGNUM);
1623
1624 /* If there is a frame pointer, that is saved too. */
1625 if (frame_pointer_needed)
1626 spoff += 2;
1627
1628 /* Account for the saved PC in the function call. */
1629 return spoff + 2;
1630 }
1631 }
1632
1633 /* A copy of output_addr_const modified for pdp11 expression syntax.
1634 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1635 use, and for debugging output, which we don't support with this port either.
1636 So this copy should get called whenever needed.
1637 */
1638 void
output_addr_const_pdp11(FILE * file,rtx x)1639 output_addr_const_pdp11 (FILE *file, rtx x)
1640 {
1641 char buf[256];
1642 int i;
1643
1644 restart:
1645 switch (GET_CODE (x))
1646 {
1647 case PC:
1648 gcc_assert (flag_pic);
1649 putc ('.', file);
1650 break;
1651
1652 case SYMBOL_REF:
1653 assemble_name (file, XSTR (x, 0));
1654 break;
1655
1656 case LABEL_REF:
1657 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1658 assemble_name (file, buf);
1659 break;
1660
1661 case CODE_LABEL:
1662 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1663 assemble_name (file, buf);
1664 break;
1665
1666 case CONST_INT:
1667 i = INTVAL (x);
1668 if (i < 0)
1669 {
1670 i = -i;
1671 fprintf (file, "-");
1672 }
1673 fprintf (file, "%#o", i & 0xffff);
1674 break;
1675
1676 case CONST:
1677 /* This used to output parentheses around the expression,
1678 but that does not work on the 386 (either ATT or BSD assembler). */
1679 output_addr_const_pdp11 (file, XEXP (x, 0));
1680 break;
1681
1682 case CONST_DOUBLE:
1683 if (GET_MODE (x) == VOIDmode)
1684 {
1685 /* We can use %o if the number is one word and positive. */
1686 gcc_assert (!CONST_DOUBLE_HIGH (x));
1687 fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
1688 }
1689 else
1690 /* We can't handle floating point constants;
1691 PRINT_OPERAND must handle them. */
1692 output_operand_lossage ("floating constant misused");
1693 break;
1694
1695 case PLUS:
1696 /* Some assemblers need integer constants to appear last (e.g. masm). */
1697 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1698 {
1699 output_addr_const_pdp11 (file, XEXP (x, 1));
1700 if (INTVAL (XEXP (x, 0)) >= 0)
1701 fprintf (file, "+");
1702 output_addr_const_pdp11 (file, XEXP (x, 0));
1703 }
1704 else
1705 {
1706 output_addr_const_pdp11 (file, XEXP (x, 0));
1707 if (INTVAL (XEXP (x, 1)) >= 0)
1708 fprintf (file, "+");
1709 output_addr_const_pdp11 (file, XEXP (x, 1));
1710 }
1711 break;
1712
1713 case MINUS:
1714 /* Avoid outputting things like x-x or x+5-x,
1715 since some assemblers can't handle that. */
1716 x = simplify_subtraction (x);
1717 if (GET_CODE (x) != MINUS)
1718 goto restart;
1719
1720 output_addr_const_pdp11 (file, XEXP (x, 0));
1721 if (GET_CODE (XEXP (x, 1)) != CONST_INT
1722 || INTVAL (XEXP (x, 1)) >= 0)
1723 fprintf (file, "-");
1724 output_addr_const_pdp11 (file, XEXP (x, 1));
1725 break;
1726
1727 case ZERO_EXTEND:
1728 case SIGN_EXTEND:
1729 output_addr_const_pdp11 (file, XEXP (x, 0));
1730 break;
1731
1732 default:
1733 output_operand_lossage ("invalid expression as operand");
1734 }
1735 }
1736
1737 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1738
1739 static bool
pdp11_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)1740 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1741 {
1742 /* Integers 32 bits and under, and scalar floats (if FPU), are returned
1743 in registers. The rest go into memory. */
1744 return (TYPE_MODE (type) == DImode
1745 || (FLOAT_MODE_P (TYPE_MODE (type)) && ! TARGET_AC0)
1746 || TREE_CODE (type) == VECTOR_TYPE
1747 || COMPLEX_MODE_P (TYPE_MODE (type)));
1748 }
1749
1750 /* Worker function for TARGET_FUNCTION_VALUE.
1751
1752 On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! ) */
1753
1754 static rtx
pdp11_function_value(const_tree valtype,const_tree fntype_or_decl ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)1755 pdp11_function_value (const_tree valtype,
1756 const_tree fntype_or_decl ATTRIBUTE_UNUSED,
1757 bool outgoing ATTRIBUTE_UNUSED)
1758 {
1759 return gen_rtx_REG (TYPE_MODE (valtype),
1760 BASE_RETURN_VALUE_REG(TYPE_MODE(valtype)));
1761 }
1762
1763 /* Worker function for TARGET_LIBCALL_VALUE. */
1764
1765 static rtx
pdp11_libcall_value(enum machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)1766 pdp11_libcall_value (enum machine_mode mode,
1767 const_rtx fun ATTRIBUTE_UNUSED)
1768 {
1769 return gen_rtx_REG (mode, BASE_RETURN_VALUE_REG(mode));
1770 }
1771
1772 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1773
1774 On the pdp, the first "output" reg is the only register thus used.
1775
1776 maybe ac0 ? - as option someday! */
1777
1778 static bool
pdp11_function_value_regno_p(const unsigned int regno)1779 pdp11_function_value_regno_p (const unsigned int regno)
1780 {
1781 return (regno == RETVAL_REGNUM) || (TARGET_AC0 && (regno == AC0_REGNUM));
1782 }
1783
1784 /* Worker function for TARGET_TRAMPOLINE_INIT.
1785
1786 trampoline - how should i do it in separate i+d ?
1787 have some allocate_trampoline magic???
1788
1789 the following should work for shared I/D:
1790
1791 MOV #STATIC, $4 01270Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
1792 JMP @#FUNCTION 000137 0x0000 <- FUNCTION
1793 */
1794
1795 static void
pdp11_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)1796 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1797 {
1798 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
1799 rtx mem;
1800
1801 gcc_assert (!TARGET_SPLIT);
1802
1803 mem = adjust_address (m_tramp, HImode, 0);
1804 emit_move_insn (mem, GEN_INT (012700+STATIC_CHAIN_REGNUM));
1805 mem = adjust_address (m_tramp, HImode, 2);
1806 emit_move_insn (mem, chain_value);
1807 mem = adjust_address (m_tramp, HImode, 4);
1808 emit_move_insn (mem, GEN_INT (000137));
1809 emit_move_insn (mem, fnaddr);
1810 }
1811
1812 /* Worker function for TARGET_FUNCTION_ARG.
1813
1814 Determine where to put an argument to a function.
1815 Value is zero to push the argument on the stack,
1816 or a hard register in which to store the argument.
1817
1818 MODE is the argument's machine mode.
1819 TYPE is the data type of the argument (as a tree).
1820 This is null for libcalls where that information may
1821 not be available.
1822 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1823 the preceding args and about the function being called.
1824 NAMED is nonzero if this argument is a named parameter
1825 (otherwise it is an extra parameter matching an ellipsis). */
1826
1827 static rtx
pdp11_function_arg(cumulative_args_t cum ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,const_tree type ATTRIBUTE_UNUSED,bool named ATTRIBUTE_UNUSED)1828 pdp11_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED,
1829 enum machine_mode mode ATTRIBUTE_UNUSED,
1830 const_tree type ATTRIBUTE_UNUSED,
1831 bool named ATTRIBUTE_UNUSED)
1832 {
1833 return NULL_RTX;
1834 }
1835
1836 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
1837
1838 Update the data in CUM to advance over an argument of mode MODE and
1839 data type TYPE. (TYPE is null for libcalls where that information
1840 may not be available.) */
1841
1842 static void
pdp11_function_arg_advance(cumulative_args_t cum_v,enum machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)1843 pdp11_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1844 const_tree type, bool named ATTRIBUTE_UNUSED)
1845 {
1846 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1847
1848 *cum += (mode != BLKmode
1849 ? GET_MODE_SIZE (mode)
1850 : int_size_in_bytes (type));
1851 }
1852
1853 /* Make sure everything's fine if we *don't* have an FPU.
1854 This assumes that putting a register in fixed_regs will keep the
1855 compiler's mitts completely off it. We don't bother to zero it out
1856 of register classes. Also fix incompatible register naming with
1857 the UNIX assembler. */
1858
1859 static void
pdp11_conditional_register_usage(void)1860 pdp11_conditional_register_usage (void)
1861 {
1862 int i;
1863 HARD_REG_SET x;
1864 if (!TARGET_FPU)
1865 {
1866 COPY_HARD_REG_SET (x, reg_class_contents[(int)FPU_REGS]);
1867 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ )
1868 if (TEST_HARD_REG_BIT (x, i))
1869 fixed_regs[i] = call_used_regs[i] = 1;
1870 }
1871
1872 if (TARGET_AC0)
1873 call_used_regs[AC0_REGNUM] = 1;
1874 if (TARGET_UNIX_ASM)
1875 {
1876 /* Change names of FPU registers for the UNIX assembler. */
1877 reg_names[8] = "fr0";
1878 reg_names[9] = "fr1";
1879 reg_names[10] = "fr2";
1880 reg_names[11] = "fr3";
1881 reg_names[12] = "fr4";
1882 reg_names[13] = "fr5";
1883 }
1884 }
1885
1886 static section *
pdp11_function_section(tree decl ATTRIBUTE_UNUSED,enum node_frequency freq ATTRIBUTE_UNUSED,bool startup ATTRIBUTE_UNUSED,bool exit ATTRIBUTE_UNUSED)1887 pdp11_function_section (tree decl ATTRIBUTE_UNUSED,
1888 enum node_frequency freq ATTRIBUTE_UNUSED,
1889 bool startup ATTRIBUTE_UNUSED,
1890 bool exit ATTRIBUTE_UNUSED)
1891 {
1892 return NULL;
1893 }
1894
1895 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1896
1897 static bool
pdp11_legitimate_constant_p(enum machine_mode mode ATTRIBUTE_UNUSED,rtx x)1898 pdp11_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1899 {
1900 return GET_CODE (x) != CONST_DOUBLE || legitimate_const_double_p (x);
1901 }
1902
1903 struct gcc_target targetm = TARGET_INITIALIZER;
1904