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