[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