Changeset 8466
- Timestamp:
- Feb 11, 2008, 2:24:09 PM (17 years ago)
- File:
-
- 1 edited
-
branches/ia32/lisp-kernel/x86-spentry32.s (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/ia32/lisp-kernel/x86-spentry32.s
r8391 r8466 478 478 _endsubp(makes64) 479 479 480 /* xxx make lisp integer out of mm0 */480 /* xxx make lisp integer out of mm0? */ 481 481 /* Make a lisp integer (probably a bignum) out of the %edx:%eax pair. */ 482 482 /* We assume that the node_regs_mask in the TCR has been set to mark */ … … 493 493 __(movd %mm1,misc_data_offset(%arg_z)) 494 494 __(movl %edx,misc_data_offset+4(%arg_z)) 495 __(mark_as_node(%edx)) 495 496 __(ret) 496 497 _endfn … … 867 868 _endsubp(keyword_args) 868 869 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 882 define([keyword_flags_aok_bit],[16]) 883 define([keyword_flags_unknown_keys_bit],[17]) 884 define([keyword_flags_rest_bit],[18]) 885 define([keyword_flags_seen_aok_bit],[19]) 881 886 882 887 _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) 897 0: __(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) 902 1: __(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. */ 911 local_label(even): 912 __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y) 913 __(TSP_Alloc_Var(%arg_y,%imm0)) 914 2: __(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) 926 3: __(push $nil_value) 927 __(push $nil_value) 928 4: __(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 962 local_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 */ 975 6: __(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) 987 7: __(addl $node_size,%imm0) 988 local_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" */ 995 8: __(btsl $keyword_flags_unknown_keys_bit,12(%esp)) 996 9: __(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 */ 1018 0: __(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. */ 1024 1: __(movl %rcontext:tcr.save_tsp,%arg_z) 1025 __(mov (%arg_z),%arg_y) 1026 __(jmp 3f) 1027 2: __(push (%arg_z)) 1028 __(push node_size(%arg_z)) 1029 3: __(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) 1043 4: __(pop %arg_y) 1044 __(Cons(%arg_y,%arg_z,%arg_z)) 1045 __(subl $node_size,%nargs) 1046 5: __(jnz 4b) 1047 __(movl $XBADKEYS,%arg_y) 1048 __(set_nargs(2)) 1049 __(movl 0(%esp),%ra0) 1050 __(jmp _SPksignalerr) 1051 9: __(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 1057 local_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) 1063 0: __(push %imm0) 1064 __(push %imm0) 1065 1: __(subl $fixnumone,%arg_z) 1066 __(jge 0b) 1067 __(jmp *%ra0) 884 1068 _endsubp(keyword_bind) 885 1069 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.) */ 886 1076 _spentry(ksignalerr) 887 __(mov $nrs.errdisp,%fname) 888 __(jump_fname) 1077 __(mov $nrs.errdisp,%imm0) 1078 __(mov symbol.fcell(%imm0),%fn) 1079 __(jump_fn) 889 1080 _endsubp(ksignalerr) 890 1081 … … 1191 1382 _endsubp(restoreintlevel) 1192 1383 1384 /* Make a lisp integer from the unsigned value in imm0 */ 1193 1385 _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) 1390 0: __(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) 1398 1: __(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) 1195 1403 _endsubp(makeu32) 1196 1404 … … 1310 1518 __(jo,pn C(fix_one_bit_overflow)) 1311 1519 __(repret) 1312 __( int $3)1520 __(jump_builtin(_builtin_minus,2)) 1313 1521 _endsubp(builtin_minus) 1314 1522 1523 /* %arg_z -< arg_y * arg_z. */ 1524 /* Do the fixnum case---including overflow---inline. Call out otherwise. */ 1315 1525 _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) 1539 1: __(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)) 1544 2: __(jump_builtin(_builtin_times,2)) 1317 1545 _endsubp(builtin_times) 1318 1546 … … 1519 1747 _endsubp(builtin_aref1) 1520 1748 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 1521 1760 _spentry(ffcall) 1522 __(int $3) 1761 LocalLabelPrefix[]ffcall: 1762 __(unbox_fixnum(%arg_z,%imm0)) 1763 __(testb $fixnummask,%arg_z_b) 1764 __(je 0f) 1765 __(movl macptr.address(%arg_z),%imm0) 1766 0: 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) 1783 LocalLabelPrefix[]ffcall_setup: 1784 __(addl $node_size,%esp) 1785 LocalLabelPrefix[]ffcall_call: 1786 __(call *%eax) 1787 LocalLabelPrefix[]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 */ 1523 1815 _endsubp(ffcall) 1524 1816 1525 1817 _spentry(ffcall_return_registers) 1526 1818 __(int $3)
Note:
See TracChangeset
for help on using the changeset viewer.
