Skip to content
Closed
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
6 changes: 6 additions & 0 deletions target/i386/latx/include/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ typedef struct TRANSLATION_DATA {

int curr_top; /* top value (changes when translating) */

/*
* VEX.128 writes make the architectural YMM high half zero. With LASX,
* defer that zeroing until the high half is observed or the TB exits.
*/
uint16_t ymmh_zero_pending;
uint8_t ymmh_zero_defer_disabled;
/* TODO : support static translation */
uint8 curr_ir1_skipped_eflags; /* these eflag calculation can be skipped */
/* (because of flag pattern, etc) */
Expand Down
4 changes: 4 additions & 0 deletions target/i386/latx/include/translate.h
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,10 @@ IR2_OPND load_freg128_from_ir1(IR1_OPND *);
void load_imm_to_ir1_opnd_gpr(IR1_OPND *opnd0, uint64_t imm);
IR2_OPND load_freg256_from_ir1(IR1_OPND *opnd1);
void set_high128_xreg_to_zero(IR2_OPND opnd);
void materialize_deferred_ymmh_zero(IR2_OPND opnd);
void materialize_deferred_ymmh_zeros_now(void);
void materialize_deferred_ymmh_zeros_for_exit(void);
void disable_deferred_ymmh_zero_for_tb(void);
IR2_OPND load_ymm_high128_shadow(int index);
void store_ymm_high128_shadow(IR2_OPND src, int index);
void clear_ymm_high128_shadow(int index);
Expand Down
31 changes: 31 additions & 0 deletions target/i386/latx/optimization/hbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,20 @@ static void init_xmm_state(uint32_t xmm[XMM_NUM])
#include "tu.h"
typedef bool (*xmm_analyse_func)(TranslationBlock *, IR1_INST *, uint32_t *);

static bool tb_has_ymm_operand(TranslationBlock *tb)
{
for (int i = 0; i < tb_ir1_num(tb); ++i) {
IR1_INST *ir1 = tb_ir1_inst(tb, i);

for (int j = 0; j < ir1_get_opnd_num(ir1); ++j) {
if (ir1_opnd_is_ymm(ir1_get_opnd(ir1, j))) {
return true;
}
}
}
return false;
}

/* static int xcount, scount, ncount; */
static void tb_xmm_analyse(TranslationBlock *tb,
xmm_analyse_func analyse_func, uint32_t *xmm)
Expand All @@ -755,6 +769,23 @@ static void tb_xmm_analyse(TranslationBlock *tb,
tb->s_data->xmm_use = 0;
tb->s_data->xmm_def = 0;
IR1_INST *ir1 = NULL;

/*
* SHBR models the low 128-bit XMM value only. Optimizing an XMM
* instruction in a TB that also uses YMM can leave the upper half in a
* different physical register state across TU-internal entries. Keep all
* vector registers live and skip SHBR for these mixed-width TBs.
*/
if (tb_has_ymm_operand(tb)) {
tb->s_data->xmm_use = SHBR_XMM_ALL;
for (int i = 0; i < tb_ir1_num(tb); ++i) {
ir1 = tb_ir1_inst(tb, i);
ir1->xmm_def = 0;
ir1->xmm_use = 0;
}
return;
}

for (int i = 0; i < tb_ir1_num(tb); ++i) {
ir1 = tb_ir1_inst(tb, i);
ir1->xmm_def = 0;
Expand Down
Loading