source: release/1.3/source/lisp-kernel/x86-macros.s @ 11830

Last change on this file since 11830 was 11830, checked in by gb, 11 years ago

r11828,r11829 (probe during cstack allocation on win32, win64) to 1.3

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.5 KB
Line 
1/*   Copyright (C) 2005 Clozure Associates  */
2/*   This file is part of OpenMCL.    */
3
4/*   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public  */
5/*   License , known as the LLGPL and distributed with OpenMCL as the  */
6/*   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,  */
7/*   which is distributed with OpenMCL as the file "LGPL".  Where these  */
8/*   conflict, the preamble takes precedence.    */
9
10/*   OpenMCL 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's interrupted, the interrupting  */
256/* process needs to be able to determine what's 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't  */
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 isn't 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 isn't 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's 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's 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
544define([extract_subtag],[
545        __(movb misc_subtag_offset($1),$2)
546])
547
548ifdef([X8632],[
549define([extract_typecode],[
550        new_macro_labels()
551        __(mov $1,$2)
552        __(andl $tagmask,$2)
553        __(cmpb $tag_misc,$2_b)
554        __(jne macro_label(done))
555        __(movb misc_subtag_offset($1),$2_b)
556macro_label(done):
557])],[
558define([extract_typecode],[
559        new_macro_labels()
560        __(movzbl $1_b,$2_l)
561        __(andb $tagmask,$2_b)
562        __(cmpb $tag_misc,$2_b)
563        __(jne macro_label(done))
564        __(movb misc_subtag_offset($1),$2_b)
565macro_label(done):
566])])
567
568/* dnode_align(src,delta,dest)  */
569
570define([dnode_align],[
571        __(lea ($2+(dnode_size-1))($1),$3)
572        __(andb $~(dnode_size-1),$3_b)
573])
574
575ifdef([X8632],[
576define([push_argregs],[
577        new_macro_labels()
578        /* xxx hack alert: when the compiler calls a keyword subprim */
579        /* (SPsimple_keywords, SPkeyword_args, SP_keyword_bind) */
580        /* it puts some flags in the upper half of %temp1, which
581        /* is %nargs.  We use the cmpw here to avoid seeing those flags. */
582        __(cmpw [$]1*node_size,%nargs_w)
583        __(jb macro_label(done))
584        __(je macro_label(z))
585        __(push %arg_y)
586macro_label(z):
587        __(push %arg_z)
588macro_label(done):
589])],[
590define([push_argregs],[
591        new_macro_labels()
592        __(testl %nargs,%nargs)
593        __(jz macro_label(done))
594        __(cmpl [$]2*node_size,%nargs)
595        __(je macro_label(yz))
596        __(jb macro_label(z))
597        __(push %arg_x)
598macro_label(yz):
599        __(push %arg_y)
600macro_label(z):
601        __(push %arg_z)
602macro_label(done):
603])])   
604
605
606/* $1 = ndigits.  Assumes 4-byte digits           */
607define([aligned_bignum_size],[((~(dnode_size-1)&(node_size+(dnode_size-1)+(4*$1))))])
608
609define([discard_temp_frame],[
610        __(mov rcontext(tcr.save_tsp),$1)
611        __(mov ($1),$1)
612        __(mov $1,rcontext(tcr.save_tsp))
613        __(mov $1,rcontext(tcr.next_tsp))
614])
615
616ifdef([X8632],[
617define([check_pending_enabled_interrupt],[
618        __(btrl [$]31,rcontext(tcr.interrupt_pending))
619        __(jnc $1)
620        interrupt_now()
621])],[
622define([check_pending_enabled_interrupt],[
623        __(btrq [$]63,rcontext(tcr.interrupt_pending))
624        __(jnc $1)
625        interrupt_now()
626])])
627       
628/* $1 = scratch register, used to access tcr.tlb_pointer.  An interrupt  */
629/*   should be taken if interrupts are enabled and the most significant  */
630/*   bit of tcr.interrupt_pending is set.  If we take the interrupt, we  */
631/*   test and clear the pending bit.  */
632
633define([check_pending_interrupt],[
634        new_macro_labels()
635        __(mov rcontext(tcr.tlb_pointer),$1)
636        __(cmp [$]0,INTERRUPT_LEVEL_BINDING_INDEX($1))
637        __(js macro_label(done))
638        check_pending_enabled_interrupt(macro_label(done))
639macro_label(done):
640])
641
642/* This should only be called from a foreign context; it should be */
643/* assumed to bash all non-volatile C registers.  And of course it's */
644/* ugly, awful, non-portable, and slow.  %rdi should point to the */
645/* linear address that %gs should be made to address (tcr or pthread data) */
646                               
647ifdef([DARWIN_GS_HACK],[
648define([set_gs_base],[
649        ifelse($1,[],[
650        ],[
651        __(movq $1,%rdi)
652        ])
653        __(movl [$]0x3000003,%eax)
654        __(syscall)
655])
656
657/* %gs addresses the tcr.  Make it address pthread data before running */
658/* foreign code */       
659       
660define([set_foreign_gs_base],[
661        set_gs_base([rcontext(tcr.osid)])
662])
663
664/* %gs addresses the tcr.  Get the linear address of the tcr and */
665/* copy it to $1 */
666
667define([save_tcr_linear],[
668        __(movq rcontext(tcr.linear),$1)
669])
670       
671])
672
673/*  On AMD hardware (at least), a one-byte RET instruction should be */
674/*  prefixed with a REP prefix if it (a) is the target of a  */
675/*  branch or (b) immediately follows a conditional branch not taken. */
676define([repret],[
677        __(.byte 0xf3)
678        __(ret)
679])
680
681ifdef([X8632],[
682define([regnum],[ifelse($1, [%eax], [0],
683       $1, [%ecx], [1],
684       $1, [%edx], [2],
685       $1, [%ebx], [3],
686       $1, [%esp], [4],
687       $1, [%ebp], [5],
688       $1, [%esi], [6],
689       $1, [%edi], [7],
690        "unknown register")dnl
691])
692
693define([mark_as_node], [
694        __(xorl $1,$1)
695        __(orb [$](1<<regnum($1)), rcontext(tcr.node_regs_mask))
696])
697
698define([mark_as_imm],[
699        __(andb [$]~(1<<regnum($1)), rcontext(tcr.node_regs_mask))
700])
701])
702
703define([check_cstack_alignment],[
704        new_macro_labels()
705        __(testb [$]7,rcontext(tcr.foreign_sp))
706        __(je macro_label(done))
707        __(hlt)
708macro_label(done):
709])
710
711        __ifdef([WINDOWS])
712define([windows_cstack_probe],[
713        new_macro_labels()
714        __(cmp [$]0x1000,$1)
715        __(jb macro_label(done))
716        __(mov rcontext(tcr.foreign_sp),$2)
717        __(orl [$]0,-0x1000($2))
718        __(cmp [$]0x2000,$1)
719        __(jb macro_label(done))
720        __(orl [$]0,-0x2000($2))
721        __(cmp [$]0x3000,$1)
722        __(jb macro_label(done))
723        __(orl [$]0,-0x3000($2))
724        __(cmp [$]0x4000,$1)
725        __(jb macro_label(done))
726        __(orl [$]0,-0x4000($2))
727        __(cmp [$]0x5000,$1)
728        __(jb macro_label(done))
729        __(orl [$]0,-0x5000($2))
730        __(cmp [$]0x6000,$1)
731        __(jb macro_label(done))
732        __(orl [$]0,-0x6000($2))
733        __(cmp [$]0x7000,$1)
734        __(jb macro_label(done))
735        __(orl [$]0,-0x7000($2))
736        __(cmp [$]0x8000,$1)
737        __(jb macro_label(done))
738        __(orl [$]0,-0x8000($2))
739        __(cmp [$]0x9000,$1)
740        __(jb macro_label(done))
741        __(orl [$]0,-0x9000($2))
742        __(cmp [$]0xa000,$1)
743        __(jb macro_label(done))
744        __(orl [$]0,-0xa000($2))
745        __(cmp [$]0xb000,$1)
746        __(jb macro_label(done))
747        __(orl [$]0,-0xb000($2))
748        __(cmp [$]0xc000,$1)
749        __(jb macro_label(done))
750        __(orl [$]0,-0xc000($2))
751        __(cmp [$]0xd000,$1)
752        __(jb macro_label(done))
753        __(orl [$]0,-0xd000($2))
754        __(cmp [$]0xe000,$1)
755        __(jb macro_label(done))
756        __(orl [$]0,-0xe000($2))
757        __(cmp [$]0xf000,$1)
758        __(jb macro_label(done))
759        __(orl [$]0,-0xf000($2))
760macro_label(done):     
761])
762
763
764        __endif               
765                       
Note: See TracBrowser for help on using the repository browser.