jackc/vm/vm-templates.h

298 lines
3.3 KiB
C

#ifndef VM_TEMPLATES
#define VM_TEMPLATES
#else
#error vm-templates may only be included once
#endif
#include "util.h"
#define mktemplate(name, array) TEMPLATE name = { .items = array, .count = strcount(array) };
typedef struct {
char** items;
int count;
} TEMPLATE;
char* tpushlns[] = {
"",
"",
"",
"A=D+A",
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
};
mktemplate(tpush, tpushlns);
char* tpushconslns[] = {
"",
"D=A",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
};
mktemplate(tpushcons, tpushconslns);
char* tpushstatlns[] = {
"",
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
};
mktemplate(tpushstat, tpushstatlns);
mktemplate(tpushtemp, tpushstatlns);
mktemplate(tpushpointer, tpushstatlns);
char* tpoplns[] = {
"",
"",
"",
"D=D+A",
"@R13",
"M=D",
"@SP",
"AM=M-1",
"D=M",
"@R13",
"A=M",
"M=D"
};
mktemplate(tpop, tpoplns);
char* tpopstatlns[] = {
"@SP",
"AM=M-1",
"D=M",
"",
""
};
mktemplate(tpopstat, tpopstatlns);
mktemplate(tpoptemp, tpopstatlns);
mktemplate(tpoppointer, tpopstatlns);
char* tarithlns[] = {
"@SP",
"AM=M-1",
"D=M",
"A=A-1",
""
};
mktemplate(tarith, tarithlns);
char* tneglns[] = {
"@SP",
"A=M-1",
"M=-M",
};
mktemplate(tneg, tneglns);
char* tnotlns[] = {
"@SP",
"A=M-1",
"M=!M",
};
mktemplate(tnot, tnotlns);
char* tcomplns[] = {
"@SP",
"AM=M-1",
"D=M",
"A=A-1",
"D=D-M",
"M=-1",
"",
"",
"@SP",
"A=M-1",
"M=0",
""
};
mktemplate(tcomp, tcomplns);
char* tlabellns[] = {
""
};
mktemplate(tlabel, tlabellns);
char* tgotolns[] = {
"",
"0;JMP"
};
mktemplate(tgoto, tgotolns);
char* tifgotolns[] = {
"@SP",
"AM=M-1",
"D=M",
"",
"D;JNE"
};
mktemplate(tifgoto, tifgotolns);
char* tcallstartlns[] = {
"D=A",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
};
mktemplate(tcallstart, tcallstartlns);
char* tcallpushlns[] = {
"",
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
};
mktemplate(tcallpush, tcallpushlns);
char* tcallsetarglns[] = {
"@SP",
"D=M",
"@LCL",
"M=D",
"",
"D=D-A",
"@ARG",
"M=D"
};
mktemplate(tcallsetarg, tcallsetarglns);
char* tcalljmplns[] = {
"",
"0;JMP",
""
};
mktemplate(tcalljmp, tcalljmplns);
char* tframevarslns[] = {
"@LCL",
"@ARG",
"@THIS",
"@THAT"
};
mktemplate(tframevars, tframevarslns);
char* tfunctionlns[] = {
""
};
mktemplate(tfunction, tfunctionlns);
char* tfunctionpushlns[] = {
"@SP",
"A=M",
"M=0",
"@SP",
"M=M+1"
};
mktemplate(tfunctionpush, tfunctionpushlns);
char* tstartreturnlns[] = {
"@LCL",
"D=M",
"@5",
"A=D-A",
"D=M",
"@R13",
"M=D",
"@SP",
"A=M-1",
"D=M",
"@ARG",
"A=M",
"M=D",
"@ARG",
"D=M+1",
"@SP",
"M=D"
};
mktemplate(tstartreturn, tstartreturnlns);
char* tretpoplns[] = {
"@LCL",
"AM=M-1",
"D=M",
"",
"M=D",
};
mktemplate(tretpop, tretpoplns);
char* tendreturnlns[] = {
"@R13",
"A=M",
"0;JMP"
};
mktemplate(tendreturn, tendreturnlns);
char* tbootstraplns[] = {
"@256",
"D=A",
"@SP",
"M=D",
"@BOOTSTRAP$ret",
"D=A",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
"@LCL",
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
"@ARG",
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
"@THIS",
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
"@THAT",
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1",
"@5",
"D=A",
"@SP",
"D=M-D",
"@ARG",
"M=D",
"@SP",
"D=M",
"@LCL",
"M=D",
"@Sys.init",
"0;JMP",
"(BOOTSTRAP$ret)"
};
mktemplate(tbootstrap, tbootstraplns);