Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions linux-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,60 @@ static void handle_arg_latx_imm_reg(const char *arg)
options_parse_imm_reg(arg);
}

static void handle_arg_latx_imm_rip(const char *arg)
{
int value;

if (qemu_strtoi(arg, NULL, 0, &value) || value < 0 || value > 1) {
error_report("LATX_IMM_RIP must be exactly 0 or 1 (got '%s')", arg);
exit(EXIT_FAILURE);
}
option_imm_rip = value;
if (value) {
option_imm_reg = 1;
}
}

static void handle_arg_latx_imm_rip_stats(const char *arg)
{
int value;

if (qemu_strtoi(arg, NULL, 0, &value) || value < 0 || value > 1) {
error_report("LATX_IMM_RIP_STATS must be exactly 0 or 1 (got '%s')",
arg);
exit(EXIT_FAILURE);
}
option_imm_rip_stats = value;
}

static void handle_arg_latx_imm_complex(const char *arg)
{
int value;

if (qemu_strtoi(arg, NULL, 0, &value) || value < 0 ||
value > LATX_IMM_COMPLEX_ALL) {
error_report("LATX_IMM_COMPLEX must be a mask from 0 to %d (got '%s')",
LATX_IMM_COMPLEX_ALL, arg);
exit(EXIT_FAILURE);
}
option_imm_complex = value;
if (value) {
option_imm_reg = 1;
}
}

static void handle_arg_latx_imm_complex_stats(const char *arg)
{
int value;

if (qemu_strtoi(arg, NULL, 0, &value) || value < 0 || value > 1) {
error_report("LATX_IMM_COMPLEX_STATS must be exactly 0 or 1 "
"(got '%s')", arg);
exit(EXIT_FAILURE);
}
option_imm_complex_stats = value;
}

static void handle_arg_save_xmm(const char *arg)
{
if (strtol(arg, NULL, 0)) {
Expand Down Expand Up @@ -945,6 +999,17 @@ static const struct qemu_argument arg_table[] = {
"", "enable jrra"},
{"latx-imm-reg", "LATX_IMM_REG", true, handle_arg_latx_imm_reg,
"", "enable imm reg optimization"},
{"latx-imm-rip", "LATX_IMM_RIP", true, handle_arg_latx_imm_rip,
"0|1", "enable CODE64 RIP-relative immediate cache"},
{"latx-imm-rip-stats", "LATX_IMM_RIP_STATS", true,
handle_arg_latx_imm_rip_stats, "0|1",
"report per-TB RIP-relative immediate cache statistics"},
{"latx-imm-complex", "LATX_IMM_COMPLEX", true,
handle_arg_latx_imm_complex, "mask",
"enable complex-address cache modes (1=base, 2=index, 4=combined)"},
{"latx-imm-complex-stats", "LATX_IMM_COMPLEX_STATS", true,
handle_arg_latx_imm_complex_stats, "0|1",
"report per-TB complex-address cache statistics"},
{"latx-mem-test", "LATX_MT", true, handle_arg_latx_mem_test,
"", "test memory right when memory access"},
{"latx-real-maps", "LATX_REAL_MAPS", true, handle_arg_latx_real_maps,
Expand Down
6 changes: 4 additions & 2 deletions target/i386/latx/include/aot.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ extern const char *aot_left_file_minsize_optarg;
* +--------------+
*/
#ifdef CONFIG_LATX_DEBUG
#define AOT_VERSION "Version: "LATX_VERSION"-debug"
#define AOT_VERSION "Version: "LATX_VERSION"-debug-immcfg2"
#else
#define AOT_VERSION "Version: "LATX_VERSION"-release"
#define AOT_VERSION "Version: "LATX_VERSION"-release-immcfg2"
#endif
typedef struct aot_header {
uint32_t lib_size;
Expand All @@ -57,6 +57,8 @@ typedef struct aot_header {
#define CACHE_AOT_FILE 4
#define HASH_AOT_FILE 8
uint8_t aot_file_type;
uint8_t imm_rip;
uint8_t imm_complex;
} aot_header;

typedef struct aot_file_info {
Expand Down
54 changes: 54 additions & 0 deletions target/i386/latx/include/imm-cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#define CACHE_DEFAULT_CAPACITY 4
#define CACHE_MAX_CAPACITY 300
#define IMM_CACHE_RIP_BASE (-100)

#define imm_log(FMT, ...) \
do { \
Expand Down Expand Up @@ -61,6 +62,54 @@ typedef struct {
int64 max_offset;
} IMM_CACHE_BUCKET;

typedef struct {
uint64_t calls;
uint64_t hits;
uint64_t misses;
uint64_t replacements;
uint64_t itemp_fallbacks;
uint64_t direct_hits;
uint64_t host_offset_hits;
uint64_t addi_hits;
uint64_t full_loads;
uint64_t helper_invalidations;
} IMM_CACHE_RIP_STATS;

typedef enum {
IMM_CACHE_COMPLEX_BASE_DISP,
IMM_CACHE_COMPLEX_INDEX_DISP,
IMM_CACHE_COMPLEX_BASE_INDEX_DISP,
IMM_CACHE_COMPLEX_KIND_COUNT,
} IMM_CACHE_COMPLEX_KIND;

typedef enum {
IMM_CACHE_COMPLEX_SKIP_DISABLED,
IMM_CACHE_COMPLEX_SKIP_NOT_CODE64,
IMM_CACHE_COMPLEX_SKIP_ADDR_SIZE,
IMM_CACHE_COMPLEX_SKIP_SEGMENT,
IMM_CACHE_COMPLEX_SKIP_UNSUPPORTED_FORM,
IMM_CACHE_COMPLEX_SKIP_INVALID_SCALE,
IMM_CACHE_COMPLEX_SKIP_NO_BENEFIT,
IMM_CACHE_COMPLEX_SKIP_INSTRUCTION,
IMM_CACHE_COMPLEX_SKIP_FIXED_DEST,
IMM_CACHE_COMPLEX_SKIP_COUNT,
} IMM_CACHE_COMPLEX_SKIP_REASON;

typedef struct {
uint64_t calls[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t hits[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t misses[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t replacements[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t itemp_conflicts[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t direct_hits[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t host_offset_hits[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t addi_hits[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t full_generations[IMM_CACHE_COMPLEX_KIND_COUNT];
uint64_t skips[IMM_CACHE_COMPLEX_SKIP_COUNT];
uint64_t base_index_invalidations;
uint64_t use_def_fallbacks;
} IMM_CACHE_COMPLEX_STATS;

/**
* imm format:
* (offset can be 0)
Expand Down Expand Up @@ -93,6 +142,8 @@ typedef struct {
* if we use cached itemp, ra_free_temp should skip
*/
bool itemp_allocated;
IMM_CACHE_RIP_STATS rip_stats;
IMM_CACHE_COMPLEX_STATS complex_stats;

/**
* for complex imm, we need to compare whether base/index reg has been
Expand Down Expand Up @@ -156,6 +207,9 @@ void imm_cache_free_itemp(IMM_CACHE *cache, int itemp_num);
void imm_cache_free_dead_cache(IMM_CACHE *cache);
void imm_cache_free(IMM_CACHE *cache, int id);
void imm_cache_free_all(IMM_CACHE *cache);
void imm_cache_invalidate_for_helper(void);
void imm_cache_print_rip_stats(IMM_CACHE *cache, uint64_t tb_pc);
void imm_cache_print_complex_stats(IMM_CACHE *cache, uint64_t tb_pc);
bool imm_cache_is_imm_itemp(int itemp_num);
bool imm_cache_itemp_is_used(IR2_OPND opnd);
void imm_cache_free_cache_use_target_reg(IR2_OPND opnd);
Expand Down
10 changes: 10 additions & 0 deletions target/i386/latx/include/latx-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,13 @@ extern int option_anonym;
extern int option_imm_reg;
extern int option_imm_precache;
extern int option_imm_rip;
extern int option_imm_rip_stats;
#define LATX_IMM_COMPLEX_BASE_DISP (1 << 0)
#define LATX_IMM_COMPLEX_INDEX_DISP (1 << 1)
#define LATX_IMM_COMPLEX_BASE_INDEX_DISP (1 << 2)
#define LATX_IMM_COMPLEX_ALL ((1 << 3) - 1)
extern int option_imm_complex;
extern int option_imm_complex_stats;
extern int option_debug_imm_reg;
extern uint64_t imm_skip_pc;
extern int option_mem_test;
Expand Down Expand Up @@ -160,6 +166,10 @@ extern unsigned long long counter_mips_tr;
ENVFUN(SAVE_XMM, handle_arg_save_xmm) \
ENVFUN(LATX_JRRA, handle_arg_latx_jrra) \
ENVFUN(LATX_IMM_REG, handle_arg_latx_imm_reg) \
ENVFUN(LATX_IMM_RIP, handle_arg_latx_imm_rip) \
ENVFUN(LATX_IMM_RIP_STATS, handle_arg_latx_imm_rip_stats) \
ENVFUN(LATX_IMM_COMPLEX, handle_arg_latx_imm_complex) \
ENVFUN(LATX_IMM_COMPLEX_STATS, handle_arg_latx_imm_complex_stats) \
ENVFUN(LATX_MT, handle_arg_latx_mem_test) \
ENVFUN(LATX_REAL_MAPS, handle_arg_latx_real_maps) \
ENVFUN(LATX_MONITOR_SHARED_MEM, handle_arg_latx_monitor_shared_mem) \
Expand Down
14 changes: 11 additions & 3 deletions target/i386/latx/latx-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ int option_smc_reload;
int option_debug_aot;
int option_imm_reg;
int option_imm_rip;
int option_imm_rip_stats;
int option_imm_precache;
int option_imm_complex;
int option_imm_complex_stats;
int option_debug_imm_reg;
uint64_t imm_skip_pc;
uint64_t debug_tb_pc;
Expand Down Expand Up @@ -255,10 +257,16 @@ void options_init(void)
#endif
option_smc_reload = 0;
#ifdef CONFIG_LATX_IMM_REG
#ifdef TARGET_X86_64
option_imm_reg = 1;
option_imm_complex = LATX_IMM_COMPLEX_ALL;
#else
option_imm_reg = 0;
option_imm_rip = 0;
// complex:base+index*scale
option_imm_complex = 0;
#endif
option_imm_rip = 0;
option_imm_rip_stats = 0;
option_imm_complex_stats = 0;
option_imm_precache = 0;
option_debug_imm_reg = 0;
imm_skip_pc = 0;
Expand Down Expand Up @@ -342,7 +350,7 @@ void options_parse_imm_reg(const char *bits)
}

if (bits[OPTIONS_IMM_COMPLEX] == '1') {
option_imm_complex = 1;
option_imm_complex = LATX_IMM_COMPLEX_ALL;
} else if (bits[OPTIONS_IMM_COMPLEX] == '0') {
option_imm_complex = 0;
} else {
Expand Down
Loading