mirror of https://github.com/xemu-project/xemu.git
Fixes for bugs found by inspection and internal testing
Tests added to tests/tcg/hexagon/misc.c -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJg209IAAoJEHsCRPsS3kQigLsIAJ3MsBLjiWa6QL18uLuSw3lr guisbOS5WWoTQ01r8Ek/+AcFIVvfHCQwvUdB6R+LR0XCrz7jJMsMGqXtz5OA+oeR kr5DvNgfBU+k5o2Z6A1gKBxlczdxe5lLmihY3NDbnySOOWvNGbiHM73HCzt913PA 24/iD1GaE98++R1sg+51+VY+CRF6Bf5pN/yOuiKT4+6XBwxyM+ohdCfaADgHDwJl HczXbyZzjX8CybQLp88balQrfuD48aC75STvHEz1txV9sEdVJw8rgZj0XYYvQiaU pdn4Vqq7rMhm797xAUDBWRGl4SjrJsXl+bswKo5qnoocqlfmgtxXtciPfcx6MnU= =ZvUq -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/quic/tags/pull-hex-20210629' into staging Fixes for bugs found by inspection and internal testing Tests added to tests/tcg/hexagon/misc.c # gpg: Signature made Tue 29 Jun 2021 17:50:16 BST # gpg: using RSA key 7B0244FB12DE4422 # gpg: Good signature from "Taylor Simpson (Rock on) <tsimpson@quicinc.com>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 3635 C788 CE62 B91F D4C5 9AB4 7B02 44FB 12DE 4422 * remotes/quic/tags/pull-hex-20210629: Hexagon (target/hexagon) remove unused TCG variables Hexagon (target/hexagon) cleanup gen_store_conditional[48] functions Hexagon (target/hexagon) fix l2fetch instructions Hexagon (target/hexagon) fix bug in fLSBNEW* Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d940d468e2
|
@ -424,9 +424,9 @@
|
|||
#define fGEN_TCG_L4_loadd_locked(SHORTCODE) \
|
||||
SHORTCODE
|
||||
#define fGEN_TCG_S2_storew_locked(SHORTCODE) \
|
||||
do { SHORTCODE; READ_PREG(PdV, PdN); } while (0)
|
||||
SHORTCODE
|
||||
#define fGEN_TCG_S4_stored_locked(SHORTCODE) \
|
||||
do { SHORTCODE; READ_PREG(PdV, PdN); } while (0)
|
||||
SHORTCODE
|
||||
|
||||
#define fGEN_TCG_STORE(SHORTCODE) \
|
||||
do { \
|
||||
|
@ -734,4 +734,15 @@
|
|||
#define fGEN_TCG_F2_dfmpyhh(SHORTCODE) \
|
||||
gen_helper_dfmpyhh(RxxV, cpu_env, RxxV, RssV, RttV)
|
||||
|
||||
/* Nothing to do for these in qemu, need to suppress compiler warnings */
|
||||
#define fGEN_TCG_Y4_l2fetch(SHORTCODE) \
|
||||
do { \
|
||||
RsV = RsV; \
|
||||
RtV = RtV; \
|
||||
} while (0)
|
||||
#define fGEN_TCG_Y5_l2fetch(SHORTCODE) \
|
||||
do { \
|
||||
RsV = RsV; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,12 +27,6 @@
|
|||
#undef QEMU_GENERATE
|
||||
#include "gen_tcg.h"
|
||||
|
||||
static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
|
||||
{
|
||||
tcg_gen_mov_tl(pred, hex_pred[num]);
|
||||
return pred;
|
||||
}
|
||||
|
||||
static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot)
|
||||
{
|
||||
TCGv zero = tcg_const_tl(0);
|
||||
|
@ -121,10 +115,7 @@ static void gen_log_reg_write_pair(int rnum, TCGv_i64 val)
|
|||
|
||||
static inline void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val)
|
||||
{
|
||||
TCGv zero = tcg_const_tl(0);
|
||||
TCGv base_val = tcg_temp_new();
|
||||
TCGv and_val = tcg_temp_new();
|
||||
TCGv pred_written = tcg_temp_new();
|
||||
|
||||
tcg_gen_andi_tl(base_val, val, 0xff);
|
||||
|
||||
|
@ -143,10 +134,7 @@ static inline void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val)
|
|||
}
|
||||
tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << pnum);
|
||||
|
||||
tcg_temp_free(zero);
|
||||
tcg_temp_free(base_val);
|
||||
tcg_temp_free(and_val);
|
||||
tcg_temp_free(pred_written);
|
||||
}
|
||||
|
||||
static inline void gen_read_p3_0(TCGv control_reg)
|
||||
|
@ -334,8 +322,7 @@ static inline void gen_load_locked8u(TCGv_i64 dest, TCGv vaddr, int mem_index)
|
|||
tcg_gen_mov_i64(hex_llsc_val_i64, dest);
|
||||
}
|
||||
|
||||
static inline void gen_store_conditional4(CPUHexagonState *env,
|
||||
DisasContext *ctx, int prednum,
|
||||
static inline void gen_store_conditional4(DisasContext *ctx,
|
||||
TCGv pred, TCGv vaddr, TCGv src)
|
||||
{
|
||||
TCGLabel *fail = gen_new_label();
|
||||
|
@ -349,7 +336,7 @@ static inline void gen_store_conditional4(CPUHexagonState *env,
|
|||
tmp = tcg_temp_new();
|
||||
tcg_gen_atomic_cmpxchg_tl(tmp, hex_llsc_addr, hex_llsc_val, src,
|
||||
ctx->mem_idx, MO_32);
|
||||
tcg_gen_movcond_tl(TCG_COND_EQ, hex_pred[prednum], tmp, hex_llsc_val,
|
||||
tcg_gen_movcond_tl(TCG_COND_EQ, pred, tmp, hex_llsc_val,
|
||||
one, zero);
|
||||
tcg_temp_free(one);
|
||||
tcg_temp_free(zero);
|
||||
|
@ -363,8 +350,7 @@ static inline void gen_store_conditional4(CPUHexagonState *env,
|
|||
tcg_gen_movi_tl(hex_llsc_addr, ~0);
|
||||
}
|
||||
|
||||
static inline void gen_store_conditional8(CPUHexagonState *env,
|
||||
DisasContext *ctx, int prednum,
|
||||
static inline void gen_store_conditional8(DisasContext *ctx,
|
||||
TCGv pred, TCGv vaddr, TCGv_i64 src)
|
||||
{
|
||||
TCGLabel *fail = gen_new_label();
|
||||
|
@ -380,7 +366,7 @@ static inline void gen_store_conditional8(CPUHexagonState *env,
|
|||
ctx->mem_idx, MO_64);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64,
|
||||
one, zero);
|
||||
tcg_gen_extrl_i64_i32(hex_pred[prednum], tmp);
|
||||
tcg_gen_extrl_i64_i32(pred, tmp);
|
||||
tcg_temp_free_i64(one);
|
||||
tcg_temp_free_i64(zero);
|
||||
tcg_temp_free_i64(tmp);
|
||||
|
|
|
@ -493,6 +493,9 @@ DEF_ENC32(Y2_dccleana, ICLASS_ST" 000 00 00sssss PP------ --------")
|
|||
DEF_ENC32(Y2_dcinva, ICLASS_ST" 000 00 01sssss PP------ --------")
|
||||
DEF_ENC32(Y2_dccleaninva, ICLASS_ST" 000 00 10sssss PP------ --------")
|
||||
|
||||
DEF_ENC32(Y4_l2fetch, ICLASS_ST" 011 00 00sssss PP-ttttt 000-----")
|
||||
DEF_ENC32(Y5_l2fetch, ICLASS_ST" 011 01 00sssss PP-ttttt --------")
|
||||
|
||||
/*******************************/
|
||||
/* */
|
||||
/* */
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define READ_REG(dest, NUM) gen_read_reg(dest, NUM)
|
||||
#define READ_PREG(dest, NUM) gen_read_preg(dest, (NUM))
|
||||
#else
|
||||
#define READ_REG(NUM) (env->gpr[(NUM)])
|
||||
#define READ_PREG(NUM) (env->pred[NUM])
|
||||
|
@ -239,33 +238,26 @@ static inline void gen_pred_cancel(TCGv pred, int slot_num)
|
|||
#endif
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define fLSBNEW(PVAL) tcg_gen_mov_tl(LSB, (PVAL))
|
||||
#define fLSBNEW0 tcg_gen_mov_tl(LSB, hex_new_pred_value[0])
|
||||
#define fLSBNEW1 tcg_gen_mov_tl(LSB, hex_new_pred_value[1])
|
||||
#define fLSBNEW(PVAL) tcg_gen_andi_tl(LSB, (PVAL), 1)
|
||||
#define fLSBNEW0 tcg_gen_andi_tl(LSB, hex_new_pred_value[0], 1)
|
||||
#define fLSBNEW1 tcg_gen_andi_tl(LSB, hex_new_pred_value[1], 1)
|
||||
#else
|
||||
#define fLSBNEW(PVAL) (PVAL)
|
||||
#define fLSBNEW0 new_pred_value(env, 0)
|
||||
#define fLSBNEW1 new_pred_value(env, 1)
|
||||
#define fLSBNEW(PVAL) ((PVAL) & 1)
|
||||
#define fLSBNEW0 (env->new_pred_value[0] & 1)
|
||||
#define fLSBNEW1 (env->new_pred_value[1] & 1)
|
||||
#endif
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
static inline void gen_logical_not(TCGv dest, TCGv src)
|
||||
{
|
||||
TCGv one = tcg_const_tl(1);
|
||||
TCGv zero = tcg_const_tl(0);
|
||||
|
||||
tcg_gen_movcond_tl(TCG_COND_NE, dest, src, zero, zero, one);
|
||||
|
||||
tcg_temp_free(one);
|
||||
tcg_temp_free(zero);
|
||||
}
|
||||
#define fLSBOLDNOT(VAL) \
|
||||
do { \
|
||||
tcg_gen_andi_tl(LSB, (VAL), 1); \
|
||||
tcg_gen_xori_tl(LSB, LSB, 1); \
|
||||
} while (0)
|
||||
#define fLSBNEWNOT(PNUM) \
|
||||
gen_logical_not(LSB, (PNUM))
|
||||
do { \
|
||||
tcg_gen_andi_tl(LSB, (PNUM), 1); \
|
||||
tcg_gen_xori_tl(LSB, LSB, 1); \
|
||||
} while (0)
|
||||
#else
|
||||
#define fLSBNEWNOT(PNUM) (!fLSBNEW(PNUM))
|
||||
#define fLSBOLDNOT(VAL) (!fLSBOLD(VAL))
|
||||
|
@ -598,7 +590,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
|
|||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define fSTORE_LOCKED(NUM, SIZE, EA, SRC, PRED) \
|
||||
gen_store_conditional##SIZE(env, ctx, PdN, PRED, EA, SRC);
|
||||
gen_store_conditional##SIZE(ctx, PRED, EA, SRC);
|
||||
#endif
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
|
|
|
@ -128,11 +128,6 @@ void HELPER(debug_start_packet)(CPUHexagonState *env)
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t new_pred_value(CPUHexagonState *env, int pnum)
|
||||
{
|
||||
return env->new_pred_value[pnum];
|
||||
}
|
||||
|
||||
/* Checks for bookkeeping errors between disassembly context and runtime */
|
||||
void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check)
|
||||
{
|
||||
|
|
|
@ -273,7 +273,6 @@ static void gen_reg_writes(DisasContext *ctx)
|
|||
|
||||
static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
|
||||
{
|
||||
TCGv zero, control_reg, pval;
|
||||
int i;
|
||||
|
||||
/* Early exit if the log is empty */
|
||||
|
@ -281,10 +280,6 @@ static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
|
|||
return;
|
||||
}
|
||||
|
||||
zero = tcg_const_tl(0);
|
||||
control_reg = tcg_temp_new();
|
||||
pval = tcg_temp_new();
|
||||
|
||||
/*
|
||||
* Only endloop instructions will conditionally
|
||||
* write a predicate. If there are no endloop
|
||||
|
@ -292,6 +287,7 @@ static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
|
|||
* write of the predicates.
|
||||
*/
|
||||
if (pkt->pkt_has_endloop) {
|
||||
TCGv zero = tcg_const_tl(0);
|
||||
TCGv pred_written = tcg_temp_new();
|
||||
for (i = 0; i < ctx->preg_log_idx; i++) {
|
||||
int pred_num = ctx->preg_log[i];
|
||||
|
@ -302,6 +298,7 @@ static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
|
|||
hex_new_pred_value[pred_num],
|
||||
hex_pred[pred_num]);
|
||||
}
|
||||
tcg_temp_free(zero);
|
||||
tcg_temp_free(pred_written);
|
||||
} else {
|
||||
for (i = 0; i < ctx->preg_log_idx; i++) {
|
||||
|
@ -314,10 +311,6 @@ static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
tcg_temp_free(zero);
|
||||
tcg_temp_free(control_reg);
|
||||
tcg_temp_free(pval);
|
||||
}
|
||||
|
||||
static void gen_check_store_width(DisasContext *ctx, int slot_num)
|
||||
|
|
|
@ -181,6 +181,19 @@ static inline void S4_storeirifnew_io(void *p, int pred)
|
|||
: "p0", "memory");
|
||||
}
|
||||
|
||||
static int L2_ploadrifnew_pi(void *p, int pred)
|
||||
{
|
||||
int result;
|
||||
asm volatile("%0 = #31\n\t"
|
||||
"{\n\t"
|
||||
" p0 = cmp.eq(%1, #1)\n\t"
|
||||
" if (!p0.new) %0 = memw(%2++#4)\n\t"
|
||||
"}\n\t"
|
||||
: "=r"(result) : "r"(pred), "r"(p)
|
||||
: "p0");
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that compound-compare-jump is executed in 2 parts
|
||||
* First we have to do all the compares in the packet and
|
||||
|
@ -298,8 +311,31 @@ static int auto_and(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
void test_lsbnew(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
asm("r0 = #2\n\t"
|
||||
"r1 = #5\n\t"
|
||||
"{\n\t"
|
||||
" p0 = r0\n\t"
|
||||
" if (p0.new) r1 = #3\n\t"
|
||||
"}\n\t"
|
||||
"%0 = r1\n\t"
|
||||
: "=r"(result) :: "r0", "r1", "p0");
|
||||
check(result, 5);
|
||||
}
|
||||
|
||||
void test_l2fetch(void)
|
||||
{
|
||||
/* These don't do anything in qemu, just make sure they don't assert */
|
||||
asm volatile ("l2fetch(r0, r1)\n\t"
|
||||
"l2fetch(r0, r3:2)\n\t");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int res;
|
||||
long long res64;
|
||||
int pred;
|
||||
|
||||
|
@ -394,6 +430,12 @@ int main()
|
|||
S4_storeirifnew_io(&array[8], 1);
|
||||
check(array[9], 9);
|
||||
|
||||
memcpy(array, init, sizeof(array));
|
||||
res = L2_ploadrifnew_pi(&array[6], 0);
|
||||
check(res, 6);
|
||||
res = L2_ploadrifnew_pi(&array[7], 1);
|
||||
check(res, 31);
|
||||
|
||||
int x = cmpnd_cmp_jump();
|
||||
check(x, 12);
|
||||
|
||||
|
@ -406,7 +448,7 @@ int main()
|
|||
check((int)pair, 5);
|
||||
check((int)(pair >> 32), 7);
|
||||
|
||||
int res = test_clrtnew(1, 7);
|
||||
res = test_clrtnew(1, 7);
|
||||
check(res, 0);
|
||||
res = test_clrtnew(2, 7);
|
||||
check(res, 7);
|
||||
|
@ -422,6 +464,10 @@ int main()
|
|||
res = auto_and();
|
||||
check(res, 0);
|
||||
|
||||
test_lsbnew();
|
||||
|
||||
test_l2fetch();
|
||||
|
||||
puts(err ? "FAIL" : "PASS");
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue