Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/frv/frv.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 /* Copyright (C) 1997-2017 Free Software Foundation, Inc. | 1 /* Copyright (C) 1997-2018 Free Software Foundation, Inc. |
2 Contributed by Red Hat, Inc. | 2 Contributed by Red Hat, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify | 6 GCC is free software; you can redistribute it and/or modify |
14 GNU General Public License for more details. | 14 GNU General Public License for more details. |
15 | 15 |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with GCC; see the file COPYING3. If not see | 17 along with GCC; see the file COPYING3. If not see |
18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
19 | |
20 #define IN_TARGET_CODE 1 | |
19 | 21 |
20 #include "config.h" | 22 #include "config.h" |
21 #include "system.h" | 23 #include "system.h" |
22 #include "coretypes.h" | 24 #include "coretypes.h" |
23 #include "backend.h" | 25 #include "backend.h" |
314 static rtx frv_expand_mrdacc_builtin (enum insn_code, tree); | 316 static rtx frv_expand_mrdacc_builtin (enum insn_code, tree); |
315 static rtx frv_expand_mwtacc_builtin (enum insn_code, tree); | 317 static rtx frv_expand_mwtacc_builtin (enum insn_code, tree); |
316 static rtx frv_expand_noargs_builtin (enum insn_code); | 318 static rtx frv_expand_noargs_builtin (enum insn_code); |
317 static void frv_split_iacc_move (rtx, rtx); | 319 static void frv_split_iacc_move (rtx, rtx); |
318 static rtx frv_emit_comparison (enum rtx_code, rtx, rtx); | 320 static rtx frv_emit_comparison (enum rtx_code, rtx, rtx); |
319 static void frv_ifcvt_add_insn (rtx, rtx, int); | 321 static void frv_ifcvt_add_insn (rtx, rtx_insn *, int); |
320 static rtx frv_ifcvt_rewrite_mem (rtx, machine_mode, rtx); | 322 static rtx frv_ifcvt_rewrite_mem (rtx, machine_mode, rtx); |
321 static rtx frv_ifcvt_load_value (rtx, rtx); | 323 static rtx frv_ifcvt_load_value (rtx, rtx); |
322 static unsigned int frv_insn_unit (rtx_insn *); | 324 static unsigned int frv_insn_unit (rtx_insn *); |
323 static bool frv_issues_to_branch_unit_p (rtx_insn *); | 325 static bool frv_issues_to_branch_unit_p (rtx_insn *); |
324 static int frv_cond_flags (rtx); | 326 static int frv_cond_flags (rtx); |
523 #define TARGET_HARD_REGNO_MODE_OK frv_hard_regno_mode_ok | 525 #define TARGET_HARD_REGNO_MODE_OK frv_hard_regno_mode_ok |
524 #undef TARGET_MODES_TIEABLE_P | 526 #undef TARGET_MODES_TIEABLE_P |
525 #define TARGET_MODES_TIEABLE_P frv_modes_tieable_p | 527 #define TARGET_MODES_TIEABLE_P frv_modes_tieable_p |
526 #undef TARGET_CONSTANT_ALIGNMENT | 528 #undef TARGET_CONSTANT_ALIGNMENT |
527 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings | 529 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings |
530 | |
531 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE | |
532 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed | |
528 | 533 |
529 struct gcc_target targetm = TARGET_INITIALIZER; | 534 struct gcc_target targetm = TARGET_INITIALIZER; |
530 | 535 |
531 #define FRV_SYMBOL_REF_TLS_P(RTX) \ | 536 #define FRV_SYMBOL_REF_TLS_P(RTX) \ |
532 (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0) | 537 (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0) |
1411 will return correctly. It also does the VLIW packing. */ | 1416 will return correctly. It also does the VLIW packing. */ |
1412 | 1417 |
1413 static void | 1418 static void |
1414 frv_function_prologue (FILE *file) | 1419 frv_function_prologue (FILE *file) |
1415 { | 1420 { |
1416 rtx_insn *insn, *next, *last_call; | |
1417 | |
1418 /* If no frame was created, check whether the function uses a call | 1421 /* If no frame was created, check whether the function uses a call |
1419 instruction to implement a far jump. If so, save the link in gr3 and | 1422 instruction to implement a far jump. If so, save the link in gr3 and |
1420 replace all returns to LR with returns to GR3. GR3 is used because it | 1423 replace all returns to LR with returns to GR3. GR3 is used because it |
1421 is call-clobbered, because is not available to the register allocator, | 1424 is call-clobbered, because is not available to the register allocator, |
1422 and because all functions that take a hidden argument pointer will have | 1425 and because all functions that take a hidden argument pointer will have |
1453 | 1456 |
1454 frv_pack_insns (); | 1457 frv_pack_insns (); |
1455 | 1458 |
1456 /* Allow the garbage collector to free the nops created by frv_reorg. */ | 1459 /* Allow the garbage collector to free the nops created by frv_reorg. */ |
1457 memset (frv_nops, 0, sizeof (frv_nops)); | 1460 memset (frv_nops, 0, sizeof (frv_nops)); |
1458 | |
1459 /* Locate CALL_ARG_LOCATION notes that have been misplaced | |
1460 and move them back to where they should be located. */ | |
1461 last_call = NULL; | |
1462 for (insn = get_insns (); insn; insn = next) | |
1463 { | |
1464 next = NEXT_INSN (insn); | |
1465 if (CALL_P (insn) | |
1466 || (INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE | |
1467 && CALL_P (XVECEXP (PATTERN (insn), 0, 0)))) | |
1468 last_call = insn; | |
1469 | |
1470 if (!NOTE_P (insn) || NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION) | |
1471 continue; | |
1472 | |
1473 if (NEXT_INSN (last_call) == insn) | |
1474 continue; | |
1475 | |
1476 SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn); | |
1477 SET_PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn); | |
1478 SET_PREV_INSN (insn) = last_call; | |
1479 SET_NEXT_INSN (insn) = NEXT_INSN (last_call); | |
1480 SET_PREV_INSN (NEXT_INSN (insn)) = insn; | |
1481 SET_NEXT_INSN (PREV_INSN (insn)) = insn; | |
1482 last_call = insn; | |
1483 } | |
1484 } | 1461 } |
1485 | 1462 |
1486 | 1463 |
1487 /* Return the next available temporary register in a given class. */ | 1464 /* Return the next available temporary register in a given class. */ |
1488 | 1465 |
5184 | 5161 |
5185 /* Internal function to add a potential insn to the list of insns to be inserted | 5162 /* Internal function to add a potential insn to the list of insns to be inserted |
5186 if the conditional execution conversion is successful. */ | 5163 if the conditional execution conversion is successful. */ |
5187 | 5164 |
5188 static void | 5165 static void |
5189 frv_ifcvt_add_insn (rtx pattern, rtx insn, int before_p) | 5166 frv_ifcvt_add_insn (rtx pattern, rtx_insn *insn, int before_p) |
5190 { | 5167 { |
5191 rtx link = alloc_EXPR_LIST (VOIDmode, pattern, insn); | 5168 rtx link = alloc_EXPR_LIST (VOIDmode, pattern, insn); |
5192 | 5169 |
5193 link->jump = before_p; /* Mark to add this before or after insn. */ | 5170 link->jump = before_p; /* Mark to add this before or after insn. */ |
5194 frv_ifcvt.added_insns_list = alloc_EXPR_LIST (VOIDmode, link, | 5171 frv_ifcvt.added_insns_list = alloc_EXPR_LIST (VOIDmode, link, |
5866 insn cannot be converted to be executed conditionally. */ | 5843 insn cannot be converted to be executed conditionally. */ |
5867 | 5844 |
5868 rtx | 5845 rtx |
5869 frv_ifcvt_modify_insn (ce_if_block *ce_info, | 5846 frv_ifcvt_modify_insn (ce_if_block *ce_info, |
5870 rtx pattern, | 5847 rtx pattern, |
5871 rtx insn) | 5848 rtx_insn *insn) |
5872 { | 5849 { |
5873 rtx orig_ce_pattern = pattern; | 5850 rtx orig_ce_pattern = pattern; |
5874 rtx set; | 5851 rtx set; |
5875 rtx op0; | 5852 rtx op0; |
5876 rtx op1; | 5853 rtx op1; |
6130 conditional if information CE_INFO. */ | 6107 conditional if information CE_INFO. */ |
6131 | 6108 |
6132 void | 6109 void |
6133 frv_ifcvt_modify_final (ce_if_block *ce_info ATTRIBUTE_UNUSED) | 6110 frv_ifcvt_modify_final (ce_if_block *ce_info ATTRIBUTE_UNUSED) |
6134 { | 6111 { |
6135 rtx existing_insn; | 6112 rtx_insn *existing_insn; |
6136 rtx check_insn; | 6113 rtx check_insn; |
6137 rtx p = frv_ifcvt.added_insns_list; | 6114 rtx p = frv_ifcvt.added_insns_list; |
6138 int i; | 6115 int i; |
6139 | 6116 |
6140 /* Loop inserting the check insns. The last check insn is the first test, | 6117 /* Loop inserting the check insns. The last check insn is the first test, |
6145 { | 6122 { |
6146 rtx check_and_insert_insns = XEXP (p, 0); | 6123 rtx check_and_insert_insns = XEXP (p, 0); |
6147 rtx old_p = p; | 6124 rtx old_p = p; |
6148 | 6125 |
6149 check_insn = XEXP (check_and_insert_insns, 0); | 6126 check_insn = XEXP (check_and_insert_insns, 0); |
6150 existing_insn = XEXP (check_and_insert_insns, 1); | 6127 existing_insn = as_a <rtx_insn *> (XEXP (check_and_insert_insns, 1)); |
6151 p = XEXP (p, 1); | 6128 p = XEXP (p, 1); |
6152 | 6129 |
6153 /* The jump bit is used to say that the new insn is to be inserted BEFORE | 6130 /* The jump bit is used to say that the new insn is to be inserted BEFORE |
6154 the existing insn, otherwise it is to be inserted AFTER. */ | 6131 the existing insn, otherwise it is to be inserted AFTER. */ |
6155 if (check_and_insert_insns->jump) | 6132 if (check_and_insert_insns->jump) |
6166 while (p != NULL_RTX); | 6143 while (p != NULL_RTX); |
6167 | 6144 |
6168 /* Load up any constants needed into temp gprs */ | 6145 /* Load up any constants needed into temp gprs */ |
6169 for (i = 0; i < frv_ifcvt.cur_scratch_regs; i++) | 6146 for (i = 0; i < frv_ifcvt.cur_scratch_regs; i++) |
6170 { | 6147 { |
6171 rtx insn = emit_insn_before (frv_ifcvt.scratch_regs[i], existing_insn); | 6148 rtx_insn *insn = emit_insn_before (frv_ifcvt.scratch_regs[i], existing_insn); |
6172 if (! frv_ifcvt.scratch_insns_bitmap) | 6149 if (! frv_ifcvt.scratch_insns_bitmap) |
6173 frv_ifcvt.scratch_insns_bitmap = BITMAP_ALLOC (NULL); | 6150 frv_ifcvt.scratch_insns_bitmap = BITMAP_ALLOC (NULL); |
6174 bitmap_set_bit (frv_ifcvt.scratch_insns_bitmap, INSN_UID (insn)); | 6151 bitmap_set_bit (frv_ifcvt.scratch_insns_bitmap, INSN_UID (insn)); |
6175 frv_ifcvt.scratch_regs[i] = NULL_RTX; | 6152 frv_ifcvt.scratch_regs[i] = NULL_RTX; |
6176 } | 6153 } |
7960 alignment = 4; | 7937 alignment = 4; |
7961 for (x = NEXT_INSN (last); x != 0 && !INSN_P (x); x = NEXT_INSN (x)) | 7938 for (x = NEXT_INSN (last); x != 0 && !INSN_P (x); x = NEXT_INSN (x)) |
7962 { | 7939 { |
7963 if (LABEL_P (x)) | 7940 if (LABEL_P (x)) |
7964 { | 7941 { |
7965 unsigned int subalign = 1 << label_to_alignment (x); | 7942 unsigned int subalign = 1 << label_to_alignment (x).levels[0].log; |
7966 alignment = MAX (alignment, subalign); | 7943 alignment = MAX (alignment, subalign); |
7967 label = x; | 7944 label = x; |
7968 } | 7945 } |
7969 if (BARRIER_P (x)) | 7946 if (BARRIER_P (x)) |
7970 barrier = x; | 7947 barrier = x; |