source: trunk/source/lisp-kernel/x86-macros.s @ 16083

Last change on this file since 16083 was 14993, checked in by rme, 9 years ago

Remove DARWIN_GS_HACK code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.8 KB
RevLine 
[13067]1/*   Copyright (C) 2005-2009 Clozure Associates  */
[13066]2/*   This file is part of Clozure CL.    */
[2799]3
[13066]4/*   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public  */
5/*   License , known as the LLGPL and distributed with Clozure CL as the  */
[4315]6/*   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,  */
[13066]7/*   which is distributed with Clozure CL as the file "LGPL".  Where these  */
[4315]8/*   conflict, the preamble takes precedence.    */
[2799]9
[13066]10/*   Clozure CL is referenced in the preamble as the "LIBRARY."  */
[2799]11
[4315]12/*   The LLGPL is also available online at  */
13/*   http://opensource.franz.com/preamble.html  */
[2811]14
[4206]15
[5009]16/* Try to make macros follow GAS/ATT conventions, where source precedes  */
[4315]17/* destination.  */
[4299]18
[13337]19define(`lisp_global',`lisp_globals.$1')
[4206]20                                       
[13337]21define(`ref_global',`
[8242]22        __(mov lisp_global($1),$2)
[13337]23')
[2811]24
[13337]25define(`set_global',`
[8242]26        __(mov $1,lisp_global($2))
[13337]27')
[2819]28
[13337]29define(`ref_nrs_value',`
[8242]30        __(mov nrs.$1+symbol.vcell,$2)
[13337]31')
[2819]32       
[13337]33define(`set_nrs_value',`
[8242]34        __(mov $1,nrs.$2+symbol.vcell)
[13337]35')
[2819]36                                                       
[13337]37define(`unbox_fixnum',`
[8242]38        __(mov $1,$2)
[13337]39        __(sar `$'fixnumshift,$2)
40')
[2811]41
[13337]42define(`box_fixnum',`
43        __(imul `$'fixnumone,$1,$2)
44')     
[3374]45
[5158]46
47/* box_fixnum, with no effect on flags */
[13337]48define(`box_fixnum_no_flags',`
[10089]49        __(lea (,$1,fixnumone),$2)
[13337]50')
[2811]51
[10089]52
[4315]53/* Zero $3 bytes worth of dnodes, starting at offset $2 relative  */
54/* to the base register $1.  */
[3366]55
[4299]56
[13337]57ifdef(`DarwinAssembler',`
[3368]58        .macro zero_dnodes
59        .if $2
[13337]60        ifdef(`X8664',`
[8242]61        __(movapd %fpzero,$1($0))
[13337]62        ',`
[10089]63        __(movsd %fpzero,$1($0))
[13337]64        ')
[8242]65        __(zero_dnodes $0,$1+dnode_size,$2-dnode_size)
[3368]66        .endif
67        .endmacro
[13337]68',`
[3368]69        .macro zero_dnodes base,disp,nbytes
70        .ifgt \nbytes
[13337]71        ifdef(`X8664',`
[8279]72        movapd %fpzero,\disp(\base)
[13337]73        ',`
[10089]74        movsd %fpzero,\disp(\base)
[13337]75        ')
[3377]76        zero_dnodes \base,"\disp+dnode_size","\nbytes-dnode_size"
[3368]77        .endif
78        .endm
[13337]79')     
[3368]80
81
[4315]82/* Allocate $1+dnode_size zeroed bytes on the tstack, using $2 as a temp  */
83/* reg.  */
[10089]84
[13337]85ifdef(`X8632',`
86define(`TSP_Alloc_Fixed',`
87        define(`TSP_Alloc_Size',`((($1+node_size) & ~(dnode_size-1))+dnode_size)')
88        __(subl `$'TSP_Alloc_Size,rcontext(tcr.next_tsp))
[10089]89        __(movd rcontext(tcr.save_tsp),%stack_temp)
90        __(movl rcontext(tcr.next_tsp),$2)
91        zero_dnodes $2,0,TSP_Alloc_Size
92        __(movd %stack_temp,($2))
93        __(movl %ebp,tsp_frame.save_ebp($2))
94        __(movl $2,rcontext(tcr.save_tsp))
[13337]95        undefine(`TSP_Alloc_Size')
96')',`
97define(`TSP_Alloc_Fixed',`
98        define(`TSP_Alloc_Size',`((($1+node_size) & ~(dnode_size-1))+dnode_size)')
99        __(subq `$'TSP_Alloc_Size,rcontext(tcr.next_tsp))
[8562]100        __(movq rcontext(tcr.save_tsp),%stack_temp)
101        __(movq rcontext(tcr.next_tsp),$2)
[3368]102        zero_dnodes $2,0,TSP_Alloc_Size
[8242]103        __(movq %stack_temp,($2))
104        __(movq %rbp,tsp_frame.save_rbp($2))
[8562]105        __(movq $2,rcontext(tcr.save_tsp))
[13337]106        undefine(`TSP_Alloc_Size')
107')')
[3366]108
[4315]109/* $1 = size (dnode-aligned, including tsp overhead, $2 scratch.  */
110/* Modifies both $1 and $2; on exit, $2 = new_tsp+tsp_overhead, $1 = old tsp  */
[10089]111
[13337]112ifdef(`X8632',`
113define(`TSP_Alloc_Var',`
[10089]114        new_macro_labels()
115        __(subl $1,rcontext(tcr.next_tsp))
116        __(movd rcontext(tcr.save_tsp),%stack_temp)
117        __(movl rcontext(tcr.next_tsp),$2)
118        __(jmp macro_label(test))
119macro_label(loop):
120        __(movsd %fpzero,0($2))
121        __(addl $dnode_size,$2)
122macro_label(test):
123        __(subl $dnode_size,$1)
124        __(jge macro_label(loop))
125        __(movl rcontext(tcr.next_tsp),$2)
126        __(movd %stack_temp,$1)
127        __(movl $1,($2))
128        __(movl %ebp,tsp_frame.save_ebp($2))
129        __(movl $2,rcontext(tcr.save_tsp))
130        __(addl $dnode_size,$2)
[13337]131')',`
132define(`TSP_Alloc_Var',`
[4753]133        new_macro_labels()
[8562]134        subq $1,rcontext(tcr.next_tsp)
135        __(movq rcontext(tcr.save_tsp),%stack_temp)
136        __(movq rcontext(tcr.next_tsp),$2)
[8242]137        __(jmp macro_label(test))
[3390]138macro_label(loop):
[8242]139        __(movapd %fpzero,0($2))
140        __(addq $dnode_size,$2)
[3390]141macro_label(test):     
[8242]142        __(subq $dnode_size,$1)
143        __(jge macro_label(loop))
[8562]144        __(movq rcontext(tcr.next_tsp),$2)
[8242]145        __(movd %stack_temp,$1)
146        __(movq $1,($2))
147        __(movq %rbp,tsp_frame.save_rbp($2))
[8562]148        __(movq $2,rcontext(tcr.save_tsp))
[8242]149        __(addq $dnode_size,$2)
[13337]150')')
[3390]151       
152       
[13337]153ifdef(`X8632',`
154define(`Allocate_Catch_Frame',`
[10089]155        TSP_Alloc_Fixed(catch_frame.size,$1)
[13337]156        __(movl `$'(catch_frame.element_count<<subtag_shift)|subtag_catch_frame,dnode_size($1))
157        __(addl `$'dnode_size+fulltag_misc,$1)
158')',`
159define(`Allocate_Catch_Frame',`
[3368]160        TSP_Alloc_Fixed(catch_frame.size,$1)
[13337]161        __(movq `$'(catch_frame.element_count<<subtag_shift)|subtag_catch_frame,dnode_size($1))
162        __(addq `$'dnode_size+fulltag_misc,$1)
163')')
[3366]164
[4315]165/* %arg_z = tag,  %xfn = pc, $1 = mvflag          */
[10089]166
[13337]167ifdef(`X8632',`
168define(`Make_Catch',`
[10089]169        Allocate_Catch_Frame(%imm0)
170        __(movd rcontext(tcr.catch_top),%mm0)
171        __(movd rcontext(tcr.db_link),%mm1)
172        __(movl %arg_z,catch_frame.catch_tag(%imm0))
173        __(movd %mm0,catch_frame.link(%imm0))
[13337]174        __(movl `$'$1,catch_frame.mvflag(%imm0))
[10089]175        __(movd rcontext(tcr.xframe),%mm0)
176        __(movl %esp,catch_frame.esp(%imm0))
177        __(movl %ebp,catch_frame.ebp(%imm0))
178        __(movd rcontext(tcr.foreign_sp),%stack_temp)
179        __(movd %stack_temp,catch_frame.foreign_sp(%imm0))
180        __(movd %mm1,catch_frame.db_link(%imm0))
181        __(movd %mm0,catch_frame.xframe(%imm0))
182        __(movl %xfn,catch_frame.pc(%imm0))
183        __(movl %imm0,rcontext(tcr.catch_top))
[13337]184')',`
185define(`Make_Catch',`
[6529]186        Allocate_Catch_Frame(%imm2)
[8562]187        __(movq rcontext(tcr.catch_top),%imm0)
188        __(movq rcontext(tcr.db_link),%imm1)
[8242]189        __(movq %arg_z,catch_frame.catch_tag(%imm2))
190        __(movq %imm0,catch_frame.link(%imm2))
[13337]191        __(movq `$'$1,catch_frame.mvflag(%imm2))
[8562]192        __(movq rcontext(tcr.xframe),%imm0)
[8242]193        __(movq %rsp,catch_frame.rsp(%imm2))
194        __(movq %rbp,catch_frame.rbp(%imm2))
[8562]195        __(movq rcontext(tcr.foreign_sp),%stack_temp)
[8242]196        __(movq %imm1,catch_frame.db_link(%imm2))
[13337]197        __ifndef(`WINDOWS')
[8242]198        __(movq %save3,catch_frame._save3(%imm2))
[8607]199        __endif
[8242]200        __(movq %save2,catch_frame._save2(%imm2))
201        __(movq %save1,catch_frame._save1(%imm2))
202        __(movq %save0,catch_frame._save0(%imm2))
203        __(movq %imm0,catch_frame.xframe(%imm2))
204        __(movq %stack_temp,catch_frame.foreign_sp(%imm2))
205        __(movq %xfn,catch_frame.pc(%imm2))
[8562]206        __(movq %imm2,rcontext(tcr.catch_top))
[13337]207')')   
[6529]208
[13337]209ifdef(`X8632',`
210define(`nMake_Catch',`
[10089]211        Allocate_Catch_Frame(%imm0)
212        __(movd rcontext(tcr.catch_top),%mm0)
213        __(movd rcontext(tcr.db_link),%mm1)
214        __(movl %arg_z,catch_frame.catch_tag(%imm0))
215        __(movd %mm0,catch_frame.link(%imm0))
216        __(movl %esp,catch_frame.esp(%imm0))
217        __(addl $node_size,catch_frame.esp(%imm0))
[13337]218        __(movl `$'$1,catch_frame.mvflag(%imm0))
[10089]219        __(movd rcontext(tcr.xframe),%mm0)
220        __(movl %ebp,catch_frame.ebp(%imm0))
221        __(movd rcontext(tcr.foreign_sp),%stack_temp)
222        __(movd %mm1,catch_frame.db_link(%imm0))
223        __(movd %mm0,catch_frame.xframe(%imm0))
224        __(movd %stack_temp,catch_frame.foreign_sp(%imm0))
225        __(movl %xfn,catch_frame.pc(%imm0))
226        __(movl %imm0,rcontext(tcr.catch_top))
[13337]227')',`   
228define(`nMake_Catch',`
[6529]229        Allocate_Catch_Frame(%imm2)
[8562]230        __(movq rcontext(tcr.catch_top),%imm0)
231        __(movq rcontext(tcr.db_link),%imm1)
[8242]232        __(movq %arg_z,catch_frame.catch_tag(%imm2))
233        __(movq %imm0,catch_frame.link(%imm2))
234        __(lea node_size(%rsp),%imm0)
[13337]235        __(movq `$'$1,catch_frame.mvflag(%imm2))
[8242]236        __(movq %imm0,catch_frame.rsp(%imm2))
[8562]237        __(movq rcontext(tcr.xframe),%imm0)
[8242]238        __(movq %rbp,catch_frame.rbp(%imm2))
[8562]239        __(movq rcontext(tcr.foreign_sp),%stack_temp)
[8242]240        __(movq %imm1,catch_frame.db_link(%imm2))
[13337]241        __ifndef(`WINDOWS')
[8242]242        __(movq %save3,catch_frame._save3(%imm2))
[8607]243        __endif
[8242]244        __(movq %save2,catch_frame._save2(%imm2))
245        __(movq %save1,catch_frame._save1(%imm2))
246        __(movq %save0,catch_frame._save0(%imm2))
247        __(movq %imm0,catch_frame.xframe(%imm2))
248        __(movq %stack_temp,catch_frame.foreign_sp(%imm2))
249        __(movq %xfn,catch_frame.pc(%imm2))
[8562]250        __(movq %imm2,rcontext(tcr.catch_top))
[13337]251')')   
[6529]252               
[3366]253       
[4315]254/* Consing can get interrupted (either by PROCESS-INTERRUPT or by GC  */
[13337]255/* activity in some other thread; if it is interrupted, the interrupting  */
256/* process needs to be able to determine what is going on well enough  */
[4315]257/* to be able to either back out of the attempt or finish the job.  */
258/* That requires that we use easily recogninized instruction sequences  */
259/* and follow certain conventions when consing (either in the kernel  */
260/* or in compiled code.)  (One of those conventions involves using  */
[13337]261/* %allocptr = %temp0 as a freepointer; when consing, %temp0 can not  */
[4315]262/* contain a live value.)  */
263/* Making a CONS cell is a little simpler than making a uvector.  */
[4299]264
[4315]265/* $1=new_car,$2=new_cdr,$3=dest   */
[10089]266
[13337]267ifdef(`X8632',`
268define(`Cons',`
[2811]269        new_macro_labels()
[4315]270/* The instructions where tcr.save_allocptr is tagged are difficult  */
271/* to interrupt; the interrupting code has to recognize and possibly  */
272/* emulate the instructions in between   */
[10089]273        __(subl $cons.size-fulltag_cons,rcontext(tcr.save_allocptr))
274        __(movl rcontext(tcr.save_allocptr),%allocptr)
275        __(rcmpl(%allocptr,rcontext(tcr.save_allocbase)))
[11556]276        __(ja macro_label(no_trap))
[10089]277        uuo_alloc()
278macro_label(no_trap):
279        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
[13337]280/* Easy to interrupt now that tcr.save_allocptr is not tagged as a cons    */
[10089]281        __(movl $2,cons.cdr(%allocptr))
282        __(movl $1,cons.car(%allocptr))
[13337]283        ifelse($3,`',`',`
[10089]284         __(movl %allocptr,$3)
[13337]285        ')
286')',`
[10089]287
[13337]288define(`Cons',`
[10089]289        new_macro_labels()
290/* The instructions where tcr.save_allocptr is tagged are difficult  */
291/* to interrupt; the interrupting code has to recognize and possibly  */
292/* emulate the instructions in between   */
[8562]293        __(subq $cons.size-fulltag_cons,rcontext(tcr.save_allocptr))
294        __(movq rcontext(tcr.save_allocptr),%allocptr)
295        __(rcmpq(%allocptr,rcontext(tcr.save_allocbase)))
[11556]296        __(ja macro_label(no_trap))
[3231]297        uuo_alloc()
[2811]298macro_label(no_trap):   
[8562]299        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
[13337]300/* Easy to interrupt now that tcr.save_allocptr is not tagged as a cons    */
[8242]301        __(movq $2,cons.cdr(%allocptr))
302        __(movq $1,cons.car(%allocptr))
[13337]303        ifelse($3,`',`',`
[8242]304         __(movq %allocptr,$3)
[13337]305        ')
306')')
[2811]307
[13337]308ifdef(`X8632',`
[10089]309/* Header in %mm0, size in bytes in %imm0.  We bash %imm0. */
[13337]310define(`Misc_Alloc',`
311        __(sub `$'fulltag_misc,%imm0)
[10089]312        Misc_Alloc_Internal($1)
[13337]313')',`
[10089]314/* Header in %imm0, size in bytes in %imm1.  We bash %imm1. */
[13337]315define(`Misc_Alloc',`
316        __(subq `$'fulltag_misc,%imm1)
[3915]317        Misc_Alloc_Internal($1)
[13337]318')')
[3915]319
[4315]320/* Here Be Monsters: we have to treat some/all of this instruction   */
321/* sequence atomically, as soon as tcr.save_allocptr becomes tagged.  */
[4299]322               
[13337]323ifdef(`X8632',`
324define(`Misc_Alloc_Internal',`                 
[10089]325        new_macro_labels()
326        __(subl %imm0,rcontext(tcr.save_allocptr))
327        __(movl rcontext(tcr.save_allocptr),%allocptr)
328        __(cmpl rcontext(tcr.save_allocbase),%allocptr)
[11556]329        __(ja macro_label(no_trap))
[10089]330        uuo_alloc()
331macro_label(no_trap):   
332        __(movd %mm0,misc_header_offset(%allocptr))
333        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
[13337]334/* Now that tcr.save_allocptr is untagged, it is easier to be interrupted   */
335        ifelse($1,`',`',`
[10089]336         __(mov %allocptr,$1)
[13337]337        ')
338')',`   
339define(`Misc_Alloc_Internal',`                 
[3915]340        new_macro_labels()
[8562]341        __(subq %imm1,rcontext(tcr.save_allocptr))
342        __(movq rcontext(tcr.save_allocptr),%allocptr)
343        __(rcmpq(%allocptr,rcontext(tcr.save_allocbase)))
[11556]344        __(ja macro_label(no_trap))
[3231]345        uuo_alloc()
[2811]346macro_label(no_trap):   
[8242]347        __(movq %imm0,misc_header_offset(%allocptr))
[8562]348        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
[13337]349/* Now that tcr.save_allocptr is untagged, it is easier to be interrupted   */
350        ifelse($1,`',`',`
[8242]351         __(mov %allocptr,$1)
[13337]352        ')
353')')
[10089]354
[13337]355ifdef(`X8632',`
356define(`Misc_Alloc_Fixed',`
357        __(mov `$'$2-fulltag_misc,%imm0)
[10089]358        Misc_Alloc_Internal($1)
[13337]359')',`
360define(`Misc_Alloc_Fixed',`
361        __(movq `$'$2-fulltag_misc,%imm1)
[3915]362        Misc_Alloc_Internal($1)
[13337]363')')                                   
[2819]364
[13337]365define(`vrefr',`
[8242]366        __(mov misc_data_offset+($3<<word_shift)($2),$1)
[13337]367')     
[2819]368
[13337]369define(`jump_fn',`
[10089]370        __(jmp *%fn)
[13337]371')
[2819]372                       
[13337]373define(`jump_fname',`
[8242]374        __(mov symbol.fcell(%fname),%fn)
[3236]375        jump_fn()
[13337]376')     
[10089]377
[13337]378ifdef(`X8632',`
379define(`set_nargs',`
[10089]380        __(xorl %nargs,%nargs)
[13337]381        __(addl `$'$1<<fixnumshift,%nargs)
382')',`
383define(`set_nargs',`
384        ifelse(eval($1>15),1,`
385        __(movl `$'$1<<fixnumshift,%nargs)
386        ',`
[8341]387        __(xorl %nargs,%nargs)
[13337]388        ifelse(eval($1),0,`',`
389        __(addl `$'$1<<fixnumshift,%nargs)
390        ')')')
391')
[2819]392
[4315]393/* $1 = ndigits.  Assumes 4-byte digits           */
[13337]394define(`aligned_bignum_size',`((~(dnode_size-1)&(node_size+(dnode_size-1)+(4*$1))))')
[2819]395       
[2836]396
[13337]397define(`_car',`
[10089]398        __(mov cons.car($1),$2)
[13337]399')     
[2836]400
[13337]401define(`_rplaca',`
[10089]402        __(mov $2,cons.car($1))
[13337]403')     
[3453]404               
[13337]405define(`_cdr',`
[10089]406        __(mov cons.cdr($1),$2)
[13337]407')
[3453]408
[13337]409define(`_rplacd',`
[10089]410        __(mov $2,cons.cdr($1))
[13337]411')     
[3453]412               
[3368]413       
[3453]414       
[13337]415ifdef(`X8632',`
416define(`tra',`
[5009]417        .p2align 3
[10089]418        .long 0
419        .byte 0
420$1:     
[13337]421')',`
422define(`tra',`
[10089]423        .p2align 3
[13337]424        ifelse($2,`',`
[3390]425        .long 0
[13337]426        ',`
[2836]427        .long $1-$2
[13337]428        ')
[3390]429$1:     
[13337]430')')
[10089]431
[13337]432ifdef(`X8632',`
433define(`do_funcall',`
[10089]434        new_macro_labels()
435        extract_fulltag(%temp0,%imm0)
436        __(cmpb $fulltag_misc,%imm0_b)
437        __(jne macro_label(bad))
438        __(cmpb $subtag_function,misc_subtag_offset(%temp0))
439        __(jne macro_label(maybe_symbol))
440        __(mov %temp0,%fn)
441        __(jmp *%fn)
442macro_label(maybe_symbol):
443        __(cmpb $subtag_symbol,misc_subtag_offset(%temp0))
444        __(jne macro_label(bad))
445        /* %fname == %temp0 */
446        __(mov symbol.fcell(%fname),%fn)
447        __(jmp *%fn)
448macro_label(bad):
449        __(uuo_error_not_callable)
[13337]450')',`
451define(`do_funcall',`
[2836]452        new_macro_labels()
[8242]453        __(movb %temp0_b,%imm0_b)
454        __(andb $fulltagmask,%imm0_b)
455        __(cmpb $fulltag_symbol,%imm0_b)
[4315]456        /* %fname == %temp0   */
[8242]457        __(cmovgq %temp0,%fn)
[3846]458        jl macro_label(bad)
[8242]459        __(cmoveq symbol.fcell(%fname),%fn)
460        __(jmp *%fn)
[3846]461macro_label(bad):               
462        __(uuo_error_not_callable)
[13337]463')')
[3334]464
[13337]465define(`getvheader',`
[10089]466        __(mov misc_header_offset($1),$2)
[13337]467')
[3334]468
[4315]469/* "Size" is unboxed element-count.  $1 (header) and $2 (dest) should  */
470/*    both be immediate registers   */
[13337]471define(`header_size',`
[10089]472        __(mov $1,$2)
[8242]473        __(shr $num_subtag_bits,$2)
[13337]474')
[3334]475
[4315]476/* $2 (length) is fixnum element-count.   */
[13337]477define(`header_length',`
[10089]478        __(mov $~255,$2)
479        __(and $1,$2)
[8242]480        __(shr $num_subtag_bits-fixnumshift,$2)
[13337]481')
[3334]482
[4315]483/* $1 = vector, $2 = header, $3 = dest   */
[13337]484define(`vector_size',`                                 
[10089]485        __(getvheader($1,$2))
486        __(header_size($2,$3))
[13337]487')
[3334]488
[4315]489/* $1 = vector, $2 = dest   */
[13337]490define(`vector_length',`                                 
[10089]491        __(mov $~255,$2)
492        __(and misc_header_offset($1),$2)
[8242]493        __(shr $num_subtag_bits-fixnumshift,$2)
[13337]494')
[3341]495               
[4315]496/* GAS/ATT comparison arg order drives me nuts   */
[13337]497define(`rcmpq',`
[8242]498        __(cmpq $2,$1)
[13337]499')
[3368]500
[13337]501define(`rcmpl',`
[8242]502        __(cmpl $2,$1)
[13337]503')     
[3368]504
[13337]505define(`rcmpw',`
[8242]506        __(cmpw $2,$1)
[13337]507')     
[3368]508
[13337]509define(`rcmpb',`
[8242]510        __(cmpb $2,$1)
[13337]511')             
[3368]512
513
[13337]514define(`condition_to_boolean',`
515        __(movl `$'t_value,$2_l)
[8242]516        __(lea (-t_offset)($2),$3)
517        __(cmov$1l $2_l,$3_l)
[13337]518')
[3537]519
[13337]520ifdef(`X8632',`
521define(`compare_reg_to_nil',`
[10089]522        __(cmp $nil_value,$1)
[13337]523')',`
524define(`compare_reg_to_nil',`
[8242]525        __(cmpb $fulltag_nil,$1_b)
[13337]526')')
[10089]527
[13337]528ifdef(`X8632',`
529define(`extract_lisptag',`
[10089]530        __(movl $1,$2)
[13337]531        __(and `$'tagmask,$2)
532')',`
533define(`extract_lisptag',`
[8242]534        __(movzbl $1_b,$2_l)
[13337]535        __(andb `$'tagmask,$2_b)
536')')
[4142]537
[3368]538                                                               
[13337]539define(`extract_fulltag',`
[8242]540        __(movzbl $1_b,$2_l)
[13337]541        __(andb `$'fulltagmask,$2_b)
542')
[3368]543
[14631]544ifdef(`X8664',`
[13337]545define(`extract_subtag',`
[14629]546        __(movzbl misc_subtag_offset($1),$2_l)
[13337]547')
[14631]548',`
549define(`extract_subtag',`
550        __(movb misc_subtag_offset($1),$2)
551')')       
552               
[3390]553
[14629]554
[13337]555ifdef(`X8632',`
556define(`extract_typecode',`
[3699]557        new_macro_labels()
[10089]558        __(mov $1,$2)
559        __(andl $tagmask,$2)
560        __(cmpb $tag_misc,$2_b)
561        __(jne macro_label(done))
562        __(movb misc_subtag_offset($1),$2_b)
563macro_label(done):
[13337]564')',`
565define(`extract_typecode',`
[10089]566        new_macro_labels()
[8242]567        __(movzbl $1_b,$2_l)
568        __(andb $tagmask,$2_b)
569        __(cmpb $tag_misc,$2_b)
570        __(jne macro_label(done))
571        __(movb misc_subtag_offset($1),$2_b)
[10089]572macro_label(done):
[13337]573')')
[3453]574
[4315]575/* dnode_align(src,delta,dest)  */
[4299]576
[13337]577define(`dnode_align',`
[8242]578        __(lea ($2+(dnode_size-1))($1),$3)
579        __(andb $~(dnode_size-1),$3_b)
[13337]580')
[10089]581
[13337]582ifdef(`X8632',`
583define(`push_argregs',`
[3453]584        new_macro_labels()
[10089]585        /* xxx hack alert: when the compiler calls a keyword subprim */
586        /* (SPsimple_keywords, SPkeyword_args, SP_keyword_bind) */
587        /* it puts some flags in the upper half of %temp1, which
588        /* is %nargs.  We use the cmpw here to avoid seeing those flags. */
[13337]589        __(cmpw `$'1*node_size,%nargs_w)
[10089]590        __(jb macro_label(done))
591        __(je macro_label(z))
592        __(push %arg_y)
593macro_label(z):
594        __(push %arg_z)
595macro_label(done):
[13337]596')',`
597define(`push_argregs',`
[10089]598        new_macro_labels()
[8341]599        __(testl %nargs,%nargs)
[8242]600        __(jz macro_label(done))
[13337]601        __(cmpl `$'2*node_size,%nargs)
[8242]602        __(je macro_label(yz))
603        __(jb macro_label(z))
604        __(push %arg_x)
[3453]605macro_label(yz):
[8242]606        __(push %arg_y)
[3453]607macro_label(z):
[8242]608        __(push %arg_z)
[3453]609macro_label(done):
[13337]610')')   
[3459]611
612
[4315]613/* $1 = ndigits.  Assumes 4-byte digits           */
[13337]614define(`aligned_bignum_size',`((~(dnode_size-1)&(node_size+(dnode_size-1)+(4*$1))))')
[3537]615
[13337]616define(`discard_temp_frame',`
[10089]617        __(mov rcontext(tcr.save_tsp),$1)
618        __(mov ($1),$1)
619        __(mov $1,rcontext(tcr.save_tsp))
620        __(mov $1,rcontext(tcr.next_tsp))
[13337]621')
[4753]622
[13337]623ifdef(`X8632',`
624define(`check_pending_enabled_interrupt',`
625        __(btrl `$'31,rcontext(tcr.interrupt_pending))
[10089]626        __(jnc $1)
627        interrupt_now()
[13337]628')',`
629define(`check_pending_enabled_interrupt',`
630        __(btrq `$'63,rcontext(tcr.interrupt_pending))
[10387]631        __(jnc $1)
[4043]632        interrupt_now()
[13337]633')')
[4043]634       
[4315]635/* $1 = scratch register, used to access tcr.tlb_pointer.  An interrupt  */
636/*   should be taken if interrupts are enabled and the most significant  */
637/*   bit of tcr.interrupt_pending is set.  If we take the interrupt, we  */
638/*   test and clear the pending bit.  */
[4299]639
[13337]640define(`check_pending_interrupt',`
[4043]641        new_macro_labels()
[10089]642        __(mov rcontext(tcr.tlb_pointer),$1)
[13337]643        __(cmp `$'0,INTERRUPT_LEVEL_BINDING_INDEX($1))
[10089]644        __(js macro_label(done))
[4043]645        check_pending_enabled_interrupt(macro_label(done))
646macro_label(done):
[13337]647')
[4982]648
[6529]649/*  On AMD hardware (at least), a one-byte RET instruction should be */
650/*  prefixed with a REP prefix if it (a) is the target of a  */
651/*  branch or (b) immediately follows a conditional branch not taken. */
[13337]652define(`repret',`
[8242]653        __(.byte 0xf3)
654        __(ret)
[13337]655')
[10089]656
[13337]657ifdef(`X8632',`
658define(`regnum',`ifelse($1, `%eax', `0',
659       $1, `%ecx', `1',
660       $1, `%edx', `2',
661       $1, `%ebx', `3',
662       $1, `%esp', `4',
663       $1, `%ebp', `5',
664       $1, `%esi', `6',
665       $1, `%edi', `7',
[10089]666        "unknown register")dnl
[13337]667')
[10089]668
[13337]669define(`mark_as_node', `
[10089]670        __(xorl $1,$1)
[13337]671        __(orb `$'(1<<regnum($1)), rcontext(tcr.node_regs_mask))
672')
[10089]673
[13337]674define(`mark_as_imm',`
675        __(andb `$'~(1<<regnum($1)), rcontext(tcr.node_regs_mask))
676')
677')
[10089]678
[13337]679define(`check_cstack_alignment',`
[10499]680        new_macro_labels()
[13337]681        __(testb `$'7,rcontext(tcr.foreign_sp))
[10499]682        __(je macro_label(done))
683        __(hlt)
684macro_label(done):
[13337]685')
[11828]686
[13337]687        __ifdef(`WINDOWS')
688define(`windows_cstack_probe',`
[11828]689        new_macro_labels()
[13337]690        __(cmp `$'0x1000,$1)
[11828]691        __(jb macro_label(done))
[11829]692        __(mov rcontext(tcr.foreign_sp),$2)
[13337]693        __(orl `$'0,-0x1000($2))
694        __(cmp `$'0x2000,$1)
[11828]695        __(jb macro_label(done))
[13337]696        __(orl `$'0,-0x2000($2))
697        __(cmp `$'0x3000,$1)
[11828]698        __(jb macro_label(done))
[13337]699        __(orl `$'0,-0x3000($2))
700        __(cmp `$'0x4000,$1)
[11828]701        __(jb macro_label(done))
[13337]702        __(orl `$'0,-0x4000($2))
703        __(cmp `$'0x5000,$1)
[11828]704        __(jb macro_label(done))
[13337]705        __(orl `$'0,-0x5000($2))
706        __(cmp `$'0x6000,$1)
[11828]707        __(jb macro_label(done))
[13337]708        __(orl `$'0,-0x6000($2))
709        __(cmp `$'0x7000,$1)
[11828]710        __(jb macro_label(done))
[13337]711        __(orl `$'0,-0x7000($2))
712        __(cmp `$'0x8000,$1)
[11828]713        __(jb macro_label(done))
[13337]714        __(orl `$'0,-0x8000($2))
715        __(cmp `$'0x9000,$1)
[11828]716        __(jb macro_label(done))
[13337]717        __(orl `$'0,-0x9000($2))
718        __(cmp `$'0xa000,$1)
[11828]719        __(jb macro_label(done))
[13337]720        __(orl `$'0,-0xa000($2))
721        __(cmp `$'0xb000,$1)
[11828]722        __(jb macro_label(done))
[13337]723        __(orl `$'0,-0xb000($2))
724        __(cmp `$'0xc000,$1)
[11828]725        __(jb macro_label(done))
[13337]726        __(orl `$'0,-0xc000($2))
727        __(cmp `$'0xd000,$1)
[11828]728        __(jb macro_label(done))
[13337]729        __(orl `$'0,-0xd000($2))
730        __(cmp `$'0xe000,$1)
[11828]731        __(jb macro_label(done))
[13337]732        __(orl `$'0,-0xe000($2))
733        __(cmp `$'0xf000,$1)
[11828]734        __(jb macro_label(done))
[13337]735        __(orl `$'0,-0xf000($2))
[11828]736macro_label(done):     
[13337]737')
[11828]738
739
740        __endif               
[13067]741                       
Note: See TracBrowser for help on using the repository browser.