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