203 lines
4.9 KiB
C
203 lines
4.9 KiB
C
#include "../includes/opcodes.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define OPCODECOUNT 15
|
|
|
|
struct _instruction {
|
|
char* Name;
|
|
Mnemonic Mnemonic;
|
|
};
|
|
|
|
struct _instruction instructions[OPCODECOUNT] = {
|
|
{ "add", ADD },//, Reg, Reg | Constant },
|
|
{ "sub", SUB },//, Reg, Reg | Constant },
|
|
{ "jz", JZ },//, Address, None },
|
|
{ "int", INT },//, Constant, None },
|
|
{ "yld", YLD },//, None, None },
|
|
{ "ret", RET },//, None, None },
|
|
{ "cmp", CMP },//, Reg, Reg | Constant },
|
|
{ "inc", INC },//, Constant | Reg, None},
|
|
{ "dec", DEC },//, None, None},
|
|
{ "nop", NOP },//, None, None},
|
|
{ "jmp", JMP },//, Address, None},
|
|
{ "call", CALL },//, Address, None}
|
|
{ "load", LOAD },
|
|
{ "je", JE },
|
|
{ "loadb", LOADB}
|
|
};
|
|
|
|
Instruction* CreateInstruction(Mnemonic mnemonic) {
|
|
Instruction* instruction = calloc(1, sizeof(Instruction));
|
|
|
|
if (!instruction) {
|
|
fprintf(stderr, "Failed to calloc room for an Instruction. %s.\n", strerror(errno));
|
|
|
|
return NULL;
|
|
}
|
|
|
|
instruction->Mnemonic = mnemonic;
|
|
// instruction->ParameterOne = CreateParameter(NoParameter);
|
|
// instruction->ParameterTwo = CreateParameter(NoParameter);
|
|
|
|
return instruction;
|
|
}
|
|
|
|
Parameter* CreateParameter(OpcodeParameter parameterType) {
|
|
Parameter* param = calloc(1, sizeof(Parameter));
|
|
|
|
if (!param) {
|
|
fprintf(stderr, "Failed to calloc room for a Parameter. %s,\n", strerror(errno));
|
|
|
|
return NULL;
|
|
}
|
|
|
|
param->ParameterType = parameterType;
|
|
|
|
return param;
|
|
}
|
|
|
|
void FreeInstruction(Instruction* instruction) {
|
|
if (!instruction) return;
|
|
|
|
free(instruction);
|
|
}
|
|
|
|
unsigned char GetInstructionMask(Mnemonic type) {
|
|
switch (type) {
|
|
case LOAD:
|
|
return 0x20; //0b00100000; ORing 0x80 marks the first parameter as an address
|
|
case ADD:
|
|
return 0x40;//0b01000000;
|
|
case SUB:
|
|
return 0x60;//0b01100000;
|
|
case CMP:
|
|
return 0x80;//0b10000000;
|
|
case JZ:
|
|
return 0x01;//0b00000001;
|
|
case INT:
|
|
return 0x02; //0b00000010;
|
|
case YLD:
|
|
return 0x03;
|
|
case RET:
|
|
return 0x04;
|
|
case CALL:
|
|
return 0x05;
|
|
case JMP:
|
|
return 0x06;//0b00000110;
|
|
case INC:
|
|
return 0x07;//0b00000111;
|
|
case DEC:
|
|
return 0x08;//0b00001000;
|
|
default:
|
|
return 0x00;
|
|
}
|
|
}
|
|
|
|
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]) {
|
|
memset(buffer, '\0', 12);
|
|
|
|
for(int i = 0; i < OPCODECOUNT; i++) {
|
|
if (instructions[i].Mnemonic == mnemonic) {
|
|
strncpy(buffer, instructions[i].Name, 11);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
NOP - 0000 0000 NOP
|
|
JZ - 0000 0001 JZ Address
|
|
INT - 0000 0010 INT Constant
|
|
YLD - 0000 0011 YLD
|
|
RET - 0000 0100 RET
|
|
CALL - 0000 0101 CALL Address
|
|
JMP - 0000 0110 JMP Address
|
|
IN - 0000 0111 IN Constant
|
|
OUT - 0000 1000 OUT Constant
|
|
COPY - 0010 0XXX COPY REG, REG
|
|
- 0010 1XXX COPY REG, Constant
|
|
- 0011 0XXX COPY REG, Address
|
|
- 1010 0XXX COPY Address, REG
|
|
- 1010 1XXX COPY Address, Constant
|
|
- 1011 0XXX COPY Address, Address
|
|
ADD - 0100 0XXX ADD REG, REG
|
|
- 0100 1XXX ADD REG, Constant
|
|
SUB - 0110 0XXX SUB REG, REG
|
|
- 0110 1XXX SUB REG, Constant
|
|
CMP - 1000 0XXX CMP REG, REG
|
|
- 1000 1XXX CMP REG, Constant
|
|
- 1001 0XXX CMP REG, Address
|
|
*/
|
|
//COPY X01X XXXX
|
|
//ADD 010X XXXX
|
|
//SUB 011X XXXX
|
|
//CMP 100X XXXX
|
|
//REG XXX0 0XXX
|
|
//Constant XXX0 1XXX
|
|
//Address XXX1 0XXX
|
|
//R1 XXXX X000 -> XXXX X111 (R1 to R8)
|
|
|
|
// Register registers[REGISTERCOUNT] = {
|
|
// { "r1", R1 },
|
|
// { "r2", R2 },
|
|
// { "r3", R3 },
|
|
// { "r4", R4 },
|
|
// { "r5", R5 },
|
|
// { "r6", R6 },
|
|
// { "r7", R7 },
|
|
// { "r8", R8 }
|
|
// };
|
|
|
|
// const Instruction* GetOpcodeDetails(Mnemonic type) {
|
|
// for(int i = 0; i < OPCODECOUNT; i++) {
|
|
// if (instructions[i].op == type) return &instructions[i];
|
|
// }
|
|
|
|
// return NULL;
|
|
// }
|
|
|
|
int IsOpcode(const char* text, Mnemonic* opcode) {
|
|
if (!text) return 0;
|
|
|
|
for(int i = 0; i < OPCODECOUNT; i++) {
|
|
if (strcmp(instructions[i].Name, text) == 0) {
|
|
if (opcode) *opcode = instructions[i].Mnemonic;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int IsRegister(const char* text, Registers* reg) {
|
|
if (!text) return 0;
|
|
|
|
int length = strlen(text);
|
|
Registers r = R8;
|
|
|
|
if (length != 2) return 0;
|
|
if (text[0] != 'r') return 0;
|
|
|
|
switch(text[1]) {
|
|
case '1':
|
|
r--;
|
|
case '2':
|
|
r--;
|
|
case '3':
|
|
r--;
|
|
case '4':
|
|
r--;
|
|
case '5':
|
|
r--;
|
|
case '6':
|
|
r--;
|
|
case '7':
|
|
r--;
|
|
case '8':
|
|
if (reg) *reg = r;
|
|
return 1;
|
|
default:
|
|
return 0;
|
|
}
|
|
} |