Skip to contentSkip to conversation

reorganize register set for SPE + TCG

PATCH In review Nathan Froyd 3 participants 4 messages Oct 15, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 reorganize register set for SPE + TCG

The (large, invasive) patch below is a preparation patch for converting (most) SPE instructions to use TCG. The rationale is that your ordinary SPE instruction deals with three 64-bit quantaties (and a potential 64-bit accumulator). In the current implementation, it's extremely laborious/difficult to pass those 64-bit quantaties to helpers, since the high/low words for SPE registers are not contiguous in the environment. (TCG helpers for SPE instructions are not yet implemented, but they will be necessary as part of the total conversion to TCG.)

The only way I see to do it is to pass six things--the 32-bit argument words and two pointers to the result words--and deal with high/low words separately (and two more to account for potential accumulators). Except that TCG currently doesn't support six-argument (eight-argument) helpers--at least not as far as I can see.

I suppose TCG could be changed to accommodate eight-argument helpers, but I know the PPC target a bit better than I know TCG, so this is the way I decided to go for now. Forcing that complexity into TCG for one target's purposes also doesn't seem like the greatest idea. The TARGET_PPC64 cases would have to be implemented separately as well (or require changes which are similar to the ones I have made), which gets tedious to read and write after a while.

The main idea of the patch is simple enough: the GPRs in the environment are now always 64-bit quantities and we access the relevant 32-bit halves or 64-bit whole as necessary. Most of the bulk of the patch comes from env->gpr[i] not being an integer type anymore; I introduced a helper macro to reference the 64-bit whole or the appropriate 32-bit half instead. Marshaling 64-bit quantities is extremely easy now that the high/low words for SPE registers are contiguous in the environment; we can just pass a pointer to the relevant location. Implementing a normal SPE instruction (one result, two arguments, and optional accumulator) then requires just four pointer arguments...a perfect fit for TCG.

Other (potential) benefits of this change include the ability to implement certain 2-element vector instructions directly in TCG without helpers and general elimination of TARGET_PPC64 #ifs. I included a small bugfix to the way Altivec registers were implemented in the patch; if the patch proves to be too invasive, then I can break that out and submit that separately.

I don't know if the introduction of so many tcg_global_mem_new's will be detrimental to TCG's performance, but I will leave comment on that to somebody more expert than I.

-Nathan

gdbstub.c +2 -2
diff -r 5ed4e3fd0fe7 -r 8a7ea9ce5335 gdbstub.c
@@ -426,7 +426,7 @@
 {
     if (n < 32) {
         /* gprs */
-        GET_REGL(env->gpr[n]);
+        GET_REGL(GPR(env, n));
     } else if (n < 64) {
         /* fprs */
         stfq_p(mem_buf, env->fpr[n]);
@@ -456,7 +456,7 @@
 {
     if (n < 32) {
         /* gprs */
-        env->gpr[n] = ldtul_p(mem_buf);
+        GPR(env, n) = ldtul_p(mem_buf);
         return sizeof(target_ulong);
     } else if (n < 64) {
         /* fprs */
linux-user/main.c +7 -7
diff -r 5ed4e3fd0fe7 -r 8a7ea9ce5335 linux-user/main.c
@@ -1439,18 +1439,18 @@
              * in syscalls.
              */
 #if 0
-            printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
-                   env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
+            printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", GPR(env, 0),
+                   GPR(env, 3), GPR(env, 4), GPR(env, 5), GPR(env, 6));
 #endif
             env->crf[0] &= ~0x1;
-            ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
-                             env->gpr[5], env->gpr[6], env->gpr[7],
-                             env->gpr[8]);
+            ret = do_syscall(env, GPR(env, 0), GPR(env, 3), GPR(env, 4),
+                             GPR(env, 5), GPR(env, 6), GPR(env, 7),
+                             GPR(env, 8));
             if (ret > (uint32_t)(-515)) {
                 env->crf[0] |= 0x1;
                 ret = -ret;
             }
-            env->gpr[3] = ret;
+            GPR(env, 3) = ret;
 #if 0
             printf("syscall returned 0x%08x (%d)\n", ret, ret);
 #endif
@@ -2557,7 +2557,7 @@
 #endif
         env->nip = regs->nip;
         for(i = 0; i < 32; i++) {
-            env->gpr[i] = regs->gpr[i];
+          GPR(env, i) = regs->gpr[i];
         }
     }
 #elif defined(TARGET_M68K)
linux-user/ppc/target_signal.h +1 -1
diff -r 5ed4e3fd0fe7 -r 8a7ea9ce5335 linux-user/ppc/target_signal.h
@@ -23,7 +23,7 @@
 
 static inline abi_ulong get_sp_from_cpustate(CPUPPCState *state)
 {
-    return state->gpr[1];
+    return GPR(state, 1);
 }
 
 #endif /* TARGET_SIGNAL_H */
target-ppc/cpu.h +23 -21

80 lines not on this page · raw message

target-ppc/exec.h +21 -6
diff -r 5ed4e3fd0fe7 -r 8a7ea9ce5335 target-ppc/exec.h
@@ -34,9 +34,24 @@
 register struct CPUPPCState *env asm(AREG0);
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 /* no registers can be used */
-#define T0 (env->t0)
-#define T1 (env->t1)
-#define T2 (env->t2)
+#if defined(TARGET_PPC64)
+#define T0 (env->t0.u64)
+#define T1 (env->t1.u64)
+#define T2 (env->t2.u64)
+#else
+#if defined(WORDS_BIGENDIAN)
+#define HI 0
+#define LO 1
+#else
+#define HI 1
+#define LO 0
+#endif
+#define T0 (env->t0.u32[LO])
+#define T1 (env->t1.u32[LO])
+#define T2 (env->t2.u32[LO])
+#undef HI
+#undef LO
+#endif
 #define TDX "%016" PRIx64
 #else
 register target_ulong T0 asm(AREG1);
@@ -46,9 +61,9 @@
 #endif
 /* We may, sometime, need 64 bits registers on 32 bits targets */
 #if !defined(TARGET_PPC64)
-#define T0_64 (env->t0_64)
-#define T1_64 (env->t1_64)
-#define T2_64 (env->t2_64)
+#define T0_64 (env->t0.u64)
+#define T1_64 (env->t1.u64)
+#define T2_64 (env->t2.u64)
 #else
 #define T0_64 T0
 #define T1_64 T1
target-ppc/helper_regs.h +8 -8
diff -r 5ed4e3fd0fe7 -r 8a7ea9ce5335 target-ppc/helper_regs.h
@@ -44,17 +44,17 @@
 {
     target_ulong tmp;
 
-    tmp = env->gpr[0];
-    env->gpr[0] = env->tgpr[0];
+    tmp = GPR(env, 0);
+    GPR(env, 0) = env->tgpr[0];
     env->tgpr[0] = tmp;
-    tmp = env->gpr[1];
-    env->gpr[1] = env->tgpr[1];
+    tmp = GPR(env, 1);
+    GPR(env, 1) = env->tgpr[1];
     env->tgpr[1] = tmp;
-    tmp = env->gpr[2];
-    env->gpr[2] = env->tgpr[2];
+    tmp = GPR(env, 2);
+    GPR(env, 2) = env->tgpr[2];
     env->tgpr[2] = tmp;
-    tmp = env->gpr[3];
-    env->gpr[3] = env->tgpr[3];
+    tmp = GPR(env, 3);
+    GPR(env, 3) = env->tgpr[3];
     env->tgpr[3] = tmp;
 }
 
target-ppc/op_helper_mem.h +17 -17
diff -r 5ed4e3fd0fe7 -r 8a7ea9ce5335 target-ppc/op_helper_mem.h
@@ -24,7 +24,7 @@
 void glue(do_lmw, MEMSUFFIX) (int dst)
 {
     for (; dst < 32; dst++, T0 += 4) {
-        env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
+        GPR(env, dst) = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
     }
 }
 
@@ -32,7 +32,7 @@
 void glue(do_lmw_64, MEMSUFFIX) (int dst)
 {
     for (; dst < 32; dst++, T0 += 4) {
-        env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
+        GPR(env, dst) = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
     }
 }
 #endif
@@ -40,7 +40,7 @@
 void glue(do_stmw, MEMSUFFIX) (int src)
 {
     for (; src < 32; src++, T0 += 4) {
-        glue(st32, MEMSUFFIX)((uint32_t)T0, env->gpr[src]);
+        glue(st32, MEMSUFFIX)((uint32_t)T0, GPR(env, src));
     }
 }
 
@@ -48,7 +48,7 @@
 void glue(do_stmw_64, MEMSUFFIX) (int src)
 {
     for (; src < 32; src++, T0 += 4) {
-        glue(st32, MEMSUFFIX)((uint64_t)T0, env->gpr[src]);
+        glue(st32, MEMSUFFIX)((uint64_t)T0, GPR(env, src));
     }
 }
 #endif
@@ -56,7 +56,7 @@
 void glue(do_lmw_le, MEMSUFFIX) (int dst)
 {
     for (; dst < 32; dst++, T0 += 4) {
-        env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint32_t)T0);
+        GPR(env, dst) = glue(ldu32r, MEMSUFFIX)((uint32_t)T0);
     }
 }
 
@@ -64,7 +64,7 @@
 void glue(do_lmw_le_64, MEMSUFFIX) (int dst)
 {
     for (; dst < 32; dst++, T0 += 4) {
-        env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint64_t)T0);
+        GPR(env, dst) = glue(ldu32r, MEMSUFFIX)((uint64_t)T0);
     }
 }
 #endif
@@ -72,7 +72,7 @@
 void glue(do_stmw_le, MEMSUFFIX) (int src)
 {
     for (; src < 32; src++, T0 += 4) {
-        glue(st32r, MEMSUFFIX)((uint32_t)T0, env->gpr[src]);
+        glue(st32r, MEMSUFFIX)((uint32_t)T0, GPR(env, src));
     }
 }
 
@@ -80,7 +80,7 @@
 void glue(do_stmw_le_64, MEMSUFFIX) (int src)
 {
     for (; src < 32; src++, T0 += 4) {
-        glue(st32r, MEMSUFFIX)((uint64_t)T0, env->gpr[src]);
+        glue(st32r, MEMSUFFIX)((uint64_t)T0, GPR(env, src));
     }
 }
 #endif
@@ -91,7 +91,7 @@
     int sh;
 
     for (; T1 > 3; T1 -= 4, T0 += 4) {
-        env->gpr[dst++] = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
+        GPR(env, dst++) = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
         if (unlikely(dst == 32))
             dst = 0;
     }
@@ -100,7 +100,7 @@
         for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
             tmp |= glue(ldu8, MEMSUFFIX)((uint32_t)T0) << sh;
         }
-        env->gpr[dst] = tmp;
+        GPR(env, dst) = tmp;
     }
 }
 
@@ -111,7 +111,7 @@
     int sh;
 
     for (; T1 > 3; T1 -= 4, T0 += 4) {
-        env->gpr[dst++] = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
+        GPR(env, dst++) = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
         if (unlikely(dst == 32))
             dst = 0;
     }
@@ -120,7 +120,7 @@
         for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
             tmp |= glue(ldu8, MEMSUFFIX)((uint64_t)T0) << sh;
         }
-        env->gpr[dst] = tmp;
+        GPR(env, dst) = tmp;
     }
 }
 #endif
@@ -130,13 +130,13 @@
     int sh;
 
     for (; T1 > 3; T1 -= 4, T0 += 4) {
-        glue(st32, MEMSUFFIX)((uint32_t)T0, env->gpr[src++]);
+        glue(st32, MEMSUFFIX)((uint32_t)T0, GPR(env, src++));
         if (unlikely(src == 32))
             src = 0;
     }
     if (unlikely(T1 != 0)) {
         for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
-            glue(st8, MEMSUFFIX)((uint32_t)T0, (env->gpr[src] >> sh) & 0xFF);
+            glue(st8, MEMSUFFIX)((uint32_t)T0, (GPR(env, src) >> sh) & 0xFF);
     }
 }
 
@@ -146,13 +146,13 @@
     int sh;
 
     for (; T1 > 3; T1 -= 4, T0 += 4) {
-        glue(st32, MEMSUFFIX)((uint64_t)T0, env->gpr[src++]);
+        glue(st32, MEMSUFFIX)((uint64_t)T0, GPR(env, src++));
         if (unlikely(src == 32))
             src = 0;
     }
     if (unlikely(T1 != 0)) {
         for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
-            glue(st8, MEMSUFFIX)((uint64_t)T0, (env->gpr[src] >> sh) & 0xFF);
+            glue(st8, MEMSUFFIX)((uint64_t)T0, (GPR(env, src) >> sh) & 0xFF);
     }
 }
 #endif
@@ -294,7 +294,7 @@
         c = glue(ldu8, MEMSUFFIX)((uint32_t)T0++);
         /* ra (if not 0) and rb are never modified */
         if (likely(reg != rb && (ra == 0 || reg != ra))) {
-            env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d);
+            GPR(env, reg) = (GPR(env, reg) & ~(0xFF << d)) | (c << d);
         }
         if (unlikely(c == T2))
             break;
target-ppc/translate.c +56 -25

145 lines not on this page · raw message

hw/ppc405_boards.c +7 -7
diff -r 8a7ea9ce5335 -r 6585f5f2be1b hw/ppc405_boards.c
@@ -297,7 +297,7 @@
         bd.bi_pci_busfreq = 33333333;
         bd.bi_opbfreq = 33333333;
         bdloc = ppc405_set_bootinfo(env, &bd, 0x00000001);
-        env->gpr[3] = bdloc;
+        GPR(env, 3) = bdloc;
         kernel_base = KERNEL_LOAD_ADDR;
         /* now we can load the kernel */
         kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
@@ -326,18 +326,18 @@
             initrd_base = 0;
             initrd_size = 0;
         }
-        env->gpr[4] = initrd_base;
-        env->gpr[5] = initrd_size;
+        GPR(env, 4) = initrd_base;
+        GPR(env, 5) = initrd_size;
         ppc_boot_device = 'm';
         if (kernel_cmdline != NULL) {
             len = strlen(kernel_cmdline);
             bdloc -= ((len + 255) & ~255);
             memcpy(phys_ram_base + bdloc, kernel_cmdline, len + 1);
-            env->gpr[6] = bdloc;
-            env->gpr[7] = bdloc + len;
+            GPR(env, 6) = bdloc;
+            GPR(env, 7) = bdloc + len;
         } else {
-            env->gpr[6] = 0;
-            env->gpr[7] = 0;
+            GPR(env, 6) = 0;
+            GPR(env, 7) = 0;
         }
         env->nip = KERNEL_LOAD_ADDR;
     } else {
hw/ppc_oldworld.c +20 -20
diff -r 8a7ea9ce5335 -r 6585f5f2be1b hw/ppc_oldworld.c
@@ -47,49 +47,49 @@
 
     /* same handler as PearPC, coming from the original MOL video
        driver. */
-    switch(env->gpr[5]) {
+    switch(GPR(env, 5)) {
     case 4:
         break;
     case 28: /* set_vmode */
-        if (env->gpr[6] != 1 || env->gpr[7] != 0)
-            env->gpr[3] = 1;
+        if (GPR(env, 6) != 1 || GPR(env, 7) != 0)
+            GPR(env, 3) = 1;
         else
-            env->gpr[3] = 0;
+            GPR(env, 3) = 0;
         break;
     case 29: /* get_vmode_info */
-        if (env->gpr[6] != 0) {
-            if (env->gpr[6] != 1 || env->gpr[7] != 0) {
-                env->gpr[3] = 1;
+        if (GPR(env, 6) != 0) {
+            if (GPR(env, 6) != 1 || GPR(env, 7) != 0) {
+                GPR(env, 3) = 1;
                 break;
             }
         }
-        env->gpr[3] = 0;
-        env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */
-        env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */
-        env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */
-        env->gpr[7] = 85 << 16; /* refresh rate */
-        env->gpr[8] = (graphic_depth + 7) & ~7; /* depth (round to byte) */
+        GPR(env, 3) = 0;
+        GPR(env, 4) = (1 << 16) | 1; /* num_vmodes, cur_vmode */
+        GPR(env, 5) = (1 << 16) | 0; /* num_depths, cur_depth_mode */
+        GPR(env, 6) = (graphic_width << 16) | graphic_height; /* w, h */
+        GPR(env, 7) = 85 << 16; /* refresh rate */
+        GPR(env, 8) = (graphic_depth + 7) & ~7; /* depth (round to byte) */
         linesize = ((graphic_depth + 7) >> 3) * graphic_width;
         linesize = (linesize + 3) & ~3;
-        env->gpr[9] = (linesize << 16) | 0; /* row_bytes, offset */
+        GPR(env, 9) = (linesize << 16) | 0; /* row_bytes, offset */
         break;
     case 31: /* set_video power */
-        env->gpr[3] = 0;
+        GPR(env, 3) = 0;
         break;
     case 39: /* video_ctrl */
-        if (env->gpr[6] == 0 || env->gpr[6] == 1)
-            vga_vbl_enabled = env->gpr[6];
-        env->gpr[3] = 0;
+        if (GPR(env, 6) == 0 || GPR(env, 6) == 1)
+            vga_vbl_enabled = GPR(env, 6);
+        GPR(env, 3) = 0;
         break;
     case 47:
         break;
     case 59: /* set_color */
         /* R6 = index, R7 = RGB */
-        env->gpr[3] = 0;
+        GPR(env, 3) = 0;
         break;
     case 64: /* get color */
         /* R6 = index */
-        env->gpr[3] = 0;
+        GPR(env, 3) = 0;
         break;
     case 116: /* set hwcursor */
         /* R6 = x, R7 = y, R8 = visible, R9 = data */
darwin-user/main.c +14 -14
diff -r 6585f5f2be1b -r f465712154ba darwin-user/main.c
@@ -491,21 +491,21 @@
         case POWERPC_EXCP_SYSCALL_USER:
             /* system call in user-mode emulation */
             /* system call */
-            if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
-                ret = do_unix_syscall(env, env->gpr[0]/*, env->gpr[3], env->gpr[4],
-                                      env->gpr[5], env->gpr[6], env->gpr[7],
-                                      env->gpr[8], env->gpr[9], env->gpr[10]*/);
-            else if(((int)env->gpr[0])<0)
-                ret = do_mach_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
-                                      env->gpr[5], env->gpr[6], env->gpr[7],
-                                      env->gpr[8], env->gpr[9], env->gpr[10]);
+            if(((int)GPR(env, 0)) <= SYS_MAXSYSCALL && ((int)GPR(env, 0))>0)
+                ret = do_unix_syscall(env, GPR(env, 0)/*, GPR(env, 3), GPR(env, 4),
+                                      GPR(env, 5), GPR(env, 6), GPR(env, 7),
+                                      GPR(env, 8), GPR(env, 9), GPR(env, 10)*/);
+            else if(((int)GPR(env, 0))<0)
+                ret = do_mach_syscall(env, GPR(env, 0), GPR(env, 3), GPR(env, 4),
+                                      GPR(env, 5), GPR(env, 6), GPR(env, 7),
+                                      GPR(env, 8), GPR(env, 9), GPR(env, 10));
             else
-                ret = do_thread_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
-                                        env->gpr[5], env->gpr[6], env->gpr[7],
-                                        env->gpr[8], env->gpr[9], env->gpr[10]);
+                ret = do_thread_syscall(env, GPR(env, 0), GPR(env, 3), GPR(env, 4),
+                                        GPR(env, 5), GPR(env, 6), GPR(env, 7),
+                                        GPR(env, 8), GPR(env, 9), GPR(env, 10));
 
             /* Unix syscall error signaling */
-            if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
+            if(((int)GPR(env, 0)) <= SYS_MAXSYSCALL && ((int)GPR(env, 0))>0)
             {
                 if( (int)ret < 0 )
                     env->nip += 0;
@@ -514,7 +514,7 @@
             }
 
             /* Return value */
-            env->gpr[3] = ret;
+            GPR(env, 3) = ret;
             break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -1027,7 +1027,7 @@
 #endif
         env->nip = regs->nip;
         for(i = 0; i < 32; i++) {
-            env->gpr[i] = regs->gpr[i];
+            GPR(env, i) = regs->gpr[i];
         }
     }
 #else
darwin-user/qemu.h +1 -1
diff -r 6585f5f2be1b -r f465712154ba darwin-user/qemu.h
@@ -162,7 +162,7 @@
 static inline uint32_t get_int_arg(int *i, CPUPPCState *cpu_env)
 {
     /* XXX: won't work when args goes on stack after gpr10 */
-    uint32_t args = (uint32_t)(cpu_env->gpr[3+(*i & 0xff)/4]);
+    uint32_t args = (uint32_t)(GPR(cpu_env, 3+(*i & 0xff)/4));
     *i+=4;
     return tswap32(args);
 }
darwin-user/syscall.c +8 -8
diff -r 6585f5f2be1b -r f465712154ba darwin-user/syscall.c
@@ -963,11 +963,11 @@
 #elif TARGET_PPC
     {
         int i;
-        uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr;
+        CPUPPCState *env = (CPUPPCState*)cpu_env;
         for(i = 3; i < 11; i++)
-            *regs[i] = *regs[i+1];
+            GPR(env, i) = GPR(env, i+1);
         /* XXX: not necessary */
-        *regs[0] = new_num;
+        GPR(env, 0) = new_num;
     }
 #endif
     ret = do_unix_syscall(cpu_env, new_num);
@@ -979,11 +979,11 @@
     {
         int i;
         /* XXX: not really needed those regs are volatile accross calls */
-        uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr;
+        CPUPPCState *env = (CPUPPCState*)cpu_env;
         for(i = 11; i > 3; i--)
-            *regs[i] = *regs[i-1];
-        regs[3] = new_num;
-        *regs[0] = num;
+            GPR(env, i) = GPR(env, i-1);
+        GPR(env, 3) = new_num;
+        GPR(env, 0) = num;
     }
 #endif
     return ret;
@@ -1225,7 +1225,7 @@
     ((CPUX86State *)cpu_env)->regs[R_EDX] = (uint32_t)((r >> 32) & 0xffffffff) ;
 #elif defined TARGET_PPC
     ret = r & 0xffffffff; /* will be set to r3 after do_unix_syscall exit */
-    ((CPUPPCState *)cpu_env)->gpr[4] = (uint32_t)((r >> 32) & 0xffffffff) ;
+    GPR(((CPUPPCState *)cpu_env), 4) = (uint32_t)((r >> 32) & 0xffffffff) ;
 #else
     qerror("64 bit ret value on your arch?");
 #endif
target-ppc/helper.c +1 -1
diff -r 6585f5f2be1b -r f465712154ba target-ppc/helper.c
@@ -2349,7 +2349,7 @@
         /* NOTE: this is a temporary hack to support graphics OSI
            calls from the MOL driver */
         /* XXX: To be removed */
-        if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
+        if (GPR(env, 3) == 0x113724fa && GPR(env, 4) == 0x77810f9b &&
             env->osi_call) {
             if (env->osi_call(env) != 0) {
                 env->exception_index = POWERPC_EXCP_NONE;
#1 lore raw
Quoted 8 lines · Nathan Froyd

The (large, invasive) patch below is a preparation patch for converting (most) SPE instructions to use TCG. The rationale is that your ordinary SPE instruction deals with three 64-bit quantaties (and a potential 64-bit accumulator). In the current implementation, it's extremely laborious/difficult to pass those 64-bit quantaties to helpers, since the high/low words for SPE registers are not contiguous in the environment. (TCG helpers for SPE instructions are not yet implemented, but they will be necessary as part of the total conversion to TCG.)

I should clarify here that I meant passing pointers to the 64-bit quantities; Paul pointed out to me that passing 64-bit arguments obviously works, since you can emulate 64-bit targets on a 32-bit host. I thought I would need to pass pointers to 64-bit quantities since that's how, e.g., MMX helpers work, but that may not be the best example of how TCG is supposed to be used.

I still like my patch for exposing the halves of the registers directly and thereby opening up more efficient translation of some things, but it appears that there are better ways to do what I want to do.

-Nathan

#2 lore raw
In reply to Nathan Froyd
Quoted 8 lines · Nathan Froyd

The (large, invasive) patch below is a preparation patch for converting (most) SPE instructions to use TCG. The rationale is that your ordinary SPE instruction deals with three 64-bit quantaties (and a potential 64-bit accumulator). In the current implementation, it's extremely laborious/difficult to pass those 64-bit quantaties to helpers, since the high/low words for SPE registers are not contiguous in the environment. (TCG helpers for SPE instructions are not yet implemented, but they will be necessary as part of the total conversion to TCG.)

Constructing and passing 64-bit arguments from a pair of 32-bit values should be fairly simple with TCG. There's no reason to pass low and high halves of a value separately.

Quoted 3 lines

I don't know if the introduction of so many tcg_global_mem_new's will be detrimental to TCG's performance, but I will leave comment on that to somebody more expert than I.

I'm not sure if tcg variables are allowed to overlap. I suspect requiring they be unique simplifies code generation, but don't know if the current TCG code takes care of this.

Paul

#3 lore raw
In reply to Nathan Froyd
Quoted 8 lines · Nathan Froyd

The (large, invasive) patch below is a preparation patch for converting (most) SPE instructions to use TCG. The rationale is that your ordinary SPE instruction deals with three 64-bit quantaties (and a potential 64-bit accumulator). In the current implementation, it's extremely laborious/difficult to pass those 64-bit quantaties to helpers, since the high/low words for SPE registers are not contiguous in the environment. (TCG helpers for SPE instructions are not yet implemented, but they will be necessary as part of the total conversion to TCG.)

You can pass 64-bit TCG registers to helpers. And you can create one TCG 64-bit value from two 32-bits value if needed, and split it back later. This is exactly what is already done with load_gpr64() and store_gpr64().

Then the limit on the number of arguments of TCG helpers is not a problem anymore.

Signature · 4 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net