goomsl.c
来自「linux下的MPEG1」· C语言 代码 · 共 1,510 行 · 第 1/3 页
C
1,510 行
case INSTR_SUBF_VAR_VAR : printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISLOWERF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISLOWERF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISLOWERI_VAR_VAR: jitc_add(jitc,"mov edx, [$d]", instr->data.udest.var_int); jitc_add(jitc,"sub edx, [$d]", instr->data.usrc.var_int); jitc_add(jitc,"shr edx, $d", 31); break; case INSTR_ISLOWERI_VAR_INTEGER: jitc_add(jitc,"mov edx, [$d]", instr->data.udest.var_int); jitc_add(jitc,"sub edx, $d", instr->data.usrc.value_int); jitc_add(jitc,"shr edx, $d", 31); break; case INSTR_ADDI_VAR_INTEGER: jitc_add(jitc, "add [$d], $d", instr->data.udest.var_int, instr->data.usrc.value_int); break; case INSTR_ADDI_VAR_VAR: jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "add eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; case INSTR_ADDF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ADDF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_MULI_VAR_INTEGER: if (instr->data.usrc.value_int != 1) { int po2 = powerOfTwo(instr->data.usrc.value_int); if (po2) { /* performs (V / 2^n) by doing V >> n */ jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "sal eax, $d", po2); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); } else { jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "imul eax, $d", instr->data.usrc.value_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); } } break; case INSTR_MULI_VAR_VAR: jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "imul eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; case INSTR_MULF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_MULF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_DIVI_VAR_INTEGER: if ((instr->data.usrc.value_int != 1) && (instr->data.usrc.value_int != 0)) { int po2 = powerOfTwo(instr->data.usrc.value_int); if (po2) { /* performs (V / 2^n) by doing V >> n */ jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "sar eax, $d", po2); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); } else { /* performs (V/n) by doing (V*(32^2/n)) */ long coef; double dcoef = (double)4294967296.0 / (double)instr->data.usrc.value_int; if (dcoef < 0.0) dcoef = -dcoef; coef = (long)floor(dcoef); dcoef -= floor(dcoef); if (dcoef < 0.5) coef += 1; jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "mov edx, $d", coef); jitc_add(jitc, "imul edx"); if (instr->data.usrc.value_int < 0) jitc_add(jitc, "neg edx"); jitc_add(jitc, "mov [$d], edx", instr->data.udest.var_int); } } break; case INSTR_DIVI_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "cdq"); /* sign extend eax into edx */ jitc_add(jitc, "idiv [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; case INSTR_DIVF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_DIVF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_JZERO: jitc_add(jitc, "cmp edx, $d", 0); jitc_add(jitc, "je $s", instr->jump_label); break; case INSTR_ISEQUALP_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_ptr); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, [$d]", instr->data.usrc.var_ptr); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALP_VAR_PTR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_ptr); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, $d", instr->data.usrc.value_ptr); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALI_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALI_VAR_INTEGER : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, $d", instr->data.usrc.value_int); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALF_VAR_VAR : printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISEQUALF_VAR_FLOAT : printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_CALL: jitc_add(jitc, "call $s", instr->jump_label); break; case INSTR_RET: jitc_add(jitc, "ret"); break; case INSTR_EXT_CALL: jitc_add(jitc, "mov eax, [$d]", &(instr->data.udest.external_function->vars)); jitc_add(jitc, "push eax"); jitc_add(jitc, "mov edx, [$d]", &(currentGoomSL->vars)); jitc_add(jitc, "push edx"); jitc_add(jitc, "mov eax, [$d]", &(currentGoomSL)); jitc_add(jitc, "push eax"); jitc_add(jitc, "mov eax, [$d]", &(instr->data.udest.external_function)); jitc_add(jitc, "mov eax, [eax]"); jitc_add(jitc, "call [eax]"); jitc_add(jitc, "add esp, $d", 12); break; case INSTR_NOT_VAR: jitc_add(jitc, "mov eax, edx"); jitc_add(jitc, "mov edx, $d", 1); jitc_add(jitc, "sub edx, eax"); break; case INSTR_JNZERO: jitc_add(jitc, "cmp edx, $d", 0); jitc_add(jitc, "jne $s", instr->jump_label); break; case INSTR_SETS_VAR_VAR: { int loop = DEST_STRUCT_SIZE / sizeof(int); int dst = (int)pDEST_VAR; int src = (int)pSRC_VAR; while (loop--) { jitc_add(jitc,"mov eax, [$d]", src); jitc_add(jitc,"mov [$d], eax", dst); src += 4; dst += 4; } } break; case INSTR_ISEQUALS_VAR_VAR: break; case INSTR_ADDS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { /* TODO interlace 2 */ jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "add eax, [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } /* process floats */ i=0; while (DEST_STRUCT_FBLOCK(i).size > 0) { int j=DEST_STRUCT_FBLOCK(i).size; while (j--) { /* DEST_STRUCT_FBLOCK_VAR(i,j) += SRC_STRUCT_FBLOCK_VAR(i,j); */ /* TODO */ } ++i; } break; } case INSTR_SUBS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "sub eax, [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } break; } case INSTR_MULS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "imul eax, [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } break; } case INSTR_DIVS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "cdq"); jitc_add(jitc, "idiv [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } break; } } } JITC_ADD_LABEL (jitc, "__very_end__"); jitc_add(jitc, "call $s", "__very_start__"); jitc_add(jitc, "mov eax, $d", 0); jitc_validate_func(jitc);#else InstructionFlow *iflow = currentGoomSL->iflow; FastInstructionFlow *fastiflow = (FastInstructionFlow*)malloc(sizeof(FastInstructionFlow)); fastiflow->mallocedInstr = calloc(number*16, sizeof(FastInstruction)); /* fastiflow->instr = (FastInstruction*)(((int)fastiflow->mallocedInstr) + 16 - (((int)fastiflow->mallocedInstr)%16)); */ fastiflow->instr = (FastInstruction*)fastiflow->mallocedInstr; fastiflow->number = number; for(i=0;i<number;++i) { fastiflow->instr[i].id = iflow->instr[i]->id; fastiflow->instr[i].data = iflow->instr[i]->data; fastiflow->instr[i].proto = iflow->instr[i]; } currentGoomSL->fastiflow = fastiflow;#endif} /* }}} */void yy_scan_string(const char *str);void yyparse(void);GoomHash *gsl_globals(GoomSL *_this){ return _this->vars;}/** * Some native external functions */static void ext_charAt(GoomSL *gsl, GoomHash *global, GoomHash *local){ char *string = GSL_LOCAL_PTR(gsl, local, "value"); int index = GSL_LOCAL_INT(gsl, local, "index"); GSL_GLOBAL_INT(gsl, "charAt") = 0; if (string == NULL) { return; } if (index < strlen(string)) GSL_GLOBAL_INT(gsl, "charAt") = string[index];}static void ext_i2f(GoomSL *gsl, GoomHash *global, GoomHash *local){ int i = GSL_LOCAL_INT(gsl, local, "value"); GSL_GLOBAL_FLOAT(gsl, "i2f") = i;}static void ext_f2i(GoomSL *gsl, GoomHash *global, GoomHash *local){ float f = GSL_LOCAL_FLOAT(gsl, local, "value"); GSL_GLOBAL_INT(gsl, "f2i") = f;}/** * */void gsl_compile(GoomSL *_currentGoomSL, const char *script){ /* {{{ */ char *script_and_externals; static const char *sBinds = "external <charAt: string value, int index> : int\n" "external <f2i: float value> : int\n" "external <i2f: int value> : float\n";#ifdef VERBOSE printf("\n=== Starting Compilation ===\n");#endif script_and_externals = malloc(strlen(script) + strlen(sBinds) + 2); strcpy(script_and_externals, sBinds); strcat(script_and_externals, script); /* 0- reset */ currentGoomSL = _currentGoomSL; reset_scanner(currentGoomSL); /* 1- create the syntaxic tree */ yy_scan_string(script_and_externals); yyparse(); /* 2- generate code */ gsl_commit_compilation(); /* 3- resolve symbols */ calculate_labels(currentGoomSL->iflow); /* 4- optimize code */ gsl_create_fast_iflow(); /* 5- bind a few internal functions */ gsl_bind_function(currentGoomSL, "charAt", ext_charAt); gsl_bind_function(currentGoomSL, "f2i", ext_f2i); gsl_bind_function(currentGoomSL, "i2f", ext_i2f); free(script_and_externals); #ifdef VERBOSE printf("=== Compilation done. # of lines: %d. # of instr: %d ===\n", currentGoomSL->num_lines, currentGoomSL->iflow->number);#endif} /* }}} */void gsl_execute(GoomSL *scanner){ /* {{{ */ if (scanner->compilationOK) {#if USE_JITC_X86 scanner->jitc_func();#else iflow_execute(scanner->fastiflow, scanner);#endif }} /* }}} */GoomSL *gsl_new(void){ /* {{{ */ GoomSL *gss = (GoomSL*)malloc(sizeof(GoomSL)); gss->iflow = iflow_new(); gss->vars = goom_hash_new(); gss->functions = goom_hash_new(); gss->nbStructID = 0; gss->structIDS = goom_hash_new(); gss->gsl_struct_size = 32; gss->gsl_struct = (GSL_Struct**)malloc(gss->gsl_struct_size * sizeof(GSL_Struct*)); gss->currentNS = 0; gss->namespaces[0] = gss->vars; gss->data_heap = goom_heap_new(); reset_scanner(gss); gss->compilationOK = 0; gss->nbPtr=0; gss->ptrArraySize=256; gss->ptrArray = (void**)malloc(gss->ptrArraySize * sizeof(void*));#ifdef USE_JITC_X86 gss->jitc = NULL;#endif return gss;} /* }}} */void gsl_bind_function(GoomSL *gss, const char *fname, GoomSL_ExternalFunction func){ /* {{{ */ HashValue *val = goom_hash_get(gss->functions, fname); if (val) { ExternalFunctionStruct *gef = (ExternalFunctionStruct*)val->ptr; gef->function = func; } else fprintf(stderr, "Unable to bind function %s\n", fname);} /* }}} */int gsl_is_compiled(GoomSL *gss){ /* {{{ */ return gss->compilationOK;} /* }}} */void gsl_free(GoomSL *gss){ /* {{{ */ iflow_free(gss->iflow); free(gss->vars); free(gss->functions); free(gss);} /* }}} */static int gsl_nb_import;static char gsl_already_imported[256][256];char *gsl_init_buffer(const char *fname){ char *fbuffer; fbuffer = (char*)malloc(512); fbuffer[0]=0; gsl_nb_import = 0; if (fname) gsl_append_file_to_buffer(fname,&fbuffer); return fbuffer;}static char *gsl_read_file(const char *fname){ FILE *f; char *buffer; int fsize; f = fopen(fname,"rt"); if (!f) { fprintf(stderr, "ERROR: Could not load file %s\n", fname); exit(1); } fseek(f,0,SEEK_END); fsize = ftell(f); rewind(f); buffer = (char*)malloc(fsize+512); fread(buffer,1,fsize,f); fclose(f); buffer[fsize]=0; return buffer;}void gsl_append_file_to_buffer(const char *fname, char **buffer){ char *fbuffer; int size,fsize,i=0; char reset_msg[256]; /* look if the file have not been already imported */ for (i=0;i<gsl_nb_import;++i) { if (strcmp(gsl_already_imported[i], fname) == 0) return; } /* add fname to the already imported files. */ strcpy(gsl_already_imported[gsl_nb_import++], fname); /* load the file */ fbuffer = gsl_read_file(fname); fsize = strlen(fbuffer); /* look for #import */ while (fbuffer[i]) { if ((fbuffer[i]=='#') && (fbuffer[i+1]=='i')) { char impName[256]; int j; while (fbuffer[i] && (fbuffer[i]!=' ')) i++; i++; j=0; while (fbuffer[i] && (fbuffer[i]!='\n')) impName[j++] = fbuffer[i++]; impName[j++] = 0; gsl_append_file_to_buffer(impName, buffer); } i++; } sprintf(reset_msg, "\n#FILE %s#\n#RST_LINE#\n", fname); strcat(*buffer, reset_msg); size=strlen(*buffer); *buffer = (char*)realloc(*buffer, size+fsize+256); strcat((*buffer)+size, fbuffer); free(fbuffer);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?