#include "alu.h" #include "config.h" #include "exceptions.h" #include "registre.h" #include "interne.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) */ /* Renvoie un couple de bits */ chars CreerChars(char x, char y) { chars z; z.st = x; z.nd = y; return (z); } /* 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)))); } /* 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); } Uint32 NOT(Uint32 a) { int i; 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())); } Uint32 Decalage(Uint32 a, char c) { int i; 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++) { aux = AddBit((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); } /* 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++) { 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 NMultiplicationNonSigne(Uint32 a, Uint32 b) { return MUL_UU(a,b); } Uint32 NMultiplicationSigne(Uint32 a, Uint32 b) { return MUL_SS(a,b); } Uint32 NDivisionNonSigne(Uint32 a, Uint32 b) { return DivMod_UU(a,b); } Uint32 NDivisionSigne(Uint32 a, Uint32 b) { return DivMod_SS(a,b); } 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); } }