diff options
author | chaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-30 23:09:28 +0000 |
---|---|---|
committer | chaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-30 23:09:28 +0000 |
commit | b563b483b9f482b0ebd10d79d5982fb6eb3653d7 (patch) | |
tree | 147d8f8e5f66c5b18b1af215b5ed27814c9a27a1 /gcc | |
parent | 84373723043bc16686594a725911ed92be41db24 (diff) | |
download | gcc-b563b483b9f482b0ebd10d79d5982fb6eb3653d7.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127941 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/c-lex.c | 130 | ||||
-rw-r--r-- | gcc/final.c | 4 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 58 |
4 files changed, 205 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a6d0393e2e..b2bde282f1d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +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. diff --git a/gcc/c-lex.c b/gcc/c-lex.c index a4e3b0c8094..17cb9ed5e22 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -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 diff --git a/gcc/final.c b/gcc/final.c index aac9a9e3c0f..7c2b4ea9f08 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -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) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 3a8e8ed688f..857b7412343 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -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, @@ -4605,6 +4617,25 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op, *vp++ = 0; } 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 (); @@ -4723,6 +4754,28 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op, elems[elem] = CONST_DOUBLE_FROM_REAL_VALUE (r, outer_submode); } 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); |