TOS finally changed to work with 8-bit long integers, added a few instructions

This commit is contained in:
Alex Vanin 2014-01-26 11:45:07 +04:00
parent 486b73fcea
commit 17e632ad0b
5 changed files with 61 additions and 18 deletions

View file

@ -6,7 +6,7 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
double d1, d2; double d1, d2;
int i1, i2; long long i1, i2;
char* code; char* code;
int ip; int ip;
@ -22,6 +22,19 @@ int main(int argc, char** argv)
{ {
switch (code[ip]) switch (code[ip])
{ {
case INVALID:
//DO(INVALID, "Invalid instruction.", 1)
ip++; break;
case DLOAD:
//DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9)
d1 = *((double*)(code+(++ip)));
push_double(d1);
ip+=8; break;
case ILOAD:
//DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9)
i1 = *((long long*)(code+(++ip)));
push_int(i1);
ip++; break;
case DLOAD0: case DLOAD0:
// DO(DLOAD0, "Load double 0 on TOS.", 1) // DO(DLOAD0, "Load double 0 on TOS.", 1)
push_double(0); push_double(0);
@ -145,6 +158,29 @@ int main(int argc, char** argv)
push_double(d1); push_double(d1);
printf("%f", d1); printf("%f", d1);
ip++; break; ip++; break;
case I2D:
//DO(I2D, "Convert int on TOS to double.", 1)
i1 = pop_int();
d1 = (double)i1;
push_double(d1);
ip++; break;
case D2I:
//DO(D2I, "Convert double on TOS to int.", 1)
d1 = pop_double();
i1 = (int)d1;
push_int(i1);
ip++; break;
case SWAP:
//DO(SWAP, "Swap 2 topmost values.", 1)
i1 = pop_int();
i2 = pop_int();
push_int(i1);
push_int(i2);
ip++; break;
case POP:
//DO(POP, "Remove topmost value.", 1)
TOS--;
ip++; break;
case STOP: case STOP:
//DO(STOP, "Stop execution.", 1) //DO(STOP, "Stop execution.", 1)
exec_status = 0; exec_status = 0;

View file

@ -2,6 +2,9 @@
#define OPCODE_H #define OPCODE_H
enum opcode enum opcode
{ {
INVALID,
DLOAD,
ILOAD,
DLOAD0, DLOAD0,
ILOAD0, ILOAD0,
DLOAD1, DLOAD1,
@ -24,6 +27,10 @@ enum opcode
IAXOR, IAXOR,
IPRINT, IPRINT,
DPRINT, DPRINT,
I2D,
D2I,
SWAP,
POP,
STOP STOP
}; };
#endif #endif

View file

@ -1,18 +1,18 @@
#include <malloc.h> #include <malloc.h>
#include "TOS.h" #include "TOS.h"
void push_int(int num) void push_int(long long num)
{ {
tos_num number; tos_num number;
number.num_i[1] = num; number.num_i = num;
TOS[tp++] = number.num_d; TOS[tp++] = number.num_d;
} }
int pop_int() long long pop_int()
{ {
tos_num number; tos_num number;
number.num_d = TOS[--tp]; number.num_d = TOS[--tp];
return number.num_i[1]; return number.num_i;
} }
void push_double(double num) void push_double(double num)

View file

@ -4,15 +4,15 @@
typedef union typedef union
{ {
double num_d; double num_d;
int num_i[2]; long long num_i;
} tos_num; } tos_num;
double* TOS; double* TOS;
int tp; int tp;
int initTOS(); int initTOS();
void push_int(int); void push_int(long long);
void push_double(double); void push_double(double);
int pop_int(); long long pop_int();
double pop_double(); double pop_double();
#endif #endif

View file

@ -1,7 +1,7 @@
#define FOR_BYTECODES(DO) \ #define FOR_BYTECODES(DO) \
DO(INVALID, "Invalid instruction.", 1) \ -DO(INVALID, "Invalid instruction.", 1) \
DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9) \ +DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9) \
DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9) \ +DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9) \
DO(SLOAD, "Load string reference on TOS, next two bytes - constant id.", 3) \ DO(SLOAD, "Load string reference on TOS, next two bytes - constant id.", 3) \
+DO(DLOAD0, "Load double 0 on TOS.", 1) \ +DO(DLOAD0, "Load double 0 on TOS.", 1) \
+DO(ILOAD0, "Load int 0 on TOS.", 1) \ +DO(ILOAD0, "Load int 0 on TOS.", 1) \
@ -22,16 +22,16 @@
+DO(DNEG, "Negate double on TOS.", 1) \ +DO(DNEG, "Negate double on TOS.", 1) \
+DO(INEG, "Negate int on TOS.", 1) \ +DO(INEG, "Negate int on TOS.", 1) \
+DO(IAOR, "Arithmetic OR of 2 ints on TOS, push value back.", 1) \ +DO(IAOR, "Arithmetic OR of 2 ints on TOS, push value back.", 1) \
DO(IAAND, "Arithmetic AND of 2 ints on TOS, push value back.", 1) \ +DO(IAAND, "Arithmetic AND of 2 ints on TOS, push value back.", 1) \
DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1) \ +DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1) \
+DO(IPRINT, "Pop and print integer TOS.", 1) \ +DO(IPRINT, "Pop and print integer TOS.", 1) \
+DO(DPRINT, "Pop and print double TOS.", 1) \ +DO(DPRINT, "Pop and print double TOS.", 1) \
DO(SPRINT, "Pop and print string TOS.", 1) \ DO(SPRINT, "Pop and print string TOS.", 1) \
DO(I2D, "Convert int on TOS to double.", 1) \ +DO(I2D, "Convert int on TOS to double.", 1) \
DO(D2I, "Convert double on TOS to int.", 1) \ +DO(D2I, "Convert double on TOS to int.", 1) \
DO(S2I, "Convert string on TOS to int.", 1) \ DO(S2I, "Convert string on TOS to int.", 1) \
DO(SWAP, "Swap 2 topmost values.", 1) \ +DO(SWAP, "Swap 2 topmost values.", 1) \
DO(POP, "Remove topmost value.", 1) \ +DO(POP, "Remove topmost value.", 1) \
DO(LOADDVAR0, "Load double from variable 0, push on TOS.", 1) \ DO(LOADDVAR0, "Load double from variable 0, push on TOS.", 1) \
DO(LOADDVAR1, "Load double from variable 1, push on TOS.", 1) \ DO(LOADDVAR1, "Load double from variable 1, push on TOS.", 1) \
DO(LOADDVAR2, "Load double from variable 2, push on TOS.", 1) \ DO(LOADDVAR2, "Load double from variable 2, push on TOS.", 1) \
@ -68,7 +68,7 @@
DO(STORECTXDVAR, "Pop TOS and store to double variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \ DO(STORECTXDVAR, "Pop TOS and store to double variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
DO(STORECTXIVAR, "Pop TOS and store to int variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \ DO(STORECTXIVAR, "Pop TOS and store to int variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
DO(STORECTXSVAR, "Pop TOS and store to string variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \ DO(STORECTXSVAR, "Pop TOS and store to string variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
DO(DCMP, "Compare 2 topmost doubles, pushing libc-stryle comparator value cmp(upper, lower) as integer.", 1) \ DO(DCMP, "Compare 2 topmost doubles, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \
DO(ICMP, "Compare 2 topmost ints, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \ DO(ICMP, "Compare 2 topmost ints, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \
DO(JA, "Jump always, next two bytes - signed offset of jump destination.", 3) \ DO(JA, "Jump always, next two bytes - signed offset of jump destination.", 3) \
DO(IFICMPNE, "Compare two topmost integers and jump if upper != lower, next two bytes - signed offset of jump destination.", 3) \ DO(IFICMPNE, "Compare two topmost integers and jump if upper != lower, next two bytes - signed offset of jump destination.", 3) \