diff --git a/docs/document.tex b/docs/document.tex index e7a01ca..1eaf6b2 100644 --- a/docs/document.tex +++ b/docs/document.tex @@ -103,16 +103,28 @@ \OpcodeTable{0x20}{sub}{Register}{Register}\\[6pt] Performs subtraction on a register with a value from another (or the same) register. \section{JMP (Jump)} - \OpcodeTable{0x20}{jmp}{Address}{None}\\[6pt] + \OpcodeTable{0x20}{jmp}{Register}{None}\\[6pt] Jumps unconditionally to a memory address. Sets the Program Counter to Address. \section{JZ (Jump if Zero)} \OpcodeTable{0x20}{jz}{Register}{None}\\[6pt] Jumps to a memory address if the status flag is zero. \section{JG (Jump if Greater Than)} - \OpcodeTable{0x70}{jg}{Address}{None}\\[6pt] + \OpcodeTable{0x70}{jg}{Register}{None}\\[6pt] Jump to the Address if the status flag is greater than zero. \section{JL (Jump if Less Than)} - \OpcodeTable{0x00}{jl}{Address}{None}\\[6pt] + \OpcodeTable{0x00}{jl}{Register}{None}\\[6pt] + Jumps to the address if the status flag is less than zero. + \section{JMPA (Jump to Address)} + \OpcodeTable{0x20}{jmpa}{Address}{None}\\[6pt] + Jumps unconditionally to a memory address. Sets the Program Counter to Address. + \section{JZA (Jump to Address if Zero)} + \OpcodeTable{0x20}{jza}{Address}{None}\\[6pt] + Jumps to a memory address if the status flag is zero. + \section{JGA (Jump to Address if Greater Than)} + \OpcodeTable{0x70}{jga}{Address}{None}\\[6pt] + Jump to the Address if the status flag is greater than zero. + \section{JLA (Jump to Address if Less Than)} + \OpcodeTable{0x00}{jla}{Address}{None}\\[6pt] Jumps to the address if the status flag is less than zero. \section{AND (Logical AND)} \OpcodeTable{0x00}{and}{Register}{Register}\\[6pt] diff --git a/includes/opcodes.h b/includes/opcodes.h index 695af54..93482b7 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -13,7 +13,8 @@ typedef enum { typedef enum { ADD, SUB, JZ, INT, YLD, RET, CMP, CMPI, NOP, JMP, CALL, LODW, LAA, LODWI, JE, INC, DEC, LOADB, - STOB, STOW, JG, JL, AND, XOR, OR, NOT, SHR, SHL, POP, PUSH, LODB + STOB, STOW, JG, JL, AND, XOR, OR, NOT, SHR, SHL, POP, PUSH, LODB, + JMPA, JZA, JLA, JGA } Mnemonic; typedef enum { diff --git a/misc/test.asm b/misc/test.asm index a4bf49d..74a367d 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -17,4 +17,8 @@ cmp r1, 5 and r1, r2 add r4, r7 inc r1 ;increment r1 -xor r1, r1 ;clear self \ No newline at end of file +xor r1, r1 ;clear self +pop r3 +jmp unknown_symbol +jmp r4 +jz unknown_symbol \ No newline at end of file diff --git a/src/opcodes.c b/src/opcodes.c index 93395bf..b36d53c 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -2,7 +2,7 @@ #include #include -#define OPCODECOUNT 30 +#define OPCODECOUNT 34 struct _instruction { char* Name; @@ -41,7 +41,11 @@ struct _instruction instructions[OPCODECOUNT] = { { "nop", NOP, NoParameter, NoParameter }, { "pop", POP, RegisterParameter, NoParameter }, { "push", PUSH, RegisterParameter, NoParameter }, - { "lodb", LODB, RegisterParameter, RegisterParameter} + { "lodb", LODB, RegisterParameter, RegisterParameter}, + { "jmpa", JMPA, RegisterParameter, NoParameter}, + { "jza", JZA, RegisterParameter, NoParameter}, + { "jla", JLA, RegisterParameter, NoParameter}, + { "jga", JGA, RegisterParameter, NoParameter}, }; void ExpectParameters(Mnemonic mnemonic, OpcodeParameter* paramOne, OpcodeParameter* paramTwo) { diff --git a/src/parser.c b/src/parser.c index da1e990..6dc41bc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -264,6 +264,58 @@ void HandleOpcode(void) { case POP: ExpectRegister(); break; + case JMP: + { + Token* arg = PeekToken(); + + if (arg->Class == IdentifierClass) { + ExpectIdentifier(0, ForwardParser); + + opcode->Value.Mnemonic = JMPA; + opcode->Lemexe = "JMPA"; + } + else ExpectRegister(); + } + break; + case JZ: + { + Token* arg = PeekToken(); + + if (arg->Class == IdentifierClass) { + ExpectIdentifier(0, ForwardParser); + + opcode->Value.Mnemonic = JZA; + opcode->Lemexe = "JZA"; + } + else ExpectRegister(); + } + break; + case JG: + { + Token* arg = PeekToken(); + + if (arg->Class == IdentifierClass) { + ExpectIdentifier(0, ForwardParser); + + opcode->Value.Mnemonic = JGA; + opcode->Lemexe = "JGA"; + } + else ExpectRegister(); + } + break; + case JL: + { + Token* arg = PeekToken(); + + if (arg->Class == IdentifierClass) { + ExpectIdentifier(0, ForwardParser); + + opcode->Value.Mnemonic = JLA; + opcode->Lemexe = "JLA"; + } + else ExpectRegister(); + } + break; default: break; }