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); }
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; }
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); }
/** * 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; }
/** * 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); }
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 ); }
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 ); }
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; }
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; }
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; }
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; } }