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

Subversion Repositories minimips

[/] [minimips/] [trunk/] [gasm/] [src/] [synthetiseur.c] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 louismarie
#include "synthetiseur.h"
2
 
3
/* Autres modules utilisés par le synthétiseur.                                              */
4
#include <debogueur.h>
5
#include <dialogue.h>
6
#include <formateur.h>
7
#include <parametres.h>
8
#include <adaptateur.h>
9
#include <analyseur.h>
10
 
11
/* Cette fonction convertit un masque en talbeau de char équivalent.                         */
12
/* La chaine étant allouée dynamiquement, il conviendra de la libérer après utilisation.     */
13
char * cnv_mask_str(type_mask * m)
14
{
15
        char * res;
16
        int i;
17
        type_valeur_mask v;
18
        if (m==NULL) return NULL;
19
        res = malloc((m->taille)*sizeof(char));
20
        if (res==NULL) DIALOGUE("synthetiseur(cnv_mask_str)", 0, F_ERR_MEM);
21
        v=m->valeur;
22
        for (i=m->taille-1 ; i>=0 ; i--)
23
        {
24
                res[i]= (v & 0xFF);
25
                v>>=8;
26
        }
27
        return res;
28
}
29
 
30
/* numéro de la colonne où l'on écrit le texte du code source dans la liste d'assemblage.   */
31
#define COL_TEXT        (2*sizeof(type_valeur_mask)+10)
32
 
33
/* Cette fonction recopie le flux srce dans dest jusqu'à la ligne fin exclue, sachant que le */
34
/* flux source est supposé positionné à la ligne debut.                                      */
35
/* Le flux srce sera positionné au début de la ligne fin après l'exécution de la fonction.   */
36
/* La fonction retourne le numéro de la ligne à laquelle se trouve effectivement le flux.    */
37
/* Au début de chaque ligne, la fonction écrit son numéro puis \t suivi de COL_TEXT espaces. */
38
int recopie(FILE * srce, FILE * dest, int debut, int fin)
39
{
40
        while (debut<fin)
41
        {
42
                int c;
43
                long col;
44
                fprintf(dest, "%d\t", debut);
45
                /* On complète la tête de ligne avec des espaces.                            */
46
                for (col=0 ; col<COL_TEXT ; col++) fputc(' ', dest);
47
                while ((c=fgetc(srce))!='\n' && c!=EOF) fputc(c, dest);
48
                if (c!='\n') return debut; /* Fin du fichier atteinte.                       */
49
                fputc(c, dest);
50
                ++debut;
51
        }
52
        return debut;
53
}
54
 
55
/* Recopie la ligne courante de srce dans dest, y compris le \n.                             */
56
void ligne_cp(FILE * srce, FILE * dest)
57
{
58
        int c;
59
        while ((c=fgetc(srce))!='\n' && c!=EOF) fputc(c, dest);
60
        if (c=='\n') fputc('\n', dest);
61
}
62
 
63
/* Cette fonction effectue le traitement de seconde passe des données actuellement dans la   */
64
/* file de précode. Le nombre d'erreurs est retourné.                                        */
65
int synthese()
66
{
67
        int err=0;
68
        type_precode * pcd;
69
 
70
        for ( pcd=file_precode ; pcd!=NULL ; pcd=pcd->suivant )
71
        {
72
                int i;
73
 
74
                pco=pcd->pco;
75
 
76
                for (i=0 ; i<pcd->nbr_func ; i++)
77
                {
78
                        type_mask * res;
79
                        res = (pcd->func)[i](pcd->param);
80
 
81
                        switch (eval_code)
82
                        { /* Application du masque généré par la fonction de seconde passe.  */
83
                                case EVAL_REUSSIE       :
84
                                        if (res==NULL || res->taille==0) break;
85
                                        if (pcd->mask==NULL || res->taille!=pcd->mask->taille)
86
                                        { /* On a défini un nouveau masque incompatible.     */
87
                                                DIALOGUE(pcd->fichier_orig,
88
                                                                pcd->ligne_orig, S_FUN_ERR);
89
                                                /* On remplace le précode par une erreur.    */
90
                                                CLEAR_PRECODE(pcd);
91
                                                pcd->erreur=S_FUN_ERR;
92
                                                err++;
93
                                                break;
94
                                        }
95
                                        /* Le nouveau masque est ajouté.                     */
96
                                        pcd->mask->valeur|=res->valeur;
97
                                        break;
98
                                case EVAL_IMPOSSIBLE    : /* En seconde passe, erreur.       */
99
                                case EVAL_ERREUR        :
100
                                        affiche_message(pcd->fichier_orig, pcd->ligne_orig);
101
                                        err++;
102
                                        /* On remplace le précode par une erreur.            */
103
                                        CLEAR_PRECODE(pcd);
104
                                        pcd->erreur=err_code;
105
                                        break;
106
                                default                 :
107
                                        DIALOGUE(pcd->fichier_orig,
108
                                                        pcd->ligne_orig, S_ADAP_ERR);
109
                                        CLEAR_PRECODE(pcd);
110
                                        pcd->erreur=S_ADAP_ERR;
111
                                        err++;
112
                                        break;
113
                        }
114
                        if (res!=NULL) FREE_MASK(res);
115
                }
116
                /* On libère l'espace alloué pour le tableau des fonctions de seconde passe. */
117
                if (pcd->func!=NULL) free(pcd->func);
118
                pcd->func=NULL;
119
                pcd->nbr_func=0;
120
        }
121
        return err;
122
}
123
 
124
 
125
/* Cette fonction est utilisée pour écrire dans un flux le code binaire généré et            */
126
/* actuellement enregistré dans la pile de précode. Il faut au préalable exécuter la seconde */
127
/* passe faute de quoi le code sera incomplet.                                               */
128
void write_objet(FILE * f_obj)
129
{
130
        type_precode * pcd;
131
        int i;
132
        int local_pco=-1;
133
        long c_head=-5; /* Utilisé pour mémoriser la position de l'entête du bloc courant.   */
134
        long n_head; /* Position du nouvel entête de bloc.                                   */
135
        int addimp;
136
        int taille;
137
 
138
        if (f_obj==NULL) DIALOGUE("synthetiseur(write_objet)", 0, F_FLUX_NULL);
139
 
140
        for (pcd=file_precode ; pcd!=NULL ; pcd=pcd->suivant)
141
        {
142
                if (pcd->erreur==NO_ERR && pcd->mask!=NULL)
143
                { /* On ne s'occupe ici que des précodes générant du code.                   */
144
                        char * code_bin;
145
 
146
                        if (pcd->pco!=local_pco)
147
                        { /* Ecriture d'un nouvel entête de bloc en complétion du précédent. */
148
                                n_head=ftell(f_obj);
149
                                addimp=pcd->pco;
150
                                if (c_head!=-5) /* Il ne s'agit pas du premier bloc.         */
151
                                { /* Ecriture de la taille du bloc que l'on ferme.           */
152
                                        /* Calcul de la taille du bloc terminé.              */
153
                                        taille=n_head-c_head-4;
154
                                        /* Ecriture de la taille au bon emplacement.         */
155
                                        fseek(f_obj, c_head+2, SEEK_SET);
156
                                        for (i=1 ; i>=0 ; i--)
157
                                                fputc((taille>>(8*i)) & 0xFF, f_obj);
158
                                        /* Retour au nouveau bloc.                           */
159
                                        fseek(f_obj, n_head, SEEK_SET);
160
                                }
161
                                /* Ecriture de l'adresse d'implantation.                     */
162
                                for (i=1 ; i>=0 ; i--) fputc((addimp>>(8*i)) & 0xFF , f_obj);
163
                                /* Ecriture de 0 pour la taille du prochain bloc.            */
164
                                for (i=0; i<2; i++) fputc(0, f_obj);
165
                                c_head=n_head;
166
                                local_pco=pcd->pco;
167
                        }
168
 
169
                        /* On écrit le masque du précode courant dans le fichier.            */
170
                        code_bin=cnv_mask_str(pcd->mask); /* Conversion du masque.           */
171
                        /* Insertion des caractères dans le fichier objet.                   */
172
                        for (i=0 ; i<pcd->mask->taille ; i++) fputc(code_bin[i], f_obj);
173
                        free(code_bin); /* On libère la chaine allouée.                      */
174
 
175
                        local_pco+=pcd->mask->taille; /* Avancement du pco.                  */
176
                }
177
        }
178
 
179
        /* Ecriture de la taille du dernier bloc.                                            */
180
        n_head=ftell(f_obj);
181
        /* Calcul de la taille du bloc terminé.                                              */
182
        taille=n_head-c_head-4;
183
        /* Ecriture de la taille au bon emplacement.                                         */
184
        fseek(f_obj, c_head+2, SEEK_SET);
185
        for (i=1 ; i>=0 ; i--) fputc((taille>>(8*i)) & 0xFF, f_obj);
186
        /* Retour au nouveau bloc, en fin de fichier.                                        */
187
        fseek(f_obj, n_head, SEEK_SET);
188
}
189
 
190
 
191
/* Cette fonction est utilisée pour écrire dans un flux la liste d'assemblage correspondant  */
192
/* aux données enregistrée dans la pile de précode. Il faut au préalable exécuter la seconde */
193
/* passe faute de quoi le code sera incomplet.                                               */
194
void write_liste(FILE * f_lst, FILE * f_src)
195
{
196
        int ligne=1; /* Ligne courante dans le fichier source.                               */
197
        type_precode * pcd_cour=file_precode;
198
 
199
        if (f_lst==NULL) DIALOGUE("synthetiseur(write_liste)", 0, F_FLUX_NULL);
200
 
201
        while (pcd_cour!=NULL)
202
        {
203
                int lbloc; /* Numéro de ligne de l'instruction que l'on va traiter.          */
204
                int pco_ecrit=0; /* Drapeau de controle de l'écriture du pco.                */
205
                long col=0; /* Colonne courante dans la ligne actuelle du fichier.           */
206
                type_precode * pcd;
207
 
208
                lbloc=pcd_cour->ligne_orig; /* Ligne courante dans la source.                */
209
 
210
                /* On recopie la portion de code jusqu'à la ligne ayant généré le précode.   */
211
                ligne=recopie(f_src, f_lst, ligne, lbloc);
212
 
213
                if (ligne!=lbloc)
214
                { /* Le fichier source a changé par rapport aux lignes mémorisées.           */
215
                        DIALOGUE(NULL, 0, W_SRCE_MOD);
216
                        return;
217
                }
218
 
219
                fprintf(f_lst, "%d\t", ligne); /* Ecriture du numéro de la ligne en cours.   */
220
                col=ftell(f_lst); /* On mémorise la colonne de départ.                       */
221
 
222
                for (pcd=pcd_cour ; pcd!=NULL && pcd->ligne_orig==lbloc ; pcd=pcd->suivant)
223
                { /* On parcourt tous les précodes de la ligne.                              */
224
                        if (pcd->erreur==NO_ERR && pcd->mask!=NULL)
225
                        {
226
                                char str[3*sizeof(type_taille_mask)+3];
227
 
228
                                if (!pco_ecrit) /* Le pco n'est écrit que sur les lignes     */
229
                                { /* générant du code et ce une seule fois.                  */
230
                                        fprintf(f_lst, "%04X  ", pcd->pco);
231
                                        pco_ecrit=1;
232
                                }
233
 
234
                                sprintf(str, "%%0%dX", pcd->mask->taille*2);
235
                                fprintf(f_lst, str, pcd->mask->valeur);
236
                        }
237
                }
238
 
239
                /* On complète avec des espaces pour aligner le code source.                 */
240
                for ( col=ftell(f_lst)-col ; col<COL_TEXT ; col++) fputc(' ', f_lst);
241
 
242
                ligne_cp(f_src, f_lst); /* Ecriture de la ligne source du code traité.       */
243
                ligne++;
244
 
245
                while (pcd_cour!=NULL && pcd_cour->ligne_orig==lbloc)
246
                { /* Ecriture des éventuelles erreurs du bloc.                               */
247
                        if (pcd_cour->erreur!=NO_ERR)
248
                        { /* On affiche le message d'erreur dans la liste d'assemblage.      */
249
                                int i;
250
                                err_code=pcd_cour->erreur;
251
                                fputc('\t', f_lst);
252
                                for (i=0; i<COL_TEXT; i++) fputc(' ', f_lst);
253
                                fprintf(f_lst, "%s\n", search_msg());
254
                        }
255
                        pcd_cour=pcd_cour->suivant;
256
                }
257
        }
258
 
259
        /* Recopie de la fin du fichier source dans la liste d'assemblage.                   */
260
        while (!feof(f_src))
261
        {
262
                int i;
263
                fprintf(f_lst, "%d\t", ligne++);
264
                for (i=0; i<COL_TEXT; i++) fputc(' ', f_lst);
265
                ligne_cp(f_src, f_lst);
266
        }
267
        fprintf(f_lst, "\n");
268
 
269
        write_data(f_lst); /* Ecriture des données complémentaires de l'adaptateur.          */
270
}

powered by: WebSVN 2.1.0

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