diff --git a/doc/install.html b/doc/install.html index 967f25fd..bb625ec8 100644 --- a/doc/install.html +++ b/doc/install.html @@ -134,9 +134,9 @@ operating systems, CPUs and compilers: PPC GCC 4.3+ -GCC 4.3+
GCC 4.1 (PS3) -  +GCC 4.3+
GCC 4.1 (PS3)   +XEDK (XBox 360) PPC/e500v2 @@ -376,7 +376,7 @@ CPU. make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \ TARGET_CFLAGS="-mfloat-abi=soft" -# ARM soft-float ABI with VFP (example for Cortex-a8) +# ARM soft-float ABI with VFP (example for Cortex-A8) make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \ TARGET_CFLAGS="-mcpu=cortex-a8 -mfloat-abi=softfp" @@ -387,8 +387,6 @@ make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf- make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu- # PPC/e500v2 (fast interpreter only) make HOST_CC="gcc -m32" CROSS=powerpc-e500v2-linux-gnuspe- -# PS3 (fast interpreter only) -make HOST_CC="gcc -m32" CROSS=ppu-lv2- # MIPS big-endian make HOST_CC="gcc -m32" CROSS=mips-linux- @@ -460,6 +458,30 @@ ISDKF="-arch armv7 -isysroot $ISDK/SDKs/$ISDKVER" make HOST_CC="gcc -m32 -arch i386" CROSS=$ISDKP TARGET_FLAGS="$ISDKF" \ TARGET_SYS=iOS +

+You can cross-compile for PS3 using the PS3 SDK from +a Linux host or a Windows host (requires 32 bit MinGW (GCC) on the host, +too). Due to restrictions on consoles, the JIT compiler is disabled and +only the fast interpreter is built: +

+
+make HOST_CC="gcc -m32" CROSS=ppu-lv2-
+
+

+You can cross-compile for XBox 360 using the +XBox 360 SDK (MSVC + XEDK). Due to restrictions on consoles, the +JIT compiler is disabled and only the fast interpreter is built. +

+

+Open a "Visual Studio .NET Command Prompt" (32 bit host compiler), +cd to the directory where you've unpacked the sources and run +the following commands. This builds a static library luajit20.lib, +which can be linked against your game, just like the Lua library. +

+
+cd src
+xedkbuild
+

Embedding LuaJIT

diff --git a/doc/luajit.html b/doc/luajit.html index 8fb0e05f..51338412 100644 --- a/doc/luajit.html +++ b/doc/luajit.html @@ -158,7 +158,7 @@ LuaJIT is Copyright © 2005-2012 Mike Pall, released under the WindowsLinuxBSDOSXPOSIX - +
EmbeddedAndroidiOSPS3
EmbeddedAndroidiOSPS3XBox 360
diff --git a/src/host/buildvm.c b/src/host/buildvm.c index 72b74f1f..b56ec1e1 100644 --- a/src/host/buildvm.c +++ b/src/host/buildvm.c @@ -100,6 +100,8 @@ static const char *sym_decorate(BuildCtx *ctx, char *p; #if LJ_64 const char *symprefix = ctx->mode == BUILD_machasm ? "_" : ""; +#elif LJ_TARGET_XBOX360 + const char *symprefix = ""; #else const char *symprefix = ctx->mode != BUILD_elfasm ? "_" : ""; #endif @@ -136,7 +138,11 @@ static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type) ctx->reloc[ctx->nreloc].sym = relocmap[idx]; ctx->reloc[ctx->nreloc].type = type; ctx->nreloc++; +#if LJ_TARGET_XBOX360 + return (int)(ctx->code - addr) + 4; /* Encode symbol offset of .text. */ +#else return 0; /* Encode symbol offset of 0. */ +#endif } /* Naive insertion sort. Performance doesn't matter here. */ diff --git a/src/host/buildvm_peobj.c b/src/host/buildvm_peobj.c index 17b3293a..28b771a3 100644 --- a/src/host/buildvm_peobj.c +++ b/src/host/buildvm_peobj.c @@ -9,7 +9,7 @@ #include "buildvm.h" #include "lj_bc.h" -#if LJ_TARGET_X86ORX64 +#if LJ_TARGET_X86ORX64 || LJ_TARGET_PPC /* Context for PE object emitter. */ static char *strtab; @@ -84,11 +84,21 @@ typedef struct PEsymaux { #define PEOBJ_ARCH_TARGET 0x014c #define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */ #define PEOBJ_RELOC_DIR32 0x06 +#define PEOBJ_RELOC_OFS 0 +#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */ #elif LJ_TARGET_X64 #define PEOBJ_ARCH_TARGET 0x8664 #define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */ #define PEOBJ_RELOC_DIR32 0x02 #define PEOBJ_RELOC_ADDR32NB 0x03 +#define PEOBJ_RELOC_OFS 0 +#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */ +#elif LJ_TARGET_PPC +#define PEOBJ_ARCH_TARGET 0x01f2 +#define PEOBJ_RELOC_REL32 0x06 +#define PEOBJ_RELOC_DIR32 0x02 +#define PEOBJ_RELOC_OFS (-4) +#define PEOBJ_TEXT_FLAGS 0x60400020 /* 60=r+x, 40=align8, 20=code. */ #endif /* Section numbers (0-based). */ @@ -170,12 +180,6 @@ void emit_peobj(BuildCtx *ctx) int i, nrsym; union { uint8_t b; uint32_t u; } host_endian; - host_endian.u = 1; - if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) { - fprintf(stderr, "Error: different byte order for host and target\n"); - exit(1); - } - sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection); /* Fill in PE sections. */ @@ -186,7 +190,7 @@ void emit_peobj(BuildCtx *ctx) pesect[PEOBJ_SECT_TEXT].relocofs = sofs; sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE; /* Flags: 60 = read+execute, 50 = align16, 20 = code. */ - pesect[PEOBJ_SECT_TEXT].flags = 0x60500020; + pesect[PEOBJ_SECT_TEXT].flags = PEOBJ_TEXT_FLAGS; #if LJ_TARGET_X64 memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1); @@ -236,10 +240,22 @@ void emit_peobj(BuildCtx *ctx) owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS); /* Write .text section. */ + host_endian.u = 1; + if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) { +#if LJ_TARGET_PPC + uint32_t *p = (uint32_t *)ctx->code; + int n = (int)(ctx->codesz >> 2); + for (i = 0; i < n; i++, p++) + *p = lj_bswap(*p); /* Byteswap .text section. */ +#else + fprintf(stderr, "Error: different byte order for host and target\n"); + exit(1); +#endif + } owrite(ctx, ctx->code, ctx->codesz); for (i = 0; i < ctx->nreloc; i++) { PEreloc reloc; - reloc.vaddr = (uint32_t)ctx->reloc[i].ofs; + reloc.vaddr = (uint32_t)ctx->reloc[i].ofs + PEOBJ_RELOC_OFS; reloc.symidx = 1+2+ctx->reloc[i].sym; /* Reloc syms are after .text sym. */ reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32; owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); diff --git a/src/lj_arch.h b/src/lj_arch.h index 10071ca4..4be2f566 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -398,7 +398,7 @@ #endif /* Various workarounds for embedded operating systems. */ -#if (defined(__ANDROID__) && !defined(LJ_TARGET_X86ORX64)) || defined(__symbian__) +#if (defined(__ANDROID__) && !defined(LJ_TARGET_X86ORX64)) || defined(__symbian__) || LJ_TARGET_XBOX360 #define LUAJIT_NO_LOG2 #endif #if defined(__symbian__) diff --git a/src/lj_def.h b/src/lj_def.h index a28d84d7..3d8a972d 100644 --- a/src/lj_def.h +++ b/src/lj_def.h @@ -242,12 +242,18 @@ static LJ_AINLINE uint32_t lj_getu32(const void *p) #define LJ_FASTCALL __fastcall #endif +#ifdef _M_PPC +#pragma intrinsic(_CountLeadingZeros) +unsigned int _CountLeadingZeros(long); +static LJ_AINLINE uint32_t lj_fls(uint32_t x) +{ + return _CountLeadingZeros(x) ^ 31; +} +#else #pragma intrinsic(_BitScanForward) #pragma intrinsic(_BitScanReverse) unsigned char _BitScanForward(uint32_t *, unsigned long); unsigned char _BitScanReverse(uint32_t *, unsigned long); -unsigned long _byteswap_ulong(unsigned long); -uint64_t _byteswap_uint64(uint64_t); static LJ_AINLINE uint32_t lj_ffs(uint32_t x) { @@ -258,13 +264,33 @@ static LJ_AINLINE uint32_t lj_fls(uint32_t x) { uint32_t r; _BitScanReverse(&r, x); return r; } +#endif +unsigned long _byteswap_ulong(unsigned long); +uint64_t _byteswap_uint64(uint64_t); #define lj_bswap(x) (_byteswap_ulong((x))) #define lj_bswap64(x) (_byteswap_uint64((x))) -/* MSVC is only supported on x86/x64, where unaligned loads are always ok. */ +#if defined(_M_PPC) && defined(LUAJIT_NO_UNALIGNED) +/* +** Replacement for unaligned loads on XBox 360. Disabled by default since it's +** usually more costly than the occasional stall when crossing a cache-line. +*/ +static LJ_AINLINE uint16_t lj_getu16(const void *v) +{ + const uint8_t *p = (const uint8_t *)v; + return (uint16_t)((p[0]<<8) | p[1]); +} +static LJ_AINLINE uint32_t lj_getu32(const void *v) +{ + const uint8_t *p = (const uint8_t *)v; + return (uint32_t)((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]); +} +#else +/* Unaligned loads are generally ok on x86/x64. */ #define lj_getu16(p) (*(uint16_t *)(p)) #define lj_getu32(p) (*(uint32_t *)(p)) +#endif #else #error "missing defines for your compiler" diff --git a/src/lj_frame.h b/src/lj_frame.h index b8af2349..99b349c2 100644 --- a/src/lj_frame.h +++ b/src/lj_frame.h @@ -104,7 +104,16 @@ enum { #endif #define CFRAME_SHIFT_MULTRES 3 #elif LJ_TARGET_PPC -#if LJ_ARCH_PPC64 +#if LJ_TARGET_XBOX360 +#define CFRAME_OFS_ERRF 424 +#define CFRAME_OFS_NRES 420 +#define CFRAME_OFS_PREV 400 +#define CFRAME_OFS_L 416 +#define CFRAME_OFS_PC 412 +#define CFRAME_OFS_MULTRES 408 +#define CFRAME_SIZE 384 +#define CFRAME_SHIFT_MULTRES 3 +#elif LJ_ARCH_PPC64 #define CFRAME_OFS_ERRF 472 #define CFRAME_OFS_NRES 468 #define CFRAME_OFS_PREV 448 diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index ac572ec5..19692638 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc @@ -21,6 +21,7 @@ |// Note: a full PPC64 _LP64 port is not planned. |// GPR64 64 bit registers (but possibly 32 bit pointers, e.g. PS3). |// Affects reg saves, stack layout, carry/overflow/dot flags etc. +|// FRAME32 Use 32 bit frame layout, even with GPR64 (XBox 360). |// TOC Need table of contents (64 bit or 32 bit variant, e.g. PS3). |// Function pointers are really a struct: code, TOC, env (optional). |// TOCENV Function pointers have an environment pointer, too (not on PS3). @@ -128,6 +129,37 @@ | |// Stack layout while in interpreter. Must match with lj_frame.h. |.if GPR64 +|.if FRAME32 +| +|// 456(sp) // \ 32/64 bit C frame info +|.define TONUM_LO, 452(sp) // | +|.define TONUM_HI, 448(sp) // | +|.define TMPD_LO, 444(sp) // | +|.define TMPD_HI, 440(sp) // | +|.define SAVE_CR, 432(sp) // | 64 bit CR save. +|.define SAVE_ERRF, 424(sp) // > Parameter save area. +|.define SAVE_NRES, 420(sp) // | +|.define SAVE_L, 416(sp) // | +|.define SAVE_PC, 412(sp) // | +|.define SAVE_MULTRES, 408(sp) // | +|.define SAVE_CFRAME, 400(sp) // / 64 bit C frame chain. +|// 392(sp) // Reserved. +|.define CFRAME_SPACE, 384 // Delta for sp. +|// Back chain for sp: 384(sp) <-- sp entering interpreter +|.define SAVE_LR, 376(sp) // 32 bit LR stored in hi-part. +|.define SAVE_GPR_, 232 // .. 232+18*8: 64 bit GPR saves. +|.define SAVE_FPR_, 88 // .. 88+18*8: 64 bit FPR saves. +|// 80(sp) // Needed for 16 byte stack frame alignment. +|// 16(sp) // Callee parameter save area (ABI mandated). +|// 8(sp) // Reserved +|// Back chain for sp: 0(sp) <-- sp while in interpreter +|// 32 bit sp stored in hi-part of 0(sp). +| +|.define TMPD_BLO, 447(sp) +|.define TMPD, TMPD_HI +|.define TONUM_D, TONUM_HI +| +|.else | |// 508(sp) // \ 32 bit C frame info. |.define SAVE_ERRF, 472(sp) // | @@ -155,6 +187,7 @@ |.define TMPD, TMPD_HI |.define TONUM_D, TONUM_HI | +|.endif |.else | |.define SAVE_LR, 276(sp) @@ -201,7 +234,7 @@ |.endmacro | |.macro saveregs -|.if GPR64 +|.if GPR64 and not FRAME32 | stdu sp, -CFRAME_SPACE(sp) |.else | stwu sp, -CFRAME_SPACE(sp) @@ -209,7 +242,7 @@ | save_ 14; save_ 15; save_ 16 | mflr r0 | save_ 17; save_ 18; save_ 19; save_ 20; save_ 21; save_ 22 -|.if GPR64 +|.if GPR64 and not FRAME32 | std r0, SAVE_LR |.else | stw r0, SAVE_LR @@ -226,10 +259,15 @@ |.endmacro | |.macro restoreregs -|.if GPR64 -| ld r0, SAVE_LR; ld r12, SAVE_CR +|.if GPR64 and not FRAME32 +| ld r0, SAVE_LR |.else -| lwz r0, SAVE_LR; lwz r12, SAVE_CR +| lwz r0, SAVE_LR +|.endif +|.if GPR64 +| ld r12, SAVE_CR +|.else +| lwz r12, SAVE_CR |.endif | rest_ 14; rest_ 15; rest_ 16; rest_ 17; rest_ 18; rest_ 19 | mtlr r0; diff --git a/src/xedkbuild.bat b/src/xedkbuild.bat new file mode 100644 index 00000000..0d84d92c --- /dev/null +++ b/src/xedkbuild.bat @@ -0,0 +1,91 @@ +@rem Script to build LuaJIT with the XBox 360 SDK. +@rem Donated to the public domain. +@rem +@rem Open a "Visual Studio .NET Command Prompt" (32 bit host compiler) +@rem Then cd to this directory and run this script. + +@if not defined INCLUDE goto :FAIL +@if not defined XEDK goto :FAIL + +@setlocal +@rem ---- Host compiler ---- +@set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE +@set LJLINK=link /nologo +@set LJMT=mt /nologo +@set DASMDIR=..\dynasm +@set DASM=%DASMDIR%\dynasm.lua +@set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c + +%LJCOMPILE% host\minilua.c +@if errorlevel 1 goto :BAD +%LJLINK% /out:minilua.exe minilua.obj +@if errorlevel 1 goto :BAD +if exist minilua.exe.manifest^ + %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe + +@rem Error out for 64 bit host compiler +@minilua +@if errorlevel 8 goto :FAIL + +@set DASMFLAGS=-D GPR64 -D FRAME32 -D PPE -D SQRT -D DUALNUM +minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_ppc.dasc +@if errorlevel 1 goto :BAD + +%LJCOMPILE% /I "." /I %DASMDIR% /D_XBOX_VER=200 /DLUAJIT_TARGET=LUAJIT_ARCH_PPC host\buildvm*.c +@if errorlevel 1 goto :BAD +%LJLINK% /out:buildvm.exe buildvm*.obj +@if errorlevel 1 goto :BAD +if exist buildvm.exe.manifest^ + %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe + +buildvm -m peobj -o lj_vm.obj +@if errorlevel 1 goto :BAD +buildvm -m bcdef -o lj_bcdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m ffdef -o lj_ffdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m libdef -o lj_libdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m recdef -o lj_recdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m folddef -o lj_folddef.h lj_opt_fold.c +@if errorlevel 1 goto :BAD + +@rem ---- Cross compiler ---- +@set LJCOMPILE="%XEDK%\bin\win32\cl" /nologo /c /MT /O2 /W3 /GF /Gm- /GR- /GS- /Gy /openmp- /D_CRT_SECURE_NO_DEPRECATE /DNDEBUG /D_XBOX /D_LIB /DLUAJIT_USE_SYSMALLOC +@set LJLIB="%XEDK%\bin\win32\lib" /nologo + +@if "%1" neq "debug" goto :NODEBUG +@shift +@set LJCOMPILE="%LJCOMPILE%" /Zi +:NODEBUG +@if "%1"=="amalg" goto :AMALG +%LJCOMPILE% /DLUA_BUILD_AS_DLL lj_*.c lib_*.c +@if errorlevel 1 goto :BAD +%LJLIB% /OUT:luajit20.lib lj_*.obj lib_*.obj +@if errorlevel 1 goto :BAD +@goto :NOAMALG +:AMALG +%LJCOMPILE% /DLUA_BUILD_AS_DLL ljamalg.c +@if errorlevel 1 goto :BAD +%LJLIB% /OUT:luajit20.lib ljamalg.obj lj_vm.obj +@if errorlevel 1 goto :BAD +:NOAMALG + +@del *.obj *.manifest minilua.exe buildvm.exe +@echo. +@echo === Successfully built LuaJIT for XBox 360 === + +@goto :END +:BAD +@echo. +@echo ******************************************************* +@echo *** Build FAILED -- Please check the error messages *** +@echo ******************************************************* +@goto :END +:FAIL +@echo To run this script you must open a "Visual Studio .NET Command Prompt" +@echo (32 bit host compiler). The XBox 360 SDK must be installed, too. +:END
GCCCLANG
LLVM
MSVC