qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/2] tcg/i386: Use segment for 32-bit guest base on


From: Richard Henderson
Subject: [Qemu-devel] [PATCH 2/2] tcg/i386: Use segment for 32-bit guest base on linux
Date: Sat, 4 Jun 2016 00:54:07 -0700

From: Richard Henderson <address@hidden>

This saves 3 bytes per memory operation.

Signed-off-by: Richard Henderson <address@hidden>
---
 tcg/i386/tcg-target.inc.c | 44 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 37 insertions(+), 7 deletions(-)

diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 11cbb3c..d8c2f6d 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -290,14 +290,13 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 # define P_REXW         0x1000          /* Set REX.W = 1 */
 # define P_REXB_R       0x2000          /* REG field as byte register */
 # define P_REXB_RM      0x4000          /* R/M field as byte register */
-# define P_GS           0x8000          /* gs segment override */
 #else
 # define P_ADDR32      0
 # define P_REXW                0
 # define P_REXB_R      0
 # define P_REXB_RM     0
-# define P_GS           0
 #endif
+#define P_SEG           0x8000          /* fs/gs segment override */
 #define P_SIMDF3        0x10000         /* 0xf3 opcode prefix */
 #define P_SIMDF2        0x20000         /* 0xf2 opcode prefix */
 
@@ -420,8 +419,8 @@ static void tcg_out_opc(TCGContext *s, int opc, int r, int 
rm, int x)
 {
     int rex;
 
-    if (opc & P_GS) {
-        tcg_out8(s, 0x65);
+    if (opc & P_SEG) {
+        tcg_out8(s, 0x65); /* %gs */
     }
     if (opc & P_DATA16) {
         /* We should never be asking for both 16 and 64-bit operation.  */
@@ -462,6 +461,9 @@ static void tcg_out_opc(TCGContext *s, int opc, int r, int 
rm, int x)
 #else
 static void tcg_out_opc(TCGContext *s, int opc)
 {
+    if (opc & P_SEG) {
+        tcg_out8(s, 0x64); /* %fs */
+    }
     if (opc & P_DATA16) {
         tcg_out8(s, 0x66);
     }
@@ -1461,7 +1463,7 @@ static void setup_guest_base(TCGContext *s)
     }
 # ifdef __linux__
     if (arch_prctl(ARCH_SET_GS, guest_base) == 0) {
-        guest_base_flags = (TARGET_LONG_BITS == 32 ? P_GS | P_ADDR32 : P_GS);
+        guest_base_flags = P_SEG + (TARGET_LONG_BITS == 32) * P_ADDR32;
         return;
     }
 # endif
@@ -1473,6 +1475,33 @@ static void setup_guest_base(TCGContext *s)
         tcg_out_movi(s, TCG_TYPE_PTR, guest_base_reg, guest_base);
     }
 }
+#elif defined(__linux__)
+# include <asm/ldt.h>
+# include <sys/syscall.h>
+
+static int32_t guest_base_ofs;
+static int guest_base_flags;
+#define guest_base_reg    -1
+static void setup_guest_base(TCGContext *s)
+{
+    if (guest_base != 0) {
+        struct user_desc desc = {
+            .entry_number = -1,
+            .base_addr = guest_base,
+            .limit = 0xfffff,
+            .seg_32bit = 1,
+            .limit_in_pages = 1,
+            .useable = 1,
+        };
+        if (syscall(SYS_set_thread_area, &desc) == 0) {
+           int seg = desc.entry_number * 8 + 3;
+            asm volatile("movl %0,%%fs" : : "r"(seg));
+           guest_base_flags = P_SEG;
+            return;
+       }
+    }
+    guest_base_ofs = guest_base;
+}
 #else
 # define guest_base_flags  0
 # define guest_base_reg    -1
@@ -2310,6 +2339,9 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     tcg_out_ld(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP,
                (ARRAY_SIZE(tcg_target_callee_save_regs) + 1) * 4);
     tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
+# if !defined(CONFIG_SOFTMMU)
+    setup_guest_base(s);
+# endif
     /* jmp *tb.  */
     tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_ESP,
                         (ARRAY_SIZE(tcg_target_callee_save_regs) + 2) * 4
@@ -2317,11 +2349,9 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 #else
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
     tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
-
 # if !defined(CONFIG_SOFTMMU)
     setup_guest_base(s);
 # endif
-
     /* jmp *tb.  */
     tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
 #endif
-- 
2.5.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]