Files
assm-test/src/opcodes.c
T

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;
}
}