#include "../includes/opcodes.h" #include #include #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; } }