298 lines
3.3 KiB
C
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);
|