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

Subversion Repositories minimips_superscalar

[/] [minimips_superscalar/] [trunk/] [gasm_with_mult2_instruction/] [src/] [adaptateur.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 mcafruni
/* 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
printf("diff = %d\n", diff);
615
        if (diff==-1)
616
        {       printf("diff-pco = %d\n", diff-(pco));
617
                err_code=S_BAD_ETIQ;
618
                eval_code=EVAL_IMPOSSIBLE;
619
                return NULL;
620
        }
621
                printf("diferente de -1, diff-pco = %d\n", diff-(pco));
622
        diff=diff-(pco);   /* Le PCO ne tient pas encore compte des 4 octets du masque       */
623
        if (diff & 3)           /* Vérif que l'étiquette est bien aligné sur 32 bits         */
624
        {
625
                err_code=S_BAD_ALIGN;
626
                eval_code=EVAL_ERREUR;
627
                return NULL;
628
        }
629
 
630
        valres=code_signed(diff>>2, 16);
631
        if (err_code!=NO_ERR)   /* Si le déplacement est sur plus de 16 bits...              */
632
        {
633
                eval_code=EVAL_ERREUR;
634
                return NULL;
635
        }
636
printf("valres = %d\n", valres);
637
        ALLOC_MASK(res);
638
        if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM);
639
        res->taille=4;
640
        res->valeur=valres;
641
 
642
        err_code=NO_ERR;
643
        eval_code=EVAL_REUSSIE;
644
        return res;
645
}
646
 
647
type_mask * offset3(type_file_lexeme * args)
648
{ return offset(args, 3); }
649
type_mask * offset5(type_file_lexeme * args)
650
{ return offset(args, 5); }
651
 
652
/* Fonction de création d'un masque de 32 bits dont les 16 bits de poids faible
653
 * contiennent la valeur signée tenant sur 16 bits correspondant au lexème étiquette de rang i
654
 * dans la liste de paramètres.                                                             */
655
type_mask * val_etiq(type_file_lexeme * args, int i)
656
{
657
        type_valeur_mask valres;
658
        int diff;
659
        type_mask * res;
660
        type_lexeme * lex;
661
 
662
        lex = argn(args, i);
663
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
664
        {
665
                err_code=S_ARG_INCOMP;
666
                eval_code=EVAL_ERREUR;
667
                return NULL;
668
        }
669
 
670
        diff=find_address_label(lex->valeur.alpha);
671
        if (diff==-1)
672
        {
673
                err_code=S_BAD_ETIQ;
674
                eval_code=EVAL_IMPOSSIBLE;
675
                return NULL;
676
        }
677
 
678
        valres=code_unsigned(diff, 16);
679
        if (err_code!=NO_ERR)   /* Si le déplacement est sur plus de 16 bits...              */
680
        {
681
                eval_code=EVAL_ERREUR;
682
                return NULL;
683
        }
684
 
685
        ALLOC_MASK(res);
686
        if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM);
687
        res->taille=4;
688
        res->valeur=valres;
689
 
690
        err_code=NO_ERR;
691
        eval_code=EVAL_REUSSIE;
692
        return res;
693
}
694
 
695
type_mask * val_etiq3(type_file_lexeme * args)
696
{ return val_etiq(args, 3); }
697
type_mask * val_etiq5(type_file_lexeme * args)
698
{ return val_etiq(args, 5); }
699
 
700
/* Fonction de création d'un masque de 32 bits dont les 26 bits de poids faible
701
 * contiennent l'adresse dans la région courante de 256 Mo tenant sur 28 bits correspondant
702
 * au lexème étiquette de rang i dans la liste de paramètres mais donc les 2 bits de poids
703
 * faible ont été tronqués.                                                                  */
704
type_mask * absolu(type_file_lexeme * args, int i)
705
{
706
        type_valeur_mask valres;
707
        int diff;
708
        type_mask * res;
709
        type_lexeme * lex;
710
 
711
        lex = argn(args, i);
712
        if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type))
713
        {
714
                err_code=S_ARG_INCOMP;
715
                eval_code=EVAL_ERREUR;
716
                return NULL;
717
        }
718
 
719
        diff=find_address_label(lex->valeur.alpha);
720
        if (diff==-1)
721
        {
722
                err_code=S_BAD_ETIQ;
723
                eval_code=EVAL_IMPOSSIBLE;
724
                return NULL;
725
        }
726
        if ((pco >> 26) != (diff >> 26))        /* Test que le saut ne change pas de région  */
727
        {
728
                err_code=S_TOO_FAR;
729
                eval_code=EVAL_ERREUR;
730
                return NULL;
731
        }
732
        diff=diff & 0xFFFFFFF;   /* On ne conserve que les 28 bits de poids faible           */
733
        if (diff & 3)           /* Vérif que l'étiquette est bien aligné sur 32 bits */
734
        {
735
                err_code=S_BAD_ALIGN;
736
                eval_code=EVAL_ERREUR;
737
                return NULL;
738
        }
739
        valres=code_signed(diff>>2, 26);        /* L'offset est codé sur 26 bits             */
740
        if (err_code!=NO_ERR)
741
        {
742
                eval_code=EVAL_ERREUR;
743
                return NULL;
744
        }
745
 
746
        ALLOC_MASK(res);
747
        if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM);
748
        res->taille=4;
749
        res->valeur=valres;
750
 
751
        err_code=NO_ERR;
752
        eval_code=EVAL_REUSSIE;
753
        return res;
754
}
755
 
756
type_mask * absolu1(type_file_lexeme * args)
757
{ return absolu(args, 1); }
758
 
759
/*********************************************************************************************/
760
/* Définition du tableau des correspondances entre nom et fonction de génération de masque.  */
761
/*********************************************************************************************/
762
 
763
type_paire_fonction index_nf[] =
764
        { {"R1S"                , &r1s                  }  /* Codage des opérandes */
765
        , {"R3S"                , &r3s                  }
766
        , {"R5S"                , &r5s                  }
767
        , {"R1T"                , &r1t                  }
768
        , {"R3T"                , &r3t                  }
769
        , {"R5T"                , &r5t                  }
770
        , {"R1D"                , &r1d                  }
771
        , {"R3D"                , &r3d                  }
772
        , {"R5D"                , &r5d                  }
773
        , {"IMM1"               , &imm1                 }
774
        , {"IMM3"               , &imm3                 }
775
        , {"IMM5"               , &imm5                 }
776
        , {"ETIQ3"              , &val_etiq3            }
777
        , {"ETIQ5"              , &val_etiq5            }
778
            , {"SA5"                    , &sa5                          }
779
 
780
        , {"OFFSET3"            , &offset3              } /* Création des masques d'adresse */
781
        , {"OFFSET5"            , &offset5              }
782
        , {"ABSOLU1"            , &absolu1              }
783
 
784
        , {"Ajoute_Etiquette"   , &ajoute_etiquette     } /* Ajoute éiquette */
785
 
786
        , {"Complete_Zeros"     , &complete_zeros       } /* Gestion des directives */
787
        , {"AddEqu"             , &add_equ              }
788
        , {"Dcb_Int"            , &dcb_int              }
789
        , {"Dcb_Alpha"          , &dcb_alpha            }
790
        , {"Dcw_Int"            , &dcw_int              }
791
        , {"Dcw_Alpha"          , &dcw_alpha            }
792
        , {"Org_Int"            , &org_int              }
793
        , {"Org_Label"          , &org_label            }
794
 
795
        , {NULL                 , NULL                  }
796
        };
797
 

powered by: WebSVN 2.1.0

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