forked from pfaure/CrossAssembleur
327 lines
8.5 KiB
C
327 lines
8.5 KiB
C
|
|
/*
|
|
----------------------------------------
|
|
| Adresse | Registre | Modifié |
|
|
----------------------------------------
|
|
| | | |
|
|
| | | |
|
|
| | | |
|
|
| i | 0x777756b8 | int |
|
|
| size | 0x777756b8 | int |
|
|
----------------------------------------
|
|
*/
|
|
|
|
#include "tables.h"
|
|
#define NB_REG 4
|
|
#define MEM_SIZE 16
|
|
#define NB_INSTRUCTIONS 64
|
|
#define MEM_INST_SIZE 64
|
|
#define NB_BITS_INSTRUCTION 5
|
|
#define NB_BITS 8
|
|
|
|
int traduction_JMP[NB_INSTRUCTIONS];
|
|
|
|
struct str_instruction {
|
|
enum instruction_t instruction;
|
|
int param1;
|
|
int param2;
|
|
int param3;
|
|
};
|
|
|
|
int last_instruction = 0;
|
|
struct str_instruction buffer[3*NB_INSTRUCTIONS];
|
|
|
|
void add_instruction(enum instruction_t inst, int param1, int param2, int param3) {
|
|
struct str_instruction my_instruction = {inst, param1, param2, param3};
|
|
buffer[last_instruction] = my_instruction;
|
|
last_instruction++;
|
|
}
|
|
|
|
void write_asm(FILE * file) {
|
|
int i = 0;
|
|
while (i<MEM_INST_SIZE) {
|
|
if (buffer[i].instruction == ADD) {
|
|
fprintf(file, "ADD %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
|
|
} else if (buffer[i].instruction == SUB) {
|
|
fprintf(file, "SUB %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
|
|
} else if (buffer[i].instruction == MUL) {
|
|
fprintf(file, "MUL %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
|
|
} else if (buffer[i].instruction == DIV) {
|
|
fprintf(file, "DIV %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
|
|
} else if (buffer[i].instruction == INF) {
|
|
fprintf(file, "INF %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
|
|
} else if (buffer[i].instruction == SUP) {
|
|
fprintf(file, "SUP %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
|
|
} else if (buffer[i].instruction == EQU) {
|
|
fprintf(file, "EQU %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
|
|
|
|
} else if (buffer[i].instruction == AFC) {
|
|
fprintf(file, "AFC %d %d\n", buffer[i].param1, buffer[i].param2);
|
|
} else if (buffer[i].instruction == CPY) {
|
|
fprintf(file, "CPY %d %d\n", buffer[i].param1, buffer[i].param2);
|
|
|
|
} else if (buffer[i].instruction == LOAD) {
|
|
fprintf(file, "LOAD %d %d\n", buffer[i].param1, buffer[i].param2);
|
|
} else if (buffer[i].instruction == STORE) {
|
|
fprintf(file, "STORE %d %d\n", buffer[i].param1, buffer[i].param2);
|
|
} else if (buffer[i].instruction == LOADI) {
|
|
fprintf(file, "LOADI %d %d\n", buffer[i].param1, buffer[i].param2);
|
|
} else if (buffer[i].instruction == STOREI) {
|
|
fprintf(file, "STOREI %d %d\n", buffer[i].param1, buffer[i].param2);
|
|
} else if (buffer[i].instruction == STOREA) {
|
|
fprintf(file, "STOREA %d %d\n", buffer[i].param1, buffer[i].param2);
|
|
|
|
} else if (buffer[i].instruction == JMP) {
|
|
fprintf(file, "JMP %d\n", traduction_JMP[buffer[i].param1]);
|
|
} else if (buffer[i].instruction == JMZ) {
|
|
fprintf(file, "JMZ %d\n", traduction_JMP[buffer[i].param1]);
|
|
} else if (buffer[i].instruction == GET) {
|
|
fprintf(file, "GET %d\n", buffer[i].param1);
|
|
} else if (buffer[i].instruction == PRI) {
|
|
fprintf(file, "PRI %d\n", buffer[i].param1);
|
|
|
|
} else if (buffer[i].instruction == CALL) {
|
|
fprintf(file, "CALL %d %d\n", traduction_JMP[buffer[i].param1], buffer[i].param2);
|
|
} else if (buffer[i].instruction == RET) {
|
|
fprintf(file, "RET\n");
|
|
} else if (buffer[i].instruction == STOP) {
|
|
fprintf(file, "STOP %d\n", buffer[i].param1);
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void int_2_bin(char * buff, int n) {
|
|
int _m = n;
|
|
for (int i = 0; i < 32; i++) {
|
|
buff[31 - i] = ((_m & (1 << 31)) ? '1' : '0');
|
|
_m = _m << 1;
|
|
}
|
|
}
|
|
|
|
void convert_to_binary_on_N(int value, int N, char * buff) {
|
|
char tampon[33];
|
|
int_2_bin(tampon, value);
|
|
int i;
|
|
for (i = N-1; i>=0; i--) {
|
|
buff[N-1-i] = tampon[i];
|
|
}
|
|
buff[N] = '\0';
|
|
}
|
|
|
|
void write_instruction_binary(FILE * file, struct str_instruction instr) {
|
|
char buff1[33];
|
|
char buff2[33];
|
|
char buff3[33];
|
|
char buff4[33];
|
|
convert_to_binary_on_N(instr.instruction, NB_BITS_INSTRUCTION, buff1);
|
|
convert_to_binary_on_N(instr.param1, NB_BITS, buff2);
|
|
convert_to_binary_on_N(instr.param2, NB_BITS, buff3);
|
|
convert_to_binary_on_N(instr.param3, NB_BITS, buff4);
|
|
fprintf(file, "\"%s%s%s%s\" & ", buff1, buff2, buff3, buff4);
|
|
}
|
|
|
|
|
|
void write_code_machine(FILE * file) {
|
|
int i = MEM_INST_SIZE - 1;
|
|
while (i>=0) {
|
|
write_instruction_binary(file, buffer[i]);
|
|
i--;
|
|
}
|
|
}
|
|
|
|
|
|
struct case_adresse {
|
|
int adresse;
|
|
int registre;
|
|
char modifie;
|
|
};
|
|
|
|
struct case_adresse tableau[MEM_SIZE];
|
|
int registres[NB_REG];
|
|
|
|
void init (void) {
|
|
int i;
|
|
struct case_adresse case_courante = {0, -1, 0};
|
|
for (i=0; i<MEM_SIZE; i++) {
|
|
case_courante.adresse = i;
|
|
tableau[i] = case_courante;
|
|
}
|
|
for (i=0; i<NB_REG; i++) {
|
|
registres[i] = 0;
|
|
}
|
|
struct str_instruction nop = {NOP, 0, 0, 0};
|
|
for (i=0; i<MEM_INST_SIZE; i++) {
|
|
buffer[i] = nop;
|
|
}
|
|
}
|
|
|
|
void print_case_adresse(struct case_adresse case_courante) {
|
|
printf("{addr : %d ; reg : %d ; modi : %d}\n", case_courante.adresse, case_courante.registre, (int)case_courante.modifie);
|
|
}
|
|
|
|
void print() {
|
|
int i;
|
|
for (i=0; i<MEM_SIZE; i++) {
|
|
print_case_adresse(tableau[i]);
|
|
}
|
|
}
|
|
|
|
|
|
struct case_adresse get_info(int adresse) {
|
|
return tableau[adresse];
|
|
}
|
|
|
|
int get_adresse (int registre) {
|
|
int i = 0;
|
|
while (i < MEM_SIZE && tableau[i].registre != registre) {
|
|
i++;
|
|
}
|
|
if (i == MEM_SIZE) {
|
|
return -1;
|
|
} else {
|
|
return tableau[i].adresse;
|
|
}
|
|
}
|
|
|
|
void set_registre(int adresse, int registre) {
|
|
tableau[adresse].registre = registre;
|
|
}
|
|
|
|
void set_modifie(int adresse, char modifie) {
|
|
tableau[adresse].modifie = modifie;
|
|
}
|
|
|
|
void increment_time() {
|
|
int i;
|
|
for (i=0; i<NB_REG; i++) {
|
|
registres[i]++;
|
|
}
|
|
}
|
|
|
|
void refresh_registre(int registre) {
|
|
registres[registre] = 0;
|
|
}
|
|
|
|
int get_register() {
|
|
int i;
|
|
int index_max = 0;
|
|
for (i=0; i<NB_REG; i++) {
|
|
if (registres[index_max] < registres[i]) {
|
|
index_max = i;
|
|
}
|
|
}
|
|
return index_max;
|
|
}
|
|
|
|
int get_reg_write(int adresse, int * added_instruction) {
|
|
if (adresse == -1) {
|
|
int dispo = get_register();
|
|
int previous_addr = get_adresse(dispo);
|
|
if (previous_addr != -1) {
|
|
struct case_adresse ancienne_case = get_info(previous_addr);
|
|
if (ancienne_case.modifie == 1) {
|
|
add_instruction(STORE, previous_addr, dispo, 0);
|
|
*added_instruction = (*added_instruction) + 1;
|
|
set_modifie(previous_addr, 0);
|
|
}
|
|
set_registre(previous_addr, -1);
|
|
}
|
|
return dispo;
|
|
} else {
|
|
set_modifie(adresse, 1);
|
|
struct case_adresse ma_case = get_info(adresse);
|
|
if (ma_case.registre == -1) {
|
|
int dispo = get_register();
|
|
int previous_addr = get_adresse(dispo);
|
|
if (previous_addr != -1) {
|
|
struct case_adresse ancienne_case = get_info(previous_addr);
|
|
if (ancienne_case.modifie == 1) {
|
|
*added_instruction = (*added_instruction) + 1;
|
|
add_instruction(STORE, previous_addr, dispo, 0);
|
|
set_modifie(previous_addr, 0);
|
|
}
|
|
set_registre(previous_addr, -1);
|
|
}
|
|
set_registre(adresse, dispo);
|
|
refresh_registre(dispo);
|
|
return dispo;
|
|
} else {
|
|
refresh_registre(ma_case.registre);
|
|
return ma_case.registre;
|
|
}
|
|
}
|
|
}
|
|
|
|
int get_reg_read(int adresse, int * added_instruction) {
|
|
struct case_adresse ma_case = get_info(adresse);
|
|
if (ma_case.registre == -1) {
|
|
int dispo = get_register();
|
|
int previous_addr = get_adresse(dispo);
|
|
if (previous_addr != -1) {
|
|
struct case_adresse ancienne_case = get_info(previous_addr);
|
|
if (ancienne_case.modifie == 1) {
|
|
*added_instruction = (*added_instruction) + 1;
|
|
add_instruction(STORE, previous_addr, dispo, 0);
|
|
set_modifie(previous_addr, 0);
|
|
}
|
|
set_registre(previous_addr, -1);
|
|
}
|
|
*added_instruction = (*added_instruction) + 1;
|
|
add_instruction(LOAD, dispo, adresse, 0);
|
|
set_registre(adresse, dispo);
|
|
refresh_registre(dispo);
|
|
return dispo;
|
|
} else {
|
|
refresh_registre(ma_case.registre);
|
|
return ma_case.registre;
|
|
}
|
|
}
|
|
|
|
|
|
int flush_and_init() {
|
|
int i;
|
|
int added_instruction = 0;
|
|
for (i = 0; i<MEM_SIZE; i++) {
|
|
if (tableau[i].registre != -1) {
|
|
if (tableau[i].modifie == 0) {
|
|
tableau[i].registre = -1;
|
|
} else {
|
|
add_instruction(STORE, i, tableau[i].registre, 0);
|
|
added_instruction++;
|
|
tableau[i].registre = -1;
|
|
tableau[i].modifie = 0;
|
|
}
|
|
}
|
|
}
|
|
for (i=0; i<NB_REG; i++) {
|
|
registres[i] = 0;
|
|
}
|
|
return added_instruction;
|
|
}
|
|
|
|
void new_instruction(int nb_inst) {
|
|
static int last_intruction_adresse = 0;
|
|
static int current_instruction = 0;
|
|
traduction_JMP[current_instruction] = last_intruction_adresse;
|
|
current_instruction++;
|
|
last_intruction_adresse += nb_inst;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|