455 lines
11 KiB
ArmAsm
455 lines
11 KiB
ArmAsm
# Copyright Digital Equipment Corporation & INRIA 1988, 1989
|
|
#
|
|
# KerN for Pyramid Architecture
|
|
# Bernard Paul Serpette
|
|
#
|
|
.text 0
|
|
|
|
.globl _BnnSetToZero
|
|
_BnnSetToZero: subw $1,pr1 # nl--;
|
|
blt BSTZ2 # if(nl < 0) return;
|
|
BSTZ1: movw $0,(pr0) # *nn = 0;
|
|
addw $4,pr0 # nn++;
|
|
subw $1,pr1 # nl--;
|
|
bge BSTZ1 # if(nl >= 0) goto BSTZ1;
|
|
BSTZ2: ret # return;
|
|
|
|
.globl _BnnAssign
|
|
_BnnAssign: ucmpw pr1,pr0
|
|
bgt BAG3 # if(mm > nn) goto BAG3;
|
|
subw $1,pr2 # nl--;
|
|
bge BAG2 # if(nl >= 0) goto BAG2;
|
|
ret
|
|
BAG1: addw $4,pr0 # mm++;
|
|
addw $4,pr1 # nn++;
|
|
BAG2: movw (pr1),(pr0) # *mm = *nn;
|
|
subw $1,pr2 # nl--;
|
|
bge BAG1 # if(nl >= 0) goto BAG1;
|
|
ret
|
|
|
|
BAG3: mova (pr1)[pr2*0x4],pr1 # nn += nl;
|
|
mova (pr0)[pr2*0x4],pr0 # mm += nl;
|
|
subw $1,pr2 # nl--;
|
|
blt BAG5 # if(nl < 0) return;
|
|
BAG4: subw $4,pr0 # mm--;
|
|
subw $4,pr1 # nn--;
|
|
movw (pr1),(pr0) # *mm = *nn;
|
|
subw $1,pr2 # nl--;
|
|
bge BAG4 # if(nl >= 0) goto BAG4;
|
|
BAG5: ret
|
|
|
|
.globl _BnnSetDigit
|
|
_BnnSetDigit: movw pr1,(pr0) # *nn = d;
|
|
ret
|
|
|
|
.globl _BnnGetDigit
|
|
_BnnGetDigit: movw (pr0),pr0 # return(*nn);
|
|
ret
|
|
|
|
.globl _BnnNumDigits
|
|
_BnnNumDigits:
|
|
mova (pr0)[pr1*0x4],pr0 # nn += nl;
|
|
br BND2
|
|
BND1: subw $4,pr0 # nn--;
|
|
mtstw (pr0),pr2
|
|
bne BND3 # if(*nn) goto BND3
|
|
subw $1,pr1 # nl--;
|
|
BND2: mtstw pr1,pr2
|
|
bne BND1 # if(nl) goto BND1;
|
|
movw $1,pr0 # return(1);
|
|
ret
|
|
BND3: movw pr1,pr0 # return(nl);
|
|
ret
|
|
|
|
.globl _BnnNumLeadingZeroBitsInDigit
|
|
_BnnNumLeadingZeroBitsInDigit:
|
|
movw $0,pr1 # p = 0;
|
|
mtstw pr0,pr0
|
|
bne BLZ2 # if(!d) goto BLZ2;
|
|
movw $32,pr0 # return(32);
|
|
ret
|
|
BLZ1: addw $1,pr1 # p++;
|
|
lshlw $1,pr0 # d <<= 1;
|
|
BLZ2: mtstw pr0,pr0
|
|
bgt BLZ1 # if(d > 0) goto BLZ1;
|
|
movw pr1,pr0 # return(p);
|
|
ret
|
|
|
|
.globl _BnnDoesDigitFitInWord
|
|
_BnnDoesDigitFitInWord:
|
|
movw $1,pr0 # return(1);
|
|
ret
|
|
|
|
.globl _BnnIsDigitZero
|
|
_BnnIsDigitZero:
|
|
mtstw pr0,pr0 # set NZVC flags
|
|
mpsw pr0 # mov NZVC flags in register
|
|
andw $4,pr0 # return(Z);
|
|
ret
|
|
|
|
.globl _BnnIsDigitNormalized
|
|
_BnnIsDigitNormalized:
|
|
mtstw pr0,pr0 # set NZVC flags
|
|
mpsw pr0 # mov NZVC flags in register
|
|
andw $8,pr0 # return(N);
|
|
ret
|
|
|
|
.globl _BnnIsDigitOdd
|
|
_BnnIsDigitOdd:
|
|
andw $1,pr0 # return(d & 1);
|
|
ret
|
|
|
|
.globl _BnnCompareDigits
|
|
_BnnCompareDigits:
|
|
ucmpw pr1,pr0
|
|
bgt BCDsup
|
|
bne BCDinf
|
|
movw $0,pr0
|
|
ret
|
|
BCDinf: movw $-1,pr0
|
|
ret
|
|
BCDsup: movw $1,pr0
|
|
ret
|
|
|
|
.globl _BnnComplement
|
|
_BnnComplement:
|
|
subw $1,pr1 # nl--;
|
|
blt BCM2 # if(nl < 0) goto BCM2
|
|
BCM1: mcomw (pr0),pr2 # tmp = *nn ^ -1;
|
|
movw pr2,(pr0) # *nn = tmp;
|
|
addw $4,pr0 # nn++;
|
|
subw $1,pr1 # nl--;
|
|
bge BCM1 # if(nl >= 0) goto BCM1;
|
|
BCM2: ret
|
|
|
|
.globl _BnnAndDigits
|
|
_BnnAndDigits: andw (pr0),pr1 # d &= *nn;
|
|
movw pr1,(pr0) # *nn = d;
|
|
ret
|
|
|
|
.globl _BnnOrDigits
|
|
_BnnOrDigits: orw (pr0),pr1 # d |= *nn;
|
|
movw pr1,(pr0) # *nn = d;
|
|
ret
|
|
|
|
.globl _BnnXorDigits
|
|
_BnnXorDigits: xorw (pr0),pr1 # d ^= *nn;
|
|
movw pr1,(pr0) # *nn = d;
|
|
ret
|
|
|
|
.globl _BnnShiftLeft
|
|
_BnnShiftLeft: movw $0,lr1 # res = 0;
|
|
mtstw pr2,pr2
|
|
beq BSL2 # if(!nbi) return(res);
|
|
movw $32,lr2 # rnbi = 32;
|
|
subw pr2,lr2 # rnbi -= nbi;
|
|
subw $1,pr1 # ml--;
|
|
blt BSL2 # if(ml < 0) return(res);
|
|
BSL1: movw (pr0),lr0 # save = *mm;
|
|
movw lr0,pr3 # X = save;
|
|
lshlw pr2,pr3 # X <<= nbi;
|
|
orw lr1,pr3 # X |= res;
|
|
movw pr3,(pr0) # *mm = X;
|
|
addw $4,pr0 # mm++;
|
|
movw lr0,lr1 # res = save;
|
|
lshrw lr2,lr1 # res >>= rnbi;
|
|
subw $1,pr1 # ml--;
|
|
bge BSL1 # if(ml >= 0) goto BSL1;
|
|
BSL2: movw lr1,pr0 # return(res);
|
|
ret
|
|
|
|
.globl _BnnShiftRight
|
|
_BnnShiftRight: movw $0,lr1 # res = 0;
|
|
mtstw pr2,pr2
|
|
beq BSR2 # if(!nbi) return(res);
|
|
mova (pr0)[pr1*0x4],pr0 # mm += ml;
|
|
movw $32,lr2 # lnbi = 32;
|
|
subw pr2,lr2 # lnbi -= nbi;
|
|
subw $1,pr1 # ml--;
|
|
blt BSR2 # if(ml < 0) return(res);
|
|
BSR1: subw $4,pr0 # mm--;
|
|
movw (pr0),lr0 # save = *mm;
|
|
movw lr0,pr3 # X = save;
|
|
lshrw pr2,pr3 # X >>= nbi;
|
|
orw lr1,pr3 # X |= res;
|
|
movw pr3,(pr0) # *mm = X;
|
|
movw lr0,lr1 # res = save;
|
|
lshlw lr2,lr1 # res <<= lnbi;
|
|
subw $1,pr1 # ml--;
|
|
bge BSR1 # if(ml >= 0) goto BSR1;
|
|
BSR2: movw lr1,pr0 # return(res);
|
|
ret
|
|
|
|
.globl _BnnAddCarry
|
|
_BnnAddCarry: mtstw pr2,pr2
|
|
beq BAC3 # if(!carryin) return(0);
|
|
mtstw pr1,pr1
|
|
beq BAC2 # if(!nl) return(1);
|
|
subw $1,pr1 # nl--;
|
|
BAC1: icmpw $0,(pr0) # Z = (++(nn) == 0);
|
|
bne BAC3 # if(!Z) goto BAC3;
|
|
addw $4,pr0 # nn++;
|
|
subw $1,pr1 # nl--
|
|
bge BAC1 # if(nl >= 0) goto BAC1;
|
|
BAC2: movw $1,pr0 # return(1);
|
|
ret
|
|
BAC3: movw $0,pr0 # return(0);
|
|
ret
|
|
|
|
.globl _BnnAdd
|
|
_BnnAdd: subw pr3,pr1 # ml -= nl;
|
|
mtstw pr3,pr3
|
|
beq BADD5 # if(!nl) goto BADD5;
|
|
BADD1: subw $1,pr3 # nl--;
|
|
BADDX: movw (pr0),pr5 # X1 = *mm
|
|
bicpsw $1
|
|
bispsw pr4 # Set the carry C;
|
|
addwc (pr2),pr5 # X1 += *nn + C;
|
|
mpsw pr4
|
|
andw $1,pr4 # get the carry C;
|
|
movw pr5,(pr0) # *mm = X1;
|
|
addw $4,pr0 # mm++;
|
|
addw $4,pr2 # nn++;
|
|
subw $1,pr3 # nl--;
|
|
bge BADDX # if(nl >= 0) goto BADDX;
|
|
BADD5: mtstw pr4,pr4
|
|
bne BADD7 # if(car) goto BADD7;
|
|
BADD6: movw $0,pr0 # return(0);
|
|
ret
|
|
BADD7: mtstw pr1,pr1
|
|
beq BADD9 # if(!ml) return(1);
|
|
subw $1,pr1 # ml--;
|
|
BADD8: icmpw $0,(pr0) # Z = (++(mm) == 0);
|
|
bne BADD6 # if(!Z) goto BADD6;
|
|
addw $4,pr0 # nn++;
|
|
subw $1,pr1 # nl--
|
|
bge BADD8 # if(nl >= 0) goto BADD8;
|
|
BADD9: movw $1,pr0 # return(1);
|
|
ret
|
|
|
|
.globl _BnnSubtractBorrow
|
|
_BnnSubtractBorrow:
|
|
mtstw pr2,pr2
|
|
bne BSB3 # if(carryin) return(1);
|
|
mtstw pr1,pr1
|
|
beq BSB2 # if(!nl) return(1);
|
|
subw $1,pr1 # nl--;
|
|
BSB1: dcmpw $-1,(pr0) # Z = (--(nn) == -1);
|
|
bne BSB3 # if(!Z) goto BSB3;
|
|
addw $4,pr0 # nn++;
|
|
subw $1,pr1 # nl--
|
|
bge BSB1 # if(nl >= 0) goto BSB1;
|
|
BSB2: movw $0,pr0 # return(0);
|
|
ret
|
|
BSB3: movw $1,pr0 # return(1);
|
|
ret
|
|
|
|
|
|
.globl _BnnSubtract
|
|
_BnnSubtract: subw pr3,pr1 # ml -= nl;
|
|
mtstw pr3,pr3
|
|
beq BS5 # if(!nl) goto BS5;
|
|
BS1: subw $1,pr3 # nl--;
|
|
BSX: movw (pr0),pr5 # X1 = *mm
|
|
bicpsw $1
|
|
bispsw pr4 # Set the carry C;
|
|
subwb (pr2),pr5 # X1 -= *nn + C;
|
|
mpsw pr4
|
|
andw $1,pr4 # get the carry C;
|
|
movw pr5,(pr0) # *mm = X1;
|
|
addw $4,pr0 # mm++;
|
|
addw $4,pr2 # nn++;
|
|
subw $1,pr3 # nl--;
|
|
bge BSX # if(nl >= 0) goto BSX;
|
|
BS5: mtstw pr4,pr4
|
|
beq BS7 # if(!car) goto BS7;
|
|
BS6: movw $1,pr0 # return(1);
|
|
ret
|
|
BS7: mtstw pr1,pr1
|
|
beq BS9 # if(!ml) return(1);
|
|
subw $1,pr1 # ml--;
|
|
BS8: dcmpw $-1,(pr0) # Z = (--(mm) == -1);
|
|
bne BS6 # if(!Z) goto BS6;
|
|
addw $4,pr0 # nn++;
|
|
subw $1,pr1 # nl--
|
|
bge BS8 # if(nl >= 0) goto BS8;
|
|
BS9: movw $0,pr0 # return(0);
|
|
ret
|
|
|
|
.globl _BnnMultiplyDigit # (pp, pl, mm, ml, d)
|
|
_BnnMultiplyDigit:
|
|
mtstw pr4,pr4
|
|
bne BMD1 # if(!d) return(0);
|
|
movw $0,pr0
|
|
ret
|
|
BMD1: ucmpw $1,pr4
|
|
bne BMD2 # if(d != 1) goto BMD2;
|
|
movw $0,pr4
|
|
br _BnnAdd # BnnAdd(p,pl,m,ml,0);
|
|
BMD2: subw pr3,pr1 # pl -= ml;
|
|
movw $0,pr8 # Un zero.
|
|
movw pr8,pr7 # low = 0;
|
|
br BMD4
|
|
BMD3: subw $1,pr3 # pl--;
|
|
movw (pr2),pr6 # X = *mm;
|
|
addw $4,pr2 # mm++;
|
|
uemul pr4,pr5 # X *= d;
|
|
addw pr7,pr6 # X += low;
|
|
addwc pr8,pr5 # X(hight) += Carry;
|
|
addw (pr0),pr6 # X += *pp;
|
|
addwc pr8,pr5 # X(hight) += Carry;
|
|
movw pr6,(pr0) # *pp = X(low);
|
|
addw $4,pr0 # pp++;
|
|
movw pr5,pr7 # low = X(Hight);
|
|
BMD4: mtstw pr3,pr3
|
|
bne BMD3 # if(ml) goto BMD3;
|
|
addw (pr0),pr7 # low += *pp;
|
|
movw pr7,(pr0) # *pp = low;
|
|
bcs BMD7 # if(Carry) goto BMD7;
|
|
BMD6: movw $0,pr0 # return(0);
|
|
ret
|
|
BMD7: addw $4,pr0 # pp++;
|
|
subw $1,pr1 # pl--;
|
|
beq BMD10 # if(!pl) return(1);
|
|
subw $1,pr1 # pl--;
|
|
BMD8: icmpw $0,(pr0) # Z = (++(*pp) == 0)
|
|
bne BMD6 # if(!!Z) goto BADD6;
|
|
addw $4,pr0 # pp++;
|
|
subw $1,pr1 # pl--
|
|
bge BMD8 # if(pl >= 0) goto BADD8;
|
|
BMD10: movw $1,pr0 # return(1);
|
|
ret
|
|
|
|
# The 64 bits/32 bits unsigned division, like in Vaxes, must be simulated
|
|
#by a 64/32 signed division:
|
|
#
|
|
#N = D*Q + R
|
|
#D = 2D' + d0
|
|
#Cas 1: 0 <= D < 2^31
|
|
#------
|
|
# Sous-cas 1: N < D'*2^32 -> Calcul direct signe'
|
|
# -----------
|
|
#
|
|
# Sous-cas 2: N >= D'*2^32
|
|
# -----------
|
|
# N = 2N' + n0
|
|
# N' = DQ' + R' (0 <= R' < D)
|
|
# N = 2DQ' + 2R' + n0 (0 <= 2R' + n0 < 2D)
|
|
# Si 2R' + n0 < D
|
|
# Q = 2Q' et R = 2R' + n0
|
|
# sinon Q = 2Q' + 1 et R = 2R' + n0 - D
|
|
#
|
|
#Cas 2: 2^31 <= D < 2^32
|
|
#------
|
|
# N = 8N' + 4n2 + 2n1 + n0
|
|
# N' = D'Q' + R' (0 <= R' <= D' - 1)
|
|
# N = 8D'Q' + 8R' + 4n2 + 2n1 + n0
|
|
# N = 4DQ' + 8R' + 4n2 + 2n1 + n0 - 4Q'd0
|
|
# N = 4DQ' + 2(2(2R' + n2 - Q'd0) + n1) + n0 (0 <= 2R' + n2 < D)
|
|
# Q' < 2^31 <= D
|
|
# -D <= R1 = 2R' + n2 - Q'd0 < D
|
|
# Si d0 = 1 et -D < R1 < 0
|
|
# Q1 = Q' - 1; R1 = R1 + D
|
|
# N = 4Q1D + 2(2R1 + n1) + n0
|
|
# Q0 = 2Q1; R0 = 2R1 + n1
|
|
# Si R2 >= D
|
|
# Q0 = Q0 + 1; R2 = R2 - D
|
|
# N = 2Q0 + 2R0 + n0
|
|
# Q = 2Q0; R = 2R0 + n0
|
|
# Si R >= d
|
|
# Q = Q + 1; R = R - D
|
|
.globl _BnnDivideDigit # (qq, nn, nl, d)
|
|
_BnnDivideDigit:
|
|
subw $1,pr2 # nl--;
|
|
mova (pr1)[pr2*0x4],pr1 # nn += nl;
|
|
mova (pr0)[pr2*0x4],pr0 # qq += nl;
|
|
movw (pr1),pr4 # N(Hight) = *nn;
|
|
movw pr3,pr6
|
|
lshrw $1,pr6 # D' = D >> 1;
|
|
mtstw pr3,pr3
|
|
bge BDD2
|
|
movw pr3,lr5
|
|
andw $1,lr5
|
|
movw $1,lr6 # lr6 <- 0x1FFFFFFF
|
|
lshlw $29,lr6 # pour le
|
|
subw $1,lr6 # shift arithme'tique
|
|
br BDD5
|
|
BDD1: subw $4,pr1 # nn--;
|
|
movw (pr1),pr5 # N(low) = *nn;
|
|
ucmpw pr6,pr4
|
|
blt BDD11 # if(N < D'*2^32) goto BDD11;
|
|
movw pr5,lr0
|
|
andw $1,lr0 # n0 = N & 1;
|
|
ashrl $1,pr4 # N = N' = N / 2;
|
|
ediv pr3,pr4 # Q = N' / D
|
|
# R = N' % D
|
|
lshlw $1,pr4 # Q = 2Q
|
|
lshlw $1,pr5 # R = 2R;
|
|
addw lr0,pr5 # R = R + n0
|
|
ucmpw pr3,pr5
|
|
blt BDD12 # if(R < D) goto BDD12;
|
|
addw $1,pr4 # Q = Q + 1;
|
|
subw pr3,pr5 # R = R - D;
|
|
br BDD12 # goto BDD12
|
|
BDD11: ediv pr3,pr4 # N(Hight) = N / d;
|
|
# N(low) = N % d;
|
|
BDD12: subw $4,pr0 # qq--;
|
|
movw pr4,(pr0) # *qq = X(low);
|
|
movw pr5,pr4
|
|
BDD2: subw $1,pr2
|
|
bge BDD1
|
|
movw pr4,pr0
|
|
ret
|
|
|
|
BDD3: subw $4,pr1 # nn--;
|
|
movw (pr1),pr5 # N(low) = *nn;
|
|
movw pr5,lr0
|
|
andw $1,lr0 # lr0 = n0 = N & 1;
|
|
movw pr5,lr1
|
|
andw $2,lr1 # lr1 = 2n1 = N & 2;
|
|
movw pr5,lr2
|
|
andw $4,lr2 # lr2 = 4n2 = N & 4;
|
|
ashrl $3,pr4 # N = N' = N / 8;
|
|
andw lr6,pr4 # shift arithme'tique!!
|
|
ediv pr6,pr4 # Q' = N' / D';
|
|
# R' = N' % D';
|
|
addw pr5,pr5 # R1 = 2 * R'; Q1 = Q';
|
|
mtstw lr5,lr5
|
|
beq BDD33 # if(d0 == 0) goto BDD33;
|
|
ucmpw pr4,pr5
|
|
bge BDD32 # if(R1 >= Q') goto BDD32;
|
|
subw pr4,pr5 # R1 = R1 - Q'
|
|
subw $1,pr4 # Q1 = Q1 - 1;
|
|
addw pr3,pr5 # R1 = R1 + D;
|
|
br BDD33
|
|
BDD32: subw pr4,pr5 # R1 = R1 - Q'
|
|
BDD33: addw pr4,pr4 # Q0 = 2 * Q1;
|
|
addw pr5,pr5 # R0 = 2 * R1;
|
|
bcs BDD4
|
|
ucmpw pr3,pr5
|
|
blt BDD40 # if(R0 < D) goto BDD40;
|
|
BDD4: addw $1,pr4 # Q0 = Q0 + 1;
|
|
subw pr3,pr5 # R0 = R0 - D
|
|
BDD40: addw pr4,pr4 # Q = 2 * Q0;
|
|
addw pr5,pr5 # R = 2 * R0;
|
|
bcs BDD41
|
|
ucmpw pr3,pr5
|
|
blt BDD42 # if(R < D) goto BDD42;
|
|
BDD41: addw $1,pr4 # Q = Q + 1;
|
|
subw pr3,pr5 # R = R - D;
|
|
BDD42: addw lr2,pr5
|
|
addw lr1,pr5
|
|
addw lr0,pr5 # R = R + lr2 + lr1 + lr0;
|
|
ucmpw pr3,pr5
|
|
blt BDD43 # if(R < D) goto BDD43
|
|
addw $1,pr4 # Q = Q + 1;
|
|
subw pr3,pr5 # R = R - D;
|
|
BDD43: subw $4,pr0 # qq--;
|
|
movw pr4,(pr0) # *qq = X(low);
|
|
movw pr5,pr4
|
|
BDD5: subw $1,pr2
|
|
bge BDD3
|
|
movw pr4,pr0
|
|
ret
|
|
|