• Aucun résultat trouvé

5.4 Jeu d’instructions et spécifications

5.4.3 Jeu d’instructions

Le jeu d’instructions du WUC est un jeu d’instructions RISC 16 bits ayant trois modes d’adressage : l’adressage indirect à registre, l’adressage base + index, l’adressage base + offset. Différents types d’instructions ont été mis en place avec des instructions à 3 opérandes, 2 opérandes sur les registres avec la possibilité d’utilisation d’immédiats en signés ou non signés.

Dans un premier temps les instructions vont être présentées au niveau fonctionnel en différents groupes (tableau 5.1). Il y a 7 groupes : les instructions mémoires, arithmétiques, logiques, de gestion des signes, de support d’appel aux fonctions, de branchements et les instructions spéciales.

Mémoire Arithmétique Logique Gestion

signe Fonction Branchement Spéciale

33 instructions

LDRB ADD AND SXTB PUSH B ENDIT

LDRH SUB XOR SXTH POP BREAK

LDR COMP OR UXTB BL LDRSB BIC UXTH LDRSH BIT STRB NOT STRH LSL STR LSR MOVBL MOVBU MOV PCREL

5.4.3.1 Instructions mémoire

Les instructions mémoire sont les instructions qui permettent de faire des chargements de données vers les registres généraux du WUC, des sauvegardes des registres généraux du WUC vers l’espace d’adressage et des déplacements de données dans les registres généraux. Le récapitulatif des instructions mémoire et de ce qu’elles exécutent sont présentés tableau 5.2.

Type Instruction Assembleur Opération

MOV

MOVBL

imm MOVBL #imm, Rd {24′b0 : [imm8]} -> Rd MOVBU

imm MOVBU #imm, Rd {16′b0 : [imm8] : 8b0} -> Rd

MOV R MOV Rs, Rd Rs -> Rd

LOAD

LDRB imm LDRB [Rs, #imm] , Rd ZeroExtend([Rs+imm5][7 :0]) -> Rd LDRH imm LDRH [Rs, #imm], Rd ZeroExtend([Rs+(imm5 :0)][15 :0]) -> Rd

LDR imm LDR [Rs, #imm], Rd [Rs+(imm5 :00)] -> Rd LDRSB imm LDRSB [Rs, #imm] , Rd SignExtend([Rs+imm5][7 :0]) -> Rd LDRSH imm LDRSH [Rs, #imm], Rd SignExtend([Rs+(imm5 :0)][15 :0]) -> Rd

LDRB R-R LDRB [Rs1, Rs2], Rd ZeroExtend([Rs1+Rs2][7 :0]) -> Rd LDRH R-R LDRH [Rs1, Rs2], Rd ZeroExtend([Rs1+Rs2][15 :0]) -> Rd LDR R-R LDR [Rs1, Rs2], Rd [Rs1 + Rs2] -> Rd LDRSB R-R LDRSB [Rs1, Rs2], Rd SignExtend([Rs1+Rs2][7 :0]) -> Rd LDRSH R-R LDRSH [Rs1, Rs2], Rd SignExtend([Rs1+Rs2][15 :0]) -> Rd LDRB R LDRB [Rs], Rd ZeroExtend([Rs][7 :0]) -> Rd LDRH R LDRH [Rs], Rd ZeroExtend([Rs][15 :0]) -> Rd LDR R LDR [Rs], Rd [Rs] -> Rd LDRSB R LDRSB [Rs], Rd SignExtend([Rs][7 :0]) -> Rd LDRSH R LDRSH [Rs], Rd SignExtend([Rs][15 :0]) -> Rd

PCREL LDR Label, Rd [PC + (offset8 :0)] -> Rd

STORE

STRB imm STRB [Rs, #imm], Rd Rd[7 :0] -> [Rs + imm5][7 :0] STRH imm STRH [Rs, #imm], Rd Rd[15 :0] -> [Rs+(imm5 :0)][15 :0]

STR imm STR [Rs, #imm], Rd Rd -> [Rs+(imm5 :00)] STRB R-R STRB [Rs1, Rs2], Rd Rd -> [Rs1 + Rs2][7 :0] STRH R-R STRH [Rs1, Rs2], Rd Rd -> [Rs1 + Rs2][15 :0] STR R-R STR [Rs1, Rs2], Rd Rd -> [Rs1+Rs2] STRB R STRB [Rs], Rd Rd[7 :0] -> [Rs][7 :0] STRH R STRH [Rs], Rd Rd[15 :0] -> [Rs][15 :0] STR R STR [Rs], Rd Rd -> [Rs]

Table 5.2 – Récapitulatif des instructions mémoires du Wake Up Controller

Les périphériques et la mémoire de programme/données étant tous interconnectés sur le même bus de communication, il n’y a alors pas besoin d’instructions dédiées pour les périphériques et pour la mémoire. Pour gérer la taille des données, les instructions de char- gement (Load) et de sauvegarde (Store) existent en version octet (Byte), demi-mot (Half

Word) et mot (Word). Pour charger et travailler sur des nombres signés, les instructions Load existent aussi pour les nombres signés en étendant leur signe sur 32 bits. L’adressage

dans le WUC s’effectue en Little Endian (l’adresse de l’octet, du demi mot ou du mot pointe sur l’octet de poids faible). La mémoire a une largeur de 32 bits et peut être écrite par octet, demi mot ou mot. Une lecture dans la mémoire renvoie automatiquement un mot de 32 bits. La logique doit donc sélectionner dans le mot la bonne partie et la décaler sur l’octet de poids faible pour le stocker dans le registre général. Pour une sauvegarde dans la mémoire, l’octet ou le demi-mot sont dupliqués sur le bus de 32 bits. Une opération de masquage s’effectue dans la mémoire en fonction de l’adresse où écrire et de la taille de la donnée à sauver.

Les instructions Load et Store existent sous les trois modes d’adressages expliqués dans la section 5.4.1 et sont possibles pour des octets, des demi-mots et des mots. Il y a des

Jeu d’instructions et spécifications 75 cas d’un octet ou d’un demi-mot. Il existe aussi une instruction de chargement relatif au compteur programme PCREL, pour charger des données provenant d’une table ou Literal

Pool qui permet de charger un mot de l’adresse courante à l’adresse courante + 510.

L’instruction MOVBL permet de charger un immédiat sur 8 bits directement dans un registre alors que l’instruction MOVBU permet de charger un immédiat de 8 bits sur l’octet de poids fort d’un demi-mot. En enchainant ensuite avec un une addition en immédiat ceci permet de créer des adresses sur 16 bits.

5.4.3.2 Instructions arithmétiques et logiques

Le jeu d’instructions du Wake Up Controller inclut des opérations classiques arithmé- tiques et logiques. Le tableau 5.3 référence toutes les opérations arithmétiques et logiques du WUC ainsi que leurs opérations et leur action sur les bits de statut du processeur qui sont utilisés par l’unité de branchement. Les opérations logiques sont très utiles pour faire des opérations de masquage afin de configurer des registres par exemple. Les opérations arithmétiques permettent de faire un minimum de calcul sur les données, de créer des adresses ou d’évaluer des prédicats dans le cadre d’exécution de machines d’états. De plus, si les nombres sont signés alors il est nécessaire d’étendre leur signe sur 32 bits si ce sont des données de 8 ou 16 bits (SXTB, SXTH). Une extension en nombre non signé peut être nécessaire quelque fois pour forcer la conversion de type (cast).

Type Instruction Assembleur Mise à jour Opération

Logique

AND AND Rs, Rd Z Rs . Rd -> Rd

XOR XOR Rs, Rd Z Rs ˆ Rd -> Rd

OR OR Rs, Rd Z Rs | Rd -> Rd

BIC BIC Rs, Rd Z Rs & Rd -> Rd

BIT BIT Rs, Rd Z Rs & Rd

NOT NOT Rs, Rd Z Rs -> Rd

LSL LSL #shift, Rs, Rd N,Z,C {Rs << shif t5 : shif t5b0} -> Rd LSR LSR #shift, Rs, Rd N,Z,C {shif t5b0 : Rs >> shif t5} -> Rd

Signe

SXTB SXTB Rs, Rd N,Z SignExtend(Rs[7 :0]) -> Rd SXTH SXTH Rs, Rd N,Z SignExtend(Rs[15 :0]) -> Rd UXTB UXTB Rs, Rd Z ZeroExtend(Rs[7 :0]) -> Rd UXTH UXTH Rs, Rd Z ZeroExtend(Rs[15 :0]) -> Rd

Arith

ADD Imm ADD #imm, Rd N,Z,C,V Rd + imm8 -> Rd

ADD R ADD Rs, Rd N,Z,C,V Rd + Rs -> Rd

SUB Imm SUB #imm, Rd N,Z,C,V Rd - imm8 -> Rd SUB R SUB Rs, Rd N,Z,C,V Rd - Rs -> Rd

COMP R CMP Rs, Rd N,Z,C,V Rd - Rs

Table5.3 – Récapitulatif des instructions arithmétiques et logiques du Wake Up Controller

Ces instructions ont la plupart d’entre elles deux opérandes provenant du banc de registres R0 à R15, et viennent mettre à jour les bits d’état du processeur N, Z, C, V qui sont les bits qui indiquent si le résultat de l’opération est négatif, nul, s’il a engendré une retenue (Carry) et si le résultat a entrainé un débordement (Overflow) quand le signe du résultat diffère du signe des opérandes.

Ces instructions sont les seules instructions à modifier les bits de statut du processeur qui sont ensuite utilisés par l’unité de branchement pour évaluer si une branche doit être prise ou non.

5.4.3.3 Instructions de branchements

Les instructions de branchements permettent d’évaluer le résultat précédent pour savoir s’il faut sauter à un autre endroit dans le programme ou s’il faut continuer à l’instruction

suivante. Ici la gestion des branchements est simple à mettre en place puisque chaque instruction s’exécute jusqu’à complétion avant de charger l’instruction suivante. Ainsi il n’y a pas besoin d’avoir d’instructions dites de delay slot après un branchement retardé comme il peut y en avoir dans les processeurs pipelinés pour remplir le pipeline le temps que le branchement soit évalué, ou carrément de stopper le remplissage du pipeline le temps que l’instruction de branchement soit exécutée.

Instruction Assembleur Opération Test

BEQ

B{cond}Label

Branch if Z == 1 x == y

BNE Branch if Z == 0 x != y

BHS Branch if C == 1 uint x ≥ uint y

BLO Branch if C == 0 uint x < uint y

BN Branch if N == 1 x < 0

BPZ Branch if N == 0 x > 0

BVS Branch if V == 1 Branch if Overflow

BVC Branch if V == 0 Branch if No Overflow

BHI Branch if C == 1 and Z == 0 uint x > uint y BLS Branch if C == 0 or Z == 1 uint x ≤ uint y

BGE Branch if N == V int x ≥ int y

BLT Branch if N != V int x < int y

BGT Branch if Z == 0 and N == V int x > int y BLE Branch if Z == 1 or N != V int x ≤ int y

BA Branch always Branch Always

Table5.4 – Récapitulatif des instructions de branchement du Wake Up Controller

Lorsque la condition est vraie alors le PC prend l’adresse de branchement qui est égale à la valeur du PC courant plus un offset signé

(@Branch = PC + (SignedExtend(Offset9):0)) ce qui permet de faire des sauts en mé- moire de -512 à 511 octets. Si le branchement n’est pas pris alors le PC s’incrémente de 2 pour sauter à l’instruction suivante.

Le processeur travaille sur des valeurs signées et non signées et les conditions à tester peuvent être de multiples sortes dans un programme c’est pourquoi les conditions à tester doivent prendre en compte les 4 tests plus grand que, plus grand ou égal, plus petit que et plus petit ou égal pour des nombres signés et non signés, ainsi que les tests égal, non égal, positif et négatif. Dans le WUC, les mêmes conditions que dans le jeu d’instructions ARMV6-M ont été utilisées et sont présentés tableau 5.4 avec l’opération de test sur les bits de statut et la condition mathématique équivalente testée.

5.4.3.4 Instructions d’appels aux fonctions

Lorsqu’une fonction est appelée dans le code il faut alors sauvegarder le compteur pro- gramme qui suit la fonction quelque part, mais aussi sauvegarder le contexte des registres généraux dans la mémoire, pour ensuite commencer à exécuter le code de la fonction qui travaille sur les registres généraux. Pour cela une fonction de branchement spéciale Branch

and Link (BL) est implémentée pour sauvegarder l’adresse de retour dans un registre spé-

cial appelé Link Register (LR) et pour faire sauter le programme à l’adresse de la fonction qui est stocker dans un registre général. L’instruction de retour d’une fonction est ému- lée par l’instruction MOV LR, PC. Pour la sauvegarde et la restauration du contexte lors d’appels de fonctions, des instructions PUSH et POP ont été implémentées.

Ces instructions prennent en opérande une liste de registres où les 1 signifient qu’il faut sauvegarder en mémoire ou restaurer le registre depuis la mémoire. Ainsi, en une ins- truction, le processeur est capable de sauvegarder 9 registres en mémoire et d’en restaurer 8 tout en ayant la possibilité de faire brancher le PC au précédent LR sauvé. Cela évite d’utiliser une multitude de load et store et accélère les appels et sorties de fonctions. Un

Jeu d’instructions et spécifications 77

Instruction Assembleur Opération

BL BL Rd PC + 2 -> LR ; Rd & 0xFFFE -> PC

RET* RET LR -> PC

PUSH PUSH opt, Reglist

Push LR(if opt == 1) and Register onto stack ([R13 R12 R11 R10 R9 R8 R5 R4])

where Reglist[i] == 1 POP POP opt, Reglist

Pop data from memory to Register ([R13 R12 R11 R10 R9 R8 R5 R4]) where Reglist[i] ==

1 and (if opt == 1) load data to PC *émulée par MOV

Table5.5 – Récapitulatif des instructions de support d’appels aux fonctions du Wake Up Control-

ler

exemple de PUSH et POP et de l’état de la pile après leur exécution est présenté figure 5.3. Lors d’un PUSH le pointeur de pile est décrémenté alors qu’avec un POP il s’incrémente.

Figure5.3 – Opération d’une instruction PUSH et POP et état de la pile en mémoire

5.4.3.5 Instructions spéciales

Le processeur ne fonctionnant que sur interruptions. Il a donc besoin de connaitre la fin de la routine d’interruption. Pour cela une instruction ENDIT a été implémentée pour que le processeur arrête de charger des instructions et pour que le contrôleur d’interruption soit informé afin qu’il évalue l’interruption la plus prioritaire (tableau 5.6). Dans le cas où une nouvelle interruption est en attente il l’indique immédiatement au cœur sinon celui ci se met en état de veille.

Instruction Assembleur Opération

ENDIT ENDIT Indique la fin d’une interruption BREAK BREAK met le cœur en attente jusqu’à ce qu’il reçoive

un signal de continuation

Table5.6 – Récapitulatif des instructions spéciales du Wake Up Controller

Dans le cadre du débogage sur puce, il est très intéressant de pouvoir poser des points d’arrêt, c’est pourquoi une instruction BREAK a été implémentée pour que le cœur s’arrête et ne charge plus de nouvelles instructions. L’instruction BREAK est écrite à la place de l’instruction sur laquelle on veut s’arrêter. Dès que l’instruction BREAK est décodée, le cœur est en attente de commandes pour relancer le cœur ou faire du pas à pas sur le code. Le principe de fonctionnement sera expliqué dans le détail section 5.5.5. Avant de

relancer le cœur il faut veiller à bien réécrire l’instruction qui a été remplacée par le Break en mémoire.

5.4.3.6 Encodage du jeu d’instructions

Afin de simplifier au maximum le format et le décodage des instructions, celles-ci sont toutes codées sur 16 bits. Le tableau 5.7 liste tous les formats d’instructions, ainsi que les instructions concernées par ces formats. Le WUC possède huit sous formats d’instructions regroupés dans quatre gros formats (séparés par les doubles lignes dans le tableau), ce qui permet de faire le pré-décodage sur les trois premiers bits de l’instruction et de distribuer l’instruction au bon décodeur de format ensuite. Le pré-décodage permet aussi d’identifier immédiatement les instructions spéciales pour en informer la machine d’état du décodeur.

16 bits Instructions

op (5 bits) imm5 Rs (3 bits) Rd (3 bits)

(LDR Imm)*3, (LDRS Imm)*2, (STR Imm)*3, LSL, LSR

op (5 bits) Imm8 Rd (3 bits)

MOVBU, MOVBL, PCREL, ADD Imm,

SUB Imm

op (7 bits) - (1 bit) Rs (4 bits) Rd (4 bits)

MOV R, (LDR R)*3, (LDRS R)*2, (STR

R)*3, AND, XOR, OR, BIC, BIT, NOT,

(SXT)*2, (UXT)*2, ADD R, SUB R,

COMP R op (7 bits) Rs1 (3 bits) Rs2 (3 bits) Rd (3 bits) (LDR R-R)*3, (LDRS

R-R)*2, (STR R-R)*3 op (7 bits) option (1 bit) Reglist (8 bits) PUSH, POP op (3 bits) Cond (4 bits) SignedOffset (9 bits) B<Cond>

op (5 bits) - (7 bits) Rd (4 bits) BL

op (5 bits) - (11 bits) ENDIT, BREAK

Table5.7 – Huit différents formats d’encodage des instructions du Wake Up Controller

Une documentation complète existe sur l’encodage du jeu d’instructions pour plus de détail.