From: Herman A.J. ten Brugge Date: Mon, 22 Jan 2001 10:29:14 +0000 (+0100) Subject: c4x.c (c4x_check_legit_addr): Only check CONST. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5078f5eb76d9796bfb97fff2a269508e71b12ad2;p=gcc.git c4x.c (c4x_check_legit_addr): Only check CONST. * c4x.c (c4x_check_legit_addr): Only check CONST. Not if CONST contains SYMBOL_REF, LABEL_REF and CONST_INT. (c4x_U_constraint, symbolic_address_operand): Likewise. (c4x_immed_float_constant): Do not check if CONST_DOUBLE is in memory. (c4x_r11_set_p, c4x_check_laj_p): New functions. * c4x-protos.h (c4x_check_laj_p): Add prototype. * c4x.md (in_annul_slot_3): Do not allow auto-increment in last anulling slot because of silicon bug. (laj, lajv): Call c4x_check_laj_p to check for silicon bug. From-SVN: r39180 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eda0a28e498..d68d6127e54 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2001-01-22 Herman A.J. ten Brugge + + * c4x.c (c4x_check_legit_addr): Only check CONST. Not if CONST + contains SYMBOL_REF, LABEL_REF and CONST_INT. + (c4x_U_constraint, symbolic_address_operand): Likewise. + (c4x_immed_float_constant): Do not check if CONST_DOUBLE is in + memory. + (c4x_r11_set_p, c4x_check_laj_p): New functions. + * c4x-protos.h (c4x_check_laj_p): Add prototype. + * c4x.md (in_annul_slot_3): Do not allow auto-increment in last + anulling slot because of silicon bug. + (laj, lajv): Call c4x_check_laj_p to check for silicon bug. + 2001-01-22 Alan Modra * cppexp.c (parse_charconst): Change `mask' type to agree diff --git a/gcc/config/c4x/c4x-protos.h b/gcc/config/c4x/c4x-protos.h index 8c8b77032b7..4814e97cd8c 100644 --- a/gcc/config/c4x/c4x-protos.h +++ b/gcc/config/c4x/c4x-protos.h @@ -121,6 +121,8 @@ extern int c4x_rptb_nop_p PARAMS ((rtx)); extern int c4x_rptb_rpts_p PARAMS ((rtx, rtx)); +extern int c4x_check_laj_p PARAMS ((rtx)); + extern int c4x_autoinc_operand PARAMS ((rtx, enum machine_mode)); extern int any_operand PARAMS ((rtx, enum machine_mode)); diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c index 496da47ada2..a23b3c8e536 100644 --- a/gcc/config/c4x/c4x.c +++ b/gcc/config/c4x/c4x.c @@ -186,6 +186,7 @@ static int c4x_arn_reg_operand PARAMS ((rtx, enum machine_mode, unsigned int)); static int c4x_arn_mem_operand PARAMS ((rtx, enum machine_mode, unsigned int)); static void c4x_check_attribute PARAMS ((const char *, tree, tree, tree *)); static int c4x_parse_pragma PARAMS ((const char *, tree *, tree *)); +static int c4x_r11_set_p PARAMS ((rtx)); /* Called to register all of our global variables with the garbage collector. */ @@ -1558,15 +1559,7 @@ c4x_check_legit_addr (mode, addr, strict) return 1; if (GET_CODE (op1) == CONST) - { - addr = XEXP (op1, 0); - - if (GET_CODE (addr) == PLUS - && (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF - || GET_CODE (XEXP (addr, 0)) == LABEL_REF) - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - return 1; - } + return 1; return 0; } break; @@ -2432,8 +2425,9 @@ c4x_immed_float_constant (op) if (GET_CODE (op) != CONST_DOUBLE) return 0; - if (GET_CODE (XEXP (op, 0)) == MEM) - return 0; + /* Do not check if the CONST_DOUBLE is in memory. If there is a MEM + present this only means that a MEM rtx has been generated. It does + not mean the rtx is really in memory. */ return GET_MODE (op) == QFmode || GET_MODE (op) == HFmode; } @@ -2835,14 +2829,9 @@ c4x_U_constraint (op) rtx op; { /* Don't allow direct addressing to an arbitrary constant. */ - if (GET_CODE (op) == CONST - && GET_CODE (XEXP (op, 0)) == PLUS - && (GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF - || GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF) - && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT) - return 1; - - return GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF; + return GET_CODE (op) == CONST + || GET_CODE (op) == SYMBOL_REF + || GET_CODE (op) == LABEL_REF; } @@ -3228,14 +3217,10 @@ symbolic_address_operand (op, mode) { switch (GET_CODE (op)) { + case CONST: case SYMBOL_REF: case LABEL_REF: return 1; - case CONST: - op = XEXP (op, 0); - return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - || GET_CODE (XEXP (op, 0)) == LABEL_REF) - && GET_CODE (XEXP (op, 1)) == CONST_INT); default: return 0; } @@ -4720,6 +4705,75 @@ c4x_rptb_rpts_p (insn, op) } +/* Check if register r11 is used as the destination of an insn. */ + +static int +c4x_r11_set_p(x) + rtx x; +{ + RTX_CODE code; + rtx set; + int i, j; + const char *fmt; + + if (x == 0) + return 0; + + code = GET_CODE (x); + if (code == INSN && GET_CODE (PATTERN (x)) == SEQUENCE) + x = XVECEXP (PATTERN (x), 0, XVECLEN (PATTERN (x), 0) - 1); + + if (code == INSN && (set = single_set (x))) + return c4x_r11_set_p (SET_DEST (set)); + + if (code == REG && REGNO (x) == R11_REGNO) + return 1; + + fmt = GET_RTX_FORMAT (GET_CODE (x)); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + if (fmt[i] == 'e') + { + if (c4x_r11_set_p (XEXP (x, i))) + return 1; + } + else if (fmt[i] == 'E') + for (j = XVECLEN (x, i) - 1; j >= 0; j--) + if (c4x_r11_set_p (XVECEXP (x, i, j))) + return 1; + } + return 0; +} + + +/* The c4x sometimes has a problem when the insn before the laj insn + sets the r11 register. Check for this situation. */ + +int +c4x_check_laj_p (insn) + rtx insn; +{ + insn = prev_nonnote_insn (insn); + + /* If this is the start of the function no nop is needed. */ + if (insn == 0) + return 0; + + /* If the previous insn is a code label we have to insert a nop. This + could be a jump or table jump. We can find the normal jumps by + scanning the function but this will not find table jumps. */ + if (GET_CODE (insn) == CODE_LABEL) + return 1; + + /* If the previous insn sets register r11 we have to insert a nop. */ + if (c4x_r11_set_p (insn)) + return 1; + + /* No nop needed. */ + return 0; +} + + /* Adjust the cost of a scheduling dependency. Return the new cost of a dependency LINK or INSN on DEP_INSN. COST is the current cost. A set of an address register followed by a use occurs a 2 cycle diff --git a/gcc/config/c4x/c4x.md b/gcc/config/c4x/c4x.md index 5d2656c0ab5..3a81ef65d24 100644 --- a/gcc/config/c4x/c4x.md +++ b/gcc/config/c4x/c4x.md @@ -377,10 +377,12 @@ (const_string "false"))) /* Disable ldp because the c4x contains a bug. The ldp insn modifies - the dp register when the insn is anulled or not. */ + the dp register when the insn is anulled or not. + Also disable autoincrement insns because of a silicon bug. */ (define_attr "in_annul_slot_3" "false,true" - (if_then_else (and (eq_attr "cpu" "c4x") - (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi")) + (if_then_else (and (and (eq_attr "cpu" "c4x") + (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi")) + (eq_attr "onlyreg_nomod" "true")) (const_string "true") (const_string "false"))) @@ -5133,7 +5135,8 @@ "! TARGET_C3X" "* if (final_sequence) - return \"laj%U0\\t%C0\"; + return c4x_check_laj_p (insn) + ? \"nop\\n\\tlaj%U0\\t%C0\" : \"laj%U0\\t%C0\"; else return \"call%U0\\t%C0\";" [(set_attr "type" "laj")]) @@ -5181,7 +5184,8 @@ "! TARGET_C3X" "* if (final_sequence) - return \"laj%U1\\t%C1\"; + return c4x_check_laj_p (insn) + ? \"nop\\n\\tlaj%U1\\t%C1\" : \"laj%U1\\t%C1\"; else return \"call%U1\\t%C1\";" [(set_attr "type" "laj")])