Skip to content

Commit

Permalink
Hexagon (target/hexagon) assignment to c4 should wait until packet co…
Browse files Browse the repository at this point in the history
…mmit

On Hexagon, c4 is an alias for predicate registers P3:0.  If we assign to
c4 inside a packet with reads from predicate registers, the predicate
reads should get the old values.

Test case added to tests/tcg/hexagon/preg_alias.c

Co-authored-by: Michael Lambert <mlambert@cuicinc.com>
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
Message-Id: <20220210021556.9217-13-tsimpson@quicinc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
taylorsimpson and Michael Lambert committed Mar 12, 2022
1 parent 3977ba3 commit c0d8606
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
14 changes: 9 additions & 5 deletions target/hexagon/genptr.c
@@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -210,11 +210,15 @@ static inline void gen_read_ctrl_reg_pair(DisasContext *ctx, const int reg_num,
}
}

static inline void gen_write_p3_0(TCGv control_reg)
static void gen_write_p3_0(DisasContext *ctx, TCGv control_reg)
{
TCGv hex_p8 = tcg_temp_new();
for (int i = 0; i < NUM_PREGS; i++) {
tcg_gen_extract_tl(hex_pred[i], control_reg, i * 8, 8);
tcg_gen_extract_tl(hex_p8, control_reg, i * 8, 8);
gen_log_pred_write(ctx, i, hex_p8);
ctx_log_pred_write(ctx, i);
}
tcg_temp_free(hex_p8);
}

/*
Expand All @@ -228,7 +232,7 @@ static inline void gen_write_ctrl_reg(DisasContext *ctx, int reg_num,
TCGv val)
{
if (reg_num == HEX_REG_P3_0) {
gen_write_p3_0(val);
gen_write_p3_0(ctx, val);
} else {
gen_log_reg_write(reg_num, val);
ctx_log_reg_write(ctx, reg_num);
Expand All @@ -250,7 +254,7 @@ static inline void gen_write_ctrl_reg_pair(DisasContext *ctx, int reg_num,
if (reg_num == HEX_REG_P3_0) {
TCGv val32 = tcg_temp_new();
tcg_gen_extrl_i64_i32(val32, val);
gen_write_p3_0(val32);
gen_write_p3_0(ctx, val32);
tcg_gen_extrh_i64_i32(val32, val);
gen_log_reg_write(reg_num + 1, val32);
tcg_temp_free(val32);
Expand Down
38 changes: 38 additions & 0 deletions tests/tcg/hexagon/preg_alias.c
Expand Up @@ -97,6 +97,42 @@ static inline void creg_alias_pair(unsigned int cval, PRegs *pregs)
check(c5, 0xdeadbeef);
}

static void test_packet(void)
{
/*
* Test that setting c4 inside a packet doesn't impact the predicates
* that are read during the packet.
*/

int result;
int old_val = 0x0000001c;

/* Test a predicated register transfer */
result = old_val;
asm (
"c4 = %1\n\t"
"{\n\t"
" c4 = %2\n\t"
" if (!p2) %0 = %3\n\t"
"}\n\t"
: "+r"(result)
: "r"(0xffffffff), "r"(0xff00ffff), "r"(0x837ed653)
: "p0", "p1", "p2", "p3");
check(result, old_val);

/* Test a predicated store */
result = 0xffffffff;
asm ("c4 = %0\n\t"
"{\n\t"
" c4 = %1\n\t"
" if (!p2) memw(%2) = #0\n\t"
"}\n\t"
:
: "r"(0), "r"(0xffffffff), "r"(&result)
: "p0", "p1", "p2", "p3", "memory");
check(result, 0x0);
}

int main()
{
int c4;
Expand Down Expand Up @@ -162,6 +198,8 @@ int main()
creg_alias_pair(0xffffffff, &pregs);
check(pregs.creg, 0xffffffff);

test_packet();

puts(err ? "FAIL" : "PASS");
return err;
}

0 comments on commit c0d8606

Please sign in to comment.