Changeset 8466


Ignore:
Timestamp:
Feb 11, 2008, 10:24:09 PM (14 years ago)
Author:
rme
Message:

First cut at SPkeyword_bind, SPmakeu32, SPbuiltin_times, SPff_call.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/ia32/lisp-kernel/x86-spentry32.s

    r8391 r8466  
    478478_endsubp(makes64)       
    479479
    480 /* xxx make lisp integer out of mm0 */
     480/* xxx make lisp integer out of mm0? */
    481481/* Make a lisp integer (probably a bignum) out of the %edx:%eax pair. */
    482482/* We assume that the node_regs_mask in the TCR has been set to mark */
     
    493493        __(movd %mm1,misc_data_offset(%arg_z))
    494494        __(movl %edx,misc_data_offset+4(%arg_z))
     495        __(mark_as_node(%edx))
    495496        __(ret)
    496497_endfn
     
    867868_endsubp(keyword_args)
    868869       
    869 /* There are %nargs words of arguments on the stack; %imm0 contains the number  */
    870 /* of non-keyword args pushed.  It's possible that we never actually got  */
    871 /* any keyword args, which would make things much simpler.   */
    872 
    873 /* On entry, temp1 contains a fixnum with bits indicating whether   */
    874 /* &allow-other-keys and/or &rest was present in the lambda list.  */
    875 /* Once we get here, we can use the arg registers.  */
    876 
    877 define([keyword_flags_aok_bit],[fixnumshift])
    878 define([keyword_flags_unknown_keys_bit],[fixnumshift+1])
    879 define([keyword_flags_rest_bit],[fixnumshift+2])
    880 define([keyword_flags_seen_aok_bit],[fixnumshift+3])       
     870/* There are %nargs words of arguments on the stack; %imm0 contains the */
     871/* number of non-keyword args pushed.  It's possible that we never actually */
     872/* got any keyword args, which would make things much simpler. */
     873
     874/* On entry, the upper half of %temp1 (aka %nargs) contains some bits */
     875/* indicating whether &allow-other-keys and/or &rest was present in the */
     876/* lambda list.  We therefore need to access %nargs as a 16-bit register. */
     877
     878/* Once we get here, we can use the arg registers. */
     879
     880/* N.B.: %ra0 is %temp0, and must not be clobbered. */
     881
     882define([keyword_flags_aok_bit],[16])
     883define([keyword_flags_unknown_keys_bit],[17])
     884define([keyword_flags_rest_bit],[18])
     885define([keyword_flags_seen_aok_bit],[19])
    881886       
    882887_spentry(keyword_bind)
    883         __(int $3)
     888        __(movzwl %nargs_w,%arg_z)
     889        __(subl %imm0,%arg_z)
     890        __(jbe local_label(no_keyword_values))
     891        __(btl $word_shift,%arg_z)
     892        __(jnc local_label(even))
     893        __(movl $nil_value,%arg_y)
     894        __(movw %arg_z_w,%nargs_w)
     895        __(testw %nargs_w,%nargs_w)
     896        __(jmp 1f)
     8970:      __(pop %arg_z)
     898        __(push %ra0) /* aka temp0; temp0 can't be live while consing. */
     899        __(Cons(%arg_z,%arg_y,%arg_y))
     900        __(pop %ra0)  /* the push/pop in a loop is disgusting. */
     901        __(subw $node_size,%nargs_w)
     9021:      __(jnz 0b)
     903        __(movl %arg_y,%arg_z)
     904        __(movl $XBADKEYS,%arg_y)
     905        __(set_nargs(2))
     906        __(jmp _SPksignalerr)
     907
     908        /* Now that we're sure that we have an even number of */
     909        /* keywords and values (in %arg_z), move the pairs over */
     910        /* to the temp stack. */
     911local_label(even):
     912        __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y)
     913        __(TSP_Alloc_Var(%arg_y,%imm0))
     9142:      __(subl $node_size,%arg_y)
     915        __(pop (%arg_y))
     916        __(cmpl %arg_y,%imm0)
     917        __(jne 2b)
     918
     919        /* Get the keyword vector into %arg_y, and its length into %imm0. */
     920        /* Push %imm0 pairs of NILs (representing value, supplied-p) */
     921        /* for each declared keyword. */
     922        __(movzwl misc_data_offset(%fn),%imm0)
     923        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
     924        __(vector_length(%arg_y,%imm0))
     925        __(jmp 4f)
     9263:      __(push $nil_value)
     927        __(push $nil_value)
     9284:      __(subl $fixnumone,%imm0)
     929        __(jge 3b)
     930
     931        /* We can now push %ra0 (aka %temp0) and %nargs (aka %temp1) */
     932        /* in order to get a couple more registers to work with. */
     933        __(push %ra0)
     934        __(push %nargs)
     935
     936        /* At this point we have: */
     937        /* number of supplied keywords and values in %arg_z */
     938        /* keyword vector in %arg_y */
     939        __(vector_length(%arg_y,%imm0))
     940        __(push %imm0)          /* count of declared keywords */
     941        __(push %arg_z)         /* count of supplied keys and values */
     942       
     943        /* For each declared keyword, iterate over the supplied k/v pairs */
     944        /* to see if it's supplied and what the value is. */
     945        /* checking to see if any */
     946        /* key-value pairs were unexpectedly supplied. */
     947
     948        __(movl %rcontext:tcr.save_tsp,%temp0)
     949        __(addl $2*node_size,%temp0) /* skip frame overhead */
     950        /* %temp0: top of tstack (skipping frame overhead) */
     951        __(lea 4*node_size(%esp,%imm0,2),%temp1)
     952        /* %temp1: word above 0th value/supplied-p pair on vstack */
     953        /* %arg_y: keyword vector */
     954        __(xorl %imm0,%imm0)
     955        /* %imm0: index */
     956        /* %arg_z: temporary */
     957
     958        /* Iterate over supplied k/v pairs on tstack.  See if key is */
     959        /* in the keyword vector.  Copy value and set supplied-p on */
     960        /* vstack if found. */
     961
     962local_label(tstack_loop):
     963        __(movl (%temp0,%imm0,2),%arg_z)        /* keyword */
     964        __(push %imm0)
     965        __(xorl %imm0,%imm0)
     966        __(cmpl $nrs.kallowotherkeys,%arg_z)
     967        __(jne local_label(next_keyvect_entry))
     968        __(btsl $keyword_flags_seen_aok_bit,12(%esp))
     969        __(jc local_label(next_keyvect_entry))
     970        __(cmpl $nil_value,node_size(%temp0,%imm0,2))
     971        __(je local_label(next_keyvect_entry))
     972        __(btsl $keyword_flags_aok_bit,12(%esp))
     973        __(jmp local_label(next_keyvect_entry))
     974        /* loop through keyword vector */
     9756:      __(cmpl misc_data_offset(%arg_y,%imm0),%arg_z)
     976        __(jne 7f)
     977        /* Got a match; have we already seen this keyword? */
     978        __(negl %imm0)
     979        __(cmpl $nil_value,-node_size*2(%temp1,%imm0,2))
     980        __(jne 9f)      /* seen it, ignore this value */
     981        __(movl (%esp),%arg_z)
     982        __(lea (%temp0,%arg_z,2),%arg_z)
     983        __(movl node_size(%arg_z),%arg_z) /* value for this key */
     984        __(movl %arg_z,-node_size(%temp1,%imm0,2))
     985        __(movl $t_value,-node_size*2(%temp1,%imm0,2))
     986        __(jmp 9f)
     9877:      __(addl $node_size,%imm0)
     988local_label(next_keyvect_entry):
     989        __(cmpl %imm0,8(%esp))
     990        __(jne 6b)
     991        /* Didn't match anything in the keyword vector.  Is the keyword */
     992        /* :allow-other-keys? */
     993        __(cmpl $nrs.kallowotherkeys,%arg_z)
     994        __(je 9f)       /* :allow-other-keys is never "unknown" */
     9958:      __(btsl $keyword_flags_unknown_keys_bit,12(%esp))
     9969:      __(pop %imm0)
     997        __(addl $fixnumone,%imm0)
     998        __(movl %imm0,%arg_z)
     999        __(shll $1,%arg_z)      /* pairs of tstack words */
     1000        __(cmpl %arg_z,0(%esp))
     1001        __(jne local_label(tstack_loop))
     1002
     1003        __(pop %imm0)   /* count of supplied keys and values */
     1004        __(addl $node_size,%esp)
     1005        __(pop %nargs)
     1006        __(pop %ra0)
     1007
     1008        /* If the function takes an &rest arg, or if we got an unrecognized */
     1009        /* keyword and don't allow that, copy the incoming k/v pairs from */
     1010        /* the temp stack back to the value stack. */
     1011        __(btl $keyword_flags_rest_bit,%temp1)
     1012        __(jc 1f)
     1013        __(btl $keyword_flags_unknown_keys_bit,%temp1)
     1014        __(jnc 0f)
     1015        __(btl $keyword_flags_aok_bit,%temp1)
     1016        __(jnc 1f)
     1017        /* pop the tstack frame */
     10180:      __(discard_temp_frame(%imm0))
     1019        __(jmp *%ra0)
     1020
     1021        /* Copy the k/v pairs from the tstack back to the value stack, */
     1022        /* either because the function takes an &rest arg or because */
     1023        /* we need to signal an "unknown keywords" error. */
     10241:      __(movl %rcontext:tcr.save_tsp,%arg_z)
     1025        __(mov (%arg_z),%arg_y)
     1026        __(jmp 3f)
     10272:      __(push (%arg_z))
     1028        __(push node_size(%arg_z))
     10293:      __(addl $dnode_size,%arg_z)
     1030        __(cmpl %arg_z,%arg_y)
     1031        __(jne 2b)
     1032        __(discard_temp_frame(%arg_z))
     1033        __(btl $keyword_flags_unknown_keys_bit,%temp1)
     1034        __(jnc 9f)
     1035        __(btl $keyword_flags_aok_bit,%temp1)
     1036        __(jc 9f)
     1037        /* Signal an "unknown keywords" error */
     1038        __(movl %imm0,%nargs)
     1039        __(movl $nil_value,%arg_z)
     1040        __(test %nargs,%nargs)
     1041        __(push %ra0)
     1042        __(jmp 5f)
     10434:      __(pop %arg_y)
     1044        __(Cons(%arg_y,%arg_z,%arg_z))
     1045        __(subl $node_size,%nargs)
     10465:      __(jnz 4b)
     1047        __(movl $XBADKEYS,%arg_y)
     1048        __(set_nargs(2))
     1049        __(movl 0(%esp),%ra0)
     1050        __(jmp _SPksignalerr)
     10519:      __(jmp *%ra0)
     1052       
     1053/* No keyword value were provided.  Access the keyword vector (which is the */
     1054/* 0th constant in %fn), determine its length N, and push N pairs of NILs. */
     1055/* N could be 0... */
     1056
     1057local_label(no_keyword_values):
     1058        __(movzwl misc_data_offset(%fn),%imm0)
     1059        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
     1060        __(vector_length(%arg_y,%arg_z))
     1061        __(movl $nil_value,%imm0)
     1062        __(jmp 1f)
     10630:      __(push %imm0)
     1064        __(push %imm0)
     10651:      __(subl $fixnumone,%arg_z)
     1066        __(jge 0b)
     1067        __(jmp *%ra0)
    8841068_endsubp(keyword_bind)
    8851069
     1070/* Normally, we'd just set %fname (aka %temp0) and do */
     1071/* jump_fname().  Sometimes, though, %temp0 is being used */
     1072/* as %ra0, and I'm not sure that it's going to be safe to */
     1073/* clobber that.  (Note that nil-relative symbols aren't going */
     1074/* get moved around by the GC, so we can get away with putting */
     1075/* '%err-disp in %imm0.) */
    8861076_spentry(ksignalerr)
    887         __(mov $nrs.errdisp,%fname)
    888         __(jump_fname) 
     1077        __(mov $nrs.errdisp,%imm0)
     1078        __(mov symbol.fcell(%imm0),%fn)
     1079        __(jump_fn)
    8891080_endsubp(ksignalerr)
    8901081
     
    11911382_endsubp(restoreintlevel)
    11921383
     1384/* Make a lisp integer from the unsigned value in imm0 */
    11931385_spentry(makeu32)
    1194         __(int $3)
     1386        __(cmpl $(1<<29),%imm0)
     1387        __(jae 0f)      /* need to make a bignum */
     1388        __(box_fixnum(%imm0,%arg_z))
     1389        __(ret)
     13900:      __(movd %imm0,%mm1)
     1391        __(test %imm0,%imm0)
     1392        __(js 1f)
     1393        __(movl $one_digit_bignum_header,%imm0)
     1394        __(movd %imm0,%mm0)
     1395        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
     1396        __(movd %mm1,misc_data_offset(%arg_z))
     1397        __(ret)
     13981:      __(movl $two_digit_bignum_header,%imm0)
     1399        __(movd %imm0,%mm0)
     1400        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
     1401        __(movd %mm1,misc_data_offset(%arg_z))
     1402        __(ret)
    11951403_endsubp(makeu32)
    11961404
     
    13101518        __(jo,pn C(fix_one_bit_overflow))
    13111519        __(repret)
    1312         __(int $3)
     1520        __(jump_builtin(_builtin_minus,2))
    13131521_endsubp(builtin_minus)
    13141522
     1523/* %arg_z -< arg_y * arg_z. */
     1524/* Do the fixnum case---including overflow---inline.  Call out otherwise. */
    13151525_spentry(builtin_times)
    1316         __(int $3)
     1526        __(movl %arg_y,%imm0)
     1527        __(orb %arg_z_b,%imm0_b)
     1528        __(testb $fixnummask,%imm0_b)
     1529        __(jne 2f)
     1530        __(unbox_fixnum(%arg_z,%imm0))
     1531        __(mark_as_imm(%edx))
     1532        /* 64-bit fixnum result in %edx:%eax.  Overflow set if %edx */
     1533        /* is significant. */
     1534        __(imul %arg_y)
     1535        __(jo 1f)
     1536        __(movl %imm0,%arg_z)
     1537        __(mark_as_node(%edx))
     1538        __(ret)
     15391:      __(unbox_fixnum(%arg_z,%eax))
     1540        __(unbox_fixnum(%arg_y,%edx))
     1541        __(imul %edx)
     1542        /* SPmakes64 expects that %edx will be marked as an imm reg */
     1543        __(jmp C(makes64))
     15442:      __(jump_builtin(_builtin_times,2))
    13171545_endsubp(builtin_times)
    13181546
     
    15191747_endsubp(builtin_aref1)
    15201748
     1749/* Maybe check the x87 tag word to see if st(0) is valid and pop it */
     1750/* if so.  This might allow us to avoid having to have a priori */
     1751/* knowledge of whether a foreign function returns a floating-point result. */
     1752/* backlink to saved %esp, below */
     1753/* arg n-1 */
     1754/* arg n-2 */
     1755/* ... */
     1756/* arg 0 */
     1757/* space for alignment */
     1758/* previous %esp */
     1759
    15211760_spentry(ffcall)
    1522         __(int $3)
     1761LocalLabelPrefix[]ffcall:
     1762        __(unbox_fixnum(%arg_z,%imm0))
     1763        __(testb $fixnummask,%arg_z_b)
     1764        __(je 0f)
     1765        __(movl macptr.address(%arg_z),%imm0)
     17660:
     1767        /* Save lisp registers. */
     1768        __(push %ebp)
     1769        __(mov %esp,%ebp)
     1770        __(push %temp0)
     1771        __(push %temp1)
     1772        __(push %arg_y)
     1773        __(push %arg_z)
     1774        __(push %fn)
     1775        __(movl %esp,%rcontext:tcr.save_vsp)
     1776        __(movl %ebp,%rcontext:tcr.save_ebp)
     1777        __(movl $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
     1778        __(movl %rcontext:tcr.foreign_sp,%esp)
     1779        __(stmxcsr %rcontext:tcr.lisp_mxcsr)
     1780        __(emms)
     1781        __(ldmxcsr %rcontext:tcr.foreign_mxcsr)
     1782        __(movl (%esp),%ebp)
     1783LocalLabelPrefix[]ffcall_setup:
     1784        __(addl $node_size,%esp)
     1785LocalLabelPrefix[]ffcall_call:
     1786        __(call *%eax)
     1787LocalLabelPrefix[]ffcall_call_end:
     1788        __(movl %ebp,%esp)
     1789        __(movl %esp,%rcontext:tcr.foreign_sp)
     1790        __(clr %arg_z)
     1791        __(clr %arg_y)
     1792        __(clr %temp1)
     1793        __(clr %temp0)
     1794        __(clr %fn)
     1795        __(pxor %fpzero,%fpzero)
     1796        __ifdef([DARWIN])
     1797        /* Darwin's math library seems to cause spurious FP exceptions. */
     1798        __(movl %arg_z,%rcontext:tcr.ffi_exception)
     1799        __else
     1800        __(stmxcsr %rcontext:tcr.ffi_exception)
     1801        __endif
     1802        __(movl %rcontext:tcr.save_vsp,%esp)
     1803        __(movl %rcontext:tcr.save_ebp,%ebp)
     1804        __(movl $TCR_STATE_LISP,%rcontext:tcr.valence)
     1805        __(pop %fn)
     1806        __(pop %arg_z)
     1807        __(pop %arg_y)
     1808        __(pop %temp1)
     1809        __(ldmxcsr %rcontext:tcr.lisp_mxcsr)
     1810        __(check_pending_interrupt(%temp0))
     1811        __(pop %temp0)
     1812        __(leave)
     1813        __(ret)
     1814        /* need to deal with NSExceptions and Objc-2.0 execptions */
    15231815_endsubp(ffcall)
    1524        
     1816
    15251817_spentry(ffcall_return_registers)
    15261818        __(int $3)
Note: See TracChangeset for help on using the changeset viewer.