Revision abb6ae2c tcg/x86_64/tcg-target.c
b/tcg/x86_64/tcg-target.c | ||
---|---|---|
363 | 363 |
} |
364 | 364 |
} |
365 | 365 |
|
366 |
static void tcg_out_goto(TCGContext *s, int call, uint8_t *target) |
|
367 |
{ |
|
368 |
int32_t disp; |
|
369 |
|
|
370 |
disp = target - s->code_ptr - 5; |
|
371 |
if (disp == (target - s->code_ptr - 5)) { |
|
372 |
tcg_out8(s, call ? 0xe8 : 0xe9); |
|
373 |
tcg_out32(s, disp); |
|
374 |
} else { |
|
375 |
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, (tcg_target_long) target); |
|
376 |
tcg_out_modrm(s, 0xff, call ? 2 : 4, TCG_REG_R10); |
|
377 |
} |
|
378 |
} |
|
379 |
|
|
366 | 380 |
static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret, |
367 | 381 |
int arg1, tcg_target_long arg2) |
368 | 382 |
{ |
... | ... | |
559 | 573 |
|
560 | 574 |
/* XXX: move that code at the end of the TB */ |
561 | 575 |
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RSI, mem_index); |
562 |
tcg_out8(s, 0xe8); |
|
563 |
tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] - |
|
564 |
(tcg_target_long)s->code_ptr - 4); |
|
576 |
tcg_out_goto(s, 1, qemu_ld_helpers[s_bits]); |
|
565 | 577 |
|
566 | 578 |
switch(opc) { |
567 | 579 |
case 0 | 4: |
... | ... | |
774 | 786 |
break; |
775 | 787 |
} |
776 | 788 |
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index); |
777 |
tcg_out8(s, 0xe8); |
|
778 |
tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - |
|
779 |
(tcg_target_long)s->code_ptr - 4); |
|
789 |
tcg_out_goto(s, 1, qemu_st_helpers[s_bits]); |
|
780 | 790 |
|
781 | 791 |
/* jmp label2 */ |
782 | 792 |
tcg_out8(s, 0xeb); |
... | ... | |
865 | 875 |
switch(opc) { |
866 | 876 |
case INDEX_op_exit_tb: |
867 | 877 |
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, args[0]); |
868 |
tcg_out8(s, 0xe9); /* jmp tb_ret_addr */ |
|
869 |
tcg_out32(s, tb_ret_addr - s->code_ptr - 4); |
|
878 |
tcg_out_goto(s, 0, tb_ret_addr); |
|
870 | 879 |
break; |
871 | 880 |
case INDEX_op_goto_tb: |
872 | 881 |
if (s->tb_jmp_offset) { |
... | ... | |
885 | 894 |
break; |
886 | 895 |
case INDEX_op_call: |
887 | 896 |
if (const_args[0]) { |
888 |
tcg_out8(s, 0xe8); |
|
889 |
tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4); |
|
897 |
tcg_out_goto(s, 1, (void *) args[0]); |
|
890 | 898 |
} else { |
891 | 899 |
tcg_out_modrm(s, 0xff, 2, args[0]); |
892 | 900 |
} |
893 | 901 |
break; |
894 | 902 |
case INDEX_op_jmp: |
895 | 903 |
if (const_args[0]) { |
896 |
tcg_out8(s, 0xe9); |
|
897 |
tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4); |
|
904 |
tcg_out_goto(s, 0, (void *) args[0]); |
|
898 | 905 |
} else { |
899 | 906 |
tcg_out_modrm(s, 0xff, 4, args[0]); |
900 | 907 |
} |
Also available in: Unified diff