emit-rtl.c (global_rtl): Update comment.
* emit-rtl.c (global_rtl): Update comment. (const_double_htab, const_double_htab_hash, const_double_htab_hash, lookup_const_double): New. (const_int_htab_hash, const_int_htab_eq): Remove const qualifiers, which cause tons of warnings with RTL checking on. (gen_rtx_CONST_DOUBLE): Deleted. (const_double_from_real_value): New function - bears some resemblance to the former immed_real_const_1. (immed_double_const): Moved here from varasm.c and simplified. (gen_rtx_REG): Make REGNO unsigned to squelch warnings. (gen_rtx_SUBREG): Use gen_rtx_raw_SUBREG. (gen_rtx): Use immed_double_const. (init_emit_once): Initialize the const_double_htab. Use REAL_VALUE_FROM_INT where possible. Can now use CONST_DOUBLE_FROM_REAL_VALUE when setting up const_tiny_rtx. * varasm.c (struct varasm_status): Remove x_const_double_chain. (const_double_chain, immed_real_const, clear_const_double_mem): Delete. (immed_double_const, immed_real_const_1): Moved to emit-rtl.c. (init_varasm_status, mark_varasm_status): Don't touch x_const_double_chain. * output.h: Delete prototype for clear_const_double_mem. * real.h: Make REAL_VALUE_TYPE a macro again. Remove leading '0' slot from all CONST_DOUBLE_FORMAT definitions. Prototype const_double_from_real_value, not immed_real_const_1, and use it to define CONST_DOUBLE_FROM_REAL_VALUE. Define new macro CONST_DOUBLE_ATOF. * rtl.h (CONST_DOUBLE_CHAIN): Kill. (CONST_DOUBLE_LOW, CONST_DOUBLE_HIGH): Adjust. (gen_rtx_CONST_DOUBLE, immed_real_const): Delete prototypes. (gen_rtx_REG): Second arg is unsigned. * gengenrtl.c (special_rtx): Take out CONST_DOUBLE. (excluded_rtx): New, return true for CONST_DOUBLE. (genmacro): Write nothing for excluded codes. * combine.c (combine_simplify_rtx): Use CONST_DOUBLE_FROM_REAL_VALUE. * expr.c (expand_expr): Likewise. * ggc-common.c (ggc_mark_rtx_children_1): Don't mark the CONST_DOUBLE_CHAIN. * toplev.c (rest_of_compilation): Don't call clear_const_double_mem. * config/rs6000/rs6000.c (rs6000_float_const): Delete. (rs6000_hash_constant): Remove CONST_DOUBLE special case. (toc_hash_eq): Remove CONST_DOUBLE and LABEL_REF special cases. * config/rs6000/rs6000-protos.h: Don't prototype rs6000_float_const. * config/c4x/c4x.md, config/rs6000/rs6000.md: Use CONST_DOUBLE_ATOF. * config/dsp16xx/dsp16xx.md, config/mips/mips.md, config/pa/pa.md: Use CONST_DOUBLE_FROM_REAL_VALUE. * config/sparc/sparc.md, config/sparc/sparc.c: Use immed_double_const. From-SVN: r53409
This commit is contained in:
parent
31397a7b64
commit
5692c7bc60
20 changed files with 324 additions and 366 deletions
110
gcc/ChangeLog
110
gcc/ChangeLog
|
@ -1,3 +1,57 @@
|
|||
2002-05-12 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* emit-rtl.c (global_rtl): Update comment.
|
||||
(const_double_htab, const_double_htab_hash,
|
||||
const_double_htab_hash, lookup_const_double): New.
|
||||
(const_int_htab_hash, const_int_htab_eq): Remove const
|
||||
qualifiers, which cause tons of warnings with RTL checking on.
|
||||
(gen_rtx_CONST_DOUBLE): Deleted.
|
||||
(const_double_from_real_value): New function - bears some
|
||||
resemblance to the former immed_real_const_1.
|
||||
(immed_double_const): Moved here from varasm.c and
|
||||
simplified.
|
||||
(gen_rtx_REG): Make REGNO unsigned to squelch warnings.
|
||||
(gen_rtx_SUBREG): Use gen_rtx_raw_SUBREG.
|
||||
(gen_rtx): Use immed_double_const.
|
||||
(init_emit_once): Initialize the const_double_htab. Use
|
||||
REAL_VALUE_FROM_INT where possible. Can now use
|
||||
CONST_DOUBLE_FROM_REAL_VALUE when setting up const_tiny_rtx.
|
||||
* varasm.c (struct varasm_status): Remove x_const_double_chain.
|
||||
(const_double_chain, immed_real_const, clear_const_double_mem): Delete.
|
||||
(immed_double_const, immed_real_const_1): Moved to emit-rtl.c.
|
||||
(init_varasm_status, mark_varasm_status): Don't touch
|
||||
x_const_double_chain.
|
||||
|
||||
* output.h: Delete prototype for clear_const_double_mem.
|
||||
* real.h: Make REAL_VALUE_TYPE a macro again. Remove leading
|
||||
'0' slot from all CONST_DOUBLE_FORMAT definitions. Prototype
|
||||
const_double_from_real_value, not immed_real_const_1, and use
|
||||
it to define CONST_DOUBLE_FROM_REAL_VALUE. Define new macro
|
||||
CONST_DOUBLE_ATOF.
|
||||
* rtl.h (CONST_DOUBLE_CHAIN): Kill.
|
||||
(CONST_DOUBLE_LOW, CONST_DOUBLE_HIGH): Adjust.
|
||||
(gen_rtx_CONST_DOUBLE, immed_real_const): Delete prototypes.
|
||||
(gen_rtx_REG): Second arg is unsigned.
|
||||
|
||||
* gengenrtl.c (special_rtx): Take out CONST_DOUBLE.
|
||||
(excluded_rtx): New, return true for CONST_DOUBLE.
|
||||
(genmacro): Write nothing for excluded codes.
|
||||
* combine.c (combine_simplify_rtx): Use CONST_DOUBLE_FROM_REAL_VALUE.
|
||||
* expr.c (expand_expr): Likewise.
|
||||
* ggc-common.c (ggc_mark_rtx_children_1): Don't mark the
|
||||
CONST_DOUBLE_CHAIN.
|
||||
* toplev.c (rest_of_compilation): Don't call
|
||||
clear_const_double_mem.
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_float_const): Delete.
|
||||
(rs6000_hash_constant): Remove CONST_DOUBLE special case.
|
||||
(toc_hash_eq): Remove CONST_DOUBLE and LABEL_REF special cases.
|
||||
* config/rs6000/rs6000-protos.h: Don't prototype rs6000_float_const.
|
||||
* config/c4x/c4x.md, config/rs6000/rs6000.md: Use CONST_DOUBLE_ATOF.
|
||||
* config/dsp16xx/dsp16xx.md, config/mips/mips.md,
|
||||
config/pa/pa.md: Use CONST_DOUBLE_FROM_REAL_VALUE.
|
||||
* config/sparc/sparc.md, config/sparc/sparc.c: Use immed_double_const.
|
||||
|
||||
2002-05-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* mips/iris6.h (CPLUSPLUS_CPP_SPEC): Define.
|
||||
|
@ -313,38 +367,38 @@ Thu May 9 14:52:45 CEST 2002 Jan Hubicka <jh@suse.cz>
|
|||
* final.c (end_final): Use C trees to output data structures for profiling.
|
||||
|
||||
* Makefile.in (LIBGCC_DEPS): Added missing dependency on gcov-io.h
|
||||
(profile.o): New dependency profile.h
|
||||
(final.o): New dependency profile.h
|
||||
* profile.h: New file. New global structure profile_info.
|
||||
* final.h (count_edges_instrumented_now): Declare.
|
||||
(current_function_cfg_checksum): Declare.
|
||||
(function_list): New structure.
|
||||
(functions_head, functions_tail): New static variables.
|
||||
(end_final): Emits more data, removed some -ax stuff.
|
||||
(final): Stores function names and chcksums.
|
||||
* gcov-io.h (__write_gcov_string): New function.
|
||||
(__read_gcov_string): New function.
|
||||
* gcov.c (read_profile): New function.
|
||||
(create_program_flow_graph): Uses read_profile instead of reading
|
||||
(profile.o): New dependency profile.h
|
||||
(final.o): New dependency profile.h
|
||||
* profile.h: New file. New global structure profile_info.
|
||||
* final.h (count_edges_instrumented_now): Declare.
|
||||
(current_function_cfg_checksum): Declare.
|
||||
(function_list): New structure.
|
||||
(functions_head, functions_tail): New static variables.
|
||||
(end_final): Emits more data, removed some -ax stuff.
|
||||
(final): Stores function names and chcksums.
|
||||
* gcov-io.h (__write_gcov_string): New function.
|
||||
(__read_gcov_string): New function.
|
||||
* gcov.c (read_profile): New function.
|
||||
(create_program_flow_graph): Uses read_profile instead of reading
|
||||
da_file.
|
||||
(read_files): Removed da_file checking, it's done by read_profile now.
|
||||
* libgcc2.c (bb_function_info): New structure.
|
||||
(bb): New field in structure, removed some -ax stuff.
|
||||
(__bb_exit_func): Changed structure of da_file.
|
||||
* profile.c (count_edges_instrumented_now): New global variable.
|
||||
(current_function_cfg_checksum): New global variable.
|
||||
(max_counter_in_program): New global variable.
|
||||
(get_exec_counts): New function.
|
||||
(compute_checksum): New function.
|
||||
(instrument_edges): Sets count_edges_instrumented_now.
|
||||
(compute_branch_probabilities): Uses get_exec_counts instead of
|
||||
(read_files): Removed da_file checking, it's done by read_profile now.
|
||||
* libgcc2.c (bb_function_info): New structure.
|
||||
(bb): New field in structure, removed some -ax stuff.
|
||||
(__bb_exit_func): Changed structure of da_file.
|
||||
* profile.c (count_edges_instrumented_now): New global variable.
|
||||
(current_function_cfg_checksum): New global variable.
|
||||
(max_counter_in_program): New global variable.
|
||||
(get_exec_counts): New function.
|
||||
(compute_checksum): New function.
|
||||
(instrument_edges): Sets count_edges_instrumented_now.
|
||||
(compute_branch_probabilities): Uses get_exec_counts instead of
|
||||
reading da_file.
|
||||
(branch_prob): Calls compute_checksum and writes extra data to bbg_file.
|
||||
(init_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
(branch_prob): Calls compute_checksum and writes extra data to bbg_file.
|
||||
(init_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
now.
|
||||
(end_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
(end_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
now.
|
||||
* gcov.texi: Updated information about gcov file format.
|
||||
* gcov.texi: Updated information about gcov file format.
|
||||
|
||||
2002-05-09 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
|
|
|
@ -3773,7 +3773,8 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
|
|||
if (temp == const0_rtx)
|
||||
temp = CONST0_RTX (mode);
|
||||
else
|
||||
temp = immed_real_const_1 (FLOAT_STORE_FLAG_VALUE (mode), mode);
|
||||
temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
|
||||
mode);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
|
|
@ -3714,8 +3714,7 @@
|
|||
operands[4] = gen_reg_rtx (QFmode);
|
||||
operands[5] = gen_reg_rtx (QFmode);
|
||||
operands[6] = gen_reg_rtx (QFmode);
|
||||
emit_move_insn (operands[5],
|
||||
immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", QFmode), QFmode));")
|
||||
emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", QFmode));")
|
||||
|
||||
(define_expand "floatunsqihf2"
|
||||
[(set (match_dup 2) (match_dup 3))
|
||||
|
@ -3737,8 +3736,7 @@
|
|||
operands[4] = gen_reg_rtx (HFmode);
|
||||
operands[5] = gen_reg_rtx (HFmode);
|
||||
operands[6] = gen_reg_rtx (HFmode);
|
||||
emit_move_insn (operands[5],
|
||||
immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", HFmode), HFmode));")
|
||||
emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", HFmode));")
|
||||
|
||||
(define_insn "floatqihf2"
|
||||
[(set (match_operand:HF 0 "reg_operand" "=h")
|
||||
|
@ -3877,8 +3875,7 @@
|
|||
operands[3] = gen_reg_rtx (QFmode);
|
||||
operands[4] = gen_reg_rtx (QImode);
|
||||
operands[5] = gen_reg_rtx (QFmode);
|
||||
emit_move_insn (operands[5],
|
||||
immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", QFmode), QFmode));")
|
||||
emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", QFmode));")
|
||||
|
||||
(define_expand "fixuns_trunchfqi2"
|
||||
[(parallel [(set (match_dup 2)
|
||||
|
@ -3900,8 +3897,7 @@
|
|||
operands[3] = gen_reg_rtx (HFmode);
|
||||
operands[4] = gen_reg_rtx (QImode);
|
||||
operands[5] = gen_reg_rtx (HFmode);
|
||||
emit_move_insn (operands[5],
|
||||
immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", HFmode), HFmode));")
|
||||
emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", HFmode));")
|
||||
|
||||
(define_expand "fixuns_truncqfhi2"
|
||||
[(parallel [(set (match_operand:HI 0 "reg_operand" "")
|
||||
|
@ -3981,10 +3977,8 @@
|
|||
operands[2] = gen_reg_rtx (QFmode);
|
||||
operands[3] = gen_reg_rtx (QFmode);
|
||||
operands[4] = gen_reg_rtx (QFmode);
|
||||
operands[5] = immed_real_const_1 (REAL_VALUE_ATOF (\"0.5\", QFmode),
|
||||
QFmode);
|
||||
operands[6] = immed_real_const_1 (REAL_VALUE_ATOF (\"1.5\", QFmode),
|
||||
QFmode);")
|
||||
operands[5] = CONST_DOUBLE_ATOF (\"0.5\", QFmode);
|
||||
operands[6] = CONST_DOUBLE_ATOF (\"1.5\", QFmode);")
|
||||
|
||||
(define_expand "sqrtqf2"
|
||||
[(parallel [(set (match_operand:QF 0 "reg_operand" "")
|
||||
|
@ -6197,8 +6191,8 @@
|
|||
operands[2] = gen_reg_rtx (HFmode);
|
||||
operands[3] = gen_reg_rtx (HFmode);
|
||||
operands[4] = gen_reg_rtx (HFmode);
|
||||
operands[5] = immed_real_const_1 (REAL_VALUE_ATOF (\"0.5\", HFmode), HFmode);
|
||||
operands[6] = immed_real_const_1 (REAL_VALUE_ATOF (\"1.5\", HFmode), HFmode);
|
||||
operands[5] = CONST_DOUBLE_ATOF (\"0.5\", HFmode);
|
||||
operands[6] = CONST_DOUBLE_ATOF (\"1.5\", HFmode);
|
||||
")
|
||||
|
||||
|
||||
|
|
|
@ -1939,7 +1939,7 @@
|
|||
|
||||
if (reg1) /* turn off complaints about unreached code */
|
||||
{
|
||||
emit_move_insn (reg1, immed_real_const_1 (offset, HFmode));
|
||||
emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, HFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
emit_insn (gen_cmphf (operands[1], reg1));
|
||||
|
|
|
@ -4509,7 +4509,7 @@ move\\t%0,%z4\\n\\
|
|||
|
||||
if (reg1) /* turn off complaints about unreached code */
|
||||
{
|
||||
emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
|
||||
emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
emit_insn (gen_cmpdf (operands[1], reg1));
|
||||
|
@ -4553,7 +4553,7 @@ move\\t%0,%z4\\n\\
|
|||
|
||||
if (reg1) /* turn off complaints about unreached code */
|
||||
{
|
||||
emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
|
||||
emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
emit_insn (gen_cmpdf (operands[1], reg1));
|
||||
|
@ -4597,7 +4597,7 @@ move\\t%0,%z4\\n\\
|
|||
|
||||
if (reg1) /* turn off complaints about unreached code */
|
||||
{
|
||||
emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
|
||||
emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
emit_insn (gen_cmpsf (operands[1], reg1));
|
||||
|
@ -4641,7 +4641,7 @@ move\\t%0,%z4\\n\\
|
|||
|
||||
if (reg1) /* turn off complaints about unreached code */
|
||||
{
|
||||
emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
|
||||
emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
emit_insn (gen_cmpsf (operands[1], reg1));
|
||||
|
|
|
@ -4796,7 +4796,8 @@
|
|||
emit_insn (gen_negdf2_fast (operands[0], operands[1]));
|
||||
else
|
||||
{
|
||||
operands[2] = force_reg (DFmode, immed_real_const_1 (dconstm1, DFmode));
|
||||
operands[2] = force_reg (DFmode,
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, DFmode));
|
||||
emit_insn (gen_muldf3 (operands[0], operands[1], operands[2]));
|
||||
}
|
||||
DONE;
|
||||
|
@ -4826,7 +4827,8 @@
|
|||
emit_insn (gen_negsf2_fast (operands[0], operands[1]));
|
||||
else
|
||||
{
|
||||
operands[2] = force_reg (SFmode, immed_real_const_1 (dconstm1, SFmode));
|
||||
operands[2] = force_reg (SFmode,
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, SFmode));
|
||||
emit_insn (gen_mulsf3 (operands[0], operands[1], operands[2]));
|
||||
}
|
||||
DONE;
|
||||
|
|
|
@ -160,8 +160,6 @@ extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
|
|||
extern void optimization_options PARAMS ((int, int));
|
||||
extern void rs6000_override_options PARAMS ((const char *));
|
||||
extern void rs6000_file_start PARAMS ((FILE *, const char *));
|
||||
extern struct rtx_def *rs6000_float_const PARAMS ((const char *,
|
||||
enum machine_mode));
|
||||
extern int direct_return PARAMS ((void));
|
||||
extern union tree_node *rs6000_build_va_list PARAMS ((void));
|
||||
extern int first_reg_to_save PARAMS ((void));
|
||||
|
|
|
@ -702,19 +702,6 @@ rs6000_file_start (file, default_cpu)
|
|||
putc ('\n', file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Create a CONST_DOUBLE from a string. */
|
||||
|
||||
struct rtx_def *
|
||||
rs6000_float_const (string, mode)
|
||||
const char *string;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
REAL_VALUE_TYPE value;
|
||||
value = REAL_VALUE_ATOF (string, mode);
|
||||
return immed_real_const_1 (value, mode);
|
||||
}
|
||||
|
||||
/* Return non-zero if this function is known to have a null epilogue. */
|
||||
|
||||
|
@ -10044,9 +10031,7 @@ rs6000_hash_constant (k)
|
|||
if (GET_CODE (k) == LABEL_REF)
|
||||
return result * 1231 + X0INT (XEXP (k, 0), 3);
|
||||
|
||||
if (GET_CODE (k) == CONST_DOUBLE)
|
||||
fidx = 1;
|
||||
else if (GET_CODE (k) == CODE_LABEL)
|
||||
if (GET_CODE (k) == CODE_LABEL)
|
||||
fidx = 3;
|
||||
else
|
||||
fidx = 0;
|
||||
|
@ -10112,29 +10097,7 @@ toc_hash_eq (h1, h2)
|
|||
!= ((const struct toc_hash_struct *) h2)->key_mode)
|
||||
return 0;
|
||||
|
||||
/* Gotcha: One of these const_doubles will be in memory.
|
||||
The other may be on the constant-pool chain.
|
||||
So rtx_equal_p will think they are different... */
|
||||
if (r1 == r2)
|
||||
return 1;
|
||||
if (GET_CODE (r1) != GET_CODE (r2)
|
||||
|| GET_MODE (r1) != GET_MODE (r2))
|
||||
return 0;
|
||||
if (GET_CODE (r1) == CONST_DOUBLE)
|
||||
{
|
||||
int format_len = strlen (GET_RTX_FORMAT (CONST_DOUBLE));
|
||||
int i;
|
||||
for (i = 1; i < format_len; i++)
|
||||
if (XWINT (r1, i) != XWINT (r2, i))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (GET_CODE (r1) == LABEL_REF)
|
||||
return (CODE_LABEL_NUMBER (XEXP (r1, 0))
|
||||
== CODE_LABEL_NUMBER (XEXP (r2, 0)));
|
||||
else
|
||||
return rtx_equal_p (r1, r2);
|
||||
return rtx_equal_p (r1, r2);
|
||||
}
|
||||
|
||||
/* Mark the hash table-entry HASH_ENTRY. */
|
||||
|
|
|
@ -5253,7 +5253,7 @@
|
|||
"
|
||||
{
|
||||
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
|
||||
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
|
||||
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
|
||||
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
|
||||
operands[5] = gen_reg_rtx (DFmode);
|
||||
operands[6] = gen_reg_rtx (SImode);
|
||||
|
@ -5320,7 +5320,7 @@
|
|||
"
|
||||
{
|
||||
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
|
||||
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
|
||||
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
|
||||
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
|
||||
operands[5] = gen_reg_rtx (DFmode);
|
||||
}")
|
||||
|
|
|
@ -1379,9 +1379,8 @@ sparc_emit_set_const32 (op0, op1)
|
|||
&& (INTVAL (op1) & 0x80000000) != 0)
|
||||
emit_insn (gen_rtx_SET
|
||||
(VOIDmode, temp,
|
||||
gen_rtx_CONST_DOUBLE (VOIDmode,
|
||||
INTVAL (op1) & ~(HOST_WIDE_INT)0x3ff,
|
||||
0)));
|
||||
immed_double_const (INTVAL (op1) & ~(HOST_WIDE_INT)0x3ff,
|
||||
0, DImode)));
|
||||
else
|
||||
emit_insn (gen_rtx_SET (VOIDmode, temp,
|
||||
GEN_INT (INTVAL (op1)
|
||||
|
@ -1559,11 +1558,10 @@ static rtx gen_safe_XOR64 PARAMS ((rtx, HOST_WIDE_INT));
|
|||
#define GEN_INT64(__x) GEN_INT (__x)
|
||||
#else
|
||||
#define GEN_HIGHINT64(__x) \
|
||||
gen_rtx_CONST_DOUBLE (VOIDmode, (__x) & ~(HOST_WIDE_INT)0x3ff, 0)
|
||||
immed_double_const ((__x) & ~(HOST_WIDE_INT)0x3ff, 0, DImode)
|
||||
#define GEN_INT64(__x) \
|
||||
gen_rtx_CONST_DOUBLE (VOIDmode, (__x) & 0xffffffff, \
|
||||
((__x) & 0x80000000 \
|
||||
? -1 : 0))
|
||||
immed_double_const ((__x) & 0xffffffff, \
|
||||
((__x) & 0x80000000 ? -1 : 0), DImode)
|
||||
#endif
|
||||
|
||||
/* The optimizer is not to assume anything about exactly
|
||||
|
@ -2133,9 +2131,9 @@ sparc_emit_set_const64 (op0, op1)
|
|||
negated_const = GEN_INT (((~low_bits) & 0xfffffc00) |
|
||||
(((HOST_WIDE_INT)((~high_bits) & 0xffffffff))<<32));
|
||||
#else
|
||||
negated_const = gen_rtx_CONST_DOUBLE (DImode,
|
||||
(~low_bits) & 0xfffffc00,
|
||||
(~high_bits) & 0xffffffff);
|
||||
negated_const = immed_double_const ((~low_bits) & 0xfffffc00,
|
||||
(~high_bits) & 0xffffffff,
|
||||
DImode);
|
||||
#endif
|
||||
sparc_emit_set_const64 (temp, negated_const);
|
||||
}
|
||||
|
|
|
@ -3158,7 +3158,7 @@
|
|||
emit_insn (gen_movdi (operands[0], GEN_INT (val)));
|
||||
#else
|
||||
emit_insn (gen_movdi (operands[0],
|
||||
gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
|
||||
immed_double_const (l[1], l[0], DImode)));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
206
gcc/emit-rtl.c
206
gcc/emit-rtl.c
|
@ -87,8 +87,8 @@ static int no_line_numbers;
|
|||
|
||||
/* Commonly used rtx's, so that we only need space for one copy.
|
||||
These are initialized once for the entire compilation.
|
||||
All of these except perhaps the floating-point CONST_DOUBLEs
|
||||
are unique; no other rtx-object will be equal to any of these. */
|
||||
All of these are unique; no other rtx-object will be equal to any
|
||||
of these. */
|
||||
|
||||
rtx global_rtl[GR_MAX];
|
||||
|
||||
|
@ -148,6 +148,9 @@ static htab_t const_int_htab;
|
|||
/* A hash table storing memory attribute structures. */
|
||||
static htab_t mem_attrs_htab;
|
||||
|
||||
/* A hash table storing all CONST_DOUBLEs. */
|
||||
static htab_t const_double_htab;
|
||||
|
||||
/* start_sequence and gen_sequence can make a lot of rtx expressions which are
|
||||
shortly thrown away. We use two mechanisms to prevent this waste:
|
||||
|
||||
|
@ -188,6 +191,10 @@ static void mark_label_nuses PARAMS ((rtx));
|
|||
static hashval_t const_int_htab_hash PARAMS ((const void *));
|
||||
static int const_int_htab_eq PARAMS ((const void *,
|
||||
const void *));
|
||||
static hashval_t const_double_htab_hash PARAMS ((const void *));
|
||||
static int const_double_htab_eq PARAMS ((const void *,
|
||||
const void *));
|
||||
static rtx lookup_const_double PARAMS ((rtx));
|
||||
static hashval_t mem_attrs_htab_hash PARAMS ((const void *));
|
||||
static int mem_attrs_htab_eq PARAMS ((const void *,
|
||||
const void *));
|
||||
|
@ -208,7 +215,7 @@ static hashval_t
|
|||
const_int_htab_hash (x)
|
||||
const void *x;
|
||||
{
|
||||
return (hashval_t) INTVAL ((const struct rtx_def *) x);
|
||||
return (hashval_t) INTVAL ((struct rtx_def *) x);
|
||||
}
|
||||
|
||||
/* Returns non-zero if the value represented by X (which is really a
|
||||
|
@ -220,7 +227,40 @@ const_int_htab_eq (x, y)
|
|||
const void *x;
|
||||
const void *y;
|
||||
{
|
||||
return (INTVAL ((const struct rtx_def *) x) == *((const HOST_WIDE_INT *) y));
|
||||
return (INTVAL ((rtx) x) == *((const HOST_WIDE_INT *) y));
|
||||
}
|
||||
|
||||
/* Returns a hash code for X (which is really a CONST_DOUBLE). */
|
||||
static hashval_t
|
||||
const_double_htab_hash (x)
|
||||
const void *x;
|
||||
{
|
||||
hashval_t h = 0;
|
||||
size_t i;
|
||||
rtx value = (rtx) x;
|
||||
|
||||
for (i = 0; i < sizeof(CONST_DOUBLE_FORMAT)-1; i++)
|
||||
h ^= XWINT (value, i);
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Returns non-zero if the value represented by X (really a ...)
|
||||
is the same as that represented by Y (really a ...) */
|
||||
static int
|
||||
const_double_htab_eq (x, y)
|
||||
const void *x;
|
||||
const void *y;
|
||||
{
|
||||
rtx a = (rtx)x, b = (rtx)y;
|
||||
size_t i;
|
||||
|
||||
if (GET_MODE (a) != GET_MODE (b))
|
||||
return 0;
|
||||
for (i = 0; i < sizeof(CONST_DOUBLE_FORMAT)-1; i++)
|
||||
if (XWINT (a, i) != XWINT (b, i))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns a hash code for X (which is a really a mem_attrs *). */
|
||||
|
@ -363,32 +403,130 @@ gen_int_mode (c, mode)
|
|||
return GEN_INT (trunc_int_for_mode (c, mode));
|
||||
}
|
||||
|
||||
/* CONST_DOUBLEs needs special handling because their length is known
|
||||
only at run-time. */
|
||||
/* CONST_DOUBLEs might be created from pairs of integers, or from
|
||||
REAL_VALUE_TYPEs. Also, their length is known only at run time,
|
||||
so we cannot use gen_rtx_raw_CONST_DOUBLE. */
|
||||
|
||||
/* Determine whether REAL, a CONST_DOUBLE, already exists in the
|
||||
hash table. If so, return its counterpart; otherwise add it
|
||||
to the hash table and return it. */
|
||||
static rtx
|
||||
lookup_const_double (real)
|
||||
rtx real;
|
||||
{
|
||||
void **slot = htab_find_slot (const_double_htab, real, INSERT);
|
||||
if (*slot == 0)
|
||||
*slot = real;
|
||||
|
||||
return (rtx) *slot;
|
||||
}
|
||||
|
||||
/* Return a CONST_DOUBLE rtx for a floating-point value specified by
|
||||
VALUE in mode MODE. */
|
||||
rtx
|
||||
const_double_from_real_value (value, mode)
|
||||
REAL_VALUE_TYPE value;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
rtx real = rtx_alloc (CONST_DOUBLE);
|
||||
PUT_MODE (real, mode);
|
||||
|
||||
memcpy (&CONST_DOUBLE_LOW (real), &value, sizeof (REAL_VALUE_TYPE));
|
||||
|
||||
return lookup_const_double (real);
|
||||
}
|
||||
|
||||
/* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair
|
||||
of ints: I0 is the low-order word and I1 is the high-order word.
|
||||
Do not use this routine for non-integer modes; convert to
|
||||
REAL_VALUE_TYPE and use CONST_DOUBLE_FROM_REAL_VALUE. */
|
||||
|
||||
rtx
|
||||
gen_rtx_CONST_DOUBLE (mode, arg0, arg1)
|
||||
immed_double_const (i0, i1, mode)
|
||||
HOST_WIDE_INT i0, i1;
|
||||
enum machine_mode mode;
|
||||
HOST_WIDE_INT arg0, arg1;
|
||||
{
|
||||
rtx r = rtx_alloc (CONST_DOUBLE);
|
||||
int i;
|
||||
rtx value;
|
||||
unsigned int i;
|
||||
|
||||
PUT_MODE (r, mode);
|
||||
X0EXP (r, 0) = NULL_RTX;
|
||||
XWINT (r, 1) = arg0;
|
||||
XWINT (r, 2) = arg1;
|
||||
if (mode != VOIDmode)
|
||||
{
|
||||
int width;
|
||||
if (GET_MODE_CLASS (mode) != MODE_INT
|
||||
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
|
||||
abort ();
|
||||
|
||||
for (i = GET_RTX_LENGTH (CONST_DOUBLE) - 1; i > 2; --i)
|
||||
XWINT (r, i) = 0;
|
||||
/* We clear out all bits that don't belong in MODE, unless they and
|
||||
our sign bit are all one. So we get either a reasonable negative
|
||||
value or a reasonable unsigned value for this mode. */
|
||||
width = GET_MODE_BITSIZE (mode);
|
||||
if (width < HOST_BITS_PER_WIDE_INT
|
||||
&& ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1)))
|
||||
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
|
||||
i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0;
|
||||
else if (width == HOST_BITS_PER_WIDE_INT
|
||||
&& ! (i1 == ~0 && i0 < 0))
|
||||
i1 = 0;
|
||||
else if (width > 2 * HOST_BITS_PER_WIDE_INT)
|
||||
/* We cannot represent this value as a constant. */
|
||||
abort ();
|
||||
|
||||
return r;
|
||||
/* If this would be an entire word for the target, but is not for
|
||||
the host, then sign-extend on the host so that the number will
|
||||
look the same way on the host that it would on the target.
|
||||
|
||||
For example, when building a 64 bit alpha hosted 32 bit sparc
|
||||
targeted compiler, then we want the 32 bit unsigned value -1 to be
|
||||
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
|
||||
The latter confuses the sparc backend. */
|
||||
|
||||
if (width < HOST_BITS_PER_WIDE_INT
|
||||
&& (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
|
||||
i0 |= ((HOST_WIDE_INT) (-1) << width);
|
||||
|
||||
/* If MODE fits within HOST_BITS_PER_WIDE_INT, always use a
|
||||
CONST_INT.
|
||||
|
||||
??? Strictly speaking, this is wrong if we create a CONST_INT for
|
||||
a large unsigned constant with the size of MODE being
|
||||
HOST_BITS_PER_WIDE_INT and later try to interpret that constant
|
||||
in a wider mode. In that case we will mis-interpret it as a
|
||||
negative number.
|
||||
|
||||
Unfortunately, the only alternative is to make a CONST_DOUBLE for
|
||||
any constant in any mode if it is an unsigned constant larger
|
||||
than the maximum signed integer in an int on the host. However,
|
||||
doing this will break everyone that always expects to see a
|
||||
CONST_INT for SImode and smaller.
|
||||
|
||||
We have always been making CONST_INTs in this case, so nothing
|
||||
new is being broken. */
|
||||
|
||||
if (width <= HOST_BITS_PER_WIDE_INT)
|
||||
i1 = (i0 < 0) ? ~(HOST_WIDE_INT) 0 : 0;
|
||||
}
|
||||
|
||||
/* If this integer fits in one word, return a CONST_INT. */
|
||||
if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
|
||||
return GEN_INT (i0);
|
||||
|
||||
/* We use VOIDmode for integers. */
|
||||
value = rtx_alloc (CONST_DOUBLE);
|
||||
PUT_MODE (value, VOIDmode);
|
||||
|
||||
CONST_DOUBLE_LOW (value) = i0;
|
||||
CONST_DOUBLE_HIGH (value) = i1;
|
||||
|
||||
for (i = 2; i < (sizeof CONST_DOUBLE_FORMAT - 1); i++)
|
||||
XWINT (value, i) = 0;
|
||||
|
||||
return lookup_const_double (value);
|
||||
}
|
||||
|
||||
rtx
|
||||
gen_rtx_REG (mode, regno)
|
||||
enum machine_mode mode;
|
||||
int regno;
|
||||
unsigned int regno;
|
||||
{
|
||||
/* In case the MD file explicitly references the frame pointer, have
|
||||
all such references point to the same frame pointer. This is
|
||||
|
@ -463,7 +601,7 @@ gen_rtx_SUBREG (mode, reg, offset)
|
|||
if (offset >= GET_MODE_SIZE (GET_MODE (reg)))
|
||||
abort ();
|
||||
#endif
|
||||
return gen_rtx_fmt_ei (SUBREG, mode, reg, offset);
|
||||
return gen_rtx_raw_SUBREG (mode, reg, offset);
|
||||
}
|
||||
|
||||
/* Generate a SUBREG representing the least-significant part of REG if MODE
|
||||
|
@ -532,7 +670,7 @@ gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
|
|||
HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
|
||||
HOST_WIDE_INT arg1 = va_arg (p, HOST_WIDE_INT);
|
||||
|
||||
rt_val = gen_rtx_CONST_DOUBLE (mode, arg0, arg1);
|
||||
rt_val = immed_double_const (arg0, arg1, mode);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4849,11 +4987,16 @@ init_emit_once (line_numbers)
|
|||
enum machine_mode mode;
|
||||
enum machine_mode double_mode;
|
||||
|
||||
/* Initialize the CONST_INT and memory attribute hash tables. */
|
||||
/* Initialize the CONST_INT, CONST_DOUBLE, and memory attribute hash
|
||||
tables. */
|
||||
const_int_htab = htab_create (37, const_int_htab_hash,
|
||||
const_int_htab_eq, NULL);
|
||||
ggc_add_deletable_htab (const_int_htab, 0, 0);
|
||||
|
||||
const_double_htab = htab_create (37, const_double_htab_hash,
|
||||
const_double_htab_eq, NULL);
|
||||
ggc_add_deletable_htab (const_double_htab, 0, 0);
|
||||
|
||||
mem_attrs_htab = htab_create (37, mem_attrs_htab_hash,
|
||||
mem_attrs_htab_eq, NULL);
|
||||
ggc_add_deletable_htab (mem_attrs_htab, 0, mem_attrs_mark);
|
||||
|
@ -4937,10 +5080,10 @@ init_emit_once (line_numbers)
|
|||
else
|
||||
const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
|
||||
|
||||
dconst0 = REAL_VALUE_ATOF ("0", double_mode);
|
||||
dconst1 = REAL_VALUE_ATOF ("1", double_mode);
|
||||
dconst2 = REAL_VALUE_ATOF ("2", double_mode);
|
||||
dconstm1 = REAL_VALUE_ATOF ("-1", double_mode);
|
||||
REAL_VALUE_FROM_INT (dconst0, 0, 0, double_mode);
|
||||
REAL_VALUE_FROM_INT (dconst1, 1, 0, double_mode);
|
||||
REAL_VALUE_FROM_INT (dconst2, 2, 0, double_mode);
|
||||
REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);
|
||||
|
||||
for (i = 0; i <= 2; i++)
|
||||
{
|
||||
|
@ -4949,17 +5092,8 @@ init_emit_once (line_numbers)
|
|||
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
|
||||
mode = GET_MODE_WIDER_MODE (mode))
|
||||
{
|
||||
rtx tem = rtx_alloc (CONST_DOUBLE);
|
||||
|
||||
/* Can't use CONST_DOUBLE_FROM_REAL_VALUE here; that uses the
|
||||
tables we're setting up right now. */
|
||||
memcpy (&CONST_DOUBLE_LOW (tem), r, sizeof (REAL_VALUE_TYPE));
|
||||
CONST_DOUBLE_CHAIN (tem) = NULL_RTX;
|
||||
PUT_MODE (tem, mode);
|
||||
|
||||
const_tiny_rtx[i][(int) mode] = tem;
|
||||
}
|
||||
const_tiny_rtx[i][(int) mode] =
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
|
||||
|
||||
const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);
|
||||
|
||||
|
|
|
@ -6486,7 +6486,8 @@ expand_expr (exp, target, tmode, modifier)
|
|||
many insns, so we'd end up copying it to a register in any case.
|
||||
|
||||
Now, we do the copying in expand_binop, if appropriate. */
|
||||
return immed_real_const (exp);
|
||||
return CONST_DOUBLE_FROM_REAL_VALUE (TREE_REAL_CST (exp),
|
||||
TYPE_MODE (TREE_TYPE (exp)));
|
||||
|
||||
case COMPLEX_CST:
|
||||
case STRING_CST:
|
||||
|
|
|
@ -132,21 +132,31 @@ special_format (fmt)
|
|||
|| strchr (fmt, 'n') != 0);
|
||||
}
|
||||
|
||||
/* Return nonzero if the RTL code given by index IDX is one that we should not
|
||||
generate a gen_RTX_FOO function foo (because that function is present
|
||||
elsewhere in the compiler). */
|
||||
/* Return nonzero if the RTL code given by index IDX is one that we should
|
||||
generate a gen_rtx_raw_FOO macro for, not gen_rtx_FOO (because gen_rtx_FOO
|
||||
is a wrapper in emit-rtl.c). */
|
||||
|
||||
static int
|
||||
special_rtx (idx)
|
||||
int idx;
|
||||
{
|
||||
return (strcmp (defs[idx].enumname, "CONST_INT") == 0
|
||||
|| strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0
|
||||
|| strcmp (defs[idx].enumname, "REG") == 0
|
||||
|| strcmp (defs[idx].enumname, "SUBREG") == 0
|
||||
|| strcmp (defs[idx].enumname, "MEM") == 0);
|
||||
}
|
||||
|
||||
/* Return nonzero if the RTL code given by index IDX is one that we should
|
||||
generate no macro for at all (because gen_rtx_FOO is never used or
|
||||
cannot have the obvious interface). */
|
||||
|
||||
static int
|
||||
excluded_rtx (idx)
|
||||
int idx;
|
||||
{
|
||||
return (strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0);
|
||||
}
|
||||
|
||||
/* Place a list of all format specifiers we use into the array FORMAT. */
|
||||
|
||||
static void
|
||||
|
@ -213,6 +223,10 @@ genmacro (idx)
|
|||
/* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to
|
||||
gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE. */
|
||||
|
||||
if (excluded_rtx (idx))
|
||||
/* Don't define a macro for this code. */
|
||||
return;
|
||||
|
||||
printf ("#define gen_rtx_%s%s(MODE",
|
||||
special_rtx (idx) ? "raw_" : "", defs[idx].enumname);
|
||||
|
||||
|
|
|
@ -347,9 +347,6 @@ ggc_mark_rtx_children_1 (r)
|
|||
case ADDRESSOF:
|
||||
ggc_mark_tree (ADDRESSOF_DECL (r));
|
||||
break;
|
||||
case CONST_DOUBLE:
|
||||
ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
|
||||
break;
|
||||
case NOTE:
|
||||
switch (NOTE_LINE_NUMBER (r))
|
||||
{
|
||||
|
|
|
@ -357,11 +357,6 @@ extern void assemble_real PARAMS ((REAL_VALUE_TYPE,
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* At the end of a function, forget the memory-constants
|
||||
previously made for CONST_DOUBLEs. Mark them as not on real_constant_chain.
|
||||
Also clear out real_constant_chain and clear out all the chain-pointers. */
|
||||
extern void clear_const_double_mem PARAMS ((void));
|
||||
|
||||
/* Start deferring output of subconstants. */
|
||||
extern void defer_addressed_constants PARAMS ((void));
|
||||
|
||||
|
|
26
gcc/real.h
26
gcc/real.h
|
@ -89,7 +89,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
+ (REAL_VALUE_TYPE_SIZE%HOST_BITS_PER_WIDE_INT ? 1 : 0)) /* round up */
|
||||
typedef struct {
|
||||
HOST_WIDE_INT r[REAL_WIDTH];
|
||||
} REAL_VALUE_TYPE;
|
||||
} realvaluetype;
|
||||
/* Various headers condition prototypes on #ifdef REAL_VALUE_TYPE, so it needs
|
||||
to be a macro. */
|
||||
#define REAL_VALUE_TYPE realvaluetype
|
||||
|
||||
/* Calculate the format for CONST_DOUBLE. We need as many slots as
|
||||
are necessary to overlay a REAL_VALUE_TYPE on them. This could be
|
||||
|
@ -99,19 +102,19 @@ typedef struct {
|
|||
slots in a CONST_DOUBLE, so we provide them even if one would suffice. */
|
||||
|
||||
#if REAL_WIDTH == 1
|
||||
# define CONST_DOUBLE_FORMAT "0ww"
|
||||
# define CONST_DOUBLE_FORMAT "ww"
|
||||
#else
|
||||
# if REAL_WIDTH == 2
|
||||
# define CONST_DOUBLE_FORMAT "0ww"
|
||||
# define CONST_DOUBLE_FORMAT "ww"
|
||||
# else
|
||||
# if REAL_WIDTH == 3
|
||||
# define CONST_DOUBLE_FORMAT "0www"
|
||||
# define CONST_DOUBLE_FORMAT "www"
|
||||
# else
|
||||
# if REAL_WIDTH == 4
|
||||
# define CONST_DOUBLE_FORMAT "0wwww"
|
||||
# define CONST_DOUBLE_FORMAT "wwww"
|
||||
# else
|
||||
# if REAL_WIDTH == 5
|
||||
# define CONST_DOUBLE_FORMAT "0wwwww"
|
||||
# define CONST_DOUBLE_FORMAT "wwwww"
|
||||
# else
|
||||
#error "REAL_WIDTH > 5 not supported"
|
||||
# endif
|
||||
|
@ -265,9 +268,14 @@ REAL_VALUE_TYPE real_value_from_int_cst PARAMS ((union tree_node *,
|
|||
|
||||
/* Return a CONST_DOUBLE with value R and mode M. */
|
||||
|
||||
#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) immed_real_const_1 (r, m)
|
||||
extern struct rtx_def *immed_real_const_1 PARAMS ((REAL_VALUE_TYPE,
|
||||
enum machine_mode));
|
||||
#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) \
|
||||
const_double_from_real_value (r, m)
|
||||
extern rtx const_double_from_real_value PARAMS ((REAL_VALUE_TYPE,
|
||||
enum machine_mode));
|
||||
|
||||
/* Shorthand; can be handy in machine descriptions. */
|
||||
#define CONST_DOUBLE_ATOF(s, m) \
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_ATOF (s, m), m)
|
||||
|
||||
/* Replace R by 1/R in the given machine mode, if the result is exact. */
|
||||
extern int exact_real_inverse PARAMS ((enum machine_mode, REAL_VALUE_TYPE *));
|
||||
|
|
12
gcc/rtl.h
12
gcc/rtl.h
|
@ -946,11 +946,8 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
|
|||
For a float, the number of ints varies,
|
||||
and CONST_DOUBLE_LOW is the one that should come first *in memory*.
|
||||
So use &CONST_DOUBLE_LOW(r) as the address of an array of ints. */
|
||||
#define CONST_DOUBLE_LOW(r) XCWINT (r, 1, CONST_DOUBLE)
|
||||
#define CONST_DOUBLE_HIGH(r) XCWINT (r, 2, CONST_DOUBLE)
|
||||
|
||||
/* Link for chain of all CONST_DOUBLEs in use in current function. */
|
||||
#define CONST_DOUBLE_CHAIN(r) XCEXP (r, 0, CONST_DOUBLE)
|
||||
#define CONST_DOUBLE_LOW(r) XCWINT (r, 0, CONST_DOUBLE)
|
||||
#define CONST_DOUBLE_HIGH(r) XCWINT (r, 1, CONST_DOUBLE)
|
||||
|
||||
/* For a CONST_VECTOR, return element #n. */
|
||||
#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)
|
||||
|
@ -1802,11 +1799,9 @@ extern rtx return_address_pointer_rtx;
|
|||
add to this list, modify special_rtx in gengenrtl.c as well. You
|
||||
should also modify gen_rtx to use the special function. */
|
||||
|
||||
extern rtx gen_rtx_CONST_DOUBLE PARAMS ((enum machine_mode,
|
||||
HOST_WIDE_INT, HOST_WIDE_INT));
|
||||
extern rtx gen_rtx_CONST_INT PARAMS ((enum machine_mode, HOST_WIDE_INT));
|
||||
extern rtx gen_raw_REG PARAMS ((enum machine_mode, int));
|
||||
extern rtx gen_rtx_REG PARAMS ((enum machine_mode, int));
|
||||
extern rtx gen_rtx_REG PARAMS ((enum machine_mode, unsigned));
|
||||
extern rtx gen_rtx_SUBREG PARAMS ((enum machine_mode, rtx, int));
|
||||
extern rtx gen_rtx_MEM PARAMS ((enum machine_mode, rtx));
|
||||
|
||||
|
@ -1883,7 +1878,6 @@ extern rtx gen_lowpart_SUBREG PARAMS ((enum machine_mode, rtx));
|
|||
extern rtx find_next_ref PARAMS ((rtx, rtx));
|
||||
|
||||
extern rtx output_constant_def PARAMS ((tree, int));
|
||||
extern rtx immed_real_const PARAMS ((tree));
|
||||
|
||||
/* Define a default value for STORE_FLAG_VALUE. */
|
||||
|
||||
|
|
|
@ -3491,10 +3491,6 @@ rest_of_compilation (decl)
|
|||
longer valid. */
|
||||
init_insn_lengths ();
|
||||
|
||||
/* Clear out the real_constant_chain before some of the rtx's
|
||||
it runs through become garbage. */
|
||||
clear_const_double_mem ();
|
||||
|
||||
/* Show no temporary slots allocated. */
|
||||
init_temp_slots ();
|
||||
|
||||
|
|
191
gcc/varasm.c
191
gcc/varasm.c
|
@ -95,10 +95,6 @@ struct varasm_status
|
|||
/* Current offset in constant pool (does not include any machine-specific
|
||||
header). */
|
||||
HOST_WIDE_INT x_pool_offset;
|
||||
|
||||
/* Chain of all CONST_DOUBLE rtx's constructed for the current function.
|
||||
They are chained through the CONST_DOUBLE_CHAIN. */
|
||||
rtx x_const_double_chain;
|
||||
};
|
||||
|
||||
#define const_rtx_hash_table (cfun->varasm->x_const_rtx_hash_table)
|
||||
|
@ -106,7 +102,6 @@ struct varasm_status
|
|||
#define first_pool (cfun->varasm->x_first_pool)
|
||||
#define last_pool (cfun->varasm->x_last_pool)
|
||||
#define pool_offset (cfun->varasm->x_pool_offset)
|
||||
#define const_double_chain (cfun->varasm->x_const_double_chain)
|
||||
|
||||
/* Number for making the label on the next
|
||||
constant that is stored in memory. */
|
||||
|
@ -2104,190 +2099,6 @@ assemble_real (d, mode, align)
|
|||
}
|
||||
}
|
||||
|
||||
/* Here we combine duplicate floating constants to make
|
||||
CONST_DOUBLE rtx's, and force those out to memory when necessary. */
|
||||
|
||||
/* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair of ints.
|
||||
For an integer, I0 is the low-order word and I1 is the high-order word.
|
||||
For a real number, I0 is the word with the low address
|
||||
and I1 is the word with the high address. */
|
||||
|
||||
rtx
|
||||
immed_double_const (i0, i1, mode)
|
||||
HOST_WIDE_INT i0, i1;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
rtx r;
|
||||
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
|| GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
|
||||
{
|
||||
/* We clear out all bits that don't belong in MODE, unless they and our
|
||||
sign bit are all one. So we get either a reasonable negative value
|
||||
or a reasonable unsigned value for this mode. */
|
||||
int width = GET_MODE_BITSIZE (mode);
|
||||
if (width < HOST_BITS_PER_WIDE_INT
|
||||
&& ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1)))
|
||||
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
|
||||
i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0;
|
||||
else if (width == HOST_BITS_PER_WIDE_INT
|
||||
&& ! (i1 == ~0 && i0 < 0))
|
||||
i1 = 0;
|
||||
else if (width > 2 * HOST_BITS_PER_WIDE_INT)
|
||||
/* We cannot represent this value as a constant. */
|
||||
abort ();
|
||||
|
||||
/* If this would be an entire word for the target, but is not for
|
||||
the host, then sign-extend on the host so that the number will look
|
||||
the same way on the host that it would on the target.
|
||||
|
||||
For example, when building a 64 bit alpha hosted 32 bit sparc
|
||||
targeted compiler, then we want the 32 bit unsigned value -1 to be
|
||||
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
|
||||
The later confuses the sparc backend. */
|
||||
|
||||
if (width < HOST_BITS_PER_WIDE_INT
|
||||
&& (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
|
||||
i0 |= ((HOST_WIDE_INT) (-1) << width);
|
||||
|
||||
/* If MODE fits within HOST_BITS_PER_WIDE_INT, always use a CONST_INT.
|
||||
|
||||
??? Strictly speaking, this is wrong if we create a CONST_INT
|
||||
for a large unsigned constant with the size of MODE being
|
||||
HOST_BITS_PER_WIDE_INT and later try to interpret that constant in a
|
||||
wider mode. In that case we will mis-interpret it as a negative
|
||||
number.
|
||||
|
||||
Unfortunately, the only alternative is to make a CONST_DOUBLE
|
||||
for any constant in any mode if it is an unsigned constant larger
|
||||
than the maximum signed integer in an int on the host. However,
|
||||
doing this will break everyone that always expects to see a CONST_INT
|
||||
for SImode and smaller.
|
||||
|
||||
We have always been making CONST_INTs in this case, so nothing new
|
||||
is being broken. */
|
||||
|
||||
if (width <= HOST_BITS_PER_WIDE_INT)
|
||||
i1 = (i0 < 0) ? ~(HOST_WIDE_INT) 0 : 0;
|
||||
|
||||
/* If this integer fits in one word, return a CONST_INT. */
|
||||
if ((i1 == 0 && i0 >= 0)
|
||||
|| (i1 == ~0 && i0 < 0))
|
||||
return GEN_INT (i0);
|
||||
|
||||
/* We use VOIDmode for integers. */
|
||||
mode = VOIDmode;
|
||||
}
|
||||
|
||||
/* Search the chain for an existing CONST_DOUBLE with the right value.
|
||||
If one is found, return it. */
|
||||
if (cfun != 0)
|
||||
for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
|
||||
if (CONST_DOUBLE_LOW (r) == i0 && CONST_DOUBLE_HIGH (r) == i1
|
||||
&& GET_MODE (r) == mode)
|
||||
return r;
|
||||
|
||||
/* No; make a new one and add it to the chain. */
|
||||
r = gen_rtx_CONST_DOUBLE (mode, i0, i1);
|
||||
|
||||
/* Don't touch const_double_chain if not inside any function. */
|
||||
if (current_function_decl != 0)
|
||||
{
|
||||
CONST_DOUBLE_CHAIN (r) = const_double_chain;
|
||||
const_double_chain = r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Return a CONST_DOUBLE for a specified `double' value
|
||||
and machine mode. */
|
||||
|
||||
rtx
|
||||
immed_real_const_1 (d, mode)
|
||||
REAL_VALUE_TYPE d;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
rtx r;
|
||||
|
||||
/* Detect special cases. Check for NaN first, because some ports
|
||||
(specifically the i386) do not emit correct ieee-fp code by default, and
|
||||
thus will generate a core dump here if we pass a NaN to REAL_VALUES_EQUAL
|
||||
and if REAL_VALUES_EQUAL does a floating point comparison. */
|
||||
if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_IDENTICAL (dconst0, d))
|
||||
return CONST0_RTX (mode);
|
||||
else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst1, d))
|
||||
return CONST1_RTX (mode);
|
||||
else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst2, d))
|
||||
return CONST2_RTX (mode);
|
||||
|
||||
if (sizeof (REAL_VALUE_TYPE) == sizeof (HOST_WIDE_INT))
|
||||
return immed_double_const (d.r[0], 0, mode);
|
||||
if (sizeof (REAL_VALUE_TYPE) == 2 * sizeof (HOST_WIDE_INT))
|
||||
return immed_double_const (d.r[0], d.r[1], mode);
|
||||
|
||||
/* The rest of this function handles the case where
|
||||
a float value requires more than 2 ints of space.
|
||||
It will be deleted as dead code on machines that don't need it. */
|
||||
|
||||
/* Search the chain for an existing CONST_DOUBLE with the right value.
|
||||
If one is found, return it. */
|
||||
if (cfun != 0)
|
||||
for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
|
||||
if (! memcmp ((char *) &CONST_DOUBLE_LOW (r), (char *) &d, sizeof d)
|
||||
&& GET_MODE (r) == mode)
|
||||
return r;
|
||||
|
||||
/* No; make a new one and add it to the chain.
|
||||
|
||||
We may be called by an optimizer which may be discarding any memory
|
||||
allocated during its processing (such as combine and loop). However,
|
||||
we will be leaving this constant on the chain, so we cannot tolerate
|
||||
freed memory. */
|
||||
r = rtx_alloc (CONST_DOUBLE);
|
||||
PUT_MODE (r, mode);
|
||||
memcpy ((char *) &CONST_DOUBLE_LOW (r), (char *) &d, sizeof d);
|
||||
|
||||
/* If we aren't inside a function, don't put r on the
|
||||
const_double_chain. */
|
||||
if (current_function_decl != 0)
|
||||
{
|
||||
CONST_DOUBLE_CHAIN (r) = const_double_chain;
|
||||
const_double_chain = r;
|
||||
}
|
||||
else
|
||||
CONST_DOUBLE_CHAIN (r) = NULL_RTX;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Return a CONST_DOUBLE rtx for a value specified by EXP,
|
||||
which must be a REAL_CST tree node. */
|
||||
|
||||
rtx
|
||||
immed_real_const (exp)
|
||||
tree exp;
|
||||
{
|
||||
return immed_real_const_1 (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)));
|
||||
}
|
||||
|
||||
/* At the end of a function, forget the memory-constants
|
||||
previously made for CONST_DOUBLEs. Mark them as not on real_constant_chain.
|
||||
Also clear out real_constant_chain and clear out all the chain-pointers. */
|
||||
|
||||
void
|
||||
clear_const_double_mem ()
|
||||
{
|
||||
rtx r, next;
|
||||
|
||||
for (r = const_double_chain; r; r = next)
|
||||
{
|
||||
next = CONST_DOUBLE_CHAIN (r);
|
||||
CONST_DOUBLE_CHAIN (r) = 0;
|
||||
}
|
||||
const_double_chain = 0;
|
||||
}
|
||||
|
||||
/* Given an expression EXP with a constant value,
|
||||
reduce it to the sum of an assembler symbol and an integer.
|
||||
Store them both in the structure *VALUE.
|
||||
|
@ -3470,7 +3281,6 @@ init_varasm_status (f)
|
|||
|
||||
p->x_first_pool = p->x_last_pool = 0;
|
||||
p->x_pool_offset = 0;
|
||||
p->x_const_double_chain = 0;
|
||||
}
|
||||
|
||||
/* Mark PC for GC. */
|
||||
|
@ -3498,7 +3308,6 @@ mark_varasm_status (p)
|
|||
return;
|
||||
|
||||
mark_pool_constant (p->x_first_pool);
|
||||
ggc_mark_rtx (p->x_const_double_chain);
|
||||
}
|
||||
|
||||
/* Clear out all parts of the state in F that can safely be discarded
|
||||
|
|
Loading…
Add table
Reference in a new issue