Changeset 14791


Ignore:
Timestamp:
May 10, 2011, 5:33:37 AM (8 years ago)
Author:
gb
Message:

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().

Location:
trunk/source/lisp-kernel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/arm-exceptions.c

    r14754 r14791  
    15451545  egc_rplacd,
    15461546  egc_set_hash_key_conditional,
    1547   egc_set_hash_key_conditional_test;
     1547  egc_set_hash_key_conditional_test,
     1548  swap_lr_lisp_frame_temp0,
     1549  swap_lr_lisp_frame_arg_z;
    15481550
    15491551
     
    17201722        xpGPR(xp,allocptr) = VOID_ALLOCPTR;
    17211723      }
     1724      return;
    17221725    }
    17231726    return;
     1727  }
     1728  {
     1729    lisp_frame *swap_frame = NULL;
     1730    pc base = &swap_lr_lisp_frame_temp0;
     1731   
     1732    if ((program_counter >base)             /* sic */
     1733        && (program_counter < (base+3))) {
     1734      swap_frame = (lisp_frame *)xpGPR(xp,temp0);
     1735    } else {
     1736      base = &swap_lr_lisp_frame_arg_z;
     1737      if ((program_counter > base) && (program_counter < (base+3))) {
     1738        swap_frame = (lisp_frame *)xpGPR(xp,arg_z);
     1739      }
     1740    }
     1741    if (swap_frame) {
     1742      if (program_counter == (base+1)) {
     1743        swap_frame->savelr = xpGPR(xp,Rlr);
     1744      }
     1745      xpGPR(xp,Rlr) = xpGPR(xp,imm0);
     1746      xpPC(xp) = base+3;
     1747      return;
     1748    }
    17241749  }
    17251750}
  • trunk/source/lisp-kernel/arm-spentry.s

    r14783 r14791  
    40104010        /* protect.  (Clever, eh ?)  */
    40114011        __(add sp,sp,#catch_frame.size)
    4012         /* swp is deprecated on ARMv6+.  It's not useful as a basis
    4013            for synchronization, but that's not why we're using it here. */
     4012        /* We used to use a swp instruction to exchange the lr with
     4013        the lisp_frame.savelr field of the lisp frame that temp0 addresses.
     4014        Multicore ARMv7 machines include the ability to disable the swp
     4015        instruction, and some Linux kernels do so and emulate the instruction.
     4016        There seems to be evidence that they sometimes do so incorrectly,
     4017        so we stopped using swp.
     4018        pc_luser_xp() needs to do some extra work if the thread is interrupted
     4019        in the midst of the three-instruction sequence at
     4020        swap_lr_lisp_frame_temp0.
     4021        */
    40144022        __(mov imm1,#0)
    40154023        __(mov temp0,sp)
     
    40174025        __(orr imm0,imm0,#subtag_simple_vector)
    40184026        __(stmdb sp!,{imm0,imm1,arg_z,temp2})
    4019         __(add imm0,temp0,#lisp_frame.savelr)
    4020         __(swp lr,lr,[imm0])
     4027        .globl C(swap_lr_lisp_frame_temp0)
     4028        .globl C(swap_lr_lisp_frame_temp0_end)
     4029        /* This instruction sequence needs support from pc_luser_xp() */
     4030C(swap_lr_lisp_frame_temp0):           
     4031        __(ldr imm0,[temp0,#lisp_frame.savelr])
     4032        __(str lr,[temp0,#lisp_frame.savelr])
     4033        __(mov lr,imm0)
     4034C(swap_lr_lisp_frame_temp0_end):           
    40214035        __(ldr nfn,[temp0,#lisp_frame.savefn])
    40224036        __(str fn,[temp0,#lisp_frame.savefn])
     
    41054119        __(bge local_label(nthrownv_tpushloop))
    41064120        __(mov imm1,#0)
    4107         __(add imm0,arg_z,#lisp_frame.savelr)
    4108         __(swp lr,lr,[imm0])
     4121        /* This instruction sequence needs support from pc_luser_xp() */
     4122        .globl C(swap_lr_lisp_frame_arg_z)
     4123        .globl C(swap_lr_lisp_frame_arg_z_end)
     4124C(swap_lr_lisp_frame_arg_z):                   
     4125        __(ldr imm0,[arg_z,#lisp_frame.savelr])
     4126        __(str lr,[arg_z,#lisp_frame.savelr])
     4127        __(mov lr,imm0)
     4128C(swap_lr_lisp_frame_arg_z_end):                   
    41094129        __(ldr nfn,[arg_z,#lisp_frame.savefn])
    41104130        __(str fn,[arg_z,#lisp_frame.savefn])
Note: See TracChangeset for help on using the changeset viewer.