tcg-target.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,300 行 · 第 1/3 页
C
1,300 行
tcg_out_modrm(s, 0xff, 2, args[0]); } break; case INDEX_op_jmp: if (const_args[0]) { tcg_out8(s, 0xe9); tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4); } else { tcg_out_modrm(s, 0xff, 4, args[0]); } break; case INDEX_op_br: tcg_out_jxx(s, JCC_JMP, args[0]); break; case INDEX_op_movi_i32: tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]); break; case INDEX_op_movi_i64: tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]); break; case INDEX_op_ld8u_i32: case INDEX_op_ld8u_i64: /* movzbl */ tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]); break; case INDEX_op_ld8s_i32: /* movsbl */ tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]); break; case INDEX_op_ld8s_i64: /* movsbq */ tcg_out_modrm_offset(s, 0xbe | P_EXT | P_REXW, args[0], args[1], args[2]); break; case INDEX_op_ld16u_i32: case INDEX_op_ld16u_i64: /* movzwl */ tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]); break; case INDEX_op_ld16s_i32: /* movswl */ tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]); break; case INDEX_op_ld16s_i64: /* movswq */ tcg_out_modrm_offset(s, 0xbf | P_EXT | P_REXW, args[0], args[1], args[2]); break; case INDEX_op_ld_i32: case INDEX_op_ld32u_i64: /* movl */ tcg_out_modrm_offset(s, 0x8b, args[0], args[1], args[2]); break; case INDEX_op_ld32s_i64: /* movslq */ tcg_out_modrm_offset(s, 0x63 | P_REXW, args[0], args[1], args[2]); break; case INDEX_op_ld_i64: /* movq */ tcg_out_modrm_offset(s, 0x8b | P_REXW, args[0], args[1], args[2]); break; case INDEX_op_st8_i32: case INDEX_op_st8_i64: /* movb */ tcg_out_modrm_offset(s, 0x88 | P_REXB, args[0], args[1], args[2]); break; case INDEX_op_st16_i32: case INDEX_op_st16_i64: /* movw */ tcg_out8(s, 0x66); tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]); break; case INDEX_op_st_i32: case INDEX_op_st32_i64: /* movl */ tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]); break; case INDEX_op_st_i64: /* movq */ tcg_out_modrm_offset(s, 0x89 | P_REXW, args[0], args[1], args[2]); break; case INDEX_op_sub_i32: c = ARITH_SUB; goto gen_arith32; case INDEX_op_and_i32: c = ARITH_AND; goto gen_arith32; case INDEX_op_or_i32: c = ARITH_OR; goto gen_arith32; case INDEX_op_xor_i32: c = ARITH_XOR; goto gen_arith32; case INDEX_op_add_i32: c = ARITH_ADD; gen_arith32: if (const_args[2]) { tgen_arithi32(s, c, args[0], args[2]); } else { tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]); } break; case INDEX_op_sub_i64: c = ARITH_SUB; goto gen_arith64; case INDEX_op_and_i64: c = ARITH_AND; goto gen_arith64; case INDEX_op_or_i64: c = ARITH_OR; goto gen_arith64; case INDEX_op_xor_i64: c = ARITH_XOR; goto gen_arith64; case INDEX_op_add_i64: c = ARITH_ADD; gen_arith64: if (const_args[2]) { tgen_arithi64(s, c, args[0], args[2]); } else { tcg_out_modrm(s, 0x01 | (c << 3) | P_REXW, args[2], args[0]); } break; case INDEX_op_mul_i32: if (const_args[2]) { int32_t val; val = args[2]; if (val == (int8_t)val) { tcg_out_modrm(s, 0x6b, args[0], args[0]); tcg_out8(s, val); } else { tcg_out_modrm(s, 0x69, args[0], args[0]); tcg_out32(s, val); } } else { tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]); } break; case INDEX_op_mul_i64: if (const_args[2]) { int32_t val; val = args[2]; if (val == (int8_t)val) { tcg_out_modrm(s, 0x6b | P_REXW, args[0], args[0]); tcg_out8(s, val); } else { tcg_out_modrm(s, 0x69 | P_REXW, args[0], args[0]); tcg_out32(s, val); } } else { tcg_out_modrm(s, 0xaf | P_EXT | P_REXW, args[0], args[2]); } break; case INDEX_op_div2_i32: tcg_out_modrm(s, 0xf7, 7, args[4]); break; case INDEX_op_divu2_i32: tcg_out_modrm(s, 0xf7, 6, args[4]); break; case INDEX_op_div2_i64: tcg_out_modrm(s, 0xf7 | P_REXW, 7, args[4]); break; case INDEX_op_divu2_i64: tcg_out_modrm(s, 0xf7 | P_REXW, 6, args[4]); break; case INDEX_op_shl_i32: c = SHIFT_SHL; gen_shift32: if (const_args[2]) { if (args[2] == 1) { tcg_out_modrm(s, 0xd1, c, args[0]); } else { tcg_out_modrm(s, 0xc1, c, args[0]); tcg_out8(s, args[2]); } } else { tcg_out_modrm(s, 0xd3, c, args[0]); } break; case INDEX_op_shr_i32: c = SHIFT_SHR; goto gen_shift32; case INDEX_op_sar_i32: c = SHIFT_SAR; goto gen_shift32; case INDEX_op_shl_i64: c = SHIFT_SHL; gen_shift64: if (const_args[2]) { if (args[2] == 1) { tcg_out_modrm(s, 0xd1 | P_REXW, c, args[0]); } else { tcg_out_modrm(s, 0xc1 | P_REXW, c, args[0]); tcg_out8(s, args[2]); } } else { tcg_out_modrm(s, 0xd3 | P_REXW, c, args[0]); } break; case INDEX_op_shr_i64: c = SHIFT_SHR; goto gen_shift64; case INDEX_op_sar_i64: c = SHIFT_SAR; goto gen_shift64; case INDEX_op_brcond_i32: tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3], 0); break; case INDEX_op_brcond_i64: tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3], P_REXW); break; case INDEX_op_bswap_i32: tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT, 0, args[0], 0); break; case INDEX_op_bswap_i64: tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT | P_REXW, 0, args[0], 0); break; case INDEX_op_neg_i32: tcg_out_modrm(s, 0xf7, 3, args[0]); break; case INDEX_op_neg_i64: tcg_out_modrm(s, 0xf7 | P_REXW, 3, args[0]); break; case INDEX_op_qemu_ld8u: tcg_out_qemu_ld(s, args, 0); break; case INDEX_op_qemu_ld8s: tcg_out_qemu_ld(s, args, 0 | 4); break; case INDEX_op_qemu_ld16u: tcg_out_qemu_ld(s, args, 1); break; case INDEX_op_qemu_ld16s: tcg_out_qemu_ld(s, args, 1 | 4); break; case INDEX_op_qemu_ld32u: tcg_out_qemu_ld(s, args, 2); break; case INDEX_op_qemu_ld32s: tcg_out_qemu_ld(s, args, 2 | 4); break; case INDEX_op_qemu_ld64: tcg_out_qemu_ld(s, args, 3); break; case INDEX_op_qemu_st8: tcg_out_qemu_st(s, args, 0); break; case INDEX_op_qemu_st16: tcg_out_qemu_st(s, args, 1); break; case INDEX_op_qemu_st32: tcg_out_qemu_st(s, args, 2); break; case INDEX_op_qemu_st64: tcg_out_qemu_st(s, args, 3); break; default: tcg_abort(); }}static int tcg_target_callee_save_regs[] = { TCG_REG_RBP, TCG_REG_RBX, TCG_REG_R12, TCG_REG_R13, /* TCG_REG_R14, */ /* currently used for the global env, so no need to save */ TCG_REG_R15,};static inline void tcg_out_push(TCGContext *s, int reg){ tcg_out_opc(s, (0x50 + (reg & 7)), 0, reg, 0);}static inline void tcg_out_pop(TCGContext *s, int reg){ tcg_out_opc(s, (0x58 + (reg & 7)), 0, reg, 0);}/* Generate global QEMU prologue and epilogue code */void tcg_target_qemu_prologue(TCGContext *s){ int i, frame_size, push_size, stack_addend; /* TB prologue */ /* save all callee saved registers */ for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { tcg_out_push(s, tcg_target_callee_save_regs[i]); } /* reserve some stack space */ push_size = 8 + ARRAY_SIZE(tcg_target_callee_save_regs) * 8; frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE; frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & ~(TCG_TARGET_STACK_ALIGN - 1); stack_addend = frame_size - push_size; tcg_out_addi(s, TCG_REG_RSP, -stack_addend); tcg_out_modrm(s, 0xff, 4, TCG_REG_RDI); /* jmp *%rdi */ /* TB epilogue */ tb_ret_addr = s->code_ptr; tcg_out_addi(s, TCG_REG_RSP, stack_addend); for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) { tcg_out_pop(s, tcg_target_callee_save_regs[i]); } tcg_out8(s, 0xc3); /* ret */}static const TCGTargetOpDef x86_64_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, /* XXX: might need a specific constant constraint */ { INDEX_op_jmp, { "ri" } }, /* XXX: might need a specific constant constraint */ { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, { INDEX_op_movi_i32, { "r" } }, { INDEX_op_ld8u_i32, { "r", "r" } }, { INDEX_op_ld8s_i32, { "r", "r" } }, { INDEX_op_ld16u_i32, { "r", "r" } }, { INDEX_op_ld16s_i32, { "r", "r" } }, { INDEX_op_ld_i32, { "r", "r" } }, { INDEX_op_st8_i32, { "r", "r" } }, { INDEX_op_st16_i32, { "r", "r" } }, { INDEX_op_st_i32, { "r", "r" } }, { INDEX_op_add_i32, { "r", "0", "ri" } }, { INDEX_op_mul_i32, { "r", "0", "ri" } }, { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } }, { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } }, { INDEX_op_sub_i32, { "r", "0", "ri" } }, { INDEX_op_and_i32, { "r", "0", "ri" } }, { INDEX_op_or_i32, { "r", "0", "ri" } }, { INDEX_op_xor_i32, { "r", "0", "ri" } }, { INDEX_op_shl_i32, { "r", "0", "ci" } }, { INDEX_op_shr_i32, { "r", "0", "ci" } }, { INDEX_op_sar_i32, { "r", "0", "ci" } }, { INDEX_op_brcond_i32, { "r", "ri" } }, { INDEX_op_mov_i64, { "r", "r" } }, { INDEX_op_movi_i64, { "r" } }, { INDEX_op_ld8u_i64, { "r", "r" } }, { INDEX_op_ld8s_i64, { "r", "r" } }, { INDEX_op_ld16u_i64, { "r", "r" } }, { INDEX_op_ld16s_i64, { "r", "r" } }, { INDEX_op_ld32u_i64, { "r", "r" } }, { INDEX_op_ld32s_i64, { "r", "r" } }, { INDEX_op_ld_i64, { "r", "r" } }, { INDEX_op_st8_i64, { "r", "r" } }, { INDEX_op_st16_i64, { "r", "r" } }, { INDEX_op_st32_i64, { "r", "r" } }, { INDEX_op_st_i64, { "r", "r" } }, { INDEX_op_add_i64, { "r", "0", "re" } }, { INDEX_op_mul_i64, { "r", "0", "re" } }, { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } }, { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } }, { INDEX_op_sub_i64, { "r", "0", "re" } }, { INDEX_op_and_i64, { "r", "0", "reZ" } }, { INDEX_op_or_i64, { "r", "0", "re" } }, { INDEX_op_xor_i64, { "r", "0", "re" } }, { INDEX_op_shl_i64, { "r", "0", "ci" } }, { INDEX_op_shr_i64, { "r", "0", "ci" } }, { INDEX_op_sar_i64, { "r", "0", "ci" } }, { INDEX_op_brcond_i64, { "r", "re" } }, { INDEX_op_bswap_i32, { "r", "0" } }, { INDEX_op_bswap_i64, { "r", "0" } }, { INDEX_op_neg_i32, { "r", "0" } }, { INDEX_op_neg_i64, { "r", "0" } }, { INDEX_op_qemu_ld8u, { "r", "L" } }, { INDEX_op_qemu_ld8s, { "r", "L" } }, { INDEX_op_qemu_ld16u, { "r", "L" } }, { INDEX_op_qemu_ld16s, { "r", "L" } }, { INDEX_op_qemu_ld32u, { "r", "L" } }, { INDEX_op_qemu_ld32s, { "r", "L" } }, { INDEX_op_qemu_ld64, { "r", "L" } }, { INDEX_op_qemu_st8, { "L", "L" } }, { INDEX_op_qemu_st16, { "L", "L" } }, { INDEX_op_qemu_st32, { "L", "L" } }, { INDEX_op_qemu_st64, { "L", "L", "L" } }, { -1 },};void tcg_target_init(TCGContext *s){ /* fail safe */ if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) tcg_abort(); tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff); tcg_regset_set32(tcg_target_call_clobber_regs, 0, (1 << TCG_REG_RDI) | (1 << TCG_REG_RSI) | (1 << TCG_REG_RDX) | (1 << TCG_REG_RCX) | (1 << TCG_REG_R8) | (1 << TCG_REG_R9) | (1 << TCG_REG_RAX) | (1 << TCG_REG_R10) | (1 << TCG_REG_R11)); tcg_regset_clear(s->reserved_regs); tcg_regset_set_reg(s->reserved_regs, TCG_REG_RSP); tcg_add_target_add_op_defs(x86_64_op_defs);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?