diff options
author | Sofiane Naci <sofiane.naci@arm.com> | 2013-07-31 14:32:39 +0000 |
---|---|---|
committer | Sofiane Naci <sofiane@gcc.gnu.org> | 2013-07-31 14:32:39 +0000 |
commit | c3f35647ff0ca30479971bb449058b733384d728 (patch) | |
tree | 8f78ee617f809fa9d16862c363e929c594cbe1c0 /gcc | |
parent | 701bd1bd9cb1d26a57a812fc3d67563d59c3a2fb (diff) | |
download | gcc-c3f35647ff0ca30479971bb449058b733384d728.zip gcc-c3f35647ff0ca30479971bb449058b733384d728.tar.gz gcc-c3f35647ff0ca30479971bb449058b733384d728.tar.bz2 |
config.gcc (arm*-*-*): Add aarch-common.o to extra_objs.
* config.gcc (arm*-*-*): Add aarch-common.o to extra_objs. Add
aarch-common-protos.h to extra_headers.
(arm*-*-*): Add arm/aarch-common-protos.h to tm_p_file.
* config/arm/arm.c (arm_early_load_addr_dep): Move from here to ...
(arm_early_store_addr_dep): Likewise.
(arm_no_early_alu_shift_dep: Likewise.
(arm_no_early_alu_shift_value_dep: Likewise.
(arm_no_early_mul_dep: Likewise.
(arm_no_early_store_addr_dep: Likewise.
(arm_mac_accumulator_is_mul_result: Likewise.
(arm_mac_accumulator_is_result: Likewise.
* config/arm/aarch-common.c: ... here. New file.
* config/arm/arm-protos.h (arm_early_load_addr_dep): Move from here to ...
(arm_early_store_addr_dep): Likewise.
(arm_no_early_alu_shift_dep: Likewise.
(arm_no_early_alu_shift_value_dep: Likewise.
(arm_no_early_mul_dep: Likewise.
(arm_no_early_store_addr_dep: Likewise.
(arm_mac_accumulator_is_mul_result: Likewise.
(arm_mac_accumulator_is_result: Likewise.
* config/arm/aarch-common-protos.h: ... here. New file.
* config/arm/t-arm (aarch-common.o): Define.
From-SVN: r201376
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 33 | ||||
-rw-r--r-- | gcc/config.gcc | 7 | ||||
-rw-r--r-- | gcc/config/arm/aarch-common-protos.h | 36 | ||||
-rw-r--r-- | gcc/config/arm/aarch-common.c | 278 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 8 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 246 | ||||
-rw-r--r-- | gcc/config/arm/t-arm | 5 |
7 files changed, 358 insertions, 255 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5664eee..e343f2c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,36 @@ +2013-07-31 Sofiane Naci <sofiane.naci@arm.com> + + * config.gcc (arm*-*-*): Add aarch-common.o to extra_objs. Add + aarch-common-protos.h to extra_headers. + (arm*-*-*): Add arm/aarch-common-protos.h to tm_p_file. + * config/arm/arm.c (arm_early_load_addr_dep): Move from here to ... + (arm_early_store_addr_dep): Likewise. + (arm_no_early_alu_shift_dep: Likewise. + (arm_no_early_alu_shift_value_dep: Likewise. + (arm_no_early_mul_dep: Likewise. + (arm_no_early_store_addr_dep: Likewise. + (arm_mac_accumulator_is_mul_result: Likewise. + (arm_mac_accumulator_is_result: Likewise. + * config/arm/aarch-common.c: ... here. New file. + * config/arm/arm-protos.h (arm_early_load_addr_dep): Move from here to ... + (arm_early_store_addr_dep): Likewise. + (arm_no_early_alu_shift_dep: Likewise. + (arm_no_early_alu_shift_value_dep: Likewise. + (arm_no_early_mul_dep: Likewise. + (arm_no_early_store_addr_dep: Likewise. + (arm_mac_accumulator_is_mul_result: Likewise. + (arm_mac_accumulator_is_result: Likewise. + * config/arm/aarch-common-protos.h: ... here. New file. + * config/arm/t-arm (aarch-common.o): Define. + +2013-07-31 Sofiane Naci <sofiane.naci@arm.com> + + * config/arm/arm.md: Include new file "types.md". + (define_attr "type"): Move from here to ... + (define_attr "mul32"): Likewise. + (define_attr "mul64"): Likewise. + * config/arm/types.md: ... here. New file. + 2013-07-31 Sebastian Huber <sebastian.huber@embedded-brains.de> * config.gcc (*-*-rtems*): Use __cxa_atexit by default. diff --git a/gcc/config.gcc b/gcc/config.gcc index e5e9485..fda3c6e 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -327,6 +327,7 @@ am33_2.0-*-linux*) arm*-*-*) cpu_type=arm extra_headers="mmintrin.h arm_neon.h" + extra_objs="aarch-common.o" target_type_format_char='%' c_target_objs="arm-c.o" cxx_target_objs="arm-c.o" @@ -559,7 +560,11 @@ x86_64-*-*) fi tm_file="vxworks-dummy.h ${tm_file}" ;; -arm*-*-* | mips*-*-* | sh*-*-* | sparc*-*-*) +arm*-*-*) + tm_p_file="${tm_p_file} arm/aarch-common-protos.h" + tm_file="vxworks-dummy.h ${tm_file}" + ;; +mips*-*-* | sh*-*-* | sparc*-*-*) tm_file="vxworks-dummy.h ${tm_file}" ;; esac diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h new file mode 100644 index 0000000..97768fce --- /dev/null +++ b/gcc/config/arm/aarch-common-protos.h @@ -0,0 +1,36 @@ +/* Function prototypes for instruction scheduling dependeoncy routines, + defined in aarch-common.c + + Copyright (C) 1991-2013 Free Software Foundation, Inc. + Contributed by ARM Ltd. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + + +#ifndef GCC_AARCH_COMMON_PROTOS_H +#define GCC_AARCH_COMMON_PROTOS_H + +extern int arm_early_load_addr_dep (rtx, rtx); +extern int arm_early_store_addr_dep (rtx, rtx); +extern int arm_mac_accumulator_is_mul_result (rtx, rtx); +extern int arm_mac_accumulator_is_result (rtx, rtx); +extern int arm_no_early_alu_shift_dep (rtx, rtx); +extern int arm_no_early_alu_shift_value_dep (rtx, rtx); +extern int arm_no_early_mul_dep (rtx, rtx); +extern int arm_no_early_store_addr_dep (rtx, rtx); + +#endif /* GCC_AARCH_COMMON_PROTOS_H */ diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c new file mode 100644 index 0000000..69366af --- /dev/null +++ b/gcc/config/arm/aarch-common.c @@ -0,0 +1,278 @@ +/* Dependency checks for instruction scheduling, shared between ARM and + AARCH64. + + Copyright (C) 1991-2013 Free Software Foundation, Inc. + Contributed by ARM Ltd. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + + +/* Return nonzero if the CONSUMER instruction (a load) does need + PRODUCER's value to calculate the address. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tm_p.h" +#include "rtl.h" +#include "tree.h" +#include "c-family/c-common.h" +#include "rtl.h" + +int +arm_early_load_addr_dep (rtx producer, rtx consumer) +{ + rtx value = PATTERN (producer); + rtx addr = PATTERN (consumer); + + if (GET_CODE (value) == COND_EXEC) + value = COND_EXEC_CODE (value); + if (GET_CODE (value) == PARALLEL) + value = XVECEXP (value, 0, 0); + value = XEXP (value, 0); + if (GET_CODE (addr) == COND_EXEC) + addr = COND_EXEC_CODE (addr); + if (GET_CODE (addr) == PARALLEL) + { + if (GET_CODE (XVECEXP (addr, 0, 0)) == RETURN) + addr = XVECEXP (addr, 0, 1); + else + addr = XVECEXP (addr, 0, 0); + } + addr = XEXP (addr, 1); + + return reg_overlap_mentioned_p (value, addr); +} + +/* Return nonzero if the CONSUMER instruction (an ALU op) does not + have an early register shift value or amount dependency on the + result of PRODUCER. */ + +int +arm_no_early_alu_shift_dep (rtx producer, rtx consumer) +{ + rtx value = PATTERN (producer); + rtx op = PATTERN (consumer); + rtx early_op; + + if (GET_CODE (value) == COND_EXEC) + value = COND_EXEC_CODE (value); + if (GET_CODE (value) == PARALLEL) + value = XVECEXP (value, 0, 0); + value = XEXP (value, 0); + if (GET_CODE (op) == COND_EXEC) + op = COND_EXEC_CODE (op); + if (GET_CODE (op) == PARALLEL) + op = XVECEXP (op, 0, 0); + op = XEXP (op, 1); + + early_op = XEXP (op, 0); + /* This is either an actual independent shift, or a shift applied to + the first operand of another operation. We want the whole shift + operation. */ + if (REG_P (early_op)) + early_op = op; + + return !reg_overlap_mentioned_p (value, early_op); +} + +/* Return nonzero if the CONSUMER instruction (an ALU op) does not + have an early register shift value dependency on the result of + PRODUCER. */ + +int +arm_no_early_alu_shift_value_dep (rtx producer, rtx consumer) +{ + rtx value = PATTERN (producer); + rtx op = PATTERN (consumer); + rtx early_op; + + if (GET_CODE (value) == COND_EXEC) + value = COND_EXEC_CODE (value); + if (GET_CODE (value) == PARALLEL) + value = XVECEXP (value, 0, 0); + value = XEXP (value, 0); + if (GET_CODE (op) == COND_EXEC) + op = COND_EXEC_CODE (op); + if (GET_CODE (op) == PARALLEL) + op = XVECEXP (op, 0, 0); + op = XEXP (op, 1); + + early_op = XEXP (op, 0); + + /* This is either an actual independent shift, or a shift applied to + the first operand of another operation. We want the value being + shifted, in either case. */ + if (!REG_P (early_op)) + early_op = XEXP (early_op, 0); + + return !reg_overlap_mentioned_p (value, early_op); +} + +/* Return nonzero if the CONSUMER (a mul or mac op) does not + have an early register mult dependency on the result of + PRODUCER. */ + +int +arm_no_early_mul_dep (rtx producer, rtx consumer) +{ + rtx value = PATTERN (producer); + rtx op = PATTERN (consumer); + + if (GET_CODE (value) == COND_EXEC) + value = COND_EXEC_CODE (value); + if (GET_CODE (value) == PARALLEL) + value = XVECEXP (value, 0, 0); + value = XEXP (value, 0); + if (GET_CODE (op) == COND_EXEC) + op = COND_EXEC_CODE (op); + if (GET_CODE (op) == PARALLEL) + op = XVECEXP (op, 0, 0); + op = XEXP (op, 1); + + if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) + { + if (GET_CODE (XEXP (op, 0)) == MULT) + return !reg_overlap_mentioned_p (value, XEXP (op, 0)); + else + return !reg_overlap_mentioned_p (value, XEXP (op, 1)); + } + + return 0; +} + +/* Return nonzero if the CONSUMER instruction (a store) does not need + PRODUCER's value to calculate the address. */ + +int +arm_no_early_store_addr_dep (rtx producer, rtx consumer) +{ + rtx value = PATTERN (producer); + rtx addr = PATTERN (consumer); + + if (GET_CODE (value) == COND_EXEC) + value = COND_EXEC_CODE (value); + if (GET_CODE (value) == PARALLEL) + value = XVECEXP (value, 0, 0); + value = XEXP (value, 0); + if (GET_CODE (addr) == COND_EXEC) + addr = COND_EXEC_CODE (addr); + if (GET_CODE (addr) == PARALLEL) + addr = XVECEXP (addr, 0, 0); + addr = XEXP (addr, 0); + + return !reg_overlap_mentioned_p (value, addr); +} + +/* Return nonzero if the CONSUMER instruction (a store) does need + PRODUCER's value to calculate the address. */ + +int +arm_early_store_addr_dep (rtx producer, rtx consumer) +{ + return !arm_no_early_store_addr_dep (producer, consumer); +} + +/* Return non-zero iff the consumer (a multiply-accumulate or a + multiple-subtract instruction) has an accumulator dependency on the + result of the producer and no other dependency on that result. It + does not check if the producer is multiply-accumulate instruction. */ +int +arm_mac_accumulator_is_result (rtx producer, rtx consumer) +{ + rtx result; + rtx op0, op1, acc; + + producer = PATTERN (producer); + consumer = PATTERN (consumer); + + if (GET_CODE (producer) == COND_EXEC) + producer = COND_EXEC_CODE (producer); + if (GET_CODE (consumer) == COND_EXEC) + consumer = COND_EXEC_CODE (consumer); + + if (GET_CODE (producer) != SET) + return 0; + + result = XEXP (producer, 0); + + if (GET_CODE (consumer) != SET) + return 0; + + /* Check that the consumer is of the form + (set (...) (plus (mult ...) (...))) + or + (set (...) (minus (...) (mult ...))). */ + if (GET_CODE (XEXP (consumer, 1)) == PLUS) + { + if (GET_CODE (XEXP (XEXP (consumer, 1), 0)) != MULT) + return 0; + + op0 = XEXP (XEXP (XEXP (consumer, 1), 0), 0); + op1 = XEXP (XEXP (XEXP (consumer, 1), 0), 1); + acc = XEXP (XEXP (consumer, 1), 1); + } + else if (GET_CODE (XEXP (consumer, 1)) == MINUS) + { + if (GET_CODE (XEXP (XEXP (consumer, 1), 1)) != MULT) + return 0; + + op0 = XEXP (XEXP (XEXP (consumer, 1), 1), 0); + op1 = XEXP (XEXP (XEXP (consumer, 1), 1), 1); + acc = XEXP (XEXP (consumer, 1), 0); + } + else + return 0; + + return (reg_overlap_mentioned_p (result, acc) + && !reg_overlap_mentioned_p (result, op0) + && !reg_overlap_mentioned_p (result, op1)); +} + +/* Return non-zero if the consumer (a multiply-accumulate instruction) + has an accumulator dependency on the result of the producer (a + multiplication instruction) and no other dependency on that result. */ +int +arm_mac_accumulator_is_mul_result (rtx producer, rtx consumer) +{ + rtx mul = PATTERN (producer); + rtx mac = PATTERN (consumer); + rtx mul_result; + rtx mac_op0, mac_op1, mac_acc; + + if (GET_CODE (mul) == COND_EXEC) + mul = COND_EXEC_CODE (mul); + if (GET_CODE (mac) == COND_EXEC) + mac = COND_EXEC_CODE (mac); + + /* Check that mul is of the form (set (...) (mult ...)) + and mla is of the form (set (...) (plus (mult ...) (...))). */ + if ((GET_CODE (mul) != SET || GET_CODE (XEXP (mul, 1)) != MULT) + || (GET_CODE (mac) != SET || GET_CODE (XEXP (mac, 1)) != PLUS + || GET_CODE (XEXP (XEXP (mac, 1), 0)) != MULT)) + return 0; + + mul_result = XEXP (mul, 0); + mac_op0 = XEXP (XEXP (XEXP (mac, 1), 0), 0); + mac_op1 = XEXP (XEXP (XEXP (mac, 1), 0), 1); + mac_acc = XEXP (XEXP (mac, 1), 1); + + return (reg_overlap_mentioned_p (mul_result, mac_acc) + && !reg_overlap_mentioned_p (mul_result, mac_op0) + && !reg_overlap_mentioned_p (mul_result, mac_op1)); +} diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index ef94bbc..f694dfd 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -97,14 +97,6 @@ extern bool arm_tls_referenced_p (rtx); extern int arm_coproc_mem_operand (rtx, bool); extern int neon_vector_mem_operand (rtx, int, bool); extern int neon_struct_mem_operand (rtx); -extern int arm_no_early_store_addr_dep (rtx, rtx); -extern int arm_early_store_addr_dep (rtx, rtx); -extern int arm_early_load_addr_dep (rtx, rtx); -extern int arm_no_early_alu_shift_dep (rtx, rtx); -extern int arm_no_early_alu_shift_value_dep (rtx, rtx); -extern int arm_no_early_mul_dep (rtx, rtx); -extern int arm_mac_accumulator_is_result (rtx, rtx); -extern int arm_mac_accumulator_is_mul_result (rtx, rtx); extern int tls_mentioned_p (rtx); extern int symbol_mentioned_p (rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 294de80..0ee4d91 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -25394,163 +25394,6 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v, *pretend_size = (NUM_ARG_REGS - nregs) * UNITS_PER_WORD; } -/* Return nonzero if the CONSUMER instruction (a store) does not need - PRODUCER's value to calculate the address. */ - -int -arm_no_early_store_addr_dep (rtx producer, rtx consumer) -{ - rtx value = PATTERN (producer); - rtx addr = PATTERN (consumer); - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (addr) == COND_EXEC) - addr = COND_EXEC_CODE (addr); - if (GET_CODE (addr) == PARALLEL) - addr = XVECEXP (addr, 0, 0); - addr = XEXP (addr, 0); - - return !reg_overlap_mentioned_p (value, addr); -} - -/* Return nonzero if the CONSUMER instruction (a store) does need - PRODUCER's value to calculate the address. */ - -int -arm_early_store_addr_dep (rtx producer, rtx consumer) -{ - return !arm_no_early_store_addr_dep (producer, consumer); -} - -/* Return nonzero if the CONSUMER instruction (a load) does need - PRODUCER's value to calculate the address. */ - -int -arm_early_load_addr_dep (rtx producer, rtx consumer) -{ - rtx value = PATTERN (producer); - rtx addr = PATTERN (consumer); - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (addr) == COND_EXEC) - addr = COND_EXEC_CODE (addr); - if (GET_CODE (addr) == PARALLEL) - { - if (GET_CODE (XVECEXP (addr, 0, 0)) == RETURN) - addr = XVECEXP (addr, 0, 1); - else - addr = XVECEXP (addr, 0, 0); - } - addr = XEXP (addr, 1); - - return reg_overlap_mentioned_p (value, addr); -} - -/* Return nonzero if the CONSUMER instruction (an ALU op) does not - have an early register shift value or amount dependency on the - result of PRODUCER. */ - -int -arm_no_early_alu_shift_dep (rtx producer, rtx consumer) -{ - rtx value = PATTERN (producer); - rtx op = PATTERN (consumer); - rtx early_op; - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (op) == COND_EXEC) - op = COND_EXEC_CODE (op); - if (GET_CODE (op) == PARALLEL) - op = XVECEXP (op, 0, 0); - op = XEXP (op, 1); - - early_op = XEXP (op, 0); - /* This is either an actual independent shift, or a shift applied to - the first operand of another operation. We want the whole shift - operation. */ - if (REG_P (early_op)) - early_op = op; - - return !reg_overlap_mentioned_p (value, early_op); -} - -/* Return nonzero if the CONSUMER instruction (an ALU op) does not - have an early register shift value dependency on the result of - PRODUCER. */ - -int -arm_no_early_alu_shift_value_dep (rtx producer, rtx consumer) -{ - rtx value = PATTERN (producer); - rtx op = PATTERN (consumer); - rtx early_op; - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (op) == COND_EXEC) - op = COND_EXEC_CODE (op); - if (GET_CODE (op) == PARALLEL) - op = XVECEXP (op, 0, 0); - op = XEXP (op, 1); - - early_op = XEXP (op, 0); - - /* This is either an actual independent shift, or a shift applied to - the first operand of another operation. We want the value being - shifted, in either case. */ - if (!REG_P (early_op)) - early_op = XEXP (early_op, 0); - - return !reg_overlap_mentioned_p (value, early_op); -} - -/* Return nonzero if the CONSUMER (a mul or mac op) does not - have an early register mult dependency on the result of - PRODUCER. */ - -int -arm_no_early_mul_dep (rtx producer, rtx consumer) -{ - rtx value = PATTERN (producer); - rtx op = PATTERN (consumer); - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (op) == COND_EXEC) - op = COND_EXEC_CODE (op); - if (GET_CODE (op) == PARALLEL) - op = XVECEXP (op, 0, 0); - op = XEXP (op, 1); - - if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) - { - if (GET_CODE (XEXP (op, 0)) == MULT) - return !reg_overlap_mentioned_p (value, XEXP (op, 0)); - else - return !reg_overlap_mentioned_p (value, XEXP (op, 1)); - } - - return 0; -} - /* We can't rely on the caller doing the proper promotion when using APCS or ATPCS. */ @@ -25600,95 +25443,6 @@ arm_cxx_guard_type (void) return TARGET_AAPCS_BASED ? integer_type_node : long_long_integer_type_node; } -/* Return non-zero iff the consumer (a multiply-accumulate or a - multiple-subtract instruction) has an accumulator dependency on the - result of the producer and no other dependency on that result. It - does not check if the producer is multiply-accumulate instruction. */ -int -arm_mac_accumulator_is_result (rtx producer, rtx consumer) -{ - rtx result; - rtx op0, op1, acc; - - producer = PATTERN (producer); - consumer = PATTERN (consumer); - - if (GET_CODE (producer) == COND_EXEC) - producer = COND_EXEC_CODE (producer); - if (GET_CODE (consumer) == COND_EXEC) - consumer = COND_EXEC_CODE (consumer); - - if (GET_CODE (producer) != SET) - return 0; - - result = XEXP (producer, 0); - - if (GET_CODE (consumer) != SET) - return 0; - - /* Check that the consumer is of the form - (set (...) (plus (mult ...) (...))) - or - (set (...) (minus (...) (mult ...))). */ - if (GET_CODE (XEXP (consumer, 1)) == PLUS) - { - if (GET_CODE (XEXP (XEXP (consumer, 1), 0)) != MULT) - return 0; - - op0 = XEXP (XEXP (XEXP (consumer, 1), 0), 0); - op1 = XEXP (XEXP (XEXP (consumer, 1), 0), 1); - acc = XEXP (XEXP (consumer, 1), 1); - } - else if (GET_CODE (XEXP (consumer, 1)) == MINUS) - { - if (GET_CODE (XEXP (XEXP (consumer, 1), 1)) != MULT) - return 0; - - op0 = XEXP (XEXP (XEXP (consumer, 1), 1), 0); - op1 = XEXP (XEXP (XEXP (consumer, 1), 1), 1); - acc = XEXP (XEXP (consumer, 1), 0); - } - else - return 0; - - return (reg_overlap_mentioned_p (result, acc) - && !reg_overlap_mentioned_p (result, op0) - && !reg_overlap_mentioned_p (result, op1)); -} - -/* Return non-zero if the consumer (a multiply-accumulate instruction) - has an accumulator dependency on the result of the producer (a - multiplication instruction) and no other dependency on that result. */ -int -arm_mac_accumulator_is_mul_result (rtx producer, rtx consumer) -{ - rtx mul = PATTERN (producer); - rtx mac = PATTERN (consumer); - rtx mul_result; - rtx mac_op0, mac_op1, mac_acc; - - if (GET_CODE (mul) == COND_EXEC) - mul = COND_EXEC_CODE (mul); - if (GET_CODE (mac) == COND_EXEC) - mac = COND_EXEC_CODE (mac); - - /* Check that mul is of the form (set (...) (mult ...)) - and mla is of the form (set (...) (plus (mult ...) (...))). */ - if ((GET_CODE (mul) != SET || GET_CODE (XEXP (mul, 1)) != MULT) - || (GET_CODE (mac) != SET || GET_CODE (XEXP (mac, 1)) != PLUS - || GET_CODE (XEXP (XEXP (mac, 1), 0)) != MULT)) - return 0; - - mul_result = XEXP (mul, 0); - mac_op0 = XEXP (XEXP (XEXP (mac, 1), 0), 0); - mac_op1 = XEXP (XEXP (XEXP (mac, 1), 0), 1); - mac_acc = XEXP (XEXP (mac, 1), 1); - - return (reg_overlap_mentioned_p (mul_result, mac_acc) - && !reg_overlap_mentioned_p (mul_result, mac_op0) - && !reg_overlap_mentioned_p (mul_result, mac_op1)); -} - /* The EABI says test the least significant bit of a guard variable. */ diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm index 246f0f5..20e79ef 100644 --- a/gcc/config/arm/t-arm +++ b/gcc/config/arm/t-arm @@ -78,6 +78,11 @@ $(srcdir)/config/arm/arm-tables.opt: $(srcdir)/config/arm/genopt.sh \ $(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \ $(srcdir)/config/arm/arm-tables.opt +aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(TM_P_H) $(RTL_H) $(TREE_H) output.h $(C_COMMON_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/arm/aarch-common.c + arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ insn-config.h conditions.h output.h dumpfile.h \ |