* mini-ops.h: Added OP_INSERT_I2.
* cpu-x86.md: Same.
* mini-x86.c (mono_arch_output_basic_block): Same.
* simd-intrinsics.c: Implement setter for Vector8s.
* simd-methods.h: Add the names of get setters of Vector8s.
svn path=/trunk/mono/; revision=119230
+2008-11-18 Rodrigo Kumpera <rkumpera@novell.com>
+
+ * mini-ops.h: Added OP_INSERT_I2.
+
+ * cpu-x86.md: Same.
+
+ * mini-x86.c (mono_arch_output_basic_block): Same.
+
+ * simd-intrinsics.c: Implement setter for Vector8s.
+
+ * simd-methods.h: Add the names of get setters of Vector8s.
+
2008-11-18 Zoltan Varga <vargaz@gmail.com>
* aot-compiler.c (mono_save_xdebug_info): Add support for parameters.
extract_u2: dest:i src1:x len:10
extract_i1: dest:i src1:x len:10
extract_u1: dest:i src1:x len:10
-extract_r8: dest:f src1:x len:17
+extract_r8: dest:f src1:x len:8
iconv_to_r8_raw: dest:f src1:i len:17
+insert_i2: dest:x src1:x src2:i len:5 clob:1
+
loadx_membase: dest:x src1:b len:7
storex_membase: dest:b src1:x len:7
storex_membase_reg: dest:b src1:x len:7
MINI_OP(OP_EXTRACT_R8, "extract_r8", FREG, XREG, NONE)
MINI_OP(OP_EXTRACT_I8, "extract_i8", IREG, XREG, NONE)
+MINI_OP(OP_INSERT_I2, "insert_i2", XREG, XREG, IREG)
+
MINI_OP(OP_FCONV_TO_R8_X, "fconv_to_r8_x", XREG, FREG, NONE)
MINI_OP(OP_XCONV_R8_TO_I4, "xconv_r8_to_i4", IREG, XREG, NONE)
MINI_OP(OP_ICONV_TO_X, "iconv_to_x", XREG, IREG, NONE)
x86_sse_alu_sd_membase_reg (code, X86_SSE_MOVSD_MEMBASE_REG, ins->backend.spill_var->inst_basereg, ins->backend.spill_var->inst_offset, ins->sreg1);
x86_fld_membase (code, ins->backend.spill_var->inst_basereg, ins->backend.spill_var->inst_offset, TRUE);
break;
-
+
+ case OP_INSERT_I2:
+ x86_sse_alu_pd_reg_reg_imm (code, X86_SSE_PINSRW, ins->sreg1, ins->sreg2, ins->inst_c0);
+ break;
+
case OP_STOREX_MEMBASE_REG:
case OP_STOREX_MEMBASE:
x86_movups_membase_reg (code, ins->dreg, ins->inst_offset, ins->sreg1);
enum {
SIMD_EMIT_BINARY,
SIMD_EMIT_UNARY,
+ SIMD_EMIT_SETTER,
SIMD_EMIT_GETTER,
SIMD_EMIT_GETTER_QWORD,
SIMD_EMIT_CTOR,
{ SN_op_Subtraction, OP_PSUBW, SIMD_EMIT_BINARY },
};
-/*
-Missing:
-setters
- */
static const SimdIntrinsc vector8s_intrinsics[] = {
{ SN_ctor, 0, SIMD_EMIT_CTOR },
{ SN_AddWithSaturation, OP_PADDW_SAT, SIMD_EMIT_BINARY },
{ SN_op_Multiply, OP_PMULW, SIMD_EMIT_BINARY },
{ SN_op_RightShift, OP_PSARW, SIMD_EMIT_SHIFT },
{ SN_op_Subtraction, OP_PSUBW, SIMD_EMIT_BINARY },
+ { SN_set_V0, 0, SIMD_EMIT_SETTER },
+ { SN_set_V1, 1, SIMD_EMIT_SETTER },
+ { SN_set_V2, 2, SIMD_EMIT_SETTER },
+ { SN_set_V3, 3, SIMD_EMIT_SETTER },
+ { SN_set_V4, 4, SIMD_EMIT_SETTER },
+ { SN_set_V5, 5, SIMD_EMIT_SETTER },
+ { SN_set_V6, 6, SIMD_EMIT_SETTER },
+ { SN_set_V7, 7, SIMD_EMIT_SETTER },
};
/*
}
return FALSE;
}
+
/*
This pass recalculate which vars need MONO_INST_INDIRECT.
if (!(vreg_flags [var->dreg] & VREG_SINGLE_BB_USE))
continue;
for (ins = target_bb [var->dreg]->code; ins; ins = ins->next) {
- /*We can, pretty much kill it.*/
- if (ins->dreg == var->dreg) {
+ /*We can avoid inserting the XZERO if the first use doesn't depend on the zero'ed value.*/
+ if (ins->dreg == var->dreg && ins->sreg1 != var->dreg && ins->sreg2 != var->dreg) {
break;
} else if (ins->sreg1 == var->dreg || ins->sreg2 == var->dreg) {
MonoInst *tmp;
}
+static MonoInst*
+simd_intrinsic_emit_setter (const SimdIntrinsc *intrinsic, MonoCompile *cfg, MonoMethod *cmethod, MonoInst **args)
+{
+ MonoInst *ins;
+
+ MONO_INST_NEW (cfg, ins, OP_INSERT_I2);
+ ins->klass = cmethod->klass;
+ /*This is a partial load so we encode the dependency on the previous value by setting dreg and sreg1 to the same value.*/
+ ins->dreg = ins->sreg1 = load_simd_vreg (cfg, cmethod, args [0]);
+ ins->type = STACK_I4;
+ ins->sreg2 = args [1]->dreg;
+ ins->inst_c0 = intrinsic->opcode;
+ MONO_ADD_INS (cfg->cbb, ins);
+
+ return ins;
+}
+
static MonoInst*
simd_intrinsic_emit_getter (const SimdIntrinsc *intrinsic, MonoCompile *cfg, MonoMethod *cmethod, MonoInst **args)
{
return simd_intrinsic_emit_binary (result, cfg, cmethod, args);
case SIMD_EMIT_UNARY:
return simd_intrinsic_emit_unary (result, cfg, cmethod, args);
+ case SIMD_EMIT_SETTER:
+ return simd_intrinsic_emit_setter (result, cfg, cmethod, args);
case SIMD_EMIT_GETTER:
return simd_intrinsic_emit_getter (result, cfg, cmethod, args);
case SIMD_EMIT_GETTER_QWORD:
SIMD_METHOD("get_V13", SN_get_V13)
SIMD_METHOD("get_V14", SN_get_V14)
SIMD_METHOD("get_V15", SN_get_V15)
+SIMD_METHOD("set_W", SN_set_W)
+SIMD_METHOD("set_X", SN_set_X)
+SIMD_METHOD("set_Y", SN_set_Y)
+SIMD_METHOD("set_Z", SN_set_Z)
+SIMD_METHOD("set_V0", SN_set_V0)
+SIMD_METHOD("set_V1", SN_set_V1)
+SIMD_METHOD("set_V2", SN_set_V2)
+SIMD_METHOD("set_V3", SN_set_V3)
+SIMD_METHOD("set_V4", SN_set_V4)
+SIMD_METHOD("set_V5", SN_set_V5)
+SIMD_METHOD("set_V6", SN_set_V6)
+SIMD_METHOD("set_V7", SN_set_V7)
+SIMD_METHOD("set_V8", SN_set_V8)
+SIMD_METHOD("set_V9", SN_set_V9)
+SIMD_METHOD("set_V10", SN_set_V10)
+SIMD_METHOD("set_V11", SN_set_V11)
+SIMD_METHOD("set_V12", SN_set_V12)
+SIMD_METHOD("set_V13", SN_set_V13)
+SIMD_METHOD("set_V14", SN_set_V14)
+SIMD_METHOD("set_V15", SN_set_V15)
SIMD_METHOD("HorizontalAdd", SN_HorizontalAdd)
SIMD_METHOD("HorizontalSub", SN_HorizontalSub)
SIMD_METHOD("InterleaveHigh", SN_InterleaveHigh)