示例#1
0
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);
}
示例#3
0
文件: orcparse.c 项目: danshapero/orc
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;
}
示例#4
0
文件: orcparse.c 项目: Distrotech/orc
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;
}
示例#5
0
文件: schromotion8.c 项目: ares89/vlc
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;
  }
}