summaryrefslogtreecommitdiff
path: root/tcg/arm
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/arm
parenta9ff9df188615d653a5a904bafbe724d40143e35 (diff)
downloadqemu-379f6698d73f476de38682b3ff96ecb226728c43.tar.gz
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/arm')
-rw-r--r--tcg/arm/tcg-target.c34
-rw-r--r--tcg/arm/tcg-target.h2
2 files changed, 34 insertions, 2 deletions
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 1edcd103f3..6cfe1d6670 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -990,7 +990,22 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
# endif
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
-#else
+#else /* !CONFIG_SOFTMMU */
+ if (GUEST_BASE) {
+ uint32_t offset = GUEST_BASE;
+ int i;
+ int rot;
+
+ while (offset) {
+ i = ctz32(offset) & ~1;
+ rot = ((32 - i) << 7) & 0xf00;
+
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
+ ((offset >> i) & 0xff) | rot);
+ addr_reg = 8;
+ offset &= ~(0xff << i);
+ }
+ }
switch (opc) {
case 0:
tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
@@ -1200,7 +1215,22 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
# endif
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
-#else
+#else /* !CONFIG_SOFTMMU */
+ if (GUEST_BASE) {
+ uint32_t offset = GUEST_BASE;
+ int i;
+ int rot;
+
+ while (offset) {
+ i = ctz32(offset) & ~1;
+ rot = ((32 - i) << 7) & 0xf00;
+
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
+ ((offset >> i) & 0xff) | rot);
+ addr_reg = 8;
+ offset &= ~(0xff << i);
+ }
+ }
switch (opc) {
case 0:
tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 78ab8fd3e5..ffa9ceeca0 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -60,6 +60,8 @@ enum {
#define TCG_TARGET_STACK_ALIGN 8
#define TCG_TARGET_CALL_STACK_OFFSET 0
+#define TCG_TARGET_HAS_GUEST_BASE
+
enum {
/* Note: must be synced with dyngen-exec.h */
TCG_AREG0 = TCG_REG_R7,