source: release/1.7/source/lisp-kernel/x86-macros.s @ 15267

Last change on this file since 15267 was 14631, checked in by gb, 8 years ago

Conditionalize definition of extract_subtag, since we have to write
to byte registers on x8632. (I don't remember if there's a penalty
for doing so.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.6 KB
Line 
1/*   Copyright (C) 2005-2009 Clozure Associates  */
2/*   This file is part of Clozure CL.    */
3
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  */
6/*   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,  */
7/*   which is distributed with Clozure CL as the file "LGPL".  Where these  */
8/*   conflict, the preamble takes precedence.    */
9
10/*   Clozure CL is referenced in the preamble as the "LIBRARY."  */
11
12/*   The LLGPL is also available online at  */
13/*   http://opensource.franz.com/preamble.html  */
14
15
16/* Try to make macros follow GAS/ATT conventions, where source precedes  */
17/* destination.  */
18
19define(`lisp_global',`lisp_globals.$1')
20                                       
21define(`ref_global',`
22        __(mov lisp_global($1),$2)
23')
24
25define(`set_global',`
26        __(mov $1,lisp_global($2))
27')
28
29define(`ref_nrs_value',`
30        __(mov nrs.$1+symbol.vcell,$2)
31')
32       
33define(`set_nrs_value',`
34        __(mov $1,nrs.$2+symbol.vcell)
35')
36                                                       
37define(`unbox_fixnum',`
38        __(mov $1,$2)
39        __(sar `$'fixnumshift,$2)
40')
41
42define(`box_fixnum',`
43        __(imul `$'fixnumone,$1,$2)
44')     
45
46
47/* box_fixnum, with no effect on flags */
48define(`box_fixnum_no_flags',`
49        __(lea (,$1,fixnumone),$2)
50')
51
52
53/* Zero $3 bytes worth of dnodes, starting at offset $2 relative  */
54/* to the base register $1.  */
55
56
57ifdef(`DarwinAssembler',`
58        .macro zero_dnodes
59        .if $2
60        ifdef(`X8664',`
61        __(movapd %fpzero,$1($0))
62        ',`
63        __(movsd %fpzero,$1($0))
64        ')
65        __(zero_dnodes $0,$1+dnode_size,$2-dnode_size)
66        .endif
67        .endmacro
68',`
69        .macro zero_dnodes base,disp,nbytes
70        .ifgt \nbytes
71        ifdef(`X8664',`
72        movapd %fpzero,\disp(\base)
73        ',`
74        movsd %fpzero,\disp(\base)
75        ')
76        zero_dnodes \base,"\disp+dnode_size","\nbytes-dnode_size"
77        .endif
78        .endm
79')     
80
81
82/* Allocate $1+dnode_size zeroed bytes on the tstack, using $2 as a temp  */
83/* reg.  */
84
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))
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))
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))
100        __(movq rcontext(tcr.save_tsp),%stack_temp)
101        __(movq rcontext(tcr.next_tsp),$2)
102        zero_dnodes $2,0,TSP_Alloc_Size
103        __(movq %stack_temp,($2))
104        __(movq %rbp,tsp_frame.save_rbp($2))
105        __(movq $2,rcontext(tcr.save_tsp))
106        undefine(`TSP_Alloc_Size')
107')')
108
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  */
111
112ifdef(`X8632',`
113define(`TSP_Alloc_Var',`
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)
131')',`
132define(`TSP_Alloc_Var',`
133        new_macro_labels()
134        subq $1,rcontext(tcr.next_tsp)
135        __(movq rcontext(tcr.save_tsp),%stack_temp)
136        __(movq rcontext(tcr.next_tsp),$2)
137        __(jmp macro_label(test))
138macro_label(loop):
139        __(movapd %fpzero,0($2))
140        __(addq $dnode_size,$2)
141macro_label(test):     
142        __(subq $dnode_size,$1)
143        __(jge macro_label(loop))
144        __(movq rcontext(tcr.next_tsp),$2)
145        __(movd %stack_temp,$1)
146        __(movq $1,($2))
147        __(movq %rbp,tsp_frame.save_rbp($2))
148        __(movq $2,rcontext(tcr.save_tsp))
149        __(addq $dnode_size,$2)
150')')
151       
152       
153ifdef(`X8632',`
154define(`Allocate_Catch_Frame',`
155        TSP_Alloc_Fixed(catch_frame.size,$1)
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',`
160        TSP_Alloc_Fixed(catch_frame.size,$1)
161        __(movq `$'(catch_frame.element_count<<subtag_shift)|subtag_catch_frame,dnode_size($1))
162        __(addq `$'dnode_size+fulltag_misc,$1)
163')')
164
165/* %arg_z = tag,  %xfn = pc, $1 = mvflag          */
166
167ifdef(`X8632',`
168define(`Make_Catch',`
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))
174        __(movl `$'$1,catch_frame.mvflag(%imm0))
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))
184')',`
185define(`Make_Catch',`
186        Allocate_Catch_Frame(%imm2)
187        __(movq rcontext(tcr.catch_top),%imm0)
188        __(movq rcontext(tcr.db_link),%imm1)
189        __(movq %arg_z,catch_frame.catch_tag(%imm2))
190        __(movq %imm0,catch_frame.link(%imm2))
191        __(movq `$'$1,catch_frame.mvflag(%imm2))
192        __(movq rcontext(tcr.xframe),%imm0)
193        __(movq %rsp,catch_frame.rsp(%imm2))
194        __(movq %rbp,catch_frame.rbp(%imm2))
195        __(movq rcontext(tcr.foreign_sp),%stack_temp)
196        __(movq %imm1,catch_frame.db_link(%imm2))
197        __ifndef(`WINDOWS')
198        __(movq %save3,catch_frame._save3(%imm2))
199        __endif
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))
206        __(movq %imm2,rcontext(tcr.catch_top))
207')')   
208
209ifdef(`X8632',`
210define(`nMake_Catch',`
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))
218        __(movl `$'$1,catch_frame.mvflag(%imm0))
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))
227')',`   
228define(`nMake_Catch',`
229        Allocate_Catch_Frame(%imm2)
230        __(movq rcontext(tcr.catch_top),%imm0)
231        __(movq rcontext(tcr.db_link),%imm1)
232        __(movq %arg_z,catch_frame.catch_tag(%imm2))
233        __(movq %imm0,catch_frame.link(%imm2))
234        __(lea node_size(%rsp),%imm0)
235        __(movq `$'$1,catch_frame.mvflag(%imm2))
236        __(movq %imm0,catch_frame.rsp(%imm2))
237        __(movq rcontext(tcr.xframe),%imm0)
238        __(movq %rbp,catch_frame.rbp(%imm2))
239        __(movq rcontext(tcr.foreign_sp),%stack_temp)
240        __(movq %imm1,catch_frame.db_link(%imm2))
241        __ifndef(`WINDOWS')
242        __(movq %save3,catch_frame._save3(%imm2))
243        __endif
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))
250        __(movq %imm2,rcontext(tcr.catch_top))
251')')   
252               
253       
254/* Consing can get interrupted (either by PROCESS-INTERRUPT or by GC  */
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  */
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  */
261/* %allocptr = %temp0 as a freepointer; when consing, %temp0 can not  */
262/* contain a live value.)  */
263/* Making a CONS cell is a little simpler than making a uvector.  */
264
265/* $1=new_car,$2=new_cdr,$3=dest   */
266
267ifdef(`X8632',`
268define(`Cons',`
269        new_macro_labels()
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   */
273        __(subl $cons.size-fulltag_cons,rcontext(tcr.save_allocptr))
274        __(movl rcontext(tcr.save_allocptr),%allocptr)
275        __(rcmpl(%allocptr,rcontext(tcr.save_allocbase)))
276        __(ja macro_label(no_trap))
277        uuo_alloc()
278macro_label(no_trap):
279        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
280/* Easy to interrupt now that tcr.save_allocptr is not tagged as a cons    */
281        __(movl $2,cons.cdr(%allocptr))
282        __(movl $1,cons.car(%allocptr))
283        ifelse($3,`',`',`
284         __(movl %allocptr,$3)
285        ')
286')',`
287
288define(`Cons',`
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   */
293        __(subq $cons.size-fulltag_cons,rcontext(tcr.save_allocptr))
294        __(movq rcontext(tcr.save_allocptr),%allocptr)
295        __(rcmpq(%allocptr,rcontext(tcr.save_allocbase)))
296        __(ja macro_label(no_trap))
297        uuo_alloc()
298macro_label(no_trap):   
299        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
300/* Easy to interrupt now that tcr.save_allocptr is not tagged as a cons    */
301        __(movq $2,cons.cdr(%allocptr))
302        __(movq $1,cons.car(%allocptr))
303        ifelse($3,`',`',`
304         __(movq %allocptr,$3)
305        ')
306')')
307
308ifdef(`X8632',`
309/* Header in %mm0, size in bytes in %imm0.  We bash %imm0. */
310define(`Misc_Alloc',`
311        __(sub `$'fulltag_misc,%imm0)
312        Misc_Alloc_Internal($1)
313')',`
314/* Header in %imm0, size in bytes in %imm1.  We bash %imm1. */
315define(`Misc_Alloc',`
316        __(subq `$'fulltag_misc,%imm1)
317        Misc_Alloc_Internal($1)
318')')
319
320/* Here Be Monsters: we have to treat some/all of this instruction   */
321/* sequence atomically, as soon as tcr.save_allocptr becomes tagged.  */
322               
323ifdef(`X8632',`
324define(`Misc_Alloc_Internal',`                 
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)
329        __(ja macro_label(no_trap))
330        uuo_alloc()
331macro_label(no_trap):   
332        __(movd %mm0,misc_header_offset(%allocptr))
333        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
334/* Now that tcr.save_allocptr is untagged, it is easier to be interrupted   */
335        ifelse($1,`',`',`
336         __(mov %allocptr,$1)
337        ')
338')',`   
339define(`Misc_Alloc_Internal',`                 
340        new_macro_labels()
341        __(subq %imm1,rcontext(tcr.save_allocptr))
342        __(movq rcontext(tcr.save_allocptr),%allocptr)
343        __(rcmpq(%allocptr,rcontext(tcr.save_allocbase)))
344        __(ja macro_label(no_trap))
345        uuo_alloc()
346macro_label(no_trap):   
347        __(movq %imm0,misc_header_offset(%allocptr))
348        __(andb $~fulltagmask,rcontext(tcr.save_allocptr))
349/* Now that tcr.save_allocptr is untagged, it is easier to be interrupted   */
350        ifelse($1,`',`',`
351         __(mov %allocptr,$1)
352        ')
353')')
354
355ifdef(`X8632',`
356define(`Misc_Alloc_Fixed',`
357        __(mov `$'$2-fulltag_misc,%imm0)
358        Misc_Alloc_Internal($1)
359')',`
360define(`Misc_Alloc_Fixed',`
361        __(movq `$'$2-fulltag_misc,%imm1)
362        Misc_Alloc_Internal($1)
363')')                                   
364
365define(`vrefr',`
366        __(mov misc_data_offset+($3<<word_shift)($2),$1)
367')     
368
369define(`jump_fn',`
370        __(jmp *%fn)
371')
372                       
373define(`jump_fname',`
374        __(mov symbol.fcell(%fname),%fn)
375        jump_fn()
376')     
377
378ifdef(`X8632',`
379define(`set_nargs',`
380        __(xorl %nargs,%nargs)
381        __(addl `$'$1<<fixnumshift,%nargs)
382')',`
383define(`set_nargs',`
384        ifelse(eval($1>15),1,`
385        __(movl `$'$1<<fixnumshift,%nargs)
386        ',`
387        __(xorl %nargs,%nargs)
388        ifelse(eval($1),0,`',`
389        __(addl `$'$1<<fixnumshift,%nargs)
390        ')')')
391')
392
393/* $1 = ndigits.  Assumes 4-byte digits           */
394define(`aligned_bignum_size',`((~(dnode_size-1)&(node_size+(dnode_size-1)+(4*$1))))')
395       
396
397define(`_car',`
398        __(mov cons.car($1),$2)
399')     
400
401define(`_rplaca',`
402        __(mov $2,cons.car($1))
403')     
404               
405define(`_cdr',`
406        __(mov cons.cdr($1),$2)
407')
408
409define(`_rplacd',`
410        __(mov $2,cons.cdr($1))
411')     
412               
413       
414       
415ifdef(`X8632',`
416define(`tra',`
417        .p2align 3
418        .long 0
419        .byte 0
420$1:     
421')',`
422define(`tra',`
423        .p2align 3
424        ifelse($2,`',`
425        .long 0
426        ',`
427        .long $1-$2
428        ')
429$1:     
430')')
431
432ifdef(`X8632',`
433define(`do_funcall',`
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)
450')',`
451define(`do_funcall',`
452        new_macro_labels()
453        __(movb %temp0_b,%imm0_b)
454        __(andb $fulltagmask,%imm0_b)
455        __(cmpb $fulltag_symbol,%imm0_b)
456        /* %fname == %temp0   */
457        __(cmovgq %temp0,%fn)
458        jl macro_label(bad)
459        __(cmoveq symbol.fcell(%fname),%fn)
460        __(jmp *%fn)
461macro_label(bad):               
462        __(uuo_error_not_callable)
463')')
464
465define(`getvheader',`
466        __(mov misc_header_offset($1),$2)
467')
468
469/* "Size" is unboxed element-count.  $1 (header) and $2 (dest) should  */
470/*    both be immediate registers   */
471define(`header_size',`
472        __(mov $1,$2)
473        __(shr $num_subtag_bits,$2)
474')
475
476/* $2 (length) is fixnum element-count.   */
477define(`header_length',`
478        __(mov $~255,$2)
479        __(and $1,$2)
480        __(shr $num_subtag_bits-fixnumshift,$2)
481')
482
483/* $1 = vector, $2 = header, $3 = dest   */
484define(`vector_size',`                                 
485        __(getvheader($1,$2))
486        __(header_size($2,$3))
487')
488
489/* $1 = vector, $2 = dest   */
490define(`vector_length',`                                 
491        __(mov $~255,$2)
492        __(and misc_header_offset($1),$2)
493        __(shr $num_subtag_bits-fixnumshift,$2)
494')
495               
496/* GAS/ATT comparison arg order drives me nuts   */
497define(`rcmpq',`
498        __(cmpq $2,$1)
499')
500
501define(`rcmpl',`
502        __(cmpl $2,$1)
503')     
504
505define(`rcmpw',`
506        __(cmpw $2,$1)
507')     
508
509define(`rcmpb',`
510        __(cmpb $2,$1)
511')             
512
513
514define(`condition_to_boolean',`
515        __(movl `$'t_value,$2_l)
516        __(lea (-t_offset)($2),$3)
517        __(cmov$1l $2_l,$3_l)
518')
519
520ifdef(`X8632',`
521define(`compare_reg_to_nil',`
522        __(cmp $nil_value,$1)
523')',`
524define(`compare_reg_to_nil',`
525        __(cmpb $fulltag_nil,$1_b)
526')')
527
528ifdef(`X8632',`
529define(`extract_lisptag',`
530        __(movl $1,$2)
531        __(and `$'tagmask,$2)
532')',`
533define(`extract_lisptag',`
534        __(movzbl $1_b,$2_l)
535        __(andb `$'tagmask,$2_b)
536')')
537
538                                                               
539define(`extract_fulltag',`
540        __(movzbl $1_b,$2_l)
541        __(andb `$'fulltagmask,$2_b)
542')
543
544ifdef(`X8664',`
545define(`extract_subtag',`
546        __(movzbl misc_subtag_offset($1),$2_l)
547')
548',`
549define(`extract_subtag',`
550        __(movb misc_subtag_offset($1),$2)
551')')       
552               
553
554
555ifdef(`X8632',`
556define(`extract_typecode',`
557        new_macro_labels()
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):
564')',`
565define(`extract_typecode',`
566        new_macro_labels()
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)
572macro_label(done):
573')')
574
575/* dnode_align(src,delta,dest)  */
576
577define(`dnode_align',`
578        __(lea ($2+(dnode_size-1))($1),$3)
579        __(andb $~(dnode_size-1),$3_b)
580')
581
582ifdef(`X8632',`
583define(`push_argregs',`
584        new_macro_labels()
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. */
589        __(cmpw `$'1*node_size,%nargs_w)
590        __(jb macro_label(done))
591        __(je macro_label(z))
592        __(push %arg_y)
593macro_label(z):
594        __(push %arg_z)
595macro_label(done):
596')',`
597define(`push_argregs',`
598        new_macro_labels()
599        __(testl %nargs,%nargs)
600        __(jz macro_label(done))
601        __(cmpl `$'2*node_size,%nargs)
602        __(je macro_label(yz))
603        __(jb macro_label(z))
604        __(push %arg_x)
605macro_label(yz):
606        __(push %arg_y)
607macro_label(z):
608        __(push %arg_z)
609macro_label(done):
610')')   
611
612
613/* $1 = ndigits.  Assumes 4-byte digits           */
614define(`aligned_bignum_size',`((~(dnode_size-1)&(node_size+(dnode_size-1)+(4*$1))))')
615
616define(`discard_temp_frame',`
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))
621')
622
623ifdef(`X8632',`
624define(`check_pending_enabled_interrupt',`
625        __(btrl `$'31,rcontext(tcr.interrupt_pending))
626        __(jnc $1)
627        interrupt_now()
628')',`
629define(`check_pending_enabled_interrupt',`
630        __(btrq `$'63,rcontext(tcr.interrupt_pending))
631        __(jnc $1)
632        interrupt_now()
633')')
634       
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.  */
639
640define(`check_pending_interrupt',`
641        new_macro_labels()
642        __(mov rcontext(tcr.tlb_pointer),$1)
643        __(cmp `$'0,INTERRUPT_LEVEL_BINDING_INDEX($1))
644        __(js macro_label(done))
645        check_pending_enabled_interrupt(macro_label(done))
646macro_label(done):
647')
648
649/* This should only be called from a foreign context; it should be */
650/* assumed to bash all non-volatile C registers.  And of course it is */
651/* ugly, awful, non-portable, and slow.  %rdi should point to the */
652/* linear address that %gs should be made to address (tcr or pthread data) */
653                               
654ifdef(`DARWIN_GS_HACK',`
655define(`set_gs_base',`
656        ifelse($1,`',`
657        ',`
658        __(movq $1,%rdi)
659        ')
660        __(movl `$'0x3000003,%eax)
661        __(syscall)
662')
663
664/* %gs addresses the tcr.  Make it address pthread data before running */
665/* foreign code */       
666       
667define(`set_foreign_gs_base',`
668        set_gs_base(`rcontext(tcr.osid)')
669')
670
671/* %gs addresses the tcr.  Get the linear address of the tcr and */
672/* copy it to $1 */
673
674define(`save_tcr_linear',`
675        __(movq rcontext(tcr.linear),$1)
676')
677       
678')
679
680/*  On AMD hardware (at least), a one-byte RET instruction should be */
681/*  prefixed with a REP prefix if it (a) is the target of a  */
682/*  branch or (b) immediately follows a conditional branch not taken. */
683define(`repret',`
684        __(.byte 0xf3)
685        __(ret)
686')
687
688ifdef(`X8632',`
689define(`regnum',`ifelse($1, `%eax', `0',
690       $1, `%ecx', `1',
691       $1, `%edx', `2',
692       $1, `%ebx', `3',
693       $1, `%esp', `4',
694       $1, `%ebp', `5',
695       $1, `%esi', `6',
696       $1, `%edi', `7',
697        "unknown register")dnl
698')
699
700define(`mark_as_node', `
701        __(xorl $1,$1)
702        __(orb `$'(1<<regnum($1)), rcontext(tcr.node_regs_mask))
703')
704
705define(`mark_as_imm',`
706        __(andb `$'~(1<<regnum($1)), rcontext(tcr.node_regs_mask))
707')
708')
709
710define(`check_cstack_alignment',`
711        new_macro_labels()
712        __(testb `$'7,rcontext(tcr.foreign_sp))
713        __(je macro_label(done))
714        __(hlt)
715macro_label(done):
716')
717
718        __ifdef(`WINDOWS')
719define(`windows_cstack_probe',`
720        new_macro_labels()
721        __(cmp `$'0x1000,$1)
722        __(jb macro_label(done))
723        __(mov rcontext(tcr.foreign_sp),$2)
724        __(orl `$'0,-0x1000($2))
725        __(cmp `$'0x2000,$1)
726        __(jb macro_label(done))
727        __(orl `$'0,-0x2000($2))
728        __(cmp `$'0x3000,$1)
729        __(jb macro_label(done))
730        __(orl `$'0,-0x3000($2))
731        __(cmp `$'0x4000,$1)
732        __(jb macro_label(done))
733        __(orl `$'0,-0x4000($2))
734        __(cmp `$'0x5000,$1)
735        __(jb macro_label(done))
736        __(orl `$'0,-0x5000($2))
737        __(cmp `$'0x6000,$1)
738        __(jb macro_label(done))
739        __(orl `$'0,-0x6000($2))
740        __(cmp `$'0x7000,$1)
741        __(jb macro_label(done))
742        __(orl `$'0,-0x7000($2))
743        __(cmp `$'0x8000,$1)
744        __(jb macro_label(done))
745        __(orl `$'0,-0x8000($2))
746        __(cmp `$'0x9000,$1)
747        __(jb macro_label(done))
748        __(orl `$'0,-0x9000($2))
749        __(cmp `$'0xa000,$1)
750        __(jb macro_label(done))
751        __(orl `$'0,-0xa000($2))
752        __(cmp `$'0xb000,$1)
753        __(jb macro_label(done))
754        __(orl `$'0,-0xb000($2))
755        __(cmp `$'0xc000,$1)
756        __(jb macro_label(done))
757        __(orl `$'0,-0xc000($2))
758        __(cmp `$'0xd000,$1)
759        __(jb macro_label(done))
760        __(orl `$'0,-0xd000($2))
761        __(cmp `$'0xe000,$1)
762        __(jb macro_label(done))
763        __(orl `$'0,-0xe000($2))
764        __(cmp `$'0xf000,$1)
765        __(jb macro_label(done))
766        __(orl `$'0,-0xf000($2))
767macro_label(done):     
768')
769
770
771        __endif               
772                       
Note: See TracBrowser for help on using the repository browser.