summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-01-21 16:43:49 +0100
committerMike Pall <mike>2013-01-21 16:43:49 +0100
commit89e4650baef2f67b12b2a7d9c91a8809f552568a (patch)
tree103638bdfba80ad8defaca562765efdf98a99ee0
parent2c293a96deb33a9a24f7b9dacd301ab70edbd559 (diff)
downloadluajit2-89e4650baef2f67b12b2a7d9c91a8809f552568a.tar.gz
Add XBox 360 port.
Thanks to Eddie Edwards.
-rw-r--r--doc/install.html32
-rw-r--r--doc/luajit.html2
-rw-r--r--src/host/buildvm.c6
-rw-r--r--src/host/buildvm_peobj.c34
-rw-r--r--src/lj_arch.h2
-rw-r--r--src/lj_def.h32
-rw-r--r--src/lj_frame.h11
-rw-r--r--src/vm_ppc.dasc46
-rw-r--r--src/xedkbuild.bat91
9 files changed, 232 insertions, 24 deletions
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:
<tr class="even">
<td class="compatcpu"><a href="#cross2">PPC</a></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 compatno">&nbsp;</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">XEDK (<a href="#xbox360">XBox 360</a>)</td>
</tr>
<tr class="odd">
<td class="compatcpu"><a href="#cross2">PPC/e500v2</a></td>
@@ -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
</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>
<p>
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 &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>
</table>
<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 class="feature compiler">
<tr><td>GCC</td><td>CLANG<br>LLVM</td><td>MSVC</td></tr>
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 and not FRAME32
+| ld r0, SAVE_LR
+|.else
+| lwz r0, SAVE_LR
+|.endif
|.if GPR64
-| ld r0, SAVE_LR; ld r12, SAVE_CR
+| ld r12, SAVE_CR
|.else
-| lwz r0, SAVE_LR; lwz r12, SAVE_CR
+| 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