comparison gcc/config/v850/v850.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Subroutines for insn-output.c for NEC V850 series 1 /* Subroutines for insn-output.c for NEC V850 series
2 Copyright (C) 1996-2017 Free Software Foundation, Inc. 2 Copyright (C) 1996-2018 Free Software Foundation, Inc.
3 Contributed by Jeff Law (law@cygnus.com). 3 Contributed by Jeff Law (law@cygnus.com).
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 it 7 GCC is free software; you can redistribute it and/or modify it
15 for more details. 15 for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see 18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */ 19 <http://www.gnu.org/licenses/>. */
20
21 #define IN_TARGET_CODE 1
20 22
21 #include "config.h" 23 #include "config.h"
22 #include "system.h" 24 #include "system.h"
23 #include "coretypes.h" 25 #include "coretypes.h"
24 #include "backend.h" 26 #include "backend.h"
64 66
65 /* True if we don't need to check any more if the current 67 /* True if we don't need to check any more if the current
66 function is an interrupt handler. */ 68 function is an interrupt handler. */
67 static int v850_interrupt_cache_p = FALSE; 69 static int v850_interrupt_cache_p = FALSE;
68 70
69 rtx v850_compare_op0, v850_compare_op1;
70
71 /* Whether current function is an interrupt handler. */ 71 /* Whether current function is an interrupt handler. */
72 static int v850_interrupt_p = FALSE; 72 static int v850_interrupt_p = FALSE;
73 73
74 static GTY(()) section * rosdata_section; 74 static GTY(()) section * rosdata_section;
75 static GTY(()) section * rozdata_section; 75 static GTY(()) section * rozdata_section;
414 } 414 }
415 /* Fall through. */ 415 /* Fall through. */
416 case 'b': 416 case 'b':
417 case 'B': 417 case 'B':
418 case 'C': 418 case 'C':
419 switch ((code == 'B' || code == 'C') 419 case 'd':
420 case 'D':
421 switch ((code == 'B' || code == 'C' || code == 'D')
420 ? reverse_condition (GET_CODE (x)) : GET_CODE (x)) 422 ? reverse_condition (GET_CODE (x)) : GET_CODE (x))
421 { 423 {
422 case NE: 424 case NE:
423 if (code == 'c' || code == 'C') 425 if (code == 'c' || code == 'C')
424 fprintf (file, "nz"); 426 fprintf (file, "nz");
430 fprintf (file, "z"); 432 fprintf (file, "z");
431 else 433 else
432 fprintf (file, "e"); 434 fprintf (file, "e");
433 break; 435 break;
434 case GE: 436 case GE:
435 fprintf (file, "ge"); 437 if (code == 'D' || code == 'd')
438 fprintf (file, "p");
439 else
440 fprintf (file, "ge");
436 break; 441 break;
437 case GT: 442 case GT:
438 fprintf (file, "gt"); 443 fprintf (file, "gt");
439 break; 444 break;
440 case LE: 445 case LE:
441 fprintf (file, "le"); 446 fprintf (file, "le");
442 break; 447 break;
443 case LT: 448 case LT:
444 fprintf (file, "lt"); 449 if (code == 'D' || code == 'd')
450 fprintf (file, "n");
451 else
452 fprintf (file, "lt");
445 break; 453 break;
446 case GEU: 454 case GEU:
447 fprintf (file, "nl"); 455 fprintf (file, "nl");
448 break; 456 break;
449 case GTU: 457 case GTU:
901 fatal_insn ("output_move_single:", gen_rtx_SET (dst, src)); 909 fatal_insn ("output_move_single:", gen_rtx_SET (dst, src));
902 return ""; 910 return "";
903 } 911 }
904 912
905 machine_mode 913 machine_mode
906 v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1 ATTRIBUTE_UNUSED) 914 v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
907 { 915 {
908 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT) 916 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
909 { 917 {
910 switch (cond) 918 switch (cond)
911 { 919 {
923 return CC_FPU_NEmode; 931 return CC_FPU_NEmode;
924 default: 932 default:
925 gcc_unreachable (); 933 gcc_unreachable ();
926 } 934 }
927 } 935 }
936
937 if (op1 == const0_rtx
938 && (cond == EQ || cond == NE || cond == LT || cond == GE)
939 && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
940 || GET_CODE (op0) == NEG || GET_CODE (op0) == AND
941 || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
942 || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT))
943 return CCNZmode;
944
928 return CCmode; 945 return CCmode;
929 } 946 }
930 947
931 machine_mode 948 machine_mode
932 v850_gen_float_compare (enum rtx_code cond, machine_mode mode ATTRIBUTE_UNUSED, rtx op0, rtx op1) 949 v850_gen_float_compare (enum rtx_code cond, machine_mode mode, rtx op0, rtx op1)
933 { 950 {
934 if (GET_MODE (op0) == DFmode) 951 if (GET_MODE (op0) == DFmode)
935 { 952 {
936 switch (cond) 953 switch (cond)
937 { 954 {
956 break; 973 break;
957 default: 974 default:
958 gcc_unreachable (); 975 gcc_unreachable ();
959 } 976 }
960 } 977 }
961 else if (GET_MODE (v850_compare_op0) == SFmode) 978 else if (mode == SFmode)
962 { 979 {
963 switch (cond) 980 switch (cond)
964 { 981 {
965 case LE: 982 case LE:
966 emit_insn (gen_cmpsf_le_insn(op0, op1)); 983 emit_insn (gen_cmpsf_le_insn(op0, op1));
987 } 1004 }
988 else 1005 else
989 gcc_unreachable (); 1006 gcc_unreachable ();
990 1007
991 return v850_select_cc_mode (cond, op0, op1); 1008 return v850_select_cc_mode (cond, op0, op1);
992 }
993
994 rtx
995 v850_gen_compare (enum rtx_code cond, machine_mode mode, rtx op0, rtx op1)
996 {
997 if (GET_MODE_CLASS(GET_MODE (op0)) != MODE_FLOAT)
998 {
999 emit_insn (gen_cmpsi_insn (op0, op1));
1000 return gen_rtx_fmt_ee (cond, mode, gen_rtx_REG(CCmode, CC_REGNUM), const0_rtx);
1001 }
1002 else
1003 {
1004 rtx cc_reg;
1005 mode = v850_gen_float_compare (cond, mode, op0, op1);
1006 cc_reg = gen_rtx_REG (mode, CC_REGNUM);
1007 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_REG (mode, FCC_REGNUM)));
1008
1009 return gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
1010 }
1011 } 1009 }
1012 1010
1013 /* Return maximum offset supported for a short EP memory reference of mode 1011 /* Return maximum offset supported for a short EP memory reference of mode
1014 MODE and signedness UNSIGNEDP. */ 1012 MODE and signedness UNSIGNEDP. */
1015 1013
1570 (hard) frame pointer | | / | | addresses 1568 (hard) frame pointer | | / | | addresses
1571 and stack pointer -> | | / _|_ | 1569 and stack pointer -> | | / _|_ |
1572 -------------------------- ---- ------------------ V */ 1570 -------------------------- ---- ------------------ V */
1573 1571
1574 int 1572 int
1575 compute_frame_size (int size, long * p_reg_saved) 1573 compute_frame_size (poly_int64 size, long * p_reg_saved)
1576 { 1574 {
1577 return (size 1575 return (size
1578 + compute_register_save_size (p_reg_saved) 1576 + compute_register_save_size (p_reg_saved)
1579 + crtl->outgoing_args_size); 1577 + crtl->outgoing_args_size);
1580 } 1578 }
1631 if (in_prologue) 1629 if (in_prologue)
1632 F (inc); 1630 F (inc);
1633 inc = reg; 1631 inc = reg;
1634 } 1632 }
1635 1633
1636 inc = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, inc)); 1634 inc = emit_insn (gen_addsi3_clobber_flags (stack_pointer_rtx, stack_pointer_rtx, inc));
1637 if (in_prologue) 1635 if (in_prologue)
1638 F (inc); 1636 F (inc);
1639 } 1637 }
1640 1638
1641 void 1639 void
1708 int alloc_stack = 4 * num_save; 1706 int alloc_stack = 4 * num_save;
1709 int offset = 0; 1707 int offset = 0;
1710 1708
1711 save_all = gen_rtx_PARALLEL 1709 save_all = gen_rtx_PARALLEL
1712 (VOIDmode, 1710 (VOIDmode,
1713 rtvec_alloc (num_save + 1 1711 rtvec_alloc (num_save + 2
1714 + (TARGET_DISABLE_CALLT ? (TARGET_LONG_CALLS ? 2 : 1) : 0))); 1712 + (TARGET_DISABLE_CALLT ? (TARGET_LONG_CALLS ? 2 : 1) : 0)));
1715 1713
1716 XVECEXP (save_all, 0, 0) 1714 XVECEXP (save_all, 0, 0)
1717 = gen_rtx_SET (stack_pointer_rtx, 1715 = gen_rtx_SET (stack_pointer_rtx,
1718 gen_rtx_PLUS (Pmode, 1716 gen_rtx_PLUS (Pmode,
1727 stack_pointer_rtx, 1725 stack_pointer_rtx,
1728 GEN_INT(offset))), 1726 GEN_INT(offset))),
1729 save_regs[i]); 1727 save_regs[i]);
1730 } 1728 }
1731 1729
1730 XVECEXP (save_all, 0, num_save + 1)
1731 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, CC_REGNUM));
1732
1732 if (TARGET_DISABLE_CALLT) 1733 if (TARGET_DISABLE_CALLT)
1733 { 1734 {
1734 XVECEXP (save_all, 0, num_save + 1) 1735 XVECEXP (save_all, 0, num_save + 2)
1735 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10)); 1736 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10));
1736 1737
1737 if (TARGET_LONG_CALLS) 1738 if (TARGET_LONG_CALLS)
1738 XVECEXP (save_all, 0, num_save + 2) 1739 XVECEXP (save_all, 0, num_save + 3)
1739 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11)); 1740 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
1740 } 1741 }
1741 1742
1742 v850_all_frame_related (save_all); 1743 v850_all_frame_related (save_all);
1743 1744
1981 1982
1982 v850_interrupt_cache_p = FALSE; 1983 v850_interrupt_cache_p = FALSE;
1983 v850_interrupt_p = FALSE; 1984 v850_interrupt_p = FALSE;
1984 } 1985 }
1985 1986
1986 /* Update the condition code from the insn. */
1987 void
1988 notice_update_cc (rtx body, rtx_insn *insn)
1989 {
1990 switch (get_attr_cc (insn))
1991 {
1992 case CC_NONE:
1993 /* Insn does not affect CC at all. */
1994 break;
1995
1996 case CC_NONE_0HIT:
1997 /* Insn does not change CC, but the 0'th operand has been changed. */
1998 if (cc_status.value1 != 0
1999 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
2000 cc_status.value1 = 0;
2001 break;
2002
2003 case CC_SET_ZN:
2004 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
2005 V,C is in an unusable state. */
2006 CC_STATUS_INIT;
2007 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
2008 cc_status.value1 = recog_data.operand[0];
2009 break;
2010
2011 case CC_SET_ZNV:
2012 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
2013 C is in an unusable state. */
2014 CC_STATUS_INIT;
2015 cc_status.flags |= CC_NO_CARRY;
2016 cc_status.value1 = recog_data.operand[0];
2017 break;
2018
2019 case CC_COMPARE:
2020 /* The insn is a compare instruction. */
2021 CC_STATUS_INIT;
2022 cc_status.value1 = SET_SRC (body);
2023 break;
2024
2025 case CC_CLOBBER:
2026 /* Insn doesn't leave CC in a usable state. */
2027 CC_STATUS_INIT;
2028 break;
2029
2030 default:
2031 break;
2032 }
2033 }
2034
2035 /* Retrieve the data area that has been chosen for the given decl. */ 1987 /* Retrieve the data area that has been chosen for the given decl. */
2036 1988
2037 v850_data_area 1989 v850_data_area
2038 v850_get_data_area (tree decl) 1990 v850_get_data_area (tree decl)
2039 { 1991 {
2070 } 2022 }
2071 2023
2072 /* Handle an "interrupt" attribute; arguments as in 2024 /* Handle an "interrupt" attribute; arguments as in
2073 struct attribute_spec.handler. */ 2025 struct attribute_spec.handler. */
2074 static tree 2026 static tree
2075 v850_handle_interrupt_attribute (tree * node, 2027 v850_handle_interrupt_attribute (tree *node, tree name,
2076 tree name,
2077 tree args ATTRIBUTE_UNUSED, 2028 tree args ATTRIBUTE_UNUSED,
2078 int flags ATTRIBUTE_UNUSED, 2029 int flags ATTRIBUTE_UNUSED,
2079 bool * no_add_attrs) 2030 bool * no_add_attrs)
2080 { 2031 {
2081 if (TREE_CODE (*node) != FUNCTION_DECL) 2032 if (TREE_CODE (*node) != FUNCTION_DECL)
2089 } 2040 }
2090 2041
2091 /* Handle a "sda", "tda" or "zda" attribute; arguments as in 2042 /* Handle a "sda", "tda" or "zda" attribute; arguments as in
2092 struct attribute_spec.handler. */ 2043 struct attribute_spec.handler. */
2093 static tree 2044 static tree
2094 v850_handle_data_area_attribute (tree* node, 2045 v850_handle_data_area_attribute (tree *node, tree name,
2095 tree name,
2096 tree args ATTRIBUTE_UNUSED, 2046 tree args ATTRIBUTE_UNUSED,
2097 int flags ATTRIBUTE_UNUSED, 2047 int flags ATTRIBUTE_UNUSED,
2098 bool * no_add_attrs) 2048 bool * no_add_attrs)
2099 { 2049 {
2100 v850_data_area data_area; 2050 v850_data_area data_area;
2377 /* Work out how many bytes to push onto the stack after storing the 2327 /* Work out how many bytes to push onto the stack after storing the
2378 registers. */ 2328 registers. */
2379 stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)); 2329 stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1));
2380 2330
2381 /* Each push will put 4 bytes from the stack.... */ 2331 /* Each push will put 4 bytes from the stack.... */
2382 stack_bytes += (count - (TARGET_LONG_CALLS ? 3 : 2)) * 4; 2332 stack_bytes += (count - (TARGET_LONG_CALLS ? 4 : 3)) * 4;
2383 2333
2384 /* Make sure that the amount we are popping either 0 or 16 bytes. */ 2334 /* Make sure that the amount we are popping either 0 or 16 bytes. */
2385 if (stack_bytes != 0) 2335 if (stack_bytes != 0)
2386 { 2336 {
2387 error ("bad amount of stack space removal: %d", stack_bytes); 2337 error ("bad amount of stack space removal: %d", stack_bytes);
2388 return NULL; 2338 return NULL;
2389 } 2339 }
2390 2340
2391 /* Now compute the bit mask of registers to push. */ 2341 /* Now compute the bit mask of registers to push. */
2392 mask = 0; 2342 mask = 0;
2393 for (i = 1; i < count - (TARGET_LONG_CALLS ? 2 : 1); i++) 2343 for (i = 1; i < count - (TARGET_LONG_CALLS ? 3 : 2); i++)
2394 { 2344 {
2395 rtx vector_element = XVECEXP (op, 0, i); 2345 rtx vector_element = XVECEXP (op, 0, i);
2396 2346
2397 gcc_assert (GET_CODE (vector_element) == SET); 2347 gcc_assert (GET_CODE (vector_element) == SET);
2398 gcc_assert (GET_CODE (SET_SRC (vector_element)) == REG); 2348 gcc_assert (GET_CODE (SET_SRC (vector_element)) == REG);
3127 if (special_symbolref_operand (x, mode) 3077 if (special_symbolref_operand (x, mode)
3128 && (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))) 3078 && (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode)))
3129 return true; 3079 return true;
3130 if (GET_CODE (x) == PLUS 3080 if (GET_CODE (x) == PLUS
3131 && v850_rtx_ok_for_base_p (XEXP (x, 0), strict_p) 3081 && v850_rtx_ok_for_base_p (XEXP (x, 0), strict_p)
3132 && constraint_satisfied_p (XEXP (x,1), CONSTRAINT_K) 3082 && (constraint_satisfied_p (XEXP (x, 1), CONSTRAINT_K)
3083 || (TARGET_V850E2V3_UP
3084 && (mode == SImode || mode == HImode || mode == QImode)
3085 && constraint_satisfied_p (XEXP (x, 1), CONSTRAINT_W)))
3133 && ((mode == QImode || INTVAL (XEXP (x, 1)) % 2 == 0) 3086 && ((mode == QImode || INTVAL (XEXP (x, 1)) % 2 == 0)
3134 && CONST_OK_FOR_K (INTVAL (XEXP (x, 1)) 3087 && CONST_OK_FOR_K (INTVAL (XEXP (x, 1))
3135 + (GET_MODE_NUNITS (mode) * UNITS_PER_WORD)))) 3088 + (GET_MODE_NUNITS (mode) * UNITS_PER_WORD))))
3136 return true; 3089 return true;
3137 3090
3185 3138
3186 /* V850 specific attributes. */ 3139 /* V850 specific attributes. */
3187 3140
3188 static const struct attribute_spec v850_attribute_table[] = 3141 static const struct attribute_spec v850_attribute_table[] =
3189 { 3142 {
3190 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, 3143 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
3191 affects_type_identity } */ 3144 affects_type_identity, handler, exclude } */
3192 { "interrupt_handler", 0, 0, true, false, false, 3145 { "interrupt_handler", 0, 0, true, false, false, false,
3193 v850_handle_interrupt_attribute, false }, 3146 v850_handle_interrupt_attribute, NULL },
3194 { "interrupt", 0, 0, true, false, false, 3147 { "interrupt", 0, 0, true, false, false, false,
3195 v850_handle_interrupt_attribute, false }, 3148 v850_handle_interrupt_attribute, NULL },
3196 { "sda", 0, 0, true, false, false, 3149 { "sda", 0, 0, true, false, false, false,
3197 v850_handle_data_area_attribute, false }, 3150 v850_handle_data_area_attribute, NULL },
3198 { "tda", 0, 0, true, false, false, 3151 { "tda", 0, 0, true, false, false, false,
3199 v850_handle_data_area_attribute, false }, 3152 v850_handle_data_area_attribute, NULL },
3200 { "zda", 0, 0, true, false, false, 3153 { "zda", 0, 0, true, false, false, false,
3201 v850_handle_data_area_attribute, false }, 3154 v850_handle_data_area_attribute, NULL },
3202 { NULL, 0, 0, false, false, false, NULL, false } 3155 { NULL, 0, 0, false, false, false, false, NULL, NULL }
3203 }; 3156 };
3204 3157
3205 static void 3158 static void
3206 v850_option_override (void) 3159 v850_option_override (void)
3207 { 3160 {
3357 #define TARGET_TRAMPOLINE_INIT v850_trampoline_init 3310 #define TARGET_TRAMPOLINE_INIT v850_trampoline_init
3358 3311
3359 #undef TARGET_LEGITIMATE_CONSTANT_P 3312 #undef TARGET_LEGITIMATE_CONSTANT_P
3360 #define TARGET_LEGITIMATE_CONSTANT_P v850_legitimate_constant_p 3313 #define TARGET_LEGITIMATE_CONSTANT_P v850_legitimate_constant_p
3361 3314
3362 #undef TARGET_LRA_P
3363 #define TARGET_LRA_P hook_bool_void_false
3364
3365 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P 3315 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
3366 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P v850_legitimate_address_p 3316 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P v850_legitimate_address_p
3367 3317
3368 #undef TARGET_CAN_USE_DOLOOP_P 3318 #undef TARGET_CAN_USE_DOLOOP_P
3369 #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost 3319 #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
3372 #define TARGET_HARD_REGNO_MODE_OK v850_hard_regno_mode_ok 3322 #define TARGET_HARD_REGNO_MODE_OK v850_hard_regno_mode_ok
3373 3323
3374 #undef TARGET_MODES_TIEABLE_P 3324 #undef TARGET_MODES_TIEABLE_P
3375 #define TARGET_MODES_TIEABLE_P v850_modes_tieable_p 3325 #define TARGET_MODES_TIEABLE_P v850_modes_tieable_p
3376 3326
3327 #undef TARGET_FLAGS_REGNUM
3328 #define TARGET_FLAGS_REGNUM 32
3329
3330 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
3331 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
3332
3377 struct gcc_target targetm = TARGET_INITIALIZER; 3333 struct gcc_target targetm = TARGET_INITIALIZER;
3378 3334
3379 #include "gt-v850.h" 3335 #include "gt-v850.h"