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