Skip to content

Instantly share code, notes, and snippets.

@rafabarbosa
Created March 26, 2017 17:13
Show Gist options
  • Save rafabarbosa/d49b06a61daa3bfb5aae8b0fa37229d4 to your computer and use it in GitHub Desktop.
Save rafabarbosa/d49b06a61daa3bfb5aae8b0fa37229d4 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
// Disciplina: Arquitetura de Computadores
// Aluno: Rafael Barbosa Conceição
// Matrícula: 201420014973
unsigned int R[39];
const char* parametro(int num);
const char* valor(int num);
void checkR0();
int main(int argc, char* argv[]){
// Variáveis para trabalhar localmente
argv[1] ="FPU.txt";
argv[2] ="saida.txt";
// mostrando informações do programa
printf("#ARGS = %i\n", argc);
printf("PROGRAMA = %s\n", argv[0]);
printf("ARG1 = %s, ARG2 = %s\n", argv[1], argv[2]);
// Ponteiros de arquivos
FILE *entrada;
FILE *saida;
// Declarando variáveis a ser utilizada
uint64_t multi, aux;
unsigned int *MEM, ch, RY, RX, OP, OPC, IM16, IM26;
int i, contaLinha = 0, cursor, Z, X, Y, N, IV, INTP = 0, result = 0, EX=0, EY=0, SZ=0, CTRL=0, S, size = 0, counter_ctrl = 0, INTT = 0;
// Determinando o valor de R0, que é imutável.
R[0] = 0x00000000;
char *terminal;
terminal = malloc(size);
terminal = NULL;
entrada = fopen(argv[1], "r");
saida = fopen(argv[2], "w");
while((cursor = fgetc(entrada)) != EOF){
if(cursor == '\n'){
MEM = (unsigned int *) realloc(NULL, contaLinha++ * sizeof(unsigned int));
}
}
fclose(entrada);
// Carregando a memória
entrada = fopen(argv[1], "r");
for(i = 0; fscanf(entrada, "%x", &ch) != EOF; i++){
MEM[i] = ch;
}
fclose(entrada);
R[32] = 0;
R[33] = 0;
R[34] = 0;
R[35] = 0x0;
R[36] = 0;
R[37] = 0x0;
fprintf(saida, "[START OF SIMULATION]\n");
while (INTP != 1) {
OP = (MEM[R[32]] & 0xFC000000) >> 26;
switch(OP){
// 000000 - Operação de adição com registradores
// Instrução ADD
// Tipo U
// R[Z] = R[X] + R[Y]
// Campo relacionado: OV
case 0x00:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
R[Z] = R[X] + R[Y];
checkR0();
R[35] = (R[Z] < R[X]) || (R[Z] < R[Y]) ? R[35] | 0x00000010 : R[35] & 0xffffffef;
// VERIFICANDO OVERFLOW
// aux = (uint64_t)R[X] + (uint64_t)R[Y];
// if(aux > 0xffffffff){
// R[35] = R[35] | 0x00000010;
// }
fprintf(saida, "add %s, %s, %s\n[U] FR = 0x%08X, %s = %s + %s = 0x%08X\n", parametro(Z), parametro(X), parametro(Y), R[35], valor(Z), valor(X), valor(Y), R[Z]);
R[32]++;
break;
// 000001 - Operação de adição imediata
// Instrução ADDI
// Tipo F
// R[Z] = R[X] + IM16
// Campo relacionado: OV
case 0x01:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
R[X] = R[Y] + IM16;
checkR0();
R[35] = (R[X] < RY) || (R[X] < IM16) ? R[35] | 0x00000010 : R[35] & 0xffffffef;
// VERIFICANDO OVERFLOW
// aux = (uint64_t)R[Y] + (uint64_t)IM16;
// if(aux > 0xffffffff){
// R[35] = R[35] | 0x00000010;
// }
fprintf(saida, "addi %s, %s, %d\n[F] FR = 0x%08X, %s = %s + 0x%04X = 0x%08X\n", parametro(X), parametro(Y), IM16, R[35], valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
// 000010 - Operação de subtração com registradores
// Instrução SUB
// Tipo U
// R[Z] = R[X] - R[Y]
// Campo relacionado: OV
case 0x02:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
R[Z] = R[X] - R[Y];
checkR0();
R[35] = (R[Z] > (R[X] + R[Y])) ? R[35] | 0x00000010 : R[35] & 0xffffffef;
// VERIFICANDO OVERFLOW
// aux = (uint64_t)R[X] - (uint64_t)R[Y];
// if(aux > 0xffffffff){
// R[35] = R[35] | 0x00000010;
// }
fprintf(saida, "sub %s, %s, %s\n[U] FR = 0x%08X, %s = %s - %s = 0x%08X\n", parametro(Z), parametro(X), parametro(Y), R[35], valor(Z), valor(X), valor(Y), R[Z]);
R[32]++;
break;
// 000011 - Operação de subtração imediata
// Instrução SUBI
// Tipo F
// R[Z] = R[X] - IM16
// Campo relacionado: OV
case 0x03:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
R[X] = R[Y] - IM16;
checkR0();
R[35] = R[X] > (R[Y] + IM16)? R[35] | 0x00000010 : R[35] & 0xffffffef;
// VERIFICANDO OVERFLOW
// aux = (uint64_t)R[Y] - (uint64_t)IM16;
// if(aux > 0xffffffff){
// R[35] = R[35] | 0x00000010;
// }
fprintf(saida, "subi %s, %s, %d\n[F] FR = 0x%08X, %s = %s - 0x%04X = 0x%08X\n", parametro(X), parametro(Y), IM16, R[35], valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
// 000100 - Operação de multiplicação com registradores
// Instrução MUL
// Tipo U
// ER|R[Z] = R[X] x R[Y]
// Campo relacionado: OV
case 0x04:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
RY = R[Y];
RX = R[X];
multi = (uint64_t) R[X] * (uint64_t) R[Y];
R[34] = multi >> 32;
R[Z] = multi;
checkR0();
R[35] = R[34] != 0 ? R[35] | 0x00000010 : R[35] & 0xffffffef;
fprintf(saida, "mul %s, %s, %s\n[U] FR = 0x%08X, ER = 0x%08X, %s = %s * %s = 0x%08X\n", parametro(Z), parametro(X), parametro(Y), R[35], R[34], valor(Z), valor(X), valor(Y), R[Z]);
R[32]++;
break;
// 000101 - Operação de multiplicação imediata
// Instrução MULI
// Tipo U
// ER|R[Z] = R[X] - IM16
// Campo relacionado: OV
case 0x05:
multi = 0;
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
RY = R[Y];
multi = (uint64_t) RY * (uint64_t) IM16;
R[34] = multi >> 32;
R[X] = multi;
checkR0();
R[35] = R[34] != 0 ? R[35] | 0x00000010 : R[35] & 0xffffffef;
fprintf(saida, "muli %s, %s, %d\n[F] FR = 0x%08X, ER = 0x%08X, %s = %s * 0x%04X = 0x%08X\n", parametro(X), parametro(Y), IM16, R[35], R[34], valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
//000110 - Operação de divisão com registradores
// Instrução DIV
// Tipo U
// R[34] = R[X] mod R[Y], R[Z] = R[X] / R[Y]
// Campo relacionado: OV e ZD
case 0x06:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
if(R[Y] == 0){
R[35] = R[35] | 0x8;
// verifica se IE == 1
if(R[35] & 0x40){
R[35] = R[35] | 0x8; // ZD = 1
R[36] = 1;
INTT = 1;
R[37] = R[32] + 1;
}
} else {
R[35] = R[35] | 0x7; // ZD = 0 //Zerando ZD
R[Z] = R[X] / R[Y];
R[34] = R[X] % R[Y];
}
fprintf(saida, "div %s, %s, %s\n[U] FR = 0x%08X, ER = 0x%08X, %s = %s / %s = 0x%08X\n", parametro(Z), parametro(X), parametro(Y), R[35], R[34], valor(Z), valor(X), valor(Y), R[Z]);
R[32]++;
break;
//000111 - Operação de divisão imediata
// Instrução DIVI
// Tipo F
// ER = R[Y] mod IM16, R[X] = R[Y] / IM16
// Campo relacionado: OV e ZD
case 0x07:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
if(IM16 == 0){
R[35] = R[35] | 0x8;
int aux = R[35] & 0x40;
// verifica se IE == 1
if(aux){
R[35] = R[35] | 0x8; // ZD = 1
R[36] = 1;
INTT = 1;
R[37] = R[32] + 1;
checkR0();
}
} else {
R[35] = R[35] | 0x7; // ZD = 0 //Zerando ZD
R[X] = R[Y] / IM16;
R[34] = R[Y] % IM16;
checkR0();
}
fprintf(saida, "divi %s, %s, %d\n[F] FR = 0x%08X, ER = 0x%08X, %s = %s / 0x%04X = 0x%08X\n", parametro(X), parametro(Y), IM16, R[35], R[34], valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
//001000 - Operação de comparação com registradores
// Instrução CMP
// Tipo U
// EQ = (R[x] == R[y])
// LT = (R[x] < R[y])
// GT = (R[x] > R[y])
case 0x08:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
//R[35] = (R[35] & 0x18);
if(R[X] == R[Y]){
R[35] = (R[35] & 0xFFFFFFF9) | 0x01;
} else if(R[X] < R[Y]){
R[35] = (R[35] & 0xFFFFFFFA) | 0x02;
} else if(R[X] > R[Y]){
R[35] = (R[35] & 0xFFFFFFFC) | 0x04;
}
fprintf(saida, "cmp %s, %s\n[U] FR = 0x%08X\n", parametro(X), parametro(Y), R[35]);
R[32]++;
break;
//001001 - Operação de comparação imediata
// Instrução CMPI
// Tipo F
// EQ = (R[x] == IM16)
// LT = (R[x] < IM16)
// GT = (R[x] > IM16)
case 0x09:
X = (MEM[R[32]] & 0x000003E0) >> 5;
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
if(R[X] == IM16){
R[35] = (R[35] & 0xF8) | 0x01;
}else if(R[X] < IM16){
R[35] = (R[35] & 0xF8) | 0x02;
}else if(R[X] > IM16){
R[35] = (R[35] & 0xF8) | 0x04;
}
fprintf(saida, "cmpi %s, %d\n[F] FR = 0x%08X\n", parametro(X), IM16, R[35]);
R[32]++;
break;
// 001010 - Operação de deslocamento para esquerda
// Instrução SHL
// Tipo U
// ER | R[Z] = ER | R[X] << (y + 1) = ER | R[x] × 2^(y+1)
case 0x0A:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
R[34] = (MEM[R[32]] & 0x00038000) >> 15;
Y = ( R[34] << 5 ) | Y;
uint64_t auxiliar = (uint64_t) R[X] << (Y+1);
R[34] = auxiliar >> 32;
R[Z] = (auxiliar << 32) >> 32;
fprintf(saida, "shl %s, %s, %d\n[U] ER = 0x%08X, %s = %s << %d = 0x%08X\n", parametro(Z), parametro(X), Y, R[34], valor(Z), valor(X), (Y + 1), R[Z]);
R[32]++;
break;
// 001011 - Operação de deslocamento para direita
// Instrução SHR
// Tipo U
// ER | R[Z] = ER | R[X] >> (y + 1) = ER | R[x] / 2^^(y+1)
case 0x0B:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
R[Z] = R[X] >> (Y + 1);
result = R[34] << (32 - (Y + 1));
R[Z] = (R[Z] | result);
R[34] = R[34] >> (32 - (Y + 1));
fprintf(saida, "shr %s, %s, %d\n[U] ER = 0x%08X, %s = %s >> %d = 0x%08X\n", parametro(Z), parametro(X), Y , R[34], valor(Z), valor(X), (Y+1), R[Z]);
R[32]++;
break;
// 001100 - Operação de AND
// Instrução AND
// Tipo U
// R[Z] = R[X] ^ R[Y]
case 0x0C:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
R[Z] = (R[X] & R[Y]);
fprintf(saida, "and %s, %s, %s\n[U] %s = %s & %s = 0x%08X\n", parametro(Z), parametro(X), parametro(Y), valor(Z), valor(X), valor(Y), R[Z]);
R[32]++;
break;
// 001101 - Operação de AND imediato
// Instrução ANDI
// Tipo F
// R[X] = R[Y] ^ IM16
case 0x0D:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
R[X] = R[Y] & IM16;
fprintf(saida, "andi %s, %s, %d\n[F] %s = %s & 0x%04X = 0x%08X\n", parametro(X), parametro(Y), IM16, valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
// 001110 - Operação de NOT
// Instrução NOT
// Tipo U
// R[X] = ~R[Y]
case 0x0E:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
R[X] = ~(R[Y]);
fprintf(saida, "not %s, %s\n[F] %s = ~%s = 0x%08X\n", parametro(X), parametro(Y), valor(X), valor(Y), R[X]);
R[32]++;
break;
// 001111 - Operação de NOT imediato
// Instrução NOTI
// Tipo F
// R[X] = ~IM16
case 0x0F:
X = (MEM[R[32]] & 0x000003E0) >> 5;
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
R[X] = ~(IM16);
fprintf(saida, "noti %s, %d\n[F] %s = ~0x%04X = 0x%08X\n", parametro(X), IM16, valor(X), IM16, R[X]);
R[32]++;
break;
// 010000 - Operação de OR
// Instrução OR
// Tipo U
// R[Z] = R[X] v R[Y]
case 0x10:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
R[Z] = R[X] | R[Y];
R[35] = R[Z];
fprintf(saida, "or %s, %s, %s\n[U] %s = %s | %s = 0x%08X\n", parametro(Z), parametro(X), parametro(Y), valor(Z), valor(X), valor(Y), R[Z]);
R[32]++;
break;
// 010001 - Operação de OR imediato
// Instrução ORI
// Tipo F
// R[X] = R[Y] v IM16
case 0x11:
X = (MEM[R[32]] & 0x000003E0) >> 5;
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
Y = (MEM[R[32]] & 0x0000001F);
R[X] = R[Y] | IM16;
fprintf(saida, "ori %s, %s, %d\n[F] %s = %s | 0x%04X = 0x%08X\n", parametro(X), parametro(Y), IM16, valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
// 010010 - Operação de XOR
// Instrução XOR
// Tipo U
// R[Z] = R[X] xor R[Y]
case 0x12:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Z = (MEM[R[32]] & 0x00007C00) >> 10;
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
Z = (((MEM[R[32]] & 0x00020000) >> 17) << 5 ) | Z;
R[Z] = R[X] ^ R[Y];
fprintf(saida, "xor %s, %s, %s\n[U] %s = %s ^ %s = 0x%08X\n", parametro(Z), parametro(X), parametro(Y), valor(Z), valor(X), valor(Y), R[Z]);
R[32]++;
break;
// 010011 - Operação de XOR imediato
// Instrução XORI
// Tipo F
// R[X] = R[Y] xor IM16
case 0x13:
X = (MEM[R[32]] & 0x000003E0) >> 5;
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
Y = (MEM[R[32]] & 0x0000001F);
R[X] = R[Y] ^ IM16;
fprintf(saida, "xori %s, %s, %d\n[F] %s = %s ^ 0x%04X = 0x%08X\n", parametro(X), parametro(Y), IM16, valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
// 010100 - Operação de leitura de palavra da memória
// Instrução LDW
// Tipo F
// R[X] = MEM[(R[Y] + IM16) << 2]
case 0x14:
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
R[X] = MEM[(R[Y] + IM16)];
fprintf(saida, "ldw %s, %s, 0x%04X\n[F] %s = MEM[(%s + 0x%04X) << 2] = 0x%08X\n", parametro(X), parametro(Y), IM16, valor(X), valor(Y), IM16, R[X]);
R[32]++;
break;
// 010101 - Operação de leitura de byte da memória
// Instrução LDB
// Tipo F
// R[X] = MEM[R[Y] + IM16]
case 0x15:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
Y = (MEM[R[32]] & 0x0000001F);
X = (MEM[R[32]] & 0x000003E0) >> 5;
unsigned int RXB = 0;
if(((R[Y] + IM16) % 4) == 3 ){
R[X] = (RX & 0xFFFFFF00) | (MEM[(R[Y] + IM16) >> 2] & 0x000000FF);
RXB = (MEM[(R[Y] + IM16) >> 2] & 0x000000FF);
}
if(((RY + IM16) % 4) == 2 ){
R[X] = (RX & 0xFFFFFF00) | (MEM[(RY + IM16) >> 2] & 0x0000FF00) >> 8;
RXB = (MEM[(RY + IM16) >> 2] & 0x0000FF00) >> 8;
}
if(((RY + IM16) % 4) == 1 ){
R[X] = (RX & 0xFFFFFF00) | (MEM[(RY + IM16) >> 2] & 0x00FF0000) >> 16;
RXB = (MEM[(RY + IM16) >> 2] & 0x00FF0000) >> 16;
}
if(((RY + IM16) % 4) == 0 ){
R[X] = (RX & 0xFFFFFF00) | (MEM[(RY + IM16) >> 2] & 0xFF000000) >> 24;
RXB = (MEM[(RY + IM16) >> 2] & 0xFF000000) >> 24;
}
fprintf(saida, "ldb %s, %s, 0x%04X\n[F] %s = MEM[%s + 0x%04X] = 0x%02X\n", parametro(X), parametro(Y), IM16, valor(X), valor(Y), IM16, RXB);
R[32]++;
X++;
break;
// 010110 - Operação de escrita de palavra da memória
// Instrução STW
// Tipo F
// MEM[(R[Y] + IM16) << 2] = R[Y]
case 0x16:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
if((R[Y] + IM16) << 2 == 0x8000){
EX = R[Y];
}else if((R[Y] + IM16) << 2 == 0x8004){
EY = R[Y];
}else if((R[Y] + IM16) << 2 == 0x8008){
SZ = R[Y];
}else if((R[Y] + IM16) << 2 == 0x800C){
CTRL = R[Y];
INTT = 2;
}else{
MEM[(R[Y] + IM16)] = RY;
}
fprintf(saida, "stw %s, 0x%04X, %s\n[F] MEM[(%s + 0x%04X) << 2] = %s = 0x%08X\n", parametro(X), IM16, parametro(Y), valor(X), IM16, valor(Y), R[Y]);
R[32]++;
break;
// 010111 - Operação de escrita de byte da memória
// Instrução STB
// Tipo F
// MEM[R[Y] + IM16] = R[Y]
case 0x17:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
// Tratar apenas os ultimos dois LSB de RY
unsigned LSB = (R[Y] & 0x000000FF);
if(R[X] + IM16 == 0x888B){
terminal = (char*) realloc(terminal, sizeof(char) * (size + 1));
terminal[size] = LSB;
size++;
} else {
if(((R[X] + IM16) % 4) == 3 ){
MEM[(R[X] + IM16) >> 2] = (R[Y] & 0x000000FF) | (MEM[(R[X] + IM16) >> 2] & 0xFFFFFF00);
}
if(((R[X] + IM16) % 4) == 2 ){
MEM[(R[X] + IM16) >> 2] = (R[Y] & 0x000000FF) << 8 | (MEM[(R[X] + IM16) >> 2] & 0xFFFF00FF);
}
if(((R[X] + IM16) % 4) == 1 ){
MEM[(R[X] + IM16) >> 2] = (R[Y] & 0x000000FF) << 16 | (MEM[(R[X] + IM16) >> 2] & 0xFF00FFFF) ;
}
if(((R[X] + IM16) % 4) == 0 ){
MEM[(R[X] + IM16) >> 2] = (R[Y] & 0x000000FF) << 24 | (MEM[(R[X] + IM16) >> 2] & 0x00FFFFFF);
}
}
fprintf(saida, "stb %s, 0x%04X, %s\n[F] MEM[%s + 0x%04X] = %s = 0x%02X\n", parametro(X), IM16, parametro(Y), valor(X), IM16, valor(Y), LSB);
R[32]++;
break;
// 011000 - PUSH
// Tipo U
// Equivalente às instruções stw e subi, empilhando o
// dado R[y] e decrementa o topo da pilha R[x]
case 0x18:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
// stw
MEM[R[X]] = R[Y];
// subi
R[X] = R[X] - 1;
fprintf(saida, "push %s, %s\n[U] MEM[%s--] = %s = 0x%08X\n", parametro(X), parametro(Y), valor(X), valor(Y), R[Y]);
R[32]++;
break;
// 011001 - POP
// Tipo U
// Equivalente às instruções ldw e addi, desempilhando
// o dado R[x] e incrementando o topo da pilha R[y]
case 0x19:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
X = (MEM[R[32]] & 0x000003E0) >> 5;
Y = (MEM[R[32]] & 0x0000001F);
Y = (((MEM[R[32]] & 0x00008000) >> 15) << 5 ) | Y;
X = (((MEM[R[32]] & 0x00010000) >> 16) << 5 ) | X;
// addi
R[Y] = R[Y] + 1;
// ldw
R[X] = MEM[R[Y]];
fprintf(saida, "pop %s, %s\n[U] %s = MEM[++%s] = 0x%08X\n", parametro(X), parametro(Y), valor(X), valor(Y), R[X]);
R[32]++;
break;
// 011010 - Operação de desvio incondicional
// Instrução BUN
// Tipo S
// PC = IM16 << 2
case 0x1A:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
R[32] = IM26;
fprintf(saida, "bun 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 011011 - Operação de desvio condicional
// Instrução BEQ
// Tipo S
// EQ -> PC = IM26 << 2
case 0x1B:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000001) == 0x1) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "beq 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 011100 - Operação de desvio condicional
// Instrução BLT
// Tipo S
// LT -> PC = IM26 << 2
case 0x1C:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000002) == 0x2) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "blt 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 011101 - Operação de desvio condicional
// Instrução BGT
// Tipo S
// GT -> PC = IM26 << 2
case 0x1D:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000004) == 0x4) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "bgt 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 011110 - Operação de desvio condicional
// Instrução BNE
// Tipo S
// ~EQ -> PC = IM26 << 2
case 0x1E:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000001) != 0x1) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "bne 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 011111 - Operação de desvio condicional
// Instrução BLE
// Tipo S
// LT v EQ -> PC = IM26 << 2
case 0x1F:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000001) == 0x1 || (R[35] & 0x00000002) == 0x2) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "ble 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 100000 - Operação de desvio condicional
// Instrução BGE
// Tipo S
// GT v EQ -> PC = IM26 << 2
case 0x20:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000001) == 0x1 || (R[35] & 0x00000004) == 0x4) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "bge 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 100001 - Operação de desvio condicional
// Instrução BZD
// Tipo S
// ZD -> PC = IM26 << 2
case 0x21:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000008) == 0x8) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "bzd 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 100010 - Operação de desvio condicional
// Instrução BNZ
// Tipo S
// ~ZD -> PC = IM26 << 2
case 0x22:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000008) != 0x8) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "bnz 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 100011 - Operação de desvio condicional
// Instrução BIV
// Tipo S
// IV -> PC = IM26 << 2
case 0x23:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000020) == 0x20) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "biv 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 100100 - Operação de desvio condicional
// Instrução BNI
// Tipo S
// ~IV -> PC = IM26 << 2
case 0x24:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if((R[35] & 0x00000020) != 0x20) {
R[32] = IM26;
} else {
R[32]++;
}
fprintf(saida, "biv 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4);
break;
// 100001 - CALL
// Tipo F
// R[X] = (PC + 4) >> 2, PC = (R[Y] + IM16) << 2
case 0x25:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
Y = (MEM[R[32]] & 0x0000001F);
X = (MEM[R[32]] & 0x000003E0) >> 5;
R[X] = R[32] + 1;
checkR0();
R[32] = R[Y] + IM16;
fprintf(saida, "call %s, %s, 0x%04X\n[F] %s = (PC + 4) >> 2 = 0x%08X, PC = (%s + 0x%04X) << 2 = 0x%08X\n", parametro(X), parametro(Y), IM16, valor(X), R[X], valor(Y), IM16, R[32] << 2);
break;
// 100110 - RET
// Tipo F
// R[32] = R[X] << 2
case 0x26:
X = (MEM[R[32]] & 0x000003E0) >> 5;
R[32] = R[X];
fprintf(saida, "ret %s\n[F] PC = %s << 2 = 0x%08X\n", parametro(X), valor(X), R[32] << 2);
break;
// 100111 - Operação de chamada de rotina de interrupção
// Instrução ISR
// Tipo F
// R[x] = IPC >> 2, R[y] = CR, PC = IM16 << 2
case 0x27:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
Y = (MEM[R[32]] & 0x0000001F);
X = (MEM[R[32]] & 0x000003E0) >> 5;
R[X] = R[37];
R[Y] = R[36];
R[32] = IM16;
fprintf(saida, "isr %s, %s, 0x%04X\n[F] %s = IPC >> 2 = 0x%08X, %s = CR = 0x%08X, PC = 0x%08X\n", parametro(X), parametro(Y), IM16, valor(X), R[37], valor(Y), R[36], R[32]*4);
break;
// 101000 - Operação de retorno de rotina de interrupção
// Instrução RETI
// Tipo F
// R[32] = R[x] << 2
case 0x28:
IM16 = (MEM[R[32]] & 0x03FFFC00) >> 10;
Y = (MEM[R[32]] & 0x0000001F);
X = (MEM[R[32]] & 0x000003E0) >> 5;
R[32] = R[X];
fprintf(saida, "reti %s\n[F] PC = %d << 2 = 0x%08X\n", parametro(X), R[X], IM16);
break;
//111111 - Operação de desvio condicional
// Instrução INT
// Tipo S
// Se IM26 == 0, a execução é finalizada
// Se IM26 != 0 -> CR = IM26, PC = 0x0000000C
case 0x3F:
IM26 = (MEM[R[32]] & 0x03FFFFFF);
if(IM26 == 0) { INTP = 1; R[32] = 0xB; }
if(IM26 != 0){
R[36] = IM26; // CR = IM26
INTT = 1; // O corre interrupção
R[37] = R[32] + 1;
R[32] = 0xC;
fprintf(saida, "int %d\n[S] CR = 0x%08X, PC = 0x%08X\n", IM26, R[36], R[32]);
}
if(INTP == 1) {
N = R[32] = 0;
R[36] = 0x0;
fprintf(saida, "int %d\n[S] CR = 0x%08X, PC = 0x%08X\n", N, R[36], R[32]*4);
fprintf(saida, "[END OF SIMULATION]");
}
break;
default:
fprintf(saida, "[INVALID INSTRUCTION @ 0x%08X]\n", R[32]*4);
R[35] = R[35] | 0x20; // SETAR IV
INTT = 1;
R[36] = R[32];
R[32]++;
R[37] = R[32];
break;
}
if(INTT == 1){
fprintf(saida, "[SOFTWARE INTERRUPTION]\n");
R[32] = 0x3;
INTT = 0;
}
if(INTT == 2){
R[36] = 255;
counter_ctrl++;
if (counter_ctrl == 4) {
R[37] = R[32];
OPC = (CTRL & 0x0000000F);
switch (OPC) {
case 0x00:
CTRL = 0;
break;
case 0x01:
SZ = sqrt(pow(EX,2) + pow(EY, 2));
CTRL = 0;
break;
case 0x02:
if(EX == 0 && EY == 0){
CTRL = 0x20;
}else{
SZ = pow(EX, EY);
CTRL = 0;
}
break;
case 0x03:
SZ = (EX + EY) / 2;
CTRL = 0;
break;
default:
break;
}
fprintf(saida, "[HARDWARE INTERRUPTION]\n");
counter_ctrl = 0;
INTT = 0;
R[32] = 0x1;
}
}
} // fim do while
// Fechando os arquivos
fclose(entrada);
fclose(saida);
return 0;
}
const char* parametro(int num){
switch(num){
case 0: return "r0"; break;
case 1: return "r1"; break;
case 2: return "r2"; break;
case 3: return "r3"; break;
case 4: return "r4"; break;
case 5: return "r5"; break;
case 6: return "r6"; break;
case 7: return "r7"; break;
case 8: return "r8"; break;
case 9: return "r9"; break;
case 10: return "r10"; break;
case 11: return "r11"; break;
case 12: return "r12"; break;
case 13: return "r13"; break;
case 14: return "r14"; break;
case 15: return "r15"; break;
case 16: return "r16"; break;
case 17: return "r17"; break;
case 18: return "r18"; break;
case 19: return "r19"; break;
case 20: return "r20"; break;
case 21: return "r21"; break;
case 22: return "r22"; break;
case 23: return "r23"; break;
case 24: return "r24"; break;
case 25: return "r25"; break;
case 26: return "r26"; break;
case 27: return "r27"; break;
case 28: return "r28"; break;
case 29: return "r29"; break;
case 30: return "r30"; break;
case 31: return "r31"; break;
case 32: return "pc"; break;
case 33: return "ir"; break;
case 34: return "er"; break;
case 35: return "fr"; break;
case 36: return "cr"; break;
case 37: return "ipc"; break;
}
}
const char* valor(int num){
switch(num){
case 0: return "R0"; break;
case 1: return "R1"; break;
case 2: return "R2"; break;
case 3: return "R3"; break;
case 4: return "R4"; break;
case 5: return "R5"; break;
case 6: return "R6"; break;
case 7: return "R7"; break;
case 8: return "R8"; break;
case 9: return "R9"; break;
case 10: return "R10"; break;
case 11: return "R11"; break;
case 12: return "R12"; break;
case 13: return "R13"; break;
case 14: return "R14"; break;
case 15: return "R15"; break;
case 16: return "R16"; break;
case 17: return "R17"; break;
case 18: return "R18"; break;
case 19: return "R19"; break;
case 20: return "R20"; break;
case 21: return "R21"; break;
case 22: return "R22"; break;
case 23: return "R23"; break;
case 24: return "R24"; break;
case 25: return "R25"; break;
case 26: return "R26"; break;
case 27: return "R27"; break;
case 28: return "R28"; break;
case 29: return "R29"; break;
case 30: return "R30"; break;
case 31: return "R31"; break;
case 32: return "PC"; break;
case 33: return "IR"; break;
case 34: return "ER"; break;
case 35: return "FR"; break;
case 36: return "CR"; break;
case 37: return "IPC"; break;
}
}
void checkR0(){
if(R[0] != 0){
R[0] = 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment