Revision 813da627 tcg/i386/tcg-target.c
b/tcg/i386/tcg-target.c | ||
---|---|---|
1989 | 1989 |
#endif |
1990 | 1990 |
}; |
1991 | 1991 |
|
1992 |
/* Compute frame size via macros, to share between tcg_target_qemu_prologue |
|
1993 |
and tcg_register_jit. */ |
|
1994 |
|
|
1995 |
#define PUSH_SIZE \ |
|
1996 |
((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \ |
|
1997 |
* (TCG_TARGET_REG_BITS / 8)) |
|
1998 |
|
|
1999 |
#define FRAME_SIZE \ |
|
2000 |
((PUSH_SIZE \ |
|
2001 |
+ TCG_STATIC_CALL_ARGS_SIZE \ |
|
2002 |
+ CPU_TEMP_BUF_NLONGS * sizeof(long) \ |
|
2003 |
+ TCG_TARGET_STACK_ALIGN - 1) \ |
|
2004 |
& ~(TCG_TARGET_STACK_ALIGN - 1)) |
|
2005 |
|
|
1992 | 2006 |
/* Generate global QEMU prologue and epilogue code */ |
1993 | 2007 |
static void tcg_target_qemu_prologue(TCGContext *s) |
1994 | 2008 |
{ |
1995 |
int i, frame_size, push_size, stack_addend;
|
|
2009 |
int i, stack_addend; |
|
1996 | 2010 |
|
1997 | 2011 |
/* TB prologue */ |
1998 | 2012 |
|
1999 | 2013 |
/* Reserve some stack space, also for TCG temps. */ |
2000 |
push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs); |
|
2001 |
push_size *= TCG_TARGET_REG_BITS / 8; |
|
2002 |
|
|
2003 |
frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE + |
|
2004 |
CPU_TEMP_BUF_NLONGS * sizeof(long); |
|
2005 |
frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & |
|
2006 |
~(TCG_TARGET_STACK_ALIGN - 1); |
|
2007 |
stack_addend = frame_size - push_size; |
|
2014 |
stack_addend = FRAME_SIZE - PUSH_SIZE; |
|
2008 | 2015 |
tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE, |
2009 | 2016 |
CPU_TEMP_BUF_NLONGS * sizeof(long)); |
2010 | 2017 |
|
... | ... | |
2070 | 2077 |
|
2071 | 2078 |
tcg_add_target_add_op_defs(x86_op_defs); |
2072 | 2079 |
} |
2080 |
|
|
2081 |
typedef struct { |
|
2082 |
uint32_t len __attribute__((aligned((sizeof(void *))))); |
|
2083 |
uint32_t id; |
|
2084 |
uint8_t version; |
|
2085 |
char augmentation[1]; |
|
2086 |
uint8_t code_align; |
|
2087 |
uint8_t data_align; |
|
2088 |
uint8_t return_column; |
|
2089 |
} DebugFrameCIE; |
|
2090 |
|
|
2091 |
typedef struct { |
|
2092 |
uint32_t len __attribute__((aligned((sizeof(void *))))); |
|
2093 |
uint32_t cie_offset; |
|
2094 |
tcg_target_long func_start __attribute__((packed)); |
|
2095 |
tcg_target_long func_len __attribute__((packed)); |
|
2096 |
uint8_t def_cfa[4]; |
|
2097 |
uint8_t reg_ofs[14]; |
|
2098 |
} DebugFrameFDE; |
|
2099 |
|
|
2100 |
typedef struct { |
|
2101 |
DebugFrameCIE cie; |
|
2102 |
DebugFrameFDE fde; |
|
2103 |
} DebugFrame; |
|
2104 |
|
|
2105 |
#if TCG_TARGET_REG_BITS == 64 |
|
2106 |
#define ELF_HOST_MACHINE EM_X86_64 |
|
2107 |
static DebugFrame debug_frame = { |
|
2108 |
.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */ |
|
2109 |
.cie.id = -1, |
|
2110 |
.cie.version = 1, |
|
2111 |
.cie.code_align = 1, |
|
2112 |
.cie.data_align = 0x78, /* sleb128 -8 */ |
|
2113 |
.cie.return_column = 16, |
|
2114 |
|
|
2115 |
.fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */ |
|
2116 |
.fde.def_cfa = { |
|
2117 |
12, 7, /* DW_CFA_def_cfa %rsp, ... */ |
|
2118 |
(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ |
|
2119 |
(FRAME_SIZE >> 7) |
|
2120 |
}, |
|
2121 |
.fde.reg_ofs = { |
|
2122 |
0x90, 1, /* DW_CFA_offset, %rip, -8 */ |
|
2123 |
/* The following ordering must match tcg_target_callee_save_regs. */ |
|
2124 |
0x86, 2, /* DW_CFA_offset, %rbp, -16 */ |
|
2125 |
0x83, 3, /* DW_CFA_offset, %rbx, -24 */ |
|
2126 |
0x8c, 4, /* DW_CFA_offset, %r12, -32 */ |
|
2127 |
0x8d, 5, /* DW_CFA_offset, %r13, -40 */ |
|
2128 |
0x8e, 6, /* DW_CFA_offset, %r14, -48 */ |
|
2129 |
0x8f, 7, /* DW_CFA_offset, %r15, -56 */ |
|
2130 |
} |
|
2131 |
}; |
|
2132 |
#else |
|
2133 |
#define ELF_HOST_MACHINE EM_386 |
|
2134 |
static DebugFrame debug_frame = { |
|
2135 |
.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */ |
|
2136 |
.cie.id = -1, |
|
2137 |
.cie.version = 1, |
|
2138 |
.cie.code_align = 1, |
|
2139 |
.cie.data_align = 0x7c, /* sleb128 -4 */ |
|
2140 |
.cie.return_column = 8, |
|
2141 |
|
|
2142 |
.fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */ |
|
2143 |
.fde.def_cfa = { |
|
2144 |
12, 4, /* DW_CFA_def_cfa %esp, ... */ |
|
2145 |
(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ |
|
2146 |
(FRAME_SIZE >> 7) |
|
2147 |
}, |
|
2148 |
.fde.reg_ofs = { |
|
2149 |
0x88, 1, /* DW_CFA_offset, %eip, -4 */ |
|
2150 |
/* The following ordering must match tcg_target_callee_save_regs. */ |
|
2151 |
0x85, 2, /* DW_CFA_offset, %ebp, -8 */ |
|
2152 |
0x83, 3, /* DW_CFA_offset, %ebx, -12 */ |
|
2153 |
0x86, 4, /* DW_CFA_offset, %esi, -16 */ |
|
2154 |
0x87, 5, /* DW_CFA_offset, %edi, -20 */ |
|
2155 |
} |
|
2156 |
}; |
|
2157 |
#endif |
|
2158 |
|
|
2159 |
void tcg_register_jit(void *buf, size_t buf_size) |
|
2160 |
{ |
|
2161 |
/* We're expecting a 2 byte uleb128 encoded value. */ |
|
2162 |
assert(FRAME_SIZE >> 14 == 0); |
|
2163 |
|
|
2164 |
debug_frame.fde.func_start = (tcg_target_long) buf; |
|
2165 |
debug_frame.fde.func_len = buf_size; |
|
2166 |
|
|
2167 |
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); |
|
2168 |
} |
Also available in: Unified diff