diff options
Diffstat (limited to 'lib/simulator.c')
-rw-r--r-- | lib/simulator.c | 413 |
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"); } |