示例#1
0
static void
powerpc_rule_swapl (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int dest = ORC_DEST_ARG (p, insn, 0);
  int perm;

  perm = powerpc_get_constant_full (p, 0x03020100, 0x07060504,
      0x0b0a0908, 0x0f0e0d0c);
  powerpc_emit_vperm (p, dest, src1, src1, perm);
}
示例#2
0
static void
powerpc_rule_mergelq (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 perm;

  perm = powerpc_get_constant_full (p, 0x00010203, 0x10111213,
      0x04050607, 0x14151617);
  powerpc_emit_vperm (p, dest, src1, src2, perm);
}
示例#3
0
static void
powerpc_rule_mergebw (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 perm;

  perm = powerpc_get_constant_full (p, 0x00100111, 0x02120313,
      0x04140515, 0x06160717);
  powerpc_emit_vperm (p, dest, src1, src2, perm);
}
示例#4
0
static void
powerpc_rule_signl (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int reg;
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int dest = ORC_DEST_ARG (p, insn, 0);

  reg = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 1);
  powerpc_emit_vminsw (p, dest, src1, reg);
  reg = powerpc_get_constant (p, ORC_CONST_SPLAT_L, -1);
  powerpc_emit_vmaxsw (p, dest, dest, reg);
}
示例#5
0
static void
powerpc_rule_convulq (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 zero;

  zero = powerpc_get_constant (p, ORC_CONST_SPLAT_B, 0);
  perm = powerpc_get_constant_full (p, 0x10101010, 0x00010203,
      0x10101010, 0x04050607);
  powerpc_emit_vperm (p, dest, src1, zero, perm);
}
示例#6
0
static void
powerpc_rule_splatbl (OrcCompiler *p, void *user, OrcInstruction *insn)
{
  int src1 = ORC_SRC_ARG (p, insn, 0);
  int dest = ORC_DEST_ARG (p, insn, 0);
#if 0
  int perm;

  perm = powerpc_get_constant_full (p, 0x00000000, 0x01010101,
      0x02020202, 0x03030303);
  powerpc_emit_vperm (p, dest, src1, src1, perm);
#else
  powerpc_emit_VX_2 (p, "vmrghb", 0x1000000c, dest, src1, src1);
  powerpc_emit_VX_2 (p, "vmrghh", 0x1000004c, dest, dest, dest);
#endif
}
示例#7
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);
}
示例#8
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);
}
示例#9
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);
}
示例#10
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);
}
示例#11
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);
  }
}
示例#12
0
void
orc_arm_emit_loop (OrcCompiler *compiler)
{
  int j;
  int k;
  OrcInstruction *insn;
  OrcStaticOpcode *opcode;
  OrcRule *rule;

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

    if (insn->flags & ORC_INSN_FLAG_INVARIANT) continue;

    orc_compiler_append_code(compiler,"# %d: %s", j, insn->opcode->name);

    /* set up args */
#if 0
    for(k=0;k<opcode->n_src + opcode->n_dest;k++){
      args[k] = compiler->vars + insn->args[k];
      orc_compiler_append_code(compiler," %d", args[k]->alloc);
      if (args[k]->is_chained) {
        orc_compiler_append_code(compiler," (chained)");
      }
    }
#endif
    orc_compiler_append_code(compiler,"\n");

    for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
      if (opcode->src_size[k] == 0) continue;

      switch (compiler->vars[insn->src_args[k]].vartype) {
        case ORC_VAR_TYPE_SRC:
        case ORC_VAR_TYPE_DEST:
          //orc_arm_emit_load_src (compiler, &compiler->vars[insn->src_args[k]]);
          break;
        case ORC_VAR_TYPE_CONST:
          break;
        case ORC_VAR_TYPE_PARAM:
          break;
        case ORC_VAR_TYPE_TEMP:
          break;
        default:
          break;
      }
    }

    rule = insn->rule;
    if (rule && rule->emit) {
      int src = ORC_SRC_ARG (compiler, insn, 0);
      int dest = ORC_DEST_ARG (compiler, insn, 0);

      if (dest != src) {
        orc_arm_emit_mov_r (compiler, ORC_ARM_COND_AL, 0, dest, src);
      }
      rule->emit (compiler, rule->emit_user, insn);
    } else {
      orc_compiler_append_code(compiler,"No rule for: %s\n", opcode->name);
    }

    for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
      if (opcode->dest_size[k] == 0) continue;

      switch (compiler->vars[insn->dest_args[k]].vartype) {
        case ORC_VAR_TYPE_DEST:
          //orc_arm_emit_store_dest (compiler, &compiler->vars[insn->dest_args[k]]);
          break;
        case ORC_VAR_TYPE_TEMP:
          break;
        default:
          break;
      }
    }
  }

  for(k=0;k<ORC_N_COMPILER_VARIABLES;k++){
    if (compiler->vars[k].name == NULL) continue;
    if (compiler->vars[k].vartype == ORC_VAR_TYPE_SRC ||
        compiler->vars[k].vartype == ORC_VAR_TYPE_DEST) {
      if (compiler->vars[k].ptr_register) {
        orc_arm_emit_add_i (compiler, ORC_ARM_COND_AL, 0,
            compiler->vars[k].ptr_register,
            compiler->vars[k].ptr_register,
            compiler->vars[k].size << compiler->loop_shift);
      } else {
        //orc_arm_emit_add_imm_memoffset (compiler, orc_arm_ptr_size,
        //    compiler->vars[k].size << compiler->loop_shift,
        //    (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k]),
        //    compiler->exec_reg);
      }
    }
  }
}