#include "alu.h" #include "config.h" #include "exceptions.h" #include "registre.h" /*****************************************/ /** **/ /** GESTION DE L'UNITE DE CALCUL **/ /** **/ /*****************************************/ int errRet = 0, Rapide = 0; Uint32 SecondResult = 0; /* ALU rapide */ Uint32 RNot(Uint32 a) { return (~a) + 1; } Uint32 RAdditionNonSigne(Uint32 a, Uint32 b) { unsigned long long tr = a, masq = 1; tr += b; masq <<= 32; if (masq & tr) { SetOverflow(); } else { ResetOverflow(); } if (tr) { ResetZero(); } else { SetZero(); } if (tr & 1) { SetParity(); } else { ResetParity(); } ResetSign(); return tr; } Uint32 RAdditionSigne(long int a, long int b) { long int tr = a; tr += b; if (((a & 0x80000000) && (b & 0x80000000) && !(tr & 0x80000000)) || (!(a & 0x80000000) && !(b & 0x80000000) && (tr & 0x80000000))) { SetOverflow(); } else { ResetOverflow(); } if (tr) { ResetZero(); } else { SetZero(); } if (tr & 1) { SetParity(); } else { ResetParity(); } if (tr & 0x80000000) { SetSign(); } else { ResetSign(); } return tr; } Uint32 RSoustractionNonSigne(Uint32 a, Uint32 b) { return RAdditionNonSigne(a, RNot(b)); } Uint32 RSoustractionSigne(Uint32 a, Uint32 b) { return RAdditionSigne(a, RNot(b)); } Uint32 RMultiplicationNonSigne(Uint32 a, Uint32 b) { unsigned long long temp = a; temp *= b; SecondResult = temp >> 32; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } ResetOverflow(); ResetSign(); return (temp); } Uint32 RMultiplicationSigne(long int a, long int b) { long long temp = a; temp *= b; SecondResult = temp >> 32; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } if (temp & 0x80000000) { SetSign(); } else { ResetSign(); } ResetOverflow(); return (temp); } Uint32 RDivisionNonSigne(Uint32 a, Uint32 b) { unsigned long long temp = a; temp /= b; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } ResetOverflow(); ResetSign(); SecondResult = a % b; return temp; } Uint32 RDivisionSigne(long int a, long int b) { long long temp = a; temp /= b; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } if (temp & 0x80000000) { SetSign(); } else { ResetSign(); } ResetOverflow(); SecondResult = a % b; return temp; } Uint32 RAND(Uint32 a, Uint32 b) { Uint32 temp = a & b; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } if (temp & 0x80000000) { SetSign(); } else { ResetSign(); } return temp; } Uint32 ROR(Uint32 a, Uint32 b) { Uint32 temp = a | b; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } if (temp & 0x80000000) { SetSign(); } else { ResetSign(); } return temp; } Uint32 RSHL(Uint32 a) { Uint32 temp = a << 1; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } if (temp & 0x80000000) { SetSign(); } else { ResetSign(); } return temp; } Uint32 RSHR(Uint32 a) { Uint32 temp = a >> 1; if (temp & 1) { SetParity(); } else { ResetParity(); } if (temp) { ResetZero(); } else { SetZero(); } if (temp & 0x80000000) { SetSign(); } else { ResetSign(); } return temp; } /* 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); } /*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); } */ /*Met a vrai le ieme bit */ Uint32 MettreAVIbit(Uint32 nb, int i) { Uint32 val = 1; return (nb | (val << i)); } /* Met a Vrai le Uint32 */ Uint32 MetAVUint32(void) { 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); } /* Inverse le Uint32 */ Uint32 InverseUint32(Uint32 x) { 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; 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 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) { 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); } couple MultipliSig(Uint32 x, Uint32 y) { 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); } Uint32 NDivisionNonSigne(Uint32 a, Uint32 b) { Uint32 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 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) { couple z; 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) { if (Rapide) { return RAdditionNonSigne(a, b); } else { return NAdditionNonSigne(a, b); } } Uint32 AdditionSigne(Uint32 a, Uint32 b) { if (Rapide) { return RAdditionSigne(a, b); } else { return NAdditionSigne(a, b); } } Uint32 SoustractionNonSigne(Uint32 a, Uint32 b) { if (Rapide) { return RSoustractionNonSigne(a, b); } else { return NSoustractionNonSigne(a, b); } } Uint32 SoustractionSigne(Uint32 a, Uint32 b) { if (Rapide) { return RSoustractionSigne(a, b); } else { return NSoustractionSigne(a, b); } } Uint32 MultiplicationNonSigne(Uint32 a, Uint32 b) { if (Rapide) { return RMultiplicationNonSigne(a, b); } else { return NMultiplicationNonSigne(a, b); } } Uint32 MultiplicationSigne(Uint32 a, Uint32 b) { if (Rapide) { return RMultiplicationSigne(a, b); } else { return NMultiplicationSigne(a, b); } } Uint32 DivisionNonSigne(Uint32 a, Uint32 b) { if (Rapide) { return RDivisionNonSigne(a, b); } else { return NDivisionNonSigne(a, b); } } Uint32 DivisionSigne(Uint32 a, Uint32 b) { if (Rapide) { return RDivisionSigne(a, b); } else { return NDivisionSigne(a, b); } } Uint32 AND(Uint32 a, Uint32 b) { if (Rapide) { return RAND(a, b); } else { return NAND(a, b); } } Uint32 OR(Uint32 a, Uint32 b) { if (Rapide) { return ROR(a, b); } else { return NOR(a, b); } } Uint32 SHL(Uint32 a) { if (Rapide) { return RSHL(a); } else { return NSHL(a); } } Uint32 SHR(Uint32 a) { if (Rapide) { return RSHR(a); } else { return NSHR(a); } }