From b87013356648872bc6095bbab5ba10f35a2d991f Mon Sep 17 00:00:00 2001 From: matt Date: Tue, 3 Jun 2014 22:34:28 +0000 Subject: [PATCH] Add some peepholes to help pushing of adjacent registers or memory locations on the stack. Add a peephole to translate two pushes on integers into one push of a DImode register. --- .../gpl3/gcc/dist/gcc/config/vax/vax-protos.h | 1 + external/gpl3/gcc/dist/gcc/config/vax/vax.c | 47 +++++++++++++++++++ external/gpl3/gcc/dist/gcc/config/vax/vax.md | 45 ++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/external/gpl3/gcc/dist/gcc/config/vax/vax-protos.h b/external/gpl3/gcc/dist/gcc/config/vax/vax-protos.h index 95d2607bff43..ef06d8704662 100644 --- a/external/gpl3/gcc/dist/gcc/config/vax/vax-protos.h +++ b/external/gpl3/gcc/dist/gcc/config/vax/vax-protos.h @@ -29,6 +29,7 @@ extern void print_operand_address (FILE *, rtx); extern void print_operand (FILE *, rtx, int); extern void vax_notice_update_cc (rtx, rtx); extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code); +extern bool vax_decomposed_dimode_operand_p (rtx, rtx); extern const char * vax_output_int_move (rtx, rtx *, enum machine_mode); extern const char * vax_output_int_add (rtx, rtx *, enum machine_mode); extern const char * vax_output_int_subtract (rtx, rtx *, enum machine_mode); diff --git a/external/gpl3/gcc/dist/gcc/config/vax/vax.c b/external/gpl3/gcc/dist/gcc/config/vax/vax.c index 5231ca4f9b5c..ad34c866dcb6 100644 --- a/external/gpl3/gcc/dist/gcc/config/vax/vax.c +++ b/external/gpl3/gcc/dist/gcc/config/vax/vax.c @@ -2325,3 +2325,50 @@ vax_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, ? (GET_MODE_SIZE (mode) + 3) & ~3 : (int_size_in_bytes (type) + 3) & ~3); } + +bool +vax_decomposed_dimode_operand_p (rtx lo, rtx hi) +{ + HOST_WIDE_INT lo_offset = 0; + HOST_WIDE_INT hi_offset = 0; + + /* If the codes aren't the same, can't be a DImode operand. */ + if (GET_CODE (lo) != GET_CODE (hi)) + return false; + + /* If a register, hi regno must be one more than the lo regno. */ + if (REG_P (lo)) + return REGNO (lo) + 1 == REGNO (hi); + + /* If not memory, can't be a DImode operand. */ + if (!MEM_P (lo)) + return false; + + /* Get addresses of memory operands. */ + lo = XEXP(lo, 0); + hi = XEXP(hi, 0); + + /* If POST_INC, regno must match. */ + if (GET_CODE (lo) == POST_INC && GET_CODE (hi) == POST_INC) + return REGNO (XEXP (lo, 0)) == REGNO (XEXP (hi, 0)); + + if (GET_CODE (lo) == PLUS) + { + /* If PLUS, this must an indexed address so fail. */ + if (GET_CODE (XEXP (lo, 0)) == PLUS || !CONST_INT_P (XEXP (lo, 1))) + return false; + lo_offset = INTVAL (XEXP (lo, 1)); + lo = XEXP(lo, 0); + } + + if (GET_CODE (hi) == PLUS) + { + /* If PLUS, this must an indexed address so fail. */ + if (GET_CODE (XEXP (hi, 0)) == PLUS || !CONST_INT_P (XEXP (hi, 1))) + return false; + hi_offset = INTVAL (XEXP (hi, 1)); + hi = XEXP(hi, 0); + } + + return rtx_equal_p(lo, hi) && lo_offset + 4 == hi_offset; +} diff --git a/external/gpl3/gcc/dist/gcc/config/vax/vax.md b/external/gpl3/gcc/dist/gcc/config/vax/vax.md index 48713aee0ff7..2d0b7e7fd40a 100644 --- a/external/gpl3/gcc/dist/gcc/config/vax/vax.md +++ b/external/gpl3/gcc/dist/gcc/config/vax/vax.md @@ -1678,3 +1678,48 @@ }) (include "builtins.md") + +(define_peephole2 + [(set (match_operand:SI 0 "push_operand" "") + (const_int 0)) + (set (match_dup 0) + (match_operand:SI 1 "const_int_operand" ""))] + "INTVAL (operands[1]) >= 0" + [(set (match_dup 0) + (match_dup 1))] + "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));") + +(define_peephole2 + [(set (match_operand:SI 0 "push_operand" "") + (match_operand:SI 1 "general_operand" "")) + (set (match_dup 0) + (match_operand:SI 2 "general_operand" ""))] + "vax_decomposed_dimode_operand_p (operands[2], operands[1])" + [(set (match_dup 0) + (match_dup 2))] + "{ + operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0)); + operands[2] = REG_P (operands[2]) + ? gen_rtx_REG(DImode, REGNO (operands[2])) + : gen_rtx_MEM(DImode, XEXP (operands[2], 0)); +}") + +; Leave this commented out until we can determine whether the second move +; precedes a jump which relies on the CC flags being set correctly. +(define_peephole2 + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (match_operand:SI 1 "general_operand" "")) + (set (match_operand:SI 2 "nonimmediate_operand" "") + (match_operand:SI 3 "general_operand" ""))] + "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3]) + && vax_decomposed_dimode_operand_p (operands[0], operands[2])" + [(set (match_dup 0) + (match_dup 1))] + "{ + operands[0] = REG_P (operands[0]) + ? gen_rtx_REG(DImode, REGNO (operands[0])) + : gen_rtx_MEM(DImode, XEXP (operands[0], 0)); + operands[1] = REG_P (operands[1]) + ? gen_rtx_REG(DImode, REGNO (operands[1])) + : gen_rtx_MEM(DImode, XEXP (operands[1], 0)); +}")