diff options
author | Paul Brook <paul@codesourcery.com> | 2009-07-17 12:48:08 +0100 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2009-07-17 13:12:41 +0100 |
commit | 379f6698d73f476de38682b3ff96ecb226728c43 (patch) | |
tree | 35ec0c77416322f16fa27d646af50c60363168e3 /tcg/x86_64 | |
parent | a9ff9df188615d653a5a904bafbe724d40143e35 (diff) |
Userspace guest address offsetting
Re-implement GUEST_BASE support.
Offset guest ddress space by default if the guest binary contains
regions below the host mmap_min_addr.
Implement support for i386, x86-64 and arm hosts.
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Paul Brook <paul@codesourcery.com>
Diffstat (limited to 'tcg/x86_64')
-rw-r--r-- | tcg/x86_64/tcg-target.c | 56 | ||||
-rw-r--r-- | tcg/x86_64/tcg-target.h | 2 |
2 files changed, 43 insertions, 15 deletions
diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c index 5378e8510b..9facb01e41 100644 --- a/tcg/x86_64/tcg-target.c +++ b/tcg/x86_64/tcg-target.c @@ -508,6 +508,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) { int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw; + int32_t offset; #if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr; #endif @@ -604,8 +605,20 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, /* add x(r1), r0 */ tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read)); + offset = 0; #else - r0 = addr_reg; + if (GUEST_BASE == (int32_t)GUEST_BASE) { + r0 = addr_reg; + offset = GUEST_BASE; + } else { + offset = 0; + /* movq $GUEST_BASE, r0 */ + tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0); + tcg_out32(s, GUEST_BASE); + tcg_out32(s, GUEST_BASE >> 32); + /* addq addr_reg, r0 */ + tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0); + } #endif #ifdef TARGET_WORDS_BIGENDIAN @@ -616,15 +629,15 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, switch(opc) { case 0: /* movzbl */ - tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, offset); break; case 0 | 4: /* movsbX */ - tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, offset); break; case 1: /* movzwl */ - tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset); if (bswap) { /* rolw $8, data_reg */ tcg_out8(s, 0x66); @@ -635,7 +648,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, case 1 | 4: if (bswap) { /* movzwl */ - tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset); /* rolw $8, data_reg */ tcg_out8(s, 0x66); tcg_out_modrm(s, 0xc1, 0, data_reg); @@ -645,12 +658,12 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg); } else { /* movswX */ - tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, offset); } break; case 2: /* movl (r0), data_reg */ - tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset); if (bswap) { /* bswap */ tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0); @@ -659,19 +672,19 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, case 2 | 4: if (bswap) { /* movl (r0), data_reg */ - tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset); /* bswap */ tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0); /* movslq */ tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg); } else { /* movslq */ - tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, offset); } break; case 3: /* movq (r0), data_reg */ - tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, offset); if (bswap) { /* bswap */ tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0); @@ -691,6 +704,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) { int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw; + int32_t offset; #if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr; #endif @@ -775,8 +789,20 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, /* add x(r1), r0 */ tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write)); + offset = 0; #else - r0 = addr_reg; + if (GUEST_BASE == (int32_t)GUEST_BASE) { + r0 = addr_reg; + offset = GUEST_BASE; + } else { + offset = 0; + /* movq $GUEST_BASE, r0 */ + tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0); + tcg_out32(s, GUEST_BASE); + tcg_out32(s, GUEST_BASE >> 32); + /* addq addr_reg, r0 */ + tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0); + } #endif #ifdef TARGET_WORDS_BIGENDIAN @@ -787,7 +813,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, switch(opc) { case 0: /* movb */ - tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, offset); break; case 1: if (bswap) { @@ -799,7 +825,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, } /* movw */ tcg_out8(s, 0x66); - tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset); break; case 2: if (bswap) { @@ -809,7 +835,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, data_reg = r1; } /* movl */ - tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset); break; case 3: if (bswap) { @@ -819,7 +845,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, data_reg = r1; } /* movq */ - tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0); + tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, offset); break; default: tcg_abort(); diff --git a/tcg/x86_64/tcg-target.h b/tcg/x86_64/tcg-target.h index 8cb05c6328..8d47e78738 100644 --- a/tcg/x86_64/tcg-target.h +++ b/tcg/x86_64/tcg-target.h @@ -73,6 +73,8 @@ enum { #define TCG_TARGET_HAS_rot_i32 #define TCG_TARGET_HAS_rot_i64 +#define TCG_TARGET_HAS_GUEST_BASE + /* Note: must be synced with dyngen-exec.h */ #define TCG_AREG0 TCG_REG_R14 #define TCG_AREG1 TCG_REG_R15 |