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