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