469 lines
12 KiB
ArmAsm
469 lines
12 KiB
ArmAsm
# Copyright Digital Equipment Corporation & INRIA 1988, 1989
|
|
#
|
|
# KerN for the RS6000
|
|
# [Bepaul]
|
|
#
|
|
# La plupart du code est celui ge'ne're' par le compilo C (Cha^peau!)
|
|
#
|
|
.set RES,3
|
|
.set CA1,3
|
|
.set CA2,4
|
|
.set CA3,5
|
|
.set CA4,6
|
|
.set CA5,7
|
|
.set X4,7
|
|
.set X3,8
|
|
.set X2,9
|
|
.set X1,10
|
|
|
|
.set NN1,CA1
|
|
.set MM1,CA1
|
|
.set D1,CA1
|
|
.set NN2,CA2
|
|
.set NL2,CA2
|
|
.set ML2,CA2
|
|
.set D2,CA2
|
|
.set NN3,CA3
|
|
.set NL3,CA3
|
|
.set NL4,CA4
|
|
|
|
.toc
|
|
T.bignum_dat: .tc bignum_dat[TC],bignum_dat[RW]
|
|
.csect bignum_dat[RW]
|
|
.csect bignum_txt[PR]
|
|
|
|
.globl .BnnSetToZero # BnnSetToZero(nn, nl)
|
|
.BnnSetToZero: cmpi 0,NL2,0 # if(nl <= 0) return;
|
|
bler
|
|
mtctr NL2 # ctr = nl;
|
|
lil X1,0 # cte = 0;
|
|
ai NN1,NN1,-4 # nn--;
|
|
BSTZ1: stu X1,4(NN1) # *(++nn) = cte;
|
|
bdn BSTZ1 # if(--ctr != 0) goto BSTZ1;
|
|
br # return;
|
|
|
|
.globl .BnnAssign # BnnAssign(mm, nn, nl)
|
|
.BnnAssign: cmpi 0,NL3,0 # if(nl <= 0) return;
|
|
bler
|
|
mtctr NL3 # ctr = nl;
|
|
cmpl 0,MM1,NN2 # if(mm >= nn) goto BAG2;
|
|
bge BAG2
|
|
ai MM1,MM1,-4 # mm--;
|
|
ai NN2,NN2,-4 # nn--;
|
|
BAG1: lu X1,4(NN2) # X = *(++nn);
|
|
stu X1,4(MM1) # *(++mm) = X;
|
|
bdn BAG1 # if(--ctr != 0) goto BAG1;
|
|
br
|
|
BAG2: beqr # if(mm == nn) return;
|
|
sli X1,NL3,2
|
|
a NN2,NN2,X1 # nn += nl;
|
|
a MM1,MM1,X1 # mm += nl;
|
|
BAG3: lu X1,-4(NN2) # X = *(--nn);
|
|
stu X1,-4(MM1) # *(--mm) = X;
|
|
bdn BAG3 # (if(--ctr != 0) goto BAG3;
|
|
br # return;
|
|
|
|
.globl .BnnSetDigit # BnnSetDigit(nn, d)
|
|
.BnnSetDigit: st D2,0(NN1)
|
|
br
|
|
|
|
.globl .BnnGetDigit # BnnGetDigit(nn)
|
|
.BnnGetDigit: l RES,0(NN1)
|
|
br
|
|
|
|
.globl .BnnNumDigits # BnnNumDigits(nn, nl)
|
|
.BnnNumDigits: cmpi 0,NL2,0 # if(nl <= 0) return(1);
|
|
ble BND2
|
|
sli X1,NL2,2
|
|
a NN1,NN1,X1 # nn += nl;
|
|
mtctr NL2 # ctr = nl;
|
|
BND1: lu X1,-4(NN1) # X = *(--nn);
|
|
cmpi 0,X1,0 # if(X != 0) goto BND3
|
|
bne BND3
|
|
bdn BND1 # if(--ctr != 0) goto BND1;
|
|
BND2: lil RES,1 # return(1);
|
|
br
|
|
BND3: mfctr RES # return(ctr);
|
|
br
|
|
|
|
.globl .BnnNumLeadingZeroBitsInDigit # (d)
|
|
.BnnNumLeadingZeroBitsInDigit:
|
|
cntlz RES,D1 # Yeah!
|
|
br
|
|
|
|
.globl .BnnDoesDigitFitInWord # (d)
|
|
.BnnDoesDigitFitInWord:
|
|
lil RES,1 # return(1);
|
|
br
|
|
|
|
.globl .BnnIsDigitZero # BnnIsDigitZero(d)
|
|
.BnnIsDigitZero: # Use the fact that nabs(d) >=0 <=> d == 0
|
|
nabs RES,D1
|
|
rlinm RES,RES,1,31,31 # sign in the lowest bit.
|
|
xoril RES,RES,1 # get the inverse.
|
|
br
|
|
|
|
.globl .BnnIsDigitNormalized # (d)
|
|
.BnnIsDigitNormalized:
|
|
rlinm RES,D1,1,31,31 # sign in the lowest bit.
|
|
br
|
|
|
|
.globl .BnnIsDigitOdd # BnnIsDigitOdd(d)
|
|
.BnnIsDigitOdd: rlinm RES,D1,0,31,31 # only the lowest bit.
|
|
br
|
|
|
|
.globl .BnnCompareDigits # BnnCompareDigits(d1, d2)
|
|
.BnnCompareDigits:
|
|
cmpl 0,D1,D2 # if(d1 == d2) return(0);
|
|
beq BSD0
|
|
bgt BCDsup # if(d1 > d2) return(1);
|
|
lil RES,-1 # return(-1);
|
|
BSDret: br
|
|
BCDsup: lil RES,1 # return(1);
|
|
br
|
|
BSD0: lil RES,0 # return(0);
|
|
br
|
|
|
|
.globl .BnnComplement #.BnnComplement(nn, nl)
|
|
.BnnComplement: cmpi 0,NL2,0 # if(nl <= 0) return;
|
|
bler
|
|
ai NN1,NN1,-4 # nn--;
|
|
mtctr NL2 # ctr = nl;
|
|
BCM1: l X1,4(NN1) # X = nn[1];
|
|
sfi X1,X1,-1 # X ^= -1;
|
|
stu X1,4(NN1) # *++nn = X;
|
|
bdn BCM1 # if(--ctr > 0) goto BCM1
|
|
br # return;
|
|
|
|
.globl .BnnAndDigits # BnnAndDigits(nn, d)
|
|
.BnnAndDigits: l X1,0(NN1) # X = *nn;
|
|
and X1,X1,D2 # X &= d;
|
|
st X1,0(NN1) # *nn = X;
|
|
br
|
|
|
|
.globl .BnnOrDigits # BnnOrDigits(nn, d)
|
|
.BnnOrDigits: l X1,0(NN1) # X = *nn;
|
|
or X1,X1,D2 # X |= d;
|
|
st X1,0(NN1) # *nn = X;
|
|
br
|
|
|
|
.globl .BnnXorDigits # BnnXorDigits(nn, d)
|
|
.BnnXorDigits: l X1,0(NN1) # X = *nn;
|
|
xor X1,X1,D2 # X ^= d;
|
|
st X1,0(NN1) # *nn = X;
|
|
br
|
|
|
|
.globl .BnnShiftLeft # BnnShiftLeft(mm, ml, nbits)
|
|
# here and in the next funxtion we use the fact that MM1 == RES.
|
|
.set NBI,CA3; .set SMM,X1; .set RNB,X2; .set SX,X3; .set SY,ML2
|
|
.BnnShiftLeft: oril SMM,MM1,0
|
|
lil RES,0 # res = 0;
|
|
cmpi 0,NBI,0 # if(nbits == 0) return(res);
|
|
beqr
|
|
cmpi 0,ML2,0 # if(ml <= 0) return(res);
|
|
bler
|
|
sfi RNB,NBI,32 # rnbits = 32 - nbits;
|
|
ai SMM,SMM,-4 # mm--;
|
|
mtctr ML2 # ctr = ml;
|
|
BSL1: l SX,4(SMM) # X = mm[1];
|
|
sl SY,SX,NBI # Y = X << nbits;
|
|
or SY,SY,RES # Y |= res;
|
|
stu SY,4(SMM) # *(++mm) = Y;
|
|
sr RES,SX,RNB # res = X >> rnbits;
|
|
bdn BSL1 # if(--ctr > 0) goto BSL1
|
|
br # return(res);
|
|
|
|
.globl .BnnShiftRight # BnnShiftRight(mm, ml, nbits)
|
|
.BnnShiftRight: sli X1,ML2,2 # mm += ml;
|
|
a SMM,MM1,X1
|
|
lil RES,0 # res = 0;
|
|
cmpi 0,NBI,0 # if(nbits == 0) return(res);
|
|
beqr
|
|
cmpi 0,ML2,0 # if(ml <= 0) return(res);
|
|
bler
|
|
sfi RNB,NBI,32 # rnbits = 32 - nbits;
|
|
mtctr ML2 # ctr = ml;
|
|
BSR1: lu SX,-4(SMM) # X = *(--mm);
|
|
sr SY,SX,NBI # Y = X >> nbits;
|
|
or SY,SY,RES # Y |= res;
|
|
st SY,0(SMM) # *(mm) = Y;
|
|
sl RES,SX,RNB # res = X << rnbits;
|
|
bdn BSR1 # if(--ctr > 0) goto BSR1
|
|
br # return(res);
|
|
|
|
.globl .BnnAddCarry # BnnAddCarry(nn, nl, carryin)
|
|
.set CARRY,CA3 # also for BnnSubtractBorrow
|
|
.BnnAddCarry: cmpi 0,CARRY,0 # if(carryin == 0) return(0);
|
|
beq BAC3
|
|
cmpi 0,NL2,0 # if(nl == 0) return(1);
|
|
beq BAC2
|
|
ai NN1,NN1,-4 # nn--;
|
|
mtctr NL2 # ctr = nl;
|
|
BAC1: l X1,4(NN1) # X = nn[1];
|
|
ai. X1,X1,1 # X++;
|
|
stu X1,4(NN1) # *(++nn) = X;
|
|
bne BAC3 # if(X != 0) return(0);
|
|
bdn BAC1 # if(--ctr > 0) goto BAC1
|
|
BAC2: lil RES,1 # return(1);
|
|
br
|
|
BAC3: lil RES,0 # return(0);
|
|
br
|
|
|
|
.globl .BnnAdd # BnnAdd(mm, ml, nn, nl, carryin)
|
|
.set CARRYIN,CA5 # also for BnnSubtract.
|
|
.BnnAdd: sf ML2,NL4,ML2 # ml -= nl;
|
|
ai NN3,NN3,-4 # nn--;
|
|
ai MM1,MM1,-4 # mm--; carry = 1;
|
|
cmpi 0,NL4,0 # if(nl == 0) goto BADD2;
|
|
beq BADD2
|
|
mtctr NL4 # ctr = nl;
|
|
cmpi 0,CARRYIN,0 # if(carryin) goto BADD1;
|
|
bne BADD1
|
|
ai X1,X1,0 # carry = 0;
|
|
BADD1: lu X2,4(NN3) # Y = *(++nn);
|
|
l X1,4(MM1) # X = mm[1];
|
|
ae X1,X1,X2 # X = X + Y + carry; carry = ??
|
|
stu X1,4(MM1) # *(++mm) = X;
|
|
bdn BADD1 # if(--ctr > 0) goto BADD1
|
|
lil X2,0
|
|
ae CARRYIN,X2,X2 # carryin = carry;
|
|
BADD2: cmpi 0,CARRYIN,0 # if(carryin == 0) return(0);
|
|
beq BADD5
|
|
cmpi 0,ML2,0 # if(ml == 0) return(1);
|
|
beq BADD4
|
|
mtctr ML2 # ctr = ml;
|
|
BADD3: l X1,4(MM1) # X = mm[1];
|
|
ai. X1,X1,1 # X++;
|
|
stu X1,4(MM1) # *(++mm) = X;
|
|
bne BADD5 # if(X != 0) return(0);
|
|
bdn BADD3 # if(--ctr > 0) goto BADD3;
|
|
BADD4: lil RES,1 # return(1);
|
|
br
|
|
BADD5: lil RES,0 # return(0);
|
|
br
|
|
|
|
.globl .BnnSubtractBorrow # (nn, nl, carryin)
|
|
.BnnSubtractBorrow:
|
|
cmpi 0,CARRY,1 # if(carryin == 1) return(1);
|
|
beq BSB3
|
|
cmpi 0,NL2,0 # if(nl == 0) return(0);
|
|
beq BSB2
|
|
ai NN1,NN1,-4 # nn--;
|
|
mtctr NL2 # ctr = nl;
|
|
BSB1: l X1,4(NN1) # X = nn[1];
|
|
si X2,X1,1 # Y= X-1;
|
|
stu X2,4(NN1) # *(++nn) = Y;
|
|
cmpi 0,X1,0
|
|
bne BSB3 # if(X != 0) return(1);
|
|
bdn BSB1 # if(--ctr > 0) goto BSB1
|
|
BSB2: lil RES,0 # return(0);
|
|
br
|
|
BSB3: lil RES,1 # return(1);
|
|
br
|
|
|
|
.globl .BnnSubtract # BnnSubtract(mm, ml, nn, nl, carryin)
|
|
.BnnSubtract: sf ML2,NL4,ML2 # ml -= nl;
|
|
ai NN3,NN3,-4 # nn--;
|
|
ai MM1,MM1,-4 # mm--; carry = 1;
|
|
cmpi 0,NL4,0 # if(nl == 0) goto BS2
|
|
beq BS2
|
|
mtctr NL4 # ctr = nl;
|
|
cmpi 0,CARRYIN,0 # if(carryin) goto BS1
|
|
bne BS1
|
|
ai X1,X1,0 # carry = 0;
|
|
BS1: lu X2,4(NN3) # Y = *(++nn);
|
|
l X1,4(MM1) # X = mm[1];
|
|
sfe X1,X2,X1 # X = X - (Y + carry); carry = ??
|
|
stu X1,4(MM1) # *(++mm) = X;
|
|
bdn BS1 # if(--ctr > 0) goto BS1
|
|
lil CA5,0
|
|
ae CA5,CA5,CA5 # carryin = carry;
|
|
BS2: cmpi 0,CA5,1 # if(carryin == 0) return(1);
|
|
beq BS5
|
|
cmpi 0,ML2,0 # if(ml == 0) return(0);
|
|
beq BS4
|
|
mtctr ML2 # ctr = ml;
|
|
BS3: l X1,4(MM1) # X = mm[1];
|
|
si X2,X1,1 # Y= X-1;
|
|
stu X2,4(MM1) # *(++mm) = Y;
|
|
cmpi 0,X1,0 # if(X != 0) return(1);
|
|
bne BS5
|
|
bdn BS3 # if(--ctr > 0) goto BS3
|
|
BS4: lil RES,0 # return(0);
|
|
br
|
|
BS5: lil RES,1 # return(1);
|
|
br
|
|
|
|
.globl .BnnMultiplyDigit # BnnMultiplyDigit(pp, pl, mm, ml, d)
|
|
.set PP,CA1; .set PL,CA2; .set MM,CA3; .set ML,CA4; .set D,CA5
|
|
.set LOW,X1; .set HIGHT,X2; .set OHIGHT,X3
|
|
.BnnMultiplyDigit:
|
|
cmpi 0,D,0 # if(d == 0) return(0);
|
|
beq BMD7
|
|
BMD1: cmpi 0,D,1 # if(d != 1) goto BMD2;
|
|
bne BMD2
|
|
lil CA5,0 # return(BnnAdd(pp, pl, mm, ml, 0));
|
|
b .BnnAdd
|
|
BMD2: sf PL,ML,PL # pl -= ml;
|
|
ai MM,MM,-4 # mm--;
|
|
ai PP,PP,-4 # pp--;
|
|
cmpi 0,ML,0 # if(ml == 0) return(0);
|
|
beq BMD7
|
|
mtctr ML # ctr = ml;
|
|
lil OHIGHT,0 # OldHight = 0;
|
|
cmpi 0,D,0 # if(D < 0) goto BMD8;
|
|
blt BMD8
|
|
BMD3: lu LOW,4(MM) # Low = mm[1];
|
|
mul HIGHT,LOW,D # Hight:MQ = Low*d
|
|
cmpi 0,LOW,0 # if(Low>=0) pas de correction.
|
|
bge BMD4
|
|
a HIGHT,HIGHT,D # Correction multiplication signe'.
|
|
BMD4: mfmq LOW # Low = MQ;
|
|
a LOW,LOW,OHIGHT # Low += OldHight;
|
|
aze HIGHT,HIGHT # Hight += carry;
|
|
l OHIGHT,4(PP) # *++pp += Low;
|
|
a LOW,LOW,OHIGHT
|
|
stu LOW,4(PP)
|
|
aze OHIGHT,HIGHT # OldHight = Hight + carry;
|
|
bdn BMD3 # if(--ctr > 0) goto BMD3;
|
|
BMD40: l LOW,4(PP) # *(++pp) += OldHight;
|
|
a LOW,LOW,OHIGHT
|
|
stu LOW,4(PP)
|
|
lil LOW,0 # if(carry == 0) return(0);
|
|
aze. LOW,LOW
|
|
beq BMD7
|
|
si. PL,PL,1 # pl--;
|
|
ble BMD6 # if(pl <= 0) return(1);
|
|
mtctr PL # ctr = pl;
|
|
BMD5: l X1,4(PP) # X = pp[1];
|
|
ai. X1,X1,1 # X++;
|
|
stu X1,4(PP) # *(++pp) = X;
|
|
bne BMD7 # if(X != 0) return(0);
|
|
bdn BMD5 # if(--ctr > 0) goto BMD5;
|
|
BMD6: lil RES,1 # return(1);
|
|
br
|
|
BMD7: lil RES,0 # return(0);
|
|
br
|
|
|
|
BMD8: lu LOW,4(MM) # Low = mm[1];
|
|
mul HIGHT,LOW,D # Hight:MQ = Low*d
|
|
a HIGHT,HIGHT,LOW # Correction pour d<0...
|
|
cmpi 0,LOW,0 # if(Low>=0) pas de correction.
|
|
bge BMD9
|
|
a HIGHT,HIGHT,D # Correction multiplication signe'.
|
|
BMD9: mfmq LOW # Low = MQ;
|
|
a LOW,LOW,OHIGHT # Low += OldHight;
|
|
aze HIGHT,HIGHT # Hight += carry;
|
|
l OHIGHT,4(PP) # *pp += Low;
|
|
a LOW,LOW,OHIGHT
|
|
stu LOW,4(PP)
|
|
aze OHIGHT,HIGHT # OldHight = Hight + carry;
|
|
bdn BMD8 # if(--ctr > 0) goto BMD8;
|
|
b BMD40 # goto BMD40;
|
|
|
|
.globl .BnnDivideDigit # BnnDivideDigit(qq, nn, nl, d)
|
|
.set QQ,CA1; .set NN,CA2; .set NL,CA3; .set DD,CA4
|
|
.set SQQ,X1; .set R,CA1; .set Q,X2; .set NLOW,X2; .set DQ,X3
|
|
.set BITS,X4; .set AUX,CA3
|
|
.BnnDivideDigit:
|
|
sli X1,NL,2
|
|
a NN,NN,X1 # nn = &nn[nl];
|
|
a SQQ,QQ,X1 # qq = &qq[nl];
|
|
si SQQ,SQQ,4 # qq--;
|
|
lu R,-4(NN) # R = *(--nn);
|
|
si. NL,NL,1 # nl--;
|
|
bler # if(nl <= 0) return(R);
|
|
mtctr NL # ctr = nl;
|
|
sri DQ,DD,1 # D'= D / 2;
|
|
cmpi 0,DD,0 # if(D<0) goto BDDinf;
|
|
blt BDDinf
|
|
# D > 0
|
|
BDDsup: lu NLOW,-4(NN) # Low = *(--nn);
|
|
cmpl 0,R,DQ # if (R < D') goto BDDsupinf;
|
|
blt BDDsupinf
|
|
andil. BITS,NLOW,1 # bits = Low & 1;
|
|
sri NLOW,NLOW,1 # Low >>= 1;
|
|
andil. AUX,R,1 # aux = R & 1;
|
|
sri R,R,1 # R >>= 1;
|
|
sli AUX,AUX,31 # Low |= aux << 31;
|
|
or NLOW,NLOW,AUX
|
|
mtmq NLOW # MQ = Low;
|
|
div Q,R,DD # Q=R:MQ/D; MQ=R:MQ%D;
|
|
mfmq R # R=MQ;
|
|
sli R,R,1 # R <<= 1;
|
|
sli Q,Q,1 # Q <<= 1;
|
|
a R,R,BITS # R+=bits;
|
|
cmpl 0,R,DD # si R<D => ok
|
|
blt BDDsup1
|
|
ai Q,Q,1 # Q++;
|
|
sf R,DD,R # R-=D;
|
|
BDDsup1: stu Q,-4(SQQ) # *(--qq)=Q;
|
|
bdn BDDsup # if(--ctr > 0) goto BDDsup;
|
|
br # return(R);
|
|
BDDsupinf: mtmq NLOW # MQ = XL;
|
|
div Q,R,DD # Q=R:MQ/D; MQ=R:MQ%D;
|
|
mfmq R # R=MQ;
|
|
stu Q,-4(SQQ) # *(--qq)=Q;
|
|
bdn BDDsup # if(--ctr > 0) goto BDDsup;
|
|
br # return(R);
|
|
|
|
# D < 0
|
|
BDDinf: lu NLOW,-4(NN) # Low = *(--nn);
|
|
andil. BITS,NLOW,7 # bits = Low & 7;
|
|
sri NLOW,NLOW,3 # Low >>= 3;
|
|
andil. AUX,R,7 # aux = R & 7;
|
|
sri R,R,3 # R >>= 3;
|
|
sli AUX,AUX,29 # Low |= aux << 29;
|
|
or NLOW,NLOW,AUX
|
|
mtmq NLOW # MQ = Low;
|
|
div Q,R,DQ # Q=R:MQ/D'; MQ=R:MQ%D';
|
|
mfmq R # R=MQ
|
|
sli R,R,1 # R *= 2;
|
|
andil. AUX,DD,1 # if((D & 1) == 0) rien a retrancher;
|
|
cmpli 0,AUX,0
|
|
beq BDDi4
|
|
# R <- R - Q
|
|
cmpl 0,R,Q # On teste avant de faire la diff.
|
|
blt BDDi3 # la diff est < 0
|
|
sf R,Q,R # la diff est > 0
|
|
b BDDi4
|
|
BDDi3: sf R,Q,R # On met a` jour
|
|
si Q,Q,1 # Q--;
|
|
a R,R,DD # R += D;
|
|
# R <- 2R; Q <- 2Q;
|
|
BDDi4: cmpl 0,R,DQ # On teste avant de faire la mult.
|
|
blt BDDi41 # Ca va passer..
|
|
bne BDDi40 # Ca va casser...
|
|
cmpli 0,AUX,0 # d0 = 1 ca passe...
|
|
bne BDDi41
|
|
BDDi40: sli Q,Q,1 # Q *= 2;
|
|
sli R,R,1 # R *= 2;
|
|
ai Q,Q,1 # Q++;
|
|
sf R,DD,R # R -= D;
|
|
b BDDi5
|
|
BDDi41: sli Q,Q,1 # Q *= 2;
|
|
sli R,R,1 # R *= 2;
|
|
# R <- 2R; Q <- 2Q;
|
|
BDDi5: cmpl 0,R,DQ # On teste avant de faire la mult.
|
|
blt BDDi51 # Ca va passer..
|
|
bne BDDi50 # Ca va casser...
|
|
cmpli 0,AUX,0 # d0 = 1 ca passe...
|
|
bne BDDi51
|
|
BDDi50: sli Q,Q,1 # Q *= 2;
|
|
sli R,R,1 # R *= 2;
|
|
ai Q,Q,1 # Q++;
|
|
sf R,DD,R # R -= D;
|
|
b BDDi6
|
|
BDDi51: sli Q,Q,1 # Q *= 2;
|
|
sli R,R,1 # R *= 2;
|
|
# R += bits;
|
|
BDDi6: sf AUX,BITS,DD # pour tester sans de'bordement..
|
|
cmpl 0,R,AUX
|
|
blt BDDi61 # Ca va passer..
|
|
ai Q,Q,1 # Q++;
|
|
sf R,DD,R # R -= D;
|
|
BDDi61: a R,R,BITS # R += bits;
|
|
stu Q,-4(SQQ) # *(--qq)=Q;
|
|
bdn BDDinf # if(--ctr > 0) goto BDDinf;
|
|
br
|