1#if defined(__i386__) 2.text 3.align 6,0x90 4L_vpaes_consts: 5.long 218628480,235210255,168496130,67568393 6.long 252381056,17041926,33884169,51187212 7.long 252645135,252645135,252645135,252645135 8.long 1512730624,3266504856,1377990664,3401244816 9.long 830229760,1275146365,2969422977,3447763452 10.long 3411033600,2979783055,338359620,2782886510 11.long 4209124096,907596821,221174255,1006095553 12.long 191964160,3799684038,3164090317,1589111125 13.long 182528256,1777043520,2877432650,3265356744 14.long 1874708224,3503451415,3305285752,363511674 15.long 1606117888,3487855781,1093350906,2384367825 16.long 197121,67569157,134941193,202313229 17.long 67569157,134941193,202313229,197121 18.long 134941193,202313229,197121,67569157 19.long 202313229,197121,67569157,134941193 20.long 33619971,100992007,168364043,235736079 21.long 235736079,33619971,100992007,168364043 22.long 168364043,235736079,33619971,100992007 23.long 100992007,168364043,235736079,33619971 24.long 50462976,117835012,185207048,252579084 25.long 252314880,51251460,117574920,184942860 26.long 184682752,252054788,50987272,118359308 27.long 118099200,185467140,251790600,50727180 28.long 2946363062,528716217,1300004225,1881839624 29.long 1532713819,1532713819,1532713819,1532713819 30.long 3602276352,4288629033,3737020424,4153884961 31.long 1354558464,32357713,2958822624,3775749553 32.long 1201988352,132424512,1572796698,503232858 33.long 2213177600,1597421020,4103937655,675398315 34.long 2749646592,4273543773,1511898873,121693092 35.long 3040248576,1103263732,2871565598,1608280554 36.long 2236667136,2588920351,482954393,64377734 37.long 3069987328,291237287,2117370568,3650299247 38.long 533321216,3573750986,2572112006,1401264716 39.long 1339849704,2721158661,548607111,3445553514 40.long 2128193280,3054596040,2183486460,1257083700 41.long 655635200,1165381986,3923443150,2344132524 42.long 190078720,256924420,290342170,357187870 43.long 1610966272,2263057382,4103205268,309794674 44.long 2592527872,2233205587,1335446729,3402964816 45.long 3973531904,3225098121,3002836325,1918774430 46.long 3870401024,2102906079,2284471353,4117666579 47.long 617007872,1021508343,366931923,691083277 48.long 2528395776,3491914898,2968704004,1613121270 49.long 3445188352,3247741094,844474987,4093578302 50.long 651481088,1190302358,1689581232,574775300 51.long 4289380608,206939853,2555985458,2489840491 52.long 2130264064,327674451,3566485037,3349835193 53.long 2470714624,316102159,3636825756,3393945945 54.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105 55.byte 111,110,32,65,69,83,32,102,111,114,32,120,56,54,47,83 56.byte 83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117 57.byte 114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105 58.byte 118,101,114,115,105,116,121,41,0 59.align 6,0x90 60.private_extern __vpaes_preheat 61.align 4 62__vpaes_preheat: 63 addl (%esp),%ebp 64 movdqa -48(%ebp),%xmm7 65 movdqa -16(%ebp),%xmm6 66 ret 67.private_extern __vpaes_encrypt_core 68.align 4 69__vpaes_encrypt_core: 70 movl $16,%ecx 71 movl 240(%edx),%eax 72 movdqa %xmm6,%xmm1 73 movdqa (%ebp),%xmm2 74 pandn %xmm0,%xmm1 75 pand %xmm6,%xmm0 76 movdqu (%edx),%xmm5 77.byte 102,15,56,0,208 78 movdqa 16(%ebp),%xmm0 79 pxor %xmm5,%xmm2 80 psrld $4,%xmm1 81 addl $16,%edx 82.byte 102,15,56,0,193 83 leal 192(%ebp),%ebx 84 pxor %xmm2,%xmm0 85 jmp L000enc_entry 86.align 4,0x90 87L001enc_loop: 88 movdqa 32(%ebp),%xmm4 89 movdqa 48(%ebp),%xmm0 90.byte 102,15,56,0,226 91.byte 102,15,56,0,195 92 pxor %xmm5,%xmm4 93 movdqa 64(%ebp),%xmm5 94 pxor %xmm4,%xmm0 95 movdqa -64(%ebx,%ecx,1),%xmm1 96.byte 102,15,56,0,234 97 movdqa 80(%ebp),%xmm2 98 movdqa (%ebx,%ecx,1),%xmm4 99.byte 102,15,56,0,211 100 movdqa %xmm0,%xmm3 101 pxor %xmm5,%xmm2 102.byte 102,15,56,0,193 103 addl $16,%edx 104 pxor %xmm2,%xmm0 105.byte 102,15,56,0,220 106 addl $16,%ecx 107 pxor %xmm0,%xmm3 108.byte 102,15,56,0,193 109 andl $48,%ecx 110 subl $1,%eax 111 pxor %xmm3,%xmm0 112L000enc_entry: 113 movdqa %xmm6,%xmm1 114 movdqa -32(%ebp),%xmm5 115 pandn %xmm0,%xmm1 116 psrld $4,%xmm1 117 pand %xmm6,%xmm0 118.byte 102,15,56,0,232 119 movdqa %xmm7,%xmm3 120 pxor %xmm1,%xmm0 121.byte 102,15,56,0,217 122 movdqa %xmm7,%xmm4 123 pxor %xmm5,%xmm3 124.byte 102,15,56,0,224 125 movdqa %xmm7,%xmm2 126 pxor %xmm5,%xmm4 127.byte 102,15,56,0,211 128 movdqa %xmm7,%xmm3 129 pxor %xmm0,%xmm2 130.byte 102,15,56,0,220 131 movdqu (%edx),%xmm5 132 pxor %xmm1,%xmm3 133 jnz L001enc_loop 134 movdqa 96(%ebp),%xmm4 135 movdqa 112(%ebp),%xmm0 136.byte 102,15,56,0,226 137 pxor %xmm5,%xmm4 138.byte 102,15,56,0,195 139 movdqa 64(%ebx,%ecx,1),%xmm1 140 pxor %xmm4,%xmm0 141.byte 102,15,56,0,193 142 ret 143.private_extern __vpaes_decrypt_core 144.align 4 145__vpaes_decrypt_core: 146 leal 608(%ebp),%ebx 147 movl 240(%edx),%eax 148 movdqa %xmm6,%xmm1 149 movdqa -64(%ebx),%xmm2 150 pandn %xmm0,%xmm1 151 movl %eax,%ecx 152 psrld $4,%xmm1 153 movdqu (%edx),%xmm5 154 shll $4,%ecx 155 pand %xmm6,%xmm0 156.byte 102,15,56,0,208 157 movdqa -48(%ebx),%xmm0 158 xorl $48,%ecx 159.byte 102,15,56,0,193 160 andl $48,%ecx 161 pxor %xmm5,%xmm2 162 movdqa 176(%ebp),%xmm5 163 pxor %xmm2,%xmm0 164 addl $16,%edx 165 leal -352(%ebx,%ecx,1),%ecx 166 jmp L002dec_entry 167.align 4,0x90 168L003dec_loop: 169 movdqa -32(%ebx),%xmm4 170 movdqa -16(%ebx),%xmm1 171.byte 102,15,56,0,226 172.byte 102,15,56,0,203 173 pxor %xmm4,%xmm0 174 movdqa (%ebx),%xmm4 175 pxor %xmm1,%xmm0 176 movdqa 16(%ebx),%xmm1 177.byte 102,15,56,0,226 178.byte 102,15,56,0,197 179.byte 102,15,56,0,203 180 pxor %xmm4,%xmm0 181 movdqa 32(%ebx),%xmm4 182 pxor %xmm1,%xmm0 183 movdqa 48(%ebx),%xmm1 184.byte 102,15,56,0,226 185.byte 102,15,56,0,197 186.byte 102,15,56,0,203 187 pxor %xmm4,%xmm0 188 movdqa 64(%ebx),%xmm4 189 pxor %xmm1,%xmm0 190 movdqa 80(%ebx),%xmm1 191.byte 102,15,56,0,226 192.byte 102,15,56,0,197 193.byte 102,15,56,0,203 194 pxor %xmm4,%xmm0 195 addl $16,%edx 196.byte 102,15,58,15,237,12 197 pxor %xmm1,%xmm0 198 subl $1,%eax 199L002dec_entry: 200 movdqa %xmm6,%xmm1 201 movdqa -32(%ebp),%xmm2 202 pandn %xmm0,%xmm1 203 pand %xmm6,%xmm0 204 psrld $4,%xmm1 205.byte 102,15,56,0,208 206 movdqa %xmm7,%xmm3 207 pxor %xmm1,%xmm0 208.byte 102,15,56,0,217 209 movdqa %xmm7,%xmm4 210 pxor %xmm2,%xmm3 211.byte 102,15,56,0,224 212 pxor %xmm2,%xmm4 213 movdqa %xmm7,%xmm2 214.byte 102,15,56,0,211 215 movdqa %xmm7,%xmm3 216 pxor %xmm0,%xmm2 217.byte 102,15,56,0,220 218 movdqu (%edx),%xmm0 219 pxor %xmm1,%xmm3 220 jnz L003dec_loop 221 movdqa 96(%ebx),%xmm4 222.byte 102,15,56,0,226 223 pxor %xmm0,%xmm4 224 movdqa 112(%ebx),%xmm0 225 movdqa (%ecx),%xmm2 226.byte 102,15,56,0,195 227 pxor %xmm4,%xmm0 228.byte 102,15,56,0,194 229 ret 230.private_extern __vpaes_schedule_core 231.align 4 232__vpaes_schedule_core: 233 addl (%esp),%ebp 234 movdqu (%esi),%xmm0 235 movdqa 320(%ebp),%xmm2 236 movdqa %xmm0,%xmm3 237 leal (%ebp),%ebx 238 movdqa %xmm2,4(%esp) 239 call __vpaes_schedule_transform 240 movdqa %xmm0,%xmm7 241 testl %edi,%edi 242 jnz L004schedule_am_decrypting 243 movdqu %xmm0,(%edx) 244 jmp L005schedule_go 245L004schedule_am_decrypting: 246 movdqa 256(%ebp,%ecx,1),%xmm1 247.byte 102,15,56,0,217 248 movdqu %xmm3,(%edx) 249 xorl $48,%ecx 250L005schedule_go: 251 cmpl $192,%eax 252 ja L006schedule_256 253 je L007schedule_192 254L008schedule_128: 255 movl $10,%eax 256L009loop_schedule_128: 257 call __vpaes_schedule_round 258 decl %eax 259 jz L010schedule_mangle_last 260 call __vpaes_schedule_mangle 261 jmp L009loop_schedule_128 262.align 4,0x90 263L007schedule_192: 264 movdqu 8(%esi),%xmm0 265 call __vpaes_schedule_transform 266 movdqa %xmm0,%xmm6 267 pxor %xmm4,%xmm4 268 movhlps %xmm4,%xmm6 269 movl $4,%eax 270L011loop_schedule_192: 271 call __vpaes_schedule_round 272.byte 102,15,58,15,198,8 273 call __vpaes_schedule_mangle 274 call __vpaes_schedule_192_smear 275 call __vpaes_schedule_mangle 276 call __vpaes_schedule_round 277 decl %eax 278 jz L010schedule_mangle_last 279 call __vpaes_schedule_mangle 280 call __vpaes_schedule_192_smear 281 jmp L011loop_schedule_192 282.align 4,0x90 283L006schedule_256: 284 movdqu 16(%esi),%xmm0 285 call __vpaes_schedule_transform 286 movl $7,%eax 287L012loop_schedule_256: 288 call __vpaes_schedule_mangle 289 movdqa %xmm0,%xmm6 290 call __vpaes_schedule_round 291 decl %eax 292 jz L010schedule_mangle_last 293 call __vpaes_schedule_mangle 294 pshufd $255,%xmm0,%xmm0 295 movdqa %xmm7,20(%esp) 296 movdqa %xmm6,%xmm7 297 call L_vpaes_schedule_low_round 298 movdqa 20(%esp),%xmm7 299 jmp L012loop_schedule_256 300.align 4,0x90 301L010schedule_mangle_last: 302 leal 384(%ebp),%ebx 303 testl %edi,%edi 304 jnz L013schedule_mangle_last_dec 305 movdqa 256(%ebp,%ecx,1),%xmm1 306.byte 102,15,56,0,193 307 leal 352(%ebp),%ebx 308 addl $32,%edx 309L013schedule_mangle_last_dec: 310 addl $-16,%edx 311 pxor 336(%ebp),%xmm0 312 call __vpaes_schedule_transform 313 movdqu %xmm0,(%edx) 314 pxor %xmm0,%xmm0 315 pxor %xmm1,%xmm1 316 pxor %xmm2,%xmm2 317 pxor %xmm3,%xmm3 318 pxor %xmm4,%xmm4 319 pxor %xmm5,%xmm5 320 pxor %xmm6,%xmm6 321 pxor %xmm7,%xmm7 322 ret 323.private_extern __vpaes_schedule_192_smear 324.align 4 325__vpaes_schedule_192_smear: 326 pshufd $128,%xmm6,%xmm1 327 pshufd $254,%xmm7,%xmm0 328 pxor %xmm1,%xmm6 329 pxor %xmm1,%xmm1 330 pxor %xmm0,%xmm6 331 movdqa %xmm6,%xmm0 332 movhlps %xmm1,%xmm6 333 ret 334.private_extern __vpaes_schedule_round 335.align 4 336__vpaes_schedule_round: 337 movdqa 8(%esp),%xmm2 338 pxor %xmm1,%xmm1 339.byte 102,15,58,15,202,15 340.byte 102,15,58,15,210,15 341 pxor %xmm1,%xmm7 342 pshufd $255,%xmm0,%xmm0 343.byte 102,15,58,15,192,1 344 movdqa %xmm2,8(%esp) 345L_vpaes_schedule_low_round: 346 movdqa %xmm7,%xmm1 347 pslldq $4,%xmm7 348 pxor %xmm1,%xmm7 349 movdqa %xmm7,%xmm1 350 pslldq $8,%xmm7 351 pxor %xmm1,%xmm7 352 pxor 336(%ebp),%xmm7 353 movdqa -16(%ebp),%xmm4 354 movdqa -48(%ebp),%xmm5 355 movdqa %xmm4,%xmm1 356 pandn %xmm0,%xmm1 357 psrld $4,%xmm1 358 pand %xmm4,%xmm0 359 movdqa -32(%ebp),%xmm2 360.byte 102,15,56,0,208 361 pxor %xmm1,%xmm0 362 movdqa %xmm5,%xmm3 363.byte 102,15,56,0,217 364 pxor %xmm2,%xmm3 365 movdqa %xmm5,%xmm4 366.byte 102,15,56,0,224 367 pxor %xmm2,%xmm4 368 movdqa %xmm5,%xmm2 369.byte 102,15,56,0,211 370 pxor %xmm0,%xmm2 371 movdqa %xmm5,%xmm3 372.byte 102,15,56,0,220 373 pxor %xmm1,%xmm3 374 movdqa 32(%ebp),%xmm4 375.byte 102,15,56,0,226 376 movdqa 48(%ebp),%xmm0 377.byte 102,15,56,0,195 378 pxor %xmm4,%xmm0 379 pxor %xmm7,%xmm0 380 movdqa %xmm0,%xmm7 381 ret 382.private_extern __vpaes_schedule_transform 383.align 4 384__vpaes_schedule_transform: 385 movdqa -16(%ebp),%xmm2 386 movdqa %xmm2,%xmm1 387 pandn %xmm0,%xmm1 388 psrld $4,%xmm1 389 pand %xmm2,%xmm0 390 movdqa (%ebx),%xmm2 391.byte 102,15,56,0,208 392 movdqa 16(%ebx),%xmm0 393.byte 102,15,56,0,193 394 pxor %xmm2,%xmm0 395 ret 396.private_extern __vpaes_schedule_mangle 397.align 4 398__vpaes_schedule_mangle: 399 movdqa %xmm0,%xmm4 400 movdqa 128(%ebp),%xmm5 401 testl %edi,%edi 402 jnz L014schedule_mangle_dec 403 addl $16,%edx 404 pxor 336(%ebp),%xmm4 405.byte 102,15,56,0,229 406 movdqa %xmm4,%xmm3 407.byte 102,15,56,0,229 408 pxor %xmm4,%xmm3 409.byte 102,15,56,0,229 410 pxor %xmm4,%xmm3 411 jmp L015schedule_mangle_both 412.align 4,0x90 413L014schedule_mangle_dec: 414 movdqa -16(%ebp),%xmm2 415 leal 416(%ebp),%esi 416 movdqa %xmm2,%xmm1 417 pandn %xmm4,%xmm1 418 psrld $4,%xmm1 419 pand %xmm2,%xmm4 420 movdqa (%esi),%xmm2 421.byte 102,15,56,0,212 422 movdqa 16(%esi),%xmm3 423.byte 102,15,56,0,217 424 pxor %xmm2,%xmm3 425.byte 102,15,56,0,221 426 movdqa 32(%esi),%xmm2 427.byte 102,15,56,0,212 428 pxor %xmm3,%xmm2 429 movdqa 48(%esi),%xmm3 430.byte 102,15,56,0,217 431 pxor %xmm2,%xmm3 432.byte 102,15,56,0,221 433 movdqa 64(%esi),%xmm2 434.byte 102,15,56,0,212 435 pxor %xmm3,%xmm2 436 movdqa 80(%esi),%xmm3 437.byte 102,15,56,0,217 438 pxor %xmm2,%xmm3 439.byte 102,15,56,0,221 440 movdqa 96(%esi),%xmm2 441.byte 102,15,56,0,212 442 pxor %xmm3,%xmm2 443 movdqa 112(%esi),%xmm3 444.byte 102,15,56,0,217 445 pxor %xmm2,%xmm3 446 addl $-16,%edx 447L015schedule_mangle_both: 448 movdqa 256(%ebp,%ecx,1),%xmm1 449.byte 102,15,56,0,217 450 addl $-16,%ecx 451 andl $48,%ecx 452 movdqu %xmm3,(%edx) 453 ret 454.globl _vpaes_set_encrypt_key 455.private_extern _vpaes_set_encrypt_key 456.align 4 457_vpaes_set_encrypt_key: 458L_vpaes_set_encrypt_key_begin: 459 pushl %ebp 460 pushl %ebx 461 pushl %esi 462 pushl %edi 463 movl 20(%esp),%esi 464 leal -56(%esp),%ebx 465 movl 24(%esp),%eax 466 andl $-16,%ebx 467 movl 28(%esp),%edx 468 xchgl %esp,%ebx 469 movl %ebx,48(%esp) 470 movl %eax,%ebx 471 shrl $5,%ebx 472 addl $5,%ebx 473 movl %ebx,240(%edx) 474 movl $48,%ecx 475 movl $0,%edi 476 leal L_vpaes_consts+0x30-L016pic_point,%ebp 477 call __vpaes_schedule_core 478L016pic_point: 479 movl 48(%esp),%esp 480 xorl %eax,%eax 481 popl %edi 482 popl %esi 483 popl %ebx 484 popl %ebp 485 ret 486.globl _vpaes_set_decrypt_key 487.private_extern _vpaes_set_decrypt_key 488.align 4 489_vpaes_set_decrypt_key: 490L_vpaes_set_decrypt_key_begin: 491 pushl %ebp 492 pushl %ebx 493 pushl %esi 494 pushl %edi 495 movl 20(%esp),%esi 496 leal -56(%esp),%ebx 497 movl 24(%esp),%eax 498 andl $-16,%ebx 499 movl 28(%esp),%edx 500 xchgl %esp,%ebx 501 movl %ebx,48(%esp) 502 movl %eax,%ebx 503 shrl $5,%ebx 504 addl $5,%ebx 505 movl %ebx,240(%edx) 506 shll $4,%ebx 507 leal 16(%edx,%ebx,1),%edx 508 movl $1,%edi 509 movl %eax,%ecx 510 shrl $1,%ecx 511 andl $32,%ecx 512 xorl $32,%ecx 513 leal L_vpaes_consts+0x30-L017pic_point,%ebp 514 call __vpaes_schedule_core 515L017pic_point: 516 movl 48(%esp),%esp 517 xorl %eax,%eax 518 popl %edi 519 popl %esi 520 popl %ebx 521 popl %ebp 522 ret 523.globl _vpaes_encrypt 524.private_extern _vpaes_encrypt 525.align 4 526_vpaes_encrypt: 527L_vpaes_encrypt_begin: 528 pushl %ebp 529 pushl %ebx 530 pushl %esi 531 pushl %edi 532 leal L_vpaes_consts+0x30-L018pic_point,%ebp 533 call __vpaes_preheat 534L018pic_point: 535 movl 20(%esp),%esi 536 leal -56(%esp),%ebx 537 movl 24(%esp),%edi 538 andl $-16,%ebx 539 movl 28(%esp),%edx 540 xchgl %esp,%ebx 541 movl %ebx,48(%esp) 542 movdqu (%esi),%xmm0 543 call __vpaes_encrypt_core 544 movdqu %xmm0,(%edi) 545 movl 48(%esp),%esp 546 popl %edi 547 popl %esi 548 popl %ebx 549 popl %ebp 550 ret 551.globl _vpaes_decrypt 552.private_extern _vpaes_decrypt 553.align 4 554_vpaes_decrypt: 555L_vpaes_decrypt_begin: 556 pushl %ebp 557 pushl %ebx 558 pushl %esi 559 pushl %edi 560 leal L_vpaes_consts+0x30-L019pic_point,%ebp 561 call __vpaes_preheat 562L019pic_point: 563 movl 20(%esp),%esi 564 leal -56(%esp),%ebx 565 movl 24(%esp),%edi 566 andl $-16,%ebx 567 movl 28(%esp),%edx 568 xchgl %esp,%ebx 569 movl %ebx,48(%esp) 570 movdqu (%esi),%xmm0 571 call __vpaes_decrypt_core 572 movdqu %xmm0,(%edi) 573 movl 48(%esp),%esp 574 popl %edi 575 popl %esi 576 popl %ebx 577 popl %ebp 578 ret 579.globl _vpaes_cbc_encrypt 580.private_extern _vpaes_cbc_encrypt 581.align 4 582_vpaes_cbc_encrypt: 583L_vpaes_cbc_encrypt_begin: 584 pushl %ebp 585 pushl %ebx 586 pushl %esi 587 pushl %edi 588 movl 20(%esp),%esi 589 movl 24(%esp),%edi 590 movl 28(%esp),%eax 591 movl 32(%esp),%edx 592 subl $16,%eax 593 jc L020cbc_abort 594 leal -56(%esp),%ebx 595 movl 36(%esp),%ebp 596 andl $-16,%ebx 597 movl 40(%esp),%ecx 598 xchgl %esp,%ebx 599 movdqu (%ebp),%xmm1 600 subl %esi,%edi 601 movl %ebx,48(%esp) 602 movl %edi,(%esp) 603 movl %edx,4(%esp) 604 movl %ebp,8(%esp) 605 movl %eax,%edi 606 leal L_vpaes_consts+0x30-L021pic_point,%ebp 607 call __vpaes_preheat 608L021pic_point: 609 cmpl $0,%ecx 610 je L022cbc_dec_loop 611 jmp L023cbc_enc_loop 612.align 4,0x90 613L023cbc_enc_loop: 614 movdqu (%esi),%xmm0 615 pxor %xmm1,%xmm0 616 call __vpaes_encrypt_core 617 movl (%esp),%ebx 618 movl 4(%esp),%edx 619 movdqa %xmm0,%xmm1 620 movdqu %xmm0,(%ebx,%esi,1) 621 leal 16(%esi),%esi 622 subl $16,%edi 623 jnc L023cbc_enc_loop 624 jmp L024cbc_done 625.align 4,0x90 626L022cbc_dec_loop: 627 movdqu (%esi),%xmm0 628 movdqa %xmm1,16(%esp) 629 movdqa %xmm0,32(%esp) 630 call __vpaes_decrypt_core 631 movl (%esp),%ebx 632 movl 4(%esp),%edx 633 pxor 16(%esp),%xmm0 634 movdqa 32(%esp),%xmm1 635 movdqu %xmm0,(%ebx,%esi,1) 636 leal 16(%esi),%esi 637 subl $16,%edi 638 jnc L022cbc_dec_loop 639L024cbc_done: 640 movl 8(%esp),%ebx 641 movl 48(%esp),%esp 642 movdqu %xmm1,(%ebx) 643L020cbc_abort: 644 popl %edi 645 popl %esi 646 popl %ebx 647 popl %ebp 648 ret 649#endif 650