diff mbox series

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

Message ID 20230426004130.1318973-1-tsimpson@quicinc.com (mailing list archive)
State New, archived
Headers show
Series Hexagon (target/hexagon) short-circuit and move to DisasContext | expand

Commit Message

Taylor Simpson April 26, 2023, 12:41 a.m. UTC
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(+)

Comments

Richard Henderson April 26, 2023, 5:39 p.m. UTC | #1
On 4/26/23 01:41, Taylor Simpson wrote:
> +#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

Better as

     tmp = tcg_temp_new_i32();
     tcg_gen_xor_i32(tmp, hex_gpr[HEX_REG_LR], hex_gpr[HEX_REG_FRAMEKEY]);
     tcg_gen_concat_i32_i64(result, hex_gpr[HEX_REG_FRAMEKEY], tmp);

> +#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 */
> +}

g_assert_not_reached();

> +    TCGv_i64 frame = tcg_temp_new_i64();
> +    tcg_gen_addi_tl(r30, r29, -8);
> +    gen_frame_scramble(frame);

Perhaps better as

     TCGv_i64 frame = gen_frame_scramble();

with the allocation inside the subroutine.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
diff mbox series

Patch

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)
 {
     /*