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