qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 04/21] Hexagon (target/hexagon) Add overrides for allocframe/deal


From: Taylor Simpson
Subject: [PATCH 04/21] Hexagon (target/hexagon) Add overrides for allocframe/deallocframe
Date: Tue, 25 Apr 2023 17:41:30 -0700

These instructions have implicit writes to registers, so we don't
want them to be helpers when idef-parser is off.

Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
---
 target/hexagon/gen_tcg.h | 32 +++++++++++++++++++++++++++++
 target/hexagon/genptr.c  | 44 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 5774af4a59..7c5cb93297 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -500,6 +500,38 @@
 #define fGEN_TCG_Y2_icinva(SHORTCODE) \
     do { RsV = RsV; } while (0)
 
+/*
+ * allocframe(#uiV)
+ *     RxV == r29
+ */
+#define fGEN_TCG_S2_allocframe(SHORTCODE) \
+    gen_allocframe(ctx, RxV, uiV)
+
+/* sub-instruction version (no RxV, so handle it manually) */
+#define fGEN_TCG_SS2_allocframe(SHORTCODE) \
+    do { \
+        TCGv r29 = tcg_temp_new(); \
+        tcg_gen_mov_tl(r29, hex_gpr[HEX_REG_SP]); \
+        gen_allocframe(ctx, r29, uiV); \
+        gen_log_reg_write(ctx, HEX_REG_SP, r29); \
+    } while (0)
+
+/*
+ * Rdd32 = deallocframe(Rs32):raw
+ *     RddV == r31:30
+ *     RsV  == r30
+ */
+#define fGEN_TCG_L2_deallocframe(SHORTCODE) \
+    gen_deallocframe(ctx, RddV, RsV)
+
+/* sub-instruction version (no RddV/RsV, so handle it manually) */
+#define fGEN_TCG_SL2_deallocframe(SHORTCODE) \
+    do { \
+        TCGv_i64 r31_30 = tcg_temp_new_i64(); \
+        gen_deallocframe(ctx, r31_30, hex_gpr[HEX_REG_FP]); \
+        gen_log_reg_write_pair(ctx, HEX_REG_FP, r31_30); \
+    } while (0)
+
 /*
  * dealloc_return
  * Assembler mapped to
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 4c34da8407..570770b7d5 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -709,6 +709,18 @@ static void gen_cond_callr(DisasContext *ctx,
     gen_set_label(skip);
 }
 
+#ifndef CONFIG_HEXAGON_IDEF_PARSER
+/* frame = ((LR << 32) | FP) ^ (FRAMEKEY << 32)) */
+static void gen_frame_scramble(TCGv_i64 result)
+{
+    TCGv_i64 framekey = tcg_temp_new_i64();
+    tcg_gen_extu_i32_i64(framekey, hex_gpr[HEX_REG_FRAMEKEY]);
+    tcg_gen_shli_i64(framekey, framekey, 32);
+    tcg_gen_concat_i32_i64(result, hex_gpr[HEX_REG_FP], hex_gpr[HEX_REG_LR]);
+    tcg_gen_xor_i64(result, result, framekey);
+}
+#endif
+
 /* frame ^= (int64_t)FRAMEKEY << 32 */
 static void gen_frame_unscramble(TCGv_i64 frame)
 {
@@ -725,6 +737,38 @@ static void gen_load_frame(DisasContext *ctx, TCGv_i64 
frame, TCGv EA)
     tcg_gen_qemu_ld64(frame, EA, ctx->mem_idx);
 }
 
+#ifndef CONFIG_HEXAGON_IDEF_PARSER
+/* Stack overflow check */
+static void gen_framecheck(TCGv EA, int framesize)
+{
+    /* Not modelled in linux-user mode */
+    /* Placeholder for system mode */
+}
+
+static void gen_allocframe(DisasContext *ctx, TCGv r29, int framesize)
+{
+    TCGv r30 = tcg_temp_new();
+    TCGv_i64 frame = tcg_temp_new_i64();
+    tcg_gen_addi_tl(r30, r29, -8);
+    gen_frame_scramble(frame);
+    gen_store8(cpu_env, r30, frame, ctx->insn->slot);
+    gen_log_reg_write(ctx, HEX_REG_FP, r30);
+    gen_framecheck(r30, framesize);
+    tcg_gen_subi_tl(r29, r30, framesize);
+}
+
+static void gen_deallocframe(DisasContext *ctx, TCGv_i64 r31_30, TCGv r30)
+{
+    TCGv r29 = tcg_temp_new();
+    TCGv_i64 frame = tcg_temp_new_i64();
+    gen_load_frame(ctx, frame, r30);
+    gen_frame_unscramble(frame);
+    tcg_gen_mov_i64(r31_30, frame);
+    tcg_gen_addi_tl(r29, r30, 8);
+    gen_log_reg_write(ctx, HEX_REG_SP, r29);
+}
+#endif
+
 static void gen_return(DisasContext *ctx, TCGv_i64 dst, TCGv src)
 {
     /*
-- 
2.25.1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]