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

Last change on this file was 16685, checked in by rme, 4 years ago

Update copyright/license headers in files.

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