OpenCores
URL https://opencores.org/ocsvn/minimips/minimips/trunk

Subversion Repositories minimips

[/] [minimips/] [trunk/] [gasm/] [src/] [adaptateur.c] - Blame information for rev 15

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 louismarie
/* Module adaptateur */
2
#include "adaptateur.h"
3
 
4
/* Autres modules du projet utilisés.                                                        */
5
#include <debogueur.h>
6
#include <parametres.h>
7
#include <dialogue.h>
8
#include <formateur.h>
9
#include <preprocesseur.h>
10
 
11
/* Autres modules de la bibliothèque standard.                                               */
12
#include <stdio.h>
13
#include <string.h>
14
 
15
 
16
/*********************************************************************************************/
17
/*                                                                                           */
18
/* POINT D'ENTRÉE PRINCIPAL DU MODULE : RETOURNE LES POINTEURS VERS LES FGM.                 */
19
/*                                                                                           */
20
/*********************************************************************************************/
21
 
22
/* Type utilisé pour enregistrer les paires fonction, pointeur.                              */
23
typedef struct
24
{
25
        char * nom;
26
        type_mask *(*fun)();
27
} type_paire_fonction;
28
 
29
/* Variable contenant les paires nom de fonction , pointeur.                                 */
30
extern type_paire_fonction index_nf[];
31
 
32
/* Cette fonction retourne le pointeur sur la fonction correspondant au nom.                 */
33
type_mask *(*alias(char * nom_fonction))()
34
{
35
        type_paire_fonction * courant;
36
 
37
        for (courant=index_nf ; courant->nom!=NULL ; courant++)
38
                if (!strcasecmp(courant->nom, nom_fonction)) return courant->fun;
39
        return NULL;
40
}
41
 
42
/* Fonctions de l'adaptateur utiles pour la "fermeture" de adaptateur.                       */
43
void fprint_lablist(FILE * flux);       /* fonction d'écriture de la liste des labels.       */
44
void clear_lablist();                   /* fonction de nettoyage de la liste des labels.     */
45
 
46
/* Cette fonction sera appelée à la fin de la synthèse du code assembleur.                   */
47
/* Elle peut écrire dans la liste d'asemblage.                                               */
48
void write_data(FILE * f_lst)
49
{ /* Attention, le flux peut être NULL.                                                      */
50
        if (f_lst!=NULL) fprint_lablist(f_lst);
51
}
52
 
53
/* Cette fonction doit libérer les variables allouées dynamiquement par l'adaptateur.        */
54
void clear_adaptateur()
55
{
56
        clear_lablist();
57
}
58
 
59
/* Drapeau pour le résultat de l'évaluation d'une fonction génératrice de masque.            */
60
/* Ce drapeau peut prendre trois valeur selon le résultat de l'évaluation :                  */
61
/* EVAL_REUSSIE         : l'évaluation a aboutit.                                            */
62
/* EVAL_IMPOSSIBLE      : l'évaluation n'est pas possible dans les conditions actuelles.     */
63
/* EVAL_ERREUR          : la fonction n'est pas applicable dans ce contexte.                 */
64
/* En plus de positionner ce drapeau, les fgm doivent spécifier le code de l'erreur dans la  */
65
/* variable err_code du module erreur.                                                       */
66
int eval_code;
67
 
68
 
69
/*********************************************************************************************/
70
/*                                                                                           */
71
/* FONCTIONS AUXILLIAIRES SPÉCIFIQUES A LA SYNTAXE.                                          */
72
/*                                                                                           */
73
/*********************************************************************************************/
74
 
75
/* Définition des sous-types spécifiés dans le fichier Syntaxe.                              */
76
#define REG     (CODE_TYPE(1))
77
 
78
/* Macro de comparaison de chaine sensible ou non à la casse.                                */
79
#define compare_chaine(c1, c2) (casse_sens ? strcmp(c1,c2):strcasecmp(c1,c2))
80
 
81
/* Définition de la liste des étiquettes.                                                    */
82
typedef struct tmp_file_lbl
83
{
84
        char * label;
85
        int valeur;
86
        struct tmp_file_lbl * suivant;
87
} type_file_lbl;
88
 
89
/* Initialisation de la liste des étiquettes.                                                */
90
type_file_lbl * label=NULL;
91
 
92
/* Retourne le nième élément de la liste des arguments ou NULL s'il n'existe pas.            */
93
type_lexeme * argn(type_file_lexeme * args, int n)
94
{
95
        if (n<0) return NULL;
96
        while (args!=NULL)
97
        {
98
                if (n==0) return args->lexeme;
99
                args = args->suivant;
100
                n--;
101
        }
102
        return NULL;
103
}
104
 
105
/* Cette fonction ajoute l'étiquette dans la liste.                                          */
106
/* Si l'étiquette existe déjà, l'ajout est impossible et le code 0 est retourné.             */
107
/* En cas de succès, la fonction renvoie 1.                                                  */
108
int add_label(char * nom)
109
{
110
        type_file_lbl * nlbl;
111
        type_file_lbl * courant;
112
 
113
        /* On vérifie que l'étiquette n'est pas déjà présente dans la liste.                 */
114
        for (courant = label ; courant!=NULL ; courant=courant->suivant)
115
                if (!compare_chaine(courant->label, nom)) return 0;
116
 
117
        /* Allocation d'un nouveau maillon pour enregistrer la nouvellle étiquette.          */
118
        nlbl = (type_file_lbl *) malloc(sizeof(type_file_lbl));
119
        if (nlbl==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM);
120
        (nlbl->label) = (char *) malloc(strlen(nom)*sizeof(char));
121
        if (nlbl->label==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM);
122
        /* Ajout de l'étiquette à la pile d'étiquettes.                                      */
123
        strcpy(nlbl->label, nom);
124
        nlbl->suivant=label;
125
        nlbl->valeur=pco;
126
        label=nlbl;
127
        return 1;
128
}
129
 
130
/* Fonction de recherche d'une étiquette dans la liste.                                      */
131
/* Si l'étiquette n'existe pas, le code -1 est retourné, sinon on renvoie sa valeur.         */
132
int find_address_label(char * nom)
133
{
134
        type_file_lbl * courant=label;
135
        while (courant!=NULL)
136
        {
137
                if (!compare_chaine(courant->label, nom))
138
                        return courant->valeur;
139
                courant = courant->suivant;
140
        }
141
        return -1;
142
}
143
 
144
/* Fonction d'écriture de la liste des étiquettes dans un flux.                              */
145
void fprint_lablist(FILE * flux)
146
{
147
        type_file_lbl * courant;
148
        if (flux==NULL) DIALOGUE("adaptateur(fprint_lablist)", 0, F_FLUX_NULL);
149
        err_code=B_TABLAB;
150
        fprintf(flux, "%s\n", search_msg());
151
        for (courant=label ; courant!=NULL ; courant=courant->suivant)
152
                fprintf(flux, "%s\t%04X\n", courant->label, courant->valeur);
153
}
154
 
155
/* Fonction de nettoyage de la liste des étiquettes.                                         */
156
void clear_lablist()
157
{
158
        type_file_lbl * courant=label;
159
        while (courant!=NULL)
160
        {
161
                type_file_lbl * tmp=courant;
162
                courant=courant->suivant;
163
                free(tmp->label);
164
                free(tmp);
165
        }
166
}
167
 
168
/* Fonctions de recodage des entiers sur un nombre quelconque de bits.                       */
169
 
170
/* Entiers signés.                                                                           */
171
/* La valeur signée est prise dans l'entier r et le masque généré retourné.                  */
172
/* n spécifie le nombre de bits à utiliser pour coder l'entier.                              */
173
/* En cas de dépassement de la capacité sur n bits signés, le err_code est positionné.       */
174
type_valeur_mask code_signed(int r, int n)
175
{
176
        long int max_taille=0;
177
        int i;
178
 
179
        /* Crée un masque contenant n-1 1 : 0..01..1                                         */
180
        for (i=0; i<n-1; i++) max_taille=(max_taille<<1)+1;
181
        /* Cas ou l'entier est trop long.                                                    */
182
        if (r<(-max_taille-1) || r>max_taille)
183
        {
184
                err_code=S_SIGNED_TL;
185
                return 0;
186
        }
187
        max_taille=(max_taille<<1)+1;   /* On inclut le bit de signe dans le masque          */
188
        r&=max_taille; /* On tronque le nombre.                                              */
189
        err_code=NO_ERR;
190
        return (type_valeur_mask) r;
191
}
192
 
193
/* Entiers non signés.                                                                       */
194
/* La valeur signée est prise dans l'entier r et le masque généré retourné.                  */
195
/* n spécifie le nombre de bits à utiliser pour coder l'entier.                              */
196
/* En cas de dépassement de la capacité sur n bits non signés, le err_code est positionné.   */
197
type_valeur_mask code_unsigned(unsigned int r, int n)
198
{
199
        long unsigned int max_taille=0;
200
        int i;
201
 
202
        /* Crée un masque contenant n 1 : 0..01..1                                           */
203
        for (i=0; i<n; i++) max_taille=(max_taille<<1)+1;
204
        /* Cas ou l'entier est trop long.                                                    */
205
        if (r<0)
206
        {
207
                err_code=S_UNSIGNED_EXPECTED;
208
                return 0;
209
        }
210
        if(r>max_taille)
211
        {
212
                err_code=S_UNSIGNED_TL;
213
                return 0;
214
        }
215
        r&=max_taille; /* On tronque.                                                        */
216
        err_code=NO_ERR;
217
        return (type_valeur_mask) r;
218
}
219
 
220
 
221
/* Cette fonction crée un masque avec les 5 bits codant l'argument i (numéro de registre)    */
222
/* et les positionne à la position j dans le masque de taille tmo.                           */
223
type_mask * rij(type_file_lexeme * args, int i, int j, type_taille_mask tmo)
224
{
225
        type_lexeme * l;
226
        type_mask * res;
227
        type_valeur_mask msk;
228
 
229
        l=argn(args, i);
230
        /* test de la cohérence du type de l'opérande */
231
        if (l==NULL || !TYPE_IS(l, ALPHA) || !SOUS_TYPE_IS(l, REG) || !LIT_MPV(l->type))
232
        {
233
                err_code=S_ARG_INCOMP;
234
                eval_code=EVAL_ERREUR;
235
                return NULL;
236
        }
237
        msk = l->valeur.alpha[1]-'0';
238
        if (strlen(l->valeur.alpha)==3)
239
        {
240
                msk*=10;
241
                msk+=l->valeur.alpha[2]-'0';
242
        }
243
        msk<<=j;
244
        ALLOC_MASK(res);
245
        if (res==NULL) DIALOGUE("adaptateur(rij)",0, F_ERR_MEM);
246
        res->valeur=msk;
247
        res->taille=tmo;
248
        err_code=NO_ERR;
249
        eval_code=EVAL_REUSSIE;
250
        return res;
251
}
252
 
253
/* Cette fonction crée un masque avec les 5 bits codant l'argument i (valeur immédiate)      */
254
/* et les positionne à la position 6 dans le masque de taille tmo.                           */
255
type_mask * shamt(type_file_lexeme * args, int i)
256
{
257
        type_lexeme * l;
258
        type_mask * res;
259
        type_valeur_mask v;
260
 
261
        l=argn(args, i);
262
        /* test de la cohérence du type de l'opérande */
263
        if (l==NULL || !TYPE_IS(l, NUM) || !LIT_MPV(l->type))
264
        {
265
                err_code=S_ARG_INCOMP;
266
                eval_code=EVAL_ERREUR;
267
                return NULL;
268
        }
269
        v=code_unsigned(l->valeur.num, 5);
270
 
271
        if (err_code!=NO_ERR)
272
        {
273
                eval_code=EVAL_ERREUR;
274
                return NULL;
275
        }
276
 
277
        v<<=6;
278
        ALLOC_MASK(res);
279
        if (res==NULL) DIALOGUE("adaptateur(shamt)",0, F_ERR_MEM);
280
        res->valeur=v;
281
        res->taille=4;
282
        err_code=NO_ERR;
283
        eval_code=EVAL_REUSSIE;
284
        return res;
285
}
286
 
287
/*********************************************************************************************/
288
/*                                                                                           */
289
/* DEFINITION DES FONCTIONS GENERATIRCES DE MASQUE ET EXPORTATION DES POINTEURS.             */
290
/*                                                                                           */
291
/*********************************************************************************************/
292
 
293
/* Fonctions de codage des numéros de registre dans différentes conditions.                  */
294
/* err_code est positionné par la fonction rij.                                              */
295
type_mask * r1s(type_file_lexeme * args)
296
{       return rij(args, 1, 21, 4);      }
297
type_mask * r3s(type_file_lexeme * args)
298
{       return rij(args, 3, 21, 4);      }
299
type_mask * r5s(type_file_lexeme * args)
300
{       return rij(args, 5, 21, 4);      }
301
type_mask * r1t(type_file_lexeme * args)
302
{       return rij(args, 1, 16, 4);      }
303
type_mask * r3t(type_file_lexeme * args)
304
{       return rij(args, 3, 16, 4);      }
305
type_mask * r5t(type_file_lexeme * args)
306
{       return rij(args, 5, 16, 4);      }
307
type_mask * r1d(type_file_lexeme * args)
308
{       return rij(args, 1, 11, 4);      }
309
type_mask * r3d(type_file_lexeme * args)
310
{       return rij(args, 3, 11, 4);      }
311
type_mask * r5d(type_file_lexeme * args)
312
{       return rij(args, 5, 11, 4);      }
313
 
314
/* Codage du shift amount lu à la position 5 de la liste d'args                              */
315
type_mask * sa5(type_file_lexeme * args)
316
{       return shamt(args, 5);   }
317
 
318
/* Fonction d'ajout d'une étiquette dans la table (déclaration).                             */
319
type_mask * ajoute_etiquette(type_file_lexeme * args)
320
{
321
        type_lexeme * lex=argn(args, 0);
322
        /* Si le lexème n'est pas un ALPHA ou s'il n'a pas de valeur.                        */
323
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
324
        {       /* Argument incorrect.                                                       */
325
                err_code=S_ARG_INCOMP;
326
                eval_code=EVAL_ERREUR;
327
                return NULL;
328
        }
329
        if (!add_label(lex->valeur.alpha))
330
        {       /* L'étiquette existe déjà dans la liste. Impossible de l'ajouter.           */
331
                err_code=S_REDEF_ETIQ;
332
                eval_code=EVAL_ERREUR;
333
                return NULL;
334
        }
335
        err_code=NO_ERR;
336
        eval_code=EVAL_REUSSIE;
337
        return NULL;
338
}
339
 
340
 
341
/* Fonction de création d'un masque de zéros pour atteindre un adresse congrue à 4.          */
342
type_mask * complete_zeros(type_file_lexeme * args)
343
{
344
        type_mask * res;
345
        int n=pco%4;
346
        /* Calcule le nombre de zéros manquants pour s'aligner sur une adresse congrue à 4.  */
347
        if (n==0) n=4;
348
        n=4-n;
349
 
350
        ALLOC_MASK(res);
351
        if (res==NULL) DIALOGUE("adaptateur(complete_zeros)", 0, F_ERR_MEM);
352
        res->taille=n;
353
        res->valeur=0;
354
 
355
        err_code=NO_ERR;
356
        eval_code=EVAL_REUSSIE;
357
        return res;
358
}
359
 
360
 
361
type_mask * org_int(type_file_lexeme * args)
362
{
363
        type_lexeme * p;
364
 
365
        p=argn(args, 1);
366
        if (p==NULL || !TYPE_IS(p, NUM))
367
        {
368
                err_code=S_ARG_INCOMP;
369
                eval_code=EVAL_ERREUR;
370
                return NULL;
371
        }
372
        pco=p->valeur.num;
373
        err_code=NO_ERR;
374
        eval_code=EVAL_REUSSIE;
375
        return NULL;
376
}
377
 
378
 
379
type_mask * org_label(type_file_lexeme * args)
380
{
381
        type_lexeme * p;
382
        int adr;
383
 
384
        p=argn(args, 1);
385
        if (p==NULL || !TYPE_IS(p, ALPHA))
386
        {
387
                err_code=S_ARG_INCOMP;
388
                eval_code=EVAL_ERREUR;
389
                return NULL;
390
        }
391
 
392
        adr=find_address_label(p->valeur.alpha);
393
 
394
        if (adr==-1)
395
        { /* Tentative d'implantation à une adresse inconnue.                                */
396
                err_code=S_ADR_INCONNUE;
397
                eval_code=EVAL_ERREUR;
398
                return NULL;
399
        }
400
 
401
        pco=adr;
402
        err_code=NO_ERR;
403
        eval_code=EVAL_REUSSIE;
404
        return NULL;
405
}
406
 
407
 
408
type_mask * add_equ(type_file_lexeme * args)
409
{
410
        FILE * f;
411
        type_lexeme * p1, * p2;
412
 
413
        p1=argn(args, 0);
414
        p2=argn(args, 2);
415
        if (p1==NULL || p2==NULL || !TYPE_IS(p1, ALPHA)
416
                || (!TYPE_IS(p2, ALPHA) && !TYPE_IS(p2, NUM)))
417
        {
418
                err_code=S_ARG_INCOMP;
419
                eval_code=EVAL_ERREUR;
420
                return NULL;
421
        }
422
 
423
        f=tmpfile();
424
        if (f==NULL) DIALOGUE("adaptateur(add_equ)",0, F_FLUX_NULL);
425
 
426
        if (TYPE_IS(p2, ALPHA))
427
        {
428
                fprintf(f, " {} {} { %s } ", p2->valeur.alpha);
429
        }
430
        else
431
        {
432
                fprintf(f, " {} {} { %d } ", p2->valeur.num);
433
        }
434
 
435
        rewind(f);
436
        ajoute_macro(p1->valeur.alpha, f);
437
        fclose(f);
438
 
439
        err_code=NO_ERR;
440
        eval_code=EVAL_REUSSIE;
441
        return NULL;
442
}
443
 
444
/* Codage de l'entier de rang i dans la liste d'arguments dans les 16 bits de poids faible.  */
445
type_mask * immediate16(type_file_lexeme * args, int i)
446
{
447
        type_lexeme * lex;
448
        type_mask * res;
449
        type_valeur_mask v;
450
 
451
        lex=argn(args, i);
452
 
453
        if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type))
454
        {
455
                err_code=S_ARG_INCOMP;
456
                eval_code=EVAL_ERREUR;
457
                return NULL;
458
        }
459
 
460
        if (lex->valeur.num<0) v=code_signed(lex->valeur.num, 16);
461
        else v=code_unsigned(lex->valeur.num, 16);
462
 
463
        if (err_code!=NO_ERR)
464
        {
465
                eval_code=EVAL_ERREUR;
466
                return NULL;
467
        }
468
 
469
        ALLOC_MASK(res);
470
        if (res==NULL) DIALOGUE("adaptateur(cimm)", 0, F_ERR_MEM);
471
        res->taille=4;
472
        res->valeur=v;
473
        err_code=NO_ERR;
474
        eval_code=EVAL_REUSSIE;
475
        return res;
476
}
477
 
478
/* Acquisistion de la valeur immediate de l'instruction                                      */
479
type_mask * imm1(type_file_lexeme * args)
480
{       return immediate16(args, 1); }
481
type_mask * imm3(type_file_lexeme * args)
482
{       return immediate16(args, 3); }
483
type_mask * imm5(type_file_lexeme * args)
484
{       return immediate16(args, 5); }
485
 
486
/* retourne le masque contenant la valeur val sur n octets.                                  */
487
type_mask * dc(int val, int n)
488
{
489
        type_mask * res;
490
        type_valeur_mask v;
491
 
492
        if (val<0) v=code_signed(val, n*8);
493
        else v=code_unsigned(val, n*8);
494
 
495
        if (err_code!=NO_ERR)
496
        {
497
                eval_code=EVAL_ERREUR;
498
                return NULL;
499
        }
500
 
501
        ALLOC_MASK(res);
502
        if (res==NULL) DIALOGUE("adaptateur(dcb)", 0, F_ERR_MEM);
503
        res->taille=n;
504
        res->valeur=v;
505
        err_code=NO_ERR;
506
        eval_code=EVAL_REUSSIE;
507
        return res;
508
}
509
 
510
/* Retourne le masque pour un entier sur 8 bits en premier argument (numérique)              */
511
type_mask * dcb_int(type_file_lexeme * args)
512
{
513
        type_lexeme * lex;
514
 
515
        lex=argn(args, 1);
516
        if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type))
517
        {
518
                err_code=S_ARG_INCOMP;
519
                eval_code=EVAL_ERREUR;
520
                return NULL;
521
        }
522
 
523
        return dc(lex->valeur.num, 1);
524
}
525
 
526
/* Retourne le masque pour un entier sur 8 bits en premier argument (étiquette)              */
527
type_mask * dcb_alpha(type_file_lexeme * args)
528
{
529
        type_lexeme * lex;
530
        int adr; /* Adresse correspondant à l'étiquette.                                     */
531
 
532
        lex=argn(args, 1);
533
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
534
        {
535
                err_code=S_ARG_INCOMP;
536
                eval_code=EVAL_ERREUR;
537
                return NULL;
538
        }
539
 
540
        adr = find_address_label(lex->valeur.alpha);
541
 
542
        if (adr==-1)
543
        {
544
                err_code=S_BAD_ETIQ;
545
                eval_code=EVAL_IMPOSSIBLE;
546
                return NULL;
547
        }
548
 
549
        return dc(adr, 1);
550
}
551
 
552
 
553
/* Retourne le masque pour un entier sur 32 bits en premier argument (numérique)             */
554
type_mask * dcw_int(type_file_lexeme * args)
555
{
556
        type_lexeme * lex;
557
 
558
        lex=argn(args, 1);
559
        if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type))
560
        {
561
                err_code=S_ARG_INCOMP;
562
                eval_code=EVAL_ERREUR;
563
                return NULL;
564
        }
565
 
566
        return dc(lex->valeur.num, 4);
567
}
568
 
569
/* Retourne le masque pour un entier sur 32 bits en premier argument (étiquette)             */
570
type_mask * dcw_alpha(type_file_lexeme * args)
571
{
572
        type_lexeme * lex;
573
        int adr; /* Adresse correspondant à l'étiquette.                                     */
574
 
575
        lex=argn(args, 1);
576
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
577
        {
578
                err_code=S_ARG_INCOMP;
579
                eval_code=EVAL_ERREUR;
580
                return NULL;
581
        }
582
 
583
        adr = find_address_label(lex->valeur.alpha);
584
 
585
        if (adr==-1)
586
        {
587
                err_code=S_BAD_ETIQ;
588
                eval_code=EVAL_IMPOSSIBLE;
589
                return NULL;
590
        }
591
 
592
        return dc(adr, 4);
593
}
594
 
595
/* Fonction de création d'un masque de 32 bits dont les 16 bits de poids faible
596
 * contiennent l'offset signé tenant sur 18 bits correspondant au lexème étiquette de rang i
597
 * dans la liste de paramètres mais donc les 2 bits de poids faible ont été tronqués.        */
598
type_mask * offset(type_file_lexeme * args, int i)
599
{
600
        type_valeur_mask valres;
601
        int diff;
602
        type_mask * res;
603
        type_lexeme * lex;
604
 
605
        lex = argn(args, i);
606
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
607
        {
608
                err_code=S_ARG_INCOMP;
609
                eval_code=EVAL_ERREUR;
610
                return NULL;
611
        }
612
 
613
        diff=find_address_label(lex->valeur.alpha);
614
        if (diff==-1)
615
        {
616
                err_code=S_BAD_ETIQ;
617
                eval_code=EVAL_IMPOSSIBLE;
618
                return NULL;
619
        }
620
        diff=diff-(pco);   /* Le PCO ne tient pas encore compte des 4 octets du masque       */
621
        if (diff & 3)           /* Vérif que l'étiquette est bien aligné sur 32 bits         */
622
        {
623
                err_code=S_BAD_ALIGN;
624
                eval_code=EVAL_ERREUR;
625
                return NULL;
626
        }
627
 
628
        valres=code_signed(diff>>2, 16);
629
        if (err_code!=NO_ERR)   /* Si le déplacement est sur plus de 16 bits...              */
630
        {
631
                eval_code=EVAL_ERREUR;
632
                return NULL;
633
        }
634
 
635
        ALLOC_MASK(res);
636
        if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM);
637
        res->taille=4;
638
        res->valeur=valres;
639
 
640
        err_code=NO_ERR;
641
        eval_code=EVAL_REUSSIE;
642
        return res;
643
}
644
 
645
type_mask * offset3(type_file_lexeme * args)
646
{ return offset(args, 3); }
647
type_mask * offset5(type_file_lexeme * args)
648
{ return offset(args, 5); }
649
 
650
/* Fonction de création d'un masque de 32 bits dont les 16 bits de poids faible
651
 * contiennent la valeur signée tenant sur 16 bits correspondant au lexème étiquette de rang i
652
 * dans la liste de paramètres.                                                             */
653
type_mask * val_etiq(type_file_lexeme * args, int i)
654
{
655
        type_valeur_mask valres;
656
        int diff;
657
        type_mask * res;
658
        type_lexeme * lex;
659
 
660
        lex = argn(args, i);
661
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
662
        {
663
                err_code=S_ARG_INCOMP;
664
                eval_code=EVAL_ERREUR;
665
                return NULL;
666
        }
667
 
668
        diff=find_address_label(lex->valeur.alpha);
669
        if (diff==-1)
670
        {
671
                err_code=S_BAD_ETIQ;
672
                eval_code=EVAL_IMPOSSIBLE;
673
                return NULL;
674
        }
675
 
676
        valres=code_unsigned(diff, 16);
677
        if (err_code!=NO_ERR)   /* Si le déplacement est sur plus de 16 bits...              */
678
        {
679
                eval_code=EVAL_ERREUR;
680
                return NULL;
681
        }
682
 
683
        ALLOC_MASK(res);
684
        if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM);
685
        res->taille=4;
686
        res->valeur=valres;
687
 
688
        err_code=NO_ERR;
689
        eval_code=EVAL_REUSSIE;
690
        return res;
691
}
692
 
693
type_mask * val_etiq3(type_file_lexeme * args)
694
{ return val_etiq(args, 3); }
695
type_mask * val_etiq5(type_file_lexeme * args)
696
{ return val_etiq(args, 5); }
697
 
698
/* Fonction de création d'un masque de 32 bits dont les 26 bits de poids faible
699
 * contiennent l'adresse dans la région courante de 256 Mo tenant sur 28 bits correspondant
700
 * au lexème étiquette de rang i dans la liste de paramètres mais donc les 2 bits de poids
701
 * faible ont été tronqués.                                                                  */
702
type_mask * absolu(type_file_lexeme * args, int i)
703
{
704
        type_valeur_mask valres;
705
        int diff;
706
        type_mask * res;
707
        type_lexeme * lex;
708
 
709
        lex = argn(args, i);
710
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
711
        {
712
                err_code=S_ARG_INCOMP;
713
                eval_code=EVAL_ERREUR;
714
                return NULL;
715
        }
716
 
717
        diff=find_address_label(lex->valeur.alpha);
718
        if (diff==-1)
719
        {
720
                err_code=S_BAD_ETIQ;
721
                eval_code=EVAL_IMPOSSIBLE;
722
                return NULL;
723
        }
724
        if ((pco >> 26) != (diff >> 26))        /* Test que le saut ne change pas de région  */
725
        {
726
                err_code=S_TOO_FAR;
727
                eval_code=EVAL_ERREUR;
728
                return NULL;
729
        }
730
        diff=diff & 0xFFFFFFF;   /* On ne conserve que les 28 bits de poids faible           */
731
        if (diff & 3)           /* Vérif que l'étiquette est bien aligné sur 32 bits */
732
        {
733
                err_code=S_BAD_ALIGN;
734
                eval_code=EVAL_ERREUR;
735
                return NULL;
736
        }
737
        valres=code_signed(diff>>2, 26);        /* L'offset est codé sur 26 bits             */
738
        if (err_code!=NO_ERR)
739
        {
740
                eval_code=EVAL_ERREUR;
741
                return NULL;
742
        }
743
 
744
        ALLOC_MASK(res);
745
        if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM);
746
        res->taille=4;
747
        res->valeur=valres;
748
 
749
        err_code=NO_ERR;
750
        eval_code=EVAL_REUSSIE;
751
        return res;
752
}
753
 
754
type_mask * absolu1(type_file_lexeme * args)
755
{ return absolu(args, 1); }
756
 
757
/*********************************************************************************************/
758
/* Définition du tableau des correspondances entre nom et fonction de génération de masque.  */
759
/*********************************************************************************************/
760
 
761
type_paire_fonction index_nf[] =
762
        { {"R1S"                , &r1s                  }  /* Codage des opérandes */
763
        , {"R3S"                , &r3s                  }
764
        , {"R5S"                , &r5s                  }
765
        , {"R1T"                , &r1t                  }
766
        , {"R3T"                , &r3t                  }
767
        , {"R5T"                , &r5t                  }
768
        , {"R1D"                , &r1d                  }
769
        , {"R3D"                , &r3d                  }
770
        , {"R5D"                , &r5d                  }
771
        , {"IMM1"               , &imm1                 }
772
        , {"IMM3"               , &imm3                 }
773
        , {"IMM5"               , &imm5                 }
774
        , {"ETIQ3"              , &val_etiq3            }
775
        , {"ETIQ5"              , &val_etiq5            }
776
            , {"SA5"                    , &sa5                          }
777
 
778
        , {"OFFSET3"            , &offset3              } /* Création des masques d'adresse */
779
        , {"OFFSET5"            , &offset5              }
780
        , {"ABSOLU1"            , &absolu1              }
781
 
782
        , {"Ajoute_Etiquette"   , &ajoute_etiquette     } /* Ajoute éiquette */
783
 
784
        , {"Complete_Zeros"     , &complete_zeros       } /* Gestion des directives */
785
        , {"AddEqu"             , &add_equ              }
786
        , {"Dcb_Int"            , &dcb_int              }
787
        , {"Dcb_Alpha"          , &dcb_alpha            }
788
        , {"Dcw_Int"            , &dcw_int              }
789
        , {"Dcw_Alpha"          , &dcw_alpha            }
790
        , {"Org_Int"            , &org_int              }
791
        , {"Org_Label"          , &org_label            }
792
 
793
        , {NULL                 , NULL                  }
794
        };
795
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.