Example #1
0
void
orc_mips_emit_conditional_branch (OrcCompiler *compiler,
                                  int condition,
                                  OrcMipsRegister rs,
                                  OrcMipsRegister rt,
                                  unsigned int label)
{
  int offset;
  char *opcode_name[] = { NULL, NULL, NULL, NULL,
    "beq ",
    "bne ",
    "blez",
    "bgtz"
  };
  switch (condition) {
  case ORC_MIPS_BEQ:
  case ORC_MIPS_BNE:
    ORC_ASM_CODE (compiler, "  %s    %s, %s, .L%s%d\n", opcode_name[condition],
                  orc_mips_reg_name (rs), orc_mips_reg_name (rt),
                  compiler->program->name, label);
    break;
  case ORC_MIPS_BLEZ:
  case ORC_MIPS_BGTZ:
    ORC_ASSERT (rt == ORC_MIPS_ZERO);
    ORC_ASM_CODE (compiler, "  %s    %s, .L%s%d\n", opcode_name[condition],
                  orc_mips_reg_name (rs),
                  compiler->program->name, label);
    break;
  default:
    ORC_PROGRAM_ERROR (compiler, "unknown branch type: 0x%x", condition);
  }
  if (compiler->labels[label]) {
    offset = (compiler->labels[label] - (compiler->codeptr+4)) >> 2;
  } else {
Example #2
0
File: orc.c Project: genesi/orc
/**
 * orc_init:
 * 
 * This function initializes the Orc library, and
 * should be called before using any other Orc function.
 * Subsequent calls to this function have no effect.
 */
void
orc_init (void)
{
  static int _inited = 0;
  if (_inited) return;

  _inited = 1;

  ORC_ASSERT(sizeof(OrcExecutor) == sizeof(OrcExecutorAlt));

  _orc_debug_init();
  _orc_once_init();
  _orc_compiler_init();
  orc_opcode_init();
  orc_c_init();
#ifdef ENABLE_BACKEND_C64X
  orc_c64x_c_init();
#endif
#ifdef ENABLE_BACKEND_MMX
  orc_mmx_init();
#endif
#ifdef ENABLE_BACKEND_SSE
  orc_sse_init();
#endif
#ifdef ENABLE_BACKEND_ALTIVEC
  orc_powerpc_init();
#endif
#ifdef ENABLE_BACKEND_ARM
  orc_arm_init();
#endif
#ifdef ENABLE_BACKEND_NEON
  orc_neon_init();
#endif
}
Example #3
0
void
orc_mips_emit_label (OrcCompiler *compiler, unsigned int label)
{
  ORC_ASSERT (label < ORC_N_LABELS);
  ORC_ASM_CODE(compiler,".L%s%d:\n", compiler->program->name, label);
  compiler->labels[label] = compiler->codeptr;
}
Example #4
0
void
orc_mips_add_fixup (OrcCompiler *compiler, int label, int type)
{
  ORC_ASSERT (compiler->n_fixups < ORC_N_FIXUPS);

  compiler->fixups[compiler->n_fixups].ptr = compiler->codeptr;
  compiler->fixups[compiler->n_fixups].label = label;
  compiler->fixups[compiler->n_fixups].type = type;
  compiler->n_fixups++;
}
Example #5
0
static OrcStaticOpcode *
get_store_opcode_for_size (int size)
{
  switch (size) {
    case 1:
      return orc_opcode_find_by_name ("storeb");
    case 2:
      return orc_opcode_find_by_name ("storew");
    case 4:
      return orc_opcode_find_by_name ("storel");
    case 8:
      return orc_opcode_find_by_name ("storeq");
    default:
      ORC_ASSERT(0);
  }
  return NULL;
}
Example #6
0
static OrcStaticOpcode *
get_loadp_opcode_for_size (int size)
{
  switch (size) {
    case 1:
      return orc_opcode_find_by_name ("loadpb");
    case 2:
      return orc_opcode_find_by_name ("loadpw");
    case 4:
      return orc_opcode_find_by_name ("loadpl");
    case 8:
      return orc_opcode_find_by_name ("loadpq");
    default:
      ORC_ASSERT(0);
  }
  return NULL;
}
Example #7
0
static void
load_constant (void *data, int size, orc_uint64 value)
{
  switch (size) {
    case 1:
      {
        int l;
        orc_int8 *d = data;
        for(l=0;l<CHUNK_SIZE;l++) {
          d[l] = value;
        }
      }
      break;
    case 2:
      {
        int l;
        orc_int16 *d = data;
        for(l=0;l<CHUNK_SIZE;l++) {
          d[l] = value;
        }
      }
      break;
    case 4:
      {
        int l;
        orc_int32 *d = data;
        for(l=0;l<CHUNK_SIZE;l++) {
          d[l] = value;
        }
      }
      break;
    case 8:
      {
        int l;
        orc_int64 *d = data;
        for(l=0;l<CHUNK_SIZE;l++) {
          d[l] = value;
        }
      }
      break;
    default:
      ORC_ASSERT(0);
  }

}
Example #8
0
void
orc_mips_do_fixups (OrcCompiler *compiler)
{
  int i;
  for(i=0;i<compiler->n_fixups;i++){
    /* Type 0 of fixup is a branch label that could not be resolved at first
     * pass. We compute the offset, which should be the 16 least significant
     * bits of the instruction. */
    unsigned char *label = compiler->labels[compiler->fixups[i].label];
    unsigned char *ptr = compiler->fixups[i].ptr;
    orc_uint32 code;
    int offset;
    ORC_ASSERT (compiler->fixups[i].type == 0);
    offset = (label - (ptr + 4)) >> 2;
    code = ORC_READ_UINT32_LE (ptr);
    code |= offset & 0xffff;
    ORC_WRITE_UINT32_LE (ptr, code);
  }
}
Example #9
0
OrcCodeChunk *
orc_code_region_get_free_chunk (int size)
{
  int i;
  OrcCodeRegion *region;
  OrcCodeChunk *chunk;

  orc_global_mutex_lock ();
  for(i=0;i<orc_code_n_regions;i++){
    region = orc_code_regions[i];
    for(chunk = region->chunks; chunk; chunk = chunk->next) {
      if (!chunk->used && size <= chunk->size) {
        orc_global_mutex_unlock ();
        return chunk;
      }
    }
  }

  orc_code_regions = realloc (orc_code_regions,
      sizeof(void *)*(orc_code_n_regions+1));
  orc_code_regions[orc_code_n_regions] = orc_code_region_new ();
  region = orc_code_regions[orc_code_n_regions];
  orc_code_n_regions++;

  for(chunk = region->chunks; chunk; chunk = chunk->next) {
    if (!chunk->used && size <= chunk->size){
      orc_global_mutex_unlock ();
      return chunk;
    }
  }
  orc_global_mutex_unlock ();

  ORC_ASSERT(0);

  return NULL;
}
Example #10
0
File: orcc.c Project: mojaves/orc
void
output_code_execute (OrcProgram *p, FILE *output, int is_inline)
{
  OrcVariable *var;
  int i;

  if (!use_lazy_init) {
    const char *storage;
    if (is_inline) {
      storage = "extern ";
    } else {
      if (use_inline) {
        storage = "";
      } else {
        storage = "static ";
      }
    }
    if (use_code) {
      fprintf(output, "%sOrcCode *_orc_code_%s;\n", storage, p->name);
    } else {
      fprintf(output, "%sOrcProgram *_orc_program_%s;\n", storage, p->name);
    }
  }
  if (is_inline) {
    fprintf(output, "static inline void\n");
  } else {
    fprintf(output, "void\n");
  }
  output_prototype (p, output);
  fprintf(output, "\n");
  fprintf(output, "{\n");
  fprintf(output, "  OrcExecutor _ex, *ex = &_ex;\n");
  if (!use_lazy_init) {
    if (use_code) {
      fprintf(output, "  OrcCode *c = _orc_code_%s;\n", p->name);
    } else {
      fprintf(output, "  OrcProgram *p = _orc_program_%s;\n", p->name);
    }
  } else {
    fprintf(output, "  static volatile int p_inited = 0;\n");
    if (use_code) {
      fprintf(output, "  static OrcCode *c = 0;\n");
    } else {
      fprintf(output, "  static OrcProgram *p = 0;\n");
    }
  }
  fprintf(output, "  void (*func) (OrcExecutor *);\n");
  fprintf(output, "\n");
  if (use_lazy_init) {
    fprintf(output, "  if (!p_inited) {\n");
    fprintf(output, "    orc_once_mutex_lock ();\n");
    fprintf(output, "    if (!p_inited) {\n");
    if (use_code) {
      fprintf(output, "      OrcProgram *p;\n");
    }
    fprintf(output, "\n");
    output_program_generation (p, output, is_inline);
    fprintf(output, "\n");
    fprintf(output, "      orc_program_compile (p);\n");
    if (use_code) {
      fprintf(output, "      c = orc_program_take_code (p);\n");
      fprintf(output, "      orc_program_free (p);\n");
    }
    fprintf(output, "    }\n");
    fprintf(output, "    p_inited = TRUE;\n");
    fprintf(output, "    orc_once_mutex_unlock ();\n");
    fprintf(output, "  }\n");
  }
  if (use_code) {
    fprintf(output, "  ex->arrays[ORC_VAR_A2] = c;\n");
    fprintf(output, "  ex->program = 0;\n");
  } else {
    fprintf(output, "  ex->program = p;\n");
  }
  fprintf(output, "\n");
  if (p->constant_n) {
    fprintf(output, "  ex->n = %d;\n", p->constant_n);
  } else {
    fprintf(output, "  ex->n = n;\n");
  }
  if (p->is_2d) {
    if (p->constant_m) {
      fprintf(output, "  ORC_EXECUTOR_M(ex) = %d;\n", p->constant_m);
    } else {
      fprintf(output, "  ORC_EXECUTOR_M(ex) = m;\n");
    }
  }
  for(i=0;i<4;i++){
    var = &p->vars[ORC_VAR_D1 + i];
    if (var->size) {
      fprintf(output, "  ex->arrays[%s] = %s;\n",
          enumnames[ORC_VAR_D1 + i], varnames[ORC_VAR_D1 + i]);
      if (p->is_2d) {
        fprintf(output, "  ex->params[%s] = %s_stride;\n",
            enumnames[ORC_VAR_D1 + i], varnames[ORC_VAR_D1 + i]);
      }
    }
  }
  for(i=0;i<8;i++){
    var = &p->vars[ORC_VAR_S1 + i];
    if (var->size) {
      fprintf(output, "  ex->arrays[%s] = (void *)%s;\n",
          enumnames[ORC_VAR_S1 + i], varnames[ORC_VAR_S1 + i]);
      if (p->is_2d) {
        fprintf(output, "  ex->params[%s] = %s_stride;\n",
            enumnames[ORC_VAR_S1 + i], varnames[ORC_VAR_S1 + i]);
      }
    }
  }
  for(i=0;i<8;i++){
    var = &p->vars[ORC_VAR_P1 + i];
    if (var->size) {
      switch (var->param_type) {
        case ORC_PARAM_TYPE_INT:
          fprintf(output, "  ex->params[%s] = %s;\n",
              enumnames[ORC_VAR_P1 + i], varnames[ORC_VAR_P1 + i]);
          break;
        case ORC_PARAM_TYPE_FLOAT:
          REQUIRE(0,4,5,1);
          fprintf(output, "  {\n");
          fprintf(output, "    orc_union32 tmp;\n");
          fprintf(output, "    tmp.f = %s;\n", varnames[ORC_VAR_P1 + i]);
          fprintf(output, "    ex->params[%s] = tmp.i;\n",
              enumnames[ORC_VAR_P1 + i]);
          fprintf(output, "  }\n");
          break;
        case ORC_PARAM_TYPE_INT64:
          REQUIRE(0,4,7,1);
          fprintf(output, "  {\n");
          fprintf(output, "    orc_union64 tmp;\n");
          fprintf(output, "    tmp.i = %s;\n", varnames[ORC_VAR_P1 + i]);
          fprintf(output, "    ex->params[%s] = tmp.x2[0];\n",
              enumnames[ORC_VAR_P1 + i]);
          fprintf(output, "    ex->params[%s] = tmp.x2[1];\n",
              enumnames[ORC_VAR_T1 + i]);
          fprintf(output, "  }\n");
          break;
        case ORC_PARAM_TYPE_DOUBLE:
          REQUIRE(0,4,5,1);
          fprintf(output, "  {\n");
          fprintf(output, "    orc_union64 tmp;\n");
          fprintf(output, "    tmp.f = %s;\n", varnames[ORC_VAR_P1 + i]);
          fprintf(output, "    ex->params[%s] = tmp.x2[0];\n",
              enumnames[ORC_VAR_P1 + i]);
          fprintf(output, "    ex->params[%s] = tmp.x2[1];\n",
              enumnames[ORC_VAR_T1 + i]);
          fprintf(output, "  }\n");
          break;
        default:
          ORC_ASSERT(0);
      }
    }
  }
  fprintf(output, "\n");
  if (use_code) {
    fprintf(output, "  func = c->exec;\n");
  } else {
    fprintf(output, "  func = p->code_exec;\n");
  }
  fprintf(output, "  func (ex);\n");
  for(i=0;i<4;i++){
    var = &p->vars[ORC_VAR_A1 + i];
    if (var->size) {
      fprintf(output, "  *%s = orc_executor_get_accumulator (ex, %s);\n",
          varnames[ORC_VAR_A1 + i], enumnames[ORC_VAR_A1 + i]);
    }
  }
  fprintf(output, "}\n");

}
Example #11
0
File: orcc.c Project: mojaves/orc
void
output_prototype (OrcProgram *p, FILE *output)
{
  OrcVariable *var;
  int i;
  int need_comma;

  fprintf(output, "%s (", p->name);
  need_comma = FALSE;
  for(i=0;i<4;i++){
    var = &p->vars[ORC_VAR_D1 + i];
    if (var->size) {
      if (need_comma) fprintf(output, ", ");
      if (var->type_name) {
        fprintf(output, "%s * ORC_RESTRICT %s", orcify_typename(var->type_name),
            varnames[ORC_VAR_D1 + i]);
      } else {
        fprintf(output, "orc_uint%d * ORC_RESTRICT %s", var->size*8,
            varnames[ORC_VAR_D1 + i]);
      }
      if (p->is_2d) {
        fprintf(output, ", int %s_stride", varnames[ORC_VAR_D1 + i]);
      }
      need_comma = TRUE;
    }
  }
  for(i=0;i<4;i++){
    var = &p->vars[ORC_VAR_A1 + i];
    if (var->size) {
      if (need_comma) fprintf(output, ", ");
      if (var->type_name) {
        fprintf(output, "%s * ORC_RESTRICT %s", orcify_typename(var->type_name),
            varnames[ORC_VAR_A1 + i]);
      } else {
        fprintf(output, "orc_uint%d * ORC_RESTRICT %s", var->size*8,
            varnames[ORC_VAR_A1 + i]);
      }
      need_comma = TRUE;
    }
  }
  for(i=0;i<8;i++){
    var = &p->vars[ORC_VAR_S1 + i];
    if (var->size) {
      if (need_comma) fprintf(output, ", ");
      if (var->type_name) {
        fprintf(output, "const %s * ORC_RESTRICT %s",
            orcify_typename(var->type_name),
            varnames[ORC_VAR_S1 + i]);
      } else {
        fprintf(output, "const orc_uint%d * ORC_RESTRICT %s", var->size*8,
            varnames[ORC_VAR_S1 + i]);
      }
      if (p->is_2d) {
        fprintf(output, ", int %s_stride", varnames[ORC_VAR_S1 + i]);
      }
      need_comma = TRUE;
    }
  }
  for(i=0;i<8;i++){
    var = &p->vars[ORC_VAR_P1 + i];
    if (var->size) {
      if (need_comma) fprintf(output, ", ");
      switch (var->param_type) {
        case ORC_PARAM_TYPE_INT:
          fprintf(output, "int %s", varnames[ORC_VAR_P1 + i]);
          break;
        case ORC_PARAM_TYPE_FLOAT:
          REQUIRE(0,4,5,1);
          fprintf(output, "float %s", varnames[ORC_VAR_P1 + i]);
          break;
        case ORC_PARAM_TYPE_INT64:
          REQUIRE(0,4,7,1);
          fprintf(output, "orc_int64 %s", varnames[ORC_VAR_P1 + i]);
          break;
        case ORC_PARAM_TYPE_DOUBLE:
          REQUIRE(0,4,7,1);
          fprintf(output, "double %s", varnames[ORC_VAR_P1 + i]);
          break;
        default:
          ORC_ASSERT(0);
      }
      need_comma = TRUE;
    }
  }
  if (p->constant_n == 0) {
    if (need_comma) fprintf(output, ", ");
    fprintf(output, "int n");
    need_comma = TRUE;
  }
  if (p->is_2d && p->constant_m == 0) {
    if (need_comma) fprintf(output, ", ");
    fprintf(output, "int m");
  }
  fprintf(output, ")");
}
Example #12
0
void
orc_executor_emulate (OrcExecutor *ex)
{
  int i;
  int j;
  int k;
  int m, m_index;
  OrcCode *code;
  OrcInstruction *insn;
  OrcStaticOpcode *opcode;
  OrcOpcodeExecutor *opcode_ex;
  void *tmpspace[ORC_N_COMPILER_VARIABLES] = { 0 };

  if (ex->program) {
    code = ex->program->orccode;
  } else {
    code = (OrcCode *)ex->arrays[ORC_VAR_A2];
  }

  ex->accumulators[0] = 0;
  ex->accumulators[1] = 0;
  ex->accumulators[2] = 0;
  ex->accumulators[3] = 0;

  ORC_DEBUG("emulating");

  memset (&opcode_ex, 0, sizeof(opcode_ex));

  if (code == NULL) {
    ORC_ERROR("attempt to run program that failed to compile");
    ORC_ASSERT(0);
  }

  if (code->is_2d) {
    m = ORC_EXECUTOR_M(ex);
  } else {
    m = 1;
  }

  for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){
    OrcCodeVariable *var = code->vars + i;

    if (var->size) {
      tmpspace[i] = malloc(ORC_MAX_VAR_SIZE * CHUNK_SIZE);
    }
  }

  opcode_ex = malloc(sizeof(OrcOpcodeExecutor)*code->n_insns);

  for(j=0;j<code->n_insns;j++){
    insn = code->insns + j;
    opcode = insn->opcode;

    opcode_ex[j].emulateN = opcode->emulateN;
    opcode_ex[j].shift = 0;
    if (insn->flags & ORC_INSTRUCTION_FLAG_X2) {
      opcode_ex[j].shift = 1;
    } else if (insn->flags & ORC_INSTRUCTION_FLAG_X4) {
      opcode_ex[j].shift = 2;
    }

    for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++) {
      OrcCodeVariable *var = code->vars + insn->src_args[k];
      if (opcode->src_size[k] == 0) continue;

      if (var->vartype == ORC_VAR_TYPE_CONST) {
        opcode_ex[j].src_ptrs[k] = tmpspace[insn->src_args[k]];
        /* FIXME hack */
        load_constant (tmpspace[insn->src_args[k]], 8,
            var->value.i);
      } else if (var->vartype == ORC_VAR_TYPE_PARAM) {
        opcode_ex[j].src_ptrs[k] = tmpspace[insn->src_args[k]];
        /* FIXME hack */
        load_constant (tmpspace[insn->src_args[k]], 8,
            (orc_uint64)(orc_uint32)ex->params[insn->src_args[k]] |
            (((orc_uint64)(orc_uint32)ex->params[insn->src_args[k] +
             (ORC_VAR_T1 - ORC_VAR_P1)])<<32));
      } else if (var->vartype == ORC_VAR_TYPE_TEMP) {
        opcode_ex[j].src_ptrs[k] = tmpspace[insn->src_args[k]];
      } else if (var->vartype == ORC_VAR_TYPE_SRC) {
        if (ORC_PTR_TO_INT(ex->arrays[insn->src_args[k]]) & (var->size - 1)) {
          ORC_ERROR("Unaligned array for src%d, program %s",
              (insn->src_args[k]-ORC_VAR_S1), ex->program->name);
        }
        opcode_ex[j].src_ptrs[k] = ex->arrays[insn->src_args[k]];
      } else if (var->vartype == ORC_VAR_TYPE_DEST) {
        if (ORC_PTR_TO_INT(ex->arrays[insn->src_args[k]]) & (var->size - 1)) {
          ORC_ERROR("Unaligned array for dest%d, program %s",
              (insn->src_args[k]-ORC_VAR_D1), ex->program->name);
        }
        opcode_ex[j].src_ptrs[k] = ex->arrays[insn->src_args[k]];
      }
    }
    for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++) {
      OrcCodeVariable *var = code->vars + insn->dest_args[k];
      if (opcode->dest_size[k] == 0) continue;

      if (var->vartype == ORC_VAR_TYPE_TEMP) {
        ORC_DEBUG("dest vartype tmp %d", insn->dest_args[k]);
        opcode_ex[j].dest_ptrs[k] = tmpspace[insn->dest_args[k]];
      } else if (var->vartype == ORC_VAR_TYPE_ACCUMULATOR) {
        opcode_ex[j].dest_ptrs[k] =
          &ex->accumulators[insn->dest_args[k] - ORC_VAR_A1];
      } else if (var->vartype == ORC_VAR_TYPE_DEST) {
        if (ORC_PTR_TO_INT(ex->arrays[insn->dest_args[k]]) & (var->size - 1)) {
          ORC_ERROR("Unaligned array for dest%d, program %s",
              (insn->dest_args[k]-ORC_VAR_D1), ex->program->name);
        }
        opcode_ex[j].dest_ptrs[k] = ex->arrays[insn->dest_args[k]];
      }
    }
    ORC_DEBUG("opcode %s %p %p %p", opcode->name,
        opcode_ex[j].dest_ptrs[0], opcode_ex[j].src_ptrs[0],
        opcode_ex[j].src_ptrs[1]);
  }
  
  ORC_DEBUG("src ptr %p stride %d", ex->arrays[ORC_VAR_S1], ex->params[ORC_VAR_S1]);
  for(m_index=0;m_index<m;m_index++){
    ORC_DEBUG("m_index %d m %d", m_index, m);

    for(j=0;j<code->n_insns;j++){
      insn = code->insns + j;
      opcode = insn->opcode;

      for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++) {
        OrcCodeVariable *var = code->vars + insn->src_args[k];
        if (opcode->src_size[k] == 0) continue;

        if (var->vartype == ORC_VAR_TYPE_SRC) {
          opcode_ex[j].src_ptrs[k] =
            ORC_PTR_OFFSET(ex->arrays[insn->src_args[k]],
                ex->params[insn->src_args[k]]*m_index);
        } else if (var->vartype == ORC_VAR_TYPE_DEST) {
          opcode_ex[j].src_ptrs[k] =
            ORC_PTR_OFFSET(ex->arrays[insn->src_args[k]],
                ex->params[insn->src_args[k]]*m_index);
        }
      }
      for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++) {
        OrcCodeVariable *var = code->vars + insn->dest_args[k];
        if (opcode->dest_size[k] == 0) continue;

        if (var->vartype == ORC_VAR_TYPE_DEST) {
          opcode_ex[j].dest_ptrs[k] =
            ORC_PTR_OFFSET(ex->arrays[insn->dest_args[k]],
                ex->params[insn->dest_args[k]]*m_index);
        }
      }
    }

    for(i=0;i<ex->n;i+=CHUNK_SIZE){
      for(j=0;j<code->n_insns;j++){
        if (ex->n - i >= CHUNK_SIZE) {
          opcode_ex[j].emulateN (opcode_ex + j, i, CHUNK_SIZE << opcode_ex[j].shift);
        } else {
          opcode_ex[j].emulateN (opcode_ex + j, i, (ex->n - i) << opcode_ex[j].shift);
        }
      }
    }
  }

  free (opcode_ex);
  for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){
    if (tmpspace[i]) free (tmpspace[i]);
  }
}
Example #13
0
void
show (OrcProgram *program)
{
  OrcCompileResult result;
  OrcTarget *target;
  const char *target_name;
  unsigned int target_flags;
  int n, m;
  OrcExecutor *ex;
  OrcArray *dest[4] = { NULL, NULL, NULL, NULL };
  OrcArray *src[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  int i,j;
  OrcRandomContext rand_context = { 0 };


  target_name = NULL;
  target = orc_target_get_by_name (target_name);

  target_flags = orc_target_get_default_flags (target);

  result = orc_program_compile_full (program, target, target_flags);
  if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) {
    printf("%s: compile failed\n", program->name);
    return;
  }

  printf("%s:\n", program->name);

  if (program->constant_n > 0) {
    n = program->constant_n;
  } else {
    n = array_n;
  }

  ex = orc_executor_new (program);
  orc_executor_set_n (ex, n);
  if (program->is_2d) {
    if (program->constant_m > 0) {
      m = program->constant_m;
    } else {
      m = 2;
    }
  } else {
    m = 1;
  }
  orc_executor_set_m (ex, m);

  for(i=0;i<ORC_N_VARIABLES;i++){
    if (program->vars[i].name == NULL) continue;

    if (program->vars[i].vartype == ORC_VAR_TYPE_SRC) {
      src[i-ORC_VAR_S1] = orc_array_new (n, m, program->vars[i].size, 0);
      orc_array_set_random (src[i-ORC_VAR_S1], &rand_context);
    } else if (program->vars[i].vartype == ORC_VAR_TYPE_DEST) {
      dest[i-ORC_VAR_D1] = orc_array_new (n, m, program->vars[i].size, 0);
      orc_array_set_pattern (dest[i], ORC_OOB_VALUE);
    } else if (program->vars[i].vartype == ORC_VAR_TYPE_PARAM) {
      switch (program->vars[i].param_type) {
        case ORC_PARAM_TYPE_INT:
          orc_executor_set_param (ex, i, 2);
          break;
        case ORC_PARAM_TYPE_FLOAT:
          orc_executor_set_param_float (ex, i, 2.0);
          break;
        case ORC_PARAM_TYPE_INT64:
          orc_executor_set_param_int64 (ex, i, 2);
          break;
        case ORC_PARAM_TYPE_DOUBLE:
          orc_executor_set_param_double (ex, i, 2.0);
          break;
        default:
          ORC_ASSERT(0);
      }
    }
  }

  orc_executor_set_n (ex, n);
  orc_executor_set_m (ex, m);
  for(j=0;j<ORC_N_VARIABLES;j++){
    if (program->vars[j].vartype == ORC_VAR_TYPE_DEST) {
      orc_executor_set_array (ex, j, dest[j-ORC_VAR_D1]->data);
      orc_executor_set_stride (ex, j, dest[j-ORC_VAR_D1]->stride);
    }
    if (program->vars[j].vartype == ORC_VAR_TYPE_SRC) {
      orc_executor_set_array (ex, j, src[j-ORC_VAR_S1]->data);
      orc_executor_set_stride (ex, j, src[j-ORC_VAR_S1]->stride);
    }
  }

  orc_executor_run (ex);

  {
    int i,j;

    for(j=0;j<m;j++){
      for(i=0;i<n;i++){
        int l;

        printf("%2d %2d:", i, j);

        for(l=ORC_VAR_S1;l<ORC_VAR_S1+8;l++){
          if (program->vars[l].size > 0) {
            switch (format) {
              case FORMAT_FLOAT:
                print_array_val_float (src[l-ORC_VAR_S1], i, j);
                break;
              case FORMAT_HEX:
                print_array_val_hex (src[l-ORC_VAR_S1], i, j);
                break;
              case FORMAT_SIGNED:
                print_array_val_signed (src[l-ORC_VAR_S1], i, j);
                break;
              case FORMAT_UNSIGNED:
                print_array_val_unsigned (src[l-ORC_VAR_S1], i, j);
                break;
            }
          }
        }

        printf(" ->");
        for(l=ORC_VAR_D1;l<ORC_VAR_D1+4;l++){
          if (program->vars[l].size > 0) {
            switch (format) {
              case FORMAT_FLOAT:
                print_array_val_float (dest[l-ORC_VAR_D1], i, j);
                break;
              case FORMAT_HEX:
                print_array_val_hex (dest[l-ORC_VAR_D1], i, j);
                break;
              case FORMAT_SIGNED:
                print_array_val_signed (dest[l-ORC_VAR_D1], i, j);
                break;
              case FORMAT_UNSIGNED:
                print_array_val_unsigned (dest[l-ORC_VAR_D1], i, j);
                break;
            }
          }
        }

        printf("\n");
      }
    }
  }



  for(i=0;i<4;i++){
    if (dest[i]) orc_array_free (dest[i]);
  }
  for(i=0;i<8;i++){
    if (src[i]) orc_array_free (src[i]);
  }

  orc_executor_free (ex);

}