Support remaining Sha1 intrinsics on Arm (#48413)
authorFan Yang <52458914+fanyang-mono@users.noreply.github.com>
Thu, 18 Feb 2021 20:33:37 +0000 (15:33 -0500)
committerGitHub <noreply@github.com>
Thu, 18 Feb 2021 20:33:37 +0000 (15:33 -0500)
* Add support for Sha1 API with vector64 arguments

* Promote return to vector64

* Return a 2 x i32 instead of i64

* Update src/mono/mono/mini/mini-llvm.c

* Fix format

Co-authored-by: imhameed <imhameed@microsoft.com>
src/mono/mono/mini/mini-llvm.c

index f8b9706..4ef1ff0 100644 (file)
@@ -9090,19 +9090,27 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                }
                case OP_XOP_X_X_X_X: {
                        IntrinsicId id = (IntrinsicId)0;
+                       gboolean getLowerElement = FALSE;
+                       int idx = -1;
                        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;
+                       case SIMD_OP_ARM64_SHA1C: id = INTRINS_AARCH64_SHA1C; getLowerElement = TRUE; idx = 1; break;
+                       case SIMD_OP_ARM64_SHA1M: id = INTRINS_AARCH64_SHA1M; getLowerElement = TRUE; idx = 1; break;
+                       case SIMD_OP_ARM64_SHA1P: id = INTRINS_AARCH64_SHA1P; getLowerElement = TRUE; idx = 1; break;
                        default: g_assert_not_reached (); break;
                        }
                        LLVMValueRef args [] = { lhs, rhs, arg3 };
+                       if (getLowerElement)
+                               args [idx] = LLVMBuildExtractElement (ctx->builder, args [idx], const_int32 (0), "");
                        values [ins->dreg] = call_intrins (ctx, id, args, "");
                        break;
                }
                case OP_XOP_X_X: {
                        IntrinsicId id = (IntrinsicId)0;
+                       gboolean getLowerElement = FALSE;
                        switch (ins->inst_c0) {
                        case SIMD_OP_AES_IMC: id = INTRINS_AARCH64_AESIMC; break;
                        case SIMD_OP_ARM64_AES_AESMC: id = INTRINS_AARCH64_AESMC; break;
@@ -9116,11 +9124,20 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        case SIMD_OP_LLVM_I16ABS_SATURATE: id = INTRINS_AARCH64_ADV_SIMD_ABS_SATURATE_INT16; break;
                        case SIMD_OP_LLVM_I32ABS_SATURATE: id = INTRINS_AARCH64_ADV_SIMD_ABS_SATURATE_INT32; break;
                        case SIMD_OP_LLVM_I64ABS_SATURATE: id = INTRINS_AARCH64_ADV_SIMD_ABS_SATURATE_INT64; break;
+                       case SIMD_OP_ARM64_SHA1H: id = INTRINS_AARCH64_SHA1H; getLowerElement = TRUE; break;
                        default: g_assert_not_reached (); break;
                        }
-
                        LLVMValueRef arg0 = lhs;
-                       values [ins->dreg] = call_intrins (ctx, id, &arg0, "");
+                       LLVMValueRef result;
+                       if (getLowerElement)
+                               arg0 = LLVMBuildExtractElement (ctx->builder, arg0, const_int32 (0), "");
+                       result = call_intrins (ctx, id, &arg0, "");
+                       if (getLowerElement) {
+                               LLVMTypeRef t = simd_class_to_llvm_type (ctx, ins->klass);
+                               result = LLVMBuildInsertElement (ctx->builder, LLVMConstNull (t), result, const_int32 (0), "");
+                       }
+                       values [ins->dreg] = result;
+
                        break;
                }
                case OP_LSCNT32: