[Openmcl-cvs-notifications] r14791 - in /trunk/source/lisp-kernel: arm-exceptions.c arm-spentry.s

gb at clozure.com gb at clozure.com
Tue May 10 00:33:37 CDT 2011


Author: gb
Date: Tue May 10 00:33:37 2011
New Revision: 14791

Log:
Don't use swp instructions: they're deprecated and may be disabled
and/or improperly emulated on some Linux kernels.  (And they're generally
somewhat slow.)

Support the alternative instruction sequences (which involve loading a
PC into a register not expected to contain one) in pc_luser_xp().

Modified:
    trunk/source/lisp-kernel/arm-exceptions.c
    trunk/source/lisp-kernel/arm-spentry.s

Modified: trunk/source/lisp-kernel/arm-exceptions.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/lisp-kernel/arm-exceptions.c (original)
+++ trunk/source/lisp-kernel/arm-exceptions.c Tue May 10 00:33:37 2011
@@ -1544,7 +1544,9 @@
   egc_rplaca,
   egc_rplacd,
   egc_set_hash_key_conditional,
-  egc_set_hash_key_conditional_test;
+  egc_set_hash_key_conditional_test,
+  swap_lr_lisp_frame_temp0,
+  swap_lr_lisp_frame_arg_z;
 =

 =

 extern opcode ffcall_return_window, ffcall_return_window_end;
@@ -1719,8 +1721,31 @@
            VOID_ALLOCPTR */
         xpGPR(xp,allocptr) =3D VOID_ALLOCPTR;
       }
+      return;
     }
     return;
+  }
+  {
+    lisp_frame *swap_frame =3D NULL;
+    pc base =3D &swap_lr_lisp_frame_temp0;
+    =

+    if ((program_counter >base)             /* sic */
+        && (program_counter < (base+3))) {
+      swap_frame =3D (lisp_frame *)xpGPR(xp,temp0);
+    } else {
+      base =3D &swap_lr_lisp_frame_arg_z;
+      if ((program_counter > base) && (program_counter < (base+3))) { =

+        swap_frame =3D (lisp_frame *)xpGPR(xp,arg_z);
+      }
+    }
+    if (swap_frame) {
+      if (program_counter =3D=3D (base+1)) {
+        swap_frame->savelr =3D xpGPR(xp,Rlr);
+      }
+      xpGPR(xp,Rlr) =3D xpGPR(xp,imm0);
+      xpPC(xp) =3D base+3;
+      return;
+    }
   }
 }
 =


Modified: trunk/source/lisp-kernel/arm-spentry.s
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/lisp-kernel/arm-spentry.s (original)
+++ trunk/source/lisp-kernel/arm-spentry.s Tue May 10 00:33:37 2011
@@ -4009,15 +4009,29 @@
         /* Save our caller's LR and FN in the csp frame created by the unw=
ind-  */
         /* protect.  (Clever, eh ?)  */
         __(add sp,sp,#catch_frame.size)
-        /* swp is deprecated on ARMv6+.  It's not useful as a basis
-           for synchronization, but that's not why we're using it here. */
+        /* We used to use a swp instruction to exchange the lr with
+        the lisp_frame.savelr field of the lisp frame that temp0 addresses.
+        Multicore ARMv7 machines include the ability to disable the swp
+        instruction, and some Linux kernels do so and emulate the instruct=
ion.
+        There seems to be evidence that they sometimes do so incorrectly,
+        so we stopped using swp.
+        pc_luser_xp() needs to do some extra work if the thread is interru=
pted
+        in the midst of the three-instruction sequence at
+	swap_lr_lisp_frame_temp0.
+        */
         __(mov imm1,#0)
         __(mov temp0,sp)
         __(mov imm0,#3<<num_subtag_bits)
         __(orr imm0,imm0,#subtag_simple_vector)
         __(stmdb sp!,{imm0,imm1,arg_z,temp2})
-        __(add imm0,temp0,#lisp_frame.savelr)
-        __(swp lr,lr,[imm0])
+        .globl C(swap_lr_lisp_frame_temp0)
+        .globl C(swap_lr_lisp_frame_temp0_end)
+        /* This instruction sequence needs support from pc_luser_xp() */
+C(swap_lr_lisp_frame_temp0):            =

+        __(ldr imm0,[temp0,#lisp_frame.savelr])
+        __(str lr,[temp0,#lisp_frame.savelr])
+        __(mov lr,imm0)
+C(swap_lr_lisp_frame_temp0_end):            =

         __(ldr nfn,[temp0,#lisp_frame.savefn])
         __(str fn,[temp0,#lisp_frame.savefn])
         __(ldr vsp,[temp0,#lisp_frame.savevsp])
@@ -4104,8 +4118,14 @@
         __(subs nargs,nargs,#fixnumone)
         __(bge local_label(nthrownv_tpushloop))
         __(mov imm1,#0)
-        __(add imm0,arg_z,#lisp_frame.savelr)
-        __(swp lr,lr,[imm0])
+        /* This instruction sequence needs support from pc_luser_xp() */
+        .globl C(swap_lr_lisp_frame_arg_z)
+        .globl C(swap_lr_lisp_frame_arg_z_end)
+C(swap_lr_lisp_frame_arg_z):                   =

+        __(ldr imm0,[arg_z,#lisp_frame.savelr])
+        __(str lr,[arg_z,#lisp_frame.savelr])
+        __(mov lr,imm0)
+C(swap_lr_lisp_frame_arg_z_end):                   =

         __(ldr nfn,[arg_z,#lisp_frame.savefn])
         __(str fn,[arg_z,#lisp_frame.savefn])
         __(ldr vsp,[arg_z,#lisp_frame.savevsp])



More information about the Openmcl-cvs-notifications mailing list