reorganize register set for SPE + TCG
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 definedTARGET_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
@@ -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 ;
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
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
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