3339 borrow := aSmallInteger abs. |
3339 borrow := aSmallInteger abs. |
3340 |
3340 |
3341 %{ |
3341 %{ |
3342 if (__isByteArray(__INST(digitByteArray)) |
3342 if (__isByteArray(__INST(digitByteArray)) |
3343 && __isByteArray(resultDigitByteArray)) { |
3343 && __isByteArray(resultDigitByteArray)) { |
3344 unsigned INT __borrow = __intVal(borrow); |
3344 unsigned INT __borrow = __intVal(borrow); |
3345 INT __diff; |
3345 INT __diff; |
3346 int __index = 1; |
3346 int __index = 1; |
3347 int __len = __intVal(len); |
3347 int __len = __intVal(len); |
3348 unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
3348 unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
3349 unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
3349 unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
3350 int __len3; |
3350 int __len3; |
3351 |
3351 |
3352 #if defined(__LSBFIRST__) |
3352 #if defined(__LSBFIRST__) |
3353 # if (__POINTER_SIZE__ == 8) |
3353 # if (__POINTER_SIZE__ == 8) |
3354 /* |
3354 /* |
3355 * subtract int-wise |
3355 * subtract int-wise |
3356 */ |
3356 */ |
3357 __len3 = __len - 3; |
3357 __len3 = __len - 3; |
3358 while (__index < __len3) { |
3358 while (__index < __len3) { |
3359 /* do not make this into one expression - ask cg why */ |
3359 /* do not make this into one expression - ask cg why */ |
3360 __diff = ((unsigned int *)(__digitP + __index-1))[0]; |
3360 __diff = ((unsigned int *)(__digitP + __index-1))[0]; |
3361 __diff -= (__borrow & 0xFFFFFFFFL); |
3361 __diff -= (__borrow & 0xFFFFFFFFL); |
3362 __borrow >>= 32; |
3362 __borrow >>= 32; |
3363 if (__diff < 0) { |
3363 ((unsigned int *)(__resultP+__index-1))[0] = __diff; |
3364 /* __diff += 0x100000000; */ |
3364 __index += 4; |
3365 __borrow++; |
3365 if (__diff < 0) { |
3366 } |
3366 /* __diff += 0x100000000; */ |
3367 ((unsigned int *)(__resultP+__index-1))[0] = __diff; |
3367 __borrow++; |
3368 __index += 4; |
3368 } else { |
3369 } |
3369 if (__borrow == 0) { |
|
3370 /* nothing more to subtract .. */ |
|
3371 while (__index < __len3) { |
|
3372 ((unsigned int *)(__resultP+__index-1))[0] = ((unsigned int *)(__digitP+__index-1))[0]; |
|
3373 __index += 4; |
|
3374 } |
|
3375 if (__index < __len) { |
|
3376 ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0]; |
|
3377 __index += 2; |
|
3378 } |
|
3379 if (__index <= __len) { |
|
3380 __resultP[__index-1] = __digitP[__index-1]; |
|
3381 } |
|
3382 break; |
|
3383 } |
|
3384 } |
|
3385 } |
3370 # endif |
3386 # endif |
3371 /* |
3387 /* |
3372 * subtract short-wise |
3388 * subtract short-wise |
3373 */ |
3389 */ |
3374 while (__index < __len) { |
3390 while (__index < __len) { |
3375 /* do not make this into one expression - ask cg why */ |
3391 /* do not make this into one expression - ask cg why */ |
3376 __diff = ((unsigned short *)(__digitP+__index-1))[0]; |
3392 __diff = ((unsigned short *)(__digitP+__index-1))[0]; |
3377 __diff -= (__borrow & 0xFFFF); |
3393 __diff -= (__borrow & 0xFFFF); |
3378 __borrow >>= 16; |
3394 __borrow >>= 16; |
3379 if (__diff < 0) { |
3395 ((unsigned short *)(__resultP+__index-1))[0] = __diff; |
3380 /* __diff += 0x10000; */ |
3396 __index += 2; |
3381 __borrow++; |
3397 if (__diff < 0) { |
3382 } else { |
3398 /* __diff += 0x10000; */ |
3383 if (__borrow == 0) { |
3399 __borrow++; |
3384 ((unsigned short *)(__resultP+__index-1))[0] = __diff; |
3400 } else { |
3385 __index += 2; |
3401 if (__borrow == 0) { |
3386 |
3402 /* nothing more to subtract .. */ |
3387 /* nothing more to subtract .. */ |
3403 while (__index < __len) { |
3388 while (__index < __len) { |
3404 ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0]; |
3389 ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0]; |
3405 __index += 2; |
3390 __index += 2; |
3406 } |
3391 } |
3407 if (__index <= __len) { |
3392 if (__index <= __len) { |
3408 __resultP[__index-1] = __digitP[__index-1]; |
3393 __resultP[__index-1] = __digitP[__index-1]; |
3409 } |
3394 } |
3410 break; |
3395 break; |
3411 } |
3396 } |
3412 } |
3397 } |
3413 } |
3398 ((unsigned short *)(__resultP+__index-1))[0] = __diff; |
|
3399 __index += 2; |
|
3400 } |
|
3401 #endif |
3414 #endif |
3402 /* |
3415 /* |
3403 * subtract byte-wise |
3416 * subtract byte-wise |
3404 */ |
3417 */ |
3405 while (__index <= __len) { |
3418 while (__index <= __len) { |
3406 __diff = __digitP[__index-1]; |
3419 __diff = __digitP[__index-1]; |
3407 __diff -= (__borrow & 0xFF); |
3420 __diff -= (__borrow & 0xFF); |
3408 __borrow >>= 8; |
3421 __borrow >>= 8; |
3409 if (__diff < 0) { |
3422 __resultP[__index-1] = __diff; |
3410 /* __diff += 0x100; */ |
3423 __index++; |
3411 __borrow++; |
3424 if (__diff < 0) { |
3412 } else { |
3425 /* __diff += 0x100; */ |
3413 if (__borrow == 0) { |
3426 __borrow++; |
3414 __resultP[__index-1] = __diff; |
3427 } else { |
3415 __index++; |
3428 if (__borrow == 0) { |
3416 |
3429 /* nothing more to subtract .. */ |
3417 /* nothing more to subtract .. */ |
3430 while (__index <= __len) { |
3418 while (__index <= __len) { |
3431 __resultP[__index-1] = __digitP[__index-1]; |
3419 __resultP[__index-1] = __digitP[__index-1]; |
3432 __index++; |
3420 __index++; |
3433 } |
3421 } |
3434 break; |
3422 break; |
3435 } |
3423 } |
3436 } |
3424 } |
3437 } |
3425 __resultP[__index-1] = __diff; |
3438 lastDigit = __mkSmallInteger( __resultP[__index-1-1] ); |
3426 __index++; |
3439 ok = true; |
3427 } |
|
3428 lastDigit = __mkSmallInteger( __resultP[__index-1-1] ); |
|
3429 ok = true; |
|
3430 } |
3440 } |
3431 %}. |
3441 %}. |
3432 |
3442 |
3433 ok == true ifFalse:[ "/ cannot happen |
3443 ok == true ifFalse:[ "/ cannot happen |
3434 index := 1. |
3444 index := 1. |
3435 [borrow ~~ 0] whileTrue:[ |
3445 [borrow ~~ 0] whileTrue:[ |
3436 (index <= len) ifTrue:[ |
3446 (index <= len) ifTrue:[ |
3437 diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF). |
3447 diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF). |
3438 borrow := borrow bitShift:-8. |
3448 borrow := borrow bitShift:-8. |
3439 diff < 0 ifTrue:[ |
3449 diff < 0 ifTrue:[ |
3440 diff := diff + 256. |
3450 diff := diff + 256. |
3441 borrow := borrow + 1. |
3451 borrow := borrow + 1. |
3442 ] |
3452 ] |
3443 ] ifFalse:[ |
3453 ] ifFalse:[ |
3444 diff := borrow bitAnd:255. |
3454 diff := borrow bitAnd:255. |
3445 borrow := borrow bitShift:-8. |
3455 borrow := borrow bitShift:-8. |
3446 ]. |
3456 ]. |
3447 resultDigitByteArray basicAt:index put:(lastDigit := diff). |
3457 resultDigitByteArray basicAt:index put:(lastDigit := diff). |
3448 index := index + 1 |
3458 index := index + 1 |
3449 ]. |
3459 ]. |
3450 [index <= len] whileTrue:[ |
3460 [index <= len] whileTrue:[ |
3451 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
3461 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
3452 index := index + 1 |
3462 index := index + 1 |
3453 ]. |
3463 ]. |
3454 (index <= rsltLen) ifTrue:[ |
3464 (index <= rsltLen) ifTrue:[ |
3455 lastDigit := 0. |
3465 lastDigit := 0. |
3456 ] |
3466 ] |
3457 ]. |
3467 ]. |
3458 |
3468 |
3459 (lastDigit == 0 or:[rsltLen <= SmallInteger maxBytes]) ifTrue:[ |
3469 (lastDigit == 0 or:[rsltLen <= SmallInteger maxBytes]) ifTrue:[ |
3460 ^ result compressed. |
3470 ^ result compressed. |
3461 ]. |
3471 ]. |
3462 ^ result |
3472 ^ result |
3463 |
3473 |
3464 " |
3474 " |
3465 12345678900000000000 absFastMinus:1 sign:1 |
3475 12345678900000000000 absFastMinus:1 sign:1 |
3522 |
3532 |
3523 %{ |
3533 %{ |
3524 if (__isByteArray(__INST(digitByteArray)) |
3534 if (__isByteArray(__INST(digitByteArray)) |
3525 && __isByteArray(resultDigitByteArray) |
3535 && __isByteArray(resultDigitByteArray) |
3526 && __isSmallInteger(aSmallInteger)) { |
3536 && __isSmallInteger(aSmallInteger)) { |
3527 /* carry is NOT unsigned (see negation below) */ |
3537 /* carry is NOT unsigned (see negation below) */ |
3528 INT __carry = __intVal(aSmallInteger); |
3538 INT __carry = __intVal(aSmallInteger); |
3529 int __index = 1; |
3539 int __index = 1; |
3530 int __len = __intVal(len); |
3540 int __len = __intVal(len); |
3531 unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element); |
3541 unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element); |
3532 unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element); |
3542 unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element); |
3533 INT __ptrDelta = __dst - __src; |
3543 INT __ptrDelta = __dst - __src; |
3534 unsigned char *__srcLast = __src + __len - 1; |
3544 unsigned char *__srcLast = __src + __len - 1; |
3535 int __rsltLen = __intVal(rsltLen); |
3545 int __rsltLen = __intVal(rsltLen); |
3536 |
3546 |
3537 if (__carry < 0) { |
3547 if (__carry < 0) { |
3538 __carry = -__carry; |
3548 __carry = -__carry; |
3539 } |
3549 } |
3540 |
3550 |
3541 #if defined(__LSBFIRST__) |
3551 #if defined(__LSBFIRST__) |
3542 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4) |
3552 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4) |
3543 # if 0 /* NOTICE - the code below is 20% slower ... - why */ |
3553 # if 0 /* NOTICE - the code below is 20% slower ... - why */ |
3544 /* |
3554 /* |
3545 * add long-wise |
3555 * add long-wise |
3546 */ |
3556 */ |
3547 asm(" jecxz nothingToDo \n\ |
3557 asm(" jecxz nothingToDo \n\ |
3548 movl %%eax, %%esi /* __src input */ \n\ |
3558 movl %%eax, %%esi /* __src input */ \n\ |
3549 movl %%ebx, %%edi /* __dst input */ \n\ |
3559 movl %%ebx, %%edi /* __dst input */ \n\ |
3550 \n\ |
3560 \n\ |
3551 /* the first 4-byte int */ \n\ |
3561 /* the first 4-byte int */ \n\ |
3552 lodsl /* fetch */ \n\ |
3562 lodsl /* fetch */ \n\ |
3553 addl %%edx, %%eax /* add */ \n\ |
3563 addl %%edx, %%eax /* add */ \n\ |
3554 stosl /* store */ \n\ |
3564 stosl /* store */ \n\ |
3555 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3565 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3556 jecxz doneLoop /* any more ? */ \n\ |
3566 jecxz doneLoop /* any more ? */ \n\ |
3557 /* remaining 4-byte ints */ \n\ |
3567 /* remaining 4-byte ints */ \n\ |
3558 jmp addLoop \n\ |
3568 jmp addLoop \n\ |
3559 \n\ |
3569 \n\ |
3560 .align 8 \n\ |
3570 .align 8 \n\ |
3561 addLoop: \n\ |
3571 addLoop: \n\ |
3562 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3572 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3563 jnc copyLoop2 \n\ |
3573 jnc copyLoop2 \n\ |
3564 movl $0, %%eax \n\ |
3574 movl $0, %%eax \n\ |
3565 leal 4(%%esi), %%esi \n\ |
3575 leal 4(%%esi), %%esi \n\ |
3566 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3576 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3567 leal 8(%%edi), %%edi \n\ |
3577 leal 8(%%edi), %%edi \n\ |
3568 movl %%eax, -8(%%edi) /* store */ \n\ |
3578 movl %%eax, -8(%%edi) /* store */ \n\ |
3569 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3579 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3570 jecxz doneLoop /* any more ? */ \n\ |
3580 jecxz doneLoop /* any more ? */ \n\ |
3571 \n\ |
3581 \n\ |
3572 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3582 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3573 movl $0, %%eax \n\ |
3583 movl $0, %%eax \n\ |
3574 leal 4(%%esi), %%esi \ |
3584 leal 4(%%esi), %%esi \ |
3575 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3585 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3576 movl %%eax, -4(%%edi) /* store */ \n\ |
3586 movl %%eax, -4(%%edi) /* store */ \n\ |
3577 \n\ |
3587 \n\ |
3578 loop addLoop \n\ |
3588 loop addLoop \n\ |
3579 jmp doneLoop \n\ |
3589 jmp doneLoop \n\ |
3580 \n\ |
3590 \n\ |
3581 .align 8 \n\ |
3591 .align 8 \n\ |
3582 copyLoop: \n\ |
3592 copyLoop: \n\ |
3583 movl 0(%%esi), %%ebx \n\ |
3593 movl 0(%%esi), %%ebx \n\ |
3584 copyLoop2: \n\ |
3594 copyLoop2: \n\ |
3585 add $4, %%esi \n\ |
3595 add $4, %%esi \n\ |
3586 add $4, %%edi \n\ |
3596 add $4, %%edi \n\ |
3587 movl %%ebx, -4(%%edi) \n\ |
3597 movl %%ebx, -4(%%edi) \n\ |
3588 loop copyLoop \n\ |
3598 loop copyLoop \n\ |
3589 \n\ |
3599 \n\ |
3590 doneLoop: \n\ |
3600 doneLoop: \n\ |
3591 movl $0, %%edx /* do not clobber carry (xorl clears it) */ \n\ |
3601 movl $0, %%edx /* do not clobber carry (xorl clears it) */ \n\ |
3592 adcl $0, %%edx \n\ |
3602 adcl $0, %%edx \n\ |
3593 movl %%esi, %%eax /* __src output */ \n\ |
3603 movl %%esi, %%eax /* __src output */ \n\ |
3594 nothingToDo: \n\ |
3604 nothingToDo: \n\ |
3595 " : "=d" ((unsigned long)(__carry)), |
3605 " : "=d" ((unsigned long)(__carry)), |
3596 "=a" (__src) |
3606 "=a" (__src) |
3597 : "1" (__src), |
3607 : "1" (__src), |
3598 "b" (__dst), |
3608 "b" (__dst), |
3599 "c" (__len / 4), |
3609 "c" (__len / 4), |
3600 "0" (__carry) |
3610 "0" (__carry) |
3601 : "esi", "edi"); |
3611 : "esi", "edi"); |
3602 |
3612 |
3603 # else |
3613 # else |
3604 { |
3614 { |
3605 unsigned char *__srcLastX; |
3615 unsigned char *__srcLastX; |
3606 |
3616 |
3607 __srcLastX = __srcLast - 3 - 4; |
3617 __srcLastX = __srcLast - 3 - 4; |
3608 while (__src <= __srcLastX) { |
3618 while (__src <= __srcLastX) { |
3609 unsigned int __sum, __sum2; |
3619 unsigned int __sum, __sum2; |
3610 unsigned __digit1, __digit2; |
3620 unsigned __digit1, __digit2; |
3611 |
3621 |
3612 __digit1 = ((unsigned *)__src)[0]; |
3622 __digit1 = ((unsigned *)__src)[0]; |
3613 __digit2 = ((unsigned *)__src)[1]; |
3623 __digit2 = ((unsigned *)__src)[1]; |
3614 asm ("addl %%edx,%%ecx \n\ |
3624 asm ("addl %%edx,%%ecx \n\ |
3615 adcl $0, %%eax \n\ |
3625 adcl $0, %%eax \n\ |
3616 movl $0, %%edx \n\ |
3626 movl $0, %%edx \n\ |
3617 adcl $0, %%edx" |
3627 adcl $0, %%edx" |
3618 : "=d" ((unsigned long)(__carry)), |
3628 : "=d" ((unsigned long)(__carry)), |
3619 "=c" ((unsigned long)(__sum)), |
3629 "=c" ((unsigned long)(__sum)), |
3620 "=a" ((unsigned long)(__sum2)) |
3630 "=a" ((unsigned long)(__sum2)) |
3621 : "0" ((unsigned long)(__carry)), |
3631 : "0" ((unsigned long)(__carry)), |
3622 "1" (__digit1), |
3632 "1" (__digit1), |
3623 "2" (__digit2)); |
3633 "2" (__digit2)); |
3624 |
3634 |
3625 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3635 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3626 ((unsigned int *)(__src + __ptrDelta))[1] = __sum2; |
3636 ((unsigned int *)(__src + __ptrDelta))[1] = __sum2; |
3627 |
3637 |
3628 __src += 8; |
3638 __src += 8; |
3629 |
3639 |
3630 if (__carry == 0) { |
3640 if (__carry == 0) { |
3631 while (__src <= __srcLastX) { |
3641 while (__src <= __srcLastX) { |
3632 /* copy over words */ |
3642 /* copy over words */ |
3633 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3643 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3634 ((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1]; |
3644 ((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1]; |
3635 __src += 8; |
3645 __src += 8; |
3636 } |
3646 } |
3637 while (__src <= __srcLast) { |
3647 while (__src <= __srcLast) { |
3638 /* copy over bytes */ |
3648 /* copy over bytes */ |
3639 __src[__ptrDelta] = __src[0]; |
3649 __src[__ptrDelta] = __src[0]; |
3640 __src ++; |
3650 __src ++; |
3641 } |
3651 } |
3642 goto doneSource; |
3652 goto doneSource; |
3643 } |
3653 } |
3644 } |
3654 } |
3645 |
3655 |
3646 __srcLastX = __srcLastX + 4; |
3656 __srcLastX = __srcLastX + 4; |
3647 if (__src <= __srcLastX) { |
3657 if (__src <= __srcLastX) { |
3648 unsigned int __sum, __digit; |
3658 unsigned int __sum, __digit; |
3649 |
3659 |
3650 __digit = ((unsigned *)__src)[0]; |
3660 __digit = ((unsigned *)__src)[0]; |
3651 |
3661 |
3652 asm ("addl %%eax,%%edx \n\ |
3662 asm ("addl %%eax,%%edx \n\ |
3653 movl $0,%%eax \n\ |
3663 movl $0,%%eax \n\ |
3654 adcl $0,%%eax" |
3664 adcl $0,%%eax" |
3655 : "=a" ((unsigned long)(__carry)), |
3665 : "=a" ((unsigned long)(__carry)), |
3656 "=d" ((unsigned long)(__sum)) |
3666 "=d" ((unsigned long)(__sum)) |
3657 : "0" ((unsigned long)(__carry)), |
3667 : "0" ((unsigned long)(__carry)), |
3658 "1" (__digit) ); |
3668 "1" (__digit) ); |
3659 |
3669 |
3660 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3670 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3661 __src += 4; |
3671 __src += 4; |
3662 |
3672 |
3663 if (__carry == 0) { |
3673 if (__carry == 0) { |
3664 while (__src <= __srcLast) { |
3674 while (__src <= __srcLast) { |
3665 /* copy over bytes */ |
3675 /* copy over bytes */ |
3666 __src[__ptrDelta] = __src[0]; |
3676 __src[__ptrDelta] = __src[0]; |
3667 __src ++; |
3677 __src ++; |
3668 } |
3678 } |
3669 goto doneSource; |
3679 goto doneSource; |
3670 } |
3680 } |
3671 } |
3681 } |
3672 } |
3682 } |
3673 # endif |
3683 # endif |
3674 # else /* not i386-GNUC */ |
3684 # else /* not i386-GNUC */ |
3675 # if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4) |
3685 # if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4) |
3676 { |
3686 { |
3677 unsigned char *__srcLast4; |
3687 unsigned char *__srcLast4; |
3678 |
3688 |
3679 /* |
3689 /* |
3680 * add long-wise |
3690 * add long-wise |
3681 */ |
3691 */ |
3682 __srcLast4 = __srcLast - 3; |
3692 __srcLast4 = __srcLast - 3; |
3683 while (__src <= __srcLast4) { |
3693 while (__src <= __srcLast4) { |
3684 unsigned int __sum; |
3694 unsigned int __sum; |
3685 |
3695 |
3686 __sum = ((unsigned int *)__src)[0]; |
3696 __sum = ((unsigned int *)__src)[0]; |
3687 asm { |
3697 asm { |
3688 mov eax, __sum |
3698 mov eax, __sum |
3689 add eax, __carry |
3699 add eax, __carry |
3690 mov edx, 0 |
3700 mov edx, 0 |
3691 adc edx, 0 |
3701 adc edx, 0 |
3692 mov __sum, eax |
3702 mov __sum, eax |
3693 mov __carry, edx |
3703 mov __carry, edx |
3694 } |
3704 } |
3695 |
3705 |
3696 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3706 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3697 __src += 4; |
3707 __src += 4; |
3698 if (__carry == 0) { |
3708 if (__carry == 0) { |
3699 while (__src <= __srcLast4) { |
3709 while (__src <= __srcLast4) { |
3700 /* copy over words */ |
3710 /* copy over words */ |
3701 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3711 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3702 __src += 4; |
3712 __src += 4; |
3703 } |
3713 } |
3704 while (__src <= __srcLast) { |
3714 while (__src <= __srcLast) { |
3705 /* copy over bytes */ |
3715 /* copy over bytes */ |
3706 __src[__ptrDelta] = __src[0]; |
3716 __src[__ptrDelta] = __src[0]; |
3707 __src ++; |
3717 __src ++; |
3708 } |
3718 } |
3709 goto doneSource; |
3719 goto doneSource; |
3710 } |
3720 } |
3711 } |
3721 } |
3712 } |
3722 } |
3713 # else /* not i386-WIN32 */ |
3723 # else /* not i386-WIN32 */ |
3714 # if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8) |
3724 # if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8) |
3715 { |
3725 { |
3716 unsigned char *__srcLast4; |
3726 unsigned char *__srcLast4; |
3717 |
3727 |
3718 /* |
3728 /* |
3719 * add long-wise |
3729 * add long-wise |
3720 */ |
3730 */ |
3721 __srcLast4 = __srcLast - 3; |
3731 __srcLast4 = __srcLast - 3; |
3722 while (__src <= __srcLast4) { |
3732 while (__src <= __srcLast4) { |
3723 unsigned INT __sum; |
3733 unsigned INT __sum; |
3724 |
3734 |
3725 __sum = ((unsigned int *)__src)[0] + __carry; |
3735 __sum = (INT)(((unsigned int *)__src)[0]); |
3726 ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */; |
3736 __sum += __carry; |
3727 __src += 4; |
3737 ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */; |
3728 __carry = __sum >> 32; |
3738 __src += 4; |
3729 if (__carry == 0) { |
3739 __carry = __sum >> 32; |
3730 while (__src <= __srcLast4) { |
3740 if (__carry == 0) { |
3731 /* copy over words */ |
3741 while (__src <= __srcLast4) { |
3732 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3742 /* copy over words */ |
3733 __src += 4; |
3743 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3734 } |
3744 __src += 4; |
3735 while (__src <= __srcLast) { |
3745 } |
3736 /* copy over bytes */ |
3746 while (__src <= __srcLast) { |
3737 __src[__ptrDelta] = __src[0]; |
3747 /* copy over bytes */ |
3738 __src ++; |
3748 __src[__ptrDelta] = __src[0]; |
3739 } |
3749 __src ++; |
3740 goto doneSource; |
3750 } |
3741 } |
3751 goto doneSource; |
3742 } |
3752 } |
3743 } |
3753 } |
|
3754 } |
3744 # endif /* LSB+64bit */ |
3755 # endif /* LSB+64bit */ |
3745 # endif /* __i386__ & WIN32 */ |
3756 # endif /* __i386__ & WIN32 */ |
3746 # endif /* __i386__ & GNUC */ |
3757 # endif /* __i386__ & GNUC */ |
3747 |
3758 |
3748 /* |
3759 /* |
3749 * add short-wise |
3760 * add short-wise |
3750 */ |
3761 */ |
3751 while (__src < __srcLast) { |
3762 while (__src < __srcLast) { |
3752 __carry += ((unsigned short *)__src)[0]; |
3763 __carry += ((unsigned short *)__src)[0]; |
3753 ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */; |
3764 ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */; |
3754 __carry >>= 16; |
3765 __carry >>= 16; |
3755 __src += 2; |
3766 __src += 2; |
3756 } |
3767 } |
3757 /* |
3768 /* |
3758 * last (odd) byte |
3769 * last (odd) byte |
3759 */ |
3770 */ |
3760 if (__src <= __srcLast) { |
3771 if (__src <= __srcLast) { |
3761 __carry += __src[0]; |
3772 __carry += __src[0]; |
3762 __src[__ptrDelta] = __carry /* & 0xFF */; |
3773 __src[__ptrDelta] = __carry /* & 0xFF */; |
3763 __carry >>= 8; |
3774 __carry >>= 8; |
3764 __src++; |
3775 __src++; |
3765 } |
3776 } |
3766 #else /* not __LSBFIRST__ */ |
3777 #else /* not __LSBFIRST__ */ |
3767 |
3778 |
3768 /* |
3779 /* |
3769 * add byte-wise |
3780 * add byte-wise |
3770 */ |
3781 */ |
3771 while (__src <= __srcLast) { |
3782 while (__src <= __srcLast) { |
3772 __carry += __src[0]; |
3783 __carry += __src[0]; |
3773 __src[__ptrDelta] = __carry /* & 0xFF */; |
3784 __src[__ptrDelta] = __carry /* & 0xFF */; |
3774 __src++; |
3785 __src++; |
3775 __carry >>= 8; |
3786 __carry >>= 8; |
3776 |
3787 |
3777 if (__carry == 0) { |
3788 if (__carry == 0) { |
3778 while (__src <= __srcLast) { |
3789 while (__src <= __srcLast) { |
3779 /* copy over rest */ |
3790 /* copy over rest */ |
3780 __src[__ptrDelta] = __src[0]; |
3791 __src[__ptrDelta] = __src[0]; |
3781 __src++; |
3792 __src++; |
3782 } |
3793 } |
3783 goto doneSource; |
3794 goto doneSource; |
3784 } |
3795 } |
3785 } |
3796 } |
3786 #endif /* __LSBFIRST__ */ |
3797 #endif /* __LSBFIRST__ */ |
3787 |
3798 |
3788 doneSource: ; |
3799 doneSource: ; |
3789 /* |
3800 /* |
3790 * now, at most one other byte is to be stored ... |
3801 * now, at most one other byte is to be stored ... |
3791 */ |
3802 */ |
3792 if (__len < __rsltLen) { |
3803 if (__len < __rsltLen) { |
3793 __src[__ptrDelta] = __carry /* & 0xFF */; |
3804 __src[__ptrDelta] = __carry /* & 0xFF */; |
3794 __src++; |
3805 __src++; |
3795 } |
3806 } |
3796 |
3807 |
3797 if (__src[__ptrDelta-1]) { /* lastDigit */ |
3808 if (__src[__ptrDelta-1] != 0) { /* lastDigit */ |
3798 RETURN (result); |
3809 RETURN (result); |
3799 } |
3810 } |
3800 ok = true; |
3811 // must compress |
|
3812 ok = true; |
3801 } |
3813 } |
3802 %}. |
3814 %}. |
3803 |
3815 |
3804 ok ~~ true ifTrue:[ |
3816 ok ~~ true ifTrue:[ |
3805 index := 1. |
3817 index := 1. |
3806 carry := aSmallInteger abs. |
3818 carry := aSmallInteger abs. |
3807 |
3819 |
3808 [carry ~~ 0] whileTrue:[ |
3820 [carry ~~ 0] whileTrue:[ |
3809 (index <= len) ifTrue:[ |
3821 (index <= len) ifTrue:[ |
3810 carry := (digitByteArray basicAt:index) + carry. |
3822 carry := (digitByteArray basicAt:index) + carry. |
3811 ]. |
3823 ]. |
3812 resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF). |
3824 resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF). |
3813 carry := carry bitShift:-8. |
3825 carry := carry bitShift:-8. |
3814 index := index + 1 |
3826 index := index + 1 |
3815 ]. |
3827 ]. |
3816 |
3828 |
3817 (index <= rsltLen) ifTrue:[ |
3829 (index <= rsltLen) ifTrue:[ |
3818 [index <= len] whileTrue:[ |
3830 [index <= len] whileTrue:[ |
3819 resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index). |
3831 resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index). |
3820 index := index + 1 |
3832 index := index + 1 |
3821 ]. |
3833 ]. |
3822 lastDigit := 0. |
3834 lastDigit := 0. |
3823 ]. |
3835 ]. |
3824 |
3836 |
3825 (lastDigit ~~ 0 and:[rsltLen > SmallInteger maxBytes]) ifTrue:[ |
3837 (lastDigit ~~ 0 and:[rsltLen > SmallInteger maxBytes]) ifTrue:[ |
3826 ^ result |
3838 ^ result |
3827 ]. |
3839 ]. |
3828 ]. |
3840 ]. |
3829 |
3841 |
3830 ^ result compressed |
3842 ^ result compressed |
3831 |
3843 |
3832 "Modified: 24.3.1997 / 21:32:41 / cg" |
3844 "Modified: 24.3.1997 / 21:32:41 / cg" |