Changeset 14823


Ignore:
Timestamp:
Jun 13, 2011, 11:24:41 AM (8 years ago)
Author:
gb
Message:

Save the (C) non-volatile FPRs (d8-d15, which are aliased to s16-s31)
when creating CATCH/UNWIND-PROTECT frames; restore them appropriately
when throwing/unwinding. (Having lisp treat the C non-volatile FPRs
as non-volatile means that we don't have to do anything special on
callbacks.)

Most of these changes are transparent to compiled code, but try to
account for the presence of an extra stack-allocated object (a
DOUBLE-FLOAT vector) during unwind-protect cleanup. That's all
intended to allow code like:

(tagbody
  (unwind-protect
       (some-protected-form)
    (go OUT))
  OUT
  ...)

to work, but I'm not sure that it ever has on the ARM.

Technically, this is an ABI change but it's obscure enough (and I'm
lazy enough) that I did't change FASL or image version numbers.
If you have code like the above, recompile it (or take it out back
and shoot it, if you prefer.)

Having the values of these FPRs perserved by CATCH and friends is
one prerequisite to using them in compiled lisp code. (There's
a lot more to that, of course.)

Location:
trunk/source
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/compiler/ARM/arm2.lisp

    r14787 r14823  
    78807880           (*arm2-top-vstack-lcell* *arm2-top-vstack-lcell*)
    78817881           (*arm2-cstack* (%i+ *arm2-cstack* arm::lisp-frame.size)))
     7882      (arm2-open-undo $undostkblk)      ; saved fpr vector
    78827883      (arm2-open-undo $undostkblk)      ; tsp frame created by nthrow.
    78837884      (! save-cleanup-context)
     
    78857886                               arm::lisp-frame.size))       ; the frame we just pushed
    78867887      (arm2-form seg nil nil cleanup-form)
     7888      (arm2-close-undo)
    78877889      (arm2-close-undo)
    78887890      (! restore-cleanup-context)
  • trunk/source/lisp-kernel/arm-macros.s

    r14515 r14823  
    328328')
    329329
    330 
     330/* Save the non-volatile FPRs (d8-d15) in a stack-allocated vector.
     331   Clobber d7,r0,r1.  Note that d7/s14 wind up looking like denormalized
     332   floats (we effectively load a vector header into d7.)
     333*/       
     334   
     335define(`push_fprs',`
     336        __(movc16(imm0,make_header(8,subtag_double_float_vector)))
     337        __(mov imm1,#0)
     338        __(fmdrr d7,imm0,imm1)
     339        __(fstmfdd sp!,{d7-d15})
     340')
     341
     342/* Pop the non-volatile FPRs (d8-d15) from the stack-consed vector
     343   on top of the stack.  This loads the vector header
     344   into d7 as a side-effect. */
     345define(`pop_fprs',`
     346        __(fldmfdd sp!,{d7-d15})
     347')
     348
     349/* Reload the non-volatile FPRs (d8-d15) from the stack-consed vector
     350   on top of the stack, leaving the vector in place.  d7 winds up with
     351   a denormalized float in it, if anything cares. */
     352define(`restore_fprs',`
     353        __(fldmfdd $1,{d7-d15})
     354')               
     355
     356/* discard the stack-consed vector which contains a set of 8 non-volatile
     357   FPRs. */
     358define(`discard_fprs',`
     359        __(add sp,sp,#9*8)
     360')                       
     361       
    331362define(`mkcatch',`
    332363        new_macro_labels()
     364        __(push_fprs())
    333365        __(build_lisp_frame(imm0))
    334366        __(movc16(imm0,make_header(catch_frame.element_count,subtag_catch_frame)))
     
    348380
    349381
    350        
    351 define(`check_stack_alignment',`
    352         new_macro_labels()
    353         __(andi. $1,sp,STACK_ALIGN_MASK)
    354         __(beq+ macro_label(stack_ok))
    355         __(.long 0)
    356 macro_label(stack_ok):
    357 ')
     382
    358383
    359384define(`stack_align',`((($1)+STACK_ALIGN_MASK)&~STACK_ALIGN_MASK)')
  • trunk/source/lisp-kernel/arm-spentry.s

    r14791 r14823  
    23442344_spentry(progvrestore)
    23452345        __(skip_stack_vector(imm0,imm1,sp))
    2346         __(ldr imm0,[imm0,#lisp_frame.size+node_size])
     2346        __(ldr imm0,[imm0,#lisp_frame.size+(9*8)+node_size]) /* 9*8 = size of saved FPR vector, with header */
    23472347        __(cmp imm0,#0)
    23482348        __(unbox_fixnum(imm0,imm0))
     
    39753975        __(ldr lr,[sp,#catch_frame.size+lisp_frame.savelr])
    39763976        __(add sp,sp,#catch_frame.size+lisp_frame.size)
     3977        __(pop_fprs())
    39773978        __(bx lr)
    39783979_endfn(C(_throw_found))       
     
    40034004        __(ldreq vsp,[sp,#catch_frame.size+lisp_frame.savevsp])
    40044005        __(add sp,sp,#catch_frame.size+lisp_frame.size)
     4006        __(pop_fprs())
    40054007        __(b local_label(_nthrow1v_nextframe))
    40064008local_label(_nthrow1v_do_unwind):
     
    40374039        __(ldr vsp,[temp0,#lisp_frame.savevsp])
    40384040        __(mov fn,nfn)
     4041        __(add temp0,temp0,#lisp_frame.size)
     4042        __(restore_fprs(temp0))
    40394043        __(str imm1,[rcontext,#tcr.unwinding])
    40404044        __(blx lr)
     
    40454049        __(add sp,sp,#4*node_size)
    40464050        __(restore_lisp_frame(imm0))
     4051        __(discard_fprs())
    40474052        __(b local_label(_nthrow1v_nextframe))
    40484053local_label(_nthrow1v_done):
     
    40914096local_label(nthrownv_skip):     
    40924097        __(add sp,sp,#catch_frame.size+lisp_frame.size)
     4098        __(pop_fprs())
    40934099        __(b local_label(nthrownv_nextframe))               
    40944100local_label(nthrownv_do_unwind):
     
    41304136        __(str fn,[arg_z,#lisp_frame.savefn])
    41314137        __(ldr vsp,[arg_z,#lisp_frame.savevsp])
     4138        __(add arg_z,arg_z,#lisp_frame.size)
     4139        __(restore_fprs(arg_z))
    41324140        __(str imm1,[rcontext,#tcr.unwinding])
    41334141        __(mov fn,nfn)
     
    41544162        __(ldr lr,[sp,#lisp_frame.savelr])
    41554163        __(discard_lisp_frame())
     4164        __(discard_fprs())
    41564165        __(b local_label(nthrownv_nextframe))
    41574166local_label(nthrownv_done):     
Note: See TracChangeset for help on using the changeset viewer.