1 /* jit/x86_64/asmpart.S - Java-C interface functions for x86_64
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,
9 This file is part of CACAO.
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.
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.
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
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
32 $Id: asmpart.S 1151 2004-06-06 15:01:06Z twisti $
38 #include "jit/x86_64/offsets.h"
41 #define MethodPointer -8
47 #define ExTableSize -32
48 #define ExTableStart -32
50 #define ExEntrySize -32
53 #define ExHandlerPC -24
54 #define ExCatchType -32
57 /* define it like the risc way */
83 /********************* exported functions and variables ***********************/
85 .globl asm_calljavafunction
86 .globl calljava_xhandler
87 .globl asm_calljavafunction2
88 .globl asm_calljavafunction2long
89 .globl asm_calljavafunction2double
90 .globl calljava_xhandler2
91 .globl asm_call_jit_compiler
92 .globl asm_handle_exception
93 .globl asm_handle_nat_exception
94 .globl asm_check_clinit
95 .globl asm_builtin_checkarraycast
96 .globl asm_builtin_anewarray
97 .globl asm_builtin_newarray_array
98 .globl asm_builtin_aastore
99 .globl asm_builtin_monitorenter
100 .globl asm_builtin_monitorexit
101 .globl asm_builtin_f2i
102 .globl asm_builtin_f2l
103 .globl asm_builtin_d2i
104 .globl asm_builtin_d2l
105 .globl asm_builtin_arrayinstanceof
106 .globl asm_perform_threadswitch
107 .globl asm_initialize_thread_stack
108 .globl asm_switchstackandcall
109 .globl asm_criticalsections
110 .globl asm_getclassvalues_atomic
113 /*************************** imported functions *******************************/
116 .globl builtin_monitorexit
117 .globl builtin_throw_exception
118 .globl builtin_trace_exception
119 .globl codegen_findmethod
122 /********************* function asm_calljavafunction ***************************
124 * This function calls a Java-method (which possibly needs compilation) *
125 * with up to 4 address parameters. *
127 * This functions calls the JIT-compiler which eventually translates the *
128 * method into machine code. *
131 * javaobject_header *asm_calljavamethod (methodinfo *m, *
132 * void *arg1, void *arg2, void *arg3, void *arg4); *
134 *******************************************************************************/
137 .ascii "calljavafunction\0\0"
140 .quad 0 /* catch type all */
141 .quad calljava_xhandler /* handler pc */
142 .quad calljava_xhandler /* end pc */
143 .quad asm_calljavafunction /* start pc */
144 .long 1 /* extable size */
145 .long 0 /* fltsave */
146 .long 0 /* intsave */
149 .long 8 /* frame size */
150 .quad 0 /* method pointer (pointer to name) */
152 asm_calljavafunction:
153 sub $(3*8),%rsp /* keep stack 16-byte aligned */
155 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
156 mov %rdi,%rax /* move function pointer to %rax */
157 /* compilerstub uses this */
159 mov %rsi,%rdi /* pass remaining parameters */
164 lea asm_call_jit_compiler,%r11
165 call *%r11 /* call JIT compiler */
169 add $(3*8),%rsp /* free stack space */
173 mov %rax,%rdi /* pass exception pointer */
174 call builtin_throw_exception
181 /********************* function asm_calljavafunction ***************************
183 * This function calls a Java-method (which possibly needs compilation) *
184 * with up to 4 address parameters. *
186 * This functions calls the JIT-compiler which eventually translates the *
187 * method into machine code. *
190 * javaobject_header *asm_calljavamethod (methodinfo *m, *
191 * void *arg1, void *arg2, void *arg3, void *arg4); *
193 *******************************************************************************/
196 .ascii "calljavafunction2\0\0"
199 .quad 0 /* catch type all */
200 .quad calljava_xhandler2 /* handler pc */
201 .quad calljava_xhandler2 /* end pc */
202 .quad asm_calljavafunction2 /* start pc */
203 .long 1 /* extable size */
204 .long 0 /* fltsave */
205 .long 0 /* intsave */
208 .long 8 /* frame size */
209 .quad 0 /* method pointer (pointer to name) */
211 asm_calljavafunction2:
212 asm_calljavafunction2double:
213 asm_calljavafunction2long:
214 sub $(1*8),%rsp /* keep stack 16-byte aligned */
215 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
217 mov %rdi,%rax /* save method pointer for compiler */
218 mov %rsi,%r11 /* arg count */
219 mov %rcx,%r10 /* pointer to arg block */
223 test %r11,%r11 /* maybe we have no args */
224 jle calljava_copydone
226 movb offjniitemtype(%r10),%dil /* which type has the current item */
227 andb 0x02,%dil /* is this a float/double type */
232 mov offjniitem(%r10),%rdi /* move args into registers */
237 mov offjniitem+sizejniblock*1(%r10),%rsi
242 mov offjniitem+sizejniblock*2(%r10),%rdx
243 mov offjniitem+sizejniblock*3(%r10),%rcx
246 lea asm_call_jit_compiler,%r11
247 call *%r11 /* call JIT compiler */
250 add $(1*8),%rsp /* free stack space */
254 mov %rax,%rdi /* pass exception pointer */
255 call builtin_throw_exception
261 /****************** function asm_call_jit_compiler *****************************
263 * invokes the compiler for untranslated JavaVM methods. *
265 * Register R0 contains a pointer to the method info structure (prepared *
266 * by createcompilerstub). Using the return address in R26 and the *
267 * offset in the LDA instruction or using the value in methodptr R28 the *
268 * patching address for storing the method address can be computed: *
270 * method address was either loaded using *
272 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
273 * i386_call_reg(REG_ITMP2) *
277 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
278 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
279 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
280 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
281 * i386_call_reg(REG_ITMP1) *
283 * in the static case the method pointer can be computed using the *
284 * return address and the lda function following the jmp instruction *
286 *******************************************************************************/
288 asm_call_jit_compiler:
289 sub $8,%rsp /* keep stack 16-byte aligned */
291 mov %rbx,(%rsp) /* save register */
293 mov 8(%rsp),%r11 /* get return address */
294 mov -1(%r11),%bl /* get function code */
295 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
296 jne L_not_static_special
298 sub $11,%r11 /* calculate address of immediate */
299 jmp L_call_jit_compile
301 L_not_static_special:
302 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
303 jne L_not_virtual_interface
305 sub $7,%r11 /* calculate address of offset */
306 mov (%r11),%r11d /* get offset (32-bit) */
307 add %r10,%r11 /* add base address to get method address */
308 jmp L_call_jit_compile
310 L_not_virtual_interface: /* a call from asm_calljavamethod */
314 mov (%rsp),%rbx /* restore register */
316 sub $(24*8),%rsp /* 8 + 48 + 64 + 64 */
318 mov %r11,0*8(%rsp) /* save address for method pointer */
320 mov %rdi,1*8(%rsp) /* save arguments */
330 movq %xmm3,10*8(%rsp)
331 movq %xmm4,11*8(%rsp)
332 movq %xmm5,12*8(%rsp)
333 movq %xmm6,13*8(%rsp)
334 movq %xmm7,14*8(%rsp)
336 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
337 movq %xmm9,16*8(%rsp)
338 movq %xmm10,17*8(%rsp)
339 movq %xmm11,18*8(%rsp)
340 movq %xmm12,19*8(%rsp)
341 movq %xmm13,20*8(%rsp)
342 movq %xmm14,21*8(%rsp)
343 movq %xmm15,22*8(%rsp)
345 mov %rax,%rdi /* pass method pointer */
360 movq 10*8(%rsp),%xmm3
361 movq 11*8(%rsp),%xmm4
362 movq 12*8(%rsp),%xmm5
363 movq 13*8(%rsp),%xmm6
364 movq 14*8(%rsp),%xmm7
366 movq 15*8(%rsp),%xmm8
367 movq 16*8(%rsp),%xmm9
368 movq 17*8(%rsp),%xmm10
369 movq 18*8(%rsp),%xmm11
370 movq 19*8(%rsp),%xmm12
371 movq 20*8(%rsp),%xmm13
372 movq 21*8(%rsp),%xmm14
373 movq 22*8(%rsp),%xmm15
377 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
380 mov %rax,(%r11) /* and now save the new pointer */
383 add $8,%rsp /* keep stack 16-byte aligned */
384 jmp *%rax /* ...and now call the new method */
387 /********************* function asm_handle_exception ***************************
389 * This function handles an exception. It does not use the usual calling *
390 * conventions. The exception pointer is passed in REG_ITMP1 and the *
391 * pc from the exception raising position is passed in REG_ITMP2. It searches *
392 * the local exception table for a handler. If no one is found, it unwinds *
393 * stacks and continues searching the callers. *
395 * void asm_handle_exception (exceptionptr, exceptionpc); *
397 *******************************************************************************/
399 asm_handle_nat_exception:
400 add $8,%rsp /* clear return address of native stub*/
402 asm_handle_exception:
404 mov xptr,0*8(%rsp) /* save exception pointer */
405 mov xpc,1*8(%rsp) /* save exception pc */
407 mov xpc,%rdi /* exception pc */
408 call codegen_findmethod
410 mov %rax,2*8(%rsp) /* save data segment pointer */
412 mov 0*8(%rsp),%rax /* restore exception pointer */
413 mov 1*8(%rsp),%r10 /* restore exception pc */
416 mov %rax,%rdi /* exception pointer */
417 mov MethodPointer(itmp3),%rsi /* method pointer */
418 mov xpc,%rdx /* exception pc */
420 mov $1,%r8 /* set noindent flag */
421 call builtin_trace_exception
423 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
424 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
425 test %rcx,%rcx /* if empty table skip */
428 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
429 mov 0*8(%rsp),xptr /* get xptr */
432 mov 1*8(%rsp),xpc /* get xpc */
434 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
435 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
436 jg ex_table_cont /* if (false) continue */
437 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
438 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
439 jge ex_table_cont /* if (false) continue */
440 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
441 test %rdx,%rdx /* NULL catches everything */
444 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
463 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
482 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
483 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
484 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
485 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
486 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
487 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
488 cmp %edx,%esi /* xptr is instanceof catchtype */
492 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
494 mov 0*8(%rsp),%rax /* restore exception pointer */
495 add $(4*8),%rsp /* free stack frame */
497 jmp *xpc /* jump to the handler */
500 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
501 dec %rcx /* decrement entry counter */
502 test %rcx,%rcx /* if (t0 > 0) next entry */
506 mov 0*8(%rsp),%rax /* restore exception pointer */
507 mov 1*8(%rsp),%r10 /* restore exception pc */
508 mov 2*8(%rsp),%r11 /* restore data segment pointer */
511 mov %rax,%rcx /* save exception pointer */
514 movl IsSync(%r11),%eax /* %rax = SyncOffset */
515 test %rax,%rax /* if zero no monitorexit */
526 call builtin_monitorexit
534 mov FrameSize(%r11),%eax /* %eax = frame size */
535 add %rax,%rsp /* unwind stack */
536 mov %rsp,%rax /* %rax = pointer to save area */
538 mov IntSave(%r11),%edx /* %edx = saved int register count*/
565 shl $3,%edx /* multiply by 8 bytes */
569 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
592 movq -48(%rax),%xmm10
594 movq -40(%rax),%xmm11
596 movq -32(%rax),%xmm12
598 movq -24(%rax),%xmm13
600 movq -16(%rax),%xmm14
605 pop %r10 /* the new xpc is return address */
606 sub $3,%r10 /* subtract 3 bytes for call */
613 call codegen_findmethod /* get the new data segment ptr */
620 mov %rcx,%rax /* restore saved exception pointer*/
624 mov %rax,0*8(%rsp) /* save exception pointer */
625 mov %r10,1*8(%rsp) /* save exception pc */
626 mov %r11,2*8(%rsp) /* save data segment pointer */
631 /********************* function asm_check_clinit *******************************
633 * Does null check and calls monitorenter or throws an exception *
635 *******************************************************************************/
638 mov offclassinit(%rax),%r10d /* get initialized flag (int) */
642 sub $(15*8),%rsp /* keep stack 16-byte aligned */
644 mov %rdi,0*8(%rsp) /* save argument registers */
651 movq %xmm0,6*8(%rsp) /* maybe cacao does not use all 8 */
652 movq %xmm1,7*8(%rsp) /* argument register, but who knows */
655 movq %xmm4,10*8(%rsp)
656 movq %xmm5,11*8(%rsp)
657 movq %xmm6,12*8(%rsp)
658 movq %xmm7,13*8(%rsp)
660 mov %rax,%rdi /* pass classinfo pointer */
661 call class_init /* call class_init function */
663 mov 0*8(%rsp),%rdi /* restore argument registers */
674 movq 10*8(%rsp),%xmm4
675 movq 11*8(%rsp),%xmm5
676 movq 12*8(%rsp),%xmm6
677 movq 13*8(%rsp),%xmm7
681 test %rax,%rax /* we had an exception */
682 je L_initializererror
685 mov (%rsp),%rax /* get return address */
686 sub $23,%rax /* asm_putstatic call code size */
687 movb $0xeb,(%rax) /* jmp rel8 */
688 movb $21,1(%rax) /* 8-bit offset */
692 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
693 call builtin_asm_get_exceptionptrptr
695 mov (itmp2),xptr /* get the exception pointer */
696 movl $0,(itmp2) /* clear the exception pointer */
698 lea _exceptionptr,itmp2
699 mov (itmp2),xptr /* get the exception pointer */
700 movl $0,(itmp2) /* clear the exception pointer */
703 pop xpc /* delete return address */
704 sub $3,xpc /* faulting address is return adress - 3 */
706 jmp asm_handle_exception
709 /********************* function asm_builtin_monitorenter ***********************
711 * Does null check and calls monitorenter or throws an exception *
713 *******************************************************************************/
715 asm_builtin_monitorenter:
717 je nb_monitorenter /* if (null) throw exception */
718 jmp builtin_monitorenter /* else call builtin_monitorenter */
721 mov string_java_lang_NullPointerException,%rdi
724 pop %r10 /* delete return address */
725 sub $3,%r10 /* faulting address is return adress - 3 */
726 jmp asm_handle_exception
729 /********************* function asm_builtin_monitorexit ************************
731 * Does null check and calls monitorexit or throws an exception *
733 *******************************************************************************/
735 asm_builtin_monitorexit:
737 je nb_monitorexit /* if (null) throw exception */
738 jmp builtin_monitorexit /* else call builtin_monitorenter */
741 mov string_java_lang_NullPointerException,%rdi
744 pop %r10 /* delete return address */
745 sub $3,%r10 /* faulting address is return adress - 3 */
746 jmp asm_handle_exception
749 /********************* function asm_builtin_x2x ********************************
751 * Wrapper functions for float to int corner cases *
753 *******************************************************************************/
769 movq %xmm4,10*8(%rsp)
770 movq %xmm5,11*8(%rsp)
771 movq %xmm6,12*8(%rsp)
772 movq %xmm7,13*8(%rsp)
788 movq 10*8(%rsp),%xmm4
789 movq 11*8(%rsp),%xmm5
790 movq 12*8(%rsp),%xmm6
791 movq 13*8(%rsp),%xmm7
811 movq %xmm4,10*8(%rsp)
812 movq %xmm5,11*8(%rsp)
813 movq %xmm6,12*8(%rsp)
814 movq %xmm7,13*8(%rsp)
830 movq 10*8(%rsp),%xmm4
831 movq 11*8(%rsp),%xmm5
832 movq 12*8(%rsp),%xmm6
833 movq 13*8(%rsp),%xmm7
853 movq %xmm4,10*8(%rsp)
854 movq %xmm5,11*8(%rsp)
855 movq %xmm6,12*8(%rsp)
856 movq %xmm7,13*8(%rsp)
872 movq 10*8(%rsp),%xmm4
873 movq 11*8(%rsp),%xmm5
874 movq 12*8(%rsp),%xmm6
875 movq 13*8(%rsp),%xmm7
895 movq %xmm4,10*8(%rsp)
896 movq %xmm5,11*8(%rsp)
897 movq %xmm6,12*8(%rsp)
898 movq %xmm7,13*8(%rsp)
914 movq 10*8(%rsp),%xmm4
915 movq 11*8(%rsp),%xmm5
916 movq 12*8(%rsp),%xmm6
917 movq 13*8(%rsp),%xmm7
923 /******************* function asm_builtin_checkarraycast ***********************
925 * Does the cast check and eventually throws an exception *
927 *******************************************************************************/
929 asm_builtin_checkarraycast:
930 sub $24,%rsp /* keep stack 16-byte aligned */
931 mov %rdi,(%rsp) /* save object pointer */
932 call builtin_checkarraycast /* builtin_checkarraycast */
933 test %rax,%rax /* if (false) throw exception */
935 mov (%rsp),%rax /* return object pointer */
936 add $24,%rsp /* free stack space */
940 mov string_java_lang_ClassCastException,%rdi
944 pop %r10 /* delete return address */
945 sub $3,%r10 /* faulting address is return adress - 3 */
946 jmp asm_handle_exception
949 /******************* function asm_builtin_aastore ******************************
951 * Does the cast check and eventually throws an exception *
953 *******************************************************************************/
956 sub $(3*8),%rsp /* allocate stack space */
957 test %rdi,%rdi /* if null pointer throw exception */
960 movl offarraysize(%rdi),%eax /* load size */
961 cmpl %eax,%esi /* do bound check */
962 jae nb_aastore_bound /* if out of bounds throw exception */
964 shl $3,%rsi /* index * 8 */
966 add %rsi,%r10 /* add index * 8 to arrayref */
968 mov %r10,(%rsp) /* save store position */
969 mov %rdx,8(%rsp) /* save object */
971 mov %rdx,%rsi /* object is second argument */
972 call builtin_canstore /* builtin_canstore(arrayref,object) */
973 test %rax,%rax /* if (false) throw exception */
976 mov (%rsp),%r10 /* restore store position */
977 mov 8(%rsp),%rdx /* restore object */
978 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
979 add $(3*8),%rsp /* free stack space */
983 mov string_java_lang_NullPointerException,%rdi
987 pop %r10 /* delete return address */
988 sub $3,%r10 /* faulting address is return adress - 3 */
989 jmp asm_handle_exception
992 mov string_java_lang_ArrayIndexOutOfBoundsException,%rdi
993 call new_exception_int /* %rsi already contains the index */
996 pop %r10 /* delete return address */
997 sub $3,%r10 /* faulting address is return adress - 3 */
998 jmp asm_handle_exception
1001 mov string_java_lang_ArrayStoreException,%rdi
1005 pop %r10 /* delete return address */
1006 sub $3,%r10 /* faulting address is return adress - 3 */
1007 jmp asm_handle_exception
1010 /******************* function asm_initialize_thread_stack **********************
1012 * initialized a thread stack *
1013 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1015 *******************************************************************************/
1017 asm_initialize_thread_stack:
1028 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1029 mov %rsi,%rax /* return restorepoint in %rax */
1033 /******************* function asm_perform_threadswitch *************************
1035 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1037 * performs a threadswitch *
1039 *******************************************************************************/
1041 asm_perform_threadswitch:
1042 sub $(7*8),%rsp /* allocate stack frame */
1051 mov 7*8(%rsp),%rax /* save current return address */
1054 mov %rsp,(%rdi) /* first argument **from */
1055 mov %rsp,(%rdx) /* third argument **stackTop */
1057 mov (%rsi),%rsp /* load new stack pointer */
1066 mov 6*8(%rsp),%rax /* restore return address */
1067 add $(7*8),%rsp /* free stack frame */
1072 /********************* function asm_switchstackandcall *************************
1074 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1077 * Switches to a new stack, calls a function and switches back. *
1078 * a0 (%rdi) new stack pointer *
1079 * a1 (%rsi) function pointer *
1080 * a2 (%rdx) pointer to variable where stack top should be stored *
1081 * a3 (%rcx) pointer to user data, is passed to the function *
1083 *******************************************************************************/
1085 asm_switchstackandcall:
1086 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1087 sub $16,%rdi /* allocate new stack */
1089 mov 8(%rsp),%rax /* save return address on new stack */
1091 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1092 mov %rsp,(%rdx) /* save old stack pointer to variable */
1094 mov %rdi,%rsp /* switch to new stack */
1096 mov %rcx,%rdi /* pass pointer */
1097 call *%rsi /* and call function */
1099 mov (%rsp),%r10 /* load return address */
1100 mov 8(%rsp),%rsp /* switch to old stack */
1101 add $(1*8),%rsp /* free stack space */
1102 mov %r10,(%rsp) /* write return adress */
1106 asm_getclassvalues_atomic:
1109 movl offbaseval(a0),itmp1l
1110 movl offdiffval(a0),itmp2l
1111 movl offbaseval(a1),itmp3l
1113 movl itmp1l,offcast_super_baseval(a2)
1114 movl itmp2l,offcast_super_diffval(a2)
1115 movl itmp3l,offcast_sub_baseval(a2)
1120 asm_criticalsections:
1121 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1124 .long _crit_restart1
1127 .long _crit_restart2
1133 * These are local overrides for various environment variables in Emacs.
1134 * Please do not remove this and leave it at the end of the file, where
1135 * Emacs will automagically detect them.
1136 * ---------------------------------------------------------------------
1139 * indent-tabs-mode: t