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