URL
https://opencores.org/ocsvn/minimips_superscalar/minimips_superscalar/trunk
Subversion Repositories minimips_superscalar
Compare Revisions
- This comparison shows the changes necessary to convert path
/minimips_superscalar/trunk
- from Rev 3 to Rev 6
- ↔ Reverse comparison
Rev 3 → Rev 6
/gasm_with_mult2_instruction/include/adaptateur.h
0,0 → 1,50
/* Module adaptateur */ |
#ifndef M_ADAPTATEUR_FLAG |
#define M_ADAPTATEUR_FLAG |
|
|
#include <parametres.h> |
#include <stdio.h> |
|
/*********************************************************************************************/ |
/* DEFINITION DU TYPE MASQUE */ |
|
/*********************************************************************************************/ |
|
typedef short int type_taille_mask; |
typedef unsigned long type_valeur_mask; |
typedef struct |
{ |
type_taille_mask taille; /* taille du masque en octets. */ |
type_valeur_mask valeur; /* valeur du masque sur 64 bits. */ |
} type_mask; |
|
|
/* macro suivante pour simplifier le code. */ |
#define ALLOC_MASK(msk) {\ |
msk = ((type_mask *) malloc(sizeof(type_mask)));\ |
} |
|
#define FREE_MASK(msk) {\ |
free(msk);\ |
} |
|
/*********************************************************************************************/ |
/* EXPORTATION DES FONCTIONS DE L'ADAPTATEUR */ |
/*********************************************************************************************/ |
|
|
typedef type_mask *((*type_ptr_fgm)()); |
|
|
void clear_adaptateur(); /* Fonction de cloture de l'adaptateur. */ |
void write_data(FILE * f_lst); /* Ecriture d'informations dans la lsite. */ |
|
|
|
|
|
#define EVAL_IMPOSSIBLE 1 /* Evaluation impossible (fonction de seconde passe ?) */ |
|
|
#endif |
/gasm_with_mult2_instruction/include/analyseur.h
0,0 → 1,100
/*********************************************************************************************/ |
/* MODULE ANALYSEUR */ |
/* Ce module a pour but de parcourir le fichier assembleur en effectuant la correspondance */ |
|
|
|
|
/*********************************************************************************************/ |
#ifndef M_ANALYSEUR_FLAG |
#define M_ANALYSEUR_FLAG |
|
#include <parametres.h> |
#include <adaptateur.h> |
#include <preparateur.h> |
|
typedef struct file_pcd_tmp |
{ |
|
|
type_ptr_fgm * func; /* Tableau des pointeurs vers ces fonctions. */ |
|
char * fichier_orig; /* Nom du fichier d'origine de l'instruction. */ |
|
struct file_pcd_tmp * suivant; /* Pointeur vers la suite de la file de precode. */ |
|
int pco; /* Adresse d'implantation. */ |
} type_precode; |
|
|
|
|
|
|
|
|
#define ALLOC_PREC(prec) \ |
{\ |
prec = (type_precode *) malloc(sizeof(type_precode));\ |
if (prec==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ |
prec->fichier_orig=NULL;\ |
prec->ligne_orig=0;\ |
prec->mask=NULL;\ |
prec->nbr_func=0;\ |
prec->func=NULL;\ |
prec->param=NULL;\ |
prec->suivant=NULL;\ |
prec->erreur=NO_ERR;\ |
} |
|
|
#define FREE_ARGS(args) \ |
{\ |
type_file_lexeme * courant=args, * suivant;\ |
while (courant!=NULL)\ |
{\ |
suivant=courant->suivant;\ |
FREE_LEX(courant->lexeme);\ |
free(courant);\ |
courant=suivant;\ |
}\ |
args=NULL;\ |
} |
|
|
#define FREE_PRECODE(precode) \ |
{\ |
if (precode->mask) FREE_MASK(precode->mask);\ |
if (precode->nbr_func!=0 && precode->func!=NULL) free(precode->func);\ |
FREE_ARGS(precode->param);\ |
if (precode->fichier_orig) free(precode->fichier_orig);\ |
if (precode->func) free(precode->func);\ |
free(precode);\ |
} |
|
|
/* On conserve toutefois les informations sur l'origine. */ |
#define CLEAR_PRECODE(precode) \ |
{\ |
if (precode->mask) FREE_MASK(precode->mask);\ |
precode->mask=NULL;\ |
if (precode->nbr_func!=0 && precode->func!=NULL) free(precode->func);\ |
precode->func=NULL;\ |
FREE_ARGS(precode->param);\ |
precode->param=NULL;\ |
precode->nbr_func=0;\ |
} |
|
|
|
#define FPRINT_BIN(f, ptrmask) \ |
{\ |
int i;\ |
if (ptrmask)\ |
{\ |
for (i=8*ptrmask->taille-1;i>=0;i--)\ |
fprintf(f, "%c",((ptrmask->valeur>>i) % 2) ? '1' : '0');\ |
}\ |
} |
|
#endif |
/gasm_with_mult2_instruction/include/debogueur.h
0,0 → 1,29
#ifdef DEBUG |
#ifndef M_DEBUG_FLAG |
#define M_DEBUG_FLAG |
|
|
|
#include <stdlib.h> |
#include <stdio.h> |
|
/* "Surcharge" des fonctions malloc et free. */ |
#define malloc(taille) alloc_debug(taille, __LINE__, __FILE__) |
#define free(ptr) free_debug(ptr, __LINE__, __FILE__) |
|
void * alloc_debug(int size, int lg, char * fc); |
void free_debug(void * ptr, int lg, char * fc); |
void print_mem(FILE * f); |
extern int nalloc; |
|
|
#define FPRINT_MALLOC \ |
{\ |
FILE * f;\ |
f=fopen("malloc.debug", "wb");\ |
print_mem(f);\ |
fclose(f);\ |
} |
|
#endif |
#endif |
/gasm_with_mult2_instruction/include/dialogue.h
0,0 → 1,151
/*********************************************************************************************/ |
/* MODULE DIALOGUE */ |
|
|
|
|
/* */ |
/* Le module exporte des noms symboliques pour tous les codes d'erreurs et dispose de deux */ |
|
/* */ |
/*********************************************************************************************/ |
|
#ifndef M_ERREUR_FLAG |
#define M_ERREUR_FLAG |
|
/********************************************************************************************* |
* Identification de l'erreur * |
*********************************************************************************************/ |
|
|
extern int err_code; |
|
|
|
|
|
|
/* Erreurs fatales */ |
#define F_FLUX_NULL 1 /* Tentative de lecture dans un flux NULL */ |
|
|
|
|
/* Erreurs plutot du formateur */ |
#define S_ERR_FORMAT 301 |
#define S_INT_INVALID 302 /* Entier invalide */ |
#define S_ALPHA_LONG 303 /* Alpha trop long */ |
#define S_ALPHA_INVALID 304 |
#define S_CAR_INVALID 305 |
|
|
#define S_CIRCULAR_FILE 401 /* Inclusion circulaire de fichiers */ |
#define S_CIRCULAR_MACRO 402 /* Appel circulaire de macros */ |
|
|
|
|
|
|
|
|
/* Erreurs plutot du du preparateur */ |
#define S_ERR_DCL 501 |
#define S_DCL_VIDE 502 |
#define S_DCL_NON_TERM 503 |
#define S_BAD_PROP 504 |
#define S_BAD_VAL 505 |
#define S_BAD_FUN 506 |
#define S_BAD_ARG 507 |
|
|
|
|
|
|
/* Erreurs pultot de l'analyseur */ |
#define S_SYN_ERR 601 /* Erreur de syntaxe dans le fichier source. */ |
#define S_FUN_ERR 602 /* Erreur lors de l'application des fonctions de l'adapt. */ |
#define S_ADAP_ERR 603 /* Erreur de positionnement du eval_code par l'adaptateur. */ |
|
/* Erreurs plutot de l'adaptateur. */ |
#define S_FUN_INAP 701 /* Erreur, fonction non applicable. */ |
#define S_ARG_INCOMP 702 /* Args incompatbiles, erreur dans fichier Syntaxe. */ |
|
|
|
|
|
|
|
|
|
/* Erreurs plutot du synthetiseur. */ |
|
/* Warnings */ |
|
|
#define W_NO_LIST_STDIN 4003 /* La lecture dans le flux standard aussi */ |
|
|
|
|
|
|
|
#define W_ARG_INC 9001 /* Mauvaise utilisation des arguments */ |
#define W_FICH_DEF_MACRO 9002 /* Fichier macro principal non ouvert */ |
|
|
/* Commentaires. */ |
|
/* Main */ |
#define B_INIT_SYNTAX -901 /* Initialisation de la syntaxe de l'assembleur */ |
|
#define B_LECT_SRC -903 /* Lecture des sources.. */ |
#define B_STR_OBJ -904 /* Enregistrement du fichier objet... */ |
#define B_STR_LST -905 /* Creation de la liste d'assemblage... */ |
#define B_ERR_REP -906 /* Rapport d'erreurs : */ |
|
|
#define B_SYN -909 /* Analyse du code.. */ |
|
|
/* Preparateur */ |
|
|
|
#define B_INIT_D -603 /* Activation du support des macros */ |
#define B_INIT_U -604 /* Activation du support de la supression de macros */ |
#define B_INIT_I -605 /* Activation du support de l'inclusion de fichiers */ |
|
|
|
|
/* Adaptateur */ |
|
|
/* Preprocesseur */ |
|
#define B_MACRO_DISPO -402 /* Voici la liste des macros disponibles */ |
|
/********************************************************************************************* |
|
*********************************************************************************************/ |
|
/* Exportation du controleur de blabla. */ |
extern int verbose; |
|
extern char sep_fich_inclus[]; /* "Inclus depuis" */ |
char * search_msg(); /* Fonction de recherche du message correspondant au code d'erreur. */ |
void display_help(); /* Fonction d'affichage de l'aide en ligne. */ |
|
void affiche_message(char * orig, int ligne); |
|
#define DIALOGUE(ptr_org, ligne, code)\ |
{\ |
err_code=code;\ |
affiche_message(ptr_org, ligne);\ |
} |
|
#endif |
/gasm_with_mult2_instruction/include/formateur.h
0,0 → 1,168
#ifndef M_FORMATEUR_FLAG |
#define M_FORMATEUR_FLAG |
|
/* Modules de la bibliotheque standard */ |
|
#include <stdlib.h> |
#include <stdio.h> |
|
/* Autres modules utilises */ |
|
#include <dialogue.h> |
|
|
/*********************************************************************************************/ |
/* COMPOSITION DES ENSEMBLES DE CARACTERES */ |
/* Tout autre caractere rencontre dans la source sera inconnu et renverra une erreur lors de */ |
/* sa lecture. */ |
/*********************************************************************************************/ |
|
|
#define NBR_ENS 6 /* Nombre d'ensembles existant. */ |
enum {lettre, chiffre, prefixe, sep_explicite, sep_invisible, commentaire}; |
|
|
#define taille_lettre 56 |
#define taille_chiffre 22 |
#define taille_prefixe 6 |
#define taille_sep_explicite 11 |
#define taille_sep_invisible 3 |
#define taille_commentaire 2 |
|
|
extern int *ensemble[NBR_ENS]; |
|
|
#define ACF '}' |
#define ACO '{' |
#define NL '\n' |
#define DP ':' |
#define PF ')' |
#define PO '(' |
#define PS '+' |
#define MS '-' |
#define DIR '#' |
#define VIR ',' |
|
/*********************************************************************************************/ |
/* DEFINITION DES LEXEMES */ |
|
/*********************************************************************************************/ |
|
|
/* type de la structure lexeme. */ |
#define ALPHA 2 |
#define NUM 4 |
#define OP 8 |
|
|
/* trois types de base et 4 pour coder les 15 sous-types possibles. */ |
typedef unsigned char type_type_lex; |
|
/* Definition du type lexeme. */ |
|
|
/* dans tous les autres cas un char aurait suffit. */ |
typedef struct |
{ |
type_type_lex type; |
union |
{ |
char * alpha; /* champ pour coder la valeur d'un ALPHA */ |
int num; /* champ pour coder la valeur d'un NUM */ |
|
} valeur; |
} type_lexeme; |
|
/*********************************************************************************************/ |
/* MACROS DE TRAVAIL SUR LES LEXEMES */ |
|
/*********************************************************************************************/ |
|
/* Le bit 1 du type sert a indiquer la presence d'une valeur. Pour le positionner, on */ |
|
#define MASK_PRESENCE_VALEUR 1 |
/* Les trois macros suivantes permettent respectivement de positionner, de lire et de retire */ |
|
#define POS_MPV(type) ((type) | MASK_PRESENCE_VALEUR) |
#define LIT_MPV(type) ((type) & MASK_PRESENCE_VALEUR) |
#define RET_MPV(type) ((type) & ~MASK_PRESENCE_VALEUR) |
/* Macros de lecture du type de base et du sous-type. */ |
#define BASE_TYPE(ptrlex) (((ptrlex)->type) & 0x0E) /* Masque par 00001110 */ |
#define SOUS_TYPE(ptrlex) (((ptrlex)->type) & 0xF0) /* Masque par 11110000 */ |
|
#define TYPE_IS(ptrlex, tp) (((ptrlex)->type) & tp) |
#define SOUS_TYPE_IS(ptrlex, stp) (SOUS_TYPE(ptrlex)==((stp) & 0xF0)) |
|
#define CODE_TYPE(sst) (ALPHA | ((sst)<<4)) |
|
|
/* macros suivantes pour simplifier le code. */ |
|
#define ALLOC_LEX(lex) {\ |
lex=((type_lexeme *) malloc(sizeof(type_lexeme)));\ |
} |
|
#define FREE_LEX(lex) {\ |
if (TYPE_IS((lex), ALPHA) && LIT_MPV((lex)->type))\ |
free(((lex)->valeur).alpha);\ |
free(lex);\ |
} |
|
|
/* peuvent avoir besoin d'allouer une taille maximale pour celui-ci, notament par exemple */ |
|
|
#define MAX_LONG_ALPHA 128 |
|
|
#define LEX_COPY(ptrl1, ptrl2) \ |
{\ |
(ptrl2)->type = (ptrl1)->type;\ |
if (LIT_MPV((ptrl1)->type)) switch BASE_TYPE(ptrl1)\ |
{\ |
case ALPHA :\ |
(ptrl2)->valeur.alpha=malloc(strlen((ptrl1)->valeur.alpha));\ |
strcpy((ptrl2)->valeur.alpha, (ptrl1)->valeur.alpha);\ |
break;\ |
case NUM :\ |
(ptrl2)->valeur.num=(ptrl1)->valeur.num;\ |
break;\ |
case OP :\ |
(ptrl2)->valeur.op=(ptrl1)->valeur.op;\ |
break;\ |
}\ |
else (ptrl2)->valeur.alpha=NULL;\ |
} |
|
/*********************************************************************************************/ |
/* TYPES DERIVES DU TYPE LEXEME */ |
|
/*********************************************************************************************/ |
|
|
typedef struct file_lexeme_tmp |
{ |
struct file_lexeme_tmp * suivant ; |
type_lexeme * lexeme ; |
} type_file_lexeme ; |
|
/*********************************************************************************************/ |
/* */ |
|
/* */ |
/*********************************************************************************************/ |
|
int fprint_lexeme(FILE * f, type_lexeme * l); |
type_lexeme * get_lexeme(FILE *); |
int strcasecmp(char * s1, char * s2); |
int id_lexeme(type_lexeme *, type_lexeme *, int casse); |
int filtre_lexeme(type_lexeme * l, type_lexeme * filtre, int casse); |
|
|
#define lexcaseid(l1, l2) id_lexeme(l1, l2, 0) |
#define lexid(l1, l2) id_lexeme(l1, l2, 1) |
#define lexcaseftr(l, filtre) filtre_lexeme(l1, filtre, 0) |
#define lexftr(l, filtre) filtre_lexeme(l, filtre, 1) |
|
#endif |
/gasm_with_mult2_instruction/include/parametres.h
0,0 → 1,48
#ifndef M_PARAMETRES_FLAG |
#define M_PARAMETRES_FLAG |
|
#include <formateur.h> |
|
/*********************************************************************************************/ |
/* MODULE CONTENANT LES VARIABLES D'ENVIRONNEMENT */ |
/*********************************************************************************************/ |
|
|
|
|
typedef struct |
{ |
type_type_lex code; |
char * chaine; |
} type_paire; |
|
extern type_paire * regle_typage; |
|
#define MAX_SOUS_TYPES 15 /* Nombre maximum de sous types codables. */ |
|
|
extern int casse_sens; |
|
|
extern char * fich_macro_def; |
|
|
extern char * include_str; |
extern char * define_str; |
extern char * undef_str; |
|
|
extern int nbr_sous_types; |
|
|
extern type_lexeme * seplex; |
|
|
|
/* Exportation du pseudo compteur ordinal. */ |
extern int pco; |
|
/* Activation de la lsite d'assemblage. */ |
extern int active_list; |
|
#endif |
/gasm_with_mult2_instruction/include/preparateur.h
0,0 → 1,85
/*********************************************************************************************/ |
/* MODULE PREPARATEUR */ |
|
|
/* */ |
|
|
/* */ |
/*********************************************************************************************/ |
|
#ifndef M_PREPA_FLAG |
#define M_PREPA_FLAG |
|
#include <formateur.h> |
#include <parametres.h> |
#include <adaptateur.h> |
|
/*********************************************************************************************/ |
/* DEFINITION DE L'ARBRE DE LEXEMES */ |
|
/* se rapporte. */ |
/*********************************************************************************************/ |
|
|
typedef struct |
{ |
type_mask * mask_primaire; /* masque primaire du codage. */ |
char nbr_func; /* nombre de fonctions. */ |
|
} type_feuille; |
|
|
typedef struct noeud_arbre |
{ |
type_lexeme lexeme; |
struct noeud_arbre * ptr_fils; |
struct noeud_arbre * ptr_frere; |
type_feuille * ptr_feuille; |
} type_noeud; |
|
#define ALLOC_FEUILLE(feuille) \ |
{\ |
feuille=(type_feuille *) malloc(sizeof(type_feuille));\ |
if (feuille==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ |
feuille->mask_primaire=NULL;\ |
feuille->nbr_func=0;\ |
feuille->ptr_func=NULL;\ |
} |
|
#define FREE_FEUILLE(feuille) \ |
{\ |
if (feuille->mask_primaire!=NULL) FREE_MASK(feuille->mask_primaire);\ |
if (feuille->ptr_func!=NULL) free(feuille->ptr_func);\ |
free(feuille);\ |
} |
|
#define ALLOC_NOEUD(noeud) \ |
{\ |
noeud=(type_noeud *) malloc(sizeof(type_noeud));\ |
if (noeud==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ |
noeud->lexeme.type=0;\ |
noeud->lexeme.valeur.op=0;\ |
noeud->ptr_fils=NULL;\ |
noeud->ptr_frere=NULL;\ |
noeud->ptr_feuille=NULL;\ |
} |
|
#define FREE_NOEUD(noeud) \ |
{\ |
if (noeud->ptr_feuille!=NULL) FREE_FEUILLE(noeud->ptr_feuille);\ |
free(noeud);\ |
} |
|
|
|
extern type_noeud * root; |
|
|
/* Nombre maximal de fonctions pour une instruction dans le fichier Syntaxe. */ |
#define MAX_FONCTIONS 16 |
|
int init_arbre(char * fichier_syntaxe); |
void clear_preparateur(); |
|
#endif |
/gasm_with_mult2_instruction/include/preprocesseur.h
0,0 → 1,33
#ifndef M_PREPROCESSEUR_FLAG |
#define M_PREPROCESSEUR_FLAG |
|
#include <stdio.h> |
#include <parametres.h> |
|
/******************************************************************************************** |
* POINTS D'ENTREE * |
********************************************************************************************/ |
void push_lexeme(type_lexeme * ptr_recrach); |
type_lexeme * pop_lexeme(); |
|
|
|
|
|
|
|
int init_preprocesseur(char * main_asm); |
void clear_preprocesseur(); |
void suppress_macro(char * nom_macro); |
void ajoute_macro(char * nom_macro, FILE * flux_def); |
void liste_table_macro(FILE *); |
|
/******************************************************************************************** |
* GENERATION DE L'ORIGINE DES LEXEMES POUR LA LOCALISATION D'ERREUR * |
* * |
|
********************************************************************************************/ |
int ligne_courante(); |
char * gen_orig_msg(); |
|
#endif |
/gasm_with_mult2_instruction/include/synthetiseur.h
0,0 → 1,10
#ifndef M_SYNTHETISEUR_FLAG |
#define M_SYNTHETISEUR_FLAG |
|
#include <stdio.h> |
|
int synthese(); |
void write_objet(FILE * f_obj); |
void write_liste(FILE * f_lst, FILE * f_src); |
|
#endif |
/gasm_with_mult2_instruction/src/adaptateur.c
0,0 → 1,797
/* Module adaptateur */ |
#include "adaptateur.h" |
|
|
#include <debogueur.h> |
#include <parametres.h> |
#include <dialogue.h> |
#include <formateur.h> |
#include <preprocesseur.h> |
|
|
#include <stdio.h> |
#include <string.h> |
|
|
/*********************************************************************************************/ |
/* */ |
|
/* */ |
/*********************************************************************************************/ |
|
|
typedef struct |
{ |
char * nom; |
type_mask *(*fun)(); |
} type_paire_fonction; |
|
/* Variable contenant les paires nom de fonction , pointeur. */ |
extern type_paire_fonction index_nf[]; |
|
/* Cette fonction retourne le pointeur sur la fonction correspondant au nom. */ |
type_mask *(*alias(char * nom_fonction))() |
{ |
type_paire_fonction * courant; |
|
for (courant=index_nf ; courant->nom!=NULL ; courant++) |
if (!strcasecmp(courant->nom, nom_fonction)) return courant->fun; |
return NULL; |
} |
|
/* Fonctions de l'adaptateur utiles pour la "fermeture" de adaptateur. */ |
|
void clear_lablist(); /* fonction de nettoyage de la liste des labels. */ |
|
|
|
void write_data(FILE * f_lst) |
|
if (f_lst!=NULL) fprint_lablist(f_lst); |
} |
|
|
void clear_adaptateur() |
{ |
clear_lablist(); |
} |
|
|
|
|
|
/* EVAL_ERREUR : la fonction n'est pas applicable dans ce contexte. */ |
|
/* variable err_code du module erreur. */ |
int eval_code; |
|
|
/*********************************************************************************************/ |
/* */ |
|
/* */ |
/*********************************************************************************************/ |
|
|
#define REG (CODE_TYPE(1)) |
|
|
#define compare_chaine(c1, c2) (casse_sens ? strcmp(c1,c2):strcasecmp(c1,c2)) |
|
|
typedef struct tmp_file_lbl |
{ |
char * label; |
int valeur; |
struct tmp_file_lbl * suivant; |
} type_file_lbl; |
|
|
type_file_lbl * label=NULL; |
|
|
type_lexeme * argn(type_file_lexeme * args, int n) |
{ |
if (n<0) return NULL; |
while (args!=NULL) |
{ |
if (n==0) return args->lexeme; |
args = args->suivant; |
n--; |
} |
return NULL; |
} |
|
|
|
|
int add_label(char * nom) |
{ |
type_file_lbl * nlbl; |
type_file_lbl * courant; |
|
|
for (courant = label ; courant!=NULL ; courant=courant->suivant) |
if (!compare_chaine(courant->label, nom)) return 0; |
|
|
nlbl = (type_file_lbl *) malloc(sizeof(type_file_lbl)); |
if (nlbl==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM); |
(nlbl->label) = (char *) malloc(strlen(nom)*sizeof(char)); |
if (nlbl->label==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM); |
|
strcpy(nlbl->label, nom); |
nlbl->suivant=label; |
nlbl->valeur=pco; |
label=nlbl; |
return 1; |
} |
|
|
|
int find_address_label(char * nom) |
{ |
type_file_lbl * courant=label; |
while (courant!=NULL) |
{ |
if (!compare_chaine(courant->label, nom)) |
return courant->valeur; |
courant = courant->suivant; |
} |
return -1; |
} |
|
|
void fprint_lablist(FILE * flux) |
{ |
type_file_lbl * courant; |
if (flux==NULL) DIALOGUE("adaptateur(fprint_lablist)", 0, F_FLUX_NULL); |
err_code=B_TABLAB; |
fprintf(flux, "%s\n", search_msg()); |
for (courant=label ; courant!=NULL ; courant=courant->suivant) |
fprintf(flux, "%s\t%04X\n", courant->label, courant->valeur); |
} |
|
|
void clear_lablist() |
{ |
type_file_lbl * courant=label; |
while (courant!=NULL) |
{ |
type_file_lbl * tmp=courant; |
courant=courant->suivant; |
free(tmp->label); |
free(tmp); |
} |
} |
|
/* Fonctions de recodage des entiers sur un nombre quelconque de bits. */ |
|
|
|
|
|
type_valeur_mask code_signed(int r, int n) |
{ |
long int max_taille=0; |
int i; |
|
|
for (i=0; i<n-1; i++) max_taille=(max_taille<<1)+1; |
/* Cas ou l'entier est trop long. */ |
if (r<(-max_taille-1) || r>max_taille) |
{ |
err_code=S_SIGNED_TL; |
return 0; |
} |
max_taille=(max_taille<<1)+1; /* On inclut le bit de signe dans le masque */ |
r&=max_taille; /* On tronque le nombre. */ |
err_code=NO_ERR; |
return (type_valeur_mask) r; |
} |
|
|
|
|
|
type_valeur_mask code_unsigned(unsigned int r, int n) |
{ |
long unsigned int max_taille=0; |
int i; |
|
|
for (i=0; i<n; i++) max_taille=(max_taille<<1)+1; |
/* Cas ou l'entier est trop long. */ |
if (r<0) |
{ |
err_code=S_UNSIGNED_EXPECTED; |
return 0; |
} |
if(r>max_taille) |
{ |
err_code=S_UNSIGNED_TL; |
return 0; |
} |
r&=max_taille; /* On tronque. */ |
err_code=NO_ERR; |
return (type_valeur_mask) r; |
} |
|
|
|
|
type_mask * rij(type_file_lexeme * args, int i, int j, type_taille_mask tmo) |
{ |
type_lexeme * l; |
type_mask * res; |
type_valeur_mask msk; |
|
l=argn(args, i); |
|
if (l==NULL || !TYPE_IS(l, ALPHA) || !SOUS_TYPE_IS(l, REG) || !LIT_MPV(l->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
msk = l->valeur.alpha[1]-'0'; |
if (strlen(l->valeur.alpha)==3) |
{ |
msk*=10; |
msk+=l->valeur.alpha[2]-'0'; |
} |
msk<<=j; |
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(rij)",0, F_ERR_MEM); |
res->valeur=msk; |
res->taille=tmo; |
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
|
|
type_mask * shamt(type_file_lexeme * args, int i) |
{ |
type_lexeme * l; |
type_mask * res; |
type_valeur_mask v; |
|
l=argn(args, i); |
|
if (l==NULL || !TYPE_IS(l, NUM) || !LIT_MPV(l->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
v=code_unsigned(l->valeur.num, 5); |
|
if (err_code!=NO_ERR) |
{ |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
v<<=6; |
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(shamt)",0, F_ERR_MEM); |
res->valeur=v; |
res->taille=4; |
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
/*********************************************************************************************/ |
/* */ |
/* DEFINITION DES FONCTIONS GENERATIRCES DE MASQUE ET EXPORTATION DES POINTEURS. */ |
/* */ |
/*********************************************************************************************/ |
|
|
|
type_mask * r1s(type_file_lexeme * args) |
{ return rij(args, 1, 21, 4); } |
type_mask * r3s(type_file_lexeme * args) |
{ return rij(args, 3, 21, 4); } |
type_mask * r5s(type_file_lexeme * args) |
{ return rij(args, 5, 21, 4); } |
type_mask * r1t(type_file_lexeme * args) |
{ return rij(args, 1, 16, 4); } |
type_mask * r3t(type_file_lexeme * args) |
{ return rij(args, 3, 16, 4); } |
type_mask * r5t(type_file_lexeme * args) |
{ return rij(args, 5, 16, 4); } |
type_mask * r1d(type_file_lexeme * args) |
{ return rij(args, 1, 11, 4); } |
type_mask * r3d(type_file_lexeme * args) |
{ return rij(args, 3, 11, 4); } |
type_mask * r5d(type_file_lexeme * args) |
{ return rij(args, 5, 11, 4); } |
|
|
type_mask * sa5(type_file_lexeme * args) |
{ return shamt(args, 5); } |
|
|
type_mask * ajoute_etiquette(type_file_lexeme * args) |
{ |
type_lexeme * lex=argn(args, 0); |
|
if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) |
{ /* Argument incorrect. */ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
if (!add_label(lex->valeur.alpha)) |
|
err_code=S_REDEF_ETIQ; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return NULL; |
} |
|
|
|
type_mask * complete_zeros(type_file_lexeme * args) |
{ |
type_mask * res; |
int n=pco%4; |
|
if (n==0) n=4; |
n=4-n; |
|
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(complete_zeros)", 0, F_ERR_MEM); |
res->taille=n; |
res->valeur=0; |
|
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
|
type_mask * org_int(type_file_lexeme * args) |
{ |
type_lexeme * p; |
|
p=argn(args, 1); |
if (p==NULL || !TYPE_IS(p, NUM)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
pco=p->valeur.num; |
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return NULL; |
} |
|
|
type_mask * org_label(type_file_lexeme * args) |
{ |
type_lexeme * p; |
int adr; |
|
p=argn(args, 1); |
if (p==NULL || !TYPE_IS(p, ALPHA)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
adr=find_address_label(p->valeur.alpha); |
|
if (adr==-1) |
|
err_code=S_ADR_INCONNUE; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
pco=adr; |
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return NULL; |
} |
|
|
type_mask * add_equ(type_file_lexeme * args) |
{ |
FILE * f; |
type_lexeme * p1, * p2; |
|
p1=argn(args, 0); |
p2=argn(args, 2); |
if (p1==NULL || p2==NULL || !TYPE_IS(p1, ALPHA) |
|| (!TYPE_IS(p2, ALPHA) && !TYPE_IS(p2, NUM))) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
f=tmpfile(); |
if (f==NULL) DIALOGUE("adaptateur(add_equ)",0, F_FLUX_NULL); |
|
if (TYPE_IS(p2, ALPHA)) |
{ |
fprintf(f, " {} {} { %s } ", p2->valeur.alpha); |
} |
else |
{ |
fprintf(f, " {} {} { %d } ", p2->valeur.num); |
} |
|
rewind(f); |
ajoute_macro(p1->valeur.alpha, f); |
fclose(f); |
|
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return NULL; |
} |
|
/* Codage de l'entier de rang i dans la liste d'arguments dans les 16 bits de poids faible. */ |
type_mask * immediate16(type_file_lexeme * args, int i) |
{ |
type_lexeme * lex; |
type_mask * res; |
type_valeur_mask v; |
|
lex=argn(args, i); |
|
if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
if (lex->valeur.num<0) v=code_signed(lex->valeur.num, 16); |
else v=code_unsigned(lex->valeur.num, 16); |
|
if (err_code!=NO_ERR) |
{ |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(cimm)", 0, F_ERR_MEM); |
res->taille=4; |
res->valeur=v; |
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
/* Acquisistion de la valeur immediate de l'instruction */ |
type_mask * imm1(type_file_lexeme * args) |
{ return immediate16(args, 1); } |
type_mask * imm3(type_file_lexeme * args) |
{ return immediate16(args, 3); } |
type_mask * imm5(type_file_lexeme * args) |
{ return immediate16(args, 5); } |
|
/* retourne le masque contenant la valeur val sur n octets. */ |
type_mask * dc(int val, int n) |
{ |
type_mask * res; |
type_valeur_mask v; |
|
if (val<0) v=code_signed(val, n*8); |
else v=code_unsigned(val, n*8); |
|
if (err_code!=NO_ERR) |
{ |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(dcb)", 0, F_ERR_MEM); |
res->taille=n; |
res->valeur=v; |
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
|
type_mask * dcb_int(type_file_lexeme * args) |
{ |
type_lexeme * lex; |
|
lex=argn(args, 1); |
if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
return dc(lex->valeur.num, 1); |
} |
|
|
type_mask * dcb_alpha(type_file_lexeme * args) |
{ |
type_lexeme * lex; |
|
|
lex=argn(args, 1); |
if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
adr = find_address_label(lex->valeur.alpha); |
|
if (adr==-1) |
{ |
err_code=S_BAD_ETIQ; |
eval_code=EVAL_IMPOSSIBLE; |
return NULL; |
} |
|
return dc(adr, 1); |
} |
|
|
|
type_mask * dcw_int(type_file_lexeme * args) |
{ |
type_lexeme * lex; |
|
lex=argn(args, 1); |
if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
return dc(lex->valeur.num, 4); |
} |
|
|
type_mask * dcw_alpha(type_file_lexeme * args) |
{ |
type_lexeme * lex; |
|
|
lex=argn(args, 1); |
if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
adr = find_address_label(lex->valeur.alpha); |
|
if (adr==-1) |
{ |
err_code=S_BAD_ETIQ; |
eval_code=EVAL_IMPOSSIBLE; |
return NULL; |
} |
|
return dc(adr, 4); |
} |
|
|
|
|
type_mask * offset(type_file_lexeme * args, int i) |
{ |
type_valeur_mask valres; |
int diff; |
type_mask * res; |
type_lexeme * lex; |
|
lex = argn(args, i); |
if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
diff=find_address_label(lex->valeur.alpha); |
printf("diff = %d\n", diff); |
if (diff==-1) |
{ printf("diff-pco = %d\n", diff-(pco)); |
err_code=S_BAD_ETIQ; |
eval_code=EVAL_IMPOSSIBLE; |
return NULL; |
} |
printf("diferente de -1, diff-pco = %d\n", diff-(pco)); |
diff=diff-(pco); /* Le PCO ne tient pas encore compte des 4 octets du masque */ |
|
{ |
err_code=S_BAD_ALIGN; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
valres=code_signed(diff>>2, 16); |
|
{ |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
printf("valres = %d\n", valres); |
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); |
res->taille=4; |
res->valeur=valres; |
|
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
type_mask * offset3(type_file_lexeme * args) |
{ return offset(args, 3); } |
type_mask * offset5(type_file_lexeme * args) |
{ return offset(args, 5); } |
|
|
|
|
type_mask * val_etiq(type_file_lexeme * args, int i) |
{ |
type_valeur_mask valres; |
int diff; |
type_mask * res; |
type_lexeme * lex; |
|
lex = argn(args, i); |
if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
diff=find_address_label(lex->valeur.alpha); |
if (diff==-1) |
{ |
err_code=S_BAD_ETIQ; |
eval_code=EVAL_IMPOSSIBLE; |
return NULL; |
} |
|
valres=code_unsigned(diff, 16); |
|
{ |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); |
res->taille=4; |
res->valeur=valres; |
|
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
type_mask * val_etiq3(type_file_lexeme * args) |
{ return val_etiq(args, 3); } |
type_mask * val_etiq5(type_file_lexeme * args) |
{ return val_etiq(args, 5); } |
|
|
|
|
|
type_mask * absolu(type_file_lexeme * args, int i) |
{ |
type_valeur_mask valres; |
int diff; |
type_mask * res; |
type_lexeme * lex; |
|
lex = argn(args, i); |
if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) |
{ |
err_code=S_ARG_INCOMP; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
diff=find_address_label(lex->valeur.alpha); |
if (diff==-1) |
{ |
err_code=S_BAD_ETIQ; |
eval_code=EVAL_IMPOSSIBLE; |
return NULL; |
} |
|
{ |
err_code=S_TOO_FAR; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
diff=diff & 0xFFFFFFF; /* On ne conserve que les 28 bits de poids faible */ |
|
{ |
err_code=S_BAD_ALIGN; |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
if (err_code!=NO_ERR) |
{ |
eval_code=EVAL_ERREUR; |
return NULL; |
} |
|
ALLOC_MASK(res); |
if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); |
res->taille=4; |
res->valeur=valres; |
|
err_code=NO_ERR; |
eval_code=EVAL_REUSSIE; |
return res; |
} |
|
type_mask * absolu1(type_file_lexeme * args) |
{ return absolu(args, 1); } |
|
/*********************************************************************************************/ |
|
/*********************************************************************************************/ |
|
type_paire_fonction index_nf[] = |
|
, {"R3S" , &r3s } |
, {"R5S" , &r5s } |
, {"R1T" , &r1t } |
, {"R3T" , &r3t } |
, {"R5T" , &r5t } |
, {"R1D" , &r1d } |
, {"R3D" , &r3d } |
, {"R5D" , &r5d } |
, {"IMM1" , &imm1 } |
, {"IMM3" , &imm3 } |
, {"IMM5" , &imm5 } |
, {"ETIQ3" , &val_etiq3 } |
, {"ETIQ5" , &val_etiq5 } |
, {"SA5" , &sa5 } |
|
|
, {"OFFSET5" , &offset5 } |
, {"ABSOLU1" , &absolu1 } |
|
|
|
, {"Complete_Zeros" , &complete_zeros } /* Gestion des directives */ |
, {"AddEqu" , &add_equ } |
, {"Dcb_Int" , &dcb_int } |
, {"Dcb_Alpha" , &dcb_alpha } |
, {"Dcw_Int" , &dcw_int } |
, {"Dcw_Alpha" , &dcw_alpha } |
, {"Org_Int" , &org_int } |
, {"Org_Label" , &org_label } |
|
, {NULL , NULL } |
}; |
|
/gasm_with_mult2_instruction/src/analyseur.c
0,0 → 1,257
/*********************************************************************************************/ |
/* MODULE ANALYSEUR */ |
/* Ce module a pour but de parcourir le fichier assembleur en effectuant la correspondance */ |
|
|
|
|
/*********************************************************************************************/ |
|
#include "analyseur.h" |
|
|
#include <debogueur.h> |
#include <parametres.h> |
#include <dialogue.h> |
#include <formateur.h> |
#include <preprocesseur.h> |
#include <adaptateur.h> |
|
type_precode * file_precode=NULL, * fin_file_precode=NULL; |
|
|
|
|
#define filtre(l, filtre) filtre_lexeme(l, filtre, casse_sens) |
#define compare_lexeme(l1, l2) (casse_sens ? lexid(l1, l2) : lexcaseid(l1,l2)) |
|
|
static type_file_lexeme * ptr_arg=NULL; |
|
|
void push_local(type_lexeme * l) |
{ |
type_file_lexeme * nouv; |
|
nouv = (type_file_lexeme *) malloc(sizeof(type_file_lexeme)); |
if (nouv==NULL) DIALOGUE("analyseur(push_local)", 0, F_ERR_MEM); |
|
nouv->suivant=ptr_arg; |
nouv->lexeme=l; |
ptr_arg=nouv; |
} |
|
|
type_feuille * analyse_rec(type_noeud * n_cour) |
{ |
type_lexeme * l_cour; |
type_noeud * fils_cour; |
|
|
fils_cour=n_cour->ptr_fils; |
|
while (fils_cour!=NULL && l_cour!=NULL) |
{ |
if (filtre(l_cour, &(fils_cour->lexeme))) |
|
type_feuille * rescur; |
rescur=analyse_rec(fils_cour); |
if (rescur!=NULL) |
{ /* Validation de la transition. */ |
push_local(l_cour); /* Ajout dans la file locale. */ |
return rescur; |
} |
} |
|
|
} |
|
|
return (n_cour->ptr_feuille); /* Si la feuille est valide, l'instruction l'est. */ |
} |
|
/*********************************************************************************************/ |
/* */ |
|
|
/* */ |
/*********************************************************************************************/ |
|
|
#define INIT_PRECODE(precode) \ |
{\ |
ALLOC_PREC(precode)\ |
precode->fichier_orig=f_orig;\ |
precode->ligne_orig=l_orig;\ |
precode->pco=pco;\ |
} |
|
|
#define EMPILE_PRECODE(precode) \ |
{\ |
if (file_precode==NULL)\ |
{\ |
file_precode=precode;\ |
fin_file_precode=precode;\ |
}\ |
else\ |
{\ |
fin_file_precode->suivant=precode;\ |
fin_file_precode=precode;\ |
}\ |
} |
|
int analyse() |
{ |
int err=0; |
char * msg_orig = "analyseur(analyse)"; |
type_lexeme * lex; |
|
pco = 0; /* Initialisation du pseudo compteur ordinal. */ |
|
if (seplex == NULL) |
|
DIALOGUE(NULL, 0, W_SEPLEX_INIT); |
seplex=(type_lexeme *) malloc(sizeof(type_lexeme)); |
if (seplex==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM); |
seplex->type = POS_MPV(OP); |
seplex->valeur.op = NL; |
} |
|
|
{ |
int l_orig = ligne_courante(); /* On conserve la ligne de l'instruction. */ |
char * f_orig = gen_orig_msg(); /* On conserve le fichier d'origine. */ |
type_feuille * feuille; |
|
|
feuille = analyse_rec(root); /* Analyse de l'instruction suivante. */ |
|
if (feuille==NULL) |
|
type_lexeme * lex_depile; |
type_precode * err_pcd; |
INIT_PRECODE(err_pcd); |
|
|
|
|
DIALOGUE(f_orig, l_orig, S_SYN_ERR); |
|
while ((lex_depile=pop_lexeme())!=NULL |
&& !compare_lexeme(lex_depile, seplex)) |
|
FREE_LEX(lex_depile); |
} |
if (lex_depile!=NULL) FREE_LEX(lex_depile); /* Efface le "seplex". */ |
} |
else |
|
type_precode * pcd; |
int p2f[MAX_FONCTIONS]; /* tableau des fonctions de seconde passe. */ |
int i; |
INIT_PRECODE(pcd); |
|
|
pcd->param = ptr_arg; |
|
/* Recopie du masque de la feuille. */ |
if (feuille->mask_primaire==NULL) pcd->mask=NULL; |
else |
{ |
ALLOC_MASK(pcd->mask); |
if (pcd->mask==NULL) |
DIALOGUE(msg_orig, 0, F_ERR_MEM); |
pcd->mask->valeur=feuille->mask_primaire->valeur; |
pcd->mask->taille=feuille->mask_primaire->taille; |
} |
|
for (i=0 ; i<feuille->nbr_func ; i++) |
{ /* Tentative d'application des fonctions de l'adaptateur. */ |
type_mask * res = (feuille->ptr_func)[i](ptr_arg); |
|
|
switch (eval_code) |
{ |
|
if (pcd->mask==NULL) |
{ |
pcd->mask=res; /* Pas encore de masque. */ |
|
break; |
} |
|
if (res->taille==pcd->mask->taille) |
{ /* On ajoute le nouveau masque. */ |
pcd->mask->valeur|=res->valeur; |
break; |
} |
|
DIALOGUE(f_orig, l_orig, S_FUN_ERR); |
|
pcd->erreur=S_FUN_ERR; |
err++; |
break; |
case EVAL_IMPOSSIBLE : /* Fonction de seconde passe. */ |
p2f[(int)(pcd->nbr_func)++]=i; |
break; |
case EVAL_ERREUR : /* Erreur de l'adaptateur/Syntaxe. */ |
affiche_message(f_orig, l_orig); |
err++; |
|
pcd->erreur=err_code; |
break; |
default : /* Erreur de l'adaptateur. */ |
DIALOGUE(f_orig, l_orig, S_ADAP_ERR); |
CLEAR_PRECODE(pcd); |
pcd->erreur=S_ADAP_ERR; |
err++; |
break; |
} |
if (res!=NULL) FREE_MASK(res); /* Suppression du masque. */ |
} |
|
if (pcd->nbr_func!=0) /* Recopie des pointeurs vers les p2f. */ |
{ /* Il reste des fonctions de seconde passe. */ |
|
malloc((pcd->nbr_func)*sizeof(type_ptr_fgm)); |
for (i=0; i<pcd->nbr_func; i++) |
{ /* On recopie les fonctions de seconde passe. */ |
(pcd->func)[i]=(feuille->ptr_func)[p2f[i]]; |
} |
} |
else |
{ /* Plus de fonctions de seconde passe, effacement des arguments. */ |
pcd->func = NULL; |
FREE_ARGS(pcd->param); |
} |
|
if ((pcd->mask==NULL || pcd->mask->taille==0) && pcd->func==NULL |
&& pcd->erreur==NO_ERR) |
|
FREE_PRECODE(pcd); |
} |
else |
{ |
EMPILE_PRECODE(pcd); |
if (pcd->mask!=NULL) pco+=pcd->mask->taille; |
} |
|
|
} |
} |
return err; |
} |
|
|
|
void clear_analyseur() |
{ |
while (file_precode!=NULL) |
{ |
type_precode * pcd=file_precode; |
file_precode=pcd->suivant; |
FREE_PRECODE(pcd); |
} |
fin_file_precode=NULL; |
} |
/gasm_with_mult2_instruction/src/dialogue.c
0,0 → 1,226
#include "dialogue.h" |
|
#include <stdio.h> |
#include <stdlib.h> |
|
#include <debogueur.h> |
|
int err_code=0; |
|
int verbose=0; |
|
/* Texte de l'aide en ligne. */ |
char help[]="\n\ |
Assembleur pour le microprocesseur miniMIPS version 1.0\n\ |
Utilisation : asmips [options] [fichier]\n\ |
\n\ |
Exemple : asmips -vo a.obj -l a.lst source.asm\n\ |
\n\ |
Options disponibles :\n\ |
\n\ |
-v active le mode verbeux\n\ |
\n\ |
|
\n\ |
|
\n\ |
-p assemble vers la sortie standard\n\ |
\n\ |
-l nom_fichier nom du fichier pour la liste d'assemblage\n\ |
|
\n\ |
|
\n\ |
|
pseudo-instructions de l'assembleur\n\ |
\n\ |
Notes d'utilisation :\n\ |
\n\ |
|
|
|
\n\ |
|
|
\n\ |
|
\n\ |
shangoue@enserg.fr\n\ |
lmouton@enserg.fr\n\ |
"; |
|
|
typedef struct |
{ |
int code; |
char * chaine; |
} type_paire_msg; |
|
static type_paire_msg message[] = |
|
|
|
|
|
,{ F_ERR_OUV, "Erreur d'ouverture du fichier" } |
|
/* Erreurs du formateur : */ |
|
|
|
|
|
|
,{ S_CIRCULAR_FILE, "Inclusion circulaire de fichier(s)" } |
,{ S_CIRCULAR_MACRO, "Inclusion circulaire de macro" } |
|
|
,{ S_USE_MACRO_EOF, "Fin du fichier inattendue lors de l'utlisation d'une macro" } |
|
|
|
|
|
|
|
|
|
|
|
|
,{ S_BAD_ARG, "Mauvais argument pour la commande SET" } |
|
|
|
|
/* Erreurs de l'analyseur : */ |
,{ S_SYN_ERR, "Erreur de syntaxe" } |
|
,{ S_ADAP_ERR, "Erreur dans la valeur de retour d'une fonction de l'adaptateur" } |
/* Erreurs de l'adaptateur : */ |
|
|
|
|
|
|
,{ S_BAD_ETIQ, "Etiquette inexistante" } |
|
|
|
/* Erreurs du synthetiseur. */ |
|
/* Warnings : */ |
|
|
,{ W_ARG_INC, "Argument incorrect" } |
|
|
|
,{ W_NO_LIST_STDIN, "La lecture dans le flux standard interdit la liste d'assemblage" } |
,{ W_NO_SYNTAX, "Pas de fichier de syntaxe" } |
|
|
|
|
|
|
/* Commentaires */ |
|
/* Main */ |
,{ B_INIT_SYNTAX, "Initialisation de la syntaxe de l'assembleur..." } |
,{ B_INIT_MACRO, "Chargement des pseudo-instructions..." } |
,{ B_LECT_SRC, "Lecture des sources..." } |
,{ B_STR_OBJ, "Enregistrement du fichier objet..." } |
,{ B_STR_LST, "Creation de la liste d'assemblage..." } |
,{ B_ERR_REP, "Rapport d'erreurs :" } |
|
|
|
,{ B_ANA, "Analyse du code..." } |
/* Preparateur */ |
|
|
|
,{ B_INIT_D, "Activation du support des macros" } |
,{ B_INIT_U, "Activation du support de la supression de macros" } |
,{ B_INIT_I, "Activation du support de l'inclusion de fichiers" } |
|
|
|
/* Preprocesseur */ |
|
,{ B_MACRO_DISPO, "Macros disponibles :" } |
/* Adaptateur */ |
|
|
/* Terminateur de la table, ne pas supprimer ! */ |
,{ 0, NULL } |
}; |
|
char sep_fich_inclus[] = " inclus depuis "; |
|
char * search_msg() |
{ |
type_paire_msg * pmsg=message; |
while(pmsg->chaine!=NULL) |
{ |
if (pmsg->code==err_code) return pmsg->chaine; |
pmsg++; |
} |
return message->chaine; |
} |
|
void affiche_message(char * origine, int ligne) |
{ |
if (err_code>=1000) /* Warning */ |
{ |
if (origine && ligne) |
fprintf(stderr, "Attention ! \'%s\' : %d : %s.\n" |
, origine, ligne, search_msg()); |
else if (origine) |
fprintf(stderr, "Attention ! \'%s\' : %s.\n", origine, search_msg()); |
else |
fprintf(stderr, "Attention ! %s.\n", search_msg()); |
} |
else if (err_code < 0) /* Commentaire */ |
{ |
if (verbose) |
{ |
if (origine && ligne) |
fprintf(stderr, "-- \'%s\' : %d : %s\n" |
, origine, ligne, search_msg()); |
else if (origine) |
fprintf(stderr, "-- %s %s\n", search_msg(), origine); |
else |
fprintf(stderr, "-- %s\n", search_msg()); |
} |
} |
else if (err_code<100) /* Fatal Error */ |
{ |
if (origine && ligne) |
fprintf(stderr, "Erreur fatale ! \'%s\' : %d : %s.\n" |
, origine, ligne, search_msg()); |
else if (origine) |
fprintf(stderr, "Erreur fatale ! \'%s\' : %s.\n" |
, origine, search_msg()); |
else |
fprintf(stderr, "Erreur fatale ! %s.\n", search_msg()); |
exit(err_code); |
} |
else /* Erreur de Syntaxe */ |
{ |
if (origine && ligne) |
fprintf(stderr, "\'%s\' : %d : %s.\n" |
, origine, ligne, search_msg()); |
else if (origine) |
fprintf(stderr, "\'%s\' : %s.\n", origine, search_msg()); |
else |
fprintf(stderr, "%s.\n", search_msg()); |
} |
} |
|
void display_help() |
{ /* fonction d'affichage de l'aide en ligne. */ |
fprintf(stderr, help); |
} |
/gasm_with_mult2_instruction/src/formateur.c
0,0 → 1,453
#include "formateur.h" |
|
/* Autres modules utilises */ |
|
#include <debogueur.h> |
#include <dialogue.h> |
|
/* Modules de la bibliotheque standard */ |
|
#include <stdlib.h> |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
|
/*********************************************************************************************/ |
/* COMPOSITION DES ENSEMBLES DE CARACTERES */ |
/* Tout autre caractere rencontre dans la source sera inconnu et renverra une erreur lors de */ |
/* sa lecture. */ |
/*********************************************************************************************/ |
|
|
|
int taille_ensemble[NBR_ENS] = {taille_lettre, taille_chiffre, taille_prefixe, |
taille_sep_explicite, taille_sep_invisible, taille_commentaire}; |
|
|
|
int ens_lettre[taille_lettre] = |
{ |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', |
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', |
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', |
'Z', '_', '.', '?', '$' |
}; |
|
int ens_chiffre[taille_chiffre] = |
{ |
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', |
'b', 'c', 'd', 'e', 'f' |
}; |
|
int ens_prefixe[taille_prefixe] = |
{ |
'@', '%', '&', '+', '-', '\'' |
}; |
|
int ens_sep_explicite[taille_sep_explicite] = |
{ |
ACF, ACO, NL, DP, PF, PO, PS, MS, DIR, VIR, EOF |
}; |
|
int ens_sep_invisible[taille_sep_invisible] = |
{ |
'\t', ' ', '\r' |
}; |
|
int ens_commentaire[taille_commentaire] = |
{ |
';', '\n' |
}; |
|
|
int *ensemble[NBR_ENS] = {ens_lettre, ens_chiffre, ens_prefixe, |
ens_sep_explicite, ens_sep_invisible, ens_commentaire}; |
|
|
char car_ech[] = "nt\\"; |
char seq_ech[] = "\n\t\\"; |
|
|
/*********************************************************************************************/ |
/* MACROS DE TRAVAIL SUR LES ENSEMBLES */ |
|
|
|
/*********************************************************************************************/ |
|
|
#define MASK_ENSEMBLE(ensbl) (1<<ensbl) |
|
|
#define CAR_ENC (ensemble[prefixe][5]) |
|
|
#define DEBUT_COM (ensemble[commentaire][0]) |
#define FIN_COM (ensemble[commentaire][1]) |
|
|
|
#define IGNORE_FIN_COMMENT 0 |
|
|
|
#define CAR_TO_NUM(car) (\ |
((car >= '0') && (car <= '9')) ? (car - '0') :\ |
((car >= 'a') && (car <= 'f')) ? (10 + car - 'a') :\ |
((car >= 'A') && (car <= 'F')) ? (10 + car - 'A') :\ |
0) |
|
|
#define VAL_BASE(prefixe) (\ |
(prefixe == '\'') ? 0 :\ |
(prefixe == '@') ? 16 :\ |
(prefixe == '%') ? 2 :\ |
(prefixe == '&') ? 8 :\ |
10\ |
) |
|
|
#define SGN_INIT(prefixe) (\ |
(prefixe == '-') ? -1 :\ |
1\ |
) |
|
|
/*********************************************************************************************/ |
/* FONCTIONS DE TRAVAIL SUR LES ENSEMBLES */ |
|
/*********************************************************************************************/ |
|
char type_car(int c) |
|
/* chaque ensemble auquel il appartient. */ |
{ |
char type=0; |
int i, j, flag; |
|
for(i=0; i<NBR_ENS; i++) |
{ |
flag =0; |
for (j=0; (j<taille_ensemble[i]) && !flag; j++) |
flag = (c == ensemble[i][j]); |
if (flag) type |= MASK_ENSEMBLE(i); |
} |
return type; |
} |
|
|
/*********************************************************************************************/ |
/* */ |
/* POINT D'ENTREE PRINCIPAL DU MODULE */ |
/* */ |
/* type_lexeme * get_lexeme(FILE * f) */ |
/* */ |
|
|
/* */ |
/*********************************************************************************************/ |
|
type_lexeme * get_lexeme(FILE * f) |
{ |
|
#define LIT_CAR {\ |
if ( (car=fgetc(f) )==EOF && !( feof(f)) )\ |
DIALOGUE("formateur(get_lexeme)",0, F_ERR_LECT);\ |
typ=type_car(car);\ |
} |
|
|
|
#define LIT_SIGNIFICATIF {do LIT_CAR\ |
while((!(typ & ~MASK_ENSEMBLE(sep_invisible))) && typ);\ |
} |
|
int car, typ; |
type_lexeme * ptr_lex; |
|
if (f==NULL) DIALOGUE("formateur(get_lexeme)",0, F_FLUX_NULL); |
|
LIT_SIGNIFICATIF; |
|
if (!typ) |
{ |
err_code=S_CAR_INVALID; |
return NULL; |
} |
|
if (typ & MASK_ENSEMBLE(lettre)) |
{ /* Lire lexeme ALPHA */ |
char memo_string[MAX_LONG_ALPHA]; |
int i=0; |
|
{ |
if (i==MAX_LONG_ALPHA-1) |
{ |
err_code=S_ALPHA_LONG; |
return NULL; |
} |
memo_string[i++]=car; |
LIT_CAR; |
} |
while(typ & (MASK_ENSEMBLE(lettre) | MASK_ENSEMBLE(chiffre))); |
|
|
if ((typ & (MASK_ENSEMBLE(sep_explicite) | MASK_ENSEMBLE(sep_invisible))) |
|| (car == DEBUT_COM)) |
{ |
|
ungetc(car, f); |
memo_string[i]='\0'; |
ALLOC_LEX(ptr_lex); |
if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); |
ptr_lex->type=POS_MPV(ALPHA); |
(ptr_lex->valeur).alpha=(char*) malloc(i+1); |
strcpy((ptr_lex->valeur).alpha, memo_string); |
return ptr_lex; |
} |
else |
{ |
err_code=S_ALPHA_INVALID; |
return NULL; |
} |
} |
|
|
if (typ & (MASK_ENSEMBLE(chiffre) | MASK_ENSEMBLE(prefixe))) |
|
int val, sgn, base, car_in, typ_in, err_sel = 0; |
|
|
/* choix ne serait pas le bon. */ |
car_in = car; |
typ_in = typ; |
|
val = CAR_TO_NUM(car); /* Initialisation de la valeur de l'entier. */ |
sgn = SGN_INIT(car); /* initialistaion du signe de l'entier. */ |
|
|
|
{ |
long pos=ftell(f); |
char * car_trouve; |
int err_ech=0; |
LIT_CAR; |
|
{ |
LIT_CAR; |
if ((car_trouve=strchr(car_ech, car))!=NULL) |
car=*(seq_ech+(car_trouve-car_ech)); |
else err_ech=1; |
} |
val=car; |
LIT_CAR; |
if (err_ech || car!=CAR_ENC) |
{ |
err_sel=1; |
car=car_in; |
typ=typ_in; |
fseek(f,pos-ftell(f),SEEK_CUR); |
} |
else |
{ |
ALLOC_LEX(ptr_lex); |
if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); |
ptr_lex->type=POS_MPV(NUM); |
(ptr_lex->valeur).num=val; |
return ptr_lex; |
} |
} |
|
if (typ & MASK_ENSEMBLE(prefixe)) |
|
|
/* invisibles. */ |
LIT_SIGNIFICATIF; |
val = CAR_TO_NUM(car); |
if (!((typ & MASK_ENSEMBLE(chiffre)) && (val < base))) |
|
ungetc(car, f); |
car = car_in; |
typ = typ_in; |
err_sel = 1; |
} |
} |
|
|
{ |
LIT_CAR; |
while (typ & MASK_ENSEMBLE(chiffre)) |
{ |
int chiffre_val = CAR_TO_NUM(car); |
if (chiffre_val >= base) |
{ |
err_code=S_INT_INVALID; |
return NULL; /* chiffre valide ? */ |
} |
val *= base; |
val += chiffre_val; |
LIT_CAR; |
} |
|
|
if ((typ & (MASK_ENSEMBLE(sep_explicite)|MASK_ENSEMBLE(sep_invisible))) |
|| (car == DEBUT_COM)) |
{ |
ungetc(car, f); |
ALLOC_LEX(ptr_lex); |
if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); |
ptr_lex->type=POS_MPV(NUM); |
(ptr_lex->valeur).num=val*sgn; |
return ptr_lex; |
} |
else |
{ |
err_code=S_INT_INVALID; |
return NULL; |
} |
} |
} |
|
|
if (typ & MASK_ENSEMBLE(sep_explicite)) |
{ /* Lire lexeme operateur. */ |
ALLOC_LEX(ptr_lex); |
if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); |
ptr_lex->type=POS_MPV(OP); |
(ptr_lex->valeur).op=car; |
return ptr_lex; |
} |
|
|
if (car == DEBUT_COM) |
{ /* Epuiser le commentaire. */ |
do |
{ |
LIT_CAR; |
} |
while(car!=FIN_COM && car!=EOF); |
if (!IGNORE_FIN_COMMENT) ungetc(car, f); |
return get_lexeme(f); |
} |
|
|
err_code=S_ERR_FORMAT; |
return NULL; |
} |
|
|
/* Renvoie 1 si l est compatible avec filtre */ |
int filtre_lexeme(type_lexeme * l, type_lexeme * filtre, int casse) |
{ |
int (* compare)(); |
int v_comp=0; |
|
compare = casse ? (void *) &strcmp : (void *) &strcasecmp; |
|
|
if (BASE_TYPE(l) != BASE_TYPE(filtre)) return 0; |
|
if (SOUS_TYPE(filtre)!=0 && SOUS_TYPE(l)!=SOUS_TYPE(filtre)) return 0; |
|
if (!LIT_MPV(l->type) || !LIT_MPV(filtre->type)) v_comp=0; |
else switch (BASE_TYPE(l)) |
{ |
case ALPHA : if ((*compare) (l->valeur.alpha, |
filtre->valeur.alpha)) |
v_comp=0; |
else v_comp=1; |
break; |
case NUM : if (l->valeur.num != filtre->valeur.num) |
v_comp=0; |
else v_comp=1; |
break; |
case OP : if (l->valeur.op != filtre->valeur.op) |
v_comp=0; |
else v_comp=1; |
break; |
default : v_comp=0; |
break; |
} |
|
|
if (LIT_MPV(filtre->type) && (!LIT_MPV(l->type) || !v_comp)) return 0; |
return 1; |
} |
|
|
int id_lexeme(type_lexeme * l1, type_lexeme * l2, int casse) |
{ |
int (* compare)(); |
|
|
|
|
compare = casse ? (void *) &strcmp : (void *) &strcasecmp; |
|
switch BASE_TYPE(l1) |
{ |
case ALPHA : if (!(*compare)(l1->valeur.alpha, l2->valeur.alpha)) |
return 1; |
break; |
case NUM : if (l1->valeur.num == l2->valeur.num) |
return 1; |
break; |
case OP : if (l1->valeur.op == l2->valeur.op) |
return 1; |
break; |
default : return 0; |
break; |
} |
return 0; |
} |
|
|
/*********************************************************************************************/ |
/* */ |
/* POINT D'ENTREE SECONDAIRE DU MODULE */ |
/* */ |
/* void print_lexeme(type_lexeme * l) */ |
/* */ |
|
|
/* */ |
/*********************************************************************************************/ |
|
int fprint_lexeme(FILE * f, type_lexeme * l) |
{ |
#define ALPHA_VAL (l->valeur.alpha) |
#define NUM_VAL (l->valeur.num) |
#define OP_VAL (l->valeur.op) |
long int pos=ftell(f); |
|
switch (BASE_TYPE(l)) |
{ |
case ALPHA : if (LIT_MPV(l->type)) fprintf(f, "%s", ALPHA_VAL); |
break; |
case NUM : if (LIT_MPV(l->type)) fprintf(f, "%d", NUM_VAL); |
break; |
case OP : if (LIT_MPV(l->type)) fprintf(f, "%c", OP_VAL); |
break; |
} |
return ftell(f)-pos; |
} |
|
/********************************************************************************************* |
* * |
* POINT D'ENTREE SECONDAIRE DU MODULE * |
* * |
* int strcasecmp(const char *, const char *) * |
* * |
* Redefinit cette fonction car elle n'est pas posix. * |
* * |
|
* * |
*********************************************************************************************/ |
|
int strcasecmp(char * s1, char * s2) |
{ |
for(; tolower(*s1)==tolower(*s2); s1++, s2++) |
if (*s1=='\0') return 0; |
return (*s1-*s2); |
} |
|
/gasm_with_mult2_instruction/src/parametres.c
0,0 → 1,20
#include "parametres.h" |
|
#include <stdio.h> |
|
#include <debogueur.h> |
#include <formateur.h> |
|
/* Variables d'environnement. */ |
int active_list=1; /* Activation de la lsite d'assemblage. */ |
|
|
|
|
|
|
|
|
|
int nbr_sous_types=0; /* Nombre de sous types admis par la syntaxe. */ |
|
/gasm_with_mult2_instruction/src/preparateur.c
0,0 → 1,786
/*********************************************************************************************/ |
/* MODULE PREPARATEUR */ |
|
|
/* */ |
|
|
/* */ |
/*********************************************************************************************/ |
|
#include "preparateur.h" |
|
|
#include <stdio.h> |
#include <string.h> |
|
|
#include <debogueur.h> |
#include <parametres.h> |
#include <dialogue.h> |
#include <formateur.h> |
#include <adaptateur.h> |
|
|
|
#define string_comp strcasecmp |
#define lexeme_comp lexcaseid |
|
|
|
|
static int ligne=1; |
static char * n_fich; |
static FILE * f_syn; |
|
/*********************************************************************************************/ |
/* */ |
|
/* trouve : */ |
/* */ |
|
|
|
/* */ |
/*********************************************************************************************/ |
|
|
/* TABLES DES MOTS CLEF */ |
typedef struct |
{ |
char * nom; |
type_type_lex code; |
} type_table; |
|
/* Table statique des mots clefs correspondant aux types de base. */ |
|
static type_table table_clef_base[NUM_KEYWORD] = |
{ { "alpha" , ALPHA} |
, { "int" , NUM} |
}; |
|
/* Table dynamique des mots clefs correspondant aux sous types. */ |
static type_table * table_clef_sst=NULL; |
|
|
/* TABLE DES PROPRIETES */ |
#define NUM_PROP 3 |
static char *prop_table[NUM_PROP] = |
{ "TMO" |
, "MSK" |
, "FUN" |
}; |
|
|
|
/* TABLE DES FONCTIONS */ |
|
/* demande du fichier Syntaxe lors de la rencontre de l'instruction SET. */ |
|
/* En cas d'erreur, ces fonctions renvoient 1 et positionnent la variable errcode du module */ |
/* erreur. La fonction appelante se charge de l'affichage de l'erreur. */ |
|
int casse() |
{ |
casse_sens = 1; |
DIALOGUE(NULL, 0, B_CASSE); |
return 0; |
} |
|
int nocasse() |
{ |
casse_sens = 0; |
DIALOGUE(NULL, 0, B_NOCASSE); |
return 0; |
} |
|
|
{ |
long pos=ftell(f_syn); |
type_lexeme * l; |
|
DIALOGUE(NULL, 0, B_MAC_DEF); |
|
l=get_lexeme(f_syn); |
if (l==NULL) |
{ |
err_code=S_BAD_ARG; |
return 1; |
} |
if (!TYPE_IS(l, ALPHA) || !LIT_MPV(l->type)) |
{ |
FREE_LEX(l); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
|
if (fich_macro_def!=NULL) free(fich_macro_def); |
fich_macro_def=l->valeur.alpha; |
|
l->type=RET_MPV(l->type); |
FREE_LEX(l); |
|
err_code = NO_ERR; |
return 0; |
} |
|
int setdefine() |
{ |
long pos=ftell(f_syn); |
type_lexeme * lex; |
|
DIALOGUE(NULL, 0, B_INIT_D); |
|
lex=get_lexeme(f_syn); |
if (lex==NULL) |
{ /* Erreur de lecture de l'argument. */ |
err_code=S_BAD_ARG; |
return 1; |
} |
if (!TYPE_IS(lex,ALPHA)) |
{ /* L'argument n'a pas le bon type. */ |
FREE_LEX(lex); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
if (define_str!=NULL) free(define_str); |
define_str=malloc(strlen(lex->valeur.alpha)+1); |
strcpy(define_str, lex->valeur.alpha); |
FREE_LEX(lex); |
|
err_code = NO_ERR; |
return 0; |
} |
|
int setundef() |
{ |
long pos=ftell(f_syn); |
type_lexeme * lex; |
|
DIALOGUE(NULL, 0, B_INIT_U); |
|
lex=get_lexeme(f_syn); |
if (lex==NULL) |
{ /* Erreur de lecture de l'argument. */ |
err_code=S_BAD_ARG; |
return 1; |
} |
if (!TYPE_IS(lex,ALPHA)) |
{ /* L'argument n'a pas le bon type. */ |
FREE_LEX(lex); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
if (undef_str!=NULL) free(undef_str); |
undef_str=malloc(strlen(lex->valeur.alpha)+1); |
strcpy(undef_str, lex->valeur.alpha); |
FREE_LEX(lex); |
|
err_code = NO_ERR; |
return 0; |
} |
|
int setinclude() |
{ |
long pos=ftell(f_syn); |
type_lexeme * lex; |
|
DIALOGUE(NULL, 0, B_INIT_I); |
|
lex=get_lexeme(f_syn); |
if (lex==NULL) |
{ |
err_code=S_BAD_ARG; |
return 1; /* Erreur de lecture de l'argument. */ |
} |
if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ |
{ |
FREE_LEX(lex); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
|
if (include_str!=NULL) free(include_str); |
include_str=malloc(strlen(lex->valeur.alpha)+1); |
strcpy(include_str, lex->valeur.alpha); |
FREE_LEX(lex); |
|
err_code = NO_ERR; |
return 0; |
} |
|
int setsep() |
{ |
type_lexeme * lex; |
lex=get_lexeme(f_syn); |
|
DIALOGUE(NULL, 0, B_INIT_SEP); |
|
if (lex==NULL) |
{ |
err_code=S_BAD_ARG; |
return 1; |
} |
if (seplex!=NULL) FREE_LEX(seplex); |
if (TYPE_IS(lex, OP) && lex->valeur.op==NL) ligne++; |
seplex=lex; |
|
err_code = NO_ERR; |
return 0; |
} |
|
|
|
int setnumsst() |
{ |
long pos=ftell(f_syn); |
type_lexeme * lex; |
|
DIALOGUE(NULL, 0, B_PREP_SST); |
|
|
{ |
err_code = S_SEC_SST_DEC; |
return 1; |
} |
|
lex=get_lexeme(f_syn); |
if (lex==NULL) |
{ /* Erreur de lecture de l'argument. */ |
err_code=S_BAD_ARG; |
return 1; |
} |
if (!TYPE_IS(lex,NUM)) /* L'argument n'a pas le bon type. */ |
{ |
FREE_LEX(lex); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
sst_max=lex->valeur.num; |
|
FREE_LEX(lex); |
/* Allocation des tables locales et globale des sous types. */ |
regle_typage = (type_paire *) malloc(sst_max*sizeof(type_paire)); |
if (regle_typage==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM); |
table_clef_sst = (type_table*) malloc(sst_max*sizeof(type_table)); |
if (table_clef_sst==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM); |
|
err_code = NO_ERR; |
return 0; |
} |
|
int setnewsst() |
{ |
long pos=ftell(f_syn); |
type_lexeme * lex; |
char * nom, *filtre; |
type_type_lex code; |
int i, bk=0; |
|
DIALOGUE(NULL, 0, B_ADD_SST); |
|
|
if (regle_typage==NULL || table_clef_sst==NULL || nbr_sous_types>=sst_max) |
{ |
err_code=S_BAD_SST_DEC; |
return 1; |
} |
|
/* Lecture du mot clef correspondant au sous-type. */ |
lex=get_lexeme(f_syn); |
if (lex==NULL) |
{ |
err_code=S_BAD_ARG; |
return 1; /* Erreur de lecture de l'argument. */ |
} |
if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ |
{ |
FREE_LEX(lex); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
/* Ajout du mot clef. */ |
nom = lex->valeur.alpha; |
|
lex->type=RET_MPV(lex->type); |
FREE_LEX(lex); |
|
|
|
lex=get_lexeme(f_syn); |
if (lex==NULL) |
{ |
err_code=S_BAD_ARG; |
return 1; /* Erreur de lecture de l'argument. */ |
} |
if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ |
{ |
FREE_LEX(lex); |
free(nom); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
|
filtre=lex->valeur.alpha; |
|
lex->type=RET_MPV(lex->type); |
FREE_LEX(lex); |
|
/* Lecture du code correspondant au sous-type. */ |
lex=get_lexeme(f_syn); |
if (lex==NULL) |
{ |
err_code=S_BAD_ARG; |
return 1; /* Erreur de lecture de l'argument. */ |
} |
if (!TYPE_IS(lex,NUM)) /* L'argument n'a pas le bon type. */ |
{ |
FREE_LEX(lex); |
free(nom); |
free(filtre); |
|
err_code=S_BAD_ARG; |
return 1; |
} |
|
if (lex->valeur.num<0 || lex->valeur.num>MAX_SOUS_TYPES) |
|
FREE_LEX(lex); |
free(nom); |
free(filtre); |
err_code=S_DEP_SST; |
|
return 1; |
} |
code=CODE_TYPE(lex->valeur.num); |
FREE_LEX(lex); |
|
for (i=0 ; i<nbr_sous_types ; i++) |
|
|
if (!bk && table_clef_sst[i].code==code |
&& string_comp(table_clef_sst[i].nom, nom)) |
|
DIALOGUE(nom, 0, W_REDEF_CODE); |
|
} |
|
|
if (!bk && table_clef_sst[i].code!=code |
&& !string_comp(table_clef_sst[i].nom, nom)) |
|
DIALOGUE(nom, 0, W_REDEF_SST); |
|
} |
} |
|
|
table_clef_sst[nbr_sous_types].nom=nom; |
table_clef_sst[nbr_sous_types].code=code; |
regle_typage[nbr_sous_types].chaine=filtre; |
regle_typage[nbr_sous_types].code=code; |
|
|
|
err_code=NO_ERR; |
return 0; |
} |
|
#define SET "SET" /* Nom symbolique de la commande SET. */ |
#define NUM_FONC 9 |
|
|
|
|
struct |
{ |
char * nom; |
int (*fonction)(); |
} fonc_table[NUM_FONC] = |
{ { "CASSE" , &casse} |
, { "NOCASSE" , &nocasse} |
, { "MACROFILE" , ¯ofile} |
, { "UNDEFSTR" , &setundef} |
, { "DEFINESTR" , &setdefine} |
, { "INCLUDESTR" , &setinclude} |
, { "SEP" , &setsep} |
, { "NUMSST" , &setnumsst} |
, { "NEWSST" , &setnewsst} |
}; |
|
|
|
|
#define REINIT \ |
{\ |
if (table_clef_sst!=NULL)\ |
{ /* Vidage de la table des sous types. */\ |
int i;\ |
for (i=0 ; i<nbr_sous_types ; i++) free(table_clef_sst[i].nom);\ |
free(table_clef_sst);\ |
}\ |
table_clef_sst=NULL;\ |
if (fich_macro_def!=NULL) free(fich_macro_def);\ |
fich_macro_def=NULL;\ |
if (define_str!=NULL) free(define_str);\ |
define_str=NULL;\ |
if (undef_str!=NULL) free(undef_str);\ |
undef_str=NULL;\ |
if (include_str!=NULL) free(include_str);\ |
include_str=NULL;\ |
if (seplex!=NULL) FREE_LEX(seplex);\ |
seplex=NULL;\ |
if (regle_typage!=NULL)\ |
{\ |
for ( ; nbr_sous_types>0 ; nbr_sous_types--)\ |
free(regle_typage[nbr_sous_types-1].chaine);\ |
free(regle_typage);\ |
regle_typage=NULL;\ |
}\ |
casse_sens=1;\ |
sst_max=0;\ |
nbr_sous_types=0;\ |
} |
|
|
/*********************************************************************************************/ |
/* FONCTION place_lexeme */ |
/* */ |
/* type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root) */ |
/* */ |
|
|
/* renvoie ce nouveau pointeur. */ |
/* */ |
/*********************************************************************************************/ |
|
type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root) |
{ |
|
type_noeud * cur_fils = (cur_root->ptr_fils); |
|
while (cur_fils != NULL) |
{ |
if (lexeme_comp(l, &(cur_fils->lexeme))) return cur_fils; |
cur_fils = cur_fils->ptr_frere; |
} |
ALLOC_NOEUD(cur_fils); |
cur_fils->ptr_frere = cur_root->ptr_fils; |
LEX_COPY(l, &(cur_fils->lexeme)); |
cur_root->ptr_fils = cur_fils; |
return cur_fils; |
} |
|
|
/*********************************************************************************************/ |
/* FONCTION lit_feuille */ |
/* */ |
/* type_feuille * lit_feuille(FILE * f_syn) */ |
/* */ |
|
|
/* pour les enregistrer et renvoie un pointeur vers celle-ci. En cas d'erreur, un pointeur */ |
|
/* */ |
/*********************************************************************************************/ |
|
#define OPERATEUR (TYPE_IS(lex, OP)) |
#define VAL_OP ((lex->valeur).op) |
#define VAL_ALPHA ((lex->valeur).alpha) |
|
#define ERR_LF(val) {\ |
if (lex!=NULL) FREE_LEX(lex);\ |
if (mask_ptr!=NULL) FREE_MASK(mask_ptr);\ |
DIALOGUE(n_fich, ligne, val);\ |
return NULL;\ |
} |
|
|
|
#define LIT_LEXEME {\ |
do\ |
{\ |
if (lex!=NULL) FREE_LEX(lex);\ |
lex=get_lexeme(f_syn);\ |
if (lex==NULL) ERR_LF(err_code)\ |
if (OPERATEUR && VAL_OP==NL) ligne++;\ |
}\ |
while (OPERATEUR && VAL_OP==NL);\ |
} |
|
#define INIT_MASK {\ |
if (mask_ptr==NULL)\ |
{\ |
ALLOC_MASK(mask_ptr);\ |
mask_ptr->taille=0;\ |
mask_ptr->valeur=0;\ |
}\ |
if (mask_ptr==NULL)\ |
|
} |
|
type_feuille * lit_feuille() |
{ |
char * msg_orig="preparateur(lit_feuille)"; |
int i, c, tmo_lu=0, i_fun=0; |
type_valeur_mask tmp_msk=0; |
type_lexeme * lex=NULL; |
type_ptr_fgm fun_ptr[MAX_FONCTIONS]; |
type_mask * mask_ptr=NULL; |
type_feuille * tmp_feuille; |
|
|
while (!OPERATEUR || (VAL_OP!=EOF && VAL_OP!=ACO)) |
{ |
if (!TYPE_IS(lex, ALPHA)) ERR_LF(S_BAD_PROP); |
|
i=-1; |
while (++i<NUM_PROP && string_comp(prop_table[i], VAL_ALPHA)); |
|
switch (i) |
|
case TMO : LIT_LEXEME; |
if (!TYPE_IS(lex,NUM)) ERR_LF(S_BAD_VAL); |
INIT_MASK; |
tmo_lu=1; |
mask_ptr->taille=(lex->valeur).num; |
break; |
case MSK : LIT_LEXEME; |
if (!TYPE_IS(lex,ALPHA)||VAL_ALPHA[0]!='_') |
ERR_LF(S_BAD_VAL); |
INIT_MASK; |
i=1; tmp_msk=0; |
while ((c=VAL_ALPHA[i++])!='\0') |
{ |
if (c!='0' && c!='1') |
{ |
if (c!='_') ERR_LF(S_BAD_VAL); |
} |
else |
{ |
tmp_msk<<=1; |
tmp_msk+=(c-'0'); |
} |
} |
(mask_ptr->valeur)|=tmp_msk; |
break; |
case FUN : if (i_fun==MAX_FONCTIONS) ERR_LF(S_DEP_FUNC_NB); |
LIT_LEXEME; |
if (!TYPE_IS(lex,ALPHA)) ERR_LF(S_BAD_VAL); |
fun_ptr[i_fun]=alias(VAL_ALPHA); |
if (fun_ptr[i_fun]==NULL) |
{ /* Fonction inexistante. */ |
ERR_LF(S_BAD_FUN); |
} |
i_fun++; |
break; |
default : return NULL; |
} |
LIT_LEXEME; |
} |
|
FREE_LEX(lex); |
ALLOC_FEUILLE(tmp_feuille); |
if (!tmo_lu && mask_ptr!=NULL) |
|
FREE_MASK(mask_ptr); |
mask_ptr=NULL; |
} |
tmp_feuille->mask_primaire=mask_ptr; |
|
|
tmp_feuille->nbr_func=i_fun; |
if (i_fun) |
{ |
tmp_feuille->ptr_func=(type_ptr_fgm *) (malloc(i_fun*sizeof(type_ptr_fgm))); |
if (tmp_feuille->ptr_func==NULL) |
|
while ((i_fun--)>0) |
{ |
tmp_feuille->ptr_func[i_fun] = fun_ptr[i_fun]; |
} |
} |
else tmp_feuille->ptr_func=NULL; |
|
return tmp_feuille; |
} |
|
|
/*********************************************************************************************/ |
/* FONCTION init_arbre */ |
/* */ |
/* int init_arbre(char * fichier_syntaxe) */ |
/* */ |
|
|
|
|
/* */ |
/*********************************************************************************************/ |
|
int init_arbre(char * fichier_syntaxe) |
|
|
#define ERREUR(val) {\ |
DIALOGUE(fichier_syntaxe, ligne, val);\ |
err=1;\ |
} |
|
|
#define LIT_VALIDE {\ |
if (lex!=NULL) FREE_LEX(lex);\ |
while ((lex=get_lexeme(f_syn))==NULL)\ |
{\ |
err=1;\ |
ERREUR(err_code);\ |
}\ |
if (OPERATEUR && VAL_OP==NL) ligne++;\ |
} |
/* Recherche de la prochaine accolade ouvrante (instruction suivante) */ |
#define ACO_SUIV do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF)) |
#define LIGNE_SUIV do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=NL && VAL_OP!=EOF)) |
|
{ |
char * msg_orig="preparateur(init_arbre)"; |
type_lexeme * lex=NULL; |
int err=0,gblerr=0; /* err est vrai lors d'une erreur, gblerr s'il y a eu une erreur */ |
type_noeud * courant; |
type_feuille * feuille=NULL; |
|
|
REINIT; |
ALLOC_NOEUD(root); |
|
f_syn=fopen(fichier_syntaxe, "rb"); /* ouverture du fichier Syntaxe. */ |
if (f_syn==NULL) |
{ |
DIALOGUE(NULL, 0, W_NO_SYNTAX); |
return 0; |
} |
|
n_fich = fichier_syntaxe; /* Positionne la variable commune au module. */ |
|
|
|
{ |
LIT_VALIDE; |
if (TYPE_IS(lex, ALPHA) && !string_comp(VAL_ALPHA, SET)) |
|
int i=-1; |
LIT_VALIDE; |
if (!TYPE_IS(lex, ALPHA)) |
{ |
ERREUR(S_BAD_ARG); |
gblerr++; |
LIGNE_SUIV; |
} |
else |
{ |
while (++i<NUM_FONC && /* Recherche de la fonction. */ |
string_comp(fonc_table[i].nom, VAL_ALPHA)); |
if (i==NUM_FONC) |
|
ERREUR(S_BAD_ARG); |
gblerr++; |
LIGNE_SUIV; |
} |
else if (fonc_table[i].fonction()) |
|
affiche_message(fichier_syntaxe, ligne); |
gblerr++; |
LIGNE_SUIV; |
} |
} |
} |
else if (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF && VAL_OP!=NL)) |
|
gblerr++; |
ERREUR(S_SYN_ERR); |
|
} |
} while (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF)); |
|
|
{ |
courant=root; |
err=0; |
LIT_VALIDE; |
if (OPERATEUR && VAL_OP==EOF) err=2; |
|
else while ((!OPERATEUR || VAL_OP!=ACF) && !err) |
|
if (LIT_MPV(lex->type) && TYPE_IS(lex, ALPHA)) |
{ /* Si on a un mot clef, on ajuste le type (on supprime la valeur) */ |
int i, key=0; |
/* Recherche dans les mots clef de base. */ |
for (i=0 ; i<NUM_KEYWORD && !key ; i++) |
if (!string_comp(table_clef_base[i].nom, VAL_ALPHA)) |
{ |
lex->type=table_clef_base[i].code; |
key=1; |
} |
/* Recherche dans les mots clef des sous-types. */ |
for (i=0 ; i<nbr_sous_types && !key ; i++) |
if (!string_comp(table_clef_sst[i].nom, VAL_ALPHA)) |
{ |
lex->type=table_clef_sst[i].code; |
key=1; |
} |
if (key) free(lex->valeur.alpha); |
} |
courant = place_lexeme(lex, courant); |
LIT_VALIDE; |
if (OPERATEUR && VAL_OP==EOF) ERREUR(S_DCL_NON_TERM); |
} |
|
|
if (courant->ptr_feuille!=NULL) ERREUR(S_REDEF_INS); |
|
if (!err) feuille=lit_feuille(); /* Lecture de la feuille. */ |
|
|
|
if (!err) courant->ptr_feuille=feuille; |
|
gblerr+=(err==1); /* Le code d'erreur est uniquement 1. */ |
} |
while (!OPERATEUR || VAL_OP!=EOF); |
FREE_LEX(lex); |
fclose(f_syn); |
return gblerr; |
} |
|
|
void free_arbre(type_noeud * courant) |
{ |
type_noeud * fils_courant; |
|
if (courant==NULL) return; |
fils_courant=courant->ptr_fils; |
while (fils_courant!=NULL) |
|
free_arbre(fils_courant); |
fils_courant=fils_courant->ptr_frere; |
} |
|
if (TYPE_IS(&(courant->lexeme), ALPHA) && LIT_MPV(courant->lexeme.type) |
&& (courant->lexeme.valeur.alpha!=NULL)) |
free(courant->lexeme.valeur.alpha); |
FREE_NOEUD(courant); |
} |
|
|
void clear_preparateur() |
{ |
free_arbre(root); |
|
REINIT; |
} |
|
/gasm_with_mult2_instruction/src/preprocesseur.c
0,0 → 1,839
/********************************************************************************************* |
* * |
* MODULE PREPROCESSEUR * |
* * |
* Ce module a pour but de fournir sur demande les lexemes correspondant au code * |
|
* * |
* Il gere aussi l'inclusion de fichiers et l'expansion des macros. * |
* * |
|
* * |
*********************************************************************************************/ |
|
|
#include "preprocesseur.h" |
|
|
#include <stdio.h> |
#include <string.h> |
#include <stdlib.h> |
#include <ctype.h> |
|
|
#include <debogueur.h> |
#include <parametres.h> |
#include <dialogue.h> |
#include <formateur.h> |
|
#define SYNTAX_ERROR(CODE)\ |
{\ |
char * msg;\ |
msg=gen_orig_msg();\ |
DIALOGUE(msg, ligne_courante(), CODE);\ |
free(msg);\ |
} |
|
/********************************************************************************************* |
* * |
|
* * |
*********************************************************************************************/ |
|
typedef struct type_pdf_tmp |
{ |
FILE * flux; |
|
char * nom_fich; /* nom du fichier en cours de lecture */ |
char * nom_macro; /* nom de la macro si c'en est une pour eviter l'autoappel */ |
|
} type_pdf; |
|
typedef struct type_pdm_tmp |
{ |
char * nom_macro; /* Lexeme dont la rencontre entraine une expansion */ |
|
struct type_pdm_tmp * suiv; |
} type_pdm; |
|
/********************************************************************************************* |
* * |
|
* * |
*********************************************************************************************/ |
|
|
static type_pdf * ptr_pdf=NULL; |
|
|
static type_file_lexeme * ptr_pdl=NULL; |
|
/* Pointeur vers la fonction strcmp ou strcasecmp selon la casse_sens */ |
static int (*fcmp)()=NULL; |
#define CAR_EQ(a, b) ( casse_sens ? (a==b) : (tolower(a)==tolower(b)) ) |
|
|
static type_pdm * ptr_pdm=NULL; |
|
|
FILE * fich_macro=NULL; |
|
/********************************************************************************************* |
* * |
|
* * |
*********************************************************************************************/ |
|
static void empile_flux(char * nom_fich, char * nom_macro); |
static void depile_flux(); |
static type_pdm * is_macro(char *); |
static type_lexeme * read_lexeme(); |
static type_lexeme * get_true_lexeme(FILE * fich); |
static void expanse_macro(type_pdm * ptr); |
|
void empile_flux(char * nom_fich, char * nom_macro) |
{ |
type_pdf * ptr; |
char errmsg[]="preprocesseur(empile_flux)"; |
|
|
ptr=ptr_pdf; |
while(ptr!=NULL) |
{ |
if (nom_fich) |
if (strcmp(nom_fich, ptr->nom_fich)==0) |
{ |
SYNTAX_ERROR(S_CIRCULAR_FILE) |
return; |
} |
if (nom_macro) |
if (ptr->nom_macro && (*fcmp)(nom_macro, ptr->nom_macro)==0) |
{ |
SYNTAX_ERROR(S_CIRCULAR_MACRO) |
return; |
} |
ptr=ptr->prec; |
} |
|
/* Allocation de la structure */ |
ptr=(type_pdf *) malloc(sizeof(type_pdf)); |
if (!ptr) DIALOGUE(errmsg, 0, F_ERR_MEM); |
|
/* Initialisation des champs */ |
ptr->flux=NULL; |
ptr->ligne=1; |
ptr->nom_fich=NULL; |
ptr->nom_macro=NULL; |
ptr->prec=NULL; |
|
/* Ouverture du fichier */ |
if (nom_fich) |
{ |
ptr->flux=fopen(nom_fich, "rb"); |
if (!ptr->flux) |
{ |
char * msg; |
msg=gen_orig_msg(); |
DIALOGUE(msg, ptr_pdf->ligne, S_FICH_NON_TROUVE); |
free(msg); |
free(ptr); |
return; |
} |
|
/* Recopie des chaines transmises en parametres */ |
ptr->nom_fich=(char *) malloc(strlen(nom_fich)); |
if (!ptr->nom_fich) DIALOGUE(errmsg, 0, F_ERR_MEM); |
strcpy(ptr->nom_fich, nom_fich); |
} |
if (nom_macro) |
{ |
ptr->nom_macro=(char *) malloc(strlen(nom_macro)); |
if (!ptr->nom_macro) DIALOGUE(errmsg, 0, F_ERR_MEM); |
strcpy(ptr->nom_macro, nom_macro); |
} |
|
/* Empilement */ |
ptr->prec=ptr_pdf; |
ptr_pdf=ptr; |
} |
|
void depile_flux() |
{ |
type_pdf * ptr_sav; |
ptr_sav=ptr_pdf->prec; |
fclose(ptr_pdf->flux); |
if (ptr_pdf->nom_macro) |
free(ptr_pdf->nom_macro); |
else |
free(ptr_pdf->nom_fich); |
free(ptr_pdf); |
ptr_pdf=ptr_sav; |
} |
|
/* Cette fonction cherche et retourne la position d'une macro dans la table. */ |
type_pdm * is_macro(char * lex_alpha) |
{ |
type_pdm * ptr_mac; |
for( ptr_mac=ptr_pdm; |
ptr_mac && (*fcmp)(ptr_mac->nom_macro, lex_alpha); |
ptr_mac=ptr_mac->suiv) |
; |
return ptr_mac; |
} |
|
/* Cette fonction renvoie le prochain lexeme valide disponible dans la pile de flux, * |
|
|
|
type_lexeme * read_lexeme() |
{ |
type_lexeme * ptr_lex; |
static int germac=1; /* Permet de ne pas expansionner * |
* certains bouts de code... */ |
|
|
|
/* Aucun fichier ouvert => NULL */ |
if (ptr_pdf==NULL) return NULL; |
|
if (last_is_NL) |
{ |
last_is_NL=0; |
ptr_pdf->ligne++; |
} |
|
|
ptr_lex=get_true_lexeme(ptr_pdf->flux); |
|
/* Traitement des macros et sous-typage */ |
if (TYPE_IS(ptr_lex, ALPHA)) /* si macro expansion, sinon sous-typage */ |
{ |
int i; |
char * p_regle, * p_alpha; |
type_pdm * ptr_mac; |
if (germac && (ptr_mac=is_macro(ptr_lex->valeur.alpha))!=NULL) |
{ |
FREE_LEX(ptr_lex); |
expanse_macro(ptr_mac); |
ptr_lex=read_lexeme(); |
} |
else /* Test si c'est sous-typable */ |
for(i=0; i<nbr_sous_types && regle_typage[i].chaine; i++) |
{ |
p_regle=regle_typage[i].chaine; |
p_alpha=ptr_lex->valeur.alpha; |
while((*p_regle)!='\0') |
{ |
|
{ /* les 2 car suiv sont les bornes */ |
if ((*p_alpha)<*(++p_regle) || (*p_alpha)>*(++p_regle)) |
break; |
} |
else if (!CAR_EQ(*p_regle, *p_alpha)) break; |
p_regle++; |
p_alpha++; |
} |
|
if ((*p_regle)=='\0' && (*p_alpha)=='\0') |
{ |
|
ptr_lex->type = POS_MPV(regle_typage[i].code); |
break; |
} |
} |
} |
|
else |
|
/* Traitment des directives, des sauts de ligne et des fin de flux */ |
|
switch(ptr_lex->valeur.op) |
{ |
case NL: /* Fin de ligne */ |
last_is_NL=1; |
break; |
case EOF: /* Fin de fichier : on ne retourne pas de lexemes */ |
FREE_LEX(ptr_lex) |
depile_flux(); |
ptr_lex=read_lexeme(); |
break; |
|
{ |
type_lexeme * ptr_sauv_lex; |
int pas_dir=1; /* Drapeau soupconneux */ |
ptr_sauv_lex=ptr_lex; |
germac=0; |
ptr_lex=read_lexeme(); |
if (TYPE_IS(ptr_lex, ALPHA)) |
{ |
if (define_str && |
(*fcmp)(ptr_lex->valeur.alpha, define_str)==0) |
{ /* Ajout d'1 macro */ |
pas_dir=0; |
FREE_LEX(ptr_lex); |
ptr_lex=read_lexeme(); |
if (!TYPE_IS(ptr_lex, ALPHA)) |
SYNTAX_ERROR(S_NOM_MAC_INVALID) |
else |
ajoute_macro(ptr_lex->valeur.alpha |
, ptr_pdf->flux); |
} |
else if (include_str && |
(*fcmp)(ptr_lex->valeur.alpha,include_str)==0) |
{ /* Empliement d'un fichier */ |
pas_dir=0; |
FREE_LEX(ptr_lex); |
ptr_lex=read_lexeme(); |
if (!TYPE_IS(ptr_lex, ALPHA)) |
SYNTAX_ERROR(S_NOM_INCFICH_INVALID) |
else |
empile_flux(ptr_lex->valeur.alpha |
,NULL); |
} |
else if (undef_str && |
(*fcmp)(ptr_lex->valeur.alpha,undef_str)==0) |
{ /* Empliement d'un fichier */ |
pas_dir=0; |
FREE_LEX(ptr_lex); |
ptr_lex=read_lexeme(); |
if (!TYPE_IS(ptr_lex, ALPHA)) |
SYNTAX_ERROR(S_NOM_MAC_INVALID) |
else |
suppress_macro(ptr_lex->valeur.alpha); |
} |
} |
germac=1; |
|
{ |
|
|
} |
else |
{ |
FREE_LEX(ptr_sauv_lex); |
FREE_LEX(ptr_lex); |
ptr_lex=read_lexeme(); |
} |
} |
} |
|
return ptr_lex; |
} |
|
|
|
* dernier renvoie NULL. */ |
type_lexeme * get_true_lexeme(FILE * fich) |
{ |
type_lexeme * p; |
p=get_lexeme(fich); |
if (p==NULL) |
{ |
SYNTAX_ERROR(err_code) |
p=get_true_lexeme(fich); |
} |
return p; |
} |
|
/* Vide le flux jusqu'a la prochaine accolade ouvrante comprise, * |
|
int next_ACO(FILE * flux) |
{ |
int drap=0; |
type_lexeme * p; |
do |
{ |
p=get_true_lexeme(flux); |
if (TYPE_IS(p, OP)) |
{ |
if (p->valeur.op==EOF) |
{ |
FREE_LEX(p) |
err_code=S_DEF_MACRO_EOF; |
return 1; |
} |
if (p->valeur.op==ACO) drap=1; |
} |
FREE_LEX(p); |
} |
while(!drap); |
return 0; |
} |
|
|
|
type_lexeme * read_all_but_ACF(FILE * flux) |
{ |
type_lexeme * p; |
p=get_true_lexeme(flux); |
if (TYPE_IS(p,OP)) |
{ |
if (p->valeur.op==EOF) |
{ |
FREE_LEX(p) |
err_code=S_DEF_MACRO_EOF; |
return NULL; |
} |
if (p->valeur.op==ACF) |
{ |
FREE_LEX(p) |
err_code=NO_ERR; |
return NULL; |
} |
} |
return p; |
} |
|
|
* dans un nouveau buffer qu'elle empile avant de rendre la main. */ |
void expanse_macro(type_pdm * ptr_mac) |
#define FREE_TABLE\ |
while(table)\ |
{\ |
parcourt_table=table->suiv;\ |
FREE_LEX(table->nom_param);\ |
if (table->val_param) FREE_LEX(table->val_param)\ |
free(table);\ |
table=parcourt_table;\ |
} |
{ |
|
typedef struct type_file_param_tmp |
{ |
type_lexeme * nom_param; |
type_lexeme * val_param; |
struct type_file_param_tmp * suiv; |
} type_file_param; |
|
type_file_param * table=NULL, * parcourt_table=NULL, * ptr_new=NULL; |
type_lexeme * ptr_lex=NULL, * ptr_lex_asm=NULL; |
FILE * ftemp; |
|
|
fseek(fich_macro, ptr_mac->def_pos, SEEK_SET); |
|
|
if (next_ACO(fich_macro)) |
{ |
SYNTAX_ERROR(err_code) |
return; |
} |
|
|
while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) |
{ |
|
ptr_new=(type_file_param *) malloc(sizeof(type_file_param)); |
if (!ptr_new) DIALOGUE("preprocesseur(expanse_macro)", 0, F_ERR_MEM); |
ptr_new->nom_param=ptr_lex; |
ptr_new->val_param=NULL; |
ptr_new->suiv=NULL; |
if (parcourt_table) |
parcourt_table=parcourt_table->suiv=ptr_new; |
else |
table=parcourt_table=ptr_new; |
/* Attention, pas de FREE_LEX car placement dans la table */ |
} |
if (err_code!=NO_ERR) |
{ |
SYNTAX_ERROR(err_code) |
FREE_TABLE |
return; |
} |
|
|
if (next_ACO(fich_macro)) |
{ |
SYNTAX_ERROR(err_code) |
return; |
} |
|
|
while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) |
{ |
/* Parcourt de l'utilisation de la macro */ |
ptr_lex_asm=get_true_lexeme(ptr_pdf->flux); |
|
for( parcourt_table=table; |
parcourt_table!=NULL |
&& !id_lexeme(parcourt_table->nom_param, ptr_lex, casse_sens); |
parcourt_table=parcourt_table->suiv); |
|
if (parcourt_table) parcourt_table->val_param=ptr_lex_asm; |
else |
{ |
if (!id_lexeme(ptr_lex, ptr_lex_asm, casse_sens)) |
{ |
err_code=S_MAC_NO_MATCH; |
FREE_LEX(ptr_lex) |
FREE_LEX(ptr_lex_asm) |
|
} |
FREE_LEX(ptr_lex_asm) |
} |
FREE_LEX(ptr_lex) |
} |
if (err_code!=NO_ERR) |
{ |
SYNTAX_ERROR(err_code) |
FREE_TABLE |
return; |
} |
|
|
for( parcourt_table=table; |
parcourt_table; |
parcourt_table=parcourt_table->suiv) |
if (parcourt_table->val_param==NULL) |
{ |
SYNTAX_ERROR(S_MAC_TROP_PARAM) |
FREE_TABLE |
return; |
} |
|
|
if (next_ACO(fich_macro)) |
{ |
SYNTAX_ERROR(err_code) |
FREE_TABLE |
return; |
} |
|
/* On expanse dans un buffer temporaire */ |
ftemp=tmpfile(); |
|
|
while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) |
{ |
|
for( parcourt_table=table; |
parcourt_table |
&& !id_lexeme(parcourt_table->nom_param, ptr_lex, casse_sens); |
parcourt_table=parcourt_table->suiv); |
if (parcourt_table==NULL) /* Si ce n'en est pas un */ |
fprint_lexeme(ftemp, ptr_lex); |
else |
fprint_lexeme(ftemp, parcourt_table->val_param); |
fputc(' ', ftemp); |
FREE_LEX(ptr_lex); |
} |
|
|
FREE_TABLE |
if (err_code!=NO_ERR) |
{ |
fclose(ftemp); |
SYNTAX_ERROR(err_code) |
return; |
} |
|
|
empile_flux(NULL, ptr_mac->nom_macro); |
ptr_pdf->flux=ftemp; |
rewind(ftemp); |
} |
|
/********************************************************************************************* |
* * |
|
* * |
*********************************************************************************************/ |
|
|
|
|
int init_preprocesseur(char * fichinit) |
{ |
FILE * ftest; |
char errmsg[]="preprocesseur(init_preprocesseur)"; |
int i; |
|
|
fcmp=casse_sens ? (void *) &strcmp : (void *) &strcasecmp; |
|
/* On test l'existence des directives */ |
if (include_str!=NULL && active_list) |
{ |
DIALOGUE(NULL, 0, W_NO_LIST_INC) |
|
/* inclusions de fichiers. */ |
} |
|
|
|
for(i=0; i<nbr_sous_types; i++) |
{ |
char * ptr=regle_typage[i].chaine; |
while(*ptr++!='\0') |
if (*ptr=='?' || *ptr=='*') |
{ |
if (*++ptr=='\0' || *++ptr=='\0') |
{ |
DIALOGUE(NULL, 0, W_REGLE_TYPAGE) |
free(regle_typage[i].chaine); |
regle_typage[i].chaine=NULL; |
} |
} |
} |
|
|
|
if (fich_macro==NULL) fich_macro=tmpfile(); |
|
|
if (fichinit[0]=='\0') /* Empilement de stdin en l'absence de fichier source */ |
{ |
type_pdf * ptr; |
|
/* Allocation de la structure */ |
ptr=(type_pdf *) malloc(sizeof(type_pdf)); |
if (!ptr) DIALOGUE(errmsg, 0, F_ERR_MEM); |
|
/* Initialisation des champs */ |
ptr->flux=stdin; |
ptr->ligne=1; |
ptr->nom_macro=NULL; |
ptr->prec=NULL; |
|
/* Recopie des chaines transmises en parametres */ |
ptr->nom_fich=(char *) malloc(6); |
if (!ptr->nom_fich) DIALOGUE(errmsg, 0, F_ERR_MEM); |
strcpy(ptr->nom_fich, "stdin"); |
|
/* Empilement */ |
ptr->prec=ptr_pdf; |
ptr_pdf=ptr; |
|
if (active_list) |
{ |
DIALOGUE(NULL, 0, W_NO_LIST_STDIN); |
|
* en cas d'utilisation du stdin. */ |
} |
} |
else |
{ |
if ((ftest=fopen(fichinit, "rb"))==NULL) return 1; |
fclose(ftest); |
empile_flux(fichinit, NULL); |
} |
return 0; |
} |
|
|
void clear_preprocesseur() |
{ |
while(ptr_pdf) depile_flux(); |
while(ptr_pdl) FREE_LEX(pop_lexeme()); |
while(ptr_pdm) |
{ |
type_pdm * p; |
p=ptr_pdm->suiv; |
free(ptr_pdm->nom_macro); |
free(ptr_pdm); |
ptr_pdm=p; |
} |
} |
|
/* Cette fonction renvoie le prochain lexeme valide disponible. Elle regarde d'abord dans la * |
|
* read_lexeme(). * |
|
type_lexeme * pop_lexeme() |
{ |
|
{ |
return read_lexeme(); |
} |
|
{ |
type_file_lexeme * ptr_sav; |
type_lexeme * ptr_lex; |
|
ptr_sav = ptr_pdl->suivant; |
ptr_lex = ptr_pdl->lexeme; |
free(ptr_pdl); |
ptr_pdl=ptr_sav; |
return ptr_lex; |
} |
} |
|
|
void push_lexeme(type_lexeme * ptr_recrach) |
{ |
type_file_lexeme * ptr_sav; |
|
ptr_sav = ptr_pdl; |
ptr_pdl = (type_file_lexeme *) malloc(sizeof(type_file_lexeme)); |
if (!ptr_pdl) DIALOGUE("preprocesseur(push_lexeme)", 0, F_ERR_MEM); |
ptr_pdl->suivant=ptr_sav; |
ptr_pdl->lexeme=ptr_recrach; |
} |
|
|
int ligne_courante() |
{ |
type_pdf * p=ptr_pdf; |
while(p && p->nom_macro) p=p->prec; |
if (p==NULL) return 0; |
return p->ligne; |
} |
|
|
|
char * gen_orig_msg() |
{ |
char * text; |
type_pdf * ptr; |
int t_src=0, t_dest=MAX_LONG_ALPHA, t_sep; |
|
t_sep=strlen(sep_fich_inclus); |
text=(char *) malloc(t_dest); |
text[0]=0; |
for(ptr=ptr_pdf; ptr; ptr=ptr->prec) |
{ |
if (ptr->nom_macro) continue; |
t_src+=strlen(ptr->nom_fich)+t_sep; |
if (t_src >= t_dest) |
{ |
t_dest=t_src+1; |
text=(char *) realloc(text, t_dest); |
} |
strcat(text, ptr->nom_fich); |
if (ptr->prec) strcat(text, sep_fich_inclus); |
} |
return text; |
} |
|
|
void suppress_macro(char * nom_macro) |
{ |
type_pdm * ptr_mac, * ptr_mac_prec; |
|
|
|
for( ptr_mac=ptr_pdm; |
ptr_mac && (*fcmp)(ptr_mac->nom_macro, nom_macro); |
ptr_mac=ptr_mac->suiv) |
ptr_mac_prec=ptr_mac; |
|
if (ptr_mac) |
{ |
type_pdm * psav; |
psav=ptr_mac->suiv; |
free(ptr_mac->nom_macro); |
free(ptr_mac); |
if (ptr_mac_prec) |
ptr_mac_prec->suiv=psav; |
else |
ptr_pdm=psav; |
} |
else |
SYNTAX_ERROR(W_UNDEF_NOMAC) |
} |
|
|
void ajoute_macro(char * nom_macro, FILE * flux_def) |
{ |
int c,i; |
long pos; |
char * org_msg = "preprocesseur(ajoute_macro)"; |
|
|
{ |
SYNTAX_ERROR(W_REDEF_MAC) |
suppress_macro(nom_macro); |
} |
|
fseek(fich_macro, 0L, SEEK_END); |
pos=ftell(fich_macro); |
|
|
for(i=0; i<3; c==ACF ? i++ : i) |
{ |
if ((c=fgetc(flux_def))==EOF) |
{ |
if (feof(flux_def)) |
SYNTAX_ERROR(S_DEF_MACRO_EOF) |
else |
DIALOGUE(org_msg, 0, F_ERR_LECT); |
break; |
} |
fputc(c, fich_macro); |
if (c==NL && flux_def==ptr_pdf->flux) ptr_pdf->ligne++; |
} |
|
|
if (i==3) |
{ |
type_pdm * ptr; |
ptr=(type_pdm *) malloc(sizeof(type_pdm)); |
if (!ptr) DIALOGUE(org_msg, 0, F_ERR_MEM); |
ptr->nom_macro=(char *) malloc(strlen(nom_macro)); |
strcpy(ptr->nom_macro,nom_macro); |
ptr->def_pos=pos; |
ptr->suiv=NULL; |
|
{ |
type_pdm * ptr_fin; |
ptr_fin=ptr_pdm; |
while (ptr_fin->suiv) ptr_fin=ptr_fin->suiv; |
ptr_fin->suiv=ptr; |
} |
else |
ptr_pdm=ptr; |
} |
} |
|
/* Petite fonction utile pour consulter (dans le stderr) la liste des macros disponibles */ |
void liste_table_macro(FILE * f) |
{ |
type_pdm * p; |
type_lexeme * ptr_lex; |
if (ptr_pdm) |
err_code=B_MACRO_DISPO; |
else |
err_code=B_NO_MACRO; |
fprintf(f, "-- %s\n", search_msg()); |
|
for(p=ptr_pdm; p!=NULL; p=p->suiv) |
{ |
fprintf(f,"-- \t%s ",p->nom_macro); |
fseek(fich_macro, p->def_pos, SEEK_SET); |
/* Ecriture de la syntaxe */ |
if (next_ACO(fich_macro) || next_ACO(fich_macro)) |
{ |
SYNTAX_ERROR(err_code) |
continue; |
} |
while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) |
{ |
fprint_lexeme(f, ptr_lex); |
FREE_LEX(ptr_lex) |
} |
if (err_code!=NO_ERR) |
{ |
SYNTAX_ERROR(err_code) |
continue; |
} |
fprintf(f, "\t\t"); |
|
if (next_ACO(fich_macro)) |
{ |
SYNTAX_ERROR(err_code) |
continue; |
} |
while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) |
{ |
fprint_lexeme(f, ptr_lex); |
fputc(' ', f); |
FREE_LEX(ptr_lex) |
} |
if (err_code!=NO_ERR) |
{ |
SYNTAX_ERROR(err_code) |
continue; |
} |
fprintf(f, "\n"); |
} |
} |
/gasm_with_mult2_instruction/src/synthetiseur.c
0,0 → 1,270
#include "synthetiseur.h" |
|
|
#include <debogueur.h> |
#include <dialogue.h> |
#include <formateur.h> |
#include <parametres.h> |
#include <adaptateur.h> |
#include <analyseur.h> |
|
|
|
char * cnv_mask_str(type_mask * m) |
{ |
char * res; |
int i; |
type_valeur_mask v; |
if (m==NULL) return NULL; |
res = malloc((m->taille)*sizeof(char)); |
if (res==NULL) DIALOGUE("synthetiseur(cnv_mask_str)", 0, F_ERR_MEM); |
v=m->valeur; |
for (i=m->taille-1 ; i>=0 ; i--) |
{ |
res[i]= (v & 0xFF); |
v>>=8; |
} |
return res; |
} |
|
|
#define COL_TEXT (2*sizeof(type_valeur_mask)+10) |
|
|
|
|
|
|
int recopie(FILE * srce, FILE * dest, int debut, int fin) |
{ |
while (debut<fin) |
{ |
int c; |
long col; |
fprintf(dest, "%d\t", debut); |
|
for (col=0 ; col<COL_TEXT ; col++) fputc(' ', dest); |
while ((c=fgetc(srce))!='\n' && c!=EOF) fputc(c, dest); |
if (c!='\n') return debut; /* Fin du fichier atteinte. */ |
fputc(c, dest); |
++debut; |
} |
return debut; |
} |
|
/* Recopie la ligne courante de srce dans dest, y compris le \n. */ |
void ligne_cp(FILE * srce, FILE * dest) |
{ |
int c; |
while ((c=fgetc(srce))!='\n' && c!=EOF) fputc(c, dest); |
if (c=='\n') fputc('\n', dest); |
} |
|
|
|
int synthese() |
{ |
int err=0; |
type_precode * pcd; |
|
for ( pcd=file_precode ; pcd!=NULL ; pcd=pcd->suivant ) |
{ |
int i; |
|
pco=pcd->pco; |
|
for (i=0 ; i<pcd->nbr_func ; i++) |
{ |
type_mask * res; |
res = (pcd->func)[i](pcd->param); |
|
switch (eval_code) |
|
case EVAL_REUSSIE : |
if (res==NULL || res->taille==0) break; |
if (pcd->mask==NULL || res->taille!=pcd->mask->taille) |
|
DIALOGUE(pcd->fichier_orig, |
pcd->ligne_orig, S_FUN_ERR); |
|
CLEAR_PRECODE(pcd); |
pcd->erreur=S_FUN_ERR; |
err++; |
break; |
} |
|
pcd->mask->valeur|=res->valeur; |
break; |
case EVAL_IMPOSSIBLE : /* En seconde passe, erreur. */ |
case EVAL_ERREUR : |
affiche_message(pcd->fichier_orig, pcd->ligne_orig); |
err++; |
|
CLEAR_PRECODE(pcd); |
pcd->erreur=err_code; |
break; |
default : |
DIALOGUE(pcd->fichier_orig, |
pcd->ligne_orig, S_ADAP_ERR); |
CLEAR_PRECODE(pcd); |
pcd->erreur=S_ADAP_ERR; |
err++; |
break; |
} |
if (res!=NULL) FREE_MASK(res); |
} |
|
if (pcd->func!=NULL) free(pcd->func); |
pcd->func=NULL; |
pcd->nbr_func=0; |
} |
return err; |
} |
|
|
|
|
/* passe faute de quoi le code sera incomplet. */ |
void write_objet(FILE * f_obj) |
{ |
type_precode * pcd; |
int i; |
int local_pco=-1; |
|
|
int addimp; |
int taille; |
|
if (f_obj==NULL) DIALOGUE("synthetiseur(write_objet)", 0, F_FLUX_NULL); |
|
for (pcd=file_precode ; pcd!=NULL ; pcd=pcd->suivant) |
{ |
if (pcd->erreur==NO_ERR && pcd->mask!=NULL) |
|
char * code_bin; |
|
if (pcd->pco!=local_pco) |
|
n_head=ftell(f_obj); |
addimp=pcd->pco; |
if (c_head!=-5) /* Il ne s'agit pas du premier bloc. */ |
{ /* Ecriture de la taille du bloc que l'on ferme. */ |
|
taille=n_head-c_head-4; |
/* Ecriture de la taille au bon emplacement. */ |
fseek(f_obj, c_head+2, SEEK_SET); |
for (i=1 ; i>=0 ; i--) |
fputc((taille>>(8*i)) & 0xFF, f_obj); |
/* Retour au nouveau bloc. */ |
fseek(f_obj, n_head, SEEK_SET); |
} |
/* Ecriture de l'adresse d'implantation. */ |
for (i=1 ; i>=0 ; i--) fputc((addimp>>(8*i)) & 0xFF , f_obj); |
/* Ecriture de 0 pour la taille du prochain bloc. */ |
for (i=0; i<2; i++) fputc(0, f_obj); |
c_head=n_head; |
local_pco=pcd->pco; |
} |
|
|
code_bin=cnv_mask_str(pcd->mask); /* Conversion du masque. */ |
|
for (i=0 ; i<pcd->mask->taille ; i++) fputc(code_bin[i], f_obj); |
|
|
local_pco+=pcd->mask->taille; /* Avancement du pco. */ |
} |
} |
|
/* Ecriture de la taille du dernier bloc. */ |
n_head=ftell(f_obj); |
|
taille=n_head-c_head-4; |
/* Ecriture de la taille au bon emplacement. */ |
fseek(f_obj, c_head+2, SEEK_SET); |
for (i=1 ; i>=0 ; i--) fputc((taille>>(8*i)) & 0xFF, f_obj); |
/* Retour au nouveau bloc, en fin de fichier. */ |
fseek(f_obj, n_head, SEEK_SET); |
} |
|
|
|
|
/* passe faute de quoi le code sera incomplet. */ |
void write_liste(FILE * f_lst, FILE * f_src) |
{ |
int ligne=1; /* Ligne courante dans le fichier source. */ |
type_precode * pcd_cour=file_precode; |
|
if (f_lst==NULL) DIALOGUE("synthetiseur(write_liste)", 0, F_FLUX_NULL); |
|
while (pcd_cour!=NULL) |
{ |
|
|
long col=0; /* Colonne courante dans la ligne actuelle du fichier. */ |
type_precode * pcd; |
|
lbloc=pcd_cour->ligne_orig; /* Ligne courante dans la source. */ |
|
|
ligne=recopie(f_src, f_lst, ligne, lbloc); |
|
if (ligne!=lbloc) |
|
DIALOGUE(NULL, 0, W_SRCE_MOD); |
return; |
} |
|
|
|
|
for (pcd=pcd_cour ; pcd!=NULL && pcd->ligne_orig==lbloc ; pcd=pcd->suivant) |
|
if (pcd->erreur==NO_ERR && pcd->mask!=NULL) |
{ |
char str[3*sizeof(type_taille_mask)+3]; |
|
|
|
fprintf(f_lst, "%04X ", pcd->pco); |
pco_ecrit=1; |
} |
|
sprintf(str, "%%0%dX", pcd->mask->taille*2); |
fprintf(f_lst, str, pcd->mask->valeur); |
} |
} |
|
|
for ( col=ftell(f_lst)-col ; col<COL_TEXT ; col++) fputc(' ', f_lst); |
|
|
ligne++; |
|
while (pcd_cour!=NULL && pcd_cour->ligne_orig==lbloc) |
|
if (pcd_cour->erreur!=NO_ERR) |
{ /* On affiche le message d'erreur dans la liste d'assemblage. */ |
int i; |
err_code=pcd_cour->erreur; |
fputc('\t', f_lst); |
for (i=0; i<COL_TEXT; i++) fputc(' ', f_lst); |
fprintf(f_lst, "%s\n", search_msg()); |
} |
pcd_cour=pcd_cour->suivant; |
} |
} |
|
/* Recopie de la fin du fichier source dans la liste d'assemblage. */ |
while (!feof(f_src)) |
{ |
int i; |
fprintf(f_lst, "%d\t", ligne++); |
for (i=0; i<COL_TEXT; i++) fputc(' ', f_lst); |
ligne_cp(f_src, f_lst); |
} |
fprintf(f_lst, "\n"); |
|
|
} |
/gasm_with_mult2_instruction/Makefile
0,0 → 1,75
# This file is part of gasm. |
# |
# |
# If you encountered any problem, please contact : |
# |
# lmouton@enserg.fr |
# shangoue@enserg.fr |
# |
|
|
# Makefile de type compilation du projet |
# |
# Cibles possibles : |
# |
# project, all, asmica Compile l'assembleur avec main.c et tous les modules en les recompilant au besoin |
|
|
# menage Fait le menage des fichiers generes |
# exec Executer le programme |
# save[fichier_tar] Archivage du projet dans sav/ |
|
COMP_OPT = -I$(INCLUDE_PATH) -O2 -Wall -ansi -pipe -s |
|
# Repertoires du projet |
|
LIB_PATH = lib |
INCLUDE_PATH = include |
SRC_PATH = src |
|
|
include Makefile.dep |
|
VPATH = $(LIB_PATH) : $(INCLUDE_PATH) : $(SRC_PATH) |
|
|
MODS_OBJ = $(addsuffix .o, $(strip $(ALL))) |
MODS_SRC = $(addsuffix .c, $(strip $(ALL))) |
|
|
CC = gcc |
LINK_OPT = |
|
.SILENT : menage exec $(MODS_OBJ) info |
.PHONY : all project exec menage |
|
all project : asmips |
|
asmips : main.c $(MODS_OBJ) |
$(CC) $(COMP_OPT) $(LINK_OPT) $< $(addprefix $(LIB_PATH)/, $(MODS_OBJ)) -o $@ |
|
$(MODS_OBJ) : %.o : %.c $(addsuffix .h, $(%_DEP)) |
@echo Compilation du module $* |
$(CC) $(COMP_OPT) -o $(LIB_PATH)/$*.o -c $< |
|
menage : |
@echo Menage des fichiers principaux du projet |
rm -f *.o |
rm -f core.* |
rm -f *~ |
rm -f asmips |
rm -f a.obj a.lst |
rm -f $(LIB_PATH)/*.o |
|
exec : |
$(MAKE) -s project |
clear |
./asmips |
|
save[%] : |
@tar -jvcf ../sav/$*.tbz2 * |
|
info : |
|
ls $(LIB_PATH) |
|
/gasm_with_mult2_instruction/Makefile.dep
0,0 → 1,23
# This file is part of gasm. |
# |
# |
# If you encountered any problem, please contact : |
# |
# lmouton@enserg.fr |
# shangoue@enserg.fr |
# |
|
|
|
|
|
dialogue_DEP = |
formateur_DEP = dialogue |
parametres_DEP = formateur |
preprocesseur_DEP = dialogue formateur parametres |
adaptateur_DEP = dialogue formateur parametres preprocesseur |
preparateur_DEP = dialogue formateur parametres adaptateur |
analyseur_DEP = dialogue formateur parametres preprocesseur adaptateur preparateur |
synthetiseur_DEP = dialogue formateur parametres adaptateur analyseur |
|
ALL = dialogue formateur parametres preprocesseur adaptateur preparateur analyseur synthetiseur |
/gasm_with_mult2_instruction/Syntaxe
0,0 → 1,529
; This file is part of gasm. |
; |
; |
; If you encountered any problem, please contact : |
; |
; lmouton@enserg.fr |
; shangoue@enserg.fr |
; |
|
|
|
;===============================================================================; |
; ; |
; ; |
; Fichier de donnees sur la syntaxe de l'assembleur du microprocesseur miniMIPS ; |
; ; |
; ; |
;===============================================================================; |
|
|
|
|
|
|
|
|
SET UNDEFSTR U ; Chaine de supression de macro |
|
|
; d'assemblage sera interdite... |
; SET INCLUDESTR I ; Chaine d'inclusion de fichier |
|
|
|
|
|
SET SEP |
|
|
|
|
|
|
|
|
|
SET NEWSST Reg $?09 1 |
SET NEWSST Reg $?02?09 1 |
SET NEWSST Reg $3?01 1 |
|
|
|
|
|
; Autorise les lignes vides |
{ |
} |
|
|
{ Alpha: } |
|
|
|
|
|
{ Alpha EQU Alpha } |
FUN AddEqu |
|
{ Alpha EQU Int } |
FUN AddEqu |
|
|
{ ALIGN4 } |
FUN Complete_zeros |
|
|
{ DCB Int } |
TMO 1 |
MSK _0000_0000_ |
FUN Dcb_Int |
{ DCB Alpha } |
TMO 1 |
MSK _0000_0000_ |
FUN Dcb_Alpha |
{ DCW Int } |
TMO 4 |
MSK _0000_0000_0000_0000__0000_0000_0000_0000_ |
FUN Dcw_Int |
{ DCW Alpha } |
TMO 2 |
MSK _0000_0000_0000_0000__0000_0000_0000_0000_ |
FUN Dcw_Alpha |
|
; Directives de positionnement de l'adresse d'implantation |
{ ORG Int } |
FUN Org_Int |
|
{ ORG Alpha } |
FUN Org_Label |
|
; DEFINITION DES INSTRUCTIONS |
|
; Instruction ADD |
{ ADD Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100000 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction ADDI |
{ ADDI Reg, Reg, Int } |
TMO 4 |
MSK _001000_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN IMM5 |
{ ADDI Reg, Reg, Alpha } |
TMO 4 |
MSK _001000_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN ETIQ5 |
|
; Instruction ADDIU |
{ ADDIU Reg, Reg, Int } |
TMO 4 |
MSK _001001_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN IMM5 |
|
; Instruction ADDU |
{ ADDU Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100001 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction AND |
{ AND Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100100 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction ANDI |
{ ANDI Reg, Reg, Int } |
TMO 4 |
MSK _001100_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN IMM5 |
{ ANDI Reg, Reg, Alpha } |
TMO 4 |
MSK _001100_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN ETIQ5 |
|
; Instruction BEQ |
{ BEQ Reg, Reg, Alpha } |
TMO 4 |
MSK _000100_00000_00000__0000_0000_0000_0000 |
FUN R1S |
FUN R3T |
FUN OFFSET5 |
|
; Instruction BGEZ |
{ BGEZ Reg, Alpha } |
TMO 4 |
MSK _000001_00000_00001__00000000_00000000 |
FUN R1S |
FUN OFFSET3 |
|
; Instruction BGEZAL |
{ BGEZAL Reg, Alpha } |
TMO 4 |
MSK _000001_00000_10001__00000000_00000000 |
FUN R1S |
FUN OFFSET3 |
|
; Instruction BGTZ |
{ BGTZ Reg, Alpha } |
TMO 4 |
MSK _000111_00000_00000__00000000_00000000 |
FUN R1S |
FUN OFFSET3 |
|
; Instruction BLEZ |
{ BLEZ Reg, Alpha } |
TMO 4 |
MSK _000110_00000_00000__00000000_00000000 |
FUN R1S |
FUN OFFSET3 |
|
; Instruction BLTZ |
{ BLTZ Reg, Alpha } |
TMO 4 |
MSK _000001_00000_00000__00000000_00000000 |
FUN R1S |
FUN OFFSET3 |
|
; Instruction BLTZAL |
{ BLTZAL Reg, Alpha } |
TMO 4 |
MSK _000001_00000_10000__00000000_00000000 |
FUN R1S |
FUN OFFSET3 |
|
; Instruction BNE |
{ BNE Reg, Reg, Alpha } |
TMO 4 |
MSK _000101_00000_00000__00000000_00000000 |
FUN R1S |
FUN R3T |
FUN OFFSET5 |
|
; Instruction BREAK |
{ BREAK } |
TMO 4 |
MSK _000000__00000_00000_00000_00000__001101 |
|
; Instruction COP0 |
{ COP0 Int } |
TMO 4 |
MSK _010000_00001_00000_0000_0000_0000_0000 |
FUN IMM1 |
|
; Instruction J |
{ J Alpha } |
TMO 4 |
MSK _000010__00_0000_0000_0000_0000_0000_0000 |
FUN ABSOLU1 |
|
; Instruction JAL |
{ JAL Alpha } |
TMO 4 |
MSK _000011__00_0000_0000_0000_0000_0000_0000 |
FUN ABSOLU1 |
|
; Instruction JALR |
{ JAL Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_001001 |
FUN R1D |
FUN R3S |
|
; Instruction JALR avec rd=$31 implicite |
{ JAL Reg } |
TMO 4 |
MSK _000000_00000_00000_11111_00000_001001 |
FUN R1S |
|
; Instruction JR |
{ JR Reg } |
TMO 4 |
MSK _000000_00000__000_0000_0000_0000__001000 |
FUN R1S |
|
; Instruction LUI |
{ LUI Reg, Int } |
TMO 4 |
MSK _001111_00000_00000__0000_0000_0000_0000 |
FUN R1T |
FUN IMM3 |
{ LUI Reg, Alpha } |
TMO 4 |
MSK _001111_00000_00000__0000_0000_0000_0000 |
FUN R1T |
FUN ETIQ3 |
|
; Instruction LW |
{ LW Reg, Int(Reg) } |
TMO 4 |
MSK _100011_00000_00000__0000_0000_0000_0000 |
FUN R1T |
FUN IMM3 |
FUN R5S |
|
; Instruction LWC0 |
{ LWC0 Reg, Int(Reg) } |
TMO 4 |
MSK _110000_00000_00000__0000_0000_0000_0000 |
FUN R1T |
FUN IMM3 |
FUN R5S |
|
; Instruction MFC0 |
{ MFC0 Reg, Reg } |
TMO 4 |
MSK _010000_00000_00000_00000__000000_00000 |
FUN R1D |
FUN R3T |
|
; Instruction MFHI |
{ MFHI Reg } |
TMO 4 |
MSK _000000_0000000000_00000_00000_010000 |
FUN R1D |
|
; Instruction MFLO |
{ MFLO Reg } |
TMO 4 |
MSK _000000_0000000000_00000_00000_010010 |
FUN R1D |
|
; Instruction MTC0 |
{ MTC0 Reg, Reg } |
TMO 4 |
MSK _010000_00100_00000_00000__000000_00000 |
FUN R1T |
FUN R3D |
|
; Instruction MTHI |
{ MTHI Reg } |
TMO 4 |
MSK _000000_00000__0_0000_0000_0000_00__010001 |
FUN R1S |
|
; Instruction MTLO |
{ MTLO Reg } |
TMO 4 |
MSK _000000_00000__0_0000_0000_0000_00__010011 |
FUN R1S |
|
; Instruction MULT |
{ MULT Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000__0000_0000_00__011000 |
FUN R1S |
FUN R3T |
; Instruction MULT2 |
{ MULT2 Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_011100 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction MULTU |
{ MULTU Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000__0000_0000_00__011001 |
FUN R1S |
FUN R3T |
|
; Instruction NOR |
{ NOR Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100111 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction OR |
{ OR Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100101 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction ORI |
{ ORI Reg, Reg, Int } |
TMO 4 |
MSK _001101_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN IMM5 |
{ ORI Reg, Reg, Alpha } |
TMO 4 |
MSK _001101_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN ETIQ5 |
|
; Instruction SLL |
{ SLL Reg, Reg, Int } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_000000 |
FUN R1D |
FUN R3T |
FUN SA5 |
|
; Instruction SLLV |
{ SLLV Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_000100 |
FUN R1D |
FUN R3T |
FUN R5S |
|
; Instruction SLT |
{ SLT Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_101010 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction SLTI |
{ SLTI Reg, Reg, Int } |
TMO 4 |
MSK _001010_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN IMM5 |
{ SLTI Reg, Reg, Alpha } |
TMO 4 |
MSK _001010_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN ETIQ5 |
|
; Instruction SLTIU |
{ SLTIU Reg, Reg, Int } |
TMO 4 |
MSK _001010_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN IMM5 |
{ SLTIU Reg, Reg, Alpha } |
TMO 4 |
MSK _001010_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN ETIQ5 |
|
; Instruction SLTU |
{ SLTU Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_101011 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction SRA |
{ SRA Reg, Reg, Int } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_000011 |
FUN R1D |
FUN R3T |
FUN SA5 |
|
; Instruction SRAV |
{ SRAV Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_000111 |
FUN R1D |
FUN R3T |
FUN R5S |
|
; Instruction SRL |
{ SRL Reg, Reg, Int } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_000010 |
FUN R1D |
FUN R3T |
FUN SA5 |
|
; Instruction SRLV |
{ SRLV Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_000110 |
FUN R1D |
FUN R3T |
FUN R5S |
|
; Instruction SUB |
{ SUB Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100010 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction SUBU |
{ SUBU Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100011 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction SW |
{ SW Reg, Int(Reg) } |
TMO 4 |
MSK _101011_00000_00000__0000_0000_0000_0000 |
FUN R1T |
FUN IMM3 |
FUN R5S |
|
; Instruction SWC0 |
{ SWC0 Reg, Int(Reg) } |
TMO 4 |
MSK _111000_00000_00000__0000_0000_0000_0000 |
FUN R1T |
FUN IMM3 |
FUN R5S |
|
; Instruction SYSCALL |
{ SYSCALL } |
TMO 4 |
MSK _000000__00000_00000_00000_00000__001100 |
|
; Instruction XOR |
{ XOR Reg, Reg, Reg } |
TMO 4 |
MSK _000000_00000_00000_00000_00000_100110 |
FUN R1D |
FUN R3S |
FUN R5T |
|
; Instruction XORI |
{ XORI Reg, Reg, Int } |
TMO 4 |
MSK _001110_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN IMM5 |
{ XORI Reg, Reg, Alpha } |
TMO 4 |
MSK _001110_00000_00000__00000000_00000000 |
FUN R1T |
FUN R3S |
FUN ETIQ5 |
/gasm_with_mult2_instruction/main.c
0,0 → 1,220
/**********************************************************************************/ |
/* */ |
/* Copyright (c) 2003, Hangouet Samuel, Mouton Louis-Marie all rights reserved */ |
/* */ |
/* This file is part of gasm. */ |
/* */ |
/* gasm is free software; you can redistribute it and/or modify */ |
/* it under the terms of the GNU General Public License as published by */ |
/* the Free Software Foundation; either version 2 of the License, or */ |
/* (at your option) any later version. */ |
/* */ |
/* gasm is distributed in the hope that it will be useful, */ |
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ |
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ |
/* GNU General Public License for more details. */ |
/* */ |
/* You should have received a copy of the GNU General Public License */ |
/* along with gasm; if not, write to the Free Software */ |
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
/* */ |
/**********************************************************************************/ |
|
|
/* If you encountered any problem, please contact : */ |
/* */ |
/* lmouton@enserg.fr */ |
/* shangoue@enserg.fr */ |
/* */ |
|
#include <debogueur.h> |
#include <dialogue.h> |
#include <formateur.h> |
#include <parametres.h> |
#include <preprocesseur.h> |
#include <adaptateur.h> |
#include <preparateur.h> |
#include <analyseur.h> |
#include <synthetiseur.h> |
|
#include <stdio.h> |
#include <string.h> |
|
static char nom_source[MAX_LONG_ALPHA+1]=""; |
static char nom_syntaxe[MAX_LONG_ALPHA+1]="Syntaxe"; |
static char nom_macro[MAX_LONG_ALPHA+1]=""; |
static char nom_liste[MAX_LONG_ALPHA+1]="a.lst"; |
static char nom_obj[MAX_LONG_ALPHA+1]="a.bin"; |
|
int gere_args(int argc, char * argv[]) |
{ |
int i; |
char * cur_arg; |
nom_source[MAX_LONG_ALPHA]=nom_syntaxe[MAX_LONG_ALPHA]=nom_macro[MAX_LONG_ALPHA]='\0'; |
for(i=1; i<argc; i++) |
{ |
cur_arg=argv[i]; |
if (*cur_arg=='-') |
{ |
while(*(++cur_arg)!='\0') switch (*cur_arg) |
{ |
case 'v': /* Active le mode verbeux. */ |
verbose=1; |
break; |
|
active_list=0; |
break; |
|
if (cur_arg[1]!='\0' || i+1>=argc) |
{ |
DIALOGUE(cur_arg, 0, W_ARG_INC); |
break; |
} |
strncpy(nom_syntaxe,argv[i+1],MAX_LONG_ALPHA); |
i++; |
break; |
|
if (cur_arg[1]!='\0' || i+1>=argc) |
{ |
DIALOGUE(cur_arg, 0, W_ARG_INC); |
break; |
} |
strncpy(nom_macro,argv[i+1],MAX_LONG_ALPHA); |
i++; |
break; |
case 'l': /* Nom du fichier liste d'assemblage. */ |
if (cur_arg[1]!='\0' || i+1>=argc) |
{ |
DIALOGUE(cur_arg, 0, W_ARG_INC); |
break; |
} |
strncpy(nom_liste,argv[i+1],MAX_LONG_ALPHA); |
i++; |
break; |
case 'o': /* Nom du fichier objet. */ |
if (cur_arg[1]!='\0' || i+1>=argc) |
{ |
DIALOGUE(cur_arg, 0, W_ARG_INC); |
break; |
} |
strncpy(nom_obj,argv[i+1],MAX_LONG_ALPHA); |
i++; |
break; |
case '?': |
case 'h': /* Aide en ligne. */ |
display_help(); |
return 0; |
break; |
case 'p': /* Utilise la sortie standard */ |
nom_obj[0]='\0'; |
break; |
default: |
DIALOGUE(cur_arg, 0, W_ARG_INC); |
break; |
} |
} |
else |
{ |
if (*nom_source!='\0') DIALOGUE(cur_arg, 0, W_ARG_INC) |
else strncpy(nom_source,cur_arg,MAX_LONG_ALPHA); |
} |
} |
return 1; |
} |
|
int main(int argc, char * argv[]) |
{ |
FILE * f_lst=NULL, * f_obj=NULL, * f_srceff=NULL; |
int err1, err2; |
int dst_std=0; |
type_lexeme * ptr_lex; |
|
|
|
/* Initialisation de la syntaxe de l'assembleur. */ |
DIALOGUE(NULL, 0, B_INIT_SYNTAX); |
init_arbre(nom_syntaxe); |
|
|
DIALOGUE(NULL, 0, B_INIT_MACRO); |
|
|
if (nom_macro[0]=='\0' && fich_macro_def) |
strcpy(nom_macro, fich_macro_def); /* nom_macro est assez long ! */ |
if (nom_macro[0]!='\0') |
{ |
if (init_preprocesseur(nom_macro)) DIALOGUE(NULL, 0, W_FICH_DEF_MACRO); |
} |
else DIALOGUE(NULL, 0, W_MACRO_MANQ); |
|
while ((ptr_lex=pop_lexeme())!=NULL) FREE_LEX(ptr_lex); |
|
|
if (init_preprocesseur(nom_source)) DIALOGUE(nom_source, 0, F_ERR_OUV); |
|
|
DIALOGUE(NULL, 0, B_ANA); |
err1=analyse(); |
if (verbose) liste_table_macro(stderr); |
|
|
|
DIALOGUE(NULL, 0, B_SYN); |
err2=synthese(); |
|
/* Ouverture du flux de sortie. */ |
if (nom_obj[0]!='\0') |
{ |
f_obj=fopen(nom_obj, "wb"); |
if (f_obj==NULL) DIALOGUE(nom_obj, 0, F_ERR_OUV); |
} |
else |
{ /* Ecriture dans le stdout. */ |
f_obj=stdout; |
strcpy(nom_obj, "stdout"); |
dst_std=1; |
} |
|
/* Ecriture du fichier objet. */ |
DIALOGUE(NULL, 0, B_STR_OBJ); |
write_objet(f_obj); |
|
if (!dst_std) fclose(f_obj); /* Fermeture du flux objet. */ |
|
if (active_list) |
|
/* Ouverture du flux source effectif et du flux de la liste si besoin est. */ |
f_srceff=fopen(nom_source, "rb"); |
if (f_srceff==NULL) DIALOGUE(nom_source, 0, F_ERR_OUV); |
f_lst=fopen(nom_liste, "wb"); |
if (f_lst==NULL) DIALOGUE(nom_liste, 0, F_ERR_OUV); |
DIALOGUE(NULL, 0, B_STR_LST); /* Ecriture de la lsite d'assemblage. */ |
write_liste(f_lst, f_srceff); |
|
fclose(f_srceff); |
fclose(f_lst); |
} |
|
if (verbose) |
|
char str_nbr[MAX_LONG_ALPHA]; |
DIALOGUE(NULL, 0, B_ERR_REP); |
sprintf(str_nbr, "%d", err1); |
DIALOGUE(str_nbr, 0, B_NBR_ERR_ANA); |
sprintf(str_nbr, "%d", err2); |
DIALOGUE(str_nbr, 0, B_NBR_ERR_SYN); |
} |
|
|
clear_preparateur(); |
clear_adaptateur(); |
clear_analyseur(); |
|
|
#ifdef DEBUG |
/* Affichage des informations de debuging : */ |
print_mem(stderr); |
#endif |
|
return 0; |
} |
/gasm_with_mult2_instruction/psd_instr.sx
0,0 → 1,110
; This file is part of gasm. |
; |
; |
; If you encountered any problem, please contact : |
; |
; lmouton@enserg.fr |
; shangoue@enserg.fr |
; |
|
|
|
|
|
|
|
|
;================================= Surnoms des registres ================================== |
|
#D $ZERO {} {} { $0 } |
|
#D $AT {} {} { $1 } |
|
#D $V0 {} {} { $2 } |
#D $V1 {} {} { $3 } |
|
#D $A0 {} {} { $4 } |
#D $A1 {} {} { $5 } |
#D $A2 {} {} { $6 } |
#D $A3 {} {} { $7 } |
|
#D $T0 {} {} { $8 } |
#D $T1 {} {} { $9 } |
#D $T2 {} {} { $10 } |
#D $T3 {} {} { $11 } |
#D $T4 {} {} { $12 } |
#D $T5 {} {} { $13 } |
#D $T6 {} {} { $14 } |
#D $T7 {} {} { $15 } |
|
#D $S1 {} {} { $16 } |
#D $S2 {} {} { $17 } |
#D $S3 {} {} { $18 } |
#D $S4 {} {} { $19 } |
#D $S5 {} {} { $20 } |
#D $S6 {} {} { $21 } |
#D $S7 {} {} { $22 } |
#D $S8 {} {} { $23 } |
|
#D $T8 {} {} { $24 } |
#D $T9 {} {} { $25 } |
|
#D $K0 {} {} { $26 } |
#D $K1 {} {} { $27 } |
|
#D $GP {} {} { $28 } |
|
#D $SP {} {} { $29 } |
|
#D $FP {} {} { $30 } |
|
#D $RA {} {} { $31 } |
|
; Registres internes du coprocesseur systeme |
|
#D STATUS {} {} { $12 } |
#D CAUSE {} {} { $13 } |
#D EPC {} {} { $14 } |
#D VECTIT {} {} { $15 } |
|
|
;============= Fonctions du coprocesseur systeme pour l'instruction COP0 ================ |
|
#D MASK {} {} { 1 } |
#D UNMASK {} {} { 2 } |
#D ITRET {} {} { 4 } ; Retour d'interruption |
|
|
;================================== Pseudo-instructions =================================== |
|
#D NOP {} {} { SLL $0, $0, 0 } |
|
#D BLT {r o a} {r, o, a} { SLT $1,r, o ;/ Justifie le registre at ($1) |
BNE $1, $0, a } ;/ reserve par l'assembleur. |
|
#D MOVE { Rt Rs } {Rt, Rs} { ADDU Rt, $0, Rs} ;/ addition 'unsigned' avec zero |
#D LI { Rt Int } {Rt, Int}{ ORI Rt, $ZERO, Int} ;/ Chargement de valeur immediate |
|
#D INC { R } { R } { ADDI R, R, 1 } |
#D DEC { R } { R } { ADDI R, R, -1 } |
#D INCW { R } { R } { ADDI R, R, 4 } |
#D DECW { R } { R } { ADDI R, R, -4 } |
#D STOP { etq } { etq } { etq: J etq } |
#D RETURN {} {} { JR $31 } |
#D RIT {} {} { COP0 ITRET } |
|
#D LOCK {} {} { LI $K0, @FFFF LW $ZERO, 0($K0) } ;/ plantage du processeur |
|
; Utilisation d'une pile |
|
#D INIT_SP { adresse } { adresse } { ADDI $SP, $0, adresse } |
#D PUSH { reg } { reg } { DECW $SP SW reg, 0($SP) } |
#D PULL { reg } { reg } { LW reg, 0($SP) INCW $SP } |
|
#D FOR { boucle reg max } |
{ reg from max downto 0 DO boucle } |
{ boucle: LI reg, max } |
#D NEXT { reg boucle } |
{ reg, boucle } |
{ DEC reg BGEZ reg, boucle } |
|
/gasm_with_mult2_instruction/readme.txt
0,0 → 1,2
1 - To generate the asmips assemblee, run make |
2 - The files Syntaxe and psd_instr.sx must be in the same repository than your assemblee code |