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:
Peter Maydell 2021-06-30 19:09:45 +01:00
commit d940d468e2
7 changed files with 80 additions and 54 deletions

View file

@ -424,9 +424,9 @@
#define fGEN_TCG_L4_loadd_locked(SHORTCODE) \ #define fGEN_TCG_L4_loadd_locked(SHORTCODE) \
SHORTCODE SHORTCODE
#define fGEN_TCG_S2_storew_locked(SHORTCODE) \ #define fGEN_TCG_S2_storew_locked(SHORTCODE) \
do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) SHORTCODE
#define fGEN_TCG_S4_stored_locked(SHORTCODE) \ #define fGEN_TCG_S4_stored_locked(SHORTCODE) \
do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) SHORTCODE
#define fGEN_TCG_STORE(SHORTCODE) \ #define fGEN_TCG_STORE(SHORTCODE) \
do { \ do { \
@ -734,4 +734,15 @@
#define fGEN_TCG_F2_dfmpyhh(SHORTCODE) \ #define fGEN_TCG_F2_dfmpyhh(SHORTCODE) \
gen_helper_dfmpyhh(RxxV, cpu_env, RxxV, RssV, RttV) 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 #endif

View file

@ -27,12 +27,6 @@
#undef QEMU_GENERATE #undef QEMU_GENERATE
#include "gen_tcg.h" #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) static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot)
{ {
TCGv zero = tcg_const_tl(0); 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) 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 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); 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_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << pnum);
tcg_temp_free(zero);
tcg_temp_free(base_val); 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) 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); tcg_gen_mov_i64(hex_llsc_val_i64, dest);
} }
static inline void gen_store_conditional4(CPUHexagonState *env, static inline void gen_store_conditional4(DisasContext *ctx,
DisasContext *ctx, int prednum,
TCGv pred, TCGv vaddr, TCGv src) TCGv pred, TCGv vaddr, TCGv src)
{ {
TCGLabel *fail = gen_new_label(); TCGLabel *fail = gen_new_label();
@ -349,7 +336,7 @@ static inline void gen_store_conditional4(CPUHexagonState *env,
tmp = tcg_temp_new(); tmp = tcg_temp_new();
tcg_gen_atomic_cmpxchg_tl(tmp, hex_llsc_addr, hex_llsc_val, src, tcg_gen_atomic_cmpxchg_tl(tmp, hex_llsc_addr, hex_llsc_val, src,
ctx->mem_idx, MO_32); 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); one, zero);
tcg_temp_free(one); tcg_temp_free(one);
tcg_temp_free(zero); tcg_temp_free(zero);
@ -363,8 +350,7 @@ static inline void gen_store_conditional4(CPUHexagonState *env,
tcg_gen_movi_tl(hex_llsc_addr, ~0); tcg_gen_movi_tl(hex_llsc_addr, ~0);
} }
static inline void gen_store_conditional8(CPUHexagonState *env, static inline void gen_store_conditional8(DisasContext *ctx,
DisasContext *ctx, int prednum,
TCGv pred, TCGv vaddr, TCGv_i64 src) TCGv pred, TCGv vaddr, TCGv_i64 src)
{ {
TCGLabel *fail = gen_new_label(); TCGLabel *fail = gen_new_label();
@ -380,7 +366,7 @@ static inline void gen_store_conditional8(CPUHexagonState *env,
ctx->mem_idx, MO_64); ctx->mem_idx, MO_64);
tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64, tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64,
one, zero); 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(one);
tcg_temp_free_i64(zero); tcg_temp_free_i64(zero);
tcg_temp_free_i64(tmp); tcg_temp_free_i64(tmp);

View file

@ -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_dcinva, ICLASS_ST" 000 00 01sssss PP------ --------")
DEF_ENC32(Y2_dccleaninva, ICLASS_ST" 000 00 10sssss 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 --------")
/*******************************/ /*******************************/
/* */ /* */
/* */ /* */

View file

@ -24,7 +24,6 @@
#ifdef QEMU_GENERATE #ifdef QEMU_GENERATE
#define READ_REG(dest, NUM) gen_read_reg(dest, NUM) #define READ_REG(dest, NUM) gen_read_reg(dest, NUM)
#define READ_PREG(dest, NUM) gen_read_preg(dest, (NUM))
#else #else
#define READ_REG(NUM) (env->gpr[(NUM)]) #define READ_REG(NUM) (env->gpr[(NUM)])
#define READ_PREG(NUM) (env->pred[NUM]) #define READ_PREG(NUM) (env->pred[NUM])
@ -239,33 +238,26 @@ static inline void gen_pred_cancel(TCGv pred, int slot_num)
#endif #endif
#ifdef QEMU_GENERATE #ifdef QEMU_GENERATE
#define fLSBNEW(PVAL) tcg_gen_mov_tl(LSB, (PVAL)) #define fLSBNEW(PVAL) tcg_gen_andi_tl(LSB, (PVAL), 1)
#define fLSBNEW0 tcg_gen_mov_tl(LSB, hex_new_pred_value[0]) #define fLSBNEW0 tcg_gen_andi_tl(LSB, hex_new_pred_value[0], 1)
#define fLSBNEW1 tcg_gen_mov_tl(LSB, hex_new_pred_value[1]) #define fLSBNEW1 tcg_gen_andi_tl(LSB, hex_new_pred_value[1], 1)
#else #else
#define fLSBNEW(PVAL) (PVAL) #define fLSBNEW(PVAL) ((PVAL) & 1)
#define fLSBNEW0 new_pred_value(env, 0) #define fLSBNEW0 (env->new_pred_value[0] & 1)
#define fLSBNEW1 new_pred_value(env, 1) #define fLSBNEW1 (env->new_pred_value[1] & 1)
#endif #endif
#ifdef QEMU_GENERATE #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) \ #define fLSBOLDNOT(VAL) \
do { \ do { \
tcg_gen_andi_tl(LSB, (VAL), 1); \ tcg_gen_andi_tl(LSB, (VAL), 1); \
tcg_gen_xori_tl(LSB, LSB, 1); \ tcg_gen_xori_tl(LSB, LSB, 1); \
} while (0) } while (0)
#define fLSBNEWNOT(PNUM) \ #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 #else
#define fLSBNEWNOT(PNUM) (!fLSBNEW(PNUM)) #define fLSBNEWNOT(PNUM) (!fLSBNEW(PNUM))
#define fLSBOLDNOT(VAL) (!fLSBOLD(VAL)) #define fLSBOLDNOT(VAL) (!fLSBOLD(VAL))
@ -598,7 +590,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
#ifdef QEMU_GENERATE #ifdef QEMU_GENERATE
#define fSTORE_LOCKED(NUM, SIZE, EA, SRC, PRED) \ #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 #endif
#ifdef QEMU_GENERATE #ifdef QEMU_GENERATE

View file

@ -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 */ /* Checks for bookkeeping errors between disassembly context and runtime */
void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check) void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check)
{ {

View file

@ -273,7 +273,6 @@ static void gen_reg_writes(DisasContext *ctx)
static void gen_pred_writes(DisasContext *ctx, Packet *pkt) static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
{ {
TCGv zero, control_reg, pval;
int i; int i;
/* Early exit if the log is empty */ /* Early exit if the log is empty */
@ -281,10 +280,6 @@ static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
return; return;
} }
zero = tcg_const_tl(0);
control_reg = tcg_temp_new();
pval = tcg_temp_new();
/* /*
* Only endloop instructions will conditionally * Only endloop instructions will conditionally
* write a predicate. If there are no endloop * 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. * write of the predicates.
*/ */
if (pkt->pkt_has_endloop) { if (pkt->pkt_has_endloop) {
TCGv zero = tcg_const_tl(0);
TCGv pred_written = tcg_temp_new(); TCGv pred_written = tcg_temp_new();
for (i = 0; i < ctx->preg_log_idx; i++) { for (i = 0; i < ctx->preg_log_idx; i++) {
int pred_num = ctx->preg_log[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_new_pred_value[pred_num],
hex_pred[pred_num]); hex_pred[pred_num]);
} }
tcg_temp_free(zero);
tcg_temp_free(pred_written); tcg_temp_free(pred_written);
} else { } else {
for (i = 0; i < ctx->preg_log_idx; i++) { 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) static void gen_check_store_width(DisasContext *ctx, int slot_num)

View file

@ -181,6 +181,19 @@ static inline void S4_storeirifnew_io(void *p, int pred)
: "p0", "memory"); : "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 * Test that compound-compare-jump is executed in 2 parts
* First we have to do all the compares in the packet and * First we have to do all the compares in the packet and
@ -298,8 +311,31 @@ static int auto_and(void)
return retval; 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 main()
{ {
int res;
long long res64; long long res64;
int pred; int pred;
@ -394,6 +430,12 @@ int main()
S4_storeirifnew_io(&array[8], 1); S4_storeirifnew_io(&array[8], 1);
check(array[9], 9); 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(); int x = cmpnd_cmp_jump();
check(x, 12); check(x, 12);
@ -406,7 +448,7 @@ int main()
check((int)pair, 5); check((int)pair, 5);
check((int)(pair >> 32), 7); check((int)(pair >> 32), 7);
int res = test_clrtnew(1, 7); res = test_clrtnew(1, 7);
check(res, 0); check(res, 0);
res = test_clrtnew(2, 7); res = test_clrtnew(2, 7);
check(res, 7); check(res, 7);
@ -422,6 +464,10 @@ int main()
res = auto_and(); res = auto_and();
check(res, 0); check(res, 0);
test_lsbnew();
test_l2fetch();
puts(err ? "FAIL" : "PASS"); puts(err ? "FAIL" : "PASS");
return err; return err;
} }