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:
parent
f8174f3ae5
commit
b870133566
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}")
|
||||
|
|
Loading…
Reference in New Issue