1 /* Output routines for CR16 processor. 2 Copyright (C) 2012-2013 Free Software Foundation, Inc. 3 Contributed by KPIT Cummins Infosystems Limited. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published 9 by the Free Software Foundation; either version 3, or (at your 10 option) any later version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 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 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "tm.h" 25 #include "rtl.h" 26 #include "tree.h" 27 #include "tm_p.h" 28 #include "regs.h" 29 #include "hard-reg-set.h" 30 #include "insn-config.h" 31 #include "conditions.h" 32 #include "output.h" 33 #include "insn-codes.h" 34 #include "insn-attr.h" 35 #include "flags.h" 36 #include "except.h" 37 #include "function.h" 38 #include "recog.h" 39 #include "expr.h" 40 #include "optabs.h" 41 #include "diagnostic-core.h" 42 #include "basic-block.h" 43 #include "target.h" 44 #include "target-def.h" 45 #include "df.h" 46 47 /* Definitions. */ 48 49 /* Maximum number of register used for passing parameters. */ 50 #define MAX_REG_FOR_PASSING_ARGS 6 51 52 /* Minimum number register used for passing parameters. */ 53 #define MIN_REG_FOR_PASSING_ARGS 2 54 55 /* The maximum count of words supported in the assembly of the architecture in 56 a push/pop instruction. */ 57 #define MAX_COUNT 8 58 59 /* Predicate is true if the current function is a 'noreturn' function, 60 i.e. it is qualified as volatile. */ 61 #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl)) 62 63 /* Predicate that holds when we need to save registers even for 'noreturn' 64 functions, to accommodate for unwinding. */ 65 #define MUST_SAVE_REGS_P() \ 66 (flag_unwind_tables || (flag_exceptions && !UI_SJLJ)) 67 68 /* Nonzero if the rtx X is a signed const int of n bits. */ 69 #define RTX_SIGNED_INT_FITS_N_BITS(X, n) \ 70 ((GET_CODE (X) == CONST_INT \ 71 && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0) 72 73 /* Nonzero if the rtx X is an unsigned const int of n bits. */ 74 #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \ 75 ((GET_CODE (X) == CONST_INT \ 76 && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0) 77 78 /* Structure for stack computations. */ 79 80 /* variable definitions in the struture 81 args_size Number of bytes saved on the stack for local 82 variables 83 84 reg_size Number of bytes saved on the stack for 85 non-scratch registers 86 87 total_size The sum of 2 sizes: locals vars and padding byte 88 for saving the registers. Used in expand_prologue() 89 and expand_epilogue() 90 91 last_reg_to_save Will hold the number of the last register the 92 prologue saves, -1 if no register is saved 93 94 save_regs[16] Each object in the array is a register number. 95 Mark 1 for registers that need to be saved 96 97 num_regs Number of registers saved 98 99 initialized Non-zero if frame size already calculated, not 100 used yet 101 102 function_makes_calls Does the function make calls ? not used yet. */ 103 104 struct cr16_frame_info 105 { 106 unsigned long var_size; 107 unsigned long args_size; 108 unsigned int reg_size; 109 unsigned long total_size; 110 long last_reg_to_save; 111 long save_regs[FIRST_PSEUDO_REGISTER]; 112 int num_regs; 113 int initialized; 114 int function_makes_calls; 115 }; 116 117 /* Current frame information calculated by cr16_compute_frame_size. */ 118 static struct cr16_frame_info current_frame_info; 119 120 /* Static Variables. */ 121 122 /* Data model that was supplied by user via command line option 123 This will be overridden in case of invalid combination 124 of core and data model options are supplied. */ 125 static enum data_model_type data_model = DM_DEFAULT; 126 127 /* TARGETM Function Prototypes and forward declarations */ 128 static void cr16_print_operand (FILE *, rtx, int); 129 static void cr16_print_operand_address (FILE *, rtx); 130 131 /* Stack layout and calling conventions. */ 132 #undef TARGET_STRUCT_VALUE_RTX 133 #define TARGET_STRUCT_VALUE_RTX cr16_struct_value_rtx 134 #undef TARGET_RETURN_IN_MEMORY 135 #define TARGET_RETURN_IN_MEMORY cr16_return_in_memory 136 137 /* Target-specific uses of '__attribute__'. */ 138 #undef TARGET_ATTRIBUTE_TABLE 139 #define TARGET_ATTRIBUTE_TABLE cr16_attribute_table 140 #undef TARGET_NARROW_VOLATILE_BITFIELD 141 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false 142 143 /* EH related. */ 144 #undef TARGET_UNWIND_WORD_MODE 145 #define TARGET_UNWIND_WORD_MODE cr16_unwind_word_mode 146 147 /* Override Options. */ 148 #undef TARGET_OPTION_OVERRIDE 149 #define TARGET_OPTION_OVERRIDE cr16_override_options 150 151 /* Conditional register usuage. */ 152 #undef TARGET_CONDITIONAL_REGISTER_USAGE 153 #define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage 154 155 /* Controlling register spills. */ 156 #undef TARGET_CLASS_LIKELY_SPILLED_P 157 #define TARGET_CLASS_LIKELY_SPILLED_P cr16_class_likely_spilled_p 158 159 /* Passing function arguments. */ 160 #undef TARGET_FUNCTION_ARG 161 #define TARGET_FUNCTION_ARG cr16_function_arg 162 #undef TARGET_FUNCTION_ARG_ADVANCE 163 #define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance 164 #undef TARGET_RETURN_POPS_ARGS 165 #define TARGET_RETURN_POPS_ARGS cr16_return_pops_args 166 167 /* Initialize the GCC target structure. */ 168 #undef TARGET_FRAME_POINTER_REQUIRED 169 #define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required 170 #undef TARGET_CAN_ELIMINATE 171 #define TARGET_CAN_ELIMINATE cr16_can_eliminate 172 #undef TARGET_LEGITIMIZE_ADDRESS 173 #define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address 174 #undef TARGET_LEGITIMATE_CONSTANT_P 175 #define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p 176 #undef TARGET_LEGITIMATE_ADDRESS_P 177 #define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p 178 179 /* Returning function value. */ 180 #undef TARGET_FUNCTION_VALUE 181 #define TARGET_FUNCTION_VALUE cr16_function_value 182 #undef TARGET_LIBCALL_VALUE 183 #define TARGET_LIBCALL_VALUE cr16_libcall_value 184 #undef TARGET_FUNCTION_VALUE_REGNO_P 185 #define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p 186 187 /* printing the values. */ 188 #undef TARGET_PRINT_OPERAND 189 #define TARGET_PRINT_OPERAND cr16_print_operand 190 #undef TARGET_PRINT_OPERAND_ADDRESS 191 #define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address 192 193 /* Relative costs of operations. */ 194 #undef TARGET_ADDRESS_COST 195 #define TARGET_ADDRESS_COST cr16_address_cost 196 #undef TARGET_REGISTER_MOVE_COST 197 #define TARGET_REGISTER_MOVE_COST cr16_register_move_cost 198 #undef TARGET_MEMORY_MOVE_COST 199 #define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost 200 201 /* Table of machine attributes. */ 202 static const struct attribute_spec cr16_attribute_table[] = { 203 /* ISRs have special prologue and epilogue requirements. */ 204 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, 205 affects_type_identity }. */ 206 {"interrupt", 0, 0, false, true, true, NULL, false}, 207 {NULL, 0, 0, false, false, false, NULL, false} 208 }; 209 210 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive 211 .?byte directive along with @c is not understood by assembler. 212 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same 213 as TARGET_ASM_ALIGNED_xx_OP. */ 214 #undef TARGET_ASM_UNALIGNED_HI_OP 215 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP 216 #undef TARGET_ASM_UNALIGNED_SI_OP 217 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP 218 #undef TARGET_ASM_UNALIGNED_DI_OP 219 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP 220 221 /* Target hook implementations. */ 222 223 /* Implements hook TARGET_RETURN_IN_MEMORY. */ 224 static bool 225 cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) 226 { 227 const HOST_WIDE_INT size = int_size_in_bytes (type); 228 return ((size == -1) || (size > 8)); 229 } 230 231 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */ 232 static bool 233 cr16_class_likely_spilled_p (reg_class_t rclass) 234 { 235 if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS 236 || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS) 237 return true; 238 239 return false; 240 } 241 242 static int 243 cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED, 244 tree funtype ATTRIBUTE_UNUSED, 245 int size ATTRIBUTE_UNUSED) 246 { 247 return 0; 248 } 249 250 /* Returns true if data model selected via command line option 251 is same as function argument. */ 252 bool 253 cr16_is_data_model (enum data_model_type model) 254 { 255 return (model == data_model); 256 } 257 258 /* Parse relevant options and override. */ 259 static void 260 cr16_override_options (void) 261 { 262 /* Disable -fdelete-null-pointer-checks option for CR16 target. 263 Programs which rely on NULL pointer dereferences _not_ halting the 264 program may not work properly with this option. So disable this 265 option. */ 266 flag_delete_null_pointer_checks = 0; 267 268 /* FIXME: To avoid spill_failure ICE during exception handling, 269 * disable cse_fllow_jumps. The spill error occurs when compiler 270 * can't find a suitable candidate in GENERAL_REGS class to reload 271 * a 32bit register. 272 * Need to find a better way of avoiding this situation. */ 273 if (flag_exceptions) 274 flag_cse_follow_jumps = 0; 275 276 /* If -fpic option, data_model == DM_FAR. */ 277 if (flag_pic == NEAR_PIC) 278 { 279 data_model = DM_FAR; 280 } 281 282 /* The only option we want to examine is data model option. */ 283 if (cr16_data_model) 284 { 285 if (strcmp (cr16_data_model, "medium") == 0) 286 data_model = DM_DEFAULT; 287 else if (strcmp (cr16_data_model, "near") == 0) 288 data_model = DM_NEAR; 289 else if (strcmp (cr16_data_model, "far") == 0) 290 { 291 if (TARGET_CR16CP) 292 data_model = DM_FAR; 293 else 294 error ("data-model=far not valid for cr16c architecture"); 295 } 296 else 297 error ("invalid data model option -mdata-model=%s", cr16_data_model); 298 } 299 else 300 data_model = DM_DEFAULT; 301 } 302 303 /* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */ 304 static void 305 cr16_conditional_register_usage (void) 306 { 307 if (flag_pic) 308 { 309 fixed_regs[12] = call_used_regs[12] = 1; 310 } 311 } 312 313 /* Stack layout and calling conventions routines. */ 314 315 /* Return nonzero if the current function being compiled is an interrupt 316 function as specified by the "interrupt" attribute. */ 317 int 318 cr16_interrupt_function_p (void) 319 { 320 tree attributes; 321 322 attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)); 323 return (lookup_attribute ("interrupt", attributes) != NULL_TREE); 324 } 325 326 /* Compute values for the array current_frame_info.save_regs and the variable 327 current_frame_info.reg_size. The index of current_frame_info.save_regs 328 is numbers of register, each will get 1 if we need to save it in the 329 current function, 0 if not. current_frame_info.reg_size is the total sum 330 of the registers being saved. */ 331 static void 332 cr16_compute_save_regs (void) 333 { 334 unsigned int regno; 335 336 /* Initialize here so in case the function is no-return it will be -1. */ 337 current_frame_info.last_reg_to_save = -1; 338 339 /* Initialize the number of bytes to be saved. */ 340 current_frame_info.reg_size = 0; 341 342 /* No need to save any registers if the function never returns. */ 343 if (FUNC_IS_NORETURN_P (current_function_decl) && !MUST_SAVE_REGS_P ()) 344 return; 345 346 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 347 { 348 if (fixed_regs[regno]) 349 { 350 current_frame_info.save_regs[regno] = 0; 351 continue; 352 } 353 354 /* If this reg is used and not call-used (except RA), save it. */ 355 if (cr16_interrupt_function_p ()) 356 { 357 if (!crtl->is_leaf && call_used_regs[regno]) 358 /* This is a volatile reg in a non-leaf interrupt routine - save 359 it for the sake of its sons. */ 360 current_frame_info.save_regs[regno] = 1; 361 else if (df_regs_ever_live_p (regno)) 362 /* This reg is used - save it. */ 363 current_frame_info.save_regs[regno] = 1; 364 else 365 /* This reg is not used, and is not a volatile - don't save. */ 366 current_frame_info.save_regs[regno] = 0; 367 } 368 else 369 { 370 /* If this reg is used and not call-used (except RA), save it. */ 371 if (df_regs_ever_live_p (regno) 372 && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM)) 373 current_frame_info.save_regs[regno] = 1; 374 else 375 current_frame_info.save_regs[regno] = 0; 376 } 377 } 378 379 /* Save registers so the exception handler can modify them. */ 380 if (crtl->calls_eh_return) 381 { 382 unsigned int i; 383 384 for (i = 0;; ++i) 385 { 386 regno = EH_RETURN_DATA_REGNO (i); 387 if (INVALID_REGNUM == regno) 388 break; 389 current_frame_info.save_regs[regno] = 1; 390 } 391 } 392 393 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 394 if (current_frame_info.save_regs[regno] == 1) 395 { 396 current_frame_info.last_reg_to_save = regno; 397 if (regno >= CR16_FIRST_DWORD_REGISTER) 398 current_frame_info.reg_size += CR16_UNITS_PER_DWORD; 399 else 400 current_frame_info.reg_size += UNITS_PER_WORD; 401 } 402 } 403 404 /* Compute the size of the local area and the size to be adjusted by the 405 prologue and epilogue. */ 406 static void 407 cr16_compute_frame (void) 408 { 409 /* For aligning the local variables. */ 410 int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT; 411 int padding_locals; 412 413 /* Padding needed for each element of the frame. */ 414 current_frame_info.var_size = get_frame_size (); 415 416 /* Align to the stack alignment. */ 417 padding_locals = current_frame_info.var_size % stack_alignment; 418 if (padding_locals) 419 padding_locals = stack_alignment - padding_locals; 420 421 current_frame_info.var_size += padding_locals; 422 current_frame_info.total_size = current_frame_info.var_size 423 + (ACCUMULATE_OUTGOING_ARGS 424 ? crtl->outgoing_args_size : 0); 425 } 426 427 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */ 428 int 429 cr16_initial_elimination_offset (int from, int to) 430 { 431 /* Compute this since we need to use current_frame_info.reg_size. */ 432 cr16_compute_save_regs (); 433 434 /* Compute this since we need to use current_frame_info.var_size. */ 435 cr16_compute_frame (); 436 437 if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM)) 438 return (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0); 439 else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM)) 440 return (current_frame_info.reg_size + current_frame_info.var_size); 441 else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM)) 442 return (current_frame_info.reg_size + current_frame_info.var_size 443 + (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0)); 444 else 445 gcc_unreachable (); 446 } 447 448 /* Register Usage. */ 449 450 /* Return the class number of the smallest class containing reg number REGNO. 451 This could be a conditional expression or could index an array. */ 452 enum reg_class 453 cr16_regno_reg_class (int regno) 454 { 455 if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER)) 456 return SHORT_REGS; 457 458 if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER)) 459 return LONG_REGS; 460 461 return NO_REGS; 462 } 463 464 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */ 465 int 466 cr16_hard_regno_mode_ok (int regno, enum machine_mode mode) 467 { 468 if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11)) 469 return 0; 470 471 if (mode == DImode || mode == DFmode) 472 { 473 if ((regno > 8) || (regno & 1)) 474 return 0; 475 return 1; 476 } 477 478 if ((TARGET_INT32) 479 && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 ))) 480 return 0; 481 482 /* CC can only hold CCmode values. */ 483 if (GET_MODE_CLASS (mode) == MODE_CC) 484 return 0; 485 return 1; 486 } 487 488 /* Returns register number for function return value.*/ 489 static inline unsigned int 490 cr16_ret_register (void) 491 { 492 return 0; 493 } 494 495 /* Implements hook TARGET_STRUCT_VALUE_RTX. */ 496 static rtx 497 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, 498 int incoming ATTRIBUTE_UNUSED) 499 { 500 return gen_rtx_REG (Pmode, cr16_ret_register ()); 501 } 502 503 /* Returning function value. */ 504 505 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */ 506 static bool 507 cr16_function_value_regno_p (const unsigned int regno) 508 { 509 return (regno == cr16_ret_register ()); 510 } 511 512 /* Create an RTX representing the place where a 513 library function returns a value of mode MODE. */ 514 static rtx 515 cr16_libcall_value (enum machine_mode mode, 516 const_rtx func ATTRIBUTE_UNUSED) 517 { 518 return gen_rtx_REG (mode, cr16_ret_register ()); 519 } 520 521 /* Create an RTX representing the place where a 522 function returns a value of data type VALTYPE. */ 523 static rtx 524 cr16_function_value (const_tree type, 525 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, 526 bool outgoing ATTRIBUTE_UNUSED) 527 { 528 return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ()); 529 } 530 531 /* Passing function arguments. */ 532 533 /* If enough param regs are available for passing the param of type TYPE return 534 the number of registers needed else 0. */ 535 static int 536 enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type, 537 enum machine_mode mode) 538 { 539 int type_size; 540 int remaining_size; 541 542 if (mode != BLKmode) 543 type_size = GET_MODE_BITSIZE (mode); 544 else 545 type_size = int_size_in_bytes (type) * BITS_PER_UNIT; 546 547 remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS 548 - (MIN_REG_FOR_PASSING_ARGS + cum->ints) + 549 1); 550 551 /* Any variable which is too big to pass in two registers, will pass on 552 stack. */ 553 if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD)) 554 return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD; 555 556 return 0; 557 } 558 559 /* Implements the macro FUNCTION_ARG defined in cr16.h. */ 560 static rtx 561 cr16_function_arg (cumulative_args_t cum_v, enum machine_mode mode, 562 const_tree type, bool named ATTRIBUTE_UNUSED) 563 { 564 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 565 cum->last_parm_in_reg = 0; 566 567 /* function_arg () is called with this type just after all the args have 568 had their registers assigned. The rtx that function_arg returns from 569 this type is supposed to pass to 'gen_call' but currently it is not 570 implemented (see macro GEN_CALL). */ 571 if (type == void_type_node) 572 return NULL_RTX; 573 574 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0)) 575 return NULL_RTX; 576 577 if (mode == BLKmode) 578 { 579 /* Enable structures that need padding bytes at the end to pass to a 580 function in registers. */ 581 if (enough_regs_for_param (cum, type, mode) != 0) 582 { 583 cum->last_parm_in_reg = 1; 584 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints); 585 } 586 } 587 588 if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS) 589 return NULL_RTX; 590 else 591 { 592 if (enough_regs_for_param (cum, type, mode) != 0) 593 { 594 cum->last_parm_in_reg = 1; 595 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints); 596 } 597 } 598 599 return NULL_RTX; 600 } 601 602 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */ 603 void 604 cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype, 605 rtx libfunc ATTRIBUTE_UNUSED) 606 { 607 tree param, next_param; 608 609 cum->ints = 0; 610 611 /* Determine if this function has variable arguments. This is indicated by 612 the last argument being 'void_type_mode' if there are no variable 613 arguments. Change here for a different vararg. */ 614 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0; 615 param != NULL_TREE; param = next_param) 616 { 617 next_param = TREE_CHAIN (param); 618 if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node)) 619 { 620 cum->ints = -1; 621 return; 622 } 623 } 624 } 625 626 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */ 627 static void 628 cr16_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, 629 const_tree type, bool named ATTRIBUTE_UNUSED) 630 { 631 CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v); 632 633 /* l holds the number of registers required. */ 634 int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD; 635 636 /* If the parameter isn't passed on a register don't advance cum. */ 637 if (!cum->last_parm_in_reg) 638 return; 639 640 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0)) 641 return; 642 643 if ((mode == SImode) || (mode == HImode) 644 || (mode == QImode) || (mode == DImode)) 645 { 646 if (l <= 1) 647 cum->ints += 1; 648 else 649 cum->ints += l; 650 } 651 else if ((mode == SFmode) || (mode == DFmode)) 652 cum->ints += l; 653 else if ((mode) == BLKmode) 654 { 655 if ((l = enough_regs_for_param (cum, type, mode)) != 0) 656 cum->ints += l; 657 } 658 return; 659 } 660 661 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h. 662 Return nonzero if N is a register used for passing parameters. */ 663 int 664 cr16_function_arg_regno_p (int n) 665 { 666 return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS)); 667 } 668 669 /* Addressing modes. 670 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS 671 defined in cr16.h. */ 672 673 /* Helper function to check if is a valid base register that can 674 hold address. */ 675 static int 676 cr16_addr_reg_p (rtx addr_reg) 677 { 678 rtx reg; 679 680 if (REG_P (addr_reg)) 681 reg = addr_reg; 682 else if ((GET_CODE (addr_reg) == SUBREG) 683 && REG_P (SUBREG_REG (addr_reg)) 684 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg))) 685 <= UNITS_PER_WORD)) 686 reg = SUBREG_REG (addr_reg); 687 else 688 return FALSE; 689 690 if (GET_MODE (reg) != Pmode) 691 return FALSE; 692 693 return TRUE; 694 } 695 696 /* Helper functions: Created specifically for decomposing operand of CONST 697 Recursively look into expression x for code or data symbol. 698 The function expects the expression to contain combination of 699 SYMBOL_REF, CONST_INT, (PLUS or MINUS) 700 LABEL_REF, CONST_INT, (PLUS or MINUS) 701 SYMBOL_REF 702 LABEL_REF 703 All other combinations will result in code = -1 and data = ILLEGAL_DM 704 code data 705 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF 706 0 DM_FAR SYMBOL_REF was found and it was far data reference. 707 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference. 708 1 ILLEGAL_DM LABEL_REF was found. 709 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */ 710 void 711 cr16_decompose_const (rtx x, int *code, enum data_model_type *data, 712 bool treat_as_const) 713 { 714 *code = -1; 715 *data = ILLEGAL_DM; 716 switch (GET_CODE (x)) 717 { 718 case SYMBOL_REF: 719 *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0; 720 /* 2 indicates func sym. */ 721 if (*code == 0) 722 { 723 if (CR16_TARGET_DATA_NEAR) 724 *data = DM_DEFAULT; 725 else if (CR16_TARGET_DATA_MEDIUM) 726 *data = DM_FAR; 727 else if (CR16_TARGET_DATA_FAR) 728 { 729 if (treat_as_const) 730 /* This will be used only for printing 731 the qualifier. This call is (may be) 732 made by cr16_print_operand_address. */ 733 *data = DM_FAR; 734 else 735 /* This call is (may be) made by 736 cr16_legitimate_address_p. */ 737 *data = ILLEGAL_DM; 738 } 739 } 740 return; 741 742 case LABEL_REF: 743 /* 1 - indicates non-function symbol. */ 744 *code = 1; 745 return; 746 747 case PLUS: 748 case MINUS: 749 /* Look into the tree nodes. */ 750 if (GET_CODE (XEXP (x, 0)) == CONST_INT) 751 cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const); 752 else if (GET_CODE (XEXP (x, 1)) == CONST_INT) 753 cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const); 754 return; 755 default: 756 return; 757 } 758 } 759 760 /* Decompose Address 761 This function decomposes the address returns the type of address 762 as defined in enum cr16_addrtype. It also fills the parameter *out. 763 The decomposed address can be used for two purposes. One to 764 check if the address is valid and second to print the address 765 operand. 766 767 Following tables list valid address supported in CR16C/C+ architectures. 768 Legend: 769 aN : Absoulte address N-bit address 770 R : One 16-bit register 771 RP : Consecutive two 16-bit registers or one 32-bit register 772 I : One 32-bit register 773 dispN : Signed displacement of N-bits 774 775 ----Code addresses---- 776 Branch operands: 777 disp9 : CR16_ABSOLUTE (disp) 778 disp17 : CR16_ABSOLUTE (disp) 779 disp25 : CR16_ABSOLUTE (disp) 780 RP + disp25 : CR16_REGP_REL (base, disp) 781 782 Jump operands: 783 RP : CR16_REGP_REL (base, disp=0) 784 a24 : CR16_ABSOLUTE (disp) 785 786 ----Data addresses---- 787 a20 : CR16_ABSOLUTE (disp) near (1M) 788 a24 : CR16_ABSOLUTE (disp) medium (16M) 789 R + d20 : CR16_REG_REL (base, disp) near (1M+64K) 790 RP + d4 : CR16_REGP_REL (base, disp) far (4G) 791 RP + d16 : CR16_REGP_REL (base, disp) far (4G) 792 RP + d20 : CR16_REGP_REL (base, disp) far (4G) 793 I : *** Valid but port does not support this 794 I + a20 : *** Valid but port does not support this 795 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G) 796 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G) 797 798 Decomposing Data model in case of absolute address. 799 800 Target Option Address type Resultant Data ref type 801 ---------------------- ------------ ----------------------- 802 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT 803 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT 804 CR16_TARGET_MODEL_NEAR ABS24 Invalid 805 CR16_TARGET_MODEL_NEAR IMM32 Invalid 806 807 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT 808 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT 809 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR 810 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid 811 812 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT 813 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT 814 CR16_TARGET_MODEL_FAR ABS24 DM_FAR 815 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */ 816 enum cr16_addrtype 817 cr16_decompose_address (rtx addr, struct cr16_address *out, 818 bool debug_print, bool treat_as_const) 819 { 820 rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX; 821 enum data_model_type data = ILLEGAL_DM; 822 int code = -1; 823 enum cr16_addrtype retval = CR16_INVALID; 824 825 switch (GET_CODE (addr)) 826 { 827 case CONST_INT: 828 /* Absolute address (known at compile time). */ 829 code = 0; 830 if (debug_print) 831 fprintf (stderr, "\ncode:%d", code); 832 disp = addr; 833 834 if (debug_print) 835 { 836 fprintf (stderr, "\ndisp:"); 837 debug_rtx (disp); 838 } 839 840 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20)) 841 { 842 data = DM_DEFAULT; 843 if (debug_print) 844 fprintf (stderr, "\ndata:%d", data); 845 retval = CR16_ABSOLUTE; 846 } 847 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24)) 848 { 849 if (!CR16_TARGET_DATA_NEAR) 850 { 851 data = DM_FAR; 852 if (debug_print) 853 fprintf (stderr, "\ndata:%d", data); 854 retval = CR16_ABSOLUTE; 855 } 856 else 857 return CR16_INVALID; /* ABS24 is not support in NEAR model. */ 858 } 859 else 860 return CR16_INVALID; 861 break; 862 863 case CONST: 864 /* A CONST is an expression of PLUS or MINUS with 865 CONST_INT, SYMBOL_REF or LABEL_REF. This is the 866 result of assembly-time arithmetic computation. */ 867 retval = CR16_ABSOLUTE; 868 disp = addr; 869 /* Call the helper function to check the validity. */ 870 cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const); 871 if ((code == 0) && (data == ILLEGAL_DM)) 872 /* CONST is not valid code or data address. */ 873 return CR16_INVALID; 874 if (debug_print) 875 { 876 fprintf (stderr, "\ndisp:"); 877 debug_rtx (disp); 878 fprintf (stderr, "\ncode:%d", code); 879 fprintf (stderr, "\ndata:%d", data); 880 } 881 break; 882 883 case LABEL_REF: 884 retval = CR16_ABSOLUTE; 885 disp = addr; 886 /* 1 - indicates non-function symbol. */ 887 code = 1; 888 if (debug_print) 889 { 890 fprintf (stderr, "\ndisp:"); 891 debug_rtx (disp); 892 fprintf (stderr, "\ncode:%d", code); 893 } 894 break; 895 896 case SYMBOL_REF: 897 /* Absolute address (known at link time). */ 898 retval = CR16_ABSOLUTE; 899 disp = addr; 900 /* This is a code address if symbol_ref is a function. */ 901 /* 2 indicates func sym. */ 902 code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0; 903 if (debug_print) 904 { 905 fprintf (stderr, "\ndisp:"); 906 debug_rtx (disp); 907 fprintf (stderr, "\ncode:%d", code); 908 } 909 /* If not function ref then check if valid data ref. */ 910 if (code == 0) 911 { 912 if (CR16_TARGET_DATA_NEAR) 913 data = DM_DEFAULT; 914 else if (CR16_TARGET_DATA_MEDIUM) 915 data = DM_FAR; 916 else if (CR16_TARGET_DATA_FAR) 917 { 918 if (treat_as_const) 919 /* This will be used only for printing the 920 qualifier. This call is (may be) made 921 by cr16_print_operand_address. */ 922 data = DM_FAR; 923 else 924 /* This call is (may be) made by 925 cr16_legitimate_address_p. */ 926 return CR16_INVALID; 927 } 928 else 929 data = DM_DEFAULT; 930 } 931 if (debug_print) 932 fprintf (stderr, "\ndata:%d", data); 933 break; 934 935 case REG: 936 case SUBREG: 937 /* Register relative address. */ 938 /* Assume REG fits in a single register. */ 939 retval = CR16_REG_REL; 940 if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD) 941 if (!LONG_REG_P (REGNO (addr))) 942 /* REG will result in reg pair. */ 943 retval = CR16_REGP_REL; 944 base = addr; 945 if (debug_print) 946 { 947 fprintf (stderr, "\nbase:"); 948 debug_rtx (base); 949 } 950 break; 951 952 case PLUS: 953 switch (GET_CODE (XEXP (addr, 0))) 954 { 955 case REG: 956 case SUBREG: 957 /* REG + DISP20. */ 958 /* All Reg relative addresses having a displacement needs 959 to fit in 20-bits. */ 960 disp = XEXP (addr, 1); 961 if (debug_print) 962 { 963 fprintf (stderr, "\ndisp:"); 964 debug_rtx (disp); 965 } 966 switch (GET_CODE (XEXP (addr, 1))) 967 { 968 case CONST_INT: 969 /* Shall fit in 20-bits. */ 970 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20)) 971 return CR16_INVALID; 972 code = 0; 973 if (debug_print) 974 fprintf (stderr, "\ncode:%d", code); 975 break; 976 977 case UNSPEC: 978 switch (XINT (XEXP (addr, 1), 1)) 979 { 980 case UNSPEC_LIBRARY_OFFSET: 981 default: 982 gcc_unreachable (); 983 } 984 break; 985 986 case LABEL_REF: 987 case SYMBOL_REF: 988 case CONST: 989 /* This is also a valid expression for address. 990 However, we cannot ascertain if the resultant 991 displacement will be valid 20-bit value. Therefore, 992 lets not allow such an expression for now. This will 993 be updated when we find a way to validate this 994 expression as legitimate address. 995 Till then fall through CR16_INVALID. */ 996 default: 997 return CR16_INVALID; 998 } 999 1000 /* Now check if REG can fit into single or pair regs. */ 1001 retval = CR16_REG_REL; 1002 base = XEXP (addr, 0); 1003 if (debug_print) 1004 { 1005 fprintf (stderr, "\nbase:"); 1006 debug_rtx (base); 1007 } 1008 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD) 1009 { 1010 if (!LONG_REG_P (REGNO ((XEXP (addr, 0))))) 1011 /* REG will result in reg pair. */ 1012 retval = CR16_REGP_REL; 1013 } 1014 break; 1015 1016 case PLUS: 1017 /* Valid expr: 1018 plus 1019 /\ 1020 / \ 1021 plus idx 1022 /\ 1023 / \ 1024 reg const_int 1025 1026 Check if the operand 1 is valid index register. */ 1027 data = ILLEGAL_DM; 1028 if (debug_print) 1029 fprintf (stderr, "\ndata:%d", data); 1030 switch (GET_CODE (XEXP (addr, 1))) 1031 { 1032 case REG: 1033 case SUBREG: 1034 if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1))) 1035 return CR16_INVALID; 1036 /* OK. REG is a valid index register. */ 1037 index = XEXP (addr, 1); 1038 if (debug_print) 1039 { 1040 fprintf (stderr, "\nindex:"); 1041 debug_rtx (index); 1042 } 1043 break; 1044 default: 1045 return CR16_INVALID; 1046 } 1047 /* Check if operand 0 of operand 0 is REGP. */ 1048 switch (GET_CODE (XEXP (XEXP (addr, 0), 0))) 1049 { 1050 case REG: 1051 case SUBREG: 1052 /* Now check if REG is a REGP and not in LONG regs. */ 1053 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0))) 1054 > BITS_PER_WORD) 1055 { 1056 if (REGNO (XEXP (XEXP (addr, 0), 0)) 1057 >= CR16_FIRST_DWORD_REGISTER) 1058 return CR16_INVALID; 1059 base = XEXP (XEXP (addr, 0), 0); 1060 if (debug_print) 1061 { 1062 fprintf (stderr, "\nbase:"); 1063 debug_rtx (base); 1064 } 1065 } 1066 else 1067 return CR16_INVALID; 1068 break; 1069 default: 1070 return CR16_INVALID; 1071 } 1072 /* Now check if the operand 1 of operand 0 is const_int. */ 1073 if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT) 1074 { 1075 disp = XEXP (XEXP (addr, 0), 1); 1076 if (debug_print) 1077 { 1078 fprintf (stderr, "\ndisp:"); 1079 debug_rtx (disp); 1080 } 1081 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20)) 1082 return CR16_INVALID; 1083 } 1084 else 1085 return CR16_INVALID; 1086 retval = CR16_INDEX_REGP_REL; 1087 break; 1088 default: 1089 return CR16_INVALID; 1090 } 1091 break; 1092 1093 default: 1094 return CR16_INVALID; 1095 } 1096 1097 /* Check if the base and index registers are valid. */ 1098 if (base && !(cr16_addr_reg_p (base))) 1099 return CR16_INVALID; 1100 if (base && !(CR16_REG_OK_FOR_BASE_P (base))) 1101 return CR16_INVALID; 1102 if (index && !(REG_OK_FOR_INDEX_P (index))) 1103 return CR16_INVALID; 1104 1105 /* Write the decomposition to out parameter. */ 1106 out->base = base; 1107 out->disp = disp; 1108 out->index = index; 1109 out->data = data; 1110 out->code = code; 1111 1112 return retval; 1113 } 1114 1115 /* Return non-zero value if 'x' is legitimate PIC operand 1116 when generating PIC code. */ 1117 int 1118 legitimate_pic_operand_p (rtx x) 1119 { 1120 switch (GET_CODE (x)) 1121 { 1122 case SYMBOL_REF: 1123 return 0; 1124 break; 1125 case LABEL_REF: 1126 return 0; 1127 break; 1128 case CONST: 1129 /* REVISIT: Use something like symbol_referenced_p. */ 1130 if (GET_CODE (XEXP (x, 0)) == PLUS 1131 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF 1132 || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF) 1133 && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)) 1134 return 0; 1135 break; 1136 case MEM: 1137 return legitimate_pic_operand_p (XEXP (x, 0)); 1138 break; 1139 default: 1140 break; 1141 } 1142 return 1; 1143 } 1144 1145 /* Convert a non-PIC address in `orig' to a PIC address in `reg'. 1146 1147 Input Output (-f pic) Output (-f PIC) 1148 orig reg 1149 1150 C1 symbol symbol@BRO (r12) symbol@GOT (r12) 1151 1152 C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12) 1153 1154 NOTE: @BRO is added using unspec:BRO 1155 NOTE: @GOT is added using unspec:GOT. */ 1156 rtx 1157 legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED, 1158 rtx reg) 1159 { 1160 /* First handle a simple SYMBOL_REF or LABEL_REF. */ 1161 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF) 1162 { 1163 if (reg == 0) 1164 reg = gen_reg_rtx (Pmode); 1165 1166 if (flag_pic == NEAR_PIC) 1167 { 1168 /* Unspec to handle -fpic option. */ 1169 emit_insn (gen_unspec_bro_addr (reg, orig)); 1170 emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx)); 1171 } 1172 else if (flag_pic == FAR_PIC) 1173 { 1174 /* Unspec to handle -fPIC option. */ 1175 emit_insn (gen_unspec_got_addr (reg, orig)); 1176 } 1177 return reg; 1178 } 1179 else if (GET_CODE (orig) == CONST) 1180 { 1181 /* To handle (symbol + offset). */ 1182 rtx base, offset; 1183 1184 if (GET_CODE (XEXP (orig, 0)) == PLUS 1185 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) 1186 return orig; 1187 1188 if (reg == 0) 1189 { 1190 gcc_assert (can_create_pseudo_p ()); 1191 reg = gen_reg_rtx (Pmode); 1192 } 1193 1194 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); 1195 1196 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); 1197 offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, 1198 base == reg ? 0 : reg); 1199 1200 /* REVISIT: Optimize for const-offsets. */ 1201 emit_insn (gen_addsi3 (reg, base, offset)); 1202 1203 return reg; 1204 } 1205 return orig; 1206 } 1207 1208 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */ 1209 static bool 1210 cr16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, 1211 rtx addr, bool strict) 1212 { 1213 enum cr16_addrtype addrtype; 1214 struct cr16_address address; 1215 1216 if (TARGET_DEBUG_ADDR) 1217 { 1218 fprintf (stderr, 1219 "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d", 1220 GET_MODE_NAME (mode), strict); 1221 debug_rtx (addr); 1222 } 1223 addrtype = cr16_decompose_address (addr, &address, 1224 (TARGET_DEBUG_ADDR ? 1 : 0), FALSE); 1225 1226 if (TARGET_DEBUG_ADDR) 1227 { 1228 const char *typestr; 1229 1230 switch (addrtype) 1231 { 1232 case CR16_INVALID: 1233 typestr = "invalid"; 1234 break; 1235 case CR16_ABSOLUTE: 1236 typestr = "absolute"; 1237 break; 1238 case CR16_REG_REL: 1239 typestr = "register relative"; 1240 break; 1241 case CR16_REGP_REL: 1242 typestr = "register pair relative"; 1243 break; 1244 case CR16_INDEX_REGP_REL: 1245 typestr = "index + register pair relative"; 1246 break; 1247 default: 1248 gcc_unreachable (); 1249 } 1250 fprintf (stderr, "\ncr16 address type: %s\n", typestr); 1251 } 1252 1253 if (addrtype == CR16_INVALID) 1254 return FALSE; 1255 1256 if (strict) 1257 { 1258 if (address.base 1259 && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address.base), mode)) 1260 { 1261 if (TARGET_DEBUG_ADDR) 1262 fprintf (stderr, "base register not strict\n"); 1263 return FALSE; 1264 } 1265 if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index))) 1266 { 1267 if (TARGET_DEBUG_ADDR) 1268 fprintf (stderr, "index register not strict\n"); 1269 return FALSE; 1270 } 1271 } 1272 1273 /* Return true if addressing mode is register relative. */ 1274 if (flag_pic) 1275 { 1276 if (addrtype == CR16_REG_REL || addrtype == CR16_REGP_REL) 1277 return TRUE; 1278 else 1279 return FALSE; 1280 } 1281 1282 return TRUE; 1283 } 1284 1285 /* Routines to compute costs. */ 1286 1287 /* Return cost of the memory address x. */ 1288 static int 1289 cr16_address_cost (rtx addr, enum machine_mode mode ATTRIBUTE_UNUSED, 1290 addr_space_t as ATTRIBUTE_UNUSED, 1291 bool speed ATTRIBUTE_UNUSED) 1292 { 1293 enum cr16_addrtype addrtype; 1294 struct cr16_address address; 1295 int cost = 2; 1296 1297 addrtype = cr16_decompose_address (addr, &address, 0, FALSE); 1298 1299 gcc_assert (addrtype != CR16_INVALID); 1300 1301 /* CR16_ABSOLUTE : 3 1302 CR16_REG_REL (disp !=0) : 4 1303 CR16_REG_REL (disp ==0) : 5 1304 CR16_REGP_REL (disp !=0) : 6 1305 CR16_REGP_REL (disp ==0) : 7 1306 CR16_INDEX_REGP_REL (disp !=0) : 8 1307 CR16_INDEX_REGP_REL (disp ==0) : 9. */ 1308 switch (addrtype) 1309 { 1310 case CR16_ABSOLUTE: 1311 cost += 1; 1312 break; 1313 case CR16_REGP_REL: 1314 cost += 2; 1315 /* Fall through. */ 1316 case CR16_REG_REL: 1317 cost += 3; 1318 if (address.disp) 1319 cost -= 1; 1320 break; 1321 case CR16_INDEX_REGP_REL: 1322 cost += 7; 1323 if (address.disp) 1324 cost -= 1; 1325 default: 1326 break; 1327 } 1328 1329 if (TARGET_DEBUG_ADDR) 1330 { 1331 fprintf (stderr, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost); 1332 debug_rtx (addr); 1333 } 1334 1335 return cost; 1336 } 1337 1338 1339 /* Implement `TARGET_REGISTER_MOVE_COST'. */ 1340 static int 1341 cr16_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, 1342 reg_class_t from ATTRIBUTE_UNUSED, reg_class_t to) 1343 { 1344 return (to != GENERAL_REGS ? 8 : 2); 1345 } 1346 1347 /* Implement `TARGET_MEMORY_MOVE_COST'. */ 1348 1349 /* Return the cost of moving data of mode MODE between a register of class 1350 CLASS and memory; IN is zero if the value is to be written to memory, 1351 nonzero if it is to be read in. This cost is relative to those in 1352 REGISTER_MOVE_COST. */ 1353 static int 1354 cr16_memory_move_cost (enum machine_mode mode, 1355 reg_class_t rclass ATTRIBUTE_UNUSED, 1356 bool in ATTRIBUTE_UNUSED) 1357 { 1358 /* One LD or ST takes twice the time of a simple reg-reg move. */ 1359 if (reg_classes_intersect_p (rclass, GENERAL_REGS)) 1360 return (4 * HARD_REGNO_NREGS (0, mode)); 1361 else 1362 return (100); 1363 } 1364 1365 /* Instruction output. */ 1366 1367 /* Check if a const_double is ok for cr16 store-immediate instructions. */ 1368 int 1369 cr16_const_double_ok (rtx op) 1370 { 1371 if (GET_MODE (op) == SFmode) 1372 { 1373 REAL_VALUE_TYPE r; 1374 long l; 1375 REAL_VALUE_FROM_CONST_DOUBLE (r, op); 1376 REAL_VALUE_TO_TARGET_SINGLE (r, l); 1377 return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0; 1378 } 1379 1380 return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4)) && 1381 (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4))) ? 1 : 0; 1382 } 1383 1384 /* Returns bit position of first 0 or 1 bit. 1385 It is safe to assume val as 16-bit wide. */ 1386 int 1387 cr16_operand_bit_pos (int val, int bitval) 1388 { 1389 int i; 1390 if (bitval == 0) 1391 val = ~val; 1392 1393 for (i = 0; i < 16; i++) 1394 if (val & (1 << i)) 1395 break; 1396 return i; 1397 } 1398 1399 /* Implements the macro PRINT_OPERAND defined in cr16.h. */ 1400 static void 1401 cr16_print_operand (FILE * file, rtx x, int code) 1402 { 1403 int ptr_dereference = 0; 1404 1405 switch (code) 1406 { 1407 case 'd': 1408 { 1409 const char *cr16_cmp_str; 1410 switch (GET_CODE (x)) 1411 { 1412 /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg) 1413 -> swap all non symmetric ops. */ 1414 case EQ: 1415 cr16_cmp_str = "eq"; 1416 break; 1417 case NE: 1418 cr16_cmp_str = "ne"; 1419 break; 1420 case GT: 1421 cr16_cmp_str = "lt"; 1422 break; 1423 case GTU: 1424 cr16_cmp_str = "lo"; 1425 break; 1426 case LT: 1427 cr16_cmp_str = "gt"; 1428 break; 1429 case LTU: 1430 cr16_cmp_str = "hi"; 1431 break; 1432 case GE: 1433 cr16_cmp_str = "le"; 1434 break; 1435 case GEU: 1436 cr16_cmp_str = "ls"; 1437 break; 1438 case LE: 1439 cr16_cmp_str = "ge"; 1440 break; 1441 case LEU: 1442 cr16_cmp_str = "hs"; 1443 break; 1444 default: 1445 gcc_unreachable (); 1446 } 1447 fprintf (file, "%s", cr16_cmp_str); 1448 return; 1449 } 1450 case '$': 1451 putc ('$', file); 1452 return; 1453 1454 case 'p': 1455 if (GET_CODE (x) == REG) 1456 { 1457 /* For Push instructions, we should not print register pairs. */ 1458 fprintf (file, "%s", reg_names[REGNO (x)]); 1459 return; 1460 } 1461 break; 1462 1463 case 'b': 1464 /* Print the immediate address for bal 1465 'b' is used instead of 'a' to avoid compiler calling 1466 the GO_IF_LEGITIMATE_ADDRESS which cannot 1467 perform checks on const_int code addresses as it 1468 assumes all const_int are data addresses. */ 1469 fprintf (file, "0x%lx", INTVAL (x)); 1470 return; 1471 1472 case 'r': 1473 /* Print bit position of first 0. */ 1474 fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 0)); 1475 return; 1476 1477 case 's': 1478 /* Print bit position of first 1. */ 1479 fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 1)); 1480 return; 1481 case 'g': 1482 /* 'g' is used for implicit mem: dereference. */ 1483 ptr_dereference = 1; 1484 case 'f': 1485 case 0: 1486 /* default. */ 1487 switch (GET_CODE (x)) 1488 { 1489 case REG: 1490 if (GET_MODE_BITSIZE (GET_MODE (x)) > BITS_PER_WORD) 1491 { 1492 if (LONG_REG_P (REGNO (x))) 1493 fprintf (file, "(%s)", reg_names[REGNO (x)]); 1494 else 1495 fprintf (file, "(%s,%s)", reg_names[REGNO (x) + 1], 1496 reg_names[REGNO (x)]); 1497 } 1498 else 1499 fprintf (file, "%s", reg_names[REGNO (x)]); 1500 return; 1501 1502 case MEM: 1503 output_address (XEXP (x, 0)); 1504 return; 1505 1506 case CONST_DOUBLE: 1507 { 1508 REAL_VALUE_TYPE r; 1509 long l; 1510 1511 REAL_VALUE_FROM_CONST_DOUBLE (r, x); 1512 REAL_VALUE_TO_TARGET_SINGLE (r, l); 1513 1514 fprintf (file, "$0x%lx", l); 1515 return; 1516 } 1517 case CONST_INT: 1518 { 1519 fprintf (file, "$%ld", INTVAL (x)); 1520 return; 1521 } 1522 case UNSPEC: 1523 switch (XINT (x, 1)) 1524 { 1525 default: 1526 gcc_unreachable (); 1527 } 1528 break; 1529 1530 default: 1531 if (!ptr_dereference) 1532 { 1533 putc ('$', file); 1534 } 1535 cr16_print_operand_address (file, x); 1536 return; 1537 } 1538 default: 1539 output_operand_lossage ("invalid %%xn code"); 1540 } 1541 1542 gcc_unreachable (); 1543 } 1544 1545 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */ 1546 1547 static void 1548 cr16_print_operand_address (FILE * file, rtx addr) 1549 { 1550 enum cr16_addrtype addrtype; 1551 struct cr16_address address; 1552 1553 /* Decompose the address. Also ask it to treat address as constant. */ 1554 addrtype = cr16_decompose_address (addr, &address, 0, TRUE); 1555 1556 if (address.disp && GET_CODE (address.disp) == UNSPEC) 1557 { 1558 debug_rtx (addr); 1559 } 1560 1561 switch (addrtype) 1562 { 1563 case CR16_REG_REL: 1564 if (address.disp) 1565 { 1566 if (GET_CODE (address.disp) == UNSPEC) 1567 cr16_print_operand (file, address.disp, 0); 1568 else 1569 output_addr_const (file, address.disp); 1570 } 1571 else 1572 fprintf (file, "0"); 1573 fprintf (file, "(%s)", reg_names[REGNO (address.base)]); 1574 break; 1575 1576 case CR16_ABSOLUTE: 1577 if (address.disp) 1578 output_addr_const (file, address.disp); 1579 else 1580 fprintf (file, "0"); 1581 break; 1582 1583 case CR16_INDEX_REGP_REL: 1584 fprintf (file, "[%s]", reg_names[REGNO (address.index)]); 1585 /* Fall through. */ 1586 case CR16_REGP_REL: 1587 if (address.disp) 1588 { 1589 if (GET_CODE (address.disp) == UNSPEC) 1590 cr16_print_operand (file, address.disp, 0); 1591 else 1592 output_addr_const (file, address.disp); 1593 } 1594 else 1595 fprintf (file, "0"); 1596 fprintf (file, "(%s,%s)", reg_names[REGNO (address.base) + 1], 1597 reg_names[REGNO (address.base)]); 1598 break; 1599 default: 1600 debug_rtx (addr); 1601 gcc_unreachable (); 1602 } 1603 /* Add qualifiers to the address expression that was just printed. */ 1604 if (flag_pic < NEAR_PIC && address.code == 0) 1605 { 1606 if (address.data == DM_FAR) 1607 /* Addr contains SYMBOL_REF & far data ptr. */ 1608 fprintf (file, "@l"); 1609 else if (address.data == DM_DEFAULT) 1610 /* Addr contains SYMBOL_REF & medium data ptr. */ 1611 fprintf (file, "@m"); 1612 /* Addr contains SYMBOL_REF & medium data ptr. */ 1613 else if (address.data == DM_NEAR) 1614 /* Addr contains SYMBOL_REF & near data ptr. */ 1615 fprintf (file, "@s"); 1616 } 1617 else if (flag_pic == NEAR_PIC 1618 && (address.code == 0) && (address.data == DM_FAR 1619 || address.data == DM_DEFAULT 1620 || address.data == DM_NEAR)) 1621 { 1622 fprintf (file, "@l"); 1623 } 1624 else if (flag_pic == NEAR_PIC && address.code == 2) 1625 { 1626 fprintf (file, "pic"); 1627 } 1628 else if (flag_pic == NEAR_PIC && address.code == 1) 1629 { 1630 fprintf (file, "@cpic"); 1631 } 1632 1633 else if (flag_pic == FAR_PIC && address.code == 2) 1634 { 1635 /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted 1636 address ! GOTc tells assembler this symbol is a text-address 1637 This needs to be fixed in such a way that this offset is done 1638 only in the case where an address is being used for indirect jump 1639 or call. Determining the potential usage of loadd is of course not 1640 possible always. Eventually, this has to be fixed in the 1641 processor. */ 1642 fprintf (file, "GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]); 1643 } 1644 else if (flag_pic == FAR_PIC && address.code == 1) 1645 { 1646 fprintf (file, "@cGOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]); 1647 } 1648 1649 else if (flag_pic == FAR_PIC && 1650 (address.data == DM_FAR || address.data == DM_DEFAULT 1651 || address.data == DM_NEAR)) 1652 { 1653 fprintf (file, "@GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]); 1654 } 1655 } 1656 1657 /* Machine description helper functions. */ 1658 1659 /* Called from cr16.md. The return value depends on the parameter push_or_pop: 1660 When push_or_pop is zero -> string for push instructions of prologue. 1661 When push_or_pop is nonzero -> string for pop/popret/retx in epilogue. 1662 Relies on the assumptions: 1663 1. RA is the last register to be saved. 1664 2. The maximal value of the counter is MAX_COUNT. */ 1665 char * 1666 cr16_prepare_push_pop_string (int push_or_pop) 1667 { 1668 /* j is the number of registers being saved, takes care that there won't be 1669 more than 8 in one push/pop instruction. */ 1670 1671 /* For the register mask string. */ 1672 static char one_inst_str[50]; 1673 1674 /* i is the index of current_frame_info.save_regs[], going from 0 until 1675 current_frame_info.last_reg_to_save. */ 1676 int i, start_reg; 1677 int word_cnt; 1678 int print_ra; 1679 char *return_str; 1680 1681 /* For reversing on the push instructions if there are more than one. */ 1682 char *temp_str; 1683 1684 return_str = (char *) xmalloc (160); 1685 temp_str = (char *) xmalloc (160); 1686 1687 /* Initialize. */ 1688 memset (return_str, 0, 3); 1689 1690 i = 0; 1691 while (i <= current_frame_info.last_reg_to_save) 1692 { 1693 /* Prepare mask for one instruction. */ 1694 one_inst_str[0] = 0; 1695 1696 /* To count number of words in one instruction. */ 1697 word_cnt = 0; 1698 start_reg = i; 1699 print_ra = 0; 1700 while ((word_cnt < MAX_COUNT) 1701 && (i <= current_frame_info.last_reg_to_save)) 1702 { 1703 /* For each non consecutive save register, 1704 a new instruction shall be generated. */ 1705 if (!current_frame_info.save_regs[i]) 1706 { 1707 /* Move to next reg and break. */ 1708 ++i; 1709 break; 1710 } 1711 1712 if (i == RETURN_ADDRESS_REGNUM) 1713 print_ra = 1; 1714 else 1715 { 1716 /* Check especially if adding 2 does not cross the MAX_COUNT. */ 1717 if ((word_cnt + ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2)) 1718 >= MAX_COUNT) 1719 break; 1720 /* Increase word count by 2 for long registers except RA. */ 1721 word_cnt += ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2); 1722 } 1723 ++i; 1724 } 1725 1726 /* No need to generate any instruction as 1727 no register or RA needs to be saved. */ 1728 if ((word_cnt == 0) && (print_ra == 0)) 1729 continue; 1730 1731 /* Now prepare the instruction operands. */ 1732 if (word_cnt > 0) 1733 { 1734 sprintf (one_inst_str, "$%d, %s", word_cnt, reg_names[start_reg]); 1735 if (print_ra) 1736 strcat (one_inst_str, ", ra"); 1737 } 1738 else 1739 strcat (one_inst_str, "ra"); 1740 1741 if (push_or_pop == 1) 1742 { 1743 /* Pop instruction. */ 1744 if (print_ra && !cr16_interrupt_function_p () 1745 && !crtl->calls_eh_return) 1746 /* Print popret if RA is saved and its not a interrupt 1747 function. */ 1748 strcpy (temp_str, "\n\tpopret\t"); 1749 else 1750 strcpy (temp_str, "\n\tpop\t"); 1751 1752 strcat (temp_str, one_inst_str); 1753 1754 /* Add the pop instruction list. */ 1755 strcat (return_str, temp_str); 1756 } 1757 else 1758 { 1759 /* Push instruction. */ 1760 strcpy (temp_str, "\n\tpush\t"); 1761 strcat (temp_str, one_inst_str); 1762 1763 /* We need to reverse the order of the instructions if there 1764 are more than one. (since the pop will not be reversed in 1765 the epilogue. */ 1766 strcat (temp_str, return_str); 1767 strcpy (return_str, temp_str); 1768 } 1769 } 1770 1771 if (push_or_pop == 1) 1772 { 1773 /* POP. */ 1774 if (cr16_interrupt_function_p ()) 1775 strcat (return_str, "\n\tretx\n"); 1776 else if (crtl->calls_eh_return) 1777 { 1778 /* Add stack adjustment before returning to exception handler 1779 NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */ 1780 strcat (return_str, "\n\taddd\t (r5, r4), (sp)\t\n"); 1781 strcat (return_str, "\n\tjump\t (ra)\n"); 1782 1783 /* But before anything else, undo the adjustment addition done in 1784 cr16_expand_epilogue (). */ 1785 strcpy (temp_str, "\n\tsubd\t (r5, r4), (sp)\t\n"); 1786 strcat (temp_str, return_str); 1787 strcpy (return_str, temp_str); 1788 } 1789 else if (!FUNC_IS_NORETURN_P (current_function_decl) 1790 && !(current_frame_info.save_regs[RETURN_ADDRESS_REGNUM])) 1791 strcat (return_str, "\n\tjump\t (ra)\n"); 1792 } 1793 1794 /* Skip the newline and the tab in the start of return_str. */ 1795 return_str += 2; 1796 return return_str; 1797 } 1798 1799 1800 /* Generate DWARF2 annotation for multi-push instruction. */ 1801 static void 1802 cr16_create_dwarf_for_multi_push (rtx insn) 1803 { 1804 rtx dwarf, reg, tmp; 1805 int i, j, from, to, word_cnt, dwarf_par_index, inc; 1806 enum machine_mode mode; 1807 int num_regs = 0, offset = 0, split_here = 0, total_push_bytes = 0; 1808 1809 for (i = 0; i <= current_frame_info.last_reg_to_save; ++i) 1810 { 1811 if (current_frame_info.save_regs[i]) 1812 { 1813 ++num_regs; 1814 if (i < CR16_FIRST_DWORD_REGISTER) 1815 total_push_bytes += 2; 1816 else 1817 total_push_bytes += 4; 1818 } 1819 } 1820 1821 if (!num_regs) 1822 return; 1823 1824 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1)); 1825 dwarf_par_index = num_regs; 1826 1827 from = current_frame_info.last_reg_to_save + 1; 1828 to = current_frame_info.last_reg_to_save; 1829 word_cnt = 0; 1830 1831 for (i = current_frame_info.last_reg_to_save; i >= 0;) 1832 { 1833 if (!current_frame_info.save_regs[i] || 0 == i || split_here) 1834 { 1835 /* This block of regs is pushed in one instruction. */ 1836 if (0 == i && current_frame_info.save_regs[i]) 1837 from = 0; 1838 1839 for (j = to; j >= from; --j) 1840 { 1841 if (j < CR16_FIRST_DWORD_REGISTER) 1842 { 1843 mode = HImode; 1844 inc = 1; 1845 } 1846 else 1847 { 1848 mode = SImode; 1849 inc = 2; 1850 } 1851 reg = gen_rtx_REG (mode, j); 1852 offset += 2 * inc; 1853 tmp = gen_rtx_SET (VOIDmode, 1854 gen_frame_mem (mode, 1855 plus_constant 1856 (Pmode, stack_pointer_rtx, 1857 total_push_bytes - offset)), 1858 reg); 1859 RTX_FRAME_RELATED_P (tmp) = 1; 1860 XVECEXP (dwarf, 0, dwarf_par_index--) = tmp; 1861 } 1862 from = i; 1863 to = --i; 1864 split_here = 0; 1865 word_cnt = 0; 1866 continue; 1867 } 1868 1869 if (i != RETURN_ADDRESS_REGNUM) 1870 { 1871 inc = (i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2; 1872 if (word_cnt + inc >= MAX_COUNT || FRAME_POINTER_REGNUM == i) 1873 { 1874 split_here = 1; 1875 from = i; 1876 continue; 1877 } 1878 word_cnt += inc; 1879 } 1880 1881 from = i--; 1882 } 1883 1884 tmp = gen_rtx_SET (SImode, stack_pointer_rtx, 1885 gen_rtx_PLUS (SImode, stack_pointer_rtx, 1886 GEN_INT (-offset))); 1887 RTX_FRAME_RELATED_P (tmp) = 1; 1888 XVECEXP (dwarf, 0, 0) = tmp; 1889 1890 add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); 1891 } 1892 1893 /* 1894 CompactRISC CR16 Architecture stack layout: 1895 1896 0 +--------------------- 1897 | 1898 . 1899 . 1900 | 1901 +==================== Sp (x) = Ap (x+1) 1902 A | Args for functions 1903 | | called by X and Dynamically 1904 | | Dynamic allocations allocated and 1905 | | (alloca, variable deallocated 1906 Stack | length arrays). 1907 grows +-------------------- Fp (x) 1908 down| | Local variables of X 1909 ward| +-------------------- 1910 | | Regs saved for X-1 1911 | +==================== Sp (x-1) = Ap (x) 1912 | Args for func X 1913 | pushed by X-1 1914 +-------------------- Fp (x-1) 1915 | 1916 | 1917 V 1918 */ 1919 void 1920 cr16_expand_prologue (void) 1921 { 1922 rtx insn; 1923 1924 cr16_compute_frame (); 1925 cr16_compute_save_regs (); 1926 1927 /* If there is no need in push and adjustment to sp, return. */ 1928 if ((current_frame_info.total_size + current_frame_info.reg_size) == 0) 1929 return; 1930 1931 if (current_frame_info.last_reg_to_save != -1) 1932 { 1933 /* If there are registers to push. */ 1934 insn = emit_insn (gen_push_for_prologue 1935 (GEN_INT (current_frame_info.reg_size))); 1936 cr16_create_dwarf_for_multi_push (insn); 1937 RTX_FRAME_RELATED_P (insn) = 1; 1938 } 1939 1940 1941 if (current_frame_info.total_size > 0) 1942 { 1943 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 1944 GEN_INT (-current_frame_info.total_size))); 1945 RTX_FRAME_RELATED_P (insn) = 1; 1946 } 1947 1948 if (frame_pointer_needed) 1949 { 1950 /* Initialize the frame pointer with the value of the stack pointer 1951 pointing now to the locals. */ 1952 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); 1953 } 1954 } 1955 1956 /* Generate insn that updates the stack for local variables and padding 1957 for registers we save. - Generate the appropriate return insn. */ 1958 void 1959 cr16_expand_epilogue (void) 1960 { 1961 rtx insn; 1962 1963 /* Nonzero if we need to return and pop only RA. This will generate a 1964 different insn. This differentiate is for the peepholes for call as 1965 last statement in function. */ 1966 int only_popret_RA = (current_frame_info.save_regs[RETURN_ADDRESS_REGNUM] 1967 && (current_frame_info.reg_size 1968 == CR16_UNITS_PER_DWORD)); 1969 1970 if (frame_pointer_needed) 1971 { 1972 /* Restore the stack pointer with the frame pointers value. */ 1973 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); 1974 } 1975 1976 if (current_frame_info.total_size > 0) 1977 { 1978 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 1979 GEN_INT (current_frame_info.total_size))); 1980 RTX_FRAME_RELATED_P (insn) = 1; 1981 } 1982 1983 if (crtl->calls_eh_return) 1984 { 1985 /* Add this here so that (r5, r4) is actually loaded with the adjustment 1986 value; otherwise, the load might be optimized away... 1987 NOTE: remember to subtract the adjustment before popping the regs 1988 and add it back before returning. */ 1989 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 1990 EH_RETURN_STACKADJ_RTX)); 1991 } 1992 1993 if (cr16_interrupt_function_p ()) 1994 { 1995 insn = emit_jump_insn (gen_interrupt_return ()); 1996 RTX_FRAME_RELATED_P (insn) = 1; 1997 } 1998 else if (crtl->calls_eh_return) 1999 { 2000 /* Special case, pop what's necessary, adjust SP and jump to (RA). */ 2001 insn = emit_jump_insn (gen_pop_and_popret_return 2002 (GEN_INT (current_frame_info.reg_size))); 2003 RTX_FRAME_RELATED_P (insn) = 1; 2004 } 2005 else if (current_frame_info.last_reg_to_save == -1) 2006 /* Nothing to pop. */ 2007 /* Don't output jump for interrupt routine, only retx. */ 2008 emit_jump_insn (gen_jump_return ()); 2009 else if (only_popret_RA) 2010 { 2011 insn = emit_jump_insn (gen_popret_RA_return ()); 2012 RTX_FRAME_RELATED_P (insn) = 1; 2013 } 2014 else 2015 { 2016 insn = emit_jump_insn (gen_pop_and_popret_return 2017 (GEN_INT (current_frame_info.reg_size))); 2018 RTX_FRAME_RELATED_P (insn) = 1; 2019 } 2020 } 2021 2022 /* Implements FRAME_POINTER_REQUIRED. */ 2023 static bool 2024 cr16_frame_pointer_required (void) 2025 { 2026 return (cfun->calls_alloca || crtl->calls_eh_return 2027 || cfun->has_nonlocal_label || crtl->calls_eh_return); 2028 } 2029 2030 static bool 2031 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) 2032 { 2033 return (to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true); 2034 } 2035 2036 2037 /* A C compound statement that attempts to replace X with 2038 a valid memory address for an operand of mode MODE. WIN 2039 will be a C statement label elsewhere in the code. 2040 X will always be the result of a call to break_out_memory_refs (), 2041 and OLDX will be the operand that was given to that function to 2042 produce X. 2043 The code generated by this macro should not alter the 2044 substructure of X. If it transforms X into a more legitimate form, 2045 it should assign X (which will always be a C variable) a new value. */ 2046 static rtx 2047 cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED, 2048 enum machine_mode mode ATTRIBUTE_UNUSED) 2049 { 2050 if (flag_pic) 2051 return legitimize_pic_address (orig_x, mode, NULL_RTX); 2052 else 2053 return x; 2054 } 2055 2056 /* Implement TARGET_LEGITIMATE_CONSTANT_P 2057 Nonzero if X is a legitimate constant for an immediate 2058 operand on the target machine. You can assume that X 2059 satisfies CONSTANT_P. In cr16c treat legitimize float 2060 constant as an immediate operand. */ 2061 static bool 2062 cr16_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, 2063 rtx x ATTRIBUTE_UNUSED) 2064 { 2065 return 1; 2066 } 2067 2068 void 2069 notice_update_cc (rtx exp) 2070 { 2071 if (GET_CODE (exp) == SET) 2072 { 2073 /* Jumps do not alter the cc's. */ 2074 if (SET_DEST (exp) == pc_rtx) 2075 return; 2076 2077 /* Moving register or memory into a register: 2078 it doesn't alter the cc's, but it might invalidate 2079 the RTX's which we remember the cc's came from. 2080 (Note that moving a constant 0 or 1 MAY set the cc's). */ 2081 if (REG_P (SET_DEST (exp)) 2082 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM)) 2083 { 2084 return; 2085 } 2086 2087 /* Moving register into memory doesn't alter the cc's. 2088 It may invalidate the RTX's which we remember the cc's came from. */ 2089 if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp))) 2090 { 2091 return; 2092 } 2093 } 2094 2095 CC_STATUS_INIT; 2096 return; 2097 } 2098 2099 static enum machine_mode 2100 cr16_unwind_word_mode (void) 2101 { 2102 return SImode; 2103 } 2104 2105 /* Helper function for md file. This function is used to emit arithmetic 2106 DI instructions. The argument "num" decides which instruction to be 2107 printed. */ 2108 const char * 2109 cr16_emit_add_sub_di (rtx *operands, enum rtx_code code) 2110 { 2111 rtx lo_op[2] ; 2112 rtx hi0_op[2] ; 2113 rtx hi1_op[2] ; 2114 2115 lo_op[0] = gen_lowpart (SImode, operands[0]); 2116 hi0_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 4); 2117 hi1_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 6); 2118 2119 lo_op[1] = gen_lowpart (SImode, operands[2]); 2120 hi0_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 4); 2121 hi1_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 6); 2122 2123 switch (code) 2124 { 2125 case PLUS: 2126 { 2127 output_asm_insn ("addd\t%1, %0", lo_op) ; 2128 output_asm_insn ("addcw\t%1, %0", hi0_op) ; 2129 output_asm_insn ("addcw\t%1, %0", hi1_op) ; 2130 break; 2131 } 2132 case MINUS: 2133 { 2134 output_asm_insn ("subd\t%1, %0", lo_op) ; 2135 output_asm_insn ("subcw\t%1, %0", hi0_op) ; 2136 output_asm_insn ("subcw\t%1, %0", hi1_op) ; 2137 break; 2138 } 2139 default: 2140 break; 2141 } 2142 2143 return ""; 2144 } 2145 2146 2147 /* Helper function for md file. This function is used to emit logical 2148 DI instructions. The argument "num" decides which instruction to be 2149 printed. */ 2150 const char * 2151 cr16_emit_logical_di (rtx *operands, enum rtx_code code) 2152 { 2153 rtx lo_op[2] ; 2154 rtx hi_op[2] ; 2155 2156 lo_op[0] = gen_lowpart (SImode, operands[0]); 2157 hi_op[0] = simplify_gen_subreg (SImode, operands[0], DImode, 4); 2158 2159 lo_op[1] = gen_lowpart (SImode, operands[2]); 2160 hi_op[1] = simplify_gen_subreg (SImode, operands[2], DImode, 4); 2161 2162 switch (code) 2163 { 2164 case AND: 2165 { 2166 output_asm_insn ("andd\t%1, %0", lo_op) ; 2167 output_asm_insn ("andd\t%1, %0", hi_op) ; 2168 return ""; 2169 } 2170 case IOR: 2171 { 2172 output_asm_insn ("ord\t%1, %0", lo_op) ; 2173 output_asm_insn ("ord\t%1, %0", hi_op) ; 2174 return ""; 2175 } 2176 case XOR: 2177 { 2178 output_asm_insn ("xord\t%1, %0", lo_op) ; 2179 output_asm_insn ("xord\t%1, %0", hi_op) ; 2180 return ""; 2181 } 2182 default: 2183 break; 2184 } 2185 2186 return ""; 2187 } 2188 2189 /* Initialize 'targetm' variable which contains pointers to functions 2190 and data relating to the target machine. */ 2191 2192 struct gcc_target targetm = TARGET_INITIALIZER; 2193