1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994-2022 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 #define IN_TARGET_CODE 1
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32 #include "df.h"
33 #include "memmodel.h"
34 #include "tm_p.h"
35 #include "insn-config.h"
36 #include "insn-attr.h"
37 #include "regs.h"
38 #include "emit-rtl.h"
39 #include "recog.h"
40 #include "conditions.h"
41 #include "output.h"
42 #include "stor-layout.h"
43 #include "varasm.h"
44 #include "calls.h"
45 #include "expr.h"
46 #include "builtins.h"
47 #include "dbxout.h"
48 #include "explow.h"
49 #include "expmed.h"
50
51 /* This file should be included last. */
52 #include "target-def.h"
53
54 /* this is the current value returned by the macro FIRST_PARM_OFFSET
55 defined in tm.h */
56 int current_first_parm_offset;
57
58 /* Routines to encode/decode pdp11 floats */
59 static void encode_pdp11_f (const struct real_format *fmt,
60 long *, const REAL_VALUE_TYPE *);
61 static void decode_pdp11_f (const struct real_format *,
62 REAL_VALUE_TYPE *, const long *);
63 static void encode_pdp11_d (const struct real_format *fmt,
64 long *, const REAL_VALUE_TYPE *);
65 static void decode_pdp11_d (const struct real_format *,
66 REAL_VALUE_TYPE *, const long *);
67
68 /* These two are taken from the corresponding vax descriptors
69 in real.cc, changing only the encode/decode routine pointers. */
70 const struct real_format pdp11_f_format =
71 {
72 encode_pdp11_f,
73 decode_pdp11_f,
74 2,
75 24,
76 24,
77 -127,
78 127,
79 15,
80 15,
81 0,
82 false,
83 false,
84 false,
85 false,
86 false,
87 false,
88 false,
89 false,
90 "pdp11_f"
91 };
92
93 const struct real_format pdp11_d_format =
94 {
95 encode_pdp11_d,
96 decode_pdp11_d,
97 2,
98 56,
99 56,
100 -127,
101 127,
102 15,
103 15,
104 0,
105 false,
106 false,
107 false,
108 false,
109 false,
110 false,
111 false,
112 false,
113 "pdp11_d"
114 };
115
116 static void
encode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)117 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
118 const REAL_VALUE_TYPE *r)
119 {
120 (*vax_f_format.encode) (fmt, buf, r);
121 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
122 }
123
124 static void
decode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)125 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
126 REAL_VALUE_TYPE *r, const long *buf)
127 {
128 long tbuf;
129 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
130 (*vax_f_format.decode) (fmt, r, &tbuf);
131 }
132
133 static void
encode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)134 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
135 const REAL_VALUE_TYPE *r)
136 {
137 (*vax_d_format.encode) (fmt, buf, r);
138 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
139 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
140 }
141
142 static void
decode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)143 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
144 REAL_VALUE_TYPE *r, const long *buf)
145 {
146 long tbuf[2];
147 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
148 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
149 (*vax_d_format.decode) (fmt, r, tbuf);
150 }
151
152 static const char *singlemove_string (rtx *);
153 static bool pdp11_assemble_integer (rtx, unsigned int, int);
154 static bool pdp11_rtx_costs (rtx, machine_mode, int, int, int *, bool);
155 static int pdp11_addr_cost (rtx, machine_mode, addr_space_t, bool);
156 static int pdp11_insn_cost (rtx_insn *insn, bool speed);
157 static rtx_insn *pdp11_md_asm_adjust (vec<rtx> &, vec<rtx> &,
158 vec<machine_mode> &, vec<const char *> &,
159 vec<rtx> &, HARD_REG_SET &, location_t);
160 static bool pdp11_return_in_memory (const_tree, const_tree);
161 static rtx pdp11_function_value (const_tree, const_tree, bool);
162 static rtx pdp11_libcall_value (machine_mode, const_rtx);
163 static bool pdp11_function_value_regno_p (const unsigned int);
164 static void pdp11_trampoline_init (rtx, tree, rtx);
165 static rtx pdp11_function_arg (cumulative_args_t, const function_arg_info &);
166 static void pdp11_function_arg_advance (cumulative_args_t,
167 const function_arg_info &);
168 static void pdp11_conditional_register_usage (void);
169 static bool pdp11_legitimate_constant_p (machine_mode, rtx);
170
171 static bool pdp11_scalar_mode_supported_p (scalar_mode);
172
173 /* Initialize the GCC target structure. */
174 #undef TARGET_ASM_BYTE_OP
175 #define TARGET_ASM_BYTE_OP NULL
176 #undef TARGET_ASM_ALIGNED_HI_OP
177 #define TARGET_ASM_ALIGNED_HI_OP NULL
178 #undef TARGET_ASM_ALIGNED_SI_OP
179 #define TARGET_ASM_ALIGNED_SI_OP NULL
180 #undef TARGET_ASM_INTEGER
181 #define TARGET_ASM_INTEGER pdp11_assemble_integer
182
183 /* These two apply to Unix and GNU assembler; for DEC, they are
184 overridden during option processing. */
185 #undef TARGET_ASM_OPEN_PAREN
186 #define TARGET_ASM_OPEN_PAREN "["
187 #undef TARGET_ASM_CLOSE_PAREN
188 #define TARGET_ASM_CLOSE_PAREN "]"
189
190 #undef TARGET_RTX_COSTS
191 #define TARGET_RTX_COSTS pdp11_rtx_costs
192
193 #undef TARGET_ADDRESS_COST
194 #define TARGET_ADDRESS_COST pdp11_addr_cost
195
196 #undef TARGET_INSN_COST
197 #define TARGET_INSN_COST pdp11_insn_cost
198
199 #undef TARGET_MD_ASM_ADJUST
200 #define TARGET_MD_ASM_ADJUST pdp11_md_asm_adjust
201
202 #undef TARGET_FUNCTION_ARG
203 #define TARGET_FUNCTION_ARG pdp11_function_arg
204 #undef TARGET_FUNCTION_ARG_ADVANCE
205 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
206
207 #undef TARGET_RETURN_IN_MEMORY
208 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
209
210 #undef TARGET_FUNCTION_VALUE
211 #define TARGET_FUNCTION_VALUE pdp11_function_value
212 #undef TARGET_LIBCALL_VALUE
213 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
214 #undef TARGET_FUNCTION_VALUE_REGNO_P
215 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
216
217 #undef TARGET_TRAMPOLINE_INIT
218 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
219
220 #undef TARGET_SECONDARY_RELOAD
221 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
222
223 #undef TARGET_REGISTER_MOVE_COST
224 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
225
226 #undef TARGET_PREFERRED_RELOAD_CLASS
227 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
228
229 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
230 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
231
232 #undef TARGET_LRA_P
233 #define TARGET_LRA_P pdp11_lra_p
234
235 #undef TARGET_LEGITIMATE_ADDRESS_P
236 #define TARGET_LEGITIMATE_ADDRESS_P pdp11_legitimate_address_p
237
238 #undef TARGET_CONDITIONAL_REGISTER_USAGE
239 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
240
241 #undef TARGET_OPTION_OVERRIDE
242 #define TARGET_OPTION_OVERRIDE pdp11_option_override
243
244 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
245 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
246
247 #undef TARGET_ASM_OUTPUT_IDENT
248 #define TARGET_ASM_OUTPUT_IDENT pdp11_output_ident
249
250 #undef TARGET_ASM_FUNCTION_SECTION
251 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
252
253 #undef TARGET_ASM_NAMED_SECTION
254 #define TARGET_ASM_NAMED_SECTION pdp11_asm_named_section
255
256 #undef TARGET_ASM_INIT_SECTIONS
257 #define TARGET_ASM_INIT_SECTIONS pdp11_asm_init_sections
258
259 #undef TARGET_ASM_FILE_START
260 #define TARGET_ASM_FILE_START pdp11_file_start
261
262 #undef TARGET_ASM_FILE_END
263 #define TARGET_ASM_FILE_END pdp11_file_end
264
265 #undef TARGET_PRINT_OPERAND
266 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
267
268 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
269 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
270
271 #undef TARGET_LEGITIMATE_CONSTANT_P
272 #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
273
274 #undef TARGET_SCALAR_MODE_SUPPORTED_P
275 #define TARGET_SCALAR_MODE_SUPPORTED_P pdp11_scalar_mode_supported_p
276
277 #undef TARGET_HARD_REGNO_NREGS
278 #define TARGET_HARD_REGNO_NREGS pdp11_hard_regno_nregs
279
280 #undef TARGET_HARD_REGNO_MODE_OK
281 #define TARGET_HARD_REGNO_MODE_OK pdp11_hard_regno_mode_ok
282
283 #undef TARGET_MODES_TIEABLE_P
284 #define TARGET_MODES_TIEABLE_P pdp11_modes_tieable_p
285
286 #undef TARGET_SECONDARY_MEMORY_NEEDED
287 #define TARGET_SECONDARY_MEMORY_NEEDED pdp11_secondary_memory_needed
288
289 #undef TARGET_CAN_CHANGE_MODE_CLASS
290 #define TARGET_CAN_CHANGE_MODE_CLASS pdp11_can_change_mode_class
291
292 #undef TARGET_INVALID_WITHIN_DOLOOP
293 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
294
295 #undef TARGET_CXX_GUARD_TYPE
296 #define TARGET_CXX_GUARD_TYPE pdp11_guard_type
297
298 #undef TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT
299 #define TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT hook_bool_void_false
300
301 #undef TARGET_CXX_LIBRARY_RTTI_COMDAT
302 #define TARGET_CXX_LIBRARY_RTTI_COMDAT hook_bool_void_false
303
304 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
305 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
306
307 #undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
308 #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P hook_bool_void_false
309
310 /* A helper function to determine if REGNO should be saved in the
311 current function's stack frame. */
312
313 static inline bool
pdp11_saved_regno(unsigned regno)314 pdp11_saved_regno (unsigned regno)
315 {
316 return !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno);
317 }
318
319 /* Expand the function prologue. */
320
321 /* Frame layout, from high to low memory (stack push order):
322 return address (from jsr instruction)
323 saved CPU registers, lowest number first
324 saved FPU registers, lowest number first, always 64 bit mode
325 *** frame pointer points here ***
326 local variables
327 alloca storage if any. */
328 void
pdp11_expand_prologue(void)329 pdp11_expand_prologue (void)
330 {
331 HOST_WIDE_INT fsize = get_frame_size ();
332 unsigned regno;
333 rtx x, via_ac = NULL;
334
335 /* If we are outputting code for main, the switch FPU to the
336 right mode if TARGET_FPU. */
337 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
338 {
339 emit_insn (gen_setd ());
340 emit_insn (gen_seti ());
341 }
342
343 /* Save CPU registers. */
344 for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++)
345 if (pdp11_saved_regno (regno))
346 {
347 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
348 x = gen_frame_mem (Pmode, x);
349 emit_move_insn (x, gen_rtx_REG (Pmode, regno));
350 }
351
352 /* Save FPU registers. */
353 for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
354 if (pdp11_saved_regno (regno))
355 {
356 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
357 x = gen_frame_mem (DFmode, x);
358 via_ac = gen_rtx_REG (DFmode, regno);
359 emit_move_insn (x, via_ac);
360 }
361
362 /* ??? Maybe make ac4, ac5 call used regs?? */
363 for (regno = AC4_REGNUM; regno <= AC5_REGNUM; regno++)
364 if (pdp11_saved_regno (regno))
365 {
366 gcc_assert (via_ac != NULL);
367 emit_move_insn (via_ac, gen_rtx_REG (DFmode, regno));
368
369 x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
370 x = gen_frame_mem (DFmode, x);
371 emit_move_insn (x, via_ac);
372 }
373
374 if (frame_pointer_needed)
375 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
376
377 /* Make local variable space. */
378 if (fsize)
379 emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
380 GEN_INT (-fsize)));
381 }
382
383 /* Generate epilogue. This uses the frame pointer to pop the local
384 variables and any alloca data off the stack. If there is no alloca
385 and frame pointer elimination hasn't been disabled, there is no
386 frame pointer and the local variables are popped by adjusting the
387 stack pointer instead. */
388
389 void
pdp11_expand_epilogue(void)390 pdp11_expand_epilogue (void)
391 {
392 HOST_WIDE_INT fsize = get_frame_size ();
393 unsigned regno;
394 rtx x, reg, via_ac = NULL;
395
396 /* Deallocate the local variables. */
397 if (fsize)
398 {
399 if (frame_pointer_needed)
400 {
401 /* We can deallocate the frame with a single move. */
402 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
403 }
404 else
405 emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
406 GEN_INT (fsize)));
407 }
408
409 /* Restore the FPU registers. */
410 if (pdp11_saved_regno (AC4_REGNUM) || pdp11_saved_regno (AC5_REGNUM))
411 {
412 /* Find a temporary with which to restore AC4/5. */
413 for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
414 if (pdp11_saved_regno (regno))
415 {
416 via_ac = gen_rtx_REG (DFmode, regno);
417 break;
418 }
419 }
420
421 /* Restore registers via pops. */
422
423 for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
424 if (pdp11_saved_regno (regno))
425 {
426 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
427 x = gen_frame_mem (DFmode, x);
428 reg = gen_rtx_REG (DFmode, regno);
429
430 if (LOAD_FPU_REG_P (regno))
431 emit_move_insn (reg, x);
432 else
433 {
434 emit_move_insn (via_ac, x);
435 emit_move_insn (reg, via_ac);
436 }
437 }
438
439 for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
440 if (pdp11_saved_regno (regno))
441 {
442 x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
443 x = gen_frame_mem (Pmode, x);
444 emit_move_insn (gen_rtx_REG (Pmode, regno), x);
445 }
446
447 emit_jump_insn (gen_rtspc ());
448 }
449
450 /* Return the best assembler insn template
451 for moving operands[1] into operands[0] as a fullword. */
452 static const char *
singlemove_string(rtx * operands)453 singlemove_string (rtx *operands)
454 {
455 if (operands[1] != const0_rtx)
456 return "mov\t%1,%0";
457
458 return "clr\t%0";
459 }
460
461
462 /* Expand multi-word operands (SImode or DImode) into the 2 or 4
463 corresponding HImode operands. The number of operands is given as
464 the third argument, the word count for the mode as the fourth
465 argument, and the required order of parts as the sixth argument.
466 The word count is explicit because sometimes we're asked to compare
467 two constants, both of which have mode VOIDmode, so we can't always
468 rely on the input operand mode to imply the operand size. */
469 bool
pdp11_expand_operands(rtx * operands,rtx exops[][2],int opcount,int words,pdp11_action * action,pdp11_partorder order)470 pdp11_expand_operands (rtx *operands, rtx exops[][2],
471 int opcount, int words,
472 pdp11_action *action, pdp11_partorder order)
473 {
474 int op, w, i, sh;
475 pdp11_partorder useorder;
476 bool sameoff = false;
477 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype;
478 long sval[2];
479
480 /* If either piece order is accepted and one is pre-decrement
481 while the other is post-increment, set order to be high order
482 word first. That will force the pre-decrement to be turned
483 into a pointer adjust, then offset addressing.
484 Otherwise, if either operand uses pre-decrement, that means
485 the order is low order first.
486 Otherwise, if both operands are registers and destination is
487 higher than source and they overlap, do low order word (highest
488 register number) first. */
489 useorder = either;
490 if (opcount == 2)
491 {
492 if (GET_CODE (operands[0]) == MEM &&
493 GET_CODE (operands[1]) == MEM &&
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 ((GET_CODE (operands[0]) == MEM &&
500 GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ||
501 (GET_CODE (operands[1]) == MEM &&
502 GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
503 useorder = little;
504 else if (REG_P (operands[0]) && REG_P (operands[1]) &&
505 REGNO (operands[0]) > REGNO (operands[1]) &&
506 REGNO (operands[0]) < REGNO (operands[1]) + words)
507 useorder = little;
508
509 /* Check for source == offset from register and dest == push of
510 the same register. In that case, we have to use the same
511 offset (the one for the low order word) for all words, because
512 the push increases the offset to each source word.
513 In theory there are other cases like this, for example dest == pop,
514 but those don't occur in real life so ignore those. */
515 if (GET_CODE (operands[0]) == MEM
516 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
517 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
518 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
519 sameoff = true;
520 }
521
522 /* If the caller didn't specify order, use the one we computed,
523 or high word first if we don't care either. If the caller did
524 specify, verify we don't have a problem with that order.
525 (If it matters to the caller, constraints need to be used to
526 ensure this case doesn't occur). */
527 if (order == either)
528 order = (useorder == either) ? big : useorder;
529 else
530 gcc_assert (useorder == either || useorder == order);
531
532
533 for (op = 0; op < opcount; op++)
534 {
535 /* First classify the operand. */
536 if (REG_P (operands[op]))
537 optype = REGOP;
538 else if (CONST_INT_P (operands[op])
539 || GET_CODE (operands[op]) == CONST_DOUBLE)
540 optype = CNSTOP;
541 else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
542 optype = POPOP;
543 else if (GET_CODE (XEXP (operands[op], 0)) == PRE_DEC)
544 optype = PUSHOP;
545 else if (!reload_in_progress || offsettable_memref_p (operands[op]))
546 optype = OFFSOP;
547 else if (GET_CODE (operands[op]) == MEM)
548 optype = MEMOP;
549 else
550 optype = RNDOP;
551
552 /* Check for the cases that the operand constraints are not
553 supposed to allow to happen. Return failure for such cases. */
554 if (optype == RNDOP)
555 return false;
556
557 if (action != NULL)
558 action[op] = no_action;
559
560 /* If the operand uses pre-decrement addressing but we
561 want to get the parts high order first,
562 decrement the former register explicitly
563 and change the operand into ordinary indexing. */
564 if (optype == PUSHOP && order == big)
565 {
566 gcc_assert (action != NULL);
567 action[op] = dec_before;
568 operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
569 XEXP (XEXP (operands[op], 0), 0));
570 optype = OFFSOP;
571 }
572 /* If the operand uses post-increment mode but we want
573 to get the parts low order first, change the operand
574 into ordinary indexing and remember to increment
575 the register explicitly when we're done. */
576 else if (optype == POPOP && order == little)
577 {
578 gcc_assert (action != NULL);
579 action[op] = inc_after;
580 operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
581 XEXP (XEXP (operands[op], 0), 0));
582 optype = OFFSOP;
583 }
584
585 if (GET_CODE (operands[op]) == CONST_DOUBLE)
586 {
587 gcc_assert (GET_MODE (operands[op]) != VOIDmode);
588 REAL_VALUE_TO_TARGET_DOUBLE
589 (*CONST_DOUBLE_REAL_VALUE (operands[op]), sval);
590 }
591
592 for (i = 0; i < words; i++)
593 {
594 if (order == big)
595 w = i;
596 else if (sameoff)
597 w = words - 1;
598 else
599 w = words - 1 - i;
600
601 /* Set the output operand to be word "w" of the input. */
602 if (optype == REGOP)
603 exops[i][op] = gen_rtx_REG (HImode, REGNO (operands[op]) + w);
604 else if (optype == OFFSOP)
605 exops[i][op] = adjust_address (operands[op], HImode, w * 2);
606 else if (optype == CNSTOP)
607 {
608 if (GET_CODE (operands[op]) == CONST_DOUBLE)
609 {
610 sh = 16 - (w & 1) * 16;
611 exops[i][op] = gen_rtx_CONST_INT (HImode, (sval[w / 2] >> sh) & 0xffff);
612 }
613 else
614 {
615 sh = ((words - 1 - w) * 16);
616 exops[i][op] = gen_rtx_CONST_INT (HImode, trunc_int_for_mode (INTVAL(operands[op]) >> sh, HImode));
617 }
618 }
619 else
620 exops[i][op] = operands[op];
621 }
622 }
623 return true;
624 }
625
626 /* Output assembler code to perform a multiple-word move insn
627 with operands OPERANDS. This moves 2 or 4 words depending
628 on the machine mode of the operands. */
629
630 const char *
output_move_multiple(rtx * operands)631 output_move_multiple (rtx *operands)
632 {
633 rtx inops[2];
634 rtx exops[4][2];
635 rtx adjops[2];
636
637 pdp11_action action[2];
638 int i, words;
639
640 words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
641 adjops[1] = gen_rtx_CONST_INT (HImode, words * 2);
642
643 inops[0] = operands[0];
644 inops[1] = operands[1];
645
646 pdp11_expand_operands (inops, exops, 2, words, action, either);
647
648 /* Check for explicit decrement before. */
649 if (action[0] == dec_before)
650 {
651 adjops[0] = XEXP (XEXP (operands[0], 0), 0);
652 output_asm_insn ("sub\t%1,%0", adjops);
653 }
654 if (action[1] == dec_before)
655 {
656 adjops[0] = XEXP (XEXP (operands[1], 0), 0);
657 output_asm_insn ("sub\t%1,%0", adjops);
658 }
659
660 /* Do the words. */
661 for (i = 0; i < words; i++)
662 output_asm_insn (singlemove_string (exops[i]), exops[i]);
663
664 /* Check for increment after. */
665 if (action[0] == inc_after)
666 {
667 adjops[0] = XEXP (XEXP (operands[0], 0), 0);
668 output_asm_insn ("add\t%1,%0", adjops);
669 }
670 if (action[1] == inc_after)
671 {
672 adjops[0] = XEXP (XEXP (operands[1], 0), 0);
673 output_asm_insn ("add\t%1,%0", adjops);
674 }
675
676 return "";
677 }
678
679 /* Build an internal label. */
680 void
pdp11_gen_int_label(char * label,const char * prefix,int num)681 pdp11_gen_int_label (char *label, const char *prefix, int num)
682 {
683 if (TARGET_DEC_ASM)
684 /* +1 because GCC numbers labels starting at zero. */
685 sprintf (label, "*%u$", num + 1);
686 else
687 sprintf (label, "*%s_%u", prefix, num);
688 }
689
690 /* Output an ascii string. */
691 void
output_ascii(FILE * file,const char * p,int size)692 output_ascii (FILE *file, const char *p, int size)
693 {
694 int i, c;
695 const char *pseudo = "\t.ascii\t";
696 bool delim = false;
697
698 if (TARGET_DEC_ASM)
699 {
700 if (p[size - 1] == '\0')
701 {
702 pseudo = "\t.asciz\t";
703 size--;
704 }
705 fputs (pseudo, file);
706 for (i = 0; i < size; i++)
707 {
708 c = *p++ & 0xff;
709 if (c < 32 || c == '"' || c > 126)
710 {
711 if (delim)
712 putc ('"', file);
713 fprintf (file, "<%o>", c);
714 delim = false;
715 }
716 else
717 {
718 if (!delim)
719 putc ('"', file);
720 delim = true;
721 putc (c, file);
722 }
723 }
724 if (delim)
725 putc ('"', file);
726 putc ('\n', file);
727 }
728 else
729 {
730 fprintf (file, "\t.byte ");
731
732 for (i = 0; i < size; i++)
733 {
734 fprintf (file, "%#o", *p++ & 0xff);
735 if (i < size - 1)
736 putc (',', file);
737 }
738 putc ('\n', file);
739 }
740 }
741
742 void
pdp11_asm_output_var(FILE * file,const char * name,int size,int align,bool global)743 pdp11_asm_output_var (FILE *file, const char *name, int size,
744 int align, bool global)
745 {
746 switch_to_section (data_section);
747 if (align > 8)
748 fprintf (file, "\t.even\n");
749 if (TARGET_DEC_ASM)
750 {
751 assemble_name (file, name);
752 if (global)
753 fputs ("::", file);
754 else
755 fputs (":", file);
756 if (align > 8)
757 fprintf (file, "\t.blkw\t%o\n", (size & 0xffff) / 2);
758 else
759 fprintf (file, "\t.blkb\t%o\n", size & 0xffff);
760 }
761 else
762 {
763 if (global)
764 {
765 fprintf (file, ".globl ");
766 assemble_name (file, name);
767 fprintf (file, "\n");
768 }
769 assemble_name (file, name);
770 fputs (":", file);
771 ASM_OUTPUT_SKIP (file, size);
772 }
773 }
774
775 /* Special format operators handled here:
776 # -- output the correct immediate operand marker for the assembler
777 dialect.
778 @ -- output the correct indirect marker for the assembler dialect.
779 o -- emit a constant value as a number (not an immediate operand)
780 in octal. */
781 static void
pdp11_asm_print_operand(FILE * file,rtx x,int code)782 pdp11_asm_print_operand (FILE *file, rtx x, int code)
783 {
784 long sval[2];
785
786 if (code == '#')
787 {
788 if (TARGET_DEC_ASM)
789 putc ('#', file);
790 else
791 putc ('$', file);
792 }
793 else if (code == '@')
794 {
795 if (TARGET_UNIX_ASM)
796 fprintf (file, "*");
797 else
798 fprintf (file, "@");
799 }
800 else if (GET_CODE (x) == REG)
801 fprintf (file, "%s", reg_names[REGNO (x)]);
802 else if (GET_CODE (x) == MEM)
803 output_address (GET_MODE (x), XEXP (x, 0));
804 else if (GET_CODE (x) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (x)))
805 {
806 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), sval);
807 if (TARGET_DEC_ASM)
808 fprintf (file, "#%lo", (sval[0] >> 16) & 0xffff);
809 else
810 fprintf (file, "$%#lo", (sval[0] >> 16) & 0xffff);
811 }
812 else
813 {
814 if (code != 'o')
815 {
816 if (TARGET_DEC_ASM)
817 putc ('#', file);
818 else
819 putc ('$', file);
820 }
821 output_addr_const_pdp11 (file, x);
822 }
823 }
824
825 static bool
pdp11_asm_print_operand_punct_valid_p(unsigned char c)826 pdp11_asm_print_operand_punct_valid_p (unsigned char c)
827 {
828 return (c == '#' || c == '@');
829 }
830
831 void
print_operand_address(FILE * file,rtx addr)832 print_operand_address (FILE *file, rtx addr)
833 {
834 rtx breg;
835 rtx offset;
836 int again = 0;
837
838 retry:
839
840 switch (GET_CODE (addr))
841 {
842 case MEM:
843 if (TARGET_UNIX_ASM)
844 fprintf (file, "*");
845 else
846 fprintf (file, "@");
847 addr = XEXP (addr, 0);
848 again = 1;
849 goto retry;
850
851 case REG:
852 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
853 break;
854
855 case PRE_MODIFY:
856 case PRE_DEC:
857 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
858 break;
859
860 case POST_MODIFY:
861 case POST_INC:
862 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
863 break;
864
865 case PLUS:
866 breg = 0;
867 offset = 0;
868 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
869 || GET_CODE (XEXP (addr, 0)) == MEM)
870 {
871 offset = XEXP (addr, 0);
872 addr = XEXP (addr, 1);
873 }
874 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
875 || GET_CODE (XEXP (addr, 1)) == MEM)
876 {
877 offset = XEXP (addr, 1);
878 addr = XEXP (addr, 0);
879 }
880 if (GET_CODE (addr) != PLUS)
881 ;
882 else if (GET_CODE (XEXP (addr, 0)) == REG)
883 {
884 breg = XEXP (addr, 0);
885 addr = XEXP (addr, 1);
886 }
887 else if (GET_CODE (XEXP (addr, 1)) == REG)
888 {
889 breg = XEXP (addr, 1);
890 addr = XEXP (addr, 0);
891 }
892 if (GET_CODE (addr) == REG)
893 {
894 gcc_assert (breg == 0);
895 breg = addr;
896 addr = 0;
897 }
898 if (offset != 0)
899 {
900 gcc_assert (addr == 0);
901 addr = offset;
902 }
903 if (addr != 0)
904 output_addr_const_pdp11 (file, addr);
905 if (breg != 0)
906 {
907 gcc_assert (GET_CODE (breg) == REG);
908 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
909 }
910 break;
911
912 default:
913 if (!again && GET_CODE (addr) == CONST_INT)
914 {
915 /* Absolute (integer number) address. */
916 if (TARGET_DEC_ASM)
917 fprintf (file, "@#");
918 else if (!TARGET_UNIX_ASM)
919 fprintf (file, "@$");
920 }
921 output_addr_const_pdp11 (file, addr);
922 }
923 }
924
925 /* Target hook to assemble integer objects. We need to use the
926 pdp-specific version of output_addr_const. */
927
928 static bool
pdp11_assemble_integer(rtx x,unsigned int size,int aligned_p)929 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
930 {
931 if (aligned_p)
932 switch (size)
933 {
934 case 1:
935 fprintf (asm_out_file, "\t.byte\t");
936 output_addr_const_pdp11 (asm_out_file, GEN_INT (INTVAL (x) & 0xff));
937 fputs ("\n", asm_out_file);
938 return true;
939
940 case 2:
941 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
942 output_addr_const_pdp11 (asm_out_file, x);
943 fputs ("\n", asm_out_file);
944 return true;
945 }
946 return default_assemble_integer (x, size, aligned_p);
947 }
948
949
950 static bool
pdp11_lra_p(void)951 pdp11_lra_p (void)
952 {
953 return TARGET_LRA;
954 }
955
956 /* Register to register moves are cheap if both are general
957 registers. */
958 static int
pdp11_register_move_cost(machine_mode mode ATTRIBUTE_UNUSED,reg_class_t c1,reg_class_t c2)959 pdp11_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
960 reg_class_t c1, reg_class_t c2)
961 {
962 if (CPU_REG_CLASS (c1) && CPU_REG_CLASS (c2))
963 return 2;
964 else if ((c1 >= LOAD_FPU_REGS && c1 <= FPU_REGS && c2 == LOAD_FPU_REGS) ||
965 (c2 >= LOAD_FPU_REGS && c2 <= FPU_REGS && c1 == LOAD_FPU_REGS))
966 return 2;
967 else
968 return 22;
969 }
970
971 /* This tries to approximate what pdp11_insn_cost would do, but
972 without visibility into the actual instruction being generated it's
973 inevitably a rough approximation. */
974 static bool
pdp11_rtx_costs(rtx x,machine_mode mode,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed)975 pdp11_rtx_costs (rtx x, machine_mode mode, int outer_code,
976 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
977 {
978 const int code = GET_CODE (x);
979 const int asize = (mode == QImode) ? 2 : GET_MODE_SIZE (mode);
980 rtx src, dest;
981 const char *fmt;
982
983 switch (code)
984 {
985 case CONST_INT:
986 /* Treat -1, 0, 1 as things that are optimized as clr or dec
987 etc. though that doesn't apply to every case. */
988 if (INTVAL (x) >= -1 && INTVAL (x) <= 1)
989 {
990 *total = 0;
991 return true;
992 }
993 /* FALL THROUGH. */
994 case REG:
995 case MEM:
996 case CONST:
997 case LABEL_REF:
998 case SYMBOL_REF:
999 case CONST_DOUBLE:
1000 *total = pdp11_addr_cost (x, mode, ADDR_SPACE_GENERIC, speed);
1001 return true;
1002 }
1003 if (GET_RTX_LENGTH (code) == 0)
1004 {
1005 if (speed)
1006 *total = 0;
1007 else
1008 *total = 2;
1009 return true;
1010 }
1011
1012 /* Pick up source and dest. We don't necessarily use the standard
1013 recursion in rtx_costs to figure the cost, because that would
1014 count the destination operand twice for three-operand insns.
1015 Also, this way we can catch special cases like move of zero, or
1016 add one. */
1017 fmt = GET_RTX_FORMAT (code);
1018 if (fmt[0] != 'e' || (GET_RTX_LENGTH (code) > 1 && fmt[1] != 'e'))
1019 {
1020 if (speed)
1021 *total = 0;
1022 else
1023 *total = 2;
1024 return true;
1025 }
1026 if (GET_RTX_LENGTH (code) > 1)
1027 src = XEXP (x, 1);
1028 dest = XEXP (x, 0);
1029
1030 /* If optimizing for size, claim everything costs 2 per word, plus
1031 whatever the operands require. */
1032 if (!speed)
1033 *total = asize;
1034 else
1035 {
1036 if (FLOAT_MODE_P (mode))
1037 {
1038 switch (code)
1039 {
1040 case MULT:
1041 case DIV:
1042 case MOD:
1043 *total = 20;
1044 break;
1045
1046 case COMPARE:
1047 *total = 4;
1048 break;
1049
1050 case PLUS:
1051 case MINUS:
1052 *total = 6;
1053 break;
1054
1055 default:
1056 *total = 2;
1057 break;
1058 }
1059 }
1060 else
1061 {
1062 /* Integer operations are scaled for SI and DI modes, though the
1063 scaling is not exactly accurate. */
1064 switch (code)
1065 {
1066 case MULT:
1067 *total = 5 * asize * asize;
1068 break;
1069
1070 case DIV:
1071 *total = 10 * asize * asize;
1072 break;
1073
1074 case MOD:
1075 /* Fake value because it's accounted for under DIV, since we
1076 use a divmod pattern. */
1077 total = 0;
1078 break;
1079
1080 case ASHIFT:
1081 case ASHIFTRT:
1082 case LSHIFTRT:
1083 /* This is a bit problematic because the cost depends on the
1084 shift amount. Make it <asize> for now, which is for the
1085 case of a one bit shift. */
1086 *total = asize;
1087 break;
1088
1089 default:
1090 *total = asize;
1091 break;
1092 }
1093 }
1094 }
1095
1096 /* Now see if we're looking at a SET. If yes, then look at the
1097 source to see if this is a move or an arithmetic operation, and
1098 continue accordingly to handle the operands. */
1099 if (code == SET)
1100 {
1101 switch (GET_CODE (src))
1102 {
1103 case REG:
1104 case MEM:
1105 case CONST_INT:
1106 case CONST:
1107 case LABEL_REF:
1108 case SYMBOL_REF:
1109 case CONST_DOUBLE:
1110 /* It's a move. */
1111 *total += pdp11_addr_cost (dest, mode, ADDR_SPACE_GENERIC, speed);
1112 if (src != const0_rtx)
1113 *total += pdp11_addr_cost (src, mode, ADDR_SPACE_GENERIC, speed);
1114 return true;
1115 default:
1116 /* Not a move. Get the cost of the source operand and add
1117 that in, but not the destination operand since we're
1118 dealing with read/modify/write operands. */
1119 *total += rtx_cost (src, mode, (enum rtx_code) outer_code, 1, speed);
1120 return true;
1121 }
1122 }
1123 else if (code == PLUS || code == MINUS)
1124 {
1125 if (GET_CODE (src) == CONST_INT &&
1126 (INTVAL (src) == 1 || INTVAL (src) == -1))
1127 {
1128 *total += rtx_cost (dest, mode, (enum rtx_code) outer_code, 0, speed);
1129 return true;
1130 }
1131 }
1132 return false;
1133 }
1134
1135 /* Return cost of accessing the supplied operand. Registers are free.
1136 Anything else starts with a cost of two. Add to that for memory
1137 references the memory accesses of the addressing mode (if any) plus
1138 the data reference; for other operands just the memory access (if
1139 any) for the mode. */
1140 static int
pdp11_addr_cost(rtx addr,machine_mode mode,addr_space_t as ATTRIBUTE_UNUSED,bool speed)1141 pdp11_addr_cost (rtx addr, machine_mode mode, addr_space_t as ATTRIBUTE_UNUSED,
1142 bool speed)
1143 {
1144 int cost = 0;
1145
1146 if (GET_CODE (addr) != REG)
1147 {
1148 if (!simple_memory_operand (addr, mode))
1149 cost = 2;
1150
1151 /* If optimizing for speed, account for the memory reference if
1152 any. */
1153 if (speed && !CONSTANT_P (addr))
1154 cost += (mode == QImode) ? 2 : GET_MODE_SIZE (mode);
1155 }
1156 return cost;
1157 }
1158
1159
1160 static int
pdp11_insn_cost(rtx_insn * insn,bool speed)1161 pdp11_insn_cost (rtx_insn *insn, bool speed)
1162 {
1163 int base_cost;
1164 rtx pat, set, dest, src, src2;
1165 machine_mode mode;
1166 enum rtx_code op;
1167
1168 if (recog_memoized (insn) < 0)
1169 return 0;
1170
1171 /* If optimizing for size, we want the insn size. */
1172 if (!speed)
1173 return get_attr_length (insn);
1174 else
1175 {
1176 /* Optimizing for speed. Get the base cost of the insn, then
1177 adjust for the cost of accessing operands. Zero means use
1178 the length as the cost even when optimizing for speed. */
1179 base_cost = get_attr_base_cost (insn);
1180 if (base_cost <= 0)
1181 base_cost = get_attr_length (insn);
1182 }
1183 /* Look for the operands. Often we have a PARALLEL that's either
1184 the actual operation plus a clobber, or the implicit compare plus
1185 the actual operation. Find the actual operation. */
1186 pat = PATTERN (insn);
1187
1188 if (GET_CODE (pat) == PARALLEL)
1189 {
1190 set = XVECEXP (pat, 0, 0);
1191 if (GET_CODE (set) != SET || GET_CODE (XEXP (set, 1)) == COMPARE)
1192 set = XVECEXP (pat, 0, 1);
1193 if (GET_CODE (set) != SET || GET_CODE (XEXP (set, 1)) == COMPARE)
1194 return 0;
1195 }
1196 else
1197 {
1198 set = pat;
1199 if (GET_CODE (set) != SET)
1200 return 0;
1201 }
1202
1203 /* Pick up the SET source and destination RTL. */
1204 dest = XEXP (set, 0);
1205 src = XEXP (set, 1);
1206 mode = GET_MODE (dest);
1207
1208 /* See if we have a move, or some arithmetic operation. If a move,
1209 account for source and destination operand costs. Otherwise,
1210 account for the destination and for the second operand of the
1211 operation -- the first is also destination and we don't want to
1212 double-count it. */
1213 base_cost += pdp11_addr_cost (dest, mode, ADDR_SPACE_GENERIC, speed);
1214 op = GET_CODE (src);
1215 switch (op)
1216 {
1217 case REG:
1218 case MEM:
1219 case CONST_INT:
1220 case CONST:
1221 case LABEL_REF:
1222 case SYMBOL_REF:
1223 case CONST_DOUBLE:
1224 /* It's a move. */
1225 if (src != const0_rtx)
1226 base_cost += pdp11_addr_cost (src, mode, ADDR_SPACE_GENERIC, speed);
1227 return base_cost;
1228 default:
1229 break;
1230 }
1231 /* There are some other cases where souce and dest are distinct. */
1232 if (FLOAT_MODE_P (mode) &&
1233 (op == FLOAT_TRUNCATE || op == FLOAT_EXTEND || op == FIX || op == FLOAT))
1234 {
1235 src2 = XEXP (src, 0);
1236 base_cost += pdp11_addr_cost (src2, mode, ADDR_SPACE_GENERIC, speed);
1237 }
1238 /* Otherwise, pick up the second operand of the arithmetic
1239 operation, if it has two operands. */
1240 else if (op != SUBREG && op != UNSPEC && GET_RTX_LENGTH (op) > 1)
1241 {
1242 src2 = XEXP (src, 1);
1243 base_cost += pdp11_addr_cost (src2, mode, ADDR_SPACE_GENERIC, speed);
1244 }
1245
1246 return base_cost;
1247 }
1248
1249 const char *
output_jump(rtx * operands,int ccnz,int length)1250 output_jump (rtx *operands, int ccnz, int length)
1251 {
1252 rtx tmpop[1];
1253 static char buf[100];
1254 const char *pos, *neg;
1255 enum rtx_code code = GET_CODE (operands[0]);
1256
1257 if (ccnz)
1258 {
1259 /* These are the branches valid for CCNZmode, i.e., a comparison
1260 with zero where the V bit is not set to zero. These cases
1261 occur when CC or FCC are set as a side effect of some data
1262 manipulation, such as the ADD instruction. */
1263 switch (code)
1264 {
1265 case EQ: pos = "beq", neg = "bne"; break;
1266 case NE: pos = "bne", neg = "beq"; break;
1267 case LT: pos = "bmi", neg = "bpl"; break;
1268 case GE: pos = "bpl", neg = "bmi"; break;
1269 default: gcc_unreachable ();
1270 }
1271 }
1272 else
1273 {
1274 switch (code)
1275 {
1276 case EQ: pos = "beq", neg = "bne"; break;
1277 case NE: pos = "bne", neg = "beq"; break;
1278 case GT: pos = "bgt", neg = "ble"; break;
1279 case GTU: pos = "bhi", neg = "blos"; break;
1280 case LT: pos = "blt", neg = "bge"; break;
1281 case LTU: pos = "blo", neg = "bhis"; break;
1282 case GE: pos = "bge", neg = "blt"; break;
1283 case GEU: pos = "bhis", neg = "blo"; break;
1284 case LE: pos = "ble", neg = "bgt"; break;
1285 case LEU: pos = "blos", neg = "bhi"; break;
1286 default: gcc_unreachable ();
1287 }
1288 }
1289 switch (length)
1290 {
1291 case 2:
1292 sprintf (buf, "%s\t%%l1", pos);
1293 return buf;
1294 case 6:
1295 tmpop[0] = gen_label_rtx ();
1296 sprintf (buf, "%s\t%%l0", neg);
1297 output_asm_insn (buf, tmpop);
1298 output_asm_insn ("jmp\t%l1", operands);
1299 output_asm_label (tmpop[0]);
1300 fputs (":\n", asm_out_file);
1301 return "";
1302 default:
1303 gcc_unreachable ();
1304 }
1305 }
1306
1307 /* Select the CC mode to be used for the side effect compare with
1308 zero, given the compare operation code in op and the compare
1309 operands in x in and y. */
1310 machine_mode
pdp11_cc_mode(enum rtx_code op ATTRIBUTE_UNUSED,rtx x,rtx y ATTRIBUTE_UNUSED)1311 pdp11_cc_mode (enum rtx_code op ATTRIBUTE_UNUSED, rtx x, rtx y ATTRIBUTE_UNUSED)
1312 {
1313 if (FLOAT_MODE_P (GET_MODE (x)))
1314 {
1315 switch (GET_CODE (x))
1316 {
1317 case ABS:
1318 case NEG:
1319 case REG:
1320 case MEM:
1321 return CCmode;
1322 default:
1323 return CCNZmode;
1324 }
1325 }
1326 else
1327 {
1328 switch (GET_CODE (x))
1329 {
1330 case XOR:
1331 case AND:
1332 case IOR:
1333 case MULT:
1334 case NOT:
1335 case REG:
1336 case MEM:
1337 return CCmode;
1338 default:
1339 return CCNZmode;
1340 }
1341 }
1342 }
1343
1344
1345 int
simple_memory_operand(rtx op,machine_mode mode ATTRIBUTE_UNUSED)1346 simple_memory_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1347 {
1348 rtx addr;
1349
1350 /* Eliminate non-memory operations */
1351 if (GET_CODE (op) != MEM)
1352 return FALSE;
1353
1354 /* Decode the address now. */
1355
1356 indirection:
1357
1358 addr = XEXP (op, 0);
1359
1360 switch (GET_CODE (addr))
1361 {
1362 case REG:
1363 /* (R0) - no extra cost */
1364 return 1;
1365
1366 case PRE_DEC:
1367 case POST_INC:
1368 case PRE_MODIFY:
1369 case POST_MODIFY:
1370 /* -(R0), (R0)+ - cheap! */
1371 return 1;
1372
1373 case MEM:
1374 /* cheap - is encoded in addressing mode info!
1375
1376 -- except for @(R0), which has to be @0(R0) !!! */
1377
1378 if (GET_CODE (XEXP (addr, 0)) == REG)
1379 return 0;
1380
1381 op=addr;
1382 goto indirection;
1383
1384 case CONST_INT:
1385 case LABEL_REF:
1386 case CONST:
1387 case SYMBOL_REF:
1388 /* @#address - extra cost */
1389 return 0;
1390
1391 case PLUS:
1392 /* X(R0) - extra cost */
1393 return 0;
1394
1395 default:
1396 break;
1397 }
1398
1399 return FALSE;
1400 }
1401
1402 /* Similar to simple_memory_operand but doesn't match push/pop. */
1403 int
no_side_effect_operand(rtx op,machine_mode mode ATTRIBUTE_UNUSED)1404 no_side_effect_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1405 {
1406 rtx addr;
1407
1408 /* Eliminate non-memory operations */
1409 if (GET_CODE (op) != MEM)
1410 return FALSE;
1411
1412 /* Decode the address now. */
1413
1414 indirection:
1415
1416 addr = XEXP (op, 0);
1417
1418 switch (GET_CODE (addr))
1419 {
1420 case REG:
1421 /* (R0) - no extra cost */
1422 return 1;
1423
1424 case PRE_DEC:
1425 case POST_INC:
1426 case PRE_MODIFY:
1427 case POST_MODIFY:
1428 return 0;
1429
1430 case MEM:
1431 /* cheap - is encoded in addressing mode info!
1432
1433 -- except for @(R0), which has to be @0(R0) !!! */
1434
1435 if (GET_CODE (XEXP (addr, 0)) == REG)
1436 return 0;
1437
1438 op=addr;
1439 goto indirection;
1440
1441 case CONST_INT:
1442 case LABEL_REF:
1443 case CONST:
1444 case SYMBOL_REF:
1445 /* @#address - extra cost */
1446 return 0;
1447
1448 case PLUS:
1449 /* X(R0) - extra cost */
1450 return 0;
1451
1452 default:
1453 break;
1454 }
1455
1456 return FALSE;
1457 }
1458
1459 /* Return TRUE if op is a push or pop using the register "regno". */
1460 bool
pushpop_regeq(rtx op,int regno)1461 pushpop_regeq (rtx op, int regno)
1462 {
1463 rtx addr;
1464
1465 /* False if not memory reference. */
1466 if (GET_CODE (op) != MEM)
1467 return FALSE;
1468
1469 /* Get the address of the memory reference. */
1470 addr = XEXP (op, 0);
1471
1472 if (GET_CODE (addr) == MEM)
1473 addr = XEXP (addr, 0);
1474
1475 switch (GET_CODE (addr))
1476 {
1477 case PRE_DEC:
1478 case POST_INC:
1479 case PRE_MODIFY:
1480 case POST_MODIFY:
1481 return REGNO (XEXP (addr, 0)) == (unsigned) regno;
1482 default:
1483 return FALSE;
1484 }
1485 }
1486
1487 /* This function checks whether a real value can be encoded as
1488 a literal, i.e., addressing mode 27. In that mode, real values
1489 are one word values, so the remaining 48 bits have to be zero. */
1490 int
legitimate_const_double_p(rtx address)1491 legitimate_const_double_p (rtx address)
1492 {
1493 long sval[2];
1494
1495 /* If it's too big for HOST_WIDE_INT, it's definitely to big here. */
1496 if (GET_MODE (address) == VOIDmode)
1497 return 0;
1498 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (address), sval);
1499
1500 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1501 return 1;
1502 return 0;
1503 }
1504
1505 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
1506 static bool
pdp11_can_change_mode_class(machine_mode from,machine_mode to,reg_class_t rclass)1507 pdp11_can_change_mode_class (machine_mode from,
1508 machine_mode to,
1509 reg_class_t rclass)
1510 {
1511 /* Also, FPU registers contain a whole float value and the parts of
1512 it are not separately accessible.
1513
1514 So we disallow all mode changes involving FPRs. */
1515 if (FLOAT_MODE_P (from) != FLOAT_MODE_P (to))
1516 return false;
1517
1518 return !reg_classes_intersect_p (FPU_REGS, rclass);
1519 }
1520
1521 /* Implement TARGET_CXX_GUARD_TYPE */
1522 static tree
pdp11_guard_type(void)1523 pdp11_guard_type (void)
1524 {
1525 return short_integer_type_node;
1526 }
1527
1528 /* TARGET_PREFERRED_RELOAD_CLASS
1529
1530 Given an rtx X being reloaded into a reg required to be
1531 in class CLASS, return the class of reg to actually use.
1532 In general this is just CLASS; but on some machines
1533 in some cases it is preferable to use a more restrictive class.
1534
1535 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1536
1537 static reg_class_t
pdp11_preferred_reload_class(rtx x,reg_class_t rclass)1538 pdp11_preferred_reload_class (rtx x, reg_class_t rclass)
1539 {
1540 if (rclass == FPU_REGS)
1541 return LOAD_FPU_REGS;
1542 if (rclass == ALL_REGS)
1543 {
1544 if (FLOAT_MODE_P (GET_MODE (x)))
1545 return LOAD_FPU_REGS;
1546 else
1547 return GENERAL_REGS;
1548 }
1549 return rclass;
1550 }
1551
1552 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1553
1554 Given an rtx X being reloaded into a reg required to be
1555 in class CLASS, return the class of reg to actually use.
1556 In general this is just CLASS; but on some machines
1557 in some cases it is preferable to use a more restrictive class.
1558
1559 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1560
1561 static reg_class_t
pdp11_preferred_output_reload_class(rtx x,reg_class_t rclass)1562 pdp11_preferred_output_reload_class (rtx x, reg_class_t rclass)
1563 {
1564 if (rclass == FPU_REGS)
1565 return LOAD_FPU_REGS;
1566 if (rclass == ALL_REGS)
1567 {
1568 if (FLOAT_MODE_P (GET_MODE (x)))
1569 return LOAD_FPU_REGS;
1570 else
1571 return GENERAL_REGS;
1572 }
1573 return rclass;
1574 }
1575
1576
1577 /* TARGET_SECONDARY_RELOAD.
1578
1579 FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1580 intermediate register (AC0-AC3: LOAD_FPU_REGS). Everything else
1581 can be loaded/stored directly. */
1582 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)1583 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED,
1584 rtx x,
1585 reg_class_t reload_class,
1586 machine_mode reload_mode ATTRIBUTE_UNUSED,
1587 secondary_reload_info *sri ATTRIBUTE_UNUSED)
1588 {
1589 if (reload_class != NO_LOAD_FPU_REGS || GET_CODE (x) != REG ||
1590 REGNO_REG_CLASS (REGNO (x)) == LOAD_FPU_REGS)
1591 return NO_REGS;
1592
1593 return LOAD_FPU_REGS;
1594 }
1595
1596 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
1597
1598 The answer is yes if we're going between general register and FPU
1599 registers. The mode doesn't matter in making this check. */
1600 static bool
pdp11_secondary_memory_needed(machine_mode,reg_class_t c1,reg_class_t c2)1601 pdp11_secondary_memory_needed (machine_mode, reg_class_t c1, reg_class_t c2)
1602 {
1603 int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS ||
1604 c1 == FPU_REGS);
1605 int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS ||
1606 c2 == FPU_REGS);
1607
1608 return (fromfloat != tofloat);
1609 }
1610
1611 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
1612 that is a valid memory address for an instruction.
1613 The MODE argument is the machine mode for the MEM expression
1614 that wants to use this address.
1615
1616 */
1617
1618 static bool
pdp11_legitimate_address_p(machine_mode mode,rtx operand,bool strict)1619 pdp11_legitimate_address_p (machine_mode mode,
1620 rtx operand, bool strict)
1621 {
1622 rtx xfoob;
1623
1624 /* accept @#address */
1625 if (CONSTANT_ADDRESS_P (operand))
1626 return true;
1627
1628 switch (GET_CODE (operand))
1629 {
1630 case REG:
1631 /* accept (R0) */
1632 return !strict || REGNO_OK_FOR_BASE_P (REGNO (operand));
1633
1634 case PLUS:
1635 /* accept X(R0) */
1636 return GET_CODE (XEXP (operand, 0)) == REG
1637 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))))
1638 && CONSTANT_ADDRESS_P (XEXP (operand, 1));
1639
1640 case PRE_DEC:
1641 /* accept -(R0) */
1642 return GET_CODE (XEXP (operand, 0)) == REG
1643 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1644
1645 case POST_INC:
1646 /* accept (R0)+ */
1647 return GET_CODE (XEXP (operand, 0)) == REG
1648 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1649
1650 case PRE_MODIFY:
1651 /* accept -(SP) -- which uses PRE_MODIFY for byte mode */
1652 return GET_CODE (XEXP (operand, 0)) == REG
1653 && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1654 && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1655 && GET_CODE (XEXP (xfoob, 0)) == REG
1656 && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1657 && CONST_INT_P (XEXP (xfoob, 1))
1658 && INTVAL (XEXP (xfoob,1)) == -2;
1659
1660 case POST_MODIFY:
1661 /* accept (SP)+ -- which uses POST_MODIFY for byte mode */
1662 return GET_CODE (XEXP (operand, 0)) == REG
1663 && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1664 && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1665 && GET_CODE (XEXP (xfoob, 0)) == REG
1666 && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1667 && CONST_INT_P (XEXP (xfoob, 1))
1668 && INTVAL (XEXP (xfoob,1)) == 2;
1669
1670 case MEM:
1671 /* handle another level of indirection ! */
1672 xfoob = XEXP (operand, 0);
1673
1674 /* (MEM:xx (MEM:xx ())) is not valid for SI, DI and currently
1675 also forbidden for float, because we have to handle this
1676 in output_move_double and/or output_move_quad() - we could
1677 do it, but currently it's not worth it!!!
1678 now that DFmode cannot go into CPU register file,
1679 maybe I should allow float ...
1680 but then I have to handle memory-to-memory moves in movdf ?? */
1681 if (GET_MODE_BITSIZE(mode) > 16)
1682 return false;
1683
1684 /* accept @address */
1685 if (CONSTANT_ADDRESS_P (xfoob))
1686 return true;
1687
1688 switch (GET_CODE (xfoob))
1689 {
1690 case REG:
1691 /* accept @(R0) - which is @0(R0) */
1692 return !strict || REGNO_OK_FOR_BASE_P(REGNO (xfoob));
1693
1694 case PLUS:
1695 /* accept @X(R0) */
1696 return GET_CODE (XEXP (xfoob, 0)) == REG
1697 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))))
1698 && CONSTANT_ADDRESS_P (XEXP (xfoob, 1));
1699
1700 case PRE_DEC:
1701 /* accept @-(R0) */
1702 return GET_CODE (XEXP (xfoob, 0)) == REG
1703 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1704
1705 case POST_INC:
1706 /* accept @(R0)+ */
1707 return GET_CODE (XEXP (xfoob, 0)) == REG
1708 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1709
1710 default:
1711 /* anything else is invalid */
1712 return false;
1713 }
1714
1715 default:
1716 /* anything else is invalid */
1717 return false;
1718 }
1719 }
1720
1721 /* Return the class number of the smallest class containing
1722 reg number REGNO. */
1723 enum reg_class
pdp11_regno_reg_class(int regno)1724 pdp11_regno_reg_class (int regno)
1725 {
1726 if (regno == ARG_POINTER_REGNUM)
1727 return NOTSP_REG;
1728 else if (regno == CC_REGNUM || regno == FCC_REGNUM)
1729 return CC_REGS;
1730 else if (regno > AC3_REGNUM)
1731 return NO_LOAD_FPU_REGS;
1732 else if (regno >= AC0_REGNUM)
1733 return LOAD_FPU_REGS;
1734 else if (regno == 6)
1735 return NOTR0_REG;
1736 else if (regno < 6)
1737 return NOTSP_REG;
1738 else
1739 return GENERAL_REGS;
1740 }
1741
1742 /* Return the regnums of the CC registers. */
1743 bool
pdp11_fixed_cc_regs(unsigned int * p1,unsigned int * p2)1744 pdp11_fixed_cc_regs (unsigned int *p1, unsigned int *p2)
1745 {
1746 *p1 = CC_REGNUM;
1747 *p2 = FCC_REGNUM;
1748 return true;
1749 }
1750
1751 static int
pdp11_reg_save_size(void)1752 pdp11_reg_save_size (void)
1753 {
1754 int offset = 0, regno;
1755
1756 for (regno = 0; regno <= PC_REGNUM; regno++)
1757 if (pdp11_saved_regno (regno))
1758 offset += 2;
1759 for (regno = AC0_REGNUM; regno <= AC5_REGNUM; regno++)
1760 if (pdp11_saved_regno (regno))
1761 offset += 8;
1762
1763 return offset;
1764 }
1765
1766 /* Return the offset between two registers, one to be eliminated, and the other
1767 its replacement, at the start of a routine. */
1768
1769 int
pdp11_initial_elimination_offset(int from,int to)1770 pdp11_initial_elimination_offset (int from, int to)
1771 {
1772 /* Get the size of the register save area. */
1773
1774 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1775 return get_frame_size ();
1776 else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1777 return pdp11_reg_save_size () + 2;
1778 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1779 return pdp11_reg_save_size () + 2 + get_frame_size ();
1780 else
1781 gcc_assert (0);
1782 }
1783
1784 /* A copy of output_addr_const modified for pdp11 expression syntax.
1785 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1786 use, and for debugging output, which we don't support with this port either.
1787 So this copy should get called whenever needed.
1788 */
1789 void
output_addr_const_pdp11(FILE * file,rtx x)1790 output_addr_const_pdp11 (FILE *file, rtx x)
1791 {
1792 char buf[256];
1793 int i;
1794
1795 restart:
1796 switch (GET_CODE (x))
1797 {
1798 case PC:
1799 gcc_assert (flag_pic);
1800 putc ('.', file);
1801 break;
1802
1803 case SYMBOL_REF:
1804 assemble_name (file, XSTR (x, 0));
1805 break;
1806
1807 case LABEL_REF:
1808 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1809 assemble_name (file, buf);
1810 break;
1811
1812 case CODE_LABEL:
1813 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1814 assemble_name (file, buf);
1815 break;
1816
1817 case CONST_INT:
1818 i = INTVAL (x);
1819 if (i < 0)
1820 {
1821 i = -i;
1822 fprintf (file, "-");
1823 }
1824 if (TARGET_DEC_ASM)
1825 fprintf (file, "%o", i & 0xffff);
1826 else
1827 fprintf (file, "%#o", i & 0xffff);
1828 break;
1829
1830 case CONST:
1831 output_addr_const_pdp11 (file, XEXP (x, 0));
1832 break;
1833
1834 case PLUS:
1835 /* Some assemblers need integer constants to appear last (e.g. masm). */
1836 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1837 {
1838 output_addr_const_pdp11 (file, XEXP (x, 1));
1839 if (INTVAL (XEXP (x, 0)) >= 0)
1840 fprintf (file, "+");
1841 output_addr_const_pdp11 (file, XEXP (x, 0));
1842 }
1843 else
1844 {
1845 output_addr_const_pdp11 (file, XEXP (x, 0));
1846 if (INTVAL (XEXP (x, 1)) >= 0)
1847 fprintf (file, "+");
1848 output_addr_const_pdp11 (file, XEXP (x, 1));
1849 }
1850 break;
1851
1852 case MINUS:
1853 /* Avoid outputting things like x-x or x+5-x,
1854 since some assemblers can't handle that. */
1855 x = simplify_subtraction (x);
1856 if (GET_CODE (x) != MINUS)
1857 goto restart;
1858
1859 output_addr_const_pdp11 (file, XEXP (x, 0));
1860 if (GET_CODE (XEXP (x, 1)) != CONST_INT
1861 || INTVAL (XEXP (x, 1)) >= 0)
1862 fprintf (file, "-");
1863 output_addr_const_pdp11 (file, XEXP (x, 1));
1864 break;
1865
1866 case ZERO_EXTEND:
1867 case SIGN_EXTEND:
1868 output_addr_const_pdp11 (file, XEXP (x, 0));
1869 break;
1870
1871 default:
1872 output_operand_lossage ("invalid expression as operand");
1873 }
1874 }
1875
1876 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1877
1878 static bool
pdp11_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)1879 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1880 {
1881 /* Integers 32 bits and under, and scalar floats (if FPU), are returned
1882 in registers. The rest go into memory. */
1883 return (TYPE_MODE (type) == DImode
1884 || (FLOAT_MODE_P (TYPE_MODE (type)) && ! TARGET_AC0)
1885 || TREE_CODE (type) == VECTOR_TYPE
1886 || COMPLEX_MODE_P (TYPE_MODE (type)));
1887 }
1888
1889 /* Worker function for TARGET_FUNCTION_VALUE.
1890
1891 On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! ) */
1892
1893 static rtx
pdp11_function_value(const_tree valtype,const_tree fntype_or_decl ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)1894 pdp11_function_value (const_tree valtype,
1895 const_tree fntype_or_decl ATTRIBUTE_UNUSED,
1896 bool outgoing ATTRIBUTE_UNUSED)
1897 {
1898 return gen_rtx_REG (TYPE_MODE (valtype),
1899 BASE_RETURN_VALUE_REG(TYPE_MODE(valtype)));
1900 }
1901
1902 /* Worker function for TARGET_LIBCALL_VALUE. */
1903
1904 static rtx
pdp11_libcall_value(machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)1905 pdp11_libcall_value (machine_mode mode,
1906 const_rtx fun ATTRIBUTE_UNUSED)
1907 {
1908 return gen_rtx_REG (mode, BASE_RETURN_VALUE_REG(mode));
1909 }
1910
1911 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1912
1913 On the pdp, the first "output" reg is the only register thus used.
1914
1915 maybe ac0 ? - as option someday! */
1916
1917 static bool
pdp11_function_value_regno_p(const unsigned int regno)1918 pdp11_function_value_regno_p (const unsigned int regno)
1919 {
1920 return (regno == RETVAL_REGNUM) || (TARGET_AC0 && (regno == AC0_REGNUM));
1921 }
1922
1923 /* Used for O constraint, matches if shift count is "small". */
1924 bool
pdp11_small_shift(int n)1925 pdp11_small_shift (int n)
1926 {
1927 return (unsigned) n < 4;
1928 }
1929
1930 /* Expand a shift insn. Returns true if the expansion was done,
1931 false if it needs to be handled by the caller. */
1932 bool
pdp11_expand_shift(rtx * operands,rtx (* shift_sc)(rtx,rtx,rtx),rtx (* shift_base)(rtx,rtx,rtx))1933 pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
1934 rtx (*shift_base) (rtx, rtx, rtx))
1935 {
1936 rtx r, test;
1937 rtx_code_label *lb;
1938
1939 if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
1940 emit_insn ((*shift_sc) (operands[0], operands[1], operands[2]));
1941 else if (TARGET_40_PLUS)
1942 return false;
1943 else
1944 {
1945 lb = gen_label_rtx ();
1946 r = gen_reg_rtx (HImode);
1947 emit_move_insn (operands[0], operands[1]);
1948 emit_move_insn (r, operands[2]);
1949 if (!CONST_INT_P (operands[2]))
1950 {
1951 test = gen_rtx_LE (HImode, r, const0_rtx);
1952 emit_jump_insn (gen_cbranchhi4 (test, r, const0_rtx, lb));
1953 }
1954 /* It would be nice to expand the loop here, but that's not
1955 possible because shifts may be generated by the loop unroll
1956 optimizer and it doesn't appreciate flow changes happening
1957 while it's doing things. */
1958 emit_insn ((*shift_base) (operands[0], operands[1], r));
1959 if (!CONST_INT_P (operands[2]))
1960 {
1961 emit_label (lb);
1962
1963 /* Allow REG_NOTES to be set on last insn (labels don't have enough
1964 fields, and can't be used for REG_NOTES anyway). */
1965 emit_use (stack_pointer_rtx);
1966 }
1967 }
1968 return true;
1969 }
1970
1971 /* Emit the instructions needed to produce a shift by a small constant
1972 amount (unrolled), or a shift made from a loop for the base machine
1973 case. */
1974 const char *
pdp11_assemble_shift(rtx * operands,machine_mode m,int code)1975 pdp11_assemble_shift (rtx *operands, machine_mode m, int code)
1976 {
1977 int i, n;
1978 rtx inops[2];
1979 rtx exops[2][2];
1980 rtx lb[1];
1981 pdp11_action action[2];
1982 const bool small = CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]));
1983
1984 gcc_assert (small || !TARGET_40_PLUS);
1985
1986 if (m == E_SImode)
1987 {
1988 inops[0] = operands[0];
1989 pdp11_expand_operands (inops, exops, 1, 2, action, either);
1990 }
1991
1992 if (!small)
1993 {
1994 /* Loop case, generate the top of loop label. */
1995 lb[0] = gen_label_rtx ();
1996 output_asm_label (lb[0]);
1997 fputs (":\n", asm_out_file);
1998 n = 1;
1999 }
2000 else
2001 n = INTVAL (operands[2]);
2002 if (code == LSHIFTRT)
2003 {
2004 output_asm_insn ("clc", NULL);
2005 switch (m)
2006 {
2007 case E_QImode:
2008 output_asm_insn ("rorb\t%0", operands);
2009 break;
2010 case E_HImode:
2011 output_asm_insn ("ror\t%0", operands);
2012 break;
2013 case E_SImode:
2014 output_asm_insn ("ror\t%0", exops[0]);
2015 output_asm_insn ("ror\t%0", exops[1]);
2016 break;
2017 default:
2018 gcc_unreachable ();
2019 }
2020 n--;
2021 }
2022 for (i = 0; i < n; i++)
2023 {
2024 switch (code)
2025 {
2026 case LSHIFTRT:
2027 case ASHIFTRT:
2028 switch (m)
2029 {
2030 case E_QImode:
2031 output_asm_insn ("asrb\t%0", operands);
2032 break;
2033 case E_HImode:
2034 output_asm_insn ("asr\t%0", operands);
2035 break;
2036 case E_SImode:
2037 output_asm_insn ("asr\t%0", exops[0]);
2038 output_asm_insn ("ror\t%0", exops[1]);
2039 break;
2040 default:
2041 gcc_unreachable ();
2042 }
2043 break;
2044 case ASHIFT:
2045 switch (m)
2046 {
2047 case E_QImode:
2048 output_asm_insn ("aslb\t%0", operands);
2049 break;
2050 case E_HImode:
2051 output_asm_insn ("asl\t%0", operands);
2052 break;
2053 case E_SImode:
2054 output_asm_insn ("asl\t%0", exops[1]);
2055 output_asm_insn ("rol\t%0", exops[0]);
2056 break;
2057 default:
2058 gcc_unreachable ();
2059 }
2060 break;
2061 }
2062 }
2063 if (!small)
2064 {
2065 /* Loop case, emit the count-down and branch if not done. */
2066 output_asm_insn ("dec\t%2", operands);
2067 output_asm_insn ("bne\t%l0", lb);
2068 }
2069 return "";
2070 }
2071
2072 /* Figure out the length of the instructions that will be produced for
2073 the given operands by pdp11_assemble_shift above. */
2074 int
pdp11_shift_length(rtx * operands,machine_mode m,int code,bool simple_operand_p)2075 pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand_p)
2076 {
2077 int shift_size;
2078
2079 /* Shift by 1 is 2 bytes if simple operand, 4 bytes if 2-word addressing mode. */
2080 shift_size = simple_operand_p ? 2 : 4;
2081
2082 /* In SImode, two shifts are needed per data item. */
2083 if (m == E_SImode)
2084 shift_size *= 2;
2085
2086 /* If shifting by a small constant, the loop is unrolled by the
2087 shift count. Otherwise, account for the size of the decrement
2088 and branch. */
2089 if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
2090 shift_size *= INTVAL (operands[2]);
2091 else
2092 shift_size += 4;
2093
2094 /* Logical right shift takes one more instruction (CLC). */
2095 if (code == LSHIFTRT)
2096 shift_size += 2;
2097
2098 return shift_size;
2099 }
2100
2101 /* Return the length of 2 or 4 word integer compares. */
2102 int
pdp11_cmp_length(rtx * operands,int words)2103 pdp11_cmp_length (rtx *operands, int words)
2104 {
2105 rtx inops[2];
2106 rtx exops[4][2];
2107 int i, len = 0;
2108
2109 if (!reload_completed)
2110 return 2;
2111
2112 inops[0] = operands[0];
2113 inops[1] = operands[1];
2114
2115 pdp11_expand_operands (inops, exops, 2, words, NULL, big);
2116
2117 for (i = 0; i < words; i++)
2118 {
2119 len += 4; /* cmp instruction word and branch that follows. */
2120 if (!REG_P (exops[i][0]) &&
2121 !simple_memory_operand (exops[i][0], HImode))
2122 len += 2; /* first operand extra word. */
2123 if (!REG_P (exops[i][1]) &&
2124 !simple_memory_operand (exops[i][1], HImode) &&
2125 !(CONST_INT_P (exops[i][1]) && INTVAL (exops[i][1]) == 0))
2126 len += 2; /* second operand extra word. */
2127 }
2128
2129 /* Deduct one word because there is no branch at the end. */
2130 return len - 2;
2131 }
2132
2133 /* Prepend to CLOBBERS hard registers that are automatically clobbered
2134 for an asm We do this for CC_REGNUM and FCC_REGNUM (on FPU target)
2135 to maintain source compatibility with the original cc0-based
2136 compiler. */
2137
2138 static rtx_insn *
pdp11_md_asm_adjust(vec<rtx> &,vec<rtx> &,vec<machine_mode> &,vec<const char * > &,vec<rtx> & clobbers,HARD_REG_SET & clobbered_regs,location_t)2139 pdp11_md_asm_adjust (vec<rtx> & /*outputs*/, vec<rtx> & /*inputs*/,
2140 vec<machine_mode> & /*input_modes*/,
2141 vec<const char *> & /*constraints*/, vec<rtx> &clobbers,
2142 HARD_REG_SET &clobbered_regs, location_t /*loc*/)
2143 {
2144 clobbers.safe_push (gen_rtx_REG (CCmode, CC_REGNUM));
2145 SET_HARD_REG_BIT (clobbered_regs, CC_REGNUM);
2146 if (TARGET_FPU)
2147 {
2148 clobbers.safe_push (gen_rtx_REG (CCmode, FCC_REGNUM));
2149 SET_HARD_REG_BIT (clobbered_regs, FCC_REGNUM);
2150 }
2151 return NULL;
2152 }
2153
2154 /* Worker function for TARGET_TRAMPOLINE_INIT.
2155
2156 trampoline - how should i do it in separate i+d ?
2157 have some allocate_trampoline magic???
2158
2159 the following should work for shared I/D:
2160
2161 MOV #STATIC, $4 01270Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
2162 JMP @#FUNCTION 000137 0x0000 <- FUNCTION
2163 */
2164 static void
pdp11_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)2165 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
2166 {
2167 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2168 rtx mem;
2169
2170 gcc_assert (!TARGET_SPLIT);
2171
2172 mem = adjust_address (m_tramp, HImode, 0);
2173 emit_move_insn (mem, GEN_INT (012700+STATIC_CHAIN_REGNUM));
2174 mem = adjust_address (m_tramp, HImode, 2);
2175 emit_move_insn (mem, chain_value);
2176 mem = adjust_address (m_tramp, HImode, 4);
2177 emit_move_insn (mem, GEN_INT (000137));
2178 emit_move_insn (mem, fnaddr);
2179 }
2180
2181 /* Worker function for TARGET_FUNCTION_ARG. */
2182
2183 static rtx
pdp11_function_arg(cumulative_args_t,const function_arg_info &)2184 pdp11_function_arg (cumulative_args_t, const function_arg_info &)
2185 {
2186 return NULL_RTX;
2187 }
2188
2189 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
2190
2191 Update the data in CUM to advance over argument ARG. */
2192
2193 static void
pdp11_function_arg_advance(cumulative_args_t cum_v,const function_arg_info & arg)2194 pdp11_function_arg_advance (cumulative_args_t cum_v,
2195 const function_arg_info &arg)
2196 {
2197 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2198
2199 *cum += arg.promoted_size_in_bytes ();
2200 }
2201
2202 /* Make sure everything's fine if we *don't* have an FPU.
2203 This assumes that putting a register in fixed_regs will keep the
2204 compiler's mitts completely off it. We don't bother to zero it out
2205 of register classes. Also fix incompatible register naming with
2206 the UNIX assembler. */
2207
2208 static void
pdp11_conditional_register_usage(void)2209 pdp11_conditional_register_usage (void)
2210 {
2211 int i;
2212 HARD_REG_SET x;
2213 if (!TARGET_FPU)
2214 {
2215 x = reg_class_contents[FPU_REGS];
2216 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ )
2217 if (TEST_HARD_REG_BIT (x, i))
2218 fixed_regs[i] = call_used_regs[i] = 1;
2219 }
2220
2221 if (TARGET_AC0)
2222 call_used_regs[AC0_REGNUM] = 1;
2223 if (TARGET_UNIX_ASM)
2224 {
2225 /* Change names of FPU registers for the UNIX assembler. */
2226 reg_names[8] = "fr0";
2227 reg_names[9] = "fr1";
2228 reg_names[10] = "fr2";
2229 reg_names[11] = "fr3";
2230 reg_names[12] = "fr4";
2231 reg_names[13] = "fr5";
2232 }
2233 }
2234
2235 static section *
pdp11_function_section(tree decl ATTRIBUTE_UNUSED,enum node_frequency freq ATTRIBUTE_UNUSED,bool startup ATTRIBUTE_UNUSED,bool exit ATTRIBUTE_UNUSED)2236 pdp11_function_section (tree decl ATTRIBUTE_UNUSED,
2237 enum node_frequency freq ATTRIBUTE_UNUSED,
2238 bool startup ATTRIBUTE_UNUSED,
2239 bool exit ATTRIBUTE_UNUSED)
2240 {
2241 return NULL;
2242 }
2243
2244 /* Support #ident for DEC assembler, but don't process the
2245 auto-generated ident string that names the compiler (since its
2246 syntax is not correct for DEC .ident). */
pdp11_output_ident(const char * ident)2247 static void pdp11_output_ident (const char *ident)
2248 {
2249 if (TARGET_DEC_ASM)
2250 {
2251 if (!startswith (ident, "GCC:"))
2252 fprintf (asm_out_file, "\t.ident\t\"%s\"\n", ident);
2253 }
2254
2255 }
2256
2257 /* This emits a (user) label, which gets a "_" prefix except for DEC
2258 assembler output. */
2259 void
pdp11_output_labelref(FILE * file,const char * name)2260 pdp11_output_labelref (FILE *file, const char *name)
2261 {
2262 if (!TARGET_DEC_ASM)
2263 fputs (USER_LABEL_PREFIX, file);
2264 fputs (name, file);
2265 }
2266
2267 /* This equates name with value. */
2268 void
pdp11_output_def(FILE * file,const char * label1,const char * label2)2269 pdp11_output_def (FILE *file, const char *label1, const char *label2)
2270 {
2271 if (TARGET_DEC_ASM)
2272 {
2273 assemble_name (file, label1);
2274 putc ('=', file);
2275 assemble_name (file, label2);
2276 }
2277 else
2278 {
2279 fputs ("\t.set\t", file);
2280 assemble_name (file, label1);
2281 putc (',', file);
2282 assemble_name (file, label2);
2283 }
2284 putc ('\n', file);
2285 }
2286
2287 void
pdp11_output_addr_vec_elt(FILE * file,int value)2288 pdp11_output_addr_vec_elt (FILE *file, int value)
2289 {
2290 char buf[256];
2291
2292 pdp11_gen_int_label (buf, "L", value);
2293 if (!TARGET_UNIX_ASM)
2294 fprintf (file, "\t.word");
2295 fprintf (file, "\t%s\n", buf + 1);
2296 }
2297
2298 /* This overrides some target hooks that are initializer elements so
2299 they can't be variables in the #define. */
2300 static void
pdp11_option_override(void)2301 pdp11_option_override (void)
2302 {
2303 if (TARGET_DEC_ASM)
2304 {
2305 targetm.asm_out.open_paren = "<";
2306 targetm.asm_out.close_paren = ">";
2307 }
2308 }
2309
2310 static void
pdp11_asm_named_section(const char * name,unsigned int flags,tree decl ATTRIBUTE_UNUSED)2311 pdp11_asm_named_section (const char *name, unsigned int flags,
2312 tree decl ATTRIBUTE_UNUSED)
2313 {
2314 const char *rwro = (flags & SECTION_WRITE) ? "rw" : "ro";
2315 const char *insdat = (flags & SECTION_CODE) ? "i" : "d";
2316
2317 gcc_assert (TARGET_DEC_ASM);
2318 fprintf (asm_out_file, "\t.psect\t%s,con,%s,%s\n", name, insdat, rwro);
2319 }
2320
2321 static void
pdp11_asm_init_sections(void)2322 pdp11_asm_init_sections (void)
2323 {
2324 if (TARGET_DEC_ASM)
2325 {
2326 bss_section = data_section;
2327 }
2328 else if (TARGET_GNU_ASM)
2329 {
2330 bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
2331 output_section_asm_op,
2332 ".bss");
2333 }
2334 }
2335
2336 static void
pdp11_file_start(void)2337 pdp11_file_start (void)
2338 {
2339 default_file_start ();
2340
2341 if (TARGET_DEC_ASM)
2342 fprintf (asm_out_file, "\t.enabl\tlsb,reg\n\n");
2343 }
2344
2345 static void
pdp11_file_end(void)2346 pdp11_file_end (void)
2347 {
2348 if (TARGET_DEC_ASM)
2349 fprintf (asm_out_file, "\t.end\n");
2350 }
2351
2352 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
2353
2354 static bool
pdp11_legitimate_constant_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x)2355 pdp11_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2356 {
2357 return GET_CODE (x) != CONST_DOUBLE || legitimate_const_double_p (x);
2358 }
2359
2360 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
2361
2362 static bool
pdp11_scalar_mode_supported_p(scalar_mode mode)2363 pdp11_scalar_mode_supported_p (scalar_mode mode)
2364 {
2365 /* Support SFmode even with -mfloat64. */
2366 if (mode == SFmode)
2367 return true;
2368 return default_scalar_mode_supported_p (mode);
2369 }
2370
2371 /* Implement TARGET_HARD_REGNO_NREGS. */
2372
2373 static unsigned int
pdp11_hard_regno_nregs(unsigned int regno,machine_mode mode)2374 pdp11_hard_regno_nregs (unsigned int regno, machine_mode mode)
2375 {
2376 if (regno <= PC_REGNUM)
2377 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
2378 return 1;
2379 }
2380
2381 /* Implement TARGET_HARD_REGNO_MODE_OK. On the pdp, the cpu registers
2382 can hold any mode other than float (because otherwise we may end up
2383 being asked to move from CPU to FPU register, which isn't a valid
2384 operation on the PDP11). For CPU registers, check alignment.
2385
2386 FPU accepts SF and DF but actually holds a DF - simplifies life! */
2387
2388 static bool
pdp11_hard_regno_mode_ok(unsigned int regno,machine_mode mode)2389 pdp11_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2390 {
2391 if (regno <= PC_REGNUM)
2392 return (GET_MODE_BITSIZE (mode) <= 16
2393 || (GET_MODE_BITSIZE (mode) >= 32
2394 && !(regno & 1)
2395 && !FLOAT_MODE_P (mode)));
2396
2397 return FLOAT_MODE_P (mode);
2398 }
2399
2400 /* Implement TARGET_MODES_TIEABLE_P. */
2401
2402 static bool
pdp11_modes_tieable_p(machine_mode mode1,machine_mode mode2)2403 pdp11_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2404 {
2405 return mode1 == HImode && mode2 == QImode;
2406 }
2407
2408 /* Implement PUSH_ROUNDING. On the pdp11, the stack is on an even
2409 boundary. */
2410
2411 poly_int64
pdp11_push_rounding(poly_int64 bytes)2412 pdp11_push_rounding (poly_int64 bytes)
2413 {
2414 return (bytes + 1) & ~1;
2415 }
2416
2417 struct gcc_target targetm = TARGET_INITIALIZER;
2418