From f1ea1f5c047c3e94c8b2c604bb1af7608cc27724 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 21 May 2012 21:32:55 +0200 Subject: [PATCH] i386.c (put_condition_code): Change "reverse" and "fp" arguments to bool. * config/i386/i386.c (put_condition_code): Change "reverse" and "fp" arguments to bool. (ix86_print_operand) : Look at mode size of the operand. Do not print '.' here. Output operand lossage error for unhandled sizes. Move. : Move. : Ditto. : Ditto. : Hardcode "code" argument into error strings. : Ditto. : Merge AVX and non-AVX codes. : Merge. Fix error string. Update call to put_condition_code. From-SVN: r187734 --- gcc/ChangeLog | 19 +- gcc/config/i386/i386.c | 470 ++++++++++++++++++----------------------- 2 files changed, 228 insertions(+), 261 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7216e5aeb21..8b24de1427c5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,11 +1,26 @@ +2012-05-21 Uros Bizjak + + * config/i386/i386.c (put_condition_code): Change "reverse" and "fp" + arguments to bool. + (ix86_print_operand) : Look at mode size of the operand. + Do not print '.' here. Output operand lossage error for unhandled + sizes. Move. + : Move. + : Ditto. + : Ditto. + : Hardcode "code" argument into error strings. + : Ditto. + : Merge AVX and non-AVX codes. + : Merge. Fix error string. + Update call to put_condition_code. + 2012-05-21 Andreas Schwab * config/m68k/m68k.md (*clzsi2_cf): Renamed from clzsi2. Call CC_STATUS_INIT. (clzsi2): New expander. (*clzsi2_68k): New insn. - * config/m68k/m68k.h: Update comment about - CLZ_DEFINED_VALUE_AT_ZERO. + * config/m68k/m68k.h: Update comment about CLZ_DEFINED_VALUE_AT_ZERO. 2012-05-21 Aldy Hernandez diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 4b27cdf28a29..12719e2b9a6e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13610,8 +13610,8 @@ ix86_find_base_term (rtx x) } static void -put_condition_code (enum rtx_code code, enum machine_mode mode, int reverse, - int fp, FILE *file) +put_condition_code (enum rtx_code code, enum machine_mode mode, bool reverse, + bool fp, FILE *file) { const char *suffix; @@ -13932,8 +13932,8 @@ get_some_local_dynamic_name (void) C -- print opcode suffix for set/cmov insn. c -- like C, but print reversed condition F,f -- likewise, but for floating-point. - O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.", - otherwise nothing + O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, print the opcode suffix for + the size of the current operand, otherwise nothing. R -- print the prefix for register names. z -- print the opcode suffix for the size of the current operand. Z -- likewise, with special suffixes for x87 instructions. @@ -13974,22 +13974,6 @@ ix86_print_operand (FILE *file, rtx x, int code) { switch (code) { - case '*': - if (ASSEMBLER_DIALECT == ASM_ATT) - putc ('*', file); - return; - - case '&': - { - const char *name = get_some_local_dynamic_name (); - if (name == NULL) - output_operand_lossage ("'%%&' used without any " - "local dynamic TLS references"); - else - assemble_name (file, name); - return; - } - case 'A': switch (ASSEMBLER_DIALECT) { @@ -14054,6 +14038,33 @@ ix86_print_operand (FILE *file, rtx x, int code) putc ('t', file); return; + case 'O': +#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX + if (ASSEMBLER_DIALECT != ASM_ATT) + return; + + switch (GET_MODE_SIZE (GET_MODE (x))) + { + case 2: + putc ('w', file); + break; + + case 4: + putc ('l', file); + break; + + case 8: + putc ('q', file); + break; + + default: + output_operand_lossage + ("invalid operand size for operand code 'O'"); + return; + } +#endif + return; + case 'z': if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) { @@ -14081,14 +14092,14 @@ ix86_print_operand (FILE *file, rtx x, int code) default: output_operand_lossage - ("invalid operand size for operand code '%c'", code); + ("invalid operand size for operand code 'z'"); return; } } if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) warning - (0, "non-integer operand used with operand code '%c'", code); + (0, "non-integer operand used with operand code 'z'"); /* FALLTHRU */ case 'Z': @@ -14151,12 +14162,12 @@ ix86_print_operand (FILE *file, rtx x, int code) else { output_operand_lossage - ("invalid operand type used with operand code '%c'", code); + ("invalid operand type used with operand code 'Z'"); return; } output_operand_lossage - ("invalid operand size for operand code '%c'", code); + ("invalid operand size for operand code 'Z'"); return; case 'd': @@ -14181,241 +14192,6 @@ ix86_print_operand (FILE *file, rtx x, int code) } return; - case 'D': - /* Little bit of braindamage here. The SSE compare instructions - does use completely different names for the comparisons that the - fp conditional moves. */ - if (TARGET_AVX) - { - switch (GET_CODE (x)) - { - case EQ: - fputs ("eq", file); - break; - case UNEQ: - fputs ("eq_us", file); - break; - case LT: - fputs ("lt", file); - break; - case UNLT: - fputs ("nge", file); - break; - case LE: - fputs ("le", file); - break; - case UNLE: - fputs ("ngt", file); - break; - case UNORDERED: - fputs ("unord", file); - break; - case NE: - fputs ("neq", file); - break; - case LTGT: - fputs ("neq_oq", file); - break; - case GE: - fputs ("ge", file); - break; - case UNGE: - fputs ("nlt", file); - break; - case GT: - fputs ("gt", file); - break; - case UNGT: - fputs ("nle", file); - break; - case ORDERED: - fputs ("ord", file); - break; - default: - output_operand_lossage ("operand is not a condition code, " - "invalid operand code 'D'"); - return; - } - } - else - { - switch (GET_CODE (x)) - { - case EQ: - case UNEQ: - fputs ("eq", file); - break; - case LT: - case UNLT: - fputs ("lt", file); - break; - case LE: - case UNLE: - fputs ("le", file); - break; - case UNORDERED: - fputs ("unord", file); - break; - case NE: - case LTGT: - fputs ("neq", file); - break; - case UNGE: - case GE: - fputs ("nlt", file); - break; - case UNGT: - case GT: - fputs ("nle", file); - break; - case ORDERED: - fputs ("ord", file); - break; - default: - output_operand_lossage ("operand is not a condition code, " - "invalid operand code 'D'"); - return; - } - } - return; - case 'O': -#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX - if (ASSEMBLER_DIALECT == ASM_ATT) - { - switch (GET_MODE (x)) - { - case HImode: putc ('w', file); break; - case SImode: - case SFmode: putc ('l', file); break; - case DImode: - case DFmode: putc ('q', file); break; - default: gcc_unreachable (); - } - putc ('.', file); - } -#endif - return; - case 'C': - if (!COMPARISON_P (x)) - { - output_operand_lossage ("operand is neither a constant nor a " - "condition code, invalid operand code " - "'C'"); - return; - } - put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file); - return; - case 'F': - if (!COMPARISON_P (x)) - { - output_operand_lossage ("operand is neither a constant nor a " - "condition code, invalid operand code " - "'F'"); - return; - } -#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX - if (ASSEMBLER_DIALECT == ASM_ATT) - putc ('.', file); -#endif - put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 1, file); - return; - - /* Like above, but reverse condition */ - case 'c': - /* Check to see if argument to %c is really a constant - and not a condition code which needs to be reversed. */ - if (!COMPARISON_P (x)) - { - output_operand_lossage ("operand is neither a constant nor a " - "condition code, invalid operand " - "code 'c'"); - return; - } - put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 0, file); - return; - case 'f': - if (!COMPARISON_P (x)) - { - output_operand_lossage ("operand is neither a constant nor a " - "condition code, invalid operand " - "code 'f'"); - return; - } -#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX - if (ASSEMBLER_DIALECT == ASM_ATT) - putc ('.', file); -#endif - put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file); - return; - - case 'H': - if (!offsettable_memref_p (x)) - { - output_operand_lossage ("operand is not an offsettable memory " - "reference, invalid operand " - "code 'H'"); - return; - } - /* It doesn't actually matter what mode we use here, as we're - only going to use this for printing. */ - x = adjust_address_nv (x, DImode, 8); - break; - - case 'K': - gcc_assert (CONST_INT_P (x)); - - if (INTVAL (x) & IX86_HLE_ACQUIRE) -#ifdef HAVE_AS_IX86_HLE - fputs ("xacquire ", file); -#else - fputs ("\n" ASM_BYTE "0xf2\n\t", file); -#endif - else if (INTVAL (x) & IX86_HLE_RELEASE) -#ifdef HAVE_AS_IX86_HLE - fputs ("xrelease ", file); -#else - fputs ("\n" ASM_BYTE "0xf3\n\t", file); -#endif - /* We do not want to print value of the operand. */ - return; - - case '+': - { - rtx x; - - if (!optimize - || optimize_function_for_size_p (cfun) - || !TARGET_BRANCH_PREDICTION_HINTS) - return; - - x = find_reg_note (current_output_insn, REG_BR_PROB, 0); - if (x) - { - int pred_val = INTVAL (XEXP (x, 0)); - - if (pred_val < REG_BR_PROB_BASE * 45 / 100 - || pred_val > REG_BR_PROB_BASE * 55 / 100) - { - bool taken = pred_val > REG_BR_PROB_BASE / 2; - bool cputaken - = final_forward_branch_p (current_output_insn) == 0; - - /* Emit hints only in the case default branch prediction - heuristics would fail. */ - if (taken != cputaken) - { - /* We use 3e (DS) prefix for taken branches and - 2e (CS) prefix for not taken branches. */ - if (taken) - fputs ("ds ; ", file); - else - fputs ("cs ; ", file); - } - } - } - return; - } - case 'Y': switch (GET_CODE (x)) { @@ -14472,6 +14248,182 @@ ix86_print_operand (FILE *file, rtx x, int code) } return; + case 'D': + /* Little bit of braindamage here. The SSE compare instructions + does use completely different names for the comparisons that the + fp conditional moves. */ + switch (GET_CODE (x)) + { + case UNEQ: + if (TARGET_AVX) + { + fputs ("eq_us", file); + break; + } + case EQ: + fputs ("eq", file); + break; + case UNLT: + if (TARGET_AVX) + { + fputs ("nge", file); + break; + } + case LT: + fputs ("lt", file); + break; + case UNLE: + if (TARGET_AVX) + { + fputs ("ngt", file); + break; + } + case LE: + fputs ("le", file); + break; + case UNORDERED: + fputs ("unord", file); + break; + case LTGT: + if (TARGET_AVX) + { + fputs ("neq_oq", file); + break; + } + case NE: + fputs ("neq", file); + break; + case GE: + if (TARGET_AVX) + { + fputs ("ge", file); + break; + } + case UNGE: + fputs ("nlt", file); + break; + case GT: + if (TARGET_AVX) + { + fputs ("gt", file); + break; + } + case UNGT: + fputs ("nle", file); + break; + case ORDERED: + fputs ("ord", file); + break; + default: + output_operand_lossage ("operand is not a condition code, " + "invalid operand code 'D'"); + return; + } + return; + + case 'C': + case 'c': + case 'F': + case 'f': + if (!COMPARISON_P (x)) + { + output_operand_lossage ("operand is not a condition code, " + "invalid operand code '%c'", code); + return; + } +#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX + if (ASSEMBLER_DIALECT == ASM_ATT) + putc ('.', file); +#endif + put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), + code == 'c' || code == 'f', + code == 'F' || code == 'f', + file); + return; + + case 'H': + if (!offsettable_memref_p (x)) + { + output_operand_lossage ("operand is not an offsettable memory " + "reference, invalid operand code 'H'"); + return; + } + /* It doesn't actually matter what mode we use here, as we're + only going to use this for printing. */ + x = adjust_address_nv (x, DImode, 8); + break; + + case 'K': + gcc_assert (CONST_INT_P (x)); + + if (INTVAL (x) & IX86_HLE_ACQUIRE) +#ifdef HAVE_AS_IX86_HLE + fputs ("xacquire ", file); +#else + fputs ("\n" ASM_BYTE "0xf2\n\t", file); +#endif + else if (INTVAL (x) & IX86_HLE_RELEASE) +#ifdef HAVE_AS_IX86_HLE + fputs ("xrelease ", file); +#else + fputs ("\n" ASM_BYTE "0xf3\n\t", file); +#endif + /* We do not want to print value of the operand. */ + return; + + case '*': + if (ASSEMBLER_DIALECT == ASM_ATT) + putc ('*', file); + return; + + case '&': + { + const char *name = get_some_local_dynamic_name (); + if (name == NULL) + output_operand_lossage ("'%%&' used without any " + "local dynamic TLS references"); + else + assemble_name (file, name); + return; + } + + case '+': + { + rtx x; + + if (!optimize + || optimize_function_for_size_p (cfun) + || !TARGET_BRANCH_PREDICTION_HINTS) + return; + + x = find_reg_note (current_output_insn, REG_BR_PROB, 0); + if (x) + { + int pred_val = INTVAL (XEXP (x, 0)); + + if (pred_val < REG_BR_PROB_BASE * 45 / 100 + || pred_val > REG_BR_PROB_BASE * 55 / 100) + { + bool taken = pred_val > REG_BR_PROB_BASE / 2; + bool cputaken + = final_forward_branch_p (current_output_insn) == 0; + + /* Emit hints only in the case default branch prediction + heuristics would fail. */ + if (taken != cputaken) + { + /* We use 3e (DS) prefix for taken branches and + 2e (CS) prefix for not taken branches. */ + if (taken) + fputs ("ds ; ", file); + else + fputs ("cs ; ", file); + } + } + } + return; + } + case ';': #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX putc (';', file);