aboutsummaryrefslogtreecommitdiff
path: root/tcg/x86_64
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2009-07-17 12:48:08 +0100
committerPaul Brook <paul@codesourcery.com>2009-07-17 13:12:41 +0100
commit379f6698d73f476de38682b3ff96ecb226728c43 (patch)
tree35ec0c77416322f16fa27d646af50c60363168e3 /tcg/x86_64
parenta9ff9df188615d653a5a904bafbe724d40143e35 (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.c56
-rw-r--r--tcg/x86_64/tcg-target.h2
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