summaryrefslogtreecommitdiff
path: root/lib/alu.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/alu.c')
-rw-r--r--lib/alu.c866
1 files changed, 278 insertions, 588 deletions
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)
{