Example #1
0
static void
test_simple (int max, int (*adder) (OrcProgram *, int, const char *))
{
  OrcProgram *p;
  int v;
  OrcCompileResult result;

  p = orc_program_new ();

  /* dummy program so compile doesn't barf */
  orc_program_add_destination (p, 2, "d1");
  orc_program_add_source (p, 2, "s1");
  orc_program_append_str (p, "addw", "d1", "d1", "s1");

  /* we've alreay added one of those */
  if (adder == orc_program_add_destination || adder == orc_program_add_source)
    max--;

  /* Check we can add up to the claimed max */
  for (v = 0; v < max; v++)
    (*adder) (p, 2, names + v);
  result = orc_program_compile (p);
  if (ORC_COMPILE_RESULT_IS_FATAL (result))
    error = TRUE;

  orc_program_reset (p);

  /* Check we can not add one more */
  (*adder) (p, 2, names + v);
  result = orc_program_compile (p);
  if (ORC_COMPILE_RESULT_IS_SUCCESSFUL (result))
    error = TRUE;

  orc_program_free (p);
}
void
orc_memcpy_u32 (guint32 * d1, const guint32 * s1, int n)
{
  OrcExecutor _ex, *ex = &_ex;
  static int p_inited = 0;
  static OrcProgram *p = 0;
  void (*func) (OrcExecutor *);

  if (!p_inited) {
    orc_once_mutex_lock ();
    if (!p_inited) {
      OrcCompileResult result;

      p = orc_program_new ();
      orc_program_set_name (p, "orc_memcpy_u32");
      orc_program_set_backup_function (p, _backup_orc_memcpy_u32);
      orc_program_add_destination (p, 4, "d1");
      orc_program_add_source (p, 4, "s1");

      orc_program_append (p, "copyl", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);

      result = orc_program_compile (p);
    }
    p_inited = TRUE;
    orc_once_mutex_unlock ();
  }
  ex->program = p;

  ex->n = n;
  ex->arrays[ORC_VAR_D1] = d1;
  ex->arrays[ORC_VAR_S1] = (void *) s1;

  func = p->code_exec;
  func (ex);
}
Example #3
0
OrcProgram *
orc_program_new_from_static_bytecode (const orc_uint8 *bytecode)
{
  OrcProgram *p;

  p = orc_program_new ();
  orc_bytecode_parse_function (p, bytecode);

  return p;
}
Example #4
0
OrcProgram *
orc_test_get_program_for_opcode (OrcStaticOpcode *opcode)
{
  OrcProgram *p;
  char s[40];
  int flags = 0;
  int args[4] = { -1, -1, -1, -1 };
  int n_args = 0;

  p = orc_program_new ();
  if (opcode->flags & ORC_STATIC_OPCODE_ACCUMULATOR) {
    args[n_args++] =
      orc_program_add_accumulator (p, opcode->dest_size[0], "d1");
  } else {
    args[n_args++] =
      orc_program_add_destination (p, opcode->dest_size[0], "d1");
  }
  if (opcode->dest_size[1] != 0) {
    args[n_args++] =
      orc_program_add_destination (p, opcode->dest_size[1], "d2");
  }
  if (opcode->flags & ORC_STATIC_OPCODE_SCALAR) {
    if (opcode->src_size[1] == 0) {
      args[n_args++] =
        orc_program_add_constant (p, opcode->src_size[0], 1, "c1");
    } else {
      args[n_args++] =
        orc_program_add_source (p, opcode->src_size[0], "s1");
      args[n_args++] =
        orc_program_add_constant (p, opcode->src_size[1], 1, "c1");
      if (opcode->src_size[2] != 0) {
        args[n_args++] =
          orc_program_add_constant (p, opcode->src_size[1], 1, "c1");
      }
    }
  } else {
    args[n_args++] =
      orc_program_add_source (p, opcode->src_size[0], "s1");
    args[n_args++] =
      orc_program_add_source (p, opcode->src_size[1], "s2");
  }

  if ((opcode->flags & ORC_STATIC_OPCODE_FLOAT_SRC) ||
      (opcode->flags & ORC_STATIC_OPCODE_FLOAT_DEST)) {
    flags = ORC_TEST_FLAGS_FLOAT;
  }

  sprintf(s, "test_%s", opcode->name);
  orc_program_set_name (p, s);

  orc_program_append_2 (p, opcode->name, 0, args[0], args[1],
      args[2], args[3]);

  return p;
}
void
test_opcode_const (OrcStaticOpcode *opcode)
{
  OrcProgram *p;
  char s[40];
  int ret;
  int flags = 0;
  int args[4] = { -1, -1, -1, -1 };
  int n_args = 0;

  if (opcode->src_size[1] == 0) {
    return;
  }

  p = orc_program_new ();
  if (opcode->flags & ORC_STATIC_OPCODE_ACCUMULATOR) {
    args[n_args++] =
      orc_program_add_accumulator (p, opcode->dest_size[0], "d1");
  } else {
    args[n_args++] =
      orc_program_add_destination (p, opcode->dest_size[0], "d1");
  }
  if (opcode->dest_size[1] != 0) {
    args[n_args++] =
      orc_program_add_destination (p, opcode->dest_size[1], "d2");
  }
  args[n_args++] =
    orc_program_add_source (p, opcode->src_size[0], "s1");
  args[n_args++] =
    orc_program_add_constant (p, opcode->src_size[1], 1, "c1");
  if (opcode->src_size[2]) {
    args[n_args++] =
      orc_program_add_constant (p, opcode->src_size[2], 1, "c2");
  }

  if ((opcode->flags & ORC_STATIC_OPCODE_FLOAT_SRC) ||
      (opcode->flags & ORC_STATIC_OPCODE_FLOAT_DEST)) {
    flags = ORC_TEST_FLAGS_FLOAT;
  }

  sprintf(s, "test_const_%s", opcode->name);
  orc_program_set_name (p, s);

  orc_program_append_2 (p, opcode->name, 0, args[0], args[1],
      args[2], args[3]);

  ret = orc_test_compare_output_full (p, flags);
  if (!ret) {
    printf("FAIL: %s const\n", opcode->name);
    error = TRUE;
  }

  orc_program_free (p);
}
Example #6
0
/**
 * orc_program_new_ds:
 * @size1: size of destination array members
 * @size2: size of source array members
 * 
 * Create a new OrcProgram, with a destination named "d1" and
 * one source named "s1".
 *
 * Returns: a pointer to an OrcProgram structure
 */
OrcProgram *
orc_program_new_ds (int size1, int size2)
{
  OrcProgram *p;

  p = orc_program_new ();

  orc_program_add_destination (p, size1, "d1");
  orc_program_add_source (p, size2, "s1");

  return p;
}
Example #7
0
/**
 * orc_program_new_as:
 * @size1: size of destination array members
 * @size2: size of source array members
 * 
 * Create a new OrcProgram, with an accumulator named "a1" and
 * one source named "s1".
 *
 * Returns: a pointer to an OrcProgram structure
 */
OrcProgram *
orc_program_new_as (int size1, int size2)
{
  OrcProgram *p;

  p = orc_program_new ();

  orc_program_add_accumulator (p, size1, "a1");
  orc_program_add_source (p, size2, "s1");

  return p;
}
void
orc_blend_u8 (guint8 * d1, int d1_stride, const guint8 * s1, int s1_stride,
    int p1, int n, int m)
{
  OrcExecutor _ex, *ex = &_ex;
  static int p_inited = 0;
  static OrcProgram *p = 0;
  void (*func) (OrcExecutor *);

  if (!p_inited) {
    orc_once_mutex_lock ();
    if (!p_inited) {
      OrcCompileResult result;

      p = orc_program_new ();
      orc_program_set_2d (p);
      orc_program_set_name (p, "orc_blend_u8");
      orc_program_set_backup_function (p, _backup_orc_blend_u8);
      orc_program_add_destination (p, 1, "d1");
      orc_program_add_source (p, 1, "s1");
      orc_program_add_constant (p, 1, 8, "c1");
      orc_program_add_parameter (p, 2, "p1");
      orc_program_add_temporary (p, 2, "t1");
      orc_program_add_temporary (p, 2, "t2");

      orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_D1, ORC_VAR_D1);
      orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S1, ORC_VAR_D1);
      orc_program_append (p, "subw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T1);
      orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P1);
      orc_program_append (p, "shlw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1);
      orc_program_append (p, "addw", ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_T2);
      orc_program_append (p, "shruw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C1);
      orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_D1);

      result = orc_program_compile (p);
    }
    p_inited = TRUE;
    orc_once_mutex_unlock ();
  }
  ex->program = p;

  ex->n = n;
  ORC_EXECUTOR_M (ex) = m;
  ex->arrays[ORC_VAR_D1] = d1;
  ex->params[ORC_VAR_D1] = d1_stride;
  ex->arrays[ORC_VAR_S1] = (void *) s1;
  ex->params[ORC_VAR_S1] = s1_stride;
  ex->params[ORC_VAR_P1] = p1;

  func = p->code_exec;
  func (ex);
}
void
test_opcode_src_const_n_2d (OrcStaticOpcode *opcode)
{
  OrcProgram *p;
  char s[40];
  int ret;
  int flags = 0;

  if (opcode->flags & ORC_STATIC_OPCODE_SCALAR) {
    return;
  }

  p = orc_program_new ();
  if (opcode->flags & ORC_STATIC_OPCODE_ACCUMULATOR) {
    orc_program_add_accumulator (p, opcode->dest_size[0], "d1");
  } else {
    orc_program_add_destination (p, opcode->dest_size[0], "d1");
  }
  if (opcode->dest_size[1] != 0) {
    orc_program_add_destination (p, opcode->dest_size[1], "d2");
  }
  orc_program_add_source (p, opcode->src_size[0], "s1");
  if (opcode->src_size[1] != 0) {
    orc_program_add_source (p, opcode->src_size[1], "s2");
  }

  if ((opcode->flags & ORC_STATIC_OPCODE_FLOAT_SRC) ||
      (opcode->flags & ORC_STATIC_OPCODE_FLOAT_DEST)) {
    flags = ORC_TEST_FLAGS_FLOAT;
  }

  sprintf(s, "test_s_%s", opcode->name);
  orc_program_set_name (p, s);
  orc_program_set_2d (p);
  orc_program_set_constant_n (p, 8);

  if (opcode->dest_size[1] != 0) {
    orc_program_append_dds_str (p, opcode->name, "d1", "d2", "s1");
  } else {
    orc_program_append_str (p, opcode->name, "d1", "s1", "s2");
  }

  ret = orc_test_compare_output_full (p, flags);
  if (!ret) {
    printf("FAIL: %s src_const_n_2d\n", opcode->name);
    error = TRUE;
  }

  orc_program_free (p);
}
Example #10
0
VipsVector *
vips_vector_new( const char *name, int dsize )
{
	static int vector_number = 0;

	VipsVector *vector;
	int i;

	if( !(vector = VIPS_NEW( NULL, VipsVector )) )
		return( NULL );
	vector->name = name;
	vector->unique_name = g_strdup_printf( "p[%d]", vector_number++ );
	vector->n_temp = 0;
	vector->n_scanline = 0;
	vector->n_source = 0;
	vector->n_destination = 0;
	vector->n_constant = 0;
	vector->n_parameter = 0;
	vector->n_instruction = 0;

	for( i = 0; i < VIPS_VECTOR_SOURCE_MAX; i++ ) {
		vector->s[i] = -1;
		vector->sl[i] = -1;
	}

	vector->d1 = -1;

	vector->compiled = FALSE;

#ifdef HAVE_ORC
	vector->program = orc_program_new();
#ifdef DEBUG_TRACE
	printf( "%s = orc_program_new();\n", vector->unique_name );
#endif /*DEBUG_TRACE*/
#endif /*HAVE_ORC*/

	/* We always make d1, our callers make either a single point source, or
	 * for area ops, a set of scanlines.
	 *
	 * Don't check error return. orc uses 0 to mean error, but the first
	 * var you create will have id 0 :-( The first var is unlikely to fail
	 * anyway. 
	 */
	vector->d1 = vips_vector_destination( vector, "d1", dsize ); 

	return( vector );
}
Example #11
0
VipsVector *
vips_vector_new( const char *name, int dsize )
{
	VipsVector *vector;
	int i;

	if( !(vector = VIPS_NEW( NULL, VipsVector )) )
		return( NULL );
	vector->name = name;
	vector->n_temp = 0;
	vector->n_scanline = 0;
	vector->n_source = 0;
	vector->n_destination = 0;
	vector->n_constant = 0;
	vector->n_parameter = 0;
	vector->n_instruction = 0;

	for( i = 0; i < VIPS_VECTOR_SOURCE_MAX; i++ ) {
		vector->s[i] = -1;
		vector->sl[i] = -1;
	}

	vector->d1 = -1;

	vector->compiled = FALSE;

#ifdef HAVE_ORC
	vector->program = orc_program_new();

	/* We always make d1, our callers make either a single point source, or
	 * for area ops, a set of scanlines.
	 */
	vector->d1 = orc_program_add_destination( vector->program, 
		dsize, "d1" );
	vector->n_destination += 1;
#endif /*HAVE_ORC*/

	return( vector );
}
Example #12
0
int
orc_parse_full (const char *code, OrcProgram ***programs, char **log)
{
  OrcParser _parser;
  OrcParser *parser = &_parser;
  char *init_function = NULL;

  memset (parser, 0, sizeof(*parser));

  parser->code = code;
  parser->code_length = strlen (code);
  parser->line_number = 0;
  parser->p = code;
  parser->opcode_set = orc_opcode_set_get ("sys");
  parser->log = malloc(100);
  parser->log_alloc = 100;
  parser->log_size = 0;

  while (parser->p[0] != 0) {
    char *p;
    char *end;
    char *token[10];
    int n_tokens;

    orc_parse_get_line (parser);

    p = parser->line;
    end = p + strlen (p);
    //printf("%d: %s\n", parser->line_number, parser->line);

    while (p[0] == ' ' || p[0] == '\t') p++;

    if (p[0] == 0) {
      continue;
    }

    if (p[0] == '#') {
      //printf("comment: %s\n", p+1);
      continue;
    }

    n_tokens = 0;

    while (p < end) {
      if (p[0] == ' ' || p[0] == '\t' || p[0] == ',') p++;
      if (p[0] == 0 || p[0] == '#') break;

      token[n_tokens] = p;
      while (p[0] != 0 && p[0] != ' ' && p[0] != '\t' && p[0] != ',') p++;
      n_tokens++;

      p[0] = 0;
      p++;
    }

    if (n_tokens == 0) {
      continue;
    }

    {
      int i;
      for(i=0;i<n_tokens;i++){
        //printf("'%s' ", token[i]);
      }
      //printf("\n");
    }

    if (token[0][0] == '.') {
      if (strcmp (token[0], ".function") == 0) {
        if (parser->program) {
          orc_parse_sanity_check (parser, parser->program);
        }
        parser->program = orc_program_new ();
        orc_program_set_name (parser->program, token[1]);
        if (parser->n_programs == parser->n_programs_alloc) {
          parser->n_programs_alloc += 32;
          parser->programs = realloc (parser->programs,
              sizeof(OrcProgram *)*parser->n_programs_alloc);
        }
        parser->programs[parser->n_programs] = parser->program;
        parser->n_programs++;
        parser->creg_index = 1;
      } else if (strcmp (token[0], ".init") == 0) {
        free (init_function);
        init_function = NULL;
        if (n_tokens < 2) {
          orc_parse_log (parser, "error: line %d: .init without function name\n",
              parser->line_number);
        } else {
          init_function = strdup (token[1]);
        }
      } else if (strcmp (token[0], ".flags") == 0) {
        int i;
        for(i=1;i<n_tokens;i++){
          if (!strcmp (token[i], "2d")) {
            orc_program_set_2d (parser->program);
          }
        }
      } else if (strcmp (token[0], ".n") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_set_constant_n (parser->program, size);
      } else if (strcmp (token[0], ".m") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_set_constant_m (parser->program, size);
      } else if (strcmp (token[0], ".source") == 0) {
        int size = strtol (token[1], NULL, 0);
        int var;
        var = orc_program_add_source (parser->program, size, token[2]);
        if (n_tokens > 3) {
          orc_program_set_type_name (parser->program, var, token[3]);
        }
      } else if (strcmp (token[0], ".dest") == 0) {
        int size = strtol (token[1], NULL, 0);
        int var;
        var = orc_program_add_destination (parser->program, size, token[2]);
        if (n_tokens > 3) {
          orc_program_set_type_name (parser->program, var, token[3]);
        }
      } else if (strcmp (token[0], ".accumulator") == 0) {
        int size = strtol (token[1], NULL, 0);
        int var;
        var = orc_program_add_accumulator (parser->program, size, token[2]);
        if (n_tokens > 3) {
          orc_program_set_type_name (parser->program, var, token[3]);
        }
      } else if (strcmp (token[0], ".temp") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_temporary (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".param") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".longparam") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter_int64 (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".const") == 0) {
        int size = strtol (token[1], NULL, 0);

        orc_program_add_constant_str (parser->program, size, token[3], token[2]);
      } else if (strcmp (token[0], ".floatparam") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter_float (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".doubleparam") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter_double (parser->program, size, token[2]);
      } else {
        orc_parse_log (parser, "error: line %d: unknown directive: %s\n",
            parser->line_number, token[0]);
      }
    } else {
      OrcStaticOpcode *o;
      unsigned int flags = 0;
      int offset = 0;

      if (strcmp (token[0], "x4") == 0) {
        flags |= ORC_INSTRUCTION_FLAG_X4;
        offset = 1;
      } else if (strcmp (token[0], "x2") == 0) {
        flags |= ORC_INSTRUCTION_FLAG_X2;
        offset = 1;
      }

      o = get_opcode (parser, token[offset]);

      if (o) {
        int n_args = opcode_n_args (o);
        int i;

        if (n_tokens != 1 + offset + n_args) {
          orc_parse_log (parser, "error: line %d: too %s arguments for %s (expected %d)\n",
              parser->line_number, (n_tokens < 1+offset+n_args) ? "few" : "many",
              token[offset], n_args);
        }

        for(i=offset+1;i<n_tokens;i++){
          char *end;
          double d;
          d = strtod (token[i], &end);
          if (end != token[i]) {
            orc_program_add_constant_str (parser->program, 0, token[i],
                token[i]);
          }
        }

        if (n_tokens - offset == 5) {
          orc_program_append_str_2 (parser->program, token[offset], flags,
              token[offset+1], token[offset+2], token[offset+3], token[offset+4]);
        } else if (n_tokens - offset == 4) {
          orc_program_append_str_2 (parser->program, token[offset], flags,
              token[offset+1], token[offset+2], token[offset+3], NULL);
        } else {
          orc_program_append_str_2 (parser->program, token[offset], flags,
              token[offset+1], token[offset+2], NULL, NULL);
        }
      } else {
        orc_parse_log (parser, "error: line %d: unknown opcode: %s\n",
            parser->line_number,
            token[offset]);
      }
    }
  }

  if (parser->program) {
    orc_parse_sanity_check (parser, parser->program);
  }

  if (parser->line) free (parser->line);

  if (log) {
    *log = parser->log;
  } else {
    free (parser->log);
  }
  if (parser->programs[0]) {
    parser->programs[0]->init_function = init_function;
  } else {
    free (init_function);
  }
  *programs = parser->programs;
  return parser->n_programs;
}
Example #13
0
int
main(int argc, char *argv[])
{
  char *s, *d;
  orc_uint8 *src, *dest;
  OrcProfile prof;
  OrcProfile prof_libc;
  double ave, std;
  double ave_libc, std_libc;
  double null;
  int i,j;
  double cpufreq;
  int unalign;
  OrcProgram *p;
  int level1, level2, level3;
  int max;
  /* const uint8_t zero = 0; */

  orc_init ();

  /* cpufreq = 2333e6; */
  cpufreq = 1;

  if (argc > 1) {
    unalign = strtoul (argv[1], NULL, 0);
  } else {
    unalign = 0;
  }

  s = malloc(1024*1024*64+1024);
  d = malloc(1024*1024*64+1024);
  src = ORC_PTR_OFFSET(ALIGN(s,128),unalign);
  dest = ALIGN(d,128);

  orc_profile_init (&prof);
  for(j=0;j<10;j++){
    orc_profile_start(&prof);
    orc_profile_stop(&prof);
  }
  orc_profile_get_ave_std (&prof, &null, &std);
  
  {
    OrcCompileResult result;

    p = orc_program_new ();
    orc_program_set_name (p, "orc_memcpy");
    /* orc_program_set_name (p, "orc_memset"); */
    orc_program_add_destination (p, 1, "d1");
    orc_program_add_source (p, 1, "s1");
    /* orc_program_add_parameter (p, 1, "p1"); */

    orc_program_append (p, "copyb", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);

    result = orc_program_compile (p);

    if (ORC_COMPILE_RESULT_IS_FATAL (result)) {
      fprintf (stderr, "Failed to compile orc_memcpy\n");
      return -1;
    }
  }

#ifndef M_LN2
#define M_LN2 0.69314718055994530942
#endif
  orc_get_data_cache_sizes (&level1, &level2, &level3);
  if (level3 > 0) {
    max = (log(level3)/M_LN2 - 6.0) * 10 + 20;
  } else if (level2 > 0) {
    max = (log(level2)/M_LN2 - 6.0) * 10 + 20;
  } else {
    max = 140;
  }

  for(i=0;i<max;i++){
    double x = i*0.1 + 6.0;
    int size = pow(2.0, x);

    if (flush_cache) {
      touch (src, (1<<18));
    }
    if (hot_src) {
      touch (src, size);
    }
    if (hot_dest) {
      touch (dest, size);
    }

    orc_profile_init (&prof);
    for(j=0;j<10;j++){
      OrcExecutor _ex, *ex = &_ex;
      void (*func) (OrcExecutor *);

      orc_profile_start(&prof);
      /* orc_memcpy (dest, src, size); */
      ex->program = p;
      ex->n = size;
      ex->arrays[ORC_VAR_D1] = dest;
      ex->arrays[ORC_VAR_S1] = (void *)src;

      func = p->code_exec;
      func (ex);

      orc_profile_stop(&prof);
      if (flush_cache) {
        touch (src, (1<<18));
      }
      if (hot_src) {
        touch (src, size);
      }
      if (hot_dest) {
        touch (dest, size);
      }
    }

    orc_profile_init (&prof_libc);
    for(j=0;j<10;j++){
      orc_profile_start(&prof_libc);
      memcpy (dest, src, size);
      orc_profile_stop(&prof_libc);
      if (flush_cache) {
        touch (src, (1<<18));
      }
      if (hot_src) {
        touch (src, size);
      }
      if (hot_dest) {
        touch (dest, size);
      }
    }

    orc_profile_get_ave_std (&prof, &ave, &std);
    orc_profile_get_ave_std (&prof_libc, &ave_libc, &std_libc);

    ave -= null;
    ave_libc -= null;

    /* printf("%d: %10.4g %10.4g %10.4g %10.4g (libc %10.4g)\n", i, ave, std, */
    /*     ave/(1<<i), cpufreq/(ave/(1<<i)), */
    /*     cpufreq/(ave_libc/(1<<i))); */
    printf("%g %10.4g %10.4g\n", x,
        cpufreq/(ave/size), cpufreq/(ave_libc/size));
    /* printf("%g %10.4g %10.4g\n", x, */
    /*     32*(ave/(size)), 32*(ave_libc/(size))); */
    fflush (stdout);
  }

  orc_program_free (p);
  free (s);
  free (d);

  return 0;
}
Example #14
0
int
orc_parse_full (const char *code, OrcProgram ***programs, char **log)
{
  OrcParser _parser;
  OrcParser *parser = &_parser;
  char *init_function = NULL;

  memset (parser, 0, sizeof(*parser));

  parser->code = code;
  parser->code_length = strlen (code);
  parser->line_number = 0;
  parser->p = code;
  parser->opcode_set = orc_opcode_set_get ("sys");
  parser->log = malloc(100);
  parser->log_alloc = 100;
  parser->log_size = 0;
  parser->log[0] = 0;

  while (parser->p[0] != 0) {
    char *p;
    char *end;
    char *token[10];
    int n_tokens;

    orc_parse_get_line (parser);
    if (parser->program) orc_program_set_line (parser->program, parser->line_number);

    p = parser->line;
    end = p + strlen (p);
    /* printf("%d: %s\n", parser->line_number, parser->line); */

    while (p[0] == ' ' || p[0] == '\t') p++;

    if (p[0] == 0) {
      continue;
    }

    if (p[0] == '#') {
      /* printf("comment: %s\n", p+1); */
      continue;
    }

    n_tokens = 0;

    while (p < end) {
      while (p[0] != 0 && (p[0] == ' ' || p[0] == '\t')) p++;
      if (p[0] == 0 || p[0] == '#') break;

      token[n_tokens] = p;
      while (p[0] != 0 && p[0] != ' ' && p[0] != '\t' && p[0] != ',') p++;
      n_tokens++;

      p[0] = 0;
      p++;
    }

    if (n_tokens == 0) {
      continue;
    }

    {
      int i;
      for(i=0;i<n_tokens;i++){
        /* printf("'%s' ", token[i]); */
      }
      /* printf("\n"); */
    }

    if (token[0][0] == '.') {
      if (strcmp (token[0], ".function") == 0) {
        if (parser->program) {
          orc_parse_sanity_check (parser, parser->program);
        }
        parser->program = orc_program_new ();
        orc_program_set_name (parser->program, token[1]);
        if (parser->n_programs == parser->n_programs_alloc) {
          parser->n_programs_alloc += 32;
          parser->programs = realloc (parser->programs,
              sizeof(OrcProgram *)*parser->n_programs_alloc);
        }
        parser->programs[parser->n_programs] = parser->program;
        parser->n_programs++;
        parser->creg_index = 1;
      } else if (strcmp (token[0], ".backup") == 0) {
        if (n_tokens < 2) {
          orc_parse_log (parser, "error: line %d: .backup without function name\n",
              parser->line_number);
        } else {
          orc_program_set_backup_name (parser->program, token[1]);
        }

      } else if (strcmp (token[0], ".init") == 0) {
        free (init_function);
        init_function = NULL;
        if (n_tokens < 2) {
          orc_parse_log (parser, "error: line %d: .init without function name\n",
              parser->line_number);
        } else {
          init_function = strdup (token[1]);
        }
      } else if (strcmp (token[0], ".flags") == 0) {
        int i;
        for(i=1;i<n_tokens;i++){
          if (!strcmp (token[i], "2d")) {
            orc_program_set_2d (parser->program);
          }
        }
      } else if (strcmp (token[0], ".n") == 0) {
        int i;
        for(i=1;i<n_tokens;i++){
          if (strcmp (token[i], "mult") == 0) {
            if (i == n_tokens - 1) {
              orc_parse_log (parser, "error: line %d: .n mult requires multiple value\n",
                  parser->line_number);
            } else {
              orc_program_set_n_multiple (parser->program,
                  strtol (token[1], NULL, 0));
              i++;
            }
          } else if (strcmp (token[i], "min") == 0) {
            if (i == n_tokens - 1) {
              orc_parse_log (parser, "error: line %d: .n min requires multiple value\n",
                  parser->line_number);
            } else {
              orc_program_set_n_minimum (parser->program,
                  strtol (token[1], NULL, 0));
              i++;
            }
          } else if (strcmp (token[i], "max") == 0) {
            if (i == n_tokens - 1) {
              orc_parse_log (parser, "error: line %d: .n max requires multiple value\n",
                  parser->line_number);
            } else {
              orc_program_set_n_maximum (parser->program,
                  strtol (token[1], NULL, 0));
              i++;
            }
          } else if (i == n_tokens - 1) {
            orc_program_set_constant_n (parser->program,
                strtol (token[1], NULL, 0));
          } else {
            orc_parse_log (parser, "error: line %d: unknown .n token '%s'\n",
                parser->line_number, token[i]);
          }
        }
      } else if (strcmp (token[0], ".m") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_set_constant_m (parser->program, size);
      } else if (strcmp (token[0], ".source") == 0) {
        int size = strtol (token[1], NULL, 0);
        int var;
        int i;
        var = orc_program_add_source (parser->program, size, token[2]);
        for(i=3;i<n_tokens;i++){
          if (strcmp (token[i], "align") == 0) {
            if (i == n_tokens - 1) {
              orc_parse_log (parser, "error: line %d: .source align requires alignment value\n",
                  parser->line_number);
            } else {
              int alignment = strtol (token[i+1], NULL, 0);
              orc_program_set_var_alignment (parser->program, var, alignment);
              i++;
            }
          } else if (i == n_tokens - 1) {
            orc_program_set_type_name (parser->program, var, token[i]);
          } else {
            orc_parse_log (parser, "error: line %d: unknown .dest token '%s'\n",
                parser->line_number, token[i]);
          }
        }
      } else if (strcmp (token[0], ".dest") == 0) {
        int size = strtol (token[1], NULL, 0);
        int var;
        int i;
        var = orc_program_add_destination (parser->program, size, token[2]);
        for(i=3;i<n_tokens;i++){
          if (strcmp (token[i], "align") == 0) {
            if (i == n_tokens - 1) {
              orc_parse_log (parser, "error: line %d: .source align requires alignment value\n",
                  parser->line_number);
            } else {
              int alignment = strtol (token[i+1], NULL, 0);
              orc_program_set_var_alignment (parser->program, var, alignment);
              i++;
            }
          } else if (i == n_tokens - 1) {
            orc_program_set_type_name (parser->program, var, token[i]);
          } else {
            orc_parse_log (parser, "error: line %d: unknown .source token '%s'\n",
                parser->line_number, token[i]);
          }
        }
      } else if (strcmp (token[0], ".accumulator") == 0) {
        int size = strtol (token[1], NULL, 0);
        int var;
        var = orc_program_add_accumulator (parser->program, size, token[2]);
        if (n_tokens > 3) {
          orc_program_set_type_name (parser->program, var, token[3]);
        }
      } else if (strcmp (token[0], ".temp") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_temporary (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".param") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".longparam") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter_int64 (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".const") == 0) {
        int size = strtol (token[1], NULL, 0);

        orc_program_add_constant_str (parser->program, size, token[3], token[2]);
      } else if (strcmp (token[0], ".floatparam") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter_float (parser->program, size, token[2]);
      } else if (strcmp (token[0], ".doubleparam") == 0) {
        int size = strtol (token[1], NULL, 0);
        orc_program_add_parameter_double (parser->program, size, token[2]);
      } else {
        orc_parse_log (parser, "error: line %d: unknown directive: %s\n",
            parser->line_number, token[0]);
      }
    } else {
      OrcStaticOpcode *o;
      unsigned int flags = 0;
      int offset = 0;

      if (strcmp (token[0], "x4") == 0) {
        flags |= ORC_INSTRUCTION_FLAG_X4;
        offset = 1;
      } else if (strcmp (token[0], "x2") == 0) {
        flags |= ORC_INSTRUCTION_FLAG_X2;
        offset = 1;
      }

      o = get_opcode (parser, token[offset]);

      if (o) {
        int n_args = opcode_n_args (o);
        int i, j;
        char *args[4] = { NULL };

        if (n_tokens != 1 + offset + n_args) {
          orc_parse_log (parser, "error: line %d: too %s arguments for %s (expected %d)\n",
              parser->line_number, (n_tokens < 1+offset+n_args) ? "few" : "many",
              token[offset], n_args);
        }

        for(i=offset+1,j=0;i<n_tokens;i++,j++){
          char *end;
          double unused ORC_GNUC_UNUSED;
          char varname[80];

          args[j] = token[i];

          unused = strtod (token[i], &end);
          if (end != token[i]) {
            int id;

            /* make a unique name based on value and size */
            snprintf (varname, sizeof (varname), "_%d.%s", opcode_arg_size(o, j), token[i]);
            id = orc_program_add_constant_str (parser->program, opcode_arg_size(o, j),
                token[i], varname);
            /* it's possible we reused an existing variable, get its name so
             * that we can refer to it in the opcode */
            args[j] = parser->program->vars[id].name;
          }
        }

        orc_program_append_str_2 (parser->program, token[offset], flags,
              args[0], args[1], args[2], args[3]);
      } else {
        orc_parse_log (parser, "error: line %d: unknown opcode: %s\n",
            parser->line_number,
            token[offset]);
      }
    }
  }

  if (parser->program) {
    orc_parse_sanity_check (parser, parser->program);
  }

  if (parser->line) free (parser->line);

  if (log) {
    *log = parser->log;
  } else {
    free (parser->log);
  }
  if (parser->programs && parser->programs[0]) {
    parser->programs[0]->init_function = init_function;
  } else {
    free (init_function);
  }
  *programs = parser->programs;
  return parser->n_programs;
}
Example #15
0
static void
schro_motion_init_functions (SchroMotion * motion)
{
  if (motion_funcs[motion->xblen >> 1].block_accumulate == NULL) {
    OrcProgram *p;
    OrcCompileResult result;

    p = orc_program_new ();
    orc_program_set_constant_n (p, motion->xblen);
    orc_program_set_2d (p);
    orc_program_set_name (p, "block_acc_Xxn");

    orc_program_add_destination (p, 2, "d1");
    orc_program_add_source (p, 2, "s1");
    orc_program_add_source (p, 1, "s2");
    orc_program_add_temporary (p, 2, "t1");

    orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S2, ORC_VAR_D1);
    orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_S1);
    orc_program_append (p, "addw", ORC_VAR_D1, ORC_VAR_D1, ORC_VAR_T1);

    result = orc_program_compile (p);
    if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (result)) {
      SCHRO_ERROR ("compile failed");
    }

    motion_funcs[motion->xblen / 2].block_accumulate = p;
  }

  if (motion_funcs[motion->xblen >> 1].block_accumulate_scaled == NULL) {
    OrcProgram *p;
    OrcCompileResult result;

    p = orc_program_new ();
    orc_program_set_constant_n (p, motion->xblen);
    orc_program_set_2d (p);
    orc_program_set_name (p, "block_acc_scaled_Xxn");

    orc_program_add_destination (p, 2, "d1");
    orc_program_add_source (p, 2, "s1");
    orc_program_add_source (p, 1, "s2");
    orc_program_add_parameter (p, 2, "p1");
    orc_program_add_constant (p, 2, 32, "c1");
    orc_program_add_constant (p, 2, 6, "c2");
    orc_program_add_temporary (p, 2, "t1");

    orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S2, ORC_VAR_D1);
    orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P1);
    orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1);
    orc_program_append (p, "shrsw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C2);
    orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_S1);
    orc_program_append (p, "addw", ORC_VAR_D1, ORC_VAR_D1, ORC_VAR_T1);

    result = orc_program_compile (p);
    if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (result)) {
      SCHRO_ERROR ("compile failed");
    }

    motion_funcs[motion->xblen / 2].block_accumulate_scaled = p;
  }

  if (motion_funcs[motion->xblen >> 1].block_accumulate_dc == NULL) {
    OrcProgram *p;
    OrcCompileResult result;

    p = orc_program_new ();
    orc_program_set_constant_n (p, motion->xblen);
    orc_program_set_2d (p);
    orc_program_set_name (p, "block_acc_dc_Xxn");

    orc_program_add_destination (p, 2, "d1");
    orc_program_add_source (p, 2, "s1");
    orc_program_add_parameter (p, 2, "p1");
    orc_program_add_temporary (p, 2, "t1");

    orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_P1);
    orc_program_append (p, "addw", ORC_VAR_D1, ORC_VAR_D1, ORC_VAR_T1);

    result = orc_program_compile (p);
    if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (result)) {
      SCHRO_ERROR ("compile failed");
    }

    motion_funcs[motion->xblen / 2].block_accumulate_dc = p;
  }

  if (motion_funcs[motion->xblen >> 1].block_accumulate_avg == NULL) {
    OrcProgram *p;
    OrcCompileResult result;

    p = orc_program_new ();
    orc_program_set_constant_n (p, motion->xblen);
    orc_program_set_2d (p);
    orc_program_set_name (p, "block_acc_avg_Xxn");

    orc_program_add_destination (p, 2, "d1");
    orc_program_add_source (p, 2, "s1");
    orc_program_add_source (p, 1, "s2");
    orc_program_add_source (p, 1, "s3");
    orc_program_add_temporary (p, 2, "t1");
    orc_program_add_temporary (p, 1, "t2");

    orc_program_append (p, "avgub", ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_S3);
    orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_T2, 0);
    orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_S1);
    orc_program_append (p, "addw", ORC_VAR_D1, ORC_VAR_D1, ORC_VAR_T1);

    result = orc_program_compile (p);
    if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (result)) {
      SCHRO_ERROR ("compile failed");
    }

    motion_funcs[motion->xblen / 2].block_accumulate_avg = p;
  }

  if (motion_funcs[motion->xblen >> 1].block_accumulate_biref == NULL) {
    OrcProgram *p;
    OrcCompileResult result;

    p = orc_program_new ();
    orc_program_set_constant_n (p, motion->xblen);
    orc_program_set_2d (p);
    orc_program_set_name (p, "block_acc_biref_Xxn");

    orc_program_add_destination (p, 2, "d1");
    orc_program_add_source (p, 2, "s1");
    orc_program_add_source (p, 1, "s2");
    orc_program_add_source (p, 1, "s3");
    orc_program_add_parameter (p, 2, "p1");
    orc_program_add_parameter (p, 2, "p2");
    orc_program_add_constant (p, 2, 32, "c1");
    orc_program_add_constant (p, 2, 6, "c2");
    orc_program_add_temporary (p, 2, "t1");
    orc_program_add_temporary (p, 2, "t2");

    orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S2, 0);
    orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P1);
    orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S3, 0);
    orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P2);
    orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
    orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1);
    orc_program_append (p, "shrsw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C2);
    orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_S1);
    orc_program_append (p, "addw", ORC_VAR_D1, ORC_VAR_D1, ORC_VAR_T1);

    result = orc_program_compile (p);
    if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (result)) {
      SCHRO_ERROR ("compile failed");
    }

    motion_funcs[motion->xblen / 2].block_accumulate_biref = p;
  }
}