vax-protos.h: Add a prototype for vax_notice_update_cc.

* config/vax/vax-protos.h: Add a prototype for
	vax_notice_update_cc.
	* config/vax/vax.c (vax_notice_update_cc): New.
	* config/vax/vax.h (NOTICE_UPDATE_CC): Call
	vax_notice_update_cc.

From-SVN: r79032
This commit is contained in:
Kazu Hirata 2004-03-06 21:14:50 +00:00 committed by Kazu Hirata
parent aaef9b06ac
commit af0ec113b8
4 changed files with 79 additions and 55 deletions

View File

@ -1,3 +1,11 @@
2004-03-06 Kazu Hirata <kazu@cs.umass.edu>
* config/vax/vax-protos.h: Add a prototype for
vax_notice_update_cc.
* config/vax/vax.c (vax_notice_update_cc): New.
* config/vax/vax.h (NOTICE_UPDATE_CC): Call
vax_notice_update_cc.
2004-03-06 David Edelsohn <edelsohn@gnu.org>
* collect2.c (main): Only export initfunc and finifunc if

View File

@ -25,6 +25,7 @@ extern const char *rev_cond_name (rtx);
extern void split_quadword_operands (rtx *, rtx *, int);
extern void print_operand_address (FILE *, rtx);
extern int vax_float_literal (rtx);
extern void vax_notice_update_cc (rtx, rtx);
#endif /* RTX_CODE */
#ifdef REAL_VALUE_TYPE

View File

@ -788,3 +788,72 @@ vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
{
return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
}
/* Worker function for NOTICE_UPDATE_CC. */
void
vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
{
if (GET_CODE (exp) == SET)
{
if (GET_CODE (SET_SRC (exp)) == CALL)
CC_STATUS_INIT;
else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT
&& GET_CODE (SET_DEST (exp)) != PC)
{
cc_status.flags = 0;
/* The integer operations below don't set carry or
set it in an incompatible way. That's ok though
as the Z bit is all we need when doing unsigned
comparisons on the result of these insns (since
they're always with 0). Set CC_NO_OVERFLOW to
generate the correct unsigned branches. */
switch (GET_CODE (SET_SRC (exp)))
{
case NEG:
if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT)
break;
case AND:
case IOR:
case XOR:
case NOT:
case MEM:
case REG:
cc_status.flags = CC_NO_OVERFLOW;
break;
default:
break;
}
cc_status.value1 = SET_DEST (exp);
cc_status.value2 = SET_SRC (exp);
}
}
else if (GET_CODE (exp) == PARALLEL
&& GET_CODE (XVECEXP (exp, 0, 0)) == SET)
{
if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL)
CC_STATUS_INIT;
else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC)
{
cc_status.flags = 0;
cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0));
cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0));
}
else
/* PARALLELs whose first element sets the PC are aob,
sob insns. They do change the cc's. */
CC_STATUS_INIT;
}
else
CC_STATUS_INIT;
if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
&& cc_status.value2
&& reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
cc_status.value2 = 0;
if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
&& cc_status.value2
&& GET_CODE (cc_status.value2) == MEM)
cc_status.value2 = 0;
/* Actual condition, one line up, should be that value2's address
depends on value1, but that is too much of a pain. */
}

View File

@ -866,61 +866,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
Do not alter them if the instruction would not alter the cc's. */
#define NOTICE_UPDATE_CC(EXP, INSN) \
{ if (GET_CODE (EXP) == SET) \
{ if (GET_CODE (SET_SRC (EXP)) == CALL) \
CC_STATUS_INIT; \
else if (GET_CODE (SET_DEST (EXP)) != ZERO_EXTRACT \
&& GET_CODE (SET_DEST (EXP)) != PC) \
{ \
cc_status.flags = 0; \
/* The integer operations below don't set carry or \
set it in an incompatible way. That's ok though \
as the Z bit is all we need when doing unsigned \
comparisons on the result of these insns (since \
they're always with 0). Set CC_NO_OVERFLOW to \
generate the correct unsigned branches. */ \
switch (GET_CODE (SET_SRC (EXP))) \
{ \
case NEG: \
if (GET_MODE_CLASS (GET_MODE (EXP)) == MODE_FLOAT)\
break; \
case AND: \
case IOR: \
case XOR: \
case NOT: \
case MEM: \
case REG: \
cc_status.flags = CC_NO_OVERFLOW; \
break; \
default: \
break; \
} \
cc_status.value1 = SET_DEST (EXP); \
cc_status.value2 = SET_SRC (EXP); } } \
else if (GET_CODE (EXP) == PARALLEL \
&& GET_CODE (XVECEXP (EXP, 0, 0)) == SET) \
{ \
if (GET_CODE (SET_SRC (XVECEXP (EXP, 0, 0))) == CALL) \
CC_STATUS_INIT; \
else if (GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) != PC) \
{ cc_status.flags = 0; \
cc_status.value1 = SET_DEST (XVECEXP (EXP, 0, 0)); \
cc_status.value2 = SET_SRC (XVECEXP (EXP, 0, 0)); } \
else \
/* PARALLELs whose first element sets the PC are aob, \
sob insns. They do change the cc's. */ \
CC_STATUS_INIT; } \
else CC_STATUS_INIT; \
if (cc_status.value1 && GET_CODE (cc_status.value1) == REG \
&& cc_status.value2 \
&& reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) \
cc_status.value2 = 0; \
if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM \
&& cc_status.value2 \
&& GET_CODE (cc_status.value2) == MEM) \
cc_status.value2 = 0; }
/* Actual condition, one line up, should be that value2's address
depends on value1, but that is too much of a pain. */
vax_notice_update_cc ((EXP), (INSN))
#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \
{ if (cc_status.flags & CC_NO_OVERFLOW) \