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 + -
显示快捷键?