summaryrefslogtreecommitdiff
path: root/lib/simulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/simulator.c')
-rw-r--r--lib/simulator.c413
1 files changed, 209 insertions, 204 deletions
diff --git a/lib/simulator.c b/lib/simulator.c
index b046129..1fabf67 100644
--- a/lib/simulator.c
+++ b/lib/simulator.c
@@ -15,14 +15,12 @@
#include "exceptions.h"
+/* CALL RET ???
+ verifier le reste
-
-// CALL RET ???
-// verifier le reste
-
-// initialisation de la MP avec un malloc
-// fermeture du prog et free
-// catch du ctrl-c
+ initialisation de la MP avec un malloc
+ fermeture du prog et free
+ catch du ctrl-c */
Uint32 LireInstruction(void)
{
@@ -41,7 +39,7 @@ Uint32 Adresse(Uint32 u, Uint32 instruction)
switch (champ(u, 2)) {
case 0:
exception(1, _("Adresse: Call With Invalid r/m Field State ( r/m=00 )"));
- return(0);
+ return (0);
case 1:
tmp = LireInstruction();
IncrementeCompteurOrdinal();
@@ -54,7 +52,7 @@ Uint32 Adresse(Uint32 u, Uint32 instruction)
return (tmp);
default:
exception(1, _("Adresse: Unmatched Addr Field"));
- return(0);
+ return (0);
}
}
@@ -82,204 +80,210 @@ void DecodeExec(Uint32 instruction, Uint32 entrypoint)
case 3:
case 4:
case 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 {
- val2 = LireInstruction(); /* Deuxième entier, stocké après l'instruction, qui va etre utilisé dans l'opération */
- IncrementeCompteurOrdinal();
- }
- 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 */
- 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 */
- if (champ(Champ1(instruction), 2) == 0) { /* r/m de arg1 = 0 */
- EcrireRegistre(Champ3(instruction), LireRegistre(Champ2(instruction)));
- } else {
- ST(Adresse(Champ1(instruction), instruction), LireRegistre(Champ2(instruction)));
- }
- } else { /* arg2 = imm32 */
- if (champ(Champ1(instruction), 2) == 0) { /* r/m de arg1 = 0 */
- EcrireRegistre(Champ3(instruction), LireInstruction());
- IncrementeCompteurOrdinal();
- } else {
- ST(Adresse(Champ1(instruction), instruction), LireInstruction());
- IncrementeCompteurOrdinal();
- }
- }
- } else {
- if (ValeurBit(Extension(instruction), 0) == 0) { /* arg2 = reg */
- if (champ(Champ1(instruction), 2) == 0) { /* r/m de arg1 = 0 */
- EcrireRegistre(Champ2(instruction), LireRegistre(Champ3(instruction)));
-
- } else {
- EcrireRegistre(Champ2(instruction), LD(Adresse(Champ1(instruction), instruction)));
- }
- } else { /* arg2 = imm32 */
- exception(1, _("MOV: Memory to Memory Forbidden On This Type Of Processor"));
- }
- }
- fin:
- break;
-
- case 9: /* NOP */
- /* Instruction nulle */
- break;
-
- case 10: /* J[cond] */
- case 11:
- int test1, test2;
-
- switch (champ(Extension(instruction), 4)) {
+ case 6:
+ case 7:
+ /* 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 {
+ val2 = LireInstruction(); /* Deuxième entier, stocké après l'instruction, qui va etre utilisé dans l'opération */
+ IncrementeCompteurOrdinal();
+ }
+ if (ValeurBit(Extension(instruction), 1) == 0) /* Teste si l'opération est signée ou pas */
+ switch (Opcode(instruction)) {
case 0:
- if (Champ1(instruction) == Champ2(instruction)) {
- test1 = 1;
- } else {
- test1 = LireRegistre(Champ1(instruction)) == LireRegistre(Champ2(instruction));
- }
+ resultat = AdditionNonSigne(val1, val2);
break;
case 1:
- test1 = LireRegistre(Champ1(instruction)) != LireRegistre(Champ2(instruction));
+ resultat = SoustractionNonSigne(val1, val2);
break;
case 2:
- test1 = LireRegistre(Champ1(instruction)) < LireRegistre(Champ2(instruction));
+ resultat = MultiplicationNonSigne(val1, val2);
break;
case 3:
- test1 = LireRegistre(Champ1(instruction)) <= LireRegistre(Champ2(instruction));
+ resultat = DivisionNonSigne(val1, val2);
break;
- }
- switch (champ(Extension(instruction) >> 2, 4)) {
- case 0:
- test2 = Overflow();
+ case 4:
+ resultat = AND(val1, val2);
break;
- case 1:
- test2 = Zero();
+ case 5:
+ resultat = OR(val1, val2);
break;
- case 2:
- test2 = Sign();
+ case 6:
+ resultat = SHL(val1);
break;
- case 3:
- test2 = Parity();
+ case 7:
+ resultat = SHR(val1);
break;
- }
- switch (champ(Extension(instruction) >> 4, 4)) {
+ } else
+ switch (Opcode(instruction)) {
case 0:
- test1 = test1;
+ resultat = AdditionSigne(val1, val2);
break;
case 1:
- test1 = test1 || test2;
+ resultat = SoustractionSigne(val1, val2);
break;
case 2:
- test1 = test1 && !test2;
+ resultat = MultiplicationSigne(val1, val2);
break;
case 3:
- test1 = test1 || !test2;
+ 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 */
+ 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 */
+ if (champ(Champ1(instruction), 2) == 0) { /* r/m de arg1 = 0 */
+ EcrireRegistre(Champ3(instruction), LireRegistre(Champ2(instruction)));
+ } else {
+ ST(Adresse(Champ1(instruction), instruction),
+ LireRegistre(Champ2(instruction)));
+ }
+ } else { /* arg2 = imm32 */
+ if (champ(Champ1(instruction), 2) == 0) { /* r/m de arg1 = 0 */
+ EcrireRegistre(Champ3(instruction), LireInstruction());
+ IncrementeCompteurOrdinal();
+ } else {
+ ST(Adresse(Champ1(instruction), instruction), LireInstruction());
+ IncrementeCompteurOrdinal();
+ }
}
- if (test1) { Uint32 tmp;
- tmp=LireInstruction();
- EcrireRegistrePC(tmp);
+ } else {
+ if (ValeurBit(Extension(instruction), 0) == 0) { /* arg2 = reg */
+ if (champ(Champ1(instruction), 2) == 0) { /* r/m de arg1 = 0 */
+ EcrireRegistre(Champ2(instruction), LireRegistre(Champ3(instruction)));
+
+ } else {
+ EcrireRegistre(Champ2(instruction),
+ LD(Adresse(Champ1(instruction), instruction)));
+ }
+ } else { /* arg2 = imm32 */
+ exception(1, _("MOV: Memory to Memory Forbidden On This Type Of Processor"));
+ }
+ }
+ fin:
+ break;
+
+ case 9: /* NOP */
+ /* Instruction nulle */
+ break;
+
+ case 10: /* J[cond] */
+ case 11:
+ int test1, test2;
+
+ switch (champ(Extension(instruction), 4)) {
+ case 0:
+ if (Champ1(instruction) == Champ2(instruction)) {
+ test1 = 1;
+ } else {
+ 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) {
+ Uint32 tmp;
+
+ tmp = LireInstruction();
+ EcrireRegistrePC(tmp);
+ }
+ break;
+
case 12: /* JMP */
case 13:
if (ValeurBit(Extension(instruction), 0) == 0) {
- /* RET */
- EcrireRegistreSP(AdditionNonSigne(LireRegistreSP(),Champ1(instruction)));
+ /* RET */
+ EcrireRegistreSP(AdditionNonSigne(LireRegistreSP(), Champ1(instruction)));
EcrireRegistreSP(AdditionNonSigne(LireRegistreSP(), 1));
EcrireRegistrePC(LD(LireRegistreSP()));
-
+
} else if (ValeurBit(Extension(instruction), 1) == 0) { /* JMP */
if (ValeurBit(Extension(instruction), 2) == 0) {
EcrireRegistrePC(LireRegistre(Champ1(instruction)));
@@ -287,8 +291,8 @@ void DecodeExec(Uint32 instruction, Uint32 entrypoint)
EcrireRegistrePC(LireInstruction());
}
} else { /* CALL */
- ST(LireRegistreSP(),LireRegistrePC());
- EcrireRegistreSP(SoustractionNonSigne(LireRegistreSP(),1));
+ ST(LireRegistreSP(), LireRegistrePC());
+ EcrireRegistreSP(SoustractionNonSigne(LireRegistreSP(), 1));
if (ValeurBit(Extension(instruction), 2) == 0) {
EcrireRegistrePC(LireRegistre(Champ1(instruction)));
} else {
@@ -297,31 +301,31 @@ void DecodeExec(Uint32 instruction, Uint32 entrypoint)
}
break;
case 14: /* PUSH */
- Uint32 val; /* valeur qui va etre stockée */
+ Uint32 val; /* valeur qui va etre stockée */
- if (ValeurBit(Extension(instruction), 0) == 0)
- val = LireRegistre(Champ1(instruction));
- else {
- val = LireInstruction();
- IncrementeCompteurOrdinal();
- }
- ST(LireRegistreSP(), val);
- EcrireRegistreSP(SoustractionNonSigne(LireRegistreSP(), 1));
- break;
+ if (ValeurBit(Extension(instruction), 0) == 0)
+ val = LireRegistre(Champ1(instruction));
+ else {
+ val = LireInstruction();
+ IncrementeCompteurOrdinal();
+ }
+ ST(LireRegistreSP(), val);
+ EcrireRegistreSP(SoustractionNonSigne(LireRegistreSP(), 1));
+ break;
case 15: /* POP */
- EcrireRegistreSP(AdditionNonSigne(LireRegistreSP(), 1));
- EcrireRegistre(Champ1(instruction), LD(LireRegistreSP()));
-
- break;
+ EcrireRegistreSP(AdditionNonSigne(LireRegistreSP(), 1));
+ EcrireRegistre(Champ1(instruction), LD(LireRegistreSP()));
+
+ break;
case 127: /* HALT-RESET */
- if (ValeurBit(Extension(instruction), 0))
- exit(0); /* Halt *//* *******************FIXMI********************* */
- else
- ResetRegistres();
- Traitement(entrypoint); /* Reset *//* ************FIXMI************** */
- break;
+ if (ValeurBit(Extension(instruction), 0))
+ exit(0); /* Halt *//* *******************FIXMI********************* */
+ else
+ ResetRegistres();
+ Traitement(entrypoint); /* Reset *//* ************FIXMI************** */
+ break;
default:
- exception(1, _("DecodeExec: Invalid Opcode"));
+ exception(1, _("DecodeExec: Invalid Opcode"));
}
}
}
@@ -333,7 +337,7 @@ void Traitement(Uint32 entrypoint)
while (!0) {
instruction = LireInstruction();
IncrementeCompteurOrdinal();
- DecodeExec(instruction, entrypoint);
+ DecodeExec(instruction, entrypoint);
}
}
@@ -351,7 +355,8 @@ void AfficheReg(void) // affiche reg
}
printf("\n");
}
- printf("Rg: %08lX | Rd: %08lX | Flag: %08lX | PC: %08lX\n", LireRegistreRG(), LireRegistreRD(), LireRegistreFLAG(), registre[REG_PC]);
+ printf("Rg: %08lX | Rd: %08lX | Flag: %08lX | PC: %08lX\n", LireRegistreRG(), LireRegistreRD(),
+ LireRegistreFLAG(), registre[REG_PC]);
printf("\n");
}