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) <case 'O'>: Look at mode size of the operand.
	Do not print '.' here.  Output operand lossage error for unhandled
	sizes.  Move.
	<case '*'>: Move.
	<case '&'>: Ditto.
	<case 'Y'>: Ditto.
	<case 'z'>: Hardcode "code" argument into error strings.
	<case 'Z'>: Ditto.
	<case 'D'>: Merge AVX and non-AVX codes.
	<case 'C', case 'c', case 'F', case 'f'>: Merge.  Fix error string.
	Update call to put_condition_code.

From-SVN: r187734
This commit is contained in:
Uros Bizjak 2012-05-21 21:32:55 +02:00
parent 07ba94b91a
commit f1ea1f5c04
2 changed files with 228 additions and 261 deletions

View File

@ -1,11 +1,26 @@
2012-05-21 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (put_condition_code): Change "reverse" and "fp"
arguments to bool.
(ix86_print_operand) <case 'O'>: Look at mode size of the operand.
Do not print '.' here. Output operand lossage error for unhandled
sizes. Move.
<case '*'>: Move.
<case '&'>: Ditto.
<case 'Y'>: Ditto.
<case 'z'>: Hardcode "code" argument into error strings.
<case 'Z'>: Ditto.
<case 'D'>: Merge AVX and non-AVX codes.
<case 'C', case 'c', case 'F', case 'f'>: Merge. Fix error string.
Update call to put_condition_code.
2012-05-21 Andreas Schwab <schwab@linux-m68k.org> 2012-05-21 Andreas Schwab <schwab@linux-m68k.org>
* config/m68k/m68k.md (*clzsi2_cf): Renamed from clzsi2. Call * config/m68k/m68k.md (*clzsi2_cf): Renamed from clzsi2. Call
CC_STATUS_INIT. CC_STATUS_INIT.
(clzsi2): New expander. (clzsi2): New expander.
(*clzsi2_68k): New insn. (*clzsi2_68k): New insn.
* config/m68k/m68k.h: Update comment about * config/m68k/m68k.h: Update comment about CLZ_DEFINED_VALUE_AT_ZERO.
CLZ_DEFINED_VALUE_AT_ZERO.
2012-05-21 Aldy Hernandez <aldyh@redhat.com> 2012-05-21 Aldy Hernandez <aldyh@redhat.com>

View File

@ -13610,8 +13610,8 @@ ix86_find_base_term (rtx x)
} }
static void static void
put_condition_code (enum rtx_code code, enum machine_mode mode, int reverse, put_condition_code (enum rtx_code code, enum machine_mode mode, bool reverse,
int fp, FILE *file) bool fp, FILE *file)
{ {
const char *suffix; const char *suffix;
@ -13932,8 +13932,8 @@ get_some_local_dynamic_name (void)
C -- print opcode suffix for set/cmov insn. C -- print opcode suffix for set/cmov insn.
c -- like C, but print reversed condition c -- like C, but print reversed condition
F,f -- likewise, but for floating-point. F,f -- likewise, but for floating-point.
O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.", O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, print the opcode suffix for
otherwise nothing the size of the current operand, otherwise nothing.
R -- print the prefix for register names. R -- print the prefix for register names.
z -- print the opcode suffix for the size of the current operand. z -- print the opcode suffix for the size of the current operand.
Z -- likewise, with special suffixes for x87 instructions. Z -- likewise, with special suffixes for x87 instructions.
@ -13974,22 +13974,6 @@ ix86_print_operand (FILE *file, rtx x, int code)
{ {
switch (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': case 'A':
switch (ASSEMBLER_DIALECT) switch (ASSEMBLER_DIALECT)
{ {
@ -14054,6 +14038,33 @@ ix86_print_operand (FILE *file, rtx x, int code)
putc ('t', file); putc ('t', file);
return; 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': case 'z':
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
{ {
@ -14081,14 +14092,14 @@ ix86_print_operand (FILE *file, rtx x, int code)
default: default:
output_operand_lossage output_operand_lossage
("invalid operand size for operand code '%c'", code); ("invalid operand size for operand code 'z'");
return; return;
} }
} }
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
warning warning
(0, "non-integer operand used with operand code '%c'", code); (0, "non-integer operand used with operand code 'z'");
/* FALLTHRU */ /* FALLTHRU */
case 'Z': case 'Z':
@ -14151,12 +14162,12 @@ ix86_print_operand (FILE *file, rtx x, int code)
else else
{ {
output_operand_lossage output_operand_lossage
("invalid operand type used with operand code '%c'", code); ("invalid operand type used with operand code 'Z'");
return; return;
} }
output_operand_lossage output_operand_lossage
("invalid operand size for operand code '%c'", code); ("invalid operand size for operand code 'Z'");
return; return;
case 'd': case 'd':
@ -14181,241 +14192,6 @@ ix86_print_operand (FILE *file, rtx x, int code)
} }
return; 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': case 'Y':
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
@ -14472,6 +14248,182 @@ ix86_print_operand (FILE *file, rtx x, int code)
} }
return; 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 ';': case ';':
#ifndef HAVE_AS_IX86_REP_LOCK_PREFIX #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
putc (';', file); putc (';', file);