Skip to content

commits extracted from sysemu PR #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: tip
Choose a base branch
from
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
5 changes: 5 additions & 0 deletions target/hexagon/cpu-param.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@
#define TARGET_PHYS_ADDR_SPACE_BITS 36
#define TARGET_VIRT_ADDR_SPACE_BITS 32

/*
* Hexagon processors have a strong memory model.
*/
#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL)

#endif
3 changes: 1 addition & 2 deletions target/hexagon/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ static void hexagon_dump(CPUHexagonState *env, FILE *f, int flags)
qemu_fprintf(f, " cs0 = 0x00000000\n");
qemu_fprintf(f, " cs1 = 0x00000000\n");
#else
print_reg(f, env, HEX_REG_CAUSE);
print_reg(f, env, HEX_REG_BADVA);
print_reg(f, env, HEX_SREG_BADVA);
print_reg(f, env, HEX_REG_CS0);
print_reg(f, env, HEX_REG_CS1);
#endif
Expand Down
4 changes: 4 additions & 0 deletions target/hexagon/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#define NUM_PREGS 4
#define TOTAL_PER_THREAD_REGS 64
#define NUM_GPREGS 32

#define SLOTS_MAX 4
#define STORES_MAX 2
Expand Down Expand Up @@ -78,6 +79,9 @@ typedef struct CPUArchState {

uint8_t slot_cancelled;
target_ulong new_value_usr;
target_ulong gpreg_written;
QEMU_BUILD_BUG_MSG(NUM_GPREGS > CHAR_BIT * sizeof(target_ulong),
"Hexagon's CPUArchState.gpreg_written type is too small");

MemLog mem_log_stores[STORES_MAX];

Expand Down
2 changes: 2 additions & 0 deletions target/hexagon/cpu_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
enum hex_event {
HEX_EVENT_NONE = -1,
HEX_EVENT_TRAP0 = 0x008,
HEX_EVENT_PRECISE = 0x2,
};

enum hex_cause {
Expand All @@ -34,6 +35,7 @@ enum hex_cause {
HEX_CAUSE_FETCH_NO_UPAGE = 0x012,
HEX_CAUSE_INVALID_PACKET = 0x015,
HEX_CAUSE_INVALID_OPCODE = 0x015,
HEX_CAUSE_REG_WRITE_CONFLICT = 0x01d,
HEX_CAUSE_PC_NOT_ALIGNED = 0x01e,
HEX_CAUSE_PRIV_NO_UREAD = 0x024,
HEX_CAUSE_PRIV_NO_UWRITE = 0x025,
Expand Down
10 changes: 7 additions & 3 deletions target/hexagon/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,9 @@ static void decode_set_insn_attr_fields(Packet *pkt)
if (GET_ATTRIB(opcode, A_SCALAR_STORE) &&
!GET_ATTRIB(opcode, A_MEMSIZE_0B)) {
if (pkt->insn[i].slot == 0) {
pkt->pkt_has_store_s0 = true;
pkt->pkt_has_scalar_store_s0 = true;
} else {
pkt->pkt_has_store_s1 = true;
pkt->pkt_has_scalar_store_s1 = true;
}
}
}
Expand Down Expand Up @@ -489,7 +489,6 @@ decode_insns(DisasContext *ctx, Insn *insn, uint32_t encoding)
insn->iclass = iclass_bits(encoding);
return 1;
}
g_assert_not_reached();
} else {
uint32_t iclass = get_duplex_iclass(encoding);
unsigned int slot0_subinsn = get_slot0_subinsn(encoding);
Expand All @@ -512,6 +511,11 @@ decode_insns(DisasContext *ctx, Insn *insn, uint32_t encoding)
}
g_assert_not_reached();
}
/*
* invalid/unrecognized opcode; return 1 and let gen_insn() raise an
* exception when it sees this empty insn.
*/
return 1;
}

static void decode_add_endloop_insn(Insn *insn, int loopnum)
Expand Down
2 changes: 1 addition & 1 deletion target/hexagon/gen_helper_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
if hex_common.need_slot(tag):
if "A_LOAD" in hex_common.attribdict[tag]:
f.write(hex_common.code_fmt(f"""\
bool pkt_has_store_s1 = slotval & 0x1;
bool pkt_has_scalar_store_s1 = slotval & 0x1;
"""))
f.write(hex_common.code_fmt(f"""\
uint32_t slot = slotval >> 1;
Expand Down
6 changes: 5 additions & 1 deletion target/hexagon/genptr.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void gen_log_reg_write(DisasContext *ctx, int rnum, TCGv val)

gen_masked_reg_write(val, hex_gpr[rnum], reg_mask);
tcg_gen_mov_tl(get_result_gpr(ctx, rnum), val);
gen_helper_check_reg_write(tcg_env, tcg_constant_tl(rnum));
}

static void gen_log_reg_write_pair(DisasContext *ctx, int rnum, TCGv_i64 val)
Expand All @@ -113,6 +114,8 @@ static void gen_log_reg_write_pair(DisasContext *ctx, int rnum, TCGv_i64 val)
/* High word */
tcg_gen_extrh_i64_i32(val32, val);
gen_log_reg_write(ctx, rnum + 1, val32);

gen_helper_check_reg_write_pair(tcg_env, tcg_constant_tl(rnum));
}

TCGv get_result_pred(DisasContext *ctx, int pnum)
Expand Down Expand Up @@ -395,7 +398,8 @@ static inline void gen_store_conditional8(DisasContext *ctx,
#ifndef CONFIG_HEXAGON_IDEF_PARSER
static TCGv gen_slotval(DisasContext *ctx)
{
int slotval = (ctx->pkt->pkt_has_store_s1 & 1) | (ctx->insn->slot << 1);
int slotval =
(ctx->pkt->pkt_has_scalar_store_s1 & 1) | (ctx->insn->slot << 1);
return tcg_constant_tl(slotval);
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions target/hexagon/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ DEF_HELPER_5(vacsh_val, s64, env, s64, s64, s64, i32)
DEF_HELPER_FLAGS_4(vacsh_pred, TCG_CALL_NO_RWG_SE, s32, env, s64, s64, s64)
DEF_HELPER_FLAGS_2(cabacdecbin_val, TCG_CALL_NO_RWG_SE, s64, s64, s64)
DEF_HELPER_FLAGS_2(cabacdecbin_pred, TCG_CALL_NO_RWG_SE, s32, s64, s64)
DEF_HELPER_2(check_reg_write, void, env, int)
DEF_HELPER_3(check_cond_reg_write, void, env, int, int)
DEF_HELPER_2(check_reg_write_pair, void, env, int)
DEF_HELPER_3(check_cond_reg_write_pair, void, env, int, int)

/* Floating point */
DEF_HELPER_2(conv_sf2df, f64, env, f32)
Expand Down
34 changes: 27 additions & 7 deletions target/hexagon/hex_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,11 @@ def need_next_PC(tag):


def need_pkt_has_multi_cof(tag):
return "A_COF" in attribdict[tag]

return (
"A_JUMP" in attribdict[tag]
or "A_CALL" in attribdict[tag]
or "J2_rte" == tag
) and tag != "J2_hintjumpr"

def need_pkt_need_commit(tag):
return 'A_IMPLICIT_WRITES_USR' in attribdict[tag]
Expand Down Expand Up @@ -349,6 +352,12 @@ def helper_arg(self):
self.reg_tcg(),
f"{self.helper_arg_type()} {self.helper_arg_name()}"
)
def from_subtype(self, subtype):
if subtype == "":
return self
raise Exception(
f"unknown subtype '{subtype}' on generic Register class")


#
# Every register is either Single or Pair or Hvx
Expand Down Expand Up @@ -1070,11 +1079,22 @@ def init_registers():
for reg in new_regs:
new_registers[f"{reg.regtype}{reg.regid}"] = reg

def get_register(tag, regtype, regid):
if f"{regtype}{regid}V" in semdict[tag]:
return registers[f"{regtype}{regid}"]
else:
return new_registers[f"{regtype}{regid}"]
def is_new_reg(tag, regid):
if regid[0] in "NO":
return True
return regid[0] == "P" and \
f"{regid}N" in semdict[tag] and \
f"{regid}V" not in semdict[tag]

def get_register(tag, regtype, regid, subtype=""):
regid = f"{regtype}{regid}"
is_new = is_new_reg(tag, regid)
try:
reg = new_registers[regid] if is_new else registers[regid]
except KeyError:
raise Exception(f"Unknown {'new ' if is_new else ''}register {regid}" +\
f"from '{tag}' with syntax '{semdict[tag]}'") from None
return reg.from_subtype(subtype)

def helper_ret_type(tag, regs):
## If there is a scalar result, it is the return type
Expand Down
2 changes: 1 addition & 1 deletion target/hexagon/idef-parser/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ tinycode for the Hexagon ``add`` instruction
::

---- 00021094
mov_i32 pkt_has_store_s1,$0x0
mov_i32 pkt_has_scalar_store_s1,$0x0
add_i32 tmp0,r2,r2
mov_i32 loc2,tmp0
mov_i32 new_r1,loc2
Expand Down
4 changes: 2 additions & 2 deletions target/hexagon/idef-parser/parser-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,7 +1725,7 @@ void gen_cancel(Context *c, YYLTYPE *locp)

void gen_load_cancel(Context *c, YYLTYPE *locp)
{
OUT(c, locp, "if (insn->slot == 0 && pkt->pkt_has_store_s1) {\n");
OUT(c, locp, "if (insn->slot == 0 && pkt->pkt_has_scalar_store_s1) {\n");
OUT(c, locp, "ctx->s1_store_processed = false;\n");
OUT(c, locp, "process_store(ctx, 1);\n");
OUT(c, locp, "}\n");
Expand All @@ -1750,7 +1750,7 @@ void gen_load(Context *c, YYLTYPE *locp, HexValue *width,

/* Lookup the effective address EA */
find_variable(c, locp, ea, ea);
OUT(c, locp, "if (insn->slot == 0 && pkt->pkt_has_store_s1) {\n");
OUT(c, locp, "if (insn->slot == 0 && pkt->pkt_has_scalar_store_s1) {\n");
OUT(c, locp, "probe_noshuf_load(", ea, ", ", width, ", ctx->mem_idx);\n");
OUT(c, locp, "process_store(ctx, 1);\n");
OUT(c, locp, "}\n");
Expand Down
4 changes: 2 additions & 2 deletions target/hexagon/insn.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ struct Packet {

bool pkt_has_dczeroa;

bool pkt_has_store_s0;
bool pkt_has_store_s1;
bool pkt_has_scalar_store_s0;
bool pkt_has_scalar_store_s1;

bool pkt_has_hvx;
Insn *vhist_insn;
Expand Down
8 changes: 4 additions & 4 deletions target/hexagon/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
*/
#define CHECK_NOSHUF(VA, SIZE) \
do { \
if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
if (insn->slot == 0 && ctx->pkt->pkt_has_scalar_store_s1) { \
probe_noshuf_load(VA, SIZE, ctx->mem_idx); \
process_store(ctx, 1); \
} \
Expand All @@ -93,11 +93,11 @@
TCGLabel *noshuf_label = gen_new_label(); \
tcg_gen_brcondi_tl(TCG_COND_EQ, PRED, 0, noshuf_label); \
GET_EA; \
if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
if (insn->slot == 0 && ctx->pkt->pkt_has_scalar_store_s1) { \
probe_noshuf_load(EA, SIZE, ctx->mem_idx); \
} \
gen_set_label(noshuf_label); \
if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
if (insn->slot == 0 && ctx->pkt->pkt_has_scalar_store_s1) { \
process_store(ctx, 1); \
} \
} while (0)
Expand Down Expand Up @@ -524,7 +524,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)

#define fLOAD(NUM, SIZE, SIGN, EA, DST) \
do { \
check_noshuf(env, pkt_has_store_s1, slot, EA, SIZE, GETPC()); \
check_noshuf(env, pkt_has_scalar_store_s1, slot, EA, SIZE, GETPC()); \
DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(env, EA, GETPC()); \
} while (0)
#endif
Expand Down
48 changes: 46 additions & 2 deletions target/hexagon/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ void log_store32(CPUHexagonState *env, target_ulong addr,
env->mem_log_stores[slot].data32 = val;
}

static void do_check_reg_write(CPUHexagonState *env, int rnum)
{
target_ulong mask = 1 << rnum;
if (rnum >= NUM_GPREGS) {
return;
}
if ((env->gpreg_written & mask) == 0) {
env->gpreg_written |= mask;
return;
}
#ifdef CONFIG_USER_ONLY
hexagon_raise_exception_err(env, HEX_CAUSE_REG_WRITE_CONFLICT, 0);
#else
env->cause_code = HEX_CAUSE_REG_WRITE_CONFLICT;
hexagon_raise_exception_err(env, HEX_EVENT_PRECISE, 0);
#endif
}

void log_store64(CPUHexagonState *env, target_ulong addr,
int64_t val, int width, int slot)
{
Expand All @@ -67,6 +85,32 @@ void log_store64(CPUHexagonState *env, target_ulong addr,
env->mem_log_stores[slot].data64 = val;
}

void HELPER(check_reg_write)(CPUHexagonState *env, int rnum)
{
do_check_reg_write(env, rnum);
}

void HELPER(check_cond_reg_write)(CPUHexagonState *env, int rnum, int skip)
{
if (!skip) {
do_check_reg_write(env, rnum);
}
}

void HELPER(check_reg_write_pair)(CPUHexagonState *env, int rnum)
{
do_check_reg_write(env, rnum);
do_check_reg_write(env, rnum + 1);
}

void HELPER(check_cond_reg_write_pair)(CPUHexagonState *env, int rnum, int skip)
{
if (!skip) {
do_check_reg_write(env, rnum);
do_check_reg_write(env, rnum + 1);
}
}

static void commit_store(CPUHexagonState *env, int slot_num, uintptr_t ra)
{
uint8_t width = env->mem_log_stores[slot_num].width;
Expand Down Expand Up @@ -463,11 +507,11 @@ void HELPER(probe_pkt_scalar_hvx_stores)(CPUHexagonState *env, int mask)
* If the load is in slot 0 and there is a store in slot1 (that
* wasn't cancelled), we have to do the store first.
*/
static void check_noshuf(CPUHexagonState *env, bool pkt_has_store_s1,
static void check_noshuf(CPUHexagonState *env, bool pkt_has_scalar_store_s1,
uint32_t slot, target_ulong vaddr, int size,
uintptr_t ra)
{
if (slot == 0 && pkt_has_store_s1 &&
if (slot == 0 && pkt_has_scalar_store_s1 &&
((env->slot_cancelled & (1 << 1)) == 0)) {
probe_read(env, vaddr, size, MMU_USER_IDX, ra);
commit_store(env, 1, ra);
Expand Down
18 changes: 11 additions & 7 deletions target/hexagon/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
TCGv hex_pred[NUM_PREGS];
TCGv hex_slot_cancelled;
TCGv hex_new_value_usr;
TCGv hex_gpreg_written;
TCGv hex_store_addr[STORES_MAX];
TCGv hex_store_width[STORES_MAX];
TCGv hex_store_val32[STORES_MAX];
Expand Down Expand Up @@ -234,11 +235,9 @@ static bool check_for_attrib(Packet *pkt, int attrib)

static bool need_slot_cancelled(Packet *pkt)
{
/* We only need slot_cancelled for conditional store instructions */
for (int i = 0; i < pkt->num_insns; i++) {
uint16_t opcode = pkt->insn[i].opcode;
if (GET_ATTRIB(opcode, A_CONDEXEC) &&
GET_ATTRIB(opcode, A_SCALAR_STORE)) {
if (GET_ATTRIB(opcode, A_CONDEXEC)) {
return true;
}
}
Expand Down Expand Up @@ -440,6 +439,7 @@ static void gen_start_packet(DisasContext *ctx)
* gen phase, so clear it again.
*/
bitmap_zero(ctx->pregs_written, NUM_PREGS);
tcg_gen_movi_tl(hex_gpreg_written, 0);

/* Initialize the runtime state for packet semantics */
if (need_slot_cancelled(pkt)) {
Expand Down Expand Up @@ -693,11 +693,11 @@ static void process_store_log(DisasContext *ctx)
* the memory accesses overlap.
*/
Packet *pkt = ctx->pkt;
if (pkt->pkt_has_store_s1) {
if (pkt->pkt_has_scalar_store_s1) {
g_assert(!pkt->pkt_has_dczeroa);
process_store(ctx, 1);
}
if (pkt->pkt_has_store_s0) {
if (pkt->pkt_has_scalar_store_s0) {
g_assert(!pkt->pkt_has_dczeroa);
process_store(ctx, 0);
}
Expand Down Expand Up @@ -822,8 +822,9 @@ static void gen_commit_packet(DisasContext *ctx)
* involved in committing the packet.
*/
Packet *pkt = ctx->pkt;
bool has_store_s0 = pkt->pkt_has_store_s0;
bool has_store_s1 = (pkt->pkt_has_store_s1 && !ctx->s1_store_processed);
bool has_store_s0 = pkt->pkt_has_scalar_store_s0;
bool has_store_s1 =
(pkt->pkt_has_scalar_store_s1 && !ctx->s1_store_processed);
bool has_hvx_store = pkt_has_hvx_store(pkt);
if (pkt->pkt_has_dczeroa) {
/*
Expand Down Expand Up @@ -1058,6 +1059,9 @@ void hexagon_translate_init(void)
hex_new_value_usr = tcg_global_mem_new(tcg_env,
offsetof(CPUHexagonState, new_value_usr), "new_value_usr");

hex_gpreg_written = tcg_global_mem_new(tcg_env,
offsetof(CPUHexagonState, gpreg_written), "gpreg_written");

for (i = 0; i < NUM_PREGS; i++) {
hex_pred[i] = tcg_global_mem_new(tcg_env,
offsetof(CPUHexagonState, pred[i]),
Expand Down
Loading