Last active
December 14, 2022 12:55
-
-
Save rafabarbosa/30ff048a2cac81a5d5e91201e1451977 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 | |
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; | |
} | |
} | |
int main(int argc, char* argv[]){ | |
// Variáveis para trabalhar localmente | |
argv[1] ="poxim2.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, R[39]; | |
int i, contaLinha = 0, cursor, Z, X, Y, N, IV, FR, 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óriaf | |
entrada = fopen(argv[1], "r"); | |
for(i = 0; fscanf(entrada, "%x", &ch) != EOF; i++){ | |
MEM[i] = ch; | |
} | |
fclose(entrada); | |
R[32] = 0; | |
R[34] = 0; | |
R[36] = 0; | |
R[37] = 0; | |
FR = 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]; | |
// VERIFICANDO OVERFLOW | |
aux = (uint64_t)R[X] + (uint64_t)R[Y]; | |
if(aux > 0xffffffff){ | |
FR = FR | 0x00000010; | |
R[35] = FR; | |
} | |
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; | |
// VERIFICANDO OVERFLOW | |
aux = (uint64_t)R[Y] + (uint64_t)IM16; | |
if(aux > 0xffffffff){ | |
FR = FR | 0x00000010; | |
R[35] = FR; | |
} | |
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]; | |
// VERIFICANDO OVERFLOW | |
aux = (uint64_t)R[X] - (uint64_t)R[Y]; | |
if(aux > 0xffffffff){ | |
FR = FR | 0x00000010; | |
R[35] = FR; | |
} | |
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; | |
// VERIFICANDO OVERFLOW | |
aux = (uint64_t)R[Y] - (uint64_t)IM16; | |
if(aux > 0xffffffff){ | |
FR = FR | 0x00000010; | |
R[35] = FR; | |
} | |
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; | |
FR = R[34] != 0 ? FR | 0x00000010 : FR & 0xffffffef; | |
R[35] = FR; | |
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; | |
FR = R[34] != 0 ? FR | 0x00000010 : FR & 0xffffffef; | |
R[35] = FR; | |
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 | |
// ER = 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){ | |
FR = FR | 0x8; | |
R[35] = FR; | |
int aux = FR & 0x40; | |
// verifica se IE == 1 | |
if(aux){ | |
FR = FR | 0x8; // ZD = 1 | |
R[35] = FR; | |
R[36] = 1; | |
INTT = 1; | |
} | |
} else { | |
FR = FR | 0x7; // ZD = 0 //Zerando ZD | |
R[35] = FR; | |
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){ | |
FR = FR | 0x8; | |
R[35] = FR; | |
int aux = FR & 0x40; | |
// verifica se IE == 1 | |
if(aux){ | |
FR = FR | 0x8; // ZD = 1 | |
R[35] = FR; | |
R[36] = 1; | |
INTT = 1; | |
} | |
} else { | |
FR = FR | 0x7; // ZD = 0 //Zerando ZD | |
R[35] = FR; | |
R[X] = R[Y] / IM16; | |
R[34] = R[Y] % IM16; | |
} | |
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; | |
RX = R[X]; | |
RY = R[Y]; | |
FR = (FR & 0x18); | |
R[35] = FR; | |
if(RX == RY){ | |
FR = FR | 0x01; | |
R[35] = FR; | |
}else if(RX < RY){ | |
FR = FR | 0x02; | |
R[35] = FR; | |
}else if(RX > RY){ | |
FR = FR | 0x04; | |
R[35] = FR; | |
}else{ | |
FR = 0x00; | |
R[35] = FR; | |
} | |
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; | |
FR = (FR & 0x18); | |
R[35] = FR; | |
if(R[X] == IM16){ | |
FR = FR | 0x01; | |
R[35] = FR; | |
}else if(R[X] < IM16){ | |
FR = FR | 0x02; | |
R[35] = FR; | |
}else if(R[X] > IM16){ | |
FR = FR | 0x04; | |
R[35] = FR; | |
} | |
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]; | |
FR = R[Z]; | |
R[35] = FR; | |
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; | |
if(((R[Y] + IM16) % 4) == 3 ){ | |
R[X] = (MEM[(R[Y] + IM16) / 4] & 0x000000FF); | |
} | |
if(((R[Y] + IM16) % 4) == 2 ){ | |
R[X] = (MEM[(R[Y] + IM16) / 4] & 0x0000FF00) >> 8; | |
} | |
if(((R[Y] + IM16) % 4) == 1 ){ | |
R[X] = (MEM[(R[Y] + IM16) / 4] & 0x00FF0000) >> 16; | |
} | |
if(((R[Y] + IM16) % 4) == 0 ){ | |
R[X] = (MEM[(R[Y] + IM16) / 4] & 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, R[X]); | |
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); | |
MEM[(R[X] + IM16)] = R[Y]; | |
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); | |
MEM[(R[X] + IM16)] = LSB; | |
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); | |
// 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); | |
// 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 | |
// R[32] = 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 -> R[32] = IM26 << 2 | |
case 0x1B: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000001) == 0x1 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x1C: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000002) == 0x2 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x1D: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000004) == 0x4 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x1E: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000001) != 0x00000001 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x1F: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000001) == 0x1 || FR == 0x2 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x20: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000001) == 0x1 || FR == 0x4 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x21: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000008) == 0x8 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x22: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000008) != 0x8 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x23: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000020) == 0x20 ? IM26 : (R[32]+1); | |
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 -> R[32] = IM26 << 2 | |
case 0x24: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
R[32] = (FR & 0x00000020) != 0x20 ? IM26 : (R[32]+1); | |
fprintf(saida, "biv 0x%08X\n[S] PC = 0x%08X\n", IM26, R[32]*4); | |
break; | |
// 100001 - CALL | |
// Tipo F | |
// R[X] = (R[32] + 4) >> 2, R[32] = (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; | |
R[0] = 0; | |
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] = IR[32] >> 2, R[y] = R[36], R[32] = 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 | |
case 0x3F: | |
IM26 = (MEM[R[32]] & 0x03FFFFFF); | |
INTP = IM26 == 0 ? 1 : 0; | |
if(INTP == 1){ | |
//N = R[32] = 0; | |
//R[36] = 0x0; | |
R[32] = 0x0C; | |
R[36] = 1; | |
fprintf(saida, "int %d\n[S] CR = 0x%08X, PC = 0x%08X\n", N, R[36], R[32]*4); | |
if(strcmp(terminal, "") != 0){ | |
fprintf(saida, "[TR[34]MINAL]\n"); | |
fprintf(saida, "%s\n", terminal); | |
} | |
fprintf(saida, "[END OF SIMULATION]"); | |
} | |
if(IM26 != 0){ | |
R[36] = IM26; | |
INTT = 1; | |
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]); | |
} | |
break; | |
default: | |
fprintf(saida, "[INVALID INSTRUCTION @ 0x%08X]\n", R[32]*4); | |
INTT = 1; | |
IV = 1; | |
R[36] = R[32]; | |
break; | |
} | |
if(INTT == 1){ | |
fprintf(saida, "[SOFTWARE INTR[34]RUPTION]\n"); | |
R[32] = 0x3; | |
INTT=0; | |
} | |
} | |
// Fechando os arquivos | |
fclose(entrada); | |
fclose(saida); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment