Skip to content

Instantly share code, notes, and snippets.

@chfast
Created July 19, 2019 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chfast/efe66fe59cca075858925eeef4737281 to your computer and use it in GitHub Desktop.
Save chfast/efe66fe59cca075858925eeef4737281 to your computer and use it in GitHub Desktop.
#include <stdint.h>
#include <stdio.h>
#include <time.h>
int32_t interp(unsigned char *code, int initval)
{
int pc = 0;
int32_t val = initval;
while(1) {
switch(code[pc++]) {
case 0:
return val;
case 1:
val++;
break;
case 2:
val--;
break;
case 3:
val *= 2;
break;
case 4:
val /= 2;
break;
case 5:
val += 3;
break;
case 6:
val = -val;
break;
case 7:
val %= code[pc++];
break;
case 8:
{
int label = code[pc++];
if (!val)
pc = label;
break;
}
case 9:
{
int cond = code[pc++];
int label1 = code[pc++];
int label2 = code[pc++];
if (val < cond)
pc = label1;
else
pc = label2;
break;
}
}
}
return val;
}
int32_t interp_cgoto2(unsigned char* code, int initval)
{
static void* dispatch_table[] = { &&do_halt, &&do_inc, &&do_dec, &&do_mul2,
&&do_div2, &&do_add7, &&do_neg, &&do_mod, &&do_jmpz, &&do_jmplt };
int pc = 0;
int32_t val = initval;
goto *dispatch_table[code[pc++]];
while (1) {
do_halt: // 0
return val;
do_inc: // 1
val++;
goto *dispatch_table[code[pc++]];
continue;
do_dec: // 2
val--;
goto *dispatch_table[code[pc++]];
continue;
do_mul2: // 3
val *= 2;
goto *dispatch_table[code[pc++]];
continue;
do_div2: // 4
val /= 2;
goto *dispatch_table[code[pc++]];
continue;
do_add7: // 5
val += 3;
goto *dispatch_table[code[pc++]];
continue;
do_neg: // 6
val = -val;
goto *dispatch_table[code[pc++]];
continue;
do_mod: // 7
val %= code[pc++];
goto *dispatch_table[code[pc++]];
continue;
do_jmpz: // 8
{
int label = code[pc++];
if (!val)
pc = label;
goto *dispatch_table[code[pc++]];
continue;
}
do_jmplt: // 9
{
int cond = code[pc++];
int label1 = code[pc++];
int label2 = code[pc++];
if (val < cond)
pc = label1;
else
pc = label2;
goto *dispatch_table[code[pc++]];
continue;
}
}
}
int main(int argc, char *argv[]) {
unsigned char code[] = {
1, // inc
// start:
1, // inc
9, 0, 6, 0, // jmplt(0, end, start)
// end:
0, // hlt
};
// printf("Calc finish: %x\n", interp(code, 0));
// printf("Calc finish: %x\n", interp_cgoto2(code, 0));
clock_t start, finish;
double cpu_time_used;
start = clock();
for (int i = 0; i < 4; i++)
printf("%x\n", interp_cgoto2(code, 0));
finish = clock();
cpu_time_used = ((double) (finish - start)) / CLOCKS_PER_SEC;
printf("CGOTO took: %f\n", cpu_time_used);
start = clock();
for (int i = 0; i < 4; i++)
printf("%x\n", interp(code, 0));
finish = clock();
cpu_time_used = ((double) (finish - start)) / CLOCKS_PER_SEC;
printf("SWITCH took: %f\n", cpu_time_used);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment