|
楼主 |
发表于 2017-6-2 11:29:30
|
显示全部楼层
本帖最后由 pic_flash 于 2017-6-2 11:35 编辑
下面是Telmah 大大的源码,他自己另外写来做64位运算的.
我没有验证过, 只是给你参考
来源: http://www.ccsinfo.com/forum/viewtopic.php?t=28815
- union bits64 {
- int8 b[8];
- int32 w[2];
- };
- typedef union bits64 int64;
- int64 scratch64;
- int1 BORROW=FALSE;
- #bit CARRY=0xFD8.0
- //Macro to add two 64bit values. Result into the first
- #define M_add64x64(M_a,M_b) \
- #asm\
- movf M_b.b[0],0\
- addwf M_a.b[0],1\
- movf M_b.b[1],0\
- addwfc M_a.b[1],1\
- movf M_b.b[2],0\
- addwfc M_a.b[2],1\
- movf M_b.b[3],0\
- addwfc M_a.b[3],1\
- movf M_b.b[4],0\
- addwfc M_a.b[4],1\
- movf M_b.b[5],0\
- addwfc M_a.b[5],1\
- movf M_b.b[6],0\
- addwfc M_a.b[6],1\
- movf M_b.b[7],0\
- addwfc M_a.b[7],1\
- #endasm
- //Macro as above, to subtract two 64bit values.
- #define M_sub64x64(M_a,M_b) \
- #asm\
- movf M_b.b[0],0\
- subwf M_a.b[0],1\
- movf M_b.b[1],0\
- subwfb M_a.b[1],1\
- movf M_b.b[2],0\
- subwfb M_a.b[2],1\
- movf M_b.b[3],0\
- subwfb M_a.b[3],1\
- movf M_b.b[4],0\
- subwfb M_a.b[4],1\
- movf M_b.b[5],0\
- subwfb M_a.b[5],1\
- movf M_b.b[6],0\
- subwfb M_a.b[6],1\
- movf M_b.b[7],0\
- subwfb M_a.b[7],1\
- #endasm
- //Macros to shift a 64bit value
- #define M_shiftleft64(x) shift_left(&x,8,0)
- #define M_shiftright64(x) shift_right(&x,8,0)
- //Macro to zero a 64bit value
- #define M_zero64(x) x.w[0]=0L;x.w[1]=0L
- #define M_iszero64(x) ((x.w[0]==0L)&&(x.w[1]==0L))
- #define bit64_set(x,i) x.b[i>>3]|=(1<<(i&7))
- int64 cast32x64(int32 a) {
- //routine to convert a 32bit int to 64bit
- int64 temp;
- int8 i;
- temp.w[0]=a;
- //and clear the top half
- temp.w[1]=0L;
- return temp;
- }
- int64 I_A_LT_B(int64 a,int64 b) {
- //Internal routine to _compare_ two 64 bit values
- //Actually performs subtraction, and returns this, with the 'borrow'
- //flag in the global variable 'BORROW'. Performs a-b, hence flag is
- //set if A less than B
- M_sub64x64(a,b);
- if (CARRY==0) BORROW=TRUE;
- else BORROW=FALSE;
- return a;
- }
- int64 add64x64(int64 a,int64 b) {
- //simple 64 bit addition call - returns (a+b)
- M_add64x64(a,b);
- return a;
- }
- int64 sub64x64(int64 a,int64 b) {
- //64 bit subtraction call as above - returns (a-b)
- M_sub64x64(a,b);
- return a;
- }
- int64 mult32x32(int32 a,int32 b) {
- //Routine to multiply two 32bit values with a 64bit result
- int64 temp2;
- int8 i;
- //zero output
- M_zero64(temp2);
- //Not trying to break any records for efficiency, so all in C, and not using
- //hardware multiply
- //start by moving the int32, into the low half of the int64
- scratch64=cast32x64(b);
- //Now need to work through all 32 bits in the 'a' variable
- for (i=0;i<32;i++) {
- //if source bit in 'a' is one, perform addition
- if (bit_test(a,i))
- M_add64x64(temp2,scratch64);
- //rotate the second value here
- M_shiftleft64(scratch64);
- }
- return temp2;
- }
- int64 div64x64(int64 a,int64 b) {
- //Routine to divide 'a' by 'b' in 64bit arithmetic
- //returns with result, leaving remainder in the scratch64
- int8 bitno=0,ctr;
- int64 temp;
- if (M_iszero64(b)) {
- if (!M_iszero64(a)) {
- //need maximum result
- temp.w[0]=temp.w[1]=0xFFFFFFFF;
- M_zero64(scratch64);
- return temp;
- }
- //Else 0/0=1
- M_zero64(temp);
- M_zero64(scratch64);
- temp.b[0]=1;
- return temp;
- //return 1
- }
- M_zero64(temp);
- bitno=0;
- //Now position divisor to suit find top bit in A, and rotate b till it's
- //top bit is in the same position
- if (a.w[1]!=0) {
- for(ctr=31;!bit_test(a.w[1], ctr);ctr--) ;
- //Now rotate b till it's top bit matches.
- while (!bit_test(b.w[1], ctr)) {
- M_shiftleft64(b);
- ++bitno;
- }
- }
- else {
- for(ctr=31;!bit_test(a.w[0], ctr);ctr--) ;
- bitno=ctr;
- //Now rotate b till it's top bit matches.
- while (!bit_test(b.w[1], ctr)) {
- M_shiftleft64(b);
- ++bitno;
- }
- }
- //bitno now stores how far b had to rotate
- while (bitno) {
- //Loop for bitno bits, performing subtract, shift & test
- scratch64=I_A_LT_B(a,b);
- if (!BORROW) {
- a=scratch64;
- //Set output bit if no borrow
- bit64_set(temp,bitno);
- }
- if (M_iszero64(a)) break;
- M_shiftright64(b);
- bitno--;
- }
- scratch64=a;
- return temp;
- }
复制代码 |
|