Skip to content

Instantly share code, notes, and snippets.

@hogelog
Created September 8, 2010 10:19
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 hogelog/569932 to your computer and use it in GitHub Desktop.
Save hogelog/569932 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <sstream>
#include <stack>
#define MEMSIZE 30000
#define CODESIZE 30000
#include "xbyak/xbyak.h"
class BFVM : public Xbyak::CodeGenerator {
private:
FILE *input;
int membuf[MEMSIZE];
static const char* toLabel(char ch, int num)
{
static std::stringstream labelStream;
labelStream.str("");
labelStream << ch << num;
return labelStream.str().c_str();
}
public:
BFVM(FILE *input) :
CodeGenerator(CODESIZE),
input(input)
{
using namespace Xbyak;
push(ebx);
push(esi);
push(edi);
Reg32 mem(ebx);
Reg32 ptrGetchar(esi);
Reg32 ptrPutchar(edi);
mov(eax, 0);
mov(mem, (int) membuf);
mov(ptrGetchar, (int) getchar);
mov(ptrPutchar, (int) putchar);
char ch = 0, nextch = 0;
int opMemCount = 0;
int opPtrCount = 0;
std::stack<int> labelStack;
int labelNum = 0;
std::string label;
do {
nextch = getc(input);
switch(ch) {
case '+':
case '-':
opMemCount += ch=='+' ? 1 : -1;
if ((nextch!='+' && nextch!='-') && opMemCount!=0) {
switch(opMemCount) {
case 1:
inc(eax);
break;
case -1:
dec(eax);
break;
default:
add(eax, opMemCount);
break;
}
opMemCount = 0;
}
break;
case '>':
case '<':
opPtrCount += ch=='>' ? 1 : -1;
if ((nextch!='>' && nextch!='<') && opPtrCount!=0) {
mov(dword [mem], eax);
add(mem, 4*opPtrCount);
mov(eax, dword [mem]);
opPtrCount = 0;
}
break;
case ',':
call(ptrGetchar);
break;
case '.':
push(eax);
call(ptrPutchar);
pop(eax);
break;
case '[':
L(toLabel('L', labelNum));
test(eax, eax);
jz(toLabel('R', labelNum), T_NEAR);
labelStack.push(labelNum);
++labelNum;
break;
case ']':
int beginNum = labelStack.top();
labelStack.pop();
jmp(toLabel('L', beginNum), T_NEAR);
L(toLabel('R', beginNum));
break;
}
ch = nextch;
} while (ch != EOF);
pop(edi);
pop(esi);
pop(ebx);
ret();
}
void execute()
{
void (*codes)() = (void (*)()) getCode();
codes();
fflush(stdout);
fprintf(stderr, "\nsize of x86-code: %d\n", getSize());
}
};
int main()
{
BFVM bf(stdin);
bf.execute();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment