summaryrefslogtreecommitdiffstats
path: root/gst/goom/goomsl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/goom/goomsl.c')
-rw-r--r--gst/goom/goomsl.c1664
1 files changed, 0 insertions, 1664 deletions
diff --git a/gst/goom/goomsl.c b/gst/goom/goomsl.c
deleted file mode 100644
index 6f407754..00000000
--- a/gst/goom/goomsl.c
+++ /dev/null
@@ -1,1664 +0,0 @@
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-#include "goomsl.h"
-#include "goomsl_private.h"
-#include "goomsl_yacc.h"
-
-/*#define TRACE_SCRIPT*/
-
- /* {{{ definition of the instructions number */
-#define INSTR_SETI_VAR_INTEGER 1
-#define INSTR_SETI_VAR_VAR 2
-#define INSTR_SETF_VAR_FLOAT 3
-#define INSTR_SETF_VAR_VAR 4
-#define INSTR_NOP 5
-/* #define INSTR_JUMP 6 */
-#define INSTR_SETP_VAR_PTR 7
-#define INSTR_SETP_VAR_VAR 8
-#define INSTR_SUBI_VAR_INTEGER 9
-#define INSTR_SUBI_VAR_VAR 10
-#define INSTR_SUBF_VAR_FLOAT 11
-#define INSTR_SUBF_VAR_VAR 12
-#define INSTR_ISLOWERF_VAR_VAR 13
-#define INSTR_ISLOWERF_VAR_FLOAT 14
-#define INSTR_ISLOWERI_VAR_VAR 15
-#define INSTR_ISLOWERI_VAR_INTEGER 16
-#define INSTR_ADDI_VAR_INTEGER 17
-#define INSTR_ADDI_VAR_VAR 18
-#define INSTR_ADDF_VAR_FLOAT 19
-#define INSTR_ADDF_VAR_VAR 20
-#define INSTR_MULI_VAR_INTEGER 21
-#define INSTR_MULI_VAR_VAR 22
-#define INSTR_MULF_VAR_FLOAT 23
-#define INSTR_MULF_VAR_VAR 24
-#define INSTR_DIVI_VAR_INTEGER 25
-#define INSTR_DIVI_VAR_VAR 26
-#define INSTR_DIVF_VAR_FLOAT 27
-#define INSTR_DIVF_VAR_VAR 28
-/* #define INSTR_JZERO 29 */
-#define INSTR_ISEQUALP_VAR_VAR 30
-#define INSTR_ISEQUALP_VAR_PTR 31
-#define INSTR_ISEQUALI_VAR_VAR 32
-#define INSTR_ISEQUALI_VAR_INTEGER 33
-#define INSTR_ISEQUALF_VAR_VAR 34
-#define INSTR_ISEQUALF_VAR_FLOAT 35
-/* #define INSTR_CALL 36 */
-/* #define INSTR_RET 37 */
-/* #define INSTR_EXT_CALL 38 */
-#define INSTR_NOT_VAR 39
-/* #define INSTR_JNZERO 40 */
-#define INSTR_SETS_VAR_VAR 41
-#define INSTR_ISEQUALS_VAR_VAR 42
-#define INSTR_ADDS_VAR_VAR 43
-#define INSTR_SUBS_VAR_VAR 44
-#define INSTR_MULS_VAR_VAR 45
-#define INSTR_DIVS_VAR_VAR 46
-
- /* }}} */
-/* {{{ definition of the validation error types */
-static const char *VALIDATE_OK = "ok";
-
-#define VALIDATE_ERROR "error while validating "
-#define VALIDATE_TODO "todo"
-#define VALIDATE_SYNTHAX_ERROR "synthax error"
-#define VALIDATE_NO_SUCH_INT "no such integer variable"
-#define VALIDATE_NO_SUCH_VAR "no such variable"
-#define VALIDATE_NO_SUCH_DEST_VAR "no such destination variable"
-#define VALIDATE_NO_SUCH_SRC_VAR "no such src variable"
-/* }}} */
-
- /***********************************/
- /* PROTOTYPE OF INTERNAL FUNCTIONS */
-/***********************************/
-
-/* {{{ */
-static void gsl_instr_free (Instruction * _this);
-static const char *gsl_instr_validate (Instruction * _this);
-static void gsl_instr_display (Instruction * _this);
-
-static InstructionFlow *iflow_new (void);
-static void iflow_add_instr (InstructionFlow * _this, Instruction * instr);
-static void iflow_clean (InstructionFlow * _this);
-static void iflow_free (InstructionFlow * _this);
-static void iflow_execute (FastInstructionFlow * _this, GoomSL * gsl);
-
-/* }}} */
-
- /************************************/
- /* DEFINITION OF INTERNAL FUNCTIONS */
-/************************************/
-
-void
-iflow_free (InstructionFlow * _this)
-{ /* {{{ */
- goom_hash_free (_this->labels);
- free (_this); /*TODO: finir cette fonction */
-} /* }}} */
-
-void
-iflow_clean (InstructionFlow * _this)
-{ /* {{{ */
- /* TODO: clean chaque instruction du flot */
- _this->number = 0;
- goom_hash_free (_this->labels);
- _this->labels = goom_hash_new ();
-} /* }}} */
-
-InstructionFlow *
-iflow_new (void)
-{ /* {{{ */
- InstructionFlow *_this =
- (InstructionFlow *) malloc (sizeof (InstructionFlow));
- _this->number = 0;
- _this->tabsize = 6;
- _this->instr =
- (Instruction **) malloc (_this->tabsize * sizeof (Instruction *));
- _this->labels = goom_hash_new ();
-
- return _this;
-} /* }}} */
-
-void
-iflow_add_instr (InstructionFlow * _this, Instruction * instr)
-{ /* {{{ */
- if (_this->number == _this->tabsize) {
- _this->tabsize *= 2;
- _this->instr =
- (Instruction **) realloc (_this->instr,
- _this->tabsize * sizeof (Instruction *));
- }
- _this->instr[_this->number] = instr;
- instr->address = _this->number;
- _this->number++;
-} /* }}} */
-
-void
-gsl_instr_set_namespace (Instruction * _this, GoomHash * ns)
-{ /* {{{ */
- if (_this->cur_param <= 0) {
- fprintf (stderr, "ERROR: Line %d, No more params to instructions\n",
- _this->line_number);
- exit (1);
- }
- _this->vnamespace[_this->cur_param - 1] = ns;
-} /* }}} */
-
-void
-gsl_instr_add_param (Instruction * instr, char *param, int type)
-{ /* {{{ */
- int len;
-
- if (instr == NULL)
- return;
- if (instr->cur_param == 0)
- return;
- --instr->cur_param;
- len = strlen (param);
- instr->params[instr->cur_param] = (char *) malloc (len + 1);
- strcpy (instr->params[instr->cur_param], param);
- instr->types[instr->cur_param] = type;
- if (instr->cur_param == 0) {
-
- const char *result = gsl_instr_validate (instr);
-
- if (result != VALIDATE_OK) {
- printf ("ERROR: Line %d: ", instr->parent->num_lines + 1);
- gsl_instr_display (instr);
- printf ("... %s\n", result);
- instr->parent->compilationOK = 0;
- exit (1);
- }
-#if USE_JITC_X86
- iflow_add_instr (instr->parent->iflow, instr);
-#else
- if (instr->id != INSTR_NOP)
- iflow_add_instr (instr->parent->iflow, instr);
- else
- gsl_instr_free (instr);
-#endif
- }
-} /* }}} */
-
-Instruction *
-gsl_instr_init (GoomSL * parent, const char *name, int id, int nb_param,
- int line_number)
-{ /* {{{ */
- Instruction *instr = (Instruction *) malloc (sizeof (Instruction));
- instr->params = (char **) malloc (nb_param * sizeof (char *));
- instr->vnamespace = (GoomHash **) malloc (nb_param * sizeof (GoomHash *));
- instr->types = (int *) malloc (nb_param * sizeof (int));
- instr->cur_param = instr->nb_param = nb_param;
- instr->parent = parent;
- instr->id = id;
- instr->name = name;
- instr->jump_label = NULL;
- instr->line_number = line_number;
- return instr;
-} /* }}} */
-
-void
-gsl_instr_free (Instruction * _this)
-{ /* {{{ */
- int i;
-
- free (_this->types);
- for (i = _this->cur_param; i < _this->nb_param; ++i)
- free (_this->params[i]);
- free (_this->params);
- free (_this);
-} /* }}} */
-
-void
-gsl_instr_display (Instruction * _this)
-{ /* {{{ */
- int i = _this->nb_param - 1;
-
- printf ("%s", _this->name);
- while (i >= _this->cur_param) {
- printf (" %s", _this->params[i]);
- --i;
- }
-} /* }}} */
-
- /****************************************/
- /* VALIDATION OF INSTRUCTION PARAMETERS */
-/****************************************/
-
-static const char *
-validate_v_v (Instruction * _this)
-{ /* {{{ */
- HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
- HashValue *src = goom_hash_get (_this->vnamespace[0], _this->params[0]);
-
- if (dest == NULL) {
- return VALIDATE_NO_SUCH_DEST_VAR;
- }
- if (src == NULL) {
- return VALIDATE_NO_SUCH_SRC_VAR;
- }
- _this->data.udest.var = dest->ptr;
- _this->data.usrc.var = src->ptr;
- return VALIDATE_OK;
-} /* }}} */
-
-static const char *
-validate_v_i (Instruction * _this)
-{ /* {{{ */
- HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
-
- _this->data.usrc.value_int = strtol (_this->params[0], NULL, 0);
-
- if (dest == NULL) {
- return VALIDATE_NO_SUCH_INT;
- }
- _this->data.udest.var = dest->ptr;
- return VALIDATE_OK;
-} /* }}} */
-
-static const char *
-validate_v_p (Instruction * _this)
-{ /* {{{ */
- HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
-
- _this->data.usrc.value_ptr = strtol (_this->params[0], NULL, 0);
-
- if (dest == NULL) {
- return VALIDATE_NO_SUCH_INT;
- }
- _this->data.udest.var = dest->ptr;
- return VALIDATE_OK;
-} /* }}} */
-
-static const char *
-validate_v_f (Instruction * _this)
-{ /* {{{ */
- HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
-
- _this->data.usrc.value_float = atof (_this->params[0]);
-
- if (dest == NULL) {
- return VALIDATE_NO_SUCH_VAR;
- }
- _this->data.udest.var = dest->ptr;
- return VALIDATE_OK;
-} /* }}} */
-
-static const char *
-validate (Instruction * _this,
- int vf_f_id, int vf_v_id,
- int vi_i_id, int vi_v_id, int vp_p_id, int vp_v_id, int vs_v_id)
-{ /* {{{ */
- if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FLOAT)) {
- _this->id = vf_f_id;
- return validate_v_f (_this);
- } else if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FVAR)) {
- _this->id = vf_v_id;
- return validate_v_v (_this);
- } else if ((_this->types[1] == TYPE_IVAR)
- && (_this->types[0] == TYPE_INTEGER)) {
- _this->id = vi_i_id;
- return validate_v_i (_this);
- } else if ((_this->types[1] == TYPE_IVAR) && (_this->types[0] == TYPE_IVAR)) {
- _this->id = vi_v_id;
- return validate_v_v (_this);
- } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PTR)) {
- if (vp_p_id == INSTR_NOP)
- return VALIDATE_ERROR;
- _this->id = vp_p_id;
- return validate_v_p (_this);
- } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PVAR)) {
- _this->id = vp_v_id;
- if (vp_v_id == INSTR_NOP)
- return VALIDATE_ERROR;
- return validate_v_v (_this);
- } else if ((_this->types[1] < FIRST_RESERVED) && (_this->types[1] >= 0)
- && (_this->types[0] == _this->types[1])) {
- _this->id = vs_v_id;
- if (vs_v_id == INSTR_NOP)
- return "Impossible operation to perform between two structs";
- return validate_v_v (_this);
- }
- return VALIDATE_ERROR;
-} /* }}} */
-
-const char *
-gsl_instr_validate (Instruction * _this)
-{ /* {{{ */
- if (_this->id != INSTR_EXT_CALL) {
- int i = _this->nb_param;
-
- while (i > 0) {
- i--;
- if (_this->types[i] == TYPE_VAR) {
- int type = gsl_type_of_var (_this->vnamespace[i], _this->params[i]);
-
- if (type == INSTR_INT)
- _this->types[i] = TYPE_IVAR;
- else if (type == INSTR_FLOAT)
- _this->types[i] = TYPE_FVAR;
- else if (type == INSTR_PTR)
- _this->types[i] = TYPE_PVAR;
- else if ((type >= 0) && (type < FIRST_RESERVED))
- _this->types[i] = type;
- else
- fprintf (stderr, "WARNING: Line %d, %s has no namespace\n",
- _this->line_number, _this->params[i]);
- }
- }
- }
-
- switch (_this->id) {
-
- /* set */
- case INSTR_SET:
- return validate (_this,
- INSTR_SETF_VAR_FLOAT, INSTR_SETF_VAR_VAR,
- INSTR_SETI_VAR_INTEGER, INSTR_SETI_VAR_VAR,
- INSTR_SETP_VAR_PTR, INSTR_SETP_VAR_VAR, INSTR_SETS_VAR_VAR);
-
- /* extcall */
- case INSTR_EXT_CALL:
- if (_this->types[0] == TYPE_VAR) {
- HashValue *fval =
- goom_hash_get (_this->parent->functions, _this->params[0]);
- if (fval) {
- _this->data.udest.external_function =
- (struct _ExternalFunctionStruct *) fval->ptr;
- return VALIDATE_OK;
- }
- }
- return VALIDATE_ERROR;
-
- /* call */
- case INSTR_CALL:
- if (_this->types[0] == TYPE_LABEL) {
- _this->jump_label = _this->params[0];
- return VALIDATE_OK;
- }
- return VALIDATE_ERROR;
-
- /* ret */
- case INSTR_RET:
- return VALIDATE_OK;
-
- /* jump */
- case INSTR_JUMP:
-
- if (_this->types[0] == TYPE_LABEL) {
- _this->jump_label = _this->params[0];
- return VALIDATE_OK;
- }
- return VALIDATE_ERROR;
-
- /* jzero / jnzero */
- case INSTR_JZERO:
- case INSTR_JNZERO:
-
- if (_this->types[0] == TYPE_LABEL) {
- _this->jump_label = _this->params[0];
- return VALIDATE_OK;
- }
- return VALIDATE_ERROR;
-
- /* label */
- case INSTR_LABEL:
-
- if (_this->types[0] == TYPE_LABEL) {
- _this->id = INSTR_NOP;
- _this->nop_label = _this->params[0];
- goom_hash_put_int (_this->parent->iflow->labels, _this->params[0],
- _this->parent->iflow->number);
- return VALIDATE_OK;
- }
- return VALIDATE_ERROR;
-
- /* isequal */
- case INSTR_ISEQUAL:
- return validate (_this,
- INSTR_ISEQUALF_VAR_FLOAT, INSTR_ISEQUALF_VAR_VAR,
- INSTR_ISEQUALI_VAR_INTEGER, INSTR_ISEQUALI_VAR_VAR,
- INSTR_ISEQUALP_VAR_PTR, INSTR_ISEQUALP_VAR_VAR,
- INSTR_ISEQUALS_VAR_VAR);
-
- /* not */
- case INSTR_NOT:
- _this->id = INSTR_NOT_VAR;
- return VALIDATE_OK;
-
- /* islower */
- case INSTR_ISLOWER:
- return validate (_this,
- INSTR_ISLOWERF_VAR_FLOAT, INSTR_ISLOWERF_VAR_VAR,
- INSTR_ISLOWERI_VAR_INTEGER, INSTR_ISLOWERI_VAR_VAR,
- INSTR_NOP, INSTR_NOP, INSTR_NOP);
-
- /* add */
- case INSTR_ADD:
- return validate (_this,
- INSTR_ADDF_VAR_FLOAT, INSTR_ADDF_VAR_VAR,
- INSTR_ADDI_VAR_INTEGER, INSTR_ADDI_VAR_VAR,
- INSTR_NOP, INSTR_NOP, INSTR_ADDS_VAR_VAR);
-
- /* mul */
- case INSTR_MUL:
- return validate (_this,
- INSTR_MULF_VAR_FLOAT, INSTR_MULF_VAR_VAR,
- INSTR_MULI_VAR_INTEGER, INSTR_MULI_VAR_VAR,
- INSTR_NOP, INSTR_NOP, INSTR_MULS_VAR_VAR);
-
- /* sub */
- case INSTR_SUB:
- return validate (_this,
- INSTR_SUBF_VAR_FLOAT, INSTR_SUBF_VAR_VAR,
- INSTR_SUBI_VAR_INTEGER, INSTR_SUBI_VAR_VAR,
- INSTR_NOP, INSTR_NOP, INSTR_SUBS_VAR_VAR);
-
- /* div */
- case INSTR_DIV:
- return validate (_this,
- INSTR_DIVF_VAR_FLOAT, INSTR_DIVF_VAR_VAR,
- INSTR_DIVI_VAR_INTEGER, INSTR_DIVI_VAR_VAR,
- INSTR_NOP, INSTR_NOP, INSTR_DIVS_VAR_VAR);
-
- default:
- return VALIDATE_TODO;
- }
-} /* }}} */
-
- /*************/
- /* EXECUTION */
-/*************/
-void
-iflow_execute (FastInstructionFlow * _this, GoomSL * gsl)
-{ /* {{{ */
- int flag = 0;
- int ip = 0;
- FastInstruction *instr = _this->instr;
- int stack[0x10000];
- int stack_pointer = 0;
-
- stack[stack_pointer++] = -1;
-
- /* Quelques Macro pour rendre le code plus lisible */
-#define pSRC_VAR instr[ip].data.usrc.var
-#define SRC_VAR_INT *instr[ip].data.usrc.var_int
-#define SRC_VAR_FLOAT *instr[ip].data.usrc.var_float
-#define SRC_VAR_PTR *instr[ip].data.usrc.var_ptr
-
-#define pDEST_VAR instr[ip].data.udest.var
-#define DEST_VAR_INT *instr[ip].data.udest.var_int
-#define DEST_VAR_FLOAT *instr[ip].data.udest.var_float
-#define DEST_VAR_PTR *instr[ip].data.udest.var_ptr
-
-#define VALUE_INT instr[ip].data.usrc.value_int
-#define VALUE_FLOAT instr[ip].data.usrc.value_float
-#define VALUE_PTR instr[ip].data.usrc.value_ptr
-
-#define JUMP_OFFSET instr[ip].data.udest.jump_offset
-
-#define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1]
-#define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1]
-#define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i]
-#define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i]
-#define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i]
-#define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i]
-#define DEST_STRUCT_IBLOCK_VAR(i,j) \
- ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j]
-#define DEST_STRUCT_FBLOCK_VAR(i,j) \
- ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j]
-#define SRC_STRUCT_IBLOCK_VAR(i,j) \
- ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j]
-#define SRC_STRUCT_FBLOCK_VAR(i,j) \
- ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j]
-#define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size
-
- while (1) {
- int i;
-
-#ifdef TRACE_SCRIPT
- printf ("execute ");
- gsl_instr_display (instr[ip].proto);
- printf ("\n");
-#endif
- switch (instr[ip].id) {
-
- /* SET.I */
- case INSTR_SETI_VAR_INTEGER:
- DEST_VAR_INT = VALUE_INT;
- ++ip;
- break;
-
- case INSTR_SETI_VAR_VAR:
- DEST_VAR_INT = SRC_VAR_INT;
- ++ip;
- break;
-
- /* SET.F */
- case INSTR_SETF_VAR_FLOAT:
- DEST_VAR_FLOAT = VALUE_FLOAT;
- ++ip;
- break;
-
- case INSTR_SETF_VAR_VAR:
- DEST_VAR_FLOAT = SRC_VAR_FLOAT;
- ++ip;
- break;
-
- /* SET.P */
- case INSTR_SETP_VAR_VAR:
- DEST_VAR_PTR = SRC_VAR_PTR;
- ++ip;
- break;
-
- case INSTR_SETP_VAR_PTR:
- DEST_VAR_PTR = VALUE_PTR;
- ++ip;
- break;
-
- /* JUMP */
- case INSTR_JUMP:
- ip += JUMP_OFFSET;
- break;
-
- /* JZERO */
- case INSTR_JZERO:
- ip += (flag ? 1 : JUMP_OFFSET);
- break;
-
- case INSTR_NOP:
- ++ip;
- break;
-
- /* ISEQUAL.P */
- case INSTR_ISEQUALP_VAR_VAR:
- flag = (DEST_VAR_PTR == SRC_VAR_PTR);
- ++ip;
- break;
-
- case INSTR_ISEQUALP_VAR_PTR:
- flag = (DEST_VAR_PTR == VALUE_PTR);
- ++ip;
- break;
-
- /* ISEQUAL.I */
- case INSTR_ISEQUALI_VAR_VAR:
- flag = (DEST_VAR_INT == SRC_VAR_INT);
- ++ip;
- break;
-
- case INSTR_ISEQUALI_VAR_INTEGER:
- flag = (DEST_VAR_INT == VALUE_INT);
- ++ip;
- break;
-
- /* ISEQUAL.F */
- case INSTR_ISEQUALF_VAR_VAR:
- flag = (DEST_VAR_FLOAT == SRC_VAR_FLOAT);
- ++ip;
- break;
-
- case INSTR_ISEQUALF_VAR_FLOAT:
- flag = (DEST_VAR_FLOAT == VALUE_FLOAT);
- ++ip;
- break;
-
- /* ISLOWER.I */
- case INSTR_ISLOWERI_VAR_VAR:
- flag = (DEST_VAR_INT < SRC_VAR_INT);
- ++ip;
- break;
-
- case INSTR_ISLOWERI_VAR_INTEGER:
- flag = (DEST_VAR_INT < VALUE_INT);
- ++ip;
- break;
-
- /* ISLOWER.F */
- case INSTR_ISLOWERF_VAR_VAR:
- flag = (DEST_VAR_FLOAT < SRC_VAR_FLOAT);
- ++ip;
- break;
-
- case INSTR_ISLOWERF_VAR_FLOAT:
- flag = (DEST_VAR_FLOAT < VALUE_FLOAT);
- ++ip;
- break;
-
- /* ADD.I */
- case INSTR_ADDI_VAR_VAR:
- DEST_VAR_INT += SRC_VAR_INT;
- ++ip;
- break;
-
- case INSTR_ADDI_VAR_INTEGER:
- DEST_VAR_INT += VALUE_INT;
- ++ip;
- break;
-
- /* ADD.F */
- case INSTR_ADDF_VAR_VAR:
- DEST_VAR_FLOAT += SRC_VAR_FLOAT;
- ++ip;
- break;
-
- case INSTR_ADDF_VAR_FLOAT:
- DEST_VAR_FLOAT += VALUE_FLOAT;
- ++ip;
- break;
-
- /* MUL.I */
- case INSTR_MULI_VAR_VAR:
- DEST_VAR_INT *= SRC_VAR_INT;
- ++ip;
- break;
-
- case INSTR_MULI_VAR_INTEGER:
- DEST_VAR_INT *= VALUE_INT;
- ++ip;
- break;
-
- /* MUL.F */
- case INSTR_MULF_VAR_FLOAT:
- DEST_VAR_FLOAT *= VALUE_FLOAT;
- ++ip;
- break;
-
- case INSTR_MULF_VAR_VAR:
- DEST_VAR_FLOAT *= SRC_VAR_FLOAT;
- ++ip;
- break;
-
- /* DIV.I */
- case INSTR_DIVI_VAR_VAR:
- DEST_VAR_INT /= SRC_VAR_INT;
- ++ip;
- break;
-
- case INSTR_DIVI_VAR_INTEGER:
- DEST_VAR_INT /= VALUE_INT;
- ++ip;
- break;
-
- /* DIV.F */
- case INSTR_DIVF_VAR_FLOAT:
- DEST_VAR_FLOAT /= VALUE_FLOAT;
- ++ip;
- break;
-
- case INSTR_DIVF_VAR_VAR:
- DEST_VAR_FLOAT /= SRC_VAR_FLOAT;
- ++ip;
- break;
-
- /* SUB.I */
- case INSTR_SUBI_VAR_VAR:
- DEST_VAR_INT -= SRC_VAR_INT;
- ++ip;
- break;
-
- case INSTR_SUBI_VAR_INTEGER:
- DEST_VAR_INT -= VALUE_INT;
- ++ip;
- break;
-
- /* SUB.F */
- case INSTR_SUBF_VAR_FLOAT:
- DEST_VAR_FLOAT -= VALUE_FLOAT;
- ++ip;
- break;
-
- case INSTR_SUBF_VAR_VAR:
- DEST_VAR_FLOAT -= SRC_VAR_FLOAT;
- ++ip;
- break;
-
- /* CALL */
- case INSTR_CALL:
- stack[stack_pointer++] = ip + 1;
- ip += JUMP_OFFSET;
- break;
-
- /* RET */
- case INSTR_RET:
- ip = stack[--stack_pointer];
- if (ip < 0)
- return;
- break;
-
- /* EXT_CALL */
- case INSTR_EXT_CALL:
- instr[ip].data.udest.external_function->function (gsl, gsl->vars,
- instr[ip].data.udest.external_function->vars);
- ++ip;
- break;
-
- /* NOT */
- case INSTR_NOT_VAR:
- flag = !flag;
- ++ip;
- break;
-
- /* JNZERO */
- case INSTR_JNZERO:
- ip += (flag ? JUMP_OFFSET : 1);
- break;
-
- case INSTR_SETS_VAR_VAR:
- memcpy (pDEST_VAR, pSRC_VAR, DEST_STRUCT_SIZE);
- ++ip;
- break;
-
- case INSTR_ISEQUALS_VAR_VAR:
- break;
-
- case INSTR_ADDS_VAR_VAR:
- /* process integers */
- i = 0;
- while (DEST_STRUCT_IBLOCK (i).size > 0) {
- int j = DEST_STRUCT_IBLOCK (i).size;
-
- while (j--) {
- DEST_STRUCT_IBLOCK_VAR (i, j) += SRC_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);
- }
- ++i;
- }
- ++ip;
- break;
-
- case INSTR_SUBS_VAR_VAR:
- /* process integers */
- i = 0;
- while (DEST_STRUCT_IBLOCK (i).size > 0) {
- int j = DEST_STRUCT_IBLOCK (i).size;
-
- while (j--) {
- DEST_STRUCT_IBLOCK_VAR (i, j) -= SRC_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);
- }
- ++i;
- }
- ++ip;
- break;
-
- case INSTR_MULS_VAR_VAR:
- /* process integers */
- i = 0;
- while (DEST_STRUCT_IBLOCK (i).size > 0) {
- int j = DEST_STRUCT_IBLOCK (i).size;
-
- while (j--) {
- DEST_STRUCT_IBLOCK_VAR (i, j) *= SRC_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);
- }
- ++i;
- }
- ++ip;
- break;
-
- case INSTR_DIVS_VAR_VAR:
- /* process integers */
- i = 0;
- while (DEST_STRUCT_IBLOCK (i).size > 0) {
- int j = DEST_STRUCT_IBLOCK (i).size;
-
- while (j--) {
- DEST_STRUCT_IBLOCK_VAR (i, j) /= SRC_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);
- }
- ++i;
- }
- ++ip;
- break;
-
- default:
- printf ("NOT IMPLEMENTED : %d\n", instr[ip].id);
- ++ip;
- exit (1);
- }
- }
-} /* }}} */
-
-int
-gsl_malloc (GoomSL * _this, int size)
-{ /* {{{ */
- if (_this->nbPtr >= _this->ptrArraySize) {
- _this->ptrArraySize *= 2;
- _this->ptrArray =
- (void **) realloc (_this->ptrArray,
- sizeof (void *) * _this->ptrArraySize);
- }
- _this->ptrArray[_this->nbPtr] = malloc (size);
- return _this->nbPtr++;
-} /* }}} */
-
-void *
-gsl_get_ptr (GoomSL * _this, int id)
-{ /* {{{ */
- if ((id >= 0) && (id < _this->nbPtr))
- return _this->ptrArray[id];
- fprintf (stderr, "INVALID GET PTR 0x%08x\n", id);
- return NULL;
-} /* }}} */
-
-void
-gsl_free_ptr (GoomSL * _this, int id)
-{ /* {{{ */
- if ((id >= 0) && (id < _this->nbPtr)) {
- free (_this->ptrArray[id]);
- _this->ptrArray[id] = 0;
- }
-} /* }}} */
-
-void
-gsl_enternamespace (const char *name)
-{ /* {{{ */
- HashValue *val = goom_hash_get (currentGoomSL->functions, name);
-
- if (val) {
- ExternalFunctionStruct *function = (ExternalFunctionStruct *) val->ptr;
-
- currentGoomSL->currentNS++;
- currentGoomSL->namespaces[currentGoomSL->currentNS] = function->vars;
- } else {
- fprintf (stderr, "ERROR: Line %d, Could not find namespace: %s\n",
- currentGoomSL->num_lines, name);
- exit (1);
- }
-} /* }}} */
-
-void
-gsl_reenternamespace (GoomHash * nsinfo)
-{
- currentGoomSL->currentNS++;
- currentGoomSL->namespaces[currentGoomSL->currentNS] = nsinfo;
-}
-
-GoomHash *
-gsl_leavenamespace (void)
-{ /* {{{ */
- currentGoomSL->currentNS--;
- return currentGoomSL->namespaces[currentGoomSL->currentNS + 1];
-} /* }}} */
-
-GoomHash *
-gsl_find_namespace (const char *name)
-{ /* {{{ */
- int i;
-
- for (i = currentGoomSL->currentNS; i >= 0; --i) {
- if (goom_hash_get (currentGoomSL->namespaces[i], name))
- return currentGoomSL->namespaces[i];
- }
- return NULL;
-} /* }}} */
-
-void
-gsl_declare_task (const char *name)
-{ /* {{{ */
- if (goom_hash_get (currentGoomSL->functions, name)) {
- return;
- } else {
- ExternalFunctionStruct *gef =
- (ExternalFunctionStruct *) malloc (sizeof (ExternalFunctionStruct));
- gef->function = 0;
- gef->vars = goom_hash_new ();
- gef->is_extern = 0;
- goom_hash_put_ptr (currentGoomSL->functions, name, (void *) gef);
- }
-} /* }}} */
-
-void
-gsl_declare_external_task (const char *name)
-{ /* {{{ */
- if (goom_hash_get (currentGoomSL->functions, name)) {
- fprintf (stderr, "ERROR: Line %d, Duplicate declaration of %s\n",
- currentGoomSL->num_lines, name);
- return;
- } else {
- ExternalFunctionStruct *gef =
- (ExternalFunctionStruct *) malloc (sizeof (ExternalFunctionStruct));
- gef->function = 0;
- gef->vars = goom_hash_new ();
- gef->is_extern = 1;
- goom_hash_put_ptr (currentGoomSL->functions, name, (void *) gef);
- }
-} /* }}} */
-
-static void
-reset_scanner (GoomSL * gss)
-{ /* {{{ */
- gss->num_lines = 0;
- gss->instr = NULL;
- iflow_clean (gss->iflow);
-
- /* reset variables */
- goom_hash_free (gss->vars);
- gss->vars = goom_hash_new ();
- gss->currentNS = 0;
- gss->namespaces[0] = gss->vars;
-
- goom_hash_free (gss->structIDS);
- gss->structIDS = goom_hash_new ();
-
- while (gss->nbStructID > 0) {
- int i;
-
- gss->nbStructID--;
- for (i = 0; i < gss->gsl_struct[gss->nbStructID]->nbFields; ++i)
- free (gss->gsl_struct[gss->nbStructID]->fields[i]);
- free (gss->gsl_struct[gss->nbStructID]);
- }
-
- gss->compilationOK = 1;
-
- goom_heap_delete (gss->data_heap);
- gss->data_heap = goom_heap_new ();
-} /* }}} */
-
-static void
-calculate_labels (InstructionFlow * iflow)
-{ /* {{{ */
- int i = 0;
-
- while (i < iflow->number) {
- Instruction *instr = iflow->instr[i];
-
- if (instr->jump_label) {
- HashValue *label = goom_hash_get (iflow->labels, instr->jump_label);
-
- if (label) {
- instr->data.udest.jump_offset = -instr->address + label->i;
- } else {
- fprintf (stderr, "ERROR: Line %d, Could not find label %s\n",
- instr->line_number, instr->jump_label);
- instr->id = INSTR_NOP;
- instr->nop_label = 0;
- exit (1);
- }
- }
- ++i;
- }
-} /* }}} */
-
-#ifdef USE_JITC_X86
-static int
-powerOfTwo (int i)
-{
- int b;
-
- for (b = 0; b < 31; b++)
- if (i == (1 << b))
- return b;
- return 0;
-}
-#endif
-
-/* Cree un flow d'instruction optimise */
-static void
-gsl_create_fast_iflow (void)
-{ /* {{{ */
- int number = currentGoomSL->iflow->number;
- int i;
-
-#ifdef USE_JITC_X86
-
- /* pour compatibilite avec les MACROS servant a execution */
- int ip = 0;
- GoomSL *gsl = currentGoomSL;
-
- JitcX86Env *jitc;
-
- if (currentGoomSL->jitc != NULL)
- jitc_x86_delete (currentGoomSL->jitc);
- jitc = currentGoomSL->jitc = jitc_x86_env_new (0xffff);
- currentGoomSL->jitc_func = jitc_prepare_func (jitc);
-
-#if 0
-#define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1]
-#define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1]
-#define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i]
-#define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i]
-#define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i]
-#define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i]
-#define DEST_STRUCT_IBLOCK_VAR(i,j) \
- ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j]
-#define DEST_STRUCT_FBLOCK_VAR(i,j) \
- ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j]
-#define SRC_STRUCT_IBLOCK_VAR(i,j) \
- ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j]
-#define SRC_STRUCT_FBLOCK_VAR(i,j) \
- ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j]
-#define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size
-#endif
-
- JITC_JUMP_LABEL (jitc, "__very_end__");
- JITC_ADD_LABEL (jitc, "__very_start__");
-
- for (i = 0; i < number; ++i) {
- Instruction *instr = currentGoomSL->iflow->instr[i];
-
- switch (instr->id) {
- case INSTR_SETI_VAR_INTEGER:
- jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_int,
- instr->data.usrc.value_int);
- break;
- case INSTR_SETI_VAR_VAR:
- jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_int);
- jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
- break;
- /* SET.F */
- case INSTR_SETF_VAR_FLOAT:
- jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_float,
- *(int *) (&instr->data.usrc.value_float));
- break;
- case INSTR_SETF_VAR_VAR:
- jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_float);
- jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_float);
- break;
- case INSTR_NOP:
- if (instr->nop_label != 0)
- JITC_ADD_LABEL (jitc, instr->nop_label);
- break;
- case INSTR_JUMP:
- JITC_JUMP_LABEL (jitc, instr->jump_label);
- break;
- case INSTR_SETP_VAR_PTR:
- jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_ptr,
- instr->data.usrc.value_ptr);
- break;
- case INSTR_SETP_VAR_VAR:
- jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_ptr);
- jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_ptr);
- break;
- case INSTR_SUBI_VAR_INTEGER:
- jitc_add (jitc, "add [$d], $d", instr->data.udest.var_int,
- -instr->data.usrc.value_int);
- break;
- case INSTR_SUBI_VAR_VAR:
- jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
- jitc_add (jitc, "sub eax, [$d]", instr->data.usrc.var_int);
- jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
- break;
- case INSTR_SUBF_VAR_FLOAT:
- printf ("NOT IMPLEMENTED : %d\n", instr->id);
- break;
- 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);
- if (fread (buffer, 1, fsize, f) != fsize) {
- buffer[0] = '\0';
- }
- 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);
-}