]> git.saurik.com Git - apple/xnu.git/blob - bsd/crypto/aes/i386/ExpandKeyForEncryption.s
xnu-1699.24.23.tar.gz
[apple/xnu.git] / bsd / crypto / aes / i386 / ExpandKeyForEncryption.s
1 /* This file defines _aes_encrypt_key, _aes_encrypt_key128,
2 _aes_encrypt_key192, and _aes_encrypt_key256. It is designed to be
3 included in another assembly file with the preprocessor #include directive,
4 to benefit from some assembly-time calculations.
5
6 Written by Eric Postpischil, January 2008.
7
8 The comments here do not say much about the algorithm; the code just
9 follows the FIPS-197 specification. I recommend reading the specification
10 before working with this code or examining the C code in the parent
11 directory that illustrates key expansion.
12 */
13
14
15 /* Routines:
16
17 _aes_encrypt_key.
18
19 _aes_encrypt_key128, _aes_encrypt_key192, and _aes_encrypt_key256.
20
21 Function:
22
23 Expand the user's cipher key into the key schedule, as defined in
24 Federal Information Processing Standards Publication 197 (FIPS-197),
25 November 26, 2001.
26
27 Input:
28
29 Constant data:
30
31 The following names must be locally defined so the assembler
32 can calculate certain offsets.
33
34 static const Word _AESSubBytesWordTable[4][256].
35
36 _AESSubBytesWordTable[i][j] = SubBytes(j) << 8*i, where
37 SubBytes is defined in FIPS-197. _AESSubBytesWordTable
38 differs from _AESEncryptTable in that it does not include
39 the MixColumn operation. It is used in performing the last
40 round, which differs fromm the previous rounds in that it
41 does not include the MixColumn operation.
42
43 static const Byte _AESRcon[].
44
45 Round constants, beginning with AESRcon[1] for the first round
46 (AESRcon[0] is padding.)
47
48 Arguments:
49
50 const uint8_t *Key
51
52 Address of user's cipher key.
53
54 int Length
55
56 Number of bytes (16, 24, or 32) or bits (128, 192, or 256) in
57 user's cipher key.
58
59 This argument is used with _aes_encrypt_key. It is not
60 present for the other routines. In those routines, Context
61 is the second argument.
62
63 aes_encrypt_ctx *Context
64
65 Structure to contain the expanded key beginning at offset
66 ContextKey and a four-byte "key length" beginning at offset
67 ContextKeyLength. The "key length" is the number of bytes from
68 the start of the first round key to the start of the last round
69 key. That is 16 less than the number of bytes in the entire
70 key.
71
72 Output:
73
74 The expanded key and the "key length" are written to *Context.
75
76 Return:
77
78 aes_rval // -1 if "key length" is invalid. 0 otherwise.
79 */
80
81 /* add AES HW detection and program branch if AES HW is detected cclee 3-12-10 */
82 #ifdef KERNEL
83 #include <i386/cpu_capabilities.h>
84 #else
85 #include <System/i386/cpu_capabilities.h>
86 #endif
87
88 .text
89 .globl _aes_encrypt_key
90 // .private_extern _aes_encrypt_key
91 _aes_encrypt_key:
92
93 // detect AES HW, cclee-3-13-10
94 #if defined __x86_64__
95 movq __cpu_capabilities@GOTPCREL(%rip), %rax // %rax -> __cpu_capabilities
96 mov (%rax), %eax // %eax = __cpu_capabilities
97 #else
98 #if defined KERNEL
99 leal __cpu_capabilities, %eax // %eax -> __cpu_capabilities
100 mov (%eax), %eax // %eax = __cpu_capabilities
101 #else
102 mov _COMM_PAGE_CPU_CAPABILITIES, %eax
103 #endif
104 #endif
105 test $(kHasAES), %eax // __cpu_capabilities & kHasAES
106 jne _aes_encrypt_key_hw // if AES HW detected, branch to _aes_encrypt_key_hw
107
108 #define dr r0d // Dissection register.
109 #define drl r0l // Low 8 bits of dissection register.
110 #define drh r0h // Second-lowest 8 bits of dissection register.
111
112 #define t0 r1
113 #define t0d r1d // Low 32 bits of t0.
114
115 #define offset Arch(r5, r11) // Address offset and loop sentinel.
116
117 #define R r7 // Address of round constant.
118 #define K r7 // User key pointer.
119 // R and K overlap.
120
121 #define E r6 // Expanded key pointer.
122
123 #define ve0 %xmm0
124 #define ve1 %xmm1
125 #define ve2 %xmm2
126 #define ve3 %xmm3
127 #define vt3 %xmm4
128 #define vt2 %xmm5
129 #define vt1 %xmm6
130 #define vt0 %xmm7
131
132 #if defined __i386__
133 #define LookupS(table, index) \
134 _AESSubBytesWordTable+(table)*TableSize(, index, 4)
135 #elif defined __x86_64__
136 #define LookupS(table, index) (table)*TableSize(STable, index, 4)
137 #endif
138
139 /* Save registers and set SaveSize to the number of bytes pushed onto the
140 stack so far, including the caller's return address.
141 */
142 push r3
143 #if defined __i386__
144 push r5
145 push r6
146 push r7
147 #define SaveSize (5*4)
148 #else
149 #define SaveSize (2*8)
150 #endif
151
152 /* Number of bytes used for local variables:
153
154 8 16-byte spaces to save XMM registers.
155 */
156 #define LocalsSize (8*16)
157
158 #if 0 < LocalsSize
159 // Padding to position stack pointer at a multiple of 16 bytes.
160 #define Padding (15 & -(SaveSize + LocalsSize))
161 sub $Padding + LocalsSize, r4 // Allocate space on stack.
162 #else
163 #define Padding 0
164 #endif
165
166 /* StackFrame is the number of bytes in our stack frame, from caller's
167 stack pointer to ours (so it includes the return address).
168 */
169 #define StackFrame (SaveSize + Padding + LocalsSize)
170
171 // Save xmm registers.
172 movaps %xmm0, 0*16(r4)
173 movaps %xmm1, 1*16(r4)
174 movaps %xmm2, 2*16(r4)
175 movaps %xmm3, 3*16(r4)
176 movaps %xmm4, 4*16(r4)
177 movaps %xmm5, 5*16(r4)
178 movaps %xmm6, 6*16(r4)
179 movaps %xmm7, 7*16(r4)
180
181 #if defined __i386__
182
183 // Define location of argument i.
184 #define Argument(i) StackFrame+4*(i)(r4)
185
186 #define Nk t0d
187
188 // Load arguments.
189 mov Argument(2), E
190 mov Argument(1), Nk
191 mov Argument(0), K
192
193 #elif defined __x86_64__
194
195 #define Nk r9d // Number of words in key.
196 mov r6d, Nk // Move Nk argument out of way.
197 mov r2, E // Move E argument to common register.
198
199 #endif
200
201 // Dispatch on key length.
202 cmp $128, Nk
203 jge 2f
204 shl $3, Nk // Convert from bytes to bits.
205 cmp $128, Nk
206 2:
207 je EKeyHas4Words
208 cmp $192, Nk
209 je EKeyHas6Words
210 cmp $256, Nk
211 je EKeyHas8Words
212 mov $-1, r0 // Return error.
213 jmp 9f
214
215 // Stop using Nk.
216 #undef Nk
217
218 .globl _aes_encrypt_key128
219 // .private_extern _aes_encrypt_key128
220 _aes_encrypt_key128:
221
222 /* Save registers and set SaveSize to the number of bytes pushed onto the
223 stack so far, including the caller's return address.
224 */
225 push r3
226 #if defined __i386__
227 push r5
228 push r6
229 push r7
230 #define SaveSize (5*4)
231 #else
232 #define SaveSize (2*8)
233 #endif
234
235 /* Number of bytes used for local variables:
236
237 8 16-byte spaces to save XMM registers.
238 */
239 #define LocalsSize (8*16)
240
241 #if 0 < LocalsSize
242 // Padding to position stack pointer at a multiple of 16 bytes.
243 #define Padding (15 & -(SaveSize + LocalsSize))
244 sub $Padding + LocalsSize, r4 // Allocate space on stack.
245 #else
246 #define Padding 0
247 #endif
248
249 /* StackFrame is the number of bytes in our stack frame, from caller's
250 stack pointer to ours (so it includes the return address).
251 */
252 #define StackFrame (SaveSize + Padding + LocalsSize)
253
254 // Save xmm registers.
255 movaps %xmm0, 0*16(r4)
256 movaps %xmm1, 1*16(r4)
257 movaps %xmm2, 2*16(r4)
258 movaps %xmm3, 3*16(r4)
259 movaps %xmm4, 4*16(r4)
260 movaps %xmm5, 5*16(r4)
261 movaps %xmm6, 6*16(r4)
262 movaps %xmm7, 7*16(r4)
263
264 #if defined __i386__
265
266 // Load arguments.
267 #define Argument(i) StackFrame+4*(i)(r4)
268 mov Argument(1), E
269 mov Argument(0), K
270
271 #endif
272
273 // Merge point for _aes_encrypt_key and _aes_encrypt_key128.
274 EKeyHas4Words:
275
276 #define e0 r2d
277 #define e1 r3d
278 #define e2 Arch(r5d, r11d)
279 #define e3 r7d
280
281 // First words of expanded key are copied from user key.
282 mov 0*4(K), e0
283 mov 1*4(K), e1
284 mov 2*4(K), e2
285 mov 3*4(K), e3
286
287 movl $10*16, ContextKeyLength(E) // Set "key length."
288
289 #if 0 != ContextKey
290 add $ContextKey, E
291 #endif
292
293 // K cannot be used after we write to R, since they use the same register.
294
295 // Cache round constants in output buffer. The last is a sentinel.
296 movb $0x01, 1*16(E)
297 movb $0x02, 2*16(E)
298 movb $0x04, 3*16(E)
299 movb $0x08, 4*16(E)
300 movb $0x10, 5*16(E)
301 movb $0x20, 6*16(E)
302 movb $0x40, 7*16(E)
303 movb $0x80, 8*16(E)
304 movb $0x1b, 9*16(E)
305 movb $0x36, 10*16(E)
306
307 #if defined __x86_64__
308
309 #define STable r8
310 lea _AESSubBytesWordTable(%rip), STable
311
312 #endif
313
314 // Store initial words of expanded key, which are copies of user's key.
315 mov e0, 0*4(E)
316 mov e1, 1*4(E)
317 mov e2, 2*4(E)
318 mov e3, 3*4(E)
319
320 1:
321 mov e3, dr // Put previous word into dissection register.
322
323 // Perform SubWord(RotWord(dr)).
324 movzx drl, t0
325 xor LookupS(3, t0), e0 // Look up byte 0 in table 3.
326 movzx drh, t0d
327 xor LookupS(0, t0), e0 // Look up byte 1 in table 0.
328 shr $16, dr
329 movzx drl, t0d
330 xor LookupS(1, t0), e0 // Look up byte 2 in table 1.
331 movzx drh, t0d
332 xor LookupS(2, t0), e0 // Look up byte 3 in table 2.
333
334 add $4*4, E
335
336 movzx (E), t0d // Get cached round constant.
337 xor t0d, e0 // XOR with word from four words back.
338
339 // Chain to successive words.
340 mov e0, 0*4(E)
341 xor e0, e1
342 mov e1, 1*4(E)
343 xor e1, e2
344 mov e2, 2*4(E)
345 xor e2, e3
346 mov e3, 3*4(E)
347
348 cmp $0x36, t0d // Was this the last round constant?
349
350 jne 1b
351
352 xor r0, r0 // Return success.
353
354 9:
355 // Pop stack and restore registers.
356 movaps 7*16(r4), %xmm7
357 movaps 6*16(r4), %xmm6
358 movaps 5*16(r4), %xmm5
359 movaps 4*16(r4), %xmm4
360 movaps 3*16(r4), %xmm3
361 movaps 2*16(r4), %xmm2
362 movaps 1*16(r4), %xmm1
363 movaps 0*16(r4), %xmm0
364 #if 0 < LocalsSize
365 add $Padding + LocalsSize, r4
366 #endif
367 #if defined __i386__
368 pop r7
369 pop r6
370 pop r5
371 #endif
372 pop r3
373
374 ret
375
376
377 // Reset definitions for next case.
378 #undef e0
379 #undef e1
380 #undef e2
381 #undef e3
382
383 #undef vt3
384 #undef vt2
385 #define ve4 %xmm4
386 #define ve5 %xmm5
387
388
389 .globl _aes_encrypt_key192
390 // .private_extern _aes_encrypt_key192
391 _aes_encrypt_key192:
392
393 /* Save registers and set SaveSize to the number of bytes pushed onto the
394 stack so far, including the caller's return address.
395 */
396 push r3
397 #if defined __i386__
398 push r5
399 push r6
400 push r7
401 #define SaveSize (5*4)
402 #else
403 #define SaveSize (2*8)
404 #endif
405
406 /* Number of bytes used for local variables:
407
408 8 16-byte spaces to save XMM registers.
409 */
410 #define LocalsSize (8*16)
411
412 #if 0 < LocalsSize
413 // Padding to position stack pointer at a multiple of 16 bytes.
414 #define Padding (15 & -(SaveSize + LocalsSize))
415 sub $Padding + LocalsSize, r4 // Allocate space on stack.
416 #else
417 #define Padding 0
418 #endif
419
420 /* StackFrame is the number of bytes in our stack frame, from caller's
421 stack pointer to ours (so it includes the return address).
422 */
423 #define StackFrame (SaveSize + Padding + LocalsSize)
424
425 // Save xmm registers.
426 movaps %xmm0, 0*16(r4)
427 movaps %xmm1, 1*16(r4)
428 movaps %xmm2, 2*16(r4)
429 movaps %xmm3, 3*16(r4)
430 movaps %xmm4, 4*16(r4)
431 movaps %xmm5, 5*16(r4)
432 movaps %xmm6, 6*16(r4)
433 movaps %xmm7, 7*16(r4)
434
435 #if defined __i386__
436
437 // Load arguments.
438 #define Argument(i) StackFrame+4*(i)(r4)
439 mov Argument(1), E
440 mov Argument(0), K
441
442 #endif
443
444 // Merge point for _aes_encrypt_key and _aes_encrypt_key192.
445 EKeyHas6Words:
446
447 // First words of expanded key are copied from user key.
448 movd 0*4(K), ve0
449 movd 1*4(K), ve1
450 movd 2*4(K), ve2
451 movd 3*4(K), ve3
452
453 movl $12*16, ContextKeyLength(E) // Set "key length."
454
455 #if 0 != ContextKey
456 add $ContextKey, E
457 #endif
458
459 movd 4*4(K), ve4
460 movd 5*4(K), ve5
461
462 // K cannot be used after we write to R, since they use the same register.
463
464 #if defined __i386__
465
466 lea _AESRcon, R
467
468 #elif defined __x86_64__
469
470 lea _AESRcon(%rip), R
471 lea _AESSubBytesWordTable(%rip), STable
472
473 #endif
474
475 /* With a six-word key, there are twelve rounds (thirteen 16-byte key
476 blocks).
477 */
478 mov $-12*4*4, offset
479 sub offset, E
480
481 // Store initial words of expanded key, which are copies of user's key.
482 movd ve0, 0*4(E, offset)
483 movd ve1, 1*4(E, offset)
484 movd ve2, 2*4(E, offset)
485 movd ve3, 3*4(E, offset)
486 movd ve4, 4*4(E, offset)
487 movd ve5, 5*4(E, offset)
488
489 /* Jump into loop body. The key expansion processes six four-byte words per
490 iteration. 52 are needed in the key. So only four are needed in the last
491 iteration.
492 */
493 jmp 2f
494 1:
495 // Continue chaining to successive words.
496 pxor ve3, ve4
497 movd ve4, 4*4(E, offset)
498 pxor ve4, ve5
499 movd ve5, 5*4(E, offset)
500 2:
501 add $1, R // Advance pointer.
502 movd ve5, dr // Put previous word into dissection register.
503 movzx (R), t0 // Get round constant.
504 movd t0d, vt1
505 pxor vt1, ve0 // XOR with word from six words back.
506
507 // Perform SubWord(RotWord(dr)).
508 movzx drl, t0d
509 movd LookupS(3, t0), vt0 // Look up byte 0 in table 3.
510 movzx drh, t0d
511 movd LookupS(0, t0), vt1 // Look up byte 1 in table 0.
512 shr $16, dr
513 movzx drl, t0d
514 pxor vt1, vt0
515 pxor vt0, ve0
516 movd LookupS(1, t0), vt0 // Look up byte 2 in table 1.
517 movzx drh, t0d
518 movd LookupS(2, t0), vt1 // Look up byte 3 in table 2.
519 pxor vt1, vt0
520 pxor vt0, ve0
521
522 add $6*4, offset
523
524 // Chain to successive words.
525 movd ve0, 0*4(E, offset)
526 pxor ve0, ve1
527 movd ve1, 1*4(E, offset)
528 pxor ve1, ve2
529 movd ve2, 2*4(E, offset)
530 pxor ve2, ve3
531 movd ve3, 3*4(E, offset)
532
533 jne 1b
534
535 xor r0, r0 // Return success.
536
537 // Pop stack and restore registers.
538 movaps 7*16(r4), %xmm7
539 movaps 6*16(r4), %xmm6
540 movaps 5*16(r4), %xmm5
541 movaps 4*16(r4), %xmm4
542 movaps 3*16(r4), %xmm3
543 movaps 2*16(r4), %xmm2
544 movaps 1*16(r4), %xmm1
545 movaps 0*16(r4), %xmm0
546 #if 0 < LocalsSize
547 add $Padding + LocalsSize, r4
548 #endif
549 #if defined __i386__
550 pop r7
551 pop r6
552 pop r5
553 #endif
554 pop r3
555
556 ret
557
558
559 // Reset definitions for next case.
560 #undef ve4
561 #undef ve5
562 #define vt3 %xmm4
563 #define vt2 %xmm5
564
565
566 .globl _aes_encrypt_key256
567 // .private_extern _aes_encrypt_key256
568 _aes_encrypt_key256:
569
570 /* Save registers and set SaveSize to the number of bytes pushed onto the
571 stack so far, including the caller's return address.
572 */
573 push r3
574 #if defined __i386__
575 push r5
576 push r6
577 push r7
578 #define SaveSize (5*4)
579 #else
580 #define SaveSize (2*8)
581 #endif
582
583 /* Number of bytes used for local variables:
584
585 8 16-byte spaces to save XMM registers.
586 */
587 #define LocalsSize (8*16)
588
589 #if 0 < LocalsSize
590 // Padding to position stack pointer at a multiple of 16 bytes.
591 #define Padding (15 & -(SaveSize + LocalsSize))
592 sub $Padding + LocalsSize, r4 // Allocate space on stack.
593 #else
594 #define Padding 0
595 #endif
596
597 /* StackFrame is the number of bytes in our stack frame, from caller's
598 stack pointer to ours (so it includes the return address).
599 */
600 #define StackFrame (SaveSize + Padding + LocalsSize)
601
602 // Save xmm registers.
603 movaps %xmm0, 0*16(r4)
604 movaps %xmm1, 1*16(r4)
605 movaps %xmm2, 2*16(r4)
606 movaps %xmm3, 3*16(r4)
607 movaps %xmm4, 4*16(r4)
608 movaps %xmm5, 5*16(r4)
609 movaps %xmm6, 6*16(r4)
610 movaps %xmm7, 7*16(r4)
611
612 #if defined __i386__
613
614 // Load arguments.
615 #define Argument(i) StackFrame+4*(i)(r4)
616 mov Argument(1), E
617 mov Argument(0), K
618
619 #endif
620
621 // Merge point for _aes_encrypt_key and _aes_encrypt_key256.
622 EKeyHas8Words:
623
624 // First words of expanded key are copied from user key.
625 movd 0*4(K), ve0
626 movd 1*4(K), ve1
627 movd 2*4(K), ve2
628 movd 3*4(K), ve3
629
630 movl $14*16, ContextKeyLength(E) // Set "key length."
631
632 #if 0 != ContextKey
633 add $ContextKey, E
634 #endif
635
636 // Store initial words of expanded key, which are copies of user's key.
637 movd ve0, 0*4(E)
638 movd ve1, 1*4(E)
639 movd ve2, 2*4(E)
640 movd ve3, 3*4(E)
641 movd 4*4(K), ve0
642 movd 5*4(K), ve1
643 movd 6*4(K), ve2
644 movd 7*4(K), ve3
645
646 // K cannot be used after we write to R, since they use the same register.
647
648 #if defined __i386__
649
650 lea _AESRcon, R
651
652 #elif defined __x86_64__
653
654 lea _AESRcon(%rip), R
655 lea _AESSubBytesWordTable(%rip), STable
656
657 #endif
658
659 /* With an eight-word key, there are fourteen rounds (fifteen 16-byte key
660 blocks).
661 */
662 mov $-14*4*4, offset
663 sub offset, E
664
665 // Store initial words of expanded key, which are copies of user's key.
666 movd ve0, 4*4(E, offset)
667 movd ve1, 5*4(E, offset)
668 movd ve2, 6*4(E, offset)
669 movd ve3, 7*4(E, offset)
670
671 /* Jump into loop body. The key expansion processes eight four-byte words per
672 iteration. 60 are needed in the key. So only four are needed in the last
673 iteration.
674 */
675 jmp 2f
676 1:
677 movd ve3, dr // Put previous word into dissection register.
678
679 /* Get word from eight words back (it is four words back from where E
680 currently points, and we use it to prepare the value to be stored
681 four words beyond where E currently points).
682 */
683 movd -4*4(E, offset), ve0
684
685 // Perform SubWord(dr).
686 movzx drl, t0
687 movd LookupS(0, t0), vt0 // Look up byte 0 in table 0.
688 movzx drh, t0d
689 movd LookupS(1, t0), vt1 // Look up byte 1 in table 1.
690 shr $16, dr
691 movzx drl, t0d
692 movd LookupS(2, t0), vt2 // Look up byte 2 in table 2.
693 movzx drh, t0d
694 movd LookupS(3, t0), vt3 // Look up byte 3 in table 3.
695 pxor vt1, vt0
696 pxor vt3, vt2
697 pxor vt0, ve0
698 pxor vt2, ve0
699
700 movd -3*4(E, offset), ve1 // Get words from eight words back.
701 movd -2*4(E, offset), ve2
702 movd -1*4(E, offset), ve3
703
704 // Chain to successive words.
705 movd ve0, 4*4(E, offset)
706 pxor ve0, ve1
707 movd ve1, 5*4(E, offset)
708 pxor ve1, ve2
709 movd ve2, 6*4(E, offset)
710 pxor ve2, ve3
711 movd ve3, 7*4(E, offset)
712
713 2:
714 add $1, R // Advance pointer.
715 movd ve3, dr // Put previous word into dissection register.
716 movzx (R), t0d // Get round constant.
717 movd t0d, vt1
718 movd 0*4(E, offset), ve0 // Get word from eight words back.
719 pxor vt1, ve0
720
721 // Perform SubWord(RotWord(dr)).
722 movzx drl, t0
723 movd LookupS(3, t0), vt0 // Look up byte 0 in table 3.
724 movzx drh, t0d
725 movd LookupS(0, t0), vt1 // Look up byte 1 in table 0.
726 shr $16, dr
727 movzx drl, t0d
728 movd LookupS(1, t0), vt2 // Look up byte 2 in table 1.
729 movzx drh, t0d
730 movd LookupS(2, t0), vt3 // Look up byte 3 in table 2.
731 pxor vt1, vt0
732 pxor vt3, vt2
733 pxor vt0, ve0
734 pxor vt2, ve0
735
736 movd 1*4(E, offset), ve1
737 movd 2*4(E, offset), ve2
738 movd 3*4(E, offset), ve3
739
740 add $8*4, offset
741
742 // Chain to successive words.
743 movd ve0, 0*4(E, offset)
744 pxor ve0, ve1
745 movd ve1, 1*4(E, offset)
746 pxor ve1, ve2
747 movd ve2, 2*4(E, offset)
748 pxor ve2, ve3
749 movd ve3, 3*4(E, offset)
750
751 jne 1b
752
753 xor r0, r0 // Return success.
754
755 // Pop stack and restore registers.
756 movaps 7*16(r4), %xmm7
757 movaps 6*16(r4), %xmm6
758 movaps 5*16(r4), %xmm5
759 movaps 4*16(r4), %xmm4
760 movaps 3*16(r4), %xmm3
761 movaps 2*16(r4), %xmm2
762 movaps 1*16(r4), %xmm1
763 movaps 0*16(r4), %xmm0
764 #if 0 < LocalsSize
765 add $Padding + LocalsSize, r4
766 #endif
767 #if defined __i386__
768 pop r7
769 pop r6
770 pop r5
771 #endif
772 pop r3
773
774 ret
775
776
777 #undef Address
778 #undef Argument
779 #undef E
780 #undef K
781 #undef LocalsSize
782 #undef LookupS
783 #undef Padding
784 #undef R
785 #undef SaveSize
786 #undef STable
787 #undef StackFrame
788 #undef dr
789 #undef drh
790 #undef drl
791 #undef offset
792 #undef t0
793 #undef t0d
794 #undef ve0
795 #undef ve1
796 #undef ve2
797 #undef ve3
798 #undef vt0
799 #undef vt1
800 #undef vt2
801 #undef vt3