From 9a602824b6b2b9820261a3d3bb608f9751d366d6 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Tue, 18 Oct 2022 21:14:50 -0500 Subject: [PATCH] Added all the instructions supported to a structure to help make validation of parameters easier. --- includes/opcodes.h | 14 +++-- src/opcodes.c | 152 +++++++++++++++------------------------------ 2 files changed, 59 insertions(+), 107 deletions(-) diff --git a/includes/opcodes.h b/includes/opcodes.h index 2fe200e..321f4f4 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -12,15 +12,16 @@ typedef enum { typedef enum { ADD, SUB, JZ, INT, YLD, RET, - CMP, NOP, JMP, CALL, LOAD, JE, INC, DEC, LOADB + CMP, CMPI, NOP, JMP, CALL, LODW, LAA, LODWI, JE, INC, DEC, LOADB, + STOB, STOW, JG, JL, AND, XOR, OR, NOT, SHR, SHL } Mnemonic; typedef enum { - NoParameter, - ConstantParameter, - AddressParameter, - RegisterParameter, - UnresolvedParameter + NoParameter = 1, + ConstantParameter = 2, + AddressParameter = 4, + RegisterParameter = 8, + UnresolvedParameter = 16 } OpcodeParameter; typedef struct { @@ -45,6 +46,7 @@ Parameter* CreateParameter(OpcodeParameter parameterType); void FreeInstruction(Instruction* instruction); int IsOpcode(const char*, Mnemonic*); int IsRegister(const char*, Registers*); +void ExpectParameters(Mnemonic mnemonic, OpcodeParameter* paramOne, OpcodeParameter* paramTwo); void GetMnemonicText(Mnemonic mnemonic, char buffer[12]); void GetRegisterText(Registers reg, char buffer[3]); unsigned char GetInstructionMask(Mnemonic type); diff --git a/src/opcodes.c b/src/opcodes.c index a1709f5..1450540 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -2,31 +2,66 @@ #include #include -#define OPCODECOUNT 15 +#define OPCODECOUNT 30 struct _instruction { char* Name; Mnemonic Mnemonic; + OpcodeParameter ParameterOne; + OpcodeParameter ParameterTwo; }; 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} + { "add", ADD, RegisterParameter, RegisterParameter }, + { "sub", SUB, RegisterParameter, RegisterParameter },//, Reg, Reg | Constant }, + { "jz", JZ, AddressParameter, NoParameter },//, Address, None }, + { "int", INT, ConstantParameter, NoParameter },//, Constant, None }, + { "yld", YLD, NoParameter, NoParameter },//, None, None }, + { "ret", RET, NoParameter, NoParameter },//, None, None }, + { "cmp", CMP, RegisterParameter, RegisterParameter },//, Reg, Reg | Constant }, + { "cmpi", CMPI, RegisterParameter, ConstantParameter }, + { "inc", INC, RegisterParameter, NoParameter },//, Constant | Reg, None}, + { "dec", DEC, RegisterParameter, NoParameter },//, None, None}, + { "nop", NOP, NoParameter, NoParameter },//, None, None}, + { "jmp", JMP, AddressParameter, NoParameter },//, Address, None}, + { "call", CALL, AddressParameter, NoParameter },//, Address, None} + { "lodwi", LODWI, RegisterParameter, ConstantParameter }, + { "je", JE, AddressParameter, NoParameter }, + { "lodb", LOADB, RegisterParameter, RegisterParameter }, + { "stob", STOB, RegisterParameter, AddressParameter }, + { "stow", STOW, RegisterParameter, AddressParameter }, + { "laa", LAA, RegisterParameter, AddressParameter }, + { "lodw", LODW, RegisterParameter, RegisterParameter }, + { "jmp", JMP, AddressParameter, NoParameter }, + { "jg", JG, AddressParameter, NoParameter }, + { "jl", JL, AddressParameter, NoParameter }, + { "and", AND, RegisterParameter, RegisterParameter }, + { "xor", XOR, RegisterParameter, RegisterParameter }, + { "or", OR, RegisterParameter, RegisterParameter }, + { "not", NOT, RegisterParameter, NoParameter }, + { "shr", SHR, RegisterParameter, ConstantParameter }, + { "shl", SHL, RegisterParameter, ConstantParameter }, + { "nop", NOP, NoParameter, NoParameter } }; +void ExpectParameters(Mnemonic mnemonic, OpcodeParameter* paramOne, OpcodeParameter* paramTwo) { + *paramOne = NoParameter; + *paramTwo = NoParameter; + + for (int i = 0; i < OPCODECOUNT; i++) { + struct _instruction ins = instructions[i]; + + if (ins.Mnemonic == mnemonic) { + *paramOne = ins.ParameterOne; + *paramTwo = ins.ParameterTwo; + + return; + } + } + + fprintf(stderr, "[Warning] Could not find mnemonic (%d) when looking for parameters.\n", mnemonic); +} + Instruction* CreateInstruction(Mnemonic mnemonic) { Instruction* instruction = calloc(1, sizeof(Instruction)); @@ -37,8 +72,6 @@ Instruction* CreateInstruction(Mnemonic mnemonic) { } instruction->Mnemonic = mnemonic; - // instruction->ParameterOne = CreateParameter(NoParameter); - // instruction->ParameterTwo = CreateParameter(NoParameter); return instruction; } @@ -63,37 +96,6 @@ void FreeInstruction(Instruction* instruction) { 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); @@ -114,58 +116,6 @@ void GetRegisterText(Registers reg, char buffer[3]) { buffer[1] = reg + 49; } -/* - 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;