Revision b03cce8e tcg/i386/tcg-target.c

b/tcg/i386/tcg-target.c
46 46
const int tcg_target_call_iarg_regs[3] = { TCG_REG_EAX, TCG_REG_EDX, TCG_REG_ECX };
47 47
const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX };
48 48

  
49
static uint8_t *tb_ret_addr;
50

  
49 51
static void patch_reloc(uint8_t *code_ptr, int type, 
50 52
                        tcg_target_long value, tcg_target_long addend)
51 53
{
......
879 881
    switch(opc) {
880 882
    case INDEX_op_exit_tb:
881 883
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
882
        tcg_out8(s, 0xc3); /* ret */
884
        tcg_out8(s, 0xe9); /* jmp tb_ret_addr */
885
        tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
883 886
        break;
884 887
    case INDEX_op_goto_tb:
885 888
        if (s->tb_jmp_offset) {
......
1145 1148
    { -1 },
1146 1149
};
1147 1150

  
1151
static int tcg_target_callee_save_regs[] = {
1152
    /*    TCG_REG_EBP, */ /* currently used for the global env, so no
1153
                             need to save */
1154
    TCG_REG_EBX,
1155
    TCG_REG_ESI,
1156
    TCG_REG_EDI,
1157
};
1158

  
1159
static inline void tcg_out_push(TCGContext *s, int reg)
1160
{
1161
    tcg_out_opc(s, 0x50 + reg);
1162
}
1163

  
1164
static inline void tcg_out_pop(TCGContext *s, int reg)
1165
{
1166
    tcg_out_opc(s, 0x58 + reg);
1167
}
1168

  
1169
/* Generate global QEMU prologue and epilogue code */
1170
void tcg_target_qemu_prologue(TCGContext *s)
1171
{
1172
    int i, frame_size, push_size, stack_addend;
1173
    
1174
    /* TB prologue */
1175
    /* save all callee saved registers */
1176
    for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1177
        tcg_out_push(s, tcg_target_callee_save_regs[i]);
1178
    }
1179
    /* reserve some stack space */
1180
    push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
1181
    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
1182
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & 
1183
        ~(TCG_TARGET_STACK_ALIGN - 1);
1184
    stack_addend = frame_size - push_size;
1185
    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
1186

  
1187
    tcg_out_modrm(s, 0xff, 4, TCG_REG_EAX); /* jmp *%eax */
1188
    
1189
    /* TB epilogue */
1190
    tb_ret_addr = s->code_ptr;
1191
    tcg_out_addi(s, TCG_REG_ESP, stack_addend);
1192
    for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1193
        tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1194
    }
1195
    tcg_out8(s, 0xc3); /* ret */
1196
}
1197

  
1148 1198
void tcg_target_init(TCGContext *s)
1149 1199
{
1150 1200
    /* fail safe */

Also available in: Unified diff