1 | The following changes since commit 3e246da2c3f85298b52f8a1154b832acf36aa656: | 1 | The following changes since commit a5ba0a7e4e150d1350a041f0d0ef9ca6c8d7c307: |
---|---|---|---|
2 | 2 | ||
3 | Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2024-06-08 07:40:08 -0700) | 3 | Merge tag 'pull-aspeed-20241211' of https://github.com/legoater/qemu into staging (2024-12-11 15:16:47 +0000) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://github.com/quic/qemu tags/pull-hex-20240608 | 7 | https://github.com/quic/qemu tags/pull-hex-20241212 |
8 | 8 | ||
9 | for you to fetch changes up to 1967a1ea985299c090dfd3efc1e5323ce60d75df: | 9 | for you to fetch changes up to b29b11b51f1ac1884a64c5b6bde969a46206263f: |
10 | 10 | ||
11 | target/hexagon: idef-parser simplify predicate init (2024-06-08 17:49:36 -0700) | 11 | target/hexagon: Make HVX vector args. restrict * (2024-12-12 21:43:57 -0600) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | * hexagon: idef-parser cleanup | 14 | Remove HEX_DEBUG, EXCP/CAUSE fixes |
15 | * hexagon: implement PC alignment exception, tests | ||
16 | * hexagon: fix for HVX new-value store | ||
17 | 15 | ||
18 | ---------------------------------------------------------------- | 16 | ---------------------------------------------------------------- |
19 | Anton Johansson (4): | 17 | Anton Johansson (2): |
20 | target/hexagon: idef-parser remove unused defines | 18 | target/hexagon: Use argparse in all python scripts |
21 | target/hexagon: idef-parser remove undefined functions | 19 | target/hexagon: Make HVX vector args. restrict * |
22 | target/hexagon: idef-parser fix leak of init_list | ||
23 | target/hexagon: idef-parser simplify predicate init | ||
24 | 20 | ||
25 | Matheus Tavares Bernardino (2): | 21 | Brian Cain (2): |
26 | Hexagon: fix HVX store new | 22 | target/hexagon: rename HEX_EXCP_*=>HEX_CAUSE_* |
27 | Hexagon: add PC alignment check and exception | 23 | target/hexagon: add enums for event, cause |
28 | 24 | ||
29 | linux-user/hexagon/cpu_loop.c | 4 ++ | 25 | Taylor Simpson (1): |
30 | target/hexagon/cpu.h | 7 ++ | 26 | Hexagon (target/hexagon) Remove HEX_DEBUG/HEX_DEBUG_LOG |
31 | target/hexagon/cpu_bits.h | 4 ++ | 27 | |
32 | target/hexagon/gen_trans_funcs.py | 9 ++- | 28 | linux-user/hexagon/cpu_loop.c | 4 +- |
33 | target/hexagon/idef-parser/idef-parser.h | 10 --- | 29 | target/hexagon/README | 9 --- |
34 | target/hexagon/idef-parser/idef-parser.y | 2 - | 30 | target/hexagon/cpu.h | 8 +-- |
35 | target/hexagon/idef-parser/parser-helpers.c | 35 +++++---- | 31 | target/hexagon/cpu_bits.h | 21 ++++-- |
36 | target/hexagon/idef-parser/parser-helpers.h | 13 ---- | 32 | target/hexagon/gen_analyze_funcs.py | 6 +- |
37 | target/hexagon/macros.h | 3 - | 33 | target/hexagon/gen_decodetree.py | 19 ++++-- |
38 | target/hexagon/op_helper.c | 9 ++- | 34 | target/hexagon/gen_helper_funcs.py | 7 +- |
39 | tests/tcg/hexagon/Makefile.target | 2 + | 35 | target/hexagon/gen_helper_protos.py | 7 +- |
40 | tests/tcg/hexagon/hvx_misc.c | 23 ++++++ | 36 | target/hexagon/gen_idef_parser_funcs.py | 11 +++- |
41 | tests/tcg/hexagon/unaligned_pc.c | 107 ++++++++++++++++++++++++++++ | 37 | target/hexagon/gen_op_attribs.py | 11 +++- |
42 | 13 files changed, 179 insertions(+), 49 deletions(-) | 38 | target/hexagon/gen_opcodes_def.py | 11 +++- |
43 | create mode 100644 tests/tcg/hexagon/unaligned_pc.c | 39 | target/hexagon/gen_printinsn.py | 11 +++- |
40 | target/hexagon/gen_tcg.h | 2 +- | ||
41 | target/hexagon/gen_tcg_func_table.py | 11 +++- | ||
42 | target/hexagon/gen_tcg_funcs.py | 9 +-- | ||
43 | target/hexagon/gen_trans_funcs.py | 18 ++++- | ||
44 | target/hexagon/genptr.c | 7 -- | ||
45 | target/hexagon/helper.h | 3 - | ||
46 | target/hexagon/hex_common.py | 33 +++++----- | ||
47 | target/hexagon/internal.h | 11 ---- | ||
48 | target/hexagon/meson.build | 2 +- | ||
49 | target/hexagon/mmvec/macros.h | 36 +++++----- | ||
50 | target/hexagon/op_helper.c | 112 -------------------------------- | ||
51 | target/hexagon/translate.c | 72 +------------------- | ||
52 | target/hexagon/translate.h | 2 - | ||
53 | 25 files changed, 148 insertions(+), 295 deletions(-) | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> | ||
2 | 1 | ||
3 | At 09a7e7db0f (Hexagon (target/hexagon) Remove uses of | ||
4 | op_regs_generated.h.inc, 2024-03-06), we've changed the logic of | ||
5 | check_new_value() to use the new pre-calculated | ||
6 | packet->insn[...].dest_idx instead of calculating the index on the fly | ||
7 | using opcode_reginfo[...]. The dest_idx index is calculated roughly like | ||
8 | the following: | ||
9 | |||
10 | for reg in iset[tag]["syntax"]: | ||
11 | if reg.is_written(): | ||
12 | dest_idx = regno | ||
13 | break | ||
14 | |||
15 | Thus, we take the first register that is writtable. Before that, | ||
16 | however, we also used to follow an alphabetical order on the register | ||
17 | type: 'd', 'e', 'x', and 'y'. No longer following that makes us select | ||
18 | the wrong register index and the HVX store new instruction does not | ||
19 | update the memory like expected. | ||
20 | |||
21 | Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> | ||
22 | Reviewed-by: Brian Cain <bcain@quicinc.com> | ||
23 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> | ||
24 | Message-Id: <f548dc1c240819c724245e887f29f918441e9125.1716220379.git.quic_mathbern@quicinc.com> | ||
25 | Signed-off-by: Brian Cain <bcain@quicinc.com> | ||
26 | --- | ||
27 | target/hexagon/gen_trans_funcs.py | 9 ++++++--- | ||
28 | tests/tcg/hexagon/hvx_misc.c | 23 +++++++++++++++++++++++ | ||
29 | 2 files changed, 29 insertions(+), 3 deletions(-) | ||
30 | |||
31 | diff --git a/target/hexagon/gen_trans_funcs.py b/target/hexagon/gen_trans_funcs.py | ||
32 | index XXXXXXX..XXXXXXX 100755 | ||
33 | --- a/target/hexagon/gen_trans_funcs.py | ||
34 | +++ b/target/hexagon/gen_trans_funcs.py | ||
35 | @@ -XXX,XX +XXX,XX @@ def gen_trans_funcs(f): | ||
36 | |||
37 | new_read_idx = -1 | ||
38 | dest_idx = -1 | ||
39 | + dest_idx_reg_id = None | ||
40 | has_pred_dest = "false" | ||
41 | for regno, (reg_type, reg_id, *_) in enumerate(regs): | ||
42 | reg = hex_common.get_register(tag, reg_type, reg_id) | ||
43 | @@ -XXX,XX +XXX,XX @@ def gen_trans_funcs(f): | ||
44 | """)) | ||
45 | if reg.is_read() and reg.is_new(): | ||
46 | new_read_idx = regno | ||
47 | - # dest_idx should be the first destination, so check for -1 | ||
48 | - if reg.is_written() and dest_idx == -1: | ||
49 | - dest_idx = regno | ||
50 | + if reg.is_written(): | ||
51 | + # dest_idx should be the first destination alphabetically | ||
52 | + if dest_idx_reg_id is None or reg_id < dest_idx_reg_id: | ||
53 | + dest_idx = regno | ||
54 | + dest_idx_reg_id = reg_id | ||
55 | if reg_type == "P" and reg.is_written() and not reg.is_read(): | ||
56 | has_pred_dest = "true" | ||
57 | |||
58 | diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/tests/tcg/hexagon/hvx_misc.c | ||
61 | +++ b/tests/tcg/hexagon/hvx_misc.c | ||
62 | @@ -XXX,XX +XXX,XX @@ static void test_vcombine(void) | ||
63 | check_output_w(__LINE__, BUFSIZE); | ||
64 | } | ||
65 | |||
66 | +void test_store_new() | ||
67 | +{ | ||
68 | + asm volatile( | ||
69 | + "r0 = #0x12345678\n" | ||
70 | + "v0 = vsplat(r0)\n" | ||
71 | + "r0 = #0xff00ff00\n" | ||
72 | + "v1 = vsplat(r0)\n" | ||
73 | + "{\n" | ||
74 | + " vdeal(v1,v0,r0)\n" | ||
75 | + " vmem(%0) = v0.new\n" | ||
76 | + "}\n" | ||
77 | + : | ||
78 | + : "r"(&output[0]) | ||
79 | + : "r0", "v0", "v1", "memory" | ||
80 | + ); | ||
81 | + for (int i = 0; i < MAX_VEC_SIZE_BYTES / 4; i++) { | ||
82 | + expect[0].w[i] = 0x12345678; | ||
83 | + } | ||
84 | + check_output_w(__LINE__, 1); | ||
85 | +} | ||
86 | + | ||
87 | int main() | ||
88 | { | ||
89 | init_buffers(); | ||
90 | @@ -XXX,XX +XXX,XX @@ int main() | ||
91 | |||
92 | test_vcombine(); | ||
93 | |||
94 | + test_store_new(); | ||
95 | + | ||
96 | puts(err ? "FAIL" : "PASS"); | ||
97 | return err ? 1 : 0; | ||
98 | } | ||
99 | -- | ||
100 | 2.25.1 | ||
101 | diff view generated by jsdifflib |
1 | From: Anton Johansson <anjo@rev.ng> | 1 | From: Taylor Simpson <ltaylorsimpson@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | Only predicate instruction arguments need to be initialized by | 3 | All Hexagon debugging is now done with QEMU mechanisms |
4 | idef-parser. This commit removes registers from the init_list and | 4 | (e.g., -d in_asm) or with a connected debugger (lldb). |
5 | simplifies gen_inst_init_args() slightly. | ||
6 | 5 | ||
7 | Signed-off-by: Anton Johansson <anjo@rev.ng> | 6 | Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com> |
8 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> | 7 | Reviewed-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> |
9 | Reviewed-by: Brian Cain <bcain@quicinc.com> | 8 | Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com> |
10 | Message-Id: <20240523125901.27797-5-anjo@rev.ng> | 9 | Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> |
11 | Signed-off-by: Brian Cain <bcain@quicinc.com> | ||
12 | --- | 10 | --- |
13 | target/hexagon/idef-parser/idef-parser.y | 2 -- | 11 | target/hexagon/README | 9 --- |
14 | target/hexagon/idef-parser/parser-helpers.c | 26 +++++++++++---------- | 12 | target/hexagon/cpu.h | 6 -- |
15 | 2 files changed, 14 insertions(+), 14 deletions(-) | 13 | target/hexagon/genptr.c | 7 --- |
14 | target/hexagon/helper.h | 3 - | ||
15 | target/hexagon/internal.h | 11 ---- | ||
16 | target/hexagon/op_helper.c | 112 ------------------------------------- | ||
17 | target/hexagon/translate.c | 66 ---------------------- | ||
18 | target/hexagon/translate.h | 2 - | ||
19 | 8 files changed, 216 deletions(-) | ||
16 | 20 | ||
17 | diff --git a/target/hexagon/idef-parser/idef-parser.y b/target/hexagon/idef-parser/idef-parser.y | 21 | diff --git a/target/hexagon/README b/target/hexagon/README |
18 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/hexagon/idef-parser/idef-parser.y | 23 | --- a/target/hexagon/README |
20 | +++ b/target/hexagon/idef-parser/idef-parser.y | 24 | +++ b/target/hexagon/README |
21 | @@ -XXX,XX +XXX,XX @@ code : '{' statements '}' | 25 | @@ -XXX,XX +XXX,XX @@ For Hexagon Vector eXtensions (HVX), the following fields are used |
22 | argument_decl : REG | 26 | |
23 | { | 27 | *** Debugging *** |
24 | emit_arg(c, &@1, &$1); | 28 | |
25 | - /* Enqueue register into initialization list */ | 29 | -You can turn on a lot of debugging by changing the HEX_DEBUG macro to 1 in |
26 | - g_array_append_val(c->inst.init_list, $1); | 30 | -internal.h. This will stream a lot of information as it generates TCG and |
27 | } | 31 | -executes the code. |
28 | | PRED | 32 | - |
29 | { | 33 | To track down nasty issues with Hexagon->TCG generation, we compare the |
30 | diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c | 34 | execution results with actual hardware running on a Hexagon Linux target. |
31 | index XXXXXXX..XXXXXXX 100644 | 35 | Run qemu with the "-d cpu" option. Then, we can diff the results and figure |
32 | --- a/target/hexagon/idef-parser/parser-helpers.c | 36 | @@ -XXX,XX +XXX,XX @@ Here are some handy places to set breakpoints |
33 | +++ b/target/hexagon/idef-parser/parser-helpers.c | 37 | The helper function for each instruction is named helper_<TAG>, so here's |
34 | @@ -XXX,XX +XXX,XX @@ void gen_inst(Context *c, GString *iname) | 38 | an example that will set a breakpoint at the start |
35 | 39 | br helper_A2_add | |
36 | 40 | - If you have the HEX_DEBUG macro set, the following will be useful | |
37 | /* | 41 | - At the start of execution of a packet for a given PC |
38 | - * Initialize declared but uninitialized registers, but only for | 42 | - br helper_debug_start_packet if env->gpr[41] == 0xdeadbeef |
39 | - * non-conditional instructions | 43 | - At the end of execution of a packet for a given PC |
40 | + * Initialize declared but uninitialized instruction arguments. Only needed for | 44 | - br helper_debug_commit_end if this_PC == 0xdeadbeef |
41 | + * predicate arguments, initialization of registers is handled by the Hexagon | 45 | diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h |
42 | + * frontend. | 46 | index XXXXXXX..XXXXXXX 100644 |
43 | */ | 47 | --- a/target/hexagon/cpu.h |
44 | void gen_inst_init_args(Context *c, YYLTYPE *locp) | 48 | +++ b/target/hexagon/cpu.h |
45 | { | 49 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
46 | + HexValue *val = NULL; | 50 | uint8_t slot_cancelled; |
47 | + char suffix; | 51 | target_ulong new_value_usr; |
48 | + | 52 | |
49 | + /* If init_list is NULL arguments have already been initialized */ | 53 | - /* |
50 | if (!c->inst.init_list) { | 54 | - * Only used when HEX_DEBUG is on, but unconditionally included |
51 | return; | 55 | - * to reduce recompile time when turning HEX_DEBUG on/off. |
52 | } | 56 | - */ |
53 | 57 | - target_ulong reg_written[TOTAL_PER_THREAD_REGS]; | |
54 | for (unsigned i = 0; i < c->inst.init_list->len; i++) { | 58 | - |
55 | - HexValue *val = &g_array_index(c->inst.init_list, HexValue, i); | 59 | MemLog mem_log_stores[STORES_MAX]; |
56 | - if (val->type == REGISTER_ARG) { | 60 | |
57 | - /* Nothing to do here */ | 61 | float_status fp_status; |
58 | - } else if (val->type == PREDICATE) { | 62 | diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c |
59 | - char suffix = val->is_dotnew ? 'N' : 'V'; | 63 | index XXXXXXX..XXXXXXX 100644 |
60 | - EMIT_HEAD(c, "tcg_gen_movi_i%u(P%c%c, 0);\n", val->bit_width, | 64 | --- a/target/hexagon/genptr.c |
61 | - val->pred.id, suffix); | 65 | +++ b/target/hexagon/genptr.c |
66 | @@ -XXX,XX +XXX,XX @@ void gen_log_reg_write(DisasContext *ctx, int rnum, TCGv val) | ||
67 | |||
68 | gen_masked_reg_write(val, hex_gpr[rnum], reg_mask); | ||
69 | tcg_gen_mov_tl(get_result_gpr(ctx, rnum), val); | ||
70 | - if (HEX_DEBUG) { | ||
71 | - /* Do this so HELPER(debug_commit_end) will know */ | ||
72 | - tcg_gen_movi_tl(hex_reg_written[rnum], 1); | ||
73 | - } | ||
74 | } | ||
75 | |||
76 | static void gen_log_reg_write_pair(DisasContext *ctx, int rnum, TCGv_i64 val) | ||
77 | @@ -XXX,XX +XXX,XX @@ void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val) | ||
78 | } else { | ||
79 | tcg_gen_and_tl(pred, pred, base_val); | ||
80 | } | ||
81 | - if (HEX_DEBUG) { | ||
82 | - tcg_gen_ori_tl(ctx->pred_written, ctx->pred_written, 1 << pnum); | ||
83 | - } | ||
84 | set_bit(pnum, ctx->pregs_written); | ||
85 | } | ||
86 | |||
87 | diff --git a/target/hexagon/helper.h b/target/hexagon/helper.h | ||
88 | index XXXXXXX..XXXXXXX 100644 | ||
89 | --- a/target/hexagon/helper.h | ||
90 | +++ b/target/hexagon/helper.h | ||
91 | @@ -XXX,XX +XXX,XX @@ | ||
92 | #include "helper_protos_generated.h.inc" | ||
93 | |||
94 | DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_RETURN, noreturn, env, i32) | ||
95 | -DEF_HELPER_1(debug_start_packet, void, env) | ||
96 | -DEF_HELPER_FLAGS_3(debug_check_store_width, TCG_CALL_NO_WG, void, env, int, int) | ||
97 | -DEF_HELPER_FLAGS_5(debug_commit_end, TCG_CALL_NO_WG, void, env, i32, int, int, int) | ||
98 | DEF_HELPER_2(commit_store, void, env, int) | ||
99 | DEF_HELPER_3(gather_store, void, env, i32, int) | ||
100 | DEF_HELPER_1(commit_hvx_stores, void, env) | ||
101 | diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h | ||
102 | index XXXXXXX..XXXXXXX 100644 | ||
103 | --- a/target/hexagon/internal.h | ||
104 | +++ b/target/hexagon/internal.h | ||
105 | @@ -XXX,XX +XXX,XX @@ | ||
106 | |||
107 | #include "qemu/log.h" | ||
108 | |||
109 | -/* | ||
110 | - * Change HEX_DEBUG to 1 to turn on debugging output | ||
111 | - */ | ||
112 | -#define HEX_DEBUG 0 | ||
113 | -#define HEX_DEBUG_LOG(...) \ | ||
114 | - do { \ | ||
115 | - if (HEX_DEBUG) { \ | ||
116 | - qemu_log(__VA_ARGS__); \ | ||
117 | - } \ | ||
118 | - } while (0) | ||
119 | - | ||
120 | int hexagon_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); | ||
121 | int hexagon_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); | ||
122 | int hexagon_hvx_gdb_read_register(CPUState *env, GByteArray *mem_buf, int n); | ||
123 | diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c | ||
124 | index XXXXXXX..XXXXXXX 100644 | ||
125 | --- a/target/hexagon/op_helper.c | ||
126 | +++ b/target/hexagon/op_helper.c | ||
127 | @@ -XXX,XX +XXX,XX @@ G_NORETURN void HELPER(raise_exception)(CPUHexagonState *env, uint32_t excp) | ||
128 | void log_store32(CPUHexagonState *env, target_ulong addr, | ||
129 | target_ulong val, int width, int slot) | ||
130 | { | ||
131 | - HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx | ||
132 | - ", %" PRId32 " [0x08%" PRIx32 "])\n", | ||
133 | - width, addr, val, val); | ||
134 | env->mem_log_stores[slot].va = addr; | ||
135 | env->mem_log_stores[slot].width = width; | ||
136 | env->mem_log_stores[slot].data32 = val; | ||
137 | @@ -XXX,XX +XXX,XX @@ void log_store32(CPUHexagonState *env, target_ulong addr, | ||
138 | void log_store64(CPUHexagonState *env, target_ulong addr, | ||
139 | int64_t val, int width, int slot) | ||
140 | { | ||
141 | - HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx | ||
142 | - ", %" PRId64 " [0x016%" PRIx64 "])\n", | ||
143 | - width, addr, val, val); | ||
144 | env->mem_log_stores[slot].va = addr; | ||
145 | env->mem_log_stores[slot].width = width; | ||
146 | env->mem_log_stores[slot].data64 = val; | ||
147 | } | ||
148 | |||
149 | -/* Handy place to set a breakpoint */ | ||
150 | -void HELPER(debug_start_packet)(CPUHexagonState *env) | ||
151 | -{ | ||
152 | - HEX_DEBUG_LOG("Start packet: pc = 0x" TARGET_FMT_lx "\n", | ||
153 | - env->gpr[HEX_REG_PC]); | ||
154 | - | ||
155 | - for (int i = 0; i < TOTAL_PER_THREAD_REGS; i++) { | ||
156 | - env->reg_written[i] = 0; | ||
157 | - } | ||
158 | -} | ||
159 | - | ||
160 | -/* Checks for bookkeeping errors between disassembly context and runtime */ | ||
161 | -void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check) | ||
162 | -{ | ||
163 | - if (env->mem_log_stores[slot].width != check) { | ||
164 | - HEX_DEBUG_LOG("ERROR: %d != %d\n", | ||
165 | - env->mem_log_stores[slot].width, check); | ||
166 | - g_assert_not_reached(); | ||
167 | - } | ||
168 | -} | ||
169 | - | ||
170 | static void commit_store(CPUHexagonState *env, int slot_num, uintptr_t ra) | ||
171 | { | ||
172 | uint8_t width = env->mem_log_stores[slot_num].width; | ||
173 | @@ -XXX,XX +XXX,XX @@ void HELPER(commit_hvx_stores)(CPUHexagonState *env) | ||
174 | } | ||
175 | } | ||
176 | |||
177 | -static void print_store(CPUHexagonState *env, int slot) | ||
178 | -{ | ||
179 | - if (!(env->slot_cancelled & (1 << slot))) { | ||
180 | - uint8_t width = env->mem_log_stores[slot].width; | ||
181 | - if (width == 1) { | ||
182 | - uint32_t data = env->mem_log_stores[slot].data32 & 0xff; | ||
183 | - HEX_DEBUG_LOG("\tmemb[0x" TARGET_FMT_lx "] = %" PRId32 | ||
184 | - " (0x%02" PRIx32 ")\n", | ||
185 | - env->mem_log_stores[slot].va, data, data); | ||
186 | - } else if (width == 2) { | ||
187 | - uint32_t data = env->mem_log_stores[slot].data32 & 0xffff; | ||
188 | - HEX_DEBUG_LOG("\tmemh[0x" TARGET_FMT_lx "] = %" PRId32 | ||
189 | - " (0x%04" PRIx32 ")\n", | ||
190 | - env->mem_log_stores[slot].va, data, data); | ||
191 | - } else if (width == 4) { | ||
192 | - uint32_t data = env->mem_log_stores[slot].data32; | ||
193 | - HEX_DEBUG_LOG("\tmemw[0x" TARGET_FMT_lx "] = %" PRId32 | ||
194 | - " (0x%08" PRIx32 ")\n", | ||
195 | - env->mem_log_stores[slot].va, data, data); | ||
196 | - } else if (width == 8) { | ||
197 | - HEX_DEBUG_LOG("\tmemd[0x" TARGET_FMT_lx "] = %" PRId64 | ||
198 | - " (0x%016" PRIx64 ")\n", | ||
199 | - env->mem_log_stores[slot].va, | ||
200 | - env->mem_log_stores[slot].data64, | ||
201 | - env->mem_log_stores[slot].data64); | ||
62 | - } else { | 202 | - } else { |
63 | - yyassert(c, locp, false, "Invalid arg type!"); | 203 | - HEX_DEBUG_LOG("\tBad store width %d\n", width); |
64 | - } | 204 | - g_assert_not_reached(); |
65 | + val = &g_array_index(c->inst.init_list, HexValue, i); | 205 | - } |
66 | + suffix = val->is_dotnew ? 'N' : 'V'; | 206 | - } |
67 | + yyassert(c, locp, val->type == PREDICATE, | 207 | -} |
68 | + "Only predicates need to be initialized!"); | 208 | - |
69 | + yyassert(c, locp, val->bit_width == 32, | 209 | -/* This function is a handy place to set a breakpoint */ |
70 | + "Predicates should always be 32 bits"); | 210 | -void HELPER(debug_commit_end)(CPUHexagonState *env, uint32_t this_PC, |
71 | + EMIT_HEAD(c, "tcg_gen_movi_i32(P%c%c, 0);\n", val->pred.id, suffix); | 211 | - int pred_written, int has_st0, int has_st1) |
72 | } | 212 | -{ |
73 | 213 | - bool reg_printed = false; | |
74 | /* Free argument init list once we have initialized everything */ | 214 | - bool pred_printed = false; |
215 | - int i; | ||
216 | - | ||
217 | - HEX_DEBUG_LOG("Packet committed: pc = 0x" TARGET_FMT_lx "\n", this_PC); | ||
218 | - HEX_DEBUG_LOG("slot_cancelled = %d\n", env->slot_cancelled); | ||
219 | - | ||
220 | - for (i = 0; i < TOTAL_PER_THREAD_REGS; i++) { | ||
221 | - if (env->reg_written[i]) { | ||
222 | - if (!reg_printed) { | ||
223 | - HEX_DEBUG_LOG("Regs written\n"); | ||
224 | - reg_printed = true; | ||
225 | - } | ||
226 | - HEX_DEBUG_LOG("\tr%d = " TARGET_FMT_ld " (0x" TARGET_FMT_lx ")\n", | ||
227 | - i, env->gpr[i], env->gpr[i]); | ||
228 | - } | ||
229 | - } | ||
230 | - | ||
231 | - for (i = 0; i < NUM_PREGS; i++) { | ||
232 | - if (pred_written & (1 << i)) { | ||
233 | - if (!pred_printed) { | ||
234 | - HEX_DEBUG_LOG("Predicates written\n"); | ||
235 | - pred_printed = true; | ||
236 | - } | ||
237 | - HEX_DEBUG_LOG("\tp%d = 0x" TARGET_FMT_lx "\n", | ||
238 | - i, env->pred[i]); | ||
239 | - } | ||
240 | - } | ||
241 | - | ||
242 | - if (has_st0 || has_st1) { | ||
243 | - HEX_DEBUG_LOG("Stores\n"); | ||
244 | - if (has_st0) { | ||
245 | - print_store(env, 0); | ||
246 | - } | ||
247 | - if (has_st1) { | ||
248 | - print_store(env, 1); | ||
249 | - } | ||
250 | - } | ||
251 | - | ||
252 | - HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx "\n", env->gpr[HEX_REG_PC]); | ||
253 | - HEX_DEBUG_LOG("Exec counters: pkt = " TARGET_FMT_lx | ||
254 | - ", insn = " TARGET_FMT_lx | ||
255 | - ", hvx = " TARGET_FMT_lx "\n", | ||
256 | - env->gpr[HEX_REG_QEMU_PKT_CNT], | ||
257 | - env->gpr[HEX_REG_QEMU_INSN_CNT], | ||
258 | - env->gpr[HEX_REG_QEMU_HVX_CNT]); | ||
259 | - | ||
260 | -} | ||
261 | - | ||
262 | int32_t HELPER(fcircadd)(int32_t RxV, int32_t offset, int32_t M, int32_t CS) | ||
263 | { | ||
264 | uint32_t K_const = extract32(M, 24, 4); | ||
265 | diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c | ||
266 | index XXXXXXX..XXXXXXX 100644 | ||
267 | --- a/target/hexagon/translate.c | ||
268 | +++ b/target/hexagon/translate.c | ||
269 | @@ -XXX,XX +XXX,XX @@ TCGv hex_gpr[TOTAL_PER_THREAD_REGS]; | ||
270 | TCGv hex_pred[NUM_PREGS]; | ||
271 | TCGv hex_slot_cancelled; | ||
272 | TCGv hex_new_value_usr; | ||
273 | -TCGv hex_reg_written[TOTAL_PER_THREAD_REGS]; | ||
274 | TCGv hex_store_addr[STORES_MAX]; | ||
275 | TCGv hex_store_width[STORES_MAX]; | ||
276 | TCGv hex_store_val32[STORES_MAX]; | ||
277 | @@ -XXX,XX +XXX,XX @@ static void gen_exception_end_tb(DisasContext *ctx, int excp) | ||
278 | |||
279 | } | ||
280 | |||
281 | -#define PACKET_BUFFER_LEN 1028 | ||
282 | -static void print_pkt(Packet *pkt) | ||
283 | -{ | ||
284 | - GString *buf = g_string_sized_new(PACKET_BUFFER_LEN); | ||
285 | - snprint_a_pkt_debug(buf, pkt); | ||
286 | - HEX_DEBUG_LOG("%s", buf->str); | ||
287 | - g_string_free(buf, true); | ||
288 | -} | ||
289 | -#define HEX_DEBUG_PRINT_PKT(pkt) \ | ||
290 | - do { \ | ||
291 | - if (HEX_DEBUG) { \ | ||
292 | - print_pkt(pkt); \ | ||
293 | - } \ | ||
294 | - } while (0) | ||
295 | - | ||
296 | static int read_packet_words(CPUHexagonState *env, DisasContext *ctx, | ||
297 | uint32_t words[]) | ||
298 | { | ||
299 | @@ -XXX,XX +XXX,XX @@ static int read_packet_words(CPUHexagonState *env, DisasContext *ctx, | ||
300 | g_assert(ctx->base.num_insns == 1); | ||
301 | } | ||
302 | |||
303 | - HEX_DEBUG_LOG("decode_packet: pc = 0x%" VADDR_PRIx "\n", | ||
304 | - ctx->base.pc_next); | ||
305 | - HEX_DEBUG_LOG(" words = { "); | ||
306 | - for (int i = 0; i < nwords; i++) { | ||
307 | - HEX_DEBUG_LOG("0x%x, ", words[i]); | ||
308 | - } | ||
309 | - HEX_DEBUG_LOG("}\n"); | ||
310 | - | ||
311 | return nwords; | ||
312 | } | ||
313 | |||
314 | @@ -XXX,XX +XXX,XX @@ static void gen_start_packet(DisasContext *ctx) | ||
315 | */ | ||
316 | bitmap_zero(ctx->pregs_written, NUM_PREGS); | ||
317 | |||
318 | - if (HEX_DEBUG) { | ||
319 | - /* Handy place to set a breakpoint before the packet executes */ | ||
320 | - gen_helper_debug_start_packet(tcg_env); | ||
321 | - } | ||
322 | - | ||
323 | /* Initialize the runtime state for packet semantics */ | ||
324 | if (need_slot_cancelled(pkt)) { | ||
325 | tcg_gen_movi_tl(hex_slot_cancelled, 0); | ||
326 | @@ -XXX,XX +XXX,XX @@ static void gen_start_packet(DisasContext *ctx) | ||
327 | tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], next_PC); | ||
328 | } | ||
329 | } | ||
330 | - if (HEX_DEBUG) { | ||
331 | - ctx->pred_written = tcg_temp_new(); | ||
332 | - tcg_gen_movi_tl(ctx->pred_written, 0); | ||
333 | - } | ||
334 | |||
335 | /* Preload the predicated registers into get_result_gpr(ctx, i) */ | ||
336 | if (ctx->need_commit && | ||
337 | @@ -XXX,XX +XXX,XX @@ static void gen_pred_writes(DisasContext *ctx) | ||
338 | } | ||
339 | } | ||
340 | |||
341 | -static void gen_check_store_width(DisasContext *ctx, int slot_num) | ||
342 | -{ | ||
343 | - if (HEX_DEBUG) { | ||
344 | - TCGv slot = tcg_constant_tl(slot_num); | ||
345 | - TCGv check = tcg_constant_tl(ctx->store_width[slot_num]); | ||
346 | - gen_helper_debug_check_store_width(tcg_env, slot, check); | ||
347 | - } | ||
348 | -} | ||
349 | - | ||
350 | static bool slot_is_predicated(Packet *pkt, int slot_num) | ||
351 | { | ||
352 | for (int i = 0; i < pkt->num_insns; i++) { | ||
353 | @@ -XXX,XX +XXX,XX @@ void process_store(DisasContext *ctx, int slot_num) | ||
354 | */ | ||
355 | switch (ctx->store_width[slot_num]) { | ||
356 | case 1: | ||
357 | - gen_check_store_width(ctx, slot_num); | ||
358 | tcg_gen_qemu_st_tl(hex_store_val32[slot_num], | ||
359 | hex_store_addr[slot_num], | ||
360 | ctx->mem_idx, MO_UB); | ||
361 | break; | ||
362 | case 2: | ||
363 | - gen_check_store_width(ctx, slot_num); | ||
364 | tcg_gen_qemu_st_tl(hex_store_val32[slot_num], | ||
365 | hex_store_addr[slot_num], | ||
366 | ctx->mem_idx, MO_TEUW); | ||
367 | break; | ||
368 | case 4: | ||
369 | - gen_check_store_width(ctx, slot_num); | ||
370 | tcg_gen_qemu_st_tl(hex_store_val32[slot_num], | ||
371 | hex_store_addr[slot_num], | ||
372 | ctx->mem_idx, MO_TEUL); | ||
373 | break; | ||
374 | case 8: | ||
375 | - gen_check_store_width(ctx, slot_num); | ||
376 | tcg_gen_qemu_st_i64(hex_store_val64[slot_num], | ||
377 | hex_store_addr[slot_num], | ||
378 | ctx->mem_idx, MO_TEUQ); | ||
379 | @@ -XXX,XX +XXX,XX @@ static void gen_commit_packet(DisasContext *ctx) | ||
380 | gen_commit_hvx(ctx); | ||
381 | } | ||
382 | update_exec_counters(ctx); | ||
383 | - if (HEX_DEBUG) { | ||
384 | - TCGv has_st0 = | ||
385 | - tcg_constant_tl(pkt->pkt_has_store_s0 && !pkt->pkt_has_dczeroa); | ||
386 | - TCGv has_st1 = | ||
387 | - tcg_constant_tl(pkt->pkt_has_store_s1 && !pkt->pkt_has_dczeroa); | ||
388 | - | ||
389 | - /* Handy place to set a breakpoint at the end of execution */ | ||
390 | - gen_helper_debug_commit_end(tcg_env, tcg_constant_tl(ctx->pkt->pc), | ||
391 | - ctx->pred_written, has_st0, has_st1); | ||
392 | - } | ||
393 | |||
394 | if (pkt->vhist_insn != NULL) { | ||
395 | ctx->pre_commit = false; | ||
396 | @@ -XXX,XX +XXX,XX @@ static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx) | ||
397 | ctx->pkt = &pkt; | ||
398 | if (decode_packet(ctx, nwords, words, &pkt, false) > 0) { | ||
399 | pkt.pc = ctx->base.pc_next; | ||
400 | - HEX_DEBUG_PRINT_PKT(&pkt); | ||
401 | gen_start_packet(ctx); | ||
402 | for (i = 0; i < pkt.num_insns; i++) { | ||
403 | ctx->insn = &pkt.insn[i]; | ||
404 | @@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, | ||
405 | } | ||
406 | |||
407 | #define NAME_LEN 64 | ||
408 | -static char reg_written_names[TOTAL_PER_THREAD_REGS][NAME_LEN]; | ||
409 | static char store_addr_names[STORES_MAX][NAME_LEN]; | ||
410 | static char store_width_names[STORES_MAX][NAME_LEN]; | ||
411 | static char store_val32_names[STORES_MAX][NAME_LEN]; | ||
412 | @@ -XXX,XX +XXX,XX @@ void hexagon_translate_init(void) | ||
413 | hex_gpr[i] = tcg_global_mem_new(tcg_env, | ||
414 | offsetof(CPUHexagonState, gpr[i]), | ||
415 | hexagon_regnames[i]); | ||
416 | - | ||
417 | - if (HEX_DEBUG) { | ||
418 | - snprintf(reg_written_names[i], NAME_LEN, "reg_written_%s", | ||
419 | - hexagon_regnames[i]); | ||
420 | - hex_reg_written[i] = tcg_global_mem_new(tcg_env, | ||
421 | - offsetof(CPUHexagonState, reg_written[i]), | ||
422 | - reg_written_names[i]); | ||
423 | - } | ||
424 | } | ||
425 | hex_new_value_usr = tcg_global_mem_new(tcg_env, | ||
426 | offsetof(CPUHexagonState, new_value_usr), "new_value_usr"); | ||
427 | diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h | ||
428 | index XXXXXXX..XXXXXXX 100644 | ||
429 | --- a/target/hexagon/translate.h | ||
430 | +++ b/target/hexagon/translate.h | ||
431 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
432 | bool has_hvx_overlap; | ||
433 | TCGv new_value[TOTAL_PER_THREAD_REGS]; | ||
434 | TCGv new_pred_value[NUM_PREGS]; | ||
435 | - TCGv pred_written; | ||
436 | TCGv branch_taken; | ||
437 | TCGv dczero_addr; | ||
438 | } DisasContext; | ||
439 | @@ -XXX,XX +XXX,XX @@ extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS]; | ||
440 | extern TCGv hex_pred[NUM_PREGS]; | ||
441 | extern TCGv hex_slot_cancelled; | ||
442 | extern TCGv hex_new_value_usr; | ||
443 | -extern TCGv hex_reg_written[TOTAL_PER_THREAD_REGS]; | ||
444 | extern TCGv hex_store_addr[STORES_MAX]; | ||
445 | extern TCGv hex_store_width[STORES_MAX]; | ||
446 | extern TCGv hex_store_val32[STORES_MAX]; | ||
75 | -- | 447 | -- |
76 | 2.25.1 | 448 | 2.34.1 |
77 | 449 | diff view generated by jsdifflib |
1 | From: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> | 1 | From: Brian Cain <bcain@quicinc.com> |
---|---|---|---|
2 | 2 | ||
3 | The Hexagon Programmer's Reference Manual says that the exception 0x1e | 3 | The values previously used for "HEX_EXCP_*" were the cause code |
4 | should be raised upon an unaligned program counter. Let's implement that | 4 | definitions and not the event numbers. So in this commit, we update |
5 | and also add some tests. | 5 | the names to reflect the cause codes. In HEX_EVENT_TRAP0's case, we add |
6 | a new "HEX_EVENT_*" with the correct event number. | ||
6 | 7 | ||
7 | Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> | 8 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> |
10 | Reviewed-by: Brian Cain <bcain@quicinc.com> | 9 | Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> |
11 | Message-Id: <277b7aeda2c717a96d4dde936b3ac77707cb6517.1714755107.git.quic_mathbern@quicinc.com> | ||
12 | Signed-off-by: Brian Cain <bcain@quicinc.com> | ||
13 | --- | 10 | --- |
14 | linux-user/hexagon/cpu_loop.c | 4 ++ | 11 | linux-user/hexagon/cpu_loop.c | 4 ++-- |
15 | target/hexagon/cpu.h | 7 ++ | 12 | target/hexagon/cpu.h | 2 +- |
16 | target/hexagon/cpu_bits.h | 4 ++ | 13 | target/hexagon/cpu_bits.h | 15 ++++++++------- |
17 | target/hexagon/macros.h | 3 - | 14 | target/hexagon/gen_tcg.h | 2 +- |
18 | target/hexagon/op_helper.c | 9 ++- | 15 | target/hexagon/translate.c | 6 +++--- |
19 | tests/tcg/hexagon/Makefile.target | 2 + | 16 | 5 files changed, 15 insertions(+), 14 deletions(-) |
20 | tests/tcg/hexagon/unaligned_pc.c | 107 ++++++++++++++++++++++++++++++ | ||
21 | 7 files changed, 128 insertions(+), 8 deletions(-) | ||
22 | create mode 100644 tests/tcg/hexagon/unaligned_pc.c | ||
23 | 17 | ||
24 | diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c | 18 | diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c |
25 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/linux-user/hexagon/cpu_loop.c | 20 | --- a/linux-user/hexagon/cpu_loop.c |
27 | +++ b/linux-user/hexagon/cpu_loop.c | 21 | +++ b/linux-user/hexagon/cpu_loop.c |
28 | @@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUHexagonState *env) | 22 | @@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUHexagonState *env) |
23 | case EXCP_INTERRUPT: | ||
24 | /* just indicate that signals should be handled asap */ | ||
25 | break; | ||
26 | - case HEX_EXCP_TRAP0: | ||
27 | + case HEX_EVENT_TRAP0: | ||
28 | syscallnum = env->gpr[6]; | ||
29 | env->gpr[HEX_REG_PC] += 4; | ||
30 | ret = do_syscall(env, | ||
31 | @@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUHexagonState *env) | ||
29 | env->gpr[0] = ret; | 32 | env->gpr[0] = ret; |
30 | } | 33 | } |
31 | break; | 34 | break; |
32 | + case HEX_EXCP_PC_NOT_ALIGNED: | 35 | - case HEX_EXCP_PC_NOT_ALIGNED: |
33 | + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, | 36 | + case HEX_CAUSE_PC_NOT_ALIGNED: |
34 | + env->gpr[HEX_REG_R31]); | 37 | force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, |
35 | + break; | 38 | env->gpr[HEX_REG_R31]); |
36 | case EXCP_ATOMIC: | ||
37 | cpu_exec_step_atomic(cs); | ||
38 | break; | 39 | break; |
39 | diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h | 40 | diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h |
40 | index XXXXXXX..XXXXXXX 100644 | 41 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/target/hexagon/cpu.h | 42 | --- a/target/hexagon/cpu.h |
42 | +++ b/target/hexagon/cpu.h | 43 | +++ b/target/hexagon/cpu.h |
43 | @@ -XXX,XX +XXX,XX @@ struct ArchCPU { | ||
44 | |||
45 | FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1) | ||
46 | |||
47 | +G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env, | ||
48 | + uint32_t exception, | ||
49 | + uintptr_t pc); | ||
50 | + | ||
51 | static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc, | ||
52 | uint64_t *cs_base, uint32_t *flags) | ||
53 | { | ||
54 | @@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc, | 44 | @@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc, |
55 | hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1); | ||
56 | } | 45 | } |
57 | *flags = hex_flags; | 46 | *flags = hex_flags; |
58 | + if (*pc & PCALIGN_MASK) { | 47 | if (*pc & PCALIGN_MASK) { |
59 | + hexagon_raise_exception_err(env, HEX_EXCP_PC_NOT_ALIGNED, 0); | 48 | - hexagon_raise_exception_err(env, HEX_EXCP_PC_NOT_ALIGNED, 0); |
60 | + } | 49 | + hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0); |
50 | } | ||
61 | } | 51 | } |
62 | 52 | ||
63 | typedef HexagonCPU ArchCPU; | ||
64 | diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h | 53 | diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h |
65 | index XXXXXXX..XXXXXXX 100644 | 54 | index XXXXXXX..XXXXXXX 100644 |
66 | --- a/target/hexagon/cpu_bits.h | 55 | --- a/target/hexagon/cpu_bits.h |
67 | +++ b/target/hexagon/cpu_bits.h | 56 | +++ b/target/hexagon/cpu_bits.h |
68 | @@ -XXX,XX +XXX,XX @@ | 57 | @@ -XXX,XX +XXX,XX @@ |
69 | 58 | #define PCALIGN 4 | |
70 | #include "qemu/bitops.h" | 59 | #define PCALIGN_MASK (PCALIGN - 1) |
71 | 60 | ||
72 | +#define PCALIGN 4 | 61 | -#define HEX_EXCP_FETCH_NO_UPAGE 0x012 |
73 | +#define PCALIGN_MASK (PCALIGN - 1) | 62 | -#define HEX_EXCP_INVALID_PACKET 0x015 |
74 | + | 63 | -#define HEX_EXCP_INVALID_OPCODE 0x015 |
75 | #define HEX_EXCP_FETCH_NO_UPAGE 0x012 | 64 | -#define HEX_EXCP_PC_NOT_ALIGNED 0x01e |
76 | #define HEX_EXCP_INVALID_PACKET 0x015 | 65 | -#define HEX_EXCP_PRIV_NO_UREAD 0x024 |
77 | #define HEX_EXCP_INVALID_OPCODE 0x015 | 66 | -#define HEX_EXCP_PRIV_NO_UWRITE 0x025 |
78 | +#define HEX_EXCP_PC_NOT_ALIGNED 0x01e | 67 | +#define HEX_EVENT_TRAP0 0x008 |
79 | #define HEX_EXCP_PRIV_NO_UREAD 0x024 | 68 | |
80 | #define HEX_EXCP_PRIV_NO_UWRITE 0x025 | 69 | -#define HEX_EXCP_TRAP0 0x172 |
81 | 70 | +#define HEX_CAUSE_TRAP0 0x172 | |
82 | diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h | 71 | +#define HEX_CAUSE_FETCH_NO_UPAGE 0x012 |
72 | +#define HEX_CAUSE_INVALID_PACKET 0x015 | ||
73 | +#define HEX_CAUSE_INVALID_OPCODE 0x015 | ||
74 | +#define HEX_CAUSE_PC_NOT_ALIGNED 0x01e | ||
75 | +#define HEX_CAUSE_PRIV_NO_UREAD 0x024 | ||
76 | +#define HEX_CAUSE_PRIV_NO_UWRITE 0x025 | ||
77 | |||
78 | #define PACKET_WORDS_MAX 4 | ||
79 | |||
80 | diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h | ||
83 | index XXXXXXX..XXXXXXX 100644 | 81 | index XXXXXXX..XXXXXXX 100644 |
84 | --- a/target/hexagon/macros.h | 82 | --- a/target/hexagon/gen_tcg.h |
85 | +++ b/target/hexagon/macros.h | 83 | +++ b/target/hexagon/gen_tcg.h |
86 | @@ -XXX,XX +XXX,XX @@ | 84 | @@ -XXX,XX +XXX,XX @@ |
87 | #include "hex_regs.h" | 85 | do { \ |
88 | #include "reg_fields.h" | 86 | uiV = uiV; \ |
89 | 87 | tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->pkt->pc); \ | |
90 | -#define PCALIGN 4 | 88 | - TCGv excp = tcg_constant_tl(HEX_EXCP_TRAP0); \ |
91 | -#define PCALIGN_MASK (PCALIGN - 1) | 89 | + TCGv excp = tcg_constant_tl(HEX_EVENT_TRAP0); \ |
92 | - | 90 | gen_helper_raise_exception(tcg_env, excp); \ |
93 | #define GET_FIELD(FIELD, REGIN) \ | 91 | } while (0) |
94 | fEXTRACTU_BITS(REGIN, reg_field_info[FIELD].width, \ | 92 | #endif |
95 | reg_field_info[FIELD].offset) | 93 | diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c |
96 | diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c | ||
97 | index XXXXXXX..XXXXXXX 100644 | 94 | index XXXXXXX..XXXXXXX 100644 |
98 | --- a/target/hexagon/op_helper.c | 95 | --- a/target/hexagon/translate.c |
99 | +++ b/target/hexagon/op_helper.c | 96 | +++ b/target/hexagon/translate.c |
100 | @@ -XXX,XX +XXX,XX @@ | 97 | @@ -XXX,XX +XXX,XX @@ static void gen_insn(DisasContext *ctx) |
101 | #define SF_MANTBITS 23 | 98 | ctx->insn->generate(ctx); |
102 | 99 | mark_store_width(ctx); | |
103 | /* Exceptions processing helpers */ | 100 | } else { |
104 | -static G_NORETURN | 101 | - gen_exception_end_tb(ctx, HEX_EXCP_INVALID_OPCODE); |
105 | -void do_raise_exception_err(CPUHexagonState *env, | 102 | + gen_exception_end_tb(ctx, HEX_CAUSE_INVALID_OPCODE); |
106 | - uint32_t exception, | 103 | } |
107 | - uintptr_t pc) | ||
108 | +G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env, | ||
109 | + uint32_t exception, | ||
110 | + uintptr_t pc) | ||
111 | { | ||
112 | CPUState *cs = env_cpu(env); | ||
113 | qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception); | ||
114 | @@ -XXX,XX +XXX,XX @@ void do_raise_exception_err(CPUHexagonState *env, | ||
115 | |||
116 | G_NORETURN void HELPER(raise_exception)(CPUHexagonState *env, uint32_t excp) | ||
117 | { | ||
118 | - do_raise_exception_err(env, excp, 0); | ||
119 | + hexagon_raise_exception_err(env, excp, 0); | ||
120 | } | 104 | } |
121 | 105 | ||
122 | void log_store32(CPUHexagonState *env, target_ulong addr, | 106 | @@ -XXX,XX +XXX,XX @@ static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx) |
123 | diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target | 107 | |
124 | index XXXXXXX..XXXXXXX 100644 | 108 | nwords = read_packet_words(env, ctx, words); |
125 | --- a/tests/tcg/hexagon/Makefile.target | 109 | if (!nwords) { |
126 | +++ b/tests/tcg/hexagon/Makefile.target | 110 | - gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET); |
127 | @@ -XXX,XX +XXX,XX @@ HEX_TESTS += scatter_gather | 111 | + gen_exception_end_tb(ctx, HEX_CAUSE_INVALID_PACKET); |
128 | HEX_TESTS += hvx_misc | 112 | return; |
129 | HEX_TESTS += hvx_histogram | 113 | } |
130 | HEX_TESTS += invalid-slots | 114 | |
131 | +HEX_TESTS += unaligned_pc | 115 | @@ -XXX,XX +XXX,XX @@ static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx) |
132 | 116 | gen_commit_packet(ctx); | |
133 | run-and-check-exception = $(call run-test,$2,$3 2>$2.stderr; \ | 117 | ctx->base.pc_next += pkt.encod_pkt_size_in_bytes; |
134 | test $$? -eq 1 && grep -q "exception $(strip $1)" $2.stderr) | 118 | } else { |
135 | @@ -XXX,XX +XXX,XX @@ overflow: overflow.c hex_test.h | 119 | - gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET); |
136 | preg_alias: preg_alias.c hex_test.h | 120 | + gen_exception_end_tb(ctx, HEX_CAUSE_INVALID_PACKET); |
137 | read_write_overlap: read_write_overlap.c hex_test.h | 121 | } |
138 | reg_mut: reg_mut.c hex_test.h | 122 | } |
139 | +unaligned_pc: unaligned_pc.c | 123 | |
140 | |||
141 | # This test has to be compiled for the -mv67t target | ||
142 | usr: usr.c hex_test.h | ||
143 | diff --git a/tests/tcg/hexagon/unaligned_pc.c b/tests/tcg/hexagon/unaligned_pc.c | ||
144 | new file mode 100644 | ||
145 | index XXXXXXX..XXXXXXX | ||
146 | --- /dev/null | ||
147 | +++ b/tests/tcg/hexagon/unaligned_pc.c | ||
148 | @@ -XXX,XX +XXX,XX @@ | ||
149 | +#include <stdio.h> | ||
150 | +#include <signal.h> | ||
151 | +#include <setjmp.h> | ||
152 | +#include <stdlib.h> | ||
153 | + | ||
154 | +/* will be changed in signal handler */ | ||
155 | +volatile sig_atomic_t completed_tests; | ||
156 | +static jmp_buf after_test; | ||
157 | +static int nr_tests; | ||
158 | + | ||
159 | +void __attribute__((naked)) test_return(void) | ||
160 | +{ | ||
161 | + asm volatile( | ||
162 | + "allocframe(#0x8)\n" | ||
163 | + "r0 = #0xffffffff\n" | ||
164 | + "framekey = r0\n" | ||
165 | + "dealloc_return\n" | ||
166 | + : | ||
167 | + : | ||
168 | + : "r0", "r29", "r30", "r31", "framekey"); | ||
169 | +} | ||
170 | + | ||
171 | +void test_endloop(void) | ||
172 | +{ | ||
173 | + asm volatile( | ||
174 | + "loop0(1f, #2)\n" | ||
175 | + "1: r0 = #0x3\n" | ||
176 | + "sa0 = r0\n" | ||
177 | + "{ nop }:endloop0\n" | ||
178 | + : | ||
179 | + : | ||
180 | + : "r0", "sa0", "lc0", "usr"); | ||
181 | +} | ||
182 | + | ||
183 | +asm( | ||
184 | + ".pushsection .text.unaligned\n" | ||
185 | + ".org 0x3\n" | ||
186 | + ".global test_multi_cof_unaligned\n" | ||
187 | + "test_multi_cof_unaligned:\n" | ||
188 | + " jumpr r31\n" | ||
189 | + ".popsection\n" | ||
190 | +); | ||
191 | + | ||
192 | +#define SYS_EXIT 94 | ||
193 | + | ||
194 | +void test_multi_cof(void) | ||
195 | +{ | ||
196 | + asm volatile( | ||
197 | + "p0 = cmp.eq(r0, r0)\n" | ||
198 | + "{\n" | ||
199 | + " if (p0) jump test_multi_cof_unaligned\n" | ||
200 | + " if (!p0) jump 1f\n" | ||
201 | + "}\n" | ||
202 | + "1:" | ||
203 | + " r0 = #1\n" | ||
204 | + " r6 = #%0\n" | ||
205 | + " trap0(#1)\n" | ||
206 | + : | ||
207 | + : "i"(SYS_EXIT) | ||
208 | + : "p0", "r0", "r6"); | ||
209 | +} | ||
210 | + | ||
211 | +void sigbus_handler(int signum) | ||
212 | +{ | ||
213 | + /* retore framekey after test_return */ | ||
214 | + asm volatile( | ||
215 | + "r0 = #0\n" | ||
216 | + "framekey = r0\n" | ||
217 | + : | ||
218 | + : | ||
219 | + : "r0", "framekey"); | ||
220 | + printf("Test %d complete\n", completed_tests); | ||
221 | + completed_tests++; | ||
222 | + siglongjmp(after_test, 1); | ||
223 | +} | ||
224 | + | ||
225 | +void test_done(void) | ||
226 | +{ | ||
227 | + int err = (completed_tests != nr_tests); | ||
228 | + puts(err ? "FAIL" : "PASS"); | ||
229 | + exit(err); | ||
230 | +} | ||
231 | + | ||
232 | +typedef void (*test_fn)(void); | ||
233 | + | ||
234 | +int main() | ||
235 | +{ | ||
236 | + test_fn tests[] = { test_return, test_endloop, test_multi_cof, test_done }; | ||
237 | + nr_tests = (sizeof(tests) / sizeof(tests[0])) - 1; | ||
238 | + | ||
239 | + struct sigaction sa = { | ||
240 | + .sa_sigaction = sigbus_handler, | ||
241 | + .sa_flags = SA_SIGINFO | ||
242 | + }; | ||
243 | + | ||
244 | + if (sigaction(SIGBUS, &sa, NULL) < 0) { | ||
245 | + perror("sigaction"); | ||
246 | + return EXIT_FAILURE; | ||
247 | + } | ||
248 | + | ||
249 | + sigsetjmp(after_test, 1); | ||
250 | + tests[completed_tests](); | ||
251 | + | ||
252 | + /* should never get here */ | ||
253 | + puts("FAIL"); | ||
254 | + return 1; | ||
255 | +} | ||
256 | -- | 124 | -- |
257 | 2.25.1 | 125 | 2.34.1 |
258 | 126 | diff view generated by jsdifflib |
1 | From: Anton Johansson <anjo@rev.ng> | 1 | From: Brian Cain <bcain@quicinc.com> |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Anton Johansson <anjo@rev.ng> | ||
4 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> | 3 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> |
5 | Reviewed-by: Brian Cain <bcain@quicinc.com> | 4 | Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> |
6 | Message-Id: <20240523125901.27797-3-anjo@rev.ng> | ||
7 | Signed-off-by: Brian Cain <bcain@quicinc.com> | ||
8 | --- | 5 | --- |
9 | target/hexagon/idef-parser/parser-helpers.h | 13 ------------- | 6 | target/hexagon/cpu_bits.h | 22 ++++++++++++++-------- |
10 | 1 file changed, 13 deletions(-) | 7 | 1 file changed, 14 insertions(+), 8 deletions(-) |
11 | 8 | ||
12 | diff --git a/target/hexagon/idef-parser/parser-helpers.h b/target/hexagon/idef-parser/parser-helpers.h | 9 | diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h |
13 | index XXXXXXX..XXXXXXX 100644 | 10 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/hexagon/idef-parser/parser-helpers.h | 11 | --- a/target/hexagon/cpu_bits.h |
15 | +++ b/target/hexagon/idef-parser/parser-helpers.h | 12 | +++ b/target/hexagon/cpu_bits.h |
16 | @@ -XXX,XX +XXX,XX @@ void commit(Context *c); | 13 | @@ -XXX,XX +XXX,XX @@ |
17 | 14 | #define PCALIGN 4 | |
18 | #define OUT(c, locp, ...) FOR_EACH((c), (locp), OUT_IMPL, __VA_ARGS__) | 15 | #define PCALIGN_MASK (PCALIGN - 1) |
19 | 16 | ||
20 | -const char *cmp_swap(Context *c, YYLTYPE *locp, const char *type); | 17 | -#define HEX_EVENT_TRAP0 0x008 |
21 | - | 18 | +enum hex_event { |
22 | /** | 19 | + HEX_EVENT_NONE = -1, |
23 | * Temporary values creation | 20 | + HEX_EVENT_TRAP0 = 0x008, |
24 | */ | 21 | +}; |
25 | @@ -XXX,XX +XXX,XX @@ HexValue gen_extract_op(Context *c, | 22 | |
26 | HexValue *index, | 23 | -#define HEX_CAUSE_TRAP0 0x172 |
27 | HexExtract *extract); | 24 | -#define HEX_CAUSE_FETCH_NO_UPAGE 0x012 |
28 | 25 | -#define HEX_CAUSE_INVALID_PACKET 0x015 | |
29 | -HexValue gen_read_reg(Context *c, YYLTYPE *locp, HexValue *reg); | 26 | -#define HEX_CAUSE_INVALID_OPCODE 0x015 |
30 | - | 27 | -#define HEX_CAUSE_PC_NOT_ALIGNED 0x01e |
31 | void gen_write_reg(Context *c, YYLTYPE *locp, HexValue *reg, HexValue *value); | 28 | -#define HEX_CAUSE_PRIV_NO_UREAD 0x024 |
32 | 29 | -#define HEX_CAUSE_PRIV_NO_UWRITE 0x025 | |
33 | void gen_assign(Context *c, | 30 | +enum hex_cause { |
34 | @@ -XXX,XX +XXX,XX @@ HexValue gen_ctpop_op(Context *c, YYLTYPE *locp, HexValue *src); | 31 | + HEX_CAUSE_NONE = -1, |
35 | 32 | + HEX_CAUSE_TRAP0 = 0x172, | |
36 | HexValue gen_rotl(Context *c, YYLTYPE *locp, HexValue *src, HexValue *n); | 33 | + HEX_CAUSE_FETCH_NO_UPAGE = 0x012, |
37 | 34 | + HEX_CAUSE_INVALID_PACKET = 0x015, | |
38 | -HexValue gen_deinterleave(Context *c, YYLTYPE *locp, HexValue *mixed); | 35 | + HEX_CAUSE_INVALID_OPCODE = 0x015, |
39 | - | 36 | + HEX_CAUSE_PC_NOT_ALIGNED = 0x01e, |
40 | -HexValue gen_interleave(Context *c, | 37 | + HEX_CAUSE_PRIV_NO_UREAD = 0x024, |
41 | - YYLTYPE *locp, | 38 | + HEX_CAUSE_PRIV_NO_UWRITE = 0x025, |
42 | - HexValue *odd, | 39 | +}; |
43 | - HexValue *even); | 40 | |
44 | - | 41 | #define PACKET_WORDS_MAX 4 |
45 | HexValue gen_carry_from_add(Context *c, | 42 | |
46 | YYLTYPE *locp, | ||
47 | HexValue *op1, | ||
48 | @@ -XXX,XX +XXX,XX @@ HexValue gen_rvalue_ternary(Context *c, YYLTYPE *locp, HexValue *cond, | ||
49 | |||
50 | const char *cond_to_str(TCGCond cond); | ||
51 | |||
52 | -void emit_header(Context *c); | ||
53 | - | ||
54 | void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg); | ||
55 | |||
56 | void emit_footer(Context *c); | ||
57 | -- | 43 | -- |
58 | 2.25.1 | 44 | 2.34.1 |
59 | 45 | diff view generated by jsdifflib |
1 | From: Anton Johansson <anjo@rev.ng> | 1 | From: Anton Johansson <anjo@rev.ng> |
---|---|---|---|
2 | 2 | ||
3 | gen_inst_init_args() is called for instructions using a predicate as an | 3 | QOL commit, all the various gen_* python scripts take a large set |
4 | rvalue. Upon first call, the list of arguments which might need | 4 | arguments where order is implicit. Using argparse we also get decent |
5 | initialization init_list is freed to indicate that they have been | 5 | error messages if a field is missing or too many are added. |
6 | processed. For instructions without an rvalue predicate, | ||
7 | gen_inst_init_args() isn't called and init_list will never be freed. | ||
8 | |||
9 | Free init_list from free_instruction() if it hasn't already been freed. | ||
10 | A comment in free_instruction is also updated. | ||
11 | 6 | ||
12 | Signed-off-by: Anton Johansson <anjo@rev.ng> | 7 | Signed-off-by: Anton Johansson <anjo@rev.ng> |
13 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> | 8 | Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com> |
14 | Reviewed-by: Brian Cain <bcain@quicinc.com> | 9 | Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> |
15 | Message-Id: <20240523125901.27797-4-anjo@rev.ng> | ||
16 | Signed-off-by: Brian Cain <bcain@quicinc.com> | ||
17 | --- | 10 | --- |
18 | target/hexagon/idef-parser/parser-helpers.c | 9 ++++++++- | 11 | target/hexagon/gen_analyze_funcs.py | 6 +++-- |
19 | 1 file changed, 8 insertions(+), 1 deletion(-) | 12 | target/hexagon/gen_decodetree.py | 19 +++++++++++--- |
13 | target/hexagon/gen_helper_funcs.py | 7 +++--- | ||
14 | target/hexagon/gen_helper_protos.py | 7 +++--- | ||
15 | target/hexagon/gen_idef_parser_funcs.py | 11 +++++++-- | ||
16 | target/hexagon/gen_op_attribs.py | 11 +++++++-- | ||
17 | target/hexagon/gen_opcodes_def.py | 11 +++++++-- | ||
18 | target/hexagon/gen_printinsn.py | 11 +++++++-- | ||
19 | target/hexagon/gen_tcg_func_table.py | 11 +++++++-- | ||
20 | target/hexagon/gen_tcg_funcs.py | 9 ++++--- | ||
21 | target/hexagon/gen_trans_funcs.py | 18 +++++++++++--- | ||
22 | target/hexagon/hex_common.py | 33 ++++++++++++------------- | ||
23 | target/hexagon/meson.build | 2 +- | ||
24 | 13 files changed, 109 insertions(+), 47 deletions(-) | ||
20 | 25 | ||
21 | diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c | 26 | diff --git a/target/hexagon/gen_analyze_funcs.py b/target/hexagon/gen_analyze_funcs.py |
27 | index XXXXXXX..XXXXXXX 100755 | ||
28 | --- a/target/hexagon/gen_analyze_funcs.py | ||
29 | +++ b/target/hexagon/gen_analyze_funcs.py | ||
30 | @@ -XXX,XX +XXX,XX @@ def gen_analyze_func(f, tag, regs, imms): | ||
31 | |||
32 | |||
33 | def main(): | ||
34 | - hex_common.read_common_files() | ||
35 | + args = hex_common.parse_common_args( | ||
36 | + "Emit functions analyzing register accesses" | ||
37 | + ) | ||
38 | tagregs = hex_common.get_tagregs() | ||
39 | tagimms = hex_common.get_tagimms() | ||
40 | |||
41 | - with open(sys.argv[-1], "w") as f: | ||
42 | + with open(args.out, "w") as f: | ||
43 | f.write("#ifndef HEXAGON_ANALYZE_FUNCS_C_INC\n") | ||
44 | f.write("#define HEXAGON_ANALYZE_FUNCS_C_INC\n\n") | ||
45 | |||
46 | diff --git a/target/hexagon/gen_decodetree.py b/target/hexagon/gen_decodetree.py | ||
47 | index XXXXXXX..XXXXXXX 100755 | ||
48 | --- a/target/hexagon/gen_decodetree.py | ||
49 | +++ b/target/hexagon/gen_decodetree.py | ||
50 | @@ -XXX,XX +XXX,XX @@ | ||
51 | import textwrap | ||
52 | import iset | ||
53 | import hex_common | ||
54 | +import argparse | ||
55 | |||
56 | encs = { | ||
57 | tag: "".join(reversed(iset.iset[tag]["enc"].replace(" ", ""))) | ||
58 | @@ -XXX,XX +XXX,XX @@ def gen_decodetree_file(f, class_to_decode): | ||
59 | f.write(f"{tag}\t{enc_str} @{tag}\n") | ||
60 | |||
61 | |||
62 | +def main(): | ||
63 | + parser = argparse.ArgumentParser( | ||
64 | + description="Emit opaque macro calls with instruction semantics" | ||
65 | + ) | ||
66 | + parser.add_argument("semantics", help="semantics file") | ||
67 | + parser.add_argument("class_to_decode", help="instruction class to decode") | ||
68 | + parser.add_argument("out", help="output file") | ||
69 | + args = parser.parse_args() | ||
70 | + | ||
71 | + hex_common.read_semantics_file(args.semantics) | ||
72 | + with open(args.out, "w") as f: | ||
73 | + gen_decodetree_file(f, args.class_to_decode) | ||
74 | + | ||
75 | if __name__ == "__main__": | ||
76 | - hex_common.read_semantics_file(sys.argv[1]) | ||
77 | - class_to_decode = sys.argv[2] | ||
78 | - with open(sys.argv[3], "w") as f: | ||
79 | - gen_decodetree_file(f, class_to_decode) | ||
80 | + main() | ||
81 | diff --git a/target/hexagon/gen_helper_funcs.py b/target/hexagon/gen_helper_funcs.py | ||
82 | index XXXXXXX..XXXXXXX 100755 | ||
83 | --- a/target/hexagon/gen_helper_funcs.py | ||
84 | +++ b/target/hexagon/gen_helper_funcs.py | ||
85 | @@ -XXX,XX +XXX,XX @@ def gen_helper_function(f, tag, tagregs, tagimms): | ||
86 | |||
87 | |||
88 | def main(): | ||
89 | - hex_common.read_common_files() | ||
90 | + args = hex_common.parse_common_args( | ||
91 | + "Emit helper function definitions for each instruction" | ||
92 | + ) | ||
93 | tagregs = hex_common.get_tagregs() | ||
94 | tagimms = hex_common.get_tagimms() | ||
95 | |||
96 | - output_file = sys.argv[-1] | ||
97 | - with open(output_file, "w") as f: | ||
98 | + with open(args.out, "w") as f: | ||
99 | for tag in hex_common.tags: | ||
100 | ## Skip the priv instructions | ||
101 | if "A_PRIV" in hex_common.attribdict[tag]: | ||
102 | diff --git a/target/hexagon/gen_helper_protos.py b/target/hexagon/gen_helper_protos.py | ||
103 | index XXXXXXX..XXXXXXX 100755 | ||
104 | --- a/target/hexagon/gen_helper_protos.py | ||
105 | +++ b/target/hexagon/gen_helper_protos.py | ||
106 | @@ -XXX,XX +XXX,XX @@ def gen_helper_prototype(f, tag, tagregs, tagimms): | ||
107 | |||
108 | |||
109 | def main(): | ||
110 | - hex_common.read_common_files() | ||
111 | + args = hex_common.parse_common_args( | ||
112 | + "Emit helper function prototypes for each instruction" | ||
113 | + ) | ||
114 | tagregs = hex_common.get_tagregs() | ||
115 | tagimms = hex_common.get_tagimms() | ||
116 | |||
117 | - output_file = sys.argv[-1] | ||
118 | - with open(output_file, "w") as f: | ||
119 | + with open(args.out, "w") as f: | ||
120 | for tag in hex_common.tags: | ||
121 | ## Skip the priv instructions | ||
122 | if "A_PRIV" in hex_common.attribdict[tag]: | ||
123 | diff --git a/target/hexagon/gen_idef_parser_funcs.py b/target/hexagon/gen_idef_parser_funcs.py | ||
22 | index XXXXXXX..XXXXXXX 100644 | 124 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/hexagon/idef-parser/parser-helpers.c | 125 | --- a/target/hexagon/gen_idef_parser_funcs.py |
24 | +++ b/target/hexagon/idef-parser/parser-helpers.c | 126 | +++ b/target/hexagon/gen_idef_parser_funcs.py |
25 | @@ -XXX,XX +XXX,XX @@ void free_instruction(Context *c) | 127 | @@ -XXX,XX +XXX,XX @@ |
26 | g_string_free(g_array_index(c->inst.strings, GString*, i), TRUE); | 128 | import sys |
27 | } | 129 | import re |
28 | g_array_free(c->inst.strings, TRUE); | 130 | import string |
29 | + /* | 131 | +import argparse |
30 | + * Free list of arguments that might need initialization, if they haven't | 132 | from io import StringIO |
31 | + * already been freed. | 133 | |
32 | + */ | 134 | import hex_common |
33 | + if (c->inst.init_list) { | 135 | @@ -XXX,XX +XXX,XX @@ |
34 | + g_array_free(c->inst.init_list, TRUE); | 136 | ## them are inputs ("in" prefix), while some others are outputs. |
35 | + } | 137 | ## |
36 | /* Free INAME token value */ | 138 | def main(): |
37 | g_string_free(c->inst.name, TRUE); | 139 | - hex_common.read_semantics_file(sys.argv[1]) |
38 | - /* Free variables and registers */ | 140 | + parser = argparse.ArgumentParser( |
39 | + /* Free declared TCGv variables */ | 141 | + "Emit instruction implementations that can be fed to idef-parser" |
40 | g_array_free(c->inst.allocated, TRUE); | 142 | + ) |
41 | /* Initialize instruction-specific portion of the context */ | 143 | + parser.add_argument("semantics", help="semantics file") |
42 | memset(&(c->inst), 0, sizeof(Inst)); | 144 | + parser.add_argument("out", help="output file") |
145 | + args = parser.parse_args() | ||
146 | + hex_common.read_semantics_file(args.semantics) | ||
147 | hex_common.calculate_attribs() | ||
148 | hex_common.init_registers() | ||
149 | tagregs = hex_common.get_tagregs() | ||
150 | tagimms = hex_common.get_tagimms() | ||
151 | |||
152 | - with open(sys.argv[-1], "w") as f: | ||
153 | + with open(args.out, "w") as f: | ||
154 | f.write('#include "macros.h.inc"\n\n') | ||
155 | |||
156 | for tag in hex_common.tags: | ||
157 | diff --git a/target/hexagon/gen_op_attribs.py b/target/hexagon/gen_op_attribs.py | ||
158 | index XXXXXXX..XXXXXXX 100755 | ||
159 | --- a/target/hexagon/gen_op_attribs.py | ||
160 | +++ b/target/hexagon/gen_op_attribs.py | ||
161 | @@ -XXX,XX +XXX,XX @@ | ||
162 | import re | ||
163 | import string | ||
164 | import hex_common | ||
165 | +import argparse | ||
166 | |||
167 | |||
168 | def main(): | ||
169 | - hex_common.read_semantics_file(sys.argv[1]) | ||
170 | + parser = argparse.ArgumentParser( | ||
171 | + "Emit opaque macro calls containing instruction attributes" | ||
172 | + ) | ||
173 | + parser.add_argument("semantics", help="semantics file") | ||
174 | + parser.add_argument("out", help="output file") | ||
175 | + args = parser.parse_args() | ||
176 | + hex_common.read_semantics_file(args.semantics) | ||
177 | hex_common.calculate_attribs() | ||
178 | |||
179 | ## | ||
180 | ## Generate all the attributes associated with each instruction | ||
181 | ## | ||
182 | - with open(sys.argv[-1], "w") as f: | ||
183 | + with open(args.out, "w") as f: | ||
184 | for tag in hex_common.tags: | ||
185 | f.write( | ||
186 | f"OP_ATTRIB({tag},ATTRIBS(" | ||
187 | diff --git a/target/hexagon/gen_opcodes_def.py b/target/hexagon/gen_opcodes_def.py | ||
188 | index XXXXXXX..XXXXXXX 100755 | ||
189 | --- a/target/hexagon/gen_opcodes_def.py | ||
190 | +++ b/target/hexagon/gen_opcodes_def.py | ||
191 | @@ -XXX,XX +XXX,XX @@ | ||
192 | import re | ||
193 | import string | ||
194 | import hex_common | ||
195 | +import argparse | ||
196 | |||
197 | |||
198 | def main(): | ||
199 | - hex_common.read_semantics_file(sys.argv[1]) | ||
200 | + parser = argparse.ArgumentParser( | ||
201 | + description="Emit opaque macro calls with instruction names" | ||
202 | + ) | ||
203 | + parser.add_argument("semantics", help="semantics file") | ||
204 | + parser.add_argument("out", help="output file") | ||
205 | + args = parser.parse_args() | ||
206 | + hex_common.read_semantics_file(args.semantics) | ||
207 | |||
208 | ## | ||
209 | ## Generate a list of all the opcodes | ||
210 | ## | ||
211 | - with open(sys.argv[-1], "w") as f: | ||
212 | + with open(args.out, "w") as f: | ||
213 | for tag in hex_common.tags: | ||
214 | f.write(f"OPCODE({tag}),\n") | ||
215 | |||
216 | diff --git a/target/hexagon/gen_printinsn.py b/target/hexagon/gen_printinsn.py | ||
217 | index XXXXXXX..XXXXXXX 100755 | ||
218 | --- a/target/hexagon/gen_printinsn.py | ||
219 | +++ b/target/hexagon/gen_printinsn.py | ||
220 | @@ -XXX,XX +XXX,XX @@ | ||
221 | import re | ||
222 | import string | ||
223 | import hex_common | ||
224 | +import argparse | ||
225 | |||
226 | |||
227 | ## | ||
228 | @@ -XXX,XX +XXX,XX @@ def spacify(s): | ||
229 | |||
230 | |||
231 | def main(): | ||
232 | - hex_common.read_semantics_file(sys.argv[1]) | ||
233 | + parser = argparse.ArgumentParser( | ||
234 | + "Emit opaque macro calls with information for printing string representations of instrucions" | ||
235 | + ) | ||
236 | + parser.add_argument("semantics", help="semantics file") | ||
237 | + parser.add_argument("out", help="output file") | ||
238 | + args = parser.parse_args() | ||
239 | + hex_common.read_semantics_file(args.semantics) | ||
240 | |||
241 | immext_casere = re.compile(r"IMMEXT\(([A-Za-z])") | ||
242 | |||
243 | - with open(sys.argv[-1], "w") as f: | ||
244 | + with open(args.out, "w") as f: | ||
245 | for tag in hex_common.tags: | ||
246 | if not hex_common.behdict[tag]: | ||
247 | continue | ||
248 | diff --git a/target/hexagon/gen_tcg_func_table.py b/target/hexagon/gen_tcg_func_table.py | ||
249 | index XXXXXXX..XXXXXXX 100755 | ||
250 | --- a/target/hexagon/gen_tcg_func_table.py | ||
251 | +++ b/target/hexagon/gen_tcg_func_table.py | ||
252 | @@ -XXX,XX +XXX,XX @@ | ||
253 | import re | ||
254 | import string | ||
255 | import hex_common | ||
256 | +import argparse | ||
257 | |||
258 | |||
259 | def main(): | ||
260 | - hex_common.read_semantics_file(sys.argv[1]) | ||
261 | + parser = argparse.ArgumentParser( | ||
262 | + "Emit opaque macro calls with instruction semantics" | ||
263 | + ) | ||
264 | + parser.add_argument("semantics", help="semantics file") | ||
265 | + parser.add_argument("out", help="output file") | ||
266 | + args = parser.parse_args() | ||
267 | + hex_common.read_semantics_file(args.semantics) | ||
268 | hex_common.calculate_attribs() | ||
269 | tagregs = hex_common.get_tagregs() | ||
270 | tagimms = hex_common.get_tagimms() | ||
271 | |||
272 | - with open(sys.argv[-1], "w") as f: | ||
273 | + with open(args.out, "w") as f: | ||
274 | f.write("#ifndef HEXAGON_FUNC_TABLE_H\n") | ||
275 | f.write("#define HEXAGON_FUNC_TABLE_H\n\n") | ||
276 | |||
277 | diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py | ||
278 | index XXXXXXX..XXXXXXX 100755 | ||
279 | --- a/target/hexagon/gen_tcg_funcs.py | ||
280 | +++ b/target/hexagon/gen_tcg_funcs.py | ||
281 | @@ -XXX,XX +XXX,XX @@ def gen_def_tcg_func(f, tag, tagregs, tagimms): | ||
282 | |||
283 | |||
284 | def main(): | ||
285 | - is_idef_parser_enabled = hex_common.read_common_files() | ||
286 | + args = hex_common.parse_common_args( | ||
287 | + "Emit functions calling generated code implementing instruction semantics (helpers, idef-parser)" | ||
288 | + ) | ||
289 | tagregs = hex_common.get_tagregs() | ||
290 | tagimms = hex_common.get_tagimms() | ||
291 | |||
292 | - output_file = sys.argv[-1] | ||
293 | - with open(output_file, "w") as f: | ||
294 | + with open(args.out, "w") as f: | ||
295 | f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") | ||
296 | f.write("#define HEXAGON_TCG_FUNCS_H\n\n") | ||
297 | - if is_idef_parser_enabled: | ||
298 | + if args.idef_parser: | ||
299 | f.write('#include "idef-generated-emitter.h.inc"\n\n') | ||
300 | |||
301 | for tag in hex_common.tags: | ||
302 | diff --git a/target/hexagon/gen_trans_funcs.py b/target/hexagon/gen_trans_funcs.py | ||
303 | index XXXXXXX..XXXXXXX 100755 | ||
304 | --- a/target/hexagon/gen_trans_funcs.py | ||
305 | +++ b/target/hexagon/gen_trans_funcs.py | ||
306 | @@ -XXX,XX +XXX,XX @@ | ||
307 | import textwrap | ||
308 | import iset | ||
309 | import hex_common | ||
310 | +import argparse | ||
311 | |||
312 | encs = { | ||
313 | tag: "".join(reversed(iset.iset[tag]["enc"].replace(" ", ""))) | ||
314 | @@ -XXX,XX +XXX,XX @@ def gen_trans_funcs(f): | ||
315 | """)) | ||
316 | |||
317 | |||
318 | -if __name__ == "__main__": | ||
319 | - hex_common.read_semantics_file(sys.argv[1]) | ||
320 | +def main(): | ||
321 | + parser = argparse.ArgumentParser( | ||
322 | + description="Emit trans_*() functions to be called by " \ | ||
323 | + "instruction decoder" | ||
324 | + ) | ||
325 | + parser.add_argument("semantics", help="semantics file") | ||
326 | + parser.add_argument("out", help="output file") | ||
327 | + args = parser.parse_args() | ||
328 | + hex_common.read_semantics_file(args.semantics) | ||
329 | hex_common.init_registers() | ||
330 | - with open(sys.argv[2], "w") as f: | ||
331 | + with open(args.out, "w") as f: | ||
332 | gen_trans_funcs(f) | ||
333 | + | ||
334 | + | ||
335 | +if __name__ == "__main__": | ||
336 | + main() | ||
337 | diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py | ||
338 | index XXXXXXX..XXXXXXX 100755 | ||
339 | --- a/target/hexagon/hex_common.py | ||
340 | +++ b/target/hexagon/hex_common.py | ||
341 | @@ -XXX,XX +XXX,XX @@ | ||
342 | import re | ||
343 | import string | ||
344 | import textwrap | ||
345 | +import argparse | ||
346 | |||
347 | behdict = {} # tag ->behavior | ||
348 | semdict = {} # tag -> semantics | ||
349 | @@ -XXX,XX +XXX,XX @@ def helper_args(tag, regs, imms): | ||
350 | return args | ||
351 | |||
352 | |||
353 | -def read_common_files(): | ||
354 | - read_semantics_file(sys.argv[1]) | ||
355 | - read_overrides_file(sys.argv[2]) | ||
356 | - read_overrides_file(sys.argv[3]) | ||
357 | - ## Whether or not idef-parser is enabled is | ||
358 | - ## determined by the number of arguments to | ||
359 | - ## this script: | ||
360 | - ## | ||
361 | - ## 4 args. -> not enabled, | ||
362 | - ## 5 args. -> idef-parser enabled. | ||
363 | - ## | ||
364 | - ## The 5:th arg. then holds a list of the successfully | ||
365 | - ## parsed instructions. | ||
366 | - is_idef_parser_enabled = len(sys.argv) > 5 | ||
367 | - if is_idef_parser_enabled: | ||
368 | - read_idef_parser_enabled_file(sys.argv[4]) | ||
369 | +def parse_common_args(desc): | ||
370 | + parser = argparse.ArgumentParser(desc) | ||
371 | + parser.add_argument("semantics", help="semantics file") | ||
372 | + parser.add_argument("overrides", help="overrides file") | ||
373 | + parser.add_argument("overrides_vec", help="vector overrides file") | ||
374 | + parser.add_argument("out", help="output file") | ||
375 | + parser.add_argument("--idef-parser", | ||
376 | + help="file of instructions translated by idef-parser") | ||
377 | + args = parser.parse_args() | ||
378 | + read_semantics_file(args.semantics) | ||
379 | + read_overrides_file(args.overrides) | ||
380 | + read_overrides_file(args.overrides_vec) | ||
381 | + if args.idef_parser: | ||
382 | + read_idef_parser_enabled_file(args.idef_parser) | ||
383 | calculate_attribs() | ||
384 | init_registers() | ||
385 | - return is_idef_parser_enabled | ||
386 | + return args | ||
387 | diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build | ||
388 | index XXXXXXX..XXXXXXX 100644 | ||
389 | --- a/target/hexagon/meson.build | ||
390 | +++ b/target/hexagon/meson.build | ||
391 | @@ -XXX,XX +XXX,XX @@ if idef_parser_enabled and 'hexagon-linux-user' in target_dirs | ||
392 | # Setup input and dependencies for the next step, this depends on whether or | ||
393 | # not idef-parser is enabled | ||
394 | helper_dep = [semantics_generated, idef_generated_tcg_c, idef_generated_tcg] | ||
395 | - helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h, idef_generated_list] | ||
396 | + helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h, '--idef-parser', idef_generated_list] | ||
397 | else | ||
398 | # Setup input and dependencies for the next step, this depends on whether or | ||
399 | # not idef-parser is enabled | ||
43 | -- | 400 | -- |
44 | 2.25.1 | 401 | 2.34.1 |
45 | 402 | diff view generated by jsdifflib |
1 | From: Anton Johansson <anjo@rev.ng> | 1 | From: Anton Johansson <anjo@rev.ng> |
---|---|---|---|
2 | 2 | ||
3 | Before switching to GArray/g_string_printf we used fixed size arrays for | 3 | Adds restrict qualifier to HVX pointer arguments. This will allow the |
4 | output buffers and instructions arguments among other things. | 4 | compiler to produce better optimized code, as input vectors are now |
5 | 5 | assumed not to alias, and no runtime aliasing checks will be required. | |
6 | Macros defining the sizes of these buffers were left behind, remove | ||
7 | them. | ||
8 | 6 | ||
9 | Signed-off-by: Anton Johansson <anjo@rev.ng> | 7 | Signed-off-by: Anton Johansson <anjo@rev.ng> |
10 | Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> | 8 | Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com> |
11 | Reviewed-by: Brian Cain <bcain@quicinc.com> | 9 | Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> |
12 | Message-Id: <20240523125901.27797-2-anjo@rev.ng> | ||
13 | Signed-off-by: Brian Cain <bcain@quicinc.com> | ||
14 | --- | 10 | --- |
15 | target/hexagon/idef-parser/idef-parser.h | 10 ---------- | 11 | target/hexagon/mmvec/macros.h | 36 +++++++++++++++++------------------ |
16 | 1 file changed, 10 deletions(-) | 12 | 1 file changed, 18 insertions(+), 18 deletions(-) |
17 | 13 | ||
18 | diff --git a/target/hexagon/idef-parser/idef-parser.h b/target/hexagon/idef-parser/idef-parser.h | 14 | diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h |
19 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/hexagon/idef-parser/idef-parser.h | 16 | --- a/target/hexagon/mmvec/macros.h |
21 | +++ b/target/hexagon/idef-parser/idef-parser.h | 17 | +++ b/target/hexagon/mmvec/macros.h |
22 | @@ -XXX,XX +XXX,XX @@ | 18 | @@ -XXX,XX +XXX,XX @@ |
23 | #include <stdbool.h> | 19 | #include "mmvec/system_ext_mmvec.h" |
24 | #include <glib.h> | 20 | |
25 | 21 | #ifndef QEMU_GENERATE | |
26 | -#define TCGV_NAME_SIZE 7 | 22 | -#define VdV (*(MMVector *)(VdV_void)) |
27 | -#define MAX_WRITTEN_REGS 32 | 23 | -#define VsV (*(MMVector *)(VsV_void)) |
28 | -#define OFFSET_STR_LEN 32 | 24 | -#define VuV (*(MMVector *)(VuV_void)) |
29 | -#define ALLOC_LIST_LEN 32 | 25 | -#define VvV (*(MMVector *)(VvV_void)) |
30 | -#define ALLOC_NAME_SIZE 32 | 26 | -#define VwV (*(MMVector *)(VwV_void)) |
31 | -#define INIT_LIST_LEN 32 | 27 | -#define VxV (*(MMVector *)(VxV_void)) |
32 | -#define OUT_BUF_LEN (1024 * 1024) | 28 | -#define VyV (*(MMVector *)(VyV_void)) |
33 | -#define SIGNATURE_BUF_LEN (128 * 1024) | 29 | +#define VdV (*(MMVector *restrict)(VdV_void)) |
34 | -#define HEADER_BUF_LEN (128 * 1024) | 30 | +#define VsV (*(MMVector *restrict)(VsV_void)) |
35 | - | 31 | +#define VuV (*(MMVector *restrict)(VuV_void)) |
36 | /* Variadic macros to wrap the buffer printing functions */ | 32 | +#define VvV (*(MMVector *restrict)(VvV_void)) |
37 | #define EMIT(c, ...) \ | 33 | +#define VwV (*(MMVector *restrict)(VwV_void)) |
38 | do { \ | 34 | +#define VxV (*(MMVector *restrict)(VxV_void)) |
35 | +#define VyV (*(MMVector *restrict)(VyV_void)) | ||
36 | |||
37 | -#define VddV (*(MMVectorPair *)(VddV_void)) | ||
38 | -#define VuuV (*(MMVectorPair *)(VuuV_void)) | ||
39 | -#define VvvV (*(MMVectorPair *)(VvvV_void)) | ||
40 | -#define VxxV (*(MMVectorPair *)(VxxV_void)) | ||
41 | +#define VddV (*(MMVectorPair *restrict)(VddV_void)) | ||
42 | +#define VuuV (*(MMVectorPair *restrict)(VuuV_void)) | ||
43 | +#define VvvV (*(MMVectorPair *restrict)(VvvV_void)) | ||
44 | +#define VxxV (*(MMVectorPair *restrict)(VxxV_void)) | ||
45 | |||
46 | -#define QeV (*(MMQReg *)(QeV_void)) | ||
47 | -#define QdV (*(MMQReg *)(QdV_void)) | ||
48 | -#define QsV (*(MMQReg *)(QsV_void)) | ||
49 | -#define QtV (*(MMQReg *)(QtV_void)) | ||
50 | -#define QuV (*(MMQReg *)(QuV_void)) | ||
51 | -#define QvV (*(MMQReg *)(QvV_void)) | ||
52 | -#define QxV (*(MMQReg *)(QxV_void)) | ||
53 | +#define QeV (*(MMQReg *restrict)(QeV_void)) | ||
54 | +#define QdV (*(MMQReg *restrict)(QdV_void)) | ||
55 | +#define QsV (*(MMQReg *restrict)(QsV_void)) | ||
56 | +#define QtV (*(MMQReg *restrict)(QtV_void)) | ||
57 | +#define QuV (*(MMQReg *restrict)(QuV_void)) | ||
58 | +#define QvV (*(MMQReg *restrict)(QvV_void)) | ||
59 | +#define QxV (*(MMQReg *restrict)(QxV_void)) | ||
60 | #endif | ||
61 | |||
62 | #define LOG_VTCM_BYTE(VA, MASK, VAL, IDX) \ | ||
39 | -- | 63 | -- |
40 | 2.25.1 | 64 | 2.34.1 |
41 | 65 | diff view generated by jsdifflib |