aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/vax
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/vax')
-rw-r--r--gcc/config/vax/vax-protos.h1
-rw-r--r--gcc/config/vax/vax.c69
-rw-r--r--gcc/config/vax/vax.h56
3 files changed, 71 insertions, 55 deletions
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index 978083b..f97d31a 100644
--- a/gcc/config/vax/vax-protos.h
+++ b/gcc/config/vax/vax-protos.h
@@ -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
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index 7695d69..da1b481 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -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. */
+}
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index c2de0f6..3bc04b9 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -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) \