summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/alu.c357
-rw-r--r--lib/instructions.txt130
-rw-r--r--lib/memoire.c4
4 files changed, 282 insertions, 210 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index dedd82d..a50e586 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,4 +12,3 @@ libCompilo_la_LDFLAGS = -version-info $(ProjetArchi_VERSION_INFO)
libSimul_la_LFDLAGS = -version-info $(ProjetArchi_VERSION_INFO)
libLinker_la_LDFLAGS = -version-info $(ProjetArchi_VERSION_INFO)
-EXTRA_DIST = instructions.txt
diff --git a/lib/alu.c b/lib/alu.c
index 4047b72..4ff01f3 100644
--- a/lib/alu.c
+++ b/lib/alu.c
@@ -1,8 +1,7 @@
#include "alu.h"
#include "config.h"
#include "exceptions.h"
-
-// rajouter les overflow...
+#include "registre.h"
/*****************************************/
/** **/
@@ -16,78 +15,262 @@ Uint32 SecondResult = 0;
/* ALU rapide */
+Uint32 RNot(Uint32 a) {
+ return (~a) + 1;
+}
+
Uint32 RAdditionNonSigne(Uint32 a, Uint32 b)
{
- return (a + b);
+ unsigned long long tr = a, masq = 1;
+ tr += b;
+
+ masq <<= 32;
+ if (masq & tr) {
+ SetOverflow();
+ } else {
+ ResetOverflow();
+ }
+
+ if (tr) {
+ SetZero();
+ } else {
+ ResetZero();
+ }
+
+ if (tr & 1) {
+ SetParity();
+ } else {
+ ResetParity();
+ }
+
+ ResetSign();
+ return tr;
}
-Uint32 RAdditionSigne(Uint32 a, Uint32 b)
+Uint32 RAdditionSigne(long int a, long int b)
{
- return (a + 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) {
+ SetZero();
+ } else {
+ ResetZero();
+ }
+
+ if (tr & 1) {
+ SetParity();
+ } else {
+ ResetParity();
+ }
+
+ if (tr & 0x80000000) {
+ SetSign();
+ } else {
+ ResetSign();
+ }
+ return tr;
}
Uint32 RSoustractionNonSigne(Uint32 a, Uint32 b)
{
- return (a - b);
+ return RAdditionNonSigne(a, RNot(b));
}
Uint32 RSoustractionSigne(Uint32 a, Uint32 b)
{
- return (a - b);
+ return RAdditionSigne(a, RNot(b));
}
Uint32 RMultiplicationNonSigne(Uint32 a, Uint32 b)
{
- unsigned long long temp;
+ unsigned long long temp = a;
- temp = a * b;
+ temp *= b;
SecondResult = temp >> 32;
+ if (temp & 1) {
+ SetParity();
+ } else {
+ ResetParity();
+ }
+ if (temp) {
+ ResetZero();
+ } else {
+ SetZero();
+ }
+ ResetOverflow();
+ ResetSign();
return (temp);
}
-Uint32 RMultiplicationSigne(Uint32 a, Uint32 b)
+Uint32 RMultiplicationSigne(long int a, long int b)
{
- unsigned long long temp;
+ long long temp = a;
- temp = a * b;
+ 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 (a / b);
+ return temp;
}
-Uint32 RDivisionSigne(Uint32 a, Uint32 b)
+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 (a / b);
+ return temp;
}
Uint32 RAND(Uint32 a, Uint32 b)
{
- return (a & 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)
{
- return (a | 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)
{
- return (a >> 1);
+ 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)
{
- return (a << 1);
+ Uint32 temp = a >> 1;
+
+ if (temp & 1) {
+ SetParity();
+ } else {
+ ResetParity();
+ }
+ if (temp) {
+ ResetZero();
+ } else {
+ SetZero();
+ }
+ if (temp & 0x80000000) {
+ SetSign();
+ } else {
+ ResetSign();
+ }
+ return temp;
}
-#if 0
+/* ALU normale (binaire) */
/*On compte de 0 à 31 */
@@ -97,7 +280,7 @@ Uint32 ValeurIbitsAuDeb(Uint32 nb, int i)
Uint32 val, un = 1;
if ((i > 31) || (i < 0)) {
- exception(_("ValeurIbitsAuDeb: position not in interval"));
+ exception(1, _("ValeurIbitsAuDeb: position not in interval"));
}
val = nb >> i;
val = val & un;
@@ -125,7 +308,7 @@ Uint32 MettreAVIbit(Uint32 nb, int i)
{
Uint32 val = 1;
- return (OrBit(nb, (val << i)));
+ return (nb | (val << i));
}
@@ -157,7 +340,7 @@ Uint32 InverseIbit(Uint32 nb, int i)
Uint32 un = 1;
if ((i > 31) || (i < 0)) {
- exception(_("InverseIbit: position not in interval"));
+ exception(1, _("InverseIbit: position not in interval"));
}
un = (un << i);
return (nb ^ un);
@@ -265,7 +448,6 @@ Uint32 NAdditionNonSigne(Uint32 x, Uint32 y)
}
if (i == 31) {
if (ret == 1) {
- fprintf(stderr, "Erreur AddNonSig: erreur de depassement.\n");
errRet = 1;
}
}
@@ -317,7 +499,6 @@ Uint32 NAdditionSigne(Uint32 x, Uint32 y)
}
if (i == 30) {
if (ret == 1) {
- fprintf(stderr, "Erreur AddNonSig: erreur de depassement.\n");
errRet = 1;
}
}
@@ -369,7 +550,6 @@ Uint32 NSoustractionNonSigne(Uint32 x, Uint32 y)
}
if (i == 31) {
if (ret == 1) {
- fprintf(stdout, "Erreur SousNonSig: erreur de depassement.\n");
errRet = 1;
}
}
@@ -377,7 +557,7 @@ Uint32 NSoustractionNonSigne(Uint32 x, Uint32 y)
return (sou);
}
-Uint32 NSoustractionSignee(Uint32 x, Uint32 y)
+Uint32 NSoustractionSigne(Uint32 x, Uint32 y)
{ /* x - y */
int i;
@@ -421,7 +601,6 @@ Uint32 NSoustractionSignee(Uint32 x, Uint32 y)
}
if (i == 30) {
if (ret == 1) {
- fprintf(stdout, "Erreur SousNonSig: erreur de depassement.\n");
errRet = 1;
}
}
@@ -565,11 +744,8 @@ couple MultipliNonSig(Uint32 x, Uint32 y)
for (i = 0; i < 32; i++) {
a = ValeurIbitsAuDeb(y, i);
tp = MultChifNomb(x, a);
- fprintf(stdout, "tp = %Lu\n", tp);
dec = (tp >> (32 - i));
- fprintf(stdout, "dec = %Lu\n", dec);
- pa2 = AddNonSigUint32(pa2, dec);
- fprintf(stdout, "pa2 = %Lu\n", pa2);
+ pa2 = NAdditionNonSigne(pa2, dec);
add = tp << i;
z = Addition(pa1, add);
pa1 = z.deb;
@@ -625,12 +801,12 @@ couple MultipliSig(Uint32 x, Uint32 y)
a = ValeurIbitsAuDeb(y1, i);
tp = MultChifNomb(x1, a);
dec = tp >> (31 - i);
- pa2 = AddNonSigUint32(pa2, dec);
+ pa2 = NAdditionNonSigne(pa2, dec);
add = tp << i;
z = Add30Mul(pa1, add);
pa1 = z.deb;
if (z.fin == 1) {
- pa2 = AddNonSigUint32(pa2, 1);
+ pa2 = NAdditionNonSigne(pa2, 1);
}
}
pa1 = MettreAVIbit(pa1, 31);
@@ -640,65 +816,87 @@ couple MultipliSig(Uint32 x, Uint32 y)
return (z);
}
-Uint32 NMultiplactionNonSigne(Uint32 a, Uint32 b)
+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.deb;
- return z.fin;
+ SecondResult = z.fin;
+ return z.deb;
}
-Uint32 NMultiplactionSigne(Uint32 a, Uint32 b)
+Uint32 NMultiplicationSigne(Uint32 a, Uint32 b)
{
couple z;
z = MultipliNonSig(a, b);
- SecondResult = z.deb;
- return z.fin;
+ SecondResult = z.fin;
+ return z.deb;
}
-#else
-Uint32 NAdditionNonSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NAdditionSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NSoustractionNonSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NSoustractionSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NMultiplicationNonSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NMultiplicationSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NDivisionNonSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NDivisionSigne(Uint32 a, Uint32 b)
-{
-}
-Uint32 NAND(Uint32 a, Uint32 b)
-{
-}
-Uint32 NOR(Uint32 a, Uint32 b)
-{
-}
-Uint32 NSHR(Uint32 a)
-{
-}
-Uint32 NSHL(Uint32 a)
-{
-}
-#endif
-
Uint32 AdditionNonSigne(Uint32 a, Uint32 b)
{
if (Rapide) {
@@ -806,3 +1004,4 @@ Uint32 SHR(Uint32 a)
return NSHR(a);
}
}
+
diff --git a/lib/instructions.txt b/lib/instructions.txt
deleted file mode 100644
index 8548887..0000000
--- a/lib/instructions.txt
+++ /dev/null
@@ -1,130 +0,0 @@
-# Champ d'instructions général
-FI:c3,6;c2,6;c1,6;e,6;op,8
-
-# Champ d'adressage
-Fa:reserved,4;rm,2
-
-# Pattern des registres
-Pr:R0;R1;R2;R3;R4;R5;R6;R7;R8;R9;R10;R11;R12;R13;R14;R15;R16;R17;R18;R19;R20;R21;R22;R23;R24;R25;R26;R27;R28;R29;R30;R31;Rg;Rd;IP;Fl
-
-# Pattern des adressages
-# .O = Adresse absolue (relogée)
-# .O = Adresse relative à l'instruction en cours (ex: Label, Label + 2, __current__ + 4)
-Pm:regop=.Pr;.I=.O;[regop=.Pr;.I=.O[regop=.Pr
-
-# bits 3 - 2
-# ~~~~~~~~~~
-# 00 overflow
-# 01 zero
-# 10 sign
-# 11 parity
-
-# bits 5 - 4
-# ~~~~~~~~~~
-# 00 test1
-# 01 test1 || test2
-# 10 test1 && !test2
-# 11 test1 || !test2
-
-
-# Arithmetique
-
-I:ADD c1=.Pr,c2=.Pr,c3=.Pr;op=0x0;e=0x0
-I:ADD c1=.Pr,c2=.Pr,.I=.C;op=0x0;e=0x1
-I:ADU c1=.Pr,c2=.Pr,c3=.Pr;op=0x0;e=0x2
-I:ADU c1=.Pr,c2=.Pr,.I=.C;op=0x0;e=0x3
-I:ADD c2=.Pr,c3=.Pr;op=0x0;e=0x0;c1=c2
-I:ADD c2=.Pr,.I=.C;op=0x0;e=0x1;c1=c2
-I:ADU c2=.Pr,c3=.Pr;op=0x0;c1=c2;e=0x2
-I:ADU c2=.Pr,.I=.C;op=0x0;c1=c2;e=0x3
-
-p:ADS=ADD
-
-I:SUB c1=.Pr,c2=.Pr,c3=.Pr;op=0x1;e=0x0
-I:SUB c1=.Pr,c2=.Pr,.I=.C;op=0x1;e=0x1
-I:SBU c1=.Pr,c2=.Pr,c3=.Pr;op=0x1;e=0x2
-I:SBU c1=.Pr,c2=.Pr,.I=.C;op=0x1;e=0x3
-I:SUB c2=.Pr,c3=.Pr;op=0x1;e=0x0;c1=c2
-I:SUB c2=.Pr,.I=.C;op=0x1;e=0x1;c1=c2
-I:SBU c2=.Pr,c3=.Pr;op=0x1;e=0x2;c1=c2
-I:SBU c2=.Pr,.I=.C;op=0x1;e=0x3;c1=c2
-
-p:SBS=SUB
-
-I:MUL c2=.Pr,c3=.Pr;op=0x2;e=0x0
-I:MUL c2=.Pr,.I=.C;op=0x2;e=0x1
-
-I:DIV c2=.Pr,c3=.Pr;op=0x3;e=0x0
-I:DIV c2=.Pr,.I=.C;op=0x3;e=0x1
-
-I:AND c1=.Pr,c2=.Pr,c3=.Pr;op=0x4;e=0x0
-I:AND c1=.Pr,c2=.Pr,.I=.C;op=0x4;e=0x1
-
-I:OR c1=.Pr,c2=.Pr,c3=.Pr;op=0x5;e=0x0
-I:OR c1=.Pr,c2=.Pr,.I=.C;op=0x5;e=0x1
-
-I:SHL c1=.Pr,c2=.Pr,c3=.Pr;op=0x6;e=0x0
-I:SHL c1=.Pr,c2=.Pr,I=.C;op=0x6;e=0x1
-
-I:SHR c1=.Pr,c2=.Pr,c3=.Pr;op=0x7;e=0x0
-I:SHR c1=.Pr,c2=.Pr,.I=.C;op=0x7;e=0x1
-
-
-# Transferts
-
-I:MOV c2=.Pr,rm=.Pm;op=8;e=2;c1=.Fa;c3=regop
-I:MOV c2=.Pr,c3=.Pr;op=8;e=2
-I:MOV c3=.Pr,.I=.C;op=8;e=1
-I:MOV rm=.Pm,c2=.Pr;op=8;e=0;c1=.Fa;c3=regop
-I:MOV rm=.Pm,.I=.C;op=8;e=1;c1=.Fa;c3=regop
-
-p:MV=MOV
-
-
-# Misc1
-
-I:NOP;op=0x9
-
-
-# Branchements
-
-# bits 3 - 2
-# ~~~~~~~~~~
-# 00 overflow
-# 01 zero
-# 10 sign
-# 11 parity
-
-# bits 5 - 4
-# ~~~~~~~~~~
-# 00 test1
-# 01 test1 || test2 == !(!test1 && !test2)
-# 10 test1 && !test2 == !(!test1 || test2)
-# 11 test1 || !test2 == !(!test1 && test2)
-
-I:JE c1=.Pr,c2=.Pr,.I=.O;op=0xa;e=0x0
-I:JNE c1=.Pr,c2=.Pr,.I=.O;op=0xa;e=0x1
-I:JL c1=.Pr,c2=.Pr,.I=.O;op=0xa;e=0x2
-I:JLE c1=.Pr,c2=.Pr,.I=.O;op=0xa;e=0x3
-I:JG c2=.Pr,c1=.Pr,.I=.O;op=0xa;e=0x2
-I:JGE c2=.Pr,c1=.Pr,.I=.O;op=0xa;e=0x3
-
-I:JO .I=.O;op=0xa;e=0x10
-I:JZ .I=.O;op=0xa;e=0x14
-I:JS .I=.O;op=0xa;e=0x18
-I:JP .I=.O;op=0xa;e=0x1c
-
-I:JNO .I=.O;op=0xa;e=0x30
-I:JNZ .I=.O;op=0xa;e=0x34
-I:JNS .I=.O;op=0xa;e=0x38
-I:JNP .I=.O;op=0xa;e=0x3c
-
-I:JMP .I=.O;op=0xa;e=0x0
-
-I:HALT;op=0x7f
-I:RESET;op=0x7f;e=1
-
-I:RET;op=0xc
-I:RET c1=.C;op=0xc
-
-I:CALL .I=.O;op=0xc;e=3
diff --git a/lib/memoire.c b/lib/memoire.c
index db85ae9..b181015 100644
--- a/lib/memoire.c
+++ b/lib/memoire.c
@@ -95,6 +95,8 @@ static void AfficheBinaire(Uint32 valeur)
/* Ecrit le mot 'valeur' à l'offset 'offset' en mémoire */
void ST(Uint32 offset, Uint32 valeur)
{
+ Uint32 oldOC;
+
switch (offset) {
case 0xffffff02:
fgets(temp, BUFSIZ, stdin);
@@ -124,7 +126,9 @@ void ST(Uint32 offset, Uint32 valeur)
break;
case 0xffffff0a:
litchaine(temp, &memoire_principale[valeur]);
+ oldOC = LireRegistrePC();
ChargeBinaire(temp);
+ EcrireRegistrePC(oldOC);
default:
if (offset < 0 || offset >= TAILLE_MEMOIRE)
exception(1, _("Invalid Memory Adress"));