Add XBox 360 port.

Thanks to Eddie Edwards.
This commit is contained in:
Mike Pall 2013-01-21 16:43:49 +01:00
parent 2c293a96de
commit 89e4650bae
9 changed files with 233 additions and 25 deletions

View File

@ -134,9 +134,9 @@ operating systems, CPUs and compilers:
<tr class="even"> <tr class="even">
<td class="compatcpu"><a href="#cross2">PPC</a></td> <td class="compatcpu"><a href="#cross2">PPC</a></td>
<td class="compatos">GCC 4.3+</td> <td class="compatos">GCC 4.3+</td>
<td class="compatos">GCC 4.3+<br>GCC 4.1 (<a href="#cross2">PS3</a>)</td> <td class="compatos">GCC 4.3+<br>GCC 4.1 (<a href="#ps3">PS3</a>)</td>
<td class="compatos compatno">&nbsp;</td>
<td class="compatos compatno">&nbsp;</td> <td class="compatos compatno">&nbsp;</td>
<td class="compatos">XEDK (<a href="#xbox360">XBox 360</a>)</td>
</tr> </tr>
<tr class="odd"> <tr class="odd">
<td class="compatcpu"><a href="#cross2">PPC/e500v2</a></td> <td class="compatcpu"><a href="#cross2">PPC/e500v2</a></td>
@ -376,7 +376,7 @@ CPU.
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \ make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
TARGET_CFLAGS="-mfloat-abi=soft" 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- \ make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
TARGET_CFLAGS="-mcpu=cortex-a8 -mfloat-abi=softfp" 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- make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
# PPC/e500v2 (fast interpreter only) # PPC/e500v2 (fast interpreter only)
make HOST_CC="gcc -m32" CROSS=powerpc-e500v2-linux-gnuspe- 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 # MIPS big-endian
make HOST_CC="gcc -m32" CROSS=mips-linux- 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" \ make HOST_CC="gcc -m32 -arch i386" CROSS=$ISDKP TARGET_FLAGS="$ISDKF" \
TARGET_SYS=iOS TARGET_SYS=iOS
</pre> </pre>
<p>
You can cross-compile for <b id="ps3">PS3</b> using the PS3&nbsp;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:
</p>
<pre class="code">
make HOST_CC="gcc -m32" CROSS=ppu-lv2-
</pre>
<p>
You can cross-compile for <b id="xbox360">XBox 360</b> using the
XBox&nbsp;360 SDK (MSVC + XEDK). Due to restrictions on consoles, the
JIT compiler is disabled and only the fast interpreter is built.
</p>
<p>
Open a "Visual Studio .NET Command Prompt" (32&nbsp;bit host compiler),
<tt>cd</tt> to the directory where you've unpacked the sources and run
the following commands. This builds a static library <tt>luajit20.lib</tt>,
which can be linked against your game, just like the Lua library.
</p>
<pre class="code">
cd src
xedkbuild
</pre>
<h2 id="embed">Embedding LuaJIT</h2> <h2 id="embed">Embedding LuaJIT</h2>
<p> <p>

View File

@ -158,7 +158,7 @@ LuaJIT is Copyright &copy; 2005-2012 Mike Pall, released under the
<tr><td>Windows</td><td>Linux</td><td>BSD</td><td>OSX</td><td>POSIX</td></tr> <tr><td>Windows</td><td>Linux</td><td>BSD</td><td>OSX</td><td>POSIX</td></tr>
</table> </table>
<table class="feature os os2"> <table class="feature os os2">
<tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td><td>PS3</td></tr> <tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td><td>PS3</td><td>XBox 360</td></tr>
</table> </table>
<table class="feature compiler"> <table class="feature compiler">
<tr><td>GCC</td><td>CLANG<br>LLVM</td><td>MSVC</td></tr> <tr><td>GCC</td><td>CLANG<br>LLVM</td><td>MSVC</td></tr>

View File

@ -100,6 +100,8 @@ static const char *sym_decorate(BuildCtx *ctx,
char *p; char *p;
#if LJ_64 #if LJ_64
const char *symprefix = ctx->mode == BUILD_machasm ? "_" : ""; const char *symprefix = ctx->mode == BUILD_machasm ? "_" : "";
#elif LJ_TARGET_XBOX360
const char *symprefix = "";
#else #else
const char *symprefix = ctx->mode != BUILD_elfasm ? "_" : ""; const char *symprefix = ctx->mode != BUILD_elfasm ? "_" : "";
#endif #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].sym = relocmap[idx];
ctx->reloc[ctx->nreloc].type = type; ctx->reloc[ctx->nreloc].type = type;
ctx->nreloc++; 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. */ return 0; /* Encode symbol offset of 0. */
#endif
} }
/* Naive insertion sort. Performance doesn't matter here. */ /* Naive insertion sort. Performance doesn't matter here. */

View File

@ -9,7 +9,7 @@
#include "buildvm.h" #include "buildvm.h"
#include "lj_bc.h" #include "lj_bc.h"
#if LJ_TARGET_X86ORX64 #if LJ_TARGET_X86ORX64 || LJ_TARGET_PPC
/* Context for PE object emitter. */ /* Context for PE object emitter. */
static char *strtab; static char *strtab;
@ -84,11 +84,21 @@ typedef struct PEsymaux {
#define PEOBJ_ARCH_TARGET 0x014c #define PEOBJ_ARCH_TARGET 0x014c
#define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */ #define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */
#define PEOBJ_RELOC_DIR32 0x06 #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 #elif LJ_TARGET_X64
#define PEOBJ_ARCH_TARGET 0x8664 #define PEOBJ_ARCH_TARGET 0x8664
#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */ #define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */
#define PEOBJ_RELOC_DIR32 0x02 #define PEOBJ_RELOC_DIR32 0x02
#define PEOBJ_RELOC_ADDR32NB 0x03 #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 #endif
/* Section numbers (0-based). */ /* Section numbers (0-based). */
@ -170,12 +180,6 @@ void emit_peobj(BuildCtx *ctx)
int i, nrsym; int i, nrsym;
union { uint8_t b; uint32_t u; } host_endian; 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); sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection);
/* Fill in PE sections. */ /* Fill in PE sections. */
@ -186,7 +190,7 @@ void emit_peobj(BuildCtx *ctx)
pesect[PEOBJ_SECT_TEXT].relocofs = sofs; pesect[PEOBJ_SECT_TEXT].relocofs = sofs;
sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE; sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE;
/* Flags: 60 = read+execute, 50 = align16, 20 = code. */ /* 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 #if LJ_TARGET_X64
memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1); 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); owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS);
/* Write .text section. */ /* 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); owrite(ctx, ctx->code, ctx->codesz);
for (i = 0; i < ctx->nreloc; i++) { for (i = 0; i < ctx->nreloc; i++) {
PEreloc reloc; 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.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; reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);

View File

@ -398,7 +398,7 @@
#endif #endif
/* Various workarounds for embedded operating systems. */ /* 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 #define LUAJIT_NO_LOG2
#endif #endif
#if defined(__symbian__) #if defined(__symbian__)

View File

@ -242,12 +242,18 @@ static LJ_AINLINE uint32_t lj_getu32(const void *p)
#define LJ_FASTCALL __fastcall #define LJ_FASTCALL __fastcall
#endif #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(_BitScanForward)
#pragma intrinsic(_BitScanReverse) #pragma intrinsic(_BitScanReverse)
unsigned char _BitScanForward(uint32_t *, unsigned long); unsigned char _BitScanForward(uint32_t *, unsigned long);
unsigned char _BitScanReverse(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) 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; 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_bswap(x) (_byteswap_ulong((x)))
#define lj_bswap64(x) (_byteswap_uint64((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_getu16(p) (*(uint16_t *)(p))
#define lj_getu32(p) (*(uint32_t *)(p)) #define lj_getu32(p) (*(uint32_t *)(p))
#endif
#else #else
#error "missing defines for your compiler" #error "missing defines for your compiler"

View File

@ -104,7 +104,16 @@ enum {
#endif #endif
#define CFRAME_SHIFT_MULTRES 3 #define CFRAME_SHIFT_MULTRES 3
#elif LJ_TARGET_PPC #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_ERRF 472
#define CFRAME_OFS_NRES 468 #define CFRAME_OFS_NRES 468
#define CFRAME_OFS_PREV 448 #define CFRAME_OFS_PREV 448

View File

@ -21,6 +21,7 @@
|// Note: a full PPC64 _LP64 port is not planned. |// Note: a full PPC64 _LP64 port is not planned.
|// GPR64 64 bit registers (but possibly 32 bit pointers, e.g. PS3). |// GPR64 64 bit registers (but possibly 32 bit pointers, e.g. PS3).
|// Affects reg saves, stack layout, carry/overflow/dot flags etc. |// 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). |// TOC Need table of contents (64 bit or 32 bit variant, e.g. PS3).
|// Function pointers are really a struct: code, TOC, env (optional). |// Function pointers are really a struct: code, TOC, env (optional).
|// TOCENV Function pointers have an environment pointer, too (not on PS3). |// 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. |// Stack layout while in interpreter. Must match with lj_frame.h.
|.if GPR64 |.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. |// 508(sp) // \ 32 bit C frame info.
|.define SAVE_ERRF, 472(sp) // | |.define SAVE_ERRF, 472(sp) // |
@ -155,6 +187,7 @@
|.define TMPD, TMPD_HI |.define TMPD, TMPD_HI
|.define TONUM_D, TONUM_HI |.define TONUM_D, TONUM_HI
| |
|.endif
|.else |.else
| |
|.define SAVE_LR, 276(sp) |.define SAVE_LR, 276(sp)
@ -201,7 +234,7 @@
|.endmacro |.endmacro
| |
|.macro saveregs |.macro saveregs
|.if GPR64 |.if GPR64 and not FRAME32
| stdu sp, -CFRAME_SPACE(sp) | stdu sp, -CFRAME_SPACE(sp)
|.else |.else
| stwu sp, -CFRAME_SPACE(sp) | stwu sp, -CFRAME_SPACE(sp)
@ -209,7 +242,7 @@
| save_ 14; save_ 15; save_ 16 | save_ 14; save_ 15; save_ 16
| mflr r0 | mflr r0
| save_ 17; save_ 18; save_ 19; save_ 20; save_ 21; save_ 22 | save_ 17; save_ 18; save_ 19; save_ 20; save_ 21; save_ 22
|.if GPR64 |.if GPR64 and not FRAME32
| std r0, SAVE_LR | std r0, SAVE_LR
|.else |.else
| stw r0, SAVE_LR | stw r0, SAVE_LR
@ -226,10 +259,15 @@
|.endmacro |.endmacro
| |
|.macro restoreregs |.macro restoreregs
|.if GPR64 |.if GPR64 and not FRAME32
| ld r0, SAVE_LR; ld r12, SAVE_CR | ld r0, SAVE_LR
|.else |.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 |.endif
| rest_ 14; rest_ 15; rest_ 16; rest_ 17; rest_ 18; rest_ 19 | rest_ 14; rest_ 15; rest_ 16; rest_ 17; rest_ 18; rest_ 19
| mtlr r0; | mtlr r0;

91
src/xedkbuild.bat Normal file
View File

@ -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