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.
This commit is contained in:
matt 2014-06-03 22:34:28 +00:00
parent f8174f3ae5
commit b870133566
3 changed files with 93 additions and 0 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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));
}")