示例#1
0
文件: orccompiler.c 项目: ares89/vlc
int
orc_compiler_get_temp_constant (OrcCompiler *compiler, int size, int value)
{
  int tmp;

  tmp = orc_compiler_get_temp_reg (compiler);
  orc_compiler_load_constant (compiler, tmp, size, value);
  return tmp;
}
示例#2
0
static void
powerpc_rule_div255w (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int dest = ORC_DEST_ARG (p, insn, 0);
  int tmp = orc_compiler_get_temp_reg (p);
  int tmp2 = orc_compiler_get_temp_reg (p);
  int tmpc;

  tmpc = powerpc_get_constant (p, ORC_CONST_SPLAT_W, 0x0080);
  powerpc_emit_VX_2 (p, "vadduhm", 0x10000040, dest, src1, tmpc);

  ORC_ASM_CODE(p,"  vspltish %s, 8\n", powerpc_get_regname(tmp2));
  powerpc_emit_VX(p, 0x1000034c, powerpc_regnum(tmp2), 8, 0);

  powerpc_emit_VX_2 (p, "vsrh", 0x10000244, tmp, dest, tmp2);
  powerpc_emit_VX_2 (p, "vadduhm", 0x10000040, dest, dest, tmp);
  powerpc_emit_VX_2 (p, "vsrh", 0x10000244, dest, dest, tmp2);
}
示例#3
0
static void
powerpc_rule_divf (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int src2 = ORC_SRC_ARG (p, insn, 1);
  int dest = ORC_DEST_ARG (p, insn, 0);
  int y = orc_compiler_get_temp_reg (p);
  int t = orc_compiler_get_temp_reg (p);
  int c1;
  int c0;

  c1 = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 0x3f800000); /* 1.0 */

  powerpc_emit_VX_db (p, "vrefp", 0x1000010a, y, src2);

  powerpc_emit_VA_acb (p, "vnmsubfp", 0x1000002f, t, y, c1, src2);
  powerpc_emit_VA_acb (p, "vmaddfp", 0x1000002e, y, y, y, t);

  c0 = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 0x00000000); /* 0.0 */
  powerpc_emit_VA_acb (p, "vmaddfp", 0x1000002e, dest, y, c0, src1);
}
示例#4
0
static void
powerpc_rule_loadX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
  OrcVariable *src = compiler->vars + insn->src_args[0];
  OrcVariable *dest = compiler->vars + insn->dest_args[0];
  int size = src->size << compiler->loop_shift;
  int perm = orc_compiler_get_temp_reg (compiler);

  switch (size) {
    case 1:
      ORC_ASM_CODE(compiler,"  lvebx %s, 0, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c00000e, powerpc_regnum(dest->alloc),
          0, powerpc_regnum(src->ptr_register));
      break;
    case 2:
      ORC_ASM_CODE(compiler,"  lvehx %s, 0, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c00004e, powerpc_regnum(dest->alloc),
          0, powerpc_regnum(src->ptr_register));
      break;
    case 4:
      ORC_ASM_CODE(compiler,"  lvewx %s, 0, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c00008e, powerpc_regnum(dest->alloc),
          0, powerpc_regnum(src->ptr_register));
      break;
    case 8:
    case 16:
      ORC_ASM_CODE(compiler,"  lvx %s, 0, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c0000ce, powerpc_regnum(dest->alloc),
          0, powerpc_regnum(src->ptr_register));
      break;
    default:
      ORC_COMPILER_ERROR(compiler,"bad load size %d",
          src->size << compiler->loop_shift);
      break;
  }
  ORC_ASM_CODE(compiler,"  lvsl %s, 0, %s\n",
      powerpc_get_regname (perm),
      powerpc_get_regname (src->ptr_register));
  powerpc_emit_X (compiler, 0x7c00000c, powerpc_regnum(perm),
      0, powerpc_regnum(src->ptr_register));
  powerpc_emit_vperm (compiler, dest->alloc, dest->alloc, dest->alloc, perm);
}
示例#5
0
static void
powerpc_rule_convslq (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int dest = ORC_DEST_ARG (p, insn, 0);
  int perm;
  int tmp = orc_compiler_get_temp_reg (p);

  ORC_ASM_CODE(p,"  vspltisb %s, -1\n", powerpc_get_regname(tmp));
  powerpc_emit_VX(p, 0x1000030c, powerpc_regnum(tmp), 0x1f, 0);

  powerpc_emit_VX_2 (p, "vsraw", 0x10000384, tmp, src1, tmp);

  perm = powerpc_get_constant_full (p, 0x10101010, 0x00010203,
      0x10101010, 0x04050607);
  powerpc_emit_vperm (p, dest, src1, tmp, perm);
}
示例#6
0
static void
powerpc_rule_absl (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int tmp;
  int tmpc;
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int dest = ORC_DEST_ARG (p, insn, 0);

  tmpc = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 0);
  if (src1 != dest) {
    tmp = dest;
  } else {
    tmp = orc_compiler_get_temp_reg (p);
  }
  powerpc_emit_VX_2 (p, "vsubuwm", 0x10000480, tmp, tmpc, src1);
  powerpc_emit_VX_2 (p, "vminuw", 0x10000282, dest, tmp, src1);
}
示例#7
0
static void
powerpc_rule_convfl (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int dest = ORC_DEST_ARG (p, insn, 0);
  int tmp = orc_compiler_get_temp_reg (p);
  int tmpc;
  int tmpc2;

  if (p->target_flags & ORC_TARGET_FAST_NAN) {
    powerpc_emit_VX_dbi (p, "vctsxs", 0x100003ca, dest, src1, 0);
  } else {
    /* This changes NANs into infinities of the same sign */
    tmpc = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 0x7f800000);
    tmpc2 = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 0x007fffff);
    powerpc_emit_VX_2 (p, "vand", 0x10000404, tmp, tmpc, src1);
    powerpc_emit_VX_2 (p, "vcmpequw", 0x10000086, tmp, tmp, tmpc);
    powerpc_emit_VX_2 (p, "vand", 0x10000404, tmp, tmp, tmpc2);
    powerpc_emit_vandc (p, tmp, src1, tmp);
    powerpc_emit_VX_dbi (p, "vctsxs", 0x100003ca, dest, tmp, 0);
  }
}
示例#8
0
文件: orccompiler.c 项目: ares89/vlc
int
orc_compiler_get_constant (OrcCompiler *compiler, int size, int value)
{
  int i;
  int tmp;

  if (size < 4) {
    if (size < 2) {
      value &= 0xff;
      value |= (value<<8);
    }
    value &= 0xffff;
    value |= (value<<16);
  }

  for(i=0;i<compiler->n_constants;i++){
    if (compiler->constants[i].is_long == FALSE &&
        compiler->constants[i].value == value) {
      break;
    }
  }
  if (i == compiler->n_constants) {
    compiler->n_constants++;
    compiler->constants[i].value = value;
    compiler->constants[i].alloc_reg = 0;
    compiler->constants[i].use_count = 0;
    compiler->constants[i].is_long = FALSE;
  }

  compiler->constants[i].use_count++;

  if (compiler->constants[i].alloc_reg != 0) {;
    return compiler->constants[i].alloc_reg;
  }
  tmp = orc_compiler_get_temp_reg (compiler);
  orc_compiler_load_constant (compiler, tmp, size, value);
  return tmp;
}
示例#9
0
文件: orccompiler.c 项目: ares89/vlc
int
orc_compiler_get_constant_long (OrcCompiler *compiler,
    orc_uint32 a, orc_uint32 b, orc_uint32 c, orc_uint32 d)
{
  int i;
  int tmp;

  for(i=0;i<compiler->n_constants;i++){
    if (compiler->constants[i].is_long == TRUE &&
        compiler->constants[i].full_value[0] == a &&
        compiler->constants[i].full_value[1] == b &&
        compiler->constants[i].full_value[2] == c &&
        compiler->constants[i].full_value[3] == d) {
      break;
    }
  }
  if (i == compiler->n_constants) {
    compiler->n_constants++;
    compiler->constants[i].full_value[0] = a;
    compiler->constants[i].full_value[1] = b;
    compiler->constants[i].full_value[2] = c;
    compiler->constants[i].full_value[3] = d;
    compiler->constants[i].is_long = TRUE;
    compiler->constants[i].alloc_reg = 0;
    compiler->constants[i].use_count = 0;
  }

  compiler->constants[i].use_count++;

  if (compiler->constants[i].alloc_reg != 0) {;
    return compiler->constants[i].alloc_reg;
  }
  tmp = orc_compiler_get_temp_reg (compiler);
  orc_compiler_load_constant_long (compiler, tmp, &compiler->constants[i]);
  return tmp;
}
示例#10
0
static void
powerpc_rule_storeX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
  OrcVariable *src = compiler->vars + insn->src_args[0];
  OrcVariable *dest = compiler->vars + insn->dest_args[0];
  int size = dest->size << compiler->loop_shift;
  int perm = orc_compiler_get_temp_reg (compiler);
  int tmp = orc_compiler_get_temp_reg (compiler);

  ORC_ASM_CODE(compiler,"  lvsr %s, 0, %s\n",
      powerpc_get_regname (perm),
      powerpc_get_regname (dest->ptr_register));
  powerpc_emit_X (compiler, 0x7c00004c, powerpc_regnum(perm),
      0, powerpc_regnum(dest->ptr_register));

  powerpc_emit_vperm (compiler, tmp, src->alloc, src->alloc, perm);

  switch (size) {
    case 1:
      ORC_ASM_CODE(compiler,"  stvebx %s, 0, %s\n",
          powerpc_get_regname (tmp),
          powerpc_get_regname (dest->ptr_register));
      powerpc_emit_X (compiler, 0x7c00010e,
          powerpc_regnum(tmp),
          0, powerpc_regnum(dest->ptr_register));
      break;
    case 2:
      ORC_ASM_CODE(compiler,"  stvehx %s, 0, %s\n",
          powerpc_get_regname (tmp),
          powerpc_get_regname (dest->ptr_register));
      powerpc_emit_X (compiler, 0x7c00014e,
          powerpc_regnum(tmp),
          0, powerpc_regnum(dest->ptr_register));
      break;
    case 4:
      ORC_ASM_CODE(compiler,"  stvewx %s, 0, %s\n",
          powerpc_get_regname (tmp),
          powerpc_get_regname (dest->ptr_register));
      powerpc_emit_X (compiler, 0x7c00018e,
          powerpc_regnum(tmp),
          0, powerpc_regnum(dest->ptr_register));
      break;
    case 8:
      ORC_ASM_CODE(compiler,"  stvewx %s, 0, %s\n",
          powerpc_get_regname (tmp),
          powerpc_get_regname (dest->ptr_register));
      powerpc_emit_X (compiler, 0x7c00018e,
          powerpc_regnum(tmp),
          0, powerpc_regnum(dest->ptr_register));

      powerpc_emit_D (compiler, "addi", 0x38000000, compiler->gp_tmpreg,
          POWERPC_R0, 4);

      ORC_ASM_CODE(compiler,"  stvewx %s, %s, %s\n",
          powerpc_get_regname (tmp),
          powerpc_get_regname (compiler->gp_tmpreg),
          powerpc_get_regname (dest->ptr_register));
      powerpc_emit_X (compiler, 0x7c00018e,
          powerpc_regnum(tmp),
          powerpc_regnum(compiler->gp_tmpreg),
          powerpc_regnum(dest->ptr_register));
      break;
    case 16:
      ORC_ASM_CODE(compiler,"  stvx %s, 0, %s\n",
          powerpc_get_regname (tmp),
          powerpc_get_regname (dest->ptr_register));
      powerpc_emit_X (compiler, 0x7c0001ce,
          powerpc_regnum(tmp),
          0, powerpc_regnum(dest->ptr_register));
      break;
    default:
      ORC_COMPILER_ERROR(compiler,"bad store size %d",
          dest->size << compiler->loop_shift);
      break;
  }
}
示例#11
0
static void
powerpc_rule_loadoffX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
  OrcVariable *src = compiler->vars + insn->src_args[0];
  OrcVariable *dest = compiler->vars + insn->dest_args[0];
  int size = src->size << compiler->loop_shift;
  int perm = orc_compiler_get_temp_reg (compiler);
  int offset;

  if (compiler->vars[insn->src_args[1]].vartype != ORC_VAR_TYPE_CONST) {
    ORC_COMPILER_ERROR(compiler, "Rule only works with consts");
    return;
  }

  offset = compiler->vars[insn->src_args[1]].value.i * src->size;
  powerpc_emit_addi (compiler, compiler->gp_tmpreg, POWERPC_R0, offset);
  switch (size) {
    case 1:
      ORC_ASM_CODE(compiler,"  lvebx %s, %s, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (compiler->gp_tmpreg),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c00000e, powerpc_regnum(dest->alloc),
          powerpc_regnum(compiler->gp_tmpreg),
          powerpc_regnum(src->ptr_register));
      break;
    case 2:
      ORC_ASM_CODE(compiler,"  lvehx %s, %s, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (compiler->gp_tmpreg),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c00004e, powerpc_regnum(dest->alloc),
          powerpc_regnum(compiler->gp_tmpreg),
          powerpc_regnum(src->ptr_register));
      break;
    case 4:
      ORC_ASM_CODE(compiler,"  lvewx %s, %s, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (compiler->gp_tmpreg),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c00008e, powerpc_regnum(dest->alloc),
          powerpc_regnum(compiler->gp_tmpreg),
          powerpc_regnum(src->ptr_register));
      break;
    case 8:
    case 16:
      ORC_ASM_CODE(compiler,"  lvx %s, %s, %s\n",
          powerpc_get_regname (dest->alloc),
          powerpc_get_regname (compiler->gp_tmpreg),
          powerpc_get_regname (src->ptr_register));
      powerpc_emit_X (compiler, 0x7c0000ce, powerpc_regnum(dest->alloc),
          powerpc_regnum(compiler->gp_tmpreg),
          powerpc_regnum(src->ptr_register));
      break;
    default:
      ORC_COMPILER_ERROR(compiler,"bad load size %d",
          src->size << compiler->loop_shift);
      break;
  }
  ORC_ASM_CODE(compiler,"  lvsl %s, %s, %s\n",
      powerpc_get_regname (perm),
      powerpc_get_regname (compiler->gp_tmpreg),
      powerpc_get_regname (src->ptr_register));
  powerpc_emit_X (compiler, 0x7c00000c, powerpc_regnum(perm),
      powerpc_regnum(compiler->gp_tmpreg),
      powerpc_regnum(src->ptr_register));
  powerpc_emit_vperm (compiler, dest->alloc, dest->alloc, dest->alloc, perm);
}