Yo !
On complète arm_instruction.c aujourd'hui !
L'idée c'est de FETCH/DECODE/EXECUTE. (Classique.)
Je vais surtout détailler la partie DECODE, en particulier comment reconnaitre le type de l'instruction. On a 3 grands types d'instructions :
- Instructions de branchement (B/BL)
- Instructions de traitement de données (Les data processing comme ADD, SUB etc...)
- Instructions d’accès à la mémoire (Load/Store)
- Les reste...
Ces grand types admettent des formats particuliers (cf le tableau dans le manuel, page 110). Le format donne une idée des paramètres que recoivent les opérandes (des registres ? Des valeurs immédiates ? etc...)
Du coup il faut traiter tous les cas possibles de types+formats. Ces infos sont donnés par :
- typeinst : les bits 27 à 25 de l'instruction.
- le 4ème bit de l'instruction (que je vais nommer "form", parce-qu'il donne souvent le format, par rapport à un grand type typeinst donné)
- le bit S (quand il est présent)
***************************************************
Du coup, si on admet l'existence d'une fonction decode(), qui prend en paramètre une instruction et un format d'instruction, la partie décodage de la fonction arm_execute_instruction ressemblera à :
Si (typeinst = 000) :
- si (codeop != 10xx):
-- si (form = 0) : decode(instruction, Data processing IMMEDIATE shift)
-- sinon si (form = 1) : decode(instruction, Data processing REGISTER shift)
- sinon si (codeop = 10xx) ET (S = 0): XXX (on ne traite pas ce cas)
Si (typeinst = 001) :
- si (codeop != 10xx) : decode(instruction, Data processing IMMEDIATE)
- sinon si (codeop = 10xx) ET (S = 0):
-- si (bit[21] = 1) : decode(instruction, Move immediate to status register)
-- sinon si (bit[21] = 0) : XXX (on ne traite pas ce cas)
Si (typeinst = 010) :
decode(instruction, Load/store immediate offset)
Si (typeinst = 011) :
- si (form = 0) : decode(instruction, Load/store register offset)
- sinon si (form = 1) : XXX
Si (typeinst = 100) : decode(instruction, Load/store register offset)
Si (typeinst = 101) : decode(instruction, branch and branch with link)
Si (typeinst = 110) : Ici c'est une instruction pour les co-processeurs. Je ne suis pas certaine qu'on nous demande de gérer ça aussi... Faudrait demander aux profs pour le coup.
Si (typeinst = 111) : decode(instruction, Interrupt) [je pense que les interruptions seront à gérer à la fiiin du projet...]
***************************************************
Ce qui m'amène donc à diviser le travail ainsi :
- Il nous faut quelqu'un qui écrive la fonction suivante :
int typeInstruction(uint32_t instruction) : prend une instruction en paramètre, cherche le type de l'instruction (voir l'algo ci dessus) et renvoie un int, qui sera un code de type :
- 1 = Data processing immediate shift
- 2 = Data processing immediate shift
- 3 = Data processing immediate
- 4 = Move immediate to status register
etc...
- Quelqu'un qui écrive la fonction suivante :
void decode(uint32_t instruction, int typeinst ) : il prend en paramètre l'instruction + son type (donné par la fonction typeInstruction() ) et procède au décodage+execute, cad qu'il va extraire codeop, les opérandes, etc... Tout le nécessaire pour faire le calcul ! Puis il fait le calcul. (le calcul sera fait par des fonctions qu'on écrira dans l'étape 3, donc faites comme si ces fonctions existaient 8D)
- Pour l'étape du décodage, il faut vérifier que les conditions sont valides avant d'execute. Pour ça, il faut regarder cond (les bits [31...28] de l'instruction) et regarder les flags associés. Ceee qui nous amène à une 3ème fonction ! :
int conditionsValides(uint32_t instruction) : selon le code cond de l'instruction, il va regarder le ZNCV, et envoyer 1 si les conditions sont respectées, 0 sinon. Il me semble que ça été quasi fait. :D
***************************************************
Bon... Ce que je vous pond là, c'est pas garanti que se soit juste hein. Mais au moins y a une base sur quoi débattre demain ! ♪
J'ai posé le squelette de mon algo sur git ! Vous pouvez jeter un oeil !