- ExceptionInInitializerError stuff
[cacao.git] / src / vm / jit / alpha / asmpart.S
1 /* jit/alpha/asmpart.S - Java-C interface functions for alpha
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    Institut f. Computersprachen, TU Wien
5    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6    S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7    J. Wenninger
8
9    This file is part of CACAO.
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2, or (at
14    your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Andreas Krall
29             Reinhard Grafl
30
31    $Id: asmpart.S 1060 2004-05-16 13:44:31Z twisti $
32
33 */
34
35
36 #include "config.h"        
37 #include "offsets.h"
38
39
40 #define         MethodPointer   -8
41 #define         FrameSize       -12
42 #define     IsSync          -16
43 #define     IsLeaf          -20
44 #define     IntSave         -24
45 #define     FltSave         -28
46 /* DEFINE LINE NUMBER STUFF HERE */
47 #define     ExTableSize     -56
48 #define     ExTableStart    -56
49
50 #define     ExEntrySize     -32
51 #define     ExStartPC       -8
52 #define     ExEndPC         -16
53 #define     ExHandlerPC     -24
54 #define     ExCatchType     -32
55
56
57 #define v0      $0
58
59 #define t0      $1
60 #define t1      $2
61 #define t2      $3
62 #define t3      $4
63 #define t4      $5
64 #define t5      $6
65 #define t6      $7
66 #define t7      $8
67
68 #define s0      $9
69 #define s1      $10
70 #define s2      $11
71 #define s3      $12
72 #define s4      $13
73 #define s5      $14
74 #define s6      $15
75
76 #define a0      $16
77 #define a1      $17
78 #define a2      $18
79 #define a3      $19
80 #define a4      $20
81 #define a5      $21
82
83 #define t8      $22
84 #define t9      $23
85 #define t10     $24
86 #define t11     $25
87 #define ra      $26
88 #define t12     $27
89
90 #define pv      t12
91 #define AT      $at
92 #define gp      $29
93 #define sp      $30
94 #define zero    $31
95
96 #define itmp1   $25
97 #define itmp2   $28
98 #define itmp3   $29
99
100 #define xptr    itmp1
101 #define xpc     itmp2
102
103 #define sf0     $f2
104 #define sf1     $f3
105 #define sf2     $f4
106 #define sf3     $f5
107 #define sf4     $f6
108 #define sf5     $f7
109 #define sf6     $f8
110 #define sf7     $f9
111
112 #define fzero   $f31
113
114
115 #define PAL_imb 134
116
117         .text
118         .set    noat
119         .set    noreorder
120
121
122 /********************* exported functions and variables ***********************/
123
124         .globl has_no_x_instr_set
125         .globl synchronize_caches
126         .globl asm_calljavafunction
127         .globl asm_calljavafunction2
128         .globl asm_calljavafunction2double
129         .globl asm_calljavafunction2long
130         .globl asm_call_jit_compiler
131         .globl asm_handle_exception
132         .globl asm_handle_nat_exception
133         .globl asm_check_clinit
134         .globl asm_builtin_checkcast    
135         .globl asm_builtin_checkarraycast
136         .globl asm_builtin_aastore
137         .globl asm_builtin_monitorenter
138         .globl asm_builtin_monitorexit
139         .globl asm_builtin_idiv
140         .globl asm_builtin_irem
141         .globl asm_builtin_ldiv
142         .globl asm_builtin_lrem
143         .globl asm_perform_threadswitch
144         .globl asm_initialize_thread_stack
145         .globl asm_switchstackandcall
146         .globl asm_getcallingmethod
147         .globl asm_builtin_trace
148         .globl asm_builtin_exittrace
149
150 /*************************** imported functions *******************************/
151
152         .globl jit_compile
153         .globl _exceptionptr
154         .globl builtin_monitorexit
155         .globl builtin_throw_exception
156         .globl builtin_trace_exception
157         .globl class_java_lang_Object
158
159
160 /*********************** function has_no_x_instr_set ***************************
161 *                                                                              *
162 *   determines if the byte support instruction set (21164a and higher)         *
163 *   is available.                                                              *
164 *                                                                              *
165 *******************************************************************************/
166
167         .ent    has_no_x_instr_set
168 has_no_x_instr_set:
169
170         .long   0x47e03c20                /* amask   1,v0                         */
171         jmp     zero,(ra)                 /* return                               */
172
173         .end    has_no_x_instr_set
174
175
176 /********************* function asm_calljavafunction ***************************
177 *                                                                              *
178 *   This function calls a Java-method (which possibly needs compilation)       *
179 *   with up to 4 address parameters.                                           *
180 *                                                                              *
181 *   This functions calls the JIT-compiler which eventually translates the      *
182 *   method into machine code.                                                  *
183 *                                                                              *
184 *   C-prototype:                                                               *
185 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
186 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
187 *                                                                              *
188 *******************************************************************************/
189
190         .ent    asm_calljavafunction
191
192 call_name:
193         .ascii  "calljavafunction\0\0"
194
195         .align  2 /*3*/
196         .quad   0                         /* catch type all                       */
197         .quad   calljava_xhandler         /* handler pc                           */
198         .quad   calljava_xhandler         /* end pc                               */
199         .quad   asm_calljavafunction      /* start pc                             */
200         .long   1                         /* extable size                         */
201         .long   0                         /* PADDING */
202         .quad   0                         /* line number table start             */
203         .quad   0                         /* line number table size             */
204         .long   0                         /* PADDING */
205         .long   0                         /* fltsave */
206         .long   0                         /* intsave                              */
207         .long   0                         /* isleaf                               */
208         .long   0                         /* IsSync                               */
209         .long   32                        /* frame size                           */
210         .quad   0                         /* method pointer (pointer to name)     */
211
212 asm_calljavafunction:
213         ldgp    gp,0(pv)
214         lda     sp,-32(sp)                /* allocate stack space                 */
215         stq     gp,24(sp)                 /* save global pointer                  */
216         stq     ra,0(sp)                  /* save return address                  */
217
218         stq     a0,16(sp)                 /* save method pointer for compiler     */
219         lda     v0,16(sp)                 /* pass pointer to method pointer via v0*/
220
221         mov     a1,a0                     /* pass the remaining parameters        */
222         mov     a2,a1
223         mov     a3,a2
224         mov     a4,a3
225
226         lda     $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
227         stq     $28,8(sp)                 /* store function address               */
228         mov     sp,$28                    /* set method pointer                   */
229
230         ldq     pv,8($28)                 /* method call as in Java               */
231         jmp     ra,(pv)                   /* call JIT compiler                    */
232 calljava_jit:
233         lda     pv,-64(ra)                /* asm_calljavafunction-calljava_jit !!!!!*/
234
235 calljava_return:
236         ldq     ra,0(sp)                  /* restore return address               */
237         ldq     gp,24(sp)                 /* restore global pointer               */
238         lda     sp,32(sp)                 /* free stack space                     */
239
240 calljava_ret:
241         jmp     zero,(ra)
242
243 calljava_xhandler:
244         ldq     gp,24(sp)                 /* restore global pointer               */
245         mov     itmp1,a0
246         jsr     ra,builtin_throw_exception
247         ldq     ra,0(sp)                  /* restore return address               */
248         lda     sp,32(sp)                 /* free stack space                     */
249         jmp     zero,(ra)
250         .end    asm_calljavafunction
251
252
253
254
255         .ent    asm_calljavafunction2
256
257 call_name2:
258         .ascii  "calljavafunction2\0\0"
259
260         .align  3
261         .quad   0                         /* catch type all                       */
262         .quad   calljava_xhandler2        /* handler pc                           */
263         .quad   calljava_xhandler2        /* end pc                               */
264         .quad   asm_calljavafunction2     /* start pc                             */
265         .long   1                         /* extable size                         */
266         .long   0                         /* PADDING */
267         .quad   0                         /* line number table start             */
268         .quad   0                         /* line number table size             */
269         .long   0                         /* PADDING */
270         .long   0                         /* fltsave                              */
271         .long   1                         /* intsave                              */
272         .long   0                         /* isleaf                               */
273         .long   0                         /* IsSync                               */
274         .long   40                        /* frame size                           */
275         .quad   0                         /* method pointer (pointer to name)     */
276
277 asm_calljavafunction2:
278 asm_calljavafunction2double:
279 asm_calljavafunction2long:
280         ldgp    gp,0(pv)
281         lda     sp,-40(sp)                /* allocate stack space                 */
282         stq     ra,0(sp)                  /* save return address                  */
283         stq     s6,24(sp)
284         stq     gp,8(sp)                  /* save global pointer                  */
285
286         stq     a0,32(sp)                 /* save method pointer for compiler     */
287         mov     a3,t0                     /* pointer to arg block                 */
288         mov     a1,s6                     /* arg count                            */
289
290         ble     s6,calljava_argsloaded
291         lda     s6,-1(s6)
292         ldq     a0,offjniitem(t0)
293         ldt     $f16,offjniitem(t0)
294         ble     s6,calljava_argsloaded
295         lda     s6,-1(s6)
296         ldq     a1,offjniitem+sizejniblock*1(t0)
297         ldt     $f17,offjniitem+sizejniblock*1(t0)
298         ble     s6,calljava_argsloaded
299         lda     s6,-1(s6)
300         ldq     a2,offjniitem+sizejniblock*2(t0)
301         ldt     $f18,offjniitem+sizejniblock*2(t0)
302         ble     s6,calljava_argsloaded
303         lda     s6,-1(s6)
304         ldq     a3,offjniitem+sizejniblock*3(t0)
305         ldt     $f19,offjniitem+sizejniblock*3(t0)
306         ble     s6,calljava_argsloaded
307         lda     s6,-1(s6)
308         ldq     a4,offjniitem+sizejniblock*4(t0)
309         ldt     $f20,offjniitem+sizejniblock*4(t0)
310         ble     s6,calljava_argsloaded
311         lda     s6,-1(s6)
312         ldq     a5,offjniitem+sizejniblock*5(t0)
313         ldt     $f21,offjniitem+sizejniblock*5(t0)
314 calljava_argsloaded:
315         mov     sp,t4
316         ble     s6,calljava_nocopy
317         negq    s6,t1
318         s8addq  t1,sp,sp
319         s8addq  t1,t4,t2
320
321 calljava_copyloop:
322         ldq     t3,offjniitem+sizejniblock*6(t0)
323         stq     t3,0(t2)
324         lda     t1,1(t1)
325         lda     t0,sizejniblock(t0)
326         lda     t2,8(t2)
327         bne     t1,calljava_copyloop
328
329 calljava_nocopy:
330         lda     v0,32(t4)                 /* pass pointer to method pointer via v0*/
331
332         lda     $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
333         stq     $28,16(t4)                /* store function address               */
334         lda     $28,8(t4)                 /* set method pointer                   */
335
336         ldq     pv,8($28)                 /* method call as in Java               */
337         jmp     ra,(pv)                   /* call JIT compiler                    */
338 calljava_jit2:
339         lda     pv,-200(ra)               /* asm_calljavafunction-calljava_jit !!!*/
340
341         s8addq  s6,sp,sp
342 calljava_return2:
343         ldq     ra,0(sp)                  /* restore return address               */
344         ldq     gp,8(sp)                  /* restore global pointer               */
345         ldq     s6,24(sp)
346         lda     sp,40(sp)                 /* free stack space                     */
347
348 calljava_ret2:
349         jmp     zero,(ra)
350
351 calljava_xhandler2:
352         s8addq  s6,sp,sp
353         ldq     gp,8(sp)                  /* restore global pointer               */
354         mov     itmp1,a0
355         jsr     ra,builtin_throw_exception
356         ldq     ra,0(sp)                  /* restore return address               */
357         ldq     s6,24(sp)
358         lda     sp,40(sp)                 /* free stack space                     */
359         jmp     zero,(ra)
360         .end    asm_calljavafunction2
361                                                 
362
363 /****************** function asm_call_jit_compiler *****************************
364 *                                                                              *
365 *   invokes the compiler for untranslated JavaVM methods.                      *
366 *                                                                              *
367 *   Register R0 contains a pointer to the method info structure (prepared      *
368 *   by createcompilerstub). Using the return address in R26 and the            *
369 *   offset in the LDA instruction or using the value in methodptr R28 the      *
370 *   patching address for storing the method address can be computed:           *
371 *                                                                              *
372 *   method address was either loaded using                                     *
373 *   M_LDQ (REG_PV, REG_PV, a)        ; invokestatic/special    ($27)           *
374 *   M_LDA (REG_PV, REG_RA, low)                                                *
375 *   M_LDAH(REG_PV, REG_RA, high)     ; optional                                *
376 *   or                                                                         *
377 *   M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28)           *
378 *   in the static case the method pointer can be computed using the            *
379 *   return address and the lda function following the jmp instruction          *
380 *                                                                              *
381 *******************************************************************************/
382
383
384         .ent    asm_call_jit_compiler
385 asm_call_jit_compiler:
386
387         ldgp    gp,0(pv)
388         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
389         srl     t8,16,t8              /* shift right register number $yy          */
390         and     t8,31,t8              /* isolate register number                  */
391         subl    t8,28,t8              /* test for REG_METHODPTR                   */
392         beq     t8,noregchange       
393         ldl     t8,0(ra)              /* load instruction LDA PV,xxx(RA)          */
394         sll     t8,48,t8
395         sra     t8,48,t8              /* isolate offset                           */
396         addq    t8,ra,$28             /* compute update address                   */
397         ldl     t8,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
398         srl     t8,16,t8              /* isolate instruction code                 */
399         lda     t8,-0x177b(t8)        /* test for LDAH                            */
400         bne     t8,noregchange       
401         ldl     t8,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
402         sll     t8,16,t8              /* compute high offset                      */
403         addl    t8,0,t8               /* sign extend high offset                  */
404         addq    t8,$28,$28            /* compute update address                   */
405 noregchange:
406         lda     sp,-14*8(sp)          /* reserve stack space                      */
407         stq     a0,0*8(sp)            /* save all argument registers              */
408         stq     a1,1*8(sp)            /* they could be used by method             */
409         stq     a2,2*8(sp)
410         stq     a3,3*8(sp)
411         stq     a4,4*8(sp)
412         stq     a5,5*8(sp)
413         stt     $f16,6*8(sp)
414         stt     $f17,7*8(sp)
415         stt     $f18,8*8(sp)
416         stt     $f19,9*8(sp)
417         stt     $f20,10*8(sp)
418         stt     $f21,11*8(sp)
419         stq     $28,12*8(sp)          /* save method pointer                      */
420         stq     ra,13*8(sp)           /* save return address                      */
421
422         ldq     a0,0(v0)              /* pass 'methodinfo' pointer to             */
423         jsr     ra,jit_compile        /* jit compiler                             */
424         ldgp    gp,0(ra)
425
426         call_pal PAL_imb              /* synchronise instruction cache            */
427
428         ldq     a0,0*8(sp)            /* load argument registers                  */
429         ldq     a1,1*8(sp)
430         ldq     a2,2*8(sp)
431         ldq     a3,3*8(sp)
432         ldq     a4,4*8(sp)
433         ldq     a5,5*8(sp)
434         ldt     $f16,6*8(sp)
435         ldt     $f17,7*8(sp)
436         ldt     $f18,8*8(sp)
437         ldt     $f19,9*8(sp)
438         ldt     $f20,10*8(sp)
439         ldt     $f21,11*8(sp)
440         ldq     $28,12*8(sp)          /* load method pointer                      */
441         ldq     ra,13*8(sp)           /* load return address                      */
442         lda     sp,14*8(sp)           /* deallocate stack area                    */
443
444         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
445         sll     t8,48,t8
446         sra     t8,48,t8              /* isolate offset                           */
447
448         addq    t8,$28,t8             /* compute update address via method pointer*/
449         stq     v0,0(t8)              /* save new method address there            */
450
451         mov     v0,pv                 /* load method address into pv              */
452
453         jmp     zero,(pv)             /* and call method. The method returns      */
454                                       /* directly to the caller (ra).             */
455
456         .end    asm_call_jit_compiler
457
458
459 /********************* function asm_handle_exception ***************************
460 *                                                                              *
461 *   This function handles an exception. It does not use the usual calling      *
462 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
463 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
464 *   the local exception table for a handler. If no one is found, it unwinds    *
465 *   stacks and continues searching the callers.                                *
466 *                                                                              *
467 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
468 *                                                                              *
469 *******************************************************************************/
470
471         .ent    asm_handle_nat_exception
472 asm_handle_nat_exception:
473         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
474         sll     t0,48,t0
475         sra     t0,48,t0              /* isolate offset                           */
476         addq    t0,ra,pv              /* compute update address                   */
477         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
478         srl     t0,16,t0              /* isolate instruction code                 */
479         lda     t0,-0x177b(t0)        /* test for LDAH                            */
480         bne     t0,asm_handle_exception       
481         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
482         sll     t0,16,t0              /* compute high offset                      */
483         addl    t0,0,t0               /* sign extend high offset                  */
484         addq    t0,pv,pv              /* compute update address                   */
485
486         .aent    asm_handle_exception
487 asm_handle_exception:
488         lda     sp,-18*8(sp)          /* allocate stack                           */
489         stq     t0,0*8(sp)            /* save possible used registers             */
490         stq     t1,1*8(sp)            /* also registers used by trace_exception   */
491         stq     t2,2*8(sp)
492         stq     t3,3*8(sp)
493         stq     t4,4*8(sp)
494         stq     t5,5*8(sp)
495         stq     t6,6*8(sp)
496         stq     t7,7*8(sp)
497         stq     t8,8*8(sp)
498         stq     t9,9*8(sp)
499         stq     t10,10*8(sp)
500         stq     v0,11*8(sp)
501         stq     a0,12*8(sp)
502         stq     a1,13*8(sp)
503         stq     a2,14*8(sp)
504         stq     a3,15*8(sp)
505         stq     a4,16*8(sp)
506         stq     a5,17*8(sp)
507
508         lda     t3,1(zero)            /* set no unwind flag                       */
509 ex_stack_loop:
510         lda     sp,-5*8(sp)           /* allocate stack                           */
511         stq     xptr,0*8(sp)          /* save used register                       */
512         stq     xpc,1*8(sp)
513         stq     pv,2*8(sp)
514         stq     ra,3*8(sp)
515         stq     t3,4*8(sp)
516
517         mov     xptr,a0
518         ldq     a1,MethodPointer(pv)
519         mov     xpc,a2
520 /*      mov     t3,a3 */
521         lda             a3,0(zero)
522         lda             a4,1(zero)
523         br      ra,ex_trace           /* set ra for gp loading                    */
524 ex_trace:
525         ldgp    gp,0(ra)              /* load gp                                  */
526         jsr     ra,builtin_trace_exception /* trace_exception(xptr,methodptr)     */
527         
528         ldq     xptr,0*8(sp)          /* restore used register                    */
529         ldq     xpc,1*8(sp)
530         ldq     pv,2*8(sp)
531         ldq     ra,3*8(sp)
532         ldq     t3,4*8(sp)
533         lda     sp,5*8(sp)            /* deallocate stack                         */
534         
535         ldl     t0,ExTableSize(pv)    /* t0 = exception table size                */
536         beq     t0,empty_table        /* if empty table skip                      */
537
538         lda     t1,ExTableStart(pv)   /* t1 = start of exception table            */
539
540 ex_table_loop:
541         ldq     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
542         cmple   t2,xpc,t2             /* t2 = (startpc <= xpc)                    */
543         beq     t2,ex_table_cont      /* if (false) continue                      */
544         ldq     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
545         cmplt   xpc,t2,t2             /* t2 = (xpc < endpc)                       */
546         beq     t2,ex_table_cont      /* if (false) continue                      */
547         ldq     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
548         beq     a1,ex_handle_it       /* NULL catches everything                  */
549
550         ldl     itmp3,offclassloaded(a1)
551         bne     itmp3,L_class_loaded
552
553         subq    sp,8*8,sp             /* allocate stack                           */
554         stq     t0,0*8(sp)            /* save used register                       */
555         stq     t1,1*8(sp)
556         stq     t3,2*8(sp)
557         stq     xptr,3*8(sp)
558         stq     xpc,4*8(sp)
559         stq     pv,5*8(sp)
560         stq     ra,6*8(sp)
561         stq     a1,7*8(sp)
562
563         mov     a1,a0
564
565         br      ra,L_class_load_ra    /* set ra for gp loading                    */
566 L_class_load_ra:
567         ldgp    gp,0(ra)              /* load gp                                  */
568         jsr     ra,class_load         /* class_load(exceptionclass)               */
569
570         ldq     t0,0*8(sp)            /* restore used register                    */
571         ldq     t1,1*8(sp)
572         ldq     t3,2*8(sp)
573         ldq     xptr,3*8(sp)
574         ldq     xpc,4*8(sp)
575         ldq     pv,5*8(sp)
576         ldq     ra,6*8(sp)
577         ldq     a1,7*8(sp)
578         addq    sp,8*8,sp             /* deallocate stack                         */
579
580 L_class_loaded:
581         ldl     itmp3,offclasslinked(a1)
582         bne     itmp3,L_class_linked
583
584         subq    sp,8*8,sp             /* allocate stack                           */
585         stq     t0,0*8(sp)            /* save used register                       */
586         stq     t1,1*8(sp)
587         stq     t3,2*8(sp)
588         stq     xptr,3*8(sp)
589         stq     xpc,4*8(sp)
590         stq     pv,5*8(sp)
591         stq     ra,6*8(sp)
592         stq     a1,7*8(sp)
593
594         mov     a1,a0
595
596         br      ra,L_class_link_ra    /* set ra for gp loading                    */
597 L_class_link_ra:
598         ldgp    gp,0(ra)              /* load gp                                  */
599         jsr     ra,class_link         /* class_load(exceptionclass)               */
600
601         ldq     t0,0*8(sp)            /* restore used register                    */
602         ldq     t1,1*8(sp)
603         ldq     t3,2*8(sp)
604         ldq     xptr,3*8(sp)
605         ldq     xpc,4*8(sp)
606         ldq     pv,5*8(sp)
607         ldq     ra,6*8(sp)
608         ldq     a1,7*8(sp)
609         addq    sp,8*8,sp             /* deallocate stack                         */
610
611 L_class_linked:
612         ldq     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
613         ldq     a1,offclassvftbl(a1)  /* a1 = vftblptr(catchtype) class (not obj) */
614         ldl     a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
615         ldl     v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
616         ldl     a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
617         subl    a0,v0,a0              /* a0 = baseval(xptr) - baseval(catchtype)  */
618         cmpule  a0,a1,v0              /* v0 = xptr is instanceof catchtype        */
619         beq     v0,ex_table_cont      /* if (false) continue                      */
620
621 ex_handle_it:
622         ldq     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
623
624         beq     t3,ex_jump            /* if (!(no stack unwinding) skip           */
625
626         ldq     t0,0*8(sp)            /* restore possible used registers          */
627         ldq     t1,1*8(sp)            /* also registers used by trace_exception   */
628         ldq     t2,2*8(sp)
629         ldq     t3,3*8(sp)
630         ldq     t4,4*8(sp)
631         ldq     t5,5*8(sp)
632         ldq     t6,6*8(sp)
633         ldq     t7,7*8(sp)
634         ldq     t8,8*8(sp)
635         ldq     t9,9*8(sp)
636         ldq     t10,10*8(sp)
637         ldq     v0,11*8(sp)
638         ldq     a0,12*8(sp)
639         ldq     a1,13*8(sp)
640         ldq     a2,14*8(sp)
641         ldq     a3,15*8(sp)
642         ldq     a4,16*8(sp)
643         ldq     a5,17*8(sp)
644         lda     sp,18*8(sp)           /* deallocate stack                         */
645
646 ex_jump:
647         jmp     zero,(xpc)            /* jump to the handler                      */
648
649 ex_table_cont:
650         lda     t1,ExEntrySize(t1)    /* next exception table entry               */
651         subl    t0,1,t0               /* decrement entry counter                  */
652         bgt     t0,ex_table_loop      /* if (t0 > 0) next entry                   */
653
654 empty_table:
655         beq     t3,ex_already_cleared /* if here the first time, then             */
656         lda     sp,18*8(sp)           /* deallocate stack and                     */
657         clr     t3                    /* clear the no unwind flag                 */
658 ex_already_cleared:
659         ldl     t0,IsSync(pv)         /* t0 = SyncOffset                          */
660         beq     t0,no_monitor_exit    /* if zero no monitorexit                   */
661         addq    sp,t0,t0              /* add stackptr to Offset                   */
662         ldq     a0,-8(t0)             /* load monitorexit pointer                 */
663
664         lda     sp,-7*8(sp)           /* allocate stack                           */
665         stq     t0,0*8(sp)            /* save used register                       */
666         stq     t1,1*8(sp)
667         stq     t3,2*8(sp)
668         stq     xptr,3*8(sp)
669         stq     xpc,4*8(sp)
670         stq     pv,5*8(sp)
671         stq     ra,6*8(sp)
672
673         br      ra,ex_mon_load        /* set ra for gp loading                    */
674 ex_mon_load:
675         ldgp    gp,0(ra)              /* load gp                                  */
676         jsr     ra,builtin_monitorexit/* builtin_monitorexit(objectptr)           */
677         
678         ldq     t0,0*8(sp)            /* restore used register                    */
679         ldq     t1,1*8(sp)
680         ldq     t3,2*8(sp)
681         ldq     xptr,3*8(sp)
682         ldq     xpc,4*8(sp)
683         ldq     pv,5*8(sp)
684         ldq     ra,6*8(sp)
685         lda     sp,7*8(sp)            /* deallocate stack                         */
686
687 no_monitor_exit:
688         ldl     t0,FrameSize(pv)      /* t0 = frame size                          */
689         addq    sp,t0,sp              /* unwind stack                             */
690         mov     sp,t0                 /* t0 = pointer to save area                */
691         ldl     t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
692         bne     t1,ex_no_restore      /* if (leaf) skip                           */
693         ldq     ra,-8(t0)             /* restore ra                               */
694         lda     t0,-8(t0)             /* t0--                                     */
695 ex_no_restore:
696         mov     ra,xpc                /* the new xpc is ra                        */
697         ldl     t1,IntSave(pv)        /* t1 = saved int register count            */
698         br      t2,ex_int1            /* t2 = current pc                          */
699 ex_int1:
700         lda     t2,44(t2)             /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
701         negl    t1,t1                 /* negate register count                    */
702         s4addq  t1,t2,t2              /* t2 = ex_int_sav - 4 * register count     */
703         jmp     zero,(t2)             /* jump to save position                    */
704         ldq     s0,-56(t0)
705         ldq     s1,-48(t0)
706         ldq     s2,-40(t0)
707         ldq     s3,-32(t0)
708         ldq     s4,-24(t0)
709         ldq     s5,-16(t0)
710         ldq     s6,-8(t0)
711 ex_int2:
712         s8addq  t1,t0,t0              /* t0 = t0 - 8 * register count             */
713
714         ldl     t1,FltSave(pv)        /* t1 = saved flt register count            */
715         br      t2,ex_flt1            /* t2 = current pc                          */
716 ex_flt1:
717         lda     t2,48(t2)             /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
718         negl    t1,t1                 /* negate register count                    */
719         s4addq  t1,t2,t2              /* t2 = ex_flt_sav - 4 * register count     */
720         jmp     zero,(t2)             /* jump to save position                    */
721         ldt     $f2,-64(t0)
722         ldt     $f3,-56(t0)
723         ldt     $f4,-48(t0)
724         ldt     $f5,-40(t0)
725         ldt     $f6,-32(t0)
726         ldt     $f7,-24(t0)
727         ldt     $f8,-16(t0)
728         ldt     $f9,-8(t0)
729 ex_flt2:
730         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
731         sll     t0,48,t0
732         sra     t0,48,t0              /* isolate offset                           */
733         addq    t0,ra,pv              /* compute update address                   */
734         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
735         srl     t0,16,t0              /* isolate instruction code                 */
736         lda     t0,-0x177b(t0)        /* test for LDAH                            */
737         bne     t0,ex_stack_loop       
738         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(RA)         */
739         sll     t0,16,t0              /* compute high offset                      */
740         addl    t0,0,t0               /* sign extend high offset                  */
741         addq    t0,pv,pv              /* compute update address                   */
742         br      ex_stack_loop
743
744         .end    asm_handle_nat_exception
745
746
747 /********************* asm_check_clinit ****************************************
748 *                                                                              *
749 *   Does null check and calls monitorenter or throws an exception              *
750 *                                                                              *
751 *******************************************************************************/
752                 
753     .ent    asm_check_clinit
754
755 asm_check_clinit:
756         ldgp    gp,0(pv)
757
758         ldl             itmp2,offclassinit(itmp1)
759         bne             itmp2,L_is_initialized
760         
761         subq    sp,7*8,sp
762         stq             ra,0*8(sp)
763         stq             a0,1*8(sp)            /* save argument registers for leaf         */
764         stq             a1,2*8(sp)            /* functions and native stub                */
765         stq             a2,3*8(sp)
766         stq             a3,4*8(sp)
767         stq             a4,5*8(sp)
768         stq             a5,6*8(sp)
769                 
770         mov             itmp1,a0
771         jsr             ra,class_init
772                 
773         ldgp    gp,0(ra)
774         ldq             ra,0*8(sp)
775         ldq             a0,1*8(sp)            /* restore argument registers               */
776         ldq             a1,2*8(sp)
777         ldq             a2,3*8(sp)
778         ldq             a3,4*8(sp)
779         ldq             a4,5*8(sp)
780         ldq             a5,6*8(sp)
781         addq    sp,7*8,sp
782
783         beq     v0,L_initializererror
784
785 L_is_initialized:
786         mov     ra,itmp1              /* now patch the calling code               */
787         subq    itmp1,(3*4),itmp1     /* go back 3 instructions                   */
788         ldah    itmp2,-15392(zero)    /* br -- 0xc3e0 == -15392                   */
789         lda     itmp2,4(itmp2)        /* jump over 4 instructions                 */
790         stl     itmp2,0(itmp1)        /* store the new branch: br +4              */
791
792         jmp             zero,(ra)
793
794 L_initializererror:
795 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
796         subq    sp,1*8,sp
797         stq     ra,0*8(sp)
798         jsr     ra,builtin_asm_get_exceptionptrptr
799         ldq     ra,0*8(sp)
800         addq    sp,1*8,sp
801         ldq     xptr,0(v0)            /* get the exception pointer                */
802         stq     zero,0(v0)            /* clear the exception pointer              */
803 #else
804         lda     itmp3,_exceptionptr
805         ldq     xptr,0(itmp3)
806         stq     zero,0(itmp3)
807 #endif
808
809         subq    ra,4,xpc
810         br      asm_handle_nat_exception
811
812         .end    asm_check_clinit
813
814                 
815 /********************* function asm_builtin_monitorenter ***********************
816 *                                                                              *
817 *   Does null check and calls monitorenter or throws an exception              *
818 *                                                                              *
819 *******************************************************************************/
820
821         .ent    asm_builtin_monitorenter
822 asm_builtin_monitorenter:
823         ldgp    gp,0(pv)
824         lda     pv,builtin_monitorenter
825         beq     a0,nb_monitorenter        /* if (null) throw exception            */
826         jmp     zero,(pv)                 /* else call builtin_monitorenter       */
827
828 nb_monitorenter:
829         subq    sp,8,sp
830     stq     ra,0(sp)
831         ldq     a0,string_java_lang_NullPointerException
832     jsr     ra,new_exception_message
833     ldgp    gp,0(ra)
834         mov     v0,xptr
835     ldq     ra,0(sp)
836         addq    sp,8,sp
837         
838         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
839         br      asm_handle_nat_exception
840         .end    asm_builtin_monitorenter
841
842
843 /********************* function asm_builtin_monitorexit ************************
844 *                                                                              *
845 *   Does null check and calls monitorexit or throws an exception               *
846 *                                                                              *
847 *******************************************************************************/
848
849         .ent    asm_builtin_monitorexit
850 asm_builtin_monitorexit:
851         ldgp    gp,0(pv)
852         lda     pv,builtin_monitorexit
853         beq     a0,nb_monitorexit         /* if (null) throw exception            */
854         jmp     zero,(pv)                 /* else call builtin_monitorexit        */
855
856 nb_monitorexit:
857         subq    sp,8,sp
858     stq     ra,0(sp)
859         ldq     a0,string_java_lang_NullPointerException
860     jsr     ra,new_exception_message
861     ldgp    gp,0(ra)
862         mov     v0,xptr
863     ldq     ra,0(sp)
864         addq    sp,8,sp
865         
866         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
867         br      asm_handle_nat_exception
868         .end    asm_builtin_monitorexit
869
870
871 /************************ function asm_builtin_idiv ****************************
872 *                                                                              *
873 *   Does null check and calls idiv or throws an exception                      *
874 *                                                                              *
875 *******************************************************************************/
876
877         .ent    asm_builtin_idiv
878
879 asm_builtin_idiv:
880         ldgp    gp,0(pv)
881         lda     pv,builtin_idiv
882         beq     a1,nb_idiv                /* if (null) throw exception            */
883         jmp     zero,(pv)                 /* else call builtin_idiv               */
884
885 nb_idiv:
886         subq    sp,8,sp
887         stq     ra,0(sp)
888         ldq     a0,string_java_lang_ArithmeticException
889         ldq     a1,string_java_lang_ArithmeticException_message
890         jsr     ra,new_exception_message
891         ldgp    gp,0(ra)
892         mov     v0,xptr
893         ldq     ra,0(sp)
894         addq    sp,8,sp
895         
896         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
897         br      asm_handle_nat_exception
898
899         .end    asm_builtin_idiv
900
901
902 /************************ function asm_builtin_ldiv ****************************
903 *                                                                              *
904 *   Does null check and calls ldiv or throws an exception                      *
905 *                                                                              *
906 *******************************************************************************/
907
908         .ent    asm_builtin_ldiv
909
910 asm_builtin_ldiv:
911         ldgp    gp,0(pv)
912         lda     pv,builtin_ldiv
913         beq     a1,nb_ldiv                /* if (null) throw exception            */
914         jmp     zero,(pv)                 /* else call builtin_ldiv               */
915
916 nb_ldiv:
917         subq    sp,8,sp
918         stq     ra,0(sp)
919         ldq     a0,string_java_lang_ArithmeticException
920         ldq     a1,string_java_lang_ArithmeticException_message
921         jsr     ra,new_exception_message
922         ldgp    gp,0(ra)
923         mov     v0,xptr
924         ldq     ra,0(sp)
925         addq    sp,8,sp
926
927         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
928         br      asm_handle_nat_exception
929
930         .end    asm_builtin_ldiv
931
932
933 /************************ function asm_builtin_irem ****************************
934 *                                                                              *
935 *   Does null check and calls irem or throws an exception                      *
936 *                                                                              *
937 *******************************************************************************/
938
939         .ent    asm_builtin_irem
940
941 asm_builtin_irem:
942         ldgp    gp,0(pv)
943         lda     pv,builtin_irem
944         beq     a1,nb_irem                /* if (null) throw exception            */
945         jmp     zero,(pv)                 /* else call builtin_irem               */
946
947 nb_irem:
948         subq    sp,8,sp
949         stq     ra,0(sp)
950         ldq     a0,string_java_lang_ArithmeticException
951         ldq     a1,string_java_lang_ArithmeticException_message
952         jsr     ra,new_exception_message
953         ldgp    gp,0(ra)
954         mov     v0,xptr
955         ldq     ra,0(sp)
956         addq    sp,8,sp
957
958         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
959         br      asm_handle_nat_exception
960
961         .end    asm_builtin_irem
962
963
964 /************************ function asm_builtin_lrem ****************************
965 *                                                                              *
966 *   Does null check and calls lrem or throws an exception                      *
967 *                                                                              *
968 *******************************************************************************/
969
970         .ent    asm_builtin_lrem
971
972 asm_builtin_lrem:
973         ldgp    gp,0(pv)
974         lda     pv,builtin_lrem
975         beq     a1,nb_lrem                /* if (null) throw exception            */
976         jmp     zero,(pv)                 /* else call builtin_lrem               */
977
978 nb_lrem:
979         subq    sp,8,sp
980         stq     ra,0(sp)
981         ldq     a0,string_java_lang_ArithmeticException
982         ldq     a1,string_java_lang_ArithmeticException_message
983         jsr     ra,new_exception_message
984         ldgp    gp,0(ra)
985         mov     v0,xptr
986         ldq     ra,0(sp)
987         addq    sp,8,sp
988
989         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
990         br      asm_handle_nat_exception
991
992         .end    asm_builtin_lrem
993
994
995 /******************* function asm_builtin_checkarraycast ***********************
996 *                                                                              *
997 *   Does the cast check and eventually throws an exception                     *
998 *                                                                              *
999 *******************************************************************************/
1000
1001         .ent    asm_builtin_checkarraycast
1002
1003 asm_builtin_checkarraycast:
1004         ldgp    gp,0(pv)
1005         lda     sp,-16(sp)                /* allocate stack space                 */
1006         stq     ra,0(sp)                  /* save return address                  */
1007         stq     a0,8(sp)                  /* save object pointer                  */
1008         jsr     ra,builtin_checkarraycast /* builtin_checkarraycast               */
1009         ldgp    gp,0(ra)
1010         beq     v0,nb_carray_throw        /* if (false) throw exception           */
1011         ldq     ra,0(sp)                  /* restore return address               */
1012         ldq     v0,8(sp)                  /* return object pointer                */
1013         lda     sp,16(sp)                 /* free stack space                     */
1014         jmp     zero,(ra)
1015
1016 nb_carray_throw:
1017         ldq     a0,string_java_lang_ClassCastException
1018     jsr     ra,new_exception
1019     ldgp    gp,0(ra)
1020         mov     v0,xptr
1021
1022         ldq     ra,0(sp)                  /* restore return address               */
1023         lda     sp,16(sp)                 /* free stack space                     */
1024         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1025         br      asm_handle_nat_exception
1026
1027         .end    asm_builtin_checkarraycast
1028
1029
1030 /******************* function asm_builtin_aastore ******************************
1031 *                                                                              *
1032 *   Does the cast check and eventually throws an exception                     *
1033 *                                                                              *
1034 *******************************************************************************/
1035
1036         .ent    asm_builtin_aastore
1037
1038 asm_builtin_aastore:
1039         ldgp    gp,0(pv)
1040         beq     a0,nb_aastore_null        /* if null pointer throw exception      */
1041         ldl     t0,offarraysize(a0)       /* load size                            */
1042         lda     sp,-24(sp)                /* allocate stack space                 */
1043         stq     ra,0(sp)                  /* save return address                  */
1044         s8addq  a1,a0,t1                  /* add index*8 to arrayref              */
1045         cmpult  a1,t0,t0                  /* do bound check                       */
1046         beq     t0,nb_aastore_bound       /* if out of bounds throw exception     */
1047         mov     a2,a1                     /* object is second argument            */
1048         stq     t1,8(sp)                  /* save store position                  */
1049         stq     a1,16(sp)                 /* save object                          */
1050         jsr     ra,builtin_canstore       /* builtin_canstore(arrayref,object)    */
1051         ldgp    gp,0(ra)
1052         ldq     ra,0(sp)                  /* restore return address               */
1053         ldq     a0,8(sp)                  /* restore store position               */
1054         ldq     a1,16(sp)                 /* restore object                       */
1055         lda     sp,24(sp)                 /* free stack space                     */
1056         beq     v0,nb_aastore_throw       /* if (false) throw exception           */
1057         stq     a1,offobjarrdata(a0)      /* store objectptr in array             */
1058         jmp     zero,(ra)
1059
1060 nb_aastore_null:        
1061         subq    sp,8,sp                   /* allocate stack space                 */
1062         stq     ra,0(sp)                  /* save return address                  */
1063         ldq     a0,string_java_lang_NullPointerException
1064     jsr     ra,new_exception
1065     ldgp    gp,0(ra)
1066         mov     v0,xptr
1067         ldq     ra,0(sp)
1068         addq    sp,8,sp
1069
1070         mov     ra,xpc                    /* faulting address is return adress    */
1071         br      asm_handle_nat_exception
1072
1073 nb_aastore_bound:
1074         ldq     a0,string_java_lang_ArrayIndexOutOfBoundsException
1075     jsr     ra,new_exception_int      /* a1 already contains the index        */
1076     ldgp    gp,0(ra)
1077         mov     v0,xptr
1078
1079         ldq     ra,0(sp)                  /* restore return address               */
1080         lda     sp,24(sp)                 /* free stack space                     */
1081         mov     ra,xpc                    /* faulting address is return adress    */
1082         br      asm_handle_nat_exception
1083
1084 nb_aastore_throw:
1085         subq    sp,8,sp                   /* allocate stack space                 */
1086         stq     ra,0(sp)                  /* save return address                  */
1087         ldq     a0,string_java_lang_ArrayStoreException
1088     jsr     ra,new_exception
1089     ldgp    gp,0(ra)
1090         mov     v0,xptr
1091         ldq     ra,0(sp)
1092         addq    sp,8,sp
1093
1094         mov     ra,xpc                    /* faulting address is return adress    */
1095         br      asm_handle_nat_exception
1096
1097         .end    asm_builtin_aastore
1098
1099
1100 /******************* function asm_initialize_thread_stack **********************
1101 *                                                                              *
1102 *   initialized a thread stack                                                 *
1103 *                                                                              *
1104 *******************************************************************************/
1105
1106         .ent    asm_initialize_thread_stack
1107
1108 asm_initialize_thread_stack:
1109         lda     a1,-128(a1)
1110         stq     zero, 0(a1)
1111         stq     zero, 8(a1)
1112         stq     zero, 16(a1)
1113         stq     zero, 24(a1)
1114         stq     zero, 32(a1)
1115         stq     zero, 40(a1)
1116         stq     zero, 48(a1)
1117         stt     fzero, 56(a1)
1118         stt     fzero, 64(a1)
1119         stt     fzero, 72(a1)
1120         stt     fzero, 80(a1)
1121         stt     fzero, 88(a1)
1122         stt     fzero, 96(a1)
1123         stt     fzero, 104(a1)
1124         stt     fzero, 112(a1)
1125         stq     a0, 120(a1)
1126         mov     a1, v0
1127         jmp     zero,(ra)
1128
1129         .end    asm_initialize_thread_stack
1130
1131
1132 /******************* function asm_perform_threadswitch *************************
1133 *                                                                              *
1134 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1135 *                                                                              *
1136 *   performs a threadswitch                                                    *
1137 *                                                                              *
1138 *******************************************************************************/
1139
1140         .ent    asm_perform_threadswitch
1141
1142 asm_perform_threadswitch:
1143         subq    sp,128,sp
1144         stq     s0, 0(sp)
1145         stq     s1, 8(sp)
1146         stq     s2, 16(sp)
1147         stq     s3, 24(sp)
1148         stq     s4, 32(sp)
1149         stq     s5, 40(sp)
1150         stq     s6, 48(sp)
1151         stt     sf0, 56(sp)
1152         stt     sf1, 64(sp)
1153         stt     sf2, 72(sp)
1154         stt     sf3, 80(sp)
1155         stt     sf4, 88(sp)
1156         stt     sf5, 96(sp)
1157         stt     sf6, 104(sp)
1158         stt     sf7, 112(sp)
1159         stq     ra, 120(sp)
1160         stq     sp, 0(a0)
1161         stq     sp, 0(a2)
1162         ldq     sp, 0(a1)
1163         ldq     s0, 0(sp)
1164         ldq     s1, 8(sp)
1165         ldq     s2, 16(sp)
1166         ldq     s3, 24(sp)
1167         ldq     s4, 32(sp)
1168         ldq     s5, 40(sp)
1169         ldq     s6, 48(sp)
1170         ldt     sf0, 56(sp)
1171         ldt     sf1, 64(sp)
1172         ldt     sf2, 72(sp)
1173         ldt     sf3, 80(sp)
1174         ldt     sf4, 88(sp)
1175         ldt     sf5, 96(sp)
1176         ldt     sf6, 104(sp)
1177         ldt     sf7, 112(sp)
1178         ldq     ra, 120(sp)
1179         mov     ra, pv
1180         addq    sp, 128, sp
1181         jmp     zero,(ra)
1182
1183         .end    asm_perform_threadswitch
1184
1185
1186 /********************* function asm_switchstackandcall *************************
1187 *                                                                              *
1188 *  void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1189 *                               void *p);                                      *
1190 *                                                                              *
1191 *   Switches to a new stack, calls a function and switches back.               *
1192 *       a0      new stack pointer                                              *
1193 *       a1      function pointer                                               *
1194 *               a2              pointer to variable where stack top should be stored           *
1195 *               a3      pointer to user data, is passed to the function                *
1196 *                                                                              *
1197 *******************************************************************************/
1198
1199
1200         .ent    asm_switchstackandcall
1201
1202 asm_switchstackandcall:
1203         lda     a0,-2*8(a0)     /* allocate new stack                                 */
1204         stq     ra,0(a0)        /* save return address on new stack                   */
1205         stq     sp,1*8(a0)      /* save old stack pointer on new stack                */
1206         stq sp,0(a2)        /* save old stack pointer to variable                 */
1207         mov     a0,sp           /* switch to new stack                                */
1208         
1209         mov     a1,pv           /* load function pointer                              */
1210         mov a3,a0           /* pass pointer */
1211         jmp     ra,(pv)         /* and call function                                  */
1212
1213         ldq     ra,0(sp)        /* load return address                                */
1214         ldq     sp,1*8(sp)      /* switch to old stack                                */
1215
1216         jmp     zero,(ra)       /* return                                             */
1217
1218         .end    asm_switchstackandcall
1219
1220                 
1221 /*
1222  * These are local overrides for various environment variables in Emacs.
1223  * Please do not remove this and leave it at the end of the file, where
1224  * Emacs will automagically detect them.
1225  * ---------------------------------------------------------------------
1226  * Local variables:
1227  * mode: asm
1228  * indent-tabs-mode: t
1229  * c-basic-offset: 4
1230  * tab-width: 4
1231  * End:
1232  */