Patchwork [v2,4/4] tcg-arm: Implement tcg_register_jit

login
register
mail settings
Submitter Richard Henderson
Date June 5, 2013, 5:29 p.m.
Message ID <1370453368-21214-5-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/249155/
State New
Headers show

Comments

Richard Henderson - June 5, 2013, 5:29 p.m.
Allows unwinding past the code_gen_buffer.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/arm/tcg-target.c | 76 +++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 67 insertions(+), 9 deletions(-)
Andreas Färber - June 17, 2013, 10:12 p.m.
Am 05.06.2013 19:29, schrieb Richard Henderson:
> Allows unwinding past the code_gen_buffer.
> 
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  tcg/arm/tcg-target.c | 76 +++++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 67 insertions(+), 9 deletions(-)

How does the target learn about availability of tcg_register_jit()?
I don't see it used in the patch or in stubs/ and the arm build succeeds.

Andreas
Peter Maydell - June 17, 2013, 10:16 p.m.
On 17 June 2013 23:12, Andreas Färber <afaerber@suse.de> wrote:
> Am 05.06.2013 19:29, schrieb Richard Henderson:
>> Allows unwinding past the code_gen_buffer.
>>
>> Signed-off-by: Richard Henderson <rth@twiddle.net>
>> ---
>>  tcg/arm/tcg-target.c | 76 +++++++++++++++++++++++++++++++++++++++++++++-------
>>  1 file changed, 67 insertions(+), 9 deletions(-)
>
> How does the target learn about availability of tcg_register_jit()?

(You mean "how does the core TCG code learn about..." -- this
is an optional facility the tcg target facility can provide
to the core).

> I don't see it used in the patch or in stubs/ and the arm build succeeds.

It's gated on whether the tcg backend defines ELF_HOST_MACHINE:
see the comment at the start of the #ifdef ELF_HOST_MACHINE
section in tcg/tcg.c.

thanks
 -- PMM
Andreas Färber - June 17, 2013, 10:30 p.m.
Am 18.06.2013 00:16, schrieb Peter Maydell:
> On 17 June 2013 23:12, Andreas Färber <afaerber@suse.de> wrote:
>> Am 05.06.2013 19:29, schrieb Richard Henderson:
>>> Allows unwinding past the code_gen_buffer.
>>>
>>> Signed-off-by: Richard Henderson <rth@twiddle.net>
>>> ---
>>>  tcg/arm/tcg-target.c | 76 +++++++++++++++++++++++++++++++++++++++++++++-------
>>>  1 file changed, 67 insertions(+), 9 deletions(-)
>>
>> How does the target learn about availability of tcg_register_jit()?
> 
> (You mean "how does the core TCG code learn about..." -- this
> is an optional facility the tcg target facility can provide
> to the core).
> 
>> I don't see it used in the patch or in stubs/ and the arm build succeeds.
> 
> It's gated on whether the tcg backend defines ELF_HOST_MACHINE:
> see the comment at the start of the #ifdef ELF_HOST_MACHINE
> section in tcg/tcg.c.

Thanks, that's what I was missing.

Andreas

Patch

diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 3d43412..a20c96d 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -2100,23 +2100,31 @@  static inline void tcg_out_movi(TCGContext *s, TCGType type,
     tcg_out_movi32(s, COND_AL, ret, arg);
 }
 
+/* Compute frame size via macros, to share between tcg_target_qemu_prologue
+   and tcg_register_jit.  */
+
+#define PUSH_SIZE  ((11 - 4 + 1 + 1) * sizeof(tcg_target_long))
+
+#define FRAME_SIZE \
+    ((PUSH_SIZE \
+      + TCG_STATIC_CALL_ARGS_SIZE \
+      + CPU_TEMP_BUF_NLONGS * sizeof(long) \
+      + TCG_TARGET_STACK_ALIGN - 1) \
+     & -TCG_TARGET_STACK_ALIGN)
+
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
-    int frame_size;
+    int stack_addend;
 
     /* Calling convention requires us to save r4-r11 and lr.  */
     /* stmdb sp!, { r4 - r11, lr } */
     tcg_out32(s, (COND_AL << 28) | 0x092d4ff0);
 
-    /* Allocate the local stack frame.  */
-    frame_size = TCG_STATIC_CALL_ARGS_SIZE;
-    frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long);
-    /* We saved an odd number of registers above; keep an 8 aligned stack.  */
-    frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
-                  & -TCG_TARGET_STACK_ALIGN) + 4;
+    /* Reserve callee argument and tcg temp space.  */
+    stack_addend = FRAME_SIZE - PUSH_SIZE;
 
     tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK,
-                   TCG_REG_CALL_STACK, frame_size, 1);
+                   TCG_REG_CALL_STACK, stack_addend, 1);
     tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
                   CPU_TEMP_BUF_NLONGS * sizeof(long));
 
@@ -2127,8 +2135,58 @@  static void tcg_target_qemu_prologue(TCGContext *s)
 
     /* Epilogue.  We branch here via tb_ret_addr.  */
     tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK,
-                   TCG_REG_CALL_STACK, frame_size, 1);
+                   TCG_REG_CALL_STACK, stack_addend, 1);
 
     /* ldmia sp!, { r4 - r11, pc } */
     tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0);
 }
+
+typedef struct {
+    DebugFrameCIE cie;
+    DebugFrameFDEHeader fde;
+    uint8_t fde_def_cfa[4];
+    uint8_t fde_reg_ofs[18];
+} DebugFrame;
+
+#define ELF_HOST_MACHINE EM_ARM
+
+/* We're expecting a 2 byte uleb128 encoded value.  */
+QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
+
+static DebugFrame debug_frame = {
+    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+    .cie.id = -1,
+    .cie.version = 1,
+    .cie.code_align = 1,
+    .cie.data_align = 0x7c,             /* sleb128 -4 */
+    .cie.return_column = 14,
+
+    /* Total FDE size does not include the "len" member.  */
+    .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
+
+    .fde_def_cfa = {
+        12, 13,                         /* DW_CFA_def_cfa sp, ... */
+        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
+        (FRAME_SIZE >> 7)
+    },
+    .fde_reg_ofs = {
+        /* The following must match the stmdb in the prologue.  */
+        0x8e, 1,                        /* DW_CFA_offset, lr, -4 */
+        0x8b, 2,                        /* DW_CFA_offset, r11, -8 */
+        0x8a, 3,                        /* DW_CFA_offset, r10, -12 */
+        0x89, 4,                        /* DW_CFA_offset, r9, -16 */
+        0x88, 5,                        /* DW_CFA_offset, r8, -20 */
+        0x87, 6,                        /* DW_CFA_offset, r7, -24 */
+        0x86, 7,                        /* DW_CFA_offset, r6, -28 */
+        0x85, 8,                        /* DW_CFA_offset, r5, -32 */
+        0x84, 9,                        /* DW_CFA_offset, r4, -36 */
+    }
+};
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+    debug_frame.fde.func_start = (tcg_target_long) buf;
+    debug_frame.fde.func_len = buf_size;
+
+    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+}