From: Dave D. <d-...@sh...> - 2010-10-18 18:43:34
|
The JIT compiler is broken when compiling in GCC 4.2. In GCC 4.0 a simple PPC instruction to move 0x0580 into GPR13 would compile into 2 instructions. The ebx register (AREG1) is used as a temporary register. 1B47B092 BB80050000 mov ebx,0x580 1B47B097 895D44 mov [ebp+0x44],ebx But the ebx register should be really be saved if your code is going to use it and starting in gcc 4.2 the compiler is enforcing this automatically. So using gcc 4.2 we are generating code that looks like 1B47B091 53 push ebx 1B47B092 BB80050000 mov ebx,0x580 1B47B097 5B pop ebx 1B47B098 53 push ebx 1B47B099 895D44 mov [ebp+0x44],ebx 1B47B09C 5B pop ebx The first 3 lines end up doing nothing… ebx is saved, loaded with a new value 0x0580, then immediately restored. End result is crashing emulation. To fix SheepShaver for 64-bit compilation on Mac OS X and gcc 4.2 we need to stop using the rbx register as a temporary. For 32-bit compatibility with gcc 4.2 there are no extra registers left for a fix so a more extensive change would be needed to strip out the push ebx...pop ebx pair. As everything is going 64-bit on the Mac now it is probably not worth the effort. In file SheepShaver/src/kpx_cpu/src/cpu/jit/amd64/dyngen-target-exec.h change enum { /* callee save registers */ #define AREG0 "rbp" AREG0_ID = 5, #define AREG1 "rbx" AREG1_ID = 3, #define AREG2 "r12" AREG2_ID = 12, #define AREG3 "r13" AREG3_ID = 13, #define AREG4 "r14" AREG4_ID = 14, #define AREG5 "r15" AREG5_ID = 15, to enum { /* callee save registers */ #define AREG0 "rbp" AREG0_ID = 5, #if (defined(__APPLE__) && defined(__MACH__)) #define AREG1 "r12" AREG1_ID = 12, #define AREG2 "r13" AREG2_ID = 13, #define AREG3 "r14" AREG3_ID = 14, #define AREG4 "r15" AREG4_ID = 15, #else #define AREG1 "rbx" AREG1_ID = 3, #define AREG2 "r12" AREG2_ID = 12, #define AREG3 "r13" AREG3_ID = 13, #define AREG4 "r14" AREG4_ID = 14, #define AREG5 "r15" AREG5_ID = 15, #endif |