From: Frank T. <fra...@gm...> - 2012-06-19 00:27:14
|
Given the high level of interest in improving SheepShaver, it seems like it might be good to get it to the point at which it compiles on newer versions of Mac O.S., which probably means getting the code to compile in clang-llvm. The code (or at least the first bit of it) that breaks llvm is on line 79 of SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp. It calls a number of macros from that file and from other files, which I have consolidated here: { #define OPPROTO #if SIZEOF_VOID_P == 4 typedef uint32 uintptr; typedef int32 intptr; #elif SIZEOF_VOID_P == 8 typedef uint64 uintptr; typedef int64 intptr; #else #error "Unsupported size of pointer" #endif #if defined(__APPLE__) && defined(__MACH__) static int __op_PARAM1, __op_PARAM2, __op_PARAM3; #else extern int __op_PARAM1, __op_PARAM2, __op_PARAM3; #endif #define PARAM1 ((long)(&__op_PARAM1)) #define PARAM2 ((long)(&__op_PARAM2)) #define PARAM3 ((long)(&__op_PARAM3)) #define REG_CPU AREG0 #define REG_CPU_ID AREG0_ID #define REG_T0 AREG1 #define REG_T0_ID AREG1_ID #define REG_T1 AREG2 #define REG_T1_ID AREG2_ID #define REG_T2 AREG3 #define REG_T2_ID AREG3_ID #ifdef AREG4 #define REG_T3 AREG4 #define REG_T3_ID AREG4_ID // This is what gives us A0 and A1 and A2. #define DYNGEN_DEFINE_GLOBAL_REGISTER(REG) \ register uintptr A##REG asm(REG_T##REG); \ register uint32 T##REG asm(REG_T##REG) DYNGEN_DEFINE_GLOBAL_REGISTER(0); DYNGEN_DEFINE_GLOBAL_REGISTER(1); DYNGEN_DEFINE_GLOBAL_REGISTER(2); #if defined __x86_64__ #define MOV_AD_REG(PARAM, REG) asm volatile ("movabsq $__op_" #PARAM ",%0" : "=r" (REG)) #else #define MOV_AD_REG(PARAM, REG) REG = PARAM #endif #define DEFINE_OP(REG) \ void OPPROTO op_mov_ad_##REG##_im(void) \ { \ MOV_AD_REG(PARAM1, REG); \ } }. The problematic line is { DEFINE_OP(A0); } and seems to expand to { void op_mov_ad_A0_im(void) { asm volatile ("movabsq $__op_" ((long)(&__op_PARAM1)) ",%0" : "=r" (A0)) ; } }. __op_PARAM1 is defined as a static or external and possibly signed integer (depending upon platform) in dyngen-exec.h. The operation is apparently (judging from the 32-bit branch) designed to stuff the value of __op_PARAM1 (which is normally 32 bits but could be shorter or longer) into A0 (which is 64-bit on x86-64). I am not familiar with the __op_ token in asm and cannot find any information on it. Does anybody know what is happening here? Would it be unreasonable to allow the simple assignment if a long on the platform in question is the same size as the target register? |