source: trunk/source/lisp-kernel/ppc-macros.s @ 14347

Last change on this file since 14347 was 13337, checked in by plkrueger, 10 years ago

Don't change the m4 quoting characters from their defaults (`').
(On the ARM, square brackets are used to denote memory operands, curly
braces surround register lists, and multicharacter quoting delimeters
look funny ...)

Some versions (at least) of m4 are confused by quoting characters in
comments, so try to refrain from using contractions ...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.8 KB
Line 
1/*   Copyright (C) 2009 Clozure Associates */
2/*   Copyright (C) 1994-2001 Digitool, Inc */
3/*   This file is part of Clozure CL.  */
4
5/*   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public */
6/*   License , known as the LLGPL and distributed with Clozure CL as the */
7/*   file "LICENSE".  The LLGPL consists of a preamble and the LGPL, */
8/*   which is distributed with Clozure CL as the file "LGPL".  Where these */
9/*   conflict, the preamble takes precedence.   */
10
11/*   Clozure CL is referenced in the preamble as the "LIBRARY." */
12
13/*   The LLGPL is also available online at */
14/*   http://opensource.franz.com/preamble.html */
15
16/* The assembler has to do the arithmetic here:  the expression */
17/*   may not be evaluable by m4. */
18define(`lwi',`ifdef(`DARWIN',`
19        .if ((($2) & 0xffff8000) == 0xffff8000)
20         li $1,($2)
21        .elseif ((($2) & 0xffff8000) == 0)
22         li $1,$2
23        .else
24         lis $1,(($2)>>16)
25         .if (($2) & 0xffff) <> 0
26          ori $1,$1,(($2) & 0xffff)
27         .endif
28        .endif',`
29        .ifeq (($2) & 0xffff8000)-0xffff8000
30         li $1,$2
31        .else
32         .ifeq (($2) & 0xffff8000)
33          li $1,$2
34         .else
35          lis $1,($2>>16)
36          .ifne ($2 & 0xffff)
37           ori $1,$1,$2 & 0xffff
38          .endif
39         .endif
40        .endif
41')')
42
43ifdef(`PPC64',`
44        define(`clrrri',`clrrdi $@')       
45        define(`clrlri',`clrldi $@')
46        define(`clrlri_',`clrldi. $@')
47        define(`ldr',`ld $@')
48        define(`ldrx',`ldx $@')
49        define(`ldru',`ldu $@')
50        define(`str',`std $@')
51        define(`strx',`stdx $@')
52        define(`stru',`stdu $@')
53        define(`strux',`stdux $@')     
54        define(`cmpr',`cmpd $@')
55        define(`cmpri',`cmpdi $@')
56        define(`cmplr',`cmpld $@')
57        define(`cmplri',`cmpldi $@')
58        define(`trlge',`tdlge $@')
59        define(`trllt',`tdllt $@')
60        define(`trlt',`tdlt $@')
61        define(`trlle',`tdlle $@')
62        define(`treqi',`tdeqi $@')
63        define(`trnei',`tdnei $@')
64        define(`trgti',`tdgti $@')
65        define(`srari',`sradi $@')
66        define(`srri',`srdi $@')
67        define(`srr',`srd $@')
68        define(`slri',`sldi $@')
69        define(`lrarx',`ldarx $@')
70        define(`strcx',`stdcx. $@')
71        define(`load_highbit',`
72        __(lis $1,0x8000)
73        __(sldi $1,$1,32)
74        ')
75        define(`extract_bit_shift_count',`
76        __(clrldi $1,$2,64-bitmap_shift)
77        ')
78        define(`alloc_trap',`
79        __(tdlt allocptr,allocbase)
80        ')
81        define(`mullr',`mulld $@')
82',`
83        define(`clrrri',`clrrwi $@')
84        define(`clrlri',`clrlwi $@')
85        define(`clrlri_',`clrlwi. $@')
86        define(`ldr',`lwz $@')
87        define(`ldrx',`lwzx $@')
88        define(`ldru',`lwzu $@')
89        define(`str',`stw $@')
90        define(`strx',`stwx $@')
91        define(`stru',`stwu $@')
92        define(`strux',`stwux $@')
93        define(`cmpr',`cmpw $@')
94        define(`cmpri',`cmpwi $@')
95        define(`cmplr',`cmplw $@')
96        define(`cmplri',`cmplwi $@')
97        define(`trlge',`twlge $@')
98        define(`trllt',`twllt $@')
99        define(`trlt',`twlt $@')
100        define(`trlle',`twlle $@')       
101        define(`treqi',`tweqi $@')
102        define(`trnei',`twnei $@')
103        define(`trgti',`twgti $@')
104        define(`srari',`srawi $@')
105        define(`srri',`srwi $@')
106        define(`srr',`srw $@')
107        define(`slri',`slwi $@')
108        define(`lrarx',`lwarx $@')
109        define(`strcx',`stwcx. $@')
110        define(`load_highbit',`
111        __(lis $1,0x8000)
112        ')
113        define(`extract_bit_shift_count',`
114        __(clrlwi $1,$2,32-bitmap_shift)
115        ')
116        define(`alloc_trap',`
117        __(twllt allocptr,allocbase)
118        ')
119        define(`mullr',`mullw $@')
120')
121
122/* dnode_align(dest,src,delta) */
123        define(`dnode_align',`
124        __(la $1,($3+(dnode_size-1))($2))
125        __(clrrri($1,$1,dnode_align_bits))
126')
127
128define(`extract_fulltag',`
129        __(clrlri($1,$2,nbits_in_word-ntagbits))
130        ')
131
132define(`extract_lisptag',`
133        __(clrlri($1,$2,nbits_in_word-nlisptagbits))
134        ')
135
136define(`extract_lisptag_',`
137        __(clrlri_($1,$2,nbits_in_word-nlisptagbits))
138        ')
139
140define(`extract_subtag',`
141        __(lbz $1,misc_subtag_offset($2))
142        ')
143
144ifdef(`PPC64',`
145define(`extract_lowtag',`
146        __(clrldi $1,$2,nbits_in_word-nlowtagbits)
147')
148define(`trap_unless_lowtag_equal',`
149        __(clrldi $3,$1,nbits_in_word-nlowtagbits)
150        __(tdnei $3,$2)
151')               
152        ')
153                               
154define(`extract_lowbyte',`
155        __(clrlri($1,$2,nbits_in_word-num_subtag_bits))
156        ')
157
158define(`extract_header',`
159        __(ldr($1,misc_header_offset($2)))
160        ')
161
162
163ifdef(`PPC64',`
164define(`extract_typecode',`
165        new_macro_labels()
166        __(extract_fulltag($1,$2))
167        __(cmpdi cr0,$1,fulltag_misc)
168        __(extract_lisptag($1,$1))
169        __(bne cr0,macro_label(not_misc))
170        __(extract_subtag($1,$2))
171macro_label(not_misc):
172')',`   
173define(`extract_typecode',`
174        new_macro_labels()
175        __(extract_lisptag($1,$2))
176        __(cmpwi cr0,$1,tag_misc)
177        __(bne cr0,macro_label(not_misc))
178        __(extract_subtag($1,$2))
179macro_label(not_misc):
180')')
181
182define(`box_fixnum',`
183        __(slri($1,$2,fixnumshift))
184        ')
185
186define(`unbox_fixnum',`
187        __(srari($1,$2,fixnumshift))
188        ')
189
190define(`loaddf',`
191        __(lfd $1,dfloat.value($2))')
192       
193define(`storedf',`
194        __(stfd $1,dfloat.value($2))
195        ')
196
197define(`push',`
198        __(stru($1,-node_size($2)))
199        ')
200       
201        /* Generally not a great idea. */
202define(`pop',`
203        __(ldr($1,0($2)))
204        __(la $2,node_size($2))
205        ')
206       
207define(`vpush',`
208        __(push($1,vsp))
209        ')
210       
211define(`vpop',`
212        __(pop($1,vsp))
213        ')
214       
215               
216define(`unlink',`
217        __(ldr($1,0($1)))
218 ')
219
220       
221define(`set_nargs',`
222        __(lwi(nargs,($1)<<fixnumshift))
223        ')
224       
225define(`bitclr',`
226        __(rlwinm $1,$2,0,0x1f&((31-($3))+1),0x1f&((31-($3))-1))
227        ')
228       
229
230define(`vref32',`
231        __(lwz $1,misc_data_offset+(($3)<<2)($2))
232        ')
233       
234define(`vref16',`/* dest,src,n*/
235        __(lhz $1,misc_data_offset+(($3)<<1)($2))
236        ')
237       
238ifdef(`PPC64',`
239        define(`vref64',`
240        __(ld $1,misc_data_offset+(($3)<<3)($2))
241        ')
242
243        define(`vrefr',`
244        __(vref64($1,$2,$3))
245        ')
246',`
247        define(`vrefr',`
248        __(vref32($1,$2,$3))
249        ')
250')
251       
252                       
253define(`getvheader',`
254        __(ldr($1,vector.header($2)))
255        ')
256       
257        /* Size is unboxed element count */
258define(`header_size',`
259        __(srri($1,$2,num_subtag_bits))
260        ')
261       
262        /* "Length" is fixnum element count */
263define(`header_length',`
264ifdef(`PPC64',`
265        __(rldicr $1,$2,nbits_in_word-(num_subtag_bits-nfixnumtagbits),63-nfixnumtagbits)
266        __(clrldi $1,$1,(num_subtag_bits-nfixnumtagbits))
267        ',`               
268        __(rlwinm $1,$2,nbits_in_word-(num_subtag_bits-nfixnumtagbits),(num_subtag_bits-nfixnumtagbits),31-nfixnumtagbits)
269        ')
270')       
271
272
273define(`vector_size',`
274        __(getvheader(ifelse($3.`',$1,$3),$2))
275        __(header_size($1,ifelse($3.`',$1,$3)))
276        ')
277       
278define(`vector_length',`
279        __(getvheader($3,$2))
280        __(header_length($1,$3))
281        ')
282
283       
284define(`ref_global',`
285        __(ldr($1,lisp_globals.$2(0)))
286')
287
288define(`set_global',`
289        __(str($1,lisp_globals.$2(0)))
290')
291
292define(`ref_nrs_value',`
293        __(ldr($1,((nrs.$2)+(symbol.vcell))(0)))
294')
295       
296define(`set_nrs_value',`
297        __(str($1,((nrs.$2)+(symbol.vcell))(0)))
298')
299
300define(`extract_unsigned_byte_bits',`
301ifdef(`PPC64',`
302        __(rldicr $1,$2,64-fixnumshift,63-$3)
303',`               
304        __(rlwinm $1,$2,0,32-fixnumshift,31-($3+fixnumshift))
305')       
306')
307
308define(`extract_unsigned_byte_bits_',`
309ifdef(`PPC64',`
310        __(rldicr. $1,$2,64-fixnumshift,63-$3)
311',`               
312        __(rlwinm. $1,$2,0,32-fixnumshift,31-($3+fixnumshift))
313')       
314')
315
316        /* vpop argregs - nargs is known to be non-zero */
317define(`vpop_argregs_nz',`
318        new_macro_labels()
319        __(cmplri(cr1,nargs,node_size*2))
320        __(vpop(arg_z))
321        __(blt cr1,macro_label(l0))
322        __(vpop(arg_y))
323        __(bne cr1,macro_label(l0))
324        __(vpop(arg_x))
325macro_label(l0):')
326
327               
328        /* vpush argregs */
329define(`vpush_argregs',`
330        new_macro_labels()
331        __(cmplri(cr0,nargs,0))
332        __(cmplri(cr1,nargs,node_size*2))
333        __(beq cr0,macro_label(done))
334        __(blt cr1,macro_label(z))
335        __(beq cr1,macro_label(yz))
336        __(vpush(arg_x))
337macro_label(yz):
338        __(vpush(arg_y))
339macro_label(z):
340        __(vpush(arg_z))
341macro_label(done):
342')
343
344define(`create_lisp_frame',`
345        __(stru(sp,-lisp_frame.size(sp)))
346')
347
348               
349define(`build_lisp_frame',`
350        create_lisp_frame()
351        __(str(ifelse($1,`',fn,$1),lisp_frame.savefn(sp)))
352        __(str(ifelse($2,`',loc_pc,$2),lisp_frame.savelr(sp)))
353        __(str(ifelse($3,`',vsp,$3),lisp_frame.savevsp(sp)))
354')
355
356               
357define(`discard_lisp_frame',`
358        __(la sp,lisp_frame.size(sp))
359        ')
360       
361       
362define(`_car',`
363        __(ldr($1,cons.car($2)))
364')
365       
366define(`_cdr',`
367        __(ldr($1,cons.cdr($2)))
368        ')
369       
370define(`_rplaca',`
371        __(str($2,cons.car($1)))
372        ')
373       
374define(`_rplacd',`
375        __(str($2,cons.cdr($1)))
376        ')
377
378define(`vpush_saveregs',`
379        __(vpush(save7))
380        __(vpush(save6))
381        __(vpush(save5))
382        __(vpush(save4))
383        __(vpush(save3))
384        __(vpush(save2))
385        __(vpush(save1))
386        __(vpush(save0))
387        ')
388       
389define(`restore_saveregs',`
390        __(ldr(save0,node_size*0($1)))
391        __(ldr(save1,node_size*1($1)))
392        __(ldr(save2,node_size*2($1)))
393        __(ldr(save3,node_size*3($1)))
394        __(ldr(save4,node_size*4($1)))
395        __(ldr(save5,node_size*5($1)))
396        __(ldr(save6,node_size*6($1)))
397        __(ldr(save7,node_size*7($1)))
398')
399
400define(`vpop_saveregs',`
401        __(restore_saveregs(vsp))
402        __(la vsp,node_size*8(vsp))
403')
404
405define(`trap_unless_lisptag_equal',`
406        __(extract_lisptag($3,$1))
407        __(trnei($3,$2))
408')
409
410ifdef(`PPC64',`
411define(`trap_unless_list',`
412        new_macro_labels()
413        __(cmpdi ifelse($3,$3,cr0),$1,nil_value)
414        __(extract_fulltag($2,$1))
415        __(beq ifelse($3,$3,cr0),macro_label(is_list))
416        __(tdnei $2,fulltag_cons)
417macro_label(is_list):   
418
419')',`   
420define(`trap_unless_list',`
421        __(trap_unless_lisptag_equal($1,tag_list,$2))
422')
423')
424
425define(`trap_unless_fulltag_equal',`
426        __(extract_fulltag($3,$1))
427        __(trnei($3,$2))
428')
429       
430define(`trap_unless_typecode_equal',`
431        __(extract_typecode($3,$1))
432        __(trnei($3,$2))
433')
434       
435/* "jump" to the code-vector of the function in nfn. */
436define(`jump_nfn',`
437        __(ldr(temp0,_function.codevector(nfn)))
438        __(mtctr temp0)
439        __(bctr)
440')
441
442/* "call the code-vector of the function in nfn. */
443define(`call_nfn',`
444        __(ldr(temp0,_function.codevector(nfn)))
445        __(mtctr temp0)
446        __(bctrl)
447')
448       
449
450/* "jump" to the function in fnames function cell. */
451define(`jump_fname',`
452        __(ldr(nfn,symbol.fcell(fname)))
453        __(jump_nfn())
454')
455
456/* call the function in fnames function cell. */
457define(`call_fname',`
458        __(ldr(nfn,symbol.fcell(fname)))
459        __(call_nfn())
460')
461
462define(`do_funcall',`
463        new_macro_labels()
464        __(extract_fulltag(imm0,temp0))
465        __(cmpri(imm0,fulltag_misc))
466        __(mr nfn,temp0)
467        __(bne- macro_label(bad))
468        __(extract_subtag(imm0,temp0))
469        __(cmpri(imm0,subtag_function))
470        __(cmpri(cr1,imm0,subtag_symbol))
471        __(bne cr0,macro_label(_sym))
472        __(jump_nfn())
473macro_label(_sym):             
474        __(mr fname,temp0)
475        __(bne cr1,macro_label(bad))
476        __(jump_fname())
477macro_label(bad):
478        __(uuo_interr(error_cant_call,temp0))
479')     
480
481define(`mkcatch',`
482        __(mflr loc_pc)
483        __(ldr(imm0,tcr.catch_top(rcontext)))
484        __(lwz imm1,0(loc_pc)) /* a forward branch to the catch/unwind cleanup */
485        __(rlwinm imm1,imm1,0,6,29)     /* extract LI */
486        __(add loc_pc,loc_pc,imm1)
487        __(build_lisp_frame(fn,loc_pc,vsp))
488        __(sub loc_pc,loc_pc,imm1)
489        __(la loc_pc,4(loc_pc)) /* skip over the forward branch */
490        __(mtlr loc_pc)
491        __(lwi(imm4,(catch_frame.element_count<<num_subtag_bits)|subtag_catch_frame))
492        __(ldr(imm3,tcr.xframe(rcontext)))
493        __(ldr(imm1,tcr.db_link(rcontext)))
494        __(TSP_Alloc_Fixed_Unboxed(catch_frame.size))
495        __(la nargs,tsp_frame.data_offset+fulltag_misc(tsp))
496        __(str(imm4,catch_frame.header(nargs)))
497        __(str(arg_z,catch_frame.catch_tag(nargs)))
498        __(str(imm0,catch_frame.link(nargs)))
499        __(str(imm2,catch_frame.mvflag(nargs)))
500        __(str(sp,catch_frame.csp(nargs)))
501        __(str(imm1,catch_frame.db_link(nargs)))
502        __(str(first_nvr,catch_frame.regs+0*node_size(nargs)))
503        __(str(second_nvr,catch_frame.regs+1*node_size(nargs)))
504        __(str(third_nvr,catch_frame.regs+2*node_size(nargs)))
505        __(str(fourth_nvr,catch_frame.regs+3*node_size(nargs)))
506        __(str(fifth_nvr,catch_frame.regs+4*node_size(nargs)))
507        __(str(sixth_nvr,catch_frame.regs+5*node_size(nargs)))
508        __(str(seventh_nvr,catch_frame.regs+6*node_size(nargs)))
509        __(str(eighth_nvr,catch_frame.regs+7*node_size(nargs)))
510        __(str(imm3,catch_frame.xframe(nargs)))
511        __(str(rzero,catch_frame.tsp_segment(nargs)))
512        __(Set_TSP_Frame_Boxed())
513        __(str(nargs,tcr.catch_top(rcontext)))
514        __(li nargs,0)
515
516')     
517
518define(`restore_catch_nvrs',`
519        __(ldr(first_nvr,catch_frame.regs+(node_size*0)($1)))
520        __(ldr(second_nvr,catch_frame.regs+(node_size*1)($1)))
521        __(ldr(third_nvr,catch_frame.regs+(node_size*2)($1)))
522        __(ldr(fourth_nvr,catch_frame.regs+(node_size*3)($1)))
523        __(ldr(fifth_nvr,catch_frame.regs+(node_size*4)($1)))
524        __(ldr(sixth_nvr,catch_frame.regs+(node_size*5)($1)))
525        __(ldr(seventh_nvr,catch_frame.regs+(node_size*6)($1)))
526        __(ldr(eighth_nvr,catch_frame.regs+(node_size*7)($1)))
527')               
528
529define(`DCBZL',`
530        __(.long (31<<26)+(1<<21)+($1<<16)+($2<<11)+(1014<<1))
531')
532       
533define(`check_stack_alignment',`
534        new_macro_labels()
535        __(andi. $1,sp,STACK_ALIGN_MASK)
536        __(beq+ macro_label(stack_ok))
537        __(.long 0)
538macro_label(stack_ok):
539')
540
541define(`stack_align',`((($1)+STACK_ALIGN_MASK)&~STACK_ALIGN_MASK)')
542
543define(`clear_alloc_tag',`
544        __(clrrri(allocptr,allocptr,ntagbits))
545')
546
547/* If the GC interrupts the current thread (after the trap), it needs */
548/*   to ensure that the cons cell that's been "reserved" stays reserved */
549/*   (e.g. the tagged allocptr has to be treated as a node.)  If that */
550/*   reserved cons cell gets tenured, the car and cdr are of a generation */
551/*   that's at least as old (so memoization isn't an issue.) */
552
553/*   More generally, if the GC interrupts a thread when allocptr is */
554/*   tagged as a cons: */
555
556/*    a) if the trap hasn't been taken (yet), the GC should force the */
557/*       thread to resume in such a way that the trap will be taken ; */
558/*       the segment allocator should worry about allocating the object. */
559
560/*    b) If the trap has been taken, allocptr is treated as a node as */
561/*       described above.  Allocbase is made to point to the base of the */
562/*       cons cell, so that the thread's next allocation attempt will */
563/*       invoke the segment allocator. */
564       
565define(`Cons',`
566        __(la allocptr,(-cons.size+fulltag_cons)(allocptr))
567        __(alloc_trap())
568        __(str($3,cons.cdr(allocptr)))
569        __(str($2,cons.car(allocptr)))
570        __(mr $1,allocptr)
571        __(clear_alloc_tag())
572')
573
574
575/* This is probably only used once or twice in the entire kernel, but */
576/* I wanted a place to describe the constraints on the mechanism. */
577
578/* Those constaints are (not surprisingly) similar to those which apply */
579/* to cons cells, except for the fact that the header (and any length */
580/* field that might describe large arrays) has to have been stored in */
581/* the object if the trap has succeeded on entry to the GC.  It follows */
582/* that storing the register containing the header must immediately */
583/* follow the allocation trap (and an auxiliary length register must */
584/* be stored immediately after the header.)  Successfully falling */
585/* through the trap must emulate any header initialization: it would */
586/* be a bad idea to have allocptr pointing to a zero header ... */
587
588
589
590/* Parameters: */
591
592/* $1 = dest reg */
593/* $2 = header.  (For now, assume that this always encodes length ; */
594/* that may change with "large vector" support.) */
595/* $3 = register containing size in bytes.  (We're going to subtract */
596/* fulltag_misc from this; do it in the macro body, rather than force the
597/* (1 ?) caller to do it. */
598
599
600define(`Misc_Alloc',`
601        __(la $3,-fulltag_misc($3))
602        __(sub allocptr,allocptr,$3)
603        __(alloc_trap())
604        __(str($2,misc_header_offset(allocptr)))
605        __(mr $1,allocptr)
606        __(clear_alloc_tag())
607')
608
609/*  Parameters $1, $2 as above; $3 = physical size constant. */
610define(`Misc_Alloc_Fixed',`
611        __(la allocptr,(-$3)+fulltag_misc(allocptr))
612        __(alloc_trap())
613        __(str($2,misc_header_offset(allocptr)))
614        __(mr $1,allocptr)
615        __(clear_alloc_tag())
616')
617
618
619/*  Zero $3 bytes worth of doublewords, starting at offset $2 relative */
620/* to the base register $1. */
621
622
623ifdef(`DARWIN',`
624        .macro zero_doublewords
625        .if $2
626        stfd fp_zero,$1($0)
627        zero_doublewords $0,$1+8,$2-8
628        .endif
629        .endmacro
630')
631
632ifdef(`LINUX',`
633        .macro zero_doublewords base,disp,nbytes
634        .if \nbytes
635        stfd fp_zero,\disp(\base)
636        zero_doublewords \base,\disp+8,\nbytes-8
637        .endif
638        .endm
639')     
640
641define(`Set_TSP_Frame_Unboxed',`
642        __(str(tsp,tsp_frame.type(tsp)))
643')
644
645define(`Set_TSP_Frame_Boxed',`
646        __(str(rzero,tsp_frame.type(tsp)))
647')
648               
649/* A newly allocated TSP frame is always "raw" (has non-zero type, indicating */
650/* that it doesn't contain tagged data. */
651
652define(`TSP_Alloc_Fixed_Unboxed',`
653        __(stru(tsp,-($1+tsp_frame.data_offset)(tsp)))
654        __(Set_TSP_Frame_Unboxed())
655')
656
657define(`TSP_Alloc_Fixed_Unboxed_Zeroed',`
658        __(TSP_Alloc_Fixed_Unboxed($1))
659        __(zero_doublewords tsp,tsp_frame.fixed_overhead,$1)
660')
661
662define(`TSP_Alloc_Fixed_Boxed',`
663        __(TSP_Alloc_Fixed_Unboxed_Zeroed($1))
664        __(Set_TSP_Frame_Boxed())
665')
666
667
668       
669       
670
671/* This assumes that the backpointer points  to the first byte beyond */
672/* each frame.  If we allow segmented tstacks, that constraint might */
673/* complicate  their implementation. */
674/* We don't need to know the size of the frame (positive or negative, */
675/* with or without header).  $1 and $2 are temp registers, $3 is an */
676/* optional CR field. */
677
678
679/* Handle the general case, where the frame might be empty */
680define(`Zero_TSP_Frame',`
681        __(new_macro_labels())
682        __(la $1,tsp_frame.size-8(tsp))
683        __(ldr($2,tsp_frame.backlink(tsp)))
684        __(la $2,-8($2))
685        __(b macro_label(zero_tsp_test))
686macro_label(zero_tsp_loop):
687        __(stfdu fp_zero,8($1))
688macro_label(zero_tsp_test):     
689        __(cmpr(ifelse($3,`',`cr0',$3),$1,$2))
690        __(bne ifelse($3,`',`cr0',$3),macro_label(zero_tsp_loop))
691')
692
693/* Save some branching when we know that the frame can't be empty.*/
694define(`Zero_TSP_Frame_nz',`
695        new_macro_labels()
696        __(la $1,tsp_frame.size-8(tsp))
697        __(ldr($2,tsp_frame.backlink(tsp)))
698        __(la $2,-8($2))
699macro_label(zero_tsp_loop):
700        __(stfdu fp_zero,8($1))
701        __(cmpr(ifelse($3,`',`cr0',$3),$1,$2))
702        __(bne ifelse($3,`',`cr0',$3),macro_label(zero_tsp_loop))
703')
704       
705/* $1 = 8-byte-aligned size, positive.  $2 (optiional) set */
706/* to negated size. */
707define(`TSP_Alloc_Var_Unboxed',`
708        __(neg ifelse($2,`',$1,$2),$1)
709        __(strux(tsp,tsp,ifelse($2,`',$1,$2)))
710        __(Set_TSP_Frame_Unboxed())
711')
712
713define(`TSP_Alloc_Var_Boxed',`
714        __(TSP_Alloc_Var_Unboxed($1))
715        __(Zero_TSP_Frame($1,$2))
716        __(Set_TSP_Frame_Boxed())
717')             
718
719
720define(`TSP_Alloc_Var_Boxed_nz',`
721        __(TSP_Alloc_Var_Unboxed($1))
722        __(Zero_TSP_Frame_nz($1,$2))
723        __(Set_TSP_Frame_Boxed())
724')             
725
726define(`check_pending_interrupt',`
727        new_macro_labels()
728        __(ldr(nargs,tcr.tlb_pointer(rcontext)))
729        __(ldr(nargs,INTERRUPT_LEVEL_BINDING_INDEX(nargs)))
730        __(cmpri(ifelse($1,`',`cr0',$1),nargs,0))
731        __(blt ifelse($1,`',`cr0',$1),macro_label(done))
732        __(bgt ifelse($1,`',`cr0',$1),macro_label(trap))
733        __(ldr(nargs,tcr.interrupt_pending(rcontext)))
734macro_label(trap):
735        __(trgti(nargs,0))
736macro_label(done):
737')
738
739/* $1 = ndigits.  Assumes 4-byte digits */       
740define(`aligned_bignum_size',`((~(dnode_size-1)&(node_size+(dnode_size-1)+(4*$1))))')
741
742define(`suspend_now',`
743        __(uuo_interr(error_propagate_suspend,rzero))
744')
Note: See TracBrowser for help on using the repository browser.