Added all the instructions supported to a structure to help make validation of parameters easier.
This commit is contained in:
+8
-6
@@ -12,15 +12,16 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ADD, SUB, JZ, INT, YLD, RET,
|
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;
|
} Mnemonic;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NoParameter,
|
NoParameter = 1,
|
||||||
ConstantParameter,
|
ConstantParameter = 2,
|
||||||
AddressParameter,
|
AddressParameter = 4,
|
||||||
RegisterParameter,
|
RegisterParameter = 8,
|
||||||
UnresolvedParameter
|
UnresolvedParameter = 16
|
||||||
} OpcodeParameter;
|
} OpcodeParameter;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -45,6 +46,7 @@ Parameter* CreateParameter(OpcodeParameter parameterType);
|
|||||||
void FreeInstruction(Instruction* instruction);
|
void FreeInstruction(Instruction* instruction);
|
||||||
int IsOpcode(const char*, Mnemonic*);
|
int IsOpcode(const char*, Mnemonic*);
|
||||||
int IsRegister(const char*, Registers*);
|
int IsRegister(const char*, Registers*);
|
||||||
|
void ExpectParameters(Mnemonic mnemonic, OpcodeParameter* paramOne, OpcodeParameter* paramTwo);
|
||||||
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]);
|
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]);
|
||||||
void GetRegisterText(Registers reg, char buffer[3]);
|
void GetRegisterText(Registers reg, char buffer[3]);
|
||||||
unsigned char GetInstructionMask(Mnemonic type);
|
unsigned char GetInstructionMask(Mnemonic type);
|
||||||
|
|||||||
+51
-101
@@ -2,31 +2,66 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define OPCODECOUNT 15
|
#define OPCODECOUNT 30
|
||||||
|
|
||||||
struct _instruction {
|
struct _instruction {
|
||||||
char* Name;
|
char* Name;
|
||||||
Mnemonic Mnemonic;
|
Mnemonic Mnemonic;
|
||||||
|
OpcodeParameter ParameterOne;
|
||||||
|
OpcodeParameter ParameterTwo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _instruction instructions[OPCODECOUNT] = {
|
struct _instruction instructions[OPCODECOUNT] = {
|
||||||
{ "add", ADD },//, Reg, Reg | Constant },
|
{ "add", ADD, RegisterParameter, RegisterParameter },
|
||||||
{ "sub", SUB },//, Reg, Reg | Constant },
|
{ "sub", SUB, RegisterParameter, RegisterParameter },//, Reg, Reg | Constant },
|
||||||
{ "jz", JZ },//, Address, None },
|
{ "jz", JZ, AddressParameter, NoParameter },//, Address, None },
|
||||||
{ "int", INT },//, Constant, None },
|
{ "int", INT, ConstantParameter, NoParameter },//, Constant, None },
|
||||||
{ "yld", YLD },//, None, None },
|
{ "yld", YLD, NoParameter, NoParameter },//, None, None },
|
||||||
{ "ret", RET },//, None, None },
|
{ "ret", RET, NoParameter, NoParameter },//, None, None },
|
||||||
{ "cmp", CMP },//, Reg, Reg | Constant },
|
{ "cmp", CMP, RegisterParameter, RegisterParameter },//, Reg, Reg | Constant },
|
||||||
{ "inc", INC },//, Constant | Reg, None},
|
{ "cmpi", CMPI, RegisterParameter, ConstantParameter },
|
||||||
{ "dec", DEC },//, None, None},
|
{ "inc", INC, RegisterParameter, NoParameter },//, Constant | Reg, None},
|
||||||
{ "nop", NOP },//, None, None},
|
{ "dec", DEC, RegisterParameter, NoParameter },//, None, None},
|
||||||
{ "jmp", JMP },//, Address, None},
|
{ "nop", NOP, NoParameter, NoParameter },//, None, None},
|
||||||
{ "call", CALL },//, Address, None}
|
{ "jmp", JMP, AddressParameter, NoParameter },//, Address, None},
|
||||||
{ "load", LOAD },
|
{ "call", CALL, AddressParameter, NoParameter },//, Address, None}
|
||||||
{ "je", JE },
|
{ "lodwi", LODWI, RegisterParameter, ConstantParameter },
|
||||||
{ "loadb", LOADB}
|
{ "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* CreateInstruction(Mnemonic mnemonic) {
|
||||||
Instruction* instruction = calloc(1, sizeof(Instruction));
|
Instruction* instruction = calloc(1, sizeof(Instruction));
|
||||||
|
|
||||||
@@ -37,8 +72,6 @@ Instruction* CreateInstruction(Mnemonic mnemonic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
instruction->Mnemonic = mnemonic;
|
instruction->Mnemonic = mnemonic;
|
||||||
// instruction->ParameterOne = CreateParameter(NoParameter);
|
|
||||||
// instruction->ParameterTwo = CreateParameter(NoParameter);
|
|
||||||
|
|
||||||
return instruction;
|
return instruction;
|
||||||
}
|
}
|
||||||
@@ -63,37 +96,6 @@ void FreeInstruction(Instruction* instruction) {
|
|||||||
free(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]) {
|
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]) {
|
||||||
memset(buffer, '\0', 12);
|
memset(buffer, '\0', 12);
|
||||||
|
|
||||||
@@ -114,58 +116,6 @@ void GetRegisterText(Registers reg, char buffer[3]) {
|
|||||||
buffer[1] = reg + 49;
|
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) {
|
int IsOpcode(const char* text, Mnemonic* opcode) {
|
||||||
if (!text) return 0;
|
if (!text) return 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user