diff options
Diffstat (limited to 'mono/mini/mini-llvm.c')
-rw-r--r-- | mono/mini/mini-llvm.c | 368 |
1 files changed, 0 insertions, 368 deletions
diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 29658abd89d..c29cf857a60 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -3730,11 +3730,6 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder) case LLVMArgVtypeInReg: case LLVMArgVtypeByVal: case LLVMArgAsIArgs: -#ifdef ENABLE_NETCORE - // FIXME: Enabling this fails on windows - case LLVMArgVtypeAddr: - case LLVMArgVtypeByRef: -#endif { if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (ainfo->type))) /* Treat these as normal values */ @@ -6986,11 +6981,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) LLVMValueRef mask [32], v; int i; -#ifdef ENABLE_NETCORE - t = simd_class_to_llvm_type (ctx, ins->klass); -#else t = simd_op_to_llvm_type (ins->opcode); -#endif for (i = 0; i < 32; ++i) mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE); @@ -8794,369 +8785,10 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) } #endif -#ifdef ENABLE_NETCORE - case OP_XCAST: { - LLVMTypeRef t = simd_class_to_llvm_type (ctx, ins->klass); - - values [ins->dreg] = LLVMBuildBitCast (builder, lhs, t, ""); - break; - } - case OP_XCOMPARE_FP: { - LLVMRealPredicate pred = fpcond_to_llvm_cond [ins->inst_c0]; - LLVMValueRef cmp = LLVMBuildFCmp (builder, pred, lhs, rhs, ""); - int nelems = LLVMGetVectorSize (LLVMTypeOf (cmp)); - g_assert (LLVMTypeOf (lhs) == LLVMTypeOf (rhs)); - if (ins->inst_c1 == MONO_TYPE_R8) - values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), nelems), ""), LLVMTypeOf (lhs), ""); - else - values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), nelems), ""), LLVMTypeOf (lhs), ""); - break; - } - case OP_XCOMPARE: { - LLVMIntPredicate pred = cond_to_llvm_cond [ins->inst_c0]; - LLVMValueRef cmp = LLVMBuildICmp (builder, pred, lhs, rhs, ""); - g_assert (LLVMTypeOf (lhs) == LLVMTypeOf (rhs)); - values [ins->dreg] = LLVMBuildSExt (builder, cmp, LLVMTypeOf (lhs), ""); - break; - } - case OP_XEQUAL: { - LLVMTypeRef t; - LLVMValueRef cmp, mask [32], shuffle; - int nelems; - -#if defined(TARGET_WASM) && LLVM_API_VERSION >= 800 - /* The wasm code generator doesn't understand the shuffle/and code sequence below */ - LLVMValueRef val; - if (LLVMIsNull (lhs) || LLVMIsNull (rhs)) { - val = LLVMIsNull (lhs) ? rhs : lhs; - nelems = LLVMGetVectorSize (LLVMTypeOf (lhs)); - - IntrinsicId intrins = (IntrinsicId)0; - switch (nelems) { - case 16: - intrins = INTRINS_WASM_ANYTRUE_V16; - break; - case 8: - intrins = INTRINS_WASM_ANYTRUE_V8; - break; - case 4: - intrins = INTRINS_WASM_ANYTRUE_V4; - break; - case 2: - intrins = INTRINS_WASM_ANYTRUE_V2; - break; - default: - g_assert_not_reached (); - } - /* res = !wasm.anytrue (val) */ - values [ins->dreg] = call_intrins (ctx, intrins, &val, ""); - values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, values [ins->dreg], LLVMConstInt (LLVMInt32Type (), 0, FALSE), ""), LLVMInt32Type (), dname); - break; - } -#endif - LLVMTypeRef srcelemt = LLVMGetElementType (LLVMTypeOf (lhs)); - - //%c = icmp sgt <16 x i8> %a0, %a1 - if (srcelemt == LLVMDoubleType () || srcelemt == LLVMFloatType ()) - cmp = LLVMBuildFCmp (builder, LLVMRealOEQ, lhs, rhs, ""); - else - cmp = LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""); - nelems = LLVMGetVectorSize (LLVMTypeOf (cmp)); - - LLVMTypeRef elemt; - if (srcelemt == LLVMDoubleType ()) - elemt = LLVMInt64Type (); - else if (srcelemt == LLVMFloatType ()) - elemt = LLVMInt32Type (); - else - elemt = srcelemt; - - t = LLVMVectorType (elemt, nelems); - cmp = LLVMBuildSExt (builder, cmp, t, ""); - // cmp is a <nelems x elemt> vector, each element is either 0xff... or 0 - int half = nelems / 2; - while (half >= 1) { - // AND the top and bottom halfes into the bottom half - for (int i = 0; i < half; ++i) - mask [i] = LLVMConstInt (LLVMInt32Type (), half + i, FALSE); - for (int i = half; i < nelems; ++i) - mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE); - shuffle = LLVMBuildShuffleVector (builder, cmp, LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), ""); - cmp = LLVMBuildAnd (builder, cmp, shuffle, ""); - half = half / 2; - } - // Extract [0] - LLVMValueRef first_elem = LLVMBuildExtractElement (builder, cmp, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ""); - // convert to 0/1 - LLVMValueRef cmp_zero = LLVMBuildICmp (builder, LLVMIntNE, first_elem, LLVMConstInt (elemt, 0, FALSE), ""); - values [ins->dreg] = LLVMBuildZExt (builder, cmp_zero, LLVMInt8Type (), ""); - break; - } - case OP_XBINOP: { - switch (ins->inst_c0) { - case OP_IADD: - values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, ""); - break; - case OP_ISUB: - values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, ""); - break; - case OP_IAND: - values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, ""); - break; - case OP_IOR: - values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, ""); - break; - case OP_IXOR: - values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, ""); - break; - case OP_FADD: - values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, ""); - break; - case OP_FSUB: - values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, ""); - break; - case OP_FMUL: - values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, ""); - break; - case OP_FDIV: - values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, ""); - break; - case OP_FMAX: - case OP_FMIN: { -#if defined(TARGET_X86) || defined(TARGET_AMD64) - LLVMValueRef args [] = { lhs, rhs }; - - gboolean is_r4 = ins->inst_c1 == MONO_TYPE_R4; - if (ins->inst_c0 == OP_FMAX) - values [ins->dreg] = call_intrins (ctx, is_r4 ? INTRINS_SSE_MAXPS : INTRINS_SSE_MAXPD, args, dname); - else - values [ins->dreg] = call_intrins (ctx, is_r4 ? INTRINS_SSE_MINPS : INTRINS_SSE_MINPD, args, dname); -#else - NOT_IMPLEMENTED; -#endif - break; - } - case OP_IMAX: { - gboolean is_unsigned = ins->inst_c1 == MONO_TYPE_U1 || ins->inst_c1 == MONO_TYPE_U2 || ins->inst_c1 == MONO_TYPE_U4 || ins->inst_c1 == MONO_TYPE_U8; - LLVMValueRef cmp = LLVMBuildICmp (builder, is_unsigned ? LLVMIntUGT : LLVMIntSGT, lhs, rhs, ""); - values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, ""); - break; - } - case OP_IMIN: { - gboolean is_unsigned = ins->inst_c1 == MONO_TYPE_U1 || ins->inst_c1 == MONO_TYPE_U2 || ins->inst_c1 == MONO_TYPE_U4 || ins->inst_c1 == MONO_TYPE_U8; - LLVMValueRef cmp = LLVMBuildICmp (builder, is_unsigned ? LLVMIntULT : LLVMIntSLT, lhs, rhs, ""); - values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, ""); - } - break; - - default: - g_assert_not_reached (); - } - break; - } - case OP_XEXTRACT_I32: - case OP_XEXTRACT_I64: - case OP_XEXTRACT_R8: - case OP_XEXTRACT_R4: { - LLVMTypeRef rhst = LLVMTypeOf (rhs); - LLVMValueRef mask = NULL; - switch (ins->opcode) { - case OP_XEXTRACT_I32: case OP_XEXTRACT_R4: - mask = LLVMConstInt (rhst, 0x3, FALSE); break; - case OP_XEXTRACT_I64: case OP_XEXTRACT_R8: - mask = LLVMConstInt (rhst, 0x1, FALSE); break; - default: - g_assert_not_reached (); - } - LLVMValueRef selector = LLVMBuildAnd (builder, rhs, mask, ""); - values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, selector, ""); - break; - } - case OP_POPCNT32: - values [ins->dreg] = call_intrins (ctx, INTRINS_CTPOP_I32, &lhs, ""); - break; - case OP_POPCNT64: - values [ins->dreg] = call_intrins (ctx, INTRINS_CTPOP_I64, &lhs, ""); - break; - case OP_CTTZ32: - case OP_CTTZ64: { - LLVMValueRef args [2]; - args [0] = lhs; - args [1] = LLVMConstInt (LLVMInt1Type (), 0, FALSE); - values [ins->dreg] = call_intrins (ctx, ins->opcode == OP_CTTZ32 ? INTRINS_CTTZ_I32 : INTRINS_CTTZ_I64, args, ""); - break; - } - case OP_BEXTR32: - case OP_BEXTR64: { - LLVMValueRef args [2]; - args [0] = lhs; - args [1] = convert (ctx, rhs, ins->opcode == OP_BEXTR32 ? LLVMInt32Type () : LLVMInt64Type ()); // cast ushort to u32/u64 - values [ins->dreg] = call_intrins (ctx, ins->opcode == OP_BEXTR32 ? INTRINS_BEXTR_I32 : INTRINS_BEXTR_I64, args, ""); - break; - } - case OP_BZHI32: - case OP_BZHI64: { - LLVMValueRef args [2]; - args [0] = lhs; - args [1] = rhs; - values [ins->dreg] = call_intrins (ctx, ins->opcode == OP_BZHI32 ? INTRINS_BZHI_I32 : INTRINS_BZHI_I64, args, ""); - break; - } - case OP_MULX_H32: - case OP_MULX_H64: - case OP_MULX_HL32: - case OP_MULX_HL64: { - gboolean is_64 = ins->opcode == OP_MULX_H64 || ins->opcode == OP_MULX_HL64; - gboolean only_high = ins->opcode == OP_MULX_H32 || ins->opcode == OP_MULX_H64; - LLVMValueRef lx = LLVMBuildZExt (ctx->builder, lhs, LLVMInt128Type (), ""); - LLVMValueRef rx = LLVMBuildZExt (ctx->builder, rhs, LLVMInt128Type (), ""); - LLVMValueRef mulx = LLVMBuildMul (ctx->builder, lx, rx, ""); - if (!only_high) { - LLVMValueRef lowx = LLVMBuildTrunc (ctx->builder, mulx, is_64 ? LLVMInt64Type () : LLVMInt32Type (), ""); - LLVMBuildStore (ctx->builder, lowx, values [ins->sreg3]); - } - LLVMValueRef shift = LLVMConstInt (LLVMInt128Type (), is_64 ? 64 : 32, FALSE); - LLVMValueRef highx = LLVMBuildLShr (ctx->builder, mulx, shift, ""); - values [ins->dreg] = LLVMBuildTrunc (ctx->builder, highx, is_64 ? LLVMInt64Type () : LLVMInt32Type (), ""); - break; - } - case OP_PEXT32: - case OP_PEXT64: { - LLVMValueRef args [2]; - args [0] = lhs; - args [1] = rhs; - values [ins->dreg] = call_intrins (ctx, ins->opcode == OP_PEXT32 ? INTRINS_PEXT_I32 : INTRINS_PEXT_I64, args, ""); - break; - } - case OP_PDEP32: - case OP_PDEP64: { - LLVMValueRef args [2]; - args [0] = lhs; - args [1] = rhs; - values [ins->dreg] = call_intrins (ctx, ins->opcode == OP_PDEP32 ? INTRINS_PDEP_I32 : INTRINS_PDEP_I64, args, ""); - break; - } -#endif /* ENABLE_NETCORE */ #endif /* defined(TARGET_X86) || defined(TARGET_AMD64) */ // Shared between ARM64 and X86 -#if defined(ENABLE_NETCORE) && (defined(TARGET_ARM64) || defined(TARGET_X86) || defined(TARGET_AMD64)) - case OP_LZCNT32: - case OP_LZCNT64: { - LLVMValueRef args [2]; - args [0] = lhs; - args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE); - values [ins->dreg] = LLVMBuildCall (builder, get_intrins (ctx, ins->opcode == OP_LZCNT32 ? INTRINS_CTLZ_I32 : INTRINS_CTLZ_I64), args, 2, ""); - break; - } -#endif - -#if defined(ENABLE_NETCORE) && defined(TARGET_ARM64) - case OP_XOP_I4_I4: - case OP_XOP_I8_I8: { - IntrinsicId id = (IntrinsicId)0; - switch (ins->inst_c0) { - case SIMD_OP_ARM64_RBIT32: id = INTRINS_BITREVERSE_I32; break; - case SIMD_OP_ARM64_RBIT64: id = INTRINS_BITREVERSE_I64; break; - default: g_assert_not_reached (); break; - } - values [ins->dreg] = call_intrins (ctx, id, &lhs, ""); - break; - } - case OP_XOP_X_X_X: - case OP_XOP_I4_I4_I4: - case OP_XOP_I4_I4_I8: { - IntrinsicId id = (IntrinsicId)0; - gboolean zext_last = FALSE; - switch (ins->inst_c0) { - case SIMD_OP_ARM64_CRC32B: id = INTRINS_AARCH64_CRC32B; zext_last = TRUE; break; - case SIMD_OP_ARM64_CRC32H: id = INTRINS_AARCH64_CRC32H; zext_last = TRUE; break; - case SIMD_OP_ARM64_CRC32W: id = INTRINS_AARCH64_CRC32W; zext_last = TRUE; break; - case SIMD_OP_ARM64_CRC32X: id = INTRINS_AARCH64_CRC32X; break; - case SIMD_OP_ARM64_CRC32CB: id = INTRINS_AARCH64_CRC32CB; zext_last = TRUE; break; - case SIMD_OP_ARM64_CRC32CH: id = INTRINS_AARCH64_CRC32CH; zext_last = TRUE; break; - case SIMD_OP_ARM64_CRC32CW: id = INTRINS_AARCH64_CRC32CW; zext_last = TRUE; break; - case SIMD_OP_ARM64_CRC32CX: id = INTRINS_AARCH64_CRC32CX; break; - case SIMD_OP_ARM64_SHA1SU1: id = INTRINS_AARCH64_SHA1SU1; break; - case SIMD_OP_ARM64_SHA256SU0: id = INTRINS_AARCH64_SHA256SU0; break; - default: g_assert_not_reached (); break; - } - LLVMValueRef arg1 = rhs; - if (zext_last) - arg1 = LLVMBuildZExt (ctx->builder, arg1, LLVMInt32Type (), ""); - LLVMValueRef args [] = { lhs, arg1 }; - values [ins->dreg] = call_intrins (ctx, id, args, ""); - break; - } - case OP_XOP_X_X_X_X: { - IntrinsicId id = (IntrinsicId)0; - switch (ins->inst_c0) { - case SIMD_OP_ARM64_SHA1SU0: id = INTRINS_AARCH64_SHA1SU0; break; - case SIMD_OP_ARM64_SHA256H: id = INTRINS_AARCH64_SHA256H; break; - case SIMD_OP_ARM64_SHA256H2: id = INTRINS_AARCH64_SHA256H2; break; - case SIMD_OP_ARM64_SHA256SU1: id = INTRINS_AARCH64_SHA256SU1; break; - default: g_assert_not_reached (); break; - } - LLVMValueRef args [] = { lhs, rhs, arg3 }; - values [ins->dreg] = call_intrins (ctx, id, args, ""); - break; - } - case OP_XOP_X_X: { - IntrinsicId id = (IntrinsicId)0; - switch (ins->inst_c0) { - case SIMD_OP_LLVM_FABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_FLOAT; break; - case SIMD_OP_LLVM_DABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_DOUBLE; break; - case SIMD_OP_LLVM_I8ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT8; break; - case SIMD_OP_LLVM_I16ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT16; break; - case SIMD_OP_LLVM_I32ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT32; break; - case SIMD_OP_LLVM_I64ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT64; break; - default: g_assert_not_reached (); break; - } - LLVMValueRef arg0 = lhs; - values [ins->dreg] = call_intrins (ctx, id, &arg0, ""); - break; - } - case OP_LSCNT32: - case OP_LSCNT64: { - // %shr = ashr i32 %x, 31 - // %xor = xor i32 %shr, %x - // %mul = shl i32 %xor, 1 - // %add = or i32 %mul, 1 - // %0 = tail call i32 @llvm.ctlz.i32(i32 %add, i1 false) - LLVMValueRef shr = LLVMBuildAShr (builder, lhs, ins->opcode == OP_LSCNT32 ? - LLVMConstInt (LLVMInt32Type (), 31, FALSE) : - LLVMConstInt (LLVMInt64Type (), 63, FALSE), ""); - LLVMValueRef one = ins->opcode == OP_LSCNT32 ? - LLVMConstInt (LLVMInt32Type (), 1, FALSE) : - LLVMConstInt (LLVMInt64Type (), 1, FALSE); - LLVMValueRef xor = LLVMBuildXor (builder, shr, lhs, ""); - LLVMValueRef mul = LLVMBuildShl (builder, xor, one, ""); - LLVMValueRef add = LLVMBuildOr (builder, mul, one, ""); - - LLVMValueRef args [2]; - args [0] = add; - args [1] = LLVMConstInt (LLVMInt1Type (), 0, FALSE); - values [ins->dreg] = LLVMBuildCall (builder, get_intrins (ctx, ins->opcode == OP_LSCNT32 ? INTRINS_CTLZ_I32 : INTRINS_CTLZ_I64), args, 2, ""); - break; - } - case OP_ARM64_SMULH: - case OP_ARM64_UMULH: { - LLVMValueRef op1, op2; - if (ins->opcode == OP_ARM64_SMULH) { - op1 = LLVMBuildSExt (builder, lhs, LLVMInt128Type (), ""); - op2 = LLVMBuildSExt (builder, rhs, LLVMInt128Type (), ""); - } else { - op1 = LLVMBuildZExt (builder, lhs, LLVMInt128Type (), ""); - op2 = LLVMBuildZExt (builder, rhs, LLVMInt128Type (), ""); - } - LLVMValueRef mul = LLVMBuildMul (builder, op1, op2, ""); - LLVMValueRef hi64 = LLVMBuildLShr (builder, mul, - LLVMConstInt (LLVMInt128Type (), 64, FALSE), ""); - values [ins->dreg] = LLVMBuildTrunc (builder, hi64, LLVMInt64Type (), ""); - break; - } -#endif case OP_DUMMY_USE: break; |