Commit 14c931f1 by Chao-ying Fu Committed by Chao-ying Fu

c-lex.c (interpret_fixed): Declare.

	* c-lex.c (interpret_fixed): Declare.
	(interpret_float): Process _Fract and _Accum.
	(interpret_fixed): New function.
	* final.c (output_addr_const): Process CONST_FIXED.
	* simplify-rtx.c (simplify_const_unary_operation): Handle US_NEG.
	(simplify_binary_operation_1): Handle US_ASHIFT, SS_MULT, US_MULT,
	SS_DIV, US_DIV.
	(simplify_const_binary_operation): Handle SS_MULT, US_MULT, SS_DIV,
	US_DIV, US_ASHIFT.
	(simplify_immed_subreg): Support CONST_FIXED.
	Process MODE_FRACT, MODE_UFRACT, MODE_ACCUM, MODE_UACCUM.
	(simplify_subreg): Support CONST_FIXED.

From-SVN: r127941
parent ac6b1c67
2007-08-30 Chao-ying Fu <fu@mips.com>
* c-lex.c (interpret_fixed): Declare.
(interpret_float): Process _Fract and _Accum.
(interpret_fixed): New function.
* final.c (output_addr_const): Process CONST_FIXED.
* simplify-rtx.c (simplify_const_unary_operation): Handle US_NEG.
(simplify_binary_operation_1): Handle US_ASHIFT, SS_MULT, US_MULT,
SS_DIV, US_DIV.
(simplify_const_binary_operation): Handle SS_MULT, US_MULT, SS_DIV,
US_DIV, US_ASHIFT.
(simplify_immed_subreg): Support CONST_FIXED.
Process MODE_FRACT, MODE_UFRACT, MODE_ACCUM, MODE_UACCUM.
(simplify_subreg): Support CONST_FIXED.
2007-08-30 Andrew Pinski <andrew_pinski@playstation.sony.com>
* config/rs6000/ppu_intrinsics.h: New file.
......
......@@ -61,6 +61,7 @@ bool c_lex_return_raw_strings = false;
static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int);
static tree interpret_fixed (const cpp_token *, unsigned int);
static enum integer_type_kind narrowest_unsigned_type
(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
static enum integer_type_kind narrowest_signed_type
......@@ -640,6 +641,10 @@ interpret_float (const cpp_token *token, unsigned int flags)
char *copy;
size_t copylen;
/* Decode _Fract and _Accum. */
if (flags & CPP_N_FRACT || flags & CPP_N_ACCUM)
return interpret_fixed (token, flags);
/* Decode type based on width and properties. */
if (flags & CPP_N_DFLOAT)
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
......@@ -731,6 +736,131 @@ interpret_float (const cpp_token *token, unsigned int flags)
return value;
}
/* Interpret TOKEN, a fixed-point number with FLAGS as classified
by cpplib. */
static tree
interpret_fixed (const cpp_token *token, unsigned int flags)
{
tree type;
tree value;
FIXED_VALUE_TYPE fixed;
char *copy;
size_t copylen;
copylen = token->val.str.len;
if (flags & CPP_N_FRACT) /* _Fract. */
{
if (flags & CPP_N_UNSIGNED) /* Unsigned _Fract. */
{
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
{
type = unsigned_long_long_fract_type_node;
copylen -= 4;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
{
type = unsigned_long_fract_type_node;
copylen -= 3;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
{
type = unsigned_short_fract_type_node;
copylen -= 3;
}
else
{
type = unsigned_fract_type_node;
copylen -= 2;
}
}
else /* Signed _Fract. */
{
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
{
type = long_long_fract_type_node;
copylen -= 3;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
{
type = long_fract_type_node;
copylen -= 2;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
{
type = short_fract_type_node;
copylen -= 2;
}
else
{
type = fract_type_node;
copylen --;
}
}
}
else /* _Accum. */
{
if (flags & CPP_N_UNSIGNED) /* Unsigned _Accum. */
{
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
{
type = unsigned_long_long_accum_type_node;
copylen -= 4;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
{
type = unsigned_long_accum_type_node;
copylen -= 3;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
{
type = unsigned_short_accum_type_node;
copylen -= 3;
}
else
{
type = unsigned_accum_type_node;
copylen -= 2;
}
}
else /* Signed _Accum. */
{
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
{
type = long_long_accum_type_node;
copylen -= 3;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
{
type = long_accum_type_node;
copylen -= 2;
}
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
{
type = short_accum_type_node;
copylen -= 2;
}
else
{
type = accum_type_node;
copylen --;
}
}
}
copy = (char *) alloca (copylen + 1);
memcpy (copy, token->val.str.text, copylen);
copy[copylen] = '\0';
fixed_from_string (&fixed, copy, TYPE_MODE (type));
/* Create a node with determined type and value. */
value = build_fixed (type, fixed);
return value;
}
/* Convert a series of STRING and/or WSTRING tokens into a tree,
performing string constant concatenation. TOK is the first of
these. VALP is the location to write the string into. OBJC_STRING
......
......@@ -3377,6 +3377,10 @@ output_addr_const (FILE *file, rtx x)
output_operand_lossage ("floating constant misused");
break;
case CONST_FIXED:
fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_FIXED_VALUE_LOW (x));
break;
case PLUS:
/* Some assemblers need integer constants to appear last (eg masm). */
if (GET_CODE (XEXP (x, 0)) == CONST_INT)
......
......@@ -1149,6 +1149,7 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
case SS_TRUNCATE:
case US_TRUNCATE:
case SS_NEG:
case US_NEG:
return 0;
default:
......@@ -2565,6 +2566,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
case ASHIFT:
case SS_ASHIFT:
case US_ASHIFT:
if (trueop1 == CONST0_RTX (mode))
return op0;
if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
......@@ -2644,6 +2646,10 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
case US_PLUS:
case SS_MINUS:
case US_MINUS:
case SS_MULT:
case US_MULT:
case SS_DIV:
case US_DIV:
/* ??? There are simplifications that can be done. */
return 0;
......@@ -3353,7 +3359,12 @@ simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode,
case US_PLUS:
case SS_MINUS:
case US_MINUS:
case SS_MULT:
case US_MULT:
case SS_DIV:
case US_DIV:
case SS_ASHIFT:
case US_ASHIFT:
/* ??? There are simplifications that can be done. */
return 0;
......@@ -4466,8 +4477,9 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
return 0;
}
/* Evaluate a SUBREG of a CONST_INT or CONST_DOUBLE or CONST_VECTOR,
returning another CONST_INT or CONST_DOUBLE or CONST_VECTOR.
/* Evaluate a SUBREG of a CONST_INT or CONST_DOUBLE or CONST_FIXED
or CONST_VECTOR,
returning another CONST_INT or CONST_DOUBLE or CONST_FIXED or CONST_VECTOR.
Works by unpacking OP into a collection of 8-bit values
represented as a little-endian array of 'unsigned char', selecting by BYTE,
......@@ -4606,6 +4618,25 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op,
}
break;
case CONST_FIXED:
if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
{
for (i = 0; i < elem_bitsize; i += value_bit)
*vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
}
else
{
for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
*vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
for (; i < 2 * HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
i += value_bit)
*vp++ = CONST_FIXED_VALUE_HIGH (el)
>> (i - HOST_BITS_PER_WIDE_INT);
for (; i < elem_bitsize; i += value_bit)
*vp++ = 0;
}
break;
default:
gcc_unreachable ();
}
......@@ -4724,6 +4755,28 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op,
}
break;
case MODE_FRACT:
case MODE_UFRACT:
case MODE_ACCUM:
case MODE_UACCUM:
{
FIXED_VALUE_TYPE f;
f.data.low = 0;
f.data.high = 0;
f.mode = outer_submode;
for (i = 0;
i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
i += value_bit)
f.data.low |= (HOST_WIDE_INT)(*vp++ & value_mask) << i;
for (; i < elem_bitsize; i += value_bit)
f.data.high |= ((HOST_WIDE_INT)(*vp++ & value_mask)
<< (i - HOST_BITS_PER_WIDE_INT));
elems[elem] = CONST_FIXED_FROM_FIXED_VALUE (f, outer_submode);
}
break;
default:
gcc_unreachable ();
}
......@@ -4757,6 +4810,7 @@ simplify_subreg (enum machine_mode outermode, rtx op,
if (GET_CODE (op) == CONST_INT
|| GET_CODE (op) == CONST_DOUBLE
|| GET_CODE (op) == CONST_FIXED
|| GET_CODE (op) == CONST_VECTOR)
return simplify_immed_subreg (outermode, op, innermode, byte);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment