Browse Source

ARM: Fix ABI and build issues for iOS. Now works on iOS 3.0+.

Mike Pall 14 years ago
parent
commit
0ba34ffe50
6 changed files with 335 additions and 197 deletions
  1. 27 15
      doc/install.html
  2. 18 0
      src/Makefile
  3. 1 1
      src/buildvm.c
  4. 69 6
      src/buildvm_arm.dasc
  5. 218 173
      src/buildvm_arm.h
  6. 2 2
      src/lj_arch.h

+ 27 - 15
doc/install.html

@@ -97,14 +97,14 @@ make && sudo make install
 <p>
 <p>
 LuaJIT currently builds out-of-the box on most systems.
 LuaJIT currently builds out-of-the box on most systems.
 Here's the compatibility matrix for the supported combinations of
 Here's the compatibility matrix for the supported combinations of
-operating system, CPU and compilers:
+operating systems, CPUs and compilers:
 </p>
 </p>
 <table class="compat">
 <table class="compat">
 <tr class="compathead">
 <tr class="compathead">
 <td class="compatcpu">CPU / OS</td>
 <td class="compatcpu">CPU / OS</td>
-<td class="compatos"><a href="#posix">Linux</a> or<br><a href="#cross">Android</a></td>
-<td class="compatos"><a href="#posix">*BSD, other</a></td>
-<td class="compatos"><a href="#posix">OSX<br>10.3-10.6</a></td>
+<td class="compatos"><a href="#posix">Linux</a> or<br><a href="#android">Android</a></td>
+<td class="compatos"><a href="#posix">*BSD, Other</a></td>
+<td class="compatos"><a href="#posix">OSX 10.3+</a> or<br><a href="#ios">iOS 3.0+</a></td>
 <td class="compatos"><a href="#windows">Windows<br>98/XP/Vista/7</a></td>
 <td class="compatos"><a href="#windows">Windows<br>98/XP/Vista/7</a></td>
 </tr>
 </tr>
 <tr class="odd separate">
 <tr class="odd separate">
@@ -122,10 +122,10 @@ operating system, CPU and compilers:
 <td class="compatos">MSVC + SDK v7.0<br>WinSDK v7.0</td>
 <td class="compatos">MSVC + SDK v7.0<br>WinSDK v7.0</td>
 </tr>
 </tr>
 <tr class="odd">
 <tr class="odd">
-<td class="compatcpu">ARM</td>
+<td class="compatcpu">ARMv5+<br>ARM9E+</td>
+<td class="compatos">GCC 4.2+</td>
 <td class="compatos">GCC 4.2+</td>
 <td class="compatos">GCC 4.2+</td>
 <td class="compatos">GCC 4.2+</td>
 <td class="compatos">GCC 4.2+</td>
-<td class="compatos compatno">&nbsp;</td>
 <td class="compatos compatno">&nbsp;</td>
 <td class="compatos compatno">&nbsp;</td>
 </tr>
 </tr>
 <tr class="even">
 <tr class="even">
@@ -342,14 +342,6 @@ installing the <tt>mingw32</tt> package and running:
 make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
 make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
 </pre>
 </pre>
 <p>
 <p>
-Whenever the <b>host OS and the target OS differ</b>, you need to specify
-<tt>TARGET_SYS</tt> or you'll get assembler or linker errors. E.g. if
-you're compiling on a Windows or OSX host for embedded Linux or Android,
-you need to add <tt>TARGET_SYS=Linux</tt> to the examples below. For a
-minimal target OS, you may need to disable the built-in allocator in
-<tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.
-</p>
-<p>
 You can cross-compile for an <b>ARM target</b> on an x86 or x64 host
 You can cross-compile for an <b>ARM target</b> on an x86 or x64 host
 system using a standard GNU cross-compile toolchain (Binutils, GCC,
 system using a standard GNU cross-compile toolchain (Binutils, GCC,
 EGLIBC). The <tt>CROSS</tt> prefix may vary depending on the
 EGLIBC). The <tt>CROSS</tt> prefix may vary depending on the
@@ -359,7 +351,7 @@ EGLIBC). The <tt>CROSS</tt> prefix may vary depending on the
 make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- TARGET=arm
 make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- TARGET=arm
 </pre>
 </pre>
 <p>
 <p>
-You can cross-compile for <b>Android (ARM)</b> using the <a href="http://developer.android.com/sdk/ndk/index.html"><span class="ext">&raquo;</span>&nbsp;Android NDK</a>.
+You can cross-compile for <b id="android">Android (ARM)</b> using the <a href="http://developer.android.com/sdk/ndk/index.html"><span class="ext">&raquo;</span>&nbsp;Android NDK</a>.
 The environment variables need to match the install locations and the
 The environment variables need to match the install locations and the
 desired target platform. E.g. Android&nbsp;2.2 corresponds to ABI level&nbsp;8:
 desired target platform. E.g. Android&nbsp;2.2 corresponds to ABI level&nbsp;8:
 </p>
 </p>
@@ -372,6 +364,18 @@ NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
 make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" TARGET=arm
 make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" TARGET=arm
 </pre>
 </pre>
 <p>
 <p>
+You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="http://developer.apple.com/devcenter/ios/index.action"><span class="ext">&raquo;</span>&nbsp;iOS SDK</a>.
+The environment variables need to match the iOS SDK version:
+</p>
+<pre class="code">
+ISDK=/Developer/Platforms/iPhoneOS.platform/Developer
+ISDKVER=iPhoneOS4.3.sdk
+ISDKP=$ISDK/usr/bin/
+ISDKF="-arch armv6 -isysroot $ISDK/SDKs/$ISDKVER"
+make HOST_CC="gcc -m32 -arch i386" CROSS=$ISDKP TARGET_FLAGS="$ISDKF" \
+     TARGET=arm TARGET_SYS=iOS
+</pre>
+<p>
 You can cross-compile for a <b>PPC/e500v2 target</b> on an x86 or x64 host system
 You can cross-compile for a <b>PPC/e500v2 target</b> on an x86 or x64 host system
 using a standard GNU cross-compile toolchain (Binutils, GCC, EGLIBC).
 using a standard GNU cross-compile toolchain (Binutils, GCC, EGLIBC).
 The <tt>CROSS</tt> prefix may vary depending on the <tt>--target</tt>
 The <tt>CROSS</tt> prefix may vary depending on the <tt>--target</tt>
@@ -380,6 +384,14 @@ of the toolchain:
 <pre class="code">
 <pre class="code">
 make HOST_CC="gcc -m32" CROSS=powerpc-e500v2-linux-gnuspe- TARGET=ppcspe
 make HOST_CC="gcc -m32" CROSS=powerpc-e500v2-linux-gnuspe- TARGET=ppcspe
 </pre>
 </pre>
+<p>
+Whenever the <b>host OS and the target OS differ</b>, you need to specify
+<tt>TARGET_SYS</tt> or you'll get assembler or linker errors. E.g. if
+you're compiling on a Windows or OSX host for embedded Linux or Android,
+you need to add <tt>TARGET_SYS=Linux</tt> to the examples above. For a
+minimal target OS, you may need to disable the built-in allocator in
+<tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.
+</p>
 
 
 <h2 id="embed">Embedding LuaJIT</h2>
 <h2 id="embed">Embedding LuaJIT</h2>
 <p>
 <p>

+ 18 - 0
src/Makefile

@@ -282,6 +282,16 @@ ifeq (Darwin,$(TARGET_SYS))
     TARGET_XLDFLAGS+= -pagezero_size 10000 -image_base 100000000
     TARGET_XLDFLAGS+= -pagezero_size 10000 -image_base 100000000
     TARGET_XSHLDFLAGS+= -image_base 7fff04c4a000
     TARGET_XSHLDFLAGS+= -image_base 7fff04c4a000
   endif
   endif
+else
+ifeq (iOS,$(TARGET_SYS))
+  TARGET_STRIP+= -x
+  TARGET_AR+= 2>/dev/null
+  TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
+  HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
+  ifneq (,$(TARGET_DYNXLDOPTS))
+    TARGET_DYNXLDOPTS=
+    TARGET_XSHLDFLAGS+= -install_name $(PREFIX)/lib/$(TARGET_DYLIBNAME)
+  endif
 else
 else
   TARGET_XLDFLAGS+= -Wl,-E
   TARGET_XLDFLAGS+= -Wl,-E
   ifeq (Linux,$(TARGET_SYS))
   ifeq (Linux,$(TARGET_SYS))
@@ -292,6 +302,7 @@ else
   endif
   endif
 endif
 endif
 endif
 endif
+endif
 
 
 ifneq (,$(CCDEBUG))
 ifneq (,$(CCDEBUG))
   TARGET_STRIP= @:
   TARGET_STRIP= @:
@@ -390,6 +401,9 @@ endif
 ifeq (Darwin,$(TARGET_SYS))
 ifeq (Darwin,$(TARGET_SYS))
   LJVM_MODE= machasm
   LJVM_MODE= machasm
 endif
 endif
+ifeq (iOS,$(TARGET_SYS))
+  LJVM_MODE= machasm
+endif
 
 
 ifeq (static,$(BUILDMODE))
 ifeq (static,$(BUILDMODE))
   TARGET_DYNCC= @:
   TARGET_DYNCC= @:
@@ -409,6 +423,10 @@ ifeq (Darwin,$(TARGET_SYS))
   TARGET_DYNCC= @:
   TARGET_DYNCC= @:
   LJVMCORE_DYNO= $(LJVMCORE_O)
   LJVMCORE_DYNO= $(LJVMCORE_O)
 endif
 endif
+ifeq (iOS,$(TARGET_SYS))
+  TARGET_DYNCC= @:
+  LJVMCORE_DYNO= $(LJVMCORE_O)
+endif
 endif
 endif
 endif
 endif
 
 

+ 1 - 1
src/buildvm.c

@@ -425,7 +425,7 @@ int main(int argc, char **argv)
 
 
   if (sizeof(void *) != 4*LJ_32+8*LJ_64) {
   if (sizeof(void *) != 4*LJ_32+8*LJ_64) {
     fprintf(stderr,"Error: pointer size mismatch in cross-build.\n");
     fprintf(stderr,"Error: pointer size mismatch in cross-build.\n");
-    fprintf(stderr,"Try: make CC=\"gcc -m32\" CROSS=... TARGET=...\n\n");
+    fprintf(stderr,"Try: make HOST_CC=\"gcc -m32\" CROSS=... TARGET=...\n\n");
     return 1;
     return 1;
   }
   }
 
 

+ 69 - 6
src/buildvm_arm.dasc

@@ -17,13 +17,15 @@
 |
 |
 |// Fixed register assignments for the interpreter.
 |// Fixed register assignments for the interpreter.
 |
 |
-|// The following must be C callee-save (but BASE is often refetched).
-|.define BASE,		r4	// Base of current Lua stack frame.
+|// The following must be C callee-save.
+|.define MASKR8,	r4	// 255*8 constant for fast bytecode decoding.
 |.define KBASE,		r5	// Constants of current Lua function.
 |.define KBASE,		r5	// Constants of current Lua function.
 |.define PC,		r6	// Next PC.
 |.define PC,		r6	// Next PC.
 |.define DISPATCH,	r7	// Opcode dispatch table.
 |.define DISPATCH,	r7	// Opcode dispatch table.
 |.define LREG,		r8	// Register holding lua_State (also in SAVE_L).
 |.define LREG,		r8	// Register holding lua_State (also in SAVE_L).
-|.define MASKR8,	r9	// 255*8 constant for fast bytecode decoding.
+|
+|// C callee-save in EABI, but often refetched. Temporary in iOS 3.0+.
+|.define BASE,		r9	// Base of current Lua stack frame.
 |
 |
 |// The following temporaries are not saved across C calls, except for RA/RC.
 |// The following temporaries are not saved across C calls, except for RA/RC.
 |.define RA,		r10	// Callee-save.
 |.define RA,		r10	// Callee-save.
@@ -204,6 +206,12 @@
 |  str tmp, tab->gclist
 |  str tmp, tab->gclist
 |.endmacro
 |.endmacro
 |
 |
+|.macro IOS, a, b
+||if (LJ_TARGET_OSX) {
+|  a, b
+||}
+|.endmacro
+|
 |//-----------------------------------------------------------------------
 |//-----------------------------------------------------------------------
 
 
 #if !LJ_DUALNUM
 #if !LJ_DUALNUM
@@ -550,6 +558,7 @@ static void build_subroutines(BuildCtx *ctx)
   |   str PC, SAVE_PC
   |   str PC, SAVE_PC
   |  bl extern lj_meta_tget		// (lua_State *L, TValue *o, TValue *k)
   |  bl extern lj_meta_tget		// (lua_State *L, TValue *o, TValue *k)
   |  // Returns TValue * (finished) or NULL (metamethod).
   |  // Returns TValue * (finished) or NULL (metamethod).
+  |  IOS ldr BASE, L->base
   |  cmp CRET1, #0
   |  cmp CRET1, #0
   |  beq >3
   |  beq >3
   |  ldrd CARG34, [CRET1]
   |  ldrd CARG34, [CRET1]
@@ -604,6 +613,7 @@ static void build_subroutines(BuildCtx *ctx)
   |   str PC, SAVE_PC
   |   str PC, SAVE_PC
   |  bl extern lj_meta_tset		// (lua_State *L, TValue *o, TValue *k)
   |  bl extern lj_meta_tset		// (lua_State *L, TValue *o, TValue *k)
   |  // Returns TValue * (finished) or NULL (metamethod).
   |  // Returns TValue * (finished) or NULL (metamethod).
+  |  IOS ldr BASE, L->base
   |  cmp CRET1, #0
   |  cmp CRET1, #0
   |   ldrd CARG34, [BASE, RA]
   |   ldrd CARG34, [BASE, RA]
   |  beq >3
   |  beq >3
@@ -637,6 +647,7 @@ static void build_subroutines(BuildCtx *ctx)
   |  bl extern lj_meta_comp  // (lua_State *L, TValue *o1, *o2, int op)
   |  bl extern lj_meta_comp  // (lua_State *L, TValue *o1, *o2, int op)
   |  // Returns 0/1 or TValue * (metamethod).
   |  // Returns 0/1 or TValue * (metamethod).
   |3:
   |3:
+  |  IOS ldr BASE, L->base
   |  cmp CRET1, #1
   |  cmp CRET1, #1
   |  bhi ->vmeta_binop
   |  bhi ->vmeta_binop
   |4:
   |4:
@@ -724,6 +735,7 @@ static void build_subroutines(BuildCtx *ctx)
   |  str OP, ARG5
   |  str OP, ARG5
   |  bl extern lj_meta_arith  // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
   |  bl extern lj_meta_arith  // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
   |  // Returns NULL (finished) or TValue * (metamethod).
   |  // Returns NULL (finished) or TValue * (metamethod).
+  |  IOS ldr BASE, L->base
   |  cmp CRET1, #0
   |  cmp CRET1, #0
   |  beq ->cont_nop
   |  beq ->cont_nop
   |
   |
@@ -744,6 +756,7 @@ static void build_subroutines(BuildCtx *ctx)
   |   str PC, SAVE_PC
   |   str PC, SAVE_PC
   |  bl extern lj_meta_len		// (lua_State *L, TValue *o)
   |  bl extern lj_meta_len		// (lua_State *L, TValue *o)
   |  // Returns TValue * (metamethod base).
   |  // Returns TValue * (metamethod base).
+  |  IOS ldr BASE, L->base
   |  b ->vmeta_binop			// Binop call for compatibility.
   |  b ->vmeta_binop			// Binop call for compatibility.
   |
   |
   |//-- Call metamethod ----------------------------------------------------
   |//-- Call metamethod ----------------------------------------------------
@@ -755,7 +768,9 @@ static void build_subroutines(BuildCtx *ctx)
   |  sub CARG2, BASE, #8
   |  sub CARG2, BASE, #8
   |   str PC, SAVE_PC
   |   str PC, SAVE_PC
   |  add CARG3, BASE, NARGS8:RC
   |  add CARG3, BASE, NARGS8:RC
+  |  IOS mov RA, BASE
   |  bl extern lj_meta_call	// (lua_State *L, TValue *func, TValue *top)
   |  bl extern lj_meta_call	// (lua_State *L, TValue *func, TValue *top)
+  |  IOS mov BASE, RA
   |  ldr LFUNC:CARG3, [BASE, FRAME_FUNC]  // Guaranteed to be a function here.
   |  ldr LFUNC:CARG3, [BASE, FRAME_FUNC]  // Guaranteed to be a function here.
   |   add NARGS8:RC, NARGS8:RC, #8	// Got one more argument now.
   |   add NARGS8:RC, NARGS8:RC, #8	// Got one more argument now.
   |  ins_call
   |  ins_call
@@ -768,6 +783,7 @@ static void build_subroutines(BuildCtx *ctx)
   |   str PC, SAVE_PC
   |   str PC, SAVE_PC
   |  add CARG3, RA, NARGS8:RC
   |  add CARG3, RA, NARGS8:RC
   |  bl extern lj_meta_call	// (lua_State *L, TValue *func, TValue *top)
   |  bl extern lj_meta_call	// (lua_State *L, TValue *func, TValue *top)
+  |  IOS ldr BASE, L->base
   |  ldr LFUNC:CARG3, [RA, FRAME_FUNC]  // Guaranteed to be a function here.
   |  ldr LFUNC:CARG3, [RA, FRAME_FUNC]  // Guaranteed to be a function here.
   |   ldr PC, [BASE, FRAME_PC]
   |   ldr PC, [BASE, FRAME_PC]
   |    add NARGS8:RC, NARGS8:RC, #8	// Got one more argument now.
   |    add NARGS8:RC, NARGS8:RC, #8	// Got one more argument now.
@@ -781,6 +797,7 @@ static void build_subroutines(BuildCtx *ctx)
   |  mov CARG2, RA
   |  mov CARG2, RA
   |   str PC, SAVE_PC
   |   str PC, SAVE_PC
   |  bl extern lj_meta_for	// (lua_State *L, TValue *base)
   |  bl extern lj_meta_for	// (lua_State *L, TValue *base)
+  |  IOS ldr BASE, L->base
 #if LJ_HASJIT
 #if LJ_HASJIT
   |   ldrb OP, [PC, #-4]
   |   ldrb OP, [PC, #-4]
 #endif
 #endif
@@ -935,8 +952,10 @@ static void build_subroutines(BuildCtx *ctx)
   |  checktab CARG4, ->fff_fallback
   |  checktab CARG4, ->fff_fallback
   |   mov CARG1, L
   |   mov CARG1, L
   |   add CARG3, BASE, #8
   |   add CARG3, BASE, #8
+  |  IOS mov RA, BASE
   |  bl extern lj_tab_get  // (lua_State *L, GCtab *t, cTValue *key)
   |  bl extern lj_tab_get  // (lua_State *L, GCtab *t, cTValue *key)
   |  // Returns cTValue *.
   |  // Returns cTValue *.
+  |  IOS mov BASE, RA
   |  ldrd CARG12, [CRET1]
   |  ldrd CARG12, [CRET1]
   |  b ->fff_restv
   |  b ->fff_restv
   |
   |
@@ -984,6 +1003,7 @@ static void build_subroutines(BuildCtx *ctx)
   |   str PC, SAVE_PC
   |   str PC, SAVE_PC
   |  bl extern lj_tab_next	// (lua_State *L, GCtab *t, TValue *key)
   |  bl extern lj_tab_next	// (lua_State *L, GCtab *t, TValue *key)
   |  // Returns 0 at end of traversal.
   |  // Returns 0 at end of traversal.
+  |  IOS ldr BASE, L->base
   |  cmp CRET1, #0
   |  cmp CRET1, #0
   |  mvneq CRET2, #~LJ_TNIL
   |  mvneq CRET2, #~LJ_TNIL
   |  beq ->fff_restv			// End of traversal: return nil.
   |  beq ->fff_restv			// End of traversal: return nil.
@@ -1035,8 +1055,10 @@ static void build_subroutines(BuildCtx *ctx)
   |   mov CARG2, CARG3
   |   mov CARG2, CARG3
   |  cmp RB, #0
   |  cmp RB, #0
   |  beq ->fff_res
   |  beq ->fff_res
+  |  IOS mov RA, BASE
   |  bl extern lj_tab_getinth		// (GCtab *t, int32_t key)
   |  bl extern lj_tab_getinth		// (GCtab *t, int32_t key)
   |  // Returns cTValue * or NULL.
   |  // Returns cTValue * or NULL.
+  |  IOS mov BASE, RA
   |  cmp CRET1, #0
   |  cmp CRET1, #0
   |  beq ->fff_res
   |  beq ->fff_res
   |  ldrd CARG12, [CRET1]
   |  ldrd CARG12, [CRET1]
@@ -1275,7 +1297,9 @@ static void build_subroutines(BuildCtx *ctx)
   |  bmi <1
   |  bmi <1
   |4:
   |4:
   |  // NYI: Use internal implementation.
   |  // NYI: Use internal implementation.
+  |  IOS mov RA, BASE
   |  bl extern func
   |  bl extern func
+  |  IOS mov BASE, RA
   |  b ->fff_restv
   |  b ->fff_restv
   |.endmacro
   |.endmacro
   |
   |
@@ -1330,13 +1354,17 @@ static void build_subroutines(BuildCtx *ctx)
   |
   |
   |.macro math_extern, func
   |.macro math_extern, func
   |  .ffunc_n math_ .. func
   |  .ffunc_n math_ .. func
+  |  IOS mov RA, BASE
   |  bl extern func
   |  bl extern func
+  |  IOS mov BASE, RA
   |  b ->fff_restv
   |  b ->fff_restv
   |.endmacro
   |.endmacro
   |
   |
   |.macro math_extern2, func
   |.macro math_extern2, func
   |  .ffunc_nn math_ .. func
   |  .ffunc_nn math_ .. func
+  |  IOS mov RA, BASE
   |  bl extern func
   |  bl extern func
+  |  IOS mov BASE, RA
   |  b ->fff_restv
   |  b ->fff_restv
   |.endmacro
   |.endmacro
   |
   |
@@ -1368,12 +1396,16 @@ static void build_subroutines(BuildCtx *ctx)
   |  bhs ->fff_fallback
   |  bhs ->fff_fallback
   |  checktp CARG4, LJ_TISNUM
   |  checktp CARG4, LJ_TISNUM
   |  bne ->fff_fallback
   |  bne ->fff_fallback
+  |  IOS mov RA, BASE
   |  bl extern ldexp			// (double x, int exp)
   |  bl extern ldexp			// (double x, int exp)
+  |  IOS mov BASE, RA
   |  b ->fff_restv
   |  b ->fff_restv
   |
   |
   |.ffunc_n math_frexp
   |.ffunc_n math_frexp
   |  mov CARG3, sp
   |  mov CARG3, sp
+  |  IOS mov RA, BASE
   |  bl extern frexp
   |  bl extern frexp
+  |  IOS mov BASE, RA
   |   ldr CARG3, [sp]
   |   ldr CARG3, [sp]
   |   mvn CARG4, #~LJ_TISNUM
   |   mvn CARG4, #~LJ_TISNUM
   |    ldr PC, [BASE, FRAME_PC]
   |    ldr PC, [BASE, FRAME_PC]
@@ -1385,7 +1417,9 @@ static void build_subroutines(BuildCtx *ctx)
   |.ffunc_n math_modf
   |.ffunc_n math_modf
   |  sub CARG3, BASE, #8
   |  sub CARG3, BASE, #8
   |   ldr PC, [BASE, FRAME_PC]
   |   ldr PC, [BASE, FRAME_PC]
+  |  IOS mov RA, BASE
   |  bl extern modf
   |  bl extern modf
+  |  IOS mov BASE, RA
   |   mov RC, #(2+1)*8
   |   mov RC, #(2+1)*8
   |  strd CARG12, [BASE]
   |  strd CARG12, [BASE]
   |  b ->fff_res
   |  b ->fff_res
@@ -1600,8 +1634,10 @@ static void build_subroutines(BuildCtx *ctx)
   |
   |
   |.ffunc_1 table_getn
   |.ffunc_1 table_getn
   |  checktab CARG2, ->fff_fallback
   |  checktab CARG2, ->fff_fallback
+  |  IOS mov RA, BASE
   |  bl extern lj_tab_len		// (GCtab *t)
   |  bl extern lj_tab_len		// (GCtab *t)
   |  // Returns uint32_t (but less than 2^31).
   |  // Returns uint32_t (but less than 2^31).
+  |  IOS mov BASE, RA
   |  mvn CARG2, #~LJ_TISNUM
   |  mvn CARG2, #~LJ_TISNUM
   |  b ->fff_restv
   |  b ->fff_restv
   |
   |
@@ -2347,8 +2383,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   ins_next3
     |   ins_next3
     |2:
     |2:
     |  checktab CARG2, ->vmeta_len
     |  checktab CARG2, ->vmeta_len
+    |  IOS mov RC, BASE
     |  bl extern lj_tab_len		// (GCtab *t)
     |  bl extern lj_tab_len		// (GCtab *t)
     |  // Returns uint32_t (but less than 2^31).
     |  // Returns uint32_t (but less than 2^31).
+    |  IOS mov BASE, RC
     |  b <1
     |  b <1
     break;
     break;
 
 
@@ -2434,8 +2472,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   ins_next3
     |   ins_next3
     |5:  // FP variant.
     |5:  // FP variant.
     |  ins_arithfallback ins_arithcheck_num
     |  ins_arithfallback ins_arithcheck_num
+    |.if "intins" == "vm_modi"
+    |  IOS mov RC, BASE
+    |  bl fpcall
+    |  IOS mov BASE, RC  // NYI: remove once we use internal impl. of floor.
+    |.else
     |  bl fpcall
     |  bl fpcall
-    |.if "intins" ~= "vm_modi"
     |   ins_next1
     |   ins_next1
     |.endif
     |.endif
     |  b <4
     |  b <4
@@ -2444,7 +2486,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |.macro ins_arithfp, fpcall
     |.macro ins_arithfp, fpcall
     |  ins_arithpre
     |  ins_arithpre
     |  ins_arithfallback ins_arithcheck_num
     |  ins_arithfallback ins_arithcheck_num
+    |.if "fpcall" == "extern pow"
+    |  IOS mov RC, BASE
     |  bl fpcall
     |  bl fpcall
+    |  IOS mov BASE, RC
+    |.else
+    |  bl fpcall
+    |.endif
     |   ins_next1
     |   ins_next1
     |   ins_next2
     |   ins_next2
     |  strd CARG12, [BASE, RA]
     |  strd CARG12, [BASE, RA]
@@ -2602,7 +2650,14 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |    sub CARG1, DISPATCH, #-GG_DISP2G
     |    sub CARG1, DISPATCH, #-GG_DISP2G
     |   tst RC, #LJ_GC_WHITES
     |   tst RC, #LJ_GC_WHITES
     |  // Crossed a write barrier. Move the barrier forward.
     |  // Crossed a write barrier. Move the barrier forward.
-    |  blne extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
+    if (LJ_TARGET_OSX) {
+      |  beq <1
+      |  mov RC, BASE
+      |  bl extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
+      |  mov BASE, RC
+    } else {
+      |  blne extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
+    }
     |  b <1
     |  b <1
     break;
     break;
   case BC_USETS:
   case BC_USETS:
@@ -2629,7 +2684,14 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  cmpne RC, #0
     |  cmpne RC, #0
     |   sub CARG1, DISPATCH, #-GG_DISP2G
     |   sub CARG1, DISPATCH, #-GG_DISP2G
     |  // Crossed a write barrier. Move the barrier forward.
     |  // Crossed a write barrier. Move the barrier forward.
-    |  blne extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
+    if (LJ_TARGET_OSX) {
+      |  beq <1
+      |  mov RC, BASE
+      |  bl extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
+      |  mov BASE, RC
+    } else {
+      |  blne extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
+    }
     |  b <1
     |  b <1
     break;
     break;
   case BC_USETN:
   case BC_USETN:
@@ -3072,6 +3134,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   str PC, SAVE_PC
     |   str PC, SAVE_PC
     |  bl extern lj_tab_reasize         // (lua_State *L, GCtab *t, int nasize)
     |  bl extern lj_tab_reasize         // (lua_State *L, GCtab *t, int nasize)
     |  // Must not reallocate the stack.
     |  // Must not reallocate the stack.
+    |  IOS ldr BASE, L->base
     |  b <1
     |  b <1
     |
     |
     |7:  // Possible table write barrier for any value. Skip valiswhite check.
     |7:  // Possible table write barrier for any value. Skip valiswhite check.

File diff suppressed because it is too large
+ 218 - 173
src/buildvm_arm.h


+ 2 - 2
src/lj_arch.h

@@ -194,8 +194,8 @@
 #if defined(__ARMEB__)
 #if defined(__ARMEB__)
 #error "No support for big-endian ARM"
 #error "No support for big-endian ARM"
 #endif
 #endif
-#if !__ARM_EABI__
-#error "Only ARM EABI is supported"
+#if !(__ARM_EABI__ || LJ_TARGET_OSX)
+#error "Only ARM EABI or iOS 3.0+ ABI is supported"
 #endif
 #endif
 #elif LJ_TARGET_PPC
 #elif LJ_TARGET_PPC
 #if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
 #if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)

Some files were not shown because too many files changed in this diff