From 9925112da98bdbc8a22a49c21304797383650ff6 Mon Sep 17 00:00:00 2001 From: biouman <> Date: Sun, 20 May 2001 00:38:11 +0000 Subject: *** empty log message *** --- lib/alu.c | 866 ++++++++++++++++++++------------------------------------------ 1 file changed, 278 insertions(+), 588 deletions(-) (limited to 'lib/alu.c') diff --git a/lib/alu.c b/lib/alu.c index 0b4525a..bde852d 100644 --- a/lib/alu.c +++ b/lib/alu.c @@ -2,6 +2,7 @@ #include "config.h" #include "exceptions.h" #include "registre.h" +#include "interne.h" /*****************************************/ /** **/ @@ -275,625 +276,314 @@ Uint32 RSHR(Uint32 a) /* ALU normale (binaire) */ - /*On compte de 0 à 31 */ - /*Return la valeur du ieme bit en position 0 */ -Uint32 ValeurIbitsAuDeb(Uint32 nb, int i) -{ - Uint32 val, un = 1; - - if ((i > 31) || (i < 0)) { - exception(1, _("ValeurIbitsAuDeb: position not in interval")); - } - val = nb >> i; - val = val & un; - return (val); +/* Renvoie un couple de bits */ +chars CreerChars(char x, char y) { + chars z; + z.st = x; + z.nd = y; + return (z); } - - /*Return la valeur du ieme bit en sa position d origine */ -/* -Uint32 ValeurIbit(Uint32 nb, int i) { - Uint32 val = 0, un = 1; - - if ((i > 31) || (i < 0)) { - fprintf(stderr, "erreur, ValeurIbit: la position demande n est pas dans l'intervalle"); - return (0); - } - val = un << i; - val = AndBit(un, nb); - return (val); +/* Additionne deux bits avec retenue */ +chars AddBit(char a, char b, char re) { + return CreerChars(Xor(re, Xor(a, b)), Or(And(a, b), And(re, Xor(a,b)))); } -*/ - - /*Met a vrai le ieme bit */ -Uint32 MettreAVIbit(Uint32 nb, int i) -{ - Uint32 val = 1; - return (nb | (val << i)); +/* Soustrait deux bits avec retenue */ +chars SubBit(char a, char b, char re) { + char c = Or(And(re, Or(And(Not(a), Not(b)), And(a, b))), And(Not(re), Xor(a, b))); + char d = Or(And(Not(a), Or(re, b)), And(re, b)); + return CreerChars(c,d); } - - /* Met a Vrai le Uint32 */ -Uint32 MetAVUint32(void) -{ +Uint32 NOT(Uint32 a) { int i; - - Uint32 val = 0, un = 1; - - for (i = 0; i <= 31; i++) { - val = (val | un); - un <<= 1; - } - return (val); -} - - - /* Met a Faux le Uint32 */ -Uint32 MetAFUint32(void) -{ - return (0); -} - - - /* Inverse la valeur du i eme bit */ -Uint32 InverseIbit(Uint32 nb, int i) -{ - Uint32 un = 1; - - if ((i > 31) || (i < 0)) { - exception(1, _("InverseIbit: position not in interval")); - } - un = (un << i); - return (nb ^ un); + Uint32 s = ZERO(); + for (i = 0; i < 32; i++) + AffecteBit(&s, Not((char) ValeurBit(a, i)), i); + return (s); } +Uint32 OPP(Uint32 a) { return (ADD_UU(NOT(a), ONE())); } - /* Inverse le Uint32 */ -Uint32 InverseUint32(Uint32 x) -{ +Uint32 Decalage(Uint32 a, char c) { int i; - - Uint32 val = x; - - for (i = 0; i <= 31; i++) { - val = InverseIbit(val, i); - } - return (val); -} - -Uint32 NAND(Uint32 x, Uint32 y) -{ - Uint32 m = 1, z = 0; + Uint32 resultat; + AffecteBit(&resultat, And(c, (char) ValeurBit(a, 30)), 31); + for (i = 1; i < 31; i++) + AffecteBit(&resultat, Or(And(Not(c), (char) ValeurBit(a, i + 1)), And(c, (char) ValeurBit(a, i - 1))), i); + AffecteBit(&resultat, And(Not(c), (char) ValeurBit(a, 1)), 0); + return (resultat); +} + +Uint32 NSHR(Uint32 a) { return (Decalage(a, 0)); } + +Uint32 NSHL(Uint32 a) { return (Decalage(a, 1)); } + +/* Soustrait deux mots signés */ +Uint32 SUB_SS(Uint32 a, Uint32 b) { + Uint32 resultat; + if (!Neg(a) && !Neg(b)) { + resultat = SUB_UU(a, b); + ResetOverflow(); + } + else if (!Neg(a) && Neg(b)) { + resultat = ADD_SS(a, OPP(b)); + } + else if (Neg(a) && !Neg(b)) { + resultat = OPP(ADD_SS(OPP(a), b)); + if (Not((char) ValeurBit(resultat, 31))) + SetOverflow(); + else + ResetOverflow(); + } + else + resultat = SUB_SS(OPP(b), OPP(a)); + return resultat; +} + +/* Additionne deux mots signés */ +Uint32 ADD_SS(Uint32 a, Uint32 b) { + Uint32 resultat; + if (!Neg(a) && !Neg(b)) { + resultat = ADD_UU(a, b); + if (ValeurBit(resultat, 31)) + SetOverflow(); + else + ResetOverflow(); + } + else if (!Neg(a) && Neg(b)) { + resultat = SUB_UU(a, OPP(b)); + ResetOverflow(); + } + else if (Neg(a) && !Neg(b)) { + resultat = SUB_UU(b, OPP(a)); + ResetOverflow(); + } + else { + resultat = (OPP(ADD_SS(OPP(a), OPP(b)))); + if (Not((char) ValeurBit(resultat, 31))) + SetOverflow(); + else + ResetOverflow(); + } + return resultat; +} + +/* Additionne deux mots non signés */ +Uint32 ADD_UU(Uint32 a, Uint32 b) { int i; - + Uint32 s = ZERO(); + chars aux = CreerChars(0, 0); for (i = 0; i < 32; i++) { - z |= (x & m) & (y & m); - m <<= 1; + aux = AddBit((char) ValeurBit(a, i), (char) ValeurBit(b, i), aux.nd); + AffecteBit(&s, aux.st, i); } - return (z); + if ((aux.nd == 0) ? 0 : 1) + SetOverflow(); + else + ResetOverflow(); + return (s); } -Uint32 NOR(Uint32 x, Uint32 y) -{ - Uint32 m = 1, z = 0; +/* Soustrait deux mots non signés */ +Uint32 SUB_UU(Uint32 a, Uint32 b) { int i; - + Uint32 s = ZERO(); + chars aux = CreerChars(0, 0); for (i = 0; i < 32; i++) { - z |= (x & m) | (y & m); - m <<= 1; - } - return (z); -} + aux = SubBit((char) ValeurBit(a, i), (char) ValeurBit(b, i), aux.nd); + AffecteBit(&s, aux.st, i); + } + if ((aux.nd == 0) ? 0 : 1) + SetOverflow(); + else + ResetOverflow(); + return (s); +} + +Uint32 MUL_UU(Uint32 a, Uint32 b) { + int i, j, k; + Uint32 c; + Uint32 retenue = ZERO(); + Uint32 u = ZERO(); + Uint32 v = ZERO(); + for (k = 0; k < 64; k++) { + c = ZERO(); + for (i = 0; i < 32; i++) + for (j = 0; j < 32; j++) + if (i + j == k) + c = ADD_UU(c, And((char) ValeurBit(a, i), (char) ValeurBit(b, j))); + c = ADD_UU(c, retenue); + retenue = SHR(c); + c = ValeurBit(c, 0); + if (k < 32) + AffecteBit(&u, (char) c, k); + else + AffecteBit(&v, (char) c, k - 32); + } + + + if (OrWord(v)) + SetOverflow(); + else + ResetOverflow(); + SecondResult=u; + return (v); +} + +Uint32 MUL_SS(Uint32 a, Uint32 b) { + Uint32 RegistreRG=0, RegistreRD=0; + if (!Neg(a) && !Neg(b)) { + RegistreRG=MUL_UU(a, b); + RegistreRD=SecondResult; + if (Or((char) Overflow(), (char) ValeurBit(RegistreRD, 31))) + SetOverflow(); + else + ResetOverflow(); + + } + if (!Neg(a) && Neg(b)) { + RegistreRG=MUL_UU(a, OPP(b)); + RegistreRD=SecondResult; + RegistreRD = OPP(RegistreRD); + if (Or((char) Overflow(), Not((char) ValeurBit(RegistreRD, 31)))) + SetOverflow(); + else + ResetOverflow(); + + } + if (Neg(a) && !Neg(b)) { + RegistreRG=MUL_UU(OPP(a), b); + RegistreRD=SecondResult; + RegistreRD = OPP(RegistreRD); + if (Or((char) Overflow(), Not((char) ValeurBit(RegistreRD, 31)))) + SetOverflow(); + else + ResetOverflow(); + + } + if (Neg(a) && Neg(b)) { + RegistreRG=MUL_UU(OPP(a), OPP(b)); + RegistreRD=SecondResult; + if (Or((char) Overflow(), (char) ValeurBit(RegistreRD, 31))) + SetOverflow(); + else + ResetOverflow(); + } + SecondResult=RegistreRD; + return (RegistreRG); +} + +Uint32 DivMod_UU(Uint32 a, Uint32 b) { + Uint32 div = ZERO(); + if (OrWord(b) == 0) + SetOverflow(); + else { + ResetOverflow(); + while (ValeurBit(SUB_UU(a, b), 31) == 0) { + a = SUB_UU(a, b); + div = ADD_UU(div, ONE()); + } + } + SecondResult = a; + return (div); +} + +Uint32 DivMod_SS(Uint32 a, Uint32 b) { + Uint32 RegistreRG=0, RegistreRD=0; + if (!Neg(a) && !Neg(b)) + RegistreRG = DivMod_UU(a, b); + RegistreRD = SecondResult; + if (!Neg(a) && Neg(b)) { + RegistreRG = DivMod_UU(a, OPP(b)); + RegistreRD = SecondResult; + RegistreRG = OPP(RegistreRG); + } + if (Neg(a) && !Neg(b)) { + RegistreRG = DivMod_UU(OPP(a), b); + RegistreRD = SecondResult; + RegistreRD = OPP(RegistreRD); + RegistreRG = OPP(RegistreRG); + } + if (Neg(a) && Neg(b)) { + RegistreRG = DivMod_UU(OPP(a), OPP(b)); + RegistreRD = SecondResult; + RegistreRD = OPP(RegistreRD); + } + SecondResult = RegistreRD; + return (RegistreRG); +} + + +Uint32 NAND(Uint32 x, Uint32 y) +{ + Uint32 m = 1, z = 0; + int i; + + for (i = 0; i < 32; i++) { + z |= (x & m) & (y & m); + m <<= 1; + } + return (z); +} + +Uint32 NOR(Uint32 x, Uint32 y) +{ + Uint32 m = 1, z = 0; + int i; + + for (i = 0; i < 32; i++) { + z |= (x & m) | (y & m); + m <<= 1; + } + return (z); +} + + +Uint32 NAdditionNonSigne(Uint32 a, Uint32 b) +{ + return ADD_UU(a,b); +} + +Uint32 NAdditionSigne(Uint32 a, Uint32 b) +{ + return ADD_SS(a,b); +} + +Uint32 NSoustractionNonSigne(Uint32 a, Uint32 b) +{ + return SUB_UU(a,b); +} + +Uint32 NSoustractionSigne(Uint32 a, Uint32 b) +{ + return ADD_SS(a,b); +} -Uint32 NSHLi(Uint32 x, int i) -{ - return (x << i); -} - -Uint32 NSHRi(Uint32 x, int i) -{ - return (x >> i); -} - -Uint32 NSHL(Uint32 x) -{ - return NSHLi(x, 1); -} - -Uint32 NSHR(Uint32 x) -{ - return NSHRi(x, 1); -} - -Uint32 NAdditionNonSigne(Uint32 x, Uint32 y) -{ - int i; - - Uint32 a, b, tp, add = 0, ret = 0; - - if (x == 0) - return (y); - if (y == 0) - return (x); - for (i = 0; i < 32; i++) { - a = ValeurIbitsAuDeb(x, i); - b = ValeurIbitsAuDeb(y, i); - tp = a + b + ret; - if (tp == 3) { - ret = 1; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - if (tp == 2) { - ret = 1; - tp = 0; - tp <<= i; - add |= tp; - } - - else { - if (tp == 1) { - ret = 0; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - ret = 0; - } - } - } - if (i == 31) { - if (ret == 1) { - errRet = 1; - } - } - } - return (add); -} - -Uint32 NAdditionSigne(Uint32 x, Uint32 y) -{ - int i; - - Uint32 a, b, tp, add = 0, ret = 0; - - if (x == 0) - return (y); - if (y == 0) - return (x); - for (i = 0; i < 32; i++) { - a = ValeurIbitsAuDeb(x, i); - b = ValeurIbitsAuDeb(y, i); - tp = a + b + ret; - if (tp == 3) { - ret = 1; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - if (tp == 2) { - ret = 1; - tp = 0; - tp <<= i; - add |= tp; - } - - else { - if (tp == 1) { - ret = 0; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - ret = 0; - } - } - } - if (i == 30) { - if (ret == 1) { - errRet = 1; - } - } - } - return (add); -} - -Uint32 NSoustractionNonSigne(Uint32 x, Uint32 y) -{ /* x - y */ - int i; - - Uint32 a, b, tp, sou = 0, ret = 0; - - for (i = 0; i < 32; i++) { - a = ValeurIbitsAuDeb(x, i); - b = ValeurIbitsAuDeb(y, i); - if (((a == 0) && (b == 0) && (ret == 0)) - || ((a == 1) && (b == 1) && (ret == 0)) || ((a == 1) - && (b == 0) - && (ret == 1))) { - ret = 0; - tp = 0; - tp <<= i; - sou |= tp; - } - - else { - if (((a == 0) && (b == 0) && (ret == 1)) - || ((a == 0) && (b == 1) && (ret == 0)) || ((a == 1) - && (b == 1) - && (ret == 1))) { - ret = 1; - tp = 1; - tp <<= i; - sou |= tp; - } - - else { - if ((a == 1) && (b == 0) && (ret == 0) || 0) { - ret = 0; - tp = 1; - tp <<= i; - sou |= tp; - } - - else { - ret = 1; - tp = 0; - tp <<= i; - sou |= tp; - } - } - } - if (i == 31) { - if (ret == 1) { - errRet = 1; - } - } - } - return (sou); -} - -Uint32 NSoustractionSigne(Uint32 x, Uint32 y) -{ /* x - y */ - int i; - - Uint32 a, b, tp, sou = 0, ret = 0; - - for (i = 0; i < 32; i++) { - a = ValeurIbitsAuDeb(x, i); - b = ValeurIbitsAuDeb(y, i); - if (((a == 0) && (b == 0) && (ret == 0)) - || ((a == 1) && (b == 1) && (ret == 0)) || ((a == 1) - && (b == 0) - && (ret == 1))) { - ret = 0; - tp = 0; - tp <<= i; - sou |= tp; - } - - else { - if (((a == 0) && (b == 0) && (ret == 1)) - || ((a == 0) && (b == 1) && (ret == 0)) || ((a == 1) - && (b == 1) - && (ret == 1))) { - ret = 1; - tp = 1; - tp <<= i; - sou |= tp; - } - - else { - if ((a == 1) && (b == 0) && (ret == 0) || 0) { - ret = 0; - tp = 1; - tp <<= i; - sou |= tp; - } - - else { - ret = 1; - tp = 0; - tp <<= i; - sou |= tp; - } - } - } - if (i == 30) { - if (ret == 1) { - errRet = 1; - } - } - } - return (sou); -} - -couple Addition(Uint32 x, Uint32 y) -{ /* Renvoye le resultat + eventuellement une retenue */ - int i; - - couple z; - Uint32 a, b, tp, add = 0, ret = 0; - - for (i = 0; i < 32; i++) { - a = ValeurIbitsAuDeb(x, i); - b = ValeurIbitsAuDeb(y, i); - tp = a + b + ret; - if (tp == 3) { - ret = 1; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - if (tp == 2) { - ret = 1; - tp = 0; - tp <<= i; - add |= tp; - } - - else { - if (tp == 1) { - ret = 0; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - ret = 0; - } - } - } - if (i == 31) { - if (ret == 1) { - z.deb = add; - z.fin = 1; - return (z); - } - } - } - z.deb = add; - z.fin = 0; - return (z); -} - -couple Add30Mul(Uint32 x, Uint32 y) -{ - int i; - - couple z; - Uint32 a, b, tp, add = 0, ret = 0; - - for (i = 0; i < 31; i++) { - a = ValeurIbitsAuDeb(x, i); - b = ValeurIbitsAuDeb(y, i); - tp = a + b + ret; - if (tp == 3) { - ret = 1; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - if (tp == 2) { - ret = 1; - tp = 0; - tp <<= i; - add |= tp; - } - - else { - if (tp == 1) { - ret = 0; - tp = 1; - tp <<= i; - add |= tp; - } - - else { - ret = 0; - } - } - } - if (i == 30) { - if (ret == 1) { - z.deb = add; - z.fin = 1; - return (z); - } - } - } - z.deb = add; - z.fin = 0; - return (z); -} - -Uint32 MultChifNomb(Uint32 x, Uint32 y) -{ - int i; - - Uint32 mul = 0, a, un = 1; - - if (y == 0) - return (0); - if (x == 0) - return (0); - if (y == 1) - return (x); - for (i = 0; i < 32; i++) { - a = ValeurIbitsAuDeb(x, i); - if (a == 1) { - un <<= i; - mul |= un; - } - } - return (mul); -} - -couple MultipliNonSig(Uint32 x, Uint32 y) +Uint32 NMultiplicationNonSigne(Uint32 a, Uint32 b) { - couple z, w; - int i; - - Uint32 tp, dec, add, a, pa1 = 0, pa2 = 0; - - for (i = 0; i < 32; i++) { - a = ValeurIbitsAuDeb(y, i); - tp = MultChifNomb(x, a); - dec = (tp >> (32 - i)); - pa2 = NAdditionNonSigne(pa2, dec); - add = tp << i; - z = Addition(pa1, add); - pa1 = z.deb; - if (z.fin == 1) { - w = Addition(pa2, 1); - pa2 = w.deb; - } - } - z.deb = pa1; - z.fin = pa2; - - printf("\n"); - return (z); -} + return MUL_UU(a,b); +} -couple MultipliSig(Uint32 x, Uint32 y) +Uint32 NMultiplicationSigne(Uint32 a, Uint32 b) { - couple z, w; - int i; - - Uint32 tp, dec, add, a, b, pa1 = 0, pa2 = 0, x1 = x, y1 = y; - - a = ValeurIbitsAuDeb(x, 31); - b = ValeurIbitsAuDeb(y, 31); - if (((a == 0) && (b == 0)) || ((a == 1) && (b == 1))) { /* Le resultat sera pos */ - if ((a == 1) && (b == 1)) { - x1 = InverseIbit(x, 31); - y1 = InverseIbit(y, 31); - } - for (i = 0; i < 31; i++) { - a = ValeurIbitsAuDeb(y1, i); - tp = MultChifNomb(x1, a); - dec = tp >> (31 - i); - w = Addition(pa2, dec); - pa2 = w.deb; - add = tp << i; - z = Add30Mul(pa1, add); - pa1 = z.deb; - if (z.fin == 1) { - w = Addition(pa2, 1); - pa2 = w.deb; - } - } - z.deb = pa1; - z.fin = pa2; - return (z); - } - if (a == 1) - x1 = InverseIbit(x, 31); - if (b == 1) - y1 = InverseIbit(y, 31); - for (i = 0; i < 31; i++) { - a = ValeurIbitsAuDeb(y1, i); - tp = MultChifNomb(x1, a); - dec = tp >> (31 - i); - pa2 = NAdditionNonSigne(pa2, dec); - add = tp << i; - z = Add30Mul(pa1, add); - pa1 = z.deb; - if (z.fin == 1) { - pa2 = NAdditionNonSigne(pa2, 1); - } - } - pa1 = MettreAVIbit(pa1, 31); - pa2 = MettreAVIbit(pa2, 31); - z.deb = pa1; - z.fin = pa2; - return (z); -} + return MUL_SS(a,b); +} Uint32 NDivisionNonSigne(Uint32 a, Uint32 b) { - Uint32 quot, rest; + return DivMod_UU(a,b); +} - if (b > a) { - quot = 0; - rest = a; - } else { - if (b == a) { - quot = 1; - rest = 0; - } else { - quot = 0; - rest = a; - while (rest >= b) { - rest = NSoustractionNonSigne(rest, b); - quot++; - } - } - } - SecondResult = rest; - return quot; -} - -Uint32 NDivisionSigne(long int a, long int b) -{ - long int quot, rest; - - if (b > a) { - quot = 0; - rest = a; - } else { - if (b == a) { - quot = 1; - rest = 0; - } else { - quot = 0; - rest = a; - while (rest >= b) { - rest = NSoustractionNonSigne(rest, b); - quot++; - } - } - } - SecondResult = rest; - return quot; -} - -Uint32 NMultiplicationNonSigne(Uint32 a, Uint32 b) +Uint32 NDivisionSigne(Uint32 a, Uint32 b) { - couple z; + return DivMod_SS(a,b); +} - z = MultipliNonSig(a, b); - SecondResult = z.fin; - return z.deb; -} -Uint32 NMultiplicationSigne(Uint32 a, Uint32 b) -{ - couple z; - - z = MultipliNonSig(a, b); - - SecondResult = z.fin; - return z.deb; -} Uint32 AdditionNonSigne(Uint32 a, Uint32 b) { -- cgit v1.2.3