From: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
target/hexagon/cpu.h | 1 +
target/hexagon/cpu.c | 19 +++++++++++++++++++
target/hexagon/op_helper.c | 16 ++++++++++++++--
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 1048e767e6d..09d5cac4fe5 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -219,6 +219,7 @@ G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
* not stopped.
*/
bool hexagon_thread_is_enabled(CPUHexagonState *thread_env);
+uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg);
void hexagon_cpu_soft_reset(CPUHexagonState *env);
#endif
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index a48d6178e06..bd3eec0d525 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -765,6 +765,25 @@ static void hexagon_cpu_class_init(ObjectClass *c, const void *data)
#endif
}
+#ifndef CONFIG_USER_ONLY
+uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg)
+{
+ if (reg <= HEX_GREG_G3) {
+ return env->greg[reg];
+ }
+ switch (reg) {
+ case HEX_GREG_GPCYCLELO:
+ return hexagon_get_sys_pcycle_count_low(env);
+ case HEX_GREG_GPCYCLEHI:
+ return hexagon_get_sys_pcycle_count_high(env);
+ default:
+ qemu_log_mask(LOG_UNIMP, "reading greg %" PRId32
+ " not yet supported.\n", reg);
+ return 0;
+ }
+}
+#endif
+
#define DEFINE_CPU(type_name, initfn) \
{ \
.name = type_name, \
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index c4ad6015689..a1c0c9910f2 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1877,13 +1877,25 @@ uint64_t HELPER(sreg_read_pair)(CPUHexagonState *env, uint32_t reg)
}
uint32_t HELPER(greg_read)(CPUHexagonState *env, uint32_t reg)
+
{
- g_assert_not_reached();
+ return hexagon_greg_read(env, reg);
}
uint64_t HELPER(greg_read_pair)(CPUHexagonState *env, uint32_t reg)
+
{
- g_assert_not_reached();
+ if (reg == HEX_GREG_G0 || reg == HEX_GREG_G2) {
+ return (uint64_t)(env->greg[reg]) |
+ (((uint64_t)(env->greg[reg + 1])) << 32);
+ }
+ switch (reg) {
+ case HEX_GREG_GPCYCLELO:
+ return hexagon_get_sys_pcycle_count(env);
+ default:
+ return (uint64_t)hexagon_greg_read(env, reg) |
+ ((uint64_t)(hexagon_greg_read(env, reg + 1)) << 32);
+ }
}
/*
--
2.34.1