Implement Intel AES intrinsic
authorFei Peng <fei.peng@intel.com>
Thu, 23 Aug 2018 20:50:07 +0000 (13:50 -0700)
committerTanner Gooding <tagoo@outlook.com>
Fri, 24 Aug 2018 17:47:28 +0000 (10:47 -0700)
src/jit/emitxarch.cpp
src/jit/hwintrinsiclistxarch.h
src/jit/hwintrinsicxarch.cpp
src/jit/instrsxarch.h
src/jit/lowerxarch.cpp

index 1985ab508f28c8763109d0d1a8b215de399c7c47..b879571ffeec95dfa9cc6d65dc0312b08a4372e1 100644 (file)
@@ -145,6 +145,10 @@ bool emitter::IsDstDstSrcAVXInstruction(instruction ins)
         case INS_addss:
         case INS_addsubpd:
         case INS_addsubps:
+        case INS_aesdec:
+        case INS_aesdeclast:
+        case INS_aesenc:
+        case INS_aesenclast:
         case INS_andn:
         case INS_andnpd:
         case INS_andnps:
@@ -427,6 +431,7 @@ static bool IsDstSrcImmAvxInstruction(instruction ins)
 {
     switch (ins)
     {
+        case INS_aeskeygenassist:
         case INS_extractps:
         case INS_pextrb:
         case INS_pextrw:
index 04486fec65516cf98ac343b0bc09a7d3ba55e3c5..b7be02fd76e1216b48789c45c3fcfb92e7824157 100644 (file)
@@ -463,6 +463,12 @@ HARDWARE_INTRINSIC(AVX2_Xor,                                        "Xor",
 // ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
 //  AES Intrinsics
 HARDWARE_INTRINSIC(AES_IsSupported,                                 "get_IsSupported",                              AES,          -1,               0,           0,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_IsSupportedProperty,    HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AES_Decrypt,                                     "Decrypt",                                      AES,          -1,              16,           2,     {INS_invalid,           INS_aesdec,         INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AES_DecryptLast,                                 "DecryptLast",                                  AES,          -1,              16,           2,     {INS_invalid,           INS_aesdeclast,     INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AES_Encrypt,                                     "Encrypt",                                      AES,          -1,              16,           2,     {INS_invalid,           INS_aesenc,         INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AES_EncryptLast,                                 "EncryptLast",                                  AES,          -1,              16,           2,     {INS_invalid,           INS_aesenclast,     INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AES_InverseMixColumns,                           "InverseMixColumns",                            AES,          -1,              16,           1,     {INS_invalid,           INS_aesimc,         INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AES_KeygenAssist,                                "KeygenAssist",                                 AES,          -1,              16,           2,     {INS_invalid,           INS_aeskeygenassist,INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_IMM,                    HW_Flag_FullRangeIMM)
 
 // ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
 //                 Intrinsic ID                                     Function name                                   ISA         ival        SIMD size       NumArg                                                                                                     instructions                                                                                                     Category                            Flags
index 3cf1ac666454c8ca8060e53f40c2eeaab147ec1c..33363b59d2e81fc4dc36f9c1ed95d228957baa8f 100644 (file)
@@ -383,7 +383,6 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa)
     switch (isa)
     {
         // These ISAs have no implementation
-        case InstructionSet_AES:
         case InstructionSet_PCLMULQDQ:
         {
             return false;
@@ -399,6 +398,7 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(InstructionSet isa)
         }
 
         // These ISAs are fully implemented
+        case InstructionSet_AES:
         case InstructionSet_AVX:
         case InstructionSet_FMA:
         case InstructionSet_LZCNT:
index 7fc0f9f182fad90a3f52043b15d474f0be38a3f4..e46134ec2569af58ecd81a420cf9b9e6ad983d3d 100644 (file)
@@ -463,6 +463,14 @@ INST3( pextrq,       "pextrq"      , 0, IUM_WR, 0, 0, SSE3A(0x16),  BAD_CODE, BA
 INST3( pextrw_sse41, "pextrw"      , 0, IUM_WR, 0, 0, SSE3A(0x15),  BAD_CODE, BAD_CODE)      // Extract Word
 INST3( extractps,    "extractps"   , 0, IUM_WR, 0, 0, SSE3A(0x17),  BAD_CODE, BAD_CODE)      // Extract Packed Floating-Point Values
 
+//AES instructions
+INST3(aesdec,         "aesdec"          , 0, IUM_WR, 0, 0, BAD_CODE,     BAD_CODE, SSE38(0xDE))   // Perform one round of an AES decryption flow
+INST3(aesdeclast,     "aesdeclast"      , 0, IUM_WR, 0, 0, BAD_CODE,     BAD_CODE, SSE38(0xDF))   // Perform last round of an AES decryption flow
+INST3(aesenc,         "aesenc"          , 0, IUM_WR, 0, 0, BAD_CODE,     BAD_CODE, SSE38(0xDC))   // Perform one round of an AES encryption flow
+INST3(aesenclast,     "aesenclast"      , 0, IUM_WR, 0, 0, BAD_CODE,     BAD_CODE, SSE38(0xDD))   // Perform last round of an AES encryption flow
+INST3(aesimc,         "aesimc"          , 0, IUM_WR, 0, 0, BAD_CODE,     BAD_CODE, SSE38(0xDB))   // Perform the AES InvMixColumn Transformation
+INST3(aeskeygenassist,"aeskeygenassist" , 0, IUM_WR, 0, 0, BAD_CODE,     BAD_CODE, SSE3A(0xDF))   // AES Round Key Generation Assist
+
 INST3(LAST_SSE4_INSTRUCTION, "LAST_SSE4_INSTRUCTION",  0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, BAD_CODE)
 
 INST3(FIRST_AVX_INSTRUCTION, "FIRST_AVX_INSTRUCTION",  0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, BAD_CODE)
index 6aa295111a01af3bf001e716a46a68a3b6cdad3c..8d908da9735af86b2f121a97defbe49e4ba31702 100644 (file)
@@ -2377,6 +2377,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode, Ge
                 case NI_SSE41_Blend:
                 case NI_SSE41_DotProduct:
                 case NI_SSE41_MultipleSumAbsoluteDifferences:
+                case NI_AES_KeygenAssist:
                 case NI_AVX_Blend:
                 case NI_AVX_Compare:
                 case NI_AVX_DotProduct:
@@ -2808,6 +2809,19 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
                             break;
                         }
 
+                        case NI_AES_KeygenAssist:
+                        {
+                            if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
+                            {
+                                MakeSrcContained(node, op1);
+                            }
+                            else if (supportsRegOptional)
+                            {
+                                op1->SetRegOptional();
+                            }
+                            break;
+                        }
+
                         default:
                         {
                             break;