summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorbiouman <>2001-04-15 02:12:11 +0000
committerbiouman <>2001-04-15 02:12:11 +0000
commit62480cd55b67e10128b9a49821d94c3c5117830f (patch)
tree6139c8a867012d60f766d38085455f2cb1c156ad /lib
parent0aca28afe35e25329bd8d680b532ccf78d4e4557 (diff)
mergeage de la branche simulateur avec la branche asm
Diffstat (limited to 'lib')
-rw-r--r--lib/alu.c22
-rw-r--r--lib/archi.c349
-rw-r--r--lib/interne.c94
-rw-r--r--lib/memoire.c33
-rw-r--r--lib/registre.c166
5 files changed, 664 insertions, 0 deletions
diff --git a/lib/alu.c b/lib/alu.c
new file mode 100644
index 0000000..b394b09
--- /dev/null
+++ b/lib/alu.c
@@ -0,0 +1,22 @@
+#include "alu.h"
+
+// rajouter les overflow...
+
+/*****************************************/
+/** **/
+/** GESTION DE L'UNITE DE CALCUL **/
+/** **/
+/*****************************************/
+
+Uint32 AdditionNonSigne(Uint32 a, Uint32 b) { return (a + b); }
+Uint32 AdditionSigne(Uint32 a, Uint32 b) { return (a + b); }
+Uint32 SoustractionNonSigne(Uint32 a, Uint32 b) { return (a - b); }
+Uint32 SoustractionSigne(Uint32 a, Uint32 b) { return (a - b); }
+Uint32 MultiplicationNonSigne(Uint32 a, Uint32 b) { return (a * b); }
+Uint32 MultiplicationSigne(Uint32 a, Uint32 b) { return (a * b); }
+Uint32 DivisionNonSigne(Uint32 a, Uint32 b) { return (a / b); }
+Uint32 DivisionSigne(Uint32 a, Uint32 b) { return (a / b); }
+Uint32 AND(Uint32 a, Uint32 b) { return (a & b); }
+Uint32 OR(Uint32 a, Uint32 b) { return (a | b); }
+Uint32 SHL(Uint32 a) { return (a >> 1); }
+Uint32 SHR(Uint32 a) { return (a << 1); }
diff --git a/lib/archi.c b/lib/archi.c
new file mode 100644
index 0000000..cb8bb4a
--- /dev/null
+++ b/lib/archi.c
@@ -0,0 +1,349 @@
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define _(x) x
+#endif
+
+#include "alu.h"
+#include "registre.h"
+#include "memoire.h"
+#include "fpu.h"
+
+
+
+
+// a modifier : Adresse switch 0 c faux
+// CALL RET ???
+// verifier le reste
+
+// initialisation de la MP avec un malloc
+// fermeture du prog et free
+// catch du ctrl-c
+
+Uint32 LireInstruction(void)
+{
+ return (LD(LireRegistrePC()));
+}
+
+void IncrementeCompteurOrdinal(void)
+{
+ EcrireRegistrePC(AdditionNonSigne(LireRegistrePC(), 1));
+}
+
+Uint32 Adresse(Uint32 u, Uint32 instruction)
+{
+ switch (champ(u, 2)) {
+ case 0:
+ return (LireRegistre(Champ3(instruction))); /* directement registre A CORRIGER */
+ case 1:
+ IncrementeCompteurOrdinal();
+ return (LireInstruction());
+ case 2:
+ return (LireRegistre(Champ3(instruction))); /* Adresse dans registre */
+ case 3:
+ IncrementeCompteurOrdinal();
+ return (LireRegistre(Champ3(instruction)) + LireInstruction()); /* Adresse dans registre + decalage de nouvelle instruction */
+ default: /* Il exige une loge... */
+ return (0);
+ }
+}
+
+void Initialisation(void)
+{
+ int i;
+
+ Reset(&Err_Mem);
+ Reset(&Err_Reg);
+ for (i = 0; i < TAILLE_MEMOIRE; i++)
+ Reset(&memoire_principale[i]);
+ EcrireRegistrePP(ADD_PP);
+}
+
+void Decode(Uint32 instruction)
+{
+ Uint32 champ_registre_resultat, val1, val2, resultat;
+
+ if (Opcode(instruction) & 0x80) {
+ fpu(Opcode(instruction));
+ } else {
+ switch (Opcode(instruction)) {
+ case (0 || 1 || 2 || 3 || 4 || 5):{
+ /* ALU */
+ champ_registre_resultat = Champ1(instruction); /* Champ du registre dans lequel va etre stocké le résultat */
+ val1 = LireRegistre(Champ2(instruction)); /* Premier entier qui va etre utilisé dans l'opération */
+ if (ValeurBit(Extension(instruction), 0) == 0)
+ val2 = LireRegistre(Champ3(instruction)); /* Deuxième entier, stocké dans un registre, qui va etre utilisé dans l'opération */
+ else {
+ IncrementeCompteurOrdinal();
+ val2 = LireInstruction(); /* Deuxième entier, stocké après l'instruction, qui va etre utilisé dans l'opération */
+ }
+ if (ValeurBit(Extension(instruction), 1) == 0) /* Teste si l'opération est signée ou pas */
+ switch (Opcode(instruction)) {
+ case 0:
+ resultat = AdditionNonSigne(val1, val2);
+ break;
+ case 1:
+ resultat = SoustractionNonSigne(val1, val2);
+ break;
+ case 2:
+ resultat = MultiplicationNonSigne(val1, val2);
+ break;
+ case 3:
+ resultat = DivisionNonSigne(val1, val2);
+ break;
+ case 4:
+ resultat = AND(val1, val2);
+ break;
+ case 5:
+ resultat = OR(val1, val2);
+ break;
+ case 6:
+ resultat = SHL(val1);
+ break;
+ case 7:
+ resultat = SHR(val1);
+ break;
+ } else
+ switch (Opcode(instruction)) {
+ case 0:
+ resultat = AdditionSigne(val1, val2);
+ break;
+ case 1:
+ resultat = SoustractionSigne(val1, val2);
+ break;
+ case 2:
+ resultat = MultiplicationSigne(val1, val2);
+ break;
+ case 3:
+ resultat = DivisionSigne(val1, val2);
+ break;
+ case 4:
+ resultat = AND(val1, val2);
+ break;
+ case 5:
+ resultat = OR(val1, val2);
+ break;
+ case 6:
+ resultat = SHL(val1);
+ break;
+ case 7:
+ resultat = SHR(val1);
+ break;
+ }
+ EcrireRegistre(champ_registre_resultat, resultat); /* On écrit le résultat dans le registre de sortie */
+ break;
+ }
+ case 8:{ /* MOV <=> il exige une loge en losange ou la sauje jonche les sieges */
+ if (ValeurBit(Extension(instruction), 4) == 1) /* MOV conditionnel */
+ if (ValeurBit(Extension(instruction), 5) == 0) /* Test normal */
+ switch (champ(Extension(instruction) >> 2, 4)) { /* teste les bits 2 et 3 */
+ case 0:
+ if (Overflow() == 1)
+ goto fin;
+ case 1:
+ if (Zero() == 1)
+ goto fin;
+ case 2:
+ if (Sign() == 1)
+ goto fin;
+ case 3:
+ if (Parity() == 1)
+ goto fin;
+ } else /* Negation du test */
+ switch (champ(Extension(instruction) >> 2, 4)) { /* teste les bits 2 et 3 */
+ case 0:
+ if (Overflow() == 0)
+ goto fin;
+ case 1:
+ if (Zero() == 0)
+ goto fin;
+ case 2:
+ if (Sign() == 0)
+ goto fin;
+ case 3:
+ if (Parity() == 0)
+ goto fin;
+ }
+ /* Pas de MOV conditionnel */
+ if (ValeurBit(Extension(instruction), 1) == 0) /* Mov arg1 arg2 */
+ if (ValeurBit(Extension(instruction), 0) == 0) /* arg2 = reg */
+ EcrireRegistre(Champ1(instruction), LireRegistre(Champ2(instruction)));
+ else /* arg2 = imm32 */ if (champ(Champ2(instruction), 4) == 0)
+ EcrireRegistre(Champ1(instruction),
+ Adresse(Champ2(instruction), instruction));
+ else
+ EcrireRegistre(Champ1(instruction),
+ LD(Adresse(Champ2(instruction), instruction)));
+ else /* Mov arg2 arg1 */ if (ValeurBit(Extension(instruction), 0) == 0) /* arg2 = reg */
+ EcrireRegistre(Champ2(instruction), LireRegistre(Champ1(instruction)));
+ else /* arg1 = imm32 */ if (champ(Champ2(instruction), 4) == 0)
+ ST(Adresse(Champ2(instruction), instruction),
+ LireRegistre(Champ1(instruction)));
+ else
+ ST(Adresse(Champ2(instruction), instruction),
+ LireRegistre(Champ1(instruction)));
+ fin:
+ break;
+ }
+ case 9:{ /* NOP */
+ /* Instruction nulle */
+ break;
+ }
+ case 10: /* J */
+ case 11:{
+ int test1, test2;
+
+ switch (champ(Extension(instruction), 4)) {
+ case 0:
+ test1 = LireRegistre(Champ1(instruction)) == LireRegistre(Champ2(instruction));
+ break;
+ case 1:
+ test1 = LireRegistre(Champ1(instruction)) != LireRegistre(Champ2(instruction));
+ break;
+ case 2:
+ test1 = LireRegistre(Champ1(instruction)) < LireRegistre(Champ2(instruction));
+ break;
+ case 3:
+ test1 = LireRegistre(Champ1(instruction)) <= LireRegistre(Champ2(instruction));
+ break;
+ }
+ switch (champ(Extension(instruction) >> 2, 4)) {
+ case 0:
+ test2 = Overflow();
+ break;
+ case 1:
+ test2 = Zero();
+ break;
+ case 2:
+ test2 = Sign();
+ break;
+ case 3:
+ test2 = Parity();
+ break;
+ }
+ switch (champ(Extension(instruction) >> 4, 4)) {
+ case 0:
+ test1 = test1;
+ break;
+ case 1:
+ test1 = test1 || test2;
+ break;
+ case 2:
+ test1 = test1 && !test2;
+ break;
+ case 3:
+ test1 = test1 || !test2;
+ break;
+ }
+ if (test1) {
+ IncrementeCompteurOrdinal();
+ if (Opcode(instruction) == 10)
+ EcrireRegistrePC(LireInstruction());
+ else
+ EcrireRegistrePC(AdditionNonSigne(LireRegistrePC(), LireInstruction()));
+ }
+ break;
+ }
+ case (12): /* JMP *//* Kris Kross */
+ case (13):
+ if (ValeurBit(Extension(instruction), 0) == 0) {
+ ; /* RET */
+ } else if (ValeurBit(Extension(instruction), 1) == 0) ; /* JMP */
+ else; /* CALL */
+
+ break;
+ case 14:{ /* PUSH */
+ Uint32 val; /* valeur qui va etre stockée */
+
+ EcrireRegistrePP(SoustractionNonSigne(LireRegistrePP(), 1)); /* On pointe sur un emplacement vide */
+ if (ValeurBit(Extension(instruction), 0) == 0)
+ val = LireRegistre(Champ1(instruction));
+ else {
+ IncrementeCompteurOrdinal();
+ val = LireInstruction();
+ }
+ ST(LireRegistrePP(), val);
+ break;
+ }
+ case 15:{ /* POP */
+ EcrireRegistre(Champ1(instruction), LireRegistrePP());
+ EcrireRegistrePP(AdditionNonSigne(LireRegistrePP(), 1));
+ break;
+ }
+ case 127:{ /* HALT-RESET */
+ if (ValeurBit(Extension(instruction), 0))
+ getc(stdin); /* Halt */
+ else
+ Initialisation(); /* Reset */
+ break;
+ }
+ default:{
+ printf("soja");
+ }
+ }
+ }
+}
+void Traitement(void)
+{
+ Uint32 instruction;
+
+ while (!0) {
+ instruction = LireInstruction();
+ Decode(instruction);
+ IncrementeCompteurOrdinal();
+ }
+}
+
+void Debogueur(void) // transformer en affiche reg
+{
+ int i,j;
+
+/* gotoxy(1, 1);
+ printf("Etat des registres classiques Etat des registres");
+ gotoxy(1, 2);
+ printf(" speciaux ");
+ gotoxy(1, 11);
+ printf(" Instruction a decoder");
+ gotoxy(1, 14);
+ printf(" Prochaine instruction");
+ for (i = 1; i <= 16; i++) {
+ gotoxy(1, i + 2);
+ printf("r%2d:%9d", i - 1, registre[i - 1]);
+ }
+ for (i = 17; i <= 32; i++) {
+ gotoxy(17, i - 16 + 2);
+ printf("r%2d:%9d", i - 1, registre[i - 1]);
+ }
+ gotoxy(40, 4);
+ printf("Rg :%9d", LireRegistreRG());
+ gotoxy(40, 5);
+ printf("Rd :%9d", LireRegistreRD());
+ gotoxy(40, 6);
+ printf("PC :%9d", LireRegistrePC());
+ gotoxy(40, 7);
+ printf("Flag :%9d", LireRegistreFLAG());
+ gotoxy(40, 12);
+ printf(" %9d", LireInstruction());
+ registre[REG_PC]++;
+ gotoxy(40, 15);
+ printf(" %9d", LireInstruction());
+ registre[REG_PC]--;
+ getc(stdin);
+*/
+ for (i=0; i<=3; i++) {
+ for (j=1; j<=8;j++) {
+ printf(" R%02d ", (i*8+j));
+ }
+ printf("\n");
+ for (j=1; j<=8;j++) {
+ printf("%08lX ", (registre[i*8+j-1]));
+ }
+ printf("\n");
+
+ }
+ printf("Rg: %08lX | Rd: %08lX | Flag: %08lX | PC: %08lX\n", LireRegistreRG(), LireRegistreRD(), LireRegistreFLAG(),registre[REG_PC]);
+ printf("\n");
+}
+
diff --git a/lib/interne.c b/lib/interne.c
new file mode 100644
index 0000000..bdab97e
--- /dev/null
+++ b/lib/interne.c
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include "interne.h"
+#include "archi.h"
+
+// mettre des exceptions dans les fcns ci dessous a la place de GestionErreurs
+
+void GestionErreurs(void)
+{
+}
+
+void Reset(Uint32 * i)
+{ /* met tous les bits d'un mot à zéro */
+ *i &= 0;
+} /* Ok */
+
+void Set(Uint32 * i)
+{ /* met le bit de poids faible à 1 */
+ *i &= 1;
+} /* Ok */
+
+/* Met le bit 'position' à zéro */
+void ResetBit(Uint32 * i, int position)
+{
+ if (position < 0 || position > 31) {
+ GestionErreurs();
+ } else {
+ Uint32 aux = VAL_MAX - (1 << position);
+
+ *i &= aux;
+ }
+} /* Ok */
+
+/* Met le bit 'position' à un */
+void SetBit(Uint32 * i, int position)
+{
+ if (position < 0 || position > 31) {
+ GestionErreurs();
+ } else {
+ Uint32 aux = 1 << position;
+
+ *i |= aux;
+ }
+} /* Ok */
+
+/* Donne la valeur du bit 'position' */
+int ValeurBit(Uint32 nombre, int position)
+{
+ if (position < 0 || position > 31) {
+ GestionErreurs();
+ return (-1);
+ }
+ return ((nombre >> position) & 1);
+} /* Ok */
+
+/* Affiche tous les bits d'un mot */
+void Uint32toBin(Uint32 i)
+{
+ int k;
+
+ for (k = 31; k >= 0; k--)
+ printf("%d", ValeurBit(i, k));
+ printf("\n");
+} /* Ok */
+
+/* Extrait un champ dans un mot */
+Uint32 champ(Uint32 nombre, int taille)
+{
+ return (nombre & (taille - 1));
+} /* Ok */
+
+Uint32 Opcode(Uint32 ins)
+{
+ return (champ(ins >> 0, 256));
+} /* Ok */
+
+Uint32 Extension(Uint32 ins)
+{
+ return (champ(ins >> 8, 64));
+} /* Ok */
+
+Uint32 Champ1(Uint32 ins)
+{
+ return (champ(ins >> 14, 64));
+} /* Ok */
+
+Uint32 Champ2(Uint32 ins)
+{
+ return (champ(ins >> 20, 64));
+} /* Ok */
+
+Uint32 Champ3(Uint32 ins)
+{
+ return (champ(ins >> 26, 64));
+} /* Ok */
diff --git a/lib/memoire.c b/lib/memoire.c
new file mode 100644
index 0000000..c8dd6a4
--- /dev/null
+++ b/lib/memoire.c
@@ -0,0 +1,33 @@
+#include "memoire.h"
+#include "interne.h"
+#include "archi.h"
+
+/*****************************************/
+/** **/
+/** GESTION DE LA MEMOIRE PRINCIPALE **/
+/** **/
+/*****************************************/
+
+/* Lit le mot qui se trouve à l'offset 'offset' en mémoire */
+Uint32 LD(Uint32 offset)
+{
+ Uint32 i;
+
+ Reset(&i);
+ if (offset < 0 || offset >= TAILLE_MEMOIRE) {
+ Set(&Err_Mem);
+ return (i);
+ } else {
+ i = memoire_principale[offset];
+ return (i);
+ }
+}
+
+/* Ecrit le mot 'valeur' à l'offset 'offset' en mémoire */
+void ST(Uint32 offset, Uint32 valeur)
+{
+ if (offset < 0 || offset >= TAILLE_MEMOIRE)
+ Set(&Err_Mem);
+ else
+ memoire_principale[offset] = valeur;
+}
diff --git a/lib/registre.c b/lib/registre.c
new file mode 100644
index 0000000..f97595d
--- /dev/null
+++ b/lib/registre.c
@@ -0,0 +1,166 @@
+#include "registre.h"
+#include "interne.h"
+#include "archi.h"
+
+/*****************************************/
+/** **/
+/** GESTION DES REGISTRES **/
+/** **/
+/*****************************************/
+
+Uint32 LireRegistreRG(void)
+{
+ return (registre[REG_RG]);
+}
+
+Uint32 LireRegistreRD(void)
+{
+ return (registre[REG_RD]);
+}
+
+Uint32 LireRegistrePC(void)
+{
+ return (registre[REG_PC]);
+}
+
+Uint32 LireRegistreFLAG(void)
+{
+ return (registre[REG_FLAG]);
+}
+
+Uint32 LireRegistrePP(void)
+{
+ return (registre[REG_PUSHPOP]);
+}
+
+void EcrireRegistreRG(Uint32 val)
+{
+ registre[REG_RG] = val;
+}
+
+void EcrireRegistreRD(Uint32 val)
+{
+ registre[REG_RD] = val;
+}
+
+void EcrireRegistrePC(Uint32 val)
+{
+ registre[REG_PC] = val;
+}
+
+void EcrireRegistreFLAG(Uint32 val)
+{
+ registre[REG_FLAG] = val;
+}
+
+void EcrireRegistrePP(Uint32 val)
+{
+ registre[REG_PUSHPOP] = val;
+}
+
+/* Lit le mot qui se trouve dans le registre 'numero_registre' */
+Uint32 LireRegistre(Uint32 champ_registre)
+{
+ Uint32 i;
+
+ if (ValeurBit(champ_registre, 5) == 0) { /* Test du bit S */
+ Reset(&i);
+ if (champ_registre < 0 || champ_registre >= NB_REGISTRES_UTILISABLES) { /* Si on voudrait diminuer le nombre de registres */
+ Set(&Err_Reg); /* Il n'y a que 32 registres */
+ return (i);
+ }
+ i = registre[champ_registre]; /* Registre classique */
+ return (i);
+ } else /* Registre spécial */
+ switch (champ(champ_registre, 4)) {
+ case 0:
+ return (LireRegistreRG());
+ case 1:
+ return (LireRegistreRD());
+ case 2:
+ return (LireRegistrePC());
+ case 3:
+ return (LireRegistreFLAG());
+ default:{
+ Set(&Err_Reg);
+ return (0);
+ }
+ }
+}
+
+/* Ecrit le mot 'valeur' dans le registre 'numero_registre' */
+void EcrireRegistre(Uint32 champ_registre, Uint32 valeur)
+{
+ Uint32 i;
+
+ if (ValeurBit(champ_registre, 5) == 0) { /* Test du bit S */
+ Reset(&i);
+ if (champ_registre < 0 || champ_registre >= NB_REGISTRES_UTILISABLES)
+ Set(&Err_Reg); /* Il n'y a que 32 registres */
+ else
+ registre[champ_registre] = valeur; /* Registre classique */
+ } else /* Registre spécial */
+ switch (champ(champ_registre, 4)) {
+ case 0:
+ EcrireRegistreRG(valeur);
+ case 1:
+ EcrireRegistreRD(valeur);
+ case 2:
+ EcrireRegistrePC(valeur);
+ case 3:
+ EcrireRegistreFLAG(valeur);
+ default:
+ Set(&Err_Reg);
+ }
+}
+
+int Overflow(void)
+{
+ return (ValeurBit(LireRegistreFLAG(), 0));
+}
+int Zero(void)
+{
+ return (ValeurBit(LireRegistreFLAG(), 1));
+}
+int Sign(void)
+{
+ return (ValeurBit(LireRegistreFLAG(), 2));
+}
+int Parity(void)
+{
+ return (ValeurBit(LireRegistreFLAG(), 3));
+}
+
+void SetOverflow(void)
+{
+ registre[REG_FLAG] |= 1;
+}
+void SetZero(void)
+{
+ registre[REG_FLAG] |= 2;
+}
+void SetSign(void)
+{
+ registre[REG_FLAG] |= 4;
+}
+void SetParity(void)
+{
+ registre[REG_FLAG] |= 8;
+}
+
+void ResetOverflow(void)
+{
+ registre[REG_FLAG] &= (VAL_MAX - 1);
+}
+void ResetZero(void)
+{
+ registre[REG_FLAG] &= (VAL_MAX - 2);
+}
+void ResetSign(void)
+{
+ registre[REG_FLAG] &= (VAL_MAX - 4);
+}
+void ResetParity(void)
+{
+ registre[REG_FLAG] &= (VAL_MAX - 8);
+}