* Copyright (c) 2002-2008 VMware, Inc. All rights reserved.
* **********************************************************/
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of VMware, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#ifdef LOAD_TO_CONST
# ifndef __LOADTOCONST_H_
# define __LOADTOCONST_H_
# define NUM_VALUES_FOR_SPECULATION 40
# define SAMPLE_PERCENT (9 / 10)
# define MAX_TRACES_WAITING_FOR_LTC 20
# include "instr.h"
struct ltc_mem_ref_data {
opnd_t opnd;
int vals[NUM_VALUES_FOR_SPECULATION];
int addresses[NUM_VALUES_FOR_SPECULATION];
};
struct ltc_data {
struct ltc_mem_ref_data *mem_refs;
int num_mem_addresses;
int num_mem_samples;
bool ltc_already_optimized;
};
# ifdef LTC_STATS
extern int safe_taken, opt_taken, addrs_analyzed, addrs_made_const, traces_analyzed,
addrs_seen;
# endif
void
analyze_memrefs(dcontext_t *dcontext, app_pc tag, instrlist_t *trace);
int
check_mem_refs(app_pc tag, int errno, reg_t eflags, reg_t reg_edi, reg_t reg_esi,
reg_t reg_ebp, reg_t reg_esp, reg_t reg_ebx, reg_t reg_edx, reg_t reg_ecx,
reg_t reg_eax);
int
get_mem_address(dcontext_t *dcontext, opnd_t mem_access, int regs[8]);
int
get_mem_val(dcontext_t *dcontext, opnd_t mem_access, int address);
void
ltc_trace(dcontext_t *dcontext, fragment_t *, instrlist_t *trace);
void
remove_mem_ref_check(dcontext_t *dcontext, instrlist_t *trace);
# ifdef SIDELINE
void
LTC_examine_traces(void);
void
LTC_fragment_delete(fragment_t *frag);
# endif
void
LTC_online_optimize_and_replace(dcontext_t *dcontext, app_pc tag, fragment_t *curfrag);
void
do_single_LTC(dcontext_t *dcontext, instrlist_t *trace, opnd_t mem_access, opnd_t value);
bool
should_replace_load(dcontext_t *dcontext, struct ltc_mem_ref_data data);
opnd_t value_to_replace(struct ltc_mem_ref_data);
bool
instr_replace_reg_with_const_in_src(dcontext_t *dcontext, instr_t *in, int reg, int val);
bool
instr_replace_reg_with_const_in_dst(dcontext_t *dcontext, instr_t *in, int reg, int val);
instrlist_t *
save_eflags_list(dcontext_t *dcontext, fragment_t *frag);
instrlist_t *
restore_eflags_list(dcontext_t *dcontext, fragment_t *frag);
void
change_cbr_due_to_reversed_cmp(instr_t *in);
bool
pc_reads_flags_before_writes(dcontext_t *dcontext, app_pc target);
instr_t *
fix_cmp_containing_constant(dcontext_t *dcontext, instrlist_t *trace, instr_t *in,
opnd_t orig_op1, opnd_t orig_op2);
void
replace_self_loop_with_opnd(dcontext_t *dcontext, app_pc tag, instrlist_t *ilist,
opnd_t desiredtarget);
# define TRANSPOSE true
# define NO_TRANSPOSE false
bool
safe_to_transpose_cmp(dcontext_t *dcontext, instr_t *testinstr);
bool
safe_to_delete_cmp(dcontext_t *dcontext, instr_t *testinstr);
bool
safe_to_modify_cmp(dcontext_t *dcontext, instr_t *testinstr, bool transpose);
bool
becomes_ubr_from_cmp(instr_t *in, int op1, int op2);
bool
opnd_replace_reg_with_val(opnd_t *opnd, int old_reg, int val);
void
constant_propagate(dcontext_t *dcontext, instrlist_t *trace, app_pc tag);
void
pop_instr_off_list(dcontext_t *dcontext, instrlist_t *trace, int opcode);
void
instr_optimize_constant(dcontext_t *dcontext, instr_t *in);
bool
instr_flag_write_necessary(dcontext_t *dcontext, instr_t *in);
void
instr_replace_inplace(dcontext_t *dcontext, instr_t *in, instr_t *);
void
instr_arithmatic_simplify(dcontext_t *dcontext, instr_t *in);
void
instrlist_remove_nops(dcontext_t *dcontext, instrlist_t *trace);
bool
instrlist_depends_on_reg(dcontext_t *dcontext, instrlist_t *trace, int reg);
void
instr_add_to_exitexec_list(dcontext_t *, instr_t *in, instr_t *exitinstr);
void
instrlist_setup_pseudo_exitstubs(dcontext_t *dcontext, instrlist_t *trace);
# endif
#endif