Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/frv/frv.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, | 1 /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, |
2 2008, 2009 Free Software Foundation, Inc. | 2 2008, 2009, 2010 Free Software Foundation, Inc. |
3 Contributed by Red Hat, Inc. | 3 Contributed by Red Hat, Inc. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
37 #include "expr.h" | 37 #include "expr.h" |
38 #include "obstack.h" | 38 #include "obstack.h" |
39 #include "except.h" | 39 #include "except.h" |
40 #include "function.h" | 40 #include "function.h" |
41 #include "optabs.h" | 41 #include "optabs.h" |
42 #include "toplev.h" | 42 #include "diagnostic-core.h" |
43 #include "basic-block.h" | 43 #include "basic-block.h" |
44 #include "tm_p.h" | 44 #include "tm_p.h" |
45 #include "ggc.h" | 45 #include "ggc.h" |
46 #include <ctype.h> | |
47 #include "target.h" | 46 #include "target.h" |
48 #include "target-def.h" | 47 #include "target-def.h" |
49 #include "targhooks.h" | 48 #include "targhooks.h" |
50 #include "integrate.h" | 49 #include "integrate.h" |
51 #include "langhooks.h" | 50 #include "langhooks.h" |
106 static GTY(()) rtx frv_nops[NUM_NOP_PATTERNS]; | 105 static GTY(()) rtx frv_nops[NUM_NOP_PATTERNS]; |
107 | 106 |
108 /* The number of nop instructions in frv_nops[]. */ | 107 /* The number of nop instructions in frv_nops[]. */ |
109 static unsigned int frv_num_nops; | 108 static unsigned int frv_num_nops; |
110 | 109 |
110 /* The type of access. FRV_IO_UNKNOWN means the access can be either | |
111 a read or a write. */ | |
112 enum frv_io_type { FRV_IO_UNKNOWN, FRV_IO_READ, FRV_IO_WRITE }; | |
113 | |
111 /* Information about one __builtin_read or __builtin_write access, or | 114 /* Information about one __builtin_read or __builtin_write access, or |
112 the combination of several such accesses. The most general value | 115 the combination of several such accesses. The most general value |
113 is all-zeros (an unknown access to an unknown address). */ | 116 is all-zeros (an unknown access to an unknown address). */ |
114 struct frv_io { | 117 struct frv_io { |
115 /* The type of access. FRV_IO_UNKNOWN means the access can be either | 118 enum frv_io_type type; |
116 a read or a write. */ | |
117 enum { FRV_IO_UNKNOWN, FRV_IO_READ, FRV_IO_WRITE } type; | |
118 | 119 |
119 /* The constant address being accessed, or zero if not known. */ | 120 /* The constant address being accessed, or zero if not known. */ |
120 HOST_WIDE_INT const_address; | 121 HOST_WIDE_INT const_address; |
121 | 122 |
122 /* The run-time address, as used in operand 0 of the membar pattern. */ | 123 /* The run-time address, as used in operand 0 of the membar pattern. */ |
249 static /* GTY(()) */ frv_ifcvt_t frv_ifcvt; | 250 static /* GTY(()) */ frv_ifcvt_t frv_ifcvt; |
250 | 251 |
251 /* Map register number to smallest register class. */ | 252 /* Map register number to smallest register class. */ |
252 enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER]; | 253 enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER]; |
253 | 254 |
254 /* Map class letter into register class. */ | |
255 enum reg_class reg_class_from_letter[256]; | |
256 | |
257 /* Cached value of frv_stack_info. */ | 255 /* Cached value of frv_stack_info. */ |
258 static frv_stack_t *frv_stack_cache = (frv_stack_t *)0; | 256 static frv_stack_t *frv_stack_cache = (frv_stack_t *)0; |
259 | 257 |
260 /* -mcpu= support */ | 258 /* -mcpu= support */ |
261 frv_cpu_t frv_cpu_type = CPU_TYPE; /* value of -mcpu= */ | 259 frv_cpu_t frv_cpu_type = CPU_TYPE; /* value of -mcpu= */ |
262 | 260 |
263 /* Forward references */ | 261 /* Forward references */ |
264 | 262 |
265 static bool frv_handle_option (size_t, const char *, int); | 263 static bool frv_handle_option (size_t, const char *, int); |
264 static void frv_option_override (void); | |
266 static bool frv_legitimate_address_p (enum machine_mode, rtx, bool); | 265 static bool frv_legitimate_address_p (enum machine_mode, rtx, bool); |
267 static int frv_default_flags_for_cpu (void); | 266 static int frv_default_flags_for_cpu (void); |
268 static int frv_string_begins_with (const_tree, const char *); | 267 static int frv_string_begins_with (const_tree, const char *); |
269 static FRV_INLINE bool frv_small_data_reloc_p (rtx, int); | 268 static FRV_INLINE bool frv_small_data_reloc_p (rtx, int); |
269 static void frv_print_operand (FILE *, rtx, int); | |
270 static void frv_print_operand_address (FILE *, rtx); | |
271 static bool frv_print_operand_punct_valid_p (unsigned char code); | |
270 static void frv_print_operand_memory_reference_reg | 272 static void frv_print_operand_memory_reference_reg |
271 (FILE *, rtx); | 273 (FILE *, rtx); |
272 static void frv_print_operand_memory_reference (FILE *, rtx, int); | 274 static void frv_print_operand_memory_reference (FILE *, rtx, int); |
273 static int frv_print_operand_jump_hint (rtx); | 275 static int frv_print_operand_jump_hint (rtx); |
274 static const char *comparison_string (enum rtx_code, rtx); | 276 static const char *comparison_string (enum rtx_code, rtx); |
365 enum machine_mode, | 367 enum machine_mode, |
366 tree, int *, int); | 368 tree, int *, int); |
367 static rtx frv_expand_builtin_saveregs (void); | 369 static rtx frv_expand_builtin_saveregs (void); |
368 static void frv_expand_builtin_va_start (tree, rtx); | 370 static void frv_expand_builtin_va_start (tree, rtx); |
369 static bool frv_rtx_costs (rtx, int, int, int*, bool); | 371 static bool frv_rtx_costs (rtx, int, int, int*, bool); |
372 static int frv_register_move_cost (enum machine_mode, | |
373 reg_class_t, reg_class_t); | |
374 static int frv_memory_move_cost (enum machine_mode, | |
375 reg_class_t, bool); | |
370 static void frv_asm_out_constructor (rtx, int); | 376 static void frv_asm_out_constructor (rtx, int); |
371 static void frv_asm_out_destructor (rtx, int); | 377 static void frv_asm_out_destructor (rtx, int); |
372 static bool frv_function_symbol_referenced_p (rtx); | 378 static bool frv_function_symbol_referenced_p (rtx); |
373 static bool frv_cannot_force_const_mem (rtx); | 379 static bool frv_cannot_force_const_mem (rtx); |
374 static const char *unspec_got_name (int); | 380 static const char *unspec_got_name (int); |
377 static bool frv_function_ok_for_sibcall (tree, tree); | 383 static bool frv_function_ok_for_sibcall (tree, tree); |
378 static rtx frv_struct_value_rtx (tree, int); | 384 static rtx frv_struct_value_rtx (tree, int); |
379 static bool frv_must_pass_in_stack (enum machine_mode mode, const_tree type); | 385 static bool frv_must_pass_in_stack (enum machine_mode mode, const_tree type); |
380 static int frv_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, | 386 static int frv_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, |
381 tree, bool); | 387 tree, bool); |
388 static rtx frv_function_arg (CUMULATIVE_ARGS *, enum machine_mode, | |
389 const_tree, bool); | |
390 static rtx frv_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, | |
391 const_tree, bool); | |
392 static void frv_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, | |
393 const_tree, bool); | |
394 static unsigned int frv_function_arg_boundary (enum machine_mode, | |
395 const_tree); | |
382 static void frv_output_dwarf_dtprel (FILE *, int, rtx) | 396 static void frv_output_dwarf_dtprel (FILE *, int, rtx) |
383 ATTRIBUTE_UNUSED; | 397 ATTRIBUTE_UNUSED; |
384 static bool frv_secondary_reload (bool, rtx, enum reg_class, | 398 static reg_class_t frv_secondary_reload (bool, rtx, reg_class_t, |
385 enum machine_mode, | 399 enum machine_mode, |
386 secondary_reload_info *); | 400 secondary_reload_info *); |
387 static bool frv_frame_pointer_required (void); | 401 static bool frv_frame_pointer_required (void); |
388 static bool frv_can_eliminate (const int, const int); | 402 static bool frv_can_eliminate (const int, const int); |
403 static void frv_conditional_register_usage (void); | |
389 static void frv_trampoline_init (rtx, tree, rtx); | 404 static void frv_trampoline_init (rtx, tree, rtx); |
405 static bool frv_class_likely_spilled_p (reg_class_t); | |
406 | |
407 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
408 static const struct default_options frv_option_optimization_table[] = | |
409 { | |
410 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
411 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
412 }; | |
390 | 413 |
391 /* Allow us to easily change the default for -malloc-cc. */ | 414 /* Allow us to easily change the default for -malloc-cc. */ |
392 #ifndef DEFAULT_NO_ALLOC_CC | 415 #ifndef DEFAULT_NO_ALLOC_CC |
393 #define MASK_DEFAULT_ALLOC_CC MASK_ALLOC_CC | 416 #define MASK_DEFAULT_ALLOC_CC MASK_ALLOC_CC |
394 #else | 417 #else |
395 #define MASK_DEFAULT_ALLOC_CC 0 | 418 #define MASK_DEFAULT_ALLOC_CC 0 |
396 #endif | 419 #endif |
397 | 420 |
398 /* Initialize the GCC target structure. */ | 421 /* Initialize the GCC target structure. */ |
422 #undef TARGET_PRINT_OPERAND | |
423 #define TARGET_PRINT_OPERAND frv_print_operand | |
424 #undef TARGET_PRINT_OPERAND_ADDRESS | |
425 #define TARGET_PRINT_OPERAND_ADDRESS frv_print_operand_address | |
426 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P | |
427 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P frv_print_operand_punct_valid_p | |
399 #undef TARGET_ASM_FUNCTION_PROLOGUE | 428 #undef TARGET_ASM_FUNCTION_PROLOGUE |
400 #define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue | 429 #define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue |
401 #undef TARGET_ASM_FUNCTION_EPILOGUE | 430 #undef TARGET_ASM_FUNCTION_EPILOGUE |
402 #define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue | 431 #define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue |
403 #undef TARGET_ASM_INTEGER | 432 #undef TARGET_ASM_INTEGER |
411 | MASK_VLIW_BRANCH \ | 440 | MASK_VLIW_BRANCH \ |
412 | MASK_MULTI_CE \ | 441 | MASK_MULTI_CE \ |
413 | MASK_NESTED_CE) | 442 | MASK_NESTED_CE) |
414 #undef TARGET_HANDLE_OPTION | 443 #undef TARGET_HANDLE_OPTION |
415 #define TARGET_HANDLE_OPTION frv_handle_option | 444 #define TARGET_HANDLE_OPTION frv_handle_option |
445 #undef TARGET_OPTION_OVERRIDE | |
446 #define TARGET_OPTION_OVERRIDE frv_option_override | |
447 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
448 #define TARGET_OPTION_OPTIMIZATION_TABLE frv_option_optimization_table | |
416 #undef TARGET_INIT_BUILTINS | 449 #undef TARGET_INIT_BUILTINS |
417 #define TARGET_INIT_BUILTINS frv_init_builtins | 450 #define TARGET_INIT_BUILTINS frv_init_builtins |
418 #undef TARGET_EXPAND_BUILTIN | 451 #undef TARGET_EXPAND_BUILTIN |
419 #define TARGET_EXPAND_BUILTIN frv_expand_builtin | 452 #define TARGET_EXPAND_BUILTIN frv_expand_builtin |
420 #undef TARGET_INIT_LIBFUNCS | 453 #undef TARGET_INIT_LIBFUNCS |
421 #define TARGET_INIT_LIBFUNCS frv_init_libfuncs | 454 #define TARGET_INIT_LIBFUNCS frv_init_libfuncs |
422 #undef TARGET_IN_SMALL_DATA_P | 455 #undef TARGET_IN_SMALL_DATA_P |
423 #define TARGET_IN_SMALL_DATA_P frv_in_small_data_p | 456 #define TARGET_IN_SMALL_DATA_P frv_in_small_data_p |
457 #undef TARGET_REGISTER_MOVE_COST | |
458 #define TARGET_REGISTER_MOVE_COST frv_register_move_cost | |
459 #undef TARGET_MEMORY_MOVE_COST | |
460 #define TARGET_MEMORY_MOVE_COST frv_memory_move_cost | |
424 #undef TARGET_RTX_COSTS | 461 #undef TARGET_RTX_COSTS |
425 #define TARGET_RTX_COSTS frv_rtx_costs | 462 #define TARGET_RTX_COSTS frv_rtx_costs |
426 #undef TARGET_ASM_CONSTRUCTOR | 463 #undef TARGET_ASM_CONSTRUCTOR |
427 #define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor | 464 #define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor |
428 #undef TARGET_ASM_DESTRUCTOR | 465 #undef TARGET_ASM_DESTRUCTOR |
453 #define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack | 490 #define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack |
454 #undef TARGET_PASS_BY_REFERENCE | 491 #undef TARGET_PASS_BY_REFERENCE |
455 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack | 492 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack |
456 #undef TARGET_ARG_PARTIAL_BYTES | 493 #undef TARGET_ARG_PARTIAL_BYTES |
457 #define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes | 494 #define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes |
495 #undef TARGET_FUNCTION_ARG | |
496 #define TARGET_FUNCTION_ARG frv_function_arg | |
497 #undef TARGET_FUNCTION_INCOMING_ARG | |
498 #define TARGET_FUNCTION_INCOMING_ARG frv_function_incoming_arg | |
499 #undef TARGET_FUNCTION_ARG_ADVANCE | |
500 #define TARGET_FUNCTION_ARG_ADVANCE frv_function_arg_advance | |
501 #undef TARGET_FUNCTION_ARG_BOUNDARY | |
502 #define TARGET_FUNCTION_ARG_BOUNDARY frv_function_arg_boundary | |
458 | 503 |
459 #undef TARGET_EXPAND_BUILTIN_SAVEREGS | 504 #undef TARGET_EXPAND_BUILTIN_SAVEREGS |
460 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs | 505 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs |
461 #undef TARGET_SETUP_INCOMING_VARARGS | 506 #undef TARGET_SETUP_INCOMING_VARARGS |
462 #define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs | 507 #define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs |
469 #if HAVE_AS_TLS | 514 #if HAVE_AS_TLS |
470 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL | 515 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL |
471 #define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel | 516 #define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel |
472 #endif | 517 #endif |
473 | 518 |
519 #undef TARGET_CLASS_LIKELY_SPILLED_P | |
520 #define TARGET_CLASS_LIKELY_SPILLED_P frv_class_likely_spilled_p | |
521 | |
474 #undef TARGET_SECONDARY_RELOAD | 522 #undef TARGET_SECONDARY_RELOAD |
475 #define TARGET_SECONDARY_RELOAD frv_secondary_reload | 523 #define TARGET_SECONDARY_RELOAD frv_secondary_reload |
476 | 524 |
477 #undef TARGET_LEGITIMATE_ADDRESS_P | 525 #undef TARGET_LEGITIMATE_ADDRESS_P |
478 #define TARGET_LEGITIMATE_ADDRESS_P frv_legitimate_address_p | 526 #define TARGET_LEGITIMATE_ADDRESS_P frv_legitimate_address_p |
480 #undef TARGET_FRAME_POINTER_REQUIRED | 528 #undef TARGET_FRAME_POINTER_REQUIRED |
481 #define TARGET_FRAME_POINTER_REQUIRED frv_frame_pointer_required | 529 #define TARGET_FRAME_POINTER_REQUIRED frv_frame_pointer_required |
482 | 530 |
483 #undef TARGET_CAN_ELIMINATE | 531 #undef TARGET_CAN_ELIMINATE |
484 #define TARGET_CAN_ELIMINATE frv_can_eliminate | 532 #define TARGET_CAN_ELIMINATE frv_can_eliminate |
533 | |
534 #undef TARGET_CONDITIONAL_REGISTER_USAGE | |
535 #define TARGET_CONDITIONAL_REGISTER_USAGE frv_conditional_register_usage | |
485 | 536 |
486 #undef TARGET_TRAMPOLINE_INIT | 537 #undef TARGET_TRAMPOLINE_INIT |
487 #define TARGET_TRAMPOLINE_INIT frv_trampoline_init | 538 #define TARGET_TRAMPOLINE_INIT frv_trampoline_init |
488 | 539 |
489 #undef TARGET_FUNCTION_VALUE | 540 #undef TARGET_FUNCTION_VALUE |
542 if (unspec->offset == 0) | 593 if (unspec->offset == 0) |
543 return true; | 594 return true; |
544 | 595 |
545 if (frv_small_data_reloc_p (unspec->symbol, unspec->reloc) | 596 if (frv_small_data_reloc_p (unspec->symbol, unspec->reloc) |
546 && unspec->offset > 0 | 597 && unspec->offset > 0 |
547 && (unsigned HOST_WIDE_INT) unspec->offset < g_switch_value) | 598 && unspec->offset < g_switch_value) |
548 return true; | 599 return true; |
549 } | 600 } |
550 } | 601 } |
551 return false; | 602 return false; |
552 } | 603 } |
640 default: | 691 default: |
641 gcc_unreachable (); | 692 gcc_unreachable (); |
642 } | 693 } |
643 } | 694 } |
644 | 695 |
645 /* Sometimes certain combinations of command options do not make | 696 /* Implement TARGET_OPTION_OVERRIDE. */ |
646 sense on a particular target machine. You can define a macro | 697 |
647 `OVERRIDE_OPTIONS' to take account of this. This macro, if | 698 static void |
648 defined, is executed once just after all the command options have | 699 frv_option_override (void) |
649 been parsed. | |
650 | |
651 Don't use this macro to turn on various extra optimizations for | |
652 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */ | |
653 | |
654 void | |
655 frv_override_options (void) | |
656 { | 700 { |
657 int regno; | 701 int regno; |
658 unsigned int i; | 702 unsigned int i; |
659 | 703 |
660 target_flags |= (frv_default_flags_for_cpu () & ~target_flags_explicit); | 704 target_flags |= (frv_default_flags_for_cpu () & ~target_flags_explicit); |
664 if (TARGET_LIBPIC) | 708 if (TARGET_LIBPIC) |
665 { | 709 { |
666 if (!flag_pic) /* -fPIC */ | 710 if (!flag_pic) /* -fPIC */ |
667 flag_pic = 2; | 711 flag_pic = 2; |
668 | 712 |
669 if (! g_switch_set) /* -G0 */ | 713 if (!global_options_set.x_g_switch_value) /* -G0 */ |
670 { | 714 { |
671 g_switch_set = 1; | |
672 g_switch_value = 0; | 715 g_switch_value = 0; |
673 } | 716 } |
674 } | 717 } |
675 | 718 |
676 /* A C expression whose value is a register class containing hard | 719 /* A C expression whose value is a register class containing hard |
758 | 801 |
759 regno_reg_class[regno] = rclass; | 802 regno_reg_class[regno] = rclass; |
760 } | 803 } |
761 | 804 |
762 /* Check for small data option */ | 805 /* Check for small data option */ |
763 if (!g_switch_set) | 806 if (!global_options_set.x_g_switch_value && !TARGET_LIBPIC) |
764 g_switch_value = SDATA_DEFAULT_SIZE; | 807 g_switch_value = SDATA_DEFAULT_SIZE; |
765 | |
766 /* A C expression which defines the machine-dependent operand | |
767 constraint letters for register classes. If CHAR is such a | |
768 letter, the value should be the register class corresponding to | |
769 it. Otherwise, the value should be `NO_REGS'. The register | |
770 letter `r', corresponding to class `GENERAL_REGS', will not be | |
771 passed to this macro; you do not need to handle it. | |
772 | |
773 The following letters are unavailable, due to being used as | |
774 constraints: | |
775 '0'..'9' | |
776 '<', '>' | |
777 'E', 'F', 'G', 'H' | |
778 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' | |
779 'Q', 'R', 'S', 'T', 'U' | |
780 'V', 'X' | |
781 'g', 'i', 'm', 'n', 'o', 'p', 'r', 's' */ | |
782 | |
783 for (i = 0; i < 256; i++) | |
784 reg_class_from_letter[i] = NO_REGS; | |
785 | |
786 reg_class_from_letter['a'] = ACC_REGS; | |
787 reg_class_from_letter['b'] = EVEN_ACC_REGS; | |
788 reg_class_from_letter['c'] = CC_REGS; | |
789 reg_class_from_letter['d'] = GPR_REGS; | |
790 reg_class_from_letter['e'] = EVEN_REGS; | |
791 reg_class_from_letter['f'] = FPR_REGS; | |
792 reg_class_from_letter['h'] = FEVEN_REGS; | |
793 reg_class_from_letter['l'] = LR_REG; | |
794 reg_class_from_letter['q'] = QUAD_REGS; | |
795 reg_class_from_letter['t'] = ICC_REGS; | |
796 reg_class_from_letter['u'] = FCC_REGS; | |
797 reg_class_from_letter['v'] = ICR_REGS; | |
798 reg_class_from_letter['w'] = FCR_REGS; | |
799 reg_class_from_letter['x'] = QUAD_FPR_REGS; | |
800 reg_class_from_letter['y'] = LCR_REG; | |
801 reg_class_from_letter['z'] = SPR_REGS; | |
802 reg_class_from_letter['A'] = QUAD_ACC_REGS; | |
803 reg_class_from_letter['B'] = ACCG_REGS; | |
804 reg_class_from_letter['C'] = CR_REGS; | |
805 reg_class_from_letter['W'] = FDPIC_CALL_REGS; /* gp14+15 */ | |
806 reg_class_from_letter['Z'] = FDPIC_REGS; /* gp15 */ | |
807 | 808 |
808 /* There is no single unaligned SI op for PIC code. Sometimes we | 809 /* There is no single unaligned SI op for PIC code. Sometimes we |
809 need to use ".4byte" and sometimes we need to use ".picptr". | 810 need to use ".4byte" and sometimes we need to use ".picptr". |
810 See frv_assemble_integer for details. */ | 811 See frv_assemble_integer for details. */ |
811 if (flag_pic || TARGET_FDPIC) | 812 if (flag_pic || TARGET_FDPIC) |
825 | 826 |
826 init_machine_status = frv_init_machine_status; | 827 init_machine_status = frv_init_machine_status; |
827 } | 828 } |
828 | 829 |
829 | 830 |
830 /* Some machines may desire to change what optimizations are performed for | |
831 various optimization levels. This macro, if defined, is executed once just | |
832 after the optimization level is determined and before the remainder of the | |
833 command options have been parsed. Values set in this macro are used as the | |
834 default values for the other command line options. | |
835 | |
836 LEVEL is the optimization level specified; 2 if `-O2' is specified, 1 if | |
837 `-O' is specified, and 0 if neither is specified. | |
838 | |
839 SIZE is nonzero if `-Os' is specified, 0 otherwise. | |
840 | |
841 You should not use this macro to change options that are not | |
842 machine-specific. These should uniformly selected by the same optimization | |
843 level on all supported machines. Use this macro to enable machine-specific | |
844 optimizations. | |
845 | |
846 *Do not examine `write_symbols' in this macro!* The debugging options are | |
847 *not supposed to alter the generated code. */ | |
848 | |
849 /* On the FRV, possibly disable VLIW packing which is done by the 2nd | |
850 scheduling pass at the current time. */ | |
851 void | |
852 frv_optimization_options (int level, int size ATTRIBUTE_UNUSED) | |
853 { | |
854 if (level >= 2) | |
855 { | |
856 #ifdef DISABLE_SCHED2 | |
857 flag_schedule_insns_after_reload = 0; | |
858 #endif | |
859 #ifdef ENABLE_RCSP | |
860 flag_rcsp = 1; | |
861 #endif | |
862 } | |
863 } | |
864 | |
865 | |
866 /* Return true if NAME (a STRING_CST node) begins with PREFIX. */ | 831 /* Return true if NAME (a STRING_CST node) begins with PREFIX. */ |
867 | 832 |
868 static int | 833 static int |
869 frv_string_begins_with (const_tree name, const char *prefix) | 834 frv_string_begins_with (const_tree name, const char *prefix) |
870 { | 835 { |
893 (However, if this class is not included in `GENERAL_REGS' and all of the | 858 (However, if this class is not included in `GENERAL_REGS' and all of the |
894 insn patterns whose constraints permit this class are controlled by target | 859 insn patterns whose constraints permit this class are controlled by target |
895 switches, then GCC will automatically avoid using these registers when the | 860 switches, then GCC will automatically avoid using these registers when the |
896 target switches are opposed to them.) */ | 861 target switches are opposed to them.) */ |
897 | 862 |
898 void | 863 static void |
899 frv_conditional_register_usage (void) | 864 frv_conditional_register_usage (void) |
900 { | 865 { |
901 int i; | 866 int i; |
902 | 867 |
903 for (i = GPR_FIRST + NUM_GPRS; i <= GPR_LAST; i++) | 868 for (i = GPR_FIRST + NUM_GPRS; i <= GPR_LAST; i++) |
1170 else | 1135 else |
1171 { | 1136 { |
1172 /* Find the last argument, and see if it is __builtin_va_alist. */ | 1137 /* Find the last argument, and see if it is __builtin_va_alist. */ |
1173 for (cur_arg = DECL_ARGUMENTS (fndecl); cur_arg != (tree)0; cur_arg = next_arg) | 1138 for (cur_arg = DECL_ARGUMENTS (fndecl); cur_arg != (tree)0; cur_arg = next_arg) |
1174 { | 1139 { |
1175 next_arg = TREE_CHAIN (cur_arg); | 1140 next_arg = DECL_CHAIN (cur_arg); |
1176 if (next_arg == (tree)0) | 1141 if (next_arg == (tree)0) |
1177 { | 1142 { |
1178 if (DECL_NAME (cur_arg) | 1143 if (DECL_NAME (cur_arg) |
1179 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), "__builtin_va_alist")) | 1144 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), "__builtin_va_alist")) |
1180 varargs_p = 1; | 1145 varargs_p = 1; |
1612 it loads the constant into register OFFSET_REGNO and returns that. */ | 1577 it loads the constant into register OFFSET_REGNO and returns that. */ |
1613 static rtx | 1578 static rtx |
1614 frv_frame_offset_rtx (int offset) | 1579 frv_frame_offset_rtx (int offset) |
1615 { | 1580 { |
1616 rtx offset_rtx = GEN_INT (offset); | 1581 rtx offset_rtx = GEN_INT (offset); |
1617 if (IN_RANGE_P (offset, -2048, 2047)) | 1582 if (IN_RANGE (offset, -2048, 2047)) |
1618 return offset_rtx; | 1583 return offset_rtx; |
1619 else | 1584 else |
1620 { | 1585 { |
1621 rtx reg_rtx = gen_rtx_REG (SImode, OFFSET_REGNO); | 1586 rtx reg_rtx = gen_rtx_REG (SImode, OFFSET_REGNO); |
1622 if (IN_RANGE_P (offset, -32768, 32767)) | 1587 if (IN_RANGE (offset, -32768, 32767)) |
1623 emit_insn (gen_movsi (reg_rtx, offset_rtx)); | 1588 emit_insn (gen_movsi (reg_rtx, offset_rtx)); |
1624 else | 1589 else |
1625 { | 1590 { |
1626 emit_insn (gen_movsi_high (reg_rtx, offset_rtx)); | 1591 emit_insn (gen_movsi_high (reg_rtx, offset_rtx)); |
1627 emit_insn (gen_movsi_lo_sum (reg_rtx, offset_rtx)); | 1592 emit_insn (gen_movsi_lo_sum (reg_rtx, offset_rtx)); |
1716 && GET_CODE (XEXP (mem, 0)) == PLUS | 1681 && GET_CODE (XEXP (mem, 0)) == PLUS |
1717 && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG | 1682 && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG |
1718 && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG) | 1683 && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG) |
1719 { | 1684 { |
1720 rtx temp = gen_rtx_REG (SImode, TEMP_REGNO); | 1685 rtx temp = gen_rtx_REG (SImode, TEMP_REGNO); |
1721 rtx insn = emit_move_insn (temp, | 1686 |
1722 gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0), | 1687 emit_move_insn (temp, |
1723 XEXP (XEXP (mem, 0), 1))); | 1688 gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0), |
1689 XEXP (XEXP (mem, 0), 1))); | |
1724 mem = gen_rtx_MEM (DImode, temp); | 1690 mem = gen_rtx_MEM (DImode, temp); |
1725 } | 1691 } |
1726 emit_insn (gen_rtx_SET (VOIDmode, reg, mem)); | 1692 emit_insn (gen_rtx_SET (VOIDmode, reg, mem)); |
1727 } | 1693 } |
1728 emit_use (reg); | 1694 emit_use (reg); |
1749 if (GET_CODE (XEXP (mem, 0)) == PLUS | 1715 if (GET_CODE (XEXP (mem, 0)) == PLUS |
1750 && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG | 1716 && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG |
1751 && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG) | 1717 && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG) |
1752 { | 1718 { |
1753 rtx temp = gen_rtx_REG (SImode, TEMP_REGNO); | 1719 rtx temp = gen_rtx_REG (SImode, TEMP_REGNO); |
1754 rtx insn = emit_move_insn (temp, | 1720 emit_move_insn (temp, |
1755 gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0), | 1721 gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0), |
1756 XEXP (XEXP (mem, 0), 1))); | 1722 XEXP (XEXP (mem, 0), 1))); |
1757 mem = gen_rtx_MEM (DImode, temp); | 1723 mem = gen_rtx_MEM (DImode, temp); |
1758 } | 1724 } |
1759 | 1725 |
1760 frv_frame_insn (gen_rtx_SET (Pmode, mem, reg), | 1726 frv_frame_insn (gen_rtx_SET (Pmode, mem, reg), |
1761 gen_rtx_PARALLEL (VOIDmode, | 1727 gen_rtx_PARALLEL (VOIDmode, |
1856 /* Set up ACCESSOR for accessing region B above. If the frame pointer | 1822 /* Set up ACCESSOR for accessing region B above. If the frame pointer |
1857 isn't used, the same method will serve for C. */ | 1823 isn't used, the same method will serve for C. */ |
1858 accessor.op = FRV_STORE; | 1824 accessor.op = FRV_STORE; |
1859 if (frame_pointer_needed && info->total_size > 2048) | 1825 if (frame_pointer_needed && info->total_size > 2048) |
1860 { | 1826 { |
1861 rtx insn; | |
1862 | |
1863 accessor.base = gen_rtx_REG (Pmode, OLD_SP_REGNO); | 1827 accessor.base = gen_rtx_REG (Pmode, OLD_SP_REGNO); |
1864 accessor.base_offset = info->total_size; | 1828 accessor.base_offset = info->total_size; |
1865 insn = emit_insn (gen_movsi (accessor.base, sp)); | 1829 emit_insn (gen_movsi (accessor.base, sp)); |
1866 } | 1830 } |
1867 else | 1831 else |
1868 { | 1832 { |
1869 accessor.base = stack_pointer_rtx; | 1833 accessor.base = stack_pointer_rtx; |
1870 accessor.base_offset = 0; | 1834 accessor.base_offset = 0; |
2046 const char *name_arg0 = reg_names[FIRST_ARG_REGNUM]; | 2010 const char *name_arg0 = reg_names[FIRST_ARG_REGNUM]; |
2047 const char *name_jmp = reg_names[JUMP_REGNO]; | 2011 const char *name_jmp = reg_names[JUMP_REGNO]; |
2048 const char *parallel = (frv_issue_rate () > 1 ? ".p" : ""); | 2012 const char *parallel = (frv_issue_rate () > 1 ? ".p" : ""); |
2049 | 2013 |
2050 /* Do the add using an addi if possible. */ | 2014 /* Do the add using an addi if possible. */ |
2051 if (IN_RANGE_P (delta, -2048, 2047)) | 2015 if (IN_RANGE (delta, -2048, 2047)) |
2052 fprintf (file, "\taddi %s,#%d,%s\n", name_arg0, (int) delta, name_arg0); | 2016 fprintf (file, "\taddi %s,#%d,%s\n", name_arg0, (int) delta, name_arg0); |
2053 else | 2017 else |
2054 { | 2018 { |
2055 const char *const name_add = reg_names[TEMP_REGNO]; | 2019 const char *const name_add = reg_names[TEMP_REGNO]; |
2056 fprintf (file, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC "),%s\n", | 2020 fprintf (file, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC "),%s\n", |
2389 rtx align_rtx = operands[3]; | 2353 rtx align_rtx = operands[3]; |
2390 int constp = (GET_CODE (bytes_rtx) == CONST_INT); | 2354 int constp = (GET_CODE (bytes_rtx) == CONST_INT); |
2391 int align; | 2355 int align; |
2392 int bytes; | 2356 int bytes; |
2393 int offset; | 2357 int offset; |
2394 int num_reg; | |
2395 rtx dest_reg; | 2358 rtx dest_reg; |
2396 rtx dest_addr; | 2359 rtx dest_addr; |
2397 rtx dest_mem; | 2360 rtx dest_mem; |
2398 int clear_bytes; | 2361 int clear_bytes; |
2399 enum machine_mode mode; | 2362 enum machine_mode mode; |
2417 return FALSE; | 2380 return FALSE; |
2418 | 2381 |
2419 /* Move the address into a scratch register. */ | 2382 /* Move the address into a scratch register. */ |
2420 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0)); | 2383 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0)); |
2421 | 2384 |
2422 num_reg = offset = 0; | 2385 offset = 0; |
2423 for ( ; bytes > 0; (bytes -= clear_bytes), (offset += clear_bytes)) | 2386 for ( ; bytes > 0; (bytes -= clear_bytes), (offset += clear_bytes)) |
2424 { | 2387 { |
2425 /* Calculate the correct offset for src/dest. */ | 2388 /* Calculate the correct offset for src/dest. */ |
2426 dest_addr = ((offset == 0) | 2389 dest_addr = ((offset == 0) |
2427 ? dest_reg | 2390 ? dest_reg |
2560 plus_constant (base, index * GET_MODE_SIZE (mode))); | 2523 plus_constant (base, index * GET_MODE_SIZE (mode))); |
2561 } | 2524 } |
2562 | 2525 |
2563 | 2526 |
2564 /* Print a memory address as an operand to reference that memory location. */ | 2527 /* Print a memory address as an operand to reference that memory location. */ |
2565 void | 2528 static void |
2566 frv_print_operand_address (FILE * stream, rtx x) | 2529 frv_print_operand_address (FILE * stream, rtx x) |
2567 { | 2530 { |
2568 if (GET_CODE (x) == MEM) | 2531 if (GET_CODE (x) == MEM) |
2569 x = XEXP (x, 0); | 2532 x = XEXP (x, 0); |
2570 | 2533 |
2793 } | 2756 } |
2794 | 2757 |
2795 /* Print an operand to an assembler instruction. | 2758 /* Print an operand to an assembler instruction. |
2796 | 2759 |
2797 `%' followed by a letter and a digit says to output an operand in an | 2760 `%' followed by a letter and a digit says to output an operand in an |
2798 alternate fashion. Four letters have standard, built-in meanings described | 2761 alternate fashion. Four letters have standard, built-in meanings |
2799 below. The machine description macro `PRINT_OPERAND' can define additional | 2762 described below. The hook `TARGET_PRINT_OPERAND' can define |
2800 letters with nonstandard meanings. | 2763 additional letters with nonstandard meanings. |
2801 | 2764 |
2802 `%cDIGIT' can be used to substitute an operand that is a constant value | 2765 `%cDIGIT' can be used to substitute an operand that is a constant value |
2803 without the syntax that normally indicates an immediate operand. | 2766 without the syntax that normally indicates an immediate operand. |
2804 | 2767 |
2805 `%nDIGIT' is like `%cDIGIT' except that the value of the constant is negated | 2768 `%nDIGIT' is like `%cDIGIT' except that the value of the constant is negated |
2816 `%=' outputs a number which is unique to each instruction in the entire | 2779 `%=' outputs a number which is unique to each instruction in the entire |
2817 compilation. This is useful for making local labels to be referred to more | 2780 compilation. This is useful for making local labels to be referred to more |
2818 than once in a single template that generates multiple assembler | 2781 than once in a single template that generates multiple assembler |
2819 instructions. | 2782 instructions. |
2820 | 2783 |
2821 `%' followed by a punctuation character specifies a substitution that does | 2784 `%' followed by a punctuation character specifies a substitution that |
2822 not use an operand. Only one case is standard: `%%' outputs a `%' into the | 2785 does not use an operand. Only one case is standard: `%%' outputs a |
2823 assembler code. Other nonstandard cases can be defined in the | 2786 `%' into the assembler code. Other nonstandard cases can be defined |
2824 `PRINT_OPERAND' macro. You must also define which punctuation characters | 2787 in the `TARGET_PRINT_OPERAND' hook. You must also define which |
2825 are valid with the `PRINT_OPERAND_PUNCT_VALID_P' macro. */ | 2788 punctuation characters are valid with the |
2826 | 2789 `TARGET_PRINT_OPERAND_PUNCT_VALID_P' hook. */ |
2827 void | 2790 |
2791 static void | |
2828 frv_print_operand (FILE * file, rtx x, int code) | 2792 frv_print_operand (FILE * file, rtx x, int code) |
2829 { | 2793 { |
2830 struct frv_unspec unspec; | 2794 struct frv_unspec unspec; |
2831 HOST_WIDE_INT value; | 2795 HOST_WIDE_INT value; |
2832 int offset; | 2796 int offset; |
3111 fatal_insn ("frv_print_operand: unknown code", x); | 3075 fatal_insn ("frv_print_operand: unknown code", x); |
3112 break; | 3076 break; |
3113 } | 3077 } |
3114 | 3078 |
3115 return; | 3079 return; |
3080 } | |
3081 | |
3082 static bool | |
3083 frv_print_operand_punct_valid_p (unsigned char code) | |
3084 { | |
3085 return (code == '.' || code == '#' || code == '@' || code == '~' | |
3086 || code == '*' || code == '&'); | |
3116 } | 3087 } |
3117 | 3088 |
3118 | 3089 |
3119 /* A C statement (sans semicolon) for initializing the variable CUM for the | 3090 /* A C statement (sans semicolon) for initializing the variable CUM for the |
3120 state at the beginning of the argument list. The variable has type | 3091 state at the beginning of the argument list. The variable has type |
3183 | 3154 |
3184 /* If defined, a C expression that gives the alignment boundary, in bits, of an | 3155 /* If defined, a C expression that gives the alignment boundary, in bits, of an |
3185 argument with the specified mode and type. If it is not defined, | 3156 argument with the specified mode and type. If it is not defined, |
3186 `PARM_BOUNDARY' is used for all arguments. */ | 3157 `PARM_BOUNDARY' is used for all arguments. */ |
3187 | 3158 |
3188 int | 3159 static unsigned int |
3189 frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, | 3160 frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, |
3190 tree type ATTRIBUTE_UNUSED) | 3161 const_tree type ATTRIBUTE_UNUSED) |
3191 { | 3162 { |
3192 return BITS_PER_WORD; | 3163 return BITS_PER_WORD; |
3193 } | 3164 } |
3194 | 3165 |
3195 rtx | 3166 static rtx |
3196 frv_function_arg (CUMULATIVE_ARGS *cum, | 3167 frv_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, |
3197 enum machine_mode mode, | 3168 const_tree type ATTRIBUTE_UNUSED, bool named, |
3198 tree type ATTRIBUTE_UNUSED, | 3169 bool incoming ATTRIBUTE_UNUSED) |
3199 int named, | |
3200 int incoming ATTRIBUTE_UNUSED) | |
3201 { | 3170 { |
3202 enum machine_mode xmode = (mode == BLKmode) ? SImode : mode; | 3171 enum machine_mode xmode = (mode == BLKmode) ? SImode : mode; |
3203 int arg_num = *cum; | 3172 int arg_num = *cum; |
3204 rtx ret; | 3173 rtx ret; |
3205 const char *debstr; | 3174 const char *debstr; |
3227 fprintf (stderr, | 3196 fprintf (stderr, |
3228 "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n", | 3197 "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n", |
3229 arg_num, GET_MODE_NAME (mode), named, GET_MODE_SIZE (mode), debstr); | 3198 arg_num, GET_MODE_NAME (mode), named, GET_MODE_SIZE (mode), debstr); |
3230 | 3199 |
3231 return ret; | 3200 return ret; |
3201 } | |
3202 | |
3203 static rtx | |
3204 frv_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, | |
3205 const_tree type, bool named) | |
3206 { | |
3207 return frv_function_arg_1 (cum, mode, type, named, false); | |
3208 } | |
3209 | |
3210 static rtx | |
3211 frv_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, | |
3212 const_tree type, bool named) | |
3213 { | |
3214 return frv_function_arg_1 (cum, mode, type, named, true); | |
3232 } | 3215 } |
3233 | 3216 |
3234 | 3217 |
3235 /* A C statement (sans semicolon) to update the summarizer variable CUM to | 3218 /* A C statement (sans semicolon) to update the summarizer variable CUM to |
3236 advance past an argument in the argument list. The values MODE, TYPE and | 3219 advance past an argument in the argument list. The values MODE, TYPE and |
3239 | 3222 |
3240 This macro need not do anything if the argument in question was passed on | 3223 This macro need not do anything if the argument in question was passed on |
3241 the stack. The compiler knows how to track the amount of stack space used | 3224 the stack. The compiler knows how to track the amount of stack space used |
3242 for arguments without any special help. */ | 3225 for arguments without any special help. */ |
3243 | 3226 |
3244 void | 3227 static void |
3245 frv_function_arg_advance (CUMULATIVE_ARGS *cum, | 3228 frv_function_arg_advance (CUMULATIVE_ARGS *cum, |
3246 enum machine_mode mode, | 3229 enum machine_mode mode, |
3247 tree type ATTRIBUTE_UNUSED, | 3230 const_tree type ATTRIBUTE_UNUSED, |
3248 int named) | 3231 bool named) |
3249 { | 3232 { |
3250 enum machine_mode xmode = (mode == BLKmode) ? SImode : mode; | 3233 enum machine_mode xmode = (mode == BLKmode) ? SImode : mode; |
3251 int bytes = GET_MODE_SIZE (xmode); | 3234 int bytes = GET_MODE_SIZE (xmode); |
3252 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | 3235 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; |
3253 int arg_num = *cum; | 3236 int arg_num = *cum; |
3372 integer are stored inside a `const' RTX to mark them as constant. | 3355 integer are stored inside a `const' RTX to mark them as constant. |
3373 Therefore, there is no need to recognize such sums specifically as | 3356 Therefore, there is no need to recognize such sums specifically as |
3374 legitimate addresses. Normally you would simply recognize any `const' as | 3357 legitimate addresses. Normally you would simply recognize any `const' as |
3375 legitimate. | 3358 legitimate. |
3376 | 3359 |
3377 Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that | 3360 Usually `TARGET_PRINT_OPERAND_ADDRESS' is not prepared to handle |
3378 are not marked with `const'. It assumes that a naked `plus' indicates | 3361 constant sums that are not marked with `const'. It assumes that a |
3379 indexing. If so, then you *must* reject such naked constant sums as | 3362 naked `plus' indicates indexing. If so, then you *must* reject such |
3380 illegitimate addresses, so that none of them will be given to | 3363 naked constant sums as illegitimate addresses, so that none of them |
3381 `PRINT_OPERAND_ADDRESS'. */ | 3364 will be given to `TARGET_PRINT_OPERAND_ADDRESS'. */ |
3382 | 3365 |
3383 int | 3366 int |
3384 frv_legitimate_address_p_1 (enum machine_mode mode, | 3367 frv_legitimate_address_p_1 (enum machine_mode mode, |
3385 rtx x, | 3368 rtx x, |
3386 int strict_p, | 3369 int strict_p, |
3429 /* 12-bit immediate */ | 3412 /* 12-bit immediate */ |
3430 if (condexec_p) | 3413 if (condexec_p) |
3431 ret = FALSE; | 3414 ret = FALSE; |
3432 else | 3415 else |
3433 { | 3416 { |
3434 ret = IN_RANGE_P (INTVAL (x), -2048, 2047); | 3417 ret = IN_RANGE (INTVAL (x), -2048, 2047); |
3435 | 3418 |
3436 /* If we can't use load/store double operations, make sure we can | 3419 /* If we can't use load/store double operations, make sure we can |
3437 address the second word. */ | 3420 address the second word. */ |
3438 if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD) | 3421 if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD) |
3439 ret = IN_RANGE_P (INTVAL (x) + GET_MODE_SIZE (mode) - 1, | 3422 ret = IN_RANGE (INTVAL (x) + GET_MODE_SIZE (mode) - 1, |
3440 -2048, 2047); | 3423 -2048, 2047); |
3441 } | 3424 } |
3442 break; | 3425 break; |
3443 | 3426 |
3444 case PLUS: | 3427 case PLUS: |
3445 x0 = XEXP (x, 0); | 3428 x0 = XEXP (x, 0); |
3481 if (condexec_p) | 3464 if (condexec_p) |
3482 ret = FALSE; | 3465 ret = FALSE; |
3483 else | 3466 else |
3484 { | 3467 { |
3485 value = INTVAL (x1); | 3468 value = INTVAL (x1); |
3486 ret = IN_RANGE_P (value, -2048, 2047); | 3469 ret = IN_RANGE (value, -2048, 2047); |
3487 | 3470 |
3488 /* If we can't use load/store double operations, make sure we can | 3471 /* If we can't use load/store double operations, make sure we can |
3489 address the second word. */ | 3472 address the second word. */ |
3490 if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD) | 3473 if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD) |
3491 ret = IN_RANGE_P (value + GET_MODE_SIZE (mode) - 1, -2048, 2047); | 3474 ret = IN_RANGE (value + GET_MODE_SIZE (mode) - 1, -2048, 2047); |
3492 } | 3475 } |
3493 break; | 3476 break; |
3494 | 3477 |
3495 case CONST: | 3478 case CONST: |
3496 if (!condexec_p && got12_operand (x1, VOIDmode)) | 3479 if (!condexec_p && got12_operand (x1, VOIDmode)) |
4046 && (!reg_or_0_operand (src, SImode) | 4029 && (!reg_or_0_operand (src, SImode) |
4047 /* Virtual registers will almost always be replaced by an | 4030 /* Virtual registers will almost always be replaced by an |
4048 add instruction, so expose this to CSE by copying to | 4031 add instruction, so expose this to CSE by copying to |
4049 an intermediate register. */ | 4032 an intermediate register. */ |
4050 || (GET_CODE (src) == REG | 4033 || (GET_CODE (src) == REG |
4051 && IN_RANGE_P (REGNO (src), | 4034 && IN_RANGE (REGNO (src), |
4052 FIRST_VIRTUAL_REGISTER, | 4035 FIRST_VIRTUAL_REGISTER, |
4053 LAST_VIRTUAL_REGISTER)))) | 4036 LAST_VIRTUAL_POINTER_REGISTER)))) |
4054 { | 4037 { |
4055 emit_insn (gen_rtx_SET (VOIDmode, dest, copy_to_mode_reg (SImode, src))); | 4038 emit_insn (gen_rtx_SET (VOIDmode, dest, copy_to_mode_reg (SImode, src))); |
4056 return TRUE; | 4039 return TRUE; |
4057 } | 4040 } |
4058 | 4041 |
4350 } | 4333 } |
4351 | 4334 |
4352 else | 4335 else |
4353 value = CONST_DOUBLE_LOW (src); | 4336 value = CONST_DOUBLE_LOW (src); |
4354 | 4337 |
4355 if (IN_RANGE_P (value, -32768, 32767)) | 4338 if (IN_RANGE (value, -32768, 32767)) |
4356 return "setlos %1, %0"; | 4339 return "setlos %1, %0"; |
4357 | 4340 |
4358 return "#"; | 4341 return "#"; |
4359 } | 4342 } |
4360 | 4343 |
4921 | 4904 |
4922 /* If the first value is within an addi range and also the difference | 4905 /* If the first value is within an addi range and also the difference |
4923 between the two fits in an addi's range, load up the difference, then | 4906 between the two fits in an addi's range, load up the difference, then |
4924 conditionally move in 0, and then unconditionally add the first | 4907 conditionally move in 0, and then unconditionally add the first |
4925 value. */ | 4908 value. */ |
4926 else if (IN_RANGE_P (value1, -2048, 2047) | 4909 else if (IN_RANGE (value1, -2048, 2047) |
4927 && IN_RANGE_P (value2 - value1, -2048, 2047)) | 4910 && IN_RANGE (value2 - value1, -2048, 2047)) |
4928 ; | 4911 ; |
4929 | 4912 |
4930 /* If neither condition holds, just force the constant into a | 4913 /* If neither condition holds, just force the constant into a |
4931 register. */ | 4914 register. */ |
4932 else | 4915 else |
5016 | 4999 |
5017 /* If the first value is within an addi range and also the difference | 5000 /* If the first value is within an addi range and also the difference |
5018 between the two fits in an addi's range, load up the difference, then | 5001 between the two fits in an addi's range, load up the difference, then |
5019 conditionally move in 0, and then unconditionally add the first | 5002 conditionally move in 0, and then unconditionally add the first |
5020 value. */ | 5003 value. */ |
5021 else if (IN_RANGE_P (value1, -2048, 2047) | 5004 else if (IN_RANGE (value1, -2048, 2047) |
5022 && IN_RANGE_P (value2 - value1, -2048, 2047)) | 5005 && IN_RANGE (value2 - value1, -2048, 2047)) |
5023 { | 5006 { |
5024 rtx dest_si = ((GET_MODE (dest) == SImode) | 5007 rtx dest_si = ((GET_MODE (dest) == SImode) |
5025 ? dest | 5008 ? dest |
5026 : gen_rtx_SUBREG (SImode, dest, 0)); | 5009 : gen_rtx_SUBREG (SImode, dest, 0)); |
5027 | 5010 |
6347 rtx addr = XEXP (m_tramp, 0); | 6330 rtx addr = XEXP (m_tramp, 0); |
6348 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); | 6331 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); |
6349 rtx sc_reg = force_reg (Pmode, static_chain); | 6332 rtx sc_reg = force_reg (Pmode, static_chain); |
6350 | 6333 |
6351 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"), | 6334 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"), |
6352 FALSE, VOIDmode, 4, | 6335 LCT_NORMAL, VOIDmode, 4, |
6353 addr, Pmode, | 6336 addr, Pmode, |
6354 GEN_INT (frv_trampoline_size ()), SImode, | 6337 GEN_INT (frv_trampoline_size ()), SImode, |
6355 fnaddr, Pmode, | 6338 fnaddr, Pmode, |
6356 sc_reg, Pmode); | 6339 sc_reg, Pmode); |
6357 } | 6340 } |
6473 | 6456 |
6474 /* This hook exists to catch the case where secondary_reload_class() is | 6457 /* This hook exists to catch the case where secondary_reload_class() is |
6475 called from init_reg_autoinc() in regclass.c - before the reload optabs | 6458 called from init_reg_autoinc() in regclass.c - before the reload optabs |
6476 have been initialised. */ | 6459 have been initialised. */ |
6477 | 6460 |
6478 static bool | 6461 static reg_class_t |
6479 frv_secondary_reload (bool in_p, rtx x, enum reg_class reload_class, | 6462 frv_secondary_reload (bool in_p, rtx x, reg_class_t reload_class_i, |
6480 enum machine_mode reload_mode, | 6463 enum machine_mode reload_mode, |
6481 secondary_reload_info * sri) | 6464 secondary_reload_info * sri) |
6482 { | 6465 { |
6483 enum reg_class rclass = NO_REGS; | 6466 enum reg_class rclass = NO_REGS; |
6467 enum reg_class reload_class = (enum reg_class) reload_class_i; | |
6484 | 6468 |
6485 if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing) | 6469 if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing) |
6486 { | 6470 { |
6487 sri->icode = sri->prev_sri->t_icode; | 6471 sri->icode = sri->prev_sri->t_icode; |
6488 return NO_REGS; | 6472 return NO_REGS; |
6490 | 6474 |
6491 rclass = frv_secondary_reload_class (reload_class, reload_mode, x); | 6475 rclass = frv_secondary_reload_class (reload_class, reload_mode, x); |
6492 | 6476 |
6493 if (rclass != NO_REGS) | 6477 if (rclass != NO_REGS) |
6494 { | 6478 { |
6495 enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode] | 6479 enum insn_code icode |
6496 : reload_out_optab[(int) reload_mode]); | 6480 = direct_optab_handler (in_p ? reload_in_optab : reload_out_optab, |
6481 reload_mode); | |
6497 if (icode == 0) | 6482 if (icode == 0) |
6498 { | 6483 { |
6499 /* This happens when then the reload_[in|out]_optabs have | 6484 /* This happens when then the reload_[in|out]_optabs have |
6500 not been initialised. */ | 6485 not been initialised. */ |
6501 sri->t_icode = CODE_FOR_nothing; | 6486 sri->t_icode = CODE_FOR_nothing; |
6506 /* Fall back to the default secondary reload handler. */ | 6491 /* Fall back to the default secondary reload handler. */ |
6507 return default_secondary_reload (in_p, x, reload_class, reload_mode, sri); | 6492 return default_secondary_reload (in_p, x, reload_class, reload_mode, sri); |
6508 | 6493 |
6509 } | 6494 } |
6510 | 6495 |
6511 /* A C expression whose value is nonzero if pseudos that have been assigned to | 6496 /* Worker function for TARGET_CLASS_LIKELY_SPILLED_P. */ |
6512 registers of class RCLASS would likely be spilled because registers of RCLASS | 6497 |
6513 are needed for spill registers. | 6498 static bool |
6514 | 6499 frv_class_likely_spilled_p (reg_class_t rclass) |
6515 The default value of this macro returns 1 if RCLASS has exactly one register | |
6516 and zero otherwise. On most machines, this default should be used. Only | |
6517 define this macro to some other expression if pseudo allocated by | |
6518 `local-alloc.c' end up in memory because their hard registers were needed | |
6519 for spill registers. If this macro returns nonzero for those classes, those | |
6520 pseudos will only be allocated by `global.c', which knows how to reallocate | |
6521 the pseudo to another register. If there would not be another register | |
6522 available for reallocation, you should not change the definition of this | |
6523 macro since the only effect of such a definition would be to slow down | |
6524 register allocation. */ | |
6525 | |
6526 int | |
6527 frv_class_likely_spilled_p (enum reg_class rclass) | |
6528 { | 6500 { |
6529 switch (rclass) | 6501 switch (rclass) |
6530 { | 6502 { |
6531 default: | 6503 default: |
6532 break; | 6504 break; |
6547 case SPR_REGS: | 6519 case SPR_REGS: |
6548 case QUAD_ACC_REGS: | 6520 case QUAD_ACC_REGS: |
6549 case EVEN_ACC_REGS: | 6521 case EVEN_ACC_REGS: |
6550 case ACC_REGS: | 6522 case ACC_REGS: |
6551 case ACCG_REGS: | 6523 case ACCG_REGS: |
6552 return TRUE; | 6524 return true; |
6553 } | 6525 } |
6554 | 6526 |
6555 return FALSE; | 6527 return false; |
6556 } | 6528 } |
6557 | 6529 |
6558 | 6530 |
6559 /* An expression for the alignment of a structure field FIELD if the | 6531 /* An expression for the alignment of a structure field FIELD if the |
6560 alignment computed in the usual way is COMPUTED. GCC uses this | 6532 alignment computed in the usual way is COMPUTED. GCC uses this |
6612 { | 6584 { |
6613 tree parent = DECL_CONTEXT (field); | 6585 tree parent = DECL_CONTEXT (field); |
6614 tree prev = NULL_TREE; | 6586 tree prev = NULL_TREE; |
6615 tree cur; | 6587 tree cur; |
6616 | 6588 |
6617 for (cur = TYPE_FIELDS (parent); cur && cur != field; cur = TREE_CHAIN (cur)) | 6589 for (cur = TYPE_FIELDS (parent); cur && cur != field; cur = DECL_CHAIN (cur)) |
6618 { | 6590 { |
6619 if (TREE_CODE (cur) != FIELD_DECL) | 6591 if (TREE_CODE (cur) != FIELD_DECL) |
6620 continue; | 6592 continue; |
6621 | 6593 |
6622 prev = cur; | 6594 prev = cur; |
6890 default: | 6862 default: |
6891 return CCmode; | 6863 return CCmode; |
6892 } | 6864 } |
6893 } | 6865 } |
6894 | 6866 |
6895 /* A C expression for the cost of moving data from a register in class FROM to | 6867 |
6896 one in class TO. The classes are expressed using the enumeration values | 6868 /* Worker function for TARGET_REGISTER_MOVE_COST. */ |
6897 such as `GENERAL_REGS'. A value of 4 is the default; other values are | |
6898 interpreted relative to that. | |
6899 | |
6900 It is not required that the cost always equal 2 when FROM is the same as TO; | |
6901 on some machines it is expensive to move between registers if they are not | |
6902 general registers. | |
6903 | |
6904 If reload sees an insn consisting of a single `set' between two hard | |
6905 registers, and if `REGISTER_MOVE_COST' applied to their classes returns a | |
6906 value of 2, reload does not check to ensure that the constraints of the insn | |
6907 are met. Setting a cost of other than 2 will allow reload to verify that | |
6908 the constraints are met. You should do this if the `movM' pattern's | |
6909 constraints do not allow such copying. */ | |
6910 | 6869 |
6911 #define HIGH_COST 40 | 6870 #define HIGH_COST 40 |
6912 #define MEDIUM_COST 3 | 6871 #define MEDIUM_COST 3 |
6913 #define LOW_COST 1 | 6872 #define LOW_COST 1 |
6914 | 6873 |
6915 int | 6874 static int |
6916 frv_register_move_cost (enum reg_class from, enum reg_class to) | 6875 frv_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, |
6876 reg_class_t from, reg_class_t to) | |
6917 { | 6877 { |
6918 switch (from) | 6878 switch (from) |
6919 { | 6879 { |
6920 default: | 6880 default: |
6921 break; | 6881 break; |
6994 } | 6954 } |
6995 } | 6955 } |
6996 | 6956 |
6997 return HIGH_COST; | 6957 return HIGH_COST; |
6998 } | 6958 } |
6959 | |
6960 /* Worker function for TARGET_MEMORY_MOVE_COST. */ | |
6961 | |
6962 static int | |
6963 frv_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, | |
6964 reg_class_t rclass ATTRIBUTE_UNUSED, | |
6965 bool in ATTRIBUTE_UNUSED) | |
6966 { | |
6967 return 4; | |
6968 } | |
6969 | |
6999 | 6970 |
7000 /* Implementation of TARGET_ASM_INTEGER. In the FRV case we need to | 6971 /* Implementation of TARGET_ASM_INTEGER. In the FRV case we need to |
7001 use ".picptr" to generate safe relocations for PIC code. We also | 6972 use ".picptr" to generate safe relocations for PIC code. We also |
7002 need a fixup entry for aligned (non-debugging) code. */ | 6973 need a fixup entry for aligned (non-debugging) code. */ |
7003 | 6974 |
7052 /* Function to set up the backend function structure. */ | 7023 /* Function to set up the backend function structure. */ |
7053 | 7024 |
7054 static struct machine_function * | 7025 static struct machine_function * |
7055 frv_init_machine_status (void) | 7026 frv_init_machine_status (void) |
7056 { | 7027 { |
7057 return GGC_CNEW (struct machine_function); | 7028 return ggc_alloc_cleared_machine_function (); |
7058 } | 7029 } |
7059 | 7030 |
7060 /* Implement TARGET_SCHED_ISSUE_RATE. */ | 7031 /* Implement TARGET_SCHED_ISSUE_RATE. */ |
7061 | 7032 |
7062 int | 7033 int |
7155 frv_issues_to_branch_unit_p (rtx insn) | 7126 frv_issues_to_branch_unit_p (rtx insn) |
7156 { | 7127 { |
7157 return frv_unit_groups[frv_insn_unit (insn)] == GROUP_B; | 7128 return frv_unit_groups[frv_insn_unit (insn)] == GROUP_B; |
7158 } | 7129 } |
7159 | 7130 |
7131 /* The instructions in the packet, partitioned into groups. */ | |
7132 struct frv_packet_group { | |
7133 /* How many instructions in the packet belong to this group. */ | |
7134 unsigned int num_insns; | |
7135 | |
7136 /* A list of the instructions that belong to this group, in the order | |
7137 they appear in the rtl stream. */ | |
7138 rtx insns[ARRAY_SIZE (frv_unit_codes)]; | |
7139 | |
7140 /* The contents of INSNS after they have been sorted into the correct | |
7141 assembly-language order. Element X issues to unit X. The list may | |
7142 contain extra nops. */ | |
7143 rtx sorted[ARRAY_SIZE (frv_unit_codes)]; | |
7144 | |
7145 /* The member of frv_nops[] to use in sorted[]. */ | |
7146 rtx nop; | |
7147 }; | |
7148 | |
7160 /* The current state of the packing pass, implemented by frv_pack_insns. */ | 7149 /* The current state of the packing pass, implemented by frv_pack_insns. */ |
7161 static struct { | 7150 static struct { |
7162 /* The state of the pipeline DFA. */ | 7151 /* The state of the pipeline DFA. */ |
7163 state_t dfa_state; | 7152 state_t dfa_state; |
7164 | 7153 |
7180 | 7169 |
7181 /* The maximum number of instructions that can be packed together. */ | 7170 /* The maximum number of instructions that can be packed together. */ |
7182 unsigned int issue_rate; | 7171 unsigned int issue_rate; |
7183 | 7172 |
7184 /* The instructions in the packet, partitioned into groups. */ | 7173 /* The instructions in the packet, partitioned into groups. */ |
7185 struct frv_packet_group { | 7174 struct frv_packet_group groups[NUM_GROUPS]; |
7186 /* How many instructions in the packet belong to this group. */ | |
7187 unsigned int num_insns; | |
7188 | |
7189 /* A list of the instructions that belong to this group, in the order | |
7190 they appear in the rtl stream. */ | |
7191 rtx insns[ARRAY_SIZE (frv_unit_codes)]; | |
7192 | |
7193 /* The contents of INSNS after they have been sorted into the correct | |
7194 assembly-language order. Element X issues to unit X. The list may | |
7195 contain extra nops. */ | |
7196 rtx sorted[ARRAY_SIZE (frv_unit_codes)]; | |
7197 | |
7198 /* The member of frv_nops[] to use in sorted[]. */ | |
7199 rtx nop; | |
7200 } groups[NUM_GROUPS]; | |
7201 | 7175 |
7202 /* The instructions that make up the current packet. */ | 7176 /* The instructions that make up the current packet. */ |
7203 rtx insns[ARRAY_SIZE (frv_unit_codes)]; | 7177 rtx insns[ARRAY_SIZE (frv_unit_codes)]; |
7204 unsigned int num_insns; | 7178 unsigned int num_insns; |
7205 } frv_packet; | 7179 } frv_packet; |
7368 enum frv_insn_group group; | 7342 enum frv_insn_group group; |
7369 | 7343 |
7370 memset (frv_packet.regstate, 0, sizeof (frv_packet.regstate)); | 7344 memset (frv_packet.regstate, 0, sizeof (frv_packet.regstate)); |
7371 frv_packet.num_mems = 0; | 7345 frv_packet.num_mems = 0; |
7372 frv_packet.num_insns = 0; | 7346 frv_packet.num_insns = 0; |
7373 for (group = 0; group < NUM_GROUPS; group++) | 7347 for (group = GROUP_I; group < NUM_GROUPS; |
7348 group = (enum frv_insn_group) (group + 1)) | |
7374 frv_packet.groups[group].num_insns = 0; | 7349 frv_packet.groups[group].num_insns = 0; |
7375 } | 7350 } |
7376 | 7351 |
7377 | 7352 |
7378 /* Likewise for the start of a new basic block. */ | 7353 /* Likewise for the start of a new basic block. */ |
7717 unsigned int unit, to, from; | 7692 unsigned int unit, to, from; |
7718 enum frv_insn_group group; | 7693 enum frv_insn_group group; |
7719 struct frv_packet_group *packet_group; | 7694 struct frv_packet_group *packet_group; |
7720 | 7695 |
7721 /* First sort each group individually. */ | 7696 /* First sort each group individually. */ |
7722 for (group = 0; group < NUM_GROUPS; group++) | 7697 for (group = GROUP_I; group < NUM_GROUPS; |
7698 group = (enum frv_insn_group) (group + 1)) | |
7723 { | 7699 { |
7724 cursor[group] = 0; | 7700 cursor[group] = 0; |
7725 frv_sort_insn_group (group); | 7701 frv_sort_insn_group (group); |
7726 } | 7702 } |
7727 | 7703 |
7850 | 7826 |
7851 static void | 7827 static void |
7852 frv_extract_membar (struct frv_io *io, rtx insn) | 7828 frv_extract_membar (struct frv_io *io, rtx insn) |
7853 { | 7829 { |
7854 extract_insn (insn); | 7830 extract_insn (insn); |
7855 io->type = INTVAL (recog_data.operand[2]); | 7831 io->type = (enum frv_io_type) INTVAL (recog_data.operand[2]); |
7856 io->const_address = INTVAL (recog_data.operand[1]); | 7832 io->const_address = INTVAL (recog_data.operand[1]); |
7857 io->var_address = XEXP (recog_data.operand[0], 0); | 7833 io->var_address = XEXP (recog_data.operand[0], 0); |
7858 } | 7834 } |
7859 | 7835 |
7860 /* A note_stores callback for which DATA points to an rtx. Nullify *DATA | 7836 /* A note_stores callback for which DATA points to an rtx. Nullify *DATA |
8269 | 8245 |
8270 /* Media intrinsics that take a single, constant argument. */ | 8246 /* Media intrinsics that take a single, constant argument. */ |
8271 | 8247 |
8272 static struct builtin_description bdesc_set[] = | 8248 static struct builtin_description bdesc_set[] = |
8273 { | 8249 { |
8274 { CODE_FOR_mhdsets, "__MHDSETS", FRV_BUILTIN_MHDSETS, 0, 0 } | 8250 { CODE_FOR_mhdsets, "__MHDSETS", FRV_BUILTIN_MHDSETS, UNKNOWN, 0 } |
8275 }; | 8251 }; |
8276 | 8252 |
8277 /* Media intrinsics that take just one argument. */ | 8253 /* Media intrinsics that take just one argument. */ |
8278 | 8254 |
8279 static struct builtin_description bdesc_1arg[] = | 8255 static struct builtin_description bdesc_1arg[] = |
8280 { | 8256 { |
8281 { CODE_FOR_mnot, "__MNOT", FRV_BUILTIN_MNOT, 0, 0 }, | 8257 { CODE_FOR_mnot, "__MNOT", FRV_BUILTIN_MNOT, UNKNOWN, 0 }, |
8282 { CODE_FOR_munpackh, "__MUNPACKH", FRV_BUILTIN_MUNPACKH, 0, 0 }, | 8258 { CODE_FOR_munpackh, "__MUNPACKH", FRV_BUILTIN_MUNPACKH, UNKNOWN, 0 }, |
8283 { CODE_FOR_mbtoh, "__MBTOH", FRV_BUILTIN_MBTOH, 0, 0 }, | 8259 { CODE_FOR_mbtoh, "__MBTOH", FRV_BUILTIN_MBTOH, UNKNOWN, 0 }, |
8284 { CODE_FOR_mhtob, "__MHTOB", FRV_BUILTIN_MHTOB, 0, 0 }, | 8260 { CODE_FOR_mhtob, "__MHTOB", FRV_BUILTIN_MHTOB, UNKNOWN, 0}, |
8285 { CODE_FOR_mabshs, "__MABSHS", FRV_BUILTIN_MABSHS, 0, 0 }, | 8261 { CODE_FOR_mabshs, "__MABSHS", FRV_BUILTIN_MABSHS, UNKNOWN, 0 }, |
8286 { CODE_FOR_scutss, "__SCUTSS", FRV_BUILTIN_SCUTSS, 0, 0 } | 8262 { CODE_FOR_scutss, "__SCUTSS", FRV_BUILTIN_SCUTSS, UNKNOWN, 0 } |
8287 }; | 8263 }; |
8288 | 8264 |
8289 /* Media intrinsics that take two arguments. */ | 8265 /* Media intrinsics that take two arguments. */ |
8290 | 8266 |
8291 static struct builtin_description bdesc_2arg[] = | 8267 static struct builtin_description bdesc_2arg[] = |
8292 { | 8268 { |
8293 { CODE_FOR_mand, "__MAND", FRV_BUILTIN_MAND, 0, 0 }, | 8269 { CODE_FOR_mand, "__MAND", FRV_BUILTIN_MAND, UNKNOWN, 0}, |
8294 { CODE_FOR_mor, "__MOR", FRV_BUILTIN_MOR, 0, 0 }, | 8270 { CODE_FOR_mor, "__MOR", FRV_BUILTIN_MOR, UNKNOWN, 0}, |
8295 { CODE_FOR_mxor, "__MXOR", FRV_BUILTIN_MXOR, 0, 0 }, | 8271 { CODE_FOR_mxor, "__MXOR", FRV_BUILTIN_MXOR, UNKNOWN, 0}, |
8296 { CODE_FOR_maveh, "__MAVEH", FRV_BUILTIN_MAVEH, 0, 0 }, | 8272 { CODE_FOR_maveh, "__MAVEH", FRV_BUILTIN_MAVEH, UNKNOWN, 0}, |
8297 { CODE_FOR_msaths, "__MSATHS", FRV_BUILTIN_MSATHS, 0, 0 }, | 8273 { CODE_FOR_msaths, "__MSATHS", FRV_BUILTIN_MSATHS, UNKNOWN, 0}, |
8298 { CODE_FOR_msathu, "__MSATHU", FRV_BUILTIN_MSATHU, 0, 0 }, | 8274 { CODE_FOR_msathu, "__MSATHU", FRV_BUILTIN_MSATHU, UNKNOWN, 0}, |
8299 { CODE_FOR_maddhss, "__MADDHSS", FRV_BUILTIN_MADDHSS, 0, 0 }, | 8275 { CODE_FOR_maddhss, "__MADDHSS", FRV_BUILTIN_MADDHSS, UNKNOWN, 0}, |
8300 { CODE_FOR_maddhus, "__MADDHUS", FRV_BUILTIN_MADDHUS, 0, 0 }, | 8276 { CODE_FOR_maddhus, "__MADDHUS", FRV_BUILTIN_MADDHUS, UNKNOWN, 0}, |
8301 { CODE_FOR_msubhss, "__MSUBHSS", FRV_BUILTIN_MSUBHSS, 0, 0 }, | 8277 { CODE_FOR_msubhss, "__MSUBHSS", FRV_BUILTIN_MSUBHSS, UNKNOWN, 0}, |
8302 { CODE_FOR_msubhus, "__MSUBHUS", FRV_BUILTIN_MSUBHUS, 0, 0 }, | 8278 { CODE_FOR_msubhus, "__MSUBHUS", FRV_BUILTIN_MSUBHUS, UNKNOWN, 0}, |
8303 { CODE_FOR_mqaddhss, "__MQADDHSS", FRV_BUILTIN_MQADDHSS, 0, 0 }, | 8279 { CODE_FOR_mqaddhss, "__MQADDHSS", FRV_BUILTIN_MQADDHSS, UNKNOWN, 0}, |
8304 { CODE_FOR_mqaddhus, "__MQADDHUS", FRV_BUILTIN_MQADDHUS, 0, 0 }, | 8280 { CODE_FOR_mqaddhus, "__MQADDHUS", FRV_BUILTIN_MQADDHUS, UNKNOWN, 0}, |
8305 { CODE_FOR_mqsubhss, "__MQSUBHSS", FRV_BUILTIN_MQSUBHSS, 0, 0 }, | 8281 { CODE_FOR_mqsubhss, "__MQSUBHSS", FRV_BUILTIN_MQSUBHSS, UNKNOWN, 0}, |
8306 { CODE_FOR_mqsubhus, "__MQSUBHUS", FRV_BUILTIN_MQSUBHUS, 0, 0 }, | 8282 { CODE_FOR_mqsubhus, "__MQSUBHUS", FRV_BUILTIN_MQSUBHUS, UNKNOWN, 0}, |
8307 { CODE_FOR_mpackh, "__MPACKH", FRV_BUILTIN_MPACKH, 0, 0 }, | 8283 { CODE_FOR_mpackh, "__MPACKH", FRV_BUILTIN_MPACKH, UNKNOWN, 0}, |
8308 { CODE_FOR_mcop1, "__Mcop1", FRV_BUILTIN_MCOP1, 0, 0 }, | 8284 { CODE_FOR_mcop1, "__Mcop1", FRV_BUILTIN_MCOP1, UNKNOWN, 0}, |
8309 { CODE_FOR_mcop2, "__Mcop2", FRV_BUILTIN_MCOP2, 0, 0 }, | 8285 { CODE_FOR_mcop2, "__Mcop2", FRV_BUILTIN_MCOP2, UNKNOWN, 0}, |
8310 { CODE_FOR_mwcut, "__MWCUT", FRV_BUILTIN_MWCUT, 0, 0 }, | 8286 { CODE_FOR_mwcut, "__MWCUT", FRV_BUILTIN_MWCUT, UNKNOWN, 0}, |
8311 { CODE_FOR_mqsaths, "__MQSATHS", FRV_BUILTIN_MQSATHS, 0, 0 }, | 8287 { CODE_FOR_mqsaths, "__MQSATHS", FRV_BUILTIN_MQSATHS, UNKNOWN, 0}, |
8312 { CODE_FOR_mqlclrhs, "__MQLCLRHS", FRV_BUILTIN_MQLCLRHS, 0, 0 }, | 8288 { CODE_FOR_mqlclrhs, "__MQLCLRHS", FRV_BUILTIN_MQLCLRHS, UNKNOWN, 0}, |
8313 { CODE_FOR_mqlmths, "__MQLMTHS", FRV_BUILTIN_MQLMTHS, 0, 0 }, | 8289 { CODE_FOR_mqlmths, "__MQLMTHS", FRV_BUILTIN_MQLMTHS, UNKNOWN, 0}, |
8314 { CODE_FOR_smul, "__SMUL", FRV_BUILTIN_SMUL, 0, 0 }, | 8290 { CODE_FOR_smul, "__SMUL", FRV_BUILTIN_SMUL, UNKNOWN, 0}, |
8315 { CODE_FOR_umul, "__UMUL", FRV_BUILTIN_UMUL, 0, 0 }, | 8291 { CODE_FOR_umul, "__UMUL", FRV_BUILTIN_UMUL, UNKNOWN, 0}, |
8316 { CODE_FOR_addss, "__ADDSS", FRV_BUILTIN_ADDSS, 0, 0 }, | 8292 { CODE_FOR_addss, "__ADDSS", FRV_BUILTIN_ADDSS, UNKNOWN, 0}, |
8317 { CODE_FOR_subss, "__SUBSS", FRV_BUILTIN_SUBSS, 0, 0 }, | 8293 { CODE_FOR_subss, "__SUBSS", FRV_BUILTIN_SUBSS, UNKNOWN, 0}, |
8318 { CODE_FOR_slass, "__SLASS", FRV_BUILTIN_SLASS, 0, 0 }, | 8294 { CODE_FOR_slass, "__SLASS", FRV_BUILTIN_SLASS, UNKNOWN, 0}, |
8319 { CODE_FOR_scan, "__SCAN", FRV_BUILTIN_SCAN, 0, 0 } | 8295 { CODE_FOR_scan, "__SCAN", FRV_BUILTIN_SCAN, UNKNOWN, 0} |
8320 }; | 8296 }; |
8321 | 8297 |
8322 /* Integer intrinsics that take two arguments and have no return value. */ | 8298 /* Integer intrinsics that take two arguments and have no return value. */ |
8323 | 8299 |
8324 static struct builtin_description bdesc_int_void2arg[] = | 8300 static struct builtin_description bdesc_int_void2arg[] = |
8325 { | 8301 { |
8326 { CODE_FOR_smass, "__SMASS", FRV_BUILTIN_SMASS, 0, 0 }, | 8302 { CODE_FOR_smass, "__SMASS", FRV_BUILTIN_SMASS, UNKNOWN, 0}, |
8327 { CODE_FOR_smsss, "__SMSSS", FRV_BUILTIN_SMSSS, 0, 0 }, | 8303 { CODE_FOR_smsss, "__SMSSS", FRV_BUILTIN_SMSSS, UNKNOWN, 0}, |
8328 { CODE_FOR_smu, "__SMU", FRV_BUILTIN_SMU, 0, 0 } | 8304 { CODE_FOR_smu, "__SMU", FRV_BUILTIN_SMU, UNKNOWN, 0} |
8329 }; | 8305 }; |
8330 | 8306 |
8331 static struct builtin_description bdesc_prefetches[] = | 8307 static struct builtin_description bdesc_prefetches[] = |
8332 { | 8308 { |
8333 { CODE_FOR_frv_prefetch0, "__data_prefetch0", FRV_BUILTIN_PREFETCH0, 0, 0 }, | 8309 { CODE_FOR_frv_prefetch0, "__data_prefetch0", FRV_BUILTIN_PREFETCH0, UNKNOWN, |
8334 { CODE_FOR_frv_prefetch, "__data_prefetch", FRV_BUILTIN_PREFETCH, 0, 0 } | 8310 0}, |
8311 { CODE_FOR_frv_prefetch, "__data_prefetch", FRV_BUILTIN_PREFETCH, UNKNOWN, 0} | |
8335 }; | 8312 }; |
8336 | 8313 |
8337 /* Media intrinsics that take two arguments, the first being an ACC number. */ | 8314 /* Media intrinsics that take two arguments, the first being an ACC number. */ |
8338 | 8315 |
8339 static struct builtin_description bdesc_cut[] = | 8316 static struct builtin_description bdesc_cut[] = |
8340 { | 8317 { |
8341 { CODE_FOR_mcut, "__MCUT", FRV_BUILTIN_MCUT, 0, 0 }, | 8318 { CODE_FOR_mcut, "__MCUT", FRV_BUILTIN_MCUT, UNKNOWN, 0}, |
8342 { CODE_FOR_mcutss, "__MCUTSS", FRV_BUILTIN_MCUTSS, 0, 0 }, | 8319 { CODE_FOR_mcutss, "__MCUTSS", FRV_BUILTIN_MCUTSS, UNKNOWN, 0}, |
8343 { CODE_FOR_mdcutssi, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI, 0, 0 } | 8320 { CODE_FOR_mdcutssi, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI, UNKNOWN, 0} |
8344 }; | 8321 }; |
8345 | 8322 |
8346 /* Two-argument media intrinsics with an immediate second argument. */ | 8323 /* Two-argument media intrinsics with an immediate second argument. */ |
8347 | 8324 |
8348 static struct builtin_description bdesc_2argimm[] = | 8325 static struct builtin_description bdesc_2argimm[] = |
8349 { | 8326 { |
8350 { CODE_FOR_mrotli, "__MROTLI", FRV_BUILTIN_MROTLI, 0, 0 }, | 8327 { CODE_FOR_mrotli, "__MROTLI", FRV_BUILTIN_MROTLI, UNKNOWN, 0}, |
8351 { CODE_FOR_mrotri, "__MROTRI", FRV_BUILTIN_MROTRI, 0, 0 }, | 8328 { CODE_FOR_mrotri, "__MROTRI", FRV_BUILTIN_MROTRI, UNKNOWN, 0}, |
8352 { CODE_FOR_msllhi, "__MSLLHI", FRV_BUILTIN_MSLLHI, 0, 0 }, | 8329 { CODE_FOR_msllhi, "__MSLLHI", FRV_BUILTIN_MSLLHI, UNKNOWN, 0}, |
8353 { CODE_FOR_msrlhi, "__MSRLHI", FRV_BUILTIN_MSRLHI, 0, 0 }, | 8330 { CODE_FOR_msrlhi, "__MSRLHI", FRV_BUILTIN_MSRLHI, UNKNOWN, 0}, |
8354 { CODE_FOR_msrahi, "__MSRAHI", FRV_BUILTIN_MSRAHI, 0, 0 }, | 8331 { CODE_FOR_msrahi, "__MSRAHI", FRV_BUILTIN_MSRAHI, UNKNOWN, 0}, |
8355 { CODE_FOR_mexpdhw, "__MEXPDHW", FRV_BUILTIN_MEXPDHW, 0, 0 }, | 8332 { CODE_FOR_mexpdhw, "__MEXPDHW", FRV_BUILTIN_MEXPDHW, UNKNOWN, 0}, |
8356 { CODE_FOR_mexpdhd, "__MEXPDHD", FRV_BUILTIN_MEXPDHD, 0, 0 }, | 8333 { CODE_FOR_mexpdhd, "__MEXPDHD", FRV_BUILTIN_MEXPDHD, UNKNOWN, 0}, |
8357 { CODE_FOR_mdrotli, "__MDROTLI", FRV_BUILTIN_MDROTLI, 0, 0 }, | 8334 { CODE_FOR_mdrotli, "__MDROTLI", FRV_BUILTIN_MDROTLI, UNKNOWN, 0}, |
8358 { CODE_FOR_mcplhi, "__MCPLHI", FRV_BUILTIN_MCPLHI, 0, 0 }, | 8335 { CODE_FOR_mcplhi, "__MCPLHI", FRV_BUILTIN_MCPLHI, UNKNOWN, 0}, |
8359 { CODE_FOR_mcpli, "__MCPLI", FRV_BUILTIN_MCPLI, 0, 0 }, | 8336 { CODE_FOR_mcpli, "__MCPLI", FRV_BUILTIN_MCPLI, UNKNOWN, 0}, |
8360 { CODE_FOR_mhsetlos, "__MHSETLOS", FRV_BUILTIN_MHSETLOS, 0, 0 }, | 8337 { CODE_FOR_mhsetlos, "__MHSETLOS", FRV_BUILTIN_MHSETLOS, UNKNOWN, 0}, |
8361 { CODE_FOR_mhsetloh, "__MHSETLOH", FRV_BUILTIN_MHSETLOH, 0, 0 }, | 8338 { CODE_FOR_mhsetloh, "__MHSETLOH", FRV_BUILTIN_MHSETLOH, UNKNOWN, 0}, |
8362 { CODE_FOR_mhsethis, "__MHSETHIS", FRV_BUILTIN_MHSETHIS, 0, 0 }, | 8339 { CODE_FOR_mhsethis, "__MHSETHIS", FRV_BUILTIN_MHSETHIS, UNKNOWN, 0}, |
8363 { CODE_FOR_mhsethih, "__MHSETHIH", FRV_BUILTIN_MHSETHIH, 0, 0 }, | 8340 { CODE_FOR_mhsethih, "__MHSETHIH", FRV_BUILTIN_MHSETHIH, UNKNOWN, 0}, |
8364 { CODE_FOR_mhdseth, "__MHDSETH", FRV_BUILTIN_MHDSETH, 0, 0 }, | 8341 { CODE_FOR_mhdseth, "__MHDSETH", FRV_BUILTIN_MHDSETH, UNKNOWN, 0}, |
8365 { CODE_FOR_mqsllhi, "__MQSLLHI", FRV_BUILTIN_MQSLLHI, 0, 0 }, | 8342 { CODE_FOR_mqsllhi, "__MQSLLHI", FRV_BUILTIN_MQSLLHI, UNKNOWN, 0}, |
8366 { CODE_FOR_mqsrahi, "__MQSRAHI", FRV_BUILTIN_MQSRAHI, 0, 0 } | 8343 { CODE_FOR_mqsrahi, "__MQSRAHI", FRV_BUILTIN_MQSRAHI, UNKNOWN, 0} |
8367 }; | 8344 }; |
8368 | 8345 |
8369 /* Media intrinsics that take two arguments and return void, the first argument | 8346 /* Media intrinsics that take two arguments and return void, the first argument |
8370 being a pointer to 4 words in memory. */ | 8347 being a pointer to 4 words in memory. */ |
8371 | 8348 |
8372 static struct builtin_description bdesc_void2arg[] = | 8349 static struct builtin_description bdesc_void2arg[] = |
8373 { | 8350 { |
8374 { CODE_FOR_mdunpackh, "__MDUNPACKH", FRV_BUILTIN_MDUNPACKH, 0, 0 }, | 8351 { CODE_FOR_mdunpackh, "__MDUNPACKH", FRV_BUILTIN_MDUNPACKH, UNKNOWN, 0}, |
8375 { CODE_FOR_mbtohe, "__MBTOHE", FRV_BUILTIN_MBTOHE, 0, 0 }, | 8352 { CODE_FOR_mbtohe, "__MBTOHE", FRV_BUILTIN_MBTOHE, UNKNOWN, 0}, |
8376 }; | 8353 }; |
8377 | 8354 |
8378 /* Media intrinsics that take three arguments, the first being a const_int that | 8355 /* Media intrinsics that take three arguments, the first being a const_int that |
8379 denotes an accumulator, and that return void. */ | 8356 denotes an accumulator, and that return void. */ |
8380 | 8357 |
8381 static struct builtin_description bdesc_void3arg[] = | 8358 static struct builtin_description bdesc_void3arg[] = |
8382 { | 8359 { |
8383 { CODE_FOR_mcpxrs, "__MCPXRS", FRV_BUILTIN_MCPXRS, 0, 0 }, | 8360 { CODE_FOR_mcpxrs, "__MCPXRS", FRV_BUILTIN_MCPXRS, UNKNOWN, 0}, |
8384 { CODE_FOR_mcpxru, "__MCPXRU", FRV_BUILTIN_MCPXRU, 0, 0 }, | 8361 { CODE_FOR_mcpxru, "__MCPXRU", FRV_BUILTIN_MCPXRU, UNKNOWN, 0}, |
8385 { CODE_FOR_mcpxis, "__MCPXIS", FRV_BUILTIN_MCPXIS, 0, 0 }, | 8362 { CODE_FOR_mcpxis, "__MCPXIS", FRV_BUILTIN_MCPXIS, UNKNOWN, 0}, |
8386 { CODE_FOR_mcpxiu, "__MCPXIU", FRV_BUILTIN_MCPXIU, 0, 0 }, | 8363 { CODE_FOR_mcpxiu, "__MCPXIU", FRV_BUILTIN_MCPXIU, UNKNOWN, 0}, |
8387 { CODE_FOR_mmulhs, "__MMULHS", FRV_BUILTIN_MMULHS, 0, 0 }, | 8364 { CODE_FOR_mmulhs, "__MMULHS", FRV_BUILTIN_MMULHS, UNKNOWN, 0}, |
8388 { CODE_FOR_mmulhu, "__MMULHU", FRV_BUILTIN_MMULHU, 0, 0 }, | 8365 { CODE_FOR_mmulhu, "__MMULHU", FRV_BUILTIN_MMULHU, UNKNOWN, 0}, |
8389 { CODE_FOR_mmulxhs, "__MMULXHS", FRV_BUILTIN_MMULXHS, 0, 0 }, | 8366 { CODE_FOR_mmulxhs, "__MMULXHS", FRV_BUILTIN_MMULXHS, UNKNOWN, 0}, |
8390 { CODE_FOR_mmulxhu, "__MMULXHU", FRV_BUILTIN_MMULXHU, 0, 0 }, | 8367 { CODE_FOR_mmulxhu, "__MMULXHU", FRV_BUILTIN_MMULXHU, UNKNOWN, 0}, |
8391 { CODE_FOR_mmachs, "__MMACHS", FRV_BUILTIN_MMACHS, 0, 0 }, | 8368 { CODE_FOR_mmachs, "__MMACHS", FRV_BUILTIN_MMACHS, UNKNOWN, 0}, |
8392 { CODE_FOR_mmachu, "__MMACHU", FRV_BUILTIN_MMACHU, 0, 0 }, | 8369 { CODE_FOR_mmachu, "__MMACHU", FRV_BUILTIN_MMACHU, UNKNOWN, 0}, |
8393 { CODE_FOR_mmrdhs, "__MMRDHS", FRV_BUILTIN_MMRDHS, 0, 0 }, | 8370 { CODE_FOR_mmrdhs, "__MMRDHS", FRV_BUILTIN_MMRDHS, UNKNOWN, 0}, |
8394 { CODE_FOR_mmrdhu, "__MMRDHU", FRV_BUILTIN_MMRDHU, 0, 0 }, | 8371 { CODE_FOR_mmrdhu, "__MMRDHU", FRV_BUILTIN_MMRDHU, UNKNOWN, 0}, |
8395 { CODE_FOR_mqcpxrs, "__MQCPXRS", FRV_BUILTIN_MQCPXRS, 0, 0 }, | 8372 { CODE_FOR_mqcpxrs, "__MQCPXRS", FRV_BUILTIN_MQCPXRS, UNKNOWN, 0}, |
8396 { CODE_FOR_mqcpxru, "__MQCPXRU", FRV_BUILTIN_MQCPXRU, 0, 0 }, | 8373 { CODE_FOR_mqcpxru, "__MQCPXRU", FRV_BUILTIN_MQCPXRU, UNKNOWN, 0}, |
8397 { CODE_FOR_mqcpxis, "__MQCPXIS", FRV_BUILTIN_MQCPXIS, 0, 0 }, | 8374 { CODE_FOR_mqcpxis, "__MQCPXIS", FRV_BUILTIN_MQCPXIS, UNKNOWN, 0}, |
8398 { CODE_FOR_mqcpxiu, "__MQCPXIU", FRV_BUILTIN_MQCPXIU, 0, 0 }, | 8375 { CODE_FOR_mqcpxiu, "__MQCPXIU", FRV_BUILTIN_MQCPXIU, UNKNOWN, 0}, |
8399 { CODE_FOR_mqmulhs, "__MQMULHS", FRV_BUILTIN_MQMULHS, 0, 0 }, | 8376 { CODE_FOR_mqmulhs, "__MQMULHS", FRV_BUILTIN_MQMULHS, UNKNOWN, 0}, |
8400 { CODE_FOR_mqmulhu, "__MQMULHU", FRV_BUILTIN_MQMULHU, 0, 0 }, | 8377 { CODE_FOR_mqmulhu, "__MQMULHU", FRV_BUILTIN_MQMULHU, UNKNOWN, 0}, |
8401 { CODE_FOR_mqmulxhs, "__MQMULXHS", FRV_BUILTIN_MQMULXHS, 0, 0 }, | 8378 { CODE_FOR_mqmulxhs, "__MQMULXHS", FRV_BUILTIN_MQMULXHS, UNKNOWN, 0}, |
8402 { CODE_FOR_mqmulxhu, "__MQMULXHU", FRV_BUILTIN_MQMULXHU, 0, 0 }, | 8379 { CODE_FOR_mqmulxhu, "__MQMULXHU", FRV_BUILTIN_MQMULXHU, UNKNOWN, 0}, |
8403 { CODE_FOR_mqmachs, "__MQMACHS", FRV_BUILTIN_MQMACHS, 0, 0 }, | 8380 { CODE_FOR_mqmachs, "__MQMACHS", FRV_BUILTIN_MQMACHS, UNKNOWN, 0}, |
8404 { CODE_FOR_mqmachu, "__MQMACHU", FRV_BUILTIN_MQMACHU, 0, 0 }, | 8381 { CODE_FOR_mqmachu, "__MQMACHU", FRV_BUILTIN_MQMACHU, UNKNOWN, 0}, |
8405 { CODE_FOR_mqxmachs, "__MQXMACHS", FRV_BUILTIN_MQXMACHS, 0, 0 }, | 8382 { CODE_FOR_mqxmachs, "__MQXMACHS", FRV_BUILTIN_MQXMACHS, UNKNOWN, 0}, |
8406 { CODE_FOR_mqxmacxhs, "__MQXMACXHS", FRV_BUILTIN_MQXMACXHS, 0, 0 }, | 8383 { CODE_FOR_mqxmacxhs, "__MQXMACXHS", FRV_BUILTIN_MQXMACXHS, UNKNOWN, 0}, |
8407 { CODE_FOR_mqmacxhs, "__MQMACXHS", FRV_BUILTIN_MQMACXHS, 0, 0 } | 8384 { CODE_FOR_mqmacxhs, "__MQMACXHS", FRV_BUILTIN_MQMACXHS, UNKNOWN, 0} |
8408 }; | 8385 }; |
8409 | 8386 |
8410 /* Media intrinsics that take two accumulator numbers as argument and | 8387 /* Media intrinsics that take two accumulator numbers as argument and |
8411 return void. */ | 8388 return void. */ |
8412 | 8389 |
8413 static struct builtin_description bdesc_voidacc[] = | 8390 static struct builtin_description bdesc_voidacc[] = |
8414 { | 8391 { |
8415 { CODE_FOR_maddaccs, "__MADDACCS", FRV_BUILTIN_MADDACCS, 0, 0 }, | 8392 { CODE_FOR_maddaccs, "__MADDACCS", FRV_BUILTIN_MADDACCS, UNKNOWN, 0}, |
8416 { CODE_FOR_msubaccs, "__MSUBACCS", FRV_BUILTIN_MSUBACCS, 0, 0 }, | 8393 { CODE_FOR_msubaccs, "__MSUBACCS", FRV_BUILTIN_MSUBACCS, UNKNOWN, 0}, |
8417 { CODE_FOR_masaccs, "__MASACCS", FRV_BUILTIN_MASACCS, 0, 0 }, | 8394 { CODE_FOR_masaccs, "__MASACCS", FRV_BUILTIN_MASACCS, UNKNOWN, 0}, |
8418 { CODE_FOR_mdaddaccs, "__MDADDACCS", FRV_BUILTIN_MDADDACCS, 0, 0 }, | 8395 { CODE_FOR_mdaddaccs, "__MDADDACCS", FRV_BUILTIN_MDADDACCS, UNKNOWN, 0}, |
8419 { CODE_FOR_mdsubaccs, "__MDSUBACCS", FRV_BUILTIN_MDSUBACCS, 0, 0 }, | 8396 { CODE_FOR_mdsubaccs, "__MDSUBACCS", FRV_BUILTIN_MDSUBACCS, UNKNOWN, 0}, |
8420 { CODE_FOR_mdasaccs, "__MDASACCS", FRV_BUILTIN_MDASACCS, 0, 0 } | 8397 { CODE_FOR_mdasaccs, "__MDASACCS", FRV_BUILTIN_MDASACCS, UNKNOWN, 0} |
8421 }; | 8398 }; |
8422 | 8399 |
8423 /* Intrinsics that load a value and then issue a MEMBAR. The load is | 8400 /* Intrinsics that load a value and then issue a MEMBAR. The load is |
8424 a normal move and the ICODE is for the membar. */ | 8401 a normal move and the ICODE is for the membar. */ |
8425 | 8402 |
8426 static struct builtin_description bdesc_loads[] = | 8403 static struct builtin_description bdesc_loads[] = |
8427 { | 8404 { |
8428 { CODE_FOR_optional_membar_qi, "__builtin_read8", | 8405 { CODE_FOR_optional_membar_qi, "__builtin_read8", |
8429 FRV_BUILTIN_READ8, 0, 0 }, | 8406 FRV_BUILTIN_READ8, UNKNOWN, 0}, |
8430 { CODE_FOR_optional_membar_hi, "__builtin_read16", | 8407 { CODE_FOR_optional_membar_hi, "__builtin_read16", |
8431 FRV_BUILTIN_READ16, 0, 0 }, | 8408 FRV_BUILTIN_READ16, UNKNOWN, 0}, |
8432 { CODE_FOR_optional_membar_si, "__builtin_read32", | 8409 { CODE_FOR_optional_membar_si, "__builtin_read32", |
8433 FRV_BUILTIN_READ32, 0, 0 }, | 8410 FRV_BUILTIN_READ32, UNKNOWN, 0}, |
8434 { CODE_FOR_optional_membar_di, "__builtin_read64", | 8411 { CODE_FOR_optional_membar_di, "__builtin_read64", |
8435 FRV_BUILTIN_READ64, 0, 0 } | 8412 FRV_BUILTIN_READ64, UNKNOWN, 0} |
8436 }; | 8413 }; |
8437 | 8414 |
8438 /* Likewise stores. */ | 8415 /* Likewise stores. */ |
8439 | 8416 |
8440 static struct builtin_description bdesc_stores[] = | 8417 static struct builtin_description bdesc_stores[] = |
8441 { | 8418 { |
8442 { CODE_FOR_optional_membar_qi, "__builtin_write8", | 8419 { CODE_FOR_optional_membar_qi, "__builtin_write8", |
8443 FRV_BUILTIN_WRITE8, 0, 0 }, | 8420 FRV_BUILTIN_WRITE8, UNKNOWN, 0}, |
8444 { CODE_FOR_optional_membar_hi, "__builtin_write16", | 8421 { CODE_FOR_optional_membar_hi, "__builtin_write16", |
8445 FRV_BUILTIN_WRITE16, 0, 0 }, | 8422 FRV_BUILTIN_WRITE16, UNKNOWN, 0}, |
8446 { CODE_FOR_optional_membar_si, "__builtin_write32", | 8423 { CODE_FOR_optional_membar_si, "__builtin_write32", |
8447 FRV_BUILTIN_WRITE32, 0, 0 }, | 8424 FRV_BUILTIN_WRITE32, UNKNOWN, 0}, |
8448 { CODE_FOR_optional_membar_di, "__builtin_write64", | 8425 { CODE_FOR_optional_membar_di, "__builtin_write64", |
8449 FRV_BUILTIN_WRITE64, 0, 0 }, | 8426 FRV_BUILTIN_WRITE64, UNKNOWN, 0}, |
8450 }; | 8427 }; |
8451 | 8428 |
8452 /* Initialize media builtins. */ | 8429 /* Initialize media builtins. */ |
8453 | 8430 |
8454 static void | 8431 static void |
8799 Return the value as an rtx. */ | 8776 Return the value as an rtx. */ |
8800 | 8777 |
8801 static rtx | 8778 static rtx |
8802 frv_read_argument (tree exp, unsigned int index) | 8779 frv_read_argument (tree exp, unsigned int index) |
8803 { | 8780 { |
8804 return expand_expr (CALL_EXPR_ARG (exp, index), | 8781 return expand_normal (CALL_EXPR_ARG (exp, index)); |
8805 NULL_RTX, VOIDmode, 0); | |
8806 } | 8782 } |
8807 | 8783 |
8808 /* Like frv_read_argument, but interpret the argument as the number | 8784 /* Like frv_read_argument, but interpret the argument as the number |
8809 of an IACC register and return a (reg:MODE ...) rtx for it. */ | 8785 of an IACC register and return a (reg:MODE ...) rtx for it. */ |
8810 | 8786 |
9563 return true; | 9539 return true; |
9564 return false; | 9540 return false; |
9565 } | 9541 } |
9566 | 9542 |
9567 size = int_size_in_bytes (TREE_TYPE (decl)); | 9543 size = int_size_in_bytes (TREE_TYPE (decl)); |
9568 if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value) | 9544 if (size > 0 && size <= g_switch_value) |
9569 return true; | 9545 return true; |
9570 | 9546 |
9571 return false; | 9547 return false; |
9572 } | 9548 } |
9573 | 9549 |
9588 | 9564 |
9589 switch (code) | 9565 switch (code) |
9590 { | 9566 { |
9591 case CONST_INT: | 9567 case CONST_INT: |
9592 /* Make 12-bit integers really cheap. */ | 9568 /* Make 12-bit integers really cheap. */ |
9593 if (IN_RANGE_P (INTVAL (x), -2048, 2047)) | 9569 if (IN_RANGE (INTVAL (x), -2048, 2047)) |
9594 { | 9570 { |
9595 *total = 0; | 9571 *total = 0; |
9596 return true; | 9572 return true; |
9597 } | 9573 } |
9598 /* Fall through. */ | 9574 /* Fall through. */ |