summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src')
-rw-r--r--3rdparty/asmjit/src/asmjit.natvis146
-rw-r--r--3rdparty/asmjit/src/asmjit/asmjit.h21
-rw-r--r--3rdparty/asmjit/src/asmjit/core.h2007
-rw-r--r--3rdparty/asmjit/src/asmjit/core/api-build_p.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/api-config.h313
-rw-r--r--3rdparty/asmjit/src/asmjit/core/arch.cpp141
-rw-r--r--3rdparty/asmjit/src/asmjit/core/arch.h156
-rw-r--r--3rdparty/asmjit/src/asmjit/core/assembler.cpp316
-rw-r--r--3rdparty/asmjit/src/asmjit/core/assembler.h64
-rw-r--r--3rdparty/asmjit/src/asmjit/core/builder.cpp519
-rw-r--r--3rdparty/asmjit/src/asmjit/core/builder.h428
-rw-r--r--3rdparty/asmjit/src/asmjit/core/callconv.cpp10
-rw-r--r--3rdparty/asmjit/src/asmjit/core/callconv.h291
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codebuffer.h126
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codebufferwriter_p.h3
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codeholder.cpp127
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codeholder.h379
-rw-r--r--3rdparty/asmjit/src/asmjit/core/compiler.cpp326
-rw-r--r--3rdparty/asmjit/src/asmjit/core/compiler.h244
-rw-r--r--3rdparty/asmjit/src/asmjit/core/constpool.h37
-rw-r--r--3rdparty/asmjit/src/asmjit/core/cpuinfo.h30
-rw-r--r--3rdparty/asmjit/src/asmjit/core/datatypes.h14
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitter.cpp264
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitter.h542
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitterutils.cpp150
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitterutils_p.h109
-rw-r--r--3rdparty/asmjit/src/asmjit/core/environment.cpp64
-rw-r--r--3rdparty/asmjit/src/asmjit/core/environment.h591
-rw-r--r--3rdparty/asmjit/src/asmjit/core/errorhandler.cpp37
-rw-r--r--3rdparty/asmjit/src/asmjit/core/errorhandler.h267
-rw-r--r--3rdparty/asmjit/src/asmjit/core/features.h28
-rw-r--r--3rdparty/asmjit/src/asmjit/core/formatter.cpp469
-rw-r--r--3rdparty/asmjit/src/asmjit/core/formatter.h252
-rw-r--r--3rdparty/asmjit/src/asmjit/core/func.cpp47
-rw-r--r--3rdparty/asmjit/src/asmjit/core/func.h52
-rw-r--r--3rdparty/asmjit/src/asmjit/core/globals.cpp149
-rw-r--r--3rdparty/asmjit/src/asmjit/core/globals.h122
-rw-r--r--3rdparty/asmjit/src/asmjit/core/inst.cpp52
-rw-r--r--3rdparty/asmjit/src/asmjit/core/inst.h470
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitallocator.cpp4
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitallocator.h26
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitruntime.cpp42
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitruntime.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/logger.cpp124
-rw-r--r--3rdparty/asmjit/src/asmjit/core/logger.h (renamed from 3rdparty/asmjit/src/asmjit/core/logging.h)207
-rw-r--r--3rdparty/asmjit/src/asmjit/core/logging.cpp535
-rw-r--r--3rdparty/asmjit/src/asmjit/core/misc_p.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/operand.cpp8
-rw-r--r--3rdparty/asmjit/src/asmjit/core/operand.h291
-rw-r--r--3rdparty/asmjit/src/asmjit/core/osutils.h56
-rw-r--r--3rdparty/asmjit/src/asmjit/core/osutils_p.h94
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rabuilders_p.h31
-rw-r--r--3rdparty/asmjit/src/asmjit/core/radefs_p.h9
-rw-r--r--3rdparty/asmjit/src/asmjit/core/ralocal.cpp29
-rw-r--r--3rdparty/asmjit/src/asmjit/core/ralocal_p.h9
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rapass.cpp65
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rapass_p.h37
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rastack.cpp9
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rastack_p.h26
-rw-r--r--3rdparty/asmjit/src/asmjit/core/string.cpp30
-rw-r--r--3rdparty/asmjit/src/asmjit/core/string.h186
-rw-r--r--3rdparty/asmjit/src/asmjit/core/support.cpp10
-rw-r--r--3rdparty/asmjit/src/asmjit/core/support.h209
-rw-r--r--3rdparty/asmjit/src/asmjit/core/target.cpp3
-rw-r--r--3rdparty/asmjit/src/asmjit/core/target.h119
-rw-r--r--3rdparty/asmjit/src/asmjit/core/type.cpp54
-rw-r--r--3rdparty/asmjit/src/asmjit/core/type.h215
-rw-r--r--3rdparty/asmjit/src/asmjit/core/virtmem.cpp16
-rw-r--r--3rdparty/asmjit/src/asmjit/core/virtmem.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zone.cpp6
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zone.h7
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonehash.h3
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonelist.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonestack.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonestring.h24
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonetree.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonevector.h29
-rw-r--r--3rdparty/asmjit/src/asmjit/x86.h78
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86archdata.cpp137
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86archdata_p.h51
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp267
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86assembler.h651
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86builder.cpp8
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86builder.h310
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86callconv.cpp273
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86callconv_p.h8
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp12
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86compiler.h465
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86emitter.h4025
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86features.cpp21
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86features.h4
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp (renamed from 3rdparty/asmjit/src/asmjit/x86/x86logging.cpp)330
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86formatter_p.h (renamed from 3rdparty/asmjit/src/asmjit/x86/x86logging_p.h)60
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86globals.h178
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp324
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h10
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp1015
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instdb.h12
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86internal.cpp484
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86internal_p.h4
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86operand.h776
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp293
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h7
104 files changed, 13053 insertions, 8642 deletions
diff --git a/3rdparty/asmjit/src/asmjit.natvis b/3rdparty/asmjit/src/asmjit.natvis
index 18a083c6c12..b73d8487276 100644
--- a/3rdparty/asmjit/src/asmjit.natvis
+++ b/3rdparty/asmjit/src/asmjit.natvis
@@ -35,25 +35,25 @@
</Type>
<Type Name="asmjit::Operand_">
- <Intrinsic Name="opType" Expression="(unsigned int)(_signature &amp; 0x7)"/>
- <Intrinsic Name="opSize" Expression="(_signature &gt;&gt; 24) &amp; 0xFF"/>
+ <Intrinsic Name="opType" Expression="(unsigned int)(_signature &amp; 0x7)" />
+ <Intrinsic Name="opSize" Expression="(_signature &gt;&gt; 24) &amp; 0xFF" />
- <Intrinsic Name="regType" Expression="(_signature &gt;&gt; 3) &amp; 0x1F"/>
- <Intrinsic Name="regGroup" Expression="(_signature &gt;&gt; 8) &amp; 0xF"/>
+ <Intrinsic Name="regType" Expression="(_signature &gt;&gt; 3) &amp; 0x1F" />
+ <Intrinsic Name="regGroup" Expression="(_signature &gt;&gt; 8) &amp; 0xF" />
- <Intrinsic Name="memBaseType" Expression="(_signature &gt;&gt; 3) &amp; 0x1F"/>
- <Intrinsic Name="memIndexType" Expression="(_signature &gt;&gt; 8) &amp; 0x1F"/>
- <Intrinsic Name="memAddrType" Expression="(_signature &gt;&gt; 13) &amp; 0x3"/>
- <Intrinsic Name="memRegHome" Expression="(_signature &gt;&gt; 15) &amp; 0x1"/>
+ <Intrinsic Name="memBaseType" Expression="(_signature &gt;&gt; 3) &amp; 0x1F" />
+ <Intrinsic Name="memIndexType" Expression="(_signature &gt;&gt; 8) &amp; 0x1F" />
+ <Intrinsic Name="memAddrType" Expression="(_signature &gt;&gt; 13) &amp; 0x3" />
+ <Intrinsic Name="memRegHome" Expression="(_signature &gt;&gt; 15) &amp; 0x1" />
- <Intrinsic Name="memBaseId" Expression="_baseId"/>
- <Intrinsic Name="memIndexId" Expression="_data[0]"/>
+ <Intrinsic Name="memBaseId" Expression="_baseId" />
+ <Intrinsic Name="memIndexId" Expression="_data[0]" />
- <Intrinsic Name="memOffset32b" Expression="(__int64)int(_data[1])"/>
- <Intrinsic Name="memOffset64b" Expression="(__int64) ((unsigned __int64)_baseId &lt;&lt; 32) | ((unsigned __int64)_data[1])"/>
- <Intrinsic Name="memOffset" Expression="memBaseType() != 0 ? memOffset32b() : memOffset64b()"/>
+ <Intrinsic Name="memOffset32b" Expression="(__int64)int(_data[1])" />
+ <Intrinsic Name="memOffset64b" Expression="(__int64) ((unsigned __int64)_baseId &lt;&lt; 32) | ((unsigned __int64)_data[1])" />
+ <Intrinsic Name="memOffset" Expression="memBaseType() != 0 ? memOffset32b() : memOffset64b()" />
- <Intrinsic Name="immValue" Expression="((__int64)_data[1] &lt;&lt; 32) | (__int64)_data[0]"/>
+ <Intrinsic Name="immValue" Expression="((__int64)_data[1] &lt;&lt; 32) | (__int64)_data[0]" />
<DisplayString Condition="opType() == 0">[None]</DisplayString>
<DisplayString Condition="opType() == 1">[Reg] {{ id={_baseId, d} group={regGroup(), d} type={regType(), d} size={opSize(), d} }}</DisplayString>
@@ -80,4 +80,122 @@
<Item Name="_data[ImmLo]" Condition="opType() == 3">_data[1]</Item>
</Expand>
</Type>
+
+ <Type Name="asmjit::FuncValue">
+ <Intrinsic Name="isReg" Expression="(_data &amp; asmjit::FuncValue::kFlagIsReg) != 0" />
+ <Intrinsic Name="isStack" Expression="(_data &amp; asmjit::FuncValue::kFlagIsStack) != 0" />
+ <Intrinsic Name="isIndirect" Expression="(_data &amp; asmjit::FuncValue::kFlagIsIndirect) != 0" />
+ <Intrinsic Name="isDone" Expression="(_data &amp; asmjit::FuncValue::kFlagIsDone) != 0" />
+
+ <Intrinsic Name="typeId" Expression="((_data &amp; asmjit::FuncValue::kTypeIdMask) &gt;&gt; asmjit::FuncValue::kTypeIdShift)" />
+ <Intrinsic Name="regId" Expression="((_data &amp; asmjit::FuncValue::kRegIdMask) &gt;&gt; asmjit::FuncValue::kRegIdShift)" />
+ <Intrinsic Name="regType" Expression="((_data &amp; asmjit::FuncValue::kRegTypeMask) &gt;&gt; asmjit::FuncValue::kRegTypeShift)" />
+ <Intrinsic Name="stackOffset" Expression="((_data &amp; asmjit::FuncValue::kStackOffsetMask) &gt;&gt; asmjit::FuncValue::kStackOffsetShift)" />
+
+ <DisplayString Condition="isReg()">[RegValue {{ regType={regType()} indirect={isIndirect()} done={isDone()} }}]</DisplayString>
+ <DisplayString Condition="isStack()">[StackValue {{ indirect={isIndirect()} done={isDone()} }}]</DisplayString>
+ <DisplayString Condition="!isReg() &amp;&amp; !isStack()">[Unknown]</DisplayString>
+
+ <Expand HideRawView="true">
+ <Item Name="data">_data</Item>
+ <Item Name="typeId">(asmjit::Type::Id)(typeId())</Item>
+ <Item Name="regType" Condition="isReg()">(asmjit::BaseReg::RegType)regType()</Item>
+ <Item Name="regId" Condition="isReg()">regId()</Item>
+ <Item Name="stackOffset" Condition="isStack()">stackOffset()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="asmjit::BaseNode">
+ <Intrinsic Name="nodeType" Expression="_any._nodeType" />
+
+ <Intrinsic Name="isInst" Expression="nodeType() == asmjit::BaseNode::kNodeInst"></Intrinsic>
+ <Intrinsic Name="isSection" Expression="nodeType() == asmjit::BaseNode::kNodeSection"></Intrinsic>
+ <Intrinsic Name="isLabel" Expression="nodeType() == asmjit::BaseNode::kNodeLabel"></Intrinsic>
+ <Intrinsic Name="isAlign" Expression="nodeType() == asmjit::BaseNode::kNodeAlign"></Intrinsic>
+ <Intrinsic Name="isEmbedData" Expression="nodeType() == asmjit::BaseNode::kNodeEmbedData"></Intrinsic>
+ <Intrinsic Name="isEmbedLabel" Expression="nodeType() == asmjit::BaseNode::kNodeEmbedLabel"></Intrinsic>
+ <Intrinsic Name="isEmbedLabelDelta" Expression="nodeType() == asmjit::BaseNode::kNodeEmbedLabelDelta"></Intrinsic>
+ <Intrinsic Name="isConstPool" Expression="nodeType() == asmjit::BaseNode::kNodeConstPool"></Intrinsic>
+ <Intrinsic Name="isComment" Expression="nodeType() == asmjit::BaseNode::kNodeComment"></Intrinsic>
+ <Intrinsic Name="isSentinel" Expression="nodeType() == asmjit::BaseNode::kNodeSentinel"></Intrinsic>
+ <Intrinsic Name="isJump" Expression="nodeType() == asmjit::BaseNode::kNodeJump"></Intrinsic>
+ <Intrinsic Name="isFunc" Expression="nodeType() == asmjit::BaseNode::kNodeFunc"></Intrinsic>
+ <Intrinsic Name="isFuncRet" Expression="nodeType() == asmjit::BaseNode::kNodeFuncRet"></Intrinsic>
+ <Intrinsic Name="isInvoke" Expression="nodeType() == asmjit::BaseNode::kNodeInvoke"></Intrinsic>
+
+ <Intrinsic Name="actsAsInst" Expression="isInst() || isJump() || isFunc() || isFuncRet() || isInvoke()" />
+ <Intrinsic Name="actsAsLabel" Expression="isLabel() || isFunc()" />
+
+ <DisplayString Condition="isInst()">[InstNode]</DisplayString>
+ <DisplayString Condition="isSentinel()">[SectionNode]</DisplayString>
+ <DisplayString Condition="isLabel()">[LabelNode]</DisplayString>
+ <DisplayString Condition="isAlign()">[AlignNode]</DisplayString>
+ <DisplayString Condition="isEmbedData()">[EmbedDataNode]</DisplayString>
+ <DisplayString Condition="isEmbedLabel()">[EmbedLabelNode]</DisplayString>
+ <DisplayString Condition="isEmbedLabelDelta()">[EmbedLabelDeltaNode]</DisplayString>
+ <DisplayString Condition="isConstPool()">[ConstPoolNode]</DisplayString>
+ <DisplayString Condition="isComment()">[CommentNode]</DisplayString>
+ <DisplayString Condition="isSentinel()">[SentinelNode]</DisplayString>
+ <DisplayString Condition="isJump()">[JumpNode]</DisplayString>
+ <DisplayString Condition="isFunc()">[FuncNode]</DisplayString>
+ <DisplayString Condition="isFuncRet()">[FuncRetNode]</DisplayString>
+ <DisplayString Condition="isInvoke()">[InvokeNode]</DisplayString>
+ <DisplayString Condition="nodeType() == 0 || nodeType() &gt; 18">[UnknownNode {nodeType(), d}]</DisplayString>
+
+ <Expand HideRawView="true">
+ <Item Name="prev">_prev</Item>
+ <Item Name="next">_next</Item>
+
+ <Item Name="nodeType">(asmjit::BaseNode::NodeType)_any._nodeType</Item>
+ <Item Name="nodeFlags">(asmjit::BaseNode::Flags)_any._nodeFlags</Item>
+
+ <Item Name="position">_position</Item>
+ <Item Name="userData.u64">_userDataU64</Item>
+ <Item Name="userData.ptr">_userDataPtr</Item>
+ <Item Name="passData">_passData</Item>
+ <Item Name="inlineComment">_inlineComment, s8</Item>
+
+ <Item Name="baseInst" Condition="actsAsInst()">((asmjit::InstNode*)this)-&gt;_baseInst</Item>
+ <Item Name="opCount" Condition="actsAsInst()">_inst._opCount</Item>
+ <Item Name="opCapacity" Condition="actsAsInst()">_inst._opCapacity</Item>
+ <Item Name="opArray" Condition="actsAsInst()">((asmjit::InstNode*)this)-&gt;_opArray, [_inst._opCount]</Item>
+
+ <Item Name="sectionId" Condition="isSection()">((asmjit::SectionNode*)this)-&gt;_id</Item>
+ <Item Name="nextSection" Condition="isSection()">((asmjit::SectionNode*)this)-&gt;_nextSection</Item>
+
+ <Item Name="labelId" Condition="isLabel()">((asmjit::LabelNode*)this)-&gt;_id</Item>
+
+ <Item Name="alignMode" Condition="isAlign()">((asmjit::AlignNode*)this)-&gt;_alignMode</Item>
+ <Item Name="alignment" Condition="isAlign()">((asmjit::AlignNode*)this)-&gt;_alignment</Item>
+
+ <Item Name="typeId" Condition="isEmbedData()">_embed._typeId, d</Item>
+ <Item Name="typeSize" Condition="isEmbedData()">_embed._typeSize, d</Item>
+ <Item Name="itemCount" Condition="isEmbedData()">((asmjit::EmbedDataNode*)this)-&gt;_itemCount</Item>
+ <Item Name="repeatCount" Condition="isEmbedData()">((asmjit::EmbedDataNode*)this)-&gt;_repeatCount</Item>
+ <Item Name="inlineData" Condition="isEmbedData()">((asmjit::EmbedDataNode*)this)-&gt;_inlineData</Item>
+ <Item Name="externalData" Condition="isEmbedData()">((asmjit::EmbedDataNode*)this)-&gt;_externalData</Item>
+
+ <Item Name="labelId" Condition="isEmbedLabel()">((asmjit::EmbedLabelNode*)this)-&gt;_id</Item>
+
+ <Item Name="labelId" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_id</Item>
+ <Item Name="baseId" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_baseId</Item>
+ <Item Name="dataSize" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_dataSize</Item>
+
+ <Item Name="constPool" Condition="isConstPool()">((asmjit::ConstPoolNode*)this)-&gt;_constPool</Item>
+
+ <Item Name="sentinel.sentinelType" Condition="isSentinel()">(asmjit::SentinelNode::SentinelType)_sentinel._sentinelType</Item>
+
+ <Item Name="annotation" Condition="isJump()">((asmjit::JumpNode*)this)-&gt;_annotation</Item>
+
+ <Item Name="funcDetail" Condition="isFunc()">((asmjit::FuncNode*)this)-&gt;_funcDetail</Item>
+ <Item Name="frame" Condition="isFunc()">((asmjit::FuncNode*)this)-&gt;_frame</Item>
+ <Item Name="exitNode" Condition="isFunc()">((asmjit::FuncNode*)this)-&gt;_exitNode</Item>
+ <Item Name="end" Condition="isFunc()">((asmjit::FuncNode*)this)-&gt;_end</Item>
+ <Item Name="args" Condition="isFunc()">((asmjit::FuncNode*)this)-&gt;_args, [((asmjit::FuncNode*)this)-&gt;_funcDetail._argCount]</Item>
+
+ <Item Name="funcDetail" Condition="isInvoke()">((asmjit::InvokeNode*)this)-&gt;_funcDetail</Item>
+ <Item Name="rets" Condition="isInvoke()">((asmjit::InvokeNode*)this)-&gt;_rets, [((asmjit::InvokeNode*)this)-&gt;_funcDetail._retCount]</Item>
+ <Item Name="args" Condition="isInvoke()">((asmjit::InvokeNode*)this)-&gt;_args, [((asmjit::InvokeNode*)this)-&gt;_funcDetail._argCount]</Item>
+ </Expand>
+ </Type>
</AutoVisualizer>
diff --git a/3rdparty/asmjit/src/asmjit/asmjit.h b/3rdparty/asmjit/src/asmjit/asmjit.h
index e543a633d04..400426c40a7 100644
--- a/3rdparty/asmjit/src/asmjit/asmjit.h
+++ b/3rdparty/asmjit/src/asmjit/asmjit.h
@@ -24,27 +24,6 @@
#ifndef ASMJIT_ASMJIT_H_INCLUDED
#define ASMJIT_ASMJIT_H_INCLUDED
-//! \mainpage API Reference
-//!
-//! AsmJit C++ API reference documentation generated by Doxygen.
-//!
-//! Introduction provided by the project page at https://github.com/asmjit/asmjit.
-//!
-//! \section main_groups Groups
-//!
-//! The documentation is split into the following groups:
-//!
-//! $$DOCS_GROUP_OVERVIEW$$
-//!
-//! \section main_other Other Pages
-//!
-//! - <a href="annotated.html">Class List</a> - List of classes sorted alphabetically
-//! - <a href="namespaceasmjit.html">AsmJit Namespace</a> - List of symbols provided by `asmjit` namespace
-
-//! \namespace asmjit
-//!
-//! Root namespace used by AsmJit.
-
#include "./core.h"
#ifdef ASMJIT_BUILD_X86
diff --git a/3rdparty/asmjit/src/asmjit/core.h b/3rdparty/asmjit/src/asmjit/core.h
index f9a56fc51fb..d0fb214d0ce 100644
--- a/3rdparty/asmjit/src/asmjit/core.h
+++ b/3rdparty/asmjit/src/asmjit/core.h
@@ -24,48 +24,1983 @@
#ifndef ASMJIT_CORE_H_INCLUDED
#define ASMJIT_CORE_H_INCLUDED
+//! Root namespace used by AsmJit.
+namespace asmjit {
+
+// ============================================================================
+// [Documentation - mainpage]
+// ============================================================================
+
+//! \mainpage API Reference
+//!
+//! AsmJit C++ API reference documentation generated by Doxygen.
+//!
+//! AsmJit library uses one global namespace called \ref asmjit, which provides
+//! the whole functionality. Core functionality is within \ref asmjit namespace
+//! and architecture specific functionality is always in its own namespace. For
+//! example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation.
+//!
+//! \section main_groups Documentation Groups
+//!
+//! AsmJit documentation is structured into groups. Groups can be followed in
+//! order to learn AsmJit, but knowledge from multiple groups is required to
+//! use AsmJit properly:
+//!
+//! $$DOCS_GROUP_OVERVIEW$$
+//!
+//! \note It's important to understand that in order to learn AsmJit all groups
+//! are important. Some groups can be omitted if a particular tool is out of
+//! interest - for example \ref asmjit_assembler users don't need to know about
+//! \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users
+//! must know about \ref asmjit_assembler as it also uses operands, labels, and
+//! other concepts. Similarly \ref asmjit_compiler users must know how both \ref
+//! asmjit_assembler and \ref asmjit_builder tools work.
+//!
+//! \section where_to_start Where To Start
+//!
+//! AsmJit \ref asmjit_core provides the following two classes that are essential
+//! from the code generation perspective:
+//!
+//! - \ref CodeHolder provides functionality
+//! to temporarily hold the generated code. It stores all the necessary
+//! information about the code - code buffers, sections, labels, symbols,
+//! and information about relocations.
+//!
+//! - \ref BaseEmitter provides interface used
+//! by emitter implementations. The interface provides basic building blocks
+//! that are then implemented by \ref BaseAssembler, \ref BaseBuilder, and
+//! \ref BaseCompiler.
+//!
+//! Code emitters:
+//!
+//! - \ref asmjit_assembler - provides direct machine code generation.
+//!
+//! - \ref asmjit_builder - provides intermediate code generation that can
+//! be processed before it's serialized to \ref BaseAssembler.
+//!
+//! - \ref asmjit_compiler - provides high-level code generation with built-in
+//! register allocation.
+//!
+//! - \ref FuncNode - provides insight into how function looks from the Compiler
+//! perspective and how it's stored in a node-list.
+//!
+//! \section main_recommendations Recommendations
+//!
+//! The following steps are recommended for all AsmJit users:
+//!
+//! - Make sure that you use \ref Logger, see \ref asmjit_logging.
+//!
+//! - Make sure that you use \ref ErrorHandler, see \ref asmjit_error_handling.
+//!
+//! - Instruction validation in your debug builds can reveal problems too.
+//! AsmJit provides validation at instruction level, that can be enabled
+//! by \ref BaseEmitter::addValidationOptions().
+//!
+//! See \ref BaseEmitter::ValidationOptions for more details.
+//!
+//! - Make sure you put a breakpoint into \ref DebugUtils::errored() function
+//! if you have a problem with AsmJit returning errors during instruction
+//! encoding or register allocation. Having an active breakpoint there can
+//! help to reveal the origin of the error, to inspect variables and other
+//! conditions that caused to it.
+//!
+//! The reason for using \ref Logger and \ref ErrorHandler is that they provide
+//! a very useful information about what's happening inside emitters. In many
+//! cases the information provided by these two is crucial to quickly fix issues
+//! that happen during development (for example wrong instruction, address, or
+//! register used). In addition, output from \ref Logger is always necessary
+//! when filling bug reports. In other words, using logging and proper error
+//! handling can save a lot of time during the development.
+//!
+//! \section main_other Other Pages
+//!
+//! - <a href="annotated.html">Class List</a> - List of classes sorted alphabetically
+//! - <a href="namespaceasmjit.html">AsmJit Namespace</a> - List of symbols provided by `asmjit` namespace
+
+// ============================================================================
+// [Documentation - asmjit_build]
+// ============================================================================
+
+//! \defgroup asmjit_build Build Instructions
+//! \brief Build instructions, supported environments, and feature selection.
+//!
+//! ### Overview
+//!
+//! AsmJit is designed to be easy embeddable in any project. However, it depends
+//! on some compile-time definitions that can be used to enable or disable
+//! features to decrease the resulting binary size. A typical way of building
+//! AsmJit is to use [cmake](https://www.cmake.org), but it's also possible to
+//! just include AsmJit source code in your project and to just build it. The
+//! easiest way to include AsmJit in your project is to just include **src**
+//! directory in your project and to define \ref ASMJIT_STATIC. AsmJit can be
+//! just updated from time to time without any changes to this integration
+//! process. Do not embed AsmJit's `test` files in such case as these are used
+//! exclusively for testing.
+//!
+//! ### Supported C++ Compilers
+//!
+//! - Requirements:
+//!
+//! - AsmJit won't build without C++11 enabled. If you use older GCC or Clang
+//! you would have to enable at least C++11 standard through compiler flags.
+//!
+//! - Tested:
+//!
+//! - **Clang** - Tested by Travis-CI - Clang 3.9+ (with C++11 enabled) is
+//! officially supported (older Clang versions having C++11 support are
+//! probably fine, but are not regularly tested).
+//!
+//! - **GNU** - Tested by Travis-CI - GCC 4.8+ (with C++11 enabled) is
+//! officially supported.
+//!
+//! - **MINGW** - Tested by Travis-CI - Use the latest version, if possible.
+//!
+//! - **MSVC** - Tested by Travis-CI - VS2017+ is officially supported, VS2015
+//! is reported to work.
+//!
+//! - Untested:
+//!
+//! - **Intel** - No maintainers and no CI environment to regularly test
+//! this compiler.
+//!
+//! - **Other** C++ compilers would require basic support in
+//! [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h).
+//!
+//! ### Supported Operating Systems and Platforms
+//!
+//! - Tested:
+//!
+//! - **Linux** - Tested by Travis-CI (any distribution is generally supported).
+//!
+//! - **OSX** - Tested by Travis-CI (any version is supported).
+//!
+//! - **Windows** - Tested by Travis-CI - (Windows 7+ is officially supported).
+//!
+//! - **Emscripten** - Works if compiled with \ref ASMJIT_NO_JIT. AsmJit
+//! cannot generate WASM code, but can be used to generate X86/X64 code
+//! within a browser, for example.
+//!
+//! - Untested:
+//!
+//! - **BSDs** - No maintainers, no CI environment to regularly test BSDs,
+//! but they should work out of box.
+//!
+//! - **Haiku** - Not regularly tested, but reported to work.
+//!
+//! - **Other** operating systems would require some testing and support in
+//! the following files:
+//! - [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h)
+//! - [core/osutils.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/osutils.cpp)
+//! - [core/virtmem.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/virtmem.cpp)
+//!
+//! ### Supported Backends / Architectures
+//!
+//! - **X86** - Both 32-bit and 64-bit backends tested by Travis-CI.
+//! - **ARM** - Work-in-progress (not public at the moment).
+//!
+//! ### Static Builds and Embedding
+//!
+//! These definitions can be used to enable static library build. Embed is used
+//! when AsmJit's source code is embedded directly in another project, implies
+//! static build as well.
+//!
+//! - \ref ASMJIT_EMBED - Asmjit is embedded, implies \ref ASMJIT_STATIC.
+//! - \ref ASMJIT_STATIC - Enable static-library build.
+//!
+//! \note Projects that use AsmJit statically must define \ref ASMJIT_STATIC in
+//! all compilation units that use AsmJit, otherwise AsmJit would use dynamic
+//! library imports in \ref ASMJIT_API decorator. The recommendation is to
+//! define this macro across the whole project that uses AsmJit this way.
+//!
+//! ### Build Configuration
+//!
+//! These definitions control whether asserts are active or not. By default
+//! AsmJit would autodetect build configuration from existing pre-processor
+//! definitions, but this behavior can be overridden, for example to enable
+//! debug asserts in release configuration.
+//!
+//! - \ref ASMJIT_BUILD_DEBUG - Overrides build configuration to debug,
+//! asserts will be enabled in this case.
+//! - \ref ASMJIT_BUILD_RELEASE - Overrides build configuration to release,
+//! asserts will be disabled in this case.
+//!
+//! \note There is usually no need to override the build configuration. AsmJit
+//! detects the build configuration by checking whether `NDEBUG` is defined and
+//! automatically defines \ref ASMJIT_BUILD_RELEASE if configuration overrides
+//! were not used. We only recommend using build configuration overrides in
+//! special situations, like using AsmJit in release configuration with asserts
+//! enabled for whatever reason.
+//!
+//! ### AsmJit Backends
+//!
+//! AsmJit currently supports only X86/X64 backend, but the plan is to add more
+//! backends in the future. By default AsmJit builds only the host backend, which
+//! is autodetected at compile-time, but this can be overridden.
+//!
+//! - \ref ASMJIT_BUILD_X86 - Always build X86 backend (X86 and X86_64).
+//! - \ref ASMJIT_BUILD_ARM - Always build ARM backend (ARM and AArch64).
+//! - \ref ASMJIT_BUILD_HOST - Always build the host backend, implied by default.
+//!
+//! ### Features Selection
+//!
+//! AsmJit builds by defaults all supported features, which includes all emitters,
+//! logging, instruction validation and introspection, and JIT memory allocation.
+//! Features can be disabled at compile time by using `ASMJIT_NO_...` definitions.
+//!
+//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time
+//! so it won't be available and the compilation will fail if there is
+//! attempt to use such API. This includes deprecated classes, namespaces,
+//! enumerations, and functions.
+//!
+//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality
+//! completely. This implies \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler
+//! cannot be used without \ref asmjit_builder.
+//!
+//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality
+//! completely.
+//!
+//! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime.
+//!
+//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
+//!
+//! - \ref ASMJIT_NO_TEXT - Disables everything that contains string
+//! representation of AsmJit constants, should be used together with
+//! \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the
+//! ability to quiry instruction names, register names, etc...
+//!
+//! - \ref ASMJIT_NO_VALIDATION - Disables validation API.
+//!
+//! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API,
+//! must be used together with \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler
+//! requires introspection for its liveness analysis and register allocation.
+//!
+//! \note It's not recommended to disable features if you plan to build AsmJit
+//! as a shared library that will be used by multiple projects that you don't
+//! control how AsmJit was built (for example AsmJit in a Linux distribution).
+//! The possibility to disable certain features exists mainly for customized
+//! AsmJit builds.
+
+// ============================================================================
+// [Documentation - asmjit_breaking_changes]
+// ============================================================================
+
+//! \defgroup asmjit_breaking_changes Breaking Changes
+//! \brief Documentation of breaking changes
+//!
+//! ### Overview
+//!
+//! AsmJit is a live project that is being actively developed. Deprecating the
+//! existing API in favor of a new one is preferred, but it's not always
+//! possible if the changes are significant. AsmJit authors prefer to do
+//! accumulated breaking changes at once instead of breaking the API often.
+//! This page documents deprecated and removed APIs and should serve as a how-to
+//! guide for people that want to port existing code to work with the newest AsmJit.
+//!
+//! ### Tips
+//!
+//! Useful tips before you start:
+//!
+//! - Visit our [Public Gitter Channel](https://gitter.im/asmjit/asmjit) if
+//! you need a quick help.
+//!
+//! - Build AsmJit with `ASMJIT_NO_DEPRECATED` macro defined to make sure that
+//! you are not using deprecated functionality at all. Deprecated functions
+//! are decorated with `ASMJIT_DEPRECATED()` macro, but sometimes it's not
+//! possible to decorate everything like classes, which are used by deprecated
+//! functions as well, because some compilers would warn about that. If your
+//! project compiles fine with `ASMJIT_NO_DEPRECATED` it's not using anything,
+//! which was deprecated.
+//!
+//! ### Changes committed at 2020-05-30
+//!
+//! AsmJit has been cleaned up significantly, many todo items have been fixed
+//! and many functions and classes have been redesigned, some in an incompatible
+//! way.
+//!
+//! Core changes:
+//!
+//! - \ref Imm operand has now only \ref Imm::value() and \ref Imm::valueAs()
+//! functions that return its value content, and \ref Imm::setValue() function
+//! that sets the content. Functions like `setI8()`, `setU8()` were deprecated.
+//!
+//! Old functions were deprecated, but code using them should still compile.
+//!
+//! - `ArchInfo` has been replaced with \ref Environment. Environment provides
+//! more details about the architecture, but drops some properties that
+//! were used by arch info - `gpSize(`) and `gpCount()`. `gpSize()` can
+//! be replaced with `registerSize()` getter, which returns a native register
+//! size of the architecture the environment uses. However, `gpCount()` was
+//! removed - at the moment \ref ArchRegs can be used to access such properties.
+//!
+//! Some other functions were renamed, like `ArchInfo::isX86Family()` is
+//! now \ref Environment::isFamilyX86(), etc. The reason for changing the
+//! order was support for more propertries and all the accessors now
+//! start with the type of the property, like \ref Environment::isPlatformWindows().
+//!
+//! This function causes many other classes to provide `environment()` getter
+//! instead of `archInfo()` getter. In addition, AsmJit now uses `arch()` to
+//! get an architecture instead of `archId()`. `ArchInfo::kIdXXX` was renamed
+//! to `Environment::kArchXXX`.
+//!
+//! Some functions were deprecated, some removed...
+//!
+//! - `CodeInfo` has been removed in favor of \ref Environment. If you used
+//! `CodeInfo` to set architecture and base address, this is now possible
+//! with \ref Environment and setting base address explicitly by \ref
+//! CodeHolder::init() - the first argument is \ref Environment, and the
+//! second argument is base address, which defaults to \ref
+//! Globals::kNoBaseAddress.
+//!
+//! CodeInfo class was deprecated, but the code using it should still
+//! compile with warnings.
+//!
+//! - \ref CallConv has been updated to offer a more unified way of representing
+//! calling conventions - many calling conventions were abstracted to follow
+//! standard naming like \ref CallConv::kIdCDecl or \ref CallConv::kIdStdCall.
+//!
+//! This change means that other APIs like \ref FuncDetail::init() now
+//! require both, calling convention and target \ref Environment.
+//!
+//! - `Logging` namespace has been renamed to \ref Formatter, which now
+//! provides general functionality for formatting in AsmJit.
+//!
+//! Logging namespace should still work, but its use is deprecated.
+//! Unfortunately this will be without deprecation warnings, so please
+//! make sure you don't use it.
+//!
+//! - `Data64`, `Data128`, and `Data256` structs were deprecated and should
+//! no longer be used. There is no replacement, AsmJit users should simply
+//! create their own structures if they need them or use the new repeated
+//! embed API in emitters, see \ref BaseEmitter::embedDataArray().
+//!
+//! Emitter changes:
+//!
+//! - \ref BaseEmitter::emit() function signature has been changed to accept
+//! 3 operands by reference and the rest 3 operands as a continuous array.
+//! This change is purely cosmetic and shouldn't affect users as emit()
+//! has many overloads that dispatch to the right function.
+//!
+//! - \ref x86::Emitter (Assembler, Builder, Compiler) deprecates embed
+//! utilities like `dint8()`, `duint8()`, `duint16()`, `dxmm()`, etc...
+//! in favor of a new and more powerful \ref BaseEmitter::embedDataArray().
+//! This function also allows emitting repeated values and/or patterns,
+//! which is used by helpers \ref BaseEmitter::embedUInt8(), and others...
+//!
+//! - Validation is now available through \ref BaseEmitter::ValidationOptions,
+//! which can be enabled/disabled through \ref BaseEmitter::addValidationOptions()
+//! and \ref BaseEmitter::clearValidationOptions(), respectively. Validation
+//! options now separate between encoding and Builder/Compiler so it's possible
+//! to choose the granularity required.
+//!
+//! Builder changes:
+//!
+//! - Internal functions for creating nodes were redesigned. They now accept
+//! a pointer to the node created as a first parameter. These changes should
+//! not affect AsmJit users as these functions were used internally.
+//!
+//! Compiler changes:
+//!
+//! - `FuncCallNode` has been renamed to \ref InvokeNode. Additionally, function
+//! calls should now use \ref x86::Compiler::invoke() instead of `call()`.
+//! The reason behind this is to remove the confusion between a `call`
+//! instruction and AsmJit's `call()` intrinsic, which is now `invoke()`.
+//!
+//! - Creating new nodes also changed. Now the preferred way of invoking a
+//! function is to call \ref x86::Compiler::invoke() where the first
+//! argument is `InvokeNode**`. The function now returns an error and would
+//! call \ref ErrorHandler in case of a failure. Error handling was
+//! unspecified in the past - the function was marked noexcept, but called
+//! error handler, which could throw.
+//!
+//! The reason behind this change is to make the API consistent with other
+//! changes and to also make it possible to inspect the possible error. In
+//! the previous API it returned a new node or `nullptr` in case of error,
+//! which the user couldn't inspect unless there was an attached \ref
+//! ErrorHandler.
+//!
+//! Samples:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! using namespace asmjit;
+//!
+//! // The basic setup of JitRuntime and CodeHolder changed, use environment()
+//! // instead of codeInfo().
+//! void basicSetup() {
+//! JitRuntime rt;
+//! CodeHolder code(rt.environment());
+//! }
+//!
+//! // Calling a function (Compiler) changed - use invoke() instead of call().
+//! void functionInvocation(x86::Compiler& cc) {
+//! InvokeNode* invokeNode;
+//! cc.invoke(&invokeNode, targetOperand, FuncSignatureT<...>(...));
+//! }
+//! ```
+
+// ============================================================================
+// [Documentation - asmjit_core]
+// ============================================================================
+
//! \defgroup asmjit_core Core
-//! \brief Core API.
+//! \brief Globals, code storage, and emitter interface.
//!
-//! API that provides classes and functions not specific to any architecture.
+//! ### Overview
+//!
+//! AsmJit library uses \ref CodeHolder to hold code during code generation and
+//! emitters inheriting from \ref BaseEmitter to emit code. CodeHolder uses
+//! containers to manage its data:
+//!
+//! - \ref Section - stores information about a code or data section.
+//! - \ref CodeBuffer - stores actual code or data, part of \ref Section.
+//! - \ref LabelEntry - stores information about a label - its name, offset,
+//! section where it belongs to, and other bits.
+//! - \ref LabelLink - stores information about yet unbound label, which was
+//! already used by the assembler.
+//! - \ref RelocEntry - stores information about a relocation.
+//! - \ref AddressTableEntry - stores information about an address, which was
+//! used in a jump or call. Such address may need relocation.
+//!
+//! To generate code you would need to instantiate at least the following classes:
+//!
+//! - \ref CodeHolder - to hold code during code generation.
+//! - \ref BaseEmitter - to emit code into \ref CodeHolder.
+//! - \ref Target (optional) - most likely \ref JitRuntime to keep the generated
+//! code in executable memory. \ref Target can be customized by inheriting from
+//! it.
+//!
+//! There are also other core classes that are important:
+//!
+//! - \ref Environment - describes where the code will run. Environment brings
+//! the concept of target triples or tuples into AsmJit, which means that users
+//! can specify target architecture, platform, and ABI.
+//! - \ref Type - encapsulates lightweight type functionality that can be used
+//! to describe primitive and vector types. Types are used by higher level
+//! utilities, for example by \ref asmjit_function and \ref asmjit_compiler.
+//! - \ref CpuInfo - encapsulates CPU information - stores both CPU information
+//! and features described by \ref BaseFeatures.
+//!
+//! AsmJit also provides global constants:
+//!
+//! - \ref Globals - namespace that provides global constants.
+//! - \ref ByteOrder - byte-order constants and functionality.
+//!
+//! \note CodeHolder examples use \ref x86::Assembler as abstract interfaces cannot
+//! be used to generate code.
+//!
+//! ### CodeHolder & Emitters
+//!
+//! The example below shows how the mentioned classes interact to generate X86 code:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Signature of the generated function.
+//! typedef int (*Func)(void);
+//!
+//! int main() {
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//!
+//! CodeHolder code; // Holds code and relocation information.
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//!
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
+//! a.mov(x86::eax, 1); // Move one to eax register.
+//! a.ret(); // Return from function.
+//! // ===== x86::Assembler is no longer needed from here and can be destroyed =====
+//!
+//! Func fn; // Holds address to the generated function.
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! // ===== CodeHolder is no longer needed from here and can be destroyed =====
+//!
+//! int result = fn(); // Execute the generated code.
+//! printf("%d\n", result); // Print the resulting "1".
+//!
+//! // All classes use RAII, all resources will be released before `main()` returns,
+//! // the generated function can be, however, released explicitly if you intend to
+//! // reuse or keep the runtime alive, which you should in a production-ready code.
+//! rt.release(fn);
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! The example above used \ref x86::Assembler as an emitter. AsmJit provides the
+//! following emitters that offer various levels of abstraction:
+//!
+//! - \ref asmjit_assembler - Low-level emitter that emits directly to \ref CodeBuffer.
+//! - \ref asmjit_builder - Low-level emitter that emits to a \ref BaseNode list.
+//! - \ref asmjit_compiler - High-level emitter that provides register allocation.
+//!
+//! ### Targets and JitRuntime
+//!
+//! AsmJit's \ref Target is an interface that provides basic target abstraction.
+//! At the moment AsmJit provides only one implementation called \ref JitRuntime,
+//! which as the name suggests provides JIT code target and execution runtime.
+//! \ref JitRuntime provides all the necessary stuff to implement a simple JIT
+//! compiler with basic memory management. It only provides \ref JitRuntime::add()
+//! and \ref JitRuntime::release() functions that are used to either add code
+//! to the runtime or release it. \ref JitRuntime doesn't do any decisions on
+//! when the code should be released, the decision is up to the developer.
+//!
+//! See more at \ref asmjit_virtual_memory group.
+//!
+//! ### More About Environment
+//!
+//! In the previous example the \ref Environment is retrieved from \ref JitRuntime.
+//! It's logical as \ref JitRuntime always returns an \ref Environment that is
+//! compatible with the host. For example if your application runs in 64-bit mode
+//! the \ref Environment returned will use \ref Environment::kArchX64 architecture
+//! in contrast to \ref Environment::kArchX86, which will be used in 32-bit mode on
+//! any X86 platform.
+//!
+//! AsmJit allows to setup the \ref Environment manually and to select a different
+//! architecture and ABI when necessary. So let's do something else this time, let's
+//! always generate a 32-bit code and print its binary representation. To do that, we
+//! can create our own \ref Environment and initialize it to \ref Environment::kArchX86.
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! int main(int argc, char* argv[]) {
+//! using namespace asmjit::x86;
+//!
+//! // Create a custom environment initialized to 32-bit X86 architecture.
+//! Environment env;
+//! env.setArch(Environment::kArchX86);
+//!
+//! CodeHolder code; // Create a CodeHolder.
+//! code.init(env); // Initialize CodeHolder with custom environment.
+//!
+//! // Generate a 32-bit function that sums 4 floats and looks like:
+//! // void func(float* dst, const float* a, const float* b)
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`.
+//!
+//! a.mov(eax, dword_ptr(esp, 4)); // Load the destination pointer.
+//! a.mov(ecx, dword_ptr(esp, 8)); // Load the first source pointer.
+//! a.mov(edx, dword_ptr(esp, 12)); // Load the second source pointer.
+//!
+//! a.movups(xmm0, ptr(ecx)); // Load 4 floats from [ecx] to XMM0.
+//! a.movups(xmm1, ptr(edx)); // Load 4 floats from [edx] to XMM1.
+//! a.addps(xmm0, xmm1); // Add 4 floats in XMM1 to XMM0.
+//! a.movups(ptr(eax), xmm0); // Store the result to [eax].
+//! a.ret(); // Return from function.
+//!
+//! // We have no Runtime this time, it's on us what we do with the code.
+//! // CodeHolder stores code in Section, which provides some basic properties
+//! // and CodeBuffer structure. We are interested in section's CodeBuffer.
+//! //
+//! // NOTE: The first section is always '.text', it can be retrieved by
+//! // code.sectionById(0) or simply by code.textSection().
+//! CodeBuffer& buffer = code.textSection()->buffer();
+//!
+//! // Print the machine-code generated or do something else with it...
+//! // 8B4424048B4C24048B5424040F28010F58010F2900C3
+//! for (size_t i = 0; i < buffer.length; i++)
+//! printf("%02X", buffer.data[i]);
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! ### Explicit Code Relocation
+//!
+//! In addition to \ref Environment, \ref CodeHolder can be configured to
+//! specify a base-address (or a virtual base-address in a linker terminology),
+//! which could be static (useful when you know the location where the target's
+//! machine code will be) or dynamic. AsmJit assumes dynamic base-address by
+//! default and relocates the code held by \ref CodeHolder to a user provided
+//! address on-demand. To be able to relocate to a user provided address it needs
+//! to store some information about relocations, which is represented by \ref
+//! RelocEntry. Relocation entries are only required if you call external functions
+//! from the generated code that cannot be encoded by using a 32-bit displacement
+//! (64-bit displacements are not provided by aby supported architecture).
+//!
+//! There is also a concept called \ref LabelLink - label link is a lightweight
+//! data structure that doesn't have any identifier and is stored in \ref LabelEntry
+//! as a single-linked list. Label link represents either unbound yet used label
+//! and cross-sections links (only relevant to code that uses multiple sections).
+//! Since crossing sections is something that cannot be resolved immediately these
+//! links persist until offsets of these sections are assigned and until
+//! \ref CodeHolder::resolveUnresolvedLinks() is called. It's an error if you end
+//! up with code that has unresolved label links after flattening. You can verify
+//! it by calling \ref CodeHolder::hasUnresolvedLinks(), which inspects the value
+//! returned by \ref CodeHolder::unresolvedLinkCount().
+//!
+//! AsmJit can flatten code that uses multiple sections by assigning each section
+//! an incrementing offset that respects its alignment. Use \ref CodeHolder::flatten()
+//! to do that. After the sections are flattened their offsets and virtual-sizes
+//! are adjusted to respect each section's buffer size and alignment. The \ref
+//! CodeHolder::resolveUnresolvedLinks() function must be called before relocating
+//! the code held by \ref CodeHolder. You can also flatten your code manually by
+//! iterating over all sections and calculating their offsets (relative to base)
+//! by your own algorithm. In that case \ref CodeHolder::flatten() should not be
+//! called, however, \ref CodeHolder::resolveUnresolvedLinks() should be.
+//!
+//! The example below shows how to use a built-in virtual memory allocator
+//! \ref JitAllocator instead of using \ref JitRuntime (just in case you want
+//! to use your own memory management) and how to relocate the generated code
+//! into your own memory block - you can use your own virtual memory allocator
+//! if you prefer that, but that's OS specific and not covered by the documentation.
+//!
+//! The following code is similar to the previous one, but implements a function
+//! working in both 32-bit and 64-bit environments:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! typedef void (*SumIntsFunc)(int* dst, const int* a, const int* b);
+//!
+//! int main() {
+//! // Create a custom environment that matches the current host environment.
+//! Environment env = hostEnvironment();
+//!
+//! CodeHolder code; // Create a CodeHolder.
+//! code.init(env); // Initialize CodeHolder with environment.
+//!
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`.
+//!
+//! // Signature: 'void func(int* dst, const int* a, const int* b)'.
+//! x86::Gp dst;
+//! x86::Gp src_a;
+//! x86::Gp src_b;
+//!
+//! // Handle the difference between 32-bit and 64-bit calling conventions
+//! // (arguments passed through stack vs. arguments passed by registers).
+//! if (env.is32Bit()) {
+//! dst = x86::eax;
+//! src_a = x86::ecx;
+//! src_b = x86::edx;
+//! a.mov(dst , x86::dword_ptr(x86::esp, 4));
+//! a.mov(src_a, x86::dword_ptr(x86::esp, 8));
+//! a.mov(src_b, x86::dword_ptr(x86::esp, 12));
+//! }
+//! else {
+//! if (env.isPlatformWindows()) {
+//! dst = x86::rcx; // First argument (destination pointer).
+//! src_a = x86::rdx; // Second argument (source 'a' pointer).
+//! src_b = x86::r8; // Third argument (source 'b' pointer).
+//! }
+//! else {
+//! dst = x86::rdi; // First argument (destination pointer).
+//! src_a = x86::rsi; // Second argument (source 'a' pointer).
+//! src_b = x86::rdx; // Third argument (source 'b' pointer).
+//! }
+//! }
+//!
+//! a.movdqu(x86::xmm0, x86::ptr(src_a)); // Load 4 ints from [src_a] to XMM0.
+//! a.movdqu(x86::xmm1, x86::ptr(src_b)); // Load 4 ints from [src_b] to XMM1.
+//! a.paddd(x86::xmm0, x86::xmm1); // Add 4 ints in XMM1 to XMM0.
+//! a.movdqu(x86::ptr(dst), x86::xmm0); // Store the result to [dst].
+//! a.ret(); // Return from function.
+//!
+//! // Even when we didn't use multiple sections AsmJit could insert one section
+//! // called '.addrtab' (address table section), which would be filled by data
+//! // required by relocations (absolute jumps and calls). You can omit this code
+//! // if you are 100% sure your code doesn't contain multiple sections and
+//! // such relocations. You can use `CodeHolder::hasAddressTable()` to verify
+//! // whether the address table section does exist.
+//! code.flatten();
+//! code.resolveUnresolvedLinks();
+//!
+//! // After the code was generated it can be relocated manually to any memory
+//! // location, however, we need to know it's size before we perform memory
+//! // allocation. `CodeHolder::codeSize()` returns the worst estimated code
+//! // size in case that relocations are not possible without trampolines (in
+//! // that case some extra code at the end of the current code buffer is
+//! // generated during relocation).
+//! size_t estimatedSize = code.codeSize();
+//!
+//! // Instead of rolling up our own memory allocator we can use the one AsmJit
+//! // provides. It's decoupled so you don't need to use `JitRuntime` for that.
+//! JitAllocator allocator;
+//!
+//! // Allocate an executable virtual memory and handle a possible failure.
+//! void* p = allocator.alloc(estimatedSize);
+//! if (!p)
+//! return 0;
+//!
+//! // Now relocate the code to the address provided by the memory allocator.
+//! // Please note that this DOESN'T COPY anything to `p`. This function will
+//! // store the address in CodeHolder and use relocation entries to patch the
+//! // existing code in all sections to respect the base address provided.
+//! code.relocateToBase((uint64_t)p);
+//!
+//! // This is purely optional. There are cases in which the relocation can omit
+//! // unneeded data, which would shrink the size of address table. If that
+//! // happened the codeSize returned after relocateToBase() would be smaller
+//! // than the originally `estimatedSize`.
+//! size_t codeSize = code.codeSize();
+//!
+//! // This will copy code from all sections to `p`. Iterating over all sections
+//! // and calling `memcpy()` would work as well, however, this function supports
+//! // additional options that can be used to also zero pad sections' virtual
+//! // size, etc.
+//! //
+//! // With some additional features, copyFlattenData() does roughly this:
+//! // for (Section* section : code.sections())
+//! // memcpy((uint8_t*)p + section->offset(),
+//! // section->data(),
+//! // section->bufferSize());
+//! code.copyFlattenedData(p, codeSize, CodeHolder::kCopyPadSectionBuffer);
+//!
+//! // Execute the generated function.
+//! int inA[4] = { 4, 3, 2, 1 };
+//! int inB[4] = { 1, 5, 2, 8 };
+//! int out[4];
+//!
+//! // This code uses AsmJit's ptr_as_func<> to cast between void* and SumIntsFunc.
+//! ptr_as_func<SumIntsFunc>(p)(out, inA, inB);
+//!
+//! // Prints {5 8 4 9}
+//! printf("{%d %d %d %d}\n", out[0], out[1], out[2], out[3]);
+//!
+//! // Release 'p' is it's no longer needed. It will be destroyed with 'vm'
+//! // instance anyway, but it's a good practice to release it explicitly
+//! // when you know that the function will not be needed anymore.
+//! allocator.release(p);
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! If you know the base-address in advance (before the code generation) it can
+//! be passed as a second argument to \ref CodeHolder::init(). In that case the
+//! Assembler will know the absolute position of each instruction and would be
+//! able to use it during instruction encoding to prevent relocations where
+//! possible. The following example shows how to configure the base address:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! void initializeCodeHolder(CodeHolder& code) {
+//! Environment env = hostEnvironment();
+//! uint64_t baseAddress = uint64_t(0x1234);
+//!
+//! // initialize CodeHolder with environment and custom base address.
+//! code.init(env, baseAddress);
+//! }
+//! ```
+//!
+//! ### Label Offsets and Links
+//!
+//! When a label that is not yet bound is used by the Assembler, it creates a
+//! \ref LabelLink, which is then added to a \ref LabelEntry. These links are
+//! also created if a label is used in a different section than in which it
+//! was bound. Let's examine some functions that can be used to check whether
+//! there are any unresolved links.
+//!
+//! ```
+//! #include <asmjit/core.h>
+//! #include <stdio.h>
+//!
+//! void labelLinksExample(CodeHolder& code, const Label& label) {
+//! // Tests whether the `label` is bound.
+//! bool isBound = code.isLabelBound(label);
+//! printf("Label %u is %s\n", label.id(), isBound ? "bound" : "not bound");
+//!
+//! // Returns true if the code contains either referenced, but unbound
+//! // labels, or cross-section label links that are not resolved yet.
+//! bool hasUnresolved = code.hasUnresolvedLinks(); // Boolean answer.
+//! size_t nUnresolved = code.unresolvedLinkCount(); // Count of unresolved links.
+//!
+//! printf("Number of unresolved links: %zu\n", nUnresolved);
+//! }
+//! ```
+//!
+//! There is no function that would return the number of unbound labels as this
+//! is completely unimportant from CodeHolder's perspective. If a label is not
+//! used then it doesn't matter whether it's bound or not, only actually used
+//! labels matter. After a Label is bound it's possible to query its offset
+//! offset relative to the start of the section where it was bound:
+//!
+//! ```
+//! #include <asmjit/core.h>
+//! #include <stdio.h>
+//!
+//! void labelOffsetExample(CodeHolder& code, const Label& label) {
+//! // Label offset is known after it's bound. The offset provided is relative
+//! // to the start of the section, see below for alternative. If the given
+//! // label is not bound the offset returned will be zero. It's recommended
+//! // to always check whether the label is bound before using its offset.
+//! uint64_t sectionOffset = code.labelOffset(label);
+//! printf("Label offset relative to section: %llu\n", (unsigned long long)sectionOffset);
+//!
+//! // If you use multiple sections and want the offset relative to the base.
+//! // NOTE: This function expects that the section has already an offset and
+//! // the label-link was resolved (if this is not true you will still get an
+//! // offset relative to the start of the section).
+//! uint64_t baseOffset = code.labelOffsetFromBase(label);
+//! printf("Label offset relative to base: %llu\n", (unsigned long long)baseOffset);
+//! }
+//! ```
+//!
+//! ### Sections
+//!
+//! AsmJit allows to create multiple sections within the same \ref CodeHolder.
+//! A test-case [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp)
+//! can be used as a reference point although the following example should
+//! also provide a useful insight:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! void sectionsExample(CodeHolder& code) {
+//! // Text section is always provided as the first section.
+//! Section* text = code.textSection(); // or code.sectionById(0);
+//!
+//! // To create another section use CodeHolder::newSection().
+//! Section* data;
+//! Error err = code.newSection(&data,
+//! ".data", // Section name
+//! SIZE_MAX, // Name length if the name is not null terminated (or SIZE_MAX).
+//! 0, // Section flags, see Section::Flags.
+//! 8); // Section alignment, must be power of 2.
+//!
+//! // When you switch sections in Assembler, Builder, or Compiler the cursor
+//! // will always move to the end of that section. When you create an Assembler
+//! // the cursor would be placed at the end of the first (.text) section, which
+//! // is initially empty.
+//! x86::Assembler a(&code);
+//! Label L_Data = a.newLabel();
+//!
+//! a.mov(x86::eax, x86::ebx); // Emits in .text section.
+//!
+//! a.section(data); // Switches to the end of .data section.
+//! a.bind(L_Data); // Binds label in this .data section
+//! a.db(0x01); // Emits byte in .data section.
+//!
+//! a.section(text); // Switches to the end of .text section.
+//! a.add(x86::ebx, x86::eax); // Emits in .text section.
+//!
+//! // References a label in .text section, which was bound in .data section.
+//! // This would create a LabelLink even when the L_Data is already bound,
+//! // because the reference crosses sections. See below...
+//! a.lea(x86::rsi, x86::ptr(L_Data));
+//! }
+//! ```
+//!
+//! The last line in the example above shows that a LabelLink would be created
+//! even for bound labels that cross sections. In this case a referenced label
+//! was bound in another section, which means that the link couldn't be resolved
+//! at that moment. If your code uses sections, but you wish AsmJit to flatten
+//! these sections (you don't plan to flatten them manually) then there is an
+//! API for that.
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! // ... (continuing the previous example) ...
+//! void sectionsExampleContinued(CodeHolder& code) {
+//! // Suppose we have some code that contains multiple sections and
+//! // we would like to flatten it by using AsmJit's built-in API:
+//! Error err = code.flatten();
+//! if (err) {
+//! // There are many reasons it can fail, so always handle a possible error.
+//! printf("Failed to flatten the code: %s\n", DebugUtils::errorAsString(err));
+//! exit(1);
+//! }
+//!
+//! // After flattening all sections would contain assigned offsets
+//! // relative to base. Offsets are 64-bit unsigned integers so we
+//! // cast them to `size_t` for simplicity. On 32-bit targets it's
+//! // guaranteed that the offset cannot be greater than `2^32 - 1`.
+//! printf("Data section offset %zu", size_t(data->offset()));
+//!
+//! // The flattening doesn't resolve unresolved label links, this
+//! // has to be done manually as flattening can be done separately.
+//! err = code.resolveUnresolvedLinks();
+//! if (err) {
+//! // This is the kind of error that should always be handled...
+//! printf("Failed to resolve label links: %s\n", DebugUtils::errorAsString(err));
+//! exit(1);
+//! }
+//!
+//! if (code.hasUnresolvedLinks()) {
+//! // This would mean either unbound label or some other issue.
+//! printf("The code has %zu unbound labels\n", code.unresovedLinkCount());
+//! exit(1);
+//! }
+//! }
+//! ```
+
+// ============================================================================
+// [Documentation - asmjit_assembler]
+// ============================================================================
+
+//! \defgroup asmjit_assembler Assembler
+//! \brief Assembler interface and operands.
+//!
+//! ### Overview
+//!
+//! AsmJit's Assembler is used to emit machine code directly into a \ref
+//! CodeBuffer. In general, code generation with assembler requires the knowledge
+//! of the following:
+//!
+//! - \ref BaseAssembler and architecture-specific assemblers:
+//! - \ref x86::Assembler - Assembler specific to X86 architecture
+//! - \ref Operand and its variations:
+//! - \ref BaseReg - Base class for a register operand, inherited by:
+//! - \ref x86::Reg - Register operand specific to X86 architecture.
+//! - \ref BaseMem - Base class for a memory operand, inherited by:
+//! - \ref x86::Mem - Memory operand specific to X86 architecture.
+//! - \ref Imm - Immediate (value) operand.
+//! - \ref Label - Label operand.
+//!
+//! \note Assembler examples use \ref x86::Assembler as abstract interfaces cannot
+//! be used to generate code.
+//!
+//! ### Operand Basics
+//!
+//! Let's start with operands. \ref Operand is a data structure that defines a
+//! data layout of any operand. It can be inherited, but any class inheriting
+//! it cannot add any members to it, only the existing layout can be reused.
+//! AsmJit allows to construct operands dynamically, to store them, and to query
+//! a complete information about them at run-time. Operands are small (always 16
+//! bytes per \ref Operand) and can be copied and passed by value. Please never
+//! allocate individual operands dynamically by using a `new` keyword - it would
+//! work, but then you would have to be responsible for deleting such operands.
+//! In AsmJit operands are always part of some other data structures like \ref
+//! InstNode, which is part of \ref asmjit_builder tool.
+//!
+//! Operands contain only identifiers, but not pointers to any code-generation data.
+//! For example \ref Label operand only provides label identifier, but not a pointer
+//! to \ref LabelEntry structure. In AsmJit such IDs are used to link stuff together
+//! without having to deal with pointers.
+//!
+//! AsmJit's operands all inherit from a base class called \ref Operand. Operands
+//! have the following properties that are commonly accessible by getters and setters:
+//!
+//! - \ref Operand - Base operand, which only provides accessors that are common
+//! to all operand types.
+//! - \ref BaseReg - Describes either physical or virtual register. Physical
+//! registers have id that matches the target's machine id directly whereas
+//! virtual registers must be allocated into physical registers by a register
+//! allocator pass. Register operand provides:
+//! - Register Type - Unique id that describes each possible register provided
+//! by the target architecture - for example X86 backend provides \ref
+//! x86::Reg::RegType, which defines all variations of general purpose registers
+//! (GPB-LO, GPB-HI, GPW, GPD, and GPQ) and all types of other registers like K,
+//! MM, BND, XMM, YMM, and ZMM.
+//! - Register Group - Groups multiple register types under a single group - for
+//! example all general-purpose registers (of all sizes) on X86 are part of
+//! \ref x86::Reg::kGroupGp and all SIMD registers (XMM, YMM, ZMM) are part
+//! of \ref x86::Reg::kGroupVec.
+//! - Register Size - Contains the size of the register in bytes. If the size
+//! depends on the mode (32-bit vs 64-bit) then generally the higher size is
+//! used (for example RIP register has size 8 by default).
+//! - Register Id - Contains physical or virtual id of the register.
+//! - \ref BaseMem - Used to reference a memory location. Memory operand provides:
+//! - Base Register - A base register type and id (physical or virtual).
+//! - Index Register - An index register type and id (physical or virtual).
+//! - Offset - Displacement or absolute address to be referenced (32-bit if base
+//! register is used and 64-bit if base register is not used).
+//! - Flags that can describe various architecture dependent information (like
+//! scale and segment-override on X86).
+//! - \ref Imm - Immediate values are usually part of instructions (encoded within
+//! the instruction itself) or data.
+//! - \ref Label - used to reference a location in code or data. Labels must be
+//! created by the \ref BaseEmitter or by \ref CodeHolder. Each label has its
+//! unique id per \ref CodeHolder instance.
+//!
+//! ### Operand Manipulation
+//!
+//! AsmJit allows to construct operands dynamically, to store them, and to query
+//! a complete information about them at run-time. Operands are small (always 16
+//! bytes per `Operand`) and should be always copied (by value) if you intend to
+//! store them (don't create operands by using `new` keyword, it's not recommended).
+//! Operands are safe to be passed to `memcpy()` and `memset()`, which becomes
+//! handy when working with arrays of operands. If you set all members of an \ref
+//! Operand to zero the operand would become NONE operand, which is the same as a
+//! default constructed Operand.
+//!
+//! The example below illustrates how operands can be used and modified even
+//! without using any other code generation classes. The example uses X86
+//! architecture-specific operands.
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Registers can be copied, it's a common practice.
+//! x86::Gp dstRegByValue() { return x86::ecx; }
+//!
+//! void usingOperandsExample(x86::Assembler& a) {
+//! // Gets `ecx` register returned by a function.
+//! x86::Gp dst = dstRegByValue();
+//! // Gets `rax` register directly from the provided `x86` namespace.
+//! x86::Gp src = x86::rax;
+//! // Constructs `r10` dynamically.
+//! x86::Gp idx = x86::gpq(10);
+//! // Constructs [src + idx] memory address - referencing [rax + r10].
+//! x86::Mem m = x86::ptr(src, idx);
+//!
+//! // Examine `m`: Returns `x86::Reg::kTypeGpq`.
+//! m.indexType();
+//! // Examine `m`: Returns 10 (`r10`).
+//! m.indexId();
+//!
+//! // Reconstruct `idx` stored in mem:
+//! x86::Gp idx_2 = x86::Gp::fromTypeAndId(m.indexType(), m.indexId());
+//!
+//! // True, `idx` and idx_2` are identical.
+//! idx == idx_2;
+//!
+//! // Possible - op will still be the same as `m`.
+//! Operand op = m;
+//! // True (can be casted to BaseMem or architecture-specific Mem).
+//! op.isMem();
+//!
+//! // True, `op` is just a copy of `m`.
+//! m == op;
+//!
+//! // Static cast is fine and valid here.
+//! static_cast<BaseMem&>(op).addOffset(1);
+//! // However, using `as<T>()` to cast to a derived type is preferred.
+//! op.as<BaseMem>().addOffset(1);
+//! // False, `op` now points to [rax + r10 + 2], which is not [rax + r10].
+//! m == op;
+//!
+//! // Emitting 'mov' - type safe way.
+//! a.mov(dst, m);
+//! // Not possible, `mov` doesn't provide mov(x86::Gp, Operand) overload.
+//! a.mov(dst, op);
+//!
+//! // Type-unsafe, but possible.
+//! a.emit(x86::Inst::kIdMov, dst, m);
+//! // Also possible, `emit()` is typeless and can be used with raw Operand.
+//! a.emit(x86::Inst::kIdMov, dst, op);
+//! }
+//! ```
+//!
+//! Some operands have to be created explicitly by emitters. For example labels
+//! must be created by \ref BaseEmitter::newLabel(), which creates a label entry
+//! and returns a \ref Label operand with the id that refers to it. Such label
+//! then can be used by emitters.
+//!
+//! ### Memory Operands
+//!
+//! Some architectures like X86 provide a complex memory addressing model that
+//! allows to encode addresses having a BASE register, INDEX register with a
+//! possible scale (left shift), and displacement (called offset in AsmJit).
+//! Memory address on X86 can also specify memory segment (segment-override in
+//! X86 terminology) and some instructions (gather / scatter) require INDEX to
+//! be a \ref x86::Vec register instead of a general-purpose register.
+//!
+//! AsmJit allows to encode and work with all forms of addresses mentioned and
+//! implemented by X86. In addition, it also allows to construct absolute 64-bit
+//! memory address operands, which is only allowed in one form of 'mov' instruction.
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! void testX86Mem() {
+//! // Makes it easier to access x86 stuff...
+//! using namespace asmjit::x86;
+//!
+//! // BASE + OFFSET.
+//! Mem a = ptr(rax); // a = [rax]
+//! Mem b = ptr(rax, 15); // b = [rax + 15]
+//!
+//! // BASE + INDEX << SHIFT - Shift is in BITS as used by X86!
+//! Mem c = ptr(rax, rbx); // c = [rax + rbx]
+//! Mem d = ptr(rax, rbx, 2); // d = [rax + rbx << 2]
+//! Mem e = ptr(rax, rbx, 2, 15); // e = [rax + rbx << 2 + 15]
+//!
+//! // BASE + VM (Vector Index) (encoded as MOD+VSIB).
+//! Mem f = ptr(rax, xmm1); // f = [rax + xmm1]
+//! Mem g = ptr(rax, xmm1, 2); // g = [rax + xmm1 << 2]
+//! Mem h = ptr(rax, xmm1, 2, 15); // h = [rax + xmm1 << 2 + 15]
+//!
+//! // Absolute adddress:
+//! uint64_t addr = (uint64_t)0x1234;
+//! Mem i = ptr(addr); // i = [0x1234]
+//! Mem j = ptr(addr, rbx); // j = [0x1234 + rbx]
+//! Mem k = ptr(addr, rbx, 2); // k = [0x1234 + rbx << 2]
+//!
+//! // LABEL - Will be encoded as RIP (64-bit) or absolute address (32-bit).
+//! Label L = ...;
+//! Mem m = ptr(L); // m = [L]
+//! Mem n = ptr(L, rbx); // n = [L + rbx]
+//! Mem o = ptr(L, rbx, 2); // o = [L + rbx << 2]
+//! Mem p = ptr(L, rbx, 2, 15); // p = [L + rbx << 2 + 15]
+//!
+//! // RIP - 64-bit only (RIP can't use INDEX).
+//! Mem q = ptr(rip, 24); // q = [rip + 24]
+//! }
+//! ```
+//!
+//! Memory operands can optionally contain memory size. This is required by
+//! instructions where the memory size cannot be deduced from other operands,
+//! like `inc` and `dec` on X86:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! void testX86Mem() {
+//! // The same as: dword ptr [rax + rbx].
+//! x86::Mem a = x86::dword_ptr(rax, rbx);
+//!
+//! // The same as: qword ptr [rdx + rsi << 0 + 1].
+//! x86::Mem b = x86::qword_ptr(rdx, rsi, 0, 1);
+//! }
+//! ```
+//!
+//! Memory operands provide API that can be used to access its properties:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! void testX86Mem() {
+//! // The same as: dword ptr [rax + 12].
+//! x86::Mem mem = x86::dword_ptr(rax, 12);
+//!
+//! mem.hasBase(); // true.
+//! mem.hasIndex(); // false.
+//! mem.size(); // 4.
+//! mem.offset(); // 12.
+//!
+//! mem.setSize(0); // Sets the size to 0 (makes it sizeless).
+//! mem.addOffset(-1); // Adds -1 to the offset and makes it 11.
+//! mem.setOffset(0); // Sets the offset to 0.
+//! mem.setBase(rcx); // Changes BASE to RCX.
+//! mem.setIndex(rax); // Changes INDEX to RAX.
+//! mem.hasIndex(); // true.
+//! }
+//! // ...
+//! ```
+//!
+//! Making changes to memory operand is very comfortable when emitting loads
+//! and stores:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! void testX86Mem(CodeHolder& code) {
+//! x86::Assembler a(code); // Your initialized x86::Assembler.
+//! x86::Mem mSrc = x86::ptr(eax); // Construct [eax] memory operand.
+//!
+//! // One way of emitting bunch of loads is to use `mem.adjusted()`, which
+//! // returns a new memory operand and keeps the source operand unchanged.
+//! a.movaps(x86::xmm0, mSrc); // No adjustment needed to load [eax].
+//! a.movaps(x86::xmm1, mSrc.adjusted(16)); // Loads from [eax + 16].
+//! a.movaps(x86::xmm2, mSrc.adjusted(32)); // Loads from [eax + 32].
+//! a.movaps(x86::xmm3, mSrc.adjusted(48)); // Loads from [eax + 48].
+//!
+//! // ... do something with xmm0-3 ...
+//!
+//! // Another way of adjusting memory is to change the operand in-place.
+//! // If you want to keep the original operand you can simply clone it.
+//! x86::Mem mDst = mSrc.clone(); // Clone mSrc.
+//!
+//! a.movaps(mDst, x86::xmm0); // Stores xmm0 to [eax].
+//! mDst.addOffset(16); // Adds 16 to `mDst`.
+//!
+//! a.movaps(mDst, x86::xmm1); // Stores to [eax + 16] .
+//! mDst.addOffset(16); // Adds 16 to `mDst`.
+//!
+//! a.movaps(mDst, x86::xmm2); // Stores to [eax + 32].
+//! mDst.addOffset(16); // Adds 16 to `mDst`.
+//!
+//! a.movaps(mDst, x86::xmm3); // Stores to [eax + 48].
+//! }
+//! ```
+//!
+//! ### Assembler Examples
+//!
+//! - \ref x86::Assembler provides many X86/X64 examples.
+
+// ============================================================================
+// [Documentation - asmjit_builder]
+// ============================================================================
//! \defgroup asmjit_builder Builder
-//! \brief Builder API.
+//! \brief Builder interface, nodes, and passes.
+//!
+//! ### Overview
+//!
+//! Both \ref BaseBuilder and \ref BaseCompiler interfaces describe emitters
+//! that emit into a representation that allows further processing. The code
+//! stored in such representation is completely safe to be patched, simplified,
+//! reordered, obfuscated, removed, injected, analyzed, or processed some other
+//! way. Each instruction, label, directive, or other building block is stored
+//! as \ref BaseNode (or derived class like \ref InstNode or \ref LabelNode)
+//! and contains all the information necessary to pass that node later to the
+//! assembler.
+//!
+//! \ref BaseBuilder is an emitter that inherits from \ref BaseEmitter interface.
+//! It was designed to provide a maximum compatibility with the existing \ref
+//! BaseAssembler emitter so users can move from assembler to builder when needed,
+//! for example to implement post-processing, which is not possible with Assembler.
+//!
+//! ### Builder Nodes
+//!
+//! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate
+//! representation based on nodes, however, it allows to serialize to \ref BaseAssembler
+//! when the code is ready to be encoded.
//!
-//! Both Builder and Compiler are emitters that emit everything to a representation
-//! that allows further processing. The code stored in such representation is
-//! completely safe to be patched, simplified, reordered, obfuscated, removed,
-//! injected, analyzed, or processed some other way. Each instruction, label,
-//! directive, or other building block is stored as \ref BaseNode (or derived
-//! class like \ref InstNode or \ref LabelNode) and contains all the information
-//! necessary to pass that node later to the Assembler.
+//! There are multiple node types used by both \ref BaseBuilder and \ref BaseCompiler :
+//!
+//! - Basic nodes:
+//! - \ref BaseNode - Base class for all nodes.
+//! - \ref InstNode - Represents an instruction node.
+//! - \ref AlignNode - Represents an alignment directive (.align).
+//! - \ref LabelNode - Represents a location where to bound a \ref Label.
+//!
+//! - Data nodes:
+//! - \ref EmbedDataNode - Represents data.
+//! - \ref EmbedLabelNode - Represents \ref Label address embedded as data.
+//! - \ref EmbedLabelDeltaNode - Represents a difference of two labels
+//! embedded in data.
+//! - \ref ConstPoolNode - Represents a constant pool data embedded as data.
+//!
+//! - Informative nodes:
+//! - \ref CommentNode - Represents a comment string, doesn't affect code
+//! generation.
+//! - \ref SentinelNode - A marker that can be used to remember certain
+//! position in code or data, doesn't affect code generation. Used by
+//! \ref FuncNode to mark the end of a function.
+//!
+//! - Other nodes are provided by \ref asmjit_compiler infrastructure.
+//!
+//! ### Builder Examples
+//!
+//! - \ref x86::Builder provides many X86/X64 examples.
+
+// ============================================================================
+// [Documentation - asmjit_compiler]
+// ============================================================================
//! \defgroup asmjit_compiler Compiler
-//! \brief Compiler API.
+//! \brief Compiler interface.
+//!
+//! ### Overview
+//!
+//! \ref BaseCompiler is a high-level interface built on top of \ref BaseBuilder
+//! interface, which provides register allocation and support for defining and
+//! invoking functions. At the moment it's the easiest way of generating code
+//! in AsmJit as most architecture and OS specifics is properly abstracted and
+//! handled by AsmJit automatically. However, abstractions also mean restrictions,
+//! which means that \ref BaseCompiler has more limitations that \ref BaseAssembler
+//! or \ref BaseBuilder.
+//!
+//! Since \ref BaseCompiler provides register allocation it also establishes the
+//! concept of functions - a function in Compiler sense is a unit in which virtual
+//! registers are allocated into physical registers by the register allocator.
+//! In addition, it enables to use such virtual registers in function invocations.
+//!
+//! \ref BaseCompiler automatically handles function calling conventions. It's
+//! still architecture dependent, but makes the code generation much easies.
+//! Functions are essential; the first-step to generate some code is to define a
+//! signature of the function to be generated (before generating the function body
+//! itself). Function arguments and return value(s) are handled by assigning
+//! virtual registers to them. Similarly, function calls are handled the same way.
+//!
+//! ### Compiler Nodes
+//!
+//! \ref BaseCompiler adds some nodes that are required for function generation
+//! and invocation:
+//!
+//! - \ref FuncNode - Represents a function definition.
+//! - \ref FuncRetNode - Represents a function return.
+//! - \ref InvokeNode - Represents a function invocation.
+//!
+//! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically
+//! adds an architecture-dependent register allocator pass to the list of passes
+//! when attached to \ref CodeHolder.
+//!
+//! ### Compiler Examples
+//!
+//! - \ref x86::Compiler provides many X86/X64 examples.
+//!
+//! ### Compiler Tips
+//!
+//! Users of AsmJit have done mistakes in the past, this section should provide
+//! some useful tips for beginners:
+//!
+//! - Virtual registers in compiler are bound to a single function. At the
+//! moment the implementation doesn't care whether a single virtual register
+//! is used in multiple functions, but it sees it as two independent virtual
+//! registers in that case. This means that virtual registers cannot be used
+//! to implement global variables. Global variables are basically memory
+//! addresses which functions can read from and write to, and they have to
+//! be implemented in the same way.
+//!
+//! - Compiler provides a useful debugging functionality, which can be turned
+//! on through \ref FormatOptions::Flags. Use \ref Logger::addFlags() to
+//! turn on additional logging features when using Compiler.
+
+// ============================================================================
+// [Documentation - asmjit_function]
+// ============================================================================
+
+//! \defgroup asmjit_function Function
+//! \brief Function definitions.
+//!
+//! ### Overview
+//!
+//! AsmJit provides functionality that can be used to define function signatures
+//! and to calculate automatically optimal function frame that can be used directly
+//! by a prolog and epilog insertion. This feature was exclusive to AsmJit's Compiler
+//! for a very long time, but was abstracted out and is now available for all users
+//! regardless of the emitter they use. The following use cases are possible:
+//!
+//! - Calculate function frame before the function is generated - this is the
+//! only way available to \ref BaseAssembler users and it will be described
+//! in this section.
+//!
+//! - Calculate function frame after the function is generated - this way is
+//! generally used by \ref BaseBuilder and \ref BaseCompiler emitters and
+//! this way is generally described in \ref asmjit_compiler section.
+//!
+//! The following concepts are used to describe and create functions in AsmJit:
+//!
+//! - \ref Type::Id - Type-id is an 8-bit value that describes a platform
+//! independent type as we know from C/C++. It provides abstractions for
+//! most common types like `int8_t`, `uint32_t`, `uintptr_t`, `float`,
+//! `double`, and all possible vector types to match ISAs up to AVX512.
+//! \ref Type::Id was introduced originally for \ref asmjit_compiler, but
+//! it's now used by \ref FuncSignature as well.
+//!
+//! - \ref CallConv - Describes a calling convention - this class contains
+//! instructions to assign registers and stack addresses to function
+//! arguments and return value(s), but doesn't specify any function
+//! signature itself. Calling conventions are architecture and OS dependent.
+//!
+//! - \ref FuncSignature - Describes a function signature, for example
+//! `int func(int, int)`. FuncSignature contains a function calling convention
+//! id, return value type, and function arguments. The signature itself is
+//! platform independent and uses \ref Type::Id to describe types of function
+//! arguments and function return value(s).
+//!
+//! - \ref FuncDetail - Architecture and ABI dependent information that describes
+//! \ref CallConv and expanded \ref FuncSignature. Each function argument and
+//! return value is represented as \ref FuncValue that contains the original
+//! \ref Type::Id enriched with additional information that specifies whether
+//! the value is passed or returned by register (and which register) or by
+//! stack. Each value also contains some other metadata that provide additional
+//! information required to handle it properly (for example whether a vector is
+//! passed indirectly by a pointer as required by WIN64 calling convention).
+//!
+//! - \ref FuncFrame - Contains information about the function frame that can
+//! be used by prolog/epilog inserter (PEI). Holds call stack size size and
+//! alignment, local stack size and alignment, and various attributes that
+//! describe how prolog and epilog should be constructed. `FuncFrame` doesn't
+//! know anything about function's arguments or return values, it hold only
+//! information necessary to create a valid and ABI conforming function prologs
+//! and epilogs.
+//!
+//! - \ref FuncArgsAssignment - A helper class that can be used to reassign
+//! function arguments into user specified registers. It's architecture and
+//! ABI dependent mapping from function arguments described by \ref CallConv
+//! and \ref FuncDetail into registers specified by the user.
+//!
+//! It's a lot of concepts where each represents one step in a function frame
+//! calculation. It can be used to create function prologs, epilogs, and also
+//! to calculate information necessary to perform function calls.
+
+// ============================================================================
+// [Documentation - asmjit_logging]
+// ============================================================================
+
+//! \defgroup asmjit_logging Logging
+//! \brief Logging and formatting.
+//!
+//! ### Overview
+//!
+//! The initial phase of a project that generates machine code is not always smooth.
+//! Failure cases are common not just at the beginning phase, but also during the
+//! development or refactoring. AsmJit provides logging functionality to address
+//! this issue. AsmJit does already a good job with function overloading to prevent
+//! from emitting unencodable instructions, but it can't prevent from emitting machine
+//! code that is correct at instruction level, but doesn't work when it's executed as
+//! a whole. Logging has always been an important part of AsmJit's infrastructure and
+//! looking at logs can sometimes reveal code generation issues quickly.
+//!
+//! AsmJit provides API for logging and formatting:
+//! - \ref Logger - A logger that you can pass to \ref CodeHolder and all emitters
+//! that inherit from \ref BaseEmitter.
+//! - \ref FormatOptions - Formatting options that can change how instructions and
+//! operands are formatted.
+//! - \ref Formatter - A namespace that provides functions that can format input
+//! data like \ref Operand, \ref BaseReg, \ref Label, and \ref BaseNode into
+//! \ref String.
+//!
+//! AsmJit's \ref Logger serves the following purposes:
+//! - Provides a basic foundation for logging.
+//! - Abstract class leaving the implementation on users. The following built-in
+//! inplementations are provided for simplicty:
+//! - \ref FileLogger implements logging into a standard `FILE` stream.
+//! - \ref StringLogger serializes all logs into a \ref String instance.
+//!
+//! AsmJit's \ref FormatOptions provides the following to customize the formatting of
+//! instructions and operands through:
+//! - \ref FormatOptions::Flags
+//! - \ref FormatOptions::IndentationType
+//!
+//! ### Logging
+//!
+//! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it
+//! to all attached emitters automatically. The example below illustrates how to
+//! use \ref FileLogger that outputs to standard output:
+//!
+//! ```
+//! #include <asmjit/core.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! int main() {
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! FileLogger logger(stdout); // Logger should always survive CodeHolder.
+//!
+//! CodeHolder code; // Holds code and relocation information.
+//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
+//! code.setLogger(&logger); // Attach the `logger` to `code` holder.
+//!
+//! // ... code as usual, everything emitted will be logged to `stdout` ...
+//! return 0;
+//! }
+//! ```
+//!
+//! If output to FILE stream is not desired it's possible to use \ref StringLogger,
+//! which concatenates everything into a multi-line string:
+//!
+//! ```
+//! #include <asmjit/core.h>
+//! #include <stdio.h>
+//! #include <utility>
+//!
+//! using namespace asmjit;
+//!
+//! int main() {
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! StringLogger logger; // Logger should always survive CodeHolder.
+//!
+//! CodeHolder code; // Holds code and relocation information.
+//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
+//! code.setLogger(&logger); // Attach the `logger` to `code` holder.
+//!
+//! // ... code as usual, logging will be concatenated to logger string ...
+//!
+//! // You can either use the string from StringLogger directly or you can
+//! // move it. Logger::data() returns its content as null terminated char[].
+//! printf("Logger content: %s\n", logger.data());
+//!
+//! // It can be moved into your own string like this:
+//! String content = std::move(logger.content());
+//! printf("The same content: %s\n", content.data());
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! ### Formatting
+//!
+//! AsmJit uses \ref Formatter to format inputs that are then passed to \ref
+//! Logger. Formatting is public and can be used by AsmJit users as well. The
+//! most important thing to know regarding formatting is that \ref Formatter
+//! always appends to the output string, so it can be used to build complex
+//! strings without having to concatenate intermediate strings.
+//!
+//! The first example illustrates how to format operands:
+//!
+//! ```
+//! #include <asmjit/core.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! void logOperand(uint32_t arch, const Operand_& op) {
+//! // The emitter is optional (named labels and virtual registers need it).
+//! BaseEmitter* emitter = nullptr;
//!
-//! Compiler tool is built on top of a \ref asmjit_builder API and adds register
-//! allocation and support for defining and calling functions into it. At the
-//! moment it's the easiest way to generate some code as most architecture and
-//! OS specific stuff is properly abstracted, however, abstractions also mean
-//! that not everything is possible with the Compiler.
+//! // No flags by default.
+//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//!
+//! StringTmp<128> sb;
+//! Formatter::formatOperand(sb, formatFlags, emitter, arch, op);
+//! printf("%s\n", sb.data());
+//! }
+//!
+//! void formattingExample() {
+//! using namespace x86;
+//!
+//! // Architecture is not part of operand, it must be passed explicitly.
+//! // Format flags. We pass it explicitly also to 'logOperand' to make
+//! // compatible with what AsmJit normally does.
+//! uint32_t arch = Environment::kArchX64;
+//!
+//! log(arch, rax); // Prints 'rax'.
+//! log(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`.
+//! log(arch, dword_ptr(rax, rbx, 2)); // Prints 'dword [rax + rbx * 4]`.
+//! log(arch, imm(42)); // Prints '42'.
+//! }
+//! ```
+//!
+//! Next example illustrates how to format whole instructions:
+//!
+//! ```
+//! #include <asmjit/core.h>
+//! #include <stdio.h>
+//! #include <utility>
+//!
+//! using namespace asmjit;
+//!
+//! template<typename... Args>
+//! void logInstruction(uint32_t arch, const BaseInst& inst, Args&&... args) {
+//! // The emitter is optional (named labels and virtual registers need it).
+//! BaseEmitter* emitter = nullptr;
+//!
+//! // No flags by default.
+//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//!
+//! // The formatter expects operands in an array.
+//! Operand_ operands { std::forward<Args>(args)... };
+//!
+//! StringTmp<128> sb;
+//! Formatter::formatInstruction(
+//! sb, formatFlags, emitter, arch, inst, operands, sizeof...(args));
+//! printf("%s\n", sb.data());
+//! }
+//!
+//! void formattingExample() {
+//! using namespace x86;
+//!
+//! // Architecture is not part of operand, it must be passed explicitly.
+//! // Format flags. We pass it explicitly also to 'logOperand' to make
+//! // compatible with what AsmJit normally does.
+//! uint32_t arch = Environment::kArchX64;
+//!
+//! // Prints 'mov rax, rcx'.
+//! logInstruction(arch, BaseInst(Inst::kIdMov), rax, rcx);
+//!
+//! // Prints 'vaddpd zmm0, zmm1, [rax] {1to8}'.
+//! logInstruction(arch,
+//! BaseInst(Inst::kIdVaddpd),
+//! zmm0, zmm1, ptr(rax)._1toN());
+//!
+//! // BaseInst abstracts instruction id, instruction options, and extraReg.
+//! // Prints 'lock add [rax], rcx'.
+//! logInstruction(arch,
+//! BaseInst(Inst::kIdAdd, Inst::kOptionLock),
+//! x86::ptr(rax), rcx);
+//!
+//! // Similarly an extra register (like AVX-512 selector) can be used.
+//! // Prints 'vaddpd zmm0 {k2} {z}, zmm1, [rax]'.
+//! logInstruction(arch,
+//! BaseInst(Inst::kIdAdd, Inst::kOptionZMask, k2),
+//! zmm0, zmm1, ptr(rax));
+//! }
+//! ```
+//!
+//! And finally, the example below illustrates how to use a built-in function
+//! to format the content of \ref BaseBuilder, which consists of nodes:
+//!
+//! ```
+//! #include <asmjit/core.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! void formattingExample(BaseBuilder* builder) {
+//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//!
+//! // This also shows how temporary strings can be used.
+//! StringTmp<512> sb;
+//!
+//! // FormatNodeList requires the String for output, formatting flags, which
+//! // were zero (no extra flags), and the builder instance, which we have
+//! // provided. An overloaded version also exists, which accepts begin and
+//! // and end nodes, which can be used to only format a range of nodes.
+//! Formatter::formatNodeList(sb, formatFlags, builder);
+//!
+//! // You can do whatever else with the string, it's always null terminated,
+//! // so it can be passed to C functions like printf().
+//! printf("%s\n", sb.data());
+//! }
+//! ```
+
+// ============================================================================
+// [Documentation - asmjit_error_handling]
+// ============================================================================
+
+//! \defgroup asmjit_error_handling Error Handling
+//! \brief Error handling.
+//!
+//! ### Overview
+//!
+//! AsmJit uses error codes to represent and return errors. Every function that
+//! can fail returns an \ref Error code. Exceptions are never thrown by AsmJit
+//! itself even in extreme conditions like out-of-memory, but it's possible to
+//! override \ref ErrorHandler::handleError() to throw, in that case no error
+//! will be returned and exception will be thrown instead. All functions where
+//! this can happen are not marked `noexcept`.
+//!
+//! Errors should never be ignored, however, checking errors after each AsmJit
+//! API call would simply overcomplicate the whole code generation experience.
+//! \ref ErrorHandler exists to make the use of AsmJit API simpler as it allows
+//! to customize how errors can be handled:
+//!
+//! - Record the error and continue (the way how the error is user-implemented).
+//! - Throw an exception. AsmJit doesn't use exceptions and is completely
+//! exception-safe, but it's perfectly legal to throw an exception from
+//! the error handler.
+//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler,
+//! Builder and Compiler to a consistent state before calling \ref
+//! ErrorHandler::handleError(), so `longjmp()` can be used without issues to
+//! cancel the code-generation if an error occurred. This method can be used if
+//! exception handling in your project is turned off and you still want some
+//! comfort. In most cases it should be safe as AsmJit uses \ref Zone memory
+//! and the ownership of memory it allocates always ends with the instance that
+//! allocated it. If using this approach please never jump outside the life-time
+//! of \ref CodeHolder and \ref BaseEmitter.
+//!
+//! ### Using ErrorHandler
+//!
+//! An example of attaching \ref ErrorHandler to \ref CodeHolder.
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // A simple error handler implementation, extend according to your needs.
+//! class MyErrorHandler : public ErrorHandler {
+//! public:
+//! void handleError(Error err, const char* message, BaseEmitter* origin) override {
+//! printf("AsmJit error: %s\n", message);
+//! }
+//! };
+//!
+//! int main() {
+//! JitRuntime rt;
+//!
+//! MyErrorHandler myErrorHandler;
+//! CodeHolder code;
+//!
+//! code.init(rt.environment());
+//! code.setErrorHandler(&myErrorHandler);
+//!
+//! x86::Assembler a(&code);
+//! // ... code generation ...
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! Useful classes in error handling group:
+//!
+//! - See \ref DebugUtils that provides utilities useful for debugging.
+//! - See \ref Error that lists error codes that AsmJit uses.
+//! - See \ref ErrorHandler for more details about error handling.
-//! \defgroup asmjit_func Function
-//! \brief Function API.
+// ============================================================================
+// [Documentation - asmjit_instruction_db]
+// ============================================================================
-//! \defgroup asmjit_jit JIT
-//! \brief JIT API and Virtual Memory Management.
+//! \defgroup asmjit_instruction_db Instruction DB
+//! \brief Instruction database (introspection, read/write, validation, ...).
+//!
+//! ### Overview
+//!
+//! AsmJit provides a public instruction database that can be used to query
+//! information about a complete instruction. The instruction database requires
+//! the knowledge of the following:
+//!
+//! - \ref BaseInst - Base instruction that contains instruction id, options,
+//! and a possible extra-register that represents either REP prefix counter
+//! or AVX-512 selector (mask).
+//! - \ref Operand - Represents operands of an instruction.
+//!
+//! Each instruction can be then queried for the following information:
+//!
+//! - \ref InstRWInfo - Read/write information of instruction and its oprands.
+//! - \ref OpRWInfo - Read/write information of a single operand, part of
+//! \ref InstRWInfo data structure.
+//! - \ref BaseFeatures - CPU features required to execute the instruction.
+//!
+//! In addition to query functionality AsmJit is also able to validate whether
+//! an instruction and its operands are valid. This is useful for making sure
+//! that what user tries to emit is correct and it can be also used by other
+//! projects that parse user input, like AsmTK project.
+//!
+//! ### Query API
+//!
+//! The instruction query API is provided by \ref InstAPI namespace. The
+//! following queries are possible:
+//!
+//! - \ref InstAPI::queryRWInfo() - queries read/write information of the
+//! given instruction and its operands. Includes also CPU flags read/written.
+//!
+//! - \ref InstAPI::queryFeatures() - queries CPU features that are required
+//! to execute the given instruction. A full instruction with operands must
+//! be given as some architectures like X86 may require different features
+//! for the same instruction based on its operands.
+//!
+//! - <a href="https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_instinfo.cpp">asmjit_test_x86_instinfo.cpp</a>
+//! can be also used as a reference about accessing instruction information.
+//!
+//! ### Validation API
+//!
+//! The instruction validation API is provided by \ref InstAPI namespace in the
+//! similar fashion like the Query API, however, validation can also be turned
+//! on at \ref BaseEmitter level. The following is possible:
+//!
+//! - \ref InstAPI::validate() - low-level instruction validation function
+//! that is used internally by emitters if strict validation is enabled.
+//!
+//! - \ref BaseEmitter::addValidationOptions() - can be used to enable
+//! validation at emitter level, see \ref BaseEmitter::ValidationOptions.
-//! \defgroup asmjit_zone Zone
-//! \brief Zone allocator and zone allocated containers.
-//! \defgroup asmjit_support Support
-//! \brief Support API.
+// ============================================================================
+// [Documentation - asmjit_virtual_memory]
+// ============================================================================
+
+//! \defgroup asmjit_virtual_memory Virtual Memory
+//! \brief Virtual memory management.
+//!
+//! ### Overview
+//!
+//! AsmJit's virtual memory management is divided into two main categories:
+//!
+//! - Low level API that provides cross-platform abstractions for virtual
+//! memory allocation. Implemented in \ref VirtMem namespace.
+//! - High level API that makes it very easy to store generated code for
+//! execution. See \ref JitRuntime, which is used by many examples for its
+//! simplicity and easy integration with \ref CodeHolder. There is also
+//! \ref JitAllocator, which lays somewhere between RAW memory allocation
+//! and \ref JitRuntime.
+
+// ============================================================================
+// [Documentation - asmjit_zone_memory]
+// ============================================================================
+
+//! \defgroup asmjit_zone Zone Memory
+//! \brief Zone memory allocator and containers.
+//!
+//! ### Overview
+//!
+//! AsmJit uses zone memory allocation (also known as Arena allocation) to allocate
+//! most of the data it uses. It's a fast allocator that allows AsmJit to allocate
+//! a lot of small data structures fast and without `malloc()` overhead. Since
+//! code generators and all related classes are usually short-lived this approach
+//! decreases memory usage and fragmentation as arena-based allocators always
+//! allocate larger blocks of memory, which are then split into smaller chunks.
+//!
+//! Another advantage of zone memory allocation is that since the whole library
+//! uses this strategy it's very easy to deallocate everything that a particular
+//! instance is holding by simply releasing the memory the allocator holds. This
+//! improves destruction time of such objects as there is no destruction at all.
+//! Long-lived objects just reset its data in destructor or in their reset()
+//! member function for a future reuse. For this purpose all containers in AsmJit
+//! are also zone allocated.
+//!
+//! ### Zone Allocation
+//!
+//! - \ref Zone - Incremental zone memory allocator with minimum features. It
+//! can only allocate memory without the possibility to return it back to
+//! the allocator.
+//!
+//! - \ref ZoneTmp - A temporary \ref Zone with some initial static storage.
+//! If the allocation requests fit the static storage allocated then there
+//! will be no dynamic memory allocation during the lifetime of \ref ZoneTmp,
+//! otherwise it would act as \ref Zone with one preallocated block on the
+//! stack.
+//!
+//! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability
+//! of returning memory to the allocator. Such memory is stored in a pool for
+//! later reuse.
+//!
+//! ### Zone Allocated Containers
+//!
+//! - \ref ZoneString - Zone allocated string.
+//! - \ref ZoneHash - Zone allocated hash table.
+//! - \ref ZoneTree - Zone allocated red-black tree.
+//! - \ref ZoneList - Zone allocated double-linked list.
+//! - \ref ZoneStack - Zone allocated stack.
+//! - \ref ZoneVector - Zone allocated vector.
+//! - \ref ZoneBitVector - Zone allocated vector of bits.
+//!
+//! ### Using Zone Allocated Containers
+//!
+//! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very
+//! similar to `std::vector`, but the implementation doesn't use exceptions and
+//! uses the mentioned \ref ZoneAllocator for performance reasons. You don't have
+//! to worry about allocations as you should not need to add items to AsmJit's
+//! data structures directly as there should be API for all required operations.
+//!
+//! The following APIs in \ref CodeHolder returns \ref ZoneVector reference:
+//!
+//! ```
+//! using namespace asmjit;
+//!
+//! void example(CodeHolder& code) {
+//! // Contains all emitters attached to CodeHolder.
+//! const ZoneVector<BaseEmitter*>& emitters = code.emitters();
+//!
+//! // Contains all section entries managed by CodeHolder.
+//! const ZoneVector<Section*>& sections = code.sections();
+//!
+//! // Contains all label entries managed by CodeHolder.
+//! const ZoneVector<LabelEntry*>& labelEntries = code.labelEntries();
+//!
+//! // Contains all relocation entries managed by CodeHolder.
+//! const ZoneVector<RelocEntry*>& relocEntries = code.relocEntries();
+//! }
+//! ```
+//!
+//! \ref ZoneVector has overloaded array access operator to make it possible
+//! to access its elements through operator[]. Some standard functions like
+//! \ref ZoneVector::empty(), \ref ZoneVector::size(), and \ref ZoneVector::data()
+//! are provided as well. Vectors are also iterable through a range-based for loop:
+//!
+//! ```
+//! using namespace asmjit;
+//!
+//! void example(CodeHolder& code) {
+//! for (LabelEntry* le : code.labelEntries()) {
+//! printf("Label #%u {Bound=%s Offset=%llu}",
+//! le->id(),
+//! le->isBound() ? "true" : "false",
+//! (unsigned long long)le->offset());
+//! }
+//! }
+//! ```
+//!
+//! ### Design Considerations
+//!
+//! Zone-allocated containers do not store the allocator within the container.
+//! This decision was made to reduce the footprint of such containers as AsmJit
+//! tooling, especially Compiler's register allocation, may use many instances
+//! of such containers to perform code analysis and register allocation.
+//!
+//! For example to append an item into a \ref ZoneVector it's required to pass
+//! the allocator as the first argument, so it can be used in case that the
+//! vector needs a reallocation. Such function also returns an error, which
+//! must be propagated to the caller.
+//!
+//! ```
+//! using namespace asmjit
+//!
+//! Error example(ZoneAllocator* allocator) {
+//! ZoneVector<int> vector;
+//!
+//! // Unfortunately, allocator must be provided to all functions that mutate
+//! // the vector. However, AsmJit users should never need to do this as all
+//! // manipulation should be done through public API, which takes care of
+//! // that.
+//! for (int i = 0; i < 100; i++) {
+//! ASMJIT_PROPAGATE(vector.append(allocator, i));
+//! }
+//!
+//! // By default vector's destructor doesn't release anything as it knows
+//! // that its content is zone allocated. However, \ref ZoneVector::release
+//! // can be used to explicitly release the vector data to the allocator if
+//! // necessary
+//! vector.release(allocator);
+//! }
+//! ```
+//!
+//! Containers like \ref ZoneVector also provide a functionality to reserve a
+//! certain number of items before any items are added to it. This approach is
+//! used internally in most places as it allows to prepare space for data that
+//! will be added to some container before the data itself was created.
+//!
+//! ```
+//! using namespace asmjit
+//!
+//! Error example(ZoneAllocator* allocator) {
+//! ZoneVector<int> vector;
+//!
+//! ASMJIT_PROPAGATE(vector.willGrow(100));
+//! for (int i = 0; i < 100; i++) {
+//! // Cannot fail.
+//! vector.appendUnsafe(allocator, i);
+//! }
+//!
+//! vector.release(allocator);
+//! }
+//! ```
+
+// ============================================================================
+// [Documentation - asmjit_utilities]
+// ============================================================================
+
+//! \defgroup asmjit_utilities Utilities
+//! \brief Utility classes and functions.
+//!
+//! ### Overview
+//!
+//! AsmJit uses and provides utility classes and functions, that can be used
+//! with AsmJit. The functionality can be divided into the following topics:
+//!
+//! ### String Functionality
+//!
+//! - \ref String - AsmJit's string container, which is used internally
+//! and which doesn't use exceptions and has a stable layout, which is
+//! not dependent on C++ standard library.
+//! - \ref StringTmp - String that can have base storage allocated on
+//! stack. The amount of storage on stack can be specified as a template
+//! parameter.
+//! - \ref FixedString - Fixed string container limited up to N characters.
+//!
+//! ### Code Generation Utilities
+//!
+//! - \ref ConstPool - Constant pool used by \ref BaseCompiler, but also
+//! available to users that may find use of it.
+//!
+//! ### Support Functionality Used by AsmJit
+//!
+//! - \ref Support namespace provides many other utility functions and
+//! classes that are used by AsmJit, and made public.
+
+// ============================================================================
+// [Documentation - asmjit_<arch> backends]
+// ============================================================================
+
+//! \defgroup asmjit_x86 X86 Backend
+//! \brief X86/X64 backend.
+
+// ============================================================================
+// [Documentation - asmjit_ra]
+// ============================================================================
//! \cond INTERNAL
//! \defgroup asmjit_ra RA
//! \brief Register allocator internals.
//! \endcond
+} // {asmjit}
+
+// ============================================================================
+// [Core Headers]
+// ============================================================================
+
#include "./core/globals.h"
#include "./core/arch.h"
@@ -78,12 +2013,15 @@
#include "./core/cpuinfo.h"
#include "./core/datatypes.h"
#include "./core/emitter.h"
+#include "./core/environment.h"
+#include "./core/errorhandler.h"
#include "./core/features.h"
+#include "./core/formatter.h"
#include "./core/func.h"
#include "./core/inst.h"
#include "./core/jitallocator.h"
#include "./core/jitruntime.h"
-#include "./core/logging.h"
+#include "./core/logger.h"
#include "./core/operand.h"
#include "./core/osutils.h"
#include "./core/string.h"
@@ -99,4 +2037,23 @@
#include "./core/zonestring.h"
#include "./core/zonevector.h"
+// ============================================================================
+// [Deprecated]
+// ============================================================================
+
+#ifndef ASMJIT_NO_DEPRECATED
+namespace asmjit {
+
+#ifndef ASMJIT_NO_COMPILER
+ASMJIT_DEPRECATED("Use InvokeNode instead of FuncCallNode")
+typedef InvokeNode FuncCallNode;
+#endif // !ASMJIT_NO_COMPILER
+
+#ifndef ASMJIT_NO_LOGGING
+namespace Logging { using namespace Formatter; }
+#endif //! ASMJIT_NO_LOGGING
+
+} // {asmjit}
+#endif // !ASMJIT_NO_DEPRECATED
+
#endif // ASMJIT_CORE_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/api-build_p.h b/3rdparty/asmjit/src/asmjit/core/api-build_p.h
index 714107c204d..db37ca77e93 100644
--- a/3rdparty/asmjit/src/asmjit/core/api-build_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/api-build_p.h
@@ -53,7 +53,7 @@
#include "./api-config.h"
-#if !defined(ASMJIT_BUILD_DEBUG) && ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 4, 0)
+#if !defined(ASMJIT_BUILD_DEBUG) && defined(__GNUC__) && !defined(__clang__)
#define ASMJIT_FAVOR_SIZE __attribute__((__optimize__("Os")))
#define ASMJIT_FAVOR_SPEED __attribute__((__optimize__("O3")))
#elif ASMJIT_CXX_HAS_ATTRIBUTE(__minsize__, 0)
diff --git a/3rdparty/asmjit/src/asmjit/core/api-config.h b/3rdparty/asmjit/src/asmjit/core/api-config.h
index de5985a066a..1388da49618 100644
--- a/3rdparty/asmjit/src/asmjit/core/api-config.h
+++ b/3rdparty/asmjit/src/asmjit/core/api-config.h
@@ -28,78 +28,90 @@
// [asmjit::Version]
// ============================================================================
-#define ASMJIT_LIBRARY_VERSION 0x010200 /* 1.2.0 */
+//! \addtogroup asmjit_core
+//! \{
+
+//! AsmJit library version in `(Major << 16) | (Minor << 8) | (Patch)` format.
+#define ASMJIT_LIBRARY_VERSION 0x010400 /* 1.4.0 */
+
+//! \}
// ============================================================================
-// [asmjit::Options]
+// [asmjit::Build - Documentation]
// ============================================================================
-// AsmJit Static Builds and Embedding
-// ----------------------------------
-//
-// These definitions can be used to enable static library build. Embed is used
-// when AsmJit's source code is embedded directly in another project, implies
-// static build as well.
-//
-// #define ASMJIT_EMBED // Asmjit is embedded (implies ASMJIT_BUILD_STATIC).
-#define ASMJIT_STATIC // Enable static-library build.
+// NOTE: Doxygen cannot document macros that are not defined, that's why we have
+// to define them and then undefine them, so it won't use the macros with its
+// own preprocessor.
+#ifdef _DOXYGEN
+namespace asmjit {
-// AsmJit Build Mode
-// -----------------
-//
-// These definitions control the build mode and tracing support. The build mode
-// should be auto-detected at compile time, but it's possible to override it in
-// case that the auto-detection fails.
-//
-// Tracing is a feature that is never compiled by default and it's only used to
-// debug AsmJit itself.
-//
-// #define ASMJIT_BUILD_DEBUG // Always use debug-mode (ASMJIT_ASSERT enabled).
-// #define ASMJIT_BUILD_RELEASE // Always use release-mode (ASMJIT_ASSERT disabled).
+//! \addtogroup asmjit_build
+//! \{
-// AsmJit Build Backends
-// ---------------------
-//
-// These definitions control which backends to compile. If none of these is
-// defined AsmJit will use host architecture by default (for JIT code generation).
-//
-// #define ASMJIT_BUILD_X86 // Enable X86 targets (X86 and X86_64).
-// #define ASMJIT_BUILD_ARM // Enable ARM targets (ARM and AArch64).
-// #define ASMJIT_BUILD_HOST // Enable targets based on target arch (default).
+//! Asmjit is embedded, implies \ref ASMJIT_STATIC.
+#define ASMJIT_EMBED
-// AsmJit Build Options
-// --------------------
-//
-// Flags can be defined to disable standard features. These are handy especially
-// when building AsmJit statically and some features are not needed or unwanted
-// (like BaseCompiler).
-//
-// AsmJit features are enabled by default.
-// #define ASMJIT_NO_BUILDER // Disable Builder (completely).
-// #define ASMJIT_NO_COMPILER // Disable Compiler (completely).
-// #define ASMJIT_NO_JIT // Disable JIT memory manager and JitRuntime.
-// #define ASMJIT_NO_LOGGING // Disable logging and formatting (completely).
-// #define ASMJIT_NO_TEXT // Disable everything that contains text
-// // representation (instructions, errors, ...).
-// #define ASMJIT_NO_VALIDATION // Disable validation API and options.
-// #define ASMJIT_NO_INTROSPECTION // Disable API related to instruction database.
-// // (validation, cpu features, rw-info, etc).
+//! Enables static-library build.
+#define ASMJIT_STATIC
-// ASMJIT_NO_BUILDER implies ASMJIT_NO_COMPILER.
-#if defined(ASMJIT_NO_BUILDER) && !defined(ASMJIT_NO_COMPILER)
- #define ASMJIT_NO_COMPILER
-#endif
+//! Defined when AsmJit's build configuration is 'Debug'.
+//!
+//! \note Can be defined explicitly to bypass autodetection.
+#define ASMJIT_BUILD_DEBUG
-// Prevent compile-time errors caused by misconfiguration.
-#if defined(ASMJIT_NO_TEXT) && !defined(ASMJIT_NO_LOGGING)
- #pragma "ASMJIT_NO_TEXT can only be defined when ASMJIT_NO_LOGGING is defined."
- #undef ASMJIT_NO_TEXT
-#endif
+//! Defined when AsmJit's build configuration is 'Release'.
+//!
+//! \note Can be defined explicitly to bypass autodetection.
+#define ASMJIT_BUILD_RELEASE
-#if defined(ASMJIT_NO_INTROSPECTION) && !defined(ASMJIT_NO_COMPILER)
- #pragma message("ASMJIT_NO_INTROSPECTION can only be defined when ASMJIT_NO_COMPILER is defined")
- #undef ASMJIT_NO_INTROSPECTION
-#endif
+//! Defined to build X86/X64 backend.
+#define ASMJIT_BUILD_X86
+
+//! Defined to build ARM/AArch64 backend.
+#define ASMJIT_BUILD_ARM
+
+//! Defined to build host backend autodetected at compile-time.
+#define ASMJIT_BUILD_HOST
+
+//! Disables deprecated API at compile time.
+#define ASMJIT_NO_DEPRECATED
+
+//! Disables \ref asmjit_builder functionality completely.
+#define ASMJIT_NO_BUILDER
+
+//! Disables \ref asmjit_compiler functionality completely.
+#define ASMJIT_NO_COMPILER
+
+//! Disables JIT memory management and \ref JitRuntime.
+#define ASMJIT_NO_JIT
+
+//! Disables \ref Logger and \ref Formatter.
+#define ASMJIT_NO_LOGGING
+
+//! Disables everything that contains text.
+#define ASMJIT_NO_TEXT
+
+//! Disables instruction validation API.
+#define ASMJIT_NO_VALIDATION
+
+//! Disables instruction introspection API.
+#define ASMJIT_NO_INTROSPECTION
+
+// Avoid doxygen preprocessor using feature-selection definitions.
+#undef ASMJIT_NO_DEPRECATED
+#undef ASMJIT_NO_BUILDER
+#undef ASMJIT_NO_COMPILER
+#undef ASMJIT_NO_JIT
+#undef ASMJIT_NO_LOGGING
+#undef ASMJIT_NO_TEXT
+#undef ASMJIT_NO_VALIDATION
+#undef ASMJIT_NO_INTROSPECTION
+
+//! \}
+
+} // {asmjit}
+#endif // _DOXYGEN
// ============================================================================
// [asmjit::Dependencies]
@@ -122,23 +134,45 @@
#include <pthread.h>
#endif
+
+// ============================================================================
+// [asmjit::Options]
+// ============================================================================
+
+// ASMJIT_NO_BUILDER implies ASMJIT_NO_COMPILER.
+#if defined(ASMJIT_NO_BUILDER) && !defined(ASMJIT_NO_COMPILER)
+ #define ASMJIT_NO_COMPILER
+#endif
+
+// Prevent compile-time errors caused by misconfiguration.
+#if defined(ASMJIT_NO_TEXT) && !defined(ASMJIT_NO_LOGGING)
+ #pragma "ASMJIT_NO_TEXT can only be defined when ASMJIT_NO_LOGGING is defined."
+ #undef ASMJIT_NO_TEXT
+#endif
+
+#if defined(ASMJIT_NO_INTROSPECTION) && !defined(ASMJIT_NO_COMPILER)
+ #pragma message("ASMJIT_NO_INTROSPECTION can only be defined when ASMJIT_NO_COMPILER is defined")
+ #undef ASMJIT_NO_INTROSPECTION
+#endif
+
// ============================================================================
// [asmjit::Build - Globals - Deprecated]
// ============================================================================
-// DEPRECATED: Will be removed in the future.
-#if defined(ASMJIT_BUILD_EMBED) || defined(ASMJIT_BUILD_STATIC)
- #if defined(ASMJIT_BUILD_EMBED)
- #pragma message("'ASMJIT_BUILD_EMBED' is deprecated, use 'ASMJIT_STATIC'")
- #endif
- #if defined(ASMJIT_BUILD_STATIC)
- #pragma message("'ASMJIT_BUILD_STATIC' is deprecated, use 'ASMJIT_STATIC'")
- #endif
+#ifndef ASMJIT_NO_DEPRECATED
+ #if defined(ASMJIT_BUILD_EMBED) || defined(ASMJIT_BUILD_STATIC)
+ #if defined(ASMJIT_BUILD_EMBED)
+ #pragma message("'ASMJIT_BUILD_EMBED' is deprecated, use 'ASMJIT_STATIC'")
+ #endif
+ #if defined(ASMJIT_BUILD_STATIC)
+ #pragma message("'ASMJIT_BUILD_STATIC' is deprecated, use 'ASMJIT_STATIC'")
+ #endif
- #if !defined(ASMJIT_STATIC)
- #define ASMJIT_STATIC
+ #if !defined(ASMJIT_STATIC)
+ #define ASMJIT_STATIC
+ #endif
#endif
-#endif
+#endif // !ASMJIT_NO_DEPRECATED
// ============================================================================
// [asmjit::Build - Globals - Build Mode]
@@ -181,7 +215,7 @@
#define ASMJIT_ARCH_MIPS 0
#endif
-#define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS)
+#define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS)
#if ASMJIT_ARCH_BITS == 0
#undef ASMJIT_ARCH_BITS
#if defined (__LP64__) || defined(_LP64)
@@ -221,11 +255,8 @@
// [asmjit::Build - Globals - C++ Compiler and Features Detection]
// ============================================================================
-#define ASMJIT_CXX_CLANG 0
#define ASMJIT_CXX_GNU 0
-#define ASMJIT_CXX_INTEL 0
-#define ASMJIT_CXX_MSC 0
-#define ASMJIT_CXX_MAKE_VER(MAJOR, MINOR, PATCH) ((MAJOR) * 10000000 + (MINOR) * 100000 + (PATCH))
+#define ASMJIT_CXX_MAKE_VER(MAJOR, MINOR) ((MAJOR) * 1000 + (MINOR))
// Intel Compiler [pretends to be GNU or MSC, so it must be checked first]:
// - https://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler
@@ -233,9 +264,6 @@
// - https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler
#if defined(__INTEL_COMPILER)
- #undef ASMJIT_CXX_INTEL
- #define ASMJIT_CXX_INTEL ASMJIT_CXX_MAKE_VER(__INTEL_COMPILER / 100, (__INTEL_COMPILER / 10) % 10, __INTEL_COMPILER % 10)
-
// MSC Compiler:
// - https://msdn.microsoft.com/en-us/library/hh567368.aspx
//
@@ -247,72 +275,26 @@
// - 19.10.0 == VS2017
#elif defined(_MSC_VER) && defined(_MSC_FULL_VER)
- #undef ASMJIT_CXX_MSC
- #if _MSC_VER == _MSC_FULL_VER / 10000
- #define ASMJIT_CXX_MSC ASMJIT_CXX_MAKE_VER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)
- #else
- #define ASMJIT_CXX_MSC ASMJIT_CXX_MAKE_VER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)
- #endif
-
// Clang Compiler [Pretends to be GNU, so it must be checked before]:
// - https://clang.llvm.org/cxx_status.html
#elif defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
- #undef ASMJIT_CXX_CLANG
- #define ASMJIT_CXX_CLANG ASMJIT_CXX_MAKE_VER(__clang_major__, __clang_minor__, __clang_patchlevel__)
-
// GNU Compiler:
// - https://gcc.gnu.org/projects/cxx-status.html
#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
#undef ASMJIT_CXX_GNU
- #define ASMJIT_CXX_GNU ASMJIT_CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+ #define ASMJIT_CXX_GNU ASMJIT_CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__)
#endif
// Compiler features detection macros.
-#if ASMJIT_CXX_CLANG && defined(__has_builtin)
- #define ASMJIT_CXX_HAS_BUILTIN(NAME, CHECK) (__has_builtin(NAME))
-#else
- #define ASMJIT_CXX_HAS_BUILTIN(NAME, CHECK) (!(!(CHECK)))
-#endif
-
-#if ASMJIT_CXX_CLANG && defined(__has_extension)
- #define ASMJIT_CXX_HAS_FEATURE(NAME, CHECK) (__has_extension(NAME))
-#elif ASMJIT_CXX_CLANG && defined(__has_feature)
- #define ASMJIT_CXX_HAS_FEATURE(NAME, CHECK) (__has_feature(NAME))
-#else
- #define ASMJIT_CXX_HAS_FEATURE(NAME, CHECK) (!(!(CHECK)))
-#endif
-
-#if ASMJIT_CXX_CLANG && defined(__has_attribute)
+#if defined(__clang__) && defined(__has_attribute)
#define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (__has_attribute(NAME))
#else
#define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (!(!(CHECK)))
#endif
-#if ASMJIT_CXX_CLANG && defined(__has_cpp_attribute)
- #define ASMJIT_CXX_HAS_CPP_ATTRIBUTE(NAME, CHECK) (__has_cpp_attribute(NAME))
-#else
- #define ASMJIT_CXX_HAS_CPP_ATTRIBUTE(NAME, CHECK) (!(!(CHECK)))
-#endif
-
-// Compiler features by vendor.
-#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
- #define ASMJIT_CXX_HAS_NATIVE_WCHAR_T 0
-#else
- #define ASMJIT_CXX_HAS_NATIVE_WCHAR_T 1
-#endif
-
-#if ASMJIT_CXX_HAS_FEATURE(cxx_unicode_literals, ( \
- (ASMJIT_CXX_INTEL >= ASMJIT_CXX_MAKE_VER(14, 0, 0)) || \
- (ASMJIT_CXX_MSC >= ASMJIT_CXX_MAKE_VER(19, 0, 0)) || \
- (ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4 , 5, 0) && __cplusplus >= 201103L) ))
- #define ASMJIT_CXX_HAS_UNICODE_LITERALS 1
-#else
- #define ASMJIT_CXX_HAS_UNICODE_LITERALS 0
-#endif
-
// ============================================================================
// [asmjit::Build - Globals - API Decorators & Language Extensions]
// ============================================================================
@@ -394,6 +376,15 @@
#define ASMJIT_REGPARM(N)
#endif
+#if ASMJIT_ARCH_X86 && defined(_WIN32) && defined(_MSC_VER)
+ #define ASMJIT_VECTORCALL __vectorcall
+#elif ASMJIT_ARCH_X86 && defined(_WIN32)
+ #define ASMJIT_VECTORCALL __attribute__((__vectorcall__))
+#else
+ #define ASMJIT_VECTORCALL
+#endif
+
+
// Type alignment (not allowed by C++11 'alignas' keyword).
#if defined(__GNUC__)
#define ASMJIT_ALIGN_TYPE(TYPE, N) __attribute__((__aligned__(N))) TYPE
@@ -403,13 +394,22 @@
#define ASMJIT_ALIGN_TYPE(TYPE, N) TYPE
#endif
+//! \def ASMJIT_MAY_ALIAS
+//!
+//! Expands to `__attribute__((__may_alias__))` if supported.
#if defined(__GNUC__)
#define ASMJIT_MAY_ALIAS __attribute__((__may_alias__))
#else
#define ASMJIT_MAY_ALIAS
#endif
-// Annotations.
+//! \def ASMJIT_LIKELY(...)
+//!
+//! Condition is likely to be taken (mostly error handling and edge cases).
+
+//! \def ASMJIT_UNLIKELY(...)
+//!
+//! Condition is unlikely to be taken (mostly error handling and edge cases).
#if defined(__GNUC__)
#define ASMJIT_LIKELY(...) __builtin_expect(!!(__VA_ARGS__), 1)
#define ASMJIT_UNLIKELY(...) __builtin_expect(!!(__VA_ARGS__), 0)
@@ -418,29 +418,42 @@
#define ASMJIT_UNLIKELY(...) (__VA_ARGS__)
#endif
+//! \def ASMJIT_FALLTHROUGH
+//!
+//! Portable [[fallthrough]] attribute.
#if defined(__clang__) && __cplusplus >= 201103L
#define ASMJIT_FALLTHROUGH [[clang::fallthrough]]
-#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(7, 0, 0)
+#elif defined(__GNUC__) && __GNUC__ >= 7
#define ASMJIT_FALLTHROUGH __attribute__((__fallthrough__))
#else
#define ASMJIT_FALLTHROUGH ((void)0) /* fallthrough */
#endif
+//! \def ASMJIT_DEPRECATED
+//!
+//! Marks function, class, struct, enum, or anything else as deprecated.
+#if defined(__GNUC__)
+ #define ASMJIT_DEPRECATED(MESSAGE) __attribute__((__deprecated__(MESSAGE)))
+ #if defined(__clang__)
+ #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) __attribute__((__deprecated__(MESSAGE)))
+ #else
+ #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */
+ #endif
+#elif defined(_MSC_VER)
+ #define ASMJIT_DEPRECATED(MESSAGE) __declspec(deprecated(MESSAGE))
+ #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */
+#else
+ #define ASMJIT_DEPRECATED(MESSAGE)
+ #define ASMJIT_DEPRECATED_STRUCT(MESSAGE)
+#endif
+
// Utilities.
#define ASMJIT_OFFSET_OF(STRUCT, MEMBER) ((int)(intptr_t)((const char*)&((const STRUCT*)0x100)->MEMBER) - 0x100)
#define ASMJIT_ARRAY_SIZE(X) uint32_t(sizeof(X) / sizeof(X[0]))
-#if ASMJIT_CXX_HAS_ATTRIBUTE(attribute_deprecated_with_message, ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 5, 0))
- #define ASMJIT_DEPRECATED(DECL, MESSAGE) DECL __attribute__((__deprecated__(MESSAGE)))
-#elif ASMJIT_CXX_MSC
- #define ASMJIT_DEPRECATED(DECL, MESSAGE) __declspec(deprecated(MESSAGE)) DECL
-#else
- #define ASMJIT_DEPRECATED(DECL, MESSAGE) DECL
-#endif
-
#if ASMJIT_CXX_HAS_ATTRIBUTE(no_sanitize, 0)
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize__("undefined")))
-#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 9, 0)
+#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 9)
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize_undefined__))
#else
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF
@@ -459,8 +472,7 @@
#define ASMJIT_END_NAMESPACE \
_Pragma("clang diagnostic pop") \
}
-#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 0, 0) && \
- ASMJIT_CXX_GNU < ASMJIT_CXX_MAKE_VER(5, 0, 0)
+#elif defined(__GNUC__) && __GNUC__ == 4
#define ASMJIT_BEGIN_NAMESPACE \
namespace asmjit { \
_Pragma("GCC diagnostic push") \
@@ -468,7 +480,7 @@
#define ASMJIT_END_NAMESPACE \
_Pragma("GCC diagnostic pop") \
}
-#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(8, 0, 0)
+#elif defined(__GNUC__) && __GNUC__ >= 8
#define ASMJIT_BEGIN_NAMESPACE \
namespace asmjit { \
_Pragma("GCC diagnostic push") \
@@ -480,8 +492,8 @@
#define ASMJIT_BEGIN_NAMESPACE \
namespace asmjit { \
__pragma(warning(push)) \
- __pragma(warning(disable: 4127)) /* conditional expression is constant*/\
- __pragma(warning(disable: 4201)) /* nameless struct/union */
+ __pragma(warning(disable: 4127)) /* conditional expression is const */ \
+ __pragma(warning(disable: 4201)) /* nameless struct/union */
#define ASMJIT_END_NAMESPACE \
__pragma(warning(pop)) \
}
@@ -521,13 +533,8 @@
// [asmjit::Build - Globals - Cleanup]
// ============================================================================
-// Try to cleanup things not used in other public headers.
-#ifndef ASMJIT_EXPORTS
- #undef ASMJIT_CXX_CLANG
- #undef ASMJIT_CXX_GNU
- #undef ASMJIT_CXX_INTEL
- #undef ASMJIT_CXX_MSC
- #undef ASMJIT_CXX_MAKE_VER
-#endif
+// Cleanup definitions that are only used within this header file.
+#undef ASMJIT_CXX_GNU
+#undef ASMJIT_CXX_MAKE_VER
#endif // ASMJIT_CORE_API_CONFIG_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/arch.cpp b/3rdparty/asmjit/src/asmjit/core/arch.cpp
index 97fca9d5c47..7200897b0a0 100644
--- a/3rdparty/asmjit/src/asmjit/core/arch.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/arch.cpp
@@ -23,151 +23,34 @@
#include "../core/api-build_p.h"
#include "../core/arch.h"
-#include "../core/support.h"
-#include "../core/type.h"
#ifdef ASMJIT_BUILD_X86
- #include "../x86/x86operand.h"
+ #include "../x86/x86archdata_p.h"
#endif
#ifdef ASMJIT_BUILD_ARM
- #include "../arm/armoperand.h"
+ #include "../arm/armarchdata_p.h"
#endif
ASMJIT_BEGIN_NAMESPACE
// ============================================================================
-// [asmjit::ArchInfo]
-// ============================================================================
-
-// NOTE: Keep `const constexpr` otherwise MSC would not compile this code correctly.
-static const constexpr uint32_t archInfoTable[] = {
- // <--------------------+---------------------+-------------------+-------+
- // | Type | SubType | GPInfo|
- // <--------------------+---------------------+-------------------+-------+
- Support::bytepack32_4x8(ArchInfo::kIdNone , ArchInfo::kSubIdNone, 0, 0),
- Support::bytepack32_4x8(ArchInfo::kIdX86 , ArchInfo::kSubIdNone, 4, 8),
- Support::bytepack32_4x8(ArchInfo::kIdX64 , ArchInfo::kSubIdNone, 8, 16),
- Support::bytepack32_4x8(ArchInfo::kIdA32 , ArchInfo::kSubIdNone, 4, 16),
- Support::bytepack32_4x8(ArchInfo::kIdA64 , ArchInfo::kSubIdNone, 8, 32)
-};
-
-ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t id, uint32_t subId) noexcept {
- uint32_t index = id < ASMJIT_ARRAY_SIZE(archInfoTable) ? id : uint32_t(0);
-
- // Make sure the `archInfoTable` array is correctly indexed.
- _signature = archInfoTable[index];
- ASMJIT_ASSERT(_id == index);
-
- // Even if the architecture is not known we setup its id and sub-id,
- // however, such architecture is not really useful.
- _id = uint8_t(id);
- _subId = uint8_t(subId);
-}
-
-// ============================================================================
// [asmjit::ArchUtils]
// ============================================================================
-ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archId, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept {
- uint32_t typeId = typeIdInOut;
-
- // Zero the signature so it's clear in case that typeId is not invalid.
- regInfo._signature = 0;
+ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfoOut) noexcept {
+ // Zero the output in case the input is invalid.
+ *typeIdOut = 0;
+ regInfoOut->reset();
- // TODO: Move to X86 backend.
#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId)) {
- // Passed RegType instead of TypeId?
- if (typeId <= BaseReg::kTypeMax)
- typeId = x86::opData.archRegs.regTypeToTypeId[typeId];
-
- if (ASMJIT_UNLIKELY(!Type::isValid(typeId)))
- return DebugUtils::errored(kErrorInvalidTypeId);
-
- // First normalize architecture dependent types.
- if (Type::isAbstract(typeId)) {
- if (typeId == Type::kIdIntPtr)
- typeId = (archId == ArchInfo::kIdX86) ? Type::kIdI32 : Type::kIdI64;
- else
- typeId = (archId == ArchInfo::kIdX86) ? Type::kIdU32 : Type::kIdU64;
- }
-
- // Type size helps to construct all groupss of registers. If the size is zero
- // then the TypeId is invalid.
- uint32_t size = Type::sizeOf(typeId);
- if (ASMJIT_UNLIKELY(!size))
- return DebugUtils::errored(kErrorInvalidTypeId);
-
- if (ASMJIT_UNLIKELY(typeId == Type::kIdF80))
- return DebugUtils::errored(kErrorInvalidUseOfF80);
-
- uint32_t regType = 0;
-
- switch (typeId) {
- case Type::kIdI8:
- case Type::kIdU8:
- regType = x86::Reg::kTypeGpbLo;
- break;
-
- case Type::kIdI16:
- case Type::kIdU16:
- regType = x86::Reg::kTypeGpw;
- break;
-
- case Type::kIdI32:
- case Type::kIdU32:
- regType = x86::Reg::kTypeGpd;
- break;
-
- case Type::kIdI64:
- case Type::kIdU64:
- if (archId == ArchInfo::kIdX86)
- return DebugUtils::errored(kErrorInvalidUseOfGpq);
-
- regType = x86::Reg::kTypeGpq;
- break;
-
- // F32 and F64 are always promoted to use vector registers.
- case Type::kIdF32:
- typeId = Type::kIdF32x1;
- regType = x86::Reg::kTypeXmm;
- break;
-
- case Type::kIdF64:
- typeId = Type::kIdF64x1;
- regType = x86::Reg::kTypeXmm;
- break;
-
- // Mask registers {k}.
- case Type::kIdMask8:
- case Type::kIdMask16:
- case Type::kIdMask32:
- case Type::kIdMask64:
- regType = x86::Reg::kTypeKReg;
- break;
-
- // MMX registers.
- case Type::kIdMmx32:
- case Type::kIdMmx64:
- regType = x86::Reg::kTypeMm;
- break;
-
- // XMM|YMM|ZMM registers.
- default:
- if (size <= 16)
- regType = x86::Reg::kTypeXmm;
- else if (size == 32)
- regType = x86::Reg::kTypeYmm;
- else
- regType = x86::Reg::kTypeZmm;
- break;
- }
+ if (Environment::isFamilyX86(arch))
+ return x86::ArchInternal::typeIdToRegInfo(arch, typeId, typeIdOut, regInfoOut);
+#endif
- typeIdInOut = typeId;
- regInfo._signature = x86::opData.archRegs.regInfo[regType].signature();
- return kErrorOk;
- }
+#ifdef ASMJIT_BUILD_ARM
+ if (Environment::isFamilyARM(arch))
+ return arm::ArchInternal::typeIdToRegInfo(arch, typeId, typeIdOut, regInfoOut);
#endif
return DebugUtils::errored(kErrorInvalidArch);
diff --git a/3rdparty/asmjit/src/asmjit/core/arch.h b/3rdparty/asmjit/src/asmjit/core/arch.h
index b0a27fd9cd5..4991a3330d3 100644
--- a/3rdparty/asmjit/src/asmjit/core/arch.h
+++ b/3rdparty/asmjit/src/asmjit/core/arch.h
@@ -24,7 +24,7 @@
#ifndef ASMJIT_CORE_ARCH_H_INCLUDED
#define ASMJIT_CORE_ARCH_H_INCLUDED
-#include "../core/globals.h"
+#include "../core/environment.h"
#include "../core/operand.h"
ASMJIT_BEGIN_NAMESPACE
@@ -33,153 +33,10 @@ ASMJIT_BEGIN_NAMESPACE
//! \{
// ============================================================================
-// [asmjit::ArchInfo]
-// ============================================================================
-
-class ArchInfo {
-public:
- union {
- struct {
- //! Architecture id.
- uint8_t _id;
- //! Architecture sub-id.
- uint8_t _subId;
- //! Default size of a general purpose register.
- uint8_t _gpSize;
- //! Count of all general purpose registers.
- uint8_t _gpCount;
- };
- //! Architecture signature (32-bit int).
- uint32_t _signature;
- };
-
- //! Architecture id.
- enum Id : uint32_t {
- kIdNone = 0, //!< No/Unknown architecture.
-
- // X86 architectures.
- kIdX86 = 1, //!< X86 architecture (32-bit).
- kIdX64 = 2, //!< X64 architecture (64-bit) (AMD64).
-
- // ARM architectures.
- kIdA32 = 3, //!< ARM 32-bit architecture (AArch32/ARM/THUMB).
- kIdA64 = 4, //!< ARM 64-bit architecture (AArch64).
-
- //! Architecture detected at compile-time (architecture of the host).
- kIdHost = ASMJIT_ARCH_X86 == 32 ? kIdX86 :
- ASMJIT_ARCH_X86 == 64 ? kIdX64 :
- ASMJIT_ARCH_ARM == 32 ? kIdA32 :
- ASMJIT_ARCH_ARM == 64 ? kIdA64 : kIdNone
- };
-
- //! Architecture sub-type or execution mode.
- enum SubType : uint32_t {
- kSubIdNone = 0, //!< Default mode (or no specific mode).
-
- // X86 sub-types.
- kSubIdX86_AVX = 1, //!< Code generation uses AVX by default (VEC instructions).
- kSubIdX86_AVX2 = 2, //!< Code generation uses AVX2 by default (VEC instructions).
- kSubIdX86_AVX512 = 3, //!< Code generation uses AVX-512F by default (+32 vector regs).
- kSubIdX86_AVX512VL = 4, //!< Code generation uses AVX-512F-VL by default (+VL extensions).
-
- // ARM sub-types.
- kSubIdA32_Thumb = 8, //!< THUMB|THUMBv2 sub-type (only ARM in 32-bit mode).
-
-#if (ASMJIT_ARCH_X86) && defined(__AVX512VL__)
- kSubIdHost = kSubIdX86_AVX512VL
-#elif (ASMJIT_ARCH_X86) && defined(__AVX512F__)
- kSubIdHost = kSubIdX86_AVX512
-#elif (ASMJIT_ARCH_X86) && defined(__AVX2__)
- kSubIdHost = kSubIdX86_AVX2
-#elif (ASMJIT_ARCH_X86) && defined(__AVX__)
- kSubIdHost = kSubIdX86_AVX
-#elif (ASMJIT_ARCH_ARM == 32) && (defined(_M_ARMT) || defined(__thumb__) || defined(__thumb2__))
- kSubIdHost = kSubIdA32_Thumb
-#else
- kSubIdHost = 0
-#endif
- };
-
- //! \name Construction & Destruction
- //! \{
-
- inline ArchInfo() noexcept : _signature(0) {}
- inline ArchInfo(const ArchInfo& other) noexcept : _signature(other._signature) {}
- inline explicit ArchInfo(uint32_t type, uint32_t subType = kSubIdNone) noexcept { init(type, subType); }
- inline explicit ArchInfo(Globals::NoInit_) noexcept {}
-
- inline static ArchInfo host() noexcept { return ArchInfo(kIdHost, kSubIdHost); }
-
- inline bool isInitialized() const noexcept { return _id != kIdNone; }
-
- ASMJIT_API void init(uint32_t type, uint32_t subType = kSubIdNone) noexcept;
- inline void reset() noexcept { _signature = 0; }
-
- //! \}
-
- //! \name Overloaded Operators
- //! \{
-
- inline ArchInfo& operator=(const ArchInfo& other) noexcept = default;
-
- inline bool operator==(const ArchInfo& other) const noexcept { return _signature == other._signature; }
- inline bool operator!=(const ArchInfo& other) const noexcept { return _signature != other._signature; }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- //! Returns the architecture id, see `Id`.
- inline uint32_t archId() const noexcept { return _id; }
-
- //! Returns the architecture sub-id, see `SubType`.
- //!
- //! X86 & X64
- //! ---------
- //!
- //! Architecture subtype describe the highest instruction-set level that can
- //! be used.
- //!
- //! A32 & A64
- //! ---------
- //!
- //! Architecture mode means the instruction encoding to be used when generating
- //! machine code, thus mode can be used to force generation of THUMB and THUMBv2
- //! encoding or regular ARM encoding.
- inline uint32_t archSubId() const noexcept { return _subId; }
-
- //! Tests whether this architecture is 32-bit.
- inline bool is32Bit() const noexcept { return _gpSize == 4; }
- //! Tests whether this architecture is 64-bit.
- inline bool is64Bit() const noexcept { return _gpSize == 8; }
-
- //! Tests whether this architecture is X86, X64.
- inline bool isX86Family() const noexcept { return isX86Family(_id); }
- //! Tests whether this architecture is ARM32 or ARM64.
- inline bool isArmFamily() const noexcept { return isArmFamily(_id); }
-
- //! Returns the native size of a general-purpose register.
- inline uint32_t gpSize() const noexcept { return _gpSize; }
- //! Returns number of general-purpose registers.
- inline uint32_t gpCount() const noexcept { return _gpCount; }
-
- //! \}
-
- //! \name Static Functions
- //! \{
-
- static inline bool isX86Family(uint32_t archId) noexcept { return archId >= kIdX86 && archId <= kIdX64; }
- static inline bool isArmFamily(uint32_t archId) noexcept { return archId >= kIdA32 && archId <= kIdA64; }
-
- //! \}
-};
-
-// ============================================================================
// [asmjit::ArchRegs]
// ============================================================================
-//! Information about all architecture registers.
+//! Information about registers of a CPU architecture.
struct ArchRegs {
//! Register information and signatures indexed by `BaseReg::RegType`.
RegInfo regInfo[BaseReg::kTypeMax + 1];
@@ -193,9 +50,12 @@ struct ArchRegs {
// [asmjit::ArchUtils]
// ============================================================================
-struct ArchUtils {
- ASMJIT_API static Error typeIdToRegInfo(uint32_t archId, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept;
-};
+//! Architecture utilities.
+namespace ArchUtils {
+
+ASMJIT_API Error typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfo) noexcept;
+
+} // {ArchUtils}
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/assembler.cpp b/3rdparty/asmjit/src/asmjit/core/assembler.cpp
index 35c39ab6089..2eea9cbae94 100644
--- a/3rdparty/asmjit/src/asmjit/core/assembler.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/assembler.cpp
@@ -25,7 +25,9 @@
#include "../core/assembler.h"
#include "../core/codebufferwriter_p.h"
#include "../core/constpool.h"
-#include "../core/logging.h"
+#include "../core/emitterutils_p.h"
+#include "../core/formatter.h"
+#include "../core/logger.h"
#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
@@ -39,9 +41,7 @@ BaseAssembler::BaseAssembler() noexcept
_section(nullptr),
_bufferData(nullptr),
_bufferEnd(nullptr),
- _bufferPtr(nullptr),
- _op4(),
- _op5() {}
+ _bufferPtr(nullptr) {}
BaseAssembler::~BaseAssembler() noexcept {}
// ============================================================================
@@ -50,7 +50,7 @@ BaseAssembler::~BaseAssembler() noexcept {}
Error BaseAssembler::setOffset(size_t offset) {
if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
size_t size = Support::max<size_t>(_section->bufferSize(), this->offset());
if (ASMJIT_UNLIKELY(offset > size))
@@ -61,25 +61,6 @@ Error BaseAssembler::setOffset(size_t offset) {
}
// ============================================================================
-// [asmjit::BaseAssembler - Logging]
-// ============================================================================
-
-#ifndef ASMJIT_NO_LOGGING
-static void BaseAssembler_logLabel(BaseAssembler* self, const Label& label) noexcept {
- Logger* logger = self->_code->_logger;
-
- StringTmp<512> sb;
- size_t binSize = logger->hasFlag(FormatOptions::kFlagMachineCode) ? size_t(0) : std::numeric_limits<size_t>::max();
-
- sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationLabel));
- Logging::formatLabel(sb, logger->flags(), self, label.id());
- sb.appendChar(':');
- Logging::formatLine(sb, nullptr, binSize, 0, 0, self->_inlineComment);
- logger->log(sb.data(), sb.size());
-}
-#endif
-
-// ============================================================================
// [asmjit::BaseAssembler - Section Management]
// ============================================================================
@@ -100,8 +81,8 @@ Error BaseAssembler::section(Section* section) {
return reportError(DebugUtils::errored(kErrorInvalidSection));
#ifndef ASMJIT_NO_LOGGING
- if (hasEmitterOption(kOptionLoggingEnabled))
- _code->_logger->logf(".section %s {#%u}\n", section->name(), section->id());
+ if (_logger)
+ _logger->logf(".section %s {#%u}\n", section->name(), section->id());
#endif
BaseAssembler_initSection(this, section);
@@ -119,7 +100,8 @@ Label BaseAssembler::newLabel() {
Error err = _code->newLabelEntry(&le);
if (ASMJIT_UNLIKELY(err))
reportError(err);
- labelId = le->id();
+ else
+ labelId = le->id();
}
return Label(labelId);
}
@@ -131,20 +113,21 @@ Label BaseAssembler::newNamedLabel(const char* name, size_t nameSize, uint32_t t
Error err = _code->newNamedLabelEntry(&le, name, nameSize, type, parentId);
if (ASMJIT_UNLIKELY(err))
reportError(err);
- labelId = le->id();
+ else
+ labelId = le->id();
}
return Label(labelId);
}
Error BaseAssembler::bind(const Label& label) {
if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
Error err = _code->bindLabel(label, _section->id(), offset());
#ifndef ASMJIT_NO_LOGGING
- if (hasEmitterOption(kOptionLoggingEnabled))
- BaseAssembler_logLabel(this, label);
+ if (_logger)
+ EmitterUtils::logLabelBound(this, label);
#endif
resetInlineComment();
@@ -155,165 +138,112 @@ Error BaseAssembler::bind(const Label& label) {
}
// ============================================================================
-// [asmjit::BaseAssembler - Emit (Low-Level)]
+// [asmjit::BaseAssembler - Embed]
// ============================================================================
-Error BaseAssembler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
- _op4 = o4;
- _op5 = o5;
- _instOptions |= BaseInst::kOptionOp4Op5Used;
- return _emit(instId, o0, o1, o2, o3);
-}
-
-Error BaseAssembler::_emitOpArray(uint32_t instId, const Operand_* operands, size_t count) {
- const Operand_* o0 = &operands[0];
- const Operand_* o1 = &operands[1];
- const Operand_* o2 = &operands[2];
- const Operand_* o3 = &operands[3];
-
- switch (count) {
- case 0: o0 = &Globals::none; ASMJIT_FALLTHROUGH;
- case 1: o1 = &Globals::none; ASMJIT_FALLTHROUGH;
- case 2: o2 = &Globals::none; ASMJIT_FALLTHROUGH;
- case 3: o3 = &Globals::none; ASMJIT_FALLTHROUGH;
- case 4:
- return _emit(instId, *o0, *o1, *o2, *o3);
-
- case 5:
- _op4 = operands[4];
- _op5.reset();
- _instOptions |= BaseInst::kOptionOp4Op5Used;
- return _emit(instId, *o0, *o1, *o2, *o3);
-
- case 6:
- _op4 = operands[4];
- _op5 = operands[5];
- _instOptions |= BaseInst::kOptionOp4Op5Used;
- return _emit(instId, *o0, *o1, *o2, *o3);
-
- default:
- return DebugUtils::errored(kErrorInvalidArgument);
- }
-}
-
#ifndef ASMJIT_NO_LOGGING
-void BaseAssembler::_emitLog(
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3,
- uint32_t relSize, uint32_t immSize, uint8_t* afterCursor) {
+struct DataSizeByPower {
+ char str[4];
+};
- Logger* logger = _code->logger();
- ASMJIT_ASSERT(logger != nullptr);
- ASMJIT_ASSERT(options & BaseEmitter::kOptionLoggingEnabled);
+static const DataSizeByPower dataSizeByPowerTable[] = {
+ { "db" },
+ { "dw" },
+ { "dd" },
+ { "dq" }
+};
+#endif
- StringTmp<256> sb;
- uint32_t flags = logger->flags();
+Error BaseAssembler::embed(const void* data, size_t dataSize) {
+ if (ASMJIT_UNLIKELY(!_code))
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
- uint8_t* beforeCursor = _bufferPtr;
- intptr_t emittedSize = (intptr_t)(afterCursor - beforeCursor);
+ if (dataSize == 0)
+ return kErrorOk;
- Operand_ operands[Globals::kMaxOpCount];
- operands[0].copyFrom(o0);
- operands[1].copyFrom(o1);
- operands[2].copyFrom(o2);
- operands[3].copyFrom(o3);
+ CodeBufferWriter writer(this);
+ ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize));
- if (options & BaseInst::kOptionOp4Op5Used) {
- operands[4].copyFrom(_op4);
- operands[5].copyFrom(_op5);
- }
- else {
- operands[4].reset();
- operands[5].reset();
- }
+ writer.emitData(data, dataSize);
- sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationCode));
- Logging::formatInstruction(sb, flags, this, archId(), BaseInst(instId, options, _extraReg), operands, Globals::kMaxOpCount);
+#ifndef ASMJIT_NO_LOGGING
+ if (_logger)
+ _logger->logBinary(data, dataSize);
+#endif
- if ((flags & FormatOptions::kFlagMachineCode) != 0)
- Logging::formatLine(sb, _bufferPtr, size_t(emittedSize), relSize, immSize, inlineComment());
- else
- Logging::formatLine(sb, nullptr, std::numeric_limits<size_t>::max(), 0, 0, inlineComment());
- logger->log(sb);
+ writer.done(this);
+ return kErrorOk;
}
-Error BaseAssembler::_emitFailed(
- Error err,
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+Error BaseAssembler::embedDataArray(uint32_t typeId, const void* data, size_t itemCcount, size_t repeatCount) {
+ uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize());
+ uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta);
- StringTmp<256> sb;
- sb.appendString(DebugUtils::errorAsString(err));
- sb.appendString(": ");
+ if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId)))
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
- Operand_ operands[Globals::kMaxOpCount];
- operands[0].copyFrom(o0);
- operands[1].copyFrom(o1);
- operands[2].copyFrom(o2);
- operands[3].copyFrom(o3);
+ if (itemCcount == 0 || repeatCount == 0)
+ return kErrorOk;
- if (options & BaseInst::kOptionOp4Op5Used) {
- operands[4].copyFrom(_op4);
- operands[5].copyFrom(_op5);
- }
- else {
- operands[4].reset();
- operands[5].reset();
- }
+ uint32_t typeSize = Type::sizeOf(finalTypeId);
+ Support::FastUInt8 of = 0;
- Logging::formatInstruction(sb, 0, this, archId(), BaseInst(instId, options, _extraReg), operands, Globals::kMaxOpCount);
+ size_t dataSize = Support::mulOverflow(itemCcount, size_t(typeSize), &of);
+ size_t totalSize = Support::mulOverflow(dataSize, repeatCount, &of);
- if (inlineComment()) {
- sb.appendString(" ; ");
- sb.appendString(inlineComment());
- }
+ if (ASMJIT_UNLIKELY(of))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
- resetInstOptions();
- resetExtraReg();
- resetInlineComment();
- return reportError(err, sb.data());
-}
+ CodeBufferWriter writer(this);
+ ASMJIT_PROPAGATE(writer.ensureSpace(this, totalSize));
+
+#ifndef ASMJIT_NO_LOGGING
+ const uint8_t* start = writer.cursor();
#endif
-// ============================================================================
-// [asmjit::BaseAssembler - Embed]
-// ============================================================================
+ for (size_t i = 0; i < repeatCount; i++) {
+ writer.emitData(data, dataSize);
+ }
#ifndef ASMJIT_NO_LOGGING
-struct DataSizeByPower {
- char str[4];
-};
-
-static const DataSizeByPower dataSizeByPowerTable[] = {
- { "db" },
- { "dw" },
- { "dd" },
- { "dq" }
-};
+ if (_logger)
+ _logger->logBinary(start, totalSize);
#endif
-Error BaseAssembler::embed(const void* data, uint32_t dataSize) {
+ writer.done(this);
+ return kErrorOk;
+}
+
+Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) {
if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
- if (dataSize == 0)
- return DebugUtils::errored(kErrorInvalidArgument);
+ if (ASMJIT_UNLIKELY(!isLabelValid(label)))
+ return reportError(DebugUtils::errored(kErrorInvalidLabel));
+ ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment())));
+ ASMJIT_PROPAGATE(bind(label));
+
+ size_t size = pool.size();
CodeBufferWriter writer(this);
- ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize));
+ ASMJIT_PROPAGATE(writer.ensureSpace(this, size));
- writer.emitData(data, dataSize);
+ pool.fill(writer.cursor());
#ifndef ASMJIT_NO_LOGGING
- if (ASMJIT_UNLIKELY(hasEmitterOption(kOptionLoggingEnabled)))
- _code->_logger->logBinary(data, dataSize);
+ if (_logger)
+ _logger->logBinary(writer.cursor(), size);
#endif
+ writer.advance(size);
writer.done(this);
+
return kErrorOk;
}
Error BaseAssembler::embedLabel(const Label& label) {
if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
ASMJIT_ASSERT(_code != nullptr);
RelocEntry* re;
@@ -322,30 +252,22 @@ Error BaseAssembler::embedLabel(const Label& label) {
if (ASMJIT_UNLIKELY(!le))
return reportError(DebugUtils::errored(kErrorInvalidLabel));
- uint32_t dataSize = gpSize();
+ uint32_t dataSize = registerSize();
ASMJIT_ASSERT(dataSize <= 8);
CodeBufferWriter writer(this);
ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize));
#ifndef ASMJIT_NO_LOGGING
- if (ASMJIT_UNLIKELY(hasEmitterOption(kOptionLoggingEnabled))) {
+ if (_logger) {
StringTmp<256> sb;
- sb.appendFormat(".%s ", dataSizeByPowerTable[Support::ctz(dataSize)].str);
- Logging::formatLabel(sb, 0, this, label.id());
- sb.appendChar('\n');
- _code->_logger->log(sb);
+ sb.appendFormat("%s ", dataSizeByPowerTable[Support::ctz(dataSize)].str);
+ Formatter::formatLabel(sb, 0, this, label.id());
+ sb.append('\n');
+ _logger->log(sb);
}
#endif
- // TODO: Does it make sense to calculate the address here if everything is known?
- /*
- if (_code->hasBaseAddress() && currentSection() == _code->textSection() && le->isBound()) {
- uint64_t addr = _code->baseAddress() + _code->textSection()->offset() + le->offset();
- writer.emitValueLE(addr, dataSize);
- }
- */
-
Error err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs, dataSize);
if (ASMJIT_UNLIKELY(err))
return reportError(err);
@@ -371,9 +293,9 @@ Error BaseAssembler::embedLabel(const Label& label) {
return kErrorOk;
}
-Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, uint32_t dataSize) {
+Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
LabelEntry* labelEntry = _code->labelEntry(label);
LabelEntry* baseEntry = _code->labelEntry(base);
@@ -382,7 +304,7 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, uint
return reportError(DebugUtils::errored(kErrorInvalidLabel));
if (dataSize == 0)
- dataSize = gpSize();
+ dataSize = registerSize();
if (ASMJIT_UNLIKELY(!Support::isPowerOf2(dataSize) || dataSize > 8))
return reportError(DebugUtils::errored(kErrorInvalidOperandSize));
@@ -391,14 +313,14 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, uint
ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize));
#ifndef ASMJIT_NO_LOGGING
- if (ASMJIT_UNLIKELY(hasEmitterOption(kOptionLoggingEnabled))) {
+ if (_logger) {
StringTmp<256> sb;
sb.appendFormat(".%s (", dataSizeByPowerTable[Support::ctz(dataSize)].str);
- Logging::formatLabel(sb, 0, this, label.id());
- sb.appendString(" - ");
- Logging::formatLabel(sb, 0, this, base.id());
- sb.appendString(")\n");
- _code->_logger->log(sb);
+ Formatter::formatLabel(sb, 0, this, label.id());
+ sb.append(" - ");
+ Formatter::formatLabel(sb, 0, this, base.id());
+ sb.append(")\n");
+ _logger->log(sb);
}
#endif
@@ -409,7 +331,7 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, uint
}
else {
RelocEntry* re;
- Error err = _code->newRelocEntry(&re, RelocEntry::kTypeExpression, dataSize);
+ Error err = _code->newRelocEntry(&re, RelocEntry::kTypeExpression, uint32_t(dataSize));
if (ASMJIT_UNLIKELY(err))
return reportError(err);
@@ -433,46 +355,18 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, uint
return kErrorOk;
}
-Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (ASMJIT_UNLIKELY(!isLabelValid(label)))
- return DebugUtils::errored(kErrorInvalidLabel);
-
- ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment())));
- ASMJIT_PROPAGATE(bind(label));
-
- size_t size = pool.size();
- CodeBufferWriter writer(this);
- ASMJIT_PROPAGATE(writer.ensureSpace(this, size));
-
- pool.fill(writer.cursor());
-
-#ifndef ASMJIT_NO_LOGGING
- if (ASMJIT_UNLIKELY(hasEmitterOption(kOptionLoggingEnabled)))
- _code->_logger->logBinary(writer.cursor(), size);
-#endif
-
- writer.advance(size);
- writer.done(this);
-
- return kErrorOk;
-}
-
// ============================================================================
// [asmjit::BaseAssembler - Comment]
// ============================================================================
Error BaseAssembler::comment(const char* data, size_t size) {
if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
#ifndef ASMJIT_NO_LOGGING
- if (hasEmitterOption(kOptionLoggingEnabled)) {
- Logger* logger = _code->logger();
- logger->log(data, size);
- logger->log("\n", 1);
+ if (_logger) {
+ _logger->log(data, size);
+ _logger->log("\n", 1);
return kErrorOk;
}
#else
@@ -492,10 +386,6 @@ Error BaseAssembler::onAttach(CodeHolder* code) noexcept {
// Attach to the end of the .text section.
BaseAssembler_initSection(this, code->_sections[0]);
- // And reset everything that is used temporarily.
- _op4.reset();
- _op5.reset();
-
return kErrorOk;
}
@@ -504,10 +394,6 @@ Error BaseAssembler::onDetach(CodeHolder* code) noexcept {
_bufferData = nullptr;
_bufferEnd = nullptr;
_bufferPtr = nullptr;
-
- _op4.reset();
- _op5.reset();
-
return Base::onDetach(code);
}
diff --git a/3rdparty/asmjit/src/asmjit/core/assembler.h b/3rdparty/asmjit/src/asmjit/core/assembler.h
index fd2c1c33c28..966dabb06e0 100644
--- a/3rdparty/asmjit/src/asmjit/core/assembler.h
+++ b/3rdparty/asmjit/src/asmjit/core/assembler.h
@@ -31,14 +31,23 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_core
+//! \addtogroup asmjit_assembler
//! \{
// ============================================================================
// [asmjit::BaseAssembler]
// ============================================================================
-//! Base encoder (assembler).
+//! Base assembler.
+//!
+//! This is a base class that provides interface used by architecture specific
+//! assembler implementations. Assembler doesn't hold any data, instead it's
+//! attached to \ref CodeHolder, which provides all the data that Assembler
+//! needs and which can be altered by it.
+//!
+//! Check out architecture specific assemblers for more details and examples:
+//!
+//! - \ref x86::Assembler - X86/X64 assembler implementation.
class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter {
public:
ASMJIT_NONCOPYABLE(BaseAssembler)
@@ -52,10 +61,6 @@ public:
uint8_t* _bufferEnd;
//! Pointer in the CodeBuffer of the current section.
uint8_t* _bufferPtr;
- //! 5th operand data, used only temporarily.
- Operand_ _op4;
- //! 6th operand data, used only temporarily.
- Operand_ _op5;
//! \name Construction & Destruction
//! \{
@@ -77,10 +82,11 @@ public:
//! Returns the current position in the CodeBuffer.
inline size_t offset() const noexcept { return (size_t)(_bufferPtr - _bufferData); }
+
//! Sets the current position in the CodeBuffer to `offset`.
//!
- //! \note The `offset` cannot be outside of the buffer size (even if it's
- //! within buffer's capacity).
+ //! \note The `offset` cannot be greater than buffer size even if it's
+ //! within the buffer's capacity.
ASMJIT_API Error setOffset(size_t offset);
//! Returns the start of the CodeBuffer in the current section.
@@ -95,6 +101,7 @@ public:
//! \name Section Management
//! \{
+ //! Returns the current section.
inline Section* currentSection() const noexcept { return _section; }
ASMJIT_API Error section(Section* section) override;
@@ -110,47 +117,16 @@ public:
//! \}
- //! \cond INTERNAL
- //! \name Emit
- //! \{
-
- using BaseEmitter::_emit;
-
- ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) override;
- ASMJIT_API Error _emitOpArray(uint32_t instId, const Operand_* operands, size_t count) override;
-
-protected:
-#ifndef ASMJIT_NO_LOGGING
- void _emitLog(
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3,
- uint32_t relSize, uint32_t immSize, uint8_t* afterCursor);
-
- Error _emitFailed(
- Error err,
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
-#else
- inline Error _emitFailed(
- uint32_t err,
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
-
- DebugUtils::unused(instId, options, o0, o1, o2, o3);
- resetInstOptions();
- resetInlineComment();
- return reportError(err);
- }
-#endif
-public:
- //! \}
- //! \endcond
-
//! \name Embed
//! \{
- ASMJIT_API Error embed(const void* data, uint32_t dataSize) override;
- ASMJIT_API Error embedLabel(const Label& label) override;
- ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, uint32_t dataSize) override;
+ ASMJIT_API Error embed(const void* data, size_t dataSize) override;
+ ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t itemCcount, size_t repeatCount = 1) override;
ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
+ ASMJIT_API Error embedLabel(const Label& label) override;
+ ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize) override;
+
//! \}
//! \name Comment
diff --git a/3rdparty/asmjit/src/asmjit/core/builder.cpp b/3rdparty/asmjit/src/asmjit/core/builder.cpp
index 35d7127481c..97780c767a4 100644
--- a/3rdparty/asmjit/src/asmjit/core/builder.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/builder.cpp
@@ -25,7 +25,10 @@
#ifndef ASMJIT_NO_BUILDER
#include "../core/builder.h"
-#include "../core/logging.h"
+#include "../core/emitterutils_p.h"
+#include "../core/errorhandler.h"
+#include "../core/formatter.h"
+#include "../core/logger.h"
#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
@@ -41,13 +44,23 @@ class PostponedErrorHandler : public ErrorHandler {
public:
void handleError(Error err, const char* message, BaseEmitter* origin) override {
DebugUtils::unused(err, origin);
- _message.assignString(message);
+ _message.assign(message);
}
StringTmp<128> _message;
};
// ============================================================================
+// [asmjit::BaseBuilder - Utilities]
+// ============================================================================
+
+static void BaseBuilder_deletePasses(BaseBuilder* self) noexcept {
+ for (Pass* pass : self->_passes)
+ pass->~Pass();
+ self->_passes.reset();
+}
+
+// ============================================================================
// [asmjit::BaseBuilder - Construction / Destruction]
// ============================================================================
@@ -63,132 +76,101 @@ BaseBuilder::BaseBuilder() noexcept
_firstNode(nullptr),
_lastNode(nullptr),
_nodeFlags(0) {}
-BaseBuilder::~BaseBuilder() noexcept {}
+
+BaseBuilder::~BaseBuilder() noexcept {
+ BaseBuilder_deletePasses(this);
+}
// ============================================================================
// [asmjit::BaseBuilder - Node Management]
// ============================================================================
-LabelNode* BaseBuilder::newLabelNode() noexcept {
- LabelNode* node = newNodeT<LabelNode>();
- if (!node || registerLabelNode(node) != kErrorOk)
- return nullptr;
- return node;
-}
+Error BaseBuilder::_newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount) {
+ uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
+ ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
-AlignNode* BaseBuilder::newAlignNode(uint32_t alignMode, uint32_t alignment) noexcept {
- return newNodeT<AlignNode>(alignMode, alignment);
+ InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
+ if (ASMJIT_UNLIKELY(!node))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
+
+ *out = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
+ return kErrorOk;
}
-EmbedDataNode* BaseBuilder::newEmbedDataNode(const void* data, uint32_t size) noexcept {
- if (size > EmbedDataNode::kInlineBufferSize) {
- void* cloned = _dataZone.alloc(size);
- if (ASMJIT_UNLIKELY(!cloned))
- return nullptr;
- if (data)
- memcpy(cloned, data, size);
- data = cloned;
- }
+Error BaseBuilder::_newLabelNode(LabelNode** out) {
+ *out = nullptr;
- return newNodeT<EmbedDataNode>(const_cast<void*>(data), size);
+ ASMJIT_PROPAGATE(_newNodeT<LabelNode>(out));
+ return registerLabelNode(*out);
}
-ConstPoolNode* BaseBuilder::newConstPoolNode() noexcept {
- ConstPoolNode* node = newNodeT<ConstPoolNode>();
- if (!node || registerLabelNode(node) != kErrorOk)
- return nullptr;
- return node;
+Error BaseBuilder::_newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment) {
+ *out = nullptr;
+ return _newNodeT<AlignNode>(out, alignMode, alignment);
}
-CommentNode* BaseBuilder::newCommentNode(const char* data, size_t size) noexcept {
- if (data) {
- if (size == SIZE_MAX)
- size = strlen(data);
+Error BaseBuilder::_newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) {
+ *out = nullptr;
- if (size > 0) {
- data = static_cast<char*>(_dataZone.dup(data, size, true));
- if (!data) return nullptr;
- }
- }
+ uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize());
+ uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta);
- return newNodeT<CommentNode>(data);
-}
+ if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId)))
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
-InstNode* BaseBuilder::newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0) noexcept {
- uint32_t opCount = 1;
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= 4);
+ uint32_t typeSize = Type::sizeOf(finalTypeId);
+ Support::FastUInt8 of = 0;
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- if (ASMJIT_UNLIKELY(!node))
- return nullptr;
+ size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of);
+ if (ASMJIT_UNLIKELY(of))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
- node = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
- node->setOp(0, o0);
- node->resetOps(opCount, opCapacity);
- return node;
-}
+ EmbedDataNode* node;
+ ASMJIT_PROPAGATE(_newNodeT<EmbedDataNode>(&node));
-InstNode* BaseBuilder::newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, const Operand_& o1) noexcept {
- uint32_t opCount = 2;
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= 4);
+ node->_embed._typeId = uint8_t(typeId);
+ node->_embed._typeSize = uint8_t(typeSize);
+ node->_itemCount = itemCount;
+ node->_repeatCount = repeatCount;
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- if (ASMJIT_UNLIKELY(!node))
- return nullptr;
+ uint8_t* dstData = node->_inlineData;
+ if (dataSize > EmbedDataNode::kInlineBufferSize) {
+ dstData = static_cast<uint8_t*>(_dataZone.alloc(dataSize, 8));
+ if (ASMJIT_UNLIKELY(!dstData))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ node->_externalData = dstData;
+ }
- node = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
- node->setOp(0, o0);
- node->setOp(1, o1);
- node->resetOps(opCount, opCapacity);
- return node;
-}
+ if (data)
+ memcpy(dstData, data, dataSize);
-InstNode* BaseBuilder::newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, const Operand_& o1, const Operand_& o2) noexcept {
- uint32_t opCount = 3;
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= 4);
+ *out = node;
+ return kErrorOk;
+}
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- if (ASMJIT_UNLIKELY(!node))
- return nullptr;
+Error BaseBuilder::_newConstPoolNode(ConstPoolNode** out) {
+ *out = nullptr;
- node = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
- node->setOp(0, o0);
- node->setOp(1, o1);
- node->setOp(2, o2);
- node->resetOps(opCount, opCapacity);
- return node;
+ ASMJIT_PROPAGATE(_newNodeT<ConstPoolNode>(out));
+ return registerLabelNode(*out);
}
-InstNode* BaseBuilder::newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) noexcept {
- uint32_t opCount = 4;
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= 4);
-
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- if (ASMJIT_UNLIKELY(!node))
- return nullptr;
+Error BaseBuilder::_newCommentNode(CommentNode** out, const char* data, size_t size) {
+ *out = nullptr;
- node = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
- node->setOp(0, o0);
- node->setOp(1, o1);
- node->setOp(2, o2);
- node->setOp(3, o3);
- node->resetOps(opCount, opCapacity);
- return node;
-}
+ if (data) {
+ if (size == SIZE_MAX)
+ size = strlen(data);
-InstNode* BaseBuilder::newInstNodeRaw(uint32_t instId, uint32_t instOptions, uint32_t opCount) noexcept {
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= 4);
+ if (size > 0) {
+ data = static_cast<char*>(_dataZone.dup(data, size, true));
+ if (ASMJIT_UNLIKELY(!data))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ }
+ }
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- if (ASMJIT_UNLIKELY(!node))
- return nullptr;
- return new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
+ return _newNodeT<CommentNode>(out, data);
}
BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
@@ -368,34 +350,42 @@ BaseNode* BaseBuilder::setCursor(BaseNode* node) noexcept {
// [asmjit::BaseBuilder - Section]
// ============================================================================
-Error BaseBuilder::sectionNodeOf(SectionNode** pOut, uint32_t sectionId) noexcept {
+Error BaseBuilder::sectionNodeOf(SectionNode** out, uint32_t sectionId) {
+ *out = nullptr;
+
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
if (ASMJIT_UNLIKELY(!_code->isSectionValid(sectionId)))
- return DebugUtils::errored(kErrorInvalidSection);
+ return reportError(DebugUtils::errored(kErrorInvalidSection));
- if (sectionId >= _sectionNodes.size())
- ASMJIT_PROPAGATE(_sectionNodes.resize(&_allocator, sectionId + 1));
+ if (sectionId >= _sectionNodes.size()) {
+ Error err = _sectionNodes.reserve(&_allocator, sectionId + 1);
+ if (ASMJIT_UNLIKELY(err != kErrorOk))
+ return reportError(err);
+ }
+
+ SectionNode* node = nullptr;
+ if (sectionId < _sectionNodes.size())
+ node = _sectionNodes[sectionId];
- SectionNode* node = _sectionNodes[sectionId];
if (!node) {
- node = newNodeT<SectionNode>(sectionId);
- if (ASMJIT_UNLIKELY(!node))
- return DebugUtils::errored(kErrorOutOfMemory);
+ ASMJIT_PROPAGATE(_newNodeT<SectionNode>(&node, sectionId));
+
+ // We have already reserved enough space, this cannot fail now.
+ if (sectionId >= _sectionNodes.size())
+ _sectionNodes.resize(&_allocator, sectionId + 1);
+
_sectionNodes[sectionId] = node;
}
- *pOut = node;
+ *out = node;
return kErrorOk;
}
Error BaseBuilder::section(Section* section) {
SectionNode* node;
- Error err = sectionNodeOf(&node, section->id());
-
- if (ASMJIT_UNLIKELY(err))
- return reportError(err);
+ ASMJIT_PROPAGATE(sectionNodeOf(&node, section->id()));
if (!node->isActive()) {
// Insert the section at the end if it was not part of the code.
@@ -444,7 +434,9 @@ void BaseBuilder::updateSectionLinks() noexcept {
// [asmjit::BaseBuilder - Labels]
// ============================================================================
-Error BaseBuilder::labelNodeOf(LabelNode** pOut, uint32_t labelId) noexcept {
+Error BaseBuilder::labelNodeOf(LabelNode** out, uint32_t labelId) {
+ *out = nullptr;
+
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
@@ -457,22 +449,18 @@ Error BaseBuilder::labelNodeOf(LabelNode** pOut, uint32_t labelId) noexcept {
LabelNode* node = _labelNodes[index];
if (!node) {
- node = newNodeT<LabelNode>(labelId);
- if (ASMJIT_UNLIKELY(!node))
- return DebugUtils::errored(kErrorOutOfMemory);
+ ASMJIT_PROPAGATE(_newNodeT<LabelNode>(&node, labelId));
_labelNodes[index] = node;
}
- *pOut = node;
+ *out = node;
return kErrorOk;
}
-Error BaseBuilder::registerLabelNode(LabelNode* node) noexcept {
+Error BaseBuilder::registerLabelNode(LabelNode* node) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
- // Don't call `reportError()` from here, we are noexcept and we are called
- // by `newLabelNode()` and `newFuncNode()`, which are noexcept as well.
LabelEntry* le;
ASMJIT_PROPAGATE(_code->newLabelEntry(&le));
uint32_t labelId = le->id();
@@ -482,68 +470,58 @@ Error BaseBuilder::registerLabelNode(LabelNode* node) noexcept {
ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, labelId + 1));
_labelNodes[labelId] = node;
- node->_id = labelId;
+ node->_labelId = labelId;
return kErrorOk;
}
-static Error BaseBuilder_newLabelInternal(BaseBuilder* self, uint32_t labelId) noexcept {
+static Error BaseBuilder_newLabelInternal(BaseBuilder* self, uint32_t labelId) {
ASMJIT_ASSERT(self->_labelNodes.size() < labelId + 1);
- LabelNode* node = self->newNodeT<LabelNode>(labelId);
- if (ASMJIT_UNLIKELY(!node))
- return DebugUtils::errored(kErrorOutOfMemory);
+ uint32_t growBy = labelId - self->_labelNodes.size();
+ Error err = self->_labelNodes.willGrow(&self->_allocator, growBy);
+
+ if (ASMJIT_UNLIKELY(err))
+ return self->reportError(err);
+
+ LabelNode* node;
+ ASMJIT_PROPAGATE(self->_newNodeT<LabelNode>(&node, labelId));
- ASMJIT_PROPAGATE(self->_labelNodes.resize(&self->_allocator, labelId + 1));
+ self->_labelNodes.resize(&self->_allocator, labelId + 1);
self->_labelNodes[labelId] = node;
- node->_id = labelId;
+ node->_labelId = labelId;
return kErrorOk;
}
Label BaseBuilder::newLabel() {
uint32_t labelId = Globals::kInvalidId;
- if (_code) {
- LabelEntry* le;
- Error err = _code->newLabelEntry(&le);
- if (ASMJIT_UNLIKELY(err)) {
- reportError(err);
- }
- else {
- err = BaseBuilder_newLabelInternal(this, le->id());
- if (ASMJIT_UNLIKELY(err))
- reportError(err);
- else
- labelId = le->id();
- }
+ LabelEntry* le;
+
+ if (_code &&
+ _code->newLabelEntry(&le) == kErrorOk &&
+ BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
+ labelId = le->id();
}
+
return Label(labelId);
}
Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize, uint32_t type, uint32_t parentId) {
uint32_t labelId = Globals::kInvalidId;
- if (_code) {
- LabelEntry* le;
- Error err = _code->newNamedLabelEntry(&le, name, nameSize, type, parentId);
- if (ASMJIT_UNLIKELY(err)) {
- reportError(err);
- }
- else {
- err = BaseBuilder_newLabelInternal(this, le->id());
- if (ASMJIT_UNLIKELY(err))
- reportError(err);
- else
- labelId = le->id();
- }
+ LabelEntry* le;
+
+ if (_code &&
+ _code->newNamedLabelEntry(&le, name, nameSize, type, parentId) == kErrorOk &&
+ BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
+ labelId = le->id();
}
+
return Label(labelId);
}
Error BaseBuilder::bind(const Label& label) {
LabelNode* node;
- Error err = labelNodeOf(&node, label);
-
- if (ASMJIT_UNLIKELY(err))
- return reportError(err);
+ ASMJIT_PROPAGATE(labelNodeOf(&node, label));
addNode(node);
return kErrorOk;
@@ -610,7 +588,6 @@ Error BaseBuilder::runPasses() {
if (_passes.empty())
return kErrorOk;
- Logger* logger = code()->logger();
ErrorHandler* prev = errorHandler();
PostponedErrorHandler postponed;
@@ -619,8 +596,9 @@ Error BaseBuilder::runPasses() {
for (Pass* pass : _passes) {
_passZone.reset();
- err = pass->run(&_passZone, logger);
- if (err) break;
+ err = pass->run(&_passZone, _logger);
+ if (err)
+ break;
}
_passZone.reset();
setErrorHandler(prev);
@@ -635,104 +613,21 @@ Error BaseBuilder::runPasses() {
// [asmjit::BaseBuilder - Emit]
// ============================================================================
-Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
- uint32_t opCount = 4;
-
- if (o3.isNone()) {
- opCount = 3;
- if (o2.isNone()) {
- opCount = 2;
- if (o1.isNone()) {
- opCount = 1;
- if (o0.isNone())
- opCount = 0;
- }
- }
- }
+Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
+ uint32_t opCount = EmitterUtils::opCountFromEmitArgs(o0, o1, o2, opExt);
+ uint32_t options = instOptions() | forcedInstOptions();
- uint32_t options = instOptions() | globalInstOptions();
if (options & BaseInst::kOptionReserved) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
#ifndef ASMJIT_NO_VALIDATION
// Strict validation.
- if (hasEmitterOption(kOptionStrictValidation)) {
- Operand_ opArray[4];
- opArray[0].copyFrom(o0);
- opArray[1].copyFrom(o1);
- opArray[2].copyFrom(o2);
- opArray[3].copyFrom(o3);
-
- Error err = InstAPI::validate(archId(), BaseInst(instId, options, _extraReg), opArray, opCount);
- if (ASMJIT_UNLIKELY(err)) {
- resetInstOptions();
- resetExtraReg();
- resetInlineComment();
- return reportError(err);
- }
- }
-#endif
-
- // Clear options that should never be part of `InstNode`.
- options &= ~BaseInst::kOptionReserved;
- }
-
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= 4);
-
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- const char* comment = inlineComment();
-
- resetInstOptions();
- resetInlineComment();
-
- if (ASMJIT_UNLIKELY(!node)) {
- resetExtraReg();
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- }
-
- node = new(node) InstNode(this, instId, options, opCount, opCapacity);
- node->setExtraReg(extraReg());
- node->setOp(0, o0);
- node->setOp(1, o1);
- node->setOp(2, o2);
- node->setOp(3, o3);
- node->resetOps(4, opCapacity);
-
- if (comment)
- node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
-
- addNode(node);
- resetExtraReg();
- return kErrorOk;
-}
-
-Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
- uint32_t opCount = Globals::kMaxOpCount;
- if (o5.isNone()) {
- opCount = 5;
- if (o4.isNone())
- return _emit(instId, o0, o1, o2, o3);
- }
-
- uint32_t options = instOptions() | globalInstOptions();
- if (ASMJIT_UNLIKELY(options & BaseInst::kOptionReserved)) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
-#ifndef ASMJIT_NO_VALIDATION
- // Strict validation.
- if (hasEmitterOption(kOptionStrictValidation)) {
+ if (hasValidationOption(kValidationOptionIntermediate)) {
Operand_ opArray[Globals::kMaxOpCount];
- opArray[0].copyFrom(o0);
- opArray[1].copyFrom(o1);
- opArray[2].copyFrom(o2);
- opArray[3].copyFrom(o3);
- opArray[4].copyFrom(o4);
- opArray[5].copyFrom(o5);
-
- Error err = InstAPI::validate(archId(), BaseInst(instId, options, _extraReg), opArray, opCount);
+ EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
+
+ Error err = InstAPI::validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount);
if (ASMJIT_UNLIKELY(err)) {
resetInstOptions();
resetExtraReg();
@@ -747,7 +642,7 @@ Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1
}
uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= opCount);
+ ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
const char* comment = inlineComment();
@@ -765,11 +660,9 @@ Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1
node->setOp(0, o0);
node->setOp(1, o1);
node->setOp(2, o2);
- node->setOp(3, o3);
- node->setOp(4, o4);
-
- if (opCapacity > 5)
- node->setOp(5, o5);
+ for (uint32_t i = 3; i < opCount; i++)
+ node->setOp(i, opExt[i - 3]);
+ node->resetOpRange(opCount, opCapacity);
if (comment)
node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
@@ -787,9 +680,8 @@ Error BaseBuilder::align(uint32_t alignMode, uint32_t alignment) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
- AlignNode* node = newAlignNode(alignMode, alignment);
- if (ASMJIT_UNLIKELY(!node))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ AlignNode* node;
+ ASMJIT_PROPAGATE(_newAlignNode(&node, alignMode, alignment));
addNode(node);
return kErrorOk;
@@ -799,57 +691,71 @@ Error BaseBuilder::align(uint32_t alignMode, uint32_t alignment) {
// [asmjit::BaseBuilder - Embed]
// ============================================================================
-Error BaseBuilder::embed(const void* data, uint32_t dataSize) {
+Error BaseBuilder::embed(const void* data, size_t dataSize) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
- EmbedDataNode* node = newEmbedDataNode(data, dataSize);
- if (ASMJIT_UNLIKELY(!node))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ EmbedDataNode* node;
+ ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, data, dataSize));
addNode(node);
return kErrorOk;
}
-Error BaseBuilder::embedLabel(const Label& label) {
+Error BaseBuilder::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t itemRepeat) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
- EmbedLabelNode* node = newNodeT<EmbedLabelNode>(label.id());
- if (ASMJIT_UNLIKELY(!node))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ EmbedDataNode* node;
+ ASMJIT_PROPAGATE(_newEmbedDataNode(&node, typeId, data, itemCount, itemRepeat));
addNode(node);
return kErrorOk;
}
-Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, uint32_t dataSize) {
+Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
- EmbedLabelDeltaNode* node = newNodeT<EmbedLabelDeltaNode>(label.id(), base.id(), dataSize);
- if (ASMJIT_UNLIKELY(!node))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ if (!isLabelValid(label))
+ return reportError(DebugUtils::errored(kErrorInvalidLabel));
+ ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment())));
+ ASMJIT_PROPAGATE(bind(label));
+
+ EmbedDataNode* node;
+ ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, nullptr, pool.size()));
+
+ pool.fill(node->data());
addNode(node);
return kErrorOk;
}
-Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool) {
+Error BaseBuilder::embedLabel(const Label& label) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
- if (!isLabelValid(label))
- return reportError(DebugUtils::errored(kErrorInvalidLabel));
- ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment())));
- ASMJIT_PROPAGATE(bind(label));
+ EmbedLabelNode* node;
+ ASMJIT_PROPAGATE(_newNodeT<EmbedLabelNode>(&node, label.id()));
- EmbedDataNode* node = newEmbedDataNode(nullptr, uint32_t(pool.size()));
- if (ASMJIT_UNLIKELY(!node))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ addNode(node);
+ return kErrorOk;
+}
+
+Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
+ if (ASMJIT_UNLIKELY(!_code))
+ return DebugUtils::errored(kErrorNotInitialized);
+
+ // If dataSize is zero it means that the size is the same as target register
+ // width, however, if it's provided we really want to validate whether it's
+ // within the possible range.
+ if (dataSize && (!Support::isPowerOf2(dataSize) || dataSize > 8))
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
+
+ EmbedLabelDeltaNode* node;
+ ASMJIT_PROPAGATE(_newNodeT<EmbedLabelDeltaNode>(&node, label.id(), base.id(), uint32_t(dataSize)));
- pool.fill(node->data());
addNode(node);
return kErrorOk;
}
@@ -862,9 +768,8 @@ Error BaseBuilder::comment(const char* data, size_t size) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
- CommentNode* node = newCommentNode(data, size);
- if (ASMJIT_UNLIKELY(!node))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ CommentNode* node;
+ ASMJIT_PROPAGATE(_newCommentNode(&node, data, size));
addNode(node);
return kErrorOk;
@@ -878,12 +783,38 @@ Error BaseBuilder::serialize(BaseEmitter* dst) {
Error err = kErrorOk;
BaseNode* node_ = _firstNode;
+ Operand_ opArray[Globals::kMaxOpCount];
+
do {
dst->setInlineComment(node_->inlineComment());
if (node_->isInst()) {
InstNode* node = node_->as<InstNode>();
- err = dst->emitInst(node->baseInst(), node->operands(), node->opCount());
+
+ // NOTE: Inlined to remove one additional call per instruction.
+ dst->setInstOptions(node->instOptions());
+ dst->setExtraReg(node->extraReg());
+
+ const Operand_* op = node->operands();
+ const Operand_* opExt = EmitterUtils::noExt;
+
+ uint32_t opCount = node->opCount();
+ if (opCount > 3) {
+ uint32_t i = 4;
+ opArray[3] = op[3];
+
+ while (i < opCount) {
+ opArray[i].copyFrom(op[i]);
+ i++;
+ }
+ while (i < Globals::kMaxOpCount) {
+ opArray[i].reset();
+ i++;
+ }
+ opExt = opArray + 3;
+ }
+
+ err = dst->_emit(node->id(), op[0], op[1], op[2], opExt);
}
else if (node_->isLabel()) {
if (node_->isConstPool()) {
@@ -901,7 +832,7 @@ Error BaseBuilder::serialize(BaseEmitter* dst) {
}
else if (node_->isEmbedData()) {
EmbedDataNode* node = node_->as<EmbedDataNode>();
- err = dst->embed(node->data(), node->size());
+ err = dst->embedDataArray(node->typeId(), node->data(), node->itemCount(), node->repeatCount());
}
else if (node_->isEmbedLabel()) {
EmbedLabelNode* node = node_->as<EmbedLabelNode>();
@@ -928,23 +859,6 @@ Error BaseBuilder::serialize(BaseEmitter* dst) {
}
// ============================================================================
-// [asmjit::BaseBuilder - Logging]
-// ============================================================================
-
-#ifndef ASMJIT_NO_LOGGING
-Error BaseBuilder::dump(String& sb, uint32_t flags) const noexcept {
- BaseNode* node = _firstNode;
- while (node) {
- ASMJIT_PROPAGATE(Logging::formatNode(sb, flags, this, node));
- sb.appendChar('\n');
- node = node->next();
- }
-
- return kErrorOk;
-}
-#endif
-
-// ============================================================================
// [asmjit::BaseBuilder - Events]
// ============================================================================
@@ -962,7 +876,6 @@ Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
return err;
}
-
_cursor = initialSection;
_firstNode = initialSection;
_lastNode = initialSection;
@@ -972,7 +885,7 @@ Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
}
Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
- _passes.reset();
+ BaseBuilder_deletePasses(this);
_sectionNodes.reset();
_labelNodes.reset();
diff --git a/3rdparty/asmjit/src/asmjit/core/builder.h b/3rdparty/asmjit/src/asmjit/core/builder.h
index c6d359995fc..ba99267dafa 100644
--- a/3rdparty/asmjit/src/asmjit/core/builder.h
+++ b/3rdparty/asmjit/src/asmjit/core/builder.h
@@ -30,10 +30,12 @@
#include "../core/assembler.h"
#include "../core/codeholder.h"
#include "../core/constpool.h"
+#include "../core/formatter.h"
#include "../core/inst.h"
#include "../core/operand.h"
#include "../core/string.h"
#include "../core/support.h"
+#include "../core/type.h"
#include "../core/zone.h"
#include "../core/zonevector.h"
@@ -68,6 +70,18 @@ class JumpAnnotation;
// [asmjit::BaseBuilder]
// ============================================================================
+//! Builder interface.
+//!
+//! `BaseBuilder` interface was designed to be used as a \ref BaseAssembler
+//! replacement in case pre-processing or post-processing of the generated code
+//! is required. The code can be modified during or after code generation. Pre
+//! or post processing can be done manually or through a \ref Pass object. \ref
+//! BaseBuilder stores the emitted code as a double-linked list of nodes, which
+//! allows O(1) insertion and removal during processing.
+//!
+//! Check out architecture specific builders for more details and examples:
+//!
+//! - \ref x86::Builder - X86/X64 builder implementation.
class ASMJIT_VIRTAPI BaseBuilder : public BaseEmitter {
public:
ASMJIT_NONCOPYABLE(BaseBuilder)
@@ -127,33 +141,26 @@ public:
//! \remarks The pointer returned (if non-null) is owned by the Builder or
//! Compiler. When the Builder/Compiler is destroyed it destroys all nodes
//! it created so no manual memory management is required.
- template<typename T>
- inline T* newNodeT() noexcept {
- return _allocator.newT<T>(this);
- }
-
- //! \overload
template<typename T, typename... Args>
- inline T* newNodeT(Args&&... args) noexcept {
- return _allocator.newT<T>(this, std::forward<Args>(args)...);
+ inline Error _newNodeT(T** out, Args&&... args) {
+ *out = _allocator.newT<T>(this, std::forward<Args>(args)...);
+ if (ASMJIT_UNLIKELY(!*out))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ return kErrorOk;
}
- //! Creates a new `LabelNode`.
- ASMJIT_API LabelNode* newLabelNode() noexcept;
- //! Creates a new `AlignNode`.
- ASMJIT_API AlignNode* newAlignNode(uint32_t alignMode, uint32_t alignment) noexcept;
- //! Creates a new `EmbedDataNode`.
- ASMJIT_API EmbedDataNode* newEmbedDataNode(const void* data, uint32_t size) noexcept;
- //! Creates a new `ConstPoolNode`.
- ASMJIT_API ConstPoolNode* newConstPoolNode() noexcept;
- //! Creates a new `CommentNode`.
- ASMJIT_API CommentNode* newCommentNode(const char* data, size_t size) noexcept;
-
- ASMJIT_API InstNode* newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0) noexcept;
- ASMJIT_API InstNode* newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, const Operand_& o1) noexcept;
- ASMJIT_API InstNode* newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, const Operand_& o1, const Operand_& o2) noexcept;
- ASMJIT_API InstNode* newInstNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) noexcept;
- ASMJIT_API InstNode* newInstNodeRaw(uint32_t instId, uint32_t instOptions, uint32_t opCount) noexcept;
+ //! Creates a new \ref InstNode.
+ ASMJIT_API Error _newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount);
+ //! Creates a new \ref LabelNode.
+ ASMJIT_API Error _newLabelNode(LabelNode** out);
+ //! Creates a new \ref AlignNode.
+ ASMJIT_API Error _newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment);
+ //! Creates a new \ref EmbedDataNode.
+ ASMJIT_API Error _newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1);
+ //! Creates a new \ref ConstPoolNode.
+ ASMJIT_API Error _newConstPoolNode(ConstPoolNode** out);
+ //! Creates a new \ref CommentNode.
+ ASMJIT_API Error _newCommentNode(CommentNode** out, const char* data, size_t size);
//! Adds `node` after the current and sets the current node to the given `node`.
ASMJIT_API BaseNode* addNode(BaseNode* node) noexcept;
@@ -173,7 +180,9 @@ public:
//! added they are always added after the cursor and the cursor is changed
//! to be that newly added node. Use `setCursor()` to change where new nodes
//! are inserted.
- inline BaseNode* cursor() const noexcept { return _cursor; }
+ inline BaseNode* cursor() const noexcept {
+ return _cursor;
+ }
//! Sets the current node to `node` and return the previous one.
ASMJIT_API BaseNode* setCursor(BaseNode* node) noexcept;
@@ -182,7 +191,9 @@ public:
//!
//! Only use this function if you are concerned about performance and want
//! this inlined (for example if you set the cursor in a loop, etc...).
- inline void _setCursor(BaseNode* node) noexcept { _cursor = node; }
+ inline void _setCursor(BaseNode* node) noexcept {
+ _cursor = node;
+ }
//! \}
@@ -193,7 +204,9 @@ public:
//!
//! \note If a section of some id is not associated with the Builder/Compiler
//! it would be null, so always check for nulls if you iterate over the vector.
- inline const ZoneVector<SectionNode*>& sectionNodes() const noexcept { return _sectionNodes; }
+ inline const ZoneVector<SectionNode*>& sectionNodes() const noexcept {
+ return _sectionNodes;
+ }
//! Tests whether the `SectionNode` of the given `sectionId` was registered.
inline bool hasRegisteredSectionNode(uint32_t sectionId) const noexcept {
@@ -205,7 +218,7 @@ public:
//! \remarks This function will either get the existing `SectionNode` or create
//! it in case it wasn't created before. You can check whether a section has a
//! registered `SectionNode` by using `BaseBuilder::hasRegisteredSectionNode()`.
- ASMJIT_API Error sectionNodeOf(SectionNode** pOut, uint32_t sectionId) noexcept;
+ ASMJIT_API Error sectionNodeOf(SectionNode** out, uint32_t sectionId);
ASMJIT_API Error section(Section* section) override;
@@ -221,7 +234,7 @@ public:
//! \name Label Management
//! \{
- //! Returns a vector of LabelNode nodes.
+ //! Returns a vector of \ref LabelNode nodes.
//!
//! \note If a label of some id is not associated with the Builder/Compiler
//! it would be null, so always check for nulls if you iterate over the vector.
@@ -237,24 +250,24 @@ public:
return hasRegisteredLabelNode(label.id());
}
- //! Gets or creates a `LabelNode` that matches the given `labelId`.
+ //! Gets or creates a \ref LabelNode that matches the given `labelId`.
//!
//! \remarks This function will either get the existing `LabelNode` or create
//! it in case it wasn't created before. You can check whether a label has a
- //! registered `LabelNode` by using `BaseBuilder::hasRegisteredLabelNode()`.
- ASMJIT_API Error labelNodeOf(LabelNode** pOut, uint32_t labelId) noexcept;
+ //! registered `LabelNode` by calling \ref BaseBuilder::hasRegisteredLabelNode().
+ ASMJIT_API Error labelNodeOf(LabelNode** out, uint32_t labelId);
//! \overload
- inline Error labelNodeOf(LabelNode** pOut, const Label& label) noexcept {
- return labelNodeOf(pOut, label.id());
+ inline Error labelNodeOf(LabelNode** out, const Label& label) {
+ return labelNodeOf(out, label.id());
}
- //! Registers this label node [Internal].
+ //! Registers this \ref LabelNode (internal).
//!
//! This function is used internally to register a newly created `LabelNode`
- //! with this instance of Builder/Compiler. Use `labelNodeOf()` functions to
- //! get back `LabelNode` from a label or its identifier.
- ASMJIT_API Error registerLabelNode(LabelNode* node) noexcept;
+ //! with this instance of Builder/Compiler. Use \ref labelNodeOf() functions
+ //! to get back \ref LabelNode from a label or its identifier.
+ ASMJIT_API Error registerLabelNode(LabelNode* node);
ASMJIT_API Label newLabel() override;
ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) override;
@@ -284,12 +297,14 @@ public:
inline T* newPassT(Args&&... args) noexcept { return _codeZone.newT<T>(std::forward<Args>(args)...); }
template<typename T>
- inline Error addPassT() noexcept { return addPass(newPassT<T>()); }
+ inline Error addPassT() { return addPass(newPassT<T>()); }
template<typename T, typename... Args>
- inline Error addPassT(Args&&... args) noexcept { return addPass(newPassT<T, Args...>(std::forward<Args>(args)...)); }
+ inline Error addPassT(Args&&... args) { return addPass(newPassT<T, Args...>(std::forward<Args>(args)...)); }
//! Returns `Pass` by name.
+ //!
+ //! If the pass having the given `name` doesn't exist `nullptr` is returned.
ASMJIT_API Pass* passByName(const char* name) const noexcept;
//! Adds `pass` to the list of passes.
ASMJIT_API Error addPass(Pass* pass) noexcept;
@@ -304,8 +319,7 @@ public:
//! \name Emit
//! \{
- ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) override;
- ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) override;
+ ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
//! \}
@@ -319,11 +333,13 @@ public:
//! \name Embed
//! \{
- ASMJIT_API Error embed(const void* data, uint32_t dataSize) override;
- ASMJIT_API Error embedLabel(const Label& label) override;
- ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, uint32_t dataSize) override;
+ ASMJIT_API Error embed(const void* data, size_t dataSize) override;
+ ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t count, size_t repeat = 1) override;
ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
+ ASMJIT_API Error embedLabel(const Label& label) override;
+ ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize) override;
+
//! \}
//! \name Comment
@@ -345,15 +361,6 @@ public:
//! \}
- //! \name Logging
- //! \{
-
-#ifndef ASMJIT_NO_LOGGING
- ASMJIT_API Error dump(String& sb, uint32_t flags = 0) const noexcept;
-#endif
-
- //! \}
-
//! \name Events
//! \{
@@ -361,6 +368,15 @@ public:
ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+#ifndef ASMJIT_NO_LOGGING
+ ASMJIT_DEPRECATED("Use Formatter::formatNodeList(sb, formatFlags, builder)")
+ inline Error dump(String& sb, uint32_t formatFlags = 0) const noexcept {
+ return Formatter::formatNodeList(sb, formatFlags, this);
+ }
+#endif // !ASMJIT_NO_LOGGING
+#endif // !ASMJIT_NO_DEPRECATED
};
// ============================================================================
@@ -369,11 +385,11 @@ public:
//! Base node.
//!
-//! Every node represents a building-block used by `BaseBuilder`. It can be
-//! instruction, data, label, comment, directive, or any other high-level
+//! Every node represents a building-block used by \ref BaseBuilder. It can
+//! be instruction, data, label, comment, directive, or any other high-level
//! representation that can be transformed to the building blocks mentioned.
-//! Every class that inherits `BaseBuilder` can define its own nodes that it
-//! can lower to basic nodes.
+//! Every class that inherits \ref BaseBuilder can define its own high-level
+//! nodes that can be later lowered to basic nodes like instructions.
class BaseNode {
public:
ASMJIT_NONCOPYABLE(BaseNode)
@@ -385,7 +401,7 @@ public:
//! Next node.
BaseNode* _next;
};
- //! Links (previous and next nodes).
+ //! Links (an alternative view to previous and next nodes).
BaseNode* _links[2];
};
@@ -401,6 +417,7 @@ public:
uint8_t _reserved1;
};
+ //! Data used by \ref InstNode.
struct InstData {
//! Node type, see \ref NodeType.
uint8_t _nodeType;
@@ -412,6 +429,19 @@ public:
uint8_t _opCapacity;
};
+ //! Data used by \ref EmbedDataNode.
+ struct EmbedData {
+ //! Node type, see \ref NodeType.
+ uint8_t _nodeType;
+ //! Node flags, see \ref Flags.
+ uint8_t _nodeFlags;
+ //! Type id, see \ref Type::Id.
+ uint8_t _typeId;
+ //! Size of `_typeId`.
+ uint8_t _typeSize;
+ };
+
+ //! Data used by \ref SentinelNode.
struct SentinelData {
//! Node type, see \ref NodeType.
uint8_t _nodeType;
@@ -423,9 +453,15 @@ public:
uint8_t _reserved1;
};
+ //! Data that can have different meaning dependning on \ref NodeType.
union {
+ //! Data useful by any node type.
AnyData _any;
+ //! Data specific to \ref InstNode.
InstData _inst;
+ //! Data specific to \ref EmbedDataNode.
+ EmbedData _embed;
+ //! Data specific to \ref SentinelNode.
SentinelData _sentinel;
};
@@ -434,7 +470,9 @@ public:
//! Value reserved for AsmJit users never touched by AsmJit itself.
union {
+ //! User data as 64-bit integer.
uint64_t _userDataU64;
+ //! User data as pointer.
void* _userDataPtr;
};
@@ -451,54 +489,66 @@ public:
// [BaseBuilder]
- //! Node is `InstNode` or `InstExNode`.
+ //! Node is \ref InstNode or \ref InstExNode.
kNodeInst = 1,
- //! Node is `SectionNode`.
+ //! Node is \ref SectionNode.
kNodeSection = 2,
- //! Node is `LabelNode`.
+ //! Node is \ref LabelNode.
kNodeLabel = 3,
- //! Node is `AlignNode`.
+ //! Node is \ref AlignNode.
kNodeAlign = 4,
- //! Node is `EmbedDataNode`.
+ //! Node is \ref EmbedDataNode.
kNodeEmbedData = 5,
- //! Node is `EmbedLabelNode`.
+ //! Node is \ref EmbedLabelNode.
kNodeEmbedLabel = 6,
- //! Node is `EmbedLabelDeltaNode`.
+ //! Node is \ref EmbedLabelDeltaNode.
kNodeEmbedLabelDelta = 7,
- //! Node is `ConstPoolNode`.
+ //! Node is \ref ConstPoolNode.
kNodeConstPool = 8,
- //! Node is `CommentNode`.
+ //! Node is \ref CommentNode.
kNodeComment = 9,
- //! Node is `SentinelNode`.
+ //! Node is \ref SentinelNode.
kNodeSentinel = 10,
// [BaseCompiler]
- //! Node is `JumpNode` (acts as InstNode).
+ //! Node is \ref JumpNode (acts as InstNode).
kNodeJump = 15,
- //! Node is `FuncNode` (acts as LabelNode).
+ //! Node is \ref FuncNode (acts as LabelNode).
kNodeFunc = 16,
- //! Node is `FuncRetNode` (acts as InstNode).
+ //! Node is \ref FuncRetNode (acts as InstNode).
kNodeFuncRet = 17,
- //! Node is `FuncCallNode` (acts as InstNode).
- kNodeFuncCall = 18,
+ //! Node is \ref InvokeNode (acts as InstNode).
+ kNodeInvoke = 18,
// [UserDefined]
//! First id of a user-defined node.
- kNodeUser = 32
+ kNodeUser = 32,
+
+#ifndef ASMJIT_NO_DEPRECATED
+ kNodeFuncCall = kNodeInvoke
+#endif // !ASMJIT_NO_DEPRECATED
};
//! Node flags, specify what the node is and/or does.
enum Flags : uint32_t {
- kFlagIsCode = 0x01u, //!< Node is code that can be executed (instruction, label, align, etc...).
- kFlagIsData = 0x02u, //!< Node is data that cannot be executed (data, const-pool, etc...).
- kFlagIsInformative = 0x04u, //!< Node is informative, can be removed and ignored.
- kFlagIsRemovable = 0x08u, //!< Node can be safely removed if unreachable.
- kFlagHasNoEffect = 0x10u, //!< Node does nothing when executed (label, align, explicit nop).
- kFlagActsAsInst = 0x20u, //!< Node is an instruction or acts as it.
- kFlagActsAsLabel = 0x40u, //!< Node is a label or acts as it.
- kFlagIsActive = 0x80u //!< Node is active (part of the code).
+ //! Node is code that can be executed (instruction, label, align, etc...).
+ kFlagIsCode = 0x01u,
+ //! Node is data that cannot be executed (data, const-pool, etc...).
+ kFlagIsData = 0x02u,
+ //! Node is informative, can be removed and ignored.
+ kFlagIsInformative = 0x04u,
+ //! Node can be safely removed if unreachable.
+ kFlagIsRemovable = 0x08u,
+ //! Node does nothing when executed (label, align, explicit nop).
+ kFlagHasNoEffect = 0x10u,
+ //! Node is an instruction or acts as it.
+ kFlagActsAsInst = 0x20u,
+ //! Node is a label or acts as it.
+ kFlagActsAsLabel = 0x40u,
+ //! Node is active (part of the code).
+ kFlagIsActive = 0x80u
};
//! \name Construction & Destruction
@@ -572,8 +622,13 @@ public:
inline bool isFunc() const noexcept { return type() == kNodeFunc; }
//! Tests whether this node is `FuncRetNode`.
inline bool isFuncRet() const noexcept { return type() == kNodeFuncRet; }
- //! Tests whether this node is `FuncCallNode`.
- inline bool isFuncCall() const noexcept { return type() == kNodeFuncCall; }
+ //! Tests whether this node is `InvokeNode`.
+ inline bool isInvoke() const noexcept { return type() == kNodeInvoke; }
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use isInvoke")
+ inline bool isFuncCall() const noexcept { return isInvoke(); }
+#endif // !ASMJIT_NO_DEPRECATED
//! Returns the node flags, see \ref Flags.
inline uint32_t flags() const noexcept { return _any._nodeFlags; }
@@ -697,12 +752,13 @@ public:
_inst._opCount = uint8_t(opCount);
}
+ //! \cond INTERNAL
//! Reset all built-in operands, including `extraReg`.
inline void _resetOps() noexcept {
_baseInst.resetExtraReg();
- for (uint32_t i = 0, count = opCapacity(); i < count; i++)
- _opArray[i].reset();
+ resetOpRange(0, opCapacity());
}
+ //! \endcond
//! \}
@@ -739,12 +795,12 @@ public:
//! Resets extra register operand.
inline void resetExtraReg() noexcept { _baseInst.resetExtraReg(); }
- //! Returns operands count.
+ //! Returns operand count.
inline uint32_t opCount() const noexcept { return _inst._opCount; }
- //! Returns operands capacity.
+ //! Returns operand capacity.
inline uint32_t opCapacity() const noexcept { return _inst._opCapacity; }
- //! Sets operands count.
+ //! Sets operand count.
inline void setOpCount(uint32_t opCount) noexcept { _inst._opCount = uint8_t(opCount); }
//! Returns operands array.
@@ -752,27 +808,32 @@ public:
//! Returns operands array (const).
inline const Operand* operands() const noexcept { return (const Operand*)_opArray; }
- inline Operand& opType(uint32_t index) noexcept {
+ //! Returns operand at the given `index`.
+ inline Operand& op(uint32_t index) noexcept {
ASMJIT_ASSERT(index < opCapacity());
return _opArray[index].as<Operand>();
}
- inline const Operand& opType(uint32_t index) const noexcept {
+ //! Returns operand at the given `index` (const).
+ inline const Operand& op(uint32_t index) const noexcept {
ASMJIT_ASSERT(index < opCapacity());
return _opArray[index].as<Operand>();
}
+ //! Sets operand at the given `index` to `op`.
inline void setOp(uint32_t index, const Operand_& op) noexcept {
ASMJIT_ASSERT(index < opCapacity());
_opArray[index].copyFrom(op);
}
+ //! Resets operand at the given `index` to none.
inline void resetOp(uint32_t index) noexcept {
ASMJIT_ASSERT(index < opCapacity());
_opArray[index].reset();
}
- inline void resetOps(uint32_t start, uint32_t end) noexcept {
+ //! Resets operands at `[start, end)` range.
+ inline void resetOpRange(uint32_t start, uint32_t end) noexcept {
for (uint32_t i = start; i < end; i++)
_opArray[i].reset();
}
@@ -816,6 +877,7 @@ public:
//! \name Rewriting
//! \{
+ //! \cond INTERNAL
inline uint32_t* _getRewriteArray() noexcept { return &_baseInst._extraReg._id; }
inline const uint32_t* _getRewriteArray() const noexcept { return &_baseInst._extraReg._id; }
@@ -833,12 +895,14 @@ public:
uint32_t* array = _getRewriteArray();
array[index] = id;
}
+ //! \endcond
//! \}
//! \name Static Functions
//! \{
+ //! \cond INTERNAL
static inline uint32_t capacityOfOpCount(uint32_t opCount) noexcept {
return opCount <= kBaseOpCapacity ? kBaseOpCapacity : Globals::kMaxOpCount;
}
@@ -847,6 +911,7 @@ public:
size_t base = sizeof(InstNode) - kBaseOpCapacity * sizeof(Operand);
return base + opCapacity * sizeof(Operand);
}
+ //! \endcond
//! \}
};
@@ -855,7 +920,7 @@ public:
// [asmjit::InstExNode]
// ============================================================================
-//! Instruction node with maximum number of operands..
+//! Instruction node with maximum number of operands.
//!
//! This node is created automatically by Builder/Compiler in case that the
//! required number of operands exceeds the default capacity of `InstNode`.
@@ -925,27 +990,33 @@ class LabelNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(LabelNode)
- uint32_t _id;
+ //! Label identifier.
+ uint32_t _labelId;
//! \name Construction & Destruction
//! \{
//! Creates a new `LabelNode` instance.
- inline LabelNode(BaseBuilder* cb, uint32_t id = 0) noexcept
+ inline LabelNode(BaseBuilder* cb, uint32_t labelId = 0) noexcept
: BaseNode(cb, kNodeLabel, kFlagHasNoEffect | kFlagActsAsLabel),
- _id(id) {}
+ _labelId(labelId) {}
//! \}
//! \name Accessors
//! \{
+ //! Returns \ref Label representation of the \ref LabelNode.
+ inline Label label() const noexcept { return Label(_labelId); }
//! Returns the id of the label.
- inline uint32_t id() const noexcept { return _id; }
- //! Returns the label as `Label` operand.
- inline Label label() const noexcept { return Label(_id); }
+ inline uint32_t labelId() const noexcept { return _labelId; }
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use labelId() instead")
+ inline uint32_t id() const noexcept { return labelId(); }
+#endif // !ASMJIT_NO_DEPRECATED
};
// ============================================================================
@@ -1005,37 +1076,28 @@ public:
ASMJIT_NONCOPYABLE(EmbedDataNode)
enum : uint32_t {
- kInlineBufferSize = uint32_t(64 - sizeof(BaseNode) - 4)
+ kInlineBufferSize = 128 - (sizeof(BaseNode) + sizeof(size_t) * 2)
};
+ size_t _itemCount;
+ size_t _repeatCount;
+
union {
- struct {
- //! Embedded data buffer.
- uint8_t _buf[kInlineBufferSize];
- //! Size of the data.
- uint32_t _size;
- };
- struct {
- //! Pointer to external data.
- uint8_t* _externalPtr;
- };
+ uint8_t* _externalData;
+ uint8_t _inlineData[kInlineBufferSize];
};
//! \name Construction & Destruction
//! \{
//! Creates a new `EmbedDataNode` instance.
- inline EmbedDataNode(BaseBuilder* cb, void* data, uint32_t size) noexcept
- : BaseNode(cb, kNodeEmbedData, kFlagIsData) {
-
- if (size <= kInlineBufferSize) {
- if (data)
- memcpy(_buf, data, size);
- }
- else {
- _externalPtr = static_cast<uint8_t*>(data);
- }
- _size = size;
+ inline EmbedDataNode(BaseBuilder* cb) noexcept
+ : BaseNode(cb, kNodeEmbedData, kFlagIsData),
+ _itemCount(0),
+ _repeatCount(0) {
+ _embed._typeId = uint8_t(Type::kIdU8),
+ _embed._typeSize = uint8_t(1);
+ memset(_inlineData, 0, kInlineBufferSize);
}
//! \}
@@ -1043,10 +1105,32 @@ public:
//! \name Accessors
//! \{
- //! Returns pointer to the data.
- inline uint8_t* data() const noexcept { return _size <= kInlineBufferSize ? const_cast<uint8_t*>(_buf) : _externalPtr; }
- //! Returns size of the data.
- inline uint32_t size() const noexcept { return _size; }
+ //! Returns \ref Type::Id of the data.
+ inline uint32_t typeId() const noexcept { return _embed._typeId; }
+ //! Returns the size of a single data element.
+ inline uint32_t typeSize() const noexcept { return _embed._typeSize; }
+
+ //! Returns a pointer to the data casted to `uint8_t`.
+ inline uint8_t* data() const noexcept {
+ return dataSize() <= kInlineBufferSize ? const_cast<uint8_t*>(_inlineData) : _externalData;
+ }
+
+ //! Returns a pointer to the data casted to `T`.
+ template<typename T>
+ inline T* dataAs() const noexcept { return reinterpret_cast<T*>(data()); }
+
+ //! Returns the number of (typed) items in the array.
+ inline size_t itemCount() const noexcept { return _itemCount; }
+
+ //! Returns how many times the data is repeated (default 1).
+ //!
+ //! Repeated data is useful when defining constants for SIMD, for example.
+ inline size_t repeatCount() const noexcept { return _repeatCount; }
+
+ //! Returns the size of the data, not considering the number of times it repeats.
+ //!
+ //! \note The returned value is the same as `typeSize() * itemCount()`.
+ inline size_t dataSize() const noexcept { return typeSize() * _itemCount; }
//! \}
};
@@ -1060,32 +1144,37 @@ class EmbedLabelNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(EmbedLabelNode)
- uint32_t _id;
+ uint32_t _labelId;
//! \name Construction & Destruction
//! \{
//! Creates a new `EmbedLabelNode` instance.
- inline EmbedLabelNode(BaseBuilder* cb, uint32_t id = 0) noexcept
+ inline EmbedLabelNode(BaseBuilder* cb, uint32_t labelId = 0) noexcept
: BaseNode(cb, kNodeEmbedLabel, kFlagIsData),
- _id(id) {}
+ _labelId(labelId) {}
//! \}
//! \name Accessors
//! \{
+ //! Returns the label to embed as \ref Label operand.
+ inline Label label() const noexcept { return Label(_labelId); }
//! Returns the id of the label.
- inline uint32_t id() const noexcept { return _id; }
- //! Sets the label id (use with caution, improper use can break a lot of things).
- inline void setId(uint32_t id) noexcept { _id = id; }
+ inline uint32_t labelId() const noexcept { return _labelId; }
- //! Returns the label as `Label` operand.
- inline Label label() const noexcept { return Label(_id); }
//! Sets the label id from `label` operand.
- inline void setLabel(const Label& label) noexcept { setId(label.id()); }
+ inline void setLabel(const Label& label) noexcept { setLabelId(label.id()); }
+ //! Sets the label id (use with caution, improper use can break a lot of things).
+ inline void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; }
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use labelId() instead")
+ inline uint32_t id() const noexcept { return labelId(); }
+#endif // !ASMJIT_NO_DEPRECATED
};
// ============================================================================
@@ -1097,18 +1186,18 @@ class EmbedLabelDeltaNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(EmbedLabelDeltaNode)
- uint32_t _id;
- uint32_t _baseId;
+ uint32_t _labelId;
+ uint32_t _baseLabelId;
uint32_t _dataSize;
//! \name Construction & Destruction
//! \{
//! Creates a new `EmbedLabelDeltaNode` instance.
- inline EmbedLabelDeltaNode(BaseBuilder* cb, uint32_t id = 0, uint32_t baseId = 0, uint32_t dataSize = 0) noexcept
+ inline EmbedLabelDeltaNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t baseLabelId = 0, uint32_t dataSize = 0) noexcept
: BaseNode(cb, kNodeEmbedLabelDelta, kFlagIsData),
- _id(id),
- _baseId(baseId),
+ _labelId(labelId),
+ _baseLabelId(baseLabelId),
_dataSize(dataSize) {}
//! \}
@@ -1116,28 +1205,46 @@ public:
//! \name Accessors
//! \{
- //! Returns the id of the label.
- inline uint32_t id() const noexcept { return _id; }
- //! Sets the label id.
- inline void setId(uint32_t id) noexcept { _id = id; }
//! Returns the label as `Label` operand.
- inline Label label() const noexcept { return Label(_id); }
+ inline Label label() const noexcept { return Label(_labelId); }
+ //! Returns the id of the label.
+ inline uint32_t labelId() const noexcept { return _labelId; }
+
//! Sets the label id from `label` operand.
- inline void setLabel(const Label& label) noexcept { setId(label.id()); }
+ inline void setLabel(const Label& label) noexcept { setLabelId(label.id()); }
+ //! Sets the label id.
+ inline void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; }
- //! Returns the id of the base label.
- inline uint32_t baseId() const noexcept { return _baseId; }
- //! Sets the base label id.
- inline void setBaseId(uint32_t baseId) noexcept { _baseId = baseId; }
//! Returns the base label as `Label` operand.
- inline Label baseLabel() const noexcept { return Label(_baseId); }
+ inline Label baseLabel() const noexcept { return Label(_baseLabelId); }
+ //! Returns the id of the base label.
+ inline uint32_t baseLabelId() const noexcept { return _baseLabelId; }
+
//! Sets the base label id from `label` operand.
- inline void setBaseLabel(const Label& baseLabel) noexcept { setBaseId(baseLabel.id()); }
+ inline void setBaseLabel(const Label& baseLabel) noexcept { setBaseLabelId(baseLabel.id()); }
+ //! Sets the base label id.
+ inline void setBaseLabelId(uint32_t baseLabelId) noexcept { _baseLabelId = baseLabelId; }
+ //! Returns the size of the embedded label address.
inline uint32_t dataSize() const noexcept { return _dataSize; }
+ //! Sets the size of the embedded label address.
inline void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; }
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use labelId() instead")
+ inline uint32_t id() const noexcept { return labelId(); }
+
+ ASMJIT_DEPRECATED("Use setLabelId() instead")
+ inline void setId(uint32_t id) noexcept { setLabelId(id); }
+
+ ASMJIT_DEPRECATED("Use baseLabelId() instead")
+ inline uint32_t baseId() const noexcept { return baseLabelId(); }
+
+ ASMJIT_DEPRECATED("Use setBaseLabelId() instead")
+ inline void setBaseId(uint32_t id) noexcept { setBaseLabelId(id); }
+#endif // !ASMJIT_NO_DEPRECATED
};
// ============================================================================
@@ -1229,7 +1336,9 @@ public:
//! Type of the sentinel (purery informative purpose).
enum SentinelType : uint32_t {
+ //! Type of the sentinel is not known.
kSentinelUnknown = 0u,
+ //! This is a sentinel used at the end of \ref FuncNode.
kSentinelFuncEnd = 1u
};
@@ -1248,8 +1357,15 @@ public:
//! \name Accessors
//! \{
- inline uint32_t sentinelType() const noexcept { return _sentinel._sentinelType; }
- inline void setSentinelType(uint32_t type) noexcept { _sentinel._sentinelType = uint8_t(type); }
+ //! Returns the type of the sentinel.
+ inline uint32_t sentinelType() const noexcept {
+ return _sentinel._sentinelType;
+ }
+
+ //! Sets the type of the sentinel.
+ inline void setSentinelType(uint32_t type) noexcept {
+ _sentinel._sentinelType = uint8_t(type);
+ }
//! \}
};
@@ -1280,7 +1396,9 @@ public:
//! \name Accessors
//! \{
+ //! Returns \ref BaseBuilder associated with the pass.
inline const BaseBuilder* cb() const noexcept { return _cb; }
+ //! Returns the name of the pass.
inline const char* name() const noexcept { return _name; }
//! \}
@@ -1292,7 +1410,7 @@ public:
//!
//! This is the only function that is called by the `BaseBuilder` to process
//! the code. It passes `zone`, which will be reset after the `run()` finishes.
- virtual Error run(Zone* zone, Logger* logger) noexcept = 0;
+ virtual Error run(Zone* zone, Logger* logger) = 0;
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/callconv.cpp b/3rdparty/asmjit/src/asmjit/core/callconv.cpp
index 5d915d0e38d..722dbcdb238 100644
--- a/3rdparty/asmjit/src/asmjit/core/callconv.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/callconv.cpp
@@ -40,17 +40,17 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::CallConv - Init / Reset]
// ============================================================================
-ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId) noexcept {
+ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId, const Environment& environment) noexcept {
reset();
#ifdef ASMJIT_BUILD_X86
- if (CallConv::isX86Family(ccId))
- return x86::CallConvInternal::init(*this, ccId);
+ if (environment.isFamilyX86())
+ return x86::CallConvInternal::init(*this, ccId, environment);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (CallConv::isArmFamily(ccId))
- return arm::CallConvInternal::init(*this, ccId);
+ if (environment.isFamilyARM())
+ return arm::CallConvInternal::init(*this, ccIdv, environment);
#endif
return DebugUtils::errored(kErrorInvalidArgument);
diff --git a/3rdparty/asmjit/src/asmjit/core/callconv.h b/3rdparty/asmjit/src/asmjit/core/callconv.h
index f3dc385dfec..6e75540c545 100644
--- a/3rdparty/asmjit/src/asmjit/core/callconv.h
+++ b/3rdparty/asmjit/src/asmjit/core/callconv.h
@@ -30,7 +30,7 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_func
+//! \addtogroup asmjit_function
//! \{
// ============================================================================
@@ -46,8 +46,8 @@ ASMJIT_BEGIN_NAMESPACE
struct CallConv {
//! Calling convention id, see `Id`.
uint8_t _id;
- //! Architecture id (see `ArchInfo::Id`).
- uint8_t _archId;
+ //! Architecture identifier, see \ref Environment::Arch.
+ uint8_t _arch;
//! Register assignment strategy.
uint8_t _strategy;
//! Flags.
@@ -78,179 +78,117 @@ struct CallConv {
uint32_t packed[(kMaxRegArgsPerGroup + 3) / 4];
};
- //! Passed registers' order, per group.
+ //! Passed registers' order, per register group.
RegOrder _passedOrder[BaseReg::kGroupVirt];
//! Calling convention id.
+ //!
+ //! Calling conventions can be divided into the following groups:
+ //!
+ //! - Universal - calling conventions are applicable to any target. They
+ //! will be converted to a target dependent calling convention at runtime
+ //! by \ref init(). The purpose of these conventions is to make using
+ //! functions less target dependent and closer to how they are declared
+ //! in C and C++.
+ //!
+ //! - Target specific - calling conventions that are used by a particular
+ //! architecture and ABI. For example Windows 64-bit calling convention
+ //! and AMD64 SystemV calling convention.
enum Id : uint32_t {
//! None or invalid (can't be used).
kIdNone = 0,
// ------------------------------------------------------------------------
- // [Universal]
+ // [Universal Calling Conventions]
// ------------------------------------------------------------------------
- // TODO: To make this possible we need to know target ARCH and ABI.
-
- /*
-
- // Universal calling conventions are applicable to any target and are
- // converted to target dependent conventions at runtime. The purpose of
- // these conventions is to make using functions less target dependent.
-
+ //! Standard function call or explicit `__cdecl` where it can be specified.
+ //!
+ //! This is a universal convention, which is used to initialize specific
+ //! calling connventions based on architecture, platform, and its ABI.
kIdCDecl = 1,
+
+ //! `__stdcall` on targets that support this calling convention.
+ //!
+ //! \note This calling convention is only supported on 32-bit X86. If used
+ //! on environment that doesn't support this calling convention \ref kIdCDecl
+ //! will be used instead.
kIdStdCall = 2,
+
+ //! `__fastcall` on targets that support this calling convention.
+ //!
+ //! \note This calling convention is only supported on 32-bit X86. If used
+ //! on environment that doesn't support this calling convention \ref kIdCDecl
+ //! will be used instead.
kIdFastCall = 3,
+ //! `__vectorcall` on targets that support this calling convention.
+ //!
+ //! \note This calling convention is only supported on 32-bit and 64-bit
+ //! X86 architecture on Windows platform. If used on environment that doesn't
+ //! support this calling convention \ref kIdCDecl will be used instead.
+ kIdVectorCall = 4,
+
+ //! `__thiscall` on targets that support this calling convention.
+ //!
+ //! \note This calling convention is only supported on 32-bit X86 Windows
+ //! platform. If used on environment that doesn't support this calling
+ //! convention \ref kIdCDecl will be used instead.
+ kIdThisCall = 5,
+
+ //! `__attribute__((regparm(1)))` convention (GCC and Clang).
+ kIdRegParm1 = 6,
+ //! `__attribute__((regparm(2)))` convention (GCC and Clang).
+ kIdRegParm2 = 7,
+ //! `__attribute__((regparm(3)))` convention (GCC and Clang).
+ kIdRegParm3 = 8,
+
+ //! Soft-float calling convention (ARM).
+ //!
+ //! Floating point arguments are passed via general purpose registers.
+ kIdSoftFloat = 9,
+
+ //! Hard-float calling convention (ARM).
+ //!
+ //! Floating point arguments are passed via SIMD registers.
+ kIdHardFloat = 10,
+
//! AsmJit specific calling convention designed for calling functions
//! inside a multimedia code that don't use many registers internally,
//! but are long enough to be called and not inlined. These functions are
//! usually used to calculate trigonometric functions, logarithms, etc...
- kIdLightCall2 = 10,
- kIdLightCall3 = 11,
- kIdLightCall4 = 12,
- */
-
- // ------------------------------------------------------------------------
- // [X86]
- // ------------------------------------------------------------------------
-
- //! X86 `__cdecl` calling convention (used by C runtime and libraries).
- kIdX86CDecl = 16,
- //! X86 `__stdcall` calling convention (used mostly by WinAPI).
- kIdX86StdCall = 17,
- //! X86 `__thiscall` calling convention (MSVC/Intel).
- kIdX86MsThisCall = 18,
- //! X86 `__fastcall` convention (MSVC/Intel).
- kIdX86MsFastCall = 19,
- //! X86 `__fastcall` convention (GCC and Clang).
- kIdX86GccFastCall = 20,
- //! X86 `regparm(1)` convention (GCC and Clang).
- kIdX86GccRegParm1 = 21,
- //! X86 `regparm(2)` convention (GCC and Clang).
- kIdX86GccRegParm2 = 22,
- //! X86 `regparm(3)` convention (GCC and Clang).
- kIdX86GccRegParm3 = 23,
-
- kIdX86LightCall2 = 29,
- kIdX86LightCall3 = 30,
- kIdX86LightCall4 = 31,
-
- //! X64 calling convention - WIN64-ABI.
- kIdX86Win64 = 32,
- //! X64 calling convention - SystemV / AMD64-ABI.
- kIdX86SysV64 = 33,
-
- kIdX64LightCall2 = 45,
- kIdX64LightCall3 = 46,
- kIdX64LightCall4 = 47,
-
- // ------------------------------------------------------------------------
- // [ARM]
- // ------------------------------------------------------------------------
-
- //! Legacy calling convention, floating point arguments are passed via GP registers.
- kIdArm32SoftFP = 48,
- //! Modern calling convention, uses VFP registers to pass floating point arguments.
- kIdArm32HardFP = 49,
+ kIdLightCall2 = 16,
+ kIdLightCall3 = 17,
+ kIdLightCall4 = 18,
// ------------------------------------------------------------------------
- // [Internal]
+ // [ABI-Specific Calling Conventions]
// ------------------------------------------------------------------------
- //! \cond INTERNAL
-
- _kIdX86Start = 16,
- _kIdX86End = 31,
-
- _kIdX64Start = 32,
- _kIdX64End = 47,
-
- _kIdArmStart = 48,
- _kIdArmEnd = 49,
-
- //! \endcond
+ kIdX64SystemV = 32,
+ kIdX64Windows = 33,
// ------------------------------------------------------------------------
// [Host]
// ------------------------------------------------------------------------
-#if defined(ASMJIT_DOCGEN)
-
- //! Default calling convention based on the current C++ compiler's settings.
- //!
- //! \note This should be always the same as `kIdHostCDecl`, but some
- //! compilers allow to override the default calling convention. Overriding
- //! is not detected at the moment.
- kIdHost = DETECTED_AT_COMPILE_TIME,
-
- //! Default CDECL calling convention based on the current C++ compiler's settings.
- kIdHostCDecl = DETECTED_AT_COMPILE_TIME,
-
- //! Default STDCALL calling convention based on the current C++ compiler's settings.
- //!
- //! \note If not defined by the host then it's the same as `kIdHostCDecl`.
- kIdHostStdCall = DETECTED_AT_COMPILE_TIME,
-
- //! Compatibility for `__fastcall` calling convention.
- //!
- //! \note If not defined by the host then it's the same as `kIdHostCDecl`.
- kIdHostFastCall = DETECTED_AT_COMPILE_TIME
-
-#elif ASMJIT_ARCH_X86 == 32
-
- kIdHost = kIdX86CDecl,
- kIdHostCDecl = kIdX86CDecl,
- kIdHostStdCall = kIdX86StdCall,
-
-# if defined(_MSC_VER)
- kIdHostFastCall = kIdX86MsFastCall,
-# elif defined(__GNUC__)
- kIdHostFastCall = kIdX86GccFastCall,
-# else
- kIdHostFastCall = kIdHost,
-# endif
-
- kIdHostLightCall2 = kIdX86LightCall2,
- kIdHostLightCall3 = kIdX86LightCall3,
- kIdHostLightCall4 = kIdX86LightCall4
-
-#elif ASMJIT_ARCH_X86 == 64
-
-# if defined(_WIN32)
- kIdHost = kIdX86Win64,
-# else
- kIdHost = kIdX86SysV64,
-# endif
-
- kIdHostCDecl = kIdHost, // Doesn't exist, redirected to host.
- kIdHostStdCall = kIdHost, // Doesn't exist, redirected to host.
- kIdHostFastCall = kIdHost, // Doesn't exist, redirected to host.
-
- kIdHostLightCall2 = kIdX64LightCall2,
- kIdHostLightCall3 = kIdX64LightCall3,
- kIdHostLightCall4 = kIdX64LightCall4
-
-#elif ASMJIT_ARCH_ARM == 32
-
-# if defined(__SOFTFP__)
- kIdHost = kIdArm32SoftFP,
-# else
- kIdHost = kIdArm32HardFP,
-# endif
- // These don't exist on ARM.
- kIdHostCDecl = kIdHost, // Doesn't exist, redirected to host.
- kIdHostStdCall = kIdHost, // Doesn't exist, redirected to host.
- kIdHostFastCall = kIdHost // Doesn't exist, redirected to host.
-
+ kIdHost =
+#if ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__)
+ kIdSoftFloat
+#elif ASMJIT_ARCH_ARM == 32 && !defined(__SOFTFP__)
+ kIdHardFloat
#else
-
- kIdHost = kIdNone,
- kIdHostCDecl = kIdHost,
- kIdHostStdCall = kIdHost,
- kIdHostFastCall = kIdHost
-
+ kIdCDecl
#endif
+
+#ifndef ASMJIT_NO_DEPRECATE
+ , kIdHostCDecl = kIdCDecl
+ , kIdHostStdCall = kIdStdCall
+ , kIdHostFastCall = kIdFastCall
+ , kIdHostLightCall2 = kIdLightCall2
+ , kIdHostLightCall3 = kIdLightCall3
+ , kIdHostLightCall4 = kIdLightCall4
+#endif // !ASMJIT_NO_DEPRECATE
};
//! Strategy used to assign registers to function arguments.
@@ -262,23 +200,50 @@ struct CallConv {
//! as defined by WIN64 calling convention - it applies to 64-bit calling
//! conventions only.
enum Strategy : uint32_t {
- kStrategyDefault = 0, //!< Default register assignment strategy.
- kStrategyWin64 = 1 //!< WIN64 specific register assignment strategy.
+ //! Default register assignment strategy.
+ kStrategyDefault = 0,
+ //! Windows 64-bit ABI register assignment strategy.
+ kStrategyX64Windows = 1,
+ //! Windows 64-bit __vectorcall register assignment strategy.
+ kStrategyX64VectorCall = 2,
+
+ //! Number of assignment strategies.
+ kStrategyCount = 3
};
//! Calling convention flags.
enum Flags : uint32_t {
- kFlagCalleePopsStack = 0x01, //!< Callee is responsible for cleaning up the stack.
- kFlagPassFloatsByVec = 0x02, //!< Pass F32 and F64 arguments by VEC128 register.
- kFlagVectorCall = 0x04, //!< This is a '__vectorcall' calling convention.
- kFlagIndirectVecArgs = 0x08 //!< Pass vector arguments indirectly (as a pointer).
+ //! Callee is responsible for cleaning up the stack.
+ kFlagCalleePopsStack = 0x01u,
+ //! Pass vector arguments indirectly (as a pointer).
+ kFlagIndirectVecArgs = 0x02u,
+ //! Pass F32 and F64 arguments by VEC128 register.
+ kFlagPassFloatsByVec = 0x04u,
+ //! Pass MMX and vector arguments by stack if the function has variable arguments.
+ kFlagPassVecByStackIfVA = 0x08u,
+ //! MMX registers are passed and returned via GP registers.
+ kFlagPassMmxByGp = 0x10u,
+ //! MMX registers are passed and returned via XMM registers.
+ kFlagPassMmxByXmm = 0x20u,
+ //! Calling convention can be used with variable arguments.
+ kFlagVarArgCompatible = 0x80u
};
//! \name Construction & Destruction
//! \{
- ASMJIT_API Error init(uint32_t ccId) noexcept;
+ //! Initializes this calling convention to the given `ccId` based on the
+ //! `environment`.
+ //!
+ //! See \ref Id and \ref Environment for more details.
+ ASMJIT_API Error init(uint32_t ccId, const Environment& environment) noexcept;
+ //! Resets this CallConv struct into a defined state.
+ //!
+ //! It's recommended to reset the \ref CallConv struct in case you would
+ //! like create a custom calling convention as it prevents from using an
+ //! uninitialized data (CallConv doesn't have a constructor that would
+ //! initialize it, it's just a struct).
inline void reset() noexcept {
memset(this, 0, sizeof(*this));
memset(_passedOrder, 0xFF, sizeof(_passedOrder));
@@ -295,9 +260,9 @@ struct CallConv {
inline void setId(uint32_t id) noexcept { _id = uint8_t(id); }
//! Returns the calling function architecture id.
- inline uint32_t archId() const noexcept { return _archId; }
+ inline uint32_t arch() const noexcept { return _arch; }
//! Sets the calling function architecture id.
- inline void setArchType(uint32_t archId) noexcept { _archId = uint8_t(archId); }
+ inline void setArch(uint32_t arch) noexcept { _arch = uint8_t(arch); }
//! Returns the strategy used to assign registers to arguments, see `Strategy`.
inline uint32_t strategy() const noexcept { return _strategy; }
@@ -337,11 +302,13 @@ struct CallConv {
//! implement custom calling conventions that guarantee higher stack alignment.
inline void setNaturalStackAlignment(uint32_t value) noexcept { _naturalStackAlignment = uint8_t(value); }
+ //! Returns the order of passed registers of the given `group`, see \ref BaseReg::RegGroup.
inline const uint8_t* passedOrder(uint32_t group) const noexcept {
ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
return _passedOrder[group].id;
}
+ //! Returns the mask of passed registers of the given `group`, see \ref BaseReg::RegGroup.
inline uint32_t passedRegs(uint32_t group) const noexcept {
ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
return _passedRegs[group];
@@ -356,6 +323,7 @@ struct CallConv {
_passedOrder[group].packed[3] = p3;
}
+ //! Resets the order and mask of passed registers.
inline void setPassedToNone(uint32_t group) noexcept {
ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
@@ -363,6 +331,7 @@ struct CallConv {
_passedRegs[group] = 0u;
}
+ //! Sets the order and mask of passed registers.
inline void setPassedOrder(uint32_t group, uint32_t a0, uint32_t a1 = 0xFF, uint32_t a2 = 0xFF, uint32_t a3 = 0xFF, uint32_t a4 = 0xFF, uint32_t a5 = 0xFF, uint32_t a6 = 0xFF, uint32_t a7 = 0xFF) noexcept {
ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
@@ -383,25 +352,19 @@ struct CallConv {
(a7 != 0xFF ? 1u << a7 : 0u) ;
}
+ //! Returns preserved register mask of the given `group`, see \ref BaseReg::RegGroup.
inline uint32_t preservedRegs(uint32_t group) const noexcept {
ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
return _preservedRegs[group];
}
+ //! Sets preserved register mask of the given `group`, see \ref BaseReg::RegGroup.
inline void setPreservedRegs(uint32_t group, uint32_t regs) noexcept {
ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
_preservedRegs[group] = regs;
}
//! \}
-
- //! \name Static Functions
- //! \{
-
- static inline bool isX86Family(uint32_t ccId) noexcept { return ccId >= _kIdX86Start && ccId <= _kIdX64End; }
- static inline bool isArmFamily(uint32_t ccId) noexcept { return ccId >= _kIdArmStart && ccId <= _kIdArmEnd; }
-
- //! \}
};
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/codebuffer.h b/3rdparty/asmjit/src/asmjit/core/codebuffer.h
new file mode 100644
index 00000000000..76c86b1f631
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/codebuffer.h
@@ -0,0 +1,126 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_CORE_CODEBUFFER_H_INCLUDED
+#define ASMJIT_CORE_CODEBUFFER_H_INCLUDED
+
+#include "../core/globals.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \addtogroup asmjit_core
+//! \{
+
+// ============================================================================
+// [asmjit::CodeBuffer]
+// ============================================================================
+
+//! Code or data buffer.
+struct CodeBuffer {
+ //! The content of the buffer (data).
+ uint8_t* _data;
+ //! Number of bytes of `data` used.
+ size_t _size;
+ //! Buffer capacity (in bytes).
+ size_t _capacity;
+ //! Buffer flags.
+ uint32_t _flags;
+
+ //! Code buffer flags.
+ enum Flags : uint32_t {
+ //! Buffer is external (not allocated by asmjit).
+ kFlagIsExternal = 0x00000001u,
+ //! Buffer is fixed (cannot be reallocated).
+ kFlagIsFixed = 0x00000002u
+ };
+
+ //! \name Overloaded Operators
+ //! \{
+
+ //! Returns a referebce to the byte at the given `index`.
+ inline uint8_t& operator[](size_t index) noexcept {
+ ASMJIT_ASSERT(index < _size);
+ return _data[index];
+ }
+ //! \overload
+ inline const uint8_t& operator[](size_t index) const noexcept {
+ ASMJIT_ASSERT(index < _size);
+ return _data[index];
+ }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns code buffer flags, see \ref Flags.
+ inline uint32_t flags() const noexcept { return _flags; }
+ //! Tests whether the code buffer has the given `flag` set.
+ inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+
+ //! Tests whether this code buffer has a fixed size.
+ //!
+ //! Fixed size means that the code buffer is fixed and cannot grow.
+ inline bool isFixed() const noexcept { return hasFlag(kFlagIsFixed); }
+
+ //! Tests whether the data in this code buffer is external.
+ //!
+ //! External data can only be provided by users, it's never used by AsmJit.
+ inline bool isExternal() const noexcept { return hasFlag(kFlagIsExternal); }
+
+ //! Tests whether the data in this code buffer is allocated (non-null).
+ inline bool isAllocated() const noexcept { return _data != nullptr; }
+
+ //! Tests whether the code buffer is empty.
+ inline bool empty() const noexcept { return !_size; }
+
+ //! Returns the size of the data.
+ inline size_t size() const noexcept { return _size; }
+ //! Returns the capacity of the data.
+ inline size_t capacity() const noexcept { return _capacity; }
+
+ //! Returns the pointer to the data the buffer references.
+ inline uint8_t* data() noexcept { return _data; }
+ //! \overload
+ inline const uint8_t* data() const noexcept { return _data; }
+
+ //! \}
+
+ //! \name Iterators
+ //! \{
+
+ inline uint8_t* begin() noexcept { return _data; }
+ inline const uint8_t* begin() const noexcept { return _data; }
+
+ inline uint8_t* end() noexcept { return _data + _size; }
+ inline const uint8_t* end() const noexcept { return _data + _size; }
+
+ //! \}
+};
+
+//! \}
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_CODEBUFFER_H_INCLUDED
+
diff --git a/3rdparty/asmjit/src/asmjit/core/codebufferwriter_p.h b/3rdparty/asmjit/src/asmjit/core/codebufferwriter_p.h
index ee7521153a3..75ee04748f4 100644
--- a/3rdparty/asmjit/src/asmjit/core/codebufferwriter_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/codebufferwriter_p.h
@@ -25,12 +25,13 @@
#define ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED
#include "../core/assembler.h"
+#include "../core/codebuffer.h"
#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
//! \cond INTERNAL
-//! \addtogroup asmjit_core
+//! \addtogroup asmjit_assembler
//! \{
// ============================================================================
diff --git a/3rdparty/asmjit/src/asmjit/core/codeholder.cpp b/3rdparty/asmjit/src/asmjit/core/codeholder.cpp
index 93c9a99df88..8711e382ce4 100644
--- a/3rdparty/asmjit/src/asmjit/core/codeholder.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/codeholder.cpp
@@ -23,7 +23,7 @@
#include "../core/api-build_p.h"
#include "../core/assembler.h"
-#include "../core/logging.h"
+#include "../core/logger.h"
#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
@@ -78,13 +78,6 @@ public:
};
// ============================================================================
-// [asmjit::ErrorHandler]
-// ============================================================================
-
-ErrorHandler::ErrorHandler() noexcept {}
-ErrorHandler::~ErrorHandler() noexcept {}
-
-// ============================================================================
// [asmjit::CodeHolder - Utilities]
// ============================================================================
@@ -97,8 +90,8 @@ static void CodeHolder_resetInternal(CodeHolder* self, uint32_t resetPolicy) noe
self->detach(emitters[--i]);
// Reset everything into its construction state.
- self->_codeInfo.reset();
- self->_emitterOptions = 0;
+ self->_environment.reset();
+ self->_baseAddress = Globals::kNoBaseAddress;
self->_logger = nullptr;
self->_errorHandler = nullptr;
@@ -129,20 +122,10 @@ static void CodeHolder_resetInternal(CodeHolder* self, uint32_t resetPolicy) noe
self->_zone.reset(resetPolicy);
}
-static void CodeHolder_modifyEmitterOptions(CodeHolder* self, uint32_t clear, uint32_t add) noexcept {
- uint32_t oldOpt = self->_emitterOptions;
- uint32_t newOpt = (oldOpt & ~clear) | add;
-
- if (oldOpt == newOpt)
- return;
-
- // Modify emitter options of `CodeHolder` itself.
- self->_emitterOptions = newOpt;
-
- // Modify emitter options of all attached emitters.
+static void CodeHolder_onSettingsUpdated(CodeHolder* self) noexcept {
+ // Notify all attached emitters about a settings update.
for (BaseEmitter* emitter : self->emitters()) {
- emitter->_emitterOptions = (emitter->_emitterOptions & ~clear) | add;
- emitter->onUpdateGlobalInstOptions();
+ emitter->onSettingsUpdated();
}
}
@@ -151,8 +134,8 @@ static void CodeHolder_modifyEmitterOptions(CodeHolder* self, uint32_t clear, ui
// ============================================================================
CodeHolder::CodeHolder() noexcept
- : _codeInfo(),
- _emitterOptions(0),
+ : _environment(),
+ _baseAddress(Globals::kNoBaseAddress),
_logger(nullptr),
_errorHandler(nullptr),
_zone(16384 - Zone::kBlockOverhead),
@@ -177,7 +160,7 @@ inline void CodeHolder_setSectionDefaultName(
section->_name.u32[1] = Support::bytepack32_4x8(uint8_t(c4), uint8_t(c5), uint8_t(c6), uint8_t(c7));
}
-Error CodeHolder::init(const CodeInfo& info) noexcept {
+Error CodeHolder::init(const Environment& environment, uint64_t baseAddress) noexcept {
// Cannot reinitialize if it's locked or there is one or more emitter attached.
if (isInitialized())
return DebugUtils::errored(kErrorAlreadyInitialized);
@@ -185,7 +168,7 @@ Error CodeHolder::init(const CodeInfo& info) noexcept {
// If we are just initializing there should be no emitters attached.
ASMJIT_ASSERT(_emitters.empty());
- // Create the default section and insert it to the `_sections` array.
+ // Create a default section and insert it to the `_sections` array.
Error err = _sections.willGrow(&_allocator);
if (err == kErrorOk) {
Section* section = _allocator.allocZeroedT<Section>();
@@ -204,7 +187,8 @@ Error CodeHolder::init(const CodeInfo& info) noexcept {
return err;
}
else {
- _codeInfo = info;
+ _environment = environment;
+ _baseAddress = baseAddress;
return kErrorOk;
}
}
@@ -271,34 +255,28 @@ Error CodeHolder::detach(BaseEmitter* emitter) noexcept {
}
// ============================================================================
-// [asmjit::CodeHolder - Emitter Options]
-// ============================================================================
-
-static constexpr uint32_t kEmitterOptionsFilter = ~uint32_t(BaseEmitter::kOptionLoggingEnabled);
-
-void CodeHolder::addEmitterOptions(uint32_t options) noexcept {
- CodeHolder_modifyEmitterOptions(this, 0, options & kEmitterOptionsFilter);
-}
-
-void CodeHolder::clearEmitterOptions(uint32_t options) noexcept {
- CodeHolder_modifyEmitterOptions(this, options & kEmitterOptionsFilter, 0);
-}
-
-// ============================================================================
-// [asmjit::CodeHolder - Logging & Error Handling]
+// [asmjit::CodeHolder - Logging]
// ============================================================================
void CodeHolder::setLogger(Logger* logger) noexcept {
#ifndef ASMJIT_NO_LOGGING
_logger = logger;
- uint32_t option = !logger ? uint32_t(0) : uint32_t(BaseEmitter::kOptionLoggingEnabled);
- CodeHolder_modifyEmitterOptions(this, BaseEmitter::kOptionLoggingEnabled, option);
+ CodeHolder_onSettingsUpdated(this);
#else
DebugUtils::unused(logger);
#endif
}
// ============================================================================
+// [asmjit::CodeHolder - Error Handling]
+// ============================================================================
+
+void CodeHolder::setErrorHandler(ErrorHandler* errorHandler) noexcept {
+ _errorHandler = errorHandler;
+ CodeHolder_onSettingsUpdated(this);
+}
+
+// ============================================================================
// [asmjit::CodeHolder - Code Buffer]
// ============================================================================
@@ -440,7 +418,7 @@ Section* CodeHolder::ensureAddressTableSection() noexcept {
if (_addressTableSection)
return _addressTableSection;
- newSection(&_addressTableSection, CodeHolder_addrTabName, sizeof(CodeHolder_addrTabName) - 1, 0, _codeInfo.gpSize());
+ newSection(&_addressTableSection, CodeHolder_addrTabName, sizeof(CodeHolder_addrTabName) - 1, 0, _environment.registerSize());
return _addressTableSection;
}
@@ -458,7 +436,7 @@ Error CodeHolder::addAddressToAddressTable(uint64_t address) noexcept {
return DebugUtils::errored(kErrorOutOfMemory);
_addressTableEntries.insert(entry);
- section->_virtualSize += _codeInfo.gpSize();
+ section->_virtualSize += _environment.registerSize();
return kErrorOk;
}
@@ -470,20 +448,24 @@ Error CodeHolder::addAddressToAddressTable(uint64_t address) noexcept {
//! Only used to lookup a label from `_namedLabels`.
class LabelByName {
public:
- inline LabelByName(const char* key, size_t keySize, uint32_t hashCode) noexcept
+ inline LabelByName(const char* key, size_t keySize, uint32_t hashCode, uint32_t parentId) noexcept
: _key(key),
_keySize(uint32_t(keySize)),
- _hashCode(hashCode) {}
+ _hashCode(hashCode),
+ _parentId(parentId) {}
inline uint32_t hashCode() const noexcept { return _hashCode; }
inline bool matches(const LabelEntry* entry) const noexcept {
- return entry->nameSize() == _keySize && ::memcmp(entry->name(), _key, _keySize) == 0;
+ return entry->nameSize() == _keySize &&
+ entry->parentId() == _parentId &&
+ ::memcmp(entry->name(), _key, _keySize) == 0;
}
const char* _key;
uint32_t _keySize;
uint32_t _hashCode;
+ uint32_t _parentId;
};
// Returns a hash of `name` and fixes `nameSize` if it's `SIZE_MAX`.
@@ -539,7 +521,7 @@ LabelLink* CodeHolder::newLabelLink(LabelEntry* le, uint32_t sectionId, size_t o
}
Error CodeHolder::newLabelEntry(LabelEntry** entryOut) noexcept {
- *entryOut = 0;
+ *entryOut = nullptr;
uint32_t labelId = _labelEntries.size();
if (ASMJIT_UNLIKELY(labelId == Globals::kInvalidId))
@@ -561,7 +543,7 @@ Error CodeHolder::newLabelEntry(LabelEntry** entryOut) noexcept {
}
Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, uint32_t type, uint32_t parentId) noexcept {
- *entryOut = 0;
+ *entryOut = nullptr;
uint32_t hashCode = CodeHolder_hashNameAndGetSize(name, nameSize);
if (ASMJIT_UNLIKELY(nameSize == 0))
@@ -580,7 +562,7 @@ Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, si
case Label::kTypeGlobal:
if (ASMJIT_UNLIKELY(parentId != Globals::kInvalidId))
- return DebugUtils::errored(kErrorNonLocalLabelCantHaveParent);
+ return DebugUtils::errored(kErrorNonLocalLabelCannotHaveParent);
break;
@@ -591,7 +573,7 @@ Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, si
// Don't allow to insert duplicates. Local labels allow duplicates that have
// different id, this is already accomplished by having a different hashes
// between the same label names having different parent labels.
- LabelEntry* le = _namedLabels.get(LabelByName(name, nameSize, hashCode));
+ LabelEntry* le = _namedLabels.get(LabelByName(name, nameSize, hashCode, parentId));
if (ASMJIT_UNLIKELY(le))
return DebugUtils::errored(kErrorLabelAlreadyDefined);
@@ -610,7 +592,7 @@ Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, si
le->_hashCode = hashCode;
le->_setId(labelId);
le->_type = uint8_t(type);
- le->_parentId = Globals::kInvalidId;
+ le->_parentId = parentId;
le->_offset = 0;
ASMJIT_PROPAGATE(le->_name.setData(&_zone, name, nameSize));
@@ -622,13 +604,14 @@ Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, si
}
uint32_t CodeHolder::labelIdByName(const char* name, size_t nameSize, uint32_t parentId) noexcept {
- // TODO: Finalize - parent id is not used here?
- DebugUtils::unused(parentId);
-
uint32_t hashCode = CodeHolder_hashNameAndGetSize(name, nameSize);
- if (ASMJIT_UNLIKELY(!nameSize)) return 0;
+ if (ASMJIT_UNLIKELY(!nameSize))
+ return 0;
+
+ if (parentId != Globals::kInvalidId)
+ hashCode ^= parentId;
- LabelEntry* le = _namedLabels.get(LabelByName(name, nameSize, hashCode));
+ LabelEntry* le = _namedLabels.get(LabelByName(name, nameSize, hashCode, parentId));
return le ? le->id() : uint32_t(Globals::kInvalidId);
}
@@ -906,7 +889,6 @@ size_t CodeHolder::codeSize() const noexcept {
}
}
- // TODO: Not nice, maybe changing `codeSize()` to return `uint64_t` instead?
if ((sizeof(uint64_t) > sizeof(size_t) && offset > SIZE_MAX) || of)
return SIZE_MAX;
@@ -918,8 +900,8 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
if (ASMJIT_UNLIKELY(baseAddress == Globals::kNoBaseAddress))
return DebugUtils::errored(kErrorInvalidArgument);
- _codeInfo.setBaseAddress(baseAddress);
- uint32_t gpSize = _codeInfo.gpSize();
+ _baseAddress = baseAddress;
+ uint32_t addressSize = _environment.registerSize();
Section* addressTableSection = _addressTableSection;
uint32_t addressTableEntryCount = 0;
@@ -980,7 +962,7 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
case RelocEntry::kTypeAbsToRel: {
value -= baseAddress + sectionOffset + sourceOffset + regionSize;
- if (gpSize > 4 && !Support::isInt32(int64_t(value)))
+ if (addressSize > 4 && !Support::isInt32(int64_t(value)))
return DebugUtils::errored(kErrorRelocOffsetOutOfRange);
break;
}
@@ -1003,7 +985,7 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
if (!atEntry->hasAssignedSlot())
atEntry->_slot = addressTableEntryCount++;
- size_t atEntryIndex = size_t(atEntry->slot()) * gpSize;
+ size_t atEntryIndex = size_t(atEntry->slot()) * addressSize;
uint64_t addrSrc = sectionOffset + sourceOffset + regionSize;
uint64_t addrDst = addressTableSection->offset() + uint64_t(atEntryIndex);
@@ -1064,7 +1046,7 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
// Fixup the virtual size of the address table if it's the last section.
if (_sections.last() == addressTableSection) {
- size_t addressTableSize = addressTableEntryCount * gpSize;
+ size_t addressTableSize = addressTableEntryCount * addressSize;
addressTableSection->_buffer._size = addressTableSize;
addressTableSection->_virtualSize = addressTableSize;
}
@@ -1072,7 +1054,7 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
return kErrorOk;
}
-Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t options) noexcept {
+Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t copyOptions) noexcept {
if (ASMJIT_UNLIKELY(!isSectionValid(sectionId)))
return DebugUtils::errored(kErrorInvalidSection);
@@ -1084,7 +1066,7 @@ Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId,
memcpy(dst, section->data(), bufferSize);
- if (bufferSize < dstSize && (options & kCopyWithPadding)) {
+ if (bufferSize < dstSize && (copyOptions & kCopyPadSectionBuffer)) {
size_t paddingSize = dstSize - bufferSize;
memset(static_cast<uint8_t*>(dst) + bufferSize, 0, paddingSize);
}
@@ -1092,7 +1074,7 @@ Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId,
return kErrorOk;
}
-Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t options) noexcept {
+Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOptions) noexcept {
size_t end = 0;
for (Section* section : _sections) {
if (section->offset() > dstSize)
@@ -1108,7 +1090,7 @@ Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t options)
size_t paddingSize = 0;
memcpy(dstTarget, section->data(), bufferSize);
- if ((options & kCopyWithPadding) && bufferSize < section->virtualSize()) {
+ if ((copyOptions & kCopyPadSectionBuffer) && bufferSize < section->virtualSize()) {
paddingSize = Support::min<size_t>(dstSize - offset, size_t(section->virtualSize())) - bufferSize;
memset(dstTarget + bufferSize, 0, paddingSize);
}
@@ -1116,8 +1098,9 @@ Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t options)
end = Support::max(end, offset + bufferSize + paddingSize);
}
- // TODO: `end` is not used atm, we need an option to also pad anything beyond
- // the code in case that the destination was much larger (for example page-size).
+ if (end < dstSize && (copyOptions & kCopyPadTargetBuffer)) {
+ memset(static_cast<uint8_t*>(dst) + end, 0, dstSize - end);
+ }
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/core/codeholder.h b/3rdparty/asmjit/src/asmjit/core/codeholder.h
index 5f6a21d6241..9b3466dbb58 100644
--- a/3rdparty/asmjit/src/asmjit/core/codeholder.h
+++ b/3rdparty/asmjit/src/asmjit/core/codeholder.h
@@ -25,7 +25,9 @@
#define ASMJIT_CORE_CODEHOLDER_H_INCLUDED
#include "../core/arch.h"
+#include "../core/codebuffer.h"
#include "../core/datatypes.h"
+#include "../core/errorhandler.h"
#include "../core/operand.h"
#include "../core/string.h"
#include "../core/support.h"
@@ -56,126 +58,14 @@ class Logger;
//! Align mode.
enum AlignMode : uint32_t {
- kAlignCode = 0, //!< Align executable code.
- kAlignData = 1, //!< Align non-executable code.
- kAlignZero = 2, //!< Align by a sequence of zeros.
- kAlignCount = 3 //!< Count of alignment modes.
-};
-
-// ============================================================================
-// [asmjit::ErrorHandler]
-// ============================================================================
-
-//! Error handler can be used to override the default behavior of error handling
-//! available to all classes that inherit `BaseEmitter`.
-//!
-//! Override `ErrorHandler::handleError()` to implement your own error handler.
-class ASMJIT_VIRTAPI ErrorHandler {
-public:
- ASMJIT_BASE_CLASS(ErrorHandler)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! Creates a new `ErrorHandler` instance.
- ASMJIT_API ErrorHandler() noexcept;
- //! Destroys the `ErrorHandler` instance.
- ASMJIT_API virtual ~ErrorHandler() noexcept;
-
- // --------------------------------------------------------------------------
- // [Handle Error]
- // --------------------------------------------------------------------------
-
- //! Error handler (must be reimplemented).
- //!
- //! Error handler is called after an error happened and before it's propagated
- //! to the caller. There are multiple ways how the error handler can be used:
- //!
- //! 1. User-based error handling without throwing exception or using C's
- //! `longjmp()`. This is for users that don't use exceptions and want
- //! customized error handling.
- //!
- //! 2. Throwing an exception. AsmJit doesn't use exceptions and is completely
- //! exception-safe, but you can throw exception from your error handler if
- //! this way is the preferred way of handling errors in your project.
- //!
- //! 3. Using plain old C's `setjmp()` and `longjmp()`. Asmjit always puts
- //! `BaseEmitter` to a consistent state before calling `handleError()`
- //! so `longjmp()` can be used without any issues to cancel the code
- //! generation if an error occurred. There is no difference between
- //! exceptions and `longjmp()` from AsmJit's perspective, however,
- //! never jump outside of `CodeHolder` and `BaseEmitter` scope as you
- //! would leak memory.
- virtual void handleError(Error err, const char* message, BaseEmitter* origin) = 0;
-};
-
-// ============================================================================
-// [asmjit::CodeBuffer]
-// ============================================================================
-
-//! Code or data buffer.
-struct CodeBuffer {
- //! The content of the buffer (data).
- uint8_t* _data;
- //! Number of bytes of `data` used.
- size_t _size;
- //! Buffer capacity (in bytes).
- size_t _capacity;
- //! Buffer flags.
- uint32_t _flags;
-
- enum Flags : uint32_t {
- //! Buffer is external (not allocated by asmjit).
- kFlagIsExternal = 0x00000001u,
- //! Buffer is fixed (cannot be reallocated).
- kFlagIsFixed = 0x00000002u
- };
-
- //! \name Overloaded Operators
- //! \{
-
- inline uint8_t& operator[](size_t index) noexcept {
- ASMJIT_ASSERT(index < _size);
- return _data[index];
- }
-
- inline const uint8_t& operator[](size_t index) const noexcept {
- ASMJIT_ASSERT(index < _size);
- return _data[index];
- }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- inline uint32_t flags() const noexcept { return _flags; }
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
-
- inline bool isAllocated() const noexcept { return _data != nullptr; }
- inline bool isFixed() const noexcept { return hasFlag(kFlagIsFixed); }
- inline bool isExternal() const noexcept { return hasFlag(kFlagIsExternal); }
-
- inline uint8_t* data() noexcept { return _data; }
- inline const uint8_t* data() const noexcept { return _data; }
-
- inline bool empty() const noexcept { return !_size; }
- inline size_t size() const noexcept { return _size; }
- inline size_t capacity() const noexcept { return _capacity; }
-
- //! \}
-
- //! \name Iterators
- //! \{
-
- inline uint8_t* begin() noexcept { return _data; }
- inline const uint8_t* begin() const noexcept { return _data; }
-
- inline uint8_t* end() noexcept { return _data + _size; }
- inline const uint8_t* end() const noexcept { return _data + _size; }
-
- //! \}
+ //! Align executable code.
+ kAlignCode = 0,
+ //! Align non-executable code.
+ kAlignData = 1,
+ //! Align by a sequence of zeros.
+ kAlignZero = 2,
+ //! Count of alignment modes.
+ kAlignCount = 3
};
// ============================================================================
@@ -204,31 +94,48 @@ public:
//! Section flags.
enum Flags : uint32_t {
- kFlagExec = 0x00000001u, //!< Executable (.text sections).
- kFlagConst = 0x00000002u, //!< Read-only (.text and .data sections).
- kFlagZero = 0x00000004u, //!< Zero initialized by the loader (BSS).
- kFlagInfo = 0x00000008u, //!< Info / comment flag.
- kFlagImplicit = 0x80000000u //!< Section created implicitly and can be deleted by `Target`.
+ //! Executable (.text sections).
+ kFlagExec = 0x00000001u,
+ //! Read-only (.text and .data sections).
+ kFlagConst = 0x00000002u,
+ //! Zero initialized by the loader (BSS).
+ kFlagZero = 0x00000004u,
+ //! Info / comment flag.
+ kFlagInfo = 0x00000008u,
+ //! Section created implicitly and can be deleted by \ref Target.
+ kFlagImplicit = 0x80000000u
};
//! \name Accessors
//! \{
+ //! Returns the section id.
inline uint32_t id() const noexcept { return _id; }
+ //! Returns the section name, as a null terminated string.
inline const char* name() const noexcept { return _name.str; }
+ //! Returns the section data.
inline uint8_t* data() noexcept { return _buffer.data(); }
+ //! \overload
inline const uint8_t* data() const noexcept { return _buffer.data(); }
+ //! Returns the section flags, see \ref Flags.
inline uint32_t flags() const noexcept { return _flags; }
+ //! Tests whether the section has the given `flag`.
inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ //! Adds `flags` to the section flags.
inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ //! Removes `flags` from the section flags.
inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
+ //! Returns the minimum section alignment
inline uint32_t alignment() const noexcept { return _alignment; }
+ //! Sets the minimum section alignment
inline void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; }
+ //! Returns the section offset, relative to base.
inline uint64_t offset() const noexcept { return _offset; }
+ //! Set the section offset.
inline void setOffset(uint64_t offset) noexcept { _offset = offset; }
//! Returns the virtual size of the section.
@@ -277,46 +184,73 @@ struct LabelLink {
// [asmjit::Expression]
// ============================================================================
+//! Expression node that can reference constants, labels, and another expressions.
struct Expression {
+ //! Operation type.
enum OpType : uint8_t {
+ //! Addition.
kOpAdd = 0,
+ //! Subtraction.
kOpSub = 1,
+ //! Multiplication
kOpMul = 2,
+ //! Logical left shift.
kOpSll = 3,
+ //! Logical right shift.
kOpSrl = 4,
+ //! Arithmetic right shift.
kOpSra = 5
};
+ //! Type of \ref Value.
enum ValueType : uint8_t {
+ //! No value or invalid.
kValueNone = 0,
+ //! Value is 64-bit unsigned integer (constant).
kValueConstant = 1,
+ //! Value is \ref LabelEntry, which references a \ref Label.
kValueLabel = 2,
+ //! Value is \ref Expression
kValueExpression = 3
};
+ //! Expression value.
union Value {
+ //! Constant.
uint64_t constant;
+ //! Pointer to another expression.
Expression* expression;
+ //! Poitner to \ref LabelEntry.
LabelEntry* label;
};
+ //! Operation type.
uint8_t opType;
+ //! Value types of \ref value.
uint8_t valueType[2];
+ //! Reserved for future use, should be initialized to zero.
uint8_t reserved[5];
+ //! Expression left and right values.
Value value[2];
+ //! Resets the whole expression.
+ //!
+ //! Changes both values to \ref kValueNone.
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ //! Sets the value type at `index` to \ref kValueConstant and its content to `constant`.
inline void setValueAsConstant(size_t index, uint64_t constant) noexcept {
valueType[index] = kValueConstant;
value[index].constant = constant;
}
- inline void setValueAsLabel(size_t index, LabelEntry* label) noexcept {
+ //! Sets the value type at `index` to \ref kValueLabel and its content to `labelEntry`.
+ inline void setValueAsLabel(size_t index, LabelEntry* labelEntry) noexcept {
valueType[index] = kValueLabel;
- value[index].label = label;
+ value[index].label = labelEntry;
}
+ //! Sets the value type at `index` to \ref kValueExpression and its content to `expression`.
inline void setValueAsExpression(size_t index, Expression* expression) noexcept {
valueType[index] = kValueLabel;
value[index].expression = expression;
@@ -510,11 +444,14 @@ struct RelocEntry {
// [asmjit::AddressTableEntry]
// ============================================================================
+//! Entry in an address table.
class AddressTableEntry : public ZoneTreeNodeT<AddressTableEntry> {
public:
ASMJIT_NONCOPYABLE(AddressTableEntry)
+ //! Address.
uint64_t _address;
+ //! Slot.
uint32_t _slot;
//! \name Construction & Destruction
@@ -547,22 +484,24 @@ public:
// [asmjit::CodeHolder]
// ============================================================================
-//! Contains basic information about the target architecture plus its settings,
-//! and holds code & data (including sections, labels, and relocation information).
-//! CodeHolder can store both binary and intermediate representation of assembly,
-//! which can be generated by `BaseAssembler` and/or `BaseBuilder`.
+//! Contains basic information about the target architecture and its options.
+//!
+//! In addition, it holds assembled code & data (including sections, labels, and
+//! relocation information). `CodeHolder` can store both binary and intermediate
+//! representation of assembly, which can be generated by \ref BaseAssembler,
+//! \ref BaseBuilder, and \ref BaseCompiler
//!
-//! \note `CodeHolder` has ability to attach an `ErrorHandler`, however, the
-//! error handler is not triggered by `CodeHolder` itself, it's only used by
-//! emitters attached to `CodeHolder`.
+//! \note `CodeHolder` has an ability to attach an \ref ErrorHandler, however,
+//! the error handler is not triggered by `CodeHolder` itself, it's instead
+//! propagated to all emitters that attach to it.
class CodeHolder {
public:
ASMJIT_NONCOPYABLE(CodeHolder)
- //! Basic information about the code (architecture and other info).
- CodeInfo _codeInfo;
- //! Emitter options, propagated to all emitters when changed.
- uint32_t _emitterOptions;
+ //! Environment information.
+ Environment _environment;
+ //! Base address or \ref Globals::kNoBaseAddress.
+ uint64_t _baseAddress;
//! Attached `Logger`, used by all consumers.
Logger* _logger;
@@ -574,7 +513,7 @@ public:
//! Zone allocator, used to manage internal containers.
ZoneAllocator _allocator;
- //! Attached code emitters.
+ //! Attached emitters.
ZoneVector<BaseEmitter*> _emitters;
//! Section entries.
ZoneVector<Section*> _sections;
@@ -592,6 +531,25 @@ public:
//! Address table entries.
ZoneTree<AddressTableEntry> _addressTableEntries;
+ //! Options that can be used with \ref copySectionData() and \ref copyFlattenedData().
+ enum CopyOptions : uint32_t {
+ //! If virtual size of a section is greater than the size of its \ref CodeBuffer
+ //! then all bytes between the buffer size and virtual size will be zeroed.
+ //! If this option is not set then those bytes would be left as is, which
+ //! means that if the user didn't initialize them they would have a previous
+ //! content, which may be unwanted.
+ kCopyPadSectionBuffer = 0x00000001u,
+
+#ifndef ASMJIT_NO_DEPRECATED
+ kCopyWithPadding = kCopyPadSectionBuffer,
+#endif // !ASMJIT_NO_DEPRECATED
+
+ //! Zeroes the target buffer if the flattened data is less than the destination
+ //! size. This option works only with \ref copyFlattenedData() as it processes
+ //! multiple sections. It is ignored by \ref copySectionData().
+ kCopyPadTargetBuffer = 0x00000002u
+ };
+
//! \name Construction & Destruction
//! \{
@@ -600,10 +558,13 @@ public:
//! Destroys the CodeHolder.
ASMJIT_API ~CodeHolder() noexcept;
- inline bool isInitialized() const noexcept { return _codeInfo.isInitialized(); }
+ //! Tests whether the `CodeHolder` has been initialized.
+ //!
+ //! Emitters can be only attached to initialized `CodeHolder` instances.
+ inline bool isInitialized() const noexcept { return _environment.isInitialized(); }
- //! Initializes CodeHolder to hold code described by `codeInfo`.
- ASMJIT_API Error init(const CodeInfo& info) noexcept;
+ //! Initializes CodeHolder to hold code described by code `info`.
+ ASMJIT_API Error init(const Environment& environment, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept;
//! Detaches all code-generators attached and resets the `CodeHolder`.
ASMJIT_API void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept;
@@ -622,65 +583,62 @@ public:
//! \name Allocators
//! \{
+ //! Returns the allocator that the `CodeHolder` uses.
+ //!
+ //! \note This should be only used for AsmJit's purposes. Code holder uses
+ //! arena allocator to allocate everything, so anything allocated through
+ //! this allocator will be invalidated by \ref CodeHolder::reset() or by
+ //! CodeHolder's destructor.
inline ZoneAllocator* allocator() const noexcept { return const_cast<ZoneAllocator*>(&_allocator); }
//! \}
- //! \name Code Emitter
+ //! \name Code & Architecture
//! \{
- inline const ZoneVector<BaseEmitter*>& emitters() const noexcept { return _emitters; }
+ //! Returns the target environment information, see \ref Environment.
+ inline const Environment& environment() const noexcept { return _environment; }
- //! Returns global emitter options, internally propagated to all attached emitters.
- inline uint32_t emitterOptions() const noexcept { return _emitterOptions; }
+ //! Returns the target architecture.
+ inline uint32_t arch() const noexcept { return environment().arch(); }
+ //! Returns the target sub-architecture.
+ inline uint32_t subArch() const noexcept { return environment().subArch(); }
- //! Enables the given global emitter `options` and propagates the resulting
- //! options to all attached emitters.
- ASMJIT_API void addEmitterOptions(uint32_t options) noexcept;
-
- //! Disables the given global emitter `options` and propagates the resulting
- //! options to all attached emitters.
- ASMJIT_API void clearEmitterOptions(uint32_t options) noexcept;
+ //! Tests whether a static base-address is set.
+ inline bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
+ //! Returns a static base-address or \ref Globals::kNoBaseAddress, if not set.
+ inline uint64_t baseAddress() const noexcept { return _baseAddress; }
//! \}
- //! \name Code & Architecture
+ //! \name Emitters
//! \{
- //! Returns the target architecture information, see `ArchInfo`.
- inline const ArchInfo& archInfo() const noexcept { return _codeInfo.archInfo(); }
- //! Returns the target code information, see `CodeInfo`.
- inline const CodeInfo& codeInfo() const noexcept { return _codeInfo; }
-
- //! Returns the target architecture id.
- inline uint32_t archId() const noexcept { return archInfo().archId(); }
- //! Returns the target architecture sub-id.
- inline uint32_t archSubId() const noexcept { return archInfo().archSubId(); }
-
- //! Tests whether a static base-address is set.
- inline bool hasBaseAddress() const noexcept { return _codeInfo.hasBaseAddress(); }
- //! Returns a static base-address (uint64_t).
- inline uint64_t baseAddress() const noexcept { return _codeInfo.baseAddress(); }
+ //! Returns a vector of attached emitters.
+ inline const ZoneVector<BaseEmitter*>& emitters() const noexcept { return _emitters; }
//! \}
- //! \name Logging & Error Handling
+ //! \name Logging
//! \{
- //! Returns the attached logger.
+ //! Returns the attached logger, see \ref Logger.
inline Logger* logger() const noexcept { return _logger; }
//! Attaches a `logger` to CodeHolder and propagates it to all attached emitters.
ASMJIT_API void setLogger(Logger* logger) noexcept;
//! Resets the logger to none.
inline void resetLogger() noexcept { setLogger(nullptr); }
- //! Tests whether the global error handler is attached.
+ //! \name Error Handling
+ //! \{
+
+ //! Tests whether the CodeHolder has an attached error handler, see \ref ErrorHandler.
inline bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; }
- //! Returns the global error handler.
+ //! Returns the attached error handler.
inline ErrorHandler* errorHandler() const noexcept { return _errorHandler; }
- //! Sets the global error handler.
- inline void setErrorHandler(ErrorHandler* handler) noexcept { _errorHandler = handler; }
- //! Resets the global error handler to none.
+ //! Attach an error handler to this `CodeHolder`.
+ ASMJIT_API void setErrorHandler(ErrorHandler* errorHandler) noexcept;
+ //! Resets the error handler to none.
inline void resetErrorHandler() noexcept { setErrorHandler(nullptr); }
//! \}
@@ -688,7 +646,16 @@ public:
//! \name Code Buffer
//! \{
+ //! Makes sure that at least `n` bytes can be added to CodeHolder's buffer `cb`.
+ //!
+ //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the
+ //! behavior of the function is undefined.
ASMJIT_API Error growBuffer(CodeBuffer* cb, size_t n) noexcept;
+
+ //! Reserves the size of `cb` to at least `n` bytes.
+ //!
+ //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the
+ //! behavior of the function is undefined.
ASMJIT_API Error reserveBuffer(CodeBuffer* cb, size_t n) noexcept;
//! \}
@@ -719,7 +686,7 @@ public:
//! Returns '.text' section (section that commonly represents code).
//!
- //! \note Text section is always the first section in `CodeHolder::sections()` array.
+ //! \note Text section is always the first section in \ref CodeHolder::sections() array.
inline Section* textSection() const noexcept { return _sections[0]; }
//! Tests whether '.addrtab' section exists.
@@ -729,6 +696,8 @@ public:
//!
//! This section is used exclusively by AsmJit to store absolute 64-bit
//! addresses that cannot be encoded in instructions like 'jmp' or 'call'.
+ //!
+ //! \note This section is created on demand, the returned pointer can be null.
inline Section* addressTableSection() const noexcept { return _addressTableSection; }
//! Ensures that '.addrtab' section exists (creates it if it doesn't) and
@@ -825,18 +794,38 @@ public:
//! Returns `Error`, does not report error to `ErrorHandler`.
ASMJIT_API Error newLabelEntry(LabelEntry** entryOut) noexcept;
- //! Creates a new named label label-type `type`.
+ //! Creates a new named \ref LabelEntry of the given label `type`.
//!
- //! Returns `Error`, does not report a possible error to `ErrorHandler`.
+ //! \param entryOut Where to store the created \ref LabelEntry.
+ //! \param name The name of the label.
+ //! \param nameSize The length of `name` argument, or `SIZE_MAX` if `name` is
+ //! a null terminated string, which means that the `CodeHolder` will
+ //! use `strlen()` to determine the length.
+ //! \param type The type of the label to create, see \ref Label::LabelType.
+ //! \param parentId Parent id of a local label, otherwise it must be
+ //! \ref Globals::kInvalidId.
+ //!
+ //! \retval Always returns \ref Error, does not report a possible error to
+ //! the attached \ref ErrorHandler.
+ //!
+ //! AsmJit has a support for local labels (\ref Label::kTypeLocal) which
+ //! require a parent label id (parentId). The names of local labels can
+ //! conflict with names of other local labels that have a different parent.
ASMJIT_API Error newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, uint32_t type, uint32_t parentId = Globals::kInvalidId) noexcept;
- //! Returns a label id by name.
- ASMJIT_API uint32_t labelIdByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept;
-
+ //! Returns a label by name.
+ //!
+ //! If the named label doesn't a default constructed \ref Label is returned,
+ //! which has its id set to \ref Globals::kInvalidId.
inline Label labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept {
return Label(labelIdByName(name, nameSize, parentId));
}
+ //! Returns a label id by name.
+ //!
+ //! If the named label doesn't exist \ref Globals::kInvalidId is returned.
+ ASMJIT_API uint32_t labelIdByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept;
+
//! Tests whether there are any unresolved label links.
inline bool hasUnresolvedLinks() const noexcept { return _unresolvedLinkCount != 0; }
//! Returns the number of label links, which are unresolved.
@@ -903,24 +892,34 @@ public:
//! \note This should never be called more than once.
ASMJIT_API Error relocateToBase(uint64_t baseAddress) noexcept;
- //! Options that can be used with \ref copySectionData().
- enum CopyOptions : uint32_t {
- //! If virtual size of the section is larger than the size of its buffer
- //! then all bytes between buffer size and virtual size will be zeroed.
- kCopyWithPadding = 0x1
- };
-
//! Copies a single section into `dst`.
- ASMJIT_API Error copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t options = 0) noexcept;
+ ASMJIT_API Error copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t copyOptions = 0) noexcept;
//! Copies all sections into `dst`.
//!
//! This should only be used if the data was flattened and there are no gaps
//! between the sections. The `dstSize` is always checked and the copy will
//! never write anything outside the provided buffer.
- ASMJIT_API Error copyFlattenedData(void* dst, size_t dstSize, uint32_t options = 0) noexcept;
+ ASMJIT_API Error copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOptions = 0) noexcept;
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use 'CodeHolder::init(const Environment& environment, uint64_t baseAddress)' instead")
+ inline Error init(const CodeInfo& codeInfo) noexcept { return init(codeInfo._environment, codeInfo._baseAddress); }
+
+ ASMJIT_DEPRECATED("Use nevironment() instead")
+ inline CodeInfo codeInfo() const noexcept { return CodeInfo(_environment, _baseAddress); }
+
+ ASMJIT_DEPRECATED("Use BaseEmitter::encodingOptions() - this function always returns zero")
+ inline uint32_t emitterOptions() const noexcept { return 0; }
+
+ ASMJIT_DEPRECATED("Use BaseEmitter::addEncodingOptions() - this function does nothing")
+ inline void addEmitterOptions(uint32_t options) noexcept { DebugUtils::unused(options); }
+
+ ASMJIT_DEPRECATED("Use BaseEmitter::clearEncodingOptions() - this function does nothing")
+ inline void clearEmitterOptions(uint32_t options) noexcept { DebugUtils::unused(options); }
+#endif // !ASMJIT_NO_DEPRECATED
};
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/compiler.cpp b/3rdparty/asmjit/src/asmjit/core/compiler.cpp
index 13dbf54300a..28bc93f29f2 100644
--- a/3rdparty/asmjit/src/asmjit/core/compiler.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/compiler.cpp
@@ -27,7 +27,7 @@
#include "../core/assembler.h"
#include "../core/compiler.h"
#include "../core/cpuinfo.h"
-#include "../core/logging.h"
+#include "../core/logger.h"
#include "../core/rapass_p.h"
#include "../core/rastack_p.h"
#include "../core/support.h"
@@ -40,12 +40,12 @@ ASMJIT_BEGIN_NAMESPACE
// ============================================================================
class GlobalConstPoolPass : public Pass {
- ASMJIT_NONCOPYABLE(GlobalConstPoolPass)
typedef Pass Base;
+ ASMJIT_NONCOPYABLE(GlobalConstPoolPass)
GlobalConstPoolPass() noexcept : Pass("GlobalConstPoolPass") {}
- Error run(Zone* zone, Logger* logger) noexcept override {
+ Error run(Zone* zone, Logger* logger) override {
DebugUtils::unused(zone, logger);
// Flush the global constant pool.
@@ -54,15 +54,16 @@ class GlobalConstPoolPass : public Pass {
compiler->addAfter(compiler->_globalConstPool, compiler->lastNode());
compiler->_globalConstPool = nullptr;
}
+
return kErrorOk;
}
};
// ============================================================================
-// [asmjit::FuncCallNode - Arg / Ret]
+// [asmjit::InvokeNode - Arg / Ret]
// ============================================================================
-bool FuncCallNode::_setArg(uint32_t i, const Operand_& op) noexcept {
+bool InvokeNode::_setArg(uint32_t i, const Operand_& op) noexcept {
if ((i & ~kFuncArgHi) >= _funcDetail.argCount())
return false;
@@ -70,7 +71,7 @@ bool FuncCallNode::_setArg(uint32_t i, const Operand_& op) noexcept {
return true;
}
-bool FuncCallNode::_setRet(uint32_t i, const Operand_& op) noexcept {
+bool InvokeNode::_setRet(uint32_t i, const Operand_& op) noexcept {
if (i >= 2)
return false;
@@ -90,72 +91,81 @@ BaseCompiler::BaseCompiler() noexcept
_localConstPool(nullptr),
_globalConstPool(nullptr) {
- _type = kTypeCompiler;
+ _emitterType = uint8_t(kTypeCompiler);
+ _validationFlags = uint8_t(InstAPI::kValidationFlagVirtRegs);
}
BaseCompiler::~BaseCompiler() noexcept {}
// ============================================================================
-// [asmjit::BaseCompiler - Function API]
+// [asmjit::BaseCompiler - Function Management]
// ============================================================================
-FuncNode* BaseCompiler::newFunc(const FuncSignature& sign) noexcept {
- Error err;
-
- FuncNode* func = newNodeT<FuncNode>();
- if (ASMJIT_UNLIKELY(!func)) {
- reportError(DebugUtils::errored(kErrorOutOfMemory));
- return nullptr;
- }
+Error BaseCompiler::_newFuncNode(FuncNode** out, const FuncSignature& signature) {
+ *out = nullptr;
- err = registerLabelNode(func);
- if (ASMJIT_UNLIKELY(err)) {
- // TODO: Calls reportError, maybe rethink noexcept?
- reportError(err);
- return nullptr;
- }
-
- // Create helper nodes.
- func->_exitNode = newLabelNode();
- func->_end = newNodeT<SentinelNode>(SentinelNode::kSentinelFuncEnd);
-
- if (ASMJIT_UNLIKELY(!func->_exitNode || !func->_end)) {
- reportError(DebugUtils::errored(kErrorOutOfMemory));
- return nullptr;
- }
+ // Create FuncNode together with all the required surrounding nodes.
+ FuncNode* funcNode;
+ ASMJIT_PROPAGATE(_newNodeT<FuncNode>(&funcNode));
+ ASMJIT_PROPAGATE(_newLabelNode(&funcNode->_exitNode));
+ ASMJIT_PROPAGATE(_newNodeT<SentinelNode>(&funcNode->_end, SentinelNode::kSentinelFuncEnd));
- // Initialize the function info.
- err = func->detail().init(sign);
- if (ASMJIT_UNLIKELY(err)) {
- reportError(err);
- return nullptr;
- }
+ // Initialize the function's detail info.
+ Error err = funcNode->detail().init(signature, environment());
+ if (ASMJIT_UNLIKELY(err))
+ return reportError(err);
// If the Target guarantees greater stack alignment than required by the
// calling convention then override it as we can prevent having to perform
// dynamic stack alignment
- if (func->_funcDetail._callConv.naturalStackAlignment() < _codeInfo.stackAlignment())
- func->_funcDetail._callConv.setNaturalStackAlignment(_codeInfo.stackAlignment());
+ uint32_t environmentStackAlignment = _environment.stackAlignment();
+
+ if (funcNode->_funcDetail._callConv.naturalStackAlignment() < environmentStackAlignment)
+ funcNode->_funcDetail._callConv.setNaturalStackAlignment(environmentStackAlignment);
// Initialize the function frame.
- err = func->_frame.init(func->_funcDetail);
- if (ASMJIT_UNLIKELY(err)) {
- reportError(err);
- return nullptr;
- }
+ err = funcNode->_frame.init(funcNode->_funcDetail);
+ if (ASMJIT_UNLIKELY(err))
+ return reportError(err);
// Allocate space for function arguments.
- func->_args = nullptr;
- if (func->argCount() != 0) {
- func->_args = _allocator.allocT<VirtReg*>(func->argCount() * sizeof(VirtReg*));
- if (ASMJIT_UNLIKELY(!func->_args)) {
- reportError(DebugUtils::errored(kErrorOutOfMemory));
- return nullptr;
- }
-
- memset(func->_args, 0, func->argCount() * sizeof(VirtReg*));
+ funcNode->_args = nullptr;
+ if (funcNode->argCount() != 0) {
+ funcNode->_args = _allocator.allocT<VirtReg*>(funcNode->argCount() * sizeof(VirtReg*));
+ if (ASMJIT_UNLIKELY(!funcNode->_args))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
+ memset(funcNode->_args, 0, funcNode->argCount() * sizeof(VirtReg*));
}
- return func;
+ ASMJIT_PROPAGATE(registerLabelNode(funcNode));
+
+ *out = funcNode;
+ return kErrorOk;
+}
+
+Error BaseCompiler::_addFuncNode(FuncNode** out, const FuncSignature& signature) {
+ ASMJIT_PROPAGATE(_newFuncNode(out, signature));
+ addFunc(*out);
+ return kErrorOk;
+}
+
+Error BaseCompiler::_newRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
+ uint32_t opCount = !o1.isNone() ? 2u : !o0.isNone() ? 1u : 0u;
+ FuncRetNode* node;
+
+ ASMJIT_PROPAGATE(_newNodeT<FuncRetNode>(&node));
+ node->setOpCount(opCount);
+ node->setOp(0, o0);
+ node->setOp(1, o1);
+ node->resetOpRange(2, node->opCapacity());
+
+ *out = node;
+ return kErrorOk;
+}
+
+Error BaseCompiler::_addRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
+ ASMJIT_PROPAGATE(_newRetNode(out, o0, o1));
+ addNode(*out);
+ return kErrorOk;
}
FuncNode* BaseCompiler::addFunc(FuncNode* func) {
@@ -165,25 +175,15 @@ FuncNode* BaseCompiler::addFunc(FuncNode* func) {
addNode(func); // Function node.
BaseNode* prev = cursor(); // {CURSOR}.
addNode(func->exitNode()); // Function exit label.
- addNode(func->endNode()); // Function end marker.
+ addNode(func->endNode()); // Function end sentinel.
_setCursor(prev);
return func;
}
-FuncNode* BaseCompiler::addFunc(const FuncSignature& sign) {
- FuncNode* func = newFunc(sign);
-
- if (!func) {
- reportError(DebugUtils::errored(kErrorOutOfMemory));
- return nullptr;
- }
-
- return addFunc(func);
-}
-
Error BaseCompiler::endFunc() {
FuncNode* func = _func;
+
if (ASMJIT_UNLIKELY(!func))
return reportError(DebugUtils::errored(kErrorInvalidState));
@@ -199,6 +199,7 @@ Error BaseCompiler::endFunc() {
SentinelNode* end = func->endNode();
setCursor(end);
+
return kErrorOk;
}
@@ -217,71 +218,43 @@ Error BaseCompiler::setArg(uint32_t argIndex, const BaseReg& r) {
return kErrorOk;
}
-FuncRetNode* BaseCompiler::newRet(const Operand_& o0, const Operand_& o1) noexcept {
- FuncRetNode* node = newNodeT<FuncRetNode>();
- if (!node) {
- reportError(DebugUtils::errored(kErrorOutOfMemory));
- return nullptr;
- }
-
- node->setOp(0, o0);
- node->setOp(1, o1);
- node->setOpCount(!o1.isNone() ? 2u : !o0.isNone() ? 1u : 0u);
-
- return node;
-}
-
-FuncRetNode* BaseCompiler::addRet(const Operand_& o0, const Operand_& o1) noexcept {
- FuncRetNode* node = newRet(o0, o1);
- if (!node) return nullptr;
- return addNode(node)->as<FuncRetNode>();
-}
-
// ============================================================================
-// [asmjit::BaseCompiler - Call]
+// [asmjit::BaseCompiler - Function Invocation]
// ============================================================================
-FuncCallNode* BaseCompiler::newCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
- FuncCallNode* node = newNodeT<FuncCallNode>(instId, 0u);
- if (ASMJIT_UNLIKELY(!node)) {
- reportError(DebugUtils::errored(kErrorOutOfMemory));
- return nullptr;
- }
+Error BaseCompiler::_newInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
+ InvokeNode* node;
+ ASMJIT_PROPAGATE(_newNodeT<InvokeNode>(&node, instId, 0u));
node->setOpCount(1);
node->setOp(0, o0);
- node->resetOp(1);
- node->resetOp(2);
- node->resetOp(3);
+ node->resetOpRange(1, node->opCapacity());
- Error err = node->detail().init(sign);
- if (ASMJIT_UNLIKELY(err)) {
- reportError(err);
- return nullptr;
- }
-
- // If there are no arguments skip the allocation.
- uint32_t nArgs = sign.argCount();
- if (!nArgs) return node;
+ Error err = node->detail().init(signature, environment());
+ if (ASMJIT_UNLIKELY(err))
+ return reportError(err);
- node->_args = static_cast<Operand*>(_allocator.alloc(nArgs * sizeof(Operand)));
- if (!node->_args) {
- reportError(DebugUtils::errored(kErrorOutOfMemory));
- return nullptr;
+ // Skip the allocation if there are no arguments.
+ uint32_t argCount = signature.argCount();
+ if (argCount) {
+ node->_args = static_cast<Operand*>(_allocator.alloc(argCount * sizeof(Operand)));
+ if (!node->_args)
+ reportError(DebugUtils::errored(kErrorOutOfMemory));
+ memset(node->_args, 0, argCount * sizeof(Operand));
}
- memset(node->_args, 0, nArgs * sizeof(Operand));
- return node;
+ *out = node;
+ return kErrorOk;
}
-FuncCallNode* BaseCompiler::addCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
- FuncCallNode* node = newCall(instId, o0, sign);
- if (!node) return nullptr;
- return addNode(node)->as<FuncCallNode>();
+Error BaseCompiler::_addInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
+ ASMJIT_PROPAGATE(_newInvokeNode(out, instId, o0, signature));
+ addNode(*out);
+ return kErrorOk;
}
// ============================================================================
-// [asmjit::BaseCompiler - Vars]
+// [asmjit::BaseCompiler - Virtual Registers]
// ============================================================================
static void BaseCompiler_assignGenericName(BaseCompiler* self, VirtReg* vReg) {
@@ -294,16 +267,19 @@ static void BaseCompiler_assignGenericName(BaseCompiler* self, VirtReg* vReg) {
vReg->_name.setData(&self->_dataZone, buf, unsigned(size));
}
-VirtReg* BaseCompiler::newVirtReg(uint32_t typeId, uint32_t signature, const char* name) noexcept {
+Error BaseCompiler::newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signature, const char* name) {
+ *out = nullptr;
uint32_t index = _vRegArray.size();
+
if (ASMJIT_UNLIKELY(index >= uint32_t(Operand::kVirtIdCount)))
- return nullptr;
+ return reportError(DebugUtils::errored(kErrorTooManyVirtRegs));
- if (_vRegArray.willGrow(&_allocator) != kErrorOk)
- return nullptr;
+ if (ASMJIT_UNLIKELY(_vRegArray.willGrow(&_allocator) != kErrorOk))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
VirtReg* vReg = _vRegZone.allocZeroedT<VirtReg>();
- if (ASMJIT_UNLIKELY(!vReg)) return nullptr;
+ if (ASMJIT_UNLIKELY(!vReg))
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
uint32_t size = Type::sizeOf(typeId);
uint32_t alignment = Support::min<uint32_t>(size, 64);
@@ -320,26 +296,28 @@ VirtReg* BaseCompiler::newVirtReg(uint32_t typeId, uint32_t signature, const cha
#endif
_vRegArray.appendUnsafe(vReg);
- return vReg;
+ *out = vReg;
+
+ return kErrorOk;
}
-Error BaseCompiler::_newReg(BaseReg& out, uint32_t typeId, const char* name) {
+Error BaseCompiler::_newReg(BaseReg* out, uint32_t typeId, const char* name) {
+ out->reset();
+
RegInfo regInfo;
+ Error err = ArchUtils::typeIdToRegInfo(arch(), typeId, &typeId, &regInfo);
- Error err = ArchUtils::typeIdToRegInfo(archId(), typeId, regInfo);
- if (ASMJIT_UNLIKELY(err)) return reportError(err);
+ if (ASMJIT_UNLIKELY(err))
+ return reportError(err);
- VirtReg* vReg = newVirtReg(typeId, regInfo.signature(), name);
- if (ASMJIT_UNLIKELY(!vReg)) {
- out.reset();
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- }
+ VirtReg* vReg;
+ ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regInfo.signature(), name));
- out._initReg(regInfo.signature(), vReg->id());
+ out->_initReg(regInfo.signature(), vReg->id());
return kErrorOk;
}
-Error BaseCompiler::_newRegFmt(BaseReg& out, uint32_t typeId, const char* fmt, ...) {
+Error BaseCompiler::_newRegFmt(BaseReg* out, uint32_t typeId, const char* fmt, ...) {
va_list ap;
StringTmp<256> sb;
@@ -350,7 +328,9 @@ Error BaseCompiler::_newRegFmt(BaseReg& out, uint32_t typeId, const char* fmt, .
return _newReg(out, typeId, sb.data());
}
-Error BaseCompiler::_newReg(BaseReg& out, const BaseReg& ref, const char* name) {
+Error BaseCompiler::_newReg(BaseReg* out, const BaseReg& ref, const char* name) {
+ out->reset();
+
RegInfo regInfo;
uint32_t typeId;
@@ -412,20 +392,18 @@ Error BaseCompiler::_newReg(BaseReg& out, const BaseReg& ref, const char* name)
typeId = ref.type();
}
- Error err = ArchUtils::typeIdToRegInfo(archId(), typeId, regInfo);
- if (ASMJIT_UNLIKELY(err)) return reportError(err);
+ Error err = ArchUtils::typeIdToRegInfo(arch(), typeId, &typeId, &regInfo);
+ if (ASMJIT_UNLIKELY(err))
+ return reportError(err);
- VirtReg* vReg = newVirtReg(typeId, regInfo.signature(), name);
- if (ASMJIT_UNLIKELY(!vReg)) {
- out.reset();
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- }
+ VirtReg* vReg;
+ ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regInfo.signature(), name));
- out._initReg(regInfo.signature(), vReg->id());
+ out->_initReg(regInfo.signature(), vReg->id());
return kErrorOk;
}
-Error BaseCompiler::_newRegFmt(BaseReg& out, const BaseReg& ref, const char* fmt, ...) {
+Error BaseCompiler::_newRegFmt(BaseReg* out, const BaseReg& ref, const char* fmt, ...) {
va_list ap;
StringTmp<256> sb;
@@ -436,7 +414,9 @@ Error BaseCompiler::_newRegFmt(BaseReg& out, const BaseReg& ref, const char* fmt
return _newReg(out, ref, sb.data());
}
-Error BaseCompiler::_newStack(BaseMem& out, uint32_t size, uint32_t alignment, const char* name) {
+Error BaseCompiler::_newStack(BaseMem* out, uint32_t size, uint32_t alignment, const char* name) {
+ out->reset();
+
if (size == 0)
return reportError(DebugUtils::errored(kErrorInvalidArgument));
@@ -449,22 +429,19 @@ Error BaseCompiler::_newStack(BaseMem& out, uint32_t size, uint32_t alignment, c
if (alignment > 64)
alignment = 64;
- VirtReg* vReg = newVirtReg(0, 0, name);
- if (ASMJIT_UNLIKELY(!vReg)) {
- out.reset();
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- }
+ VirtReg* vReg;
+ ASMJIT_PROPAGATE(newVirtReg(&vReg, 0, 0, name));
vReg->_virtSize = size;
vReg->_isStack = true;
vReg->_alignment = uint8_t(alignment);
// Set the memory operand to GPD/GPQ and its id to VirtReg.
- out = BaseMem(BaseMem::Decomposed { _gpRegInfo.type(), vReg->id(), BaseReg::kTypeNone, 0, 0, 0, BaseMem::kSignatureMemRegHomeFlag });
+ *out = BaseMem(BaseMem::Decomposed { _gpRegInfo.type(), vReg->id(), BaseReg::kTypeNone, 0, 0, 0, BaseMem::kSignatureMemRegHomeFlag });
return kErrorOk;
}
-Error BaseCompiler::setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment) noexcept {
+Error BaseCompiler::setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment) {
if (!isVirtIdValid(virtId))
return DebugUtils::errored(kErrorInvalidVirtId);
@@ -493,8 +470,10 @@ Error BaseCompiler::setStackSize(uint32_t virtId, uint32_t newSize, uint32_t new
return kErrorOk;
}
-Error BaseCompiler::_newConst(BaseMem& out, uint32_t scope, const void* data, size_t size) {
+Error BaseCompiler::_newConst(BaseMem* out, uint32_t scope, const void* data, size_t size) {
+ out->reset();
ConstPoolNode** pPool;
+
if (scope == ConstPool::kScopeLocal)
pPool = &_localConstPool;
else if (scope == ConstPool::kScopeGlobal)
@@ -502,29 +481,26 @@ Error BaseCompiler::_newConst(BaseMem& out, uint32_t scope, const void* data, si
else
return reportError(DebugUtils::errored(kErrorInvalidArgument));
- ConstPoolNode* pool = *pPool;
- if (!pool) {
- pool = newConstPoolNode();
- if (ASMJIT_UNLIKELY(!pool))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- *pPool = pool;
- }
+ if (!*pPool)
+ ASMJIT_PROPAGATE(_newConstPoolNode(pPool));
+ ConstPoolNode* pool = *pPool;
size_t off;
Error err = pool->add(data, size, off);
if (ASMJIT_UNLIKELY(err))
return reportError(err);
- out = BaseMem(BaseMem::Decomposed {
+ *out = BaseMem(BaseMem::Decomposed {
Label::kLabelTag, // Base type.
- pool->id(), // Base id.
+ pool->labelId(), // Base id.
0, // Index type.
0, // Index id.
int32_t(off), // Offset.
uint32_t(size), // Size.
0 // Flags.
});
+
return kErrorOk;
}
@@ -553,38 +529,38 @@ void BaseCompiler::rename(const BaseReg& reg, const char* fmt, ...) {
// [asmjit::BaseCompiler - Jump Annotations]
// ============================================================================
-JumpNode* BaseCompiler::newJumpNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation) noexcept {
- uint32_t opCount = 1;
+Error BaseCompiler::newJumpNode(JumpNode** out, uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation) {
JumpNode* node = _allocator.allocT<JumpNode>();
+ uint32_t opCount = 1;
+
if (ASMJIT_UNLIKELY(!node))
- return nullptr;
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
node = new(node) JumpNode(this, instId, instOptions, opCount, annotation);
node->setOp(0, o0);
- node->resetOps(opCount, JumpNode::kBaseOpCapacity);
- return node;
+ node->resetOpRange(opCount, JumpNode::kBaseOpCapacity);
+
+ *out = node;
+ return kErrorOk;
}
Error BaseCompiler::emitAnnotatedJump(uint32_t instId, const Operand_& o0, JumpAnnotation* annotation) {
- uint32_t options = instOptions() | globalInstOptions();
+ uint32_t options = instOptions() | forcedInstOptions();
+ RegOnly extra = extraReg();
const char* comment = inlineComment();
- JumpNode* node = newJumpNode(instId, options, o0, annotation);
-
resetInstOptions();
resetInlineComment();
+ resetExtraReg();
- if (ASMJIT_UNLIKELY(!node)) {
- resetExtraReg();
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- }
+ JumpNode* node;
+ ASMJIT_PROPAGATE(newJumpNode(&node, instId, options, o0, annotation));
- node->setExtraReg(extraReg());
+ node->setExtraReg(extra);
if (comment)
node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
addNode(node);
- resetExtraReg();
return kErrorOk;
}
@@ -644,7 +620,7 @@ FuncPass::FuncPass(const char* name) noexcept
// [asmjit::FuncPass - Run]
// ============================================================================
-Error FuncPass::run(Zone* zone, Logger* logger) noexcept {
+Error FuncPass::run(Zone* zone, Logger* logger) {
BaseNode* node = cb()->firstNode();
if (!node) return kErrorOk;
diff --git a/3rdparty/asmjit/src/asmjit/core/compiler.h b/3rdparty/asmjit/src/asmjit/core/compiler.h
index 32b2a8bb271..71f89ec701e 100644
--- a/3rdparty/asmjit/src/asmjit/core/compiler.h
+++ b/3rdparty/asmjit/src/asmjit/core/compiler.h
@@ -51,7 +51,7 @@ class JumpAnnotation;
class JumpNode;
class FuncNode;
class FuncRetNode;
-class FuncCallNode;
+class InvokeNode;
//! \addtogroup asmjit_compiler
//! \{
@@ -60,7 +60,7 @@ class FuncCallNode;
// [asmjit::VirtReg]
// ============================================================================
-//! Virtual register data (BaseCompiler).
+//! Virtual register data, managed by \ref BaseCompiler.
class VirtReg {
public:
ASMJIT_NONCOPYABLE(VirtReg)
@@ -192,14 +192,18 @@ public:
//! primarily designed for merging multiple parts of code into a function
//! without worrying about registers and function calling conventions.
//!
-//! BaseCompiler can be used, with a minimum effort, to handle 32-bit and 64-bit
-//! code at the same time.
+//! BaseCompiler can be used, with a minimum effort, to handle 32-bit and
+//! 64-bit code generation within a single code base.
//!
//! BaseCompiler is based on BaseBuilder and contains all the features it
//! provides. It means that the code it stores can be modified (removed, added,
//! injected) and analyzed. When the code is finalized the compiler can emit
//! the code into an Assembler to translate the abstract representation into a
//! machine code.
+//!
+//! Check out architecture specific compilers for more details and examples:
+//!
+//! - \ref x86::Compiler - X86/X64 compiler implementation.
class ASMJIT_VIRTAPI BaseCompiler : public BaseBuilder {
public:
ASMJIT_NONCOPYABLE(BaseCompiler)
@@ -229,38 +233,80 @@ public:
//! \}
- //! \name Function API
+ //! \name Function Management
//! \{
//! Returns the current function.
inline FuncNode* func() const noexcept { return _func; }
- //! Creates a new `FuncNode`.
- ASMJIT_API FuncNode* newFunc(const FuncSignature& sign) noexcept;
- //! Adds a function `node` to the stream.
+ //! Creates a new \ref FuncNode.
+ ASMJIT_API Error _newFuncNode(FuncNode** out, const FuncSignature& signature);
+ //! Creates a new \ref FuncNode adds it to the compiler.
+ ASMJIT_API Error _addFuncNode(FuncNode** out, const FuncSignature& signature);
+
+ //! Creates a new \ref FuncRetNode.
+ ASMJIT_API Error _newRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1);
+ //! Creates a new \ref FuncRetNode and adds it to the compiler.
+ ASMJIT_API Error _addRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1);
+
+ //! Creates a new \ref FuncNode with the given `signature` and returns it.
+ inline FuncNode* newFunc(const FuncSignature& signature) {
+ FuncNode* node;
+ _newFuncNode(&node, signature);
+ return node;
+ }
+
+ //! Creates a new \ref FuncNode with the given `signature`, adds it to the
+ //! compiler by using the \ref addFunc(FuncNode*) overload, and returns it.
+ inline FuncNode* addFunc(const FuncSignature& signature) {
+ FuncNode* node;
+ _addFuncNode(&node, signature);
+ return node;
+ }
+
+ //! Adds a function `node` to the instruction stream.
ASMJIT_API FuncNode* addFunc(FuncNode* func);
- //! Adds a new function.
- ASMJIT_API FuncNode* addFunc(const FuncSignature& sign);
//! Emits a sentinel that marks the end of the current function.
ASMJIT_API Error endFunc();
//! Sets a function argument at `argIndex` to `reg`.
ASMJIT_API Error setArg(uint32_t argIndex, const BaseReg& reg);
- //! Creates a new `FuncRetNode`.
- ASMJIT_API FuncRetNode* newRet(const Operand_& o0, const Operand_& o1) noexcept;
- //! Adds a new `FuncRetNode`.
- ASMJIT_API FuncRetNode* addRet(const Operand_& o0, const Operand_& o1) noexcept;
+ inline FuncRetNode* newRet(const Operand_& o0, const Operand_& o1) {
+ FuncRetNode* node;
+ _newRetNode(&node, o0, o1);
+ return node;
+ }
+
+ inline FuncRetNode* addRet(const Operand_& o0, const Operand_& o1) {
+ FuncRetNode* node;
+ _addRetNode(&node, o0, o1);
+ return node;
+ }
//! \}
- //! \name Function Calls
+ //! \name Function Invocation
//! \{
- //! Creates a new `FuncCallNode`.
- ASMJIT_API FuncCallNode* newCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept;
- //! Adds a new `FuncCallNode`.
- ASMJIT_API FuncCallNode* addCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept;
+ //! Creates a new \ref InvokeNode.
+ ASMJIT_API Error _newInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature);
+ //! Creates a new \ref InvokeNode and adds it to Compiler.
+ ASMJIT_API Error _addInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature);
+
+ //! Creates a new `InvokeNode`.
+ inline InvokeNode* newCall(uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
+ InvokeNode* node;
+ _newInvokeNode(&node, instId, o0, signature);
+ return node;
+ }
+
+ //! Adds a new `InvokeNode`.
+ inline InvokeNode* addCall(uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
+ InvokeNode* node;
+ _addInvokeNode(&node, instId, o0, signature);
+ return node;
+ }
//! \}
@@ -268,13 +314,27 @@ public:
//! \{
//! Creates a new virtual register representing the given `typeId` and `signature`.
- ASMJIT_API VirtReg* newVirtReg(uint32_t typeId, uint32_t signature, const char* name) noexcept;
+ //!
+ //! \note This function is public, but it's not generally recommended to be used
+ //! by AsmJit users, use architecture-specific `newReg()` functionality instead
+ //! or functions like \ref _newReg() and \ref _newRegFmt().
+ ASMJIT_API Error newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signature, const char* name);
- ASMJIT_API Error _newReg(BaseReg& out, uint32_t typeId, const char* name = nullptr);
- ASMJIT_API Error _newRegFmt(BaseReg& out, uint32_t typeId, const char* fmt, ...);
+ //! Creates a new virtual register of the given `typeId` and stores it to `out` operand.
+ ASMJIT_API Error _newReg(BaseReg* out, uint32_t typeId, const char* name = nullptr);
- ASMJIT_API Error _newReg(BaseReg& out, const BaseReg& ref, const char* name = nullptr);
- ASMJIT_API Error _newRegFmt(BaseReg& out, const BaseReg& ref, const char* fmt, ...);
+ //! Creates a new virtual register of the given `typeId` and stores it to `out` operand.
+ //!
+ //! \note This version accepts a snprintf() format `fmt` followed by a variadic arguments.
+ ASMJIT_API Error _newRegFmt(BaseReg* out, uint32_t typeId, const char* fmt, ...);
+
+ //! Creates a new virtual register compatible with the provided reference register `ref`.
+ ASMJIT_API Error _newReg(BaseReg* out, const BaseReg& ref, const char* name = nullptr);
+
+ //! Creates a new virtual register compatible with the provided reference register `ref`.
+ //!
+ //! \note This version accepts a snprintf() format `fmt` followed by a variadic arguments.
+ ASMJIT_API Error _newRegFmt(BaseReg* out, const BaseReg& ref, const char* fmt, ...);
//! Tests whether the given `id` is a valid virtual register id.
inline bool isVirtIdValid(uint32_t id) const noexcept {
@@ -286,14 +346,20 @@ public:
return isVirtIdValid(reg.id());
}
- //! Returns `VirtReg` associated with the given `id`.
+ //! Returns \ref VirtReg associated with the given `id`.
inline VirtReg* virtRegById(uint32_t id) const noexcept {
ASMJIT_ASSERT(isVirtIdValid(id));
return _vRegArray[Operand::virtIdToIndex(id)];
}
- //! Returns `VirtReg` associated with the given `reg`.
+
+ //! Returns \ref VirtReg associated with the given `reg`.
inline VirtReg* virtRegByReg(const BaseReg& reg) const noexcept { return virtRegById(reg.id()); }
- //! Returns `VirtReg` associated with the given `index`.
+
+ //! Returns \ref VirtReg associated with the given virtual register `index`.
+ //!
+ //! \note This is not the same as virtual register id. The conversion between
+ //! id and its index is implemented by \ref Operand_::virtIdToIndex() and \ref
+ //! Operand_::indexToVirtId() functions.
inline VirtReg* virtRegByIndex(uint32_t index) const noexcept { return _vRegArray[index]; }
//! Returns an array of all virtual registers managed by the Compiler.
@@ -302,13 +368,16 @@ public:
//! \name Stack
//! \{
- ASMJIT_API Error _newStack(BaseMem& out, uint32_t size, uint32_t alignment, const char* name = nullptr);
+ //! Creates a new stack of the given `size` and `alignment` and stores it to `out`.
+ //!
+ //! \note `name` can be used to give the stack a name, for debugging purposes.
+ ASMJIT_API Error _newStack(BaseMem* out, uint32_t size, uint32_t alignment, const char* name = nullptr);
//! Updates the stack size of a stack created by `_newStack()` by its `virtId`.
- ASMJIT_API Error setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment = 0) noexcept;
+ ASMJIT_API Error setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment = 0);
//! Updates the stack size of a stack created by `_newStack()`.
- inline Error setStackSize(const BaseMem& mem, uint32_t newSize, uint32_t newAlignment = 0) noexcept {
+ inline Error setStackSize(const BaseMem& mem, uint32_t newSize, uint32_t newAlignment = 0) {
return setStackSize(mem.id(), newSize, newAlignment);
}
@@ -317,7 +386,11 @@ public:
//! \name Constants
//! \{
- ASMJIT_API Error _newConst(BaseMem& out, uint32_t scope, const void* data, size_t size);
+ //! Creates a new constant of the given `scope` (see \ref ConstPool::Scope).
+ //!
+ //! This function adds a constant of the given `size` to the built-in \ref
+ //! ConstPool and stores the reference to that constant to the `out` operand.
+ ASMJIT_API Error _newConst(BaseMem* out, uint32_t scope, const void* data, size_t size);
//! \}
@@ -325,8 +398,6 @@ public:
//! \{
//! Rename the given virtual register `reg` to a formatted string `fmt`.
- //!
- //! \note Only new name will appear in the logger.
ASMJIT_API void rename(const BaseReg& reg, const char* fmt, ...);
//! \}
@@ -338,7 +409,7 @@ public:
return _jumpAnnotations;
}
- ASMJIT_API JumpNode* newJumpNode(uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation) noexcept;
+ ASMJIT_API Error newJumpNode(JumpNode** out, uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation);
ASMJIT_API Error emitAnnotatedJump(uint32_t instId, const Operand_& o0, JumpAnnotation* annotation);
//! Returns a new `JumpAnnotation` instance, which can be used to aggregate
@@ -348,9 +419,12 @@ public:
//! \}
- // TODO: These should be removed
- inline void alloc(BaseReg& reg) { DebugUtils::unused(reg); }
- inline void spill(BaseReg& reg) { DebugUtils::unused(reg); }
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("alloc() has no effect, it will be removed in the future")
+ inline void alloc(BaseReg&) {}
+ ASMJIT_DEPRECATED("spill() has no effect, it will be removed in the future")
+ inline void spill(BaseReg&) {}
+#endif // !ASMJIT_NO_DEPRECATED
//! \name Events
//! \{
@@ -365,26 +439,44 @@ public:
// [asmjit::JumpAnnotation]
// ============================================================================
+//! Jump annotation used to annotate jumps.
+//!
+//! \ref BaseCompiler allows to emit jumps where the target is either register
+//! or memory operand. Such jumps cannot be trivially inspected, so instead of
+//! doing heuristics AsmJit allows to annotate such jumps with possible targets.
+//! Register allocator then use the annotation to construct control-flow, which
+//! is then used by liveness analysis and other tools to prepare ground for
+//! register allocation.
class JumpAnnotation {
public:
ASMJIT_NONCOPYABLE(JumpAnnotation)
+ //! Compiler that owns this JumpAnnotation.
BaseCompiler* _compiler;
+ //! Annotation identifier.
uint32_t _annotationId;
+ //! Vector of label identifiers, see \ref labelIds().
ZoneVector<uint32_t> _labelIds;
inline JumpAnnotation(BaseCompiler* compiler, uint32_t annotationId) noexcept
: _compiler(compiler),
_annotationId(annotationId) {}
+ //! Returns the compiler that owns this JumpAnnotation.
inline BaseCompiler* compiler() const noexcept { return _compiler; }
+ //! Returns the annotation id.
inline uint32_t annotationId() const noexcept { return _annotationId; }
+ //! Returns a vector of label identifiers that lists all targets of the jump.
const ZoneVector<uint32_t>& labelIds() const noexcept { return _labelIds; }
+ //! Tests whether the given `label` is a target of this JumpAnnotation.
inline bool hasLabel(const Label& label) const noexcept { return hasLabelId(label.id()); }
+ //! Tests whether the given `labelId` is a target of this JumpAnnotation.
inline bool hasLabelId(uint32_t labelId) const noexcept { return _labelIds.contains(labelId); }
+ //! Adds the `label` to the list of targets of this JumpAnnotation.
inline Error addLabel(const Label& label) noexcept { return addLabelId(label.id()); }
+ //! Adds the `labelId` to the list of targets of this JumpAnnotation.
inline Error addLabelId(uint32_t labelId) noexcept { return _labelIds.append(&_compiler->_allocator, labelId); }
};
@@ -418,8 +510,11 @@ public:
//! \name Accessors
//! \{
+ //! Tests whether this JumpNode has associated a \ref JumpAnnotation.
inline bool hasAnnotation() const noexcept { return _annotation != nullptr; }
+ //! Returns the \ref JumpAnnotation associated with this jump, or `nullptr`.
inline JumpAnnotation* annotation() const noexcept { return _annotation; }
+ //! Sets the \ref JumpAnnotation associated with this jump to `annotation`.
inline void setAnnotation(JumpAnnotation* annotation) noexcept { _annotation = annotation; }
//! \}
@@ -429,7 +524,51 @@ public:
// [asmjit::FuncNode]
// ============================================================================
-//! Function entry (BaseCompiler).
+//! Function node represents a function used by \ref BaseCompiler.
+//!
+//! A function is composed of the following:
+//!
+//! - Function entry, \ref FuncNode acts as a label, so the entry is implicit.
+//! To get the entry, simply use \ref FuncNode::label(), which is the same
+//! as \ref LabelNode::label().
+//!
+//! - Function exit, which is represented by \ref FuncNode::exitNode(). A
+//! helper function \ref FuncNode::exitLabel() exists and returns an exit
+//! label instead of node.
+//!
+//! - Function \ref FuncNode::endNode() sentinel. This node marks the end of
+//! a function - there should be no code that belongs to the function after
+//! this node, but the Compiler doesn't enforce that at the moment.
+//!
+//! - Function detail, see \ref FuncNode::detail().
+//!
+//! - Function frame, see \ref FuncNode::frame().
+//!
+//! - Function arguments mapped to virtual registers, see \ref FuncNode::args().
+//!
+//! In a node list, the function and its body looks like the following:
+//!
+//! \code{.unparsed}
+//! [...] - Anything before the function.
+//!
+//! [FuncNode] - Entry point of the function, acts as a label as well.
+//! <Prolog> - Prolog inserted by the register allocator.
+//! {...} - Function body - user code basically.
+//! [ExitLabel] - Exit label
+//! <Epilog> - Epilog inserted by the register allocator.
+//! <Return> - Return inserted by the register allocator.
+//! {...} - Can contain data or user code (error handling, special cases, ...).
+//! [FuncEnd] - End sentinel
+//!
+//! [...] - Anything after the function.
+//! \endcode
+//!
+//! When a function is added to the compiler by \ref BaseCompiler::addFunc() it
+//! actually inserts 3 nodes (FuncNode, ExitLabel, and FuncEnd) and sets the
+//! current cursor to be FuncNode. When \ref BaseCompiler::endFunc() is called
+//! the cursor is set to FuncEnd. This guarantees that user can use ExitLabel
+//! as a marker after additional code or data can be placed, and it's a common
+//! practice.
class FuncNode : public LabelNode {
public:
ASMJIT_NONCOPYABLE(FuncNode)
@@ -438,7 +577,7 @@ public:
FuncDetail _funcDetail;
//! Function frame.
FuncFrame _frame;
- //! Function exit (label).
+ //! Function exit label.
LabelNode* _exitNode;
//! Function end (sentinel).
SentinelNode* _end;
@@ -510,7 +649,9 @@ public:
_args[i] = nullptr;
}
+ //! Returns function attributes.
inline uint32_t attributes() const noexcept { return _frame.attributes(); }
+ //! Adds `attrs` to the function attributes.
inline void addAttributes(uint32_t attrs) noexcept { _frame.addAttributes(attrs); }
//! \}
@@ -520,7 +661,7 @@ public:
// [asmjit::FuncRetNode]
// ============================================================================
-//! Function return (BaseCompiler).
+//! Function return, used by \ref BaseCompiler.
class FuncRetNode : public InstNode {
public:
ASMJIT_NONCOPYABLE(FuncRetNode)
@@ -537,13 +678,13 @@ public:
};
// ============================================================================
-// [asmjit::FuncCallNode]
+// [asmjit::InvokeNode]
// ============================================================================
-//! Function call (BaseCompiler).
-class FuncCallNode : public InstNode {
+//! Function invocation, used by \ref BaseCompiler.
+class InvokeNode : public InstNode {
public:
- ASMJIT_NONCOPYABLE(FuncCallNode)
+ ASMJIT_NONCOPYABLE(InvokeNode)
//! Function detail.
FuncDetail _funcDetail;
@@ -555,12 +696,12 @@ public:
//! \name Construction & Destruction
//! \{
- //! Creates a new `FuncCallNode` instance.
- inline FuncCallNode(BaseBuilder* cb, uint32_t instId, uint32_t options) noexcept
+ //! Creates a new `InvokeNode` instance.
+ inline InvokeNode(BaseBuilder* cb, uint32_t instId, uint32_t options) noexcept
: InstNode(cb, instId, options, kBaseOpCapacity),
_funcDetail(),
_args(nullptr) {
- setType(kNodeFuncCall);
+ setType(kNodeInvoke);
_resetOps();
_rets[0].reset();
_rets[1].reset();
@@ -573,8 +714,8 @@ public:
//! \{
//! Sets the function signature.
- inline Error setSignature(const FuncSignature& sign) noexcept {
- return _funcDetail.init(sign);
+ inline Error init(const FuncSignature& signature, const Environment& environment) noexcept {
+ return _funcDetail.init(signature, environment);
}
//! Returns the function detail.
@@ -634,6 +775,7 @@ public:
// [asmjit::FuncPass]
// ============================================================================
+//! Function pass extends \ref Pass with \ref FuncPass::runOnFunction().
class ASMJIT_VIRTAPI FuncPass : public Pass {
public:
ASMJIT_NONCOPYABLE(FuncPass)
@@ -658,10 +800,10 @@ public:
//! \{
//! Calls `runOnFunction()` on each `FuncNode` node found.
- ASMJIT_API Error run(Zone* zone, Logger* logger) noexcept override;
+ ASMJIT_API Error run(Zone* zone, Logger* logger) override;
//! Called once per `FuncNode`.
- virtual Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) noexcept = 0;
+ virtual Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) = 0;
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/constpool.h b/3rdparty/asmjit/src/asmjit/core/constpool.h
index 259615fcaa8..d9ac58952a8 100644
--- a/3rdparty/asmjit/src/asmjit/core/constpool.h
+++ b/3rdparty/asmjit/src/asmjit/core/constpool.h
@@ -30,7 +30,7 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_core
+//! \addtogroup asmjit_utilities
//! \{
// ============================================================================
@@ -65,9 +65,12 @@ public:
//! Zone-allocated const-pool gap created by two differently aligned constants.
struct Gap {
- Gap* _next; //!< Pointer to the next gap
- size_t _offset; //!< Offset of the gap.
- size_t _size; //!< Remaining bytes of the gap (basically a gap size).
+ //! Pointer to the next gap
+ Gap* _next;
+ //! Offset of the gap.
+ size_t _offset;
+ //! Remaining bytes of the gap (basically a gap size).
+ size_t _size;
};
//! Zone-allocated const-pool node.
@@ -75,6 +78,11 @@ public:
public:
ASMJIT_NONCOPYABLE(Node)
+ //! If this constant is shared with another.
+ uint32_t _shared : 1;
+ //! Data offset from the beginning of the pool.
+ uint32_t _offset;
+
inline Node(size_t offset, bool shared) noexcept
: ZoneTreeNodeT<Node>(),
_shared(shared),
@@ -83,14 +91,13 @@ public:
inline void* data() const noexcept {
return static_cast<void*>(const_cast<ConstPool::Node*>(this) + 1);
}
-
- uint32_t _shared : 1; //!< If this constant is shared with another.
- uint32_t _offset; //!< Data offset from the beginning of the pool.
};
//! Data comparer used internally.
class Compare {
public:
+ size_t _dataSize;
+
inline Compare(size_t dataSize) noexcept
: _dataSize(dataSize) {}
@@ -101,12 +108,17 @@ public:
inline int operator()(const Node& a, const void* data) const noexcept {
return ::memcmp(a.data(), data, _dataSize);
}
-
- size_t _dataSize;
};
//! Zone-allocated const-pool tree.
struct Tree {
+ //! RB tree.
+ ZoneTree<Node> _tree;
+ //! Size of the tree (number of nodes).
+ size_t _size;
+ //! Size of the data.
+ size_t _dataSize;
+
inline explicit Tree(size_t dataSize = 0) noexcept
: _tree(),
_size(0),
@@ -177,13 +189,6 @@ public:
memcpy(node->data(), data, size);
return node;
}
-
- //! RB tree.
- ZoneTree<Node> _tree;
- //! Size of the tree (number of nodes).
- size_t _size;
- //! Size of the data.
- size_t _dataSize;
};
//! \endcond
diff --git a/3rdparty/asmjit/src/asmjit/core/cpuinfo.h b/3rdparty/asmjit/src/asmjit/core/cpuinfo.h
index d2defb90ed6..ee2c9e5514a 100644
--- a/3rdparty/asmjit/src/asmjit/core/cpuinfo.h
+++ b/3rdparty/asmjit/src/asmjit/core/cpuinfo.h
@@ -31,7 +31,7 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_support
+//! \addtogroup asmjit_core
//! \{
// ============================================================================
@@ -41,8 +41,12 @@ ASMJIT_BEGIN_NAMESPACE
//! CPU information.
class CpuInfo {
public:
- //! CPU architecture information.
- ArchInfo _archInfo;
+ //! Architecture.
+ uint8_t _arch;
+ //! Sub-architecture.
+ uint8_t _subArch;
+ //! Reserved for future use.
+ uint16_t _reserved;
//! CPU family ID.
uint32_t _familyId;
//! CPU model ID.
@@ -74,15 +78,15 @@ public:
inline CpuInfo(const CpuInfo& other) noexcept = default;
inline explicit CpuInfo(Globals::NoInit_) noexcept
- : _archInfo(Globals::NoInit),
- _features(Globals::NoInit) {};
+ : _features(Globals::NoInit) {};
//! Returns the host CPU information.
ASMJIT_API static const CpuInfo& host() noexcept;
- //! Initializes CpuInfo to the given architecture, see `ArchInfo`.
- inline void initArch(uint32_t archId, uint32_t archMode = 0) noexcept {
- _archInfo.init(archId, archMode);
+ //! Initializes CpuInfo to the given architecture, see \ref Environment.
+ inline void initArch(uint32_t arch, uint32_t subArch = 0u) noexcept {
+ _arch = uint8_t(arch);
+ _subArch = uint8_t(subArch);
}
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
@@ -99,12 +103,10 @@ public:
//! \name Accessors
//! \{
- //! Returns the CPU architecture information.
- inline const ArchInfo& archInfo() const noexcept { return _archInfo; }
- //! Returns the CPU architecture id, see `ArchInfo::Id`.
- inline uint32_t archId() const noexcept { return _archInfo.archId(); }
- //! Returns the CPU architecture sub-id, see `ArchInfo::SubId`.
- inline uint32_t archSubId() const noexcept { return _archInfo.archSubId(); }
+ //! Returns the CPU architecture id, see \ref Environment::Arch.
+ inline uint32_t arch() const noexcept { return _arch; }
+ //! Returns the CPU architecture sub-id, see \ref Environment::SubArch.
+ inline uint32_t subArch() const noexcept { return _subArch; }
//! Returns the CPU family ID.
inline uint32_t familyId() const noexcept { return _familyId; }
diff --git a/3rdparty/asmjit/src/asmjit/core/datatypes.h b/3rdparty/asmjit/src/asmjit/core/datatypes.h
index bee4572294c..2f6cc1e5b42 100644
--- a/3rdparty/asmjit/src/asmjit/core/datatypes.h
+++ b/3rdparty/asmjit/src/asmjit/core/datatypes.h
@@ -26,17 +26,16 @@
#include "../core/globals.h"
-ASMJIT_BEGIN_NAMESPACE
+#ifndef ASMJIT_NO_DEPRECATED
-//! \addtogroup asmjit_support
-//! \{
+ASMJIT_BEGIN_NAMESPACE
// ============================================================================
// [asmjit::Data64]
// ============================================================================
//! 64-bit data useful for creating SIMD constants.
-union Data64 {
+union ASMJIT_DEPRECATED_STRUCT("Data64 is deprecated and will be removed in the future") Data64 {
//! Array of eight 8-bit signed integers.
int8_t sb[8];
//! Array of eight 8-bit unsigned integers.
@@ -303,7 +302,7 @@ union Data64 {
// ============================================================================
//! 128-bit data useful for creating SIMD constants.
-union Data128 {
+union ASMJIT_DEPRECATED_STRUCT("Data128 is deprecated and will be removed in the future") Data128 {
//! Array of sixteen 8-bit signed integers.
int8_t sb[16];
//! Array of sixteen 8-bit unsigned integers.
@@ -648,7 +647,7 @@ union Data128 {
// ============================================================================
//! 256-bit data useful for creating SIMD constants.
-union Data256 {
+union ASMJIT_DEPRECATED_STRUCT("Data256 is deprecated and will be removed in the future") Data256 {
//! Array of thirty two 8-bit signed integers.
int8_t sb[32];
//! Array of thirty two 8-bit unsigned integers.
@@ -1066,8 +1065,7 @@ union Data256 {
//! \}
};
-//! \}
-
ASMJIT_END_NAMESPACE
+#endif // !ASMJIT_NO_DEPRECATED
#endif // ASMJIT_CORE_DATATYPES_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/emitter.cpp b/3rdparty/asmjit/src/asmjit/core/emitter.cpp
index ebf8c179008..b6ecc3d3cca 100644
--- a/3rdparty/asmjit/src/asmjit/core/emitter.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/emitter.cpp
@@ -22,7 +22,9 @@
// 3. This notice may not be removed or altered from any source distribution.
#include "../core/api-build_p.h"
-#include "../core/logging.h"
+#include "../core/emitterutils_p.h"
+#include "../core/errorhandler.h"
+#include "../core/logger.h"
#include "../core/support.h"
#ifdef ASMJIT_BUILD_X86
@@ -41,94 +43,212 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::BaseEmitter - Construction / Destruction]
// ============================================================================
-BaseEmitter::BaseEmitter(uint32_t type) noexcept
- : _type(uint8_t(type)),
- _reserved(0),
- _flags(0),
- _emitterOptions(0),
+BaseEmitter::BaseEmitter(uint32_t emitterType) noexcept
+ : _emitterType(uint8_t(emitterType)),
+ _emitterFlags(0),
+ _validationFlags(0),
+ _validationOptions(0),
+ _encodingOptions(0),
+ _forcedInstOptions(BaseInst::kOptionReserved),
+ _privateData(0),
_code(nullptr),
+ _logger(nullptr),
_errorHandler(nullptr),
- _codeInfo(),
+ _environment(),
_gpRegInfo(),
- _privateData(0),
_instOptions(0),
- _globalInstOptions(BaseInst::kOptionReserved),
_extraReg(),
_inlineComment(nullptr) {}
BaseEmitter::~BaseEmitter() noexcept {
if (_code) {
- _addFlags(kFlagDestroyed);
+ _addEmitterFlags(kFlagDestroyed);
_code->detach(this);
}
}
// ============================================================================
-// [asmjit::BaseEmitter - Code-Generation]
+// [asmjit::BaseEmitter - Finalize]
// ============================================================================
-Error BaseEmitter::_emitOpArray(uint32_t instId, const Operand_* operands, size_t count) {
- const Operand_* op = operands;
- const Operand& none_ = Globals::none;
-
- switch (count) {
- case 0: return _emit(instId, none_, none_, none_, none_);
- case 1: return _emit(instId, op[0], none_, none_, none_);
- case 2: return _emit(instId, op[0], op[1], none_, none_);
- case 3: return _emit(instId, op[0], op[1], op[2], none_);
- case 4: return _emit(instId, op[0], op[1], op[2], op[3]);
- case 5: return _emit(instId, op[0], op[1], op[2], op[3], op[4], none_);
- case 6: return _emit(instId, op[0], op[1], op[2], op[3], op[4], op[5]);
- default: return DebugUtils::errored(kErrorInvalidArgument);
- }
+Error BaseEmitter::finalize() {
+ // Does nothing by default, overridden by `BaseBuilder` and `BaseCompiler`.
+ return kErrorOk;
}
// ============================================================================
-// [asmjit::BaseEmitter - Finalize]
+// [asmjit::BaseEmitter - Internals]
// ============================================================================
-Label BaseEmitter::labelByName(const char* name, size_t nameSize, uint32_t parentId) noexcept {
- return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : uint32_t(Globals::kInvalidId));
+static constexpr uint32_t kEmitterPreservedFlags =
+ BaseEmitter::kFlagOwnLogger |
+ BaseEmitter::kFlagOwnErrorHandler ;
+
+static ASMJIT_NOINLINE void BaseEmitter_updateForcedOptions(BaseEmitter* self) noexcept {
+ bool hasLogger = self->_logger != nullptr;
+ bool hasValidationOptions;
+
+ if (self->emitterType() == BaseEmitter::kTypeAssembler)
+ hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionAssembler);
+ else
+ hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionIntermediate);
+
+ self->_forcedInstOptions &= ~BaseInst::kOptionReserved;
+ if (hasLogger || hasValidationOptions)
+ self->_forcedInstOptions |= BaseInst::kOptionReserved;
}
// ============================================================================
-// [asmjit::BaseEmitter - Finalize]
+// [asmjit::BaseEmitter - Validation Options]
// ============================================================================
-Error BaseEmitter::finalize() {
- // Does nothing by default, overridden by `BaseBuilder` and `BaseCompiler`.
- return kErrorOk;
+void BaseEmitter::addValidationOptions(uint32_t options) noexcept {
+ _validationOptions = uint8_t(_validationOptions | options);
+ BaseEmitter_updateForcedOptions(this);
+}
+
+void BaseEmitter::clearValidationOptions(uint32_t options) noexcept {
+ _validationOptions = uint8_t(_validationOptions | options);
+ BaseEmitter_updateForcedOptions(this);
+}
+
+// ============================================================================
+// [asmjit::BaseEmitter - Logging]
+// ============================================================================
+
+void BaseEmitter::setLogger(Logger* logger) noexcept {
+#ifndef ASMJIT_NO_LOGGING
+ if (logger) {
+ _logger = logger;
+ _addEmitterFlags(kFlagOwnLogger);
+ }
+ else {
+ _logger = nullptr;
+ _clearEmitterFlags(kFlagOwnLogger);
+ if (_code)
+ _logger = _code->logger();
+ }
+ BaseEmitter_updateForcedOptions(this);
+#else
+ DebugUtils::unused(logger);
+#endif
}
// ============================================================================
// [asmjit::BaseEmitter - Error Handling]
// ============================================================================
-Error BaseEmitter::reportError(Error err, const char* message) {
- ErrorHandler* handler = errorHandler();
- if (!handler) {
- if (code())
- handler = code()->errorHandler();
+void BaseEmitter::setErrorHandler(ErrorHandler* errorHandler) noexcept {
+ if (errorHandler) {
+ _errorHandler = errorHandler;
+ _addEmitterFlags(kFlagOwnErrorHandler);
}
+ else {
+ _errorHandler = nullptr;
+ _clearEmitterFlags(kFlagOwnErrorHandler);
+ if (_code)
+ _errorHandler = _code->errorHandler();
+ }
+}
- if (handler) {
+Error BaseEmitter::reportError(Error err, const char* message) {
+ ErrorHandler* eh = _errorHandler;
+ if (eh) {
if (!message)
message = DebugUtils::errorAsString(err);
- handler->handleError(err, message, this);
+ eh->handleError(err, message, this);
}
-
return err;
}
// ============================================================================
-// [asmjit::BaseEmitter - Label Management]
+// [asmjit::BaseEmitter - Labels]
// ============================================================================
+Label BaseEmitter::labelByName(const char* name, size_t nameSize, uint32_t parentId) noexcept {
+ return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : uint32_t(Globals::kInvalidId));
+}
+
bool BaseEmitter::isLabelValid(uint32_t labelId) const noexcept {
return _code && labelId < _code->labelCount();
}
// ============================================================================
+// [asmjit::BaseEmitter - Emit (Low-Level)]
+// ============================================================================
+
+using EmitterUtils::noExt;
+
+Error BaseEmitter::_emitI(uint32_t instId) {
+ return _emit(instId, noExt[0], noExt[1], noExt[2], noExt);
+}
+
+Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0) {
+ return _emit(instId, o0, noExt[1], noExt[2], noExt);
+}
+
+Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1) {
+ return _emit(instId, o0, o1, noExt[2], noExt);
+}
+
+Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2) {
+ return _emit(instId, o0, o1, o2, noExt);
+}
+
+Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+ Operand_ opExt[3] = { o3 };
+ return _emit(instId, o0, o1, o2, opExt);
+}
+
+Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4) {
+ Operand_ opExt[3] = { o3, o4 };
+ return _emit(instId, o0, o1, o2, opExt);
+}
+
+Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
+ Operand_ opExt[3] = { o3, o4, o5 };
+ return _emit(instId, o0, o1, o2, opExt);
+}
+
+Error BaseEmitter::_emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount) {
+ const Operand_* op = operands;
+
+ Operand_ opExt[3];
+
+ switch (opCount) {
+ case 0:
+ return _emit(instId, noExt[0], noExt[1], noExt[2], noExt);
+
+ case 1:
+ return _emit(instId, op[0], noExt[1], noExt[2], noExt);
+
+ case 2:
+ return _emit(instId, op[0], op[1], noExt[2], noExt);
+
+ case 3:
+ return _emit(instId, op[0], op[1], op[2], noExt);
+
+ case 4:
+ opExt[0] = op[3];
+ opExt[1].reset();
+ opExt[2].reset();
+ return _emit(instId, op[0], op[1], op[2], opExt);
+
+ case 5:
+ opExt[0] = op[3];
+ opExt[1] = op[4];
+ opExt[2].reset();
+ return _emit(instId, op[0], op[1], op[2], opExt);
+
+ case 6:
+ return _emit(instId, op[0], op[1], op[2], op + 3);
+
+ default:
+ return DebugUtils::errored(kErrorInvalidArgument);
+ }
+}
+
+// ============================================================================
// [asmjit::BaseEmitter - Emit (High-Level)]
// ============================================================================
@@ -137,12 +257,12 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitProlog(const FuncFrame& frame) {
return DebugUtils::errored(kErrorNotInitialized);
#ifdef ASMJIT_BUILD_X86
- if (archInfo().isX86Family())
+ if (environment().isFamilyX86())
return x86::X86Internal::emitProlog(as<x86::Emitter>(), frame);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (archInfo().isArmFamily())
+ if (environment().isFamilyARM())
return arm::ArmInternal::emitProlog(as<arm::Emitter>(), frame);
#endif
@@ -154,12 +274,12 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitEpilog(const FuncFrame& frame) {
return DebugUtils::errored(kErrorNotInitialized);
#ifdef ASMJIT_BUILD_X86
- if (archInfo().isX86Family())
+ if (environment().isFamilyX86())
return x86::X86Internal::emitEpilog(as<x86::Emitter>(), frame);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (archInfo().isArmFamily())
+ if (environment().isFamilyARM())
return arm::ArmInternal::emitEpilog(as<arm::Emitter>(), frame);
#endif
@@ -171,12 +291,12 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame,
return DebugUtils::errored(kErrorNotInitialized);
#ifdef ASMJIT_BUILD_X86
- if (archInfo().isX86Family())
+ if (environment().isFamilyX86())
return x86::X86Internal::emitArgsAssignment(as<x86::Emitter>(), frame, args);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (archInfo().isArmFamily())
+ if (environment().isFamilyARM())
return arm::ArmInternal::emitArgsAssignment(as<arm::Emitter>(), frame, args);
#endif
@@ -192,17 +312,11 @@ Error BaseEmitter::commentf(const char* fmt, ...) {
return DebugUtils::errored(kErrorNotInitialized);
#ifndef ASMJIT_NO_LOGGING
- StringTmp<1024> sb;
-
va_list ap;
va_start(ap, fmt);
- Error err = sb.appendVFormat(fmt, ap);
+ Error err = commentv(fmt, ap);
va_end(ap);
-
- if (ASMJIT_UNLIKELY(err))
- return err;
-
- return comment(sb.data(), sb.size());
+ return err;
#else
DebugUtils::unused(fmt);
return kErrorOk;
@@ -215,8 +329,8 @@ Error BaseEmitter::commentv(const char* fmt, va_list ap) {
#ifndef ASMJIT_NO_LOGGING
StringTmp<1024> sb;
-
Error err = sb.appendVFormat(fmt, ap);
+
if (ASMJIT_UNLIKELY(err))
return err;
@@ -233,40 +347,46 @@ Error BaseEmitter::commentv(const char* fmt, va_list ap) {
Error BaseEmitter::onAttach(CodeHolder* code) noexcept {
_code = code;
- _codeInfo = code->codeInfo();
- _emitterOptions = code->emitterOptions();
+ _environment = code->environment();
- onUpdateGlobalInstOptions();
+ onSettingsUpdated();
return kErrorOk;
}
Error BaseEmitter::onDetach(CodeHolder* code) noexcept {
DebugUtils::unused(code);
- _flags = 0;
- _emitterOptions = 0;
- _errorHandler = nullptr;
+ _clearEmitterFlags(~kEmitterPreservedFlags);
+ _forcedInstOptions = BaseInst::kOptionReserved;
+ _privateData = 0;
+
+ if (!hasOwnLogger())
+ _logger = nullptr;
+
+ if (!hasOwnErrorHandler())
+ _errorHandler = nullptr;
- _codeInfo.reset();
+ _environment.reset();
_gpRegInfo.reset();
- _privateData = 0;
_instOptions = 0;
- _globalInstOptions = BaseInst::kOptionReserved;
_extraReg.reset();
_inlineComment = nullptr;
return kErrorOk;
}
-void BaseEmitter::onUpdateGlobalInstOptions() noexcept {
- constexpr uint32_t kCriticalEmitterOptions =
- kOptionLoggingEnabled |
- kOptionStrictValidation ;
+void BaseEmitter::onSettingsUpdated() noexcept {
+ // Only called when attached to CodeHolder by CodeHolder.
+ ASMJIT_ASSERT(_code != nullptr);
+
+ if (!hasOwnLogger())
+ _logger = _code->logger();
+
+ if (!hasOwnErrorHandler())
+ _errorHandler = _code->errorHandler();
- _globalInstOptions &= ~BaseInst::kOptionReserved;
- if ((_emitterOptions & kCriticalEmitterOptions) != 0)
- _globalInstOptions |= BaseInst::kOptionReserved;
+ BaseEmitter_updateForcedOptions(this);
}
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/emitter.h b/3rdparty/asmjit/src/asmjit/core/emitter.h
index 585558457bd..cfdb6951488 100644
--- a/3rdparty/asmjit/src/asmjit/core/emitter.h
+++ b/3rdparty/asmjit/src/asmjit/core/emitter.h
@@ -25,9 +25,10 @@
#define ASMJIT_CORE_EMITTER_H_INCLUDED
#include "../core/arch.h"
+#include "../core/codeholder.h"
#include "../core/inst.h"
#include "../core/operand.h"
-#include "../core/codeholder.h"
+#include "../core/type.h"
ASMJIT_BEGIN_NAMESPACE
@@ -52,31 +53,40 @@ class ASMJIT_VIRTAPI BaseEmitter {
public:
ASMJIT_BASE_CLASS(BaseEmitter)
- //! See `EmitterType`.
- uint8_t _type;
- //! Reserved for future use.
- uint8_t _reserved;
- //! See \ref BaseEmitter::Flags.
- uint16_t _flags;
- //! Emitter options, always in sync with CodeHolder.
- uint32_t _emitterOptions;
+ //! See \ref EmitterType.
+ uint8_t _emitterType;
+ //! See \ref BaseEmitter::EmitterFlags.
+ uint8_t _emitterFlags;
+ //! Validation flags in case validation is used, see \ref InstAPI::ValidationFlags.
+ //!
+ //! \note Validation flags are specific to the emitter and they are setup at
+ //! construction time and then never changed.
+ uint8_t _validationFlags;
+ //! Validation options, see \ref ValidationOptions.
+ uint8_t _validationOptions;
+
+ //! Encoding options, see \ref EncodingOptions.
+ uint32_t _encodingOptions;
- //! CodeHolder the BaseEmitter is attached to.
+ //! Forced instruction options, combined with \ref _instOptions by \ref emit().
+ uint32_t _forcedInstOptions;
+ //! Internal private data used freely by any emitter.
+ uint32_t _privateData;
+
+ //! CodeHolder the emitter is attached to.
CodeHolder* _code;
- //! Attached `ErrorHandler`.
+ //! Attached \ref Logger.
+ Logger* _logger;
+ //! Attached \ref ErrorHandler.
ErrorHandler* _errorHandler;
- //! Basic information about the code (matches CodeHolder::_codeInfo).
- CodeInfo _codeInfo;
+ //! Describes the target environment, matches \ref CodeHolder::environment().
+ Environment _environment;
//! Native GP register signature and signature related information.
RegInfo _gpRegInfo;
- //! Internal private data used freely by any emitter.
- uint32_t _privateData;
//! Next instruction options (affects the next instruction).
uint32_t _instOptions;
- //! Global Instruction options (combined with `_instOptions` by `emit...()`).
- uint32_t _globalInstOptions;
//! Extra register (op-mask {k} on AVX-512) (affects the next instruction).
RegOnly _extraReg;
//! Inline comment of the next instruction (affects the next instruction).
@@ -86,41 +96,34 @@ public:
enum EmitterType : uint32_t {
//! Unknown or uninitialized.
kTypeNone = 0,
- //! Emitter inherits from `BaseAssembler`.
+ //! Emitter inherits from \ref BaseAssembler.
kTypeAssembler = 1,
- //! Emitter inherits from `BaseBuilder`.
+ //! Emitter inherits from \ref BaseBuilder.
kTypeBuilder = 2,
- //! Emitter inherits from `BaseCompiler`.
+ //! Emitter inherits from \ref BaseCompiler.
kTypeCompiler = 3,
+
//! Count of emitter types.
kTypeCount = 4
};
//! Emitter flags.
- enum Flags : uint32_t {
+ enum EmitterFlags : uint32_t {
+ //! The emitter has its own \ref Logger (not propagated from \ref CodeHolder).
+ kFlagOwnLogger = 0x10u,
+ //! The emitter has its own \ref ErrorHandler (not propagated from \ref CodeHolder).
+ kFlagOwnErrorHandler = 0x20u,
//! The emitter was finalized.
- kFlagFinalized = 0x4000u,
+ kFlagFinalized = 0x40u,
//! The emitter was destroyed.
- kFlagDestroyed = 0x8000u
+ kFlagDestroyed = 0x80u
};
- //! Emitter options.
- enum Options : uint32_t {
- //! Logging is enabled, `BaseEmitter::logger()` must return a valid logger.
- //! This option is set automatically by the emitter if the logger is present.
- //! User code should never alter this value.
- //!
- //! Default `false`.
- kOptionLoggingEnabled = 0x00000001u,
-
- //! Stricly validate each instruction before it's emitted.
- //!
- //! Default `false`.
- kOptionStrictValidation = 0x00000002u,
-
+ //! Encoding options.
+ enum EncodingOptions : uint32_t {
//! Emit instructions that are optimized for size, if possible.
//!
- //! Default `false`.
+ //! Default: false.
//!
//! X86 Specific
//! ------------
@@ -130,11 +133,11 @@ public:
//! by taking advantage of implicit zero extension. For example instruction
//! like `mov r64, imm` and `and r64, imm` can be translated to `mov r32, imm`
//! and `and r32, imm` when the immediate constant is lesser than `2^31`.
- kOptionOptimizedForSize = 0x00000004u,
+ kEncodingOptionOptimizeForSize = 0x00000001u,
//! Emit optimized code-alignment sequences.
//!
- //! Default `false`.
+ //! Default: false.
//!
//! X86 Specific
//! ------------
@@ -144,11 +147,11 @@ public:
//! more optimized align sequences for 2-11 bytes that may execute faster
//! on certain CPUs. If this feature is enabled AsmJit will generate
//! specialized sequences for alignment between 2 to 11 bytes.
- kOptionOptimizedAlign = 0x00000008u,
+ kEncodingOptionOptimizedAlign = 0x00000002u,
//! Emit jump-prediction hints.
//!
- //! Default `false`.
+ //! Default: false.
//!
//! X86 Specific
//! ------------
@@ -163,14 +166,56 @@ public:
//! This feature is disabled by default, because the only processor that
//! used to take into consideration prediction hints was P4. Newer processors
//! implement heuristics for branch prediction and ignore static hints. This
- //! means that this feature can be used for annotation purposes.
- kOptionPredictedJumps = 0x00000010u
+ //! means that this feature can be only used for annotation purposes.
+ kEncodingOptionPredictedJumps = 0x00000010u
+ };
+
+#ifndef ASMJIT_NO_DEPRECATED
+ enum EmitterOptions : uint32_t {
+ kOptionOptimizedForSize = kEncodingOptionOptimizeForSize,
+ kOptionOptimizedAlign = kEncodingOptionOptimizedAlign,
+ kOptionPredictedJumps = kEncodingOptionPredictedJumps
+ };
+#endif
+
+ //! Validation options are used to tell emitters to perform strict validation
+ //! of instructions passed to \ref emit().
+ //!
+ //! \ref BaseAssembler implementation perform by default only basic checks
+ //! that are necessary to identify all variations of an instruction so the
+ //! correct encoding can be selected. This is fine for production-ready code
+ //! as the assembler doesn't have to perform checks that would slow it down.
+ //! However, sometimes these checks are beneficial especially when the project
+ //! that uses AsmJit is in a development phase, in which mistakes happen often.
+ //! To make the experience of using AsmJit seamless it offers validation
+ //! features that can be controlled by `ValidationOptions`.
+ enum ValidationOptions : uint32_t {
+ //! Perform strict validation in \ref BaseAssembler::emit() implementations.
+ //!
+ //! This flag ensures that each instruction is checked before it's encoded
+ //! into a binary representation. This flag is only relevant for \ref
+ //! BaseAssembler implementations, but can be set in any other emitter type,
+ //! in that case if that emitter needs to create an assembler on its own,
+ //! for the purpose of \ref finalize() it would propagate this flag to such
+ //! assembler so all instructions passed to it are explicitly validated.
+ //!
+ //! Default: false.
+ kValidationOptionAssembler = 0x00000001u,
+
+ //! Perform strict validation in \ref BaseBuilder::emit() and \ref
+ //! BaseCompiler::emit() implementations.
+ //!
+ //! This flag ensures that each instruction is checked before an \ref
+ //! InstNode representing the instruction is created by Builder or Compiler.
+ //!
+ //! Default: false.
+ kValidationOptionIntermediate = 0x00000002u
};
//! \name Construction & Destruction
//! \{
- ASMJIT_API explicit BaseEmitter(uint32_t type) noexcept;
+ ASMJIT_API explicit BaseEmitter(uint32_t emitterType) noexcept;
ASMJIT_API virtual ~BaseEmitter() noexcept;
//! \}
@@ -190,28 +235,28 @@ public:
//! \{
//! Returns the type of this emitter, see `EmitterType`.
- inline uint32_t emitterType() const noexcept { return _type; }
+ inline uint32_t emitterType() const noexcept { return _emitterType; }
//! Returns emitter flags , see `Flags`.
- inline uint32_t emitterFlags() const noexcept { return _flags; }
+ inline uint32_t emitterFlags() const noexcept { return _emitterFlags; }
//! Tests whether the emitter inherits from `BaseAssembler`.
- inline bool isAssembler() const noexcept { return _type == kTypeAssembler; }
+ inline bool isAssembler() const noexcept { return _emitterType == kTypeAssembler; }
//! Tests whether the emitter inherits from `BaseBuilder`.
//!
//! \note Both Builder and Compiler emitters would return `true`.
- inline bool isBuilder() const noexcept { return _type >= kTypeBuilder; }
+ inline bool isBuilder() const noexcept { return _emitterType >= kTypeBuilder; }
//! Tests whether the emitter inherits from `BaseCompiler`.
- inline bool isCompiler() const noexcept { return _type == kTypeCompiler; }
+ inline bool isCompiler() const noexcept { return _emitterType == kTypeCompiler; }
//! Tests whether the emitter has the given `flag` enabled.
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ inline bool hasEmitterFlag(uint32_t flag) const noexcept { return (_emitterFlags & flag) != 0; }
//! Tests whether the emitter is finalized.
- inline bool isFinalized() const noexcept { return hasFlag(kFlagFinalized); }
+ inline bool isFinalized() const noexcept { return hasEmitterFlag(kFlagFinalized); }
//! Tests whether the emitter is destroyed (only used during destruction).
- inline bool isDestroyed() const noexcept { return hasFlag(kFlagDestroyed); }
+ inline bool isDestroyed() const noexcept { return hasEmitterFlag(kFlagDestroyed); }
- inline void _addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); }
- inline void _clearFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags & ~flags); }
+ inline void _addEmitterFlags(uint32_t flags) noexcept { _emitterFlags = uint8_t(_emitterFlags | flags); }
+ inline void _clearEmitterFlags(uint32_t flags) noexcept { _emitterFlags = uint8_t(_emitterFlags & ~flags); }
//! \}
@@ -220,90 +265,187 @@ public:
//! Returns the CodeHolder this emitter is attached to.
inline CodeHolder* code() const noexcept { return _code; }
- //! Returns an information about the code, see `CodeInfo`.
- inline const CodeInfo& codeInfo() const noexcept { return _codeInfo; }
- //! Returns an information about the architecture, see `ArchInfo`.
- inline const ArchInfo& archInfo() const noexcept { return _codeInfo.archInfo(); }
+
+ //! Returns the target environment, see \ref Environment.
+ //!
+ //! The returned \ref Environment reference matches \ref CodeHolder::environment().
+ inline const Environment& environment() const noexcept { return _environment; }
//! Tests whether the target architecture is 32-bit.
- inline bool is32Bit() const noexcept { return archInfo().is32Bit(); }
+ inline bool is32Bit() const noexcept { return environment().is32Bit(); }
//! Tests whether the target architecture is 64-bit.
- inline bool is64Bit() const noexcept { return archInfo().is64Bit(); }
+ inline bool is64Bit() const noexcept { return environment().is64Bit(); }
//! Returns the target architecture type.
- inline uint32_t archId() const noexcept { return archInfo().archId(); }
+ inline uint32_t arch() const noexcept { return environment().arch(); }
//! Returns the target architecture sub-type.
- inline uint32_t archSubId() const noexcept { return archInfo().archSubId(); }
+ inline uint32_t subArch() const noexcept { return environment().subArch(); }
+
//! Returns the target architecture's GP register size (4 or 8 bytes).
- inline uint32_t gpSize() const noexcept { return archInfo().gpSize(); }
- //! Returns the number of target GP registers.
- inline uint32_t gpCount() const noexcept { return archInfo().gpCount(); }
+ inline uint32_t registerSize() const noexcept { return environment().registerSize(); }
//! \}
//! \name Initialization & Finalization
//! \{
- //! Tests whether the BaseEmitter is initialized (i.e. attached to the `CodeHolder`).
+ //! Tests whether the emitter is initialized (i.e. attached to \ref CodeHolder).
inline bool isInitialized() const noexcept { return _code != nullptr; }
+ //! Finalizes this emitter.
+ //!
+ //! Materializes the content of the emitter by serializing it to the attached
+ //! \ref CodeHolder through an architecture specific \ref BaseAssembler. This
+ //! function won't do anything if the emitter inherits from \ref BaseAssembler
+ //! as assemblers emit directly to a \ref CodeBuffer held by \ref CodeHolder.
+ //! However, if this is an emitter that inherits from \ref BaseBuilder or \ref
+ //! BaseCompiler then these emitters need the materialization phase as they
+ //! store their content in a representation not visible to \ref CodeHolder.
ASMJIT_API virtual Error finalize();
//! \}
- //! \name Emitter Options
+ //! \name Logging
//! \{
- //! Tests whether the `option` is present in emitter options.
- inline bool hasEmitterOption(uint32_t option) const noexcept { return (_emitterOptions & option) != 0; }
- //! Returns the emitter options.
- inline uint32_t emitterOptions() const noexcept { return _emitterOptions; }
+ //! Tests whether the emitter has a logger.
+ inline bool hasLogger() const noexcept { return _logger != nullptr; }
- // TODO: Deprecate and remove, CodeHolder::addEmitterOptions() is the way.
- inline void addEmitterOptions(uint32_t options) noexcept {
- _emitterOptions |= options;
- onUpdateGlobalInstOptions();
- }
+ //! Tests whether the emitter has its own logger.
+ //!
+ //! Own logger means that it overrides the possible logger that may be used
+ //! by \ref CodeHolder this emitter is attached to.
+ inline bool hasOwnLogger() const noexcept { return hasEmitterFlag(kFlagOwnLogger); }
- inline void clearEmitterOptions(uint32_t options) noexcept {
- _emitterOptions &= ~options;
- onUpdateGlobalInstOptions();
- }
+ //! Returns the logger this emitter uses.
+ //!
+ //! The returned logger is either the emitter's own logger or it's logger
+ //! used by \ref CodeHolder this emitter is attached to.
+ inline Logger* logger() const noexcept { return _logger; }
+
+ //! Sets or resets the logger of the emitter.
+ //!
+ //! If the `logger` argument is non-null then the logger will be considered
+ //! emitter's own logger, see \ref hasOwnLogger() for more details. If the
+ //! given `logger` is null then the emitter will automatically use logger
+ //! that is attached to the \ref CodeHolder this emitter is attached to.
+ ASMJIT_API void setLogger(Logger* logger) noexcept;
- //! Returns the global instruction options.
+ //! Resets the logger of this emitter.
//!
- //! Default instruction options are merged with instruction options before the
- //! instruction is encoded. These options have some bits reserved that are used
- //! for error handling, logging, and strict validation. Other options are globals that
- //! affect each instruction, for example if VEX3 is set globally, it will all
- //! instructions, even those that don't have such option set.
- inline uint32_t globalInstOptions() const noexcept { return _globalInstOptions; }
+ //! The emitter will bail to using a logger attached to \ref CodeHolder this
+ //! emitter is attached to, or no logger at all if \ref CodeHolder doesn't
+ //! have one.
+ inline void resetLogger() noexcept { return setLogger(nullptr); }
//! \}
//! \name Error Handling
//! \{
- //! Tests whether the local error handler is attached.
+ //! Tests whether the emitter has an error handler attached.
inline bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; }
- //! Returns the local error handler.
+
+ //! Tests whether the emitter has its own error handler.
+ //!
+ //! Own error handler means that it overrides the possible error handler that
+ //! may be used by \ref CodeHolder this emitter is attached to.
+ inline bool hasOwnErrorHandler() const noexcept { return hasEmitterFlag(kFlagOwnErrorHandler); }
+
+ //! Returns the error handler this emitter uses.
+ //!
+ //! The returned error handler is either the emitter's own error handler or
+ //! it's error handler used by \ref CodeHolder this emitter is attached to.
inline ErrorHandler* errorHandler() const noexcept { return _errorHandler; }
- //! Sets the local error handler.
- inline void setErrorHandler(ErrorHandler* handler) noexcept { _errorHandler = handler; }
- //! Resets the local error handler (does nothing if not attached).
+
+ //! Sets or resets the error handler of the emitter.
+ ASMJIT_API void setErrorHandler(ErrorHandler* errorHandler) noexcept;
+
+ //! Resets the error handler.
inline void resetErrorHandler() noexcept { setErrorHandler(nullptr); }
//! Handles the given error in the following way:
- //! 1. Gets either Emitter's (preferred) or CodeHolder's ErrorHandler.
- //! 2. If exists, calls `ErrorHandler::handleError(error, message, this)`.
- //! 3. Returns the given `err` if ErrorHandler haven't thrown.
+ //! 1. If the emitter has \ref ErrorHandler attached, it calls its
+ //! \ref ErrorHandler::handleError() member function first, and
+ //! then returns the error. The `handleError()` function may throw.
+ //! 2. if the emitter doesn't have \ref ErrorHandler, the error is
+ //! simply returned.
ASMJIT_API Error reportError(Error err, const char* message = nullptr);
//! \}
+ //! \name Encoding Options
+ //! \{
+
+ //! Returns encoding options, see \ref EncodingOptions.
+ inline uint32_t encodingOptions() const noexcept { return _encodingOptions; }
+ //! Tests whether the encoding `option` is set.
+ inline bool hasEncodingOption(uint32_t option) const noexcept { return (_encodingOptions & option) != 0; }
+
+ //! Enables the given encoding `options`, see \ref EncodingOptions.
+ inline void addEncodingOptions(uint32_t options) noexcept { _encodingOptions |= options; }
+ //! Disables the given encoding `options`, see \ref EncodingOptions.
+ inline void clearEncodingOptions(uint32_t options) noexcept { _encodingOptions &= ~options; }
+
+ //! \}
+
+ //! \name Validation Options
+ //! \{
+
+ //! Returns the emitter's validation options, see \ref ValidationOptions.
+ inline uint32_t validationOptions() const noexcept {
+ return _validationOptions;
+ }
+
+ //! Tests whether the given `option` is present in validation options.
+ inline bool hasValidationOption(uint32_t option) const noexcept {
+ return (_validationOptions & option) != 0;
+ }
+
+ //! Activates the given validation `options`, see \ref ValidationOptions.
+ //!
+ //! This function is used to activate explicit validation options that will
+ //! be then used by all emitter implementations. There are in general two
+ //! possibilities:
+ //!
+ //! - Architecture specific assembler is used. In this case a
+ //! \ref kValidationOptionAssembler can be used to turn on explicit
+ //! validation that will be used before an instruction is emitted.
+ //! This means that internally an extra step will be performed to
+ //! make sure that the instruction is correct. This is needed, because
+ //! by default assemblers prefer speed over strictness.
+ //!
+ //! This option should be used in debug builds as it's pretty expensive.
+ //!
+ //! - Architecture specific builder or compiler is used. In this case
+ //! the user can turn on \ref kValidationOptionIntermediate option
+ //! that adds explicit validation step before the Builder or Compiler
+ //! creates an \ref InstNode to represent an emitted instruction. Error
+ //! will be returned if the instruction is ill-formed. In addition,
+ //! also \ref kValidationOptionAssembler can be used, which would not be
+ //! consumed by Builder / Compiler directly, but it would be propagated
+ //! to an architecture specific \ref BaseAssembler implementation it
+ //! creates during \ref BaseEmitter::finalize().
+ ASMJIT_API void addValidationOptions(uint32_t options) noexcept;
+
+ //! Deactivates the given validation `options`.
+ //!
+ //! See \ref addValidationOptions() and \ref ValidationOptions for more details.
+ ASMJIT_API void clearValidationOptions(uint32_t options) noexcept;
+
+ //! \}
+
//! \name Instruction Options
//! \{
+ //! Returns forced instruction options.
+ //!
+ //! Forced instruction options are merged with next instruction options before
+ //! the instruction is encoded. These options have some bits reserved that are
+ //! used by error handling, logging, and instruction validation purposes. Other
+ //! options are globals that affect each instruction.
+ inline uint32_t forcedInstOptions() const noexcept { return _forcedInstOptions; }
+
//! Returns options of the next instruction.
inline uint32_t instOptions() const noexcept { return _instOptions; }
//! Returns options of the next instruction.
@@ -377,100 +519,49 @@ public:
// NOTE: These `emit()` helpers are designed to address a code-bloat generated
// by C++ compilers to call a function having many arguments. Each parameter to
- // `_emit()` requires some code to pass it, which means that if we default to 4
- // operand parameters in `_emit()` and instId the C++ compiler would have to
- // generate a virtual function call having 5 parameters, which is quite a lot.
- // Since by default asm instructions have 2 to 3 operands it's better to
- // introduce helpers that pass those and fill out the remaining operands.
-
- #define OP const Operand_&
- #define NONE Globals::none
-
- //! Emits an instruction.
- ASMJIT_NOINLINE Error emit(uint32_t instId) { return _emit(instId, NONE, NONE, NONE, NONE); }
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0) { return _emit(instId, o0, NONE, NONE, NONE); }
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1) { return _emit(instId, o0, o1, NONE, NONE); }
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, OP o2) { return _emit(instId, o0, o1, o2, NONE); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3) { return _emit(instId, o0, o1, o2, o3); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4) { return _emit(instId, o0, o1, o2, o3, o4, NONE); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, OP o5) { return _emit(instId, o0, o1, o2, o3, o4, o5); }
-
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, int o0) { return _emit(instId, Imm(o0), NONE, NONE, NONE); }
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, int o1) { return _emit(instId, o0, Imm(o1), NONE, NONE); }
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, int o2) { return _emit(instId, o0, o1, Imm(o2), NONE); }
+ // `_emit()` requires some code to pass it, which means that if we default to
+ // 5 arguments in `_emit()` and instId the C++ compiler would have to generate
+ // a virtual function call having 5 parameters and additional `this` argument,
+ // which is quite a lot. Since by default most instructions have 2 to 3 operands
+ // it's better to introduce helpers that pass from 0 to 6 operands that help to
+ // reduce the size of emit(...) function call.
+
+ //! Emits an instruction (internal).
+ ASMJIT_API Error _emitI(uint32_t instId);
//! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, OP o2, int o3) { return _emit(instId, o0, o1, o2, Imm(o3)); }
+ ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0);
//! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, int o4) { return _emit(instId, o0, o1, o2, o3, Imm(o4), NONE); }
+ ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1);
//! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, int o5) { return _emit(instId, o0, o1, o2, o3, o4, Imm(o5)); }
-
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, int64_t o0) { return _emit(instId, Imm(o0), NONE, NONE, NONE); }
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, int64_t o1) { return _emit(instId, o0, Imm(o1), NONE, NONE); }
- //! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, int64_t o2) { return _emit(instId, o0, o1, Imm(o2), NONE); }
+ ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2);
//! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, OP o2, int64_t o3) { return _emit(instId, o0, o1, o2, Imm(o3)); }
+ ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
//! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, int64_t o4) { return _emit(instId, o0, o1, o2, o3, Imm(o4), NONE); }
+ ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4);
//! \overload
- ASMJIT_NOINLINE Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, int64_t o5) { return _emit(instId, o0, o1, o2, o3, o4, Imm(o5)); }
+ ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5);
- //! \overload
- inline Error emit(uint32_t instId, unsigned int o0) { return emit(instId, int64_t(o0)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, unsigned int o1) { return emit(instId, o0, int64_t(o1)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, unsigned int o2) { return emit(instId, o0, o1, int64_t(o2)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, unsigned int o3) { return emit(instId, o0, o1, o2, int64_t(o3)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, unsigned int o4) { return emit(instId, o0, o1, o2, o3, int64_t(o4)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, unsigned int o5) { return emit(instId, o0, o1, o2, o3, o4, int64_t(o5)); }
-
- //! \overload
- inline Error emit(uint32_t instId, uint64_t o0) { return emit(instId, int64_t(o0)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, uint64_t o1) { return emit(instId, o0, int64_t(o1)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, uint64_t o2) { return emit(instId, o0, o1, int64_t(o2)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, uint64_t o3) { return emit(instId, o0, o1, o2, int64_t(o3)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, uint64_t o4) { return emit(instId, o0, o1, o2, o3, int64_t(o4)); }
- //! \overload
- inline Error emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, uint64_t o5) { return emit(instId, o0, o1, o2, o3, o4, int64_t(o5)); }
-
- #undef NONE
- #undef OP
+ //! Emits an instruction `instId` with the given `operands`.
+ template<typename... Args>
+ ASMJIT_INLINE Error emit(uint32_t instId, Args&&... operands) {
+ return _emitI(instId, Support::ForwardOp<Args>::forward(operands)...);
+ }
- inline Error emitOpArray(uint32_t instId, const Operand_* operands, size_t count) { return _emitOpArray(instId, operands, count); }
+ inline Error emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount) {
+ return _emitOpArray(instId, operands, opCount);
+ }
- inline Error emitInst(const BaseInst& inst, const Operand_* operands, size_t count) {
+ inline Error emitInst(const BaseInst& inst, const Operand_* operands, size_t opCount) {
setInstOptions(inst.options());
setExtraReg(inst.extraReg());
- return _emitOpArray(inst.id(), operands, count);
+ return _emitOpArray(inst.id(), operands, opCount);
}
//! \cond INTERNAL
- //! Emits instruction having max 4 operands.
- virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) = 0;
- //! Emits instruction having max 6 operands.
- virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) = 0;
+ //! Emits an instruction - all 6 operands must be defined.
+ virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) = 0;
//! Emits instruction having operands stored in array.
- virtual Error _emitOpArray(uint32_t instId, const Operand_* operands, size_t count);
+ virtual Error _emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount);
//! \endcond
//! \}
@@ -478,19 +569,19 @@ public:
//! \name Emit Utilities
//! \{
- ASMJIT_API Error emitProlog(const FuncFrame& layout);
- ASMJIT_API Error emitEpilog(const FuncFrame& layout);
- ASMJIT_API Error emitArgsAssignment(const FuncFrame& layout, const FuncArgsAssignment& args);
+ ASMJIT_API Error emitProlog(const FuncFrame& frame);
+ ASMJIT_API Error emitEpilog(const FuncFrame& frame);
+ ASMJIT_API Error emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args);
//! \}
//! \name Align
//! \{
- //! Aligns the current CodeBuffer to the `alignment` specified.
+ //! Aligns the current CodeBuffer position to the `alignment` specified.
//!
//! The sequence that is used to fill the gap between the aligned location
- //! and the current location depends on the align `mode`, see `AlignMode`.
+ //! and the current location depends on the align `mode`, see \ref AlignMode.
virtual Error align(uint32_t alignMode, uint32_t alignment) = 0;
//! \}
@@ -498,16 +589,38 @@ public:
//! \name Embed
//! \{
- //! Embeds raw data into the CodeBuffer.
- virtual Error embed(const void* data, uint32_t dataSize) = 0;
-
- //! Embeds an absolute label address as data (4 or 8 bytes).
- virtual Error embedLabel(const Label& label) = 0;
+ //! Embeds raw data into the \ref CodeBuffer.
+ virtual Error embed(const void* data, size_t dataSize) = 0;
- //! Embeds a delta (distance) between the `label` and `base` calculating it
- //! as `label - base`. This function was designed to make it easier to embed
- //! lookup tables where each index is a relative distance of two labels.
- virtual Error embedLabelDelta(const Label& label, const Label& base, uint32_t dataSize) = 0;
+ //! Embeds a typed data array.
+ //!
+ //! This is the most flexible function for embedding data as it allows to:
+ //! - Assign a `typeId` to the data, so the emitter knows the type of
+ //! items stored in `data`. Binary data should use \ref Type::kIdU8.
+ //! - Repeat the given data `repeatCount` times, so the data can be used
+ //! as a fill pattern for example, or as a pattern used by SIMD instructions.
+ virtual Error embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) = 0;
+
+ //! Embeds int8_t `value` repeated by `repeatCount`.
+ inline Error embedInt8(int8_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI8, &value, 1, repeatCount); }
+ //! Embeds uint8_t `value` repeated by `repeatCount`.
+ inline Error embedUInt8(uint8_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU8, &value, 1, repeatCount); }
+ //! Embeds int16_t `value` repeated by `repeatCount`.
+ inline Error embedInt16(int16_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI16, &value, 1, repeatCount); }
+ //! Embeds uint16_t `value` repeated by `repeatCount`.
+ inline Error embedUInt16(uint16_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU16, &value, 1, repeatCount); }
+ //! Embeds int32_t `value` repeated by `repeatCount`.
+ inline Error embedInt32(int32_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI32, &value, 1, repeatCount); }
+ //! Embeds uint32_t `value` repeated by `repeatCount`.
+ inline Error embedUInt32(uint32_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU32, &value, 1, repeatCount); }
+ //! Embeds int64_t `value` repeated by `repeatCount`.
+ inline Error embedInt64(int64_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI64, &value, 1, repeatCount); }
+ //! Embeds uint64_t `value` repeated by `repeatCount`.
+ inline Error embedUInt64(uint64_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU64, &value, 1, repeatCount); }
+ //! Embeds a floating point `value` repeated by `repeatCount`.
+ inline Error embedFloat(float value, size_t repeatCount = 1) { return embedDataArray(Type::kIdF32, &value, 1, repeatCount); }
+ //! Embeds a floating point `value` repeated by `repeatCount`.
+ inline Error embedDouble(double value, size_t repeatCount = 1) { return embedDataArray(Type::IdOfT<double>::kTypeId, &value, 1, repeatCount); }
//! Embeds a constant pool at the current offset by performing the following:
//! 1. Aligns by using kAlignData to the minimum `pool` alignment.
@@ -515,6 +628,14 @@ public:
//! 3. Emits ConstPool content.
virtual Error embedConstPool(const Label& label, const ConstPool& pool) = 0;
+ //! Embeds an absolute label address as data (4 or 8 bytes).
+ virtual Error embedLabel(const Label& label) = 0;
+
+ //! Embeds a delta (distance) between the `label` and `base` calculating it
+ //! as `label - base`. This function was designed to make it easier to embed
+ //! lookup tables where each index is a relative distance of two labels.
+ virtual Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize) = 0;
+
//! \}
//! \name Comment
@@ -538,13 +659,48 @@ public:
//! Called after the emitter was detached from `CodeHolder`.
virtual Error onDetach(CodeHolder* code) noexcept = 0;
- //! Called to update `_globalInstOptions` based on `_emitterOptions`.
+ //! Called when \ref CodeHolder has updated an important setting, which
+ //! involves the following:
//!
- //! This function should only touch one bit `BaseInst::kOptionReserved`, which
- //! is used to handle errors and special-cases in a way that minimizes branching.
- ASMJIT_API void onUpdateGlobalInstOptions() noexcept;
+ //! - \ref Logger has been changed (\ref CodeHolder::setLogger() has been
+ //! called).
+ //! - \ref ErrorHandler has been changed (\ref CodeHolder::setErrorHandler()
+ //! has been called).
+ //!
+ //! This function ensures that the settings are properly propagated from
+ //! \ref CodeHolder to the emitter.
+ //!
+ //! \note This function is virtual and can be overridden, however, if you
+ //! do so, always call \ref BaseEmitter::onSettingsUpdated() within your
+ //! own implementation to ensure that the emitter is in a consisten state.
+ ASMJIT_API virtual void onSettingsUpdated() noexcept;
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use environment() instead")
+ inline CodeInfo codeInfo() const noexcept {
+ return CodeInfo(_environment, _code ? _code->baseAddress() : Globals::kNoBaseAddress);
+ }
+
+ ASMJIT_DEPRECATED("Use arch() instead")
+ inline uint32_t archId() const noexcept { return arch(); }
+
+ ASMJIT_DEPRECATED("Use registerSize() instead")
+ inline uint32_t gpSize() const noexcept { return registerSize(); }
+
+ ASMJIT_DEPRECATED("Use encodingOptions() instead")
+ inline uint32_t emitterOptions() const noexcept { return encodingOptions(); }
+
+ ASMJIT_DEPRECATED("Use addEncodingOptions() instead")
+ inline void addEmitterOptions(uint32_t options) noexcept { addEncodingOptions(options); }
+
+ ASMJIT_DEPRECATED("Use clearEncodingOptions() instead")
+ inline void clearEmitterOptions(uint32_t options) noexcept { clearEncodingOptions(options); }
+
+ ASMJIT_DEPRECATED("Use forcedInstOptions() instead")
+ inline uint32_t globalInstOptions() const noexcept { return forcedInstOptions(); }
+#endif // !ASMJIT_NO_DEPRECATED
};
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/emitterutils.cpp b/3rdparty/asmjit/src/asmjit/core/emitterutils.cpp
new file mode 100644
index 00000000000..1115934e21e
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/emitterutils.cpp
@@ -0,0 +1,150 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include "../core/api-build_p.h"
+#include "../core/assembler.h"
+#include "../core/emitterutils_p.h"
+#include "../core/formatter.h"
+#include "../core/logger.h"
+#include "../core/support.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+// ============================================================================
+// [asmjit::EmitterUtils]
+// ============================================================================
+
+namespace EmitterUtils {
+
+#ifndef ASMJIT_NO_LOGGING
+
+Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept {
+ size_t currentSize = sb.size();
+ size_t commentSize = comment ? Support::strLen(comment, Globals::kMaxCommentSize) : 0;
+
+ ASMJIT_ASSERT(binSize >= dispSize);
+ const size_t kNoBinSize = SIZE_MAX;
+
+ if ((binSize != 0 && binSize != kNoBinSize) || commentSize) {
+ size_t align = kMaxInstLineSize;
+ char sep = ';';
+
+ for (size_t i = (binSize == kNoBinSize); i < 2; i++) {
+ size_t begin = sb.size();
+ ASMJIT_PROPAGATE(sb.padEnd(align));
+
+ if (sep) {
+ ASMJIT_PROPAGATE(sb.append(sep));
+ ASMJIT_PROPAGATE(sb.append(' '));
+ }
+
+ // Append binary data or comment.
+ if (i == 0) {
+ ASMJIT_PROPAGATE(sb.appendHex(binData, binSize - dispSize - immSize));
+ ASMJIT_PROPAGATE(sb.appendChars('.', dispSize * 2));
+ ASMJIT_PROPAGATE(sb.appendHex(binData + binSize - immSize, immSize));
+ if (commentSize == 0) break;
+ }
+ else {
+ ASMJIT_PROPAGATE(sb.append(comment, commentSize));
+ }
+
+ currentSize += sb.size() - begin;
+ align += kMaxBinarySize;
+ sep = '|';
+ }
+ }
+
+ return sb.append('\n');
+}
+
+void logLabelBound(BaseAssembler* self, const Label& label) noexcept {
+ Logger* logger = self->logger();
+
+ StringTmp<512> sb;
+ size_t binSize = logger->hasFlag(FormatOptions::kFlagMachineCode) ? size_t(0) : SIZE_MAX;
+
+ sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationLabel));
+ Formatter::formatLabel(sb, logger->flags(), self, label.id());
+ sb.append(':');
+ EmitterUtils::formatLine(sb, nullptr, binSize, 0, 0, self->_inlineComment);
+ logger->log(sb.data(), sb.size());
+}
+
+void logInstructionEmitted(
+ BaseAssembler* self,
+ uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt,
+ uint32_t relSize, uint32_t immSize, uint8_t* afterCursor) {
+
+ Logger* logger = self->logger();
+ ASMJIT_ASSERT(logger != nullptr);
+
+ StringTmp<256> sb;
+ uint32_t flags = logger->flags();
+
+ uint8_t* beforeCursor = self->bufferPtr();
+ intptr_t emittedSize = (intptr_t)(afterCursor - beforeCursor);
+
+ Operand_ opArray[Globals::kMaxOpCount];
+ EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
+
+ sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationCode));
+ Formatter::formatInstruction(sb, flags, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
+
+ if ((flags & FormatOptions::kFlagMachineCode) != 0)
+ EmitterUtils::formatLine(sb, self->bufferPtr(), size_t(emittedSize), relSize, immSize, self->inlineComment());
+ else
+ EmitterUtils::formatLine(sb, nullptr, SIZE_MAX, 0, 0, self->inlineComment());
+ logger->log(sb);
+}
+
+Error logInstructionFailed(
+ BaseAssembler* self,
+ Error err,
+ uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
+
+ StringTmp<256> sb;
+ sb.append(DebugUtils::errorAsString(err));
+ sb.append(": ");
+
+ Operand_ opArray[Globals::kMaxOpCount];
+ EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
+
+ Formatter::formatInstruction(sb, 0, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
+
+ if (self->inlineComment()) {
+ sb.append(" ; ");
+ sb.append(self->inlineComment());
+ }
+
+ self->resetInstOptions();
+ self->resetExtraReg();
+ self->resetInlineComment();
+ return self->reportError(err, sb.data());
+}
+
+#endif
+
+} // {EmitterUtils}
+
+ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/emitterutils_p.h b/3rdparty/asmjit/src/asmjit/core/emitterutils_p.h
new file mode 100644
index 00000000000..7e222d3ad00
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/emitterutils_p.h
@@ -0,0 +1,109 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
+#define ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
+
+#include "../core/emitter.h"
+#include "../core/operand.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+class BaseAssembler;
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_core
+//! \{
+
+// ============================================================================
+// [asmjit::EmitterUtils]
+// ============================================================================
+
+namespace EmitterUtils {
+
+static const Operand_ noExt[3] {};
+
+enum kOpIndex {
+ kOp3 = 0,
+ kOp4 = 1,
+ kOp5 = 2
+};
+
+static ASMJIT_INLINE uint32_t opCountFromEmitArgs(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
+ uint32_t opCount = 0;
+
+ if (opExt[kOp3].isNone()) {
+ if (!o0.isNone()) opCount = 1;
+ if (!o1.isNone()) opCount = 2;
+ if (!o2.isNone()) opCount = 3;
+ }
+ else {
+ opCount = 4;
+ if (!opExt[kOp4].isNone()) {
+ opCount = 5 + uint32_t(!opExt[kOp5].isNone());
+ }
+ }
+
+ return opCount;
+}
+
+static ASMJIT_INLINE void opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount], const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
+ dst[0].copyFrom(o0);
+ dst[1].copyFrom(o1);
+ dst[2].copyFrom(o2);
+ dst[3].copyFrom(opExt[kOp3]);
+ dst[4].copyFrom(opExt[kOp4]);
+ dst[5].copyFrom(opExt[kOp5]);
+}
+
+#ifndef ASMJIT_NO_LOGGING
+enum : uint32_t {
+ // Has to be big to be able to hold all metadata compiler can assign to a
+ // single instruction.
+ kMaxInstLineSize = 44,
+ kMaxBinarySize = 26
+};
+
+Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept;
+
+void logLabelBound(BaseAssembler* self, const Label& label) noexcept;
+
+void logInstructionEmitted(
+ BaseAssembler* self,
+ uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt,
+ uint32_t relSize, uint32_t immSize, uint8_t* afterCursor);
+
+Error logInstructionFailed(
+ BaseAssembler* self,
+ Error err, uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt);
+#endif
+
+}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
+
diff --git a/3rdparty/asmjit/src/asmjit/core/environment.cpp b/3rdparty/asmjit/src/asmjit/core/environment.cpp
new file mode 100644
index 00000000000..3be2b15a590
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/environment.cpp
@@ -0,0 +1,64 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include "../core/api-build_p.h"
+#include "../core/environment.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+// X86 Target
+// ----------
+//
+// - 32-bit - Linux, OSX, BSD, and apparently also Haiku guarantee 16-byte
+// stack alignment. Other operating systems are assumed to have
+// 4-byte alignment by default for safety reasons.
+// - 64-bit - stack must be aligned to 16 bytes.
+//
+// ARM Target
+// ----------
+//
+// - 32-bit - Stack must be aligned to 8 bytes.
+// - 64-bit - Stack must be aligned to 16 bytes (hardware requirement).
+uint32_t Environment::stackAlignment() const noexcept {
+ if (is64Bit()) {
+ // Assume 16-byte alignment on any 64-bit target.
+ return 16;
+ }
+ else {
+ // The following platforms use 16-byte alignment in 32-bit mode.
+ if (isPlatformLinux() ||
+ isPlatformBSD() ||
+ isPlatformApple() ||
+ isPlatformHaiku()) {
+ return 16u;
+ }
+
+ if (isFamilyARM())
+ return 8;
+
+ // Bail to 4-byte alignment if we don't know.
+ return 4;
+ }
+}
+
+ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/environment.h b/3rdparty/asmjit/src/asmjit/core/environment.h
new file mode 100644
index 00000000000..99b34ec9dbd
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/environment.h
@@ -0,0 +1,591 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
+#define ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
+
+#include "../core/globals.h"
+
+#if defined(__APPLE__)
+ #include <TargetConditionals.h>
+#endif
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \addtogroup asmjit_core
+//! \{
+
+// ============================================================================
+// [asmjit::Environment]
+// ============================================================================
+
+//! Represents an environment, which is usually related to a \ref Target.
+//!
+//! Environment has usually an 'arch-subarch-vendor-os-abi' format, which is
+//! sometimes called "Triple" (historically it used to be 3 only parts) or
+//! "Tuple", which is a convention used by Debian Linux.
+//!
+//! AsmJit doesn't support all possible combinations or architectures and ABIs,
+//! however, it models the environment similarly to other compilers for future
+//! extensibility.
+class Environment {
+public:
+ //! Architecture type, see \ref Arch.
+ uint8_t _arch;
+ //! Sub-architecture type, see \ref SubArch.
+ uint8_t _subArch;
+ //! Vendor type, see \ref Vendor.
+ uint8_t _vendor;
+ //! Platform type, see \ref Platform.
+ uint8_t _platform;
+ //! ABI type, see \ref Abi.
+ uint8_t _abi;
+ //! Object format, see \ref Format.
+ uint8_t _format;
+ //! Reserved for future use, must be zero.
+ uint16_t _reserved;
+
+ //! Architecture.
+ enum Arch : uint32_t {
+ //! Unknown or uninitialized architecture.
+ kArchUnknown = 0,
+
+ //! Mask used by 32-bit architectures (odd are 32-bit, even are 64-bit).
+ kArch32BitMask = 0x01,
+ //! Mask used by big-endian architectures.
+ kArchBigEndianMask = 0x80u,
+
+ //! 32-bit X86 architecture.
+ kArchX86 = 1,
+ //! 64-bit X86 architecture also known as X86_64 and AMD64.
+ kArchX64 = 2,
+
+ //! 32-bit RISC-V architecture.
+ kArchRISCV32 = 3,
+ //! 64-bit RISC-V architecture.
+ kArchRISCV64 = 4,
+
+ //! 32-bit ARM architecture (little endian).
+ kArchARM = 5,
+ //! 32-bit ARM architecture (big endian).
+ kArchARM_BE = kArchARM | kArchBigEndianMask,
+ //! 64-bit ARM architecture in (little endian).
+ kArchAArch64 = 6,
+ //! 64-bit ARM architecture in (big endian).
+ kArchAArch64_BE = kArchAArch64 | kArchBigEndianMask,
+ //! 32-bit ARM in Thumb mode (little endian).
+ kArchThumb = 7,
+ //! 32-bit ARM in Thumb mode (big endian).
+ kArchThumb_BE = kArchThumb | kArchBigEndianMask,
+
+ // 8 is not used, even numbers are 64-bit architectures.
+
+ //! 32-bit MIPS architecture in (little endian).
+ kArchMIPS_LE = 9,
+ //! 32-bit MIPS architecture in (big endian).
+ kArchMIPS_BE = kArchMIPS_LE | kArchBigEndianMask,
+ //! 64-bit MIPS architecture in (little endian).
+ kArchMIPS64_LE = 10,
+ //! 64-bit MIPS architecture in (big endian).
+ kArchMIPS64_BE = kArchMIPS64_LE | kArchBigEndianMask,
+
+ //! Count of architectures.
+ kArchCount
+ };
+
+ //! Sub-architecture.
+ enum SubArch : uint32_t {
+ //! Unknown or uninitialized architecture sub-type.
+ kSubArchUnknown = 0,
+
+ //! Count of sub-architectures.
+ kSubArchCount
+ };
+
+ //! Vendor.
+ //!
+ //! \note AsmJit doesn't use vendor information at the moment. It's provided
+ //! for future use, if required.
+ enum Vendor : uint32_t {
+ //! Unknown or uninitialized vendor.
+ kVendorUnknown = 0,
+
+ //! Count of vendor identifiers.
+ kVendorCount
+ };
+
+ //! Platform / OS.
+ enum Platform : uint32_t {
+ //! Unknown or uninitialized platform.
+ kPlatformUnknown = 0,
+
+ //! Windows OS.
+ kPlatformWindows,
+
+ //! Other platform, most likely POSIX based.
+ kPlatformOther,
+
+ //! Linux OS.
+ kPlatformLinux,
+ //! GNU/Hurd OS.
+ kPlatformHurd,
+
+ //! FreeBSD OS.
+ kPlatformFreeBSD,
+ //! OpenBSD OS.
+ kPlatformOpenBSD,
+ //! NetBSD OS.
+ kPlatformNetBSD,
+ //! DragonFly BSD OS.
+ kPlatformDragonFlyBSD,
+
+ //! Haiku OS.
+ kPlatformHaiku,
+
+ //! Apple OSX.
+ kPlatformOSX,
+ //! Apple iOS.
+ kPlatformIOS,
+ //! Apple TVOS.
+ kPlatformTVOS,
+ //! Apple WatchOS.
+ kPlatformWatchOS,
+
+ //! Emscripten platform.
+ kPlatformEmscripten,
+
+ //! Count of platform identifiers.
+ kPlatformCount
+ };
+
+ //! ABI.
+ enum Abi : uint32_t {
+ //! Unknown or uninitialied environment.
+ kAbiUnknown = 0,
+ //! Microsoft ABI.
+ kAbiMSVC,
+ //! GNU ABI.
+ kAbiGNU,
+ //! Android Environment / ABI.
+ kAbiAndroid,
+ //! Cygwin ABI.
+ kAbiCygwin,
+
+ //! Count of known ABI types.
+ kAbiCount
+ };
+
+ //! Object format.
+ //!
+ //! \note AsmJit doesn't really use anything except \ref kFormatUnknown and
+ //! \ref kFormatJIT at the moment. Object file formats are provided for
+ //! future extensibility and a possibility to generate object files at some
+ //! point.
+ enum Format : uint32_t {
+ //! Unknown or uninitialized object format.
+ kFormatUnknown = 0,
+
+ //! JIT code generation object, most likely \ref JitRuntime or a custom
+ //! \ref Target implementation.
+ kFormatJIT,
+
+ //! Executable and linkable format (ELF).
+ kFormatELF,
+ //! Common object file format.
+ kFormatCOFF,
+ //! Extended COFF object format.
+ kFormatXCOFF,
+ //! Mach object file format.
+ kFormatMachO,
+
+ //! Count of object format types.
+ kFormatCount
+ };
+
+ //! \name Environment Detection
+ //! \{
+
+#ifdef _DOXYGEN
+ //! Architecture detected at compile-time (architecture of the host).
+ static constexpr Arch kArchHost = DETECTED_AT_COMPILE_TIME;
+ //! Sub-architecture detected at compile-time (sub-architecture of the host).
+ static constexpr SubArch kSubArchHost = DETECTED_AT_COMPILE_TIME;
+ //! Vendor detected at compile-time (vendor of the host).
+ static constexpr Vendor kVendorHost = DETECTED_AT_COMPILE_TIME;
+ //! Platform detected at compile-time (platform of the host).
+ static constexpr Platform kPlatformHost = DETECTED_AT_COMPILE_TIME;
+ //! ABI detected at compile-time (ABI of the host).
+ static constexpr Abi kAbiHost = DETECTED_AT_COMPILE_TIME;
+#else
+ static constexpr Arch kArchHost =
+ ASMJIT_ARCH_X86 == 32 ? kArchX86 :
+ ASMJIT_ARCH_X86 == 64 ? kArchX64 :
+
+ ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kArchARM :
+ ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kArchARM_BE :
+ ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kArchAArch64 :
+ ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_BE ? kArchAArch64_BE :
+
+ ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_LE ? kArchMIPS_LE :
+ ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_BE ? kArchMIPS_BE :
+ ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_LE ? kArchMIPS64_LE :
+ ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_BE ? kArchMIPS64_BE :
+
+ kArchUnknown;
+
+ static constexpr SubArch kSubArchHost =
+ kSubArchUnknown;
+
+ static constexpr Vendor kVendorHost =
+ kVendorUnknown;
+
+ static constexpr Platform kPlatformHost =
+#if defined(__EMSCRIPTEN__)
+ kPlatformEmscripten
+#elif defined(_WIN32)
+ kPlatformWindows
+#elif defined(__linux__)
+ kPlatformLinux
+#elif defined(__gnu_hurd__)
+ kPlatformHurd
+#elif defined(__FreeBSD__)
+ kPlatformFreeBSD
+#elif defined(__OpenBSD__)
+ kPlatformOpenBSD
+#elif defined(__NetBSD__)
+ kPlatformNetBSD
+#elif defined(__DragonFly__)
+ kPlatformDragonFlyBSD
+#elif defined(__HAIKU__)
+ kPlatformHaiku
+#elif defined(__APPLE__) && TARGET_OS_OSX
+ kPlatformOSX
+#elif defined(__APPLE__) && TARGET_OS_TV
+ kPlatformTVOS
+#elif defined(__APPLE__) && TARGET_OS_WATCH
+ kPlatformWatchOS
+#elif defined(__APPLE__) && TARGET_OS_IPHONE
+ kPlatformIOS
+#else
+ kPlatformOther
+#endif
+ ;
+
+ static constexpr Abi kAbiHost =
+#if defined(_MSC_VER)
+ kAbiMSVC
+#elif defined(__CYGWIN__)
+ kAbiCygwin
+#elif defined(__MINGW32__) || defined(__GLIBC__)
+ kAbiGNU
+#elif defined(__ANDROID__)
+ kAbiAndroid
+#else
+ kAbiUnknown
+#endif
+ ;
+
+#endif
+
+ //! \}
+
+ //! \name Construction / Destruction
+ //! \{
+
+ inline Environment() noexcept :
+ _arch(uint8_t(kArchUnknown)),
+ _subArch(uint8_t(kSubArchUnknown)),
+ _vendor(uint8_t(kVendorUnknown)),
+ _platform(uint8_t(kPlatformUnknown)),
+ _abi(uint8_t(kAbiUnknown)),
+ _format(uint8_t(kFormatUnknown)),
+ _reserved(0) {}
+
+ inline Environment(const Environment& other) noexcept = default;
+
+ inline explicit Environment(uint32_t arch,
+ uint32_t subArch = kSubArchUnknown,
+ uint32_t vendor = kVendorUnknown,
+ uint32_t platform = kPlatformUnknown,
+ uint32_t abi = kAbiUnknown,
+ uint32_t format = kFormatUnknown) noexcept {
+ init(arch, subArch, vendor, platform, abi, format);
+ }
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ inline Environment& operator=(const Environment& other) noexcept = default;
+
+ inline bool operator==(const Environment& other) const noexcept { return equals(other); }
+ inline bool operator!=(const Environment& other) const noexcept { return !equals(other); }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Tests whether the environment is not set up.
+ //!
+ //! Returns true if all members are zero, and thus unknown.
+ inline bool empty() const noexcept {
+ // Unfortunately compilers won't optimize fields are checked one by one...
+ return _packed() == 0;
+ }
+
+ //! Tests whether the environment is intialized, which means it must have
+ //! a valid architecture.
+ inline bool isInitialized() const noexcept {
+ return _arch != kArchUnknown;
+ }
+
+ inline uint64_t _packed() const noexcept {
+ uint64_t x;
+ memcpy(&x, this, 8);
+ return x;
+ }
+
+ //! Resets all members of the environment to zero / unknown.
+ inline void reset() noexcept {
+ _arch = uint8_t(kArchUnknown);
+ _subArch = uint8_t(kSubArchUnknown);
+ _vendor = uint8_t(kVendorUnknown);
+ _platform = uint8_t(kPlatformUnknown);
+ _abi = uint8_t(kAbiUnknown);
+ _format = uint8_t(kFormatUnknown);
+ _reserved = 0;
+ }
+
+ inline bool equals(const Environment& other) const noexcept {
+ return _packed() == other._packed();
+ }
+
+ //! Returns the architecture, see \ref Arch.
+ inline uint32_t arch() const noexcept { return _arch; }
+ //! Returns the sub-architecture, see \ref SubArch.
+ inline uint32_t subArch() const noexcept { return _subArch; }
+ //! Returns vendor, see \ref Vendor.
+ inline uint32_t vendor() const noexcept { return _vendor; }
+ //! Returns target's platform or operating system, see \ref Platform.
+ inline uint32_t platform() const noexcept { return _platform; }
+ //! Returns target's ABI, see \ref Abi.
+ inline uint32_t abi() const noexcept { return _abi; }
+ //! Returns target's object format, see \ref Format.
+ inline uint32_t format() const noexcept { return _format; }
+
+ inline void init(uint32_t arch,
+ uint32_t subArch = kSubArchUnknown,
+ uint32_t vendor = kVendorUnknown,
+ uint32_t platform = kPlatformUnknown,
+ uint32_t abi = kAbiUnknown,
+ uint32_t format = kFormatUnknown) noexcept {
+ _arch = uint8_t(arch);
+ _subArch = uint8_t(subArch);
+ _vendor = uint8_t(vendor);
+ _platform = uint8_t(platform);
+ _abi = uint8_t(abi);
+ _format = uint8_t(format);
+ _reserved = 0;
+ }
+
+ //! Tests whether the architecture is 32-bit.
+ inline bool is32Bit() const noexcept { return is32Bit(_arch); }
+ //! Tests whether the architecture is 64-bit.
+ inline bool is64Bit() const noexcept { return is64Bit(_arch); }
+
+ //! Tests whether the architecture is little endian.
+ inline bool isLittleEndian() const noexcept { return isLittleEndian(_arch); }
+ //! Tests whether the architecture is big endian.
+ inline bool isBigEndian() const noexcept { return isBigEndian(_arch); }
+
+ //! Tests whether this architecture is of X86 family.
+ inline bool isFamilyX86() const noexcept { return isFamilyX86(_arch); }
+ //! Tests whether this architecture is of ARM family.
+ inline bool isFamilyRISCV() const noexcept { return isFamilyRISCV(_arch); }
+ //! Tests whether this architecture is of ARM family.
+ inline bool isFamilyARM() const noexcept { return isFamilyARM(_arch); }
+ //! Tests whether this architecture is of ARM family.
+ inline bool isFamilyMIPS() const noexcept { return isFamilyMIPS(_arch); }
+
+ //! Tests whether the environment platform is Windows.
+ inline bool isPlatformWindows() const noexcept { return _platform == kPlatformWindows; }
+
+ //! Tests whether the environment platform is Linux.
+ inline bool isPlatformLinux() const noexcept { return _platform == kPlatformLinux; }
+
+ //! Tests whether the environment platform is Hurd.
+ inline bool isPlatformHurd() const noexcept { return _platform == kPlatformHurd; }
+
+ //! Tests whether the environment platform is Haiku.
+ inline bool isPlatformHaiku() const noexcept { return _platform == kPlatformHaiku; }
+
+ //! Tests whether the environment platform is any BSD.
+ inline bool isPlatformBSD() const noexcept {
+ return _platform == kPlatformFreeBSD ||
+ _platform == kPlatformOpenBSD ||
+ _platform == kPlatformNetBSD ||
+ _platform == kPlatformDragonFlyBSD;
+ }
+
+ //! Tests whether the environment platform is any Apple platform (OSX, iOS, TVOS, WatchOS).
+ inline bool isPlatformApple() const noexcept {
+ return _platform == kPlatformOSX ||
+ _platform == kPlatformIOS ||
+ _platform == kPlatformTVOS ||
+ _platform == kPlatformWatchOS;
+ }
+
+ //! Tests whether the ABI is MSVC.
+ inline bool isAbiMSVC() const noexcept { return _abi == kAbiMSVC; }
+ //! Tests whether the ABI is GNU.
+ inline bool isAbiGNU() const noexcept { return _abi == kAbiGNU; }
+
+ //! Returns a calculated stack alignment for this environment.
+ ASMJIT_API uint32_t stackAlignment() const noexcept;
+
+ //! Returns a native register size of this architecture.
+ uint32_t registerSize() const noexcept { return registerSizeFromArch(_arch); }
+
+ //! Sets the architecture to `arch`.
+ inline void setArch(uint32_t arch) noexcept { _arch = uint8_t(arch); }
+ //! Sets the sub-architecture to `subArch`.
+ inline void setSubArch(uint32_t subArch) noexcept { _subArch = uint8_t(subArch); }
+ //! Sets the vendor to `vendor`.
+ inline void setVendor(uint32_t vendor) noexcept { _vendor = uint8_t(vendor); }
+ //! Sets the platform to `platform`.
+ inline void setPlatform(uint32_t platform) noexcept { _platform = uint8_t(platform); }
+ //! Sets the ABI to `abi`.
+ inline void setAbi(uint32_t abi) noexcept { _abi = uint8_t(abi); }
+ //! Sets the object format to `format`.
+ inline void setFormat(uint32_t format) noexcept { _format = uint8_t(format); }
+
+ //! \}
+
+ //! \name Static Utilities
+ //! \{
+
+ //! Tests whether the given architecture `arch` is 32-bit.
+ static inline bool is32Bit(uint32_t arch) noexcept {
+ return (arch & kArch32BitMask) == kArch32BitMask;
+ }
+
+ //! Tests whether the given architecture `arch` is 64-bit.
+ static inline bool is64Bit(uint32_t arch) noexcept {
+ return (arch & kArch32BitMask) == 0;
+ }
+
+ //! Tests whether the given architecture `arch` is little endian.
+ static inline bool isLittleEndian(uint32_t arch) noexcept {
+ return (arch & kArchBigEndianMask) == 0;
+ }
+
+ //! Tests whether the given architecture `arch` is big endian.
+ static inline bool isBigEndian(uint32_t arch) noexcept {
+ return (arch & kArchBigEndianMask) == kArchBigEndianMask;
+ }
+
+ //! Tests whether the given architecture family is X86 or X64.
+ static inline bool isFamilyX86(uint32_t arch) noexcept {
+ return arch == kArchX86 ||
+ arch == kArchX64;
+ }
+
+ //! Tests whether the given architecture family is RISC-V (both 32-bit and 64-bit).
+ static inline bool isFamilyRISCV(uint32_t arch) noexcept {
+ return arch == kArchRISCV32 ||
+ arch == kArchRISCV64;
+ }
+
+ //! Tests whether the given architecture family is ARM, Thumb, or AArch64.
+ static inline bool isFamilyARM(uint32_t arch) noexcept {
+ arch &= ~kArchBigEndianMask;
+ return arch == kArchARM ||
+ arch == kArchAArch64 ||
+ arch == kArchThumb;
+ }
+
+ //! Tests whether the given architecture family is MISP or MIPS64.
+ static inline bool isFamilyMIPS(uint32_t arch) noexcept {
+ arch &= ~kArchBigEndianMask;
+ return arch == kArchMIPS_LE ||
+ arch == kArchMIPS64_LE;
+ }
+
+ //! Returns a native general purpose register size from the given architecture.
+ static uint32_t registerSizeFromArch(uint32_t arch) noexcept {
+ return is32Bit(arch) ? 4u : 8u;
+ }
+
+ //! \}
+};
+
+//! Returns the host environment constructed from preprocessor macros defined
+//! by the compiler.
+//!
+//! The returned environment should precisely match the target host architecture,
+//! sub-architecture, platform, and ABI.
+static ASMJIT_INLINE Environment hostEnvironment() noexcept {
+ return Environment(Environment::kArchHost,
+ Environment::kSubArchHost,
+ Environment::kVendorHost,
+ Environment::kPlatformHost,
+ Environment::kAbiHost,
+ Environment::kFormatUnknown);
+}
+
+static_assert(sizeof(Environment) == 8,
+ "Environment must occupy exactly 8 bytes.");
+
+//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+class ASMJIT_DEPRECATED_STRUCT("Use Environment instead") ArchInfo : public Environment {
+public:
+ inline ArchInfo() noexcept : Environment() {}
+
+ inline ArchInfo(const Environment& other) noexcept : Environment(other) {}
+ inline explicit ArchInfo(uint32_t arch, uint32_t subArch = kSubArchUnknown) noexcept
+ : Environment(arch, subArch) {}
+
+ enum Id : uint32_t {
+ kIdNone = Environment::kArchUnknown,
+ kIdX86 = Environment::kArchX86,
+ kIdX64 = Environment::kArchX64,
+ kIdA32 = Environment::kArchARM,
+ kIdA64 = Environment::kArchAArch64,
+ kIdHost = Environment::kArchHost
+ };
+
+ enum SubType : uint32_t {
+ kSubIdNone = Environment::kSubArchUnknown
+ };
+
+ static inline ArchInfo host() noexcept { return ArchInfo(hostEnvironment()); }
+};
+#endif // !ASMJIT_NO_DEPRECATED
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/errorhandler.cpp b/3rdparty/asmjit/src/asmjit/core/errorhandler.cpp
new file mode 100644
index 00000000000..8372d75a463
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/errorhandler.cpp
@@ -0,0 +1,37 @@
+
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include "../core/api-build_p.h"
+#include "../core/errorhandler.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+// ============================================================================
+// [asmjit::ErrorHandler]
+// ============================================================================
+
+ErrorHandler::ErrorHandler() noexcept {}
+ErrorHandler::~ErrorHandler() noexcept {}
+
+ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/errorhandler.h b/3rdparty/asmjit/src/asmjit/core/errorhandler.h
new file mode 100644
index 00000000000..2337cd8d841
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/errorhandler.h
@@ -0,0 +1,267 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_CORE_ERRORHANDLER_H_INCLUDED
+#define ASMJIT_CORE_ERRORHANDLER_H_INCLUDED
+
+#include "../core/globals.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \addtogroup asmjit_error_handling
+//! \{
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+class BaseEmitter;
+
+// ============================================================================
+// [asmjit::ErrorHandler]
+// ============================================================================
+
+//! Error handler can be used to override the default behavior of error handling.
+//!
+//! It's available to all classes that inherit `BaseEmitter`. Override
+//! \ref ErrorHandler::handleError() to implement your own error handler.
+//!
+//! The following use-cases are supported:
+//!
+//! - Record the error and continue code generation. This is the simplest
+//! approach that can be used to at least log possible errors.
+//! - Throw an exception. AsmJit doesn't use exceptions and is completely
+//! exception-safe, but it's perfectly legal to throw an exception from
+//! the error handler.
+//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler,
+//! Builder and Compiler to a consistent state before calling \ref handleError(),
+//! so `longjmp()` can be used without issues to cancel the code-generation if
+//! an error occurred. This method can be used if exception handling in your
+//! project is turned off and you still want some comfort. In most cases it
+//! should be safe as AsmJit uses \ref Zone memory and the ownership of memory
+//! it allocates always ends with the instance that allocated it. If using this
+//! approach please never jump outside the life-time of \ref CodeHolder and
+//! \ref BaseEmitter.
+//!
+//! \ref ErrorHandler can be attached to \ref CodeHolder or \ref BaseEmitter,
+//! which has a priority. The example below uses error handler that just prints
+//! the error, but lets AsmJit continue:
+//!
+//! ```
+//! // Error Handling #1 - Logging and returing Error.
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Error handler that just prints the error and lets AsmJit ignore it.
+//! class SimpleErrorHandler : public ErrorHandler {
+//! public:
+//! Error err;
+//!
+//! inline SimpleErrorHandler() : err(kErrorOk) {}
+//!
+//! void handleError(Error err, const char* message, BaseEmitter* origin) override {
+//! this->err = err;
+//! fprintf(stderr, "ERROR: %s\n", message);
+//! }
+//! };
+//!
+//! int main() {
+//! JitRuntime rt;
+//! SimpleErrorHandler eh;
+//!
+//! CodeHolder code;
+//! code.init(rt.environment());
+//! code.setErrorHandler(&eh);
+//!
+//! // Try to emit instruction that doesn't exist.
+//! x86::Assembler a(&code);
+//! a.emit(x86::Inst::kIdMov, x86::xmm0, x86::xmm1);
+//!
+//! if (eh.err) {
+//! // Assembler failed!
+//! return 1;
+//! }
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! If error happens during instruction emitting / encoding the assembler behaves
+//! transactionally - the output buffer won't advance if encoding failed, thus
+//! either a fully encoded instruction or nothing is emitted. The error handling
+//! shown above is useful, but it's still not the best way of dealing with errors
+//! in AsmJit. The following example shows how to use exception handling to handle
+//! errors in a more C++ way:
+//!
+//! ```
+//! // Error Handling #2 - Throwing an exception.
+//! #include <asmjit/x86.h>
+//! #include <exception>
+//! #include <string>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Error handler that throws a user-defined `AsmJitException`.
+//! class AsmJitException : public std::exception {
+//! public:
+//! Error err;
+//! std::string message;
+//!
+//! AsmJitException(Error err, const char* message) noexcept
+//! : err(err),
+//! message(message) {}
+//!
+//! const char* what() const noexcept override { return message.c_str(); }
+//! };
+//!
+//! class ThrowableErrorHandler : public ErrorHandler {
+//! public:
+//! // Throw is possible, functions that use ErrorHandler are never 'noexcept'.
+//! void handleError(Error err, const char* message, BaseEmitter* origin) override {
+//! throw AsmJitException(err, message);
+//! }
+//! };
+//!
+//! int main() {
+//! JitRuntime rt;
+//! ThrowableErrorHandler eh;
+//!
+//! CodeHolder code;
+//! code.init(rt.environment());
+//! code.setErrorHandler(&eh);
+//!
+//! x86::Assembler a(&code);
+//!
+//! // Try to emit instruction that doesn't exist.
+//! try {
+//! a.emit(x86::Inst::kIdMov, x86::xmm0, x86::xmm1);
+//! }
+//! catch (const AsmJitException& ex) {
+//! printf("EXCEPTION THROWN: %s\n", ex.what());
+//! return 1;
+//! }
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! If C++ exceptions are not what you like or your project turns off them
+//! completely there is still a way of reducing the error handling to a minimum
+//! by using a standard setjmp/longjmp approach. AsmJit is exception-safe and
+//! cleans up everything before calling the ErrorHandler, so any approach is
+//! safe. You can simply jump from the error handler without causing any
+//! side-effects or memory leaks. The following example demonstrates how it
+//! could be done:
+//!
+//! ```
+//! // Error Handling #3 - Using setjmp/longjmp if exceptions are not allowed.
+//! #include <asmjit/x86.h>
+//! #include <setjmp.h>
+//! #include <stdio.h>
+//!
+//! class LongJmpErrorHandler : public asmjit::ErrorHandler {
+//! public:
+//! inline LongJmpErrorHandler() : err(asmjit::kErrorOk) {}
+//!
+//! void handleError(asmjit::Error err, const char* message, asmjit::BaseEmitter* origin) override {
+//! this->err = err;
+//! longjmp(state, 1);
+//! }
+//!
+//! jmp_buf state;
+//! asmjit::Error err;
+//! };
+//!
+//! int main(int argc, char* argv[]) {
+//! using namespace asmjit;
+//!
+//! JitRuntime rt;
+//! LongJmpErrorHandler eh;
+//!
+//! CodeHolder code;
+//! code.init(rt.rt.environment());
+//! code.setErrorHandler(&eh);
+//!
+//! x86::Assembler a(&code);
+//!
+//! if (!setjmp(eh.state)) {
+//! // Try to emit instruction that doesn't exist.
+//! a.emit(x86::Inst::kIdMov, x86::xmm0, x86::xmm1);
+//! }
+//! else {
+//! Error err = eh.err;
+//! printf("ASMJIT ERROR: 0x%08X [%s]\n", err, DebugUtils::errorAsString(err));
+//! }
+//!
+//! return 0;
+//! }
+//! ```
+class ASMJIT_VIRTAPI ErrorHandler {
+public:
+ ASMJIT_BASE_CLASS(ErrorHandler)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Creates a new `ErrorHandler` instance.
+ ASMJIT_API ErrorHandler() noexcept;
+ //! Destroys the `ErrorHandler` instance.
+ ASMJIT_API virtual ~ErrorHandler() noexcept;
+
+ // --------------------------------------------------------------------------
+ // [Handle Error]
+ // --------------------------------------------------------------------------
+
+ //! Error handler (must be reimplemented).
+ //!
+ //! Error handler is called after an error happened and before it's propagated
+ //! to the caller. There are multiple ways how the error handler can be used:
+ //!
+ //! 1. User-based error handling without throwing exception or using C's
+ //! `longjmp()`. This is for users that don't use exceptions and want
+ //! customized error handling.
+ //!
+ //! 2. Throwing an exception. AsmJit doesn't use exceptions and is completely
+ //! exception-safe, but you can throw exception from your error handler if
+ //! this way is the preferred way of handling errors in your project.
+ //!
+ //! 3. Using plain old C's `setjmp()` and `longjmp()`. Asmjit always puts
+ //! `BaseEmitter` to a consistent state before calling `handleError()`
+ //! so `longjmp()` can be used without any issues to cancel the code
+ //! generation if an error occurred. There is no difference between
+ //! exceptions and `longjmp()` from AsmJit's perspective, however,
+ //! never jump outside of `CodeHolder` and `BaseEmitter` scope as you
+ //! would leak memory.
+ virtual void handleError(Error err, const char* message, BaseEmitter* origin) = 0;
+};
+
+//! \}
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_ERRORHANDLER_H_INCLUDED
+
diff --git a/3rdparty/asmjit/src/asmjit/core/features.h b/3rdparty/asmjit/src/asmjit/core/features.h
index 193841c76c8..fd28472c91f 100644
--- a/3rdparty/asmjit/src/asmjit/core/features.h
+++ b/3rdparty/asmjit/src/asmjit/core/features.h
@@ -36,9 +36,15 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::BaseFeatures]
// ============================================================================
+//! Base class that provides information about CPU features.
+//!
+//! Internally each feature is repreesnted by a single bit in an embedded
+//! bit-array, however, feature bits are defined by an architecture specific
+//! implementations, like \ref x86::Features.
class BaseFeatures {
public:
typedef Support::BitWord BitWord;
+ typedef Support::BitVectorIterator<BitWord> Iterator;
enum : uint32_t {
kMaxFeatures = 128,
@@ -74,9 +80,11 @@ public:
//! \name Cast
//! \{
+ //! Casts this base class into a derived type `T`.
template<typename T>
inline T& as() noexcept { return static_cast<T&>(*this); }
+ //! Casts this base class into a derived type `T` (const).
template<typename T>
inline const T& as() const noexcept { return static_cast<const T&>(*this); }
@@ -85,11 +93,27 @@ public:
//! \name Accessors
//! \{
- //! Returns all features as `BitWord` array.
+ inline bool empty() const noexcept {
+ for (uint32_t i = 0; i < kNumBitWords; i++)
+ if (_bits[i])
+ return false;
+ return true;
+ }
+
+ //! Returns all features as array of bitwords (see \ref Support::BitWord).
inline BitWord* bits() noexcept { return _bits; }
- //! Returns all features as `BitWord` array (const).
+ //! Returns all features as array of bitwords (const).
inline const BitWord* bits() const noexcept { return _bits; }
+ //! Returns the number of BitWords returned by \ref bits().
+ inline size_t bitWordCount() const noexcept { return kNumBitWords; }
+
+ //! Returns \ref Support::BitVectorIterator, that can be used to iterate
+ //! all features efficiently
+ inline Iterator iterator() const noexcept {
+ return Iterator(_bits, kNumBitWords);
+ }
+
//! Tests whether the feature `featureId` is present.
inline bool has(uint32_t featureId) const noexcept {
ASMJIT_ASSERT(featureId < kMaxFeatures);
diff --git a/3rdparty/asmjit/src/asmjit/core/formatter.cpp b/3rdparty/asmjit/src/asmjit/core/formatter.cpp
new file mode 100644
index 00000000000..404edaf3820
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/formatter.cpp
@@ -0,0 +1,469 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include "../core/api-build_p.h"
+#ifndef ASMJIT_NO_LOGGING
+
+#include "../core/builder.h"
+#include "../core/codeholder.h"
+#include "../core/compiler.h"
+#include "../core/emitter.h"
+#include "../core/formatter.h"
+#include "../core/string.h"
+#include "../core/support.h"
+#include "../core/type.h"
+
+#ifdef ASMJIT_BUILD_X86
+ #include "../x86/x86formatter_p.h"
+#endif
+
+#ifdef ASMJIT_BUILD_ARM
+ #include "../arm/armformatter_p.h"
+#endif
+
+ASMJIT_BEGIN_NAMESPACE
+
+#if defined(ASMJIT_NO_COMPILER)
+class VirtReg;
+#endif
+
+// ============================================================================
+// [asmjit::Formatter]
+// ============================================================================
+
+namespace Formatter {
+
+Error formatTypeId(String& sb, uint32_t typeId) noexcept {
+ if (typeId == Type::kIdVoid)
+ return sb.append("void");
+
+ if (!Type::isValid(typeId))
+ return sb.append("unknown");
+
+ const char* typeName = "unknown";
+ uint32_t typeSize = Type::sizeOf(typeId);
+
+ uint32_t baseId = Type::baseOf(typeId);
+ switch (baseId) {
+ case Type::kIdIntPtr : typeName = "iptr" ; break;
+ case Type::kIdUIntPtr: typeName = "uptr" ; break;
+ case Type::kIdI8 : typeName = "i8" ; break;
+ case Type::kIdU8 : typeName = "u8" ; break;
+ case Type::kIdI16 : typeName = "i16" ; break;
+ case Type::kIdU16 : typeName = "u16" ; break;
+ case Type::kIdI32 : typeName = "i32" ; break;
+ case Type::kIdU32 : typeName = "u32" ; break;
+ case Type::kIdI64 : typeName = "i64" ; break;
+ case Type::kIdU64 : typeName = "u64" ; break;
+ case Type::kIdF32 : typeName = "f32" ; break;
+ case Type::kIdF64 : typeName = "f64" ; break;
+ case Type::kIdF80 : typeName = "f80" ; break;
+ case Type::kIdMask8 : typeName = "mask8" ; break;
+ case Type::kIdMask16 : typeName = "mask16"; break;
+ case Type::kIdMask32 : typeName = "mask32"; break;
+ case Type::kIdMask64 : typeName = "mask64"; break;
+ case Type::kIdMmx32 : typeName = "mmx32" ; break;
+ case Type::kIdMmx64 : typeName = "mmx64" ; break;
+ }
+
+ uint32_t baseSize = Type::sizeOf(baseId);
+ if (typeSize > baseSize) {
+ uint32_t count = typeSize / baseSize;
+ return sb.appendFormat("%sx%u", typeName, unsigned(count));
+ }
+ else {
+ return sb.append(typeName);
+ }
+}
+
+Error formatFeature(
+ String& sb,
+ uint32_t arch,
+ uint32_t featureId) noexcept {
+
+#ifdef ASMJIT_BUILD_X86
+ if (Environment::isFamilyX86(arch))
+ return x86::FormatterInternal::formatFeature(sb, featureId);
+#endif
+
+#ifdef ASMJIT_BUILD_ARM
+ if (Environment::isFamilyARM(arch))
+ return arm::FormatterInternal::formatFeature(sb, featureId);
+#endif
+
+ return kErrorInvalidArch;
+}
+
+Error formatLabel(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t labelId) noexcept {
+
+ DebugUtils::unused(formatFlags);
+
+ const LabelEntry* le = emitter->code()->labelEntry(labelId);
+ if (ASMJIT_UNLIKELY(!le))
+ return sb.appendFormat("<InvalidLabel:%u>", labelId);
+
+ if (le->hasName()) {
+ if (le->hasParent()) {
+ uint32_t parentId = le->parentId();
+ const LabelEntry* pe = emitter->code()->labelEntry(parentId);
+
+ if (ASMJIT_UNLIKELY(!pe))
+ ASMJIT_PROPAGATE(sb.appendFormat("<InvalidLabel:%u>", labelId));
+ else if (ASMJIT_UNLIKELY(!pe->hasName()))
+ ASMJIT_PROPAGATE(sb.appendFormat("L%u", parentId));
+ else
+ ASMJIT_PROPAGATE(sb.append(pe->name()));
+
+ ASMJIT_PROPAGATE(sb.append('.'));
+ }
+ return sb.append(le->name());
+ }
+ else {
+ return sb.appendFormat("L%u", labelId);
+ }
+}
+
+Error formatRegister(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ uint32_t regType,
+ uint32_t regId) noexcept {
+
+#ifdef ASMJIT_BUILD_X86
+ if (Environment::isFamilyX86(arch))
+ return x86::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId);
+#endif
+
+#ifdef ASMJIT_BUILD_ARM
+ if (Environment::isFamilyARM(arch))
+ return arm::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId);
+#endif
+
+ return kErrorInvalidArch;
+}
+
+Error formatOperand(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ const Operand_& op) noexcept {
+
+#ifdef ASMJIT_BUILD_X86
+ if (Environment::isFamilyX86(arch))
+ return x86::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op);
+#endif
+
+#ifdef ASMJIT_BUILD_ARM
+ if (Environment::isFamilyARM(arch))
+ return arm::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op);
+#endif
+
+ return kErrorInvalidArch;
+}
+
+Error formatInstruction(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept {
+
+#ifdef ASMJIT_BUILD_X86
+ if (Environment::isFamilyX86(arch))
+ return x86::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount);
+#endif
+
+#ifdef ASMJIT_BUILD_ARM
+ if (Environment::isFamilyARM(arch))
+ return arm::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount);
+#endif
+
+ return kErrorInvalidArch;
+}
+
+#ifndef ASMJIT_NO_BUILDER
+static Error formatFuncValue(String& sb, uint32_t formatFlags, const BaseEmitter* emitter, FuncValue value) noexcept {
+ uint32_t typeId = value.typeId();
+ ASMJIT_PROPAGATE(formatTypeId(sb, typeId));
+
+ if (value.isAssigned()) {
+ ASMJIT_PROPAGATE(sb.append('@'));
+
+ if (value.isIndirect())
+ ASMJIT_PROPAGATE(sb.append('['));
+
+ // NOTE: It should be either reg or stack, but never both. We
+ // use two IFs on purpose so if the FuncValue is both it would
+ // show in logs.
+ if (value.isReg()) {
+ ASMJIT_PROPAGATE(formatRegister(sb, formatFlags, emitter, emitter->arch(), value.regType(), value.regId()));
+ }
+
+ if (value.isStack()) {
+ ASMJIT_PROPAGATE(sb.appendFormat("[%d]", int(value.stackOffset())));
+ }
+
+ if (value.isIndirect())
+ ASMJIT_PROPAGATE(sb.append(']'));
+ }
+
+ return kErrorOk;
+}
+
+static Error formatFuncRets(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ const FuncDetail& fd,
+ VirtReg* const* vRegs) noexcept {
+
+ if (!fd.hasRet())
+ return sb.append("void");
+
+ for (uint32_t i = 0; i < fd.retCount(); i++) {
+ if (i) ASMJIT_PROPAGATE(sb.append(", "));
+ ASMJIT_PROPAGATE(formatFuncValue(sb, formatFlags, emitter, fd.ret(i)));
+
+#ifndef ASMJIT_NO_COMPILER
+ if (vRegs) {
+ static const char nullRet[] = "<none>";
+ ASMJIT_PROPAGATE(sb.appendFormat(" %s", vRegs[i] ? vRegs[i]->name() : nullRet));
+ }
+#else
+ DebugUtils::unused(vRegs);
+#endif
+ }
+
+ return kErrorOk;
+}
+
+static Error formatFuncArgs(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ const FuncDetail& fd,
+ VirtReg* const* vRegs) noexcept {
+
+ uint32_t count = fd.argCount();
+ if (!count)
+ return sb.append("void");
+
+ for (uint32_t i = 0; i < count; i++) {
+ if (i)
+ ASMJIT_PROPAGATE(sb.append(", "));
+
+ ASMJIT_PROPAGATE(formatFuncValue(sb, formatFlags, emitter, fd.arg(i)));
+
+#ifndef ASMJIT_NO_COMPILER
+ if (vRegs) {
+ static const char nullArg[] = "<none>";
+ ASMJIT_PROPAGATE(sb.appendFormat(" %s", vRegs[i] ? vRegs[i]->name() : nullArg));
+ }
+#else
+ DebugUtils::unused(vRegs);
+#endif
+ }
+
+ return kErrorOk;
+}
+
+Error formatNode(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseBuilder* builder,
+ const BaseNode* node) noexcept {
+
+ if (node->hasPosition() && (formatFlags & FormatOptions::kFlagPositions) != 0)
+ ASMJIT_PROPAGATE(sb.appendFormat("<%05u> ", node->position()));
+
+ switch (node->type()) {
+ case BaseNode::kNodeInst:
+ case BaseNode::kNodeJump: {
+ const InstNode* instNode = node->as<InstNode>();
+ ASMJIT_PROPAGATE(
+ formatInstruction(sb, formatFlags, builder,
+ builder->arch(),
+ instNode->baseInst(), instNode->operands(), instNode->opCount()));
+ break;
+ }
+
+ case BaseNode::kNodeSection: {
+ const SectionNode* sectionNode = node->as<SectionNode>();
+ if (builder->_code->isSectionValid(sectionNode->id())) {
+ const Section* section = builder->_code->sectionById(sectionNode->id());
+ ASMJIT_PROPAGATE(sb.appendFormat(".section %s", section->name()));
+ }
+ break;
+ }
+
+ case BaseNode::kNodeLabel: {
+ const LabelNode* labelNode = node->as<LabelNode>();
+ ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, labelNode->labelId()));
+ ASMJIT_PROPAGATE(sb.append(":"));
+ break;
+ }
+
+ case BaseNode::kNodeAlign: {
+ const AlignNode* alignNode = node->as<AlignNode>();
+ ASMJIT_PROPAGATE(
+ sb.appendFormat("align %u (%s)",
+ alignNode->alignment(),
+ alignNode->alignMode() == kAlignCode ? "code" : "data"));
+ break;
+ }
+
+ case BaseNode::kNodeEmbedData: {
+ const EmbedDataNode* embedNode = node->as<EmbedDataNode>();
+ ASMJIT_PROPAGATE(sb.append("embed "));
+ if (embedNode->repeatCount() != 1)
+ ASMJIT_PROPAGATE(sb.appendFormat("[repeat=%zu] ", size_t(embedNode->repeatCount())));
+ ASMJIT_PROPAGATE(sb.appendFormat("%u bytes", embedNode->dataSize()));
+ break;
+ }
+
+ case BaseNode::kNodeEmbedLabel: {
+ const EmbedLabelNode* embedNode = node->as<EmbedLabelNode>();
+ ASMJIT_PROPAGATE(sb.append(".label "));
+ ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->labelId()));
+ break;
+ }
+
+ case BaseNode::kNodeEmbedLabelDelta: {
+ const EmbedLabelDeltaNode* embedNode = node->as<EmbedLabelDeltaNode>();
+ ASMJIT_PROPAGATE(sb.append(".label ("));
+ ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->labelId()));
+ ASMJIT_PROPAGATE(sb.append(" - "));
+ ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->baseLabelId()));
+ ASMJIT_PROPAGATE(sb.append(")"));
+ break;
+ }
+
+ case BaseNode::kNodeComment: {
+ const CommentNode* commentNode = node->as<CommentNode>();
+ ASMJIT_PROPAGATE(sb.appendFormat("; %s", commentNode->inlineComment()));
+ break;
+ }
+
+ case BaseNode::kNodeSentinel: {
+ const SentinelNode* sentinelNode = node->as<SentinelNode>();
+ const char* sentinelName = nullptr;
+
+ switch (sentinelNode->sentinelType()) {
+ case SentinelNode::kSentinelFuncEnd:
+ sentinelName = "[FuncEnd]";
+ break;
+
+ default:
+ sentinelName = "[Sentinel]";
+ break;
+ }
+
+ ASMJIT_PROPAGATE(sb.append(sentinelName));
+ break;
+ }
+
+#ifndef ASMJIT_NO_COMPILER
+ case BaseNode::kNodeFunc: {
+ const FuncNode* funcNode = node->as<FuncNode>();
+
+ ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, funcNode->labelId()));
+ ASMJIT_PROPAGATE(sb.append(": "));
+
+ ASMJIT_PROPAGATE(formatFuncRets(sb, formatFlags, builder, funcNode->detail(), nullptr));
+ ASMJIT_PROPAGATE(sb.append(" Func("));
+ ASMJIT_PROPAGATE(formatFuncArgs(sb, formatFlags, builder, funcNode->detail(), funcNode->args()));
+ ASMJIT_PROPAGATE(sb.append(")"));
+ break;
+ }
+
+ case BaseNode::kNodeFuncRet: {
+ const FuncRetNode* retNode = node->as<FuncRetNode>();
+ ASMJIT_PROPAGATE(sb.append("[FuncRet]"));
+
+ for (uint32_t i = 0; i < 2; i++) {
+ const Operand_& op = retNode->_opArray[i];
+ if (!op.isNone()) {
+ ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
+ ASMJIT_PROPAGATE(formatOperand(sb, formatFlags, builder, builder->arch(), op));
+ }
+ }
+ break;
+ }
+
+ case BaseNode::kNodeInvoke: {
+ const InvokeNode* invokeNode = node->as<InvokeNode>();
+ ASMJIT_PROPAGATE(
+ formatInstruction(sb, formatFlags, builder,
+ builder->arch(),
+ invokeNode->baseInst(), invokeNode->operands(), invokeNode->opCount()));
+ break;
+ }
+#endif
+
+ default: {
+ ASMJIT_PROPAGATE(sb.appendFormat("[UserNode:%u]", node->type()));
+ break;
+ }
+ }
+
+ return kErrorOk;
+}
+
+
+Error formatNodeList(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseBuilder* builder) noexcept {
+
+ return formatNodeList(sb, formatFlags, builder, builder->firstNode(), nullptr);
+}
+
+Error formatNodeList(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseBuilder* builder,
+ const BaseNode* begin,
+ const BaseNode* end) noexcept {
+
+ const BaseNode* node = begin;
+ while (node != end) {
+ ASMJIT_PROPAGATE(formatNode(sb, formatFlags, builder, node));
+ ASMJIT_PROPAGATE(sb.append('\n'));
+ node = node->next();
+ }
+ return kErrorOk;
+}
+#endif
+
+} // {Formatter}
+
+ASMJIT_END_NAMESPACE
+
+#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/formatter.h b/3rdparty/asmjit/src/asmjit/core/formatter.h
new file mode 100644
index 00000000000..81d1c77ccdf
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/formatter.h
@@ -0,0 +1,252 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_CORE_FORMATTER_H_INCLUDED
+#define ASMJIT_CORE_FORMATTER_H_INCLUDED
+
+#include "../core/inst.h"
+#include "../core/string.h"
+
+#ifndef ASMJIT_NO_LOGGING
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \addtogroup asmjit_logging
+//! \{
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+class BaseEmitter;
+struct Operand_;
+
+#ifndef ASMJIT_NO_BUILDER
+class BaseBuilder;
+class BaseNode;
+#endif
+
+// ============================================================================
+// [asmjit::FormatOptions]
+// ============================================================================
+
+//! Formatting options used by \ref Logger and \ref Formatter.
+class FormatOptions {
+public:
+ //! Format flags, see \ref Flags.
+ uint32_t _flags;
+ //! Indentation by type, see \ref IndentationType.
+ uint8_t _indentation[4];
+
+ //! Flags can enable a logging feature.
+ enum Flags : uint32_t {
+ //! No flags.
+ kNoFlags = 0u,
+
+ //! Show also binary form of each logged instruction (Assembler).
+ kFlagMachineCode = 0x00000001u,
+ //! Show a text explanation of some immediate values.
+ kFlagExplainImms = 0x00000002u,
+ //! Use hexadecimal notation of immediate values.
+ kFlagHexImms = 0x00000004u,
+ //! Use hexadecimal notation of address offsets.
+ kFlagHexOffsets = 0x00000008u,
+ //! Show casts between virtual register types (Compiler).
+ kFlagRegCasts = 0x00000010u,
+ //! Show positions associated with nodes (Compiler).
+ kFlagPositions = 0x00000020u,
+ //! Annotate nodes that are lowered by passes.
+ kFlagAnnotations = 0x00000040u,
+
+ // TODO: These must go, keep this only for formatting.
+ //! Show an additional output from passes.
+ kFlagDebugPasses = 0x00000080u,
+ //! Show an additional output from RA.
+ kFlagDebugRA = 0x00000100u
+ };
+
+ //! Describes indentation type of code, label, or comment in logger output.
+ enum IndentationType : uint32_t {
+ //! Indentation used for instructions and directives.
+ kIndentationCode = 0u,
+ //! Indentation used for labels and function nodes.
+ kIndentationLabel = 1u,
+ //! Indentation used for comments (not inline comments).
+ kIndentationComment = 2u,
+ //! \cond INTERNAL
+ //! Reserved for future use.
+ kIndentationReserved = 3u
+ //! \endcond
+ };
+
+ //! \name Construction & Destruction
+ //! \{
+
+ //! Creates a default-initialized FormatOptions.
+ constexpr FormatOptions() noexcept
+ : _flags(0),
+ _indentation { 0, 0, 0, 0 } {}
+
+ constexpr FormatOptions(const FormatOptions& other) noexcept = default;
+ inline FormatOptions& operator=(const FormatOptions& other) noexcept = default;
+
+ //! Resets FormatOptions to its default initialized state.
+ inline void reset() noexcept {
+ _flags = 0;
+ _indentation[0] = 0;
+ _indentation[1] = 0;
+ _indentation[2] = 0;
+ _indentation[3] = 0;
+ }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns format flags.
+ constexpr uint32_t flags() const noexcept { return _flags; }
+ //! Tests whether the given `flag` is set in format flags.
+ constexpr bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ //! Resets all format flags to `flags`.
+ inline void setFlags(uint32_t flags) noexcept { _flags = flags; }
+ //! Adds `flags` to format flags.
+ inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ //! Removes `flags` from format flags.
+ inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
+
+ //! Returns indentation for the given `type`, see \ref IndentationType.
+ constexpr uint8_t indentation(uint32_t type) const noexcept { return _indentation[type]; }
+ //! Sets indentation for the given `type`, see \ref IndentationType.
+ inline void setIndentation(uint32_t type, uint32_t n) noexcept { _indentation[type] = uint8_t(n); }
+ //! Resets indentation for the given `type` to zero.
+ inline void resetIndentation(uint32_t type) noexcept { _indentation[type] = uint8_t(0); }
+
+ //! \}
+};
+
+// ============================================================================
+// [asmjit::Formatter]
+// ============================================================================
+
+//! Provides formatting functionality to format operands, instructions, and nodes.
+namespace Formatter {
+
+//! Appends a formatted `typeId` to the output string `sb`.
+ASMJIT_API Error formatTypeId(
+ String& sb,
+ uint32_t typeId) noexcept;
+
+//! Appends a formatted `featureId` to the output string `sb`.
+//!
+//! See \ref BaseFeatures.
+ASMJIT_API Error formatFeature(
+ String& sb,
+ uint32_t arch,
+ uint32_t featureId) noexcept;
+
+//! Appends a formatted register to the output string `sb`.
+//!
+//! \note Emitter is optional, but it's required to format virtual registers,
+//! which won't be formatted properly if the `emitter` is not provided.
+ASMJIT_API Error formatRegister(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ uint32_t regType,
+ uint32_t regId) noexcept;
+
+//! Appends a formatted label to the output string `sb`.
+//!
+//! \note Emitter is optional, but it's required to format named labels
+//! properly, otherwise the formatted as it is an anonymous label.
+ASMJIT_API Error formatLabel(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t labelId) noexcept;
+
+//! Appends a formatted operand to the output string `sb`.
+//!
+//! \note Emitter is optional, but it's required to format named labels and
+//! virtual registers. See \ref formatRegister() and \ref formatLabel() for
+//! more details.
+ASMJIT_API Error formatOperand(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ const Operand_& op) noexcept;
+
+//! Appends a formatted instruction to the output string `sb`.
+//!
+//! \note Emitter is optional, but it's required to format named labels and
+//! virtual registers. See \ref formatRegister() and \ref formatLabel() for
+//! more details.
+ASMJIT_API Error formatInstruction(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;
+
+#ifndef ASMJIT_NO_BUILDER
+//! Appends a formatted node to the output string `sb`.
+//!
+//! The `node` must belong to the provided `builder`.
+ASMJIT_API Error formatNode(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseBuilder* builder,
+ const BaseNode* node) noexcept;
+
+//! Appends formatted nodes to the output string `sb`.
+//!
+//! All nodes that are part of the given `builder` will be appended.
+ASMJIT_API Error formatNodeList(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseBuilder* builder) noexcept;
+
+//! Appends formatted nodes to the output string `sb`.
+//!
+//! This function works the same as \ref formatNode(), but appends more nodes
+//! to the output string, separating each node with a newline '\n' character.
+ASMJIT_API Error formatNodeList(
+ String& sb,
+ uint32_t formatFlags,
+ const BaseBuilder* builder,
+ const BaseNode* begin,
+ const BaseNode* end) noexcept;
+#endif
+
+} // {Formatter}
+
+//! \}
+
+ASMJIT_END_NAMESPACE
+
+#endif
+
+#endif // ASMJIT_CORE_FORMATTER_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/func.cpp b/3rdparty/asmjit/src/asmjit/core/func.cpp
index 79eab2e83ad..514ae9db4e1 100644
--- a/3rdparty/asmjit/src/asmjit/core/func.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/func.cpp
@@ -42,41 +42,41 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::FuncDetail - Init / Reset]
// ============================================================================
-ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) {
- uint32_t ccId = sign.callConv();
- CallConv& cc = _callConv;
+ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const Environment& environment) noexcept {
+ uint32_t ccId = signature.callConv();
+ uint32_t argCount = signature.argCount();
- uint32_t argCount = sign.argCount();
if (ASMJIT_UNLIKELY(argCount > Globals::kMaxFuncArgs))
return DebugUtils::errored(kErrorInvalidArgument);
- ASMJIT_PROPAGATE(cc.init(ccId));
+ CallConv& cc = _callConv;
+ ASMJIT_PROPAGATE(cc.init(ccId, environment));
- uint32_t gpSize = (cc.archId() == ArchInfo::kIdX86) ? 4 : 8;
- uint32_t deabstractDelta = Type::deabstractDeltaOfSize(gpSize);
+ uint32_t registerSize = Environment::registerSizeFromArch(cc.arch());
+ uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize);
- const uint8_t* args = sign.args();
+ const uint8_t* args = signature.args();
for (uint32_t i = 0; i < argCount; i++) {
FuncValue& arg = _args[i];
arg.initTypeId(Type::deabstract(args[i], deabstractDelta));
}
_argCount = uint8_t(argCount);
- _vaIndex = uint8_t(sign.vaIndex());
+ _vaIndex = uint8_t(signature.vaIndex());
- uint32_t ret = sign.ret();
+ uint32_t ret = signature.ret();
if (ret != Type::kIdVoid) {
_rets[0].initTypeId(Type::deabstract(ret, deabstractDelta));
_retCount = 1;
}
#ifdef ASMJIT_BUILD_X86
- if (CallConv::isX86Family(ccId))
- return x86::X86Internal::initFuncDetail(*this, sign, gpSize);
+ if (environment.isFamilyX86())
+ return x86::X86Internal::initFuncDetail(*this, signature, registerSize);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (CallConv::isArmFamily(ccId))
- return arm::ArmInternal::initFuncDetail(*this, sign, gpSize);
+ if (environment.isFamilyARM())
+ return arm::ArmInternal::initFuncDetail(*this, signature, registerSize);
#endif
// We should never bubble here as if `cc.init()` succeeded then there has to
@@ -89,15 +89,13 @@ ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) {
// ============================================================================
ASMJIT_FAVOR_SIZE Error FuncFrame::init(const FuncDetail& func) noexcept {
- uint32_t ccId = func.callConv().id();
-
#ifdef ASMJIT_BUILD_X86
- if (CallConv::isX86Family(ccId))
+ if (Environment::isFamilyX86(func.callConv().arch()))
return x86::X86Internal::initFuncFrame(*this, func);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (CallConv::isArmFamily(ccId))
+ if (Environment::isFamilyARM(func.callConv().arch()))
return arm::ArmInternal::initFuncFrame(*this, func);
#endif
@@ -106,12 +104,12 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::init(const FuncDetail& func) noexcept {
ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId()))
+ if (Environment::isFamilyX86(arch()))
return x86::X86Internal::finalizeFuncFrame(*this);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId()))
+ if (Environment::isFamilyARM(arch()))
return arm::ArmInternal::finalizeFuncFrame(*this);
#endif
@@ -123,18 +121,19 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
// ============================================================================
ASMJIT_FAVOR_SIZE Error FuncArgsAssignment::updateFuncFrame(FuncFrame& frame) const noexcept {
+ uint32_t arch = frame.arch();
const FuncDetail* func = funcDetail();
- if (!func) return DebugUtils::errored(kErrorInvalidState);
- uint32_t ccId = func->callConv().id();
+ if (!func)
+ return DebugUtils::errored(kErrorInvalidState);
#ifdef ASMJIT_BUILD_X86
- if (CallConv::isX86Family(ccId))
+ if (Environment::isFamilyX86(arch))
return x86::X86Internal::argsToFuncFrame(*this, frame);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (CallConv::isArmFamily(ccId))
+ if (Environment::isFamilyARM(arch))
return arm::ArmInternal::argsToFuncFrame(*this, frame);
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/func.h b/3rdparty/asmjit/src/asmjit/core/func.h
index 36ebf9bb526..9c45c1f8b3d 100644
--- a/3rdparty/asmjit/src/asmjit/core/func.h
+++ b/3rdparty/asmjit/src/asmjit/core/func.h
@@ -26,13 +26,14 @@
#include "../core/arch.h"
#include "../core/callconv.h"
+#include "../core/environment.h"
#include "../core/operand.h"
#include "../core/type.h"
#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_func
+//! \addtogroup asmjit_function
//! \{
// ============================================================================
@@ -365,7 +366,7 @@ public:
inline FuncDetail(const FuncDetail& other) noexcept = default;
//! Initializes this `FuncDetail` to the given signature.
- ASMJIT_API Error init(const FuncSignature& sign);
+ ASMJIT_API Error init(const FuncSignature& signature, const Environment& environment) noexcept;
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
//! \}
@@ -472,12 +473,13 @@ public:
//! frame. The function frame in most cases won't use all of the properties
//! illustrated (for example Spill Zone and Red Zone are never used together).
//!
+//! ```
//! +-----------------------------+
//! | Arguments Passed by Stack |
//! +-----------------------------+
//! | Spill Zone |
//! +-----------------------------+ <- Stack offset (args) starts from here.
-//! | Return Address if Pushed |
+//! | Return Address, if Pushed |
//! +-----------------------------+ <- Stack pointer (SP) upon entry.
//! | Save/Restore Stack. |
//! +-----------------------------+-----------------------------+
@@ -487,32 +489,42 @@ public:
//! +-----------------------------+-----------------------------+ <- SP after prolog.
//! | Red Zone |
//! +-----------------------------+
+//! ```
class FuncFrame {
public:
enum Tag : uint32_t {
- kTagInvalidOffset = 0xFFFFFFFFu //!< Tag used to inform that some offset is invalid.
+ //! Tag used to inform that some offset is invalid.
+ kTagInvalidOffset = 0xFFFFFFFFu
};
//! Attributes are designed in a way that all are initially false, and user
//! or FuncFrame finalizer adds them when necessary.
enum Attributes : uint32_t {
- kAttrHasVarArgs = 0x00000001u, //!< Function has variable number of arguments.
- kAttrHasPreservedFP = 0x00000010u, //!< Preserve frame pointer (don't omit FP).
- kAttrHasFuncCalls = 0x00000020u, //!< Function calls other functions (is not leaf).
-
- kAttrX86AvxEnabled = 0x00010000u, //!< Use AVX instead of SSE for all operations (X86).
- kAttrX86AvxCleanup = 0x00020000u, //!< Emit VZEROUPPER instruction in epilog (X86).
- kAttrX86MmxCleanup = 0x00040000u, //!< Emit EMMS instruction in epilog (X86).
-
- kAttrAlignedVecSR = 0x40000000u, //!< Function has aligned save/restore of vector registers.
- kAttrIsFinalized = 0x80000000u //!< FuncFrame is finalized and can be used by PEI.
+ //! Function has variable number of arguments.
+ kAttrHasVarArgs = 0x00000001u,
+ //! Preserve frame pointer (don't omit FP).
+ kAttrHasPreservedFP = 0x00000010u,
+ //! Function calls other functions (is not leaf).
+ kAttrHasFuncCalls = 0x00000020u,
+
+ //! Use AVX instead of SSE for all operations (X86).
+ kAttrX86AvxEnabled = 0x00010000u,
+ //! Emit VZEROUPPER instruction in epilog (X86).
+ kAttrX86AvxCleanup = 0x00020000u,
+ //! Emit EMMS instruction in epilog (X86).
+ kAttrX86MmxCleanup = 0x00040000u,
+
+ //! Function has aligned save/restore of vector registers.
+ kAttrAlignedVecSR = 0x40000000u,
+ //! FuncFrame is finalized and can be used by PEI.
+ kAttrIsFinalized = 0x80000000u
};
//! Function attributes.
uint32_t _attributes;
- //! Architecture ID.
- uint8_t _archId;
+ //! Architecture, see \ref Environment::Arch.
+ uint8_t _arch;
//! SP register ID (to access call stack and local stack).
uint8_t _spRegId;
//! SA register ID (to access stack arguments).
@@ -591,7 +603,7 @@ public:
//! \{
//! Returns the target architecture of the function frame.
- inline uint32_t archId() const noexcept { return _archId; }
+ inline uint32_t arch() const noexcept { return _arch; }
//! Returns function frame attributes, see `Attributes`.
inline uint32_t attributes() const noexcept { return _attributes; }
@@ -784,10 +796,8 @@ public:
}
inline void setAllDirty() noexcept {
- _dirtyRegs[0] = 0xFFFFFFFFu;
- _dirtyRegs[1] = 0xFFFFFFFFu;
- _dirtyRegs[2] = 0xFFFFFFFFu;
- _dirtyRegs[3] = 0xFFFFFFFFu;
+ for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_dirtyRegs); i++)
+ _dirtyRegs[i] = 0xFFFFFFFFu;
}
inline void setAllDirty(uint32_t group) noexcept {
diff --git a/3rdparty/asmjit/src/asmjit/core/globals.cpp b/3rdparty/asmjit/src/asmjit/core/globals.cpp
index 426fce8f533..7ec66283e80 100644
--- a/3rdparty/asmjit/src/asmjit/core/globals.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/globals.cpp
@@ -33,75 +33,88 @@ ASMJIT_BEGIN_NAMESPACE
ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
#ifndef ASMJIT_NO_TEXT
- static const char errorMessages[] =
+ // @EnumStringBegin{"enum": "ErrorCode", "output": "sError", "strip": "kError"}@
+ static const char sErrorString[] =
"Ok\0"
- "Out of memory\0"
- "Invalid argument\0"
- "Invalid state\0"
- "Invalid architecture\0"
- "Not initialized\0"
- "Already initialized\0"
- "Feature not enabled\0"
- "Too many handles or file descriptors\0"
- "Too large (code or memory request)\0"
- "No code generated\0"
- "Invalid directive\0"
- "Invalid label\0"
- "Too many labels\0"
- "Label already bound\0"
- "Label already defined\0"
- "Label name too long\0"
- "Invalid label name\0"
- "Invalid parent label\0"
- "Non-local label can't have parent\0"
- "Invalid section\0"
- "Too many sections\0"
- "Invalid section name\0"
- "Too many relocations\0"
- "Invalid relocation entry\0"
- "Relocation offset out of range\0"
- "Invalid assignment\0"
- "Invalid instruction\0"
- "Invalid register type\0"
- "Invalid register group\0"
- "Invalid register physical id\0"
- "Invalid register virtual id\0"
- "Invalid prefix combination\0"
- "Invalid lock prefix\0"
- "Invalid xacquire prefix\0"
- "Invalid xrelease prefix\0"
- "Invalid rep prefix\0"
- "Invalid rex prefix\0"
- "Invalid {...} register \0"
- "Invalid use of {k}\0"
- "Invalid use of {k}{z}\0"
- "Invalid broadcast {1tox}\0"
- "Invalid {er} or {sae} option\0"
- "Invalid address\0"
- "Invalid address index\0"
- "Invalid address scale\0"
- "Invalid use of 64-bit address or offset\0"
- "Invalid use of 64-bit address or offset that requires 32-bit zero-extension\0"
- "Invalid displacement\0"
- "Invalid segment\0"
- "Invalid immediate value\0"
- "Invalid operand size\0"
- "Ambiguous operand size\0"
- "Operand size mismatch\0"
- "Invalid option\0"
- "Option already defined\0"
- "Invalid type-info\0"
- "Invalid use of a low 8-bit GPB register\0"
- "Invalid use of a 64-bit GPQ register in 32-bit mode\0"
- "Invalid use of an 80-bit float\0"
- "Not consecutive registers\0"
- "No more physical registers\0"
- "Overlapped registers\0"
- "Overlapping register and arguments base-address register\0"
- "Unbound label cannot be evaluated by expression\0"
- "Arithmetic overflow during expression evaluation\0"
- "Unknown error\0";
- return Support::findPackedString(errorMessages, Support::min<Error>(err, kErrorCount));
+ "OutOfMemory\0"
+ "InvalidArgument\0"
+ "InvalidState\0"
+ "InvalidArch\0"
+ "NotInitialized\0"
+ "AlreadyInitialized\0"
+ "FeatureNotEnabled\0"
+ "TooManyHandles\0"
+ "TooLarge\0"
+ "NoCodeGenerated\0"
+ "InvalidDirective\0"
+ "InvalidLabel\0"
+ "TooManyLabels\0"
+ "LabelAlreadyBound\0"
+ "LabelAlreadyDefined\0"
+ "LabelNameTooLong\0"
+ "InvalidLabelName\0"
+ "InvalidParentLabel\0"
+ "NonLocalLabelCannotHaveParent\0"
+ "InvalidSection\0"
+ "TooManySections\0"
+ "InvalidSectionName\0"
+ "TooManyRelocations\0"
+ "InvalidRelocEntry\0"
+ "RelocOffsetOutOfRange\0"
+ "InvalidAssignment\0"
+ "InvalidInstruction\0"
+ "InvalidRegType\0"
+ "InvalidRegGroup\0"
+ "InvalidPhysId\0"
+ "InvalidVirtId\0"
+ "InvalidPrefixCombination\0"
+ "InvalidLockPrefix\0"
+ "InvalidXAcquirePrefix\0"
+ "InvalidXReleasePrefix\0"
+ "InvalidRepPrefix\0"
+ "InvalidRexPrefix\0"
+ "InvalidExtraReg\0"
+ "InvalidKMaskUse\0"
+ "InvalidKZeroUse\0"
+ "InvalidBroadcast\0"
+ "InvalidEROrSAE\0"
+ "InvalidAddress\0"
+ "InvalidAddressIndex\0"
+ "InvalidAddressScale\0"
+ "InvalidAddress64Bit\0"
+ "InvalidAddress64BitZeroExtension\0"
+ "InvalidDisplacement\0"
+ "InvalidSegment\0"
+ "InvalidImmediate\0"
+ "InvalidOperandSize\0"
+ "AmbiguousOperandSize\0"
+ "OperandSizeMismatch\0"
+ "InvalidOption\0"
+ "OptionAlreadyDefined\0"
+ "InvalidTypeId\0"
+ "InvalidUseOfGpbHi\0"
+ "InvalidUseOfGpq\0"
+ "InvalidUseOfF80\0"
+ "NotConsecutiveRegs\0"
+ "IllegalVirtReg\0"
+ "TooManyVirtRegs\0"
+ "NoMorePhysRegs\0"
+ "OverlappedRegs\0"
+ "OverlappingStackRegWithRegArg\0"
+ "ExpressionLabelNotBound\0"
+ "ExpressionOverflow\0"
+ "<Unknown>\0";
+
+ static const uint16_t sErrorIndex[] = {
+ 0, 3, 15, 31, 44, 56, 71, 90, 108, 123, 132, 148, 165, 178, 192, 210, 230,
+ 247, 264, 283, 313, 328, 344, 363, 382, 400, 422, 440, 459, 474, 490, 504,
+ 518, 543, 561, 583, 605, 622, 639, 655, 671, 687, 704, 719, 734, 754, 774,
+ 794, 827, 847, 862, 879, 898, 919, 939, 953, 974, 988, 1006, 1022, 1038,
+ 1057, 1072, 1088, 1103, 1118, 1148, 1172, 1191
+ };
+ // @EnumStringEnd@
+
+ return sErrorString + sErrorIndex[Support::min<Error>(err, kErrorCount)];
#else
DebugUtils::unused(err);
static const char noMessage[] = "";
diff --git a/3rdparty/asmjit/src/asmjit/core/globals.h b/3rdparty/asmjit/src/asmjit/core/globals.h
index 6373b7e8c6a..67a8769a403 100644
--- a/3rdparty/asmjit/src/asmjit/core/globals.h
+++ b/3rdparty/asmjit/src/asmjit/core/globals.h
@@ -33,7 +33,7 @@ ASMJIT_BEGIN_NAMESPACE
// ============================================================================
//! \cond INTERNAL
-//! \addtogroup Support
+//! \addtogroup asmjit_utilities
//! \{
namespace Support {
//! Cast designed to cast between function and void* pointers.
@@ -88,9 +88,9 @@ constexpr uint32_t kAllocAlignment = 8;
//! Aggressive growing strategy threshold.
constexpr uint32_t kGrowThreshold = 1024 * 1024 * 16;
-//! Maximum height of RB-Tree is:
+//! Maximum depth of RB-Tree is:
//!
-//! `2 * log2(n + 1)`.
+//! `2 * log2(n + 1)`
//!
//! Size of RB node is at least two pointers (without data),
//! so a theoretical architecture limit would be:
@@ -104,7 +104,7 @@ constexpr uint32_t kMaxTreeHeight = (ASMJIT_ARCH_BITS == 32 ? 30 : 61) + 1;
//! Maximum number of operands per a single instruction.
constexpr uint32_t kMaxOpCount = 6;
-// TODO: Use this one.
+//! Maximum arguments of a function supported by the Compiler / Function API.
constexpr uint32_t kMaxFuncArgs = 16;
//! Maximum number of physical registers AsmJit can use per register group.
@@ -169,14 +169,45 @@ static const constexpr NoInit_ NoInit {};
} // {Globals}
// ============================================================================
+// [asmjit::ByteOrder]
+// ============================================================================
+
+//! Byte order.
+namespace ByteOrder {
+ enum : uint32_t {
+ kLE = 0,
+ kBE = 1,
+ kNative = ASMJIT_ARCH_LE ? kLE : kBE,
+ kSwapped = ASMJIT_ARCH_LE ? kBE : kLE
+ };
+}
+
+// ============================================================================
+// [asmjit::ptr_as_func / func_as_ptr]
+// ============================================================================
+
+template<typename Func>
+static inline Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl<Func, void*>(func); }
+
+template<typename Func>
+static inline void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_impl<void*, Func>(func); }
+
+//! \}
+
+// ============================================================================
// [asmjit::Error]
// ============================================================================
+//! \addtogroup asmjit_error_handling
+//! \{
+
//! AsmJit error type (uint32_t).
typedef uint32_t Error;
//! AsmJit error codes.
enum ErrorCode : uint32_t {
+ // @EnumValuesBegin{"enum": "ErrorCode"}@
+
//! No error (success).
kErrorOk = 0,
@@ -211,16 +242,16 @@ enum ErrorCode : uint32_t {
//! No code generated.
//!
- //! Returned by runtime if the `CodeHolder` contains no code.
+ //! Returned by runtime if the \ref CodeHolder contains no code.
kErrorNoCodeGenerated,
//! Invalid directive.
kErrorInvalidDirective,
//! Attempt to use uninitialized label.
kErrorInvalidLabel,
- //! Label index overflow - a single `Assembler` instance can hold almost
- //! 2^32 (4 billion) labels. If there is an attempt to create more labels
- //! then this error is returned.
+ //! Label index overflow - a single \ref BaseAssembler instance can hold
+ //! almost 2^32 (4 billion) labels. If there is an attempt to create more
+ //! labels then this error is returned.
kErrorTooManyLabels,
//! Label is already bound.
kErrorLabelAlreadyBound,
@@ -230,10 +261,10 @@ enum ErrorCode : uint32_t {
kErrorLabelNameTooLong,
//! Label must always be local if it's anonymous (without a name).
kErrorInvalidLabelName,
- //! Parent id passed to `CodeHolder::newNamedLabelId()` was invalid.
+ //! Parent id passed to \ref CodeHolder::newNamedLabelEntry() was invalid.
kErrorInvalidParentLabel,
//! Parent id specified for a non-local (global) label.
- kErrorNonLocalLabelCantHaveParent,
+ kErrorNonLocalLabelCannotHaveParent,
//! Invalid section.
kErrorInvalidSection,
@@ -257,9 +288,9 @@ enum ErrorCode : uint32_t {
kErrorInvalidRegType,
//! Invalid register group.
kErrorInvalidRegGroup,
- //! Invalid register's physical id.
+ //! Invalid physical register id.
kErrorInvalidPhysId,
- //! Invalid register's virtual id.
+ //! Invalid virtual register id.
kErrorInvalidVirtId,
//! Invalid prefix combination.
kErrorInvalidPrefixCombination,
@@ -319,11 +350,17 @@ enum ErrorCode : uint32_t {
kErrorInvalidUseOfGpbHi,
//! Invalid use of a 64-bit GPQ register in 32-bit mode.
kErrorInvalidUseOfGpq,
- //! Invalid use of an 80-bit float (Type::kIdF80).
+ //! Invalid use of an 80-bit float (\ref Type::kIdF80).
kErrorInvalidUseOfF80,
- //! Some registers in the instruction muse be consecutive (some ARM and AVX512 neural-net instructions).
+ //! Some registers in the instruction muse be consecutive (some ARM and AVX512
+ //! neural-net instructions).
kErrorNotConsecutiveRegs,
+ //! Illegal virtual register - reported by instruction validation.
+ kErrorIllegalVirtReg,
+ //! AsmJit cannot create more virtual registers.
+ kErrorTooManyVirtRegs,
+
//! AsmJit requires a physical register, but no one is available.
kErrorNoMorePhysRegs,
//! A variable has been assigned more than once to a function argument (BaseCompiler).
@@ -336,43 +373,24 @@ enum ErrorCode : uint32_t {
//! Arithmetic overflow during expression evaluation.
kErrorExpressionOverflow,
+ // @EnumValuesEnd@
+
//! Count of AsmJit error codes.
kErrorCount
};
// ============================================================================
-// [asmjit::ByteOrder]
-// ============================================================================
-
-//! Byte order.
-namespace ByteOrder {
- enum : uint32_t {
- kLE = 0,
- kBE = 1,
- kNative = ASMJIT_ARCH_LE ? kLE : kBE,
- kSwapped = ASMJIT_ARCH_LE ? kBE : kLE
- };
-}
-
-// ============================================================================
-// [asmjit::ptr_as_func / func_as_ptr]
-// ============================================================================
-
-template<typename Func>
-static inline Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl<Func, void*>(func); }
-template<typename Func>
-static inline void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_impl<void*, Func>(func); }
-
-// ============================================================================
// [asmjit::DebugUtils]
// ============================================================================
//! Debugging utilities.
namespace DebugUtils {
+//! \cond INTERNAL
//! Used to silence warnings about unused arguments or variables.
template<typename... Args>
static ASMJIT_INLINE void unused(Args&&...) noexcept {}
+//! \endcond
//! Returns the error `err` passed.
//!
@@ -392,23 +410,35 @@ ASMJIT_API void debugOutput(const char* str) noexcept;
//! \param line Line in the source file.
//! \param msg Message to display.
//!
-//! If you have problems with assertions put a breakpoint at assertionFailed()
-//! function (asmjit/core/globals.cpp) and check the call stack to locate the
-//! failing code.
+//! If you have problems with assertion failures a breakpoint can be put
+//! at \ref assertionFailed() function (asmjit/core/globals.cpp). A call stack
+//! will be available when such assertion failure is triggered. AsmJit always
+//! returns errors on failures, assertions are a last resort and usually mean
+//! unrecoverable state due to out of range array access or totally invalid
+//! arguments like nullptr where a valid pointer should be provided, etc...
ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, const char* msg) noexcept;
+} // {DebugUtils}
+
+//! \def ASMJIT_ASSERT(...)
+//!
+//! AsmJit's own assert macro used in AsmJit code-base.
#if defined(ASMJIT_BUILD_DEBUG)
-#define ASMJIT_ASSERT(EXP) \
+#define ASMJIT_ASSERT(...) \
do { \
- if (ASMJIT_LIKELY(EXP)) \
+ if (ASMJIT_LIKELY(__VA_ARGS__)) \
break; \
- ::asmjit::DebugUtils::assertionFailed(__FILE__, __LINE__, #EXP); \
+ ::asmjit::DebugUtils::assertionFailed(__FILE__, __LINE__, #__VA_ARGS__); \
} while (0)
#else
-#define ASMJIT_ASSERT(EXP) ((void)0)
+#define ASMJIT_ASSERT(...) ((void)0)
#endif
-//! Used by AsmJit to propagate a possible `Error` produced by `...` to the caller.
+//! \def ASMJIT_PROPAGATE(...)
+//!
+//! Propagates a possible `Error` produced by `...` to the caller by returning
+//! the error immediately. Used by AsmJit internally, but kept public for users
+//! that want to use the same technique to propagate errors to the caller.
#define ASMJIT_PROPAGATE(...) \
do { \
::asmjit::Error _err = __VA_ARGS__; \
@@ -416,8 +446,6 @@ ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, cons
return _err; \
} while (0)
-} // {DebugUtils}
-
//! \}
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/inst.cpp b/3rdparty/asmjit/src/asmjit/core/inst.cpp
index d89c29f1917..a233b9383bf 100644
--- a/3rdparty/asmjit/src/asmjit/core/inst.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/inst.cpp
@@ -42,29 +42,29 @@ ASMJIT_BEGIN_NAMESPACE
// ============================================================================
#ifndef ASMJIT_NO_TEXT
-Error InstAPI::instIdToString(uint32_t archId, uint32_t instId, String& output) noexcept {
+Error InstAPI::instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept {
#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::InstInternal::instIdToString(archId, instId, output);
+ if (Environment::isFamilyX86(arch))
+ return x86::InstInternal::instIdToString(arch, instId, output);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::InstInternal::instIdToString(archId, instId, output);
+ if (Environment::isFamilyARM(arch))
+ return arm::InstInternal::instIdToString(arch, instId, output);
#endif
return DebugUtils::errored(kErrorInvalidArch);
}
-uint32_t InstAPI::stringToInstId(uint32_t archId, const char* s, size_t len) noexcept {
+uint32_t InstAPI::stringToInstId(uint32_t arch, const char* s, size_t len) noexcept {
#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::InstInternal::stringToInstId(archId, s, len);
+ if (Environment::isFamilyX86(arch))
+ return x86::InstInternal::stringToInstId(arch, s, len);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::InstInternal::stringToInstId(archId, s, len);
+ if (Environment::isFamilyARM(arch))
+ return arm::InstInternal::stringToInstId(arch, s, len);
#endif
return 0;
@@ -76,15 +76,15 @@ uint32_t InstAPI::stringToInstId(uint32_t archId, const char* s, size_t len) noe
// ============================================================================
#ifndef ASMJIT_NO_VALIDATION
-Error InstAPI::validate(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept {
+Error InstAPI::validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept {
#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::InstInternal::validate(archId, inst, operands, opCount);
+ if (Environment::isFamilyX86(arch))
+ return x86::InstInternal::validate(arch, inst, operands, opCount, validationFlags);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::InstInternal::validate(archId, inst, operands, opCount);
+ if (Environment::isFamilyARM(arch))
+ return arm::InstInternal::validate(arch, inst, operands, opCount, validationFlags);
#endif
return DebugUtils::errored(kErrorInvalidArch);
@@ -96,18 +96,18 @@ Error InstAPI::validate(uint32_t archId, const BaseInst& inst, const Operand_* o
// ============================================================================
#ifndef ASMJIT_NO_INTROSPECTION
-Error InstAPI::queryRWInfo(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, InstRWInfo& out) noexcept {
- if (ASMJIT_UNLIKELY(opCount > 6))
+Error InstAPI::queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
+ if (ASMJIT_UNLIKELY(opCount > Globals::kMaxOpCount))
return DebugUtils::errored(kErrorInvalidArgument);
#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::InstInternal::queryRWInfo(archId, inst, operands, opCount, out);
+ if (Environment::isFamilyX86(arch))
+ return x86::InstInternal::queryRWInfo(arch, inst, operands, opCount, out);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::InstInternal::queryRWInfo(archId, inst, operands, opCount, out);
+ if (Environment::isFamilyARM(arch))
+ return arm::InstInternal::queryRWInfo(arch, inst, operands, opCount, out);
#endif
return DebugUtils::errored(kErrorInvalidArch);
@@ -119,15 +119,15 @@ Error InstAPI::queryRWInfo(uint32_t archId, const BaseInst& inst, const Operand_
// ============================================================================
#ifndef ASMJIT_NO_INTROSPECTION
-Error InstAPI::queryFeatures(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, BaseFeatures& out) noexcept {
+Error InstAPI::queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept {
#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::InstInternal::queryFeatures(archId, inst, operands, opCount, out);
+ if (Environment::isFamilyX86(arch))
+ return x86::InstInternal::queryFeatures(arch, inst, operands, opCount, out);
#endif
#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::InstInternal::queryFeatures(archId, inst, operands, opCount, out);
+ if (Environment::isFamilyARM(arch))
+ return arm::InstInternal::queryFeatures(arch, inst, operands, opCount, out);
#endif
return DebugUtils::errored(kErrorInvalidArch);
diff --git a/3rdparty/asmjit/src/asmjit/core/inst.h b/3rdparty/asmjit/src/asmjit/core/inst.h
index 91671822043..e34f93c87f1 100644
--- a/3rdparty/asmjit/src/asmjit/core/inst.h
+++ b/3rdparty/asmjit/src/asmjit/core/inst.h
@@ -31,45 +31,173 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_core
+//! \addtogroup asmjit_instruction_db
//! \{
// ============================================================================
-// [asmjit::InstInfo]
+// [asmjit::BaseInst]
// ============================================================================
-// TODO: Finalize instruction info and make more x86::InstDB methods/structs private.
+//! Instruction id, options, and extraReg in a single structure. This structure
+//! exists mainly to simplify analysis and validation API that requires `BaseInst`
+//! and `Operand[]` array.
+class BaseInst {
+public:
+ //! Instruction id, see \ref BaseInst::Id or {arch-specific}::Inst::Id.
+ uint32_t _id;
+ //! Instruction options, see \ref BaseInst::Options or {arch-specific}::Inst::Options.
+ uint32_t _options;
+ //! Extra register used by instruction (either REP register or AVX-512 selector).
+ RegOnly _extraReg;
-/*
+ enum Id : uint32_t {
+ //! Invalid or uninitialized instruction id.
+ kIdNone = 0x00000000u,
+ //! Abstract instruction (BaseBuilder and BaseCompiler).
+ kIdAbstract = 0x80000000u
+ };
+
+ enum Options : uint32_t {
+ //! Used internally by emitters for handling errors and rare cases.
+ kOptionReserved = 0x00000001u,
+
+ //! Prevents following a jump during compilation (BaseCompiler).
+ kOptionUnfollow = 0x00000010u,
-struct InstInfo {
- //! Architecture agnostic attributes.
- enum Attributes : uint32_t {
+ //! Overwrite the destination operand(s) (BaseCompiler).
+ //!
+ //! Hint that is important for register liveness analysis. It tells the
+ //! compiler that the destination operand will be overwritten now or by
+ //! adjacent instructions. BaseCompiler knows when a register is completely
+ //! overwritten by a single instruction, for example you don't have to
+ //! mark "movaps" or "pxor x, x", however, if a pair of instructions is
+ //! used and the first of them doesn't completely overwrite the content
+ //! of the destination, BaseCompiler fails to mark that register as dead.
+ //!
+ //! X86 Specific
+ //! ------------
+ //!
+ //! - All instructions that always overwrite at least the size of the
+ //! register the virtual-register uses , for example "mov", "movq",
+ //! "movaps" don't need the overwrite option to be used - conversion,
+ //! shuffle, and other miscellaneous instructions included.
+ //!
+ //! - All instructions that clear the destination register if all operands
+ //! are the same, for example "xor x, x", "pcmpeqb x x", etc...
+ //!
+ //! - Consecutive instructions that partially overwrite the variable until
+ //! there is no old content require `BaseCompiler::overwrite()` to be used.
+ //! Some examples (not always the best use cases thought):
+ //!
+ //! - `movlps xmm0, ?` followed by `movhps xmm0, ?` and vice versa
+ //! - `movlpd xmm0, ?` followed by `movhpd xmm0, ?` and vice versa
+ //! - `mov al, ?` followed by `and ax, 0xFF`
+ //! - `mov al, ?` followed by `mov ah, al`
+ //! - `pinsrq xmm0, ?, 0` followed by `pinsrq xmm0, ?, 1`
+ //!
+ //! - If allocated variable is used temporarily for scalar operations. For
+ //! example if you allocate a full vector like `x86::Compiler::newXmm()`
+ //! and then use that vector for scalar operations you should use
+ //! `overwrite()` directive:
+ //!
+ //! - `sqrtss x, y` - only LO element of `x` is changed, if you don't
+ //! use HI elements, use `compiler.overwrite().sqrtss(x, y)`.
+ kOptionOverwrite = 0x00000020u,
+ //! Emit short-form of the instruction.
+ kOptionShortForm = 0x00000040u,
+ //! Emit long-form of the instruction.
+ kOptionLongForm = 0x00000080u,
+ //! Conditional jump is likely to be taken.
+ kOptionTaken = 0x00000100u,
+ //! Conditional jump is unlikely to be taken.
+ kOptionNotTaken = 0x00000200u
};
- //! Instruction attributes.
- uint32_t _attributes;
+ //! Control type.
+ enum ControlType : uint32_t {
+ //! No control type (doesn't jump).
+ kControlNone = 0u,
+ //! Unconditional jump.
+ kControlJump = 1u,
+ //! Conditional jump (branch).
+ kControlBranch = 2u,
+ //! Function call.
+ kControlCall = 3u,
+ //! Function return.
+ kControlReturn = 4u
+ };
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ //! \name Construction & Destruction
+ //! \{
- inline uint32_t attributes() const noexcept { return _attributes; }
- inline bool hasAttribute(uint32_t attr) const noexcept { return (_attributes & attr) != 0; }
-};
+ //! Creates a new BaseInst instance with `id` and `options` set.
+ //!
+ //! Default values of `id` and `options` are zero, which means none instruciton.
+ //! Such instruction is guaranteed to never exist for any architecture supported
+ //! by AsmJit.
+ inline explicit BaseInst(uint32_t id = 0, uint32_t options = 0) noexcept
+ : _id(id),
+ _options(options),
+ _extraReg() {}
+
+ inline BaseInst(uint32_t id, uint32_t options, const RegOnly& extraReg) noexcept
+ : _id(id),
+ _options(options),
+ _extraReg(extraReg) {}
+
+ inline BaseInst(uint32_t id, uint32_t options, const BaseReg& extraReg) noexcept
+ : _id(id),
+ _options(options),
+ _extraReg { extraReg.signature(), extraReg.id() } {}
+
+ //! \}
-//! Gets attributes of the given instruction.
-ASMJIT_API Error queryCommonInfo(uint32_t archId, uint32_t instId, InstInfo& out) noexcept;
+ //! \name Instruction ID
+ //! \{
+
+ //! Returns the instruction id.
+ inline uint32_t id() const noexcept { return _id; }
+ //! Sets the instruction id to the given `id`.
+ inline void setId(uint32_t id) noexcept { _id = id; }
+ //! Resets the instruction id to zero, see \ref kIdNone.
+ inline void resetId() noexcept { _id = 0; }
+
+ //! \}
-*/
+ //! \name Instruction Options
+ //! \{
+
+ inline uint32_t options() const noexcept { return _options; }
+ inline bool hasOption(uint32_t option) const noexcept { return (_options & option) != 0; }
+ inline void setOptions(uint32_t options) noexcept { _options = options; }
+ inline void addOptions(uint32_t options) noexcept { _options |= options; }
+ inline void clearOptions(uint32_t options) noexcept { _options &= ~options; }
+ inline void resetOptions() noexcept { _options = 0; }
+
+ //! \}
+
+ //! \name Extra Register
+ //! \{
+
+ inline bool hasExtraReg() const noexcept { return _extraReg.isReg(); }
+ inline RegOnly& extraReg() noexcept { return _extraReg; }
+ inline const RegOnly& extraReg() const noexcept { return _extraReg; }
+ inline void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); }
+ inline void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
+ inline void resetExtraReg() noexcept { _extraReg.reset(); }
+
+ //! \}
+};
// ============================================================================
-// [asmjit::InstRWInfo / OpRWInfo]
+// [asmjit::OpRWInfo]
// ============================================================================
-//! Read/Write information related to a single operand, used by `InstRWInfo`.
+//! Read/Write information related to a single operand, used by \ref InstRWInfo.
struct OpRWInfo {
- //! Read/Write flags, see `OpRWInfo::Flags`.
+ //! Read/Write flags, see \ref OpRWInfo::Flags.
uint32_t _opFlags;
//! Physical register index, if required.
uint8_t _physId;
@@ -87,18 +215,12 @@ struct OpRWInfo {
//! Flags describe how the operand is accessed and some additional information.
enum Flags : uint32_t {
//! Operand is read.
- //!
- //! \note This flag must be `0x00000001`.
kRead = 0x00000001u,
//! Operand is written.
- //!
- //! \note This flag must be `0x00000002`.
kWrite = 0x00000002u,
//! Operand is both read and written.
- //!
- //! \note This combination of flags must be `0x00000003`.
kRW = 0x00000003u,
//! Register operand can be replaced by a memory operand.
@@ -107,9 +229,9 @@ struct OpRWInfo {
//! The `extendByteMask()` represents a zero extension.
kZExt = 0x00000010u,
- //! Register operand must use `physId()`.
+ //! Register operand must use \ref physId().
kRegPhysId = 0x00000100u,
- //! Base register of a memory operand must use `physId()`.
+ //! Base register of a memory operand must use \ref physId().
kMemPhysId = 0x00000200u,
//! This memory operand is only used to encode registers and doesn't access memory.
@@ -140,6 +262,8 @@ struct OpRWInfo {
kMemBasePostModify = 0x00020000u
};
+ // Don't remove these asserts. Read/Write flags are used extensively
+ // by Compiler and they must always be compatible with constants below.
static_assert(kRead == 0x1, "OpRWInfo::kRead flag must be 0x1");
static_assert(kWrite == 0x2, "OpRWInfo::kWrite flag must be 0x2");
static_assert(kRegMem == 0x4, "OpRWInfo::kRegMem flag must be 0x4");
@@ -147,7 +271,11 @@ struct OpRWInfo {
//! \name Reset
//! \{
+ //! Resets this operand information to all zeros.
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+
+ //! Resets this operand info (resets all members) and set common information
+ //! to the given `opFlags`, `regSize`, and possibly `physId`.
inline void reset(uint32_t opFlags, uint32_t regSize, uint32_t physId = BaseReg::kIdBad) noexcept {
_opFlags = opFlags;
_physId = uint8_t(physId);
@@ -169,35 +297,96 @@ struct OpRWInfo {
//! \name Operand Flags
//! \{
+ //! Returns operand flags, see \ref Flags.
inline uint32_t opFlags() const noexcept { return _opFlags; }
+ //! Tests whether operand flags contain the given `flag`.
inline bool hasOpFlag(uint32_t flag) const noexcept { return (_opFlags & flag) != 0; }
+ //! Adds the given `flags` to operand flags.
inline void addOpFlags(uint32_t flags) noexcept { _opFlags |= flags; }
+ //! Removes the given `flags` from operand flags.
inline void clearOpFlags(uint32_t flags) noexcept { _opFlags &= ~flags; }
+ //! Tests whether this operand is read from.
inline bool isRead() const noexcept { return hasOpFlag(kRead); }
+ //! Tests whether this operand is written to.
inline bool isWrite() const noexcept { return hasOpFlag(kWrite); }
+ //! Tests whether this operand is both read and write.
inline bool isReadWrite() const noexcept { return (_opFlags & kRW) == kRW; }
+ //! Tests whether this operand is read only.
inline bool isReadOnly() const noexcept { return (_opFlags & kRW) == kRead; }
+ //! Tests whether this operand is write only.
inline bool isWriteOnly() const noexcept { return (_opFlags & kRW) == kWrite; }
+
+ //! Tests whether this operand is Reg/Mem
+ //!
+ //! Reg/Mem operands can use either register or memory.
inline bool isRm() const noexcept { return hasOpFlag(kRegMem); }
+
+ //! Tests whether the operand will be zero extended.
inline bool isZExt() const noexcept { return hasOpFlag(kZExt); }
//! \}
+ //! \name Memory Flags
+ //! \{
+
+ //! Tests whether this is a fake memory operand, which is only used, because
+ //! of encoding. Fake memory operands do not access any memory, they are only
+ //! used to encode registers.
+ inline bool isMemFake() const noexcept { return hasOpFlag(kMemFake); }
+
+ //! Tests whether the instruction reads from its BASE registers.
+ inline bool isMemBaseRead() const noexcept { return hasOpFlag(kMemBaseRead); }
+ //! Tests whether the instruction writes to its BASE registers.
+ inline bool isMemBaseWrite() const noexcept { return hasOpFlag(kMemBaseWrite); }
+ //! Tests whether the instruction reads and writes from/to its BASE registers.
+ inline bool isMemBaseReadWrite() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseRW; }
+ //! Tests whether the instruction only reads from its BASE registers.
+ inline bool isMemBaseReadOnly() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseRead; }
+ //! Tests whether the instruction only writes to its BASE registers.
+ inline bool isMemBaseWriteOnly() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseWrite; }
+
+ //! Tests whether the instruction modifies the BASE register before it uses
+ //! it to calculate the target address.
+ inline bool isMemBasePreModify() const noexcept { return hasOpFlag(kMemBasePreModify); }
+ //! Tests whether the instruction modifies the BASE register after it uses
+ //! it to calculate the target address.
+ inline bool isMemBasePostModify() const noexcept { return hasOpFlag(kMemBasePostModify); }
+
+ //! Tests whether the instruction reads the INDEX registers.
+ inline bool isMemIndexRead() const noexcept { return hasOpFlag(kMemIndexRead); }
+ //! Tests whether the instruction writes to its INDEX registers.
+ inline bool isMemIndexWrite() const noexcept { return hasOpFlag(kMemIndexWrite); }
+ //! Tests whether the instruction reads and writes from/to its INDEX registers.
+ inline bool isMemIndexReadWrite() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexRW; }
+ //! Tests whether the instruction only reads from its INDEX registers.
+ inline bool isMemIndexReadOnly() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexRead; }
+ //! Tests whether the instruction only writes to its INDEX registers.
+ inline bool isMemIndexWriteOnly() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexWrite; }
+
+ //! \}
+
//! \name Physical Register ID
//! \{
+ //! Returns a physical id of the register that is fixed for this operand.
+ //!
+ //! Returns \ref BaseReg::kIdBad if any register can be used.
inline uint32_t physId() const noexcept { return _physId; }
+ //! Tests whether \ref physId() would return a valid physical register id.
inline bool hasPhysId() const noexcept { return _physId != BaseReg::kIdBad; }
+ //! Sets physical register id, which would be fixed for this operand.
inline void setPhysId(uint32_t physId) noexcept { _physId = uint8_t(physId); }
//! \}
- //! \name Reg/Mem
+ //! \name Reg/Mem Information
//! \{
+ //! Returns Reg/Mem size of the operand.
inline uint32_t rmSize() const noexcept { return _rmSize; }
+ //! Sets Reg/Mem size of the operand.
inline void setRmSize(uint32_t rmSize) noexcept { _rmSize = uint8_t(rmSize); }
//! \}
@@ -205,46 +394,76 @@ struct OpRWInfo {
//! \name Read & Write Masks
//! \{
+ //! Returns read mask.
inline uint64_t readByteMask() const noexcept { return _readByteMask; }
+ //! Returns write mask.
inline uint64_t writeByteMask() const noexcept { return _writeByteMask; }
+ //! Returns extend mask.
inline uint64_t extendByteMask() const noexcept { return _extendByteMask; }
+ //! Sets read mask.
inline void setReadByteMask(uint64_t mask) noexcept { _readByteMask = mask; }
+ //! Sets write mask.
inline void setWriteByteMask(uint64_t mask) noexcept { _writeByteMask = mask; }
+ //! Sets externd mask.
inline void setExtendByteMask(uint64_t mask) noexcept { _extendByteMask = mask; }
//! \}
};
+// ============================================================================
+// [asmjit::InstRWInfo]
+// ============================================================================
+
//! Read/Write information of an instruction.
struct InstRWInfo {
- //! Instruction flags.
+ //! Instruction flags (there are no flags at the moment, this field is reserved).
uint32_t _instFlags;
- //! Mask of flags read.
+ //! Mask of CPU flags read.
uint32_t _readFlags;
- //! Mask of flags written.
+ //! Mask of CPU flags written.
uint32_t _writeFlags;
//! Count of operands.
uint8_t _opCount;
//! CPU feature required for replacing register operand with memory operand.
uint8_t _rmFeature;
//! Reserved for future use.
- uint8_t _reserved[19];
+ uint8_t _reserved[18];
//! Read/Write onfo of extra register (rep{} or kz{}).
OpRWInfo _extraReg;
//! Read/Write info of instruction operands.
OpRWInfo _operands[Globals::kMaxOpCount];
+ //! \name Commons
+ //! \{
+
+ //! Resets this RW information to all zeros.
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ //! \}
+
+ //! \name Instruction Flags
+ //!
+ //! \{
+
inline uint32_t instFlags() const noexcept { return _instFlags; }
inline bool hasInstFlag(uint32_t flag) const noexcept { return (_instFlags & flag) != 0; }
- inline uint32_t opCount() const noexcept { return _opCount; }
+ //! }
+ //! \name CPU Flags Read/Write Information
+ //! \{
+
+ //! Returns read flags of the instruction.
inline uint32_t readFlags() const noexcept { return _readFlags; }
+ //! Returns write flags of the instruction.
inline uint32_t writeFlags() const noexcept { return _writeFlags; }
+ //! \}
+
+ //! \name Reg/Mem Information
+ //! \{
+
//! Returns the CPU feature required to replace a register operand with memory
//! operand. If the returned feature is zero (none) then this instruction
//! either doesn't provide memory operand combination or there is no extra
@@ -259,166 +478,25 @@ struct InstRWInfo {
//! 'reg/mem/imm' combination.
inline uint32_t rmFeature() const noexcept { return _rmFeature; }
+ //! \}
+
+ //! \name Operand Read/Write Information
+ //! \{
+
+ //! Returns RW information of extra register operand (extraReg).
inline const OpRWInfo& extraReg() const noexcept { return _extraReg; }
+
+ //! Returns RW information of all instruction's operands.
inline const OpRWInfo* operands() const noexcept { return _operands; }
+ //! Returns RW information of the operand at the given `index`.
inline const OpRWInfo& operand(size_t index) const noexcept {
ASMJIT_ASSERT(index < Globals::kMaxOpCount);
return _operands[index];
}
-};
-
-// ============================================================================
-// [asmjit::BaseInst]
-// ============================================================================
-
-//! Instruction id, options, and extraReg in a single structure. This structure
-//! exists mainly to simplify analysis and validation API that requires `BaseInst`
-//! and `Operand[]` array.
-class BaseInst {
-public:
- //! Instruction id.
- uint32_t _id;
- //! Instruction options.
- uint32_t _options;
- //! Extra register used by instruction (either REP register or AVX-512 selector).
- RegOnly _extraReg;
-
- enum Id : uint32_t {
- //! Invalid or uninitialized instruction id.
- kIdNone = 0x00000000u,
- //! Abstract instruction (BaseBuilder and BaseCompiler).
- kIdAbstract = 0x80000000u
- };
-
- enum Options : uint32_t {
- //! Used internally by emitters for handling errors and rare cases.
- kOptionReserved = 0x00000001u,
-
- //! Used only by Assembler to mark that `_op4` and `_op5` are used (internal).
- //!
- //! TODO: This should be removed in the future.
- kOptionOp4Op5Used = 0x00000002u,
-
- //! Prevents following a jump during compilation (BaseCompiler).
- //!
- //! TODO: This should be renamed to kOptionNoReturn.
- kOptionUnfollow = 0x00000010u,
-
- //! Overwrite the destination operand(s) (BaseCompiler).
- //!
- //! Hint that is important for register liveness analysis. It tells the
- //! compiler that the destination operand will be overwritten now or by
- //! adjacent instructions. BaseCompiler knows when a register is completely
- //! overwritten by a single instruction, for example you don't have to
- //! mark "movaps" or "pxor x, x", however, if a pair of instructions is
- //! used and the first of them doesn't completely overwrite the content
- //! of the destination, BaseCompiler fails to mark that register as dead.
- //!
- //! X86 Specific
- //! ------------
- //!
- //! - All instructions that always overwrite at least the size of the
- //! register the virtual-register uses , for example "mov", "movq",
- //! "movaps" don't need the overwrite option to be used - conversion,
- //! shuffle, and other miscellaneous instructions included.
- //!
- //! - All instructions that clear the destination register if all operands
- //! are the same, for example "xor x, x", "pcmpeqb x x", etc...
- //!
- //! - Consecutive instructions that partially overwrite the variable until
- //! there is no old content require `BaseCompiler::overwrite()` to be used.
- //! Some examples (not always the best use cases thought):
- //!
- //! - `movlps xmm0, ?` followed by `movhps xmm0, ?` and vice versa
- //! - `movlpd xmm0, ?` followed by `movhpd xmm0, ?` and vice versa
- //! - `mov al, ?` followed by `and ax, 0xFF`
- //! - `mov al, ?` followed by `mov ah, al`
- //! - `pinsrq xmm0, ?, 0` followed by `pinsrq xmm0, ?, 1`
- //!
- //! - If allocated variable is used temporarily for scalar operations. For
- //! example if you allocate a full vector like `x86::Compiler::newXmm()`
- //! and then use that vector for scalar operations you should use
- //! `overwrite()` directive:
- //!
- //! - `sqrtss x, y` - only LO element of `x` is changed, if you don't
- //! use HI elements, use `compiler.overwrite().sqrtss(x, y)`.
- kOptionOverwrite = 0x00000020u,
-
- //! Emit short-form of the instruction.
- kOptionShortForm = 0x00000040u,
- //! Emit long-form of the instruction.
- kOptionLongForm = 0x00000080u,
-
- //! Conditional jump is likely to be taken.
- kOptionTaken = 0x00000100u,
- //! Conditional jump is unlikely to be taken.
- kOptionNotTaken = 0x00000200u
- };
-
- //! Control type.
- enum ControlType : uint32_t {
- //! No control type (doesn't jump).
- kControlNone = 0u,
- //! Unconditional jump.
- kControlJump = 1u,
- //! Conditional jump (branch).
- kControlBranch = 2u,
- //! Function call.
- kControlCall = 3u,
- //! Function return.
- kControlReturn = 4u
- };
-
- //! \name Construction & Destruction
- //! \{
- inline explicit BaseInst(uint32_t id = 0, uint32_t options = 0) noexcept
- : _id(id),
- _options(options),
- _extraReg() {}
-
- inline BaseInst(uint32_t id, uint32_t options, const RegOnly& extraReg) noexcept
- : _id(id),
- _options(options),
- _extraReg(extraReg) {}
-
- inline BaseInst(uint32_t id, uint32_t options, const BaseReg& extraReg) noexcept
- : _id(id),
- _options(options),
- _extraReg { extraReg.signature(), extraReg.id() } {}
-
- //! \}
-
- //! \name Instruction ID
- //! \{
-
- inline uint32_t id() const noexcept { return _id; }
- inline void setId(uint32_t id) noexcept { _id = id; }
- inline void resetId() noexcept { _id = 0; }
-
- //! \}
-
- //! \name Instruction Options
- //! \{
-
- inline uint32_t options() const noexcept { return _options; }
- inline void setOptions(uint32_t options) noexcept { _options = options; }
- inline void addOptions(uint32_t options) noexcept { _options |= options; }
- inline void clearOptions(uint32_t options) noexcept { _options &= ~options; }
- inline void resetOptions() noexcept { _options = 0; }
-
- //! \}
-
- //! \name Extra Register
- //! \{
-
- inline bool hasExtraReg() const noexcept { return _extraReg.isReg(); }
- inline RegOnly& extraReg() noexcept { return _extraReg; }
- inline const RegOnly& extraReg() const noexcept { return _extraReg; }
- inline void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); }
- inline void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
- inline void resetExtraReg() noexcept { _extraReg.reset(); }
+ //! Returns the number of operands this instruction has.
+ inline uint32_t opCount() const noexcept { return _opCount; }
//! \}
};
@@ -430,6 +508,12 @@ public:
//! Instruction API.
namespace InstAPI {
+//! Validation flags that can be used with \ref InstAPI::validate().
+enum ValidationFlags : uint32_t {
+ //! Allow virtual registers in the instruction.
+ kValidationFlagVirtRegs = 0x01u
+};
+
#ifndef ASMJIT_NO_TEXT
//! Appends the name of the instruction specified by `instId` and `instOptions`
//! into the `output` string.
@@ -437,27 +521,29 @@ namespace InstAPI {
//! \note Instruction options would only affect instruction prefix & suffix,
//! other options would be ignored. If `instOptions` is zero then only raw
//! instruction name (without any additional text) will be appended.
-ASMJIT_API Error instIdToString(uint32_t archId, uint32_t instId, String& output) noexcept;
+ASMJIT_API Error instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept;
//! Parses an instruction name in the given string `s`. Length is specified
//! by `len` argument, which can be `SIZE_MAX` if `s` is known to be null
//! terminated.
//!
-//! The output is stored in `instId`.
-ASMJIT_API uint32_t stringToInstId(uint32_t archId, const char* s, size_t len) noexcept;
+//! Returns the parsed instruction id or \ref BaseInst::kIdNone if no such
+//! instruction exists.
+ASMJIT_API uint32_t stringToInstId(uint32_t arch, const char* s, size_t len) noexcept;
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_VALIDATION
-//! Validates the given instruction.
-ASMJIT_API Error validate(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept;
+//! Validates the given instruction considering the validation `flags`, see
+//! \ref ValidationFlags.
+ASMJIT_API Error validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags = 0) noexcept;
#endif // !ASMJIT_NO_VALIDATION
#ifndef ASMJIT_NO_INTROSPECTION
//! Gets Read/Write information of the given instruction.
-ASMJIT_API Error queryRWInfo(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, InstRWInfo& out) noexcept;
+ASMJIT_API Error queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
//! Gets CPU features required by the given instruction.
-ASMJIT_API Error queryFeatures(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, BaseFeatures& out) noexcept;
+ASMJIT_API Error queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept;
#endif // !ASMJIT_NO_INTROSPECTION
} // {InstAPI}
diff --git a/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp b/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp
index a8ca0c3d75a..b2285113d3d 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp
@@ -26,7 +26,7 @@
#include "../core/arch.h"
#include "../core/jitallocator.h"
-#include "../core/osutils.h"
+#include "../core/osutils_p.h"
#include "../core/support.h"
#include "../core/virtmem.h"
#include "../core/zone.h"
@@ -938,7 +938,7 @@ public:
// Helper class to verify that JitAllocator doesn't return addresses that overlap.
class JitAllocatorWrapper {
public:
- explicit inline JitAllocatorWrapper(const JitAllocator::CreateParams* params) noexcept
+ inline explicit JitAllocatorWrapper(const JitAllocator::CreateParams* params) noexcept
: _zone(1024 * 1024),
_heap(&_zone),
_allocator(params) {}
diff --git a/3rdparty/asmjit/src/asmjit/core/jitallocator.h b/3rdparty/asmjit/src/asmjit/core/jitallocator.h
index 111716ed59e..9cd0a1f7b7e 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitallocator.h
+++ b/3rdparty/asmjit/src/asmjit/core/jitallocator.h
@@ -32,7 +32,7 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_jit
+//! \addtogroup asmjit_virtual_memory
//! \{
// ============================================================================
@@ -132,9 +132,6 @@ public:
//! JitAllocator allocator(&params);
//! ```
struct CreateParams {
- // Reset the content of `CreateParams`.
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
-
//! Allocator options, see \ref JitAllocator::Options.
//!
//! No options are used by default.
@@ -161,6 +158,9 @@ public:
//!
//! Only used if \ref kOptionCustomFillPattern is set.
uint32_t fillPattern;
+
+ // Reset the content of `CreateParams`.
+ inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
};
//! Creates a `JitAllocator` instance.
@@ -221,6 +221,15 @@ public:
//! Statistics about `JitAllocator`.
struct Statistics {
+ //! Number of blocks `JitAllocator` maintains.
+ size_t _blockCount;
+ //! How many bytes are currently used / allocated.
+ size_t _usedSize;
+ //! How many bytes are currently reserved by the allocator.
+ size_t _reservedSize;
+ //! Allocation overhead (in bytes) required to maintain all blocks.
+ size_t _overheadSize;
+
inline void reset() noexcept {
_blockCount = 0;
_usedSize = 0;
@@ -251,15 +260,6 @@ public:
inline double overheadSizeAsPercent() const noexcept {
return (double(overheadSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
}
-
- //! Number of blocks `JitAllocator` maintains.
- size_t _blockCount;
- //! How many bytes are currently used / allocated.
- size_t _usedSize;
- //! How many bytes are currently reserved by the allocator.
- size_t _reservedSize;
- //! Allocation overhead (in bytes) required to maintain all blocks.
- size_t _overheadSize;
};
//! Returns JIT allocator statistics.
diff --git a/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp b/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp
index 625cc3d2f51..1127c866aad 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp
@@ -43,52 +43,16 @@ static inline void JitRuntime_flushInstructionCache(const void* p, size_t size)
#endif
}
-// X86 Target
-// ----------
-//
-// - 32-bit - Linux, OSX, BSD, and apparently also Haiku guarantee 16-byte
-// stack alignment. Other operating systems are assumed to have
-// 4-byte alignment by default for safety reasons.
-// - 64-bit - stack must be aligned to 16 bytes.
-//
-// ARM Target
-// ----------
-//
-// - 32-bit - Stack must be aligned to 8 bytes.
-// - 64-bit - Stack must be aligned to 16 bytes (hardware requirement).
-static inline uint32_t JitRuntime_detectNaturalStackAlignment() noexcept {
-#if ASMJIT_ARCH_BITS == 64 || \
- defined(__APPLE__ ) || \
- defined(__DragonFly__) || \
- defined(__HAIKU__ ) || \
- defined(__FreeBSD__ ) || \
- defined(__NetBSD__ ) || \
- defined(__OpenBSD__ ) || \
- defined(__bsdi__ ) || \
- defined(__linux__ )
- return 16;
-#elif ASMJIT_ARCH_ARM
- return 8;
-#else
- return uint32_t(sizeof(uintptr_t));
-#endif
-}
-
// ============================================================================
// [asmjit::JitRuntime - Construction / Destruction]
// ============================================================================
JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept
: _allocator(params) {
-
- // Setup target properties.
- _targetType = kTargetJit;
- _codeInfo._archInfo = CpuInfo::host().archInfo();
- _codeInfo._stackAlignment = uint8_t(JitRuntime_detectNaturalStackAlignment());
- _codeInfo._cdeclCallConv = CallConv::kIdHostCDecl;
- _codeInfo._stdCallConv = CallConv::kIdHostStdCall;
- _codeInfo._fastCallConv = CallConv::kIdHostFastCall;
+ _environment = hostEnvironment();
+ _environment.setFormat(Environment::kFormatJIT);
}
+
JitRuntime::~JitRuntime() noexcept {}
// ============================================================================
diff --git a/3rdparty/asmjit/src/asmjit/core/jitruntime.h b/3rdparty/asmjit/src/asmjit/core/jitruntime.h
index 97f26e7a6c1..91880e688c0 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitruntime.h
+++ b/3rdparty/asmjit/src/asmjit/core/jitruntime.h
@@ -35,7 +35,7 @@ ASMJIT_BEGIN_NAMESPACE
class CodeHolder;
-//! \addtogroup asmjit_jit
+//! \addtogroup asmjit_virtual_memory
//! \{
// ============================================================================
diff --git a/3rdparty/asmjit/src/asmjit/core/logger.cpp b/3rdparty/asmjit/src/asmjit/core/logger.cpp
new file mode 100644
index 00000000000..22e0b9af08a
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/logger.cpp
@@ -0,0 +1,124 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include "../core/api-build_p.h"
+#ifndef ASMJIT_NO_LOGGING
+
+#include "../core/logger.h"
+#include "../core/string.h"
+#include "../core/support.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+// ============================================================================
+// [asmjit::Logger - Construction / Destruction]
+// ============================================================================
+
+Logger::Logger() noexcept
+ : _options() {}
+Logger::~Logger() noexcept {}
+
+// ============================================================================
+// [asmjit::Logger - Logging]
+// ============================================================================
+
+Error Logger::logf(const char* fmt, ...) noexcept {
+ Error err;
+ va_list ap;
+
+ va_start(ap, fmt);
+ err = logv(fmt, ap);
+ va_end(ap);
+
+ return err;
+}
+
+Error Logger::logv(const char* fmt, va_list ap) noexcept {
+ StringTmp<2048> sb;
+ ASMJIT_PROPAGATE(sb.appendVFormat(fmt, ap));
+ return log(sb);
+}
+
+Error Logger::logBinary(const void* data, size_t size) noexcept {
+ static const char prefix[] = "db ";
+
+ StringTmp<256> sb;
+ sb.append(prefix, ASMJIT_ARRAY_SIZE(prefix) - 1);
+
+ size_t i = size;
+ const uint8_t* s = static_cast<const uint8_t*>(data);
+
+ while (i) {
+ uint32_t n = uint32_t(Support::min<size_t>(i, 16));
+ sb.truncate(ASMJIT_ARRAY_SIZE(prefix) - 1);
+ sb.appendHex(s, n);
+ sb.append('\n');
+ ASMJIT_PROPAGATE(log(sb));
+ s += n;
+ i -= n;
+ }
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::FileLogger - Construction / Destruction]
+// ============================================================================
+
+FileLogger::FileLogger(FILE* file) noexcept
+ : _file(file) {}
+FileLogger::~FileLogger() noexcept {}
+
+// ============================================================================
+// [asmjit::FileLogger - Logging]
+// ============================================================================
+
+Error FileLogger::_log(const char* data, size_t size) noexcept {
+ if (!_file)
+ return kErrorOk;
+
+ if (size == SIZE_MAX)
+ size = strlen(data);
+
+ fwrite(data, 1, size, _file);
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::StringLogger - Construction / Destruction]
+// ============================================================================
+
+StringLogger::StringLogger() noexcept {}
+StringLogger::~StringLogger() noexcept {}
+
+// ============================================================================
+// [asmjit::StringLogger - Logging]
+// ============================================================================
+
+Error StringLogger::_log(const char* data, size_t size) noexcept {
+ return _content.append(data, size);
+}
+
+ASMJIT_END_NAMESPACE
+
+#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/logging.h b/3rdparty/asmjit/src/asmjit/core/logger.h
index 468e3a1ba2b..2840869b476 100644
--- a/3rdparty/asmjit/src/asmjit/core/logging.h
+++ b/3rdparty/asmjit/src/asmjit/core/logger.h
@@ -26,119 +26,28 @@
#include "../core/inst.h"
#include "../core/string.h"
-
-ASMJIT_BEGIN_NAMESPACE
-
-//! \addtogroup asmjit_core
-//! \{
+#include "../core/formatter.h"
#ifndef ASMJIT_NO_LOGGING
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
-class BaseEmitter;
-class BaseReg;
-class Logger;
-struct Operand_;
-
-#ifndef ASMJIT_NO_BUILDER
-class BaseBuilder;
-class BaseNode;
-#endif
-
-// ============================================================================
-// [asmjit::FormatOptions]
-// ============================================================================
-
-class FormatOptions {
-public:
- uint32_t _flags;
- uint8_t _indentation[4];
-
- enum Flags : uint32_t {
- //! Show also binary form of each logged instruction (assembler).
- kFlagMachineCode = 0x00000001u,
- //! Show a text explanation of some immediate values.
- kFlagExplainImms = 0x00000002u,
- //! Use hexadecimal notation of immediate values.
- kFlagHexImms = 0x00000004u,
- //! Use hexadecimal notation of address offsets.
- kFlagHexOffsets = 0x00000008u,
- //! Show casts between virtual register types (compiler).
- kFlagRegCasts = 0x00000010u,
- //! Show positions associated with nodes (compiler).
- kFlagPositions = 0x00000020u,
- //! Annotate nodes that are lowered by passes.
- kFlagAnnotations = 0x00000040u,
-
- // TODO: These must go, keep this only for formatting.
- //! Show an additional output from passes.
- kFlagDebugPasses = 0x00000080u,
- //! Show an additional output from RA.
- kFlagDebugRA = 0x00000100u
- };
-
- enum IndentationType : uint32_t {
- //! Indentation used for instructions and directives.
- kIndentationCode = 0u,
- //! Indentation used for labels and function nodes.
- kIndentationLabel = 1u,
- //! Indentation used for comments (not inline comments).
- kIndentationComment = 2u,
- kIndentationReserved = 3u
- };
-
- //! \name Construction & Destruction
- //! \{
-
- constexpr FormatOptions() noexcept
- : _flags(0),
- _indentation { 0, 0, 0, 0 } {}
-
- constexpr FormatOptions(const FormatOptions& other) noexcept = default;
- inline FormatOptions& operator=(const FormatOptions& other) noexcept = default;
-
- inline void reset() noexcept {
- _flags = 0;
- _indentation[0] = 0;
- _indentation[1] = 0;
- _indentation[2] = 0;
- _indentation[3] = 0;
- }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- constexpr uint32_t flags() const noexcept { return _flags; }
- constexpr bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
- inline void setFlags(uint32_t flags) noexcept { _flags = flags; }
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
- inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
-
- constexpr uint8_t indentation(uint32_t type) const noexcept { return _indentation[type]; }
- inline void setIndentation(uint32_t type, uint32_t n) noexcept { _indentation[type] = uint8_t(n); }
- inline void resetIndentation(uint32_t type) noexcept { _indentation[type] = uint8_t(0); }
+ASMJIT_BEGIN_NAMESPACE
- //! \}
-};
+//! \addtogroup asmjit_logging
+//! \{
// ============================================================================
// [asmjit::Logger]
// ============================================================================
-//! Abstract logging interface and helpers.
+//! Logging interface.
//!
-//! This class can be inherited and reimplemented to fit into your logging
-//! subsystem. When reimplementing use `Logger::_log()` method to log into
-//! a custom stream.
+//! This class can be inherited and reimplemented to fit into your own logging
+//! needs. When reimplementing a logger use \ref Logger::_log() method to log
+//! customize the output.
//!
//! There are two `Logger` implementations offered by AsmJit:
-//! - `FileLogger` - allows to log into `FILE*`.
-//! - `StringLogger` - logs into a `String`.
+//! - \ref FileLogger - logs into a `FILE*`.
+//! - \ref StringLogger - concatenates all logs into a \ref String.
class ASMJIT_VIRTAPI Logger {
public:
ASMJIT_BASE_CLASS(Logger)
@@ -160,17 +69,28 @@ public:
//! \name Format Options
//! \{
+ //! Returns \ref FormatOptions of this logger.
inline FormatOptions& options() noexcept { return _options; }
+ //! \overload
inline const FormatOptions& options() const noexcept { return _options; }
+ //! Returns formatting flags, see \ref FormatOptions::Flags.
inline uint32_t flags() const noexcept { return _options.flags(); }
+ //! Tests whether the logger has the given `flag` enabled.
inline bool hasFlag(uint32_t flag) const noexcept { return _options.hasFlag(flag); }
+ //! Sets formatting flags to `flags`, see \ref FormatOptions::Flags.
inline void setFlags(uint32_t flags) noexcept { _options.setFlags(flags); }
+ //! Enables the given formatting `flags`, see \ref FormatOptions::Flags.
inline void addFlags(uint32_t flags) noexcept { _options.addFlags(flags); }
+ //! Disables the given formatting `flags`, see \ref FormatOptions::Flags.
inline void clearFlags(uint32_t flags) noexcept { _options.clearFlags(flags); }
+ //! Returns indentation of `type`, see \ref FormatOptions::IndentationType.
inline uint32_t indentation(uint32_t type) const noexcept { return _options.indentation(type); }
+ //! Sets indentation of the given indentation `type` to `n` spaces, see \ref
+ //! FormatOptions::IndentationType.
inline void setIndentation(uint32_t type, uint32_t n) noexcept { _options.setIndentation(type, n); }
+ //! Resets indentation of the given indentation `type` to 0 spaces.
inline void resetIndentation(uint32_t type) noexcept { _options.resetIndentation(type); }
//! \}
@@ -179,6 +99,11 @@ public:
//! \{
//! Logs `str` - must be reimplemented.
+ //!
+ //! The function can accept either a null terminated string if `size` is
+ //! `SIZE_MAX` or a non-null terminated string of the given `size`. The
+ //! function cannot assume that the data is null terminated and must handle
+ //! non-null terminated inputs.
virtual Error _log(const char* data, size_t size) noexcept = 0;
//! Logs string `str`, which is either null terminated or having size `size`.
@@ -186,15 +111,15 @@ public:
//! Logs content of a string `str`.
inline Error log(const String& str) noexcept { return _log(str.data(), str.size()); }
- //! Formats the message by using `snprintf()` and then sends the result
- //! to `log()`.
+ //! Formats the message by using `snprintf()` and then passes the formatted
+ //! string to \ref _log().
ASMJIT_API Error logf(const char* fmt, ...) noexcept;
- //! Formats the message by using `vsnprintf()` and then sends the result
- //! to `log()`.
+ //! Formats the message by using `vsnprintf()` and then passes the formatted
+ //! string to \ref _log().
ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept;
- //! Logs binary data.
+ //! Logs binary `data` of the given `size`.
ASMJIT_API Error logBinary(const void* data, size_t size) noexcept;
//! \}
@@ -267,6 +192,13 @@ public:
//! \name Logger Data Accessors
//! \{
+ //! Returns the content of the logger as \ref String.
+ //!
+ //! It can be moved, if desired.
+ inline String& content() noexcept { return _content; }
+ //! \overload
+ inline const String& content() const noexcept { return _content; }
+
//! Returns aggregated logger data as `char*` pointer.
//!
//! The pointer is owned by `StringLogger`, it can't be modified or freed.
@@ -287,69 +219,10 @@ public:
ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override;
};
-// ============================================================================
-// [asmjit::Logging]
-// ============================================================================
-
-struct Logging {
- ASMJIT_API static Error formatRegister(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- uint32_t regType,
- uint32_t regId) noexcept;
-
- ASMJIT_API static Error formatLabel(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t labelId) noexcept;
-
- ASMJIT_API static Error formatOperand(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- const Operand_& op) noexcept;
-
- ASMJIT_API static Error formatInstruction(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept;
-
- ASMJIT_API static Error formatTypeId(
- String& sb,
- uint32_t typeId) noexcept;
-
-#ifndef ASMJIT_NO_BUILDER
- ASMJIT_API static Error formatNode(
- String& sb,
- uint32_t flags,
- const BaseBuilder* cb,
- const BaseNode* node_) noexcept;
-#endif
-
- // Only used by AsmJit internals, not available to users.
-#ifdef ASMJIT_EXPORTS
- enum {
- // Has to be big to be able to hold all metadata compiler can assign to a
- // single instruction.
- kMaxInstLineSize = 44,
- kMaxBinarySize = 26
- };
-
- static Error formatLine(
- String& sb,
- const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept;
-#endif
-};
-#endif
-
//! \}
ASMJIT_END_NAMESPACE
+#endif
+
#endif // ASMJIT_CORE_LOGGER_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/logging.cpp b/3rdparty/asmjit/src/asmjit/core/logging.cpp
deleted file mode 100644
index 7e10af27c2d..00000000000
--- a/3rdparty/asmjit/src/asmjit/core/logging.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-#include "../core/api-build_p.h"
-#ifndef ASMJIT_NO_LOGGING
-
-#include "../core/builder.h"
-#include "../core/codeholder.h"
-#include "../core/compiler.h"
-#include "../core/emitter.h"
-#include "../core/logging.h"
-#include "../core/string.h"
-#include "../core/support.h"
-#include "../core/type.h"
-
-#ifdef ASMJIT_BUILD_X86
- #include "../x86/x86logging_p.h"
-#endif
-
-#ifdef ASMJIT_BUILD_ARM
- #include "../arm/armlogging_p.h"
-#endif
-
-ASMJIT_BEGIN_NAMESPACE
-
-#if defined(ASMJIT_NO_COMPILER)
-class VirtReg;
-#endif
-
-// ============================================================================
-// [asmjit::Logger - Construction / Destruction]
-// ============================================================================
-
-Logger::Logger() noexcept
- : _options() {}
-Logger::~Logger() noexcept {}
-
-// ============================================================================
-// [asmjit::Logger - Logging]
-// ============================================================================
-
-Error Logger::logf(const char* fmt, ...) noexcept {
- Error err;
- va_list ap;
-
- va_start(ap, fmt);
- err = logv(fmt, ap);
- va_end(ap);
-
- return err;
-}
-
-Error Logger::logv(const char* fmt, va_list ap) noexcept {
- StringTmp<2048> sb;
- ASMJIT_PROPAGATE(sb.appendVFormat(fmt, ap));
- return log(sb);
-}
-
-Error Logger::logBinary(const void* data, size_t size) noexcept {
- static const char prefix[] = "db ";
-
- StringTmp<256> sb;
- sb.appendString(prefix, ASMJIT_ARRAY_SIZE(prefix) - 1);
-
- size_t i = size;
- const uint8_t* s = static_cast<const uint8_t*>(data);
-
- while (i) {
- uint32_t n = uint32_t(Support::min<size_t>(i, 16));
- sb.truncate(ASMJIT_ARRAY_SIZE(prefix) - 1);
- sb.appendHex(s, n);
- sb.appendChar('\n');
- ASMJIT_PROPAGATE(log(sb));
- s += n;
- i -= n;
- }
-
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::FileLogger - Construction / Destruction]
-// ============================================================================
-
-FileLogger::FileLogger(FILE* file) noexcept
- : _file(nullptr) { setFile(file); }
-FileLogger::~FileLogger() noexcept {}
-
-// ============================================================================
-// [asmjit::FileLogger - Logging]
-// ============================================================================
-
-Error FileLogger::_log(const char* data, size_t size) noexcept {
- if (!_file)
- return kErrorOk;
-
- if (size == SIZE_MAX)
- size = strlen(data);
-
- fwrite(data, 1, size, _file);
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::StringLogger - Construction / Destruction]
-// ============================================================================
-
-StringLogger::StringLogger() noexcept {}
-StringLogger::~StringLogger() noexcept {}
-
-// ============================================================================
-// [asmjit::StringLogger - Logging]
-// ============================================================================
-
-Error StringLogger::_log(const char* data, size_t size) noexcept {
- return _content.appendString(data, size);
-}
-
-// ============================================================================
-// [asmjit::Logging]
-// ============================================================================
-
-Error Logging::formatLabel(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t labelId) noexcept {
-
- DebugUtils::unused(flags);
-
- const LabelEntry* le = emitter->code()->labelEntry(labelId);
- if (ASMJIT_UNLIKELY(!le))
- return sb.appendFormat("InvalidLabel[Id=%u]", labelId);
-
- if (le->hasName()) {
- if (le->hasParent()) {
- uint32_t parentId = le->parentId();
- const LabelEntry* pe = emitter->code()->labelEntry(parentId);
-
- if (ASMJIT_UNLIKELY(!pe))
- ASMJIT_PROPAGATE(sb.appendFormat("InvalidLabel[Id=%u]", labelId));
- else if (ASMJIT_UNLIKELY(!pe->hasName()))
- ASMJIT_PROPAGATE(sb.appendFormat("L%u", parentId));
- else
- ASMJIT_PROPAGATE(sb.appendString(pe->name()));
-
- ASMJIT_PROPAGATE(sb.appendChar('.'));
- }
- return sb.appendString(le->name());
- }
- else {
- return sb.appendFormat("L%u", labelId);
- }
-}
-
-Error Logging::formatRegister(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- uint32_t regType,
- uint32_t regId) noexcept {
-
-#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::LoggingInternal::formatRegister(sb, flags, emitter, archId, regType, regId);
-#endif
-
-#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::LoggingInternal::formatRegister(sb, flags, emitter, archId, regType, regId);
-#endif
-
- return kErrorInvalidArch;
-}
-
-Error Logging::formatOperand(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- const Operand_& op) noexcept {
-
-#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::LoggingInternal::formatOperand(sb, flags, emitter, archId, op);
-#endif
-
-#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::LoggingInternal::formatOperand(sb, flags, emitter, archId, op);
-#endif
-
- return kErrorInvalidArch;
-}
-
-Error Logging::formatInstruction(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept {
-
-#ifdef ASMJIT_BUILD_X86
- if (ArchInfo::isX86Family(archId))
- return x86::LoggingInternal::formatInstruction(sb, flags, emitter, archId, inst, operands, opCount);
-#endif
-
-#ifdef ASMJIT_BUILD_ARM
- if (ArchInfo::isArmFamily(archId))
- return arm::LoggingInternal::formatInstruction(sb, flags, emitter, archId, inst, operands, opCount);
-#endif
-
- return kErrorInvalidArch;
-}
-
-Error Logging::formatTypeId(String& sb, uint32_t typeId) noexcept {
- if (typeId == Type::kIdVoid)
- return sb.appendString("void");
-
- if (!Type::isValid(typeId))
- return sb.appendString("unknown");
-
- const char* typeName = "unknown";
- uint32_t typeSize = Type::sizeOf(typeId);
-
- uint32_t baseId = Type::baseOf(typeId);
- switch (baseId) {
- case Type::kIdIntPtr : typeName = "iptr" ; break;
- case Type::kIdUIntPtr: typeName = "uptr" ; break;
- case Type::kIdI8 : typeName = "i8" ; break;
- case Type::kIdU8 : typeName = "u8" ; break;
- case Type::kIdI16 : typeName = "i16" ; break;
- case Type::kIdU16 : typeName = "u16" ; break;
- case Type::kIdI32 : typeName = "i32" ; break;
- case Type::kIdU32 : typeName = "u32" ; break;
- case Type::kIdI64 : typeName = "i64" ; break;
- case Type::kIdU64 : typeName = "u64" ; break;
- case Type::kIdF32 : typeName = "f32" ; break;
- case Type::kIdF64 : typeName = "f64" ; break;
- case Type::kIdF80 : typeName = "f80" ; break;
- case Type::kIdMask8 : typeName = "mask8" ; break;
- case Type::kIdMask16 : typeName = "mask16"; break;
- case Type::kIdMask32 : typeName = "mask32"; break;
- case Type::kIdMask64 : typeName = "mask64"; break;
- case Type::kIdMmx32 : typeName = "mmx32" ; break;
- case Type::kIdMmx64 : typeName = "mmx64" ; break;
- }
-
- uint32_t baseSize = Type::sizeOf(baseId);
- if (typeSize > baseSize) {
- uint32_t count = typeSize / baseSize;
- return sb.appendFormat("%sx%u", typeName, unsigned(count));
- }
- else {
- return sb.appendString(typeName);
- }
-
-}
-
-#ifndef ASMJIT_NO_BUILDER
-static Error formatFuncValue(String& sb, uint32_t flags, const BaseEmitter* emitter, FuncValue value) noexcept {
- uint32_t typeId = value.typeId();
- ASMJIT_PROPAGATE(Logging::formatTypeId(sb, typeId));
-
- if (value.isReg()) {
- ASMJIT_PROPAGATE(sb.appendChar('@'));
- ASMJIT_PROPAGATE(Logging::formatRegister(sb, flags, emitter, emitter->archId(), value.regType(), value.regId()));
- }
-
- if (value.isStack()) {
- ASMJIT_PROPAGATE(sb.appendFormat("@[%d]", int(value.stackOffset())));
- }
-
- return kErrorOk;
-}
-
-static Error formatFuncRets(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- const FuncDetail& fd,
- VirtReg* const* vRegs) noexcept {
-
- if (!fd.hasRet())
- return sb.appendString("void");
-
- for (uint32_t i = 0; i < fd.retCount(); i++) {
- if (i) ASMJIT_PROPAGATE(sb.appendString(", "));
- ASMJIT_PROPAGATE(formatFuncValue(sb, flags, emitter, fd.ret(i)));
-
-#ifndef ASMJIT_NO_COMPILER
- if (vRegs) {
- static const char nullRet[] = "<none>";
- ASMJIT_PROPAGATE(sb.appendFormat(" %s", vRegs[i] ? vRegs[i]->name() : nullRet));
- }
-#else
- DebugUtils::unused(vRegs);
-#endif
- }
-
- return kErrorOk;
-}
-
-static Error formatFuncArgs(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- const FuncDetail& fd,
- VirtReg* const* vRegs) noexcept {
-
- uint32_t count = fd.argCount();
- if (!count)
- return sb.appendString("void");
-
- for (uint32_t i = 0; i < count; i++) {
- if (i) ASMJIT_PROPAGATE(sb.appendString(", "));
- ASMJIT_PROPAGATE(formatFuncValue(sb, flags, emitter, fd.arg(i)));
-
-#ifndef ASMJIT_NO_COMPILER
- if (vRegs) {
- static const char nullArg[] = "<none>";
- ASMJIT_PROPAGATE(sb.appendFormat(" %s", vRegs[i] ? vRegs[i]->name() : nullArg));
- }
-#else
- DebugUtils::unused(vRegs);
-#endif
- }
-
- return kErrorOk;
-}
-
-Error Logging::formatNode(
- String& sb,
- uint32_t flags,
- const BaseBuilder* cb,
- const BaseNode* node_) noexcept {
-
- if (node_->hasPosition() && (flags & FormatOptions::kFlagPositions) != 0)
- ASMJIT_PROPAGATE(sb.appendFormat("<%05u> ", node_->position()));
-
- switch (node_->type()) {
- case BaseNode::kNodeInst:
- case BaseNode::kNodeJump: {
- const InstNode* node = node_->as<InstNode>();
- ASMJIT_PROPAGATE(
- Logging::formatInstruction(sb, flags, cb,
- cb->archId(),
- node->baseInst(), node->operands(), node->opCount()));
- break;
- }
-
- case BaseNode::kNodeSection: {
- const SectionNode* node = node_->as<SectionNode>();
- if (cb->_code->isSectionValid(node->id())) {
- const Section* section = cb->_code->sectionById(node->id());
- ASMJIT_PROPAGATE(sb.appendFormat(".section %s", section->name()));
- }
- break;
- }
-
- case BaseNode::kNodeLabel: {
- const LabelNode* node = node_->as<LabelNode>();
- ASMJIT_PROPAGATE(formatLabel(sb, flags, cb, node->id()));
- ASMJIT_PROPAGATE(sb.appendString(":"));
- break;
- }
-
- case BaseNode::kNodeAlign: {
- const AlignNode* node = node_->as<AlignNode>();
- ASMJIT_PROPAGATE(
- sb.appendFormat(".align %u (%s)",
- node->alignment(),
- node->alignMode() == kAlignCode ? "code" : "data"));
- break;
- }
-
- case BaseNode::kNodeEmbedData: {
- const EmbedDataNode* node = node_->as<EmbedDataNode>();
- ASMJIT_PROPAGATE(sb.appendFormat(".embed (%u bytes)", node->size()));
- break;
- }
-
- case BaseNode::kNodeEmbedLabel: {
- const EmbedLabelNode* node = node_->as<EmbedLabelNode>();
- ASMJIT_PROPAGATE(sb.appendString(".label "));
- ASMJIT_PROPAGATE(formatLabel(sb, flags, cb, node->id()));
- break;
- }
-
- case BaseNode::kNodeEmbedLabelDelta: {
- const EmbedLabelDeltaNode* node = node_->as<EmbedLabelDeltaNode>();
- ASMJIT_PROPAGATE(sb.appendString(".label ("));
- ASMJIT_PROPAGATE(formatLabel(sb, flags, cb, node->id()));
- ASMJIT_PROPAGATE(sb.appendString(" - "));
- ASMJIT_PROPAGATE(formatLabel(sb, flags, cb, node->baseId()));
- ASMJIT_PROPAGATE(sb.appendString(")"));
- break;
- }
-
- case BaseNode::kNodeComment: {
- const CommentNode* node = node_->as<CommentNode>();
- ASMJIT_PROPAGATE(sb.appendFormat("; %s", node->inlineComment()));
- break;
- }
-
- case BaseNode::kNodeSentinel: {
- const SentinelNode* node = node_->as<SentinelNode>();
- const char* sentinelName = nullptr;
-
- switch (node->sentinelType()) {
- case SentinelNode::kSentinelFuncEnd:
- sentinelName = "[FuncEnd]";
- break;
-
- default:
- sentinelName = "[Sentinel]";
- break;
- }
-
- ASMJIT_PROPAGATE(sb.appendString(sentinelName));
- break;
- }
-
-#ifndef ASMJIT_NO_COMPILER
- case BaseNode::kNodeFunc: {
- const FuncNode* node = node_->as<FuncNode>();
-
- ASMJIT_PROPAGATE(formatLabel(sb, flags, cb, node->id()));
- ASMJIT_PROPAGATE(sb.appendString(": "));
-
- ASMJIT_PROPAGATE(formatFuncRets(sb, flags, cb, node->detail(), nullptr));
- ASMJIT_PROPAGATE(sb.appendString(" Func("));
- ASMJIT_PROPAGATE(formatFuncArgs(sb, flags, cb, node->detail(), node->args()));
- ASMJIT_PROPAGATE(sb.appendString(")"));
- break;
- }
-
- case BaseNode::kNodeFuncRet: {
- const FuncRetNode* node = node_->as<FuncRetNode>();
- ASMJIT_PROPAGATE(sb.appendString("[FuncRet]"));
-
- for (uint32_t i = 0; i < 2; i++) {
- const Operand_& op = node->_opArray[i];
- if (!op.isNone()) {
- ASMJIT_PROPAGATE(sb.appendString(i == 0 ? " " : ", "));
- ASMJIT_PROPAGATE(formatOperand(sb, flags, cb, cb->archId(), op));
- }
- }
- break;
- }
-
- case BaseNode::kNodeFuncCall: {
- const FuncCallNode* node = node_->as<FuncCallNode>();
- ASMJIT_PROPAGATE(
- Logging::formatInstruction(sb, flags, cb,
- cb->archId(),
- node->baseInst(), node->operands(), node->opCount()));
- break;
- }
-#endif
-
- default: {
- ASMJIT_PROPAGATE(sb.appendFormat("[User:%u]", node_->type()));
- break;
- }
- }
-
- return kErrorOk;
-}
-#endif
-
-Error Logging::formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept {
- size_t currentSize = sb.size();
- size_t commentSize = comment ? Support::strLen(comment, Globals::kMaxCommentSize) : 0;
-
- ASMJIT_ASSERT(binSize >= dispSize);
- const size_t kNoBinSize = std::numeric_limits<size_t>::max();
-
- if ((binSize != 0 && binSize != kNoBinSize) || commentSize) {
- size_t align = kMaxInstLineSize;
- char sep = ';';
-
- for (size_t i = (binSize == kNoBinSize); i < 2; i++) {
- size_t begin = sb.size();
- ASMJIT_PROPAGATE(sb.padEnd(align));
-
- if (sep) {
- ASMJIT_PROPAGATE(sb.appendChar(sep));
- ASMJIT_PROPAGATE(sb.appendChar(' '));
- }
-
- // Append binary data or comment.
- if (i == 0) {
- ASMJIT_PROPAGATE(sb.appendHex(binData, binSize - dispSize - immSize));
- ASMJIT_PROPAGATE(sb.appendChars('.', dispSize * 2));
- ASMJIT_PROPAGATE(sb.appendHex(binData + binSize - immSize, immSize));
- if (commentSize == 0) break;
- }
- else {
- ASMJIT_PROPAGATE(sb.appendString(comment, commentSize));
- }
-
- currentSize += sb.size() - begin;
- align += kMaxBinarySize;
- sep = '|';
- }
- }
-
- return sb.appendChar('\n');
-}
-
-ASMJIT_END_NAMESPACE
-
-#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/misc_p.h b/3rdparty/asmjit/src/asmjit/core/misc_p.h
index 916ca9db67c..b1056f473ae 100644
--- a/3rdparty/asmjit/src/asmjit/core/misc_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/misc_p.h
@@ -29,7 +29,7 @@
ASMJIT_BEGIN_NAMESPACE
//! \cond INTERNAL
-//! \addtogroup asmjit_support
+//! \addtogroup asmjit_utilities
//! \{
#define ASMJIT_LOOKUP_TABLE_8(T, I) T((I)), T((I+1)), T((I+2)), T((I+3)), T((I+4)), T((I+5)), T((I+6)), T((I+7))
diff --git a/3rdparty/asmjit/src/asmjit/core/operand.cpp b/3rdparty/asmjit/src/asmjit/core/operand.cpp
index 9d11f3f6ddc..46bb23a289c 100644
--- a/3rdparty/asmjit/src/asmjit/core/operand.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/operand.cpp
@@ -126,10 +126,10 @@ UNIT(operand) {
INFO("Checking basic functionality of Imm");
Imm immValue(-42);
- EXPECT(Imm(-1).i64() == int64_t(-1));
- EXPECT(imm(-1).i64() == int64_t(-1));
- EXPECT(immValue.i64() == int64_t(-42));
- EXPECT(imm(0xFFFFFFFF).i64() == int64_t(0xFFFFFFFF));
+ EXPECT(Imm(-1).value() == -1);
+ EXPECT(imm(-1).value() == -1);
+ EXPECT(immValue.value() == -42);
+ EXPECT(imm(0xFFFFFFFF).value() == int64_t(0xFFFFFFFF));
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/operand.h b/3rdparty/asmjit/src/asmjit/core/operand.h
index eee1af4244e..01cc1eaa560 100644
--- a/3rdparty/asmjit/src/asmjit/core/operand.h
+++ b/3rdparty/asmjit/src/asmjit/core/operand.h
@@ -103,7 +103,7 @@ public: \
constexpr explicit REG(uint32_t rId) noexcept \
: BASE(kSignature, rId) {}
-//! \addtogroup asmjit_core
+//! \addtogroup asmjit_assembler
//! \{
// ============================================================================
@@ -162,6 +162,16 @@ struct Operand_ {
};
static_assert(kOpMem == kOpReg + 1, "asmjit::Operand requires `kOpMem` to be `kOpReg+1`.");
+ //! Label tag.
+ enum LabelTag {
+ //! Label tag is used as a sub-type, forming a unique signature across all
+ //! operand types as 0x1 is never associated with any register type. This
+ //! means that a memory operand's BASE register can be constructed from
+ //! virtually any operand (register vs. label) by just assigning its type
+ //! (register type or label-tag) and operand id.
+ kLabelTag = 0x1
+ };
+
// \cond INTERNAL
enum SignatureBits : uint32_t {
// Operand type (3 least significant bits).
@@ -211,7 +221,6 @@ struct Operand_ {
};
//! \endcond
- //! \cond INTERNAL
//! Constants useful for VirtId <-> Index translation.
enum VirtIdConstants : uint32_t {
//! Minimum valid packed-id.
@@ -225,14 +234,12 @@ struct Operand_ {
//! Tests whether the given `id` is a valid virtual register id. Since AsmJit
//! supports both physical and virtual registers it must be able to distinguish
//! between these two. The idea is that physical registers are always limited
- //! in size, so virtual identifiers start from `kVirtIdMin` and end at
- //! `kVirtIdMax`.
+ //! in size, so virtual identifiers start from `kVirtIdMin` and end at `kVirtIdMax`.
static ASMJIT_INLINE bool isVirtId(uint32_t id) noexcept { return id - kVirtIdMin < uint32_t(kVirtIdCount); }
//! Converts a real-id into a packed-id that can be stored in Operand.
static ASMJIT_INLINE uint32_t indexToVirtId(uint32_t id) noexcept { return id + kVirtIdMin; }
//! Converts a packed-id back to real-id.
static ASMJIT_INLINE uint32_t virtIdToIndex(uint32_t id) noexcept { return id - kVirtIdMin; }
- //! \endcond
//! \name Construction & Destruction
//! \{
@@ -245,10 +252,10 @@ struct Operand_ {
_data[0] = 0;
_data[1] = 0;
}
+ //! \endcond
- //! Initializes the operand from `other` (used by operator overloads).
+ //! Initializes the operand from `other` operand (used by operator overloads).
inline void copyFrom(const Operand_& other) noexcept { memcpy(this, &other, sizeof(Operand_)); }
- //! \endcond
//! Resets the `Operand` to none.
//!
@@ -290,8 +297,10 @@ struct Operand_ {
//! \name Operator Overloads
//! \{
- constexpr bool operator==(const Operand_& other) const noexcept { return isEqual(other); }
- constexpr bool operator!=(const Operand_& other) const noexcept { return !isEqual(other); }
+ //! Tests whether this operand is the same as `other`.
+ constexpr bool operator==(const Operand_& other) const noexcept { return equals(other); }
+ //! Tests whether this operand is not the same as `other`.
+ constexpr bool operator!=(const Operand_& other) const noexcept { return !equals(other); }
//! \}
@@ -395,14 +404,22 @@ struct Operand_ {
//! initialized.
constexpr uint32_t id() const noexcept { return _baseId; }
- //! Tests whether the operand is 100% equal to `other`.
- constexpr bool isEqual(const Operand_& other) const noexcept {
+ //! Tests whether the operand is 100% equal to `other` operand.
+ //!
+ //! \note This basically performs a binary comparison, if aby bit is
+ //! different the operands are not equal.
+ constexpr bool equals(const Operand_& other) const noexcept {
return (_signature == other._signature) &
(_baseId == other._baseId ) &
(_data[0] == other._data[0] ) &
(_data[1] == other._data[1] ) ;
}
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use equals() instead")
+ constexpr bool isEqual(const Operand_& other) const noexcept { return equals(other); }
+#endif //!ASMJIT_NO_DEPRECATED
+
//! Tests whether the operand is a register matching `rType`.
constexpr bool isReg(uint32_t rType) const noexcept {
return (_signature & (kSignatureOpMask | kSignatureRegTypeMask)) ==
@@ -471,11 +488,6 @@ public:
static_assert(sizeof(Operand) == 16, "asmjit::Operand must be exactly 16 bytes long");
-namespace Globals {
- //! A default-constructed operand of `Operand_::kOpNone` type.
- static constexpr const Operand none;
-}
-
// ============================================================================
// [asmjit::Label]
// ============================================================================
@@ -519,16 +531,6 @@ public:
kTypeCount = 3
};
- // TODO: Find a better place, find a better name.
- enum {
- //! Label tag is used as a sub-type, forming a unique signature across all
- //! operand types as 0x1 is never associated with any register (reg-type).
- //! This means that a memory operand's BASE register can be constructed
- //! from virtually any operand (register vs. label) by just assigning its
- //! type (reg type or label-tag) and operand id.
- kLabelTag = 0x1
- };
-
//! \name Construction & Destruction
//! \{
@@ -536,7 +538,7 @@ public:
constexpr Label() noexcept
: Operand(Globals::Init, kOpLabel, Globals::kInvalidId, 0, 0) {}
- //! Creates a cloned label operand of `other` .
+ //! Creates a cloned label operand of `other`.
constexpr Label(const Label& other) noexcept
: Operand(other) {}
@@ -610,7 +612,7 @@ struct BaseRegTraits {
//! This information is compatible with operand's signature (32-bit integer)
//! and `RegInfo` just provides easy way to access it.
struct RegInfo {
- inline void reset() noexcept { _signature = 0; }
+ inline void reset(uint32_t signature = 0) noexcept { _signature = signature; }
inline void setSignature(uint32_t signature) noexcept { _signature = signature; }
template<uint32_t mask>
@@ -628,7 +630,7 @@ struct RegInfo {
uint32_t _signature;
};
-//! Physical/Virtual register operand.
+//! Physical or virtual register operand.
class BaseReg : public Operand {
public:
//! Architecture neutral register types.
@@ -638,7 +640,7 @@ public:
//! of a memory operand.
enum RegType : uint32_t {
//! No register - unused, invalid, multiple meanings.
- kTypeNone = 0,
+ kTypeNone = 0,
// (1 is used as a LabelTag)
@@ -736,15 +738,14 @@ public:
//! Tests whether this register is the same as `other`.
//!
//! This is just an optimization. Registers by default only use the first
- //! 8 bytes of the Operand, so this method takes advantage of this knowledge
+ //! 8 bytes of Operand data, so this method takes advantage of this knowledge
//! and only compares these 8 bytes. If both operands were created correctly
- //! then `isEqual()` and `isSame()` should give the same answer, however, if
- //! some one of the two operand contains a garbage or other metadata in the
- //! upper 8 bytes then `isSame()` may return `true` in cases where `isEqual()`
+ //! both \ref equals() and \ref isSame() should give the same answer, however,
+ //! if any of these two contains garbage or other metadata in the upper 8
+ //! bytes then \ref isSame() may return `true` in cases in which \ref equals()
//! returns false.
constexpr bool isSame(const BaseReg& other) const noexcept {
- return (_signature == other._signature) &
- (_baseId == other._baseId ) ;
+ return (_signature == other._signature) & (_baseId == other._baseId);
}
//! Tests whether the register is valid (either virtual or physical).
@@ -810,6 +811,7 @@ public:
//! \name Static Functions
//! \{
+ //! Tests whether the `op` operand is a general purpose register.
static inline bool isGp(const Operand_& op) noexcept {
// Check operand type and register group. Not interested in register type and size.
const uint32_t kSgn = (kOpReg << kSignatureOpShift ) |
@@ -817,7 +819,7 @@ public:
return (op.signature() & (kSignatureOpMask | kSignatureRegGroupMask)) == kSgn;
}
- //! Tests whether the `op` operand is either a low or high 8-bit GPB register.
+ //! Tests whether the `op` operand is a vector register.
static inline bool isVec(const Operand_& op) noexcept {
// Check operand type and register group. Not interested in register type and size.
const uint32_t kSgn = (kOpReg << kSignatureOpShift ) |
@@ -825,7 +827,9 @@ public:
return (op.signature() & (kSignatureOpMask | kSignatureRegGroupMask)) == kSgn;
}
+ //! Tests whether the `op` is a general purpose register of the given `rId`.
static inline bool isGp(const Operand_& op, uint32_t rId) noexcept { return isGp(op) & (op.id() == rId); }
+ //! Tests whether the `op` is a vector register of the given `rId`.
static inline bool isVec(const Operand_& op, uint32_t rId) noexcept { return isVec(op) & (op.id() == rId); }
//! \}
@@ -947,10 +951,14 @@ struct RegOnly {
//! index shift (scale).
class BaseMem : public Operand {
public:
+ //! Address type.
enum AddrType : uint32_t {
+ //! Default address type, Assembler will select the best type when necessary.
kAddrTypeDefault = 0,
- kAddrTypeAbs = 1,
- kAddrTypeRel = 2
+ //! Absolute address type.
+ kAddrTypeAbs = 1,
+ //! Relative address type.
+ kAddrTypeRel = 2
};
// Shortcuts.
@@ -1028,25 +1036,37 @@ public:
//! Clones the memory operand.
constexpr BaseMem clone() const noexcept { return BaseMem(*this); }
+ //! Returns the address type (see \ref AddrType) of the memory operand.
+ //!
+ //! By default, address type of newly created memory operands is always \ref kAddrTypeDefault.
constexpr uint32_t addrType() const noexcept { return _getSignaturePart<kSignatureMemAddrTypeMask>(); }
+ //! Sets the address type to `addrType`, see \ref AddrType.
inline void setAddrType(uint32_t addrType) noexcept { _setSignaturePart<kSignatureMemAddrTypeMask>(addrType); }
+ //! Resets the address type to \ref kAddrTypeDefault.
inline void resetAddrType() noexcept { _setSignaturePart<kSignatureMemAddrTypeMask>(0); }
+ //! Tests whether the address type is \ref kAddrTypeAbs.
constexpr bool isAbs() const noexcept { return addrType() == kAddrTypeAbs; }
+ //! Sets the address type to \ref kAddrTypeAbs.
inline void setAbs() noexcept { setAddrType(kAddrTypeAbs); }
+ //! Tests whether the address type is \ref kAddrTypeRel.
constexpr bool isRel() const noexcept { return addrType() == kAddrTypeRel; }
+ //! Sets the address type to \ref kAddrTypeRel.
inline void setRel() noexcept { setAddrType(kAddrTypeRel); }
+ //! Tests whether this memory operand is a register home (only used by \ref asmjit_compiler)
constexpr bool isRegHome() const noexcept { return _hasSignaturePart<kSignatureMemRegHomeFlag>(); }
+ //! Mark this memory operand as register home (only used by \ref asmjit_compiler).
inline void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; }
+ //! Marks this operand to not be a register home (only used by \ref asmjit_compiler).
inline void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; }
//! Tests whether the memory operand has a BASE register or label specified.
constexpr bool hasBase() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0; }
//! Tests whether the memory operand has an INDEX register specified.
constexpr bool hasIndex() const noexcept { return (_signature & kSignatureMemIndexTypeMask) != 0; }
- //! Tests whether the memory operand has BASE and INDEX register.
+ //! Tests whether the memory operand has BASE or INDEX register.
constexpr bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; }
//! Tests whether the memory operand has BASE and INDEX register.
constexpr bool hasBaseAndIndex() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0 && (_signature & kSignatureMemIndexTypeMask) != 0; }
@@ -1093,6 +1113,7 @@ public:
//! Sets the index register to type and id of the given `index` operand.
inline void setIndex(const BaseReg& index) noexcept { return _setIndex(index.type(), index.id()); }
+ //! \cond INTERNAL
inline void _setBase(uint32_t rType, uint32_t rId) noexcept {
_setSignaturePart<kSignatureMemBaseTypeMask>(rType);
_baseId = rId;
@@ -1102,6 +1123,7 @@ public:
_setSignaturePart<kSignatureMemIndexTypeMask>(rType);
_data[kDataMemIndexId] = rId;
}
+ //! \endcond
//! Resets the memory operand's BASE register or label.
inline void resetBase() noexcept { _setBase(0, 0); }
@@ -1159,7 +1181,7 @@ public:
//! 64-bit offset. Use it only if you know that there is a BASE register
//! and the offset is only 32 bits anyway.
- //! Adjusts the offset by a 64-bit `offset`.
+ //! Adjusts the memory operand offset by a `offset`.
inline void addOffset(int64_t offset) noexcept {
if (isOffset64Bit()) {
int64_t result = offset + int64_t(uint64_t(_data[kDataMemOffsetLo]) | (uint64_t(_baseId) << 32));
@@ -1230,77 +1252,54 @@ public:
//! \name Accessors
//! \{
- //! Returns immediate value as 8-bit signed integer, possibly cropped.
- constexpr int8_t i8() const noexcept { return int8_t(_data[kDataImmValueLo] & 0xFFu); }
- //! Returns immediate value as 8-bit unsigned integer, possibly cropped.
- constexpr uint8_t u8() const noexcept { return uint8_t(_data[kDataImmValueLo] & 0xFFu); }
- //! Returns immediate value as 16-bit signed integer, possibly cropped.
- constexpr int16_t i16() const noexcept { return int16_t(_data[kDataImmValueLo] & 0xFFFFu);}
- //! Returns immediate value as 16-bit unsigned integer, possibly cropped.
- constexpr uint16_t u16() const noexcept { return uint16_t(_data[kDataImmValueLo] & 0xFFFFu);}
- //! Returns immediate value as 32-bit signed integer, possibly cropped.
- constexpr int32_t i32() const noexcept { return int32_t(_data[kDataImmValueLo]); }
- //! Returns low 32-bit signed integer.
- constexpr int32_t i32Lo() const noexcept { return int32_t(_data[kDataImmValueLo]); }
- //! Returns high 32-bit signed integer.
- constexpr int32_t i32Hi() const noexcept { return int32_t(_data[kDataImmValueHi]); }
- //! Returns immediate value as 32-bit unsigned integer, possibly cropped.
- constexpr uint32_t u32() const noexcept { return _data[kDataImmValueLo]; }
- //! Returns low 32-bit signed integer.
- constexpr uint32_t u32Lo() const noexcept { return _data[kDataImmValueLo]; }
- //! Returns high 32-bit signed integer.
- constexpr uint32_t u32Hi() const noexcept { return _data[kDataImmValueHi]; }
- //! Returns immediate value as 64-bit signed integer.
- constexpr int64_t i64() const noexcept { return int64_t((uint64_t(_data[kDataImmValueHi]) << 32) | _data[kDataImmValueLo]); }
- //! Returns immediate value as 64-bit unsigned integer.
- constexpr uint64_t u64() const noexcept { return uint64_t(i64()); }
- //! Returns immediate value as `intptr_t`, possibly cropped if size of `intptr_t` is 32 bits.
- constexpr intptr_t iptr() const noexcept { return (sizeof(intptr_t) == sizeof(int64_t)) ? intptr_t(i64()) : intptr_t(i32()); }
- //! Returns immediate value as `uintptr_t`, possibly cropped if size of `uintptr_t` is 32 bits.
- constexpr uintptr_t uptr() const noexcept { return (sizeof(uintptr_t) == sizeof(uint64_t)) ? uintptr_t(u64()) : uintptr_t(u32()); }
+ //! Returns the immediate value as `int64_t`, which is the internal format Imm uses.
+ constexpr int64_t value() const noexcept {
+ return int64_t((uint64_t(_data[kDataImmValueHi]) << 32) | _data[kDataImmValueLo]);
+ }
//! Tests whether the immediate can be casted to 8-bit signed integer.
- constexpr bool isInt8() const noexcept { return Support::isInt8(i64()); }
+ constexpr bool isInt8() const noexcept { return Support::isInt8(value()); }
//! Tests whether the immediate can be casted to 8-bit unsigned integer.
- constexpr bool isUInt8() const noexcept { return Support::isUInt8(i64()); }
+ constexpr bool isUInt8() const noexcept { return Support::isUInt8(value()); }
//! Tests whether the immediate can be casted to 16-bit signed integer.
- constexpr bool isInt16() const noexcept { return Support::isInt16(i64()); }
+ constexpr bool isInt16() const noexcept { return Support::isInt16(value()); }
//! Tests whether the immediate can be casted to 16-bit unsigned integer.
- constexpr bool isUInt16() const noexcept { return Support::isUInt16(i64()); }
+ constexpr bool isUInt16() const noexcept { return Support::isUInt16(value()); }
//! Tests whether the immediate can be casted to 32-bit signed integer.
- constexpr bool isInt32() const noexcept { return Support::isInt32(i64()); }
+ constexpr bool isInt32() const noexcept { return Support::isInt32(value()); }
//! Tests whether the immediate can be casted to 32-bit unsigned integer.
constexpr bool isUInt32() const noexcept { return _data[kDataImmValueHi] == 0; }
- //! Sets immediate value to 8-bit signed integer `val`.
- inline void setI8(int8_t val) noexcept { setI64(val); }
- //! Sets immediate value to 8-bit unsigned integer `val`.
- inline void setU8(uint8_t val) noexcept { setU64(val); }
- //! Sets immediate value to 16-bit signed integer `val`.
- inline void setI16(int16_t val) noexcept { setI64(val); }
- //! Sets immediate value to 16-bit unsigned integer `val`.
- inline void setU16(uint16_t val) noexcept { setU64(val); }
- //! Sets immediate value to 32-bit signed integer `val`.
- inline void setI32(int32_t val) noexcept { setI64(val); }
- //! Sets immediate value to 32-bit unsigned integer `val`.
- inline void setU32(uint32_t val) noexcept { setU64(val); }
- //! Sets immediate value to 64-bit signed integer `val`.
- inline void setI64(int64_t val) noexcept {
- _data[kDataImmValueHi] = uint32_t(uint64_t(val) >> 32);
- _data[kDataImmValueLo] = uint32_t(uint64_t(val) & 0xFFFFFFFFu);
+ //! Returns the immediate value casted to `T`.
+ //!
+ //! The value is masked before it's casted to `T` so the returned value is
+ //! simply the representation of `T` considering the original value's lowest
+ //! bits.
+ template<typename T>
+ constexpr T valueAs() const noexcept {
+ return T(uint64_t(value()) & Support::allOnes<typename std::make_unsigned<T>::type>());
}
- //! Sets immediate value to 64-bit unsigned integer `val`.
- inline void setU64(uint64_t val) noexcept { setI64(int64_t(val)); }
- //! Sets immediate value to intptr_t `val`.
- inline void setIPtr(intptr_t val) noexcept { setI64(val); }
- //! Sets immediate value to uintptr_t `val`.
- inline void setUPtr(uintptr_t val) noexcept { setU64(val); }
-
- //! Sets immediate value to `val`.
+
+ //! Returns low 32-bit signed integer.
+ constexpr int32_t int32Lo() const noexcept { return int32_t(_data[kDataImmValueLo]); }
+ //! Returns high 32-bit signed integer.
+ constexpr int32_t int32Hi() const noexcept { return int32_t(_data[kDataImmValueHi]); }
+ //! Returns low 32-bit signed integer.
+ constexpr uint32_t uint32Lo() const noexcept { return _data[kDataImmValueLo]; }
+ //! Returns high 32-bit signed integer.
+ constexpr uint32_t uint32Hi() const noexcept { return _data[kDataImmValueHi]; }
+
+ //! Sets immediate value to `val`, the value is casted to a signed 64-bit integer.
template<typename T>
- inline void setValue(T val) noexcept { setI64(int64_t(Support::asNormalized(val))); }
+ inline void setValue(const T& val) noexcept {
+ int64_t val64 = int64_t(Support::asNormalized(val));
+ _data[kDataImmValueHi] = uint32_t(uint64_t(val64) >> 32);
+ _data[kDataImmValueLo] = uint32_t(uint64_t(val64) & 0xFFFFFFFFu);
+ }
- inline void setDouble(double d) noexcept { setU64(Support::bitCast<uint64_t>(d)); }
+ inline void setDouble(double d) noexcept {
+ setValue(Support::bitCast<uint64_t>(d));
+ }
//! \}
@@ -1310,15 +1309,59 @@ public:
//! Clones the immediate operand.
constexpr Imm clone() const noexcept { return Imm(*this); }
- inline void signExtend8Bits() noexcept { setI64(int64_t(i8())); }
- inline void signExtend16Bits() noexcept { setI64(int64_t(i16())); }
- inline void signExtend32Bits() noexcept { setI64(int64_t(i32())); }
+ inline void signExtend8Bits() noexcept { setValue(int64_t(valueAs<int8_t>())); }
+ inline void signExtend16Bits() noexcept { setValue(int64_t(valueAs<int16_t>())); }
+ inline void signExtend32Bits() noexcept { setValue(int64_t(valueAs<int32_t>())); }
- inline void zeroExtend8Bits() noexcept { setU64(u8()); }
- inline void zeroExtend16Bits() noexcept { setU64(u16()); }
+ inline void zeroExtend8Bits() noexcept { setValue(valueAs<uint8_t>()); }
+ inline void zeroExtend16Bits() noexcept { setValue(valueAs<uint16_t>()); }
inline void zeroExtend32Bits() noexcept { _data[kDataImmValueHi] = 0u; }
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use valueAs<int8_t>() instead")
+ inline int8_t i8() const noexcept { return valueAs<int8_t>(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<uint8_t>() instead")
+ inline uint8_t u8() const noexcept { return valueAs<uint8_t>(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<int16_t>() instead")
+ inline int16_t i16() const noexcept { return valueAs<int16_t>(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<uint16_t>() instead")
+ inline uint16_t u16() const noexcept { return valueAs<uint16_t>(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<int32_t>() instead")
+ inline int32_t i32() const noexcept { return valueAs<int32_t>(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<uint32_t>() instead")
+ inline uint32_t u32() const noexcept { return valueAs<uint32_t>(); }
+
+ ASMJIT_DEPRECATED("Use value() instead")
+ inline int64_t i64() const noexcept { return value(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<uint64_t>() instead")
+ inline uint64_t u64() const noexcept { return valueAs<uint64_t>(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<intptr_t>() instead")
+ inline intptr_t iptr() const noexcept { return valueAs<intptr_t>(); }
+
+ ASMJIT_DEPRECATED("Use valueAs<uintptr_t>() instead")
+ inline uintptr_t uptr() const noexcept { return valueAs<uintptr_t>(); }
+
+ ASMJIT_DEPRECATED("Use int32Lo() instead")
+ inline int32_t i32Lo() const noexcept { return int32Lo(); }
+
+ ASMJIT_DEPRECATED("Use uint32Lo() instead")
+ inline uint32_t u32Lo() const noexcept { return uint32Lo(); }
+
+ ASMJIT_DEPRECATED("Use int32Hi() instead")
+ inline int32_t i32Hi() const noexcept { return int32Hi(); }
+
+ ASMJIT_DEPRECATED("Use uint32Hi() instead")
+ inline uint32_t u32Hi() const noexcept { return uint32Hi(); }
+#endif // !ASMJIT_NO_DEPRECATED
};
//! Creates a new immediate operand.
@@ -1332,6 +1375,44 @@ static constexpr Imm imm(T val) noexcept {
//! \}
+// ============================================================================
+// [asmjit::Globals::none]
+// ============================================================================
+
+namespace Globals {
+ //! \ingroup asmjit_assembler
+ //!
+ //! A default-constructed operand of `Operand_::kOpNone` type.
+ static constexpr const Operand none;
+}
+
+// ============================================================================
+// [asmjit::Support::ForwardOp]
+// ============================================================================
+
+//! \cond INTERNAL
+namespace Support {
+
+template<typename T, bool IsIntegral>
+struct ForwardOpImpl {
+ static ASMJIT_INLINE const T& forward(const T& value) noexcept { return value; }
+};
+
+template<typename T>
+struct ForwardOpImpl<T, true> {
+ static ASMJIT_INLINE Imm forward(const T& value) noexcept { return Imm(value); }
+};
+
+//! Either forwards operand T or returns a new operand for T if T is a type
+//! convertible to operand. At the moment this is only used to convert integers
+//! to \ref Imm operands.
+template<typename T>
+struct ForwardOp : public ForwardOpImpl<T, std::is_integral<typename std::decay<T>::type>::value> {};
+
+}
+
+//! \endcond
+
ASMJIT_END_NAMESPACE
#endif // ASMJIT_CORE_OPERAND_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/osutils.h b/3rdparty/asmjit/src/asmjit/core/osutils.h
index b9a2df4ad8f..a4691295b20 100644
--- a/3rdparty/asmjit/src/asmjit/core/osutils.h
+++ b/3rdparty/asmjit/src/asmjit/core/osutils.h
@@ -28,7 +28,7 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_support
+//! \addtogroup asmjit_utilities
//! \{
// ============================================================================
@@ -50,7 +50,7 @@ namespace OSUtils {
//! Lock.
//!
//! Lock is internal, it cannot be used outside of AsmJit, however, its internal
-//! layout is exposed as it's used by some other public classes.
+//! layout is exposed as it's used by some other classes, which are public.
class Lock {
public:
ASMJIT_NONCOPYABLE(Lock)
@@ -78,60 +78,8 @@ public:
inline void lock() noexcept;
inline void unlock() noexcept;
};
-
-#ifdef ASMJIT_EXPORTS
-#if defined(_WIN32)
-
-// Win32 implementation.
-static_assert(sizeof(Lock::Handle) == sizeof(CRITICAL_SECTION), "asmjit::Lock::Handle layout must match CRITICAL_SECTION");
-static_assert(alignof(Lock::Handle) == alignof(CRITICAL_SECTION), "asmjit::Lock::Handle alignment must match CRITICAL_SECTION");
-
-inline Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
-inline Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
-inline void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
-inline void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
-
-#elif !defined(__EMSCRIPTEN__)
-
-// PThread implementation.
-inline Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
-inline Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); }
-inline void Lock::lock() noexcept { pthread_mutex_lock(&_handle); }
-inline void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); }
-
-#else
-
-// Dummy implementation - Emscripten or other unsupported platform.
-inline Lock::Lock() noexcept {}
-inline Lock::~Lock() noexcept {}
-inline void Lock::lock() noexcept {}
-inline void Lock::unlock() noexcept {}
-
-#endif
-#endif
-
//! \endcond
-// ============================================================================
-// [asmjit::LockGuard]
-// ============================================================================
-
-#ifdef ASMJIT_EXPORTS
-//! \cond INTERNAL
-
-//! Scoped lock.
-struct LockGuard {
- ASMJIT_NONCOPYABLE(LockGuard)
-
- Lock& _target;
-
- inline LockGuard(Lock& target) noexcept : _target(target) { _target.lock(); }
- inline ~LockGuard() noexcept { _target.unlock(); }
-};
-
-//! \endcond
-#endif
-
//! \}
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/osutils_p.h b/3rdparty/asmjit/src/asmjit/core/osutils_p.h
new file mode 100644
index 00000000000..31db308bdcf
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/osutils_p.h
@@ -0,0 +1,94 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_CORE_OSUTILS_P_H_INCLUDED
+#define ASMJIT_CORE_OSUTILS_P_H_INCLUDED
+
+#include "../core/osutils.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_utilities
+//! \{
+
+// ============================================================================
+// [asmjit::Lock]
+// ============================================================================
+
+#if defined(_WIN32)
+
+// Windows implementation.
+static_assert(sizeof(Lock::Handle) == sizeof(CRITICAL_SECTION), "asmjit::Lock::Handle layout must match CRITICAL_SECTION");
+static_assert(alignof(Lock::Handle) == alignof(CRITICAL_SECTION), "asmjit::Lock::Handle alignment must match CRITICAL_SECTION");
+
+inline Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+inline Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+inline void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+inline void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+
+#elif !defined(__EMSCRIPTEN__)
+
+// PThread implementation.
+#ifdef PTHREAD_MUTEX_INITIALIZER
+inline Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {}
+#else
+inline Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
+#endif
+inline Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); }
+inline void Lock::lock() noexcept { pthread_mutex_lock(&_handle); }
+inline void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); }
+
+#else
+
+// Dummy implementation - Emscripten or other unsupported platform.
+inline Lock::Lock() noexcept {}
+inline Lock::~Lock() noexcept {}
+inline void Lock::lock() noexcept {}
+inline void Lock::unlock() noexcept {}
+
+#endif
+
+// ============================================================================
+// [asmjit::LockGuard]
+// ============================================================================
+
+//! Scoped lock.
+class LockGuard {
+public:
+ ASMJIT_NONCOPYABLE(LockGuard)
+
+ Lock& _target;
+
+ inline LockGuard(Lock& target) noexcept
+ : _target(target) { _target.lock(); }
+ inline ~LockGuard() noexcept { _target.unlock(); }
+};
+
+//! \}
+//! \endcond
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_OSUTILS_P_H_INCLUDED
+
diff --git a/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h b/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h
index 6f400ad1c3a..50624bf58cd 100644
--- a/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h
@@ -27,6 +27,7 @@
#include "../core/api-config.h"
#ifndef ASMJIT_NO_COMPILER
+#include "../core/formatter.h"
#include "../core/rapass_p.h"
ASMJIT_BEGIN_NAMESPACE
@@ -66,7 +67,7 @@ public:
static constexpr uint32_t kCodeIndentation = 4;
// NOTE: This is a bit hacky. There are some nodes which are processed twice
- // (see `onBeforeCall()` and `onBeforeRet()`) as they can insert some nodes
+ // (see `onBeforeInvoke()` and `onBeforeRet()`) as they can insert some nodes
// around them. Since we don't have any flags to mark these we just use their
// position that is [at that time] unassigned.
static constexpr uint32_t kNodePositionDidOnBefore = 0xFFFFFFFFu;
@@ -122,7 +123,7 @@ public:
// Instruction | Jump | Invoke | Return
// ------------------------------------
- // Handle `InstNode`, `FuncCallNode`, and `FuncRetNode`. All of them
+ // Handle `InstNode`, `InvokeNode`, and `FuncRetNode`. All of them
// share the same interface that provides operands that have read/write
// semantics.
if (ASMJIT_UNLIKELY(!_curBlock)) {
@@ -135,18 +136,18 @@ public:
_hasCode = true;
- if (node->isFuncCall() || node->isFuncRet()) {
+ if (node->isInvoke() || node->isFuncRet()) {
if (node->position() != kNodePositionDidOnBefore) {
// Call and Reg are complicated as they may insert some surrounding
// code around them. The simplest approach is to get the previous
// node, call the `onBefore()` handlers and then check whether
// anything changed and restart if so. By restart we mean that the
// current `node` would go back to the first possible inserted node
- // by `onBeforeCall()` or `onBeforeRet()`.
+ // by `onBeforeInvoke()` or `onBeforeRet()`.
BaseNode* prev = node->prev();
- if (node->type() == BaseNode::kNodeFuncCall)
- ASMJIT_PROPAGATE(static_cast<This*>(this)->onBeforeCall(node->as<FuncCallNode>()));
+ if (node->type() == BaseNode::kNodeInvoke)
+ ASMJIT_PROPAGATE(static_cast<This*>(this)->onBeforeInvoke(node->as<InvokeNode>()));
else
ASMJIT_PROPAGATE(static_cast<This*>(this)->onBeforeRet(node->as<FuncRetNode>()));
@@ -159,7 +160,7 @@ public:
node->setPosition(kNodePositionDidOnBefore);
node = prev->next();
- // `onBeforeCall()` and `onBeforeRet()` can only insert instructions.
+ // `onBeforeInvoke()` and `onBeforeRet()` can only insert instructions.
ASMJIT_ASSERT(node->isInst());
}
@@ -179,8 +180,8 @@ public:
ib.reset();
ASMJIT_PROPAGATE(static_cast<This*>(this)->onInst(inst, controlType, ib));
- if (node->isFuncCall()) {
- ASMJIT_PROPAGATE(static_cast<This*>(this)->onCall(inst->as<FuncCallNode>(), ib));
+ if (node->isInvoke()) {
+ ASMJIT_PROPAGATE(static_cast<This*>(this)->onInvoke(inst->as<InvokeNode>(), ib));
}
if (node->isFuncRet()) {
@@ -409,7 +410,7 @@ public:
logNode(node, kRootIndentation);
// Unlikely: Assume that the exit label is reached only once per function.
- if (ASMJIT_UNLIKELY(node->as<LabelNode>()->id() == _exitLabelId)) {
+ if (ASMJIT_UNLIKELY(node->as<LabelNode>()->labelId() == _exitLabelId)) {
_curBlock->setLast(node);
_curBlock->makeConstructed(_blockRegStats);
ASMJIT_PROPAGATE(_pass->addExitBlock(_curBlock));
@@ -492,7 +493,7 @@ public:
// Reset everything we may need.
_blockRegStats.reset();
- _exitLabelId = func->exitNode()->id();
+ _exitLabelId = func->exitNode()->labelId();
// Initially we assume there is no code in the function body.
_hasCode = false;
@@ -599,11 +600,11 @@ public:
_sb.clear();
_sb.appendChars(' ', indentation);
if (action) {
- _sb.appendString(action);
- _sb.appendChar(' ');
+ _sb.append(action);
+ _sb.append(' ');
}
- Logging::formatNode(_sb, _logFlags, cc(), node);
- _sb.appendChar('\n');
+ Formatter::formatNode(_sb, _logFlags, cc(), node);
+ _sb.append('\n');
_logger->log(_sb);
}
#else
diff --git a/3rdparty/asmjit/src/asmjit/core/radefs_p.h b/3rdparty/asmjit/src/asmjit/core/radefs_p.h
index c63a1a33966..b77ed1bd738 100644
--- a/3rdparty/asmjit/src/asmjit/core/radefs_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/radefs_p.h
@@ -28,7 +28,7 @@
#ifndef ASMJIT_NO_COMPILER
#include "../core/compiler.h"
-#include "../core/logging.h"
+#include "../core/logger.h"
#include "../core/support.h"
#include "../core/zone.h"
#include "../core/zonevector.h"
@@ -984,10 +984,7 @@ public:
//! Stack allocation is preferred.
kFlagStackPreferred = 0x00000004u,
//! Marked for stack argument reassignment.
- kFlagStackArgToStack = 0x00000008u,
-
- // TODO: Used?
- kFlagDirtyStats = 0x80000000u
+ kFlagStackArgToStack = 0x00000008u
};
enum ArgIndex : uint32_t {
@@ -1004,7 +1001,7 @@ public:
_tiedReg(nullptr),
_stackSlot(nullptr),
_info(vReg->info()),
- _flags(kFlagDirtyStats),
+ _flags(0),
_allocatedMask(0),
_clobberSurvivalMask(0),
_regByteMask(0),
diff --git a/3rdparty/asmjit/src/asmjit/core/ralocal.cpp b/3rdparty/asmjit/src/asmjit/core/ralocal.cpp
index 98d7d8fd568..88cb86bde18 100644
--- a/3rdparty/asmjit/src/asmjit/core/ralocal.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/ralocal.cpp
@@ -596,7 +596,7 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
// DECIDE whether to MOVE or SPILL.
if (allocableRegs) {
- uint32_t reassignedId = decideOnUnassignment(group, workId, assignedId, allocableRegs);
+ uint32_t reassignedId = decideOnReassignment(group, workId, assignedId, allocableRegs);
if (reassignedId != RAAssignment::kPhysNone) {
ASMJIT_PROPAGATE(onMoveReg(group, workId, reassignedId, assignedId));
allocableRegs ^= Support::bitMask(reassignedId);
@@ -897,7 +897,7 @@ Error RALocalAllocator::allocBranch(InstNode* node, RABlock* target, RABlock* co
// Additional instructions emitted to switch from the current state to
// the `target` state. This means that we have to move these instructions
// into an independent code block and patch the jump location.
- Operand& targetOp(node->opType(node->opCount() - 1));
+ Operand& targetOp = node->op(node->opCount() - 1);
if (ASMJIT_UNLIKELY(!targetOp.isLabel()))
return DebugUtils::errored(kErrorInvalidState);
@@ -970,38 +970,39 @@ Error RALocalAllocator::allocJumpTable(InstNode* node, const RABlocks& targets,
// ============================================================================
uint32_t RALocalAllocator::decideOnAssignment(uint32_t group, uint32_t workId, uint32_t physId, uint32_t allocableRegs) const noexcept {
- DebugUtils::unused(group, physId);
ASMJIT_ASSERT(allocableRegs != 0);
+ DebugUtils::unused(group, physId);
RAWorkReg* workReg = workRegById(workId);
- // HIGHEST PRIORITY: Home register id.
+ // Prefer home register id, if possible.
if (workReg->hasHomeRegId()) {
uint32_t homeId = workReg->homeRegId();
if (Support::bitTest(allocableRegs, homeId))
return homeId;
}
- // HIGH PRIORITY: Register IDs used upon block entries.
+ // Prefer registers used upon block entries.
uint32_t previouslyAssignedRegs = workReg->allocatedMask();
if (allocableRegs & previouslyAssignedRegs)
allocableRegs &= previouslyAssignedRegs;
- if (Support::isPowerOf2(allocableRegs))
- return Support::ctz(allocableRegs);
-
- // TODO: This is not finished.
return Support::ctz(allocableRegs);
}
-uint32_t RALocalAllocator::decideOnUnassignment(uint32_t group, uint32_t workId, uint32_t physId, uint32_t allocableRegs) const noexcept {
+uint32_t RALocalAllocator::decideOnReassignment(uint32_t group, uint32_t workId, uint32_t physId, uint32_t allocableRegs) const noexcept {
ASMJIT_ASSERT(allocableRegs != 0);
+ DebugUtils::unused(group, physId);
- // TODO:
- DebugUtils::unused(allocableRegs, group, workId, physId);
+ RAWorkReg* workReg = workRegById(workId);
+
+ // Prefer allocating back to HomeId, if possible.
+ if (workReg->hasHomeRegId()) {
+ if (Support::bitTest(allocableRegs, workReg->homeRegId()))
+ return workReg->homeRegId();
+ }
- // if (!_curAssignment.isPhysDirty(group, physId)) {
- // }
+ // TODO: [Register Allocator] This could be improved.
// Decided to SPILL.
return RAAssignment::kPhysNone;
diff --git a/3rdparty/asmjit/src/asmjit/core/ralocal_p.h b/3rdparty/asmjit/src/asmjit/core/ralocal_p.h
index 0af595b3cd5..c944aad2bb4 100644
--- a/3rdparty/asmjit/src/asmjit/core/ralocal_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/ralocal_p.h
@@ -198,12 +198,13 @@ public:
//! Decides on register assignment.
uint32_t decideOnAssignment(uint32_t group, uint32_t workId, uint32_t assignedId, uint32_t allocableRegs) const noexcept;
- //! Decides on whether to MOVE or SPILL the given WorkReg.
+ //! Decides on whether to MOVE or SPILL the given WorkReg, because it's allocated
+ //! in a physical register that have to be used by another WorkReg.
//!
//! The function must return either `RAAssignment::kPhysNone`, which means that
- //! the WorkReg should be spilled, or a valid physical register ID, which means
- //! that the register should be moved to that physical register instead.
- uint32_t decideOnUnassignment(uint32_t group, uint32_t workId, uint32_t assignedId, uint32_t allocableRegs) const noexcept;
+ //! the WorkReg of `workId` should be spilled, or a valid physical register ID,
+ //! which means that the register should be moved to that physical register instead.
+ uint32_t decideOnReassignment(uint32_t group, uint32_t workId, uint32_t assignedId, uint32_t allocableRegs) const noexcept;
//! Decides on best spill given a register mask `spillableRegs`
uint32_t decideOnSpillFor(uint32_t group, uint32_t workId, uint32_t spillableRegs, uint32_t* spillWorkId) const noexcept;
diff --git a/3rdparty/asmjit/src/asmjit/core/rapass.cpp b/3rdparty/asmjit/src/asmjit/core/rapass.cpp
index 1174635d75d..c5b5ce88a16 100644
--- a/3rdparty/asmjit/src/asmjit/core/rapass.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/rapass.cpp
@@ -24,6 +24,7 @@
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_COMPILER
+#include "../core/formatter.h"
#include "../core/ralocal_p.h"
#include "../core/rapass_p.h"
#include "../core/support.h"
@@ -161,7 +162,7 @@ static void RAPass_resetVirtRegData(RAPass* self) noexcept {
}
}
-Error RAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) noexcept {
+Error RAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
_allocator.reset(zone);
#ifndef ASMJIT_NO_LOGGING
@@ -194,7 +195,6 @@ Error RAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) noexcept
// Must be called regardless of the allocation status.
onDone();
- // TODO: I don't like this...
// Reset possible connections introduced by the register allocator.
RAPass_resetVirtRegData(this);
@@ -472,7 +472,7 @@ Error RAPass::buildViews() noexcept {
if (block->hasSuccessors()) {
sb.appendFormat(" #%u -> {", block->blockId());
_dumpBlockIds(sb, block->successors());
- sb.appendString("}\n");
+ sb.append("}\n");
}
else {
sb.appendFormat(" #%u -> {Exit}\n", block->blockId());
@@ -1133,11 +1133,11 @@ static void RAPass_dumpSpans(String& sb, uint32_t index, const LiveRegSpans& liv
for (uint32_t i = 0; i < liveSpans.size(); i++) {
const LiveRegSpan& liveSpan = liveSpans[i];
- if (i) sb.appendString(", ");
+ if (i) sb.append(", ");
sb.appendFormat("[%u:%u@%u]", liveSpan.a, liveSpan.b, liveSpan.id);
}
- sb.appendChar('\n');
+ sb.append('\n');
}
#endif
@@ -1296,10 +1296,10 @@ ASMJIT_FAVOR_SPEED Error RAPass::binPack(uint32_t group) noexcept {
sb.appendFormat(" Unassigned (%u): ", count);
for (i = 0; i < numWorkRegs; i++) {
RAWorkReg* workReg = workRegs[i];
- if (i) sb.appendString(", ");
- sb.appendString(workReg->name());
+ if (i) sb.append(", ");
+ sb.append(workReg->name());
}
- sb.appendChar('\n');
+ sb.append('\n');
logger->log(sb);
});
}
@@ -1380,8 +1380,8 @@ Error RAPass::runLocalAllocator() noexcept {
}
ASMJIT_PROPAGATE(lra.allocInst(inst));
- if (inst->type() == BaseNode::kNodeFuncCall)
- ASMJIT_PROPAGATE(onEmitPreCall(inst->as<FuncCallNode>()));
+ if (inst->type() == BaseNode::kNodeInvoke)
+ ASMJIT_PROPAGATE(onEmitPreCall(inst->as<InvokeNode>()));
else
ASMJIT_PROPAGATE(lra.spillAfterAllocation(inst));
}
@@ -1595,7 +1595,7 @@ Error RAPass::useTemporaryMem(BaseMem& out, uint32_t size, uint32_t alignment) n
ASMJIT_ASSERT(alignment <= 64);
if (_temporaryMem.isNone()) {
- ASMJIT_PROPAGATE(cc()->_newStack(_temporaryMem.as<BaseMem>(), size, alignment));
+ ASMJIT_PROPAGATE(cc()->_newStack(&_temporaryMem.as<BaseMem>(), size, alignment));
}
else {
ASMJIT_ASSERT(_temporaryMem.as<BaseMem>().isRegHome());
@@ -1852,27 +1852,31 @@ static void RAPass_dumpRAInst(RAPass* pass, String& sb, const RAInst* raInst) no
for (uint32_t i = 0; i < tiedCount; i++) {
const RATiedReg& tiedReg = tiedRegs[i];
- if (i != 0) sb.appendChar(' ');
+ if (i != 0)
+ sb.append(' ');
sb.appendFormat("%s{", pass->workRegById(tiedReg.workId())->name());
- sb.appendChar(tiedReg.isReadWrite() ? 'X' :
- tiedReg.isRead() ? 'R' :
- tiedReg.isWrite() ? 'W' : '?');
+ sb.append(tiedReg.isReadWrite() ? 'X' :
+ tiedReg.isRead() ? 'R' :
+ tiedReg.isWrite() ? 'W' : '?');
if (tiedReg.hasUseId())
sb.appendFormat("|Use=%u", tiedReg.useId());
else if (tiedReg.isUse())
- sb.appendString("|Use");
+ sb.append("|Use");
if (tiedReg.hasOutId())
sb.appendFormat("|Out=%u", tiedReg.outId());
else if (tiedReg.isOut())
- sb.appendString("|Out");
+ sb.append("|Out");
+
+ if (tiedReg.isLast())
+ sb.append("|Last");
- if (tiedReg.isLast()) sb.appendString("|Last");
- if (tiedReg.isKill()) sb.appendString("|Kill");
+ if (tiedReg.isKill())
+ sb.append("|Kill");
- sb.appendString("}");
+ sb.append("}");
}
}
@@ -1887,13 +1891,13 @@ ASMJIT_FAVOR_SIZE Error RAPass::annotateCode() noexcept {
BaseNode* last = block->last();
for (;;) {
sb.clear();
- Logging::formatNode(sb, loggerFlags, cc(), node);
+ Formatter::formatNode(sb, loggerFlags, cc(), node);
if ((loggerFlags & FormatOptions::kFlagDebugRA) != 0 && node->isInst() && node->hasPassData()) {
const RAInst* raInst = node->passData<RAInst>();
if (raInst->tiedCount() > 0) {
sb.padEnd(40);
- sb.appendString(" | ");
+ sb.append(" | ");
RAPass_dumpRAInst(this, sb, raInst);
}
}
@@ -1940,15 +1944,15 @@ ASMJIT_FAVOR_SIZE Error RAPass::_dumpBlockLiveness(String& sb, const RABlock* bl
if (!n)
sb.appendFormat(" %s [", bitsName);
else
- sb.appendString(", ");
+ sb.append(", ");
- sb.appendString(wReg->name());
+ sb.append(wReg->name());
n++;
}
}
if (n)
- sb.appendString("]\n");
+ sb.append("]\n");
}
return kErrorOk;
@@ -1961,10 +1965,10 @@ ASMJIT_FAVOR_SIZE Error RAPass::_dumpLiveSpans(String& sb) noexcept {
for (uint32_t workId = 0; workId < numWorkRegs; workId++) {
RAWorkReg* workReg = _workRegs[workId];
- sb.appendString(" ");
+ sb.append(" ");
size_t oldSize = sb.size();
- sb.appendString(workReg->name());
+ sb.append(workReg->name());
sb.padEnd(oldSize + maxSize);
RALiveStats& stats = workReg->liveStats();
@@ -1973,16 +1977,17 @@ ASMJIT_FAVOR_SIZE Error RAPass::_dumpLiveSpans(String& sb) noexcept {
stats.width(),
stats.freq(),
stats.priority());
- sb.appendString(": ");
+ sb.append(": ");
LiveRegSpans& liveSpans = workReg->liveSpans();
for (uint32_t x = 0; x < liveSpans.size(); x++) {
const LiveRegSpan& liveSpan = liveSpans[x];
- if (x) sb.appendString(", ");
+ if (x)
+ sb.append(", ");
sb.appendFormat("[%u:%u]", liveSpan.a, liveSpan.b);
}
- sb.appendChar('\n');
+ sb.append('\n');
}
return kErrorOk;
diff --git a/3rdparty/asmjit/src/asmjit/core/rapass_p.h b/3rdparty/asmjit/src/asmjit/core/rapass_p.h
index 5a575ad4bae..df5eb9d7aad 100644
--- a/3rdparty/asmjit/src/asmjit/core/rapass_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/rapass_p.h
@@ -42,6 +42,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::RABlock]
// ============================================================================
+//! Basic block used by register allocator pass.
class RABlock {
public:
ASMJIT_NONCOPYABLE(RABlock)
@@ -53,6 +54,7 @@ public:
kUnassignedId = 0xFFFFFFFFu
};
+ //! Basic block flags.
enum Flags : uint32_t {
//! Block has been constructed from nodes.
kFlagIsConstructed = 0x00000001u,
@@ -111,9 +113,6 @@ public:
//! Block successors.
RABlocks _successors;
- // TODO: Used?
- RABlocks _doms;
-
enum LiveType : uint32_t {
kLiveIn = 0,
kLiveOut = 1,
@@ -157,7 +156,6 @@ public:
_idom(nullptr),
_predecessors(),
_successors(),
- _doms(),
_sharedAssignmentId(Globals::kInvalidId),
_entryScratchGpRegs(0),
_exitScratchGpRegs(0),
@@ -470,7 +468,7 @@ public:
//! \name Utilities
//! \{
- ASMJIT_INLINE Error add(RAWorkReg* workReg, uint32_t flags, uint32_t allocable, uint32_t useId, uint32_t useRewriteMask, uint32_t outId, uint32_t outRewriteMask, uint32_t rmSize = 0) noexcept {
+ Error add(RAWorkReg* workReg, uint32_t flags, uint32_t allocable, uint32_t useId, uint32_t useRewriteMask, uint32_t outId, uint32_t outRewriteMask, uint32_t rmSize = 0) noexcept {
uint32_t group = workReg->group();
RATiedReg* tiedReg = workReg->tiedReg();
@@ -510,7 +508,6 @@ public:
if (ASMJIT_UNLIKELY(tiedReg->hasOutId()))
return DebugUtils::errored(kErrorOverlappedRegs);
tiedReg->setOutId(outId);
- // TODO: ? _used[group] |= Support::bitMask(outId);
}
tiedReg->addRefCount();
@@ -523,7 +520,7 @@ public:
}
}
- ASMJIT_INLINE Error addCallArg(RAWorkReg* workReg, uint32_t useId) noexcept {
+ Error addCallArg(RAWorkReg* workReg, uint32_t useId) noexcept {
ASMJIT_ASSERT(useId != BaseReg::kIdBad);
uint32_t flags = RATiedReg::kUse | RATiedReg::kRead | RATiedReg::kUseFixed;
@@ -563,7 +560,7 @@ public:
}
}
- ASMJIT_INLINE Error addCallRet(RAWorkReg* workReg, uint32_t outId) noexcept {
+ Error addCallRet(RAWorkReg* workReg, uint32_t outId) noexcept {
ASMJIT_ASSERT(outId != BaseReg::kIdBad);
uint32_t flags = RATiedReg::kOut | RATiedReg::kWrite | RATiedReg::kOutFixed;
@@ -761,14 +758,14 @@ public:
//! \name Accessors
//! \{
- //! Returns `Logger` passed to `runOnFunction()`.
+ //! Returns \ref Logger passed to \ref runOnFunction().
inline Logger* logger() const noexcept { return _logger; }
- //! Returns `Logger` passed to `runOnFunction()` or null if `kOptionDebugPasses` is not set.
+ //! Returns \ref Logger passed to \ref runOnFunction() or null if `kOptionDebugPasses` is not set.
inline Logger* debugLogger() const noexcept { return _debugLogger; }
- //! Returns `Zone` passed to `runOnFunction()`.
+ //! Returns \ref Zone passed to \ref runOnFunction().
inline Zone* zone() const noexcept { return _allocator.zone(); }
- //! Returns `ZoneAllocator` used by the register allocator.
+ //! Returns \ref ZoneAllocator used by the register allocator.
inline ZoneAllocator* allocator() const noexcept { return const_cast<ZoneAllocator*>(&_allocator); }
inline const ZoneVector<RASharedAssignment>& sharedAssignments() const { return _sharedAssignments; }
@@ -800,7 +797,7 @@ public:
}
//! Runs the register allocator for the given `func`.
- Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) noexcept override;
+ Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) override;
//! Performs all allocation steps sequentially, called by `runOnFunction()`.
Error onPerformAllSteps() noexcept;
@@ -810,11 +807,11 @@ public:
//! \name Events
//! \{
- //! Called by `runOnFunction()` before the register allocation to initialize
+ //! Called by \ref runOnFunction() before the register allocation to initialize
//! architecture-specific data and constraints.
virtual void onInit() noexcept = 0;
- //! Called by `runOnFunction()` after register allocation to clean everything
+ //! Called by \ref runOnFunction(` after register allocation to clean everything
//! up. Called even if the register allocation failed.
virtual void onDone() noexcept = 0;
@@ -1009,7 +1006,7 @@ public:
//! \{
//! Returns a native size of the general-purpose register of the target architecture.
- inline uint32_t gpSize() const noexcept { return _sp.size(); }
+ inline uint32_t registerSize() const noexcept { return _sp.size(); }
inline uint32_t availableRegCount(uint32_t group) const noexcept { return _availableRegCount[group]; }
inline RAWorkReg* workRegById(uint32_t workId) const noexcept { return _workRegs[workId]; }
@@ -1049,9 +1046,11 @@ public:
inline RAStackSlot* getOrCreateStackSlot(RAWorkReg* workReg) noexcept {
RAStackSlot* slot = workReg->stackSlot();
- if (slot) return slot;
- slot = _stackAllocator.newSlot(_sp.id(), workReg->virtReg()->virtSize(), workReg->virtReg()->alignment(), 0);
+ if (slot)
+ return slot;
+
+ slot = _stackAllocator.newSlot(_sp.id(), workReg->virtReg()->virtSize(), workReg->virtReg()->alignment(), RAStackSlot::kFlagRegHome);
workReg->_stackSlot = slot;
workReg->markStackUsed();
return slot;
@@ -1166,7 +1165,7 @@ public:
virtual Error onEmitSave(uint32_t workId, uint32_t srcPhysId) noexcept = 0;
virtual Error onEmitJump(const Label& label) noexcept = 0;
- virtual Error onEmitPreCall(FuncCallNode* call) noexcept = 0;
+ virtual Error onEmitPreCall(InvokeNode* invokeNode) noexcept = 0;
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/rastack.cpp b/3rdparty/asmjit/src/asmjit/core/rastack.cpp
index 342b7ce7c9e..b886279a5f3 100644
--- a/3rdparty/asmjit/src/asmjit/core/rastack.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/rastack.cpp
@@ -43,11 +43,9 @@ RAStackSlot* RAStackAllocator::newSlot(uint32_t baseRegId, uint32_t size, uint32
slot->_baseRegId = uint8_t(baseRegId);
slot->_alignment = uint8_t(Support::max<uint32_t>(alignment, 1));
- slot->_reserved[0] = 0;
- slot->_reserved[1] = 0;
+ slot->_flags = uint16_t(flags);
slot->_useCount = 0;
slot->_size = size;
- slot->_flags = flags;
slot->_weight = 0;
slot->_offset = 0;
@@ -92,7 +90,7 @@ Error RAStackAllocator::calculateStackFrame() noexcept {
uint32_t alignment = slot->alignment();
ASMJIT_ASSERT(alignment > 0);
- uint32_t power = Support::ctz(alignment);
+ uint32_t power = Support::min<uint32_t>(Support::ctz(alignment), 6);
uint64_t weight;
if (slot->isRegHome())
@@ -128,7 +126,8 @@ Error RAStackAllocator::calculateStackFrame() noexcept {
ZoneVector<RAStackGap> gaps[kSizeCount - 1];
for (RAStackSlot* slot : _slots) {
- if (slot->isStackArg()) continue;
+ if (slot->isStackArg())
+ continue;
uint32_t slotAlignment = slot->alignment();
uint32_t alignedOffset = Support::alignUp(offset, slotAlignment);
diff --git a/3rdparty/asmjit/src/asmjit/core/rastack_p.h b/3rdparty/asmjit/src/asmjit/core/rastack_p.h
index d45f7aa8896..33d4e1d15e8 100644
--- a/3rdparty/asmjit/src/asmjit/core/rastack_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/rastack_p.h
@@ -41,10 +41,14 @@ ASMJIT_BEGIN_NAMESPACE
//! Stack slot.
struct RAStackSlot {
+ //! Stack slot flags.
+ //!
+ //! TODO: kFlagStackArg is not used by the current implementation, do we need to keep it?
enum Flags : uint32_t {
- // TODO: kFlagRegHome is apparently not used, but isRegHome() is.
- kFlagRegHome = 0x00000001u, //!< Stack slot is register home slot.
- kFlagStackArg = 0x00000002u //!< Stack slot position matches argument passed via stack.
+ //! Stack slot is register home slot.
+ kFlagRegHome = 0x0001u,
+ //! Stack slot position matches argument passed via stack.
+ kFlagStackArg = 0x0002u
};
enum ArgIndex : uint32_t {
@@ -56,17 +60,15 @@ struct RAStackSlot {
//! Minimum alignment required by the slot.
uint8_t _alignment;
//! Reserved for future use.
- uint8_t _reserved[2];
+ uint16_t _flags;
//! Size of memory required by the slot.
uint32_t _size;
- //! Slot flags.
- uint32_t _flags;
//! Usage counter (one unit equals one memory access).
uint32_t _useCount;
- //! Weight of the slot (calculated by `calculateStackFrame()`).
+ //! Weight of the slot, calculated by \ref RAStackAllocator::calculateStackFrame().
uint32_t _weight;
- //! Stack offset (calculated by `calculateStackFrame()`).
+ //! Stack offset, calculated by \ref RAStackAllocator::calculateStackFrame().
int32_t _offset;
//! \name Accessors
@@ -79,9 +81,11 @@ struct RAStackSlot {
inline uint32_t alignment() const noexcept { return _alignment; }
inline uint32_t flags() const noexcept { return _flags; }
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
- inline bool isRegHome() const noexcept { return (_flags & kFlagRegHome) != 0; }
- inline bool isStackArg() const noexcept { return (_flags & kFlagStackArg) != 0; }
+ inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ inline void addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); }
+
+ inline bool isRegHome() const noexcept { return hasFlag(kFlagRegHome); }
+ inline bool isStackArg() const noexcept { return hasFlag(kFlagStackArg); }
inline uint32_t useCount() const noexcept { return _useCount; }
inline void addUseCount(uint32_t n = 1) noexcept { _useCount += n; }
diff --git a/3rdparty/asmjit/src/asmjit/core/string.cpp b/3rdparty/asmjit/src/asmjit/core/string.cpp
index 564a566f042..e059884c844 100644
--- a/3rdparty/asmjit/src/asmjit/core/string.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/string.cpp
@@ -34,7 +34,7 @@ ASMJIT_BEGIN_NAMESPACE
static const char String_baseN[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
constexpr size_t kMinAllocSize = 64;
-constexpr size_t kMaxAllocSize = std::numeric_limits<size_t>::max() - Globals::kGrowThreshold;
+constexpr size_t kMaxAllocSize = SIZE_MAX - Globals::kGrowThreshold;
// ============================================================================
// [asmjit::String]
@@ -150,7 +150,7 @@ char* String::prepare(uint32_t op, size_t size) noexcept {
}
}
-Error String::assignString(const char* data, size_t size) noexcept {
+Error String::assign(const char* data, size_t size) noexcept {
char* dst = nullptr;
// Null terminated string without `size` specified.
@@ -222,7 +222,8 @@ Error String::_opString(uint32_t op, const char* str, size_t size) noexcept {
return kErrorOk;
char* p = prepare(op, size);
- if (!p) return DebugUtils::errored(kErrorOutOfMemory);
+ if (!p)
+ return DebugUtils::errored(kErrorOutOfMemory);
memcpy(p, str, size);
return kErrorOk;
@@ -230,7 +231,8 @@ Error String::_opString(uint32_t op, const char* str, size_t size) noexcept {
Error String::_opChar(uint32_t op, char c) noexcept {
char* p = prepare(op, 1);
- if (!p) return DebugUtils::errored(kErrorOutOfMemory);
+ if (!p)
+ return DebugUtils::errored(kErrorOutOfMemory);
*p = c;
return kErrorOk;
@@ -241,7 +243,8 @@ Error String::_opChars(uint32_t op, char c, size_t n) noexcept {
return kErrorOk;
char* p = prepare(op, n);
- if (!p) return DebugUtils::errored(kErrorOutOfMemory);
+ if (!p)
+ return DebugUtils::errored(kErrorOutOfMemory);
memset(p, c, n);
return kErrorOk;
@@ -349,7 +352,7 @@ Error String::_opHex(uint32_t op, const void* data, size_t size, char separator)
return kErrorOk;
if (separator) {
- if (ASMJIT_UNLIKELY(size >= std::numeric_limits<size_t>::max() / 3))
+ if (ASMJIT_UNLIKELY(size >= SIZE_MAX / 3))
return DebugUtils::errored(kErrorOutOfMemory);
dst = prepare(op, size * 3 - 1);
@@ -369,7 +372,7 @@ Error String::_opHex(uint32_t op, const void* data, size_t size, char separator)
}
}
else {
- if (ASMJIT_UNLIKELY(size >= std::numeric_limits<size_t>::max() / 2))
+ if (ASMJIT_UNLIKELY(size >= SIZE_MAX / 2))
return DebugUtils::errored(kErrorOutOfMemory);
dst = prepare(op, size * 2);
@@ -404,6 +407,9 @@ Error String::_opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept {
int fmtResult;
size_t outputSize;
+ va_list apCopy;
+ va_copy(apCopy, ap);
+
if (remainingCapacity >= 128) {
fmtResult = vsnprintf(data() + startAt, remainingCapacity, fmt, ap);
outputSize = size_t(fmtResult);
@@ -428,7 +434,7 @@ Error String::_opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept {
if (ASMJIT_UNLIKELY(!p))
return DebugUtils::errored(kErrorOutOfMemory);
- fmtResult = vsnprintf(p, outputSize + 1, fmt, ap);
+ fmtResult = vsnprintf(p, outputSize + 1, fmt, apCopy);
ASMJIT_ASSERT(size_t(fmtResult) == outputSize);
return kErrorOk;
@@ -483,7 +489,7 @@ UNIT(core_string) {
EXPECT(s.isLarge() == false);
EXPECT(s.isExternal() == false);
- EXPECT(s.assignChar('a') == kErrorOk);
+ EXPECT(s.assign('a') == kErrorOk);
EXPECT(s.size() == 1);
EXPECT(s.capacity() == String::kSSOCapacity);
EXPECT(s.data()[0] == 'a');
@@ -502,7 +508,7 @@ UNIT(core_string) {
EXPECT(s.eq("bbbb") == true);
EXPECT(s.eq("bbbb", 4) == true);
- EXPECT(s.assignString("abc") == kErrorOk);
+ EXPECT(s.assign("abc") == kErrorOk);
EXPECT(s.size() == 3);
EXPECT(s.capacity() == String::kSSOCapacity);
EXPECT(s.data()[0] == 'a');
@@ -513,7 +519,7 @@ UNIT(core_string) {
EXPECT(s.eq("abc", 3) == true);
const char* large = "Large string that will not fit into SSO buffer";
- EXPECT(s.assignString(large) == kErrorOk);
+ EXPECT(s.assign(large) == kErrorOk);
EXPECT(s.isLarge() == true);
EXPECT(s.size() == strlen(large));
EXPECT(s.capacity() > String::kSSOCapacity);
@@ -522,7 +528,7 @@ UNIT(core_string) {
const char* additional = " (additional content)";
EXPECT(s.isLarge() == true);
- EXPECT(s.appendString(additional) == kErrorOk);
+ EXPECT(s.append(additional) == kErrorOk);
EXPECT(s.size() == strlen(large) + strlen(additional));
EXPECT(s.clear() == kErrorOk);
diff --git a/3rdparty/asmjit/src/asmjit/core/string.h b/3rdparty/asmjit/src/asmjit/core/string.h
index 22108f21f8b..4c490d87b1d 100644
--- a/3rdparty/asmjit/src/asmjit/core/string.h
+++ b/3rdparty/asmjit/src/asmjit/core/string.h
@@ -29,10 +29,34 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_support
+//! \addtogroup asmjit_utilities
//! \{
// ============================================================================
+// [asmjit::FixedString]
+// ============================================================================
+
+//! A fixed string - only useful for strings that would never exceed `N - 1`
+//! characters; always null-terminated.
+template<size_t N>
+union FixedString {
+ enum : uint32_t {
+ kNumU32 = uint32_t((N + sizeof(uint32_t) - 1) / sizeof(uint32_t))
+ };
+
+ char str[kNumU32 * sizeof(uint32_t)];
+ uint32_t u32[kNumU32];
+
+ //! \name Utilities
+ //! \{
+
+ inline bool eq(const char* other) const noexcept {
+ return strcmp(str, other) == 0;
+ }
+
+ //! \}
+};
+// ============================================================================
// [asmjit::String]
// ============================================================================
@@ -60,8 +84,10 @@ public:
//! String operation.
enum Op : uint32_t {
- kOpAssign = 0,
- kOpAppend = 1
+ //! Assignment - a new content replaces the current one.
+ kOpAssign = 0,
+ //! Append - a new content is appended to the string.
+ kOpAppend = 1
};
//! String format flags.
@@ -114,12 +140,13 @@ public:
//! \name Construction & Destruction
//! \{
+ //! Creates a default-initialized string if zero length.
inline String() noexcept
: _small {} {}
+ //! Creates a string that takes ownership of the content of the `other` string.
inline String(String&& other) noexcept {
- for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_raw.uptr); i++)
- _raw.uptr[i] = other._raw.uptr[i];
+ _raw = other._raw;
other._resetInternal();
}
@@ -135,6 +162,12 @@ public:
//! \name Overloaded Operators
//! \{
+ inline String& operator=(String&& other) noexcept {
+ swap(other);
+ other.reset();
+ return *this;
+ }
+
inline bool operator==(const char* other) const noexcept { return eq(other); }
inline bool operator!=(const char* other) const noexcept { return !eq(other); }
@@ -149,13 +182,21 @@ public:
inline bool isLarge() const noexcept { return _type >= kTypeLarge; }
inline bool isExternal() const noexcept { return _type == kTypeExternal; }
+ //! Tests whether the string is empty.
inline bool empty() const noexcept { return size() == 0; }
+ //! Returns the size of the string.
inline size_t size() const noexcept { return isLarge() ? size_t(_large.size) : size_t(_type); }
+ //! Returns the capacity of the string.
inline size_t capacity() const noexcept { return isLarge() ? _large.capacity : size_t(kSSOCapacity); }
+ //! Returns the data of the string.
inline char* data() noexcept { return isLarge() ? _large.data : _small.data; }
+ //! \overload
inline const char* data() const noexcept { return isLarge() ? _large.data : _small.data; }
+ inline char* start() noexcept { return data(); }
+ inline const char* start() const noexcept { return data(); }
+
inline char* end() noexcept { return data() + size(); }
inline const char* end() const noexcept { return data() + size(); }
@@ -164,102 +205,120 @@ public:
//! \name String Operations
//! \{
- //! Clear the content of the string.
+ //! Swaps the content of this string with `other`.
+ inline void swap(String& other) noexcept {
+ std::swap(_raw, other._raw);
+ }
+
+ //! Clears the content of the string.
ASMJIT_API Error clear() noexcept;
ASMJIT_API char* prepare(uint32_t op, size_t size) noexcept;
ASMJIT_API Error _opString(uint32_t op, const char* str, size_t size = SIZE_MAX) noexcept;
- ASMJIT_API Error _opFormat(uint32_t op, const char* fmt, ...) noexcept;
- ASMJIT_API Error _opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept;
ASMJIT_API Error _opChar(uint32_t op, char c) noexcept;
ASMJIT_API Error _opChars(uint32_t op, char c, size_t n) noexcept;
ASMJIT_API Error _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept;
ASMJIT_API Error _opHex(uint32_t op, const void* data, size_t size, char separator = '\0') noexcept;
+ ASMJIT_API Error _opFormat(uint32_t op, const char* fmt, ...) noexcept;
+ ASMJIT_API Error _opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept;
- //! Replace the string content to a string specified by `data` and `size`. If
- //! `size` is `SIZE_MAX` then it's considered null-terminated and its length
- //! will be obtained through `strlen()`.
- ASMJIT_API Error assignString(const char* data, size_t size = SIZE_MAX) noexcept;
-
- //! Replace the current content by a formatted string `fmt`.
- template<typename... Args>
- inline Error assignFormat(const char* fmt, Args&&... args) noexcept {
- return _opFormat(kOpAssign, fmt, std::forward<Args>(args)...);
- }
+ //! Replaces the current of the string with `data` of the given `size`.
+ //!
+ //! Null terminated strings can set `size` to `SIZE_MAX`.
+ ASMJIT_API Error assign(const char* data, size_t size = SIZE_MAX) noexcept;
- //! Replace the current content by a formatted string `fmt` (va_list version).
- inline Error assignVFormat(const char* fmt, va_list ap) noexcept {
- return _opVFormat(kOpAssign, fmt, ap);
+ //! Replaces the current of the string with `other` string.
+ inline Error assign(const String& other) noexcept {
+ return assign(other.data(), other.size());
}
- //! Replace the current content by a single `c` character.
- inline Error assignChar(char c) noexcept {
+ //! Replaces the current of the string by a single `c` character.
+ inline Error assign(char c) noexcept {
return _opChar(kOpAssign, c);
}
- //! Replace the current content by `c` character `n` times.
+ //! Replaces the current of the string by a `c` character, repeated `n` times.
inline Error assignChars(char c, size_t n) noexcept {
return _opChars(kOpAssign, c, n);
}
- //! Replace the current content by a formatted integer `i` (signed).
+ //! Replaces the current of the string by a formatted integer `i` (signed).
inline Error assignInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
return _opNumber(kOpAssign, uint64_t(i), base, width, flags | kFormatSigned);
}
- //! Replace the current content by a formatted integer `i` (unsigned).
+ //! Replaces the current of the string by a formatted integer `i` (unsigned).
inline Error assignUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
return _opNumber(kOpAssign, i, base, width, flags);
}
- //! Replace the current content by the given `data` converted to a HEX string.
+ //! Replaces the current of the string by the given `data` converted to a HEX string.
inline Error assignHex(const void* data, size_t size, char separator = '\0') noexcept {
return _opHex(kOpAssign, data, size, separator);
}
- //! Append string `str` of size `size` (or possibly null terminated).
- inline Error appendString(const char* str, size_t size = SIZE_MAX) noexcept {
- return _opString(kOpAppend, str, size);
+ //! Replaces the current of the string by a formatted string `fmt`.
+ template<typename... Args>
+ inline Error assignFormat(const char* fmt, Args&&... args) noexcept {
+ return _opFormat(kOpAssign, fmt, std::forward<Args>(args)...);
}
- template<typename... Args>
- inline Error appendFormat(const char* fmt, Args&&... args) noexcept {
- return _opFormat(kOpAppend, fmt, std::forward<Args>(args)...);
+ //! Replaces the current of the string by a formatted string `fmt` (va_list version).
+ inline Error assignVFormat(const char* fmt, va_list ap) noexcept {
+ return _opVFormat(kOpAssign, fmt, ap);
}
- //! Append a formatted string `fmt` (va_list version).
- inline Error appendVFormat(const char* fmt, va_list ap) noexcept {
- return _opVFormat(kOpAppend, fmt, ap);
+ //! Appends `str` having the given size `size` to the string.
+ //!
+ //! Null terminated strings can set `size` to `SIZE_MAX`.
+ inline Error append(const char* str, size_t size = SIZE_MAX) noexcept {
+ return _opString(kOpAppend, str, size);
+ }
+
+ //! Appends `other` string to this string.
+ inline Error append(const String& other) noexcept {
+ return append(other.data(), other.size());
}
- //! Append a single `c` character.
- inline Error appendChar(char c) noexcept {
+ //! Appends a single `c` character.
+ inline Error append(char c) noexcept {
return _opChar(kOpAppend, c);
}
- //! Append `c` character `n` times.
+ //! Appends `c` character repeated `n` times.
inline Error appendChars(char c, size_t n) noexcept {
return _opChars(kOpAppend, c, n);
}
- ASMJIT_API Error padEnd(size_t n, char c = ' ') noexcept;
-
- //! Append `i`.
+ //! Appends a formatted integer `i` (signed).
inline Error appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
return _opNumber(kOpAppend, uint64_t(i), base, width, flags | kFormatSigned);
}
- //! Append `i`.
+ //! Appends a formatted integer `i` (unsigned).
inline Error appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
return _opNumber(kOpAppend, i, base, width, flags);
}
- //! Append the given `data` converted to a HEX string.
+ //! Appends the given `data` converted to a HEX string.
inline Error appendHex(const void* data, size_t size, char separator = '\0') noexcept {
return _opHex(kOpAppend, data, size, separator);
}
+ //! Appends a formatted string `fmt` with `args`.
+ template<typename... Args>
+ inline Error appendFormat(const char* fmt, Args&&... args) noexcept {
+ return _opFormat(kOpAppend, fmt, std::forward<Args>(args)...);
+ }
+
+ //! Appends a formatted string `fmt` (va_list version).
+ inline Error appendVFormat(const char* fmt, va_list ap) noexcept {
+ return _opVFormat(kOpAppend, fmt, ap);
+ }
+
+ ASMJIT_API Error padEnd(size_t n, char c = ' ') noexcept;
+
//! Truncate the string length into `newSize`.
ASMJIT_API Error truncate(size_t newSize) noexcept;
@@ -288,6 +347,20 @@ public:
}
//! \}
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use assign() instead of assignString()")
+ inline Error assignString(const char* data, size_t size = SIZE_MAX) noexcept { return assign(data, size); }
+
+ ASMJIT_DEPRECATED("Use assign() instead of assignChar()")
+ inline Error assignChar(char c) noexcept { return assign(c); }
+
+ ASMJIT_DEPRECATED("Use append() instead of appendString()")
+ inline Error appendString(const char* data, size_t size = SIZE_MAX) noexcept { return append(data, size); }
+
+ ASMJIT_DEPRECATED("Use append() instead of appendChar()")
+ inline Error appendChar(char c) noexcept { return append(c); }
+#endif // !ASMJIT_NO_DEPRECATED
};
// ============================================================================
@@ -320,31 +393,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::FixedString]
-// ============================================================================
-
-//! A fixed string - only useful for strings that would never exceed `N - 1`
-//! characters; always null-terminated.
-template<size_t N>
-union FixedString {
- enum : uint32_t {
- kNumU32 = uint32_t((N + sizeof(uint32_t) - 1) / sizeof(uint32_t))
- };
-
- char str[kNumU32 * sizeof(uint32_t)];
- uint32_t u32[kNumU32];
-
- //! \name Utilities
- //! \{
-
- inline bool eq(const char* other) const noexcept {
- return strcmp(str, other) == 0;
- }
-
- //! \}
-};
-
//! \}
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/support.cpp b/3rdparty/asmjit/src/asmjit/core/support.cpp
index 6b7e0854d81..a99477dc9fe 100644
--- a/3rdparty/asmjit/src/asmjit/core/support.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/support.cpp
@@ -100,7 +100,7 @@ static void testBitUtils() noexcept {
EXPECT(Support::bitTest((1 << i), i) == true, "Support::bitTest(%X, %u) should return true", (1 << i), i);
}
- INFO("Support::lsbMask()");
+ INFO("Support::lsbMask<uint32_t>()");
for (i = 0; i < 32; i++) {
uint32_t expectedBits = 0;
for (uint32_t b = 0; b < i; b++)
@@ -108,6 +108,14 @@ static void testBitUtils() noexcept {
EXPECT(Support::lsbMask<uint32_t>(i) == expectedBits);
}
+ INFO("Support::lsbMask<uint64_t>()");
+ for (i = 0; i < 64; i++) {
+ uint64_t expectedBits = 0;
+ for (uint32_t b = 0; b < i; b++)
+ expectedBits |= uint64_t(1) << b;
+ EXPECT(Support::lsbMask<uint64_t>(i) == expectedBits);
+ }
+
INFO("Support::popcnt()");
for (i = 0; i < 32; i++) EXPECT(Support::popcnt((uint32_t(1) << i)) == 1);
for (i = 0; i < 64; i++) EXPECT(Support::popcnt((uint64_t(1) << i)) == 1);
diff --git a/3rdparty/asmjit/src/asmjit/core/support.h b/3rdparty/asmjit/src/asmjit/core/support.h
index 0f49b78f0af..9e2bee477cb 100644
--- a/3rdparty/asmjit/src/asmjit/core/support.h
+++ b/3rdparty/asmjit/src/asmjit/core/support.h
@@ -32,7 +32,7 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_support
+//! \addtogroup asmjit_utilities
//! \{
//! Contains support classes and functions that may be used by AsmJit source
@@ -69,28 +69,35 @@ namespace Internal {
template<> struct AlignedInt<uint64_t, 4> { typedef uint64_t ASMJIT_ALIGN_TYPE(T, 4); };
template<> struct AlignedInt<uint64_t, 8> { typedef uint64_t T; };
- // IntBySize - Make an int-type by size (signed or unsigned) that is the
+ // StdInt - Make an int-type by size (signed or unsigned) that is the
// same as types defined by <stdint.h>.
// Int32Or64 - Make an int-type that has at least 32 bits: [u]int[32|64]_t.
- template<size_t SIZE, int IS_SIGNED>
- struct IntBySize {}; // Fail if not specialized.
+ template<size_t Size, unsigned Unsigned>
+ struct StdInt {}; // Fail if not specialized.
- template<> struct IntBySize<1, 0> { typedef uint8_t Type; };
- template<> struct IntBySize<1, 1> { typedef int8_t Type; };
- template<> struct IntBySize<2, 0> { typedef uint16_t Type; };
- template<> struct IntBySize<2, 1> { typedef int16_t Type; };
- template<> struct IntBySize<4, 0> { typedef uint32_t Type; };
- template<> struct IntBySize<4, 1> { typedef int32_t Type; };
- template<> struct IntBySize<8, 0> { typedef uint64_t Type; };
- template<> struct IntBySize<8, 1> { typedef int64_t Type; };
+ template<> struct StdInt<1, 0> { typedef int8_t Type; };
+ template<> struct StdInt<1, 1> { typedef uint8_t Type; };
+ template<> struct StdInt<2, 0> { typedef int16_t Type; };
+ template<> struct StdInt<2, 1> { typedef uint16_t Type; };
+ template<> struct StdInt<4, 0> { typedef int32_t Type; };
+ template<> struct StdInt<4, 1> { typedef uint32_t Type; };
+ template<> struct StdInt<8, 0> { typedef int64_t Type; };
+ template<> struct StdInt<8, 1> { typedef uint64_t Type; };
- template<typename T, int IS_SIGNED = std::is_signed<T>::value>
- struct Int32Or64 : public IntBySize<sizeof(T) <= 4 ? size_t(4) : sizeof(T), IS_SIGNED> {};
+ template<typename T, int Unsigned = std::is_unsigned<T>::value>
+ struct Int32Or64 : public StdInt<sizeof(T) <= 4 ? size_t(4) : sizeof(T), Unsigned> {};
}
//! \endcond
// ============================================================================
+// [asmjit::Support - Basic Traits]
+// ============================================================================
+
+template<typename T>
+static constexpr bool isUnsigned() noexcept { return std::is_unsigned<T>::value; }
+
+// ============================================================================
// [asmjit::Support - FastUInt8]
// ============================================================================
@@ -101,20 +108,32 @@ typedef unsigned int FastUInt8;
#endif
// ============================================================================
-// [asmjit::Support - IntBySize / Int32Or64]
+// [asmjit::Support - asInt / asUInt / asNormalized]
// ============================================================================
//! Casts an integer `x` to either `int32_t` or `int64_t` depending on `T`.
template<typename T>
-static constexpr typename Internal::Int32Or64<T, 1>::Type asInt(T x) noexcept { return (typename Internal::Int32Or64<T, 1>::Type)x; }
+static constexpr typename Internal::Int32Or64<T, 0>::Type asInt(const T& x) noexcept {
+ return (typename Internal::Int32Or64<T, 0>::Type)x;
+}
//! Casts an integer `x` to either `uint32_t` or `uint64_t` depending on `T`.
template<typename T>
-static constexpr typename Internal::Int32Or64<T, 0>::Type asUInt(T x) noexcept { return (typename Internal::Int32Or64<T, 0>::Type)x; }
+static constexpr typename Internal::Int32Or64<T, 1>::Type asUInt(const T& x) noexcept {
+ return (typename Internal::Int32Or64<T, 1>::Type)x;
+}
//! Casts an integer `x` to either `int32_t`, uint32_t`, `int64_t`, or `uint64_t` depending on `T`.
template<typename T>
-static constexpr typename Internal::Int32Or64<T>::Type asNormalized(T x) noexcept { return (typename Internal::Int32Or64<T>::Type)x; }
+static constexpr typename Internal::Int32Or64<T>::Type asNormalized(const T& x) noexcept {
+ return (typename Internal::Int32Or64<T>::Type)x;
+}
+
+//! Casts an integer `x` to the same type as defined by `<stdint.h>`.
+template<typename T>
+static constexpr typename Internal::StdInt<sizeof(T), isUnsigned<T>()>::Type asStdInt(const T& x) noexcept {
+ return (typename Internal::StdInt<sizeof(T), isUnsigned<T>()>::Type)x;
+}
// ============================================================================
// [asmjit::Support - BitCast]
@@ -142,7 +161,7 @@ static inline Dst bitCast(const Src& x) noexcept { return Internal::BitCastUnion
// ============================================================================
//! Storage used to store a pack of bits (should by compatible with a machine word).
-typedef Internal::IntBySize<sizeof(uintptr_t), 0>::Type BitWord;
+typedef Internal::StdInt<sizeof(uintptr_t), 1>::Type BitWord;
template<typename T>
static constexpr uint32_t bitSizeOf() noexcept { return uint32_t(sizeof(T) * 8u); }
@@ -194,14 +213,14 @@ static constexpr T blsi(T x) noexcept {
//! Generate a trailing bit-mask that has `n` least significant (trailing) bits set.
template<typename T, typename CountT>
-static constexpr T lsbMask(CountT n) noexcept {
+static constexpr T lsbMask(const CountT& n) noexcept {
typedef typename std::make_unsigned<T>::type U;
return (sizeof(U) < sizeof(uintptr_t))
+ // Prevent undefined behavior by using a larger type than T.
? T(U((uintptr_t(1) << n) - uintptr_t(1)))
- // Shifting more bits than the type provides is UNDEFINED BEHAVIOR.
- // In such case we trash the result by ORing it with a mask that has
- // all bits set and discards the UNDEFINED RESULT of the shift.
- : T(((U(1) << n) - U(1u)) | neg(U(n >= CountT(bitSizeOf<T>()))));
+ // Prevent undefined behavior by performing `n & (nBits - 1)` so it's always within the range.
+ : shr(sar(neg(T(n)), bitSizeOf<T>() - 1u),
+ neg(T(n)) & CountT(bitSizeOf<T>() - 1u));
}
//! Tests whether the given value `x` has `n`th bit set.
@@ -398,30 +417,113 @@ static constexpr T max(const T& a, const T& b, Args&&... args) noexcept { return
//! \cond
namespace Internal {
template<typename T>
- static ASMJIT_INLINE T addOverflowImpl(T x, T y, FastUInt8* of) noexcept {
+ ASMJIT_INLINE T addOverflowFallback(T x, T y, FastUInt8* of) noexcept {
typedef typename std::make_unsigned<T>::type U;
U result = U(x) + U(y);
- *of = FastUInt8(*of | FastUInt8(std::is_unsigned<T>::value ? result < U(x) : T((U(x) ^ ~U(y)) & (U(x) ^ result)) < 0));
+ *of = FastUInt8(*of | FastUInt8(isUnsigned<T>() ? result < U(x) : T((U(x) ^ ~U(y)) & (U(x) ^ result)) < 0));
return T(result);
}
template<typename T>
- static ASMJIT_INLINE T subOverflowImpl(T x, T y, FastUInt8* of) noexcept {
+ ASMJIT_INLINE T subOverflowFallback(T x, T y, FastUInt8* of) noexcept {
typedef typename std::make_unsigned<T>::type U;
U result = U(x) - U(y);
- *of = FastUInt8(*of | FastUInt8(std::is_unsigned<T>::value ? result > U(x) : T((U(x) ^ U(y)) & (U(x) ^ result)) < 0));
+ *of = FastUInt8(*of | FastUInt8(isUnsigned<T>() ? result > U(x) : T((U(x) ^ U(y)) & (U(x) ^ result)) < 0));
return T(result);
}
-}
+
+ template<typename T>
+ ASMJIT_INLINE T mulOverflowFallback(T x, T y, FastUInt8* of) noexcept {
+ typedef typename Internal::StdInt<sizeof(T) * 2, isUnsigned<T>()>::Type I;
+ typedef typename std::make_unsigned<I>::type U;
+
+ U mask = allOnes<U>();
+ if (std::is_signed<T>::value) {
+ U prod = U(I(x)) * U(I(y));
+ *of = FastUInt8(*of | FastUInt8(I(prod) < I(std::numeric_limits<T>::lowest()) || I(prod) > I(std::numeric_limits<T>::max())));
+ return T(I(prod & mask));
+ }
+ else {
+ U prod = U(x) * U(y);
+ *of = FastUInt8(*of | FastUInt8((prod & ~mask) != 0));
+ return T(prod & mask);
+ }
+ }
+
+ template<>
+ ASMJIT_INLINE int64_t mulOverflowFallback(int64_t x, int64_t y, FastUInt8* of) noexcept {
+ int64_t result = int64_t(uint64_t(x) * uint64_t(y));
+ *of = FastUInt8(*of | FastUInt8(x && (result / x != y)));
+ return result;
+ }
+
+ template<>
+ ASMJIT_INLINE uint64_t mulOverflowFallback(uint64_t x, uint64_t y, FastUInt8* of) noexcept {
+ uint64_t result = x * y;
+ *of = FastUInt8(*of | FastUInt8(y != 0 && allOnes<uint64_t>() / y < x));
+ return result;
+ }
+
+ // These can be specialized.
+ template<typename T> ASMJIT_INLINE T addOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return addOverflowFallback(x, y, of); }
+ template<typename T> ASMJIT_INLINE T subOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return subOverflowFallback(x, y, of); }
+ template<typename T> ASMJIT_INLINE T mulOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return mulOverflowFallback(x, y, of); }
+
+ #if defined(__GNUC__) && !defined(ASMJIT_NO_INTRINSICS)
+ #if defined(__clang__) || __GNUC__ >= 5
+ #define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, RESULT_T, BUILTIN) \
+ template<> \
+ ASMJIT_INLINE T FUNC(const T& x, const T& y, FastUInt8* of) noexcept { \
+ RESULT_T result; \
+ *of = FastUInt8(*of | (BUILTIN((RESULT_T)x, (RESULT_T)y, &result))); \
+ return T(result); \
+ }
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, int32_t , int , __builtin_sadd_overflow )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint32_t, unsigned int , __builtin_uadd_overflow )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, int64_t , long long , __builtin_saddll_overflow)
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint64_t, unsigned long long, __builtin_uaddll_overflow)
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, int32_t , int , __builtin_ssub_overflow )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint32_t, unsigned int , __builtin_usub_overflow )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, int64_t , long long , __builtin_ssubll_overflow)
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint64_t, unsigned long long, __builtin_usubll_overflow)
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, int32_t , int , __builtin_smul_overflow )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, uint32_t, unsigned int , __builtin_umul_overflow )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, int64_t , long long , __builtin_smulll_overflow)
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, uint64_t, unsigned long long, __builtin_umulll_overflow)
+ #undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
+ #endif
+ #endif
+
+ // There is a bug in MSVC that makes these specializations unusable, maybe in the future...
+ #if defined(_MSC_VER) && 0
+ #define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, ALT_T, BUILTIN) \
+ template<> \
+ ASMJIT_INLINE T FUNC(T x, T y, FastUInt8* of) noexcept { \
+ ALT_T result; \
+ *of = FastUInt8(*of | BUILTIN(0, (ALT_T)x, (ALT_T)y, &result)); \
+ return T(result); \
+ }
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint32_t, unsigned int , _addcarry_u32 )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint32_t, unsigned int , _subborrow_u32)
+ #if ARCH_BITS >= 64
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint64_t, unsigned __int64 , _addcarry_u64 )
+ ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint64_t, unsigned __int64 , _subborrow_u64)
+ #endif
+ #undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
+ #endif
+} // {Internal}
//! \endcond
template<typename T>
-static ASMJIT_INLINE T addOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::addOverflowImpl(x, y, of)); }
+static ASMJIT_INLINE T addOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::addOverflowImpl(asStdInt(x), asStdInt(y), of)); }
+
+template<typename T>
+static ASMJIT_INLINE T subOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::subOverflowImpl(asStdInt(x), asStdInt(y), of)); }
template<typename T>
-static ASMJIT_INLINE T subOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::subOverflowImpl(x, y, of)); }
+static ASMJIT_INLINE T mulOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::mulOverflowImpl(asStdInt(x), asStdInt(y), of)); }
// ============================================================================
// [asmjit::Support - Alignment]
@@ -429,7 +531,7 @@ static ASMJIT_INLINE T subOverflow(const T& x, const T& y, FastUInt8* of) noexce
template<typename X, typename Y>
static constexpr bool isAligned(X base, Y alignment) noexcept {
- typedef typename Internal::IntBySize<sizeof(X), 0>::Type U;
+ typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return ((U)base % (U)alignment) == 0;
}
@@ -442,27 +544,27 @@ static constexpr bool isPowerOf2(T x) noexcept {
template<typename X, typename Y>
static constexpr X alignUp(X x, Y alignment) noexcept {
- typedef typename Internal::IntBySize<sizeof(X), 0>::Type U;
+ typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return (X)( ((U)x + ((U)(alignment) - 1u)) & ~((U)(alignment) - 1u) );
}
template<typename T>
static constexpr T alignUpPowerOf2(T x) noexcept {
- typedef typename Internal::IntBySize<sizeof(T), 0>::Type U;
+ typedef typename Internal::StdInt<sizeof(T), 1>::Type U;
return (T)(fillTrailingBits(U(x) - 1u) + 1u);
}
//! Returns either zero or a positive difference between `base` and `base` when
//! aligned to `alignment`.
template<typename X, typename Y>
-static constexpr typename Internal::IntBySize<sizeof(X), 0>::Type alignUpDiff(X base, Y alignment) noexcept {
- typedef typename Internal::IntBySize<sizeof(X), 0>::Type U;
+static constexpr typename Internal::StdInt<sizeof(X), 1>::Type alignUpDiff(X base, Y alignment) noexcept {
+ typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return alignUp(U(base), alignment) - U(base);
}
template<typename X, typename Y>
static constexpr X alignDown(X x, Y alignment) noexcept {
- typedef typename Internal::IntBySize<sizeof(X), 0>::Type U;
+ typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return (X)( (U)x & ~((U)(alignment) - 1u) );
}
@@ -475,7 +577,7 @@ static constexpr X alignDown(X x, Y alignment) noexcept {
//! the number of BitWords to represent N bits, for example.
template<typename X, typename Y>
static constexpr X numGranularized(X base, Y granularity) noexcept {
- typedef typename Internal::IntBySize<sizeof(X), 0>::Type U;
+ typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return X((U(base) + U(granularity) - 1) / U(granularity));
}
@@ -620,10 +722,10 @@ static inline uint32_t byteShiftOfDWordStruct(uint32_t index) noexcept {
// ============================================================================
template<typename T>
-static constexpr T asciiToLower(T c) noexcept { return c ^ (T(c >= T('A') && c <= T('Z')) << 5); }
+static constexpr T asciiToLower(T c) noexcept { return T(c ^ T(T(c >= T('A') && c <= T('Z')) << 5)); }
template<typename T>
-static constexpr T asciiToUpper(T c) noexcept { return c ^ (T(c >= T('a') && c <= T('z')) << 5); }
+static constexpr T asciiToUpper(T c) noexcept { return T(c ^ T(T(c >= T('a') && c <= T('z')) << 5)); }
static ASMJIT_INLINE size_t strLen(const char* s, size_t maxSize) noexcept {
size_t i = 0;
@@ -920,6 +1022,7 @@ static inline void writeU64uBE(void* p, uint64_t x) noexcept { writeU64xBE<1>(p,
// [asmjit::Support - Operators]
// ============================================================================
+//! \cond INTERNAL
struct Set { template<typename T> static inline T op(T x, T y) noexcept { DebugUtils::unused(x); return y; } };
struct SetNot { template<typename T> static inline T op(T x, T y) noexcept { DebugUtils::unused(x); return ~y; } };
struct And { template<typename T> static inline T op(T x, T y) noexcept { return x & y; } };
@@ -931,6 +1034,7 @@ struct Add { template<typename T> static inline T op(T x, T y) noexcept { ret
struct Sub { template<typename T> static inline T op(T x, T y) noexcept { return x - y; } };
struct Min { template<typename T> static inline T op(T x, T y) noexcept { return min<T>(x, y); } };
struct Max { template<typename T> static inline T op(T x, T y) noexcept { return max<T>(x, y); } };
+//! \endcond
// ============================================================================
// [asmjit::Support - BitWordIterator]
@@ -1081,6 +1185,13 @@ static inline size_t bitVectorIndexOf(T* buf, size_t start, bool value) noexcept
template<typename T>
class BitVectorIterator {
public:
+ const T* _ptr;
+ size_t _idx;
+ size_t _end;
+ T _current;
+
+ ASMJIT_INLINE BitVectorIterator(const BitVectorIterator& other) noexcept = default;
+
ASMJIT_INLINE BitVectorIterator(const T* data, size_t numBitWords, size_t start = 0) noexcept {
init(data, numBitWords, start);
}
@@ -1126,11 +1237,6 @@ public:
ASMJIT_ASSERT(_current != T(0));
return _idx + ctz(_current);
}
-
- const T* _ptr;
- size_t _idx;
- size_t _end;
- T _current;
};
// ============================================================================
@@ -1142,6 +1248,12 @@ class BitVectorOpIterator {
public:
static constexpr uint32_t kTSizeInBits = bitSizeOf<T>();
+ const T* _aPtr;
+ const T* _bPtr;
+ size_t _idx;
+ size_t _end;
+ T _current;
+
ASMJIT_INLINE BitVectorOpIterator(const T* aData, const T* bData, size_t numBitWords, size_t start = 0) noexcept {
init(aData, bData, numBitWords, start);
}
@@ -1184,12 +1296,6 @@ public:
_current = bitWord;
return n;
}
-
- const T* _aPtr;
- const T* _bPtr;
- size_t _idx;
- size_t _end;
- T _current;
};
// ============================================================================
@@ -1290,7 +1396,6 @@ namespace Internal {
}
//! \endcond
-
//! Quick sort implementation.
//!
//! The main reason to provide a custom qsort implementation is that we needed
diff --git a/3rdparty/asmjit/src/asmjit/core/target.cpp b/3rdparty/asmjit/src/asmjit/core/target.cpp
index ad120b443a3..9ce94f32410 100644
--- a/3rdparty/asmjit/src/asmjit/core/target.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/target.cpp
@@ -31,8 +31,7 @@ ASMJIT_BEGIN_NAMESPACE
// ============================================================================
Target::Target() noexcept
- : _targetType(kTargetNone),
- _codeInfo() {}
+ : _environment() {}
Target::~Target() noexcept {}
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/target.h b/3rdparty/asmjit/src/asmjit/core/target.h
index f3da0e5de8e..4d144c64ee2 100644
--- a/3rdparty/asmjit/src/asmjit/core/target.h
+++ b/3rdparty/asmjit/src/asmjit/core/target.h
@@ -36,20 +36,13 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::CodeInfo]
// ============================================================================
+#ifndef ASMJIT_NO_DEPRECATED
//! Basic information about a code (or target). It describes its architecture,
//! code generation mode (or optimization level), and base address.
-class CodeInfo {
+class ASMJIT_DEPRECATED_STRUCT("Use Environment instead of CodeInfo") CodeInfo {
public:
- //!< Architecture information.
- ArchInfo _archInfo;
- //! Natural stack alignment (ARCH+OS).
- uint8_t _stackAlignment;
- //! Default CDECL calling convention.
- uint8_t _cdeclCallConv;
- //! Default STDCALL calling convention.
- uint8_t _stdCallConv;
- //! Default FASTCALL calling convention.
- uint8_t _fastCallConv;
+ //!< Environment information.
+ Environment _environment;
//! Base address.
uint64_t _baseAddress;
@@ -57,46 +50,35 @@ public:
//! \{
inline CodeInfo() noexcept
- : _archInfo(),
- _stackAlignment(0),
- _cdeclCallConv(CallConv::kIdNone),
- _stdCallConv(CallConv::kIdNone),
- _fastCallConv(CallConv::kIdNone),
+ : _environment(),
_baseAddress(Globals::kNoBaseAddress) {}
- inline explicit CodeInfo(uint32_t archId, uint32_t archMode = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept
- : _archInfo(archId, archMode),
- _stackAlignment(0),
- _cdeclCallConv(CallConv::kIdNone),
- _stdCallConv(CallConv::kIdNone),
- _fastCallConv(CallConv::kIdNone),
+ inline explicit CodeInfo(uint32_t arch, uint32_t subArch = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept
+ : _environment(arch, subArch),
_baseAddress(baseAddress) {}
+ inline explicit CodeInfo(const Environment& environment, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept
+ : _environment(environment),
+ _baseAddress(baseAddress) {}
+
+
inline CodeInfo(const CodeInfo& other) noexcept { init(other); }
inline bool isInitialized() const noexcept {
- return _archInfo.archId() != ArchInfo::kIdNone;
+ return _environment.arch() != Environment::kArchUnknown;
}
inline void init(const CodeInfo& other) noexcept {
*this = other;
}
- inline void init(uint32_t archId, uint32_t archMode = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept {
- _archInfo.init(archId, archMode);
- _stackAlignment = 0;
- _cdeclCallConv = CallConv::kIdNone;
- _stdCallConv = CallConv::kIdNone;
- _fastCallConv = CallConv::kIdNone;
+ inline void init(uint32_t arch, uint32_t subArch = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept {
+ _environment.init(arch, subArch);
_baseAddress = baseAddress;
}
inline void reset() noexcept {
- _archInfo.reset();
- _stackAlignment = 0;
- _cdeclCallConv = CallConv::kIdNone;
- _stdCallConv = CallConv::kIdNone;
- _fastCallConv = CallConv::kIdNone;
+ _environment.reset();
_baseAddress = Globals::kNoBaseAddress;
}
@@ -115,39 +97,28 @@ public:
//! \name Accessors
//! \{
- //! Returns the target architecture information, see `ArchInfo`.
- inline const ArchInfo& archInfo() const noexcept { return _archInfo; }
+ //! Returns the target environment information, see \ref Environment.
+ inline const Environment& environment() const noexcept { return _environment; }
- //! Returns the target architecture id, see `ArchInfo::Id`.
- inline uint32_t archId() const noexcept { return _archInfo.archId(); }
- //! Returns the target architecture sub-type, see `ArchInfo::SubId`.
- inline uint32_t archSubId() const noexcept { return _archInfo.archSubId(); }
+ //! Returns the target architecture, see \ref Environment::Arch.
+ inline uint32_t arch() const noexcept { return _environment.arch(); }
+ //! Returns the target sub-architecture, see \ref Environment::SubArch.
+ inline uint32_t subArch() const noexcept { return _environment.subArch(); }
//! Returns the native size of the target's architecture GP register.
- inline uint32_t gpSize() const noexcept { return _archInfo.gpSize(); }
- //! Returns the number of GP registers of the target's architecture.
- inline uint32_t gpCount() const noexcept { return _archInfo.gpCount(); }
-
- //! Returns a natural stack alignment that must be honored (or 0 if not known).
- inline uint32_t stackAlignment() const noexcept { return _stackAlignment; }
- //! Sets a natural stack alignment that must be honored.
- inline void setStackAlignment(uint32_t sa) noexcept { _stackAlignment = uint8_t(sa); }
-
- inline uint32_t cdeclCallConv() const noexcept { return _cdeclCallConv; }
- inline void setCdeclCallConv(uint32_t cc) noexcept { _cdeclCallConv = uint8_t(cc); }
-
- inline uint32_t stdCallConv() const noexcept { return _stdCallConv; }
- inline void setStdCallConv(uint32_t cc) noexcept { _stdCallConv = uint8_t(cc); }
-
- inline uint32_t fastCallConv() const noexcept { return _fastCallConv; }
- inline void setFastCallConv(uint32_t cc) noexcept { _fastCallConv = uint8_t(cc); }
+ inline uint32_t gpSize() const noexcept { return _environment.registerSize(); }
+ //! Tests whether this CodeInfo has a base address set.
inline bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
+ //! Returns the base address or \ref Globals::kNoBaseAddress if it's not set.
inline uint64_t baseAddress() const noexcept { return _baseAddress; }
+ //! Sets base address to `p`.
inline void setBaseAddress(uint64_t p) noexcept { _baseAddress = p; }
+ //! Resets base address (implicitly sets it to \ref Globals::kNoBaseAddress).
inline void resetBaseAddress() noexcept { _baseAddress = Globals::kNoBaseAddress; }
//! \}
};
+#endif // !ASMJIT_NO_DEPRECATED
// ============================================================================
// [asmjit::Target]
@@ -159,19 +130,8 @@ public:
ASMJIT_BASE_CLASS(Target)
ASMJIT_NONCOPYABLE(Target)
- //! Tartget type, see `TargetType`.
- uint8_t _targetType;
- //! Reserved for future use.
- uint8_t _reserved[7];
- //! Basic information about the Runtime's code.
- CodeInfo _codeInfo;
-
- enum TargetType : uint32_t {
- //! Uninitialized target or unknown target type.
- kTargetNone = 0,
- //! JIT target type, see `JitRuntime`.
- kTargetJit = 1
- };
+ //! Target environment information.
+ Environment _environment;
//! \name Construction & Destruction
//! \{
@@ -190,15 +150,20 @@ public:
//!
//! CodeInfo can be used to setup a CodeHolder in case you plan to generate a
//! code compatible and executable by this Runtime.
- inline const CodeInfo& codeInfo() const noexcept { return _codeInfo; }
+ inline const Environment& environment() const noexcept { return _environment; }
+
+ //! Returns the target architecture, see \ref Environment::Arch.
+ inline uint32_t arch() const noexcept { return _environment.arch(); }
+ //! Returns the target sub-architecture, see \ref Environment::SubArch.
+ inline uint32_t subArch() const noexcept { return _environment.subArch(); }
- //! Returns the target architecture id, see `ArchInfo::Id`.
- inline uint32_t archId() const noexcept { return _codeInfo.archId(); }
- //! Returns the target architecture sub-id, see `ArchInfo::SubId`.
- inline uint32_t archSubId() const noexcept { return _codeInfo.archSubId(); }
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use environment() instead")
+ inline CodeInfo codeInfo() const noexcept { return CodeInfo(_environment); }
- //! Returns the target type, see `TargetType`.
- inline uint32_t targetType() const noexcept { return _targetType; }
+ ASMJIT_DEPRECATED("Use environment().format() instead")
+ inline uint32_t targetType() const noexcept { return _environment.format(); }
+#endif // !ASMJIT_NO_DEPRECATED
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/type.cpp b/3rdparty/asmjit/src/asmjit/core/type.cpp
index 67662db5075..97892d9815e 100644
--- a/3rdparty/asmjit/src/asmjit/core/type.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/type.cpp
@@ -31,14 +31,62 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::Type]
// ============================================================================
-const Type::TypeData Type::_typeData = {
- #define VALUE(X) Type::BaseOfTypeId<X>::kTypeId
+namespace Type {
+
+template<uint32_t TYPE_ID>
+struct BaseOfTypeId {
+ static constexpr uint32_t kTypeId =
+ isBase (TYPE_ID) ? TYPE_ID :
+ isMask8 (TYPE_ID) ? kIdU8 :
+ isMask16(TYPE_ID) ? kIdU16 :
+ isMask32(TYPE_ID) ? kIdU32 :
+ isMask64(TYPE_ID) ? kIdU64 :
+ isMmx32 (TYPE_ID) ? kIdI32 :
+ isMmx64 (TYPE_ID) ? kIdI64 :
+ isVec32 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec32Start :
+ isVec64 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec64Start :
+ isVec128(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec128Start :
+ isVec256(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec256Start :
+ isVec512(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec512Start : 0;
+};
+
+template<uint32_t TYPE_ID>
+struct SizeOfTypeId {
+ static constexpr uint32_t kTypeSize =
+ isInt8 (TYPE_ID) ? 1 :
+ isUInt8 (TYPE_ID) ? 1 :
+ isInt16 (TYPE_ID) ? 2 :
+ isUInt16 (TYPE_ID) ? 2 :
+ isInt32 (TYPE_ID) ? 4 :
+ isUInt32 (TYPE_ID) ? 4 :
+ isInt64 (TYPE_ID) ? 8 :
+ isUInt64 (TYPE_ID) ? 8 :
+ isFloat32(TYPE_ID) ? 4 :
+ isFloat64(TYPE_ID) ? 8 :
+ isFloat80(TYPE_ID) ? 10 :
+ isMask8 (TYPE_ID) ? 1 :
+ isMask16 (TYPE_ID) ? 2 :
+ isMask32 (TYPE_ID) ? 4 :
+ isMask64 (TYPE_ID) ? 8 :
+ isMmx32 (TYPE_ID) ? 4 :
+ isMmx64 (TYPE_ID) ? 8 :
+ isVec32 (TYPE_ID) ? 4 :
+ isVec64 (TYPE_ID) ? 8 :
+ isVec128 (TYPE_ID) ? 16 :
+ isVec256 (TYPE_ID) ? 32 :
+ isVec512 (TYPE_ID) ? 64 : 0;
+};
+
+const TypeData _typeData = {
+ #define VALUE(X) BaseOfTypeId<X>::kTypeId
{ ASMJIT_LOOKUP_TABLE_256(VALUE, 0) },
#undef VALUE
- #define VALUE(X) Type::SizeOfTypeId<X>::kTypeSize
+ #define VALUE(X) SizeOfTypeId<X>::kTypeSize
{ ASMJIT_LOOKUP_TABLE_256(VALUE, 0) }
#undef VALUE
};
+} // {Type}
+
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/type.h b/3rdparty/asmjit/src/asmjit/core/type.h
index 59a17e92625..ef03ecb8360 100644
--- a/3rdparty/asmjit/src/asmjit/core/type.h
+++ b/3rdparty/asmjit/src/asmjit/core/type.h
@@ -35,7 +35,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::Type]
// ============================================================================
-//! Provides minimum type-system that is used by \ref asmjit_func and \ref asmjit_compiler.
+//! Provides a minimalist type-system that is used by Asmjit library.
namespace Type {
//! TypeId.
@@ -46,7 +46,7 @@ namespace Type {
//! width used) and it's also used by APIs that allow to describe and work with
//! function signatures.
enum Id : uint32_t {
- kIdVoid = 0,
+ kIdVoid = 0, //!< Void type.
_kIdBaseStart = 32,
_kIdBaseEnd = 44,
@@ -54,38 +54,38 @@ enum Id : uint32_t {
_kIdIntStart = 32,
_kIdIntEnd = 41,
- kIdIntPtr = 32,
- kIdUIntPtr = 33,
+ kIdIntPtr = 32, //!< Abstract signed integer type that has a native size.
+ kIdUIntPtr = 33, //!< Abstract unsigned integer type that has a native size.
- kIdI8 = 34,
- kIdU8 = 35,
- kIdI16 = 36,
- kIdU16 = 37,
- kIdI32 = 38,
- kIdU32 = 39,
- kIdI64 = 40,
- kIdU64 = 41,
+ kIdI8 = 34, //!< 8-bit signed integer type.
+ kIdU8 = 35, //!< 8-bit unsigned integer type.
+ kIdI16 = 36, //!< 16-bit signed integer type.
+ kIdU16 = 37, //!< 16-bit unsigned integer type.
+ kIdI32 = 38, //!< 32-bit signed integer type.
+ kIdU32 = 39, //!< 32-bit unsigned integer type.
+ kIdI64 = 40, //!< 64-bit signed integer type.
+ kIdU64 = 41, //!< 64-bit unsigned integer type.
_kIdFloatStart = 42,
_kIdFloatEnd = 44,
- kIdF32 = 42,
- kIdF64 = 43,
- kIdF80 = 44,
+ kIdF32 = 42, //!< 32-bit floating point type.
+ kIdF64 = 43, //!< 64-bit floating point type.
+ kIdF80 = 44, //!< 80-bit floating point type.
_kIdMaskStart = 45,
_kIdMaskEnd = 48,
- kIdMask8 = 45,
- kIdMask16 = 46,
- kIdMask32 = 47,
- kIdMask64 = 48,
+ kIdMask8 = 45, //!< 8-bit opmask register (K).
+ kIdMask16 = 46, //!< 16-bit opmask register (K).
+ kIdMask32 = 47, //!< 32-bit opmask register (K).
+ kIdMask64 = 48, //!< 64-bit opmask register (K).
_kIdMmxStart = 49,
_kIdMmxEnd = 50,
- kIdMmx32 = 49,
- kIdMmx64 = 50,
+ kIdMmx32 = 49, //!< 64-bit MMX register only used for 32 bits.
+ kIdMmx64 = 50, //!< 64-bit MMX register.
_kIdVec32Start = 51,
_kIdVec32End = 60,
@@ -206,72 +206,74 @@ static constexpr bool isVec128(uint32_t typeId) noexcept { return typeId >= _kId
static constexpr bool isVec256(uint32_t typeId) noexcept { return typeId >= _kIdVec256Start && typeId <= _kIdVec256End; }
static constexpr bool isVec512(uint32_t typeId) noexcept { return typeId >= _kIdVec512Start && typeId <= _kIdVec512End; }
-//! IdOfT<> template allows to get a TypeId of a C++ `T` type.
-template<typename T> struct IdOfT { /* Fail if not specialized. */ };
-
//! \cond
-template<typename T> struct IdOfT<T*> {
- enum : uint32_t { kTypeId = kIdUIntPtr };
+enum TypeCategory : uint32_t {
+ kTypeCategoryUnknown = 0,
+ kTypeCategoryEnum = 1,
+ kTypeCategoryIntegral = 2,
+ kTypeCategoryFloatingPoint = 3,
+ kTypeCategoryFunction = 4
};
-template<typename T> struct IdOfT<T&> {
- enum : uint32_t { kTypeId = kIdUIntPtr };
-};
+template<typename T, uint32_t Category>
+struct IdOfT_ByCategory {}; // Fails if not specialized.
template<typename T>
-struct IdOfIntT {
- static constexpr uint32_t kTypeId =
- sizeof(T) == 1 ? (std::is_signed<T>::value ? kIdI8 : kIdU8 ) :
- sizeof(T) == 2 ? (std::is_signed<T>::value ? kIdI16 : kIdU16) :
- sizeof(T) == 4 ? (std::is_signed<T>::value ? kIdI32 : kIdU32) :
- sizeof(T) == 8 ? (std::is_signed<T>::value ? kIdI64 : kIdU64) : kIdVoid;
+struct IdOfT_ByCategory<T, kTypeCategoryIntegral> {
+ enum : uint32_t {
+ kTypeId = (sizeof(T) == 1 && std::is_signed<T>::value) ? kIdI8 :
+ (sizeof(T) == 1 && !std::is_signed<T>::value) ? kIdU8 :
+ (sizeof(T) == 2 && std::is_signed<T>::value) ? kIdI16 :
+ (sizeof(T) == 2 && !std::is_signed<T>::value) ? kIdU16 :
+ (sizeof(T) == 4 && std::is_signed<T>::value) ? kIdI32 :
+ (sizeof(T) == 4 && !std::is_signed<T>::value) ? kIdU32 :
+ (sizeof(T) == 8 && std::is_signed<T>::value) ? kIdI64 :
+ (sizeof(T) == 8 && !std::is_signed<T>::value) ? kIdU64 : kIdVoid
+ };
};
-template<uint32_t TYPE_ID>
-struct BaseOfTypeId {
- static constexpr uint32_t kTypeId =
- isBase (TYPE_ID) ? TYPE_ID :
- isMask8 (TYPE_ID) ? kIdU8 :
- isMask16(TYPE_ID) ? kIdU16 :
- isMask32(TYPE_ID) ? kIdU32 :
- isMask64(TYPE_ID) ? kIdU64 :
- isMmx32 (TYPE_ID) ? kIdI32 :
- isMmx64 (TYPE_ID) ? kIdI64 :
- isVec32 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec32Start :
- isVec64 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec64Start :
- isVec128(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec128Start :
- isVec256(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec256Start :
- isVec512(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec512Start : 0;
+template<typename T>
+struct IdOfT_ByCategory<T, kTypeCategoryFloatingPoint> {
+ enum : uint32_t {
+ kTypeId = (sizeof(T) == 4 ) ? kIdF32 :
+ (sizeof(T) == 8 ) ? kIdF64 :
+ (sizeof(T) >= 10) ? kIdF80 : kIdVoid
+ };
};
-template<uint32_t TYPE_ID>
-struct SizeOfTypeId {
- static constexpr uint32_t kTypeSize =
- isInt8 (TYPE_ID) ? 1 :
- isUInt8 (TYPE_ID) ? 1 :
- isInt16 (TYPE_ID) ? 2 :
- isUInt16 (TYPE_ID) ? 2 :
- isInt32 (TYPE_ID) ? 4 :
- isUInt32 (TYPE_ID) ? 4 :
- isInt64 (TYPE_ID) ? 8 :
- isUInt64 (TYPE_ID) ? 8 :
- isFloat32(TYPE_ID) ? 4 :
- isFloat64(TYPE_ID) ? 8 :
- isFloat80(TYPE_ID) ? 10 :
- isMask8 (TYPE_ID) ? 1 :
- isMask16 (TYPE_ID) ? 2 :
- isMask32 (TYPE_ID) ? 4 :
- isMask64 (TYPE_ID) ? 8 :
- isMmx32 (TYPE_ID) ? 4 :
- isMmx64 (TYPE_ID) ? 8 :
- isVec32 (TYPE_ID) ? 4 :
- isVec64 (TYPE_ID) ? 8 :
- isVec128 (TYPE_ID) ? 16 :
- isVec256 (TYPE_ID) ? 32 :
- isVec512 (TYPE_ID) ? 64 : 0;
+template<typename T>
+struct IdOfT_ByCategory<T, kTypeCategoryEnum>
+ : public IdOfT_ByCategory<typename std::underlying_type<T>::type, kTypeCategoryIntegral> {};
+
+template<typename T>
+struct IdOfT_ByCategory<T, kTypeCategoryFunction> {
+ enum: uint32_t { kTypeId = kIdUIntPtr };
};
//! \endcond
+//! IdOfT<> template allows to get a TypeId from a C++ type `T`.
+template<typename T>
+struct IdOfT
+#ifdef _DOXYGEN
+ //! TypeId of C++ type `T`.
+ static constexpr uint32_t kTypeId = _TypeIdDeducedAtCompileTime_;
+#else
+ : public IdOfT_ByCategory<T,
+ std::is_enum<T>::value ? kTypeCategoryEnum :
+ std::is_integral<T>::value ? kTypeCategoryIntegral :
+ std::is_floating_point<T>::value ? kTypeCategoryFloatingPoint :
+ std::is_function<T>::value ? kTypeCategoryFunction : kTypeCategoryUnknown>
+#endif
+{};
+
+//! \cond
+template<typename T>
+struct IdOfT<T*> { enum : uint32_t { kTypeId = kIdUIntPtr }; };
+
+template<typename T>
+struct IdOfT<T&> { enum : uint32_t { kTypeId = kIdUIntPtr }; };
+//! \endcond
+
static inline uint32_t baseOf(uint32_t typeId) noexcept {
ASMJIT_ASSERT(typeId <= kIdMax);
return _typeData.baseOf[typeId];
@@ -283,14 +285,14 @@ static inline uint32_t sizeOf(uint32_t typeId) noexcept {
}
//! Returns offset needed to convert a `kIntPtr` and `kUIntPtr` TypeId
-//! into a type that matches `gpSize` (general-purpose register size).
+//! into a type that matches `registerSize` (general-purpose register size).
//! If you find such TypeId it's then only about adding the offset to it.
//!
//! For example:
//!
//! ```
-//! uint32_t gpSize = '4' or '8';
-//! uint32_t deabstractDelta = Type::deabstractDeltaOfSize(gpSize);
+//! uint32_t registerSize = '4' or '8';
+//! uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize);
//!
//! uint32_t typeId = 'some type-id';
//!
@@ -300,8 +302,8 @@ static inline uint32_t sizeOf(uint32_t typeId) noexcept {
//! // The same, but by using Type::deabstract() function.
//! typeId = Type::deabstract(typeId, deabstractDelta);
//! ```
-static constexpr uint32_t deabstractDeltaOfSize(uint32_t gpSize) noexcept {
- return gpSize >= 8 ? kIdI64 - kIdIntPtr : kIdI32 - kIdIntPtr;
+static constexpr uint32_t deabstractDeltaOfSize(uint32_t registerSize) noexcept {
+ return registerSize >= 8 ? kIdI64 - kIdIntPtr : kIdI32 - kIdIntPtr;
}
static constexpr uint32_t deabstract(uint32_t typeId, uint32_t deabstractDelta) noexcept {
@@ -350,45 +352,20 @@ namespace Type { \
}; \
}
-ASMJIT_DEFINE_TYPE_ID(bool , IdOfIntT<bool >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(char , IdOfIntT<char >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(signed char , IdOfIntT<signed char >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(unsigned char , IdOfIntT<unsigned char >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(short , IdOfIntT<short >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(unsigned short , IdOfIntT<unsigned short >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(int , IdOfIntT<int >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(unsigned int , IdOfIntT<unsigned int >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(long , IdOfIntT<long >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(unsigned long , IdOfIntT<unsigned long >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(long long , IdOfIntT<long long >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(unsigned long long, IdOfIntT<unsigned long long>::kTypeId);
-
-#if ASMJIT_CXX_HAS_NATIVE_WCHAR_T
-ASMJIT_DEFINE_TYPE_ID(wchar_t , IdOfIntT<wchar_t >::kTypeId);
-#endif
-
-#if ASMJIT_CXX_HAS_UNICODE_LITERALS
-ASMJIT_DEFINE_TYPE_ID(char16_t , IdOfIntT<char16_t >::kTypeId);
-ASMJIT_DEFINE_TYPE_ID(char32_t , IdOfIntT<char32_t >::kTypeId);
-#endif
-
-ASMJIT_DEFINE_TYPE_ID(void , kIdVoid);
-ASMJIT_DEFINE_TYPE_ID(float , kIdF32);
-ASMJIT_DEFINE_TYPE_ID(double , kIdF64);
-
-ASMJIT_DEFINE_TYPE_ID(Bool , kIdU8);
-ASMJIT_DEFINE_TYPE_ID(I8 , kIdI8);
-ASMJIT_DEFINE_TYPE_ID(U8 , kIdU8);
-ASMJIT_DEFINE_TYPE_ID(I16 , kIdI16);
-ASMJIT_DEFINE_TYPE_ID(U16 , kIdU16);
-ASMJIT_DEFINE_TYPE_ID(I32 , kIdI32);
-ASMJIT_DEFINE_TYPE_ID(U32 , kIdU32);
-ASMJIT_DEFINE_TYPE_ID(I64 , kIdI64);
-ASMJIT_DEFINE_TYPE_ID(U64 , kIdU64);
-ASMJIT_DEFINE_TYPE_ID(IPtr , kIdIntPtr);
-ASMJIT_DEFINE_TYPE_ID(UPtr , kIdUIntPtr);
-ASMJIT_DEFINE_TYPE_ID(F32 , kIdF32);
-ASMJIT_DEFINE_TYPE_ID(F64 , kIdF64);
+ASMJIT_DEFINE_TYPE_ID(void, kIdVoid);
+ASMJIT_DEFINE_TYPE_ID(Bool, kIdU8);
+ASMJIT_DEFINE_TYPE_ID(I8 , kIdI8);
+ASMJIT_DEFINE_TYPE_ID(U8 , kIdU8);
+ASMJIT_DEFINE_TYPE_ID(I16 , kIdI16);
+ASMJIT_DEFINE_TYPE_ID(U16 , kIdU16);
+ASMJIT_DEFINE_TYPE_ID(I32 , kIdI32);
+ASMJIT_DEFINE_TYPE_ID(U32 , kIdU32);
+ASMJIT_DEFINE_TYPE_ID(I64 , kIdI64);
+ASMJIT_DEFINE_TYPE_ID(U64 , kIdU64);
+ASMJIT_DEFINE_TYPE_ID(IPtr, kIdIntPtr);
+ASMJIT_DEFINE_TYPE_ID(UPtr, kIdUIntPtr);
+ASMJIT_DEFINE_TYPE_ID(F32 , kIdF32);
+ASMJIT_DEFINE_TYPE_ID(F64 , kIdF64);
//! \endcond
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/virtmem.cpp b/3rdparty/asmjit/src/asmjit/core/virtmem.cpp
index e373cf8d723..0606748ef7f 100644
--- a/3rdparty/asmjit/src/asmjit/core/virtmem.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/virtmem.cpp
@@ -45,7 +45,7 @@
// Apple recently introduced MAP_JIT flag, which we want to use.
#if defined(__APPLE__)
#include <TargetConditionals.h>
- #if defined(TARGET_OS_OSX)
+ #if TARGET_OS_OSX
#include <sys/utsname.h>
#endif
// Older SDK doesn't define `MAP_JIT`.
@@ -316,10 +316,10 @@ static ASMJIT_INLINE bool VirtMem_isHardened() noexcept {
// MAP_JIT flag required to run unsigned JIT code is only supported by kernel
// version 10.14+ (Mojave) and IOS.
static ASMJIT_INLINE bool VirtMem_hasMapJitSupport() noexcept {
-#if defined(TARGET_OS_OSX)
- static volatile uint32_t globalVersion;
+#if TARGET_OS_OSX
+ static volatile int globalVersion;
- uint32_t ver = globalVersion;
+ int ver = globalVersion;
if (!ver) {
struct utsname osname;
uname(&osname);
@@ -333,19 +333,19 @@ static ASMJIT_INLINE bool VirtMem_hasMapJitSupport() noexcept {
#endif
}
-static ASMJIT_INLINE uint32_t VirtMem_appleSpecificMMapFlags(uint32_t flags) {
+static ASMJIT_INLINE int VirtMem_appleSpecificMMapFlags(uint32_t flags) {
// Always use MAP_JIT flag if user asked for it (could be used for testing
// on non-hardened processes) and detect whether it must be used when the
// process is actually hardened (in that case it doesn't make sense to rely
// on user `flags`).
bool useMapJit = ((flags & VirtMem::kMMapEnableMapJit) != 0) || VirtMem_isHardened();
if (useMapJit)
- return VirtMem_hasMapJitSupport() ? MAP_JIT : 0u;
+ return VirtMem_hasMapJitSupport() ? int(MAP_JIT) : 0;
else
return 0;
}
#else
-static ASMJIT_INLINE uint32_t VirtMem_appleSpecificMMapFlags(uint32_t flags) {
+static ASMJIT_INLINE int VirtMem_appleSpecificMMapFlags(uint32_t flags) {
DebugUtils::unused(flags);
return 0;
}
@@ -406,7 +406,7 @@ static Error VirtMem_openAnonymousMemory(int* fd, bool preferTmpOverDevShm) noex
bits = ((bits >> 14) ^ (bits << 6)) + uint64_t(++internalCounter) * 10619863;
if (!ASMJIT_VM_SHM_DETECT || preferTmpOverDevShm) {
- uniqueName.assignString(VirtMem_getTmpDir());
+ uniqueName.assign(VirtMem_getTmpDir());
uniqueName.appendFormat(kShmFormat, (unsigned long long)bits);
*fd = open(uniqueName.data(), O_RDWR | O_CREAT | O_EXCL, 0);
if (ASMJIT_LIKELY(*fd >= 0)) {
diff --git a/3rdparty/asmjit/src/asmjit/core/virtmem.h b/3rdparty/asmjit/src/asmjit/core/virtmem.h
index a37005d947e..8d3ee01ee5b 100644
--- a/3rdparty/asmjit/src/asmjit/core/virtmem.h
+++ b/3rdparty/asmjit/src/asmjit/core/virtmem.h
@@ -31,7 +31,7 @@
ASMJIT_BEGIN_NAMESPACE
-//! \addtogroup asmjit_jit
+//! \addtogroup asmjit_virtual_memory
//! \{
// ============================================================================
diff --git a/3rdparty/asmjit/src/asmjit/core/zone.cpp b/3rdparty/asmjit/src/asmjit/core/zone.cpp
index 16de89becec..61f7cec796d 100644
--- a/3rdparty/asmjit/src/asmjit/core/zone.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/zone.cpp
@@ -144,7 +144,7 @@ void* Zone::_alloc(size_t size, size_t alignment) noexcept {
size_t newSize = Support::max(blockSize(), size);
// Prevent arithmetic overflow.
- if (ASMJIT_UNLIKELY(newSize > std::numeric_limits<size_t>::max() - kBlockSize - blockAlignmentOverhead))
+ if (ASMJIT_UNLIKELY(newSize > SIZE_MAX - kBlockSize - blockAlignmentOverhead))
return nullptr;
// Allocate new block - we add alignment overhead to `newSize`, which becomes the
@@ -200,7 +200,7 @@ void* Zone::dup(const void* data, size_t size, bool nullTerminate) noexcept {
if (ASMJIT_UNLIKELY(!data || !size))
return nullptr;
- ASMJIT_ASSERT(size != std::numeric_limits<size_t>::max());
+ ASMJIT_ASSERT(size != SIZE_MAX);
uint8_t* m = allocT<uint8_t>(size + nullTerminate);
if (ASMJIT_UNLIKELY(!m)) return nullptr;
@@ -318,7 +318,7 @@ void* ZoneAllocator::_alloc(size_t size, size_t& allocatedSize) noexcept {
size_t kBlockOverhead = sizeof(DynamicBlock) + sizeof(DynamicBlock*) + kBlockAlignment;
// Handle a possible overflow.
- if (ASMJIT_UNLIKELY(kBlockOverhead >= std::numeric_limits<size_t>::max() - size))
+ if (ASMJIT_UNLIKELY(kBlockOverhead >= SIZE_MAX - size))
return nullptr;
void* p = ::malloc(size + kBlockOverhead);
diff --git a/3rdparty/asmjit/src/asmjit/core/zone.h b/3rdparty/asmjit/src/asmjit/core/zone.h
index c426f785c0c..52e9f125461 100644
--- a/3rdparty/asmjit/src/asmjit/core/zone.h
+++ b/3rdparty/asmjit/src/asmjit/core/zone.h
@@ -383,15 +383,22 @@ public:
// [b2d::ZoneTmp]
// ============================================================================
+//! \ref Zone with `N` bytes of a static storage, used for the initial block.
+//!
+//! Temporary zones are used in cases where it's known that some memory will be
+//! required, but in many cases it won't exceed N bytes, so the whole operation
+//! can be performed without a dynamic memory allocation.
template<size_t N>
class ZoneTmp : public Zone {
public:
ASMJIT_NONCOPYABLE(ZoneTmp<N>)
+ //! Temporary storage, embedded after \ref Zone.
struct Storage {
char data[N];
} _storage;
+ //! Creates a temporary zone. Dynamic block size is specified by `blockSize`.
ASMJIT_INLINE explicit ZoneTmp(size_t blockSize, size_t blockAlignment = 1) noexcept
: Zone(blockSize, blockAlignment, Support::Temporary(_storage.data, N)) {}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/zonehash.h b/3rdparty/asmjit/src/asmjit/core/zonehash.h
index bdc1da76027..0f1f21f148c 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonehash.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonehash.h
@@ -35,7 +35,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::ZoneHashNode]
// ============================================================================
-//! Node used by `ZoneHash<>` template.
+//! Node used by \ref ZoneHash template.
//!
//! You must provide function `bool eq(const Key& key)` in order to make
//! `ZoneHash::get()` working.
@@ -60,6 +60,7 @@ public:
// [asmjit::ZoneHashBase]
// ============================================================================
+//! Base class used by \ref ZoneHash template
class ZoneHashBase {
public:
ASMJIT_NONCOPYABLE(ZoneHashBase)
diff --git a/3rdparty/asmjit/src/asmjit/core/zonelist.h b/3rdparty/asmjit/src/asmjit/core/zonelist.h
index 9d300b03606..bc726deca94 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonelist.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonelist.h
@@ -35,6 +35,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::ZoneListNode]
// ============================================================================
+//! Node used by \ref ZoneList template.
template<typename NodeT>
class ZoneListNode {
public:
@@ -69,6 +70,7 @@ public:
// [asmjit::ZoneList<T>]
// ============================================================================
+//! Zone allocated list container that uses nodes of `NodeT` type.
template <typename NodeT>
class ZoneList {
public:
diff --git a/3rdparty/asmjit/src/asmjit/core/zonestack.h b/3rdparty/asmjit/src/asmjit/core/zonestack.h
index 3c7b5ce0c45..2de6cdc05a7 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonestack.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonestack.h
@@ -35,7 +35,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::ZoneStackBase]
// ============================================================================
-//! Base class used by `ZoneStack<T>`.
+//! Base class used by \ref ZoneStack.
class ZoneStackBase {
public:
ASMJIT_NONCOPYABLE(ZoneStackBase)
diff --git a/3rdparty/asmjit/src/asmjit/core/zonestring.h b/3rdparty/asmjit/src/asmjit/core/zonestring.h
index dfb06b4c754..cb25b29ce7d 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonestring.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonestring.h
@@ -36,6 +36,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::ZoneStringBase]
// ============================================================================
+//! A helper class used by \ref ZoneString implementation.
struct ZoneStringBase {
union {
struct {
@@ -77,11 +78,12 @@ struct ZoneStringBase {
// [asmjit::ZoneString<N>]
// ============================================================================
-//! Small string is a template that helps to create strings that can be either
-//! statically allocated if they are small, or externally allocated in case
-//! their size exceeds the limit. The `N` represents the size of the whole
-//! `ZoneString` structure, based on that size the maximum size of the internal
-//! buffer is determined.
+//! A string template that can be zone allocated.
+//!
+//! Helps with creating strings that can be either statically allocated if they
+//! are small, or externally allocated in case their size exceeds the limit.
+//! The `N` represents the size of the whole `ZoneString` structure, based on
+//! that size the maximum size of the internal buffer is determined.
template<size_t N>
class ZoneString {
public:
@@ -105,12 +107,22 @@ public:
//! \name Accessors
//! \{
- inline const char* data() const noexcept { return _base._size <= kMaxEmbeddedSize ? _base._embedded : _base._external; }
+ //! Tests whether the string is empty.
inline bool empty() const noexcept { return _base._size == 0; }
+
+ //! Returns the string data.
+ inline const char* data() const noexcept { return _base._size <= kMaxEmbeddedSize ? _base._embedded : _base._external; }
+ //! Returns the string size.
inline uint32_t size() const noexcept { return _base._size; }
+ //! Tests whether the string is embedded (e.g. no dynamically allocated).
inline bool isEmbedded() const noexcept { return _base._size <= kMaxEmbeddedSize; }
+ //! Copies a new `data` of the given `size` to the string.
+ //!
+ //! If the `size` exceeds the internal buffer the given `zone` will be
+ //! used to duplicate the data, otherwise the internal buffer will be
+ //! used as a storage.
inline Error setData(Zone* zone, const char* data, size_t size) noexcept {
return _base.setData(zone, kMaxEmbeddedSize, data, size);
}
diff --git a/3rdparty/asmjit/src/asmjit/core/zonetree.h b/3rdparty/asmjit/src/asmjit/core/zonetree.h
index 6cb88ed499b..1877919d67b 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonetree.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonetree.h
@@ -99,7 +99,7 @@ public:
//! \endcond
};
-//! RB-Tree typed to `NodeT`.
+//! RB-Tree node casted to `NodeT`.
template<typename NodeT>
class ZoneTreeNodeT : public ZoneTreeNode {
public:
diff --git a/3rdparty/asmjit/src/asmjit/core/zonevector.h b/3rdparty/asmjit/src/asmjit/core/zonevector.h
index 7ee04ce7807..770543baee1 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonevector.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonevector.h
@@ -36,9 +36,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::ZoneVectorBase]
// ============================================================================
-//! \cond INTERNAL
-
-//! Base class implementing core `ZoneVector<>` functionality.
+//! Base class used by \ref ZoneVector template.
class ZoneVectorBase {
public:
ASMJIT_NONCOPYABLE(ZoneVectorBase)
@@ -93,6 +91,7 @@ protected:
}
//! \}
+ //! \endcond
public:
//! \name Accessors
@@ -133,8 +132,6 @@ public:
//! \}
};
-//! \endcond
-
// ============================================================================
// [asmjit::ZoneVector<T>]
// ============================================================================
@@ -180,7 +177,7 @@ public:
inline const T* data() const noexcept { return static_cast<const T*>(_data); }
//! Returns item at the given index `i` (const).
- inline const T& at(uint32_t i) const noexcept {
+ inline const T& at(size_t i) const noexcept {
ASMJIT_ASSERT(i < _size);
return data()[i];
}
@@ -259,6 +256,7 @@ public:
return kErrorOk;
}
+ //! Appends `other` vector at the end of this vector.
inline Error concat(ZoneAllocator* allocator, const ZoneVector<T>& other) noexcept {
uint32_t size = other._size;
if (_capacity - _size < size)
@@ -338,6 +336,7 @@ public:
::memmove(data, data + 1, size_t(size) * sizeof(T));
}
+ //! Pops the last element from the vector and returns it.
inline T pop() noexcept {
ASMJIT_ASSERT(_size > 0);
@@ -351,21 +350,33 @@ public:
}
//! Returns item at index `i`.
- inline T& operator[](uint32_t i) noexcept {
+ inline T& operator[](size_t i) noexcept {
ASMJIT_ASSERT(i < _size);
return data()[i];
}
//! Returns item at index `i`.
- inline const T& operator[](uint32_t i) const noexcept {
+ inline const T& operator[](size_t i) const noexcept {
ASMJIT_ASSERT(i < _size);
return data()[i];
}
+ //! Returns a reference to the first element of the vector.
+ //!
+ //! \note The vector must have at least one element. Attempting to use
+ //! `first()` on empty vector will trigger an assertion failure in debug
+ //! builds.
inline T& first() noexcept { return operator[](0); }
+ //! \overload
inline const T& first() const noexcept { return operator[](0); }
+ //! Returns a reference to the last element of the vector.
+ //!
+ //! \note The vector must have at least one element. Attempting to use
+ //! `last()` on empty vector will trigger an assertion failure in debug
+ //! builds.
inline T& last() noexcept { return operator[](_size - 1); }
+ //! \overload
inline const T& last() const noexcept { return operator[](_size - 1); }
//! \}
@@ -408,6 +419,7 @@ public:
// [asmjit::ZoneBitVector]
// ============================================================================
+//! Zone-allocated bit vector.
class ZoneBitVector {
public:
typedef Support::BitWord BitWord;
@@ -689,7 +701,6 @@ public:
};
//! \}
-
};
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/x86.h b/3rdparty/asmjit/src/asmjit/x86.h
index 161b3be19fb..3c2224c966a 100644
--- a/3rdparty/asmjit/src/asmjit/x86.h
+++ b/3rdparty/asmjit/src/asmjit/x86.h
@@ -24,9 +24,83 @@
#ifndef ASMJIT_X86_H_INCLUDED
#define ASMJIT_X86_H_INCLUDED
-//! \defgroup asmjit_x86 X86
+//! \addtogroup asmjit_x86
//!
-//! \brief X86/X64 Backend.
+//! ### Namespace
+//!
+//! - \ref x86 - x86 namespace provides support for X86/X64 code generation.
+//!
+//! ### Emitters
+//!
+//! - \ref x86::Assembler - X86/X64 assembler (must read, provides examples).
+//! - \ref x86::Builder - X86/X64 builder.
+//! - \ref x86::Compiler - X86/X64 compiler.
+//! - \ref x86::Emitter - X86/X64 emitter (abstract).
+//!
+//! ### Supported Instructions
+//!
+//! - Emitters:
+//! - \ref x86::EmitterExplicitT - Provides all instructions that use
+//! explicit operands, provides also utility functions. The member
+//! functions provided are part of all X86 emitters.
+//! - \ref x86::EmitterImplicitT - Provides all instructions that use
+//! implicit operands, these cannot be used with \ref x86::Compiler.
+//! - Instruction representation:
+//! - \ref x86::Inst::Id - instruction identifiers.
+//! - \ref x86::Inst::Options - instruction options.
+//!
+//! ### Register Operands
+//!
+//! - \ref x86::Reg - Base class for any X86 register.
+//! - \ref x86::Gp - General purpose register:
+//! - \ref x86::GpbLo - 8-bit low register.
+//! - \ref x86::GpbHi - 8-bit high register.
+//! - \ref x86::Gpw - 16-bit register.
+//! - \ref x86::Gpd - 32-bit register.
+//! - \ref x86::Gpq - 64-bit register (X64 only).
+//! - \ref x86::Vec - Vector (SIMD) register:
+//! - \ref x86::Xmm - 128-bit SIMD register (SSE+).
+//! - \ref x86::Ymm - 256-bit SIMD register (AVX+).
+//! - \ref x86::Zmm - 512-bit SIMD register (AVX512+).
+//! - \ref x86::Mm - 64-bit MMX register.
+//! - \ref x86::St - 80-bit FPU register.
+//! - \ref x86::KReg - opmask registers (AVX512+).
+//! - \ref x86::SReg - segment register.
+//! - \ref x86::CReg - control register.
+//! - \ref x86::DReg - debug register.
+//! - \ref x86::Bnd - bound register (discontinued).
+//! - \ref x86::Rip - relative instruction pointer.
+//!
+//! ### Memory Operands
+//!
+//! - \ref x86::Mem - X86/X64 memory operand that provides support for all
+//! X86 and X64 addressing features, including absolute addresses, index
+//! scales, and segment override prefixes.
+//!
+//! ### Other
+//!
+//! - \ref x86::Features - X86/X64 CPU features on top of \ref BaseFeatures.
+//!
+//! ### Status and Control Words
+//!
+//! - \ref asmjit::x86::FpuWord::Status - FPU status word.
+//! - \ref asmjit::x86::FpuWord::Control - FPU control word.
+//!
+//! ### Predicates
+//!
+//! - \ref x86::Predicate - namespace that provides X86/X64 predicates.
+//! - \ref x86::Predicate::Cmp - `CMP[PD|PS|SD|SS]` predicate (SSE+).
+//! - \ref x86::Predicate::PCmpStr - `[V]PCMP[I|E]STR[I|M]` predicate (SSE4.1+).
+//! - \ref x86::Predicate::Round - `ROUND[PD|PS|SD|SS]` predicate (SSE+).
+//! - \ref x86::Predicate::VCmp - `VCMP[PD|PS|SD|SS]` predicate (AVX+).
+//! - \ref x86::Predicate::VFixupImm - `VFIXUPIMM[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::Predicate::VFPClass - `VFPCLASS[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::Predicate::VGetMant - `VGETMANT[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::Predicate::VPCmp - `VPCMP[U][B|W|D|Q]` predicate (AVX512+).
+//! - \ref x86::Predicate::VPCom - `VPCOM[U][B|W|D|Q]` predicate (XOP).
+//! - \ref x86::Predicate::VRange - `VRANGE[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::Predicate::VReduce - `REDUCE[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::TLog - namespace that provides `VPTERNLOG[D|Q]` predicate / operations.
#include "./core.h"
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86archdata.cpp b/3rdparty/asmjit/src/asmjit/x86/x86archdata.cpp
new file mode 100644
index 00000000000..cd928b2534b
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/x86/x86archdata.cpp
@@ -0,0 +1,137 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include "../core/api-build_p.h"
+#ifdef ASMJIT_BUILD_X86
+
+#include "../core/support.h"
+#include "../core/type.h"
+#include "../x86/x86archdata_p.h"
+#include "../x86/x86operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(x86)
+
+// ============================================================================
+// [asmjit::x86::ArchInternal]
+// ============================================================================
+
+namespace ArchInternal {
+
+Error typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfoOut) noexcept {
+ // Passed RegType instead of TypeId?
+ if (typeId <= BaseReg::kTypeMax)
+ typeId = opData.archRegs.regTypeToTypeId[typeId];
+
+ if (ASMJIT_UNLIKELY(!Type::isValid(typeId)))
+ return DebugUtils::errored(kErrorInvalidTypeId);
+
+ // First normalize architecture dependent types.
+ if (Type::isAbstract(typeId)) {
+ bool is32Bit = arch == Environment::kArchX86;
+ if (typeId == Type::kIdIntPtr)
+ typeId = is32Bit ? Type::kIdI32 : Type::kIdI64;
+ else
+ typeId = is32Bit ? Type::kIdU32 : Type::kIdU64;
+ }
+
+ // Type size helps to construct all groups of registers.
+ // TypeId is invalid if the size is zero.
+ uint32_t size = Type::sizeOf(typeId);
+ if (ASMJIT_UNLIKELY(!size))
+ return DebugUtils::errored(kErrorInvalidTypeId);
+
+ if (ASMJIT_UNLIKELY(typeId == Type::kIdF80))
+ return DebugUtils::errored(kErrorInvalidUseOfF80);
+
+ uint32_t regType = 0;
+
+ switch (typeId) {
+ case Type::kIdI8:
+ case Type::kIdU8:
+ regType = Reg::kTypeGpbLo;
+ break;
+
+ case Type::kIdI16:
+ case Type::kIdU16:
+ regType = Reg::kTypeGpw;
+ break;
+
+ case Type::kIdI32:
+ case Type::kIdU32:
+ regType = Reg::kTypeGpd;
+ break;
+
+ case Type::kIdI64:
+ case Type::kIdU64:
+ if (arch == Environment::kArchX86)
+ return DebugUtils::errored(kErrorInvalidUseOfGpq);
+
+ regType = Reg::kTypeGpq;
+ break;
+
+ // F32 and F64 are always promoted to use vector registers.
+ case Type::kIdF32:
+ typeId = Type::kIdF32x1;
+ regType = Reg::kTypeXmm;
+ break;
+
+ case Type::kIdF64:
+ typeId = Type::kIdF64x1;
+ regType = Reg::kTypeXmm;
+ break;
+
+ // Mask registers {k}.
+ case Type::kIdMask8:
+ case Type::kIdMask16:
+ case Type::kIdMask32:
+ case Type::kIdMask64:
+ regType = Reg::kTypeKReg;
+ break;
+
+ // MMX registers.
+ case Type::kIdMmx32:
+ case Type::kIdMmx64:
+ regType = Reg::kTypeMm;
+ break;
+
+ // XMM|YMM|ZMM registers.
+ default:
+ if (size <= 16)
+ regType = Reg::kTypeXmm;
+ else if (size == 32)
+ regType = Reg::kTypeYmm;
+ else
+ regType = Reg::kTypeZmm;
+ break;
+ }
+
+ *typeIdOut = typeId;
+ regInfoOut->reset(opData.archRegs.regInfo[regType].signature());
+ return kErrorOk;
+}
+
+} // {ArchInternal}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_BUILD_X86
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86archdata_p.h b/3rdparty/asmjit/src/asmjit/x86/x86archdata_p.h
new file mode 100644
index 00000000000..e765cb9b02a
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/x86/x86archdata_p.h
@@ -0,0 +1,51 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_X86_X86ARCHDATA_P_H_INCLUDED
+#define ASMJIT_X86_X86ARCHDATA_P_H_INCLUDED
+
+#include "../core/arch.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(x86)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_x86
+//! \{
+
+// ============================================================================
+// [asmjit::x86::ArchInternal]
+// ============================================================================
+
+//! X86-specific function API (calling conventions and other utilities).
+namespace ArchInternal {
+
+Error typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfoOut) noexcept;
+
+} // {ArchInternal}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_X86_X86ARCHDATA_P_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp b/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp
index d509926e5f5..879fb2f0151 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp
@@ -24,14 +24,17 @@
#include "../core/api-build_p.h"
#ifdef ASMJIT_BUILD_X86
+#include "../core/assembler.h"
#include "../core/codebufferwriter_p.h"
#include "../core/cpuinfo.h"
-#include "../core/logging.h"
+#include "../core/emitterutils_p.h"
+#include "../core/formatter.h"
+#include "../core/logger.h"
#include "../core/misc_p.h"
#include "../core/support.h"
#include "../x86/x86assembler.h"
#include "../x86/x86instdb_p.h"
-#include "../x86/x86logging_p.h"
+#include "../x86/x86formatter_p.h"
#include "../x86/x86opcode_p.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
@@ -508,7 +511,7 @@ static ASMJIT_INLINE uint32_t x86GetMovAbsAddrType(Assembler* self, X86BufferWri
if (addrType == BaseMem::kAddrTypeDefault && !(options & Inst::kOptionModMR)) {
if (self->is64Bit()) {
- uint64_t baseAddress = self->codeInfo().baseAddress();
+ uint64_t baseAddress = self->code()->baseAddress();
if (baseAddress != Globals::kNoBaseAddress && !rmRel.hasSegment()) {
uint32_t instructionSize = x86GetMovAbsInstSize64Bit(regSize, options, rmRel);
uint64_t virtualOffset = uint64_t(writer.offsetFrom(self->_bufferData));
@@ -545,18 +548,18 @@ Assembler::~Assembler() noexcept {}
// [asmjit::x86::Assembler - Emit (Low-Level)]
// ============================================================================
-ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
constexpr uint32_t kVSHR_W = Opcode::kW_Shift - 23;
constexpr uint32_t kVSHR_PP = Opcode::kPP_Shift - 16;
constexpr uint32_t kVSHR_PP_EW = Opcode::kPP_Shift - 16;
constexpr uint32_t kRequiresSpecialHandling =
- Inst::kOptionReserved | // Logging/Validation/Error.
- Inst::kOptionRep | // REP/REPE prefix.
- Inst::kOptionRepne | // REPNE prefix.
- Inst::kOptionLock | // LOCK prefix.
- Inst::kOptionXAcquire | // XACQUIRE prefix.
- Inst::kOptionXRelease ; // XRELEASE prefix.
+ uint32_t(Inst::kOptionReserved) | // Logging/Validation/Error.
+ uint32_t(Inst::kOptionRep ) | // REP/REPE prefix.
+ uint32_t(Inst::kOptionRepne ) | // REPNE prefix.
+ uint32_t(Inst::kOptionLock ) | // LOCK prefix.
+ uint32_t(Inst::kOptionXAcquire) | // XACQUIRE prefix.
+ uint32_t(Inst::kOptionXRelease) ; // XRELEASE prefix.
Error err;
@@ -595,12 +598,12 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
// instruction) are handled by the next branch.
options = uint32_t(instId == 0);
options |= uint32_t((size_t)(_bufferEnd - writer.cursor()) < 16);
- options |= uint32_t(instOptions() | globalInstOptions());
+ options |= uint32_t(instOptions() | forcedInstOptions());
// Handle failure and rare cases first.
if (ASMJIT_UNLIKELY(options & kRequiresSpecialHandling)) {
if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
// Unknown instruction.
if (ASMJIT_UNLIKELY(instId == 0))
@@ -613,25 +616,13 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
#ifndef ASMJIT_NO_VALIDATION
// Strict validation.
- if (hasEmitterOption(kOptionStrictValidation)) {
+ if (hasValidationOption(kValidationOptionAssembler)) {
Operand_ opArray[Globals::kMaxOpCount];
+ EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- opArray[0].copyFrom(o0);
- opArray[1].copyFrom(o1);
- opArray[2].copyFrom(o2);
- opArray[3].copyFrom(o3);
-
- if (options & Inst::kOptionOp4Op5Used) {
- opArray[4].copyFrom(_op4);
- opArray[5].copyFrom(_op5);
- }
- else {
- opArray[4].reset();
- opArray[5].reset();
- }
-
- err = InstAPI::validate(archId(), BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount);
- if (ASMJIT_UNLIKELY(err)) goto Failed;
+ err = InstAPI::validate(arch(), BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount);
+ if (ASMJIT_UNLIKELY(err))
+ goto Failed;
}
#endif
@@ -693,7 +684,7 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
if (ASMJIT_UNLIKELY(isign3 != ENC_OPS1(Imm)))
goto InvalidInstruction;
- immValue = o0.as<Imm>().u8();
+ immValue = o0.as<Imm>().valueAs<uint8_t>();
immSize = 1;
ASMJIT_FALLTHROUGH;
@@ -738,14 +729,14 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
case InstDB::kEncodingX86I_xAX:
// Implicit form.
if (isign3 == ENC_OPS1(Imm)) {
- immValue = o0.as<Imm>().u8();
+ immValue = o0.as<Imm>().valueAs<uint8_t>();
immSize = 1;
goto EmitX86Op;
}
// Explicit form.
if (isign3 == ENC_OPS2(Reg, Imm) && o0.id() == Gp::kIdAx) {
- immValue = o1.as<Imm>().u8();
+ immValue = o1.as<Imm>().valueAs<uint8_t>();
immSize = 1;
goto EmitX86Op;
}
@@ -996,7 +987,7 @@ CaseX86M_GPB_MulDiv:
uint32_t size = o0.size();
rbReg = o0.id();
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
if (size == 1) {
FIXUP_GPB(o0, rbReg);
@@ -1022,8 +1013,7 @@ CaseX86M_GPB_MulDiv:
else
goto InvalidImmediate;
}
- else if (canTransformTo32Bit && hasEmitterOption(kOptionOptimizedForSize)) {
- // This is a code-size optimization.
+ else if (canTransformTo32Bit && hasEncodingOption(kEncodingOptionOptimizeForSize)) {
size = 4;
}
@@ -1053,7 +1043,7 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(memSize == 0))
goto AmbiguousOperandSize;
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = FastUInt8(Support::min<uint32_t>(memSize, 4));
// Sign extend so isInt8 returns the right result.
@@ -1098,7 +1088,7 @@ CaseX86M_GPB_MulDiv:
}
// The remaining instructions use the secondary opcode/r.
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = 1;
opcode = x86AltOpcodeOf(instInfo);
@@ -1175,8 +1165,11 @@ CaseX86M_GPB_MulDiv:
}
case InstDB::kEncodingX86Cmpxchg8b_16b: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
+ const Operand_& o4 = opExt[EmitterUtils::kOp4];
+
if (isign3 == ENC_OPS3(Mem, Reg, Reg)) {
- if (o3.isReg() && _op4.isReg()) {
+ if (o3.isReg() && o4.isReg()) {
rmRel = &o0;
goto EmitX86M;
}
@@ -1224,8 +1217,8 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86Enter:
if (isign3 == ENC_OPS2(Imm, Imm)) {
- uint32_t iw = o0.as<Imm>().u16();
- uint32_t ib = o1.as<Imm>().u8();
+ uint32_t iw = o0.as<Imm>().valueAs<uint16_t>();
+ uint32_t ib = o1.as<Imm>().valueAs<uint8_t>();
immValue = iw | (ib << 16);
immSize = 3;
@@ -1239,7 +1232,7 @@ CaseX86M_GPB_MulDiv:
opcode = 0x6B;
opcode.addPrefixBySize(o0.size());
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (!Support::isInt8(immValue) || (options & Inst::kOptionLongForm)) {
@@ -1257,7 +1250,7 @@ CaseX86M_GPB_MulDiv:
opcode = 0x6B;
opcode.addPrefixBySize(o0.size());
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
// Sign extend so isInt8 returns the right result.
@@ -1309,7 +1302,7 @@ CaseX86M_GPB_MulDiv:
opcode = 0x6B;
opcode.addPrefixBySize(o0.size());
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = 1;
// Sign extend so isInt8 returns the right result.
@@ -1333,7 +1326,7 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(o0.id() != Gp::kIdAx))
goto InvalidInstruction;
- immValue = o1.as<Imm>().u8();
+ immValue = o1.as<Imm>().valueAs<uint8_t>();
immSize = 1;
opcode = x86AltOpcodeOf(instInfo) + (o0.size() != 1);
@@ -1398,18 +1391,16 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86Int:
if (isign3 == ENC_OPS1(Imm)) {
- immValue = o0.as<Imm>().i64();
+ immValue = o0.as<Imm>().value();
immSize = 1;
goto EmitX86Op;
}
break;
case InstDB::kEncodingX86Jcc:
- if (_emitterOptions & kOptionPredictedJumps) {
- if (options & Inst::kOptionTaken)
- writer.emit8(0x3E);
- if (options & Inst::kOptionNotTaken)
- writer.emit8(0x2E);
+ if ((options & (Inst::kOptionTaken | Inst::kOptionNotTaken)) && hasEncodingOption(kEncodingOptionPredictedJumps)) {
+ uint8_t prefix = (options & Inst::kOptionTaken) ? uint8_t(0x3E) : uint8_t(0x2E);
+ writer.emit8(prefix);
}
rmRel = &o0;
@@ -1649,16 +1640,16 @@ CaseX86M_GPB_MulDiv:
FIXUP_GPB(o0, opReg);
opcode = 0xB0;
- immValue = o1.as<Imm>().u8();
+ immValue = o1.as<Imm>().valueAs<uint8_t>();
goto EmitX86OpReg;
}
else {
// 64-bit immediate in 64-bit mode is allowed.
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
// Optimize the instruction size by using a 32-bit immediate if possible.
if (immSize == 8 && !(options & Inst::kOptionLongForm)) {
- if (Support::isUInt32(immValue) && hasEmitterOption(kOptionOptimizedForSize)) {
+ if (Support::isUInt32(immValue) && hasEncodingOption(kEncodingOptionOptimizeForSize)) {
// Zero-extend by using a 32-bit GPD destination instead of a 64-bit GPQ.
immSize = 4;
}
@@ -1690,7 +1681,7 @@ CaseX86M_GPB_MulDiv:
opReg = 0;
rmRel = &o0;
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = FastUInt8(Support::min<uint32_t>(memSize, 4));
goto EmitX86M;
}
@@ -1753,7 +1744,7 @@ CaseX86M_GPB_MulDiv:
opcode = x86AltOpcodeOf(instInfo) + (o1.size() != 1);
opcode.add66hBySize(o1.size());
- immValue = o0.as<Imm>().u8();
+ immValue = o0.as<Imm>().valueAs<uint8_t>();
immSize = 1;
goto EmitX86Op;
}
@@ -1800,7 +1791,7 @@ CaseX86M_GPB_MulDiv:
}
if (isign3 == ENC_OPS1(Imm)) {
- immValue = o0.as<Imm>().i64();
+ immValue = o0.as<Imm>().value();
immSize = 4;
if (Support::isInt8(immValue) && !(options & Inst::kOptionLongForm))
@@ -1840,7 +1831,7 @@ CaseX86PushPop_Gp:
if (ASMJIT_UNLIKELY(o0.size() == 0))
goto AmbiguousOperandSize;
- if (ASMJIT_UNLIKELY(o0.size() != 2 && o0.size() != gpSize()))
+ if (ASMJIT_UNLIKELY(o0.size() != 2 && o0.size() != registerSize()))
goto InvalidInstruction;
opcode.add66hBySize(o0.size());
@@ -1857,7 +1848,7 @@ CaseX86PushPop_Gp:
}
if (isign3 == ENC_OPS1(Imm)) {
- immValue = o0.as<Imm>().i64();
+ immValue = o0.as<Imm>().value();
if (immValue == 0 && !(options & Inst::kOptionLongForm)) {
// 'ret' without immediate, change C2 to C3.
opcode.add(1);
@@ -1887,7 +1878,7 @@ CaseX86PushPop_Gp:
}
if (isign3 == ENC_OPS2(Reg, Imm)) {
- immValue = o1.as<Imm>().i64() & 0xFF;
+ immValue = o1.as<Imm>().value() & 0xFF;
immSize = 0;
if (immValue == 1 && !(options & Inst::kOptionLongForm))
@@ -1915,7 +1906,7 @@ CaseX86PushPop_Gp:
goto AmbiguousOperandSize;
rmRel = &o0;
- immValue = o1.as<Imm>().i64() & 0xFF;
+ immValue = o1.as<Imm>().value() & 0xFF;
immSize = 0;
if (immValue == 1 && !(options & Inst::kOptionLongForm))
@@ -1947,7 +1938,7 @@ CaseX86PushPop_Gp:
opReg = o1.id();
rbReg = o0.id();
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
goto EmitX86R;
}
@@ -1957,7 +1948,7 @@ CaseX86PushPop_Gp:
opReg = o1.id();
rmRel = &o0;
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
goto EmitX86M;
}
@@ -2077,11 +2068,11 @@ CaseX86PushPop_Gp:
if (o0.size() == 1) {
FIXUP_GPB(o0, rbReg);
- immValue = o1.as<Imm>().u8();
+ immValue = o1.as<Imm>().valueAs<uint8_t>();
immSize = 1;
}
else {
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = FastUInt8(Support::min<uint32_t>(o0.size(), 4));
}
@@ -2102,7 +2093,7 @@ CaseX86PushPop_Gp:
opcode.addArithBySize(o0.size());
rmRel = &o0;
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = FastUInt8(Support::min<uint32_t>(o0.size(), 4));
goto EmitX86M;
}
@@ -2345,7 +2336,7 @@ CaseFpuArith_Mem:
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
opcode.add66hIf(Reg::isXmm(o1));
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
opReg = o0.id();
@@ -2358,7 +2349,7 @@ CaseFpuArith_Mem:
opcode = x86AltOpcodeOf(instInfo);
opcode.add66hIf(Reg::isXmm(o1));
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
opReg = o1.id();
@@ -2371,7 +2362,7 @@ CaseFpuArith_Mem:
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
opcode.add66hIf(Reg::isXmm(o1));
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
opReg = o1.id();
@@ -2382,7 +2373,7 @@ CaseFpuArith_Mem:
if (isign3 == ENC_OPS3(Mem, Reg, Imm)) {
opcode.add66hIf(Reg::isXmm(o1));
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
opReg = o1.id();
@@ -2621,7 +2612,7 @@ CaseExtRm:
opReg = opcode.extractO();
if (isign3 == ENC_OPS2(Reg, Imm)) {
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = 1;
rbReg = o0.id();
@@ -2653,7 +2644,7 @@ CaseExtRm:
if (isign3 == ENC_OPS2(Reg, Imm)) {
opcode.add66hIf(Reg::isXmm(o0));
- immValue = o1.as<Imm>().i64();
+ immValue = o1.as<Imm>().value();
immSize = 1;
rbReg = o0.id();
@@ -2662,7 +2653,7 @@ CaseExtRm:
break;
case InstDB::kEncodingExtRmi:
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -2679,7 +2670,7 @@ CaseExtRm:
break;
case InstDB::kEncodingExtRmi_P:
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -2714,8 +2705,8 @@ CaseExtRm:
opcode = x86AltOpcodeOf(instInfo);
if (isign3 == ENC_OPS3(Reg, Imm, Imm)) {
- immValue = (o1.as<Imm>().u32() ) +
- (o2.as<Imm>().u32() << 8) ;
+ immValue = (uint32_t(o1.as<Imm>().valueAs<uint8_t>()) ) +
+ (uint32_t(o2.as<Imm>().valueAs<uint8_t>()) << 8) ;
immSize = 2;
rbReg = opcode.extractO();
@@ -2724,7 +2715,9 @@ CaseExtRm:
break;
case InstDB::kEncodingExtInsertq: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
const uint32_t isign4 = isign3 + (o3.opType() << 9);
+
opReg = o0.id();
rbReg = o1.id();
@@ -2735,8 +2728,8 @@ CaseExtRm:
opcode = x86AltOpcodeOf(instInfo);
if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
- immValue = (o2.as<Imm>().u32() ) +
- (o3.as<Imm>().u32() << 8) ;
+ immValue = (uint32_t(o2.as<Imm>().valueAs<uint8_t>()) ) +
+ (uint32_t(o3.as<Imm>().valueAs<uint8_t>()) << 8) ;
immSize = 2;
goto EmitX86R;
}
@@ -2869,7 +2862,7 @@ CaseExtRm:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexMri:
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -2934,24 +2927,22 @@ CaseVexRm:
break;
case InstDB::kEncodingVexRm_T1_4X: {
- if (!(options & Inst::kOptionOp4Op5Used))
- goto InvalidInstruction;
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
+ const Operand_& o4 = opExt[EmitterUtils::kOp4];
+ const Operand_& o5 = opExt[EmitterUtils::kOp5];
- if (Reg::isZmm(o0 ) && Reg::isZmm(o1) &&
- Reg::isZmm(o2 ) && Reg::isZmm(o3) &&
- Reg::isZmm(_op4) && _op5.isMem()) {
-
- // Registers [o1, o2, o3, _op4] must start aligned and must be consecutive.
+ if (Reg::isZmm(o0) && Reg::isZmm(o1) && Reg::isZmm(o2) && Reg::isZmm(o3) && Reg::isZmm(o4) && o5.isMem()) {
+ // Registers [o1, o2, o3, o4] must start aligned and must be consecutive.
uint32_t i1 = o1.id();
uint32_t i2 = o2.id();
uint32_t i3 = o3.id();
- uint32_t i4 = _op4.id();
+ uint32_t i4 = o4.id();
if (ASMJIT_UNLIKELY((i1 & 0x3) != 0 || i2 != i1 + 1 || i3 != i1 + 2 || i4 != i1 + 3))
goto NotConsecutiveRegs;
opReg = o0.id();
- rmRel = &_op5;
+ rmRel = &o5;
goto EmitVexEvexM;
}
break;
@@ -2967,7 +2958,7 @@ CaseVexRm:
case InstDB::kEncodingVexRmi:
CaseVexRmi:
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -2999,25 +2990,32 @@ CaseVexRvm_R:
}
break;
- case InstDB::kEncodingVexRvm_ZDX_Wx:
+ case InstDB::kEncodingVexRvm_ZDX_Wx: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
if (ASMJIT_UNLIKELY(!o3.isNone() && !Reg::isGp(o3, Gp::kIdDx)))
goto InvalidInstruction;
ASMJIT_FALLTHROUGH;
+ }
- case InstDB::kEncodingVexRvm_Wx:
+ case InstDB::kEncodingVexRvm_Wx: {
opcode.addWIf(Reg::isGpq(o0) | (o2.size() == 8));
goto CaseVexRvm;
+ }
- case InstDB::kEncodingVexRvm_Lx:
+ case InstDB::kEncodingVexRvm_Lx: {
opcode |= x86OpcodeLBySize(o0.size() | o1.size());
goto CaseVexRvm;
+ }
- case InstDB::kEncodingVexRvmr_Lx:
+ case InstDB::kEncodingVexRvmr_Lx: {
opcode |= x86OpcodeLBySize(o0.size() | o1.size());
ASMJIT_FALLTHROUGH;
+ }
case InstDB::kEncodingVexRvmr: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
const uint32_t isign4 = isign3 + (o3.opType() << 9);
+
immValue = o3.id() << 4;
immSize = 1;
@@ -3040,8 +3038,10 @@ CaseVexRvm_R:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvmi: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
const uint32_t isign4 = isign3 + (o3.opType() << 9);
- immValue = o3.as<Imm>().i64();
+
+ immValue = o3.as<Imm>().value();
immSize = 1;
if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
@@ -3100,8 +3100,10 @@ CaseVexRvm_R:
case InstDB::kEncodingVexRmvi: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
const uint32_t isign4 = isign3 + (o3.opType() << 9);
- immValue = o3.as<Imm>().i64();
+
+ immValue = o3.as<Imm>().value();
immSize = 1;
if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
@@ -3249,7 +3251,7 @@ CaseVexRvm_R:
opcode &= Opcode::kLL_Mask;
opcode |= x86AltOpcodeOf(instInfo);
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -3295,7 +3297,7 @@ CaseVexRvm_R:
// The following instructions use the secondary opcode.
opcode = x86AltOpcodeOf(instInfo);
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -3390,7 +3392,7 @@ CaseVexRvm_R:
opcode |= x86AltOpcodeOf(instInfo);
opReg = opcode.extractO();
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -3434,7 +3436,7 @@ CaseVexRvm_R:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexVmi:
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 1;
CaseVexVmi_AfterImm:
@@ -3453,7 +3455,7 @@ CaseVexVmi_AfterImm:
case InstDB::kEncodingVexVmi4_Wx:
opcode.addWIf(Reg::isGpq(o0) || o1.size() == 8);
- immValue = o2.as<Imm>().i64();
+ immValue = o2.as<Imm>().value();
immSize = 4;
goto CaseVexVmi_AfterImm;
@@ -3462,6 +3464,7 @@ CaseVexVmi_AfterImm:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvrmRvmr: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
const uint32_t isign4 = isign3 + (o3.opType() << 9);
if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
@@ -3495,13 +3498,16 @@ CaseVexVmi_AfterImm:
}
case InstDB::kEncodingVexRvrmiRvmri_Lx: {
- if (!(options & Inst::kOptionOp4Op5Used) || !_op4.isImm())
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
+ const Operand_& o4 = opExt[EmitterUtils::kOp4];
+
+ if (ASMJIT_UNLIKELY(!o4.isImm()))
goto InvalidInstruction;
const uint32_t isign4 = isign3 + (o3.opType() << 9);
opcode |= x86OpcodeLBySize(o0.size() | o1.size() | o2.size() | o3.size());
- immValue = _op4.as<Imm>().u8() & 0x0F;
+ immValue = o4.as<Imm>().valueAs<uint8_t>() & 0x0F;
immSize = 1;
if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
@@ -3560,6 +3566,7 @@ CaseVexVmi_AfterImm:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingFma4: {
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
const uint32_t isign4 = isign3 + (o3.opType() << 9);
if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
@@ -3600,7 +3607,7 @@ CaseVexVmi_AfterImm:
// --------------------------------------------------------------------------
EmitX86OpMovAbs:
- immSize = FastUInt8(gpSize());
+ immSize = FastUInt8(registerSize());
writer.emitSegmentOverride(rmRel->as<Mem>().segmentId());
EmitX86Op:
@@ -3805,7 +3812,7 @@ EmitModSib:
else {
bool isOffsetI32 = rmRel->as<Mem>().offsetHi32() == (relOffset >> 31);
bool isOffsetU32 = rmRel->as<Mem>().offsetHi32() == 0;
- uint64_t baseAddress = codeInfo().baseAddress();
+ uint64_t baseAddress = code()->baseAddress();
// If relative addressing was not explicitly set then we can try to guess.
// By guessing we check some properties of the memory operand and try to
@@ -4241,7 +4248,7 @@ EmitVexEvexR:
rbReg &= 0x7;
writer.emit8(x86EncodeMod(3, opReg, rbReg));
- writer.emitImmByteOrDWord(immValue, immSize);
+ writer.emitImmByteOrDWord(uint64_t(immValue), immSize);
goto EmitDone;
}
@@ -4262,7 +4269,7 @@ EmitVexEvexR:
rbReg &= 0x7;
writer.emit8(x86EncodeMod(3, opReg, rbReg));
- writer.emitImmByteOrDWord(immValue, immSize);
+ writer.emitImmByteOrDWord(uint64_t(immValue), immSize);
goto EmitDone;
}
else {
@@ -4276,7 +4283,7 @@ EmitVexEvexR:
rbReg &= 0x7;
writer.emit8(x86EncodeMod(3, opReg, rbReg));
- writer.emitImmByteOrDWord(immValue, immSize);
+ writer.emitImmByteOrDWord(uint64_t(immValue), immSize);
goto EmitDone;
}
}
@@ -4459,15 +4466,15 @@ EmitJmpCall:
}
if (rmRel->isImm()) {
- uint64_t baseAddress = codeInfo().baseAddress();
- uint64_t jumpAddress = rmRel->as<Imm>().u64();
+ uint64_t baseAddress = code()->baseAddress();
+ uint64_t jumpAddress = rmRel->as<Imm>().valueAs<uint64_t>();
// If the base-address is known calculate a relative displacement and
// check if it fits in 32 bits (which is always true in 32-bit mode).
// Emit relative displacement as it was a bound label if all checks are ok.
if (baseAddress != Globals::kNoBaseAddress) {
uint64_t rel64 = jumpAddress - (ip + baseAddress) - inst32Size;
- if (archId() == ArchInfo::kIdX86 || Support::isInt32(int64_t(rel64))) {
+ if (Environment::is32Bit(arch()) || Support::isInt32(int64_t(rel64))) {
rel32 = uint32_t(rel64 & 0xFFFFFFFFu);
goto EmitJmpCallRel;
}
@@ -4492,7 +4499,7 @@ EmitJmpCall:
// REX prefix does nothing if not patched, but allows to patch the
// instruction to use MOD/M and to point to a memory where the final
// 64-bit address is stored.
- if (archId() != ArchInfo::kIdX86 && x86IsJmpOrCall(instId)) {
+ if (Environment::is64Bit(arch()) && x86IsJmpOrCall(instId)) {
if (!rex)
writer.emit8(kX86ByteRex);
@@ -4582,13 +4589,13 @@ EmitRel:
EmitDone:
if (ASMJIT_UNLIKELY(options & Inst::kOptionReserved)) {
#ifndef ASMJIT_NO_LOGGING
- if (hasEmitterOption(kOptionLoggingEnabled))
- _emitLog(instId, options, o0, o1, o2, o3, relSize, immSize, writer.cursor());
+ if (_logger)
+ EmitterUtils::logInstructionEmitted(this, instId, options, o0, o1, o2, opExt, relSize, immSize, writer.cursor());
#endif
}
- resetInstOptions();
resetExtraReg();
+ resetInstOptions();
resetInlineComment();
writer.done(this);
@@ -4625,7 +4632,14 @@ EmitDone:
#undef ERROR_HANDLER
Failed:
- return _emitFailed(err, instId, options, o0, o1, o2, o3);
+#ifndef ASMJIT_NO_LOGGING
+ return EmitterUtils::logInstructionFailed(this, err, instId, options, o0, o1, o2, opExt);
+#else
+ resetExtraReg();
+ resetInstOptions();
+ resetInlineComment();
+ return reportError(err);
+#endif
}
// ============================================================================
@@ -4633,6 +4647,9 @@ Failed:
// ============================================================================
Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
+ if (ASMJIT_UNLIKELY(!_code))
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
+
if (ASMJIT_UNLIKELY(alignMode >= kAlignCount))
return reportError(DebugUtils::errored(kErrorInvalidArgument));
@@ -4650,7 +4667,7 @@ Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
uint8_t pattern = 0x00;
switch (alignMode) {
case kAlignCode: {
- if (hasEmitterOption(kOptionOptimizedAlign)) {
+ if (hasEncodingOption(kEncodingOptionOptimizedAlign)) {
// Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 2B (NOP).
enum { kMaxNopSize = 9 };
@@ -4699,12 +4716,11 @@ Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
}
#ifndef ASMJIT_NO_LOGGING
- if (hasEmitterOption(kOptionLoggingEnabled)) {
- Logger* logger = _code->logger();
+ if (_logger) {
StringTmp<128> sb;
- sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationCode));
+ sb.appendChars(' ', _logger->indentation(FormatOptions::kIndentationCode));
sb.appendFormat("align %u\n", alignment);
- logger->log(sb);
+ _logger->log(sb);
}
#endif
@@ -4716,22 +4732,22 @@ Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
// ============================================================================
Error Assembler::onAttach(CodeHolder* code) noexcept {
- uint32_t archId = code->archId();
- if (!ArchInfo::isX86Family(archId))
+ uint32_t arch = code->arch();
+ if (!Environment::isFamilyX86(arch))
return DebugUtils::errored(kErrorInvalidArch);
ASMJIT_PROPAGATE(Base::onAttach(code));
- if (archId == ArchInfo::kIdX86) {
+ if (Environment::is32Bit(arch)) {
// 32 bit architecture - X86.
_gpRegInfo.setSignature(Gpd::kSignature);
- _globalInstOptions |= Inst::_kOptionInvalidRex;
+ _forcedInstOptions |= Inst::_kOptionInvalidRex;
_setAddressOverrideMask(kX86MemInfo_67H_X86);
}
else {
// 64 bit architecture - X64.
_gpRegInfo.setSignature(Gpq::kSignature);
- _globalInstOptions &= ~Inst::_kOptionInvalidRex;
+ _forcedInstOptions &= ~Inst::_kOptionInvalidRex;
_setAddressOverrideMask(kX86MemInfo_67H_X64);
}
@@ -4739,6 +4755,9 @@ Error Assembler::onAttach(CodeHolder* code) noexcept {
}
Error Assembler::onDetach(CodeHolder* code) noexcept {
+ _forcedInstOptions &= ~Inst::_kOptionInvalidRex;
+ _setAddressOverrideMask(0);
+
return Base::onDetach(code);
}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86assembler.h b/3rdparty/asmjit/src/asmjit/x86/x86assembler.h
index 3e3027bab4a..8cd10143b0e 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86assembler.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86assembler.h
@@ -37,9 +37,652 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// [asmjit::Assembler]
// ============================================================================
-//! Assembler (X86).
+//! X86/X64 assembler implementation.
//!
-//! Emits X86 machine-code into buffers managed by `CodeHolder`.
+//! x86::Assembler is a code emitter that emits machine code directly into the
+//! \ref CodeBuffer. The assembler is capable of targeting both 32-bit and 64-bit
+//! instruction sets, the instruction set can be configured through \ref CodeHolder.
+//!
+//! ### Basics
+//!
+//! The following example shows a basic use of `x86::Assembler`, how to generate
+//! a function that works in both 32-bit and 64-bit modes, and how to connect
+//! \ref JitRuntime, \ref CodeHolder, and `x86::Assembler`.
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Signature of the generated function.
+//! typedef int (*SumFunc)(const int* arr, size_t count);
+//!
+//! int main() {
+//! JitRuntime rt; // Create a runtime specialized for JIT.
+//! CodeHolder code; // Create a CodeHolder.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
+//!
+//! // Decide between 32-bit CDECL, WIN64, and SysV64 calling conventions:
+//! // 32-BIT - passed all arguments by stack.
+//! // WIN64 - passes first 4 arguments by RCX, RDX, R8, and R9.
+//! // UNIX64 - passes first 6 arguments by RDI, RSI, RCX, RDX, R8, and R9.
+//! x86::Gp arr, cnt;
+//! x86::Gp sum = x86::eax; // Use EAX as 'sum' as it's a return register.
+//!
+//! if (ASMJIT_ARCH_BITS == 64) {
+//! #if defined(_WIN32)
+//! arr = x86::rcx; // First argument (array ptr).
+//! cnt = x86::rdx; // Second argument (number of elements)
+//! #else
+//! arr = x86::rdi; // First argument (array ptr).
+//! cnt = x86::rsi; // Second argument (number of elements)
+//! #endif
+//! }
+//! else {
+//! arr = x86::edx; // Use EDX to hold the array pointer.
+//! cnt = x86::ecx; // Use ECX to hold the counter.
+//! // Fetch first and second arguments from [ESP + 4] and [ESP + 8].
+//! a.mov(arr, x86::ptr(x86::esp, 4));
+//! a.mov(cnt, x86::ptr(x86::esp, 8));
+//! }
+//!
+//! Label Loop = a.newLabel(); // To construct the loop, we need some labels.
+//! Label Exit = a.newLabel();
+//!
+//! a.xor_(sum, sum); // Clear 'sum' register (shorter than 'mov').
+//! a.test(cnt, cnt); // Border case:
+//! a.jz(Exit); // If 'cnt' is zero jump to 'Exit' now.
+//!
+//! a.bind(Loop); // Start of a loop iteration.
+//! a.add(sum, x86::dword_ptr(arr)); // Add int at [arr] to 'sum'.
+//! a.add(arr, 4); // Increment 'arr' pointer.
+//! a.dec(cnt); // Decrease 'cnt'.
+//! a.jnz(Loop); // If not zero jump to 'Loop'.
+//!
+//! a.bind(Exit); // Exit to handle the border case.
+//! a.ret(); // Return from function ('sum' == 'eax').
+//! // ----> x86::Assembler is no longer needed from here and can be destroyed <----
+//!
+//! SumFunc fn;
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//!
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
+//!
+//! static const int array[6] = { 4, 8, 15, 16, 23, 42 };
+//!
+//! int result = fn(array, 6); // Execute the generated code.
+//! printf("%d\n", result); // Print sum of array (108).
+//!
+//! rt.release(fn); // Explicitly remove the function from the runtime
+//! return 0; // Everything successful...
+//! }
+//! ```
+//!
+//! The example should be self-explanatory. It shows how to work with labels,
+//! how to use operands, and how to emit instructions that can use different
+//! registers based on runtime selection. It implements 32-bit CDECL, WIN64,
+//! and SysV64 caling conventions and will work on most X86/X64 environments.
+//!
+//! Although functions prologs / epilogs can be implemented manually, AsmJit
+//! provides utilities that can be used to create function prologs and epilogs
+//! automatically, see \ref asmjit_function for more details.
+//!
+//! ### Instruction Validation
+//!
+//! Assembler prefers speed over strictness by default. The implementation checks
+//! the type of operands and fails if the signature of types is invalid, however,
+//! it does only basic checks regarding registers and their groups used in
+//! instructions. It's possible to pass operands that don't form any valid
+//! signature to the implementation and succeed. This is usually not a problem
+//! as Assembler provides typed API so operand types are normally checked by C++
+//! compiler at compile time, however, Assembler is fully dynamic and its \ref
+//! emit() function can be called with any instruction id, options, and operands.
+//! Moreover, it's also possible to form instructions that will be accepted by
+//! the typed API, for example by calling `mov(x86::eax, x86::al)` - the C++
+//! compiler won't see a problem as both EAX and AL are \ref Gp registers.
+//!
+//! To help with common mistakes AsmJit allows to activate instruction validation.
+//! This feature instruments the Assembler to call \ref InstAPI::validate() before
+//! it attempts to encode any instruction.
+//!
+//! The example below illustrates how validation can be turned on:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! int main(int argc, char* argv[]) {
+//! JitRuntime rt; // Create a runtime specialized for JIT.
+//! CodeHolder code; // Create a CodeHolder.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
+//!
+//! // Enable strict validation.
+//! a.addValidationOptions(BaseEmitter::kValidationOptionAssembler);
+//!
+//! // Try to encode invalid or ill-formed instructions.
+//! Error err;
+//!
+//! // Invalid instruction.
+//! err = a.mov(x86::eax, x86::al);
+//! printf("Status: %s\n", DebugUtils::errorAsString(err));
+//!
+//! // Invalid instruction.
+//! err = a.emit(x86::Inst::kIdMovss, x86::eax, x86::xmm0);
+//! printf("Status: %s\n", DebugUtils::errorAsString(err));
+//!
+//! // Ambiguous operand size - the pointer requires size.
+//! err = a.inc(x86::ptr(x86::rax), 1);
+//! printf("Status: %s\n", DebugUtils::errorAsString(err));
+//!
+//! return 0;
+//! }
+//! ```
+//!
+//! ### Native Registers
+//!
+//! All emitters provide functions to construct machine-size registers depending
+//! on the target. This feature is for users that want to write code targeting
+//! both 32-bit and 64-bit architectures at the same time. In AsmJit terminology
+//! such registers have prefix `z`, so for example on X86 architecture the
+//! following native registers are provided:
+//!
+//! - `zax` - mapped to either `eax` or `rax`
+//! - `zbx` - mapped to either `ebx` or `rbx`
+//! - `zcx` - mapped to either `ecx` or `rcx`
+//! - `zdx` - mapped to either `edx` or `rdx`
+//! - `zsp` - mapped to either `esp` or `rsp`
+//! - `zbp` - mapped to either `ebp` or `rbp`
+//! - `zsi` - mapped to either `esi` or `rsi`
+//! - `zdi` - mapped to either `edi` or `rdi`
+//!
+//! They are accessible through \ref x86::Assembler, \ref x86::Builder, and
+//! \ref x86::Compiler. The example below illustrates how to use this feature:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! typedef int (*Func)(void);
+//!
+//! int main(int argc, char* argv[]) {
+//! JitRuntime rt; // Create a runtime specialized for JIT.
+//! CodeHolder code; // Create a CodeHolder.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
+//!
+//! // Let's get these registers from x86::Assembler.
+//! x86::Gp zbp = a.zbp();
+//! x86::Gp zsp = a.zsp();
+//!
+//! int stackSize = 32;
+//!
+//! // Function prolog.
+//! a.push(zbp);
+//! a.mov(zbp, zsp);
+//! a.sub(zsp, stackSize);
+//!
+//! // ... emit some code (this just sets return value to zero) ...
+//! a.xor_(x86::eax, x86::eax);
+//!
+//! // Function epilog and return.
+//! a.mov(zsp, zbp);
+//! a.pop(zbp);
+//! a.ret();
+//!
+//! // To make the example complete let's call it.
+//! Func fn;
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//!
+//! int result = fn(); // Execute the generated code.
+//! printf("%d\n", result); // Print the resulting "0".
+//!
+//! rt.release(fn); // Remove the function from the runtime.
+//! return 0;
+//! }
+//! ```
+//!
+//! The example just returns `0`, but the function generated contains a standard
+//! prolog and epilog sequence and the function itself reserves 32 bytes of local
+//! stack. The advantage is clear - a single code-base can handle multiple targets
+//! easily. If you want to create a register of native size dynamically by
+//! specifying its id it's also possible:
+//!
+//! ```
+//! void example(x86::Assembler& a) {
+//! x86::Gp zax = a.gpz(x86::Gp::kIdAx);
+//! x86::Gp zbx = a.gpz(x86::Gp::kIdBx);
+//! x86::Gp zcx = a.gpz(x86::Gp::kIdCx);
+//! x86::Gp zdx = a.gpz(x86::Gp::kIdDx);
+//!
+//! // You can also change register's id easily.
+//! x86::Gp zsp = zax;
+//! zsp.setId(4); // or x86::Gp::kIdSp.
+//! }
+//! ```
+//!
+//! ### Data Embedding
+//!
+//! x86::Assembler extends the standard \ref BaseAssembler with X86/X64 specific
+//! conventions that are often used by assemblers to embed data next to the code.
+//! The following functions can be used to embed data:
+//!
+//! - \ref x86::Assembler::db() - embeds byte (8 bits) (x86 naming).
+//! - \ref x86::Assembler::dw() - embeds word (16 bits) (x86 naming).
+//! - \ref x86::Assembler::dd() - embeds dword (32 bits) (x86 naming).
+//! - \ref x86::Assembler::dq() - embeds qword (64 bits) (x86 naming).
+//!
+//! - \ref BaseAssembler::embedInt8() - embeds int8_t (portable naming).
+//! - \ref BaseAssembler::embedUInt8() - embeds uint8_t (portable naming).
+//! - \ref BaseAssembler::embedInt16() - embeds int16_t (portable naming).
+//! - \ref BaseAssembler::embedUInt16() - embeds uint16_t (portable naming).
+//! - \ref BaseAssembler::embedInt32() - embeds int32_t (portable naming).
+//! - \ref BaseAssembler::embedUInt32() - embeds uint32_t (portable naming).
+//! - \ref BaseAssembler::embedInt64() - embeds int64_t (portable naming).
+//! - \ref BaseAssembler::embedUInt64() - embeds uint64_t (portable naming).
+//! - \ref BaseAssembler::embedFloat() - embeds float (portable naming).
+//! - \ref BaseAssembler::embedDouble() - embeds double (portable naming).
+//!
+//! The following example illustrates how embed works:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! using namespace asmjit;
+//!
+//! void embedData(x86::Assembler& a) {
+//! a.db(0xFF); // Embeds 0xFF byte.
+//! a.dw(0xFF00); // Embeds 0xFF00 word (little-endian).
+//! a.dd(0xFF000000); // Embeds 0xFF000000 dword (little-endian).
+//! a.embedFloat(0.4f); // Embeds 0.4f (32-bit float, little-endian).
+//! }
+//! ```
+//!
+//! Sometimes it's required to read the data that is embedded after code, for
+//! example. This can be done through \ref Label as shown below:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! using namespace asmjit;
+//!
+//! void embedData(x86::Assembler& a, const Label& L_Data) {
+//! x86::Gp addr = a.zax(); // EAX or RAX.
+//! x86::Gp val = x86::edi; // Where to store some value...
+//!
+//! // Approach 1 - Load the address to register through LEA. This approach
+//! // is flexible as the address can be then manipulated, for
+//! // example if you have a data array, which would need index.
+//! a.lea(addr, L_Data); // Loads the address of the label to EAX or RAX.
+//! a.mov(val, dword_ptr(addr));
+//!
+//! // Approach 2 - Load the data directly by using L_Data in address. It's
+//! // worth noting that this doesn't work with indexes in X64
+//! // mode. It will use absolute address in 32-bit mode and
+//! // relative address (RIP) in 64-bit mode.
+//! a.mov(val, dword_ptr(L_Data));
+//! }
+//! ```
+//!
+//! ### Label Embedding
+//!
+//! It's also possible to embed labels. In general AsmJit provides the following
+//! options:
+//!
+//! - \ref BaseEmitter::embedLabel() - Embeds absolute address of a label.
+//! This is target dependent and would embed either 32-bit or 64-bit data
+//! that embeds absolute label address. This kind of embedding cannot be
+//! used in a position independent code.
+//!
+//! - \ref BaseEmitter::embedLabelDelta() - Embeds a difference between two
+//! labels. The size of the difference can be specified so it's possible to
+//! embed 8-bit, 16-bit, 32-bit, and 64-bit difference, which is sufficient
+//! for most purposes.
+//!
+//! The following example demonstrates how to embed labels and their differences:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! using namespace asmjit;
+//!
+//! void embedLabel(x86::Assembler& a, const Label& L_Data) {
+//! // [1] Embed L_Data - the size of the data will be dependent on the target.
+//! a.embedLabel(L_Data);
+//!
+//! // [2] Embed a 32-bit difference of two labels.
+//! Label L_Here = a.newLabel();
+//! a.bind(L_Here);
+//! // Embeds int32_t(L_Data - L_Here).
+//! a.embedLabelDelta(L_Data, L_Here, 4);
+//! }
+//! ```
+//!
+//! ### Using FuncFrame and FuncDetail with x86::Assembler
+//!
+//! The example below demonstrates how \ref FuncFrame and \ref FuncDetail can be
+//! used together with \ref x86::Assembler to generate a function that will use
+//! platform dependent calling conventions automatically depending on the target:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! typedef void (*SumIntsFunc)(int* dst, const int* a, const int* b);
+//!
+//! int main(int argc, char* argv[]) {
+//! JitRuntime rt; // Create JIT Runtime.
+//! CodeHolder code; // Create a CodeHolder.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
+//!
+//! // Decide which registers will be mapped to function arguments. Try changing
+//! // registers of dst, src_a, and src_b and see what happens in function's
+//! // prolog and epilog.
+//! x86::Gp dst = a.zax();
+//! x86::Gp src_a = a.zcx();
+//! x86::Gp src_b = a.zdx();
+//!
+//! X86::Xmm vec0 = x86::xmm0;
+//! X86::Xmm vec1 = x86::xmm1;
+//!
+//! // Create/initialize FuncDetail and FuncFrame.
+//! FuncDetail func;
+//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost));
+//!
+//! FuncFrame frame;
+//! frame.init(func);
+//!
+//! // Make XMM0 and XMM1 dirty - kGroupVec describes XMM|YMM|ZMM registers.
+//! frame.setDirtyRegs(x86::Reg::kGroupVec, IntUtils::mask(0, 1));
+//!
+//! // Alternatively, if you don't want to use register masks you can pass BaseReg
+//! // to addDirtyRegs(). The following code would add both xmm0 and xmm1.
+//! frame.addDirtyRegs(x86::xmm0, x86::xmm1);
+//!
+//! FuncArgsAssignment args(&func); // Create arguments assignment context.
+//! args.assignAll(dst, src_a, src_b);// Assign our registers to arguments.
+//! args.updateFrameInfo(frame); // Reflect our args in FuncFrame.
+//! frame.finalize(); // Finalize the FuncFrame (updates it).
+//!
+//! a.emitProlog(frame); // Emit function prolog.
+//! a.emitArgsAssignment(frame, args);// Assign arguments to registers.
+//! a.movdqu(vec0, x86::ptr(src_a)); // Load 4 ints from [src_a] to XMM0.
+//! a.movdqu(vec1, x86::ptr(src_b)); // Load 4 ints from [src_b] to XMM1.
+//! a.paddd(vec0, vec1); // Add 4 ints in XMM1 to XMM0.
+//! a.movdqu(x86::ptr(dst), vec0); // Store the result to [dst].
+//! a.emitEpilog(frame); // Emit function epilog and return.
+//!
+//! SumIntsFunc fn;
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error case.
+//!
+//! // Execute the generated function.
+//! int inA[4] = { 4, 3, 2, 1 };
+//! int inB[4] = { 1, 5, 2, 8 };
+//! int out[4];
+//! fn(out, inA, inB);
+//!
+//! // Prints {5 8 4 9}
+//! printf("{%d %d %d %d}\n", out[0], out[1], out[2], out[3]);
+//!
+//! rt.release(fn);
+//! return 0;
+//! }
+//! ```
+//!
+//! ### Using x86::Assembler as Code-Patcher
+//!
+//! This is an advanced topic that is sometimes unavoidable. AsmJit by default
+//! appends machine code it generates into a \ref CodeBuffer, however, it also
+//! allows to set the offset in \ref CodeBuffer explicitly and to overwrite its
+//! content. This technique is extremely dangerous as X86 instructions have
+//! variable length (see below), so you should in general only patch code to
+//! change instruction's immediate values or some other details not known the
+//! at a time the instruction was emitted. A typical scenario that requires
+//! code-patching is when you start emitting function and you don't know how
+//! much stack you want to reserve for it.
+//!
+//! Before we go further it's important to introduce instruction options, because
+//! they can help with code-patching (and not only patching, but that will be
+//! explained in AVX-512 section):
+//!
+//! - Many general-purpose instructions (especially arithmetic ones) on X86
+//! have multiple encodings - in AsmJit this is usually called 'short form'
+//! and 'long form'.
+//! - AsmJit always tries to use 'short form' as it makes the resulting
+//! machine-code smaller, which is always good - this decision is used
+//! by majority of assemblers out there.
+//! - AsmJit allows to override the default decision by using `short_()`
+//! and `long_()` instruction options to force short or long form,
+//! respectively. The most useful is `long_()` as it basically forces
+//! AsmJit to always emit the longest form. The `short_()` is not that
+//! useful as it's automatic (except jumps to non-bound labels). Note that
+//! the underscore after each function name avoids collision with built-in
+//! C++ types.
+//!
+//! To illustrate what short form and long form means in binary let's assume
+//! we want to emit "add esp, 16" instruction, which has two possible binary
+//! encodings:
+//!
+//! - `83C410` - This is a short form aka `short add esp, 16` - You can see
+//! opcode byte (0x8C), MOD/RM byte (0xC4) and an 8-bit immediate value
+//! representing `16`.
+//! - `81C410000000` - This is a long form aka `long add esp, 16` - You can
+//! see a different opcode byte (0x81), the same Mod/RM byte (0xC4) and a
+//! 32-bit immediate in little-endian representing `16`.
+//!
+//! It should be obvious that patching an existing instruction into an instruction
+//! having a different size may create various problems. So it's recommended to be
+//! careful and to only patch instructions into instructions having the same size.
+//! The example below demonstrates how instruction options can be used to guarantee
+//! the size of an instruction by forcing the assembler to use long-form encoding:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! typedef int (*Func)(void);
+//!
+//! int main(int argc, char* argv[]) {
+//! JitRuntime rt; // Create a runtime specialized for JIT.
+//! CodeHolder code; // Create a CodeHolder.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
+//!
+//! // Let's get these registers from x86::Assembler.
+//! x86::Gp zbp = a.zbp();
+//! x86::Gp zsp = a.zsp();
+//!
+//! // Function prolog.
+//! a.push(zbp);
+//! a.mov(zbp, zsp);
+//!
+//! // This is where we are gonna patch the code later, so let's get the offset
+//! // (the current location) from the beginning of the code-buffer.
+//! size_t patchOffset = a.offset();
+//! // Let's just emit 'sub zsp, 0' for now, but don't forget to use LONG form.
+//! a.long_().sub(zsp, 0);
+//!
+//! // ... emit some code (this just sets return value to zero) ...
+//! a.xor_(x86::eax, x86::eax);
+//!
+//! // Function epilog and return.
+//! a.mov(zsp, zbp);
+//! a.pop(zbp);
+//! a.ret();
+//!
+//! // Now we know how much stack size we want to reserve. I have chosen 128
+//! // bytes on purpose as it's encodable only in long form that we have used.
+//!
+//! int stackSize = 128; // Number of bytes to reserve on the stack.
+//! a.setOffset(patchOffset); // Move the current cursor to `patchOffset`.
+//! a.long_().sub(zsp, stackSize); // Patch the code; don't forget to use LONG form.
+//!
+//! // Now the code is ready to be called
+//! Func fn;
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//!
+//! int result = fn(); // Execute the generated code.
+//! printf("%d\n", result); // Print the resulting "0".
+//!
+//! rt.release(fn); // Remove the function from the runtime.
+//! return 0;
+//! }
+//! ```
+//!
+//! If you run the example it will just work, because both instructions have
+//! the same size. As an experiment you can try removing `long_()` form to
+//! see what happens when wrong code is generated.
+//!
+//! ### Code Patching and REX Prefix
+//!
+//! In 64-bit mode there is one more thing to worry about when patching code:
+//! REX prefix. It's a single byte prefix designed to address registers with
+//! ids from 9 to 15 and to override the default width of operation from 32
+//! to 64 bits. AsmJit, like other assemblers, only emits REX prefix when it's
+//! necessary. If the patched code only changes the immediate value as shown
+//! in the previous example then there is nothing to worry about as it doesn't
+//! change the logic behind emitting REX prefix, however, if the patched code
+//! changes register id or overrides the operation width then it's important
+//! to take care of REX prefix as well.
+//!
+//! AsmJit contains another instruction option that controls (forces) REX
+//! prefix - `rex()`. If you use it the instruction emitted will always use
+//! REX prefix even when it's encodable without it. The following list contains
+//! some instructions and their binary representations to illustrate when it's
+//! emitted:
+//!
+//! - `__83C410` - `add esp, 16` - 32-bit operation in 64-bit mode doesn't require REX prefix.
+//! - `4083C410` - `rex add esp, 16` - 32-bit operation in 64-bit mode with forced REX prefix (0x40).
+//! - `4883C410` - `add rsp, 16` - 64-bit operation in 64-bit mode requires REX prefix (0x48).
+//! - `4183C410` - `add r12d, 16` - 32-bit operation in 64-bit mode using R12D requires REX prefix (0x41).
+//! - `4983C410` - `add r12, 16` - 64-bit operation in 64-bit mode using R12 requires REX prefix (0x49).
+//!
+//! ### More Prefixes
+//!
+//! X86 architecture is known for its prefixes. AsmJit supports all prefixes
+//! that can affect how the instruction is encoded:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! void prefixesExample(x86::Assembler& a) {
+//! // Lock prefix for implementing atomics:
+//! // lock add dword ptr [dst], 1
+//! a.lock().add(x86::dword_ptr(dst), 1);
+//!
+//! // Similarly, XAcquire/XRelease prefixes are also available:
+//! // xacquire add dword ptr [dst], 1
+//! a.xacquire().add(x86::dword_ptr(dst), 1);
+//!
+//! // Rep prefix (see also repe/repz and repne/repnz):
+//! // rep movs byte ptr [dst], byte ptr [src]
+//! a.rep().movs(x86::byte_ptr(dst), x86::byte_ptr(src));
+//!
+//! // Forcing REX prefix in 64-bit mode.
+//! // rex mov eax, 1
+//! a.rex().mov(x86::eax, 1);
+//!
+//! // AVX instruction without forced prefix uses the shortest encoding:
+//! // vaddpd xmm0, xmm1, xmm2 -> [C5|F1|58|C2]
+//! a.vaddpd(x86::xmm0, x86::xmm1, x86::xmm2);
+//!
+//! // Forcing VEX3 prefix (AVX):
+//! // vex3 vaddpd xmm0, xmm1, xmm2 -> [C4|E1|71|58|C2]
+//! a.vex3().vaddpd(x86::xmm0, x86::xmm1, x86::xmm2);
+//!
+//! // Forcing EVEX prefix (AVX512):
+//! // evex vaddpd xmm0, xmm1, xmm2 -> [62|F1|F5|08|58|C2]
+//! a.evex().vaddpd(x86::xmm0, x86::xmm1, x86::xmm2);
+//!
+//! // Some instructions accept prefixes not originally intended to:
+//! // rep ret
+//! a.rep().ret();
+//! }
+//! ```
+//!
+//! It's important to understand that prefixes are part of instruction options.
+//! When a member function that involves adding a prefix is called the prefix
+//! is combined with existing instruction options, which will affect the next
+//! instruction generated.
+//!
+//! ### Generating AVX512 code.
+//!
+//! x86::Assembler can generate AVX512+ code including the use of opmask
+//! registers. Opmask can be specified through \ref x86::Assembler::k()
+//! function, which stores it as an extra register, which will be used
+//! by the next instruction. AsmJit uses such concept for manipulating
+//! instruction options as well.
+//!
+//! The following AVX512 features are supported:
+//!
+//! - Opmask selector {k} and zeroing {z}.
+//! - Rounding modes {rn|rd|ru|rz} and suppress-all-exceptions {sae} option.
+//! - AVX512 broadcasts {1toN}.
+//!
+//! The following example demonstrates how AVX512 features can be used:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! void generateAVX512Code(x86::Assembler& a) {
+//! using namespace x86;
+//!
+//! // Opmask Selectors
+//! // ----------------
+//! //
+//! // - Opmask / zeroing is part of the instruction options / extraReg.
+//! // - k(reg) is like {kreg} in Intel syntax.
+//! // - z() is like {z} in Intel syntax.
+//!
+//! // vaddpd zmm {k1} {z}, zmm1, zmm2
+//! a.k(k1).z().vaddpd(zmm0, zmm1, zmm2);
+//!
+//! // Memory Broadcasts
+//! // -----------------
+//! //
+//! // - Broadcast data is part of memory operand.
+//! // - Use x86::Mem::_1toN(), which returns a new x86::Mem operand.
+//!
+//! // vaddpd zmm0 {k1} {z}, zmm1, [rcx] {1to8}
+//! a.k(k1).z().vaddpd(zmm0, zmm1, x86::mem(rcx)._1to8());
+//!
+//! // Embedded Rounding & Suppress-All-Exceptoins
+//! // -------------------------------------------
+//! //
+//! // - Rounding mode and {sae} are part of instruction options.
+//! // - Use sae() to enable exception suppression.
+//! // - Use rn_sae(), rd_sae(), ru_sae(), and rz_sae() - to enable rounding.
+//! // - Embedded rounding implicitly sets {sae} as well, that's why the API
+//! // also has sae() suffix, to make it clear.
+//!
+//! // vcmppd k1, zmm1, zmm2, 0x00 {sae}
+//! a.sae().vcmppd(k1, zmm1, zmm2, 0);
+//!
+//! // vaddpd zmm0, zmm1, zmm2 {rz}
+//! a.rz_sae().vaddpd(zmm0, zmm1, zmm2);
+//! }
+//! ```
class ASMJIT_VIRTAPI Assembler
: public BaseAssembler,
public EmitterImplicitT<Assembler> {
@@ -69,12 +712,10 @@ public:
//! \}
//! \endcond
- //! \cond INTERNAL
//! \name Emit
//! \{
- using BaseEmitter::_emit;
- ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) override;
+ ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
//! \}
//! \endcond
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp b/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp
index 4e65c7b16b5..b3c0b261a0b 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp
@@ -46,6 +46,8 @@ Builder::~Builder() noexcept {}
Error Builder::finalize() {
ASMJIT_PROPAGATE(runPasses());
Assembler a(_code);
+ a.addEncodingOptions(encodingOptions());
+ a.addValidationOptions(validationOptions());
return serialize(&a);
}
@@ -54,13 +56,13 @@ Error Builder::finalize() {
// ============================================================================
Error Builder::onAttach(CodeHolder* code) noexcept {
- uint32_t archId = code->archId();
- if (!ArchInfo::isX86Family(archId))
+ uint32_t arch = code->arch();
+ if (!Environment::isFamilyX86(arch))
return DebugUtils::errored(kErrorInvalidArch);
ASMJIT_PROPAGATE(Base::onAttach(code));
- _gpRegInfo.setSignature(archId == ArchInfo::kIdX86 ? uint32_t(Gpd::kSignature) : uint32_t(Gpq::kSignature));
+ _gpRegInfo.setSignature(Environment::is32Bit(arch) ? uint32_t(Gpd::kSignature) : uint32_t(Gpq::kSignature));
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86builder.h b/3rdparty/asmjit/src/asmjit/x86/x86builder.h
index 66e2dfc99d8..256bc9ecbec 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86builder.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86builder.h
@@ -40,7 +40,315 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// [asmjit::x86::Builder]
// ============================================================================
-//! Architecture-dependent asm-builder (X86).
+//! X86/X64 builder implementation.
+//!
+//! The code representation used by \ref BaseBuilder is compatible with everything
+//! AsmJit provides. Each instruction is stored as \ref InstNode, which contains
+//! instruction id, options, and operands. Each instruction emitted will create
+//! a new \ref InstNode instance and add it to the current cursor in the double-linked
+//! list of nodes. Since the instruction stream used by \ref BaseBuilder can be
+//! manipulated, we can rewrite the SumInts example from \ref asmjit_assembler
+//! into the following:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! typedef void (*SumIntsFunc)(int* dst, const int* a, const int* b);
+//!
+//! // Small helper function to print the current content of `cb`.
+//! static void dumpCode(BaseBuilder& builder, const char* phase) {
+//! String sb;
+//! builder.dump(sb);
+//! printf("%s:\n%s\n", phase, sb.data());
+//! }
+//!
+//! int main() {
+//! JitRuntime rt; // Create JIT Runtime.
+//! CodeHolder code; // Create a CodeHolder.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Builder cb(&code); // Create and attach x86::Builder to `code`.
+//!
+//! // Decide which registers will be mapped to function arguments. Try changing
+//! // registers of `dst`, `srcA`, and `srcB` and see what happens in function's
+//! // prolog and epilog.
+//! x86::Gp dst = cb.zax();
+//! x86::Gp srcA = cb.zcx();
+//! x86::Gp srcB = cb.zdx();
+//!
+//! X86::Xmm vec0 = x86::xmm0;
+//! X86::Xmm vec1 = x86::xmm1;
+//!
+//! // Create and initialize `FuncDetail`.
+//! FuncDetail func;
+//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost));
+//!
+//! // Remember prolog insertion point.
+//! BaseNode* prologInsertionPoint = cb.cursor();
+//!
+//! // Emit function body:
+//! cb.movdqu(vec0, x86::ptr(srcA)); // Load 4 ints from [srcA] to XMM0.
+//! cb.movdqu(vec1, x86::ptr(srcB)); // Load 4 ints from [srcB] to XMM1.
+//! cb.paddd(vec0, vec1); // Add 4 ints in XMM1 to XMM0.
+//! cb.movdqu(x86::ptr(dst), vec0); // Store the result to [dst].
+//!
+//! // Remember epilog insertion point.
+//! BaseNode* epilogInsertionPoint = cb.cursor();
+//!
+//! // Let's see what we have now.
+//! dumpCode(cb, "Raw Function");
+//!
+//! // Now, after we emitted the function body, we can insert the prolog, arguments
+//! // allocation, and epilog. This is not possible with using pure x86::Assembler.
+//! FuncFrame frame;
+//! frame.init(func);
+//!
+//! // Make XMM0 and XMM1 dirty; `kGroupVec` describes XMM|YMM|ZMM registers.
+//! frame.setDirtyRegs(x86::Reg::kGroupVec, IntUtils::mask(0, 1));
+//!
+//! FuncArgsAssignment args(&func); // Create arguments assignment context.
+//! args.assignAll(dst, srcA, srcB); // Assign our registers to arguments.
+//! args.updateFrame(frame); // Reflect our args in FuncFrame.
+//! frame.finalize(); // Finalize the FuncFrame (updates it).
+//!
+//! // Insert function prolog and allocate arguments to registers.
+//! cb.setCursor(prologInsertionPoint);
+//! cb.emitProlog(frame);
+//! cb.emitArgsAssignment(frame, args);
+//!
+//! // Insert function epilog.
+//! cb.setCursor(epilogInsertionPoint);
+//! cb.emitEpilog(frame);
+//!
+//! // Let's see how the function's prolog and epilog looks.
+//! dumpCode(cb, "Prolog & Epilog");
+//!
+//! // IMPORTANT: Builder requires finalize() to be called to serialize its
+//! // code to the Assembler (it automatically creates one if not attached).
+//! cb.finalize();
+//!
+//! SumIntsFunc fn;
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error case.
+//!
+//! // Execute the generated function.
+//! int inA[4] = { 4, 3, 2, 1 };
+//! int inB[4] = { 1, 5, 2, 8 };
+//! int out[4];
+//! fn(out, inA, inB);
+//!
+//! // Prints {5 8 4 9}
+//! printf("{%d %d %d %d}\n", out[0], out[1], out[2], out[3]);
+//!
+//! rt.release(fn); // Explicitly remove the function from the runtime.
+//! return 0;
+//! }
+//! ```
+//!
+//! When the example is executed it should output the following (this one using
+//! AMD64-SystemV ABI):
+//!
+//! ```
+//! Raw Function:
+//! movdqu xmm0, [rcx]
+//! movdqu xmm1, [rdx]
+//! paddd xmm0, xmm1
+//! movdqu [rax], xmm0
+//!
+//! Prolog & Epilog:
+//! mov rax, rdi
+//! mov rcx, rsi
+//! movdqu xmm0, [rcx]
+//! movdqu xmm1, [rdx]
+//! paddd xmm0, xmm1
+//! movdqu [rax], xmm0
+//! ret
+//!
+//! {5 8 4 9}
+//! ```
+//!
+//! The number of use-cases of \ref BaseBuilder is not limited and highly depends
+//! on your creativity and experience. The previous example can be easily improved
+//! to collect all dirty registers inside the function programmatically and to pass
+//! them to \ref FuncFrame::setDirtyRegs().
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! // NOTE: This function doesn't cover all possible constructs. It ignores
+//! // instructions that write to implicit registers that are not part of the
+//! // operand list. It also counts read-only registers. Real implementation
+//! // would be a bit more complicated, but still relatively easy to implement.
+//! static void collectDirtyRegs(const BaseNode* first,
+//! const BaseNode* last,
+//! uint32_t regMask[BaseReg::kGroupVirt]) {
+//! const BaseNode* node = first;
+//! while (node) {
+//! if (node->actsAsInst()) {
+//! const InstNode* inst = node->as<InstNode>();
+//! const Operand* opArray = inst->operands();
+//!
+//! for (uint32_t i = 0, opCount = inst->opCount(); i < opCount; i++) {
+//! const Operand& op = opArray[i];
+//! if (op.isReg()) {
+//! const x86::Reg& reg = op.as<x86::Reg>();
+//! if (reg.group() < BaseReg::kGroupVirt) {
+//! regMask[reg.group()] |= 1u << reg.id();
+//! }
+//! }
+//! }
+//! }
+//!
+//! if (node == last)
+//! break;
+//! node = node->next();
+//! }
+//! }
+//!
+//! static void setDirtyRegsOfFuncFrame(const x86::Builder& builder, FuncFrame& frame) {
+//! uint32_t regMask[BaseReg::kGroupVirt] {};
+//! collectDirtyRegs(builder.firstNode(), builder.lastNode(), regMask);
+//!
+//! // X86/X64 ABIs only require to save GP/XMM registers:
+//! frame.setDirtyRegs(x86::Reg::kGroupGp , regMask[x86::Reg::kGroupGp ]);
+//! frame.setDirtyRegs(x86::Reg::kGroupVec, regMask[x86::Reg::kGroupVec]);
+//! }
+//! ```
+//!
+//! ### Casting Between Various Emitters
+//!
+//! Even when \ref BaseAssembler and \ref BaseBuilder provide the same interface
+//! as defined by \ref BaseEmitter their platform dependent variants like \ref
+//! x86::Assembler and \ref x86::Builder cannot be interchanged or casted
+//! to each other by using a C++ `static_cast<>`. The main reason is the
+//! inheritance graph of these classes is different and cast-incompatible, as
+//! illustrated below:
+//!
+//! ```
+//! +--------------+ +=========================+
+//! +----------------------->| x86::Emitter |<--+--# x86::EmitterImplicitT<> #<--+
+//! | +--------------+ | +=========================+ |
+//! | (abstract) | (mixin) |
+//! | +--------------+ +~~~~~~~~~~~~~~+ | |
+//! +-->| BaseAssembler|---->|x86::Assembler|<--+ |
+//! | +--------------+ +~~~~~~~~~~~~~~+ | |
+//! | (abstract) (final) | |
+//! +===============+ | +--------------+ +~~~~~~~~~~~~~~+ | |
+//! # BaseEmitter #--+-->| BaseBuilder |--+->| x86::Builder |<--+ |
+//! +===============+ +--------------+ | +~~~~~~~~~~~~~~+ |
+//! (abstract) (abstract) | (final) |
+//! +---------------------+ |
+//! | |
+//! | +--------------+ +~~~~~~~~~~~~~~+ +=========================+ |
+//! +-->| BaseCompiler |---->| x86::Compiler|<-----# x86::EmitterExplicitT<> #---+
+//! +--------------+ +~~~~~~~~~~~~~~+ +=========================+
+//! (abstract) (final) (mixin)
+//! ```
+//!
+//! The graph basically shows that it's not possible to cast between \ref
+//! x86::Assembler and \ref x86::Builder. However, since both share the
+//! base interface (\ref BaseEmitter) it's possible to cast them to a class
+//! that cannot be instantiated, but defines the same interface - the class
+//! is called \ref x86::Emitter and was introduced to make it possible to
+//! write a function that can emit to both \ref x86::Assembler and \ref
+//! x86::Builder. Note that \ref x86::Emitter cannot be created, it's abstract
+//! and has private constructors and destructors; it was only designed to be
+//! casted to and used as an interface.
+//!
+//! Each architecture-specific emitter implements a member function called
+//! `as<arch::Emitter>()`, which casts the instance to the architecture
+//! specific emitter as illustrated below:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! static void emitSomething(x86::Emitter* e) {
+//! e->mov(x86::eax, x86::ebx);
+//! }
+//!
+//! static void assemble(CodeHolder& code, bool useAsm) {
+//! if (useAsm) {
+//! x86::Assembler assembler(&code);
+//! emitSomething(assembler.as<x86::Emitter>());
+//! }
+//! else {
+//! x86::Builder builder(&code);
+//! emitSomething(builder.as<x86::Emitter>());
+//!
+//! // NOTE: Builder requires `finalize()` to be called to serialize its
+//! // content to Assembler (it automatically creates one if not attached).
+//! builder.finalize();
+//! }
+//! }
+//! ```
+//!
+//! The example above shows how to create a function that can emit code to
+//! either \ref x86::Assembler or \ref x86::Builder through \ref x86::Emitter,
+//! which provides emitter-neutral functionality. \ref x86::Emitter, however,
+//! doesn't provide any emitter-specific functionality like `setCursor()`.
+//!
+//! ### Code Injection and Manipulation
+//!
+//! \ref BaseBuilder emitter stores its nodes in a double-linked list, which
+//! makes it easy to manipulate that list during the code generation or
+//! afterwards. Each node is always emitted next to the current cursor and the
+//! cursor is advanced to that newly emitted node. The cursor can be retrieved
+//! and changed by \ref BaseBuilder::cursor() and \ref BaseBuilder::setCursor(),
+//! respectively.
+//!
+//! The example below demonstrates how to remember a node and inject something
+//! next to it.
+//!
+//! ```
+//! static void example(x86::Builder& builder) {
+//! // Emit something, after it returns the cursor would point at the last
+//! // emitted node.
+//! builder.mov(x86::rax, x86::rdx); // [1]
+//!
+//! // We can retrieve the node.
+//! BaseNode* node = builder.cursor();
+//!
+//! // Change the instruction we just emitted, just for fun...
+//! if (node->isInst()) {
+//! InstNode* inst = node->as<InstNode>();
+//! // Changes the operands at index [1] to RCX.
+//! inst->setOp(1, x86::rcx);
+//! }
+//!
+//! // ------------------------- Generate Some Code -------------------------
+//! builder.add(x86::rax, x86::rdx); // [2]
+//! builder.shr(x86::rax, 3); // [3]
+//! // ----------------------------------------------------------------------
+//!
+//! // Now, we know where our node is, and we can simply change the cursor
+//! // and start emitting something after it. The setCursor() function
+//! // returns the previous cursor, and it's always a good practice to remember
+//! // it, because you never know if you are not already injecting the code
+//! // somewhere else...
+//! BaseNode* oldCursor = builder.setCursor(node);
+//!
+//! builder.mul(x86::rax, 8); // [4]
+//!
+//! // Restore the cursor
+//! builder.setCursor(oldCursor);
+//! }
+//! ```
+//!
+//! The function above would actually emit the following:
+//!
+//! ```
+//! mov rax, rcx ; [1] Patched at the beginning.
+//! mul rax, 8 ; [4] Injected.
+//! add rax, rdx ; [2] Followed [1] initially.
+//! shr rax, 3 ; [3] Follows [2].
+//! ```
class ASMJIT_VIRTAPI Builder
: public BaseBuilder,
public EmitterImplicitT<Builder> {
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86callconv.cpp b/3rdparty/asmjit/src/asmjit/x86/x86callconv.cpp
index 7ec4c55ef0a..e0a3f213dfe 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86callconv.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86callconv.cpp
@@ -33,13 +33,19 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// [asmjit::x86::CallConvInternal - Init]
// ============================================================================
-static inline void CallConv_initX86Common(CallConv& cc) noexcept {
- cc.setNaturalStackAlignment(4);
- cc.setArchType(ArchInfo::kIdX86);
- cc.setPreservedRegs(Reg::kGroupGp, Support::bitMask(Gp::kIdBx, Gp::kIdSp, Gp::kIdBp, Gp::kIdSi, Gp::kIdDi));
+namespace CallConvInternal {
+
+static inline bool shouldThreatAsCDeclIn64BitMode(uint32_t ccId) noexcept {
+ return ccId == CallConv::kIdCDecl ||
+ ccId == CallConv::kIdStdCall ||
+ ccId == CallConv::kIdThisCall ||
+ ccId == CallConv::kIdFastCall ||
+ ccId == CallConv::kIdRegParm1 ||
+ ccId == CallConv::kIdRegParm2 ||
+ ccId == CallConv::kIdRegParm3;
}
-ASMJIT_FAVOR_SIZE Error CallConvInternal::init(CallConv& cc, uint32_t ccId) noexcept {
+ASMJIT_FAVOR_SIZE Error init(CallConv& cc, uint32_t ccId, const Environment& environment) noexcept {
constexpr uint32_t kGroupGp = Reg::kGroupGp;
constexpr uint32_t kGroupVec = Reg::kGroupVec;
constexpr uint32_t kGroupMm = Reg::kGroupMm;
@@ -54,110 +60,179 @@ ASMJIT_FAVOR_SIZE Error CallConvInternal::init(CallConv& cc, uint32_t ccId) noex
constexpr uint32_t kZsi = Gp::kIdSi;
constexpr uint32_t kZdi = Gp::kIdDi;
- switch (ccId) {
- case CallConv::kIdX86StdCall:
- cc.setFlags(CallConv::kFlagCalleePopsStack);
- CallConv_initX86Common(cc);
- break;
-
- case CallConv::kIdX86MsThisCall:
- cc.setFlags(CallConv::kFlagCalleePopsStack);
- cc.setPassedOrder(kGroupGp, kZcx);
- CallConv_initX86Common(cc);
- break;
-
- case CallConv::kIdX86MsFastCall:
- case CallConv::kIdX86GccFastCall:
- cc.setFlags(CallConv::kFlagCalleePopsStack);
- cc.setPassedOrder(kGroupGp, kZcx, kZdx);
- CallConv_initX86Common(cc);
- break;
-
- case CallConv::kIdX86GccRegParm1:
- cc.setPassedOrder(kGroupGp, kZax);
- CallConv_initX86Common(cc);
- break;
-
- case CallConv::kIdX86GccRegParm2:
- cc.setPassedOrder(kGroupGp, kZax, kZdx);
- CallConv_initX86Common(cc);
- break;
-
- case CallConv::kIdX86GccRegParm3:
- cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx);
- CallConv_initX86Common(cc);
- break;
-
- case CallConv::kIdX86CDecl:
- CallConv_initX86Common(cc);
- break;
-
- case CallConv::kIdX86Win64:
- cc.setArchType(ArchInfo::kIdX64);
- cc.setStrategy(CallConv::kStrategyWin64);
- cc.setFlags(CallConv::kFlagPassFloatsByVec | CallConv::kFlagIndirectVecArgs);
- cc.setNaturalStackAlignment(16);
- cc.setSpillZoneSize(32);
- cc.setPassedOrder(kGroupGp, kZcx, kZdx, 8, 9);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3);
- cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
- cc.setPreservedRegs(kGroupVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
- break;
-
- case CallConv::kIdX86SysV64:
- cc.setArchType(ArchInfo::kIdX64);
- cc.setFlags(CallConv::kFlagPassFloatsByVec);
- cc.setNaturalStackAlignment(16);
- cc.setRedZoneSize(128);
- cc.setPassedOrder(kGroupGp, kZdi, kZsi, kZdx, kZcx, 8, 9);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, 12, 13, 14, 15));
- break;
-
- case CallConv::kIdX86LightCall2:
- case CallConv::kIdX86LightCall3:
- case CallConv::kIdX86LightCall4: {
- uint32_t n = (ccId - CallConv::kIdX86LightCall2) + 2;
-
- cc.setArchType(ArchInfo::kIdX86);
- cc.setFlags(CallConv::kFlagPassFloatsByVec);
- cc.setNaturalStackAlignment(16);
- cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi);
- cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7);
-
- cc.setPreservedRegs(kGroupGp , Support::lsbMask<uint32_t>(8));
- cc.setPreservedRegs(kGroupVec , Support::lsbMask<uint32_t>(8) & ~Support::lsbMask<uint32_t>(n));
- break;
+ bool winABI = environment.isPlatformWindows() || environment.isAbiMSVC();
+
+ cc.setArch(environment.arch());
+
+ if (environment.is32Bit()) {
+ bool isStandardCallConv = true;
+
+ cc.setPreservedRegs(Reg::kGroupGp, Support::bitMask(Gp::kIdBx, Gp::kIdSp, Gp::kIdBp, Gp::kIdSi, Gp::kIdDi));
+ cc.setNaturalStackAlignment(4);
+
+ switch (ccId) {
+ case CallConv::kIdCDecl:
+ break;
+
+ case CallConv::kIdStdCall:
+ cc.setFlags(CallConv::kFlagCalleePopsStack);
+ break;
+
+ case CallConv::kIdFastCall:
+ cc.setFlags(CallConv::kFlagCalleePopsStack);
+ cc.setPassedOrder(kGroupGp, kZcx, kZdx);
+ break;
+
+ case CallConv::kIdVectorCall:
+ cc.setFlags(CallConv::kFlagCalleePopsStack);
+ cc.setPassedOrder(kGroupGp, kZcx, kZdx);
+ cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5);
+ break;
+
+ case CallConv::kIdThisCall:
+ // NOTE: Even MINGW (starting with GCC 4.7.0) now uses __thiscall on MS Windows,
+ // so we won't bail to any other calling convention if __thiscall was specified.
+ if (winABI) {
+ cc.setFlags(CallConv::kFlagCalleePopsStack);
+ cc.setPassedOrder(kGroupGp, kZcx);
+ }
+ else {
+ ccId = CallConv::kIdCDecl;
+ }
+ break;
+
+ case CallConv::kIdRegParm1:
+ cc.setPassedOrder(kGroupGp, kZax);
+ break;
+
+ case CallConv::kIdRegParm2:
+ cc.setPassedOrder(kGroupGp, kZax, kZdx);
+ break;
+
+ case CallConv::kIdRegParm3:
+ cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx);
+ break;
+
+ case CallConv::kIdLightCall2:
+ case CallConv::kIdLightCall3:
+ case CallConv::kIdLightCall4: {
+ uint32_t n = (ccId - CallConv::kIdLightCall2) + 2;
+
+ cc.setFlags(CallConv::kFlagPassFloatsByVec);
+ cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi);
+ cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPreservedRegs(kGroupGp, Support::lsbMask<uint32_t>(8));
+ cc.setPreservedRegs(kGroupVec, Support::lsbMask<uint32_t>(8) & ~Support::lsbMask<uint32_t>(n));
+
+ cc.setNaturalStackAlignment(16);
+ isStandardCallConv = false;
+ break;
+ }
+
+ default:
+ return DebugUtils::errored(kErrorInvalidArgument);
}
- case CallConv::kIdX64LightCall2:
- case CallConv::kIdX64LightCall3:
- case CallConv::kIdX64LightCall4: {
- uint32_t n = (ccId - CallConv::kIdX64LightCall2) + 2;
-
- cc.setArchType(ArchInfo::kIdX64);
- cc.setFlags(CallConv::kFlagPassFloatsByVec);
- cc.setNaturalStackAlignment(16);
- cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi);
- cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7);
-
- cc.setPreservedRegs(kGroupGp , Support::lsbMask<uint32_t>(16));
- cc.setPreservedRegs(kGroupVec ,~Support::lsbMask<uint32_t>(n));
- break;
+ if (isStandardCallConv) {
+ // MMX arguments is something where compiler vendors disagree. For example
+ // GCC and MSVC would pass first three via registers and the rest via stack,
+ // however Clang passes all via stack. Returning MMX registers is even more
+ // fun, where GCC uses MM0, but Clang uses EAX:EDX pair. I'm not sure it's
+ // something we should be worried about as MMX is deprecated anyway.
+ cc.setPassedOrder(kGroupMm, 0, 1, 2);
+
+ // Vector arguments (XMM|YMM|ZMM) are passed via registers. However, if the
+ // function is variadic then they have to be passed via stack.
+ cc.setPassedOrder(kGroupVec, 0, 1, 2);
+
+ // Functions with variable arguments always use stack for MM and vector
+ // arguments.
+ cc.addFlags(CallConv::kFlagPassVecByStackIfVA);
}
- default:
- return DebugUtils::errored(kErrorInvalidArgument);
+ if (ccId == CallConv::kIdCDecl) {
+ cc.addFlags(CallConv::kFlagVarArgCompatible);
+ }
+ }
+ else {
+ // Preprocess the calling convention into a common id as many conventions
+ // are normally ignored even by C/C++ compilers and treated as `__cdecl`.
+ if (shouldThreatAsCDeclIn64BitMode(ccId))
+ ccId = winABI ? CallConv::kIdX64Windows : CallConv::kIdX64SystemV;
+
+ switch (ccId) {
+ case CallConv::kIdX64SystemV: {
+ cc.setFlags(CallConv::kFlagPassFloatsByVec |
+ CallConv::kFlagPassMmxByXmm |
+ CallConv::kFlagVarArgCompatible);
+ cc.setNaturalStackAlignment(16);
+ cc.setRedZoneSize(128);
+ cc.setPassedOrder(kGroupGp, kZdi, kZsi, kZdx, kZcx, 8, 9);
+ cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, 12, 13, 14, 15));
+ break;
+ }
+
+ case CallConv::kIdX64Windows: {
+ cc.setStrategy(CallConv::kStrategyX64Windows);
+ cc.setFlags(CallConv::kFlagPassFloatsByVec |
+ CallConv::kFlagIndirectVecArgs |
+ CallConv::kFlagPassMmxByGp |
+ CallConv::kFlagVarArgCompatible);
+ cc.setNaturalStackAlignment(16);
+ // Maximum 4 arguments in registers, each adds 8 bytes to the spill zone.
+ cc.setSpillZoneSize(4 * 8);
+ cc.setPassedOrder(kGroupGp, kZcx, kZdx, 8, 9);
+ cc.setPassedOrder(kGroupVec, 0, 1, 2, 3);
+ cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
+ cc.setPreservedRegs(kGroupVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
+ break;
+ }
+
+ case CallConv::kIdVectorCall: {
+ cc.setStrategy(CallConv::kStrategyX64VectorCall);
+ cc.setFlags(CallConv::kFlagPassFloatsByVec |
+ CallConv::kFlagPassMmxByGp );
+ cc.setNaturalStackAlignment(16);
+ // Maximum 6 arguments in registers, each adds 8 bytes to the spill zone.
+ cc.setSpillZoneSize(6 * 8);
+ cc.setPassedOrder(kGroupGp, kZcx, kZdx, 8, 9);
+ cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5);
+ cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
+ cc.setPreservedRegs(kGroupVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
+ break;
+ }
+
+ case CallConv::kIdLightCall2:
+ case CallConv::kIdLightCall3:
+ case CallConv::kIdLightCall4: {
+ uint32_t n = (ccId - CallConv::kIdLightCall2) + 2;
+
+ cc.setFlags(CallConv::kFlagPassFloatsByVec);
+ cc.setNaturalStackAlignment(16);
+ cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi);
+ cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7);
+
+ cc.setPreservedRegs(kGroupGp, Support::lsbMask<uint32_t>(16));
+ cc.setPreservedRegs(kGroupVec, ~Support::lsbMask<uint32_t>(n));
+ break;
+ }
+
+ default:
+ return DebugUtils::errored(kErrorInvalidArgument);
+ }
}
cc.setId(ccId);
return kErrorOk;
}
+} // {CallConvInternal}
+
ASMJIT_END_SUB_NAMESPACE
#endif // ASMJIT_BUILD_X86
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86callconv_p.h b/3rdparty/asmjit/src/asmjit/x86/x86callconv_p.h
index 5fc21133cef..1607ea2e385 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86callconv_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86callconv_p.h
@@ -38,9 +38,11 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! X86-specific function API (calling conventions and other utilities).
namespace CallConvInternal {
- //! Initialize `CallConv` structure (X86 specific).
- Error init(CallConv& cc, uint32_t ccId) noexcept;
-}
+
+//! Initialize `CallConv` structure (X86 specific).
+Error init(CallConv& cc, uint32_t ccId, const Environment& environment) noexcept;
+
+} // {CallConvInternal}
//! \}
//! \endcond
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp b/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp
index 910ed5e7dde..33377e9f98b 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp
@@ -47,20 +47,24 @@ Compiler::~Compiler() noexcept {}
Error Compiler::finalize() {
ASMJIT_PROPAGATE(runPasses());
Assembler a(_code);
+ a.addEncodingOptions(encodingOptions());
+ a.addValidationOptions(validationOptions());
return serialize(&a);
}
-
// ============================================================================
// [asmjit::x86::Compiler - Events]
// ============================================================================
Error Compiler::onAttach(CodeHolder* code) noexcept {
- uint32_t archId = code->archId();
- if (!ArchInfo::isX86Family(archId))
+ uint32_t arch = code->arch();
+ if (!Environment::isFamilyX86(arch))
return DebugUtils::errored(kErrorInvalidArch);
ASMJIT_PROPAGATE(Base::onAttach(code));
- _gpRegInfo.setSignature(archId == ArchInfo::kIdX86 ? uint32_t(Gpd::kSignature) : uint32_t(Gpq::kSignature));
+
+ bool is32Bit = Environment::is32Bit(arch);
+ _gpRegInfo.setSignature(is32Bit ? uint32_t(Gpd::kSignature)
+ : uint32_t(Gpq::kSignature));
Error err = addPassT<X86RAPass>();
if (ASMJIT_UNLIKELY(err)) {
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86compiler.h b/3rdparty/asmjit/src/asmjit/x86/x86compiler.h
index cc7035b2990..4c64b3b6e40 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86compiler.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86compiler.h
@@ -41,7 +41,413 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// [asmjit::x86::Compiler]
// ============================================================================
-//! Architecture-dependent asm-compiler (X86).
+//! X86/X64 compiler implementation.
+//!
+//! ### Compiler Basics
+//!
+//! The first \ref x86::Compiler example shows how to generate a function that
+//! simply returns an integer value. It's an analogy to the first Assembler example:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Signature of the generated function.
+//! typedef int (*Func)(void);
+//!
+//! int main() {
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//!
+//! cc.addFunc(FuncSignatureT<int>());// Begin a function of `int fn(void)` signature.
+//!
+//! x86::Gp vReg = cc.newGpd(); // Create a 32-bit general purpose register.
+//! cc.mov(vReg, 1); // Move one to our virtual register `vReg`.
+//! cc.ret(vReg); // Return `vReg` from the function.
+//!
+//! cc.endFunc(); // End of the function body.
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
+//!
+//! Func fn;
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
+//!
+//! int result = fn(); // Execute the generated code.
+//! printf("%d\n", result); // Print the resulting "1".
+//!
+//! rt.release(fn); // Explicitly remove the function from the runtime.
+//! return 0;
+//! }
+//! ```
+//!
+//! The \ref BaseCompiler::addFunc() and \ref BaseCompiler::endFunc() functions
+//! are used to define the function and its end. Both must be called per function,
+//! but the body doesn't have to be generated in sequence. An example of generating
+//! two functions will be shown later. The next example shows more complicated code
+//! that contain a loop and generates a simple memory copy function that uses
+//! `uint32_t` items:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Signature of the generated function.
+//! typedef void (*MemCpy32)(uint32_t* dst, const uint32_t* src, size_t count);
+//!
+//! int main() {
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//!
+//! cc.addFunc( // Begin the function of the following signature:
+//! FuncSignatureT<void, // Return value - void (no return value).
+//! uint32_t*, // 1st argument - uint32_t* (machine reg-size).
+//! const uint32_t*, // 2nd argument - uint32_t* (machine reg-size).
+//! size_t>()); // 3rd argument - size_t (machine reg-size).
+//!
+//! Label L_Loop = cc.newLabel(); // Start of the loop.
+//! Label L_Exit = cc.newLabel(); // Used to exit early.
+//!
+//! x86::Gp dst = cc.newIntPtr("dst");// Create `dst` register (destination pointer).
+//! x86::Gp src = cc.newIntPtr("src");// Create `src` register (source pointer).
+//! x86::Gp i = cc.newUIntPtr("i"); // Create `i` register (loop counter).
+//!
+//! cc.setArg(0, dst); // Assign `dst` argument.
+//! cc.setArg(1, src); // Assign `src` argument.
+//! cc.setArg(2, i); // Assign `i` argument.
+//!
+//! cc.test(i, i); // Early exit if length is zero.
+//! cc.jz(L_Exit);
+//!
+//! cc.bind(L_Loop); // Bind the beginning of the loop here.
+//!
+//! x86::Gp tmp = cc.newInt32("tmp"); // Copy a single dword (4 bytes).
+//! cc.mov(tmp, x86::dword_ptr(src)); // Load DWORD from [src] address.
+//! cc.mov(x86::dword_ptr(dst), tmp); // Store DWORD to [dst] address.
+//!
+//! cc.add(src, 4); // Increment `src`.
+//! cc.add(dst, 4); // Increment `dst`.
+//!
+//! cc.dec(i); // Loop until `i` is non-zero.
+//! cc.jnz(L_Loop);
+//!
+//! cc.bind(L_Exit); // Label used by early exit.
+//! cc.endFunc(); // End of the function body.
+//!
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
+//!
+//! // Add the generated code to the runtime.
+//! MemCpy32 memcpy32;
+//! Error err = rt.add(&memcpy32, &code);
+//!
+//! // Handle a possible error returned by AsmJit.
+//! if (err)
+//! return 1;
+//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
+//!
+//! // Test the generated code.
+//! uint32_t input[6] = { 1, 2, 3, 5, 8, 13 };
+//! uint32_t output[6];
+//! memcpy32(output, input, 6);
+//!
+//! for (uint32_t i = 0; i < 6; i++)
+//! printf("%d\n", output[i]);
+//!
+//! rt.release(memcpy32);
+//! return 0;
+//! }
+//! ```
+//!
+//! ### Recursive Functions
+//!
+//! It's possible to create more functions by using the same \ref x86::Compiler
+//! instance and make links between them. In such case it's important to keep
+//! the pointer to \ref FuncNode.
+//!
+//! The example below creates a simple Fibonacci function that calls itself recursively:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Signature of the generated function.
+//! typedef uint32_t (*Fibonacci)(uint32_t x);
+//!
+//! int main() {
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//!
+//! FuncNode* func = cc.addFunc( // Begin of the Fibonacci function, addFunc()
+//! FuncSignatureT<int, int>()); // Returns a pointer to the FuncNode node.
+//!
+//! Label L_Exit = cc.newLabel() // Exit label.
+//! x86::Gp x = cc.newU32(); // Function x argument.
+//! x86::Gp y = cc.newU32(); // Temporary.
+//!
+//! cc.setArg(0, x);
+//!
+//! cc.cmp(x, 3); // Return x if less than 3.
+//! cc.jb(L_Exit);
+//!
+//! cc.mov(y, x); // Make copy of the original x.
+//! cc.dec(x); // Decrease x.
+//!
+//! InvokeNode* invokeNode; // Function invocation:
+//! cc.invoke(&invokeNode, // - InvokeNode (output).
+//! func->label(), // - Function address or Label.
+//! FuncSignatureT<int, int>()); // - Function signature.
+//!
+//! invokeNode->setArg(0, x); // Assign x as the first argument.
+//! invokeNode->setRet(0, x); // Assign x as a return value as well.
+//!
+//! cc.add(x, y); // Combine the return value with y.
+//!
+//! cc.bind(L_Exit);
+//! cc.ret(x); // Return x.
+//! cc.endFunc(); // End of the function body.
+//!
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
+//!
+//! Fibonacci fib;
+//! Error err = rt.add(&fib, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
+//!
+//! // Test the generated code.
+//! printf("Fib(%u) -> %u\n", 8, fib(8));
+//!
+//! rt.release(fib);
+//! return 0;
+//! }
+//! ```
+//!
+//! ### Stack Management
+//!
+//! Function's stack-frame is managed automatically, which is used by the register allocator to spill virtual registers. It also provides an interface to allocate user-defined block of the stack, which can be used as a temporary storage by the generated function. In the following example a stack of 256 bytes size is allocated, filled by bytes starting from 0 to 255 and then iterated again to sum all the values.
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//! #include <stdio.h>
+//!
+//! using namespace asmjit;
+//!
+//! // Signature of the generated function.
+//! typedef int (*Func)(void);
+//!
+//! int main() {
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
+//!
+//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//!
+//! cc.addFunc(FuncSignatureT<int>());// Create a function that returns int.
+//!
+//! x86::Gp p = cc.newIntPtr("p");
+//! x86::Gp i = cc.newIntPtr("i");
+//!
+//! // Allocate 256 bytes on the stack aligned to 4 bytes.
+//! x86::Mem stack = cc.newStack(256, 4);
+//!
+//! x86::Mem stackIdx(stack); // Copy of stack with i added.
+//! stackIdx.setIndex(i); // stackIdx <- stack[i].
+//! stackIdx.setSize(1); // stackIdx <- byte ptr stack[i].
+//!
+//! // Load a stack address to `p`. This step is purely optional and shows
+//! // that `lea` is useful to load a memory operands address (even absolute)
+//! // to a general purpose register.
+//! cc.lea(p, stack);
+//!
+//! // Clear i (xor is a C++ keyword, hence 'xor_' is used instead).
+//! cc.xor_(i, i);
+//!
+//! Label L1 = cc.newLabel();
+//! Label L2 = cc.newLabel();
+//!
+//! cc.bind(L1); // First loop, fill the stack.
+//! cc.mov(stackIdx, i.r8()); // stack[i] = uint8_t(i).
+//!
+//! cc.inc(i); // i++;
+//! cc.cmp(i, 256); // if (i < 256)
+//! cc.jb(L1); // goto L1;
+//!
+//! // Second loop, sum all bytes stored in `stack`.
+//! x86::Gp sum = cc.newI32("sum");
+//! x86::Gp val = cc.newI32("val");
+//!
+//! cc.xor_(i, i);
+//! cc.xor_(sum, sum);
+//!
+//! cc.bind(L2);
+//!
+//! cc.movzx(val, stackIdx); // val = uint32_t(stack[i]);
+//! cc.add(sum, val); // sum += val;
+//!
+//! cc.inc(i); // i++;
+//! cc.cmp(i, 256); // if (i < 256)
+//! cc.jb(L2); // goto L2;
+//!
+//! cc.ret(sum); // Return the `sum` of all values.
+//! cc.endFunc(); // End of the function body.
+//!
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
+//!
+//! Func func;
+//! Error err = rt.add(&func, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
+//!
+//! printf("Func() -> %d\n", func()); // Test the generated code.
+//!
+//! rt.release(func);
+//! return 0;
+//! }
+//! ```
+//!
+//! ### Constant Pool
+//!
+//! Compiler provides two constant pools for a general purpose code generation:
+//!
+//! - Local constant pool - Part of \ref FuncNode, can be only used by a
+//! single function and added after the function epilog sequence (after
+//! `ret` instruction).
+//!
+//! - Global constant pool - Part of \ref BaseCompiler, flushed at the end
+//! of the generated code by \ref BaseEmitter::finalize().
+//!
+//! The example below illustrates how a built-in constant pool can be used:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! static void exampleUseOfConstPool(x86::Compiler& cc) {
+//! cc.addFunc(FuncSignatureT<int>());
+//!
+//! x86::Gp v0 = cc.newGpd("v0");
+//! x86::Gp v1 = cc.newGpd("v1");
+//!
+//! x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeLocal, 200);
+//! x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeLocal, 33);
+//!
+//! cc.mov(v0, c0);
+//! cc.mov(v1, c1);
+//! cc.add(v0, v1);
+//!
+//! cc.ret(v0);
+//! cc.endFunc();
+//! }
+//! ```
+//!
+//! ### Jump Tables
+//!
+//! x86::Compiler supports `jmp` instruction with reg/mem operand, which is a
+//! commonly used pattern to implement indirect jumps within a function, for
+//! example to implement `switch()` statement in a programming languages. By
+//! default AsmJit assumes that every basic block can be a possible jump
+//! target as it's unable to deduce targets from instruction's operands. This
+//! is a very pessimistic default that should be avoided if possible as it's
+//! costly and very unfriendly to liveness analysis and register allocation.
+//!
+//! Instead of relying on such pessimistic default behavior, let's use \ref
+//! JumpAnnotation to annotate a jump where all targets are known:
+//!
+//! ```
+//! #include <asmjit/x86.h>
+//!
+//! using namespace asmjit;
+//!
+//! static void exampleUseOfIndirectJump(x86::Compiler& cc) {
+//! cc.addFunc(FuncSignatureT<float, float, float, uint32_t>(CallConv::kIdHost));
+//!
+//! // Function arguments
+//! x86::Xmm a = cc.newXmmSs("a");
+//! x86::Xmm b = cc.newXmmSs("b");
+//! x86::Gp op = cc.newUInt32("op");
+//!
+//! x86::Gp target = cc.newIntPtr("target");
+//! x86::Gp offset = cc.newIntPtr("offset");
+//!
+//! Label L_Table = cc.newLabel();
+//! Label L_Add = cc.newLabel();
+//! Label L_Sub = cc.newLabel();
+//! Label L_Mul = cc.newLabel();
+//! Label L_Div = cc.newLabel();
+//! Label L_End = cc.newLabel();
+//!
+//! cc.setArg(0, a);
+//! cc.setArg(1, b);
+//! cc.setArg(2, op);
+//!
+//! // Jump annotation is a building block that allows to annotate all
+//! // possible targets where `jmp()` can jump. It then drives the CFG
+//! // contruction and liveness analysis, which impacts register allocation.
+//! JumpAnnotation* annotation = cc.newJumpAnnotation();
+//! annotation->addLabel(L_Add);
+//! annotation->addLabel(L_Sub);
+//! annotation->addLabel(L_Mul);
+//! annotation->addLabel(L_Div);
+//!
+//! // Most likely not the common indirect jump approach, but it
+//! // doesn't really matter how final address is calculated. The
+//! // most important path using JumpAnnotation with `jmp()`.
+//! cc.lea(offset, x86::ptr(L_Table));
+//! if (cc.is64Bit())
+//! cc.movsxd(target, x86::dword_ptr(offset, op.cloneAs(offset), 2));
+//! else
+//! cc.mov(target, x86::dword_ptr(offset, op.cloneAs(offset), 2));
+//! cc.add(target, offset);
+//! cc.jmp(target, annotation);
+//!
+//! // Acts like a switch() statement in C.
+//! cc.bind(L_Add);
+//! cc.addss(a, b);
+//! cc.jmp(L_End);
+//!
+//! cc.bind(L_Sub);
+//! cc.subss(a, b);
+//! cc.jmp(L_End);
+//!
+//! cc.bind(L_Mul);
+//! cc.mulss(a, b);
+//! cc.jmp(L_End);
+//!
+//! cc.bind(L_Div);
+//! cc.divss(a, b);
+//!
+//! cc.bind(L_End);
+//! cc.ret(a);
+//!
+//! cc.endFunc();
+//!
+//! // Relative int32_t offsets of `L_XXX - L_Table`.
+//! cc.bind(L_Table);
+//! cc.embedLabelDelta(L_Add, L_Table, 4);
+//! cc.embedLabelDelta(L_Sub, L_Table, 4);
+//! cc.embedLabelDelta(L_Mul, L_Table, 4);
+//! cc.embedLabelDelta(L_Div, L_Table, 4);
+//! }
+//! ```
class ASMJIT_VIRTAPI Compiler
: public BaseCompiler,
public EmitterExplicitT<Compiler> {
@@ -62,18 +468,18 @@ public:
#ifndef ASMJIT_NO_LOGGING
# define ASMJIT_NEW_REG_FMT(OUT, PARAM, FORMAT, ARGS) \
- _newRegFmt(OUT, PARAM, FORMAT, ARGS)
+ _newRegFmt(&OUT, PARAM, FORMAT, ARGS)
#else
# define ASMJIT_NEW_REG_FMT(OUT, PARAM, FORMAT, ARGS) \
DebugUtils::unused(FORMAT); \
DebugUtils::unused(std::forward<Args>(args)...); \
- _newReg(OUT, PARAM)
+ _newReg(&OUT, PARAM)
#endif
#define ASMJIT_NEW_REG_CUSTOM(FUNC, REG) \
inline REG FUNC(uint32_t typeId) { \
REG reg(Globals::NoInit); \
- _newReg(reg, typeId); \
+ _newReg(&reg, typeId); \
return reg; \
} \
\
@@ -87,7 +493,7 @@ public:
#define ASMJIT_NEW_REG_TYPED(FUNC, REG, TYPE_ID) \
inline REG FUNC() { \
REG reg(Globals::NoInit); \
- _newReg(reg, TYPE_ID); \
+ _newReg(&reg, TYPE_ID); \
return reg; \
} \
\
@@ -170,7 +576,7 @@ public:
//! Creates a new memory chunk allocated on the current function's stack.
inline Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
Mem m(Globals::NoInit);
- _newStack(m, size, alignment, name);
+ _newStack(&m, size, alignment, name);
return m;
}
@@ -182,7 +588,7 @@ public:
//! Put data to a constant-pool and get a memory reference to it.
inline Mem newConst(uint32_t scope, const void* data, size_t size) {
Mem m(Globals::NoInit);
- _newConst(m, scope, data, size);
+ _newConst(&m, scope, data, size);
return m;
}
@@ -213,12 +619,16 @@ public:
//! Put a DP-FP `val` to a constant-pool.
inline Mem newDoubleConst(uint32_t scope, double val) noexcept { return newConst(scope, &val, 8); }
- //! Put a MMX `val` to a constant-pool.
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("newMmConst() uses a deprecated Data64, use newConst() with your own data instead")
inline Mem newMmConst(uint32_t scope, const Data64& val) noexcept { return newConst(scope, &val, 8); }
- //! Put a XMM `val` to a constant-pool.
+
+ ASMJIT_DEPRECATED("newXmmConst() uses a deprecated Data128, use newConst() with your own data instead")
inline Mem newXmmConst(uint32_t scope, const Data128& val) noexcept { return newConst(scope, &val, 16); }
- //! Put a YMM `val` to a constant-pool.
+
+ ASMJIT_DEPRECATED("newYmmConst() uses a deprecated Data256, use newConst() with your own data instead")
inline Mem newYmmConst(uint32_t scope, const Data256& val) noexcept { return newConst(scope, &val, 32); }
+#endif // !ASMJIT_NO_DEPRECATED
//! \}
@@ -235,16 +645,37 @@ public:
//! \name Function Call & Ret Intrinsics
//! \{
- //! Call a function.
- inline FuncCallNode* call(const Gp& target, const FuncSignature& sign) { return addCall(Inst::kIdCall, target, sign); }
+ //! Invoke a function call without `target` type enforcement.
+ inline Error invoke_(InvokeNode** out, const Operand_& target, const FuncSignature& signature) {
+ return _addInvokeNode(out, Inst::kIdCall, target, signature);
+ }
+
+ //! Invoke a function call of the given `target` and `signature` and store
+ //! the added node to `out`.
+ //!
+ //! Creates a new \ref InvokeNode, initializes all the necessary members to
+ //! match the given function `signature`, adds the node to the compiler, and
+ //! stores its pointer to `out`. The operation is atomic, if anything fails
+ //! nullptr is stored in `out` and error code is returned.
+ inline Error invoke(InvokeNode** out, const Gp& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline FuncCallNode* call(const Mem& target, const FuncSignature& sign) { return addCall(Inst::kIdCall, target, sign); }
+ inline Error invoke(InvokeNode** out, const Mem& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline FuncCallNode* call(const Label& target, const FuncSignature& sign) { return addCall(Inst::kIdCall, target, sign); }
+ inline Error invoke(InvokeNode** out, const Label& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline FuncCallNode* call(const Imm& target, const FuncSignature& sign) { return addCall(Inst::kIdCall, target, sign); }
+ inline Error invoke(InvokeNode** out, const Imm& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline FuncCallNode* call(uint64_t target, const FuncSignature& sign) { return addCall(Inst::kIdCall, Imm(int64_t(target)), sign); }
+ inline Error invoke(InvokeNode** out, uint64_t target, const FuncSignature& signature) { return invoke_(out, Imm(int64_t(target)), signature); }
+
+#ifndef _DOXYGEN
+ template<typename Target>
+ ASMJIT_DEPRECATED("Use invoke() instead of call()")
+ inline InvokeNode* call(const Target& target, const FuncSignature& signature) {
+ InvokeNode* invokeNode;
+ invoke(&invokeNode, target, signature);
+ return invokeNode;
+ }
+#endif
//! Return.
inline FuncRetNode* ret() { return addRet(Operand(), Operand()); }
@@ -260,7 +691,9 @@ public:
using EmitterExplicitT<Compiler>::jmp;
+ //! Adds a jump to the given `target` with the provided jump `annotation`.
inline Error jmp(const BaseReg& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdJmp, target, annotation); }
+ //! \overload
inline Error jmp(const BaseMem& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdJmp, target, annotation); }
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86emitter.h b/3rdparty/asmjit/src/asmjit/x86/x86emitter.h
index cfd96a18809..561acdd6000 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86emitter.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86emitter.h
@@ -39,10 +39,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
#define ASMJIT_INST_1i(NAME, ID, T0) \
inline Error NAME(const T0& o0) { return _emitter()->emit(Inst::kId##ID, o0); } \
+ /** \cond */ \
inline Error NAME(int o0) { return _emitter()->emit(Inst::kId##ID, Support::asInt(o0)); } \
inline Error NAME(unsigned int o0) { return _emitter()->emit(Inst::kId##ID, Support::asInt(o0)); } \
inline Error NAME(int64_t o0) { return _emitter()->emit(Inst::kId##ID, Support::asInt(o0)); } \
- inline Error NAME(uint64_t o0) { return _emitter()->emit(Inst::kId##ID, Support::asInt(o0)); }
+ inline Error NAME(uint64_t o0) { return _emitter()->emit(Inst::kId##ID, Support::asInt(o0)); } \
+ /** \endcond */
#define ASMJIT_INST_1c(NAME, ID, CONV, T0) \
inline Error NAME(uint32_t cc, const T0& o0) { return _emitter()->emit(CONV(cc), o0); } \
@@ -82,10 +84,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
#define ASMJIT_INST_2i(NAME, ID, T0, T1) \
inline Error NAME(const T0& o0, const T1& o1) { return _emitter()->emit(Inst::kId##ID, o0, o1); } \
+ /** \cond */ \
inline Error NAME(const T0& o0, int o1) { return _emitter()->emit(Inst::kId##ID, o0, Support::asInt(o1)); } \
inline Error NAME(const T0& o0, unsigned int o1) { return _emitter()->emit(Inst::kId##ID, o0, Support::asInt(o1)); } \
inline Error NAME(const T0& o0, int64_t o1) { return _emitter()->emit(Inst::kId##ID, o0, Support::asInt(o1)); } \
- inline Error NAME(const T0& o0, uint64_t o1) { return _emitter()->emit(Inst::kId##ID, o0, Support::asInt(o1)); }
+ inline Error NAME(const T0& o0, uint64_t o1) { return _emitter()->emit(Inst::kId##ID, o0, Support::asInt(o1)); } \
+ /** \endcond */
#define ASMJIT_INST_2c(NAME, ID, CONV, T0, T1) \
inline Error NAME(uint32_t cc, const T0& o0, const T1& o1) { return _emitter()->emit(CONV(cc), o0, o1); } \
@@ -125,10 +129,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
#define ASMJIT_INST_3i(NAME, ID, T0, T1, T2) \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2); } \
+ /** \cond */ \
inline Error NAME(const T0& o0, const T1& o1, int o2) { return _emitter()->emit(Inst::kId##ID, o0, o1, Support::asInt(o2)); } \
inline Error NAME(const T0& o0, const T1& o1, unsigned int o2) { return _emitter()->emit(Inst::kId##ID, o0, o1, Support::asInt(o2)); } \
inline Error NAME(const T0& o0, const T1& o1, int64_t o2) { return _emitter()->emit(Inst::kId##ID, o0, o1, Support::asInt(o2)); } \
- inline Error NAME(const T0& o0, const T1& o1, uint64_t o2) { return _emitter()->emit(Inst::kId##ID, o0, o1, Support::asInt(o2)); }
+ inline Error NAME(const T0& o0, const T1& o1, uint64_t o2) { return _emitter()->emit(Inst::kId##ID, o0, o1, Support::asInt(o2)); } \
+ /** \endcond */
#define ASMJIT_INST_3ii(NAME, ID, T0, T1, T2) \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2); } \
@@ -139,10 +145,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
#define ASMJIT_INST_4i(NAME, ID, T0, T1, T2, T3) \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3); } \
+ /** \cond */ \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, int o3) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, Support::asInt(o3)); } \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, unsigned int o3) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, Support::asInt(o3)); } \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, int64_t o3) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, Support::asInt(o3)); } \
- inline Error NAME(const T0& o0, const T1& o1, const T2& o2, uint64_t o3) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, Support::asInt(o3)); }
+ inline Error NAME(const T0& o0, const T1& o1, const T2& o2, uint64_t o3) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, Support::asInt(o3)); } \
+ /** \endcond */
#define ASMJIT_INST_4ii(NAME, ID, T0, T1, T2, T3) \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3); } \
@@ -153,10 +161,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
#define ASMJIT_INST_5i(NAME, ID, T0, T1, T2, T3, T4) \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3, o4); } \
+ /** \cond */ \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, int o4) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3, Support::asInt(o4)); } \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, unsigned int o4) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3, Support::asInt(o4)); } \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, int64_t o4) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3, Support::asInt(o4)); } \
- inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, uint64_t o4) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3, Support::asInt(o4)); }
+ inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, uint64_t o4) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3, Support::asInt(o4)); } \
+ /** \endcond */
#define ASMJIT_INST_6x(NAME, ID, T0, T1, T2, T3, T4, T5) \
inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4, const T5& o5) { return _emitter()->emit(Inst::kId##ID, o0, o1, o2, o3, o4, o5); }
@@ -244,57 +254,57 @@ struct EmitterExplicitT {
//! Creates an `intptr_t` memory operand depending on the current architecture.
inline Mem intptr_ptr(const Gp& base, int32_t offset = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, offset, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, index, shift, offset, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, index, shift, offset, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(const Label& base, int32_t offset = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, offset, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(const Label& base, const Gp& index, uint32_t shift, int32_t offset = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, index, shift, offset, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(const Label& base, const Vec& index, uint32_t shift, int32_t offset = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, index, shift, offset, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(const Rip& rip, int32_t offset = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(rip, offset, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(uint64_t base) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr(uint64_t base, const Gp& index, uint32_t shift = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, index, shift, nativeGpSize);
}
//! \overload
inline Mem intptr_ptr_abs(uint64_t base) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, nativeGpSize, BaseMem::kSignatureMemAbs);
}
//! \overload
inline Mem intptr_ptr_abs(uint64_t base, const Gp& index, uint32_t shift = 0) const noexcept {
- uint32_t nativeGpSize = _emitter()->gpSize();
+ uint32_t nativeGpSize = _emitter()->registerSize();
return Mem(base, index, shift, nativeGpSize, BaseMem::kSignatureMemAbs);
}
@@ -303,46 +313,55 @@ struct EmitterExplicitT {
//! \name Embed
//! \{
- //! Adds 8-bit integer data to the CodeBuffer.
- inline Error db(uint8_t x) { return _emitter()->embed(&x, 1); }
- //! Adds 16-bit integer data to the CodeBuffer.
- inline Error dw(uint16_t x) { return _emitter()->embed(&x, 2); }
- //! Adds 32-bit integer data to the CodeBuffer.
- inline Error dd(uint32_t x) { return _emitter()->embed(&x, 4); }
- //! Adds 64-bit integer data to the CodeBuffer.
- inline Error dq(uint64_t x) { return _emitter()->embed(&x, 8); }
-
- //! Adds 8-bit integer data to the CodeBuffer.
+ //! Embeds 8-bit integer data.
+ inline Error db(uint8_t x, size_t repeatCount = 1) { return _emitter()->embedUInt8(x, repeatCount); }
+ //! Embeds 16-bit integer data.
+ inline Error dw(uint16_t x, size_t repeatCount = 1) { return _emitter()->embedUInt16(x, repeatCount); }
+ //! Embeds 32-bit integer data.
+ inline Error dd(uint32_t x, size_t repeatCount = 1) { return _emitter()->embedUInt32(x, repeatCount); }
+ //! Embeds 64-bit integer data.
+ inline Error dq(uint64_t x, size_t repeatCount = 1) { return _emitter()->embedUInt64(x, repeatCount); }
+
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use embedInt8() instead of dint8()")
inline Error dint8(int8_t x) { return _emitter()->embed(&x, sizeof(int8_t)); }
- //! Adds 8-bit integer data to the CodeBuffer.
+
+ ASMJIT_DEPRECATED("Use embedUInt8() instead of duint8()")
inline Error duint8(uint8_t x) { return _emitter()->embed(&x, sizeof(uint8_t)); }
- //! Adds 16-bit integer data to the CodeBuffer.
+ ASMJIT_DEPRECATED("Use embedInt16() instead of dint16()")
inline Error dint16(int16_t x) { return _emitter()->embed(&x, sizeof(int16_t)); }
- //! Adds 16-bit integer data to the CodeBuffer.
+
+ ASMJIT_DEPRECATED("Use embedUInt16() instead of duint16()")
inline Error duint16(uint16_t x) { return _emitter()->embed(&x, sizeof(uint16_t)); }
- //! Adds 32-bit integer data to the CodeBuffer.
+ ASMJIT_DEPRECATED("Use embedInt32() instead of dint32()")
inline Error dint32(int32_t x) { return _emitter()->embed(&x, sizeof(int32_t)); }
- //! Adds 32-bit integer data to the CodeBuffer.
+
+ ASMJIT_DEPRECATED("Use embedUInt32() instead of duint32()")
inline Error duint32(uint32_t x) { return _emitter()->embed(&x, sizeof(uint32_t)); }
- //! Adds 64-bit integer data to the CodeBuffer.
+ ASMJIT_DEPRECATED("Use embedInt64() instead of dint64()")
inline Error dint64(int64_t x) { return _emitter()->embed(&x, sizeof(int64_t)); }
- //! Adds 64-bit integer data to the CodeBuffer.
+
+ ASMJIT_DEPRECATED("Use embedUInt64() instead of duint64()")
inline Error duint64(uint64_t x) { return _emitter()->embed(&x, sizeof(uint64_t)); }
- //! Adds float data to the CodeBuffer.
+ ASMJIT_DEPRECATED("Use embedFloat() instead of float()")
inline Error dfloat(float x) { return _emitter()->embed(&x, sizeof(float)); }
- //! Adds double data to the CodeBuffer.
+
+ ASMJIT_DEPRECATED("Use embedDouble() instead of ddouble()")
inline Error ddouble(double x) { return _emitter()->embed(&x, sizeof(double)); }
- //! Adds MMX data to the CodeBuffer.
- inline Error dmm(const Data64& x) { return _emitter()->embed(&x, sizeof(Data64)); }
- //! Adds XMM data to the CodeBuffer.
- inline Error dxmm(const Data128& x) { return _emitter()->embed(&x, sizeof(Data128)); }
- //! Adds YMM data to the CodeBuffer.
- inline Error dymm(const Data256& x) { return _emitter()->embed(&x, sizeof(Data256)); }
+ ASMJIT_DEPRECATED("Use embed[U]IntN() or embed[Float|Double]() instead of dmm()")
+ inline Error dmm(const Data64& x) { return _emitter()->embed(&x, 8); }
+
+ ASMJIT_DEPRECATED("Use embed[U]IntN() or embed[Float|Double]() instead of dxmm()")
+ inline Error dxmm(const Data128& x) { return _emitter()->embed(&x, 16); }
+
+ ASMJIT_DEPRECATED("Use embed[U]IntN() or embed[Float|Double]() instead of dymm()")
+ inline Error dymm(const Data256& x) { return _emitter()->embed(&x, 32); }
+#endif // !ASMJIT_NO_DEPRECATED
//! Adds data in a given structure instance to the CodeBuffer.
template<typename T>
@@ -2025,203 +2044,90 @@ public:
ASMJIT_INST_6x(v4fmaddss, V4fmaddss, Xmm, Xmm, Xmm, Xmm, Xmm, Mem) // AVX512_4FMAPS{kz}
ASMJIT_INST_6x(v4fnmaddps, V4fnmaddps, Zmm, Zmm, Zmm, Zmm, Zmm, Mem) // AVX512_4FMAPS{kz}
ASMJIT_INST_6x(v4fnmaddss, V4fnmaddss, Xmm, Xmm, Xmm, Xmm, Xmm, Mem) // AVX512_4FMAPS{kz}
- ASMJIT_INST_3x(vaddpd, Vaddpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vaddpd, Vaddpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vaddpd, Vaddpd, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vaddpd, Vaddpd, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vaddpd, Vaddpd, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vaddpd, Vaddpd, Zmm, Zmm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vaddps, Vaddps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vaddps, Vaddps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vaddps, Vaddps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vaddps, Vaddps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vaddps, Vaddps, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vaddps, Vaddps, Zmm, Zmm, Mem) // AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vaddpd, Vaddpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vaddpd, Vaddpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vaddps, Vaddps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vaddps, Vaddps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
ASMJIT_INST_3x(vaddsd, Vaddsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vaddsd, Vaddsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vaddss, Vaddss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vaddss, Vaddss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
- ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vaddsubps, Vaddsubps, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vaddsubps, Vaddsubps, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vaddsubps, Vaddsubps, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vaddsubps, Vaddsubps, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vaesdec, Vaesdec, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vaesdec, Vaesdec, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vaesdec, Vaesdec, Ymm, Ymm, Ymm) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesdec, Vaesdec, Ymm, Ymm, Mem) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesdec, Vaesdec, Zmm, Zmm, Zmm) // VAES
- ASMJIT_INST_3x(vaesdec, Vaesdec, Zmm, Zmm, Mem) // VAES
- ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Ymm, Ymm, Ymm) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Ymm, Ymm, Mem) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Zmm, Zmm, Zmm) // VAES
- ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Zmm, Zmm, Mem) // VAES
- ASMJIT_INST_3x(vaesenc, Vaesenc, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vaesenc, Vaesenc, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vaesenc, Vaesenc, Ymm, Ymm, Ymm) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesenc, Vaesenc, Ymm, Ymm, Mem) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesenc, Vaesenc, Zmm, Zmm, Zmm) // VAES
- ASMJIT_INST_3x(vaesenc, Vaesenc, Zmm, Zmm, Mem) // VAES
- ASMJIT_INST_3x(vaesenclast, Vaesenclast, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vaesenclast, Vaesenclast, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vaesenclast, Vaesenclast, Ymm, Ymm, Ymm) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesenclast, Vaesenclast, Ymm, Ymm, Mem) // VAES AVX512_VL
- ASMJIT_INST_3x(vaesenclast, Vaesenclast, Zmm, Zmm, Zmm) // VAES
- ASMJIT_INST_3x(vaesenclast, Vaesenclast, Zmm, Zmm, Mem) // VAES
- ASMJIT_INST_2x(vaesimc, Vaesimc, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vaesimc, Vaesimc, Xmm, Mem) // AVX
- ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(valignd, Valignd, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(valignd, Valignd, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(valignd, Valignd, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(valignd, Valignd, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(valignd, Valignd, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(valignd, Valignd, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(valignq, Valignq, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(valignq, Valignq, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(valignq, Valignq, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(valignq, Valignq, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(valignq, Valignq, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(valignq, Valignq, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vandnpd, Vandnpd, Xmm, Xmm, Xmm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandnpd, Vandnpd, Xmm, Xmm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandnpd, Vandnpd, Ymm, Ymm, Ymm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandnpd, Vandnpd, Ymm, Ymm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandnpd, Vandnpd, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vandnpd, Vandnpd, Zmm, Zmm, Mem) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vandnps, Vandnps, Xmm, Xmm, Xmm) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandnps, Vandnps, Xmm, Xmm, Mem) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandnps, Vandnps, Ymm, Ymm, Ymm) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandnps, Vandnps, Ymm, Ymm, Mem) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandnps, Vandnps, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b32}
- ASMJIT_INST_3x(vandnps, Vandnps, Zmm, Zmm, Mem) // AVX512_DQ{kz|b32}
- ASMJIT_INST_3x(vandpd, Vandpd, Xmm, Xmm, Xmm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandpd, Vandpd, Xmm, Xmm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandpd, Vandpd, Ymm, Ymm, Ymm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandpd, Vandpd, Ymm, Ymm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vandpd, Vandpd, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vandpd, Vandpd, Zmm, Zmm, Mem) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vandps, Vandps, Xmm, Xmm, Xmm) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandps, Vandps, Xmm, Xmm, Mem) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandps, Vandps, Ymm, Ymm, Ymm) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandps, Vandps, Ymm, Ymm, Mem) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vandps, Vandps, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b32}
- ASMJIT_INST_3x(vandps, Vandps, Zmm, Zmm, Mem) // AVX512_DQ{kz|b32}
- ASMJIT_INST_3x(vblendmb, Vblendmb, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmb, Vblendmb, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmb, Vblendmb, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmb, Vblendmb, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmb, Vblendmb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vblendmb, Vblendmb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vblendmd, Vblendmd, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmd, Vblendmd, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmd, Vblendmd, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmd, Vblendmd, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmd, Vblendmd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vblendmd, Vblendmd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vblendmpd, Vblendmpd, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmpd, Vblendmpd, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmpd, Vblendmpd, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmpd, Vblendmpd, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmpd, Vblendmpd, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vblendmpd, Vblendmpd, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vblendmps, Vblendmps, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmps, Vblendmps, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmps, Vblendmps, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmps, Vblendmps, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vblendmps, Vblendmps, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vblendmps, Vblendmps, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vblendmq, Vblendmq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmq, Vblendmq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmq, Vblendmq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmq, Vblendmq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vblendmq, Vblendmq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vblendmq, Vblendmq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vblendmw, Vblendmw, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmw, Vblendmw, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmw, Vblendmw, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmw, Vblendmw, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vblendmw, Vblendmw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vblendmw, Vblendmw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_4i(vblendpd, Vblendpd, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vblendpd, Vblendpd, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vblendpd, Vblendpd, Ymm, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_4i(vblendpd, Vblendpd, Ymm, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vblendps, Vblendps, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vblendps, Vblendps, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vblendps, Vblendps, Ymm, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_4i(vblendps, Vblendps, Ymm, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_4x(vblendvpd, Vblendvpd, Xmm, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_4x(vblendvpd, Vblendvpd, Xmm, Xmm, Mem, Xmm) // AVX
- ASMJIT_INST_4x(vblendvpd, Vblendvpd, Ymm, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_4x(vblendvpd, Vblendvpd, Ymm, Ymm, Mem, Ymm) // AVX
- ASMJIT_INST_4x(vblendvps, Vblendvps, Xmm, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_4x(vblendvps, Vblendvps, Xmm, Xmm, Mem, Xmm) // AVX
- ASMJIT_INST_4x(vblendvps, Vblendvps, Ymm, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_4x(vblendvps, Vblendvps, Ymm, Ymm, Mem, Ymm) // AVX
- ASMJIT_INST_2x(vbroadcastf128, Vbroadcastf128, Ymm, Mem) // AVX
- ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, Ymm, Xmm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, Ymm, Mem) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, Zmm, Xmm) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, Zmm, Mem) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, Ymm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcastf32x8, Vbroadcastf32x8, Zmm, Mem) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, Ymm, Mem) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, Zmm, Mem) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcastf64x4, Vbroadcastf64x4, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcasti128, Vbroadcasti128, Ymm, Mem) // AVX2
- ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Xmm, Xmm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Xmm, Mem) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Ymm, Xmm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Ymm, Mem) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Zmm, Xmm) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Zmm, Mem) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, Zmm, Mem) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, Ymm, Xmm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, Ymm, Mem) // AVX512_DQ{kz}-VL
- ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, Zmm, Xmm) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, Zmm, Mem) // AVX512_DQ{kz}
- ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Xmm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Ymm, Mem) // AVX AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Ymm, Xmm) // AVX2 AVX512_F{kz}
- ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Zmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Zmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_4i(vcmppd, Vcmppd, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vcmppd, Vcmppd, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vcmppd, Vcmppd, Ymm, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_4i(vcmppd, Vcmppd, Ymm, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Zmm, Mem, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_4i(vcmpps, Vcmpps, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vcmpps, Vcmpps, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vcmpps, Vcmpps, Ymm, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_4i(vcmpps, Vcmpps, Ymm, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Zmm, Mem, Imm) // AVX512_F{kz|sae|b32}
+ ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vaddsubps, Vaddsubps, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vaddsubps, Vaddsubps, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vaesdec, Vaesdec, Vec, Vec, Vec) // AVX+AESNI VAES
+ ASMJIT_INST_3x(vaesdec, Vaesdec, Vec, Vec, Mem) // AVX+AESNI VAES
+ ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Vec, Vec, Vec) // AVX+AESNI VAES
+ ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, Vec, Vec, Mem) // AVX+AESNI VAES
+ ASMJIT_INST_3x(vaesenc, Vaesenc, Vec, Vec, Vec) // AVX+AESNI VAES
+ ASMJIT_INST_3x(vaesenc, Vaesenc, Vec, Vec, Mem) // AVX+AESNI VAES
+ ASMJIT_INST_3x(vaesenclast, Vaesenclast, Vec, Vec, Vec) // AVX+AESNI VAES
+ ASMJIT_INST_3x(vaesenclast, Vaesenclast, Vec, Vec, Mem) // AVX+AESNI VAES
+ ASMJIT_INST_2x(vaesimc, Vaesimc, Xmm, Xmm) // AVX+AESNI
+ ASMJIT_INST_2x(vaesimc, Vaesimc, Xmm, Mem) // AVX+AESNI
+ ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, Xmm, Xmm, Imm) // AVX+AESNI
+ ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, Xmm, Mem, Imm) // AVX+AESNI
+ ASMJIT_INST_4i(valignd, Valignd, Vec, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(valignd, Valignd, Vec, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(valignq, Valignq, Vec, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(valignq, Valignq, Vec, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vandnpd, Vandnpd, Vec, Vec, Vec) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vandnpd, Vandnpd, Vec, Vec, Mem) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vandnps, Vandnps, Vec, Vec, Vec) // AVX AVX512_DQ{kz|b32}
+ ASMJIT_INST_3x(vandnps, Vandnps, Vec, Vec, Mem) // AVX AVX512_DQ{kz|b32}
+ ASMJIT_INST_3x(vandpd, Vandpd, Vec, Vec, Vec) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vandpd, Vandpd, Vec, Vec, Mem) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vandps, Vandps, Vec, Vec, Vec) // AVX AVX512_DQ{kz|b32}
+ ASMJIT_INST_3x(vandps, Vandps, Vec, Vec, Mem) // AVX AVX512_DQ{kz|b32}
+ ASMJIT_INST_3x(vblendmb, Vblendmb, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vblendmb, Vblendmb, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vblendmd, Vblendmd, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vblendmd, Vblendmd, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vblendmpd, Vblendmpd, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vblendmpd, Vblendmpd, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vblendmps, Vblendmps, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vblendmps, Vblendmps, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vblendmq, Vblendmq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vblendmq, Vblendmq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vblendmw, Vblendmw, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vblendmw, Vblendmw, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_4i(vblendpd, Vblendpd, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vblendpd, Vblendpd, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_4i(vblendps, Vblendps, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vblendps, Vblendps, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_4x(vblendvpd, Vblendvpd, Vec, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_4x(vblendvpd, Vblendvpd, Vec, Vec, Mem, Vec) // AVX
+ ASMJIT_INST_4x(vblendvps, Vblendvps, Vec, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_4x(vblendvps, Vblendvps, Vec, Vec, Mem, Vec) // AVX
+ ASMJIT_INST_2x(vbroadcastf128, Vbroadcastf128, Vec, Mem) // AVX
+ ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, Vec, Vec) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, Vec, Mem) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcastf32x8, Vbroadcastf32x8, Vec, Mem) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, Vec, Mem) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcastf64x4, Vbroadcastf64x4, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcasti128, Vbroadcasti128, Vec, Mem) // AVX2
+ ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Vec, Vec) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, Vec, Mem) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, Vec, Mem) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, Vec, Vec) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, Vec, Mem) // AVX512_DQ{kz}
+ ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, Vec, Xmm) // AVX2 AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, Vec, Xmm) // AVX2 AVX512_F{kz}
+ ASMJIT_INST_4i(vcmppd, Vcmppd, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vcmppd, Vcmppd, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vcmppd, Vcmppd, KReg, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vcmpps, Vcmpps, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vcmpps, Vcmpps, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vcmpps, Vcmpps, KReg, Vec, Mem, Imm) // AVX512_F{kz|b32}
ASMJIT_INST_4i(vcmpsd, Vcmpsd, Xmm, Xmm, Xmm, Imm) // AVX
ASMJIT_INST_4i(vcmpsd, Vcmpsd, Xmm, Xmm, Mem, Imm) // AVX
ASMJIT_INST_4i(vcmpsd, Vcmpsd, KReg, Xmm, Xmm, Imm) // AVX512_F{kz|sae}
@@ -2234,121 +2140,46 @@ public:
ASMJIT_INST_2x(vcomisd, Vcomisd, Xmm, Mem) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vcomiss, Vcomiss, Xmm, Xmm) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vcomiss, Vcomiss, Xmm, Mem) // AVX AVX512_F{sae}
- ASMJIT_INST_2x(vcompresspd, Vcompresspd, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompresspd, Vcompresspd, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompresspd, Vcompresspd, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompresspd, Vcompresspd, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompresspd, Vcompresspd, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vcompresspd, Vcompresspd, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vcompressps, Vcompressps, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompressps, Vcompressps, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompressps, Vcompressps, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompressps, Vcompressps, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcompressps, Vcompressps, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vcompressps, Vcompressps, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Ymm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Zmm, Ymm) // AVX512_F{kz|b32}
- ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Zmm, Mem) // AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Xmm, Xmm, Xmm) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Xmm, Xmm, Mem) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Ymm, Ymm, Ymm) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Ymm, Ymm, Mem) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Zmm, Zmm, Zmm) // AVX512_BF16{kz|b32}
- ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Zmm, Zmm, Mem) // AVX512_BF16{kz|b32}
- ASMJIT_INST_2x(vcvtneps2bf16, Vcvtneps2bf16, Xmm, Xmm) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_2x(vcvtneps2bf16, Vcvtneps2bf16, Xmm, Ymm) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_2x(vcvtneps2bf16, Vcvtneps2bf16, Xmm, Mem) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_2x(vcvtneps2bf16, Vcvtneps2bf16, Ymm, Zmm) // AVX512_BF16{kz|b32}
- ASMJIT_INST_2x(vcvtneps2bf16, Vcvtneps2bf16, Ymm, Mem) // AVX512_BF16{kz|b32}
- ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, Xmm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, Ymm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, Ymm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, Xmm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, Ymm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, Ymm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Ymm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Ymm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Zmm, Zmm) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Zmm, Mem) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, Xmm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, Ymm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, Ymm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Ymm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Ymm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Zmm, Zmm) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Zmm, Mem) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Xmm, Xmm) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Xmm, Mem) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Ymm, Xmm) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Ymm, Mem) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Zmm, Ymm) // AVX512_F{kz|sae}
- ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Zmm, Mem) // AVX512_F{kz|sae}
- ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Zmm, Mem) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Ymm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Zmm, Ymm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Zmm, Mem) // AVX512_F{kz|er|b32}
- ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Xmm, Xmm, Imm) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Mem, Xmm, Imm) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Xmm, Ymm, Imm) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Mem, Ymm, Imm) // F16C AVX512_F{kz}-VL
- ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Ymm, Zmm, Imm) // AVX512_F{kz|sae}
- ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Mem, Zmm, Imm) // AVX512_F{kz|sae}
- ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Xmm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Xmm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Ymm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Ymm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Zmm, Ymm) // AVX512_DQ{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Zmm, Mem) // AVX512_DQ{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Zmm, Mem) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Xmm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Xmm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Ymm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Ymm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Zmm, Ymm) // AVX512_DQ{kz|er|b32}
- ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Zmm, Mem) // AVX512_DQ{kz|er|b32}
- ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Ymm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Ymm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Zmm, Zmm) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Zmm, Mem) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, Xmm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, Ymm, Zmm) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, Ymm, Mem) // AVX512_DQ{kz|er|b64}
+ ASMJIT_INST_2x(vcompresspd, Vcompresspd, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vcompresspd, Vcompresspd, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vcompressps, Vcompressps, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vcompressps, Vcompressps, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Vec, Vec, Vec) // AVX512_BF16{kz|b32}
+ ASMJIT_INST_3x(vcvtne2ps2bf16, Vcvtne2ps2bf16, Vec, Vec, Mem) // AVX512_BF16{kz|b32}
+ ASMJIT_INST_2x(vcvtneps2bf16, Vcvtneps2bf16, Vec, Vec) // AVX512_BF16{kz|b32}
+ ASMJIT_INST_2x(vcvtneps2bf16, Vcvtneps2bf16, Vec, Mem) // AVX512_BF16{kz|b32}
+ ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, Vec, Mem) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, Vec, Mem) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Vec, Vec) // F16C AVX512_F{kz}
+ ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, Vec, Mem) // F16C AVX512_F{kz}
+ ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Vec, Vec, Imm) // F16C AVX512_F{kz}
+ ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, Mem, Vec, Imm) // F16C AVX512_F{kz}
+ ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Vec, Vec) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, Vec, Mem) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Vec, Vec) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, Vec, Mem) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, Vec, Mem) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, Vec, Mem) // AVX512_DQ{kz|b64}
ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, Gp, Xmm) // AVX AVX512_F{er}
ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, Gp, Mem) // AVX AVX512_F{er}
ASMJIT_INST_3x(vcvtsd2ss, Vcvtsd2ss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
@@ -2365,52 +2196,22 @@ public:
ASMJIT_INST_2x(vcvtss2si, Vcvtss2si, Gp, Mem) // AVX AVX512_F{er}
ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, Gp, Xmm) // AVX512_F{er}
ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, Gp, Mem) // AVX512_F{er}
- ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, Xmm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, Ymm, Zmm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, Ymm, Mem) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Zmm, Zmm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Zmm, Mem) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, Xmm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, Ymm, Zmm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, Ymm, Mem) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Ymm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Ymm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Zmm, Zmm) // AVX512_DQ{kz|sae|b64}
- ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Zmm, Mem) // AVX512_DQ{kz|sae|b64}
- ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Zmm, Zmm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Zmm, Mem) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Xmm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Xmm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Ymm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Ymm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Zmm, Ymm) // AVX512_DQ{kz|sae|b32}
- ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Zmm, Mem) // AVX512_DQ{kz|sae|b32}
- ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Zmm, Zmm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Zmm, Mem) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Xmm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Xmm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Ymm, Xmm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Ymm, Mem) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Zmm, Ymm) // AVX512_DQ{kz|sae|b32}
- ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Zmm, Mem) // AVX512_DQ{kz|sae|b32}
+ ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, Vec, Mem) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Vec, Vec) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, Vec, Mem) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Vec, Vec) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, Vec, Mem) // AVX512_DQ{kz|b32}
ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, Gp, Xmm) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, Gp, Mem) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vcvttsd2usi, Vcvttsd2usi, Gp, Xmm) // AVX512_F{sae}
@@ -2419,415 +2220,204 @@ public:
ASMJIT_INST_2x(vcvttss2si, Vcvttss2si, Gp, Mem) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, Gp, Xmm) // AVX512_F{sae}
ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, Gp, Mem) // AVX512_F{sae}
- ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Ymm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Zmm, Ymm) // AVX512_F{kz|b32}
- ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Zmm, Mem) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Ymm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Ymm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Zmm, Zmm) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Zmm, Mem) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, Xmm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, Ymm, Zmm) // AVX512_DQ{kz|er|b64}
- ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, Ymm, Mem) // AVX512_DQ{kz|er|b64}
+ ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, Vec, Mem) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, Vec, Mem) // AVX512_DQ{kz|b64}
ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, Xmm, Xmm, Gp) // AVX512_F{er}
ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, Xmm, Xmm, Mem) // AVX512_F{er}
ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, Xmm, Xmm, Gp) // AVX512_F{er}
ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, Xmm, Xmm, Mem) // AVX512_F{er}
- ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Xmm, Xmm, Xmm, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Xmm, Xmm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Ymm, Ymm, Ymm, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Ymm, Ymm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Zmm, Zmm, Zmm, Imm) // AVX512_BW{kz}
- ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Zmm, Zmm, Mem, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vdivpd, Vdivpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vdivpd, Vdivpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vdivpd, Vdivpd, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vdivpd, Vdivpd, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vdivpd, Vdivpd, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vdivpd, Vdivpd, Zmm, Zmm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vdivps, Vdivps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vdivps, Vdivps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vdivps, Vdivps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vdivps, Vdivps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vdivps, Vdivps, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vdivps, Vdivps, Zmm, Zmm, Mem) // AVX512_F{kz|er|b32}
+ ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Vec, Vec, Vec, Imm) // AVX512_BW{kz}
+ ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, Vec, Vec, Mem, Imm) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vdivpd, Vdivpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vdivpd, Vdivpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vdivps, Vdivps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vdivps, Vdivps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
ASMJIT_INST_3x(vdivsd, Vdivsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vdivsd, Vdivsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vdivss, Vdivss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vdivss, Vdivss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
- ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Xmm, Xmm, Xmm) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Xmm, Xmm, Mem) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Ymm, Ymm, Ymm) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Ymm, Ymm, Mem) // AVX512_BF16{kz|b32}-VL
- ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Zmm, Zmm, Zmm) // AVX512_BF16{kz|b32}
- ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Zmm, Zmm, Mem) // AVX512_BF16{kz|b32}
- ASMJIT_INST_4i(vdppd, Vdppd, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vdppd, Vdppd, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vdpps, Vdpps, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vdpps, Vdpps, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vdpps, Vdpps, Ymm, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_4i(vdpps, Vdpps, Ymm, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_2x(vexp2pd, Vexp2pd, Zmm, Zmm) // AVX512_ER{kz|sae|b64}
- ASMJIT_INST_2x(vexp2pd, Vexp2pd, Zmm, Mem) // AVX512_ER{kz|sae|b64}
- ASMJIT_INST_2x(vexp2ps, Vexp2ps, Zmm, Zmm) // AVX512_ER{kz|sae|b32}
- ASMJIT_INST_2x(vexp2ps, Vexp2ps, Zmm, Mem) // AVX512_ER{kz|sae|b32}
- ASMJIT_INST_2x(vexpandpd, Vexpandpd, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandpd, Vexpandpd, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandpd, Vexpandpd, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandpd, Vexpandpd, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandpd, Vexpandpd, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vexpandpd, Vexpandpd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vexpandps, Vexpandps, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandps, Vexpandps, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandps, Vexpandps, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandps, Vexpandps, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vexpandps, Vexpandps, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vexpandps, Vexpandps, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3i(vextractf128, Vextractf128, Xmm, Ymm, Imm) // AVX
- ASMJIT_INST_3i(vextractf128, Vextractf128, Mem, Ymm, Imm) // AVX
- ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, Xmm, Ymm, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, Mem, Ymm, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, Xmm, Zmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, Mem, Zmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, Ymm, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, Mem, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, Xmm, Ymm, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, Mem, Ymm, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, Xmm, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, Mem, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, Ymm, Zmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, Mem, Zmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_3i(vextracti128, Vextracti128, Xmm, Ymm, Imm) // AVX2
- ASMJIT_INST_3i(vextracti128, Vextracti128, Mem, Ymm, Imm) // AVX2
- ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, Xmm, Ymm, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, Mem, Ymm, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, Xmm, Zmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, Mem, Zmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, Ymm, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, Mem, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, Xmm, Ymm, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, Mem, Ymm, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, Xmm, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, Mem, Zmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, Ymm, Zmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, Mem, Zmm, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Vec, Vec, Vec) // AVX512_BF16{kz|b32}
+ ASMJIT_INST_3x(vdpbf16ps, Vdpbf16ps, Vec, Vec, Mem) // AVX512_BF16{kz|b32}
+ ASMJIT_INST_4i(vdppd, Vdppd, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vdppd, Vdppd, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_4i(vdpps, Vdpps, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vdpps, Vdpps, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_2x(vexp2pd, Vexp2pd, Vec, Vec) // AVX512_ER{kz|sae|b64}
+ ASMJIT_INST_2x(vexp2pd, Vexp2pd, Vec, Mem) // AVX512_ER{kz|sae|b64}
+ ASMJIT_INST_2x(vexp2ps, Vexp2ps, Vec, Vec) // AVX512_ER{kz|sae|b32}
+ ASMJIT_INST_2x(vexp2ps, Vexp2ps, Vec, Mem) // AVX512_ER{kz|sae|b32}
+ ASMJIT_INST_2x(vexpandpd, Vexpandpd, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vexpandpd, Vexpandpd, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vexpandps, Vexpandps, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vexpandps, Vexpandps, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextractf128, Vextractf128, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_3i(vextractf128, Vextractf128, Mem, Vec, Imm) // AVX
+ ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, Mem, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, Mem, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, Mem, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, Mem, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextracti128, Vextracti128, Vec, Vec, Imm) // AVX2
+ ASMJIT_INST_3i(vextracti128, Vextracti128, Mem, Vec, Imm) // AVX2
+ ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, Mem, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, Mem, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, Mem, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, Mem, Vec, Imm) // AVX512_F{kz}
ASMJIT_INST_3i(vextractps, Vextractps, Gp, Xmm, Imm) // AVX AVX512_F
ASMJIT_INST_3i(vextractps, Vextractps, Mem, Xmm, Imm) // AVX AVX512_F
- ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|sae|b32}
+ ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Vec, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, Vec, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Vec, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, Vec, Vec, Mem, Imm) // AVX512_F{kz|b32}
ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|sae}
- ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Xmm, Xmm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Ymm, Ymm, Ymm) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Ymm, Ymm, Mem) // FMA AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Zmm, Zmm, Zmm) // FMA AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Zmm, Zmm, Mem) // FMA AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Vec, Vec, Vec) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, Vec, Vec, Mem) // FMA AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Vec, Vec, Vec) // FMA AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, Vec, Vec, Mem) // FMA AVX512_F{kz|b32}
ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, Xmm, Xmm, Xmm) // FMA AVX512_F{kz|er}
ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, Xmm, Xmm, Mem) // FMA AVX512_F{kz|er}
- ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, KReg, Xmm, Imm) // AVX512_DQ{k|b64}-VL
- ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, KReg, Mem, Imm) // AVX512_DQ{k|b64} AVX512_DQ{k|b64}-VL
- ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, KReg, Ymm, Imm) // AVX512_DQ{k|b64}-VL
- ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, KReg, Zmm, Imm) // AVX512_DQ{k|b64}
- ASMJIT_INST_3i(vfpclassps, Vfpclassps, KReg, Xmm, Imm) // AVX512_DQ{k|b32}-VL
- ASMJIT_INST_3i(vfpclassps, Vfpclassps, KReg, Mem, Imm) // AVX512_DQ{k|b32} AVX512_DQ{k|b32}-VL
- ASMJIT_INST_3i(vfpclassps, Vfpclassps, KReg, Ymm, Imm) // AVX512_DQ{k|b32}-VL
- ASMJIT_INST_3i(vfpclassps, Vfpclassps, KReg, Zmm, Imm) // AVX512_DQ{k|b32}
+ ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, KReg, Vec, Imm) // AVX512_DQ{k|b64}
+ ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, KReg, Mem, Imm) // AVX512_DQ{k|b64}
+ ASMJIT_INST_3i(vfpclassps, Vfpclassps, KReg, Vec, Imm) // AVX512_DQ{k|b32}
+ ASMJIT_INST_3i(vfpclassps, Vfpclassps, KReg, Mem, Imm) // AVX512_DQ{k|b32}
ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, KReg, Xmm, Imm) // AVX512_DQ{k}
ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, KReg, Mem, Imm) // AVX512_DQ{k}
ASMJIT_INST_3i(vfpclassss, Vfpclassss, KReg, Xmm, Imm) // AVX512_DQ{k}
ASMJIT_INST_3i(vfpclassss, Vfpclassss, KReg, Mem, Imm) // AVX512_DQ{k}
- ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, Ymm, Mem, Ymm) // AVX2
- ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, Zmm, Mem) // AVX512_F{k}
- ASMJIT_INST_3x(vgatherdps, Vgatherdps, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_3x(vgatherdps, Vgatherdps, Ymm, Mem, Ymm) // AVX2
- ASMJIT_INST_2x(vgatherdps, Vgatherdps, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherdps, Vgatherdps, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherdps, Vgatherdps, Zmm, Mem) // AVX512_F{k}
+ ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, Vec, Mem, Vec) // AVX2
+ ASMJIT_INST_2x(vgatherdps, Vgatherdps, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vgatherdps, Vgatherdps, Vec, Mem, Vec) // AVX2
ASMJIT_INST_1x(vgatherpf0dpd, Vgatherpf0dpd, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vgatherpf0dps, Vgatherpf0dps, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vgatherpf0qpd, Vgatherpf0qpd, Mem) // AVX512_PF{k}
@@ -2836,249 +2426,121 @@ public:
ASMJIT_INST_1x(vgatherpf1dps, Vgatherpf1dps, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vgatherpf1qpd, Vgatherpf1qpd, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vgatherpf1qps, Vgatherpf1qps, Mem) // AVX512_PF{k}
- ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, Ymm, Mem, Ymm) // AVX2
- ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, Zmm, Mem) // AVX512_F{k}
- ASMJIT_INST_3x(vgatherqps, Vgatherqps, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_2x(vgatherqps, Vgatherqps, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherqps, Vgatherqps, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vgatherqps, Vgatherqps, Zmm, Mem) // AVX512_F{k}
- ASMJIT_INST_2x(vgetexppd, Vgetexppd, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vgetexppd, Vgetexppd, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vgetexppd, Vgetexppd, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vgetexppd, Vgetexppd, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vgetexppd, Vgetexppd, Zmm, Zmm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vgetexppd, Vgetexppd, Zmm, Mem) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_2x(vgetexpps, Vgetexpps, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vgetexpps, Vgetexpps, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vgetexpps, Vgetexpps, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vgetexpps, Vgetexpps, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vgetexpps, Vgetexpps, Zmm, Zmm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_2x(vgetexpps, Vgetexpps, Zmm, Mem) // AVX512_F{kz|sae|b32}
+ ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, Vec, Mem, Vec) // AVX2
+ ASMJIT_INST_2x(vgatherqps, Vgatherqps, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vgatherqps, Vgatherqps, Vec, Mem, Vec) // AVX2
+ ASMJIT_INST_2x(vgetexppd, Vgetexppd, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vgetexppd, Vgetexppd, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vgetexpps, Vgetexpps, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vgetexpps, Vgetexpps, Vec, Mem) // AVX512_F{kz|b32}
ASMJIT_INST_3x(vgetexpsd, Vgetexpsd, Xmm, Xmm, Xmm) // AVX512_F{kz|sae}
ASMJIT_INST_3x(vgetexpsd, Vgetexpsd, Xmm, Xmm, Mem) // AVX512_F{kz|sae}
ASMJIT_INST_3x(vgetexpss, Vgetexpss, Xmm, Xmm, Xmm) // AVX512_F{kz|sae}
ASMJIT_INST_3x(vgetexpss, Vgetexpss, Xmm, Xmm, Mem) // AVX512_F{kz|sae}
- ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Zmm, Mem, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3i(vgetmantps, Vgetmantps, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vgetmantps, Vgetmantps, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vgetmantps, Vgetmantps, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vgetmantps, Vgetmantps, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vgetmantps, Vgetmantps, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_3i(vgetmantps, Vgetmantps, Zmm, Mem, Imm) // AVX512_F{kz|sae|b32}
+ ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vgetmantps, Vgetmantps, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vgetmantps, Vgetmantps, Vec, Mem, Imm) // AVX512_F{kz|b32}
ASMJIT_INST_4i(vgetmantsd, Vgetmantsd, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vgetmantsd, Vgetmantsd, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vgetmantss, Vgetmantss, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vgetmantss, Vgetmantss, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|sae}
- ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Xmm,Xmm,Xmm,Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Xmm,Xmm,Mem,Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Ymm,Ymm,Ymm,Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Ymm,Ymm,Mem,Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Zmm,Zmm,Zmm,Imm) // AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Zmm,Zmm,Mem,Imm) // AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Xmm, Xmm, Xmm, Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Xmm, Xmm, Mem, Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Ymm, Ymm, Ymm, Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Ymm, Ymm, Mem, Imm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Zmm, Zmm, Zmm, Imm) // AVX512_VL{kz} GFNI
- ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Zmm, Zmm, Mem, Imm) // AVX512_VL{kz} GFNI
- ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Xmm, Xmm, Xmm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Xmm, Xmm, Mem) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Ymm, Ymm, Ymm) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Ymm, Ymm, Mem) // AVX AVX512_VL{kz} GFNI
- ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Zmm, Zmm, Zmm) // AVX512_VL{kz} GFNI
- ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Zmm, Zmm, Mem) // AVX512_VL{kz} GFNI
- ASMJIT_INST_3x(vhaddpd, Vhaddpd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vhaddpd, Vhaddpd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vhaddpd, Vhaddpd, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vhaddpd, Vhaddpd, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vhaddps, Vhaddps, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vhaddps, Vhaddps, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vhaddps, Vhaddps, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vhaddps, Vhaddps, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vhsubpd, Vhsubpd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vhsubpd, Vhsubpd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vhsubpd, Vhsubpd, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vhsubpd, Vhsubpd, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vhsubps, Vhsubps, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vhsubps, Vhsubps, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vhsubps, Vhsubps, Ymm, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vhsubps, Vhsubps, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_4i(vinsertf128, Vinsertf128, Ymm, Ymm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vinsertf128, Vinsertf128, Ymm, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, Ymm, Ymm, Xmm, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, Ymm, Ymm, Mem, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, Zmm, Zmm, Xmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, Zmm, Zmm, Mem, Imm) // AVX512_F{kz}
- ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, Zmm, Zmm, Ymm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, Zmm, Zmm, Mem, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, Ymm, Ymm, Xmm, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, Ymm, Ymm, Mem, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, Zmm, Zmm, Xmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, Zmm, Zmm, Mem, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, Zmm, Zmm, Ymm, Imm) // AVX512_F{kz}
- ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, Zmm, Zmm, Mem, Imm) // AVX512_F{kz}
- ASMJIT_INST_4i(vinserti128, Vinserti128, Ymm, Ymm, Xmm, Imm) // AVX2
- ASMJIT_INST_4i(vinserti128, Vinserti128, Ymm, Ymm, Mem, Imm) // AVX2
- ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, Ymm, Ymm, Xmm, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, Ymm, Ymm, Mem, Imm) // AVX512_F{kz}-VL
- ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, Zmm, Zmm, Xmm, Imm) // AVX512_F{kz}
- ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, Zmm, Zmm, Mem, Imm) // AVX512_F{kz}
- ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, Zmm, Zmm, Ymm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, Zmm, Zmm, Mem, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, Ymm, Ymm, Xmm, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, Ymm, Ymm, Mem, Imm) // AVX512_DQ{kz}-VL
- ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, Zmm, Zmm, Xmm, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, Zmm, Zmm, Mem, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, Zmm, Zmm, Ymm, Imm) // AVX512_F{kz}
- ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, Zmm, Zmm, Mem, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Vec,Vec,Vec,Imm) // AVX AVX512_VL{kz} GFNI
+ ASMJIT_INST_4i(vgf2p8affineinvqb, Vgf2p8affineinvqb,Vec,Vec,Mem,Imm) // AVX AVX512_VL{kz} GFNI
+ ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Vec, Vec, Vec, Imm) // AVX AVX512_VL{kz} GFNI
+ ASMJIT_INST_4i(vgf2p8affineqb, Vgf2p8affineqb, Vec, Vec, Mem, Imm) // AVX AVX512_VL{kz} GFNI
+ ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Vec, Vec, Vec) // AVX AVX512_VL{kz} GFNI
+ ASMJIT_INST_3x(vgf2p8mulb, Vgf2p8mulb, Vec, Vec, Mem) // AVX AVX512_VL{kz} GFNI
+ ASMJIT_INST_3x(vhaddpd, Vhaddpd, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vhaddpd, Vhaddpd, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vhaddps, Vhaddps, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vhaddps, Vhaddps, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vhsubpd, Vhsubpd, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vhsubpd, Vhsubpd, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vhsubps, Vhsubps, Vec, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vhsubps, Vhsubps, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_4i(vinsertf128, Vinsertf128, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vinsertf128, Vinsertf128, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, Vec, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, Vec, Vec, Mem, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, Vec, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, Vec, Vec, Mem, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, Vec, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, Vec, Vec, Mem, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, Vec, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, Vec, Vec, Mem, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vinserti128, Vinserti128, Vec, Vec, Vec, Imm) // AVX2
+ ASMJIT_INST_4i(vinserti128, Vinserti128, Vec, Vec, Mem, Imm) // AVX2
+ ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, Vec, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, Vec, Vec, Mem, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, Vec, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, Vec, Vec, Mem, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, Vec, Vec, Vec, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, Vec, Vec, Mem, Imm) // AVX512_DQ{kz}
+ ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, Vec, Vec, Vec, Imm) // AVX512_F{kz}
+ ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, Vec, Vec, Mem, Imm) // AVX512_F{kz}
ASMJIT_INST_4i(vinsertps, Vinsertps, Xmm, Xmm, Xmm, Imm) // AVX AVX512_F
ASMJIT_INST_4i(vinsertps, Vinsertps, Xmm, Xmm, Mem, Imm) // AVX AVX512_F
- ASMJIT_INST_2x(vlddqu, Vlddqu, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vlddqu, Vlddqu, Ymm, Mem) // AVX
+ ASMJIT_INST_2x(vlddqu, Vlddqu, Vec, Mem) // AVX
ASMJIT_INST_1x(vldmxcsr, Vldmxcsr, Mem) // AVX
- ASMJIT_INST_3x(vmaskmovdqu, Vmaskmovdqu, Xmm, Xmm, DS_ZDI) // AVX [EXPLICIT]
- ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, Mem, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, Mem, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, Mem, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, Mem, Ymm, Ymm) // AVX
- ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, Ymm, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vmaxpd, Vmaxpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmaxpd, Vmaxpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmaxpd, Vmaxpd, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmaxpd, Vmaxpd, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmaxpd, Vmaxpd, Zmm, Zmm, Zmm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3x(vmaxpd, Vmaxpd, Zmm, Zmm, Mem) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3x(vmaxps, Vmaxps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmaxps, Vmaxps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmaxps, Vmaxps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmaxps, Vmaxps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmaxps, Vmaxps, Zmm, Zmm, Zmm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_3x(vmaxps, Vmaxps, Zmm, Zmm, Mem) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_3x(vmaxsd, Vmaxsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_3x(vmaxsd, Vmaxsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_3x(vmaxss, Vmaxss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_3x(vmaxss, Vmaxss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_3x(vminpd, Vminpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vminpd, Vminpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vminpd, Vminpd, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vminpd, Vminpd, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vminpd, Vminpd, Zmm, Zmm, Zmm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3x(vminpd, Vminpd, Zmm, Zmm, Mem) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3x(vminps, Vminps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vminps, Vminps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vminps, Vminps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vminps, Vminps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vminps, Vminps, Zmm, Zmm, Zmm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_3x(vminps, Vminps, Zmm, Zmm, Mem) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_3x(vminsd, Vminsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_3x(vminsd, Vminsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_3x(vminss, Vminss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_3x(vminss, Vminss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}-VL
- ASMJIT_INST_2x(vmovapd, Vmovapd, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovapd, Vmovapd, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovapd, Vmovapd, Mem, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovapd, Vmovapd, Ymm, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovapd, Vmovapd, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovapd, Vmovapd, Mem, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovapd, Vmovapd, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovapd, Vmovapd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovapd, Vmovapd, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovaps, Vmovaps, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovaps, Vmovaps, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovaps, Vmovaps, Mem, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovaps, Vmovaps, Ymm, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovaps, Vmovaps, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovaps, Vmovaps, Mem, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovaps, Vmovaps, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovaps, Vmovaps, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovaps, Vmovaps, Mem, Zmm) // AVX512_F{kz}
+ ASMJIT_INST_3x(vmaskmovdqu, Vmaskmovdqu, Vec, Vec, DS_ZDI) // AVX [EXPLICIT]
+ ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, Mem, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, Mem, Vec, Vec) // AVX
+ ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, Vec, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vmaxpd, Vmaxpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vmaxpd, Vmaxpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vmaxps, Vmaxps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vmaxps, Vmaxps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vmaxsd, Vmaxsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_3x(vmaxsd, Vmaxsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_3x(vmaxss, Vmaxss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_3x(vmaxss, Vmaxss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_3x(vminpd, Vminpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vminpd, Vminpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vminps, Vminps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vminps, Vminps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vminsd, Vminsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_3x(vminsd, Vminsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_3x(vminss, Vminss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_3x(vminss, Vminss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|sae}
+ ASMJIT_INST_2x(vmovapd, Vmovapd, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovapd, Vmovapd, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovapd, Vmovapd, Mem, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovaps, Vmovaps, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovaps, Vmovaps, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovaps, Vmovaps, Mem, Vec) // AVX AVX512_F{kz}
ASMJIT_INST_2x(vmovd, Vmovd, Gp, Xmm) // AVX AVX512_F
ASMJIT_INST_2x(vmovd, Vmovd, Mem, Xmm) // AVX AVX512_F
ASMJIT_INST_2x(vmovd, Vmovd, Xmm, Gp) // AVX AVX512_F
ASMJIT_INST_2x(vmovd, Vmovd, Xmm, Mem) // AVX AVX512_F
- ASMJIT_INST_2x(vmovddup, Vmovddup, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovddup, Vmovddup, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovddup, Vmovddup, Ymm, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovddup, Vmovddup, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovddup, Vmovddup, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovddup, Vmovddup, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqa, Vmovdqa, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vmovdqa, Vmovdqa, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vmovdqa, Vmovdqa, Mem, Xmm) // AVX
- ASMJIT_INST_2x(vmovdqa, Vmovdqa, Ymm, Ymm) // AVX
- ASMJIT_INST_2x(vmovdqa, Vmovdqa, Ymm, Mem) // AVX
- ASMJIT_INST_2x(vmovdqa, Vmovdqa, Mem, Ymm) // AVX
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqu, Vmovdqu, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vmovdqu, Vmovdqu, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vmovdqu, Vmovdqu, Mem, Xmm) // AVX
- ASMJIT_INST_2x(vmovdqu, Vmovdqu, Ymm, Ymm) // AVX
- ASMJIT_INST_2x(vmovdqu, Vmovdqu, Ymm, Mem) // AVX
- ASMJIT_INST_2x(vmovdqu, Vmovdqu, Mem, Ymm) // AVX
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Mem, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Mem, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Mem, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Mem, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Mem, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Mem, Zmm) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vmovddup, Vmovddup, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovddup, Vmovddup, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqa, Vmovdqa, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vmovdqa, Vmovdqa, Vec, Mem) // AVX
+ ASMJIT_INST_2x(vmovdqa, Vmovdqa, Mem, Vec) // AVX
+ ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqu, Vmovdqu, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vmovdqu, Vmovdqu, Vec, Mem) // AVX
+ ASMJIT_INST_2x(vmovdqu, Vmovdqu, Mem, Vec) // AVX
+ ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, Mem, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, Mem, Vec) // AVX512_BW{kz}
ASMJIT_INST_3x(vmovhlps, Vmovhlps, Xmm, Xmm, Xmm) // AVX AVX512_F
ASMJIT_INST_2x(vmovhpd, Vmovhpd, Mem, Xmm) // AVX AVX512_F
ASMJIT_INST_3x(vmovhpd, Vmovhpd, Xmm, Xmm, Mem) // AVX AVX512_F
@@ -3089,22 +2551,12 @@ public:
ASMJIT_INST_3x(vmovlpd, Vmovlpd, Xmm, Xmm, Mem) // AVX AVX512_F
ASMJIT_INST_2x(vmovlps, Vmovlps, Mem, Xmm) // AVX AVX512_F
ASMJIT_INST_3x(vmovlps, Vmovlps, Xmm, Xmm, Mem) // AVX AVX512_F
- ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, Gp, Xmm) // AVX
- ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, Gp, Ymm) // AVX
- ASMJIT_INST_2x(vmovmskps, Vmovmskps, Gp, Xmm) // AVX
- ASMJIT_INST_2x(vmovmskps, Vmovmskps, Gp, Ymm) // AVX
- ASMJIT_INST_2x(vmovntdq, Vmovntdq, Mem, Xmm) // AVX AVX512_F-VL
- ASMJIT_INST_2x(vmovntdq, Vmovntdq, Mem, Ymm) // AVX AVX512_F-VL
- ASMJIT_INST_2x(vmovntdq, Vmovntdq, Mem, Zmm) // AVX512_F
- ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, Xmm, Mem) // AVX AVX512_F-VL
- ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, Ymm, Mem) // AVX2 AVX512_F-VL
- ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, Zmm, Mem) // AVX512_F
- ASMJIT_INST_2x(vmovntpd, Vmovntpd, Mem, Xmm) // AVX AVX512_F-VL
- ASMJIT_INST_2x(vmovntpd, Vmovntpd, Mem, Ymm) // AVX AVX512_F-VL
- ASMJIT_INST_2x(vmovntpd, Vmovntpd, Mem, Zmm) // AVX512_F
- ASMJIT_INST_2x(vmovntps, Vmovntps, Mem, Xmm) // AVX AVX512_F-VL
- ASMJIT_INST_2x(vmovntps, Vmovntps, Mem, Ymm) // AVX AVX512_F-VL
- ASMJIT_INST_2x(vmovntps, Vmovntps, Mem, Zmm) // AVX512_F
+ ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, Gp, Vec) // AVX
+ ASMJIT_INST_2x(vmovmskps, Vmovmskps, Gp, Vec) // AVX
+ ASMJIT_INST_2x(vmovntdq, Vmovntdq, Mem, Vec) // AVX+ AVX512_F
+ ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, Vec, Mem) // AVX+ AVX512_F
+ ASMJIT_INST_2x(vmovntpd, Vmovntpd, Mem, Vec) // AVX AVX512_F
+ ASMJIT_INST_2x(vmovntps, Vmovntps, Mem, Vec) // AVX AVX512_F
ASMJIT_INST_2x(vmovq, Vmovq, Gp, Xmm) // AVX AVX512_F
ASMJIT_INST_2x(vmovq, Vmovq, Mem, Xmm) // AVX AVX512_F
ASMJIT_INST_2x(vmovq, Vmovq, Xmm, Mem) // AVX AVX512_F
@@ -3113,627 +2565,241 @@ public:
ASMJIT_INST_2x(vmovsd, Vmovsd, Mem, Xmm) // AVX AVX512_F
ASMJIT_INST_2x(vmovsd, Vmovsd, Xmm, Mem) // AVX AVX512_F{kz}
ASMJIT_INST_3x(vmovsd, Vmovsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz}
- ASMJIT_INST_2x(vmovshdup, Vmovshdup, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovshdup, Vmovshdup, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovshdup, Vmovshdup, Ymm, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovshdup, Vmovshdup, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovshdup, Vmovshdup, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovshdup, Vmovshdup, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovsldup, Vmovsldup, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovsldup, Vmovsldup, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovsldup, Vmovsldup, Ymm, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovsldup, Vmovsldup, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovsldup, Vmovsldup, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovsldup, Vmovsldup, Zmm, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vmovshdup, Vmovshdup, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovshdup, Vmovshdup, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovsldup, Vmovsldup, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovsldup, Vmovsldup, Vec, Mem) // AVX AVX512_F{kz}
ASMJIT_INST_2x(vmovss, Vmovss, Mem, Xmm) // AVX AVX512_F
ASMJIT_INST_2x(vmovss, Vmovss, Xmm, Mem) // AVX AVX512_F{kz}
ASMJIT_INST_3x(vmovss, Vmovss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz}
- ASMJIT_INST_2x(vmovupd, Vmovupd, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovupd, Vmovupd, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovupd, Vmovupd, Mem, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovupd, Vmovupd, Ymm, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovupd, Vmovupd, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovupd, Vmovupd, Mem, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovupd, Vmovupd, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovupd, Vmovupd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovupd, Vmovupd, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovups, Vmovups, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovups, Vmovups, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovups, Vmovups, Mem, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovups, Vmovups, Ymm, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovups, Vmovups, Ymm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovups, Vmovups, Mem, Ymm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vmovups, Vmovups, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovups, Vmovups, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vmovups, Vmovups, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, Ymm, Ymm, Ymm, Imm) // AVX2
- ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, Ymm, Ymm, Mem, Imm) // AVX2
- ASMJIT_INST_3x(vmulpd, Vmulpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmulpd, Vmulpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmulpd, Vmulpd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmulpd, Vmulpd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vmulpd, Vmulpd, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vmulpd, Vmulpd, Zmm, Zmm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vmulps, Vmulps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmulps, Vmulps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmulps, Vmulps, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmulps, Vmulps, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vmulps, Vmulps, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vmulps, Vmulps, Zmm, Zmm, Mem) // AVX512_F{kz|er|b32}
+ ASMJIT_INST_2x(vmovupd, Vmovupd, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovupd, Vmovupd, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovupd, Vmovupd, Mem, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovups, Vmovups, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovups, Vmovups, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_2x(vmovups, Vmovups, Mem, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, Vec, Vec, Vec, Imm) // AVX+
+ ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, Vec, Vec, Mem, Imm) // AVX+
+ ASMJIT_INST_3x(vmulpd, Vmulpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vmulpd, Vmulpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vmulps, Vmulps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vmulps, Vmulps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
ASMJIT_INST_3x(vmulsd, Vmulsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vmulsd, Vmulsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vmulss, Vmulss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vmulss, Vmulss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
- ASMJIT_INST_3x(vorpd, Vorpd, Xmm, Xmm, Xmm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vorpd, Vorpd, Xmm, Xmm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vorpd, Vorpd, Ymm, Ymm, Ymm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vorpd, Vorpd, Ymm, Ymm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vorpd, Vorpd, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vorpd, Vorpd, Zmm, Zmm, Mem) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vorps, Vorps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vorps, Vorps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vorps, Vorps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vorps, Vorps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vorps, Vorps, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vorps, Vorps, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vorpd, Vorpd, Vec, Vec, Vec) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vorpd, Vorpd, Vec, Vec, Mem) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vorps, Vorps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vorps, Vorps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
ASMJIT_INST_6x(vp4dpwssd, Vp4dpwssd, Zmm, Zmm, Zmm, Zmm, Zmm, Mem) // AVX512_4FMAPS{kz}
ASMJIT_INST_6x(vp4dpwssds, Vp4dpwssds, Zmm, Zmm, Zmm, Zmm, Zmm, Mem) // AVX512_4FMAPS{kz}
- ASMJIT_INST_2x(vpabsb, Vpabsb, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsb, Vpabsb, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsb, Vpabsb, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsb, Vpabsb, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsb, Vpabsb, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpabsb, Vpabsb, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpabsd, Vpabsd, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsd, Vpabsd, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsd, Vpabsd, Ymm, Ymm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsd, Vpabsd, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsd, Vpabsd, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpabsd, Vpabsd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpabsq, Vpabsq, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsq, Vpabsq, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsq, Vpabsq, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsq, Vpabsq, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpabsq, Vpabsq, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpabsq, Vpabsq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpabsw, Vpabsw, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsw, Vpabsw, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsw, Vpabsw, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsw, Vpabsw, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpabsw, Vpabsw, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpabsw, Vpabsw, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpackssdw, Vpackssdw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackssdw, Vpackssdw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackssdw, Vpackssdw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackssdw, Vpackssdw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackssdw, Vpackssdw, Zmm, Zmm, Zmm) // AVX512_BW{kz|b32}
- ASMJIT_INST_3x(vpackssdw, Vpackssdw, Zmm, Zmm, Mem) // AVX512_BW{kz|b32}
- ASMJIT_INST_3x(vpacksswb, Vpacksswb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpacksswb, Vpacksswb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpacksswb, Vpacksswb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpacksswb, Vpacksswb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpacksswb, Vpacksswb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpacksswb, Vpacksswb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpackusdw, Vpackusdw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackusdw, Vpackusdw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackusdw, Vpackusdw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackusdw, Vpackusdw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz|b32}-VL
- ASMJIT_INST_3x(vpackusdw, Vpackusdw, Zmm, Zmm, Zmm) // AVX512_BW{kz|b32}
- ASMJIT_INST_3x(vpackusdw, Vpackusdw, Zmm, Zmm, Mem) // AVX512_BW{kz|b32}
- ASMJIT_INST_3x(vpackuswb, Vpackuswb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpackuswb, Vpackuswb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpackuswb, Vpackuswb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpackuswb, Vpackuswb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpackuswb, Vpackuswb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpackuswb, Vpackuswb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddb, Vpaddb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddb, Vpaddb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddb, Vpaddb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddb, Vpaddb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddb, Vpaddb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddb, Vpaddb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddd, Vpaddd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpaddd, Vpaddd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpaddd, Vpaddd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpaddd, Vpaddd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpaddd, Vpaddd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpaddd, Vpaddd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpaddq, Vpaddq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpaddq, Vpaddq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpaddq, Vpaddq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpaddq, Vpaddq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpaddq, Vpaddq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpaddq, Vpaddq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpaddsb, Vpaddsb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsb, Vpaddsb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsb, Vpaddsb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsb, Vpaddsb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsb, Vpaddsb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddsb, Vpaddsb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddsw, Vpaddsw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsw, Vpaddsw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsw, Vpaddsw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsw, Vpaddsw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddsw, Vpaddsw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddsw, Vpaddsw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddusb, Vpaddusb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusb, Vpaddusb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusb, Vpaddusb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusb, Vpaddusb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusb, Vpaddusb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddusb, Vpaddusb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddusw, Vpaddusw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusw, Vpaddusw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusw, Vpaddusw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusw, Vpaddusw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddusw, Vpaddusw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddusw, Vpaddusw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddw, Vpaddw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddw, Vpaddw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddw, Vpaddw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddw, Vpaddw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpaddw, Vpaddw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpaddw, Vpaddw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_4i(vpalignr, Vpalignr, Xmm, Xmm, Xmm, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vpalignr, Vpalignr, Xmm, Xmm, Mem, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vpalignr, Vpalignr, Ymm, Ymm, Ymm, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vpalignr, Vpalignr, Ymm, Ymm, Mem, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_4i(vpalignr, Vpalignr, Zmm, Zmm, Zmm, Imm) // AVX512_BW{kz}
- ASMJIT_INST_4i(vpalignr, Vpalignr, Zmm, Zmm, Mem, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpand, Vpand, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpand, Vpand, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpand, Vpand, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpand, Vpand, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpandd, Vpandd, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandd, Vpandd, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandd, Vpandd, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandd, Vpandd, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandd, Vpandd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpandd, Vpandd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpandn, Vpandn, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpandn, Vpandn, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpandn, Vpandn, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpandn, Vpandn, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpandnd, Vpandnd, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandnd, Vpandnd, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandnd, Vpandnd, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandnd, Vpandnd, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpandnd, Vpandnd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpandnd, Vpandnd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpandnq, Vpandnq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandnq, Vpandnq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandnq, Vpandnq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandnq, Vpandnq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandnq, Vpandnq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpandnq, Vpandnq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpandq, Vpandq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandq, Vpandq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandq, Vpandq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandq, Vpandq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpandq, Vpandq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpandq, Vpandq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpavgb, Vpavgb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgb, Vpavgb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgb, Vpavgb, Ymm, Ymm, Ymm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgb, Vpavgb, Ymm, Ymm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgb, Vpavgb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpavgb, Vpavgb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpavgw, Vpavgw, Xmm, Xmm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgw, Vpavgw, Xmm, Xmm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgw, Vpavgw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgw, Vpavgw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpavgw, Vpavgw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpavgw, Vpavgw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_4i(vpblendd, Vpblendd, Xmm, Xmm, Xmm, Imm) // AVX2
- ASMJIT_INST_4i(vpblendd, Vpblendd, Xmm, Xmm, Mem, Imm) // AVX2
- ASMJIT_INST_4i(vpblendd, Vpblendd, Ymm, Ymm, Ymm, Imm) // AVX2
- ASMJIT_INST_4i(vpblendd, Vpblendd, Ymm, Ymm, Mem, Imm) // AVX2
- ASMJIT_INST_4x(vpblendvb, Vpblendvb, Xmm, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_4x(vpblendvb, Vpblendvb, Xmm, Xmm, Mem, Xmm) // AVX
- ASMJIT_INST_4x(vpblendvb, Vpblendvb, Ymm, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_4x(vpblendvb, Vpblendvb, Ymm, Ymm, Mem, Ymm) // AVX2
- ASMJIT_INST_4i(vpblendw, Vpblendw, Xmm, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_4i(vpblendw, Vpblendw, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vpblendw, Vpblendw, Ymm, Ymm, Ymm, Imm) // AVX2
- ASMJIT_INST_4i(vpblendw, Vpblendw, Ymm, Ymm, Mem, Imm) // AVX2
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Xmm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Xmm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Ymm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Xmm, Gp) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Ymm, Gp) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Zmm, Gp) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Zmm, Xmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Xmm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Xmm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Xmm, Gp) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Ymm, Gp) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Zmm, Gp) // AVX512_F{kz}
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, Xmm, KReg) // AVX512_CD-VL
- ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, Ymm, KReg) // AVX512_CD-VL
- ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, Zmm, KReg) // AVX512_CD
- ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, Xmm, KReg) // AVX512_CD-VL
- ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, Ymm, KReg) // AVX512_CD-VL
- ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, Zmm, KReg) // AVX512_CD
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Xmm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Xmm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Xmm, Gp) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Ymm, Gp) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Zmm, Gp) // AVX512_F{kz}
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Xmm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Xmm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Ymm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Xmm, Gp) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Ymm, Gp) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Zmm, Gp) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Zmm, Xmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Xmm, Xmm, Xmm, Imm) // AVX AVX512_F-VL
- ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Xmm, Xmm, Mem, Imm) // AVX AVX512_F-VL
- ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Ymm, Ymm, Ymm, Imm) // AVX512_F-VL VPCLMULQDQ
- ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Ymm, Ymm, Mem, Imm) // AVX512_F-VL VPCLMULQDQ
- ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Zmm, Zmm, Zmm, Imm) // AVX512_F VPCLMULQDQ
- ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Zmm, Zmm, Mem, Imm) // AVX512_F VPCLMULQDQ
- ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Xmm, Xmm, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Xmm, Mem, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Ymm, Ymm, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Ymm, Mem, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Zmm, Zmm, Imm) // AVX512_BW{k}
- ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Zmm, Mem, Imm) // AVX512_BW{k}
- ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Xmm, Xmm, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Xmm, Mem, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Ymm, Ymm, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Ymm, Mem, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Zmm, Zmm, Imm) // AVX512_F{k|b32}
- ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Zmm, Mem, Imm) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Xmm, Xmm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Xmm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Ymm, Ymm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Ymm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Zmm, Zmm) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Zmm, Mem) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Xmm, Xmm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Xmm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Ymm, Ymm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Ymm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Zmm, Zmm) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Zmm, Mem) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, Xmm, Xmm, Imm, ECX, EAX, EDX) // AVX [EXPLICIT]
- ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, Xmm, Mem, Imm, ECX, EAX, EDX) // AVX [EXPLICIT]
- ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, Xmm, Xmm, Imm, XMM0, EAX, EDX)// AVX [EXPLICIT]
- ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, Xmm, Mem, Imm, XMM0, EAX, EDX)// AVX [EXPLICIT]
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Xmm, Xmm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Xmm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Ymm, Ymm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Ymm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Zmm, Zmm) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Zmm, Mem) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Xmm, Xmm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Xmm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Ymm, Ymm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Ymm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Zmm, Zmm) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Zmm, Mem) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, Xmm, Xmm, Imm, ECX) // AVX [EXPLICIT]
- ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, Xmm, Mem, Imm, ECX) // AVX [EXPLICIT]
- ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, Xmm, Xmm, Imm, XMM0) // AVX [EXPLICIT]
- ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, Xmm, Mem, Imm, XMM0) // AVX [EXPLICIT]
- ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Xmm, Xmm, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Xmm, Mem, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Ymm, Ymm, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Ymm, Mem, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Zmm, Zmm, Imm) // AVX512_F{k|b64}
- ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Zmm, Mem, Imm) // AVX512_F{k|b64}
- ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Xmm, Xmm, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Xmm, Mem, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Ymm, Ymm, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Ymm, Mem, Imm) // AVX512_BW{k}-VL
- ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Zmm, Zmm, Imm) // AVX512_BW{k}
- ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Zmm, Mem, Imm) // AVX512_BW{k}
- ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Xmm, Xmm, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Xmm, Mem, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Ymm, Ymm, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Ymm, Mem, Imm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Zmm, Zmm, Imm) // AVX512_F{k|b32}
- ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Zmm, Mem, Imm) // AVX512_F{k|b32}
- ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Xmm, Xmm, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Xmm, Mem, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Ymm, Ymm, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Ymm, Mem, Imm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Zmm, Zmm, Imm) // AVX512_F{k|b64}
- ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Zmm, Mem, Imm) // AVX512_F{k|b64}
- ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Xmm, Xmm, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Xmm, Mem, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Ymm, Ymm, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Ymm, Mem, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Zmm, Zmm, Imm) // AVX512_BW{k|b64}
- ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Zmm, Mem, Imm) // AVX512_BW{k|b64}
- ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Xmm, Xmm, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Xmm, Mem, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Ymm, Ymm, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Ymm, Mem, Imm) // AVX512_BW{k|b64}-VL
- ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Zmm, Zmm, Imm) // AVX512_BW{k|b64}
- ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Zmm, Mem, Imm) // AVX512_BW{k|b64}
- ASMJIT_INST_2x(vpcompressb, Vpcompressb, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressb, Vpcompressb, Mem, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressb, Vpcompressb, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressb, Vpcompressb, Mem, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressb, Vpcompressb, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_2x(vpcompressb, Vpcompressb, Mem, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_2x(vpcompressd, Vpcompressd, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressd, Vpcompressd, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressd, Vpcompressd, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressd, Vpcompressd, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressd, Vpcompressd, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpcompressd, Vpcompressd, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpcompressq, Vpcompressq, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressq, Vpcompressq, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressq, Vpcompressq, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressq, Vpcompressq, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpcompressq, Vpcompressq, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpcompressq, Vpcompressq, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpcompressw, Vpcompressw, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressw, Vpcompressw, Mem, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressw, Vpcompressw, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressw, Vpcompressw, Mem, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpcompressw, Vpcompressw, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_2x(vpcompressw, Vpcompressw, Mem, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_2x(vpconflictd, Vpconflictd, Xmm, Xmm) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictd, Vpconflictd, Xmm, Mem) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictd, Vpconflictd, Ymm, Ymm) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictd, Vpconflictd, Ymm, Mem) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictd, Vpconflictd, Zmm, Zmm) // AVX512_CD{kz|b32}
- ASMJIT_INST_2x(vpconflictd, Vpconflictd, Zmm, Mem) // AVX512_CD{kz|b32}
- ASMJIT_INST_2x(vpconflictq, Vpconflictq, Xmm, Xmm) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictq, Vpconflictq, Xmm, Mem) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictq, Vpconflictq, Ymm, Ymm) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictq, Vpconflictq, Ymm, Mem) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vpconflictq, Vpconflictq, Zmm, Zmm) // AVX512_CD{kz|b32}
- ASMJIT_INST_2x(vpconflictq, Vpconflictq, Zmm, Mem) // AVX512_CD{kz|b32}
- ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Xmm, Xmm, Xmm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Xmm, Xmm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Ymm, Ymm, Ymm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Ymm, Ymm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Zmm, Zmm, Zmm) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Zmm, Zmm, Mem) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Xmm, Xmm, Xmm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Xmm, Xmm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Ymm, Ymm, Ymm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Ymm, Ymm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Zmm, Zmm, Zmm) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Zmm, Zmm, Mem) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Xmm, Xmm, Xmm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Xmm, Xmm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Ymm, Ymm, Ymm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Ymm, Ymm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Zmm, Zmm, Zmm) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Zmm, Zmm, Mem) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Xmm, Xmm, Xmm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Xmm, Xmm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Ymm, Ymm, Ymm) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Ymm, Ymm, Mem) // AVX512_VNNI{kz|b32}-VL
- ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Zmm, Zmm, Zmm) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Zmm, Zmm, Mem) // AVX512_VNNI{kz|b32}
- ASMJIT_INST_4i(vperm2f128, Vperm2f128, Ymm, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_4i(vperm2f128, Vperm2f128, Ymm, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_4i(vperm2i128, Vperm2i128, Ymm, Ymm, Ymm, Imm) // AVX2
- ASMJIT_INST_4i(vperm2i128, Vperm2i128, Ymm, Ymm, Mem, Imm) // AVX2
- ASMJIT_INST_3x(vpermb, Vpermb, Xmm, Xmm, Xmm) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermb, Vpermb, Xmm, Xmm, Mem) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermb, Vpermb, Ymm, Ymm, Ymm) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermb, Vpermb, Ymm, Ymm, Mem) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermb, Vpermb, Zmm, Zmm, Zmm) // AVX512_VBMI{kz}
- ASMJIT_INST_3x(vpermb, Vpermb, Zmm, Zmm, Mem) // AVX512_VBMI{kz}
- ASMJIT_INST_3x(vpermd, Vpermd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermd, Vpermd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermd, Vpermd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermd, Vpermd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2b, Vpermi2b, Xmm, Xmm, Xmm) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermi2b, Vpermi2b, Xmm, Xmm, Mem) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermi2b, Vpermi2b, Ymm, Ymm, Ymm) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermi2b, Vpermi2b, Ymm, Ymm, Mem) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermi2b, Vpermi2b, Zmm, Zmm, Zmm) // AVX512_VBMI{kz}
- ASMJIT_INST_3x(vpermi2b, Vpermi2b, Zmm, Zmm, Mem) // AVX512_VBMI{kz}
- ASMJIT_INST_3x(vpermi2d, Vpermi2d, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2d, Vpermi2d, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2d, Vpermi2d, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2d, Vpermi2d, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2d, Vpermi2d, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermi2d, Vpermi2d, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermi2q, Vpermi2q, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2q, Vpermi2q, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2q, Vpermi2q, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2q, Vpermi2q, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermi2q, Vpermi2q, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermi2q, Vpermi2q, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermi2w, Vpermi2w, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermi2w, Vpermi2w, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermi2w, Vpermi2w, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermi2w, Vpermi2w, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermi2w, Vpermi2w, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpermi2w, Vpermi2w, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpermilpd, Vpermilpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilpd, Vpermilpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilpd, Vpermilpd, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilpd, Vpermilpd, Xmm, Mem, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilpd, Vpermilpd, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilpd, Vpermilpd, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilpd, Vpermilpd, Ymm, Ymm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilpd, Vpermilpd, Ymm, Mem, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilpd, Vpermilpd, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermilpd, Vpermilpd, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpermilpd, Vpermilpd, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpermilpd, Vpermilpd, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermilps, Vpermilps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilps, Vpermilps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilps, Vpermilps, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilps, Vpermilps, Xmm, Mem, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilps, Vpermilps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilps, Vpermilps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilps, Vpermilps, Ymm, Ymm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermilps, Vpermilps, Ymm, Mem, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermilps, Vpermilps, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermilps, Vpermilps, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpermilps, Vpermilps, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpermilps, Vpermilps, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpermpd, Vpermpd, Ymm, Ymm, Imm) // AVX2
- ASMJIT_INST_3i(vpermpd, Vpermpd, Ymm, Mem, Imm) // AVX2
- ASMJIT_INST_3x(vpermps, Vpermps, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpermps, Vpermps, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3i(vpermq, Vpermq, Ymm, Ymm, Imm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermq, Vpermq, Ymm, Mem, Imm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermq, Vpermq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermq, Vpermq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermq, Vpermq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermq, Vpermq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermq, Vpermq, Zmm, Zmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpermq, Vpermq, Zmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2b, Vpermt2b, Xmm, Xmm, Xmm) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermt2b, Vpermt2b, Xmm, Xmm, Mem) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermt2b, Vpermt2b, Ymm, Ymm, Ymm) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermt2b, Vpermt2b, Ymm, Ymm, Mem) // AVX512_VBMI{kz}-VL
- ASMJIT_INST_3x(vpermt2b, Vpermt2b, Zmm, Zmm, Zmm) // AVX512_VBMI{kz}
- ASMJIT_INST_3x(vpermt2b, Vpermt2b, Zmm, Zmm, Mem) // AVX512_VBMI{kz}
- ASMJIT_INST_3x(vpermt2d, Vpermt2d, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2d, Vpermt2d, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2d, Vpermt2d, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2d, Vpermt2d, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2d, Vpermt2d, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermt2d, Vpermt2d, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpermt2q, Vpermt2q, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2q, Vpermt2q, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2q, Vpermt2q, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2q, Vpermt2q, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpermt2q, Vpermt2q, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermt2q, Vpermt2q, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpermt2w, Vpermt2w, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermt2w, Vpermt2w, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermt2w, Vpermt2w, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermt2w, Vpermt2w, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermt2w, Vpermt2w, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpermt2w, Vpermt2w, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpermw, Vpermw, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermw, Vpermw, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermw, Vpermw, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermw, Vpermw, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpermw, Vpermw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpermw, Vpermw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpexpandb, Vpexpandb, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandb, Vpexpandb, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandb, Vpexpandb, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandb, Vpexpandb, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandb, Vpexpandb, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_2x(vpexpandb, Vpexpandb, Zmm, Mem) // AVX512_VBMI2{kz}
- ASMJIT_INST_2x(vpexpandd, Vpexpandd, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandd, Vpexpandd, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandd, Vpexpandd, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandd, Vpexpandd, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandd, Vpexpandd, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpexpandd, Vpexpandd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpexpandq, Vpexpandq, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandq, Vpexpandq, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandq, Vpexpandq, Ymm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandq, Vpexpandq, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpexpandq, Vpexpandq, Zmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpexpandq, Vpexpandq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpexpandw, Vpexpandw, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandw, Vpexpandw, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandw, Vpexpandw, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandw, Vpexpandw, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_2x(vpexpandw, Vpexpandw, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_2x(vpexpandw, Vpexpandw, Zmm, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpabsb, Vpabsb, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpabsb, Vpabsb, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpabsd, Vpabsd, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpabsd, Vpabsd, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpabsq, Vpabsq, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpabsq, Vpabsq, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpabsw, Vpabsw, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpabsw, Vpabsw, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpackssdw, Vpackssdw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz|b32}
+ ASMJIT_INST_3x(vpackssdw, Vpackssdw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz|b32}
+ ASMJIT_INST_3x(vpacksswb, Vpacksswb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpacksswb, Vpacksswb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpackusdw, Vpackusdw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz|b32}
+ ASMJIT_INST_3x(vpackusdw, Vpackusdw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz|b32}
+ ASMJIT_INST_3x(vpackuswb, Vpackuswb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpackuswb, Vpackuswb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddb, Vpaddb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddb, Vpaddb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddd, Vpaddd, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpaddd, Vpaddd, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpaddq, Vpaddq, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpaddq, Vpaddq, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpaddsb, Vpaddsb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddsb, Vpaddsb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddsw, Vpaddsw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddsw, Vpaddsw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddusb, Vpaddusb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddusb, Vpaddusb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddusw, Vpaddusw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddusw, Vpaddusw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddw, Vpaddw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpaddw, Vpaddw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_4i(vpalignr, Vpalignr, Vec, Vec, Vec, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_4i(vpalignr, Vpalignr, Vec, Vec, Mem, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpand, Vpand, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpand, Vpand, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpandd, Vpandd, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpandd, Vpandd, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpandn, Vpandn, Vec, Vec, Vec) // AV+
+ ASMJIT_INST_3x(vpandn, Vpandn, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpandnd, Vpandnd, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpandnd, Vpandnd, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpandnq, Vpandnq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpandnq, Vpandnq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpandq, Vpandq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpandq, Vpandq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpavgb, Vpavgb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpavgb, Vpavgb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpavgw, Vpavgw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpavgw, Vpavgw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_4i(vpblendd, Vpblendd, Vec, Vec, Vec, Imm) // AVX2
+ ASMJIT_INST_4i(vpblendd, Vpblendd, Vec, Vec, Mem, Imm) // AVX2
+ ASMJIT_INST_4x(vpblendvb, Vpblendvb, Vec, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_4x(vpblendvb, Vpblendvb, Vec, Vec, Mem, Vec) // AVX+
+ ASMJIT_INST_4i(vpblendw, Vpblendw, Vec, Vec, Vec, Imm) // AVX+
+ ASMJIT_INST_4i(vpblendw, Vpblendw, Vec, Vec, Mem, Imm) // AVX+
+ ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Vec, Vec) // AVX2 AVX512_BW{kz}
+ ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Vec, Mem) // AVX2 AVX512_BW{kz}
+ ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, Vec, Gp) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Vec, Vec) // AVX2 AVX512_F{kz}
+ ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Vec, Mem) // AVX2 AVX512_F{kz}
+ ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, Vec, Gp) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, Vec, KReg) // AVX512_CD
+ ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, Vec, KReg) // AVX512_CD
+ ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Vec, Vec) // AVX2 AVX512_F{kz}
+ ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Vec, Mem) // AVX2 AVX512_F{kz}
+ ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, Vec, Gp) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Vec, Vec) // AVX2 AVX512_BW{kz}
+ ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Vec, Mem) // AVX2 AVX512_BW{kz}
+ ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, Vec, Gp) // AVX512_BW{kz}
+ ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Vec, Vec, Vec, Imm) // AVX VPCLMULQDQ AVX512_F
+ ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, Vec, Vec, Mem, Imm) // AVX VPCLMULQDQ AVX512_F
+ ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Vec, Vec, Imm) // AVX512_BW{k}
+ ASMJIT_INST_4i(vpcmpb, Vpcmpb, KReg, Vec, Mem, Imm) // AVX512_BW{k}
+ ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Vec, Vec, Imm) // AVX512_F{k|b32}
+ ASMJIT_INST_4i(vpcmpd, Vpcmpd, KReg, Vec, Mem, Imm) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Vec, Vec) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, KReg, Vec, Mem) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Vec, Vec) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, KReg, Vec, Mem) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, Vec, Vec, Imm, ECX, EAX, EDX) // AVX [EXPLICIT]
+ ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, Vec, Mem, Imm, ECX, EAX, EDX) // AVX [EXPLICIT]
+ ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, Vec, Vec, Imm, XMM0, EAX, EDX)// AVX [EXPLICIT]
+ ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, Vec, Mem, Imm, XMM0, EAX, EDX)// AVX [EXPLICIT]
+ ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Vec, Vec) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, KReg, Vec, Mem) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Vec, Vec) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, KReg, Vec, Mem) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, Vec, Vec, Imm, ECX) // AVX [EXPLICIT]
+ ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, Vec, Mem, Imm, ECX) // AVX [EXPLICIT]
+ ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, Vec, Vec, Imm, XMM0) // AVX [EXPLICIT]
+ ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, Vec, Mem, Imm, XMM0) // AVX [EXPLICIT]
+ ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Vec, Vec, Imm) // AVX512_F{k|b64}
+ ASMJIT_INST_4i(vpcmpq, Vpcmpq, KReg, Vec, Mem, Imm) // AVX512_F{k|b64}
+ ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Vec, Vec, Imm) // AVX512_BW{k}
+ ASMJIT_INST_4i(vpcmpub, Vpcmpub, KReg, Vec, Mem, Imm) // AVX512_BW{k}
+ ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Vec, Vec, Imm) // AVX512_F{k|b32}
+ ASMJIT_INST_4i(vpcmpud, Vpcmpud, KReg, Vec, Mem, Imm) // AVX512_F{k|b32}
+ ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Vec, Vec, Imm) // AVX512_F{k|b64}
+ ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, KReg, Vec, Mem, Imm) // AVX512_F{k|b64}
+ ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Vec, Vec, Imm) // AVX512_BW{k|b64}
+ ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, KReg, Vec, Mem, Imm) // AVX512_BW{k|b64}
+ ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Vec, Vec, Imm) // AVX512_BW{k|b64}
+ ASMJIT_INST_4i(vpcmpw, Vpcmpw, KReg, Vec, Mem, Imm) // AVX512_BW{k|b64}
+ ASMJIT_INST_2x(vpcompressb, Vpcompressb, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpcompressb, Vpcompressb, Mem, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpcompressd, Vpcompressd, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpcompressd, Vpcompressd, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpcompressq, Vpcompressq, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpcompressq, Vpcompressq, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpcompressw, Vpcompressw, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpcompressw, Vpcompressw, Mem, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpconflictd, Vpconflictd, Vec, Vec) // AVX512_CD{kz|b32}
+ ASMJIT_INST_2x(vpconflictd, Vpconflictd, Vec, Mem) // AVX512_CD{kz|b32}
+ ASMJIT_INST_2x(vpconflictq, Vpconflictq, Vec, Vec) // AVX512_CD{kz|b32}
+ ASMJIT_INST_2x(vpconflictq, Vpconflictq, Vec, Mem) // AVX512_CD{kz|b32}
+ ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Vec, Vec, Vec) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_3x(vpdpbusd, Vpdpbusd, Vec, Vec, Mem) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Vec, Vec, Vec) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_3x(vpdpbusds, Vpdpbusds, Vec, Vec, Mem) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Vec, Vec, Vec) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_3x(vpdpwssd, Vpdpwssd, Vec, Vec, Mem) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Vec, Vec, Vec) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_3x(vpdpwssds, Vpdpwssds, Vec, Vec, Mem) // AVX512_VNNI{kz|b32}
+ ASMJIT_INST_4i(vperm2f128, Vperm2f128, Vec, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_4i(vperm2f128, Vperm2f128, Vec, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_4i(vperm2i128, Vperm2i128, Vec, Vec, Vec, Imm) // AVX2
+ ASMJIT_INST_4i(vperm2i128, Vperm2i128, Vec, Vec, Mem, Imm) // AVX2
+ ASMJIT_INST_3x(vpermb, Vpermb, Vec, Vec, Vec) // AVX512_VBMI{kz}
+ ASMJIT_INST_3x(vpermb, Vpermb, Vec, Vec, Mem) // AVX512_VBMI{kz}
+ ASMJIT_INST_3x(vpermd, Vpermd, Vec, Vec, Vec) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermd, Vpermd, Vec, Vec, Mem) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermi2b, Vpermi2b, Vec, Vec, Vec) // AVX512_VBMI{kz}
+ ASMJIT_INST_3x(vpermi2b, Vpermi2b, Vec, Vec, Mem) // AVX512_VBMI{kz}
+ ASMJIT_INST_3x(vpermi2d, Vpermi2d, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermi2d, Vpermi2d, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermi2q, Vpermi2q, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermi2q, Vpermi2q, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermi2w, Vpermi2w, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpermi2w, Vpermi2w, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpermilpd, Vpermilpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermilpd, Vpermilpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vpermilpd, Vpermilpd, Vec, Vec, Imm) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vpermilpd, Vpermilpd, Vec, Mem, Imm) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermilps, Vpermilps, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermilps, Vpermilps, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vpermilps, Vpermilps, Vec, Vec, Imm) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vpermilps, Vpermilps, Vec, Mem, Imm) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vpermpd, Vpermpd, Vec, Vec, Imm) // AVX2
+ ASMJIT_INST_3i(vpermpd, Vpermpd, Vec, Mem, Imm) // AVX2
+ ASMJIT_INST_3x(vpermps, Vpermps, Vec, Vec, Vec) // AVX2
+ ASMJIT_INST_3x(vpermps, Vpermps, Vec, Vec, Mem) // AVX2
+ ASMJIT_INST_3i(vpermq, Vpermq, Vec, Vec, Imm) // AVX2 AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vpermq, Vpermq, Vec, Mem, Imm) // AVX2 AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermq, Vpermq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermq, Vpermq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermt2b, Vpermt2b, Vec, Vec, Vec) // AVX512_VBMI{kz}
+ ASMJIT_INST_3x(vpermt2b, Vpermt2b, Vec, Vec, Mem) // AVX512_VBMI{kz}
+ ASMJIT_INST_3x(vpermt2d, Vpermt2d, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermt2d, Vpermt2d, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpermt2q, Vpermt2q, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermt2q, Vpermt2q, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpermt2w, Vpermt2w, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpermt2w, Vpermt2w, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpermw, Vpermw, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpermw, Vpermw, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpexpandb, Vpexpandb, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpexpandb, Vpexpandb, Vec, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpexpandd, Vpexpandd, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpexpandd, Vpexpandd, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpexpandq, Vpexpandq, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpexpandq, Vpexpandq, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpexpandw, Vpexpandw, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_2x(vpexpandw, Vpexpandw, Vec, Mem) // AVX512_VBMI2{kz}
ASMJIT_INST_3i(vpextrb, Vpextrb, Gp, Xmm, Imm) // AVX AVX512_BW
ASMJIT_INST_3i(vpextrb, Vpextrb, Mem, Xmm, Imm) // AVX AVX512_BW
ASMJIT_INST_3i(vpextrd, Vpextrd, Gp, Xmm, Imm) // AVX AVX512_DQ
@@ -3742,51 +2808,28 @@ public:
ASMJIT_INST_3i(vpextrq, Vpextrq, Mem, Xmm, Imm) // AVX AVX512_DQ
ASMJIT_INST_3i(vpextrw, Vpextrw, Gp, Xmm, Imm) // AVX AVX512_BW
ASMJIT_INST_3i(vpextrw, Vpextrw, Mem, Xmm, Imm) // AVX AVX512_BW
- ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, Ymm, Mem, Ymm) // AVX2
- ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, Zmm, Mem) // AVX512_F{k}
- ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, Ymm, Mem, Ymm) // AVX2
- ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, Zmm, Mem) // AVX512_F{k}
- ASMJIT_INST_3x(vpgatherqd, Vpgatherqd, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, Zmm, Mem) // AVX512_F{k}
- ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, Xmm, Mem, Xmm) // AVX2
- ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, Ymm, Mem, Ymm) // AVX2
- ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, Xmm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, Ymm, Mem) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, Zmm, Mem) // AVX512_F{k}
- ASMJIT_INST_3x(vphaddd, Vphaddd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vphaddd, Vphaddd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vphaddd, Vphaddd, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vphaddd, Vphaddd, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vphaddsw, Vphaddsw, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vphaddsw, Vphaddsw, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vphaddsw, Vphaddsw, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vphaddsw, Vphaddsw, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vphaddw, Vphaddw, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vphaddw, Vphaddw, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vphaddw, Vphaddw, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vphaddw, Vphaddw, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_2x(vphminposuw, Vphminposuw, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vphminposuw, Vphminposuw, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vphsubd, Vphsubd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vphsubd, Vphsubd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vphsubd, Vphsubd, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vphsubd, Vphsubd, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vphsubsw, Vphsubsw, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vphsubsw, Vphsubsw, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vphsubsw, Vphsubsw, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vphsubsw, Vphsubsw, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vphsubw, Vphsubw, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vphsubw, Vphsubw, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vphsubw, Vphsubw, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vphsubw, Vphsubw, Ymm, Ymm, Mem) // AVX2
+ ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, Vec, Mem, Vec) // AVX2
+ ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, Vec, Mem, Vec) // AVX2
+ ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vpgatherqd, Vpgatherqd, Vec, Mem, Vec) // AVX2
+ ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, Vec, Mem) // AVX512_F{k}
+ ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, Vec, Mem, Vec) // AVX2
+ ASMJIT_INST_3x(vphaddd, Vphaddd, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vphaddd, Vphaddd, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vphaddsw, Vphaddsw, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vphaddsw, Vphaddsw, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vphaddw, Vphaddw, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vphaddw, Vphaddw, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_2x(vphminposuw, Vphminposuw, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vphminposuw, Vphminposuw, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vphsubd, Vphsubd, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vphsubd, Vphsubd, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vphsubsw, Vphsubsw, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vphsubsw, Vphsubsw, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vphsubw, Vphsubw, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vphsubw, Vphsubw, Vec, Vec, Mem) // AVX+
ASMJIT_INST_4i(vpinsrb, Vpinsrb, Xmm, Xmm, Gp, Imm) // AVX AVX512_BW{kz}
ASMJIT_INST_4i(vpinsrb, Vpinsrb, Xmm, Xmm, Mem, Imm) // AVX AVX512_BW{kz}
ASMJIT_INST_4i(vpinsrd, Vpinsrd, Xmm, Xmm, Gp, Imm) // AVX AVX512_DQ{kz}
@@ -3795,1099 +2838,411 @@ public:
ASMJIT_INST_4i(vpinsrq, Vpinsrq, Xmm, Xmm, Mem, Imm) // AVX AVX512_DQ{kz}
ASMJIT_INST_4i(vpinsrw, Vpinsrw, Xmm, Xmm, Gp, Imm) // AVX AVX512_BW{kz}
ASMJIT_INST_4i(vpinsrw, Vpinsrw, Xmm, Xmm, Mem, Imm) // AVX AVX512_BW{kz}
- ASMJIT_INST_2x(vplzcntd, Vplzcntd, Xmm, Xmm) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vplzcntd, Vplzcntd, Xmm, Mem) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vplzcntd, Vplzcntd, Ymm, Ymm) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vplzcntd, Vplzcntd, Ymm, Mem) // AVX512_CD{kz|b32}-VL
- ASMJIT_INST_2x(vplzcntd, Vplzcntd, Zmm, Zmm) // AVX512_CD{kz|b32}
- ASMJIT_INST_2x(vplzcntd, Vplzcntd, Zmm, Mem) // AVX512_CD{kz|b32}
- ASMJIT_INST_2x(vplzcntq, Vplzcntq, Xmm, Xmm) // AVX512_CD{kz|b64}-VL
- ASMJIT_INST_2x(vplzcntq, Vplzcntq, Xmm, Mem) // AVX512_CD{kz|b64}-VL
- ASMJIT_INST_2x(vplzcntq, Vplzcntq, Ymm, Ymm) // AVX512_CD{kz|b64}-VL
- ASMJIT_INST_2x(vplzcntq, Vplzcntq, Ymm, Mem) // AVX512_CD{kz|b64}-VL
- ASMJIT_INST_2x(vplzcntq, Vplzcntq, Zmm, Zmm) // AVX512_CD{kz|b64}
- ASMJIT_INST_2x(vplzcntq, Vplzcntq, Zmm, Mem) // AVX512_CD{kz|b64}
- ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Xmm, Xmm, Xmm) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Xmm, Xmm, Mem) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Ymm, Ymm, Ymm) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Ymm, Ymm, Mem) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Zmm, Zmm, Zmm) // AVX512_IFMA{kz|b64}
- ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Zmm, Zmm, Mem) // AVX512_IFMA{kz|b64}
- ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Xmm, Xmm, Xmm) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Xmm, Xmm, Mem) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Ymm, Ymm, Ymm) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Ymm, Ymm, Mem) // AVX512_IFMA{kz|b64}-VL
- ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Zmm, Zmm, Zmm) // AVX512_IFMA{kz|b64}
- ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Zmm, Zmm, Mem) // AVX512_IFMA{kz|b64}
- ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, Mem, Xmm, Xmm) // AVX2
- ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, Mem, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, Xmm, Xmm, Mem) // AVX2
- ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, Mem, Xmm, Xmm) // AVX2
- ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, Mem, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, Xmm, Xmm, Mem) // AVX2
- ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaxub, Vpmaxub, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxub, Vpmaxub, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxub, Vpmaxub, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxub, Vpmaxub, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxub, Vpmaxub, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaxub, Vpmaxub, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaxud, Vpmaxud, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxud, Vpmaxud, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxud, Vpmaxud, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxud, Vpmaxud, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmaxud, Vpmaxud, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpmaxud, Vpmaxud, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminsb, Vpminsb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsb, Vpminsb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsb, Vpminsb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsb, Vpminsb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsb, Vpminsb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminsb, Vpminsb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminsd, Vpminsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminsd, Vpminsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminsd, Vpminsd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminsd, Vpminsd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminsd, Vpminsd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpminsd, Vpminsd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpminsq, Vpminsq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminsq, Vpminsq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminsq, Vpminsq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminsq, Vpminsq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminsq, Vpminsq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpminsq, Vpminsq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpminsw, Vpminsw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsw, Vpminsw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsw, Vpminsw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsw, Vpminsw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminsw, Vpminsw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminsw, Vpminsw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminub, Vpminub, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminub, Vpminub, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminub, Vpminub, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminub, Vpminub, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminub, Vpminub, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminub, Vpminub, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminud, Vpminud, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminud, Vpminud, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminud, Vpminud, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminud, Vpminud, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpminud, Vpminud, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpminud, Vpminud, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpminuq, Vpminuq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminuq, Vpminuq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminuq, Vpminuq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminuq, Vpminuq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpminuq, Vpminuq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpminuq, Vpminuq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpminuw, Vpminuw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminuw, Vpminuw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminuw, Vpminuw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminuw, Vpminuw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpminuw, Vpminuw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpminuw, Vpminuw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, KReg, Xmm) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, KReg, Ymm) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, KReg, Zmm) // AVX512_BW
- ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, KReg, Xmm) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, KReg, Ymm) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, KReg, Zmm) // AVX512_DQ
- ASMJIT_INST_2x(vpmovdb, Vpmovdb, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdb, Vpmovdb, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdb, Vpmovdb, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdb, Vpmovdb, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdb, Vpmovdb, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovdb, Vpmovdb, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovdw, Vpmovdw, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdw, Vpmovdw, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdw, Vpmovdw, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdw, Vpmovdw, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovdw, Vpmovdw, Ymm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovdw, Vpmovdw, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, Xmm, KReg) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, Ymm, KReg) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, Zmm, KReg) // AVX512_BW
- ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, Xmm, KReg) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, Ymm, KReg) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, Zmm, KReg) // AVX512_DQ
- ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, Xmm, KReg) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, Ymm, KReg) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, Zmm, KReg) // AVX512_DQ
- ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, Xmm, KReg) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, Ymm, KReg) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, Zmm, KReg) // AVX512_BW
- ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, Gp, Xmm) // AVX
- ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, Gp, Ymm) // AVX2
- ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, KReg, Xmm) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, KReg, Ymm) // AVX512_DQ-VL
- ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, KReg, Zmm) // AVX512_DQ
- ASMJIT_INST_2x(vpmovqb, Vpmovqb, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqb, Vpmovqb, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqb, Vpmovqb, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqb, Vpmovqb, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqb, Vpmovqb, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovqb, Vpmovqb, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovqd, Vpmovqd, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqd, Vpmovqd, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqd, Vpmovqd, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqd, Vpmovqd, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqd, Vpmovqd, Ymm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovqd, Vpmovqd, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovqw, Vpmovqw, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqw, Vpmovqw, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqw, Vpmovqw, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqw, Vpmovqw, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovqw, Vpmovqw, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovqw, Vpmovqw, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Ymm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Ymm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovswb, Vpmovswb, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovswb, Vpmovswb, Mem, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovswb, Vpmovswb, Xmm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovswb, Vpmovswb, Mem, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovswb, Vpmovswb, Ymm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovswb, Vpmovswb, Mem, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Ymm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Zmm, Ymm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Zmm, Ymm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Zmm, Ymm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Ymm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Ymm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Mem, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Xmm, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Mem, Ymm) // AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Xmm, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Mem, Zmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Mem, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Xmm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Mem, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Ymm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Mem, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, KReg, Xmm) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, KReg, Ymm) // AVX512_BW-VL
- ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, KReg, Zmm) // AVX512_BW
- ASMJIT_INST_2x(vpmovwb, Vpmovwb, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovwb, Vpmovwb, Mem, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovwb, Vpmovwb, Xmm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovwb, Vpmovwb, Mem, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovwb, Vpmovwb, Ymm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovwb, Vpmovwb, Mem, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Ymm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Zmm, Ymm) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Zmm, Ymm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Zmm, Ymm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3x(vpmuldq, Vpmuldq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuldq, Vpmuldq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuldq, Vpmuldq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuldq, Vpmuldq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuldq, Vpmuldq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpmuldq, Vpmuldq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmulhw, Vpmulhw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhw, Vpmulhw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhw, Vpmulhw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhw, Vpmulhw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmulhw, Vpmulhw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmulhw, Vpmulhw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmulld, Vpmulld, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmulld, Vpmulld, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmulld, Vpmulld, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmulld, Vpmulld, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpmulld, Vpmulld, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpmulld, Vpmulld, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpmullq, Vpmullq, Xmm, Xmm, Xmm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vpmullq, Vpmullq, Xmm, Xmm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vpmullq, Vpmullq, Ymm, Ymm, Ymm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vpmullq, Vpmullq, Ymm, Ymm, Mem) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vpmullq, Vpmullq, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vpmullq, Vpmullq, Zmm, Zmm, Mem) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vpmullw, Vpmullw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmullw, Vpmullw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmullw, Vpmullw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmullw, Vpmullw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpmullw, Vpmullw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmullw, Vpmullw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Xmm, Xmm, Xmm) // AVX512_VBMI{kz|b64}-VL
- ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Xmm, Xmm, Mem) // AVX512_VBMI{kz|b64}-VL
- ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Ymm, Ymm, Ymm) // AVX512_VBMI{kz|b64}-VL
- ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Ymm, Ymm, Mem) // AVX512_VBMI{kz|b64}-VL
- ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Zmm, Zmm, Zmm) // AVX512_VBMI{kz|b64}
- ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Zmm, Zmm, Mem) // AVX512_VBMI{kz|b64}
- ASMJIT_INST_3x(vpmuludq, Vpmuludq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuludq, Vpmuludq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuludq, Vpmuludq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuludq, Vpmuludq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpmuludq, Vpmuludq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpmuludq, Vpmuludq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_2x(vpopcntb, Vpopcntb, Xmm, Xmm) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntb, Vpopcntb, Xmm, Mem) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntb, Vpopcntb, Ymm, Ymm) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntb, Vpopcntb, Ymm, Mem) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntb, Vpopcntb, Zmm, Zmm) // AVX512_BITALG{kz|b32}
- ASMJIT_INST_2x(vpopcntb, Vpopcntb, Zmm, Mem) // AVX512_BITALG{kz|b32}
- ASMJIT_INST_2x(vpopcntd, Vpopcntd, Xmm, Xmm) // AVX512_VPOPCNTDQ{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntd, Vpopcntd, Xmm, Mem) // AVX512_VPOPCNTDQ{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntd, Vpopcntd, Ymm, Ymm) // AVX512_VPOPCNTDQ{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntd, Vpopcntd, Ymm, Mem) // AVX512_VPOPCNTDQ{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntd, Vpopcntd, Zmm, Zmm) // AVX512_VPOPCNTDQ{kz|b32}
- ASMJIT_INST_2x(vpopcntd, Vpopcntd, Zmm, Mem) // AVX512_VPOPCNTDQ{kz|b32}
- ASMJIT_INST_2x(vpopcntq, Vpopcntq, Xmm, Xmm) // AVX512_VPOPCNTDQ{kz|b64}-VL
- ASMJIT_INST_2x(vpopcntq, Vpopcntq, Xmm, Mem) // AVX512_VPOPCNTDQ{kz|b64}-VL
- ASMJIT_INST_2x(vpopcntq, Vpopcntq, Ymm, Ymm) // AVX512_VPOPCNTDQ{kz|b64}-VL
- ASMJIT_INST_2x(vpopcntq, Vpopcntq, Ymm, Mem) // AVX512_VPOPCNTDQ{kz|b64}-VL
- ASMJIT_INST_2x(vpopcntq, Vpopcntq, Zmm, Zmm) // AVX512_VPOPCNTDQ{kz|b64}
- ASMJIT_INST_2x(vpopcntq, Vpopcntq, Zmm, Mem) // AVX512_VPOPCNTDQ{kz|b64}
- ASMJIT_INST_2x(vpopcntw, Vpopcntw, Xmm, Xmm) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntw, Vpopcntw, Xmm, Mem) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntw, Vpopcntw, Ymm, Ymm) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntw, Vpopcntw, Ymm, Mem) // AVX512_BITALG{kz|b32}-VL
- ASMJIT_INST_2x(vpopcntw, Vpopcntw, Zmm, Zmm) // AVX512_BITALG{kz|b32}
- ASMJIT_INST_2x(vpopcntw, Vpopcntw, Zmm, Mem) // AVX512_BITALG{kz|b32}
- ASMJIT_INST_3x(vpor, Vpor, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpor, Vpor, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpor, Vpor, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpor, Vpor, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpord, Vpord, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpord, Vpord, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpord, Vpord, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpord, Vpord, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpord, Vpord, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpord, Vpord, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vporq, Vporq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vporq, Vporq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vporq, Vporq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vporq, Vporq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vporq, Vporq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vporq, Vporq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vprold, Vprold, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprold, Vprold, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprold, Vprold, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprold, Vprold, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprold, Vprold, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vprold, Vprold, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vprolq, Vprolq, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprolq, Vprolq, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprolq, Vprolq, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprolq, Vprolq, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprolq, Vprolq, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vprolq, Vprolq, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vprolvd, Vprolvd, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprolvd, Vprolvd, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprolvd, Vprolvd, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprolvd, Vprolvd, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprolvd, Vprolvd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vprolvd, Vprolvd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vprolvq, Vprolvq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprolvq, Vprolvq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprolvq, Vprolvq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprolvq, Vprolvq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprolvq, Vprolvq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vprolvq, Vprolvq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vprord, Vprord, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprord, Vprord, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprord, Vprord, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprord, Vprord, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vprord, Vprord, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vprord, Vprord, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vprorq, Vprorq, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprorq, Vprorq, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprorq, Vprorq, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprorq, Vprorq, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vprorq, Vprorq, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vprorq, Vprorq, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vprorvd, Vprorvd, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprorvd, Vprorvd, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprorvd, Vprorvd, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprorvd, Vprorvd, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vprorvd, Vprorvd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vprorvd, Vprorvd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vprorvq, Vprorvq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprorvq, Vprorvq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprorvq, Vprorvq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprorvq, Vprorvq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vprorvq, Vprorvq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vprorvq, Vprorvq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsadbw, Vpsadbw, Xmm, Xmm, Xmm) // AVX AVX512_BW-VL
- ASMJIT_INST_3x(vpsadbw, Vpsadbw, Xmm, Xmm, Mem) // AVX AVX512_BW-VL
- ASMJIT_INST_3x(vpsadbw, Vpsadbw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW-VL
- ASMJIT_INST_3x(vpsadbw, Vpsadbw, Ymm, Ymm, Mem) // AVX2 AVX512_BW-VL
- ASMJIT_INST_3x(vpsadbw, Vpsadbw, Zmm, Zmm, Zmm) // AVX512_BW
- ASMJIT_INST_3x(vpsadbw, Vpsadbw, Zmm, Zmm, Mem) // AVX512_BW
- ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, Mem, Ymm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, Mem, Zmm) // AVX512_F{k}
- ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, Mem, Ymm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, Mem, Zmm) // AVX512_F{k}
- ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, Mem, Ymm) // AVX512_F{k}
- ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, Mem, Ymm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, Mem, Zmm) // AVX512_F{k}
- ASMJIT_INST_4i(vpshldd, Vpshldd, Xmm, Xmm, Xmm, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshldd, Vpshldd, Xmm, Xmm, Mem, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshldd, Vpshldd, Ymm, Ymm, Ymm, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshldd, Vpshldd, Ymm, Ymm, Mem, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshldd, Vpshldd, Zmm, Zmm, Zmm, Imm) // AVX512_VBMI2{kz}
- ASMJIT_INST_4i(vpshldd, Vpshldd, Zmm, Zmm, Mem, Imm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshldvd, Vpshldvd, Xmm, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvd, Vpshldvd, Xmm, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvd, Vpshldvd, Ymm, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvd, Vpshldvd, Ymm, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvd, Vpshldvd, Zmm, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshldvd, Vpshldvd, Zmm, Zmm, Mem) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshldvq, Vpshldvq, Xmm, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvq, Vpshldvq, Xmm, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvq, Vpshldvq, Ymm, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvq, Vpshldvq, Ymm, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvq, Vpshldvq, Zmm, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshldvq, Vpshldvq, Zmm, Zmm, Mem) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshldvw, Vpshldvw, Xmm, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvw, Vpshldvw, Xmm, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvw, Vpshldvw, Ymm, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvw, Vpshldvw, Ymm, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshldvw, Vpshldvw, Zmm, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshldvw, Vpshldvw, Zmm, Zmm, Mem) // AVX512_VBMI2{kz}
- ASMJIT_INST_4i(vpshrdd, Vpshrdd, Xmm, Xmm, Xmm, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdd, Vpshrdd, Xmm, Xmm, Mem, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdd, Vpshrdd, Ymm, Ymm, Ymm, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdd, Vpshrdd, Ymm, Ymm, Mem, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdd, Vpshrdd, Zmm, Zmm, Zmm, Imm) // AVX512_VBMI2{kz}
- ASMJIT_INST_4i(vpshrdd, Vpshrdd, Zmm, Zmm, Mem, Imm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Xmm, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Xmm, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Ymm, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Ymm, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Zmm, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Zmm, Zmm, Mem) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Xmm, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Xmm, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Ymm, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Ymm, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Zmm, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Zmm, Zmm, Mem) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Xmm, Xmm, Xmm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Xmm, Xmm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Ymm, Ymm, Ymm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Ymm, Ymm, Mem) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Zmm, Zmm, Zmm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Zmm, Zmm, Mem) // AVX512_VBMI2{kz}
- ASMJIT_INST_4i(vpshrdw, Vpshrdw, Xmm, Xmm, Xmm, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdw, Vpshrdw, Xmm, Xmm, Mem, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdw, Vpshrdw, Ymm, Ymm, Ymm, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdw, Vpshrdw, Ymm, Ymm, Mem, Imm) // AVX512_VBMI2{kz}-VL
- ASMJIT_INST_4i(vpshrdw, Vpshrdw, Zmm, Zmm, Zmm, Imm) // AVX512_VBMI2{kz}
- ASMJIT_INST_4i(vpshrdw, Vpshrdw, Zmm, Zmm, Mem, Imm) // AVX512_VBMI2{kz}
- ASMJIT_INST_3x(vpshufb, Vpshufb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpshufb, Vpshufb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpshufb, Vpshufb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpshufb, Vpshufb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpshufb, Vpshufb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpshufb, Vpshufb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Xmm, Xmm) // AVX512_BITALG{k}-VL
- ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Xmm, Mem) // AVX512_BITALG{k}-VL
- ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Ymm, Ymm) // AVX512_BITALG{k}-VL
- ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Ymm, Mem) // AVX512_BITALG{k}-VL
- ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Zmm, Zmm) // AVX512_BITALG{k}
- ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Zmm, Mem) // AVX512_BITALG{k}
- ASMJIT_INST_3i(vpshufd, Vpshufd, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vpshufd, Vpshufd, Xmm, Mem, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vpshufd, Vpshufd, Ymm, Ymm, Imm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vpshufd, Vpshufd, Ymm, Mem, Imm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vpshufd, Vpshufd, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vpshufd, Vpshufd, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vpshufhw, Vpshufhw, Xmm, Xmm, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshufhw, Vpshufhw, Xmm, Mem, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshufhw, Vpshufhw, Ymm, Ymm, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshufhw, Vpshufhw, Ymm, Mem, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshufhw, Vpshufhw, Zmm, Zmm, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpshufhw, Vpshufhw, Zmm, Mem, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpshuflw, Vpshuflw, Xmm, Xmm, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshuflw, Vpshuflw, Xmm, Mem, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshuflw, Vpshuflw, Ymm, Ymm, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshuflw, Vpshuflw, Ymm, Mem, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpshuflw, Vpshuflw, Zmm, Zmm, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpshuflw, Vpshuflw, Zmm, Mem, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsignb, Vpsignb, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpsignb, Vpsignb, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpsignb, Vpsignb, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpsignb, Vpsignb, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpsignd, Vpsignd, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpsignd, Vpsignd, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpsignd, Vpsignd, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpsignd, Vpsignd, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpsignw, Vpsignw, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpsignw, Vpsignw, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpsignw, Vpsignw, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpsignw, Vpsignw, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3i(vpslld, Vpslld, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpslld, Vpslld, Xmm, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpslld, Vpslld, Xmm, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpslld, Vpslld, Ymm, Ymm, Imm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpslld, Vpslld, Ymm, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpslld, Vpslld, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpslld, Vpslld, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vpslld, Vpslld, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpslld, Vpslld, Zmm, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_3x(vpslld, Vpslld, Zmm, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3i(vpslld, Vpslld, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vpslld, Vpslld, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vpslldq, Vpslldq, Xmm, Xmm, Imm) // AVX AVX512_BW-VL
- ASMJIT_INST_3i(vpslldq, Vpslldq, Ymm, Ymm, Imm) // AVX2 AVX512_BW-VL
- ASMJIT_INST_3i(vpslldq, Vpslldq, Xmm, Mem, Imm) // AVX512_BW-VL
- ASMJIT_INST_3i(vpslldq, Vpslldq, Ymm, Mem, Imm) // AVX512_BW-VL
- ASMJIT_INST_3i(vpslldq, Vpslldq, Zmm, Zmm, Imm) // AVX512_BW
- ASMJIT_INST_3i(vpslldq, Vpslldq, Zmm, Mem, Imm) // AVX512_BW
- ASMJIT_INST_3i(vpsllq, Vpsllq, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsllq, Vpsllq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsllq, Vpsllq, Xmm, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsllq, Vpsllq, Ymm, Ymm, Imm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsllq, Vpsllq, Ymm, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsllq, Vpsllq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsllq, Vpsllq, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpsllq, Vpsllq, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsllq, Vpsllq, Zmm, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_3x(vpsllq, Vpsllq, Zmm, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3i(vpsllq, Vpsllq, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpsllq, Vpsllq, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsllvd, Vpsllvd, Xmm, Xmm, Xmm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsllvd, Vpsllvd, Xmm, Xmm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsllvd, Vpsllvd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsllvd, Vpsllvd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsllvd, Vpsllvd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsllvd, Vpsllvd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsllvq, Vpsllvq, Xmm, Xmm, Xmm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsllvq, Vpsllvq, Xmm, Xmm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsllvq, Vpsllvq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsllvq, Vpsllvq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsllvq, Vpsllvq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsllvq, Vpsllvq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsllvw, Vpsllvw, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllvw, Vpsllvw, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllvw, Vpsllvw, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllvw, Vpsllvw, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllvw, Vpsllvw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsllvw, Vpsllvw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsllw, Vpsllw, Xmm, Xmm, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllw, Vpsllw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllw, Vpsllw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsllw, Vpsllw, Ymm, Ymm, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllw, Vpsllw, Ymm, Ymm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllw, Vpsllw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsllw, Vpsllw, Xmm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsllw, Vpsllw, Ymm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsllw, Vpsllw, Zmm, Zmm, Xmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsllw, Vpsllw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsllw, Vpsllw, Zmm, Zmm, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsllw, Vpsllw, Zmm, Mem, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsrad, Vpsrad, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrad, Vpsrad, Xmm, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsrad, Vpsrad, Xmm, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsrad, Vpsrad, Ymm, Ymm, Imm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrad, Vpsrad, Ymm, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsrad, Vpsrad, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsrad, Vpsrad, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vpsrad, Vpsrad, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrad, Vpsrad, Zmm, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_3x(vpsrad, Vpsrad, Zmm, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3i(vpsrad, Vpsrad, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vpsrad, Vpsrad, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsraq, Vpsraq, Xmm, Xmm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsraq, Vpsraq, Xmm, Xmm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsraq, Vpsraq, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpsraq, Vpsraq, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsraq, Vpsraq, Ymm, Ymm, Xmm) // AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsraq, Vpsraq, Ymm, Ymm, Mem) // AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsraq, Vpsraq, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpsraq, Vpsraq, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsraq, Vpsraq, Zmm, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_3x(vpsraq, Vpsraq, Zmm, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3i(vpsraq, Vpsraq, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpsraq, Vpsraq, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsravd, Vpsravd, Xmm, Xmm, Xmm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsravd, Vpsravd, Xmm, Xmm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsravd, Vpsravd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsravd, Vpsravd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsravd, Vpsravd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsravd, Vpsravd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsravq, Vpsravq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsravq, Vpsravq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsravq, Vpsravq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsravq, Vpsravq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsravq, Vpsravq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsravq, Vpsravq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsravw, Vpsravw, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsravw, Vpsravw, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsravw, Vpsravw, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsravw, Vpsravw, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsravw, Vpsravw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsravw, Vpsravw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsraw, Vpsraw, Xmm, Xmm, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsraw, Vpsraw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsraw, Vpsraw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsraw, Vpsraw, Ymm, Ymm, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsraw, Vpsraw, Ymm, Ymm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsraw, Vpsraw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsraw, Vpsraw, Xmm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsraw, Vpsraw, Ymm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsraw, Vpsraw, Zmm, Zmm, Xmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsraw, Vpsraw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsraw, Vpsraw, Zmm, Zmm, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsraw, Vpsraw, Zmm, Mem, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsrld, Vpsrld, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrld, Vpsrld, Xmm, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsrld, Vpsrld, Xmm, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsrld, Vpsrld, Ymm, Ymm, Imm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrld, Vpsrld, Ymm, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsrld, Vpsrld, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsrld, Vpsrld, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vpsrld, Vpsrld, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrld, Vpsrld, Zmm, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_3x(vpsrld, Vpsrld, Zmm, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3i(vpsrld, Vpsrld, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vpsrld, Vpsrld, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_3i(vpsrldq, Vpsrldq, Xmm, Xmm, Imm) // AVX AVX512_BW-VL
- ASMJIT_INST_3i(vpsrldq, Vpsrldq, Ymm, Ymm, Imm) // AVX2 AVX512_BW-VL
- ASMJIT_INST_3i(vpsrldq, Vpsrldq, Xmm, Mem, Imm) // AVX512_BW-VL
- ASMJIT_INST_3i(vpsrldq, Vpsrldq, Ymm, Mem, Imm) // AVX512_BW-VL
- ASMJIT_INST_3i(vpsrldq, Vpsrldq, Zmm, Zmm, Imm) // AVX512_BW
- ASMJIT_INST_3i(vpsrldq, Vpsrldq, Zmm, Mem, Imm) // AVX512_BW
- ASMJIT_INST_3i(vpsrlq, Vpsrlq, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsrlq, Vpsrlq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsrlq, Vpsrlq, Xmm, Xmm, Mem) // AVX AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsrlq, Vpsrlq, Ymm, Ymm, Imm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsrlq, Vpsrlq, Ymm, Ymm, Xmm) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3x(vpsrlq, Vpsrlq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz}-VL
- ASMJIT_INST_3i(vpsrlq, Vpsrlq, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vpsrlq, Vpsrlq, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsrlq, Vpsrlq, Zmm, Zmm, Xmm) // AVX512_F{kz}
- ASMJIT_INST_3x(vpsrlq, Vpsrlq, Zmm, Zmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_3i(vpsrlq, Vpsrlq, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3i(vpsrlq, Vpsrlq, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Xmm, Xmm, Xmm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Xmm, Xmm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Xmm, Xmm, Xmm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Xmm, Xmm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Xmm, Xmm, Xmm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Xmm, Xmm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Ymm, Ymm, Ymm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Ymm, Ymm, Mem) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsrlw, Vpsrlw, Xmm, Xmm, Imm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlw, Vpsrlw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlw, Vpsrlw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsrlw, Vpsrlw, Ymm, Ymm, Imm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlw, Vpsrlw, Ymm, Ymm, Xmm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlw, Vpsrlw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsrlw, Vpsrlw, Xmm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3i(vpsrlw, Vpsrlw, Ymm, Mem, Imm) // AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsrlw, Vpsrlw, Zmm, Zmm, Xmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsrlw, Vpsrlw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsrlw, Vpsrlw, Zmm, Zmm, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3i(vpsrlw, Vpsrlw, Zmm, Mem, Imm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubb, Vpsubb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubb, Vpsubb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubb, Vpsubb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubb, Vpsubb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubb, Vpsubb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubb, Vpsubb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubd, Vpsubd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsubd, Vpsubd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsubd, Vpsubd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsubd, Vpsubd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpsubd, Vpsubd, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsubd, Vpsubd, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpsubq, Vpsubq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsubq, Vpsubq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsubq, Vpsubq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsubq, Vpsubq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpsubq, Vpsubq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsubq, Vpsubq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpsubsb, Vpsubsb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsb, Vpsubsb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsb, Vpsubsb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsb, Vpsubsb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsb, Vpsubsb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubsb, Vpsubsb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubsw, Vpsubsw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsw, Vpsubsw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsw, Vpsubsw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsw, Vpsubsw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubsw, Vpsubsw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubsw, Vpsubsw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubusb, Vpsubusb, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusb, Vpsubusb, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusb, Vpsubusb, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusb, Vpsubusb, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusb, Vpsubusb, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubusb, Vpsubusb, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubusw, Vpsubusw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusw, Vpsubusw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusw, Vpsubusw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusw, Vpsubusw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubusw, Vpsubusw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubusw, Vpsubusw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubw, Vpsubw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubw, Vpsubw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubw, Vpsubw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubw, Vpsubw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpsubw, Vpsubw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpsubw, Vpsubw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_4i(vpternlogd, Vpternlogd, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vpternlogd, Vpternlogd, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vpternlogd, Vpternlogd, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vpternlogd, Vpternlogd, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vpternlogd, Vpternlogd, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vpternlogd, Vpternlogd, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vpternlogq, Vpternlogq, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vpternlogq, Vpternlogq, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vpternlogq, Vpternlogq, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vpternlogq, Vpternlogq, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vpternlogq, Vpternlogq, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(vpternlogq, Vpternlogq, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_2x(vptest, Vptest, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vptest, Vptest, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vptest, Vptest, Ymm, Ymm) // AVX
- ASMJIT_INST_2x(vptest, Vptest, Ymm, Mem) // AVX
- ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Xmm, Xmm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Xmm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Ymm, Ymm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Ymm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Zmm, Zmm) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Zmm, Mem) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Xmm, Xmm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Xmm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Ymm, Ymm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Ymm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Zmm, Zmm) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Zmm, Mem) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Xmm, Xmm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Xmm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Ymm, Ymm) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Ymm, Mem) // AVX512_F{k|b32}-VL
- ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Zmm, Zmm) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Zmm, Mem) // AVX512_F{k|b32}
- ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Xmm, Xmm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Xmm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Ymm, Ymm) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Ymm, Mem) // AVX512_F{k|b64}-VL
- ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Zmm, Zmm) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Zmm, Mem) // AVX512_F{k|b64}
- ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Xmm, Xmm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Xmm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Ymm, Ymm) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Ymm, Mem) // AVX512_BW{k}-VL
- ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Zmm, Zmm) // AVX512_BW{k}
- ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Zmm, Mem) // AVX512_BW{k}
- ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Xmm, Xmm, Xmm) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Xmm, Xmm, Mem) // AVX AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Ymm, Ymm, Ymm) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Ymm, Ymm, Mem) // AVX2 AVX512_BW{kz}-VL
- ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Zmm, Zmm, Zmm) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Zmm, Zmm, Mem) // AVX512_BW{kz}
- ASMJIT_INST_3x(vpxor, Vpxor, Xmm, Xmm, Xmm) // AVX
- ASMJIT_INST_3x(vpxor, Vpxor, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vpxor, Vpxor, Ymm, Ymm, Ymm) // AVX2
- ASMJIT_INST_3x(vpxor, Vpxor, Ymm, Ymm, Mem) // AVX2
- ASMJIT_INST_3x(vpxord, Vpxord, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpxord, Vpxord, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpxord, Vpxord, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpxord, Vpxord, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vpxord, Vpxord, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpxord, Vpxord, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpxorq, Vpxorq, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpxorq, Vpxorq, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpxorq, Vpxorq, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpxorq, Vpxorq, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vpxorq, Vpxorq, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vpxorq, Vpxorq, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(vrangepd, Vrangepd, Xmm, Xmm, Xmm, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_4i(vrangepd, Vrangepd, Xmm, Xmm, Mem, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_4i(vrangepd, Vrangepd, Ymm, Ymm, Ymm, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_4i(vrangepd, Vrangepd, Ymm, Ymm, Mem, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_4i(vrangepd, Vrangepd, Zmm, Zmm, Zmm, Imm) // AVX512_DQ{kz|sae|b64}
- ASMJIT_INST_4i(vrangepd, Vrangepd, Zmm, Zmm, Mem, Imm) // AVX512_DQ{kz|sae|b64}
- ASMJIT_INST_4i(vrangeps, Vrangeps, Xmm, Xmm, Xmm, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_4i(vrangeps, Vrangeps, Xmm, Xmm, Mem, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_4i(vrangeps, Vrangeps, Ymm, Ymm, Ymm, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_4i(vrangeps, Vrangeps, Ymm, Ymm, Mem, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_4i(vrangeps, Vrangeps, Zmm, Zmm, Zmm, Imm) // AVX512_DQ{kz|sae|b32}
- ASMJIT_INST_4i(vrangeps, Vrangeps, Zmm, Zmm, Mem, Imm) // AVX512_DQ{kz|sae|b32}
+ ASMJIT_INST_2x(vplzcntd, Vplzcntd, Vec, Vec) // AVX512_CD{kz|b32}
+ ASMJIT_INST_2x(vplzcntd, Vplzcntd, Vec, Mem) // AVX512_CD{kz|b32}
+ ASMJIT_INST_2x(vplzcntq, Vplzcntq, Vec, Vec) // AVX512_CD{kz|b64}
+ ASMJIT_INST_2x(vplzcntq, Vplzcntq, Vec, Mem) // AVX512_CD{kz|b64}
+ ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Vec, Vec, Vec) // AVX512_IFMA{kz|b64}
+ ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, Vec, Vec, Mem) // AVX512_IFMA{kz|b64}
+ ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Vec, Vec, Vec) // AVX512_IFMA{kz|b64}
+ ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, Vec, Vec, Mem) // AVX512_IFMA{kz|b64}
+ ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, Mem, Vec, Vec) // AVX2
+ ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, Vec, Vec, Mem) // AVX2
+ ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, Mem, Vec, Vec) // AVX2
+ ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, Vec, Vec, Mem) // AVX2
+ ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaxub, Vpmaxub, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaxub, Vpmaxub, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaxud, Vpmaxud, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpmaxud, Vpmaxud, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminsb, Vpminsb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminsb, Vpminsb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminsd, Vpminsd, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpminsd, Vpminsd, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpminsq, Vpminsq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpminsq, Vpminsq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpminsw, Vpminsw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminsw, Vpminsw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminub, Vpminub, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminub, Vpminub, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminud, Vpminud, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpminud, Vpminud, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpminuq, Vpminuq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpminuq, Vpminuq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpminuw, Vpminuw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpminuw, Vpminuw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, KReg, Vec) // AVX512_BW
+ ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, KReg, Vec) // AVX512_DQ
+ ASMJIT_INST_2x(vpmovdb, Vpmovdb, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovdb, Vpmovdb, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovdw, Vpmovdw, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovdw, Vpmovdw, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, Vec, KReg) // AVX512_BW
+ ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, Vec, KReg) // AVX512_DQ
+ ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, Vec, KReg) // AVX512_DQ
+ ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, Vec, KReg) // AVX512_BW
+ ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, Gp, Vec) // AVX+
+ ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, KReg, Vec) // AVX512_DQ
+ ASMJIT_INST_2x(vpmovqb, Vpmovqb, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovqb, Vpmovqb, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovqd, Vpmovqd, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovqd, Vpmovqd, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovqw, Vpmovqw, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovqw, Vpmovqw, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovswb, Vpmovswb, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovswb, Vpmovswb, Mem, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, Mem, Vec) // AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, Mem, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, KReg, Vec) // AVX512_BW
+ ASMJIT_INST_2x(vpmovwb, Vpmovwb, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovwb, Vpmovwb, Mem, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3x(vpmuldq, Vpmuldq, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpmuldq, Vpmuldq, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmulhw, Vpmulhw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmulhw, Vpmulhw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmulld, Vpmulld, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpmulld, Vpmulld, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpmullq, Vpmullq, Vec, Vec, Vec) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vpmullq, Vpmullq, Vec, Vec, Mem) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vpmullw, Vpmullw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmullw, Vpmullw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Vec, Vec, Vec) // AVX512_VBMI{kz|b64}
+ ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, Vec, Vec, Mem) // AVX512_VBMI{kz|b64}
+ ASMJIT_INST_3x(vpmuludq, Vpmuludq, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpmuludq, Vpmuludq, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vpopcntb, Vpopcntb, Vec, Vec) // AVX512_BITALG{kz|b32}
+ ASMJIT_INST_2x(vpopcntb, Vpopcntb, Vec, Mem) // AVX512_BITALG{kz|b32}
+ ASMJIT_INST_2x(vpopcntd, Vpopcntd, Vec, Vec) // AVX512_VPOPCNTDQ{kz|b32}
+ ASMJIT_INST_2x(vpopcntd, Vpopcntd, Vec, Mem) // AVX512_VPOPCNTDQ{kz|b32}
+ ASMJIT_INST_2x(vpopcntq, Vpopcntq, Vec, Vec) // AVX512_VPOPCNTDQ{kz|b64}
+ ASMJIT_INST_2x(vpopcntq, Vpopcntq, Vec, Mem) // AVX512_VPOPCNTDQ{kz|b64}
+ ASMJIT_INST_2x(vpopcntw, Vpopcntw, Vec, Vec) // AVX512_BITALG{kz|b32}
+ ASMJIT_INST_2x(vpopcntw, Vpopcntw, Vec, Mem) // AVX512_BITALG{kz|b32}
+ ASMJIT_INST_3x(vpor, Vpor, Vec, Vec, Vec) // AV+
+ ASMJIT_INST_3x(vpor, Vpor, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpord, Vpord, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpord, Vpord, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vporq, Vporq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vporq, Vporq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vprold, Vprold, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vprold, Vprold, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vprolq, Vprolq, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vprolq, Vprolq, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vprolvd, Vprolvd, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vprolvd, Vprolvd, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vprolvq, Vprolvq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vprolvq, Vprolvq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vprord, Vprord, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vprord, Vprord, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vprorq, Vprorq, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vprorq, Vprorq, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vprorvd, Vprorvd, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vprorvd, Vprorvd, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vprorvq, Vprorvq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vprorvq, Vprorvq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsadbw, Vpsadbw, Vec, Vec, Vec) // AVX+ AVX512_BW
+ ASMJIT_INST_3x(vpsadbw, Vpsadbw, Vec, Vec, Mem) // AVX+ AVX512_BW
+ ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, Mem, Vec) // AVX512_F{k}
+ ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, Mem, Vec) // AVX512_F{k}
+ ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, Mem, Vec) // AVX512_F{k}
+ ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, Mem, Vec) // AVX512_F{k}
+ ASMJIT_INST_4i(vpshldd, Vpshldd, Vec, Vec, Vec, Imm) // AVX512_VBMI2{kz}
+ ASMJIT_INST_4i(vpshldd, Vpshldd, Vec, Vec, Mem, Imm) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshldvd, Vpshldvd, Vec, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshldvd, Vpshldvd, Vec, Vec, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshldvq, Vpshldvq, Vec, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshldvq, Vpshldvq, Vec, Vec, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshldvw, Vpshldvw, Vec, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshldvw, Vpshldvw, Vec, Vec, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_4i(vpshrdd, Vpshrdd, Vec, Vec, Vec, Imm) // AVX512_VBMI2{kz}
+ ASMJIT_INST_4i(vpshrdd, Vpshrdd, Vec, Vec, Mem, Imm) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Vec, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshrdvd, Vpshrdvd, Vec, Vec, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Vec, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshrdvq, Vpshrdvq, Vec, Vec, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Vec, Vec, Vec) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshrdvw, Vpshrdvw, Vec, Vec, Mem) // AVX512_VBMI2{kz}
+ ASMJIT_INST_4i(vpshrdw, Vpshrdw, Vec, Vec, Vec, Imm) // AVX512_VBMI2{kz}
+ ASMJIT_INST_4i(vpshrdw, Vpshrdw, Vec, Vec, Mem, Imm) // AVX512_VBMI2{kz}
+ ASMJIT_INST_3x(vpshufb, Vpshufb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpshufb, Vpshufb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Vec, Vec) // AVX512_BITALG{k}
+ ASMJIT_INST_3x(vpshufbitqmb, Vpshufbitqmb, KReg, Vec, Mem) // AVX512_BITALG{k}
+ ASMJIT_INST_3i(vpshufd, Vpshufd, Vec, Vec, Imm) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vpshufd, Vpshufd, Vec, Mem, Imm) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vpshufhw, Vpshufhw, Vec, Vec, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3i(vpshufhw, Vpshufhw, Vec, Mem, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3i(vpshuflw, Vpshuflw, Vec, Vec, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3i(vpshuflw, Vpshuflw, Vec, Mem, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsignb, Vpsignb, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpsignb, Vpsignb, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpsignd, Vpsignd, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpsignd, Vpsignd, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpsignw, Vpsignw, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpsignw, Vpsignw, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3i(vpslld, Vpslld, Vec, Vec, Imm) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpslld, Vpslld, Vec, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3x(vpslld, Vpslld, Vec, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3i(vpslld, Vpslld, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vpslldq, Vpslldq, Vec, Vec, Imm) // AVX+ AVX512_BW
+ ASMJIT_INST_3i(vpslldq, Vpslldq, Vec, Mem, Imm) // AVX512_BW
+ ASMJIT_INST_3i(vpsllq, Vpsllq, Vec, Vec, Imm) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsllq, Vpsllq, Vec, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3x(vpsllq, Vpsllq, Vec, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3i(vpsllq, Vpsllq, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsllvd, Vpsllvd, Vec, Vec, Vec) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsllvd, Vpsllvd, Vec, Vec, Mem) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsllvq, Vpsllvq, Vec, Vec, Vec) // AVX2 AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsllvq, Vpsllvq, Vec, Vec, Mem) // AVX2 AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsllvw, Vpsllvw, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsllvw, Vpsllvw, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsllw, Vpsllw, Vec, Vec, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsllw, Vpsllw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsllw, Vpsllw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsllw, Vpsllw, Vec, Mem, Imm) // AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsrad, Vpsrad, Vec, Vec, Imm) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsrad, Vpsrad, Vec, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3x(vpsrad, Vpsrad, Vec, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3i(vpsrad, Vpsrad, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsraq, Vpsraq, Vec, Vec, Vec) // AVX512_F{kz}
+ ASMJIT_INST_3x(vpsraq, Vpsraq, Vec, Vec, Mem) // AVX512_F{kz}
+ ASMJIT_INST_3i(vpsraq, Vpsraq, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vpsraq, Vpsraq, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsravd, Vpsravd, Vec, Vec, Vec) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsravd, Vpsravd, Vec, Vec, Mem) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsravq, Vpsravq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsravq, Vpsravq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsravw, Vpsravw, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsravw, Vpsravw, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsraw, Vpsraw, Vec, Vec, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsraw, Vpsraw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsraw, Vpsraw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsraw, Vpsraw, Vec, Mem, Imm) // AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsrld, Vpsrld, Vec, Vec, Imm) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsrld, Vpsrld, Vec, Vec, Vec) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3x(vpsrld, Vpsrld, Vec, Vec, Mem) // AVX+ AVX512_F{kz}
+ ASMJIT_INST_3i(vpsrld, Vpsrld, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vpsrldq, Vpsrldq, Vec, Vec, Imm) // AVX+ AVX512_BW
+ ASMJIT_INST_3i(vpsrldq, Vpsrldq, Vec, Mem, Imm) // AVX512_BW
+ ASMJIT_INST_3i(vpsrlq, Vpsrlq, Vec, Vec, Imm) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsrlq, Vpsrlq, Vec, Vec, Vec) // AVX AVX512_F{kz}
+ ASMJIT_INST_3x(vpsrlq, Vpsrlq, Vec, Vec, Mem) // AVX AVX512_F{kz}
+ ASMJIT_INST_3i(vpsrlq, Vpsrlq, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Vec, Vec, Vec) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, Vec, Vec, Mem) // AVX2 AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Vec, Vec, Vec) // AVX2 AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, Vec, Vec, Mem) // AVX2 AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Vec, Vec, Vec) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, Vec, Vec, Mem) // AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsrlw, Vpsrlw, Vec, Vec, Imm) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsrlw, Vpsrlw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsrlw, Vpsrlw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3i(vpsrlw, Vpsrlw, Vec, Mem, Imm) // AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubb, Vpsubb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubb, Vpsubb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubd, Vpsubd, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsubd, Vpsubd, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpsubq, Vpsubq, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsubq, Vpsubq, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpsubsb, Vpsubsb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubsb, Vpsubsb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubsw, Vpsubsw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubsw, Vpsubsw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubusb, Vpsubusb, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubusb, Vpsubusb, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubusw, Vpsubusw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubusw, Vpsubusw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubw, Vpsubw, Vec, Vec, Vec) // AVX AVX512_BW{kz}
+ ASMJIT_INST_3x(vpsubw, Vpsubw, Vec, Vec, Mem) // AVX AVX512_BW{kz}
+ ASMJIT_INST_4i(vpternlogd, Vpternlogd, Vec, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vpternlogd, Vpternlogd, Vec, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vpternlogq, Vpternlogq, Vec, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vpternlogq, Vpternlogq, Vec, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vptest, Vptest, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vptest, Vptest, Vec, Mem) // AVX
+ ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vptestmb, Vptestmb, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Vec, Vec) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vptestmd, Vptestmd, KReg, Vec, Mem) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Vec, Vec) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vptestmq, Vptestmq, KReg, Vec, Mem) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vptestmw, Vptestmw, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vptestnmb, Vptestnmb, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Vec, Vec) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vptestnmd, Vptestnmd, KReg, Vec, Mem) // AVX512_F{k|b32}
+ ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Vec, Vec) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vptestnmq, Vptestnmq, KReg, Vec, Mem) // AVX512_F{k|b64}
+ ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Vec, Vec) // AVX512_BW{k}
+ ASMJIT_INST_3x(vptestnmw, Vptestnmw, KReg, Vec, Mem) // AVX512_BW{k}
+ ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Vec, Vec, Vec) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, Vec, Vec, Mem) // AVX+ AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Vec, Vec, Vec) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, Vec, Vec, Mem) // AVX+ AVX512_BW{kz}
+ ASMJIT_INST_3x(vpxor, Vpxor, Vec, Vec, Vec) // AVX+
+ ASMJIT_INST_3x(vpxor, Vpxor, Vec, Vec, Mem) // AVX+
+ ASMJIT_INST_3x(vpxord, Vpxord, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpxord, Vpxord, Vec, Vec, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vpxorq, Vpxorq, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vpxorq, Vpxorq, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vrangepd, Vrangepd, Vec, Vec, Vec, Imm) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_4i(vrangepd, Vrangepd, Vec, Vec, Mem, Imm) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_4i(vrangeps, Vrangeps, Vec, Vec, Vec, Imm) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_4i(vrangeps, Vrangeps, Vec, Vec, Mem, Imm) // AVX512_DQ{kz|b32}
ASMJIT_INST_4i(vrangesd, Vrangesd, Xmm, Xmm, Xmm, Imm) // AVX512_DQ{kz|sae}
ASMJIT_INST_4i(vrangesd, Vrangesd, Xmm, Xmm, Mem, Imm) // AVX512_DQ{kz|sae}
ASMJIT_INST_4i(vrangess, Vrangess, Xmm, Xmm, Xmm, Imm) // AVX512_DQ{kz|sae}
ASMJIT_INST_4i(vrangess, Vrangess, Xmm, Xmm, Mem, Imm) // AVX512_DQ{kz|sae}
- ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Zmm, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, Vec, Mem) // AVX512_F{kz|b32}
ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, Xmm, Xmm, Xmm) // AVX512_F{kz}
ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, Xmm, Xmm, Mem) // AVX512_F{kz}
ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, Xmm, Xmm, Xmm) // AVX512_F{kz}
ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, Xmm, Xmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, Zmm, Zmm) // AVX512_ER{kz|sae|b64}
- ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, Zmm, Mem) // AVX512_ER{kz|sae|b64}
- ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, Zmm, Zmm) // AVX512_ER{kz|sae|b32}
- ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, Zmm, Mem) // AVX512_ER{kz|sae|b32}
+ ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, Vec, Vec) // AVX512_ER{kz|sae|b64}
+ ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, Vec, Mem) // AVX512_ER{kz|sae|b64}
+ ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, Vec, Vec) // AVX512_ER{kz|sae|b32}
+ ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, Vec, Mem) // AVX512_ER{kz|sae|b32}
ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, Xmm, Xmm, Xmm) // AVX512_ER{kz|sae}
ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, Xmm, Xmm, Mem) // AVX512_ER{kz|sae}
ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, Xmm, Xmm, Xmm) // AVX512_ER{kz|sae}
ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, Xmm, Xmm, Mem) // AVX512_ER{kz|sae}
- ASMJIT_INST_2x(vrcpps, Vrcpps, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vrcpps, Vrcpps, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vrcpps, Vrcpps, Ymm, Ymm) // AVX
- ASMJIT_INST_2x(vrcpps, Vrcpps, Ymm, Mem) // AVX
+ ASMJIT_INST_2x(vrcpps, Vrcpps, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vrcpps, Vrcpps, Vec, Mem) // AVX
ASMJIT_INST_3x(vrcpss, Vrcpss, Xmm, Xmm, Xmm) // AVX
ASMJIT_INST_3x(vrcpss, Vrcpss, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3i(vreducepd, Vreducepd, Xmm, Xmm, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3i(vreducepd, Vreducepd, Xmm, Mem, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3i(vreducepd, Vreducepd, Ymm, Ymm, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3i(vreducepd, Vreducepd, Ymm, Mem, Imm) // AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3i(vreducepd, Vreducepd, Zmm, Zmm, Imm) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3i(vreducepd, Vreducepd, Zmm, Mem, Imm) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3i(vreduceps, Vreduceps, Xmm, Xmm, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3i(vreduceps, Vreduceps, Xmm, Mem, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3i(vreduceps, Vreduceps, Ymm, Ymm, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3i(vreduceps, Vreduceps, Ymm, Mem, Imm) // AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3i(vreduceps, Vreduceps, Zmm, Zmm, Imm) // AVX512_DQ{kz|b32}
- ASMJIT_INST_3i(vreduceps, Vreduceps, Zmm, Mem, Imm) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_3i(vreducepd, Vreducepd, Vec, Vec, Imm) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_3i(vreducepd, Vreducepd, Vec, Mem, Imm) // AVX512_DQ{kz|b64}
+ ASMJIT_INST_3i(vreduceps, Vreduceps, Vec, Vec, Imm) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_3i(vreduceps, Vreduceps, Vec, Mem, Imm) // AVX512_DQ{kz|b32}
ASMJIT_INST_4i(vreducesd, Vreducesd, Xmm, Xmm, Xmm, Imm) // AVX512_DQ{kz}
ASMJIT_INST_4i(vreducesd, Vreducesd, Xmm, Xmm, Mem, Imm) // AVX512_DQ{kz}
ASMJIT_INST_4i(vreducess, Vreducess, Xmm, Xmm, Xmm, Imm) // AVX512_DQ{kz}
ASMJIT_INST_4i(vreducess, Vreducess, Xmm, Xmm, Mem, Imm) // AVX512_DQ{kz}
- ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Xmm, Xmm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Xmm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Zmm, Mem, Imm) // AVX512_F{kz|sae|b64}
- ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Xmm, Xmm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Xmm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Zmm, Zmm, Imm) // AVX512_F{kz|sae|b32}
- ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Zmm, Mem, Imm) // AVX512_F{kz|sae|b32}
+ ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, Vec, Mem, Imm) // AVX512_F{kz|b32}
ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vrndscaless, Vrndscaless, Xmm, Xmm, Xmm, Imm) // AVX512_F{kz|sae}
ASMJIT_INST_4i(vrndscaless, Vrndscaless, Xmm, Xmm, Mem, Imm) // AVX512_F{kz|sae}
- ASMJIT_INST_3i(vroundpd, Vroundpd, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_3i(vroundpd, Vroundpd, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_3i(vroundpd, Vroundpd, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_3i(vroundpd, Vroundpd, Ymm, Mem, Imm) // AVX
- ASMJIT_INST_3i(vroundps, Vroundps, Xmm, Xmm, Imm) // AVX
- ASMJIT_INST_3i(vroundps, Vroundps, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_3i(vroundps, Vroundps, Ymm, Ymm, Imm) // AVX
- ASMJIT_INST_3i(vroundps, Vroundps, Ymm, Mem, Imm) // AVX
+ ASMJIT_INST_3i(vroundpd, Vroundpd, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_3i(vroundpd, Vroundpd, Vec, Mem, Imm) // AVX
+ ASMJIT_INST_3i(vroundps, Vroundps, Vec, Vec, Imm) // AVX
+ ASMJIT_INST_3i(vroundps, Vroundps, Vec, Mem, Imm) // AVX
ASMJIT_INST_4i(vroundsd, Vroundsd, Xmm, Xmm, Xmm, Imm) // AVX
ASMJIT_INST_4i(vroundsd, Vroundsd, Xmm, Xmm, Mem, Imm) // AVX
ASMJIT_INST_4i(vroundss, Vroundss, Xmm, Xmm, Xmm, Imm) // AVX
ASMJIT_INST_4i(vroundss, Vroundss, Xmm, Xmm, Mem, Imm) // AVX
- ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Zmm, Mem) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, Vec, Mem) // AVX512_F{kz|b32}
ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, Xmm, Xmm, Xmm) // AVX512_F{kz}
ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, Xmm, Xmm, Mem) // AVX512_F{kz}
ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, Xmm, Xmm, Xmm) // AVX512_F{kz}
ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, Xmm, Xmm, Mem) // AVX512_F{kz}
- ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, Zmm, Zmm) // AVX512_ER{kz|sae|b64}
- ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, Zmm, Mem) // AVX512_ER{kz|sae|b64}
- ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, Zmm, Zmm) // AVX512_ER{kz|sae|b32}
- ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, Zmm, Mem) // AVX512_ER{kz|sae|b32}
+ ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, Vec, Vec) // AVX512_ER{kz|sae|b64}
+ ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, Vec, Mem) // AVX512_ER{kz|sae|b64}
+ ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, Vec, Vec) // AVX512_ER{kz|sae|b32}
+ ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, Vec, Mem) // AVX512_ER{kz|sae|b32}
ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, Xmm, Xmm, Xmm) // AVX512_ER{kz|sae}
ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, Xmm, Xmm, Mem) // AVX512_ER{kz|sae}
ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, Xmm, Xmm, Xmm) // AVX512_ER{kz|sae}
ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, Xmm, Xmm, Mem) // AVX512_ER{kz|sae}
- ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, Ymm, Ymm) // AVX
- ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, Ymm, Mem) // AVX
+ ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, Vec, Mem) // AVX
ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, Xmm, Xmm, Xmm) // AVX
ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, Xmm, Xmm, Mem) // AVX
- ASMJIT_INST_3x(vscalefpd, Vscalefpd, Xmm, Xmm, Xmm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vscalefpd, Vscalefpd, Xmm, Xmm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vscalefpd, Vscalefpd, Ymm, Ymm, Ymm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vscalefpd, Vscalefpd, Ymm, Ymm, Mem) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vscalefpd, Vscalefpd, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vscalefpd, Vscalefpd, Zmm, Zmm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vscalefps, Vscalefps, Xmm, Xmm, Xmm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vscalefps, Vscalefps, Xmm, Xmm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vscalefps, Vscalefps, Ymm, Ymm, Ymm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vscalefps, Vscalefps, Ymm, Ymm, Mem) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vscalefps, Vscalefps, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vscalefps, Vscalefps, Zmm, Zmm, Mem) // AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vscalefpd, Vscalefpd, Vec, Vec, Vec) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vscalefpd, Vscalefpd, Vec, Vec, Mem) // AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vscalefps, Vscalefps, Vec, Vec, Vec) // AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vscalefps, Vscalefps, Vec, Vec, Mem) // AVX512_F{kz|b32}
ASMJIT_INST_3x(vscalefsd, Vscalefsd, Xmm, Xmm, Xmm) // AVX512_F{kz|er}
ASMJIT_INST_3x(vscalefsd, Vscalefsd, Xmm, Xmm, Mem) // AVX512_F{kz|er}
ASMJIT_INST_3x(vscalefss, Vscalefss, Xmm, Xmm, Xmm) // AVX512_F{kz|er}
ASMJIT_INST_3x(vscalefss, Vscalefss, Xmm, Xmm, Mem) // AVX512_F{kz|er}
- ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, Mem, Ymm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, Mem, Zmm) // AVX512_F{k}
- ASMJIT_INST_2x(vscatterdps, Vscatterdps, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vscatterdps, Vscatterdps, Mem, Ymm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vscatterdps, Vscatterdps, Mem, Zmm) // AVX512_F{k}
+ ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, Mem, Vec) // AVX512_F{k}
+ ASMJIT_INST_2x(vscatterdps, Vscatterdps, Mem, Vec) // AVX512_F{k}
ASMJIT_INST_1x(vscatterpf0dpd, Vscatterpf0dpd, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vscatterpf0dps, Vscatterpf0dps, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vscatterpf0qpd, Vscatterpf0qpd, Mem) // AVX512_PF{k}
@@ -4896,120 +3251,57 @@ public:
ASMJIT_INST_1x(vscatterpf1dps, Vscatterpf1dps, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vscatterpf1qpd, Vscatterpf1qpd, Mem) // AVX512_PF{k}
ASMJIT_INST_1x(vscatterpf1qps, Vscatterpf1qps, Mem) // AVX512_PF{k}
- ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, Mem, Ymm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, Mem, Zmm) // AVX512_F{k}
- ASMJIT_INST_2x(vscatterqps, Vscatterqps, Mem, Xmm) // AVX512_F{k}-VL
- ASMJIT_INST_2x(vscatterqps, Vscatterqps, Mem, Ymm) // AVX512_F{k}
- ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, Ymm, Ymm, Ymm, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, Ymm, Ymm, Mem, Imm) // AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(vshufpd, Vshufpd, Xmm, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshufpd, Vshufpd, Xmm, Xmm, Mem, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshufpd, Vshufpd, Ymm, Ymm, Ymm, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshufpd, Vshufpd, Ymm, Ymm, Mem, Imm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_4i(vshufpd, Vshufpd, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vshufpd, Vshufpd, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b32}
- ASMJIT_INST_4i(vshufps, Vshufps, Xmm, Xmm, Xmm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshufps, Vshufps, Xmm, Xmm, Mem, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshufps, Vshufps, Ymm, Ymm, Ymm, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshufps, Vshufps, Ymm, Ymm, Mem, Imm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_4i(vshufps, Vshufps, Zmm, Zmm, Zmm, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_4i(vshufps, Vshufps, Zmm, Zmm, Mem, Imm) // AVX512_F{kz|b64}
- ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Zmm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Zmm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_2x(vsqrtps, Vsqrtps, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vsqrtps, Vsqrtps, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vsqrtps, Vsqrtps, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vsqrtps, Vsqrtps, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_2x(vsqrtps, Vsqrtps, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_2x(vsqrtps, Vsqrtps, Zmm, Mem) // AVX512_F{kz|er|b32}
+ ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, Mem, Vec) // AVX512_F{k}
+ ASMJIT_INST_2x(vscatterqps, Vscatterqps, Mem, Vec) // AVX512_F{k}
+ ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, Vec, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, Vec, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, Vec, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, Vec, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, Vec, Vec, Vec, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, Vec, Vec, Mem, Imm) // AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, Vec, Vec, Vec, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, Vec, Vec, Mem, Imm) // AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vshufpd, Vshufpd, Vec, Vec, Vec, Imm) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vshufpd, Vshufpd, Vec, Vec, Mem, Imm) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_4i(vshufps, Vshufps, Vec, Vec, Vec, Imm) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_4i(vshufps, Vshufps, Vec, Vec, Mem, Imm) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_2x(vsqrtps, Vsqrtps, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_2x(vsqrtps, Vsqrtps, Vec, Mem) // AVX AVX512_F{kz|b32}
ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vsqrtss, Vsqrtss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vsqrtss, Vsqrtss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
ASMJIT_INST_1x(vstmxcsr, Vstmxcsr, Mem) // AVX
- ASMJIT_INST_3x(vsubpd, Vsubpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vsubpd, Vsubpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vsubpd, Vsubpd, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vsubpd, Vsubpd, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vsubpd, Vsubpd, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vsubpd, Vsubpd, Zmm, Zmm, Mem) // AVX512_F{kz|er|b64}
- ASMJIT_INST_3x(vsubps, Vsubps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vsubps, Vsubps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vsubps, Vsubps, Ymm, Ymm, Ymm) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vsubps, Vsubps, Ymm, Ymm, Mem) // AVX2 AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vsubps, Vsubps, Zmm, Zmm, Zmm) // AVX512_F{kz|er|b32}
- ASMJIT_INST_3x(vsubps, Vsubps, Zmm, Zmm, Mem) // AVX512_F{kz|er|b32}
+ ASMJIT_INST_3x(vsubpd, Vsubpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vsubpd, Vsubpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vsubps, Vsubps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vsubps, Vsubps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
ASMJIT_INST_3x(vsubsd, Vsubsd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vsubsd, Vsubsd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vsubss, Vsubss, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|er}
ASMJIT_INST_3x(vsubss, Vsubss, Xmm, Xmm, Mem) // AVX AVX512_F{kz|er}
- ASMJIT_INST_2x(vtestpd, Vtestpd, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vtestpd, Vtestpd, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vtestpd, Vtestpd, Ymm, Ymm) // AVX
- ASMJIT_INST_2x(vtestpd, Vtestpd, Ymm, Mem) // AVX
- ASMJIT_INST_2x(vtestps, Vtestps, Xmm, Xmm) // AVX
- ASMJIT_INST_2x(vtestps, Vtestps, Xmm, Mem) // AVX
- ASMJIT_INST_2x(vtestps, Vtestps, Ymm, Ymm) // AVX
- ASMJIT_INST_2x(vtestps, Vtestps, Ymm, Mem) // AVX
+ ASMJIT_INST_2x(vtestpd, Vtestpd, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vtestpd, Vtestpd, Vec, Mem) // AVX
+ ASMJIT_INST_2x(vtestps, Vtestps, Vec, Vec) // AVX
+ ASMJIT_INST_2x(vtestps, Vtestps, Vec, Mem) // AVX
ASMJIT_INST_2x(vucomisd, Vucomisd, Xmm, Xmm) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vucomisd, Vucomisd, Xmm, Mem) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vucomiss, Vucomiss, Xmm, Xmm) // AVX AVX512_F{sae}
ASMJIT_INST_2x(vucomiss, Vucomiss, Xmm, Mem) // AVX AVX512_F{sae}
- ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vunpckhps, Vunpckhps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpckhps, Vunpckhps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpckhps, Vunpckhps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpckhps, Vunpckhps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpckhps, Vunpckhps, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vunpckhps, Vunpckhps, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b64}-VL
- ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Zmm, Zmm, Zmm) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Zmm, Zmm, Mem) // AVX512_F{kz|b64}
- ASMJIT_INST_3x(vunpcklps, Vunpcklps, Xmm, Xmm, Xmm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpcklps, Vunpcklps, Xmm, Xmm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpcklps, Vunpcklps, Ymm, Ymm, Ymm) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpcklps, Vunpcklps, Ymm, Ymm, Mem) // AVX AVX512_F{kz|b32}-VL
- ASMJIT_INST_3x(vunpcklps, Vunpcklps, Zmm, Zmm, Zmm) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vunpcklps, Vunpcklps, Zmm, Zmm, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vxorpd, Vxorpd, Xmm, Xmm, Xmm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vxorpd, Vxorpd, Xmm, Xmm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vxorpd, Vxorpd, Ymm, Ymm, Ymm) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vxorpd, Vxorpd, Ymm, Ymm, Mem) // AVX AVX512_DQ{kz|b64}-VL
- ASMJIT_INST_3x(vxorpd, Vxorpd, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vxorpd, Vxorpd, Zmm, Zmm, Mem) // AVX512_DQ{kz|b64}
- ASMJIT_INST_3x(vxorps, Vxorps, Xmm, Xmm, Xmm) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vxorps, Vxorps, Xmm, Xmm, Mem) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vxorps, Vxorps, Ymm, Ymm, Ymm) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vxorps, Vxorps, Ymm, Ymm, Mem) // AVX AVX512_DQ{kz|b32}-VL
- ASMJIT_INST_3x(vxorps, Vxorps, Zmm, Zmm, Zmm) // AVX512_DQ{kz|b32}
- ASMJIT_INST_3x(vxorps, Vxorps, Zmm, Zmm, Mem) // AVX512_DQ{kz|b32}
+ ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vunpckhps, Vunpckhps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vunpckhps, Vunpckhps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Vec, Vec, Vec) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, Vec, Vec, Mem) // AVX AVX512_F{kz|b64}
+ ASMJIT_INST_3x(vunpcklps, Vunpcklps, Vec, Vec, Vec) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vunpcklps, Vunpcklps, Vec, Vec, Mem) // AVX AVX512_F{kz|b32}
+ ASMJIT_INST_3x(vxorpd, Vxorpd, Vec, Vec, Vec) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vxorpd, Vxorpd, Vec, Vec, Mem) // AVX AVX512_DQ{kz|b64}
+ ASMJIT_INST_3x(vxorps, Vxorps, Vec, Vec, Vec) // AVX AVX512_DQ{kz|b32}
+ ASMJIT_INST_3x(vxorps, Vxorps, Vec, Vec, Mem) // AVX AVX512_DQ{kz|b32}
ASMJIT_INST_0x(vzeroall, Vzeroall) // AVX
ASMJIT_INST_0x(vzeroupper, Vzeroupper) // AVX
@@ -5018,96 +3310,60 @@ public:
//! \name FMA4 Instructions
//! \{
- ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfmaddps, Vfmaddps, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddps, Vfmaddps, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddps, Vfmaddps, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmaddps, Vfmaddps, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddps, Vfmaddps, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddps, Vfmaddps, Ymm, Ymm, Ymm, Mem) // FMA4
+ ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfmaddps, Vfmaddps, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddps, Vfmaddps, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddps, Vfmaddps, Vec, Vec, Vec, Mem) // FMA4
ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, Xmm, Xmm, Xmm, Xmm) // FMA4
ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, Xmm, Xmm, Mem, Xmm) // FMA4
ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, Xmm, Xmm, Xmm, Mem) // FMA4
ASMJIT_INST_4x(vfmaddss, Vfmaddss, Xmm, Xmm, Xmm, Xmm) // FMA4
ASMJIT_INST_4x(vfmaddss, Vfmaddss, Xmm, Xmm, Mem, Xmm) // FMA4
ASMJIT_INST_4x(vfmaddss, Vfmaddss, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubps, Vfmsubps, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubps, Vfmsubps, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfmsubps, Vfmsubps, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfmsubps, Vfmsubps, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubps, Vfmsubps, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfmsubps, Vfmsubps, Ymm, Ymm, Ymm, Mem) // FMA4
+ ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfmsubps, Vfmsubps, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubps, Vfmsubps, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfmsubps, Vfmsubps, Vec, Vec, Vec, Mem) // FMA4
ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, Xmm, Xmm, Xmm, Xmm) // FMA4
ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, Xmm, Xmm, Mem, Xmm) // FMA4
ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, Xmm, Xmm, Xmm, Mem) // FMA4
ASMJIT_INST_4x(vfmsubss, Vfmsubss, Xmm, Xmm, Xmm, Xmm) // FMA4
ASMJIT_INST_4x(vfmsubss, Vfmsubss, Xmm, Xmm, Mem, Xmm) // FMA4
ASMJIT_INST_4x(vfmsubss, Vfmsubss, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Ymm, Ymm, Ymm, Mem) // FMA4
+ ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, Vec, Vec, Vec, Mem) // FMA4
ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, Xmm, Xmm, Xmm, Xmm) // FMA4
ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, Xmm, Xmm, Mem, Xmm) // FMA4
ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, Xmm, Xmm, Xmm, Mem) // FMA4
ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, Xmm, Xmm, Xmm, Xmm) // FMA4
ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, Xmm, Xmm, Mem, Xmm) // FMA4
ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Ymm, Ymm, Ymm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Xmm, Xmm, Xmm, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Xmm, Xmm, Mem, Xmm) // FMA4
- ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Xmm, Xmm, Xmm, Mem) // FMA4
- ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Ymm, Ymm, Ymm, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Ymm, Ymm, Mem, Ymm) // FMA4
- ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Ymm, Ymm, Ymm, Mem) // FMA4
+ ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, Vec, Vec, Vec, Mem) // FMA4
+ ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Vec, Vec, Vec, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Vec, Vec, Mem, Vec) // FMA4
+ ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, Vec, Vec, Vec, Mem) // FMA4
ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, Xmm, Xmm, Xmm, Xmm) // FMA4
ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, Xmm, Xmm, Mem, Xmm) // FMA4
ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, Xmm, Xmm, Xmm, Mem) // FMA4
@@ -5120,24 +3376,17 @@ public:
//! \name XOP Instructions (Deprecated)
//! \{
- ASMJIT_INST_2x(vfrczpd, Vfrczpd, Xmm, Xmm) // XOP
- ASMJIT_INST_2x(vfrczpd, Vfrczpd, Xmm, Mem) // XOP
- ASMJIT_INST_2x(vfrczpd, Vfrczpd, Ymm, Ymm) // XOP
- ASMJIT_INST_2x(vfrczpd, Vfrczpd, Ymm, Mem) // XOP
- ASMJIT_INST_2x(vfrczps, Vfrczps, Xmm, Xmm) // XOP
- ASMJIT_INST_2x(vfrczps, Vfrczps, Xmm, Mem) // XOP
- ASMJIT_INST_2x(vfrczps, Vfrczps, Ymm, Ymm) // XOP
- ASMJIT_INST_2x(vfrczps, Vfrczps, Ymm, Mem) // XOP
+ ASMJIT_INST_2x(vfrczpd, Vfrczpd, Vec, Vec) // XOP
+ ASMJIT_INST_2x(vfrczpd, Vfrczpd, Vec, Mem) // XOP
+ ASMJIT_INST_2x(vfrczps, Vfrczps, Vec, Vec) // XOP
+ ASMJIT_INST_2x(vfrczps, Vfrczps, Vec, Mem) // XOP
ASMJIT_INST_2x(vfrczsd, Vfrczsd, Xmm, Xmm) // XOP
ASMJIT_INST_2x(vfrczsd, Vfrczsd, Xmm, Mem) // XOP
ASMJIT_INST_2x(vfrczss, Vfrczss, Xmm, Xmm) // XOP
ASMJIT_INST_2x(vfrczss, Vfrczss, Xmm, Mem) // XOP
- ASMJIT_INST_4x(vpcmov, Vpcmov, Xmm, Xmm, Xmm, Xmm) // XOP
- ASMJIT_INST_4x(vpcmov, Vpcmov, Xmm, Xmm, Mem, Xmm) // XOP
- ASMJIT_INST_4x(vpcmov, Vpcmov, Xmm, Xmm, Xmm, Mem) // XOP
- ASMJIT_INST_4x(vpcmov, Vpcmov, Ymm, Ymm, Ymm, Ymm) // XOP
- ASMJIT_INST_4x(vpcmov, Vpcmov, Ymm, Ymm, Mem, Ymm) // XOP
- ASMJIT_INST_4x(vpcmov, Vpcmov, Ymm, Ymm, Ymm, Mem) // XOP
+ ASMJIT_INST_4x(vpcmov, Vpcmov, Vec, Vec, Vec, Vec) // XOP
+ ASMJIT_INST_4x(vpcmov, Vpcmov, Vec, Vec, Mem, Vec) // XOP
+ ASMJIT_INST_4x(vpcmov, Vpcmov, Vec, Vec, Vec, Mem) // XOP
ASMJIT_INST_4i(vpcomb, Vpcomb, Xmm, Xmm, Xmm, Imm) // XOP
ASMJIT_INST_4i(vpcomb, Vpcomb, Xmm, Xmm, Mem, Imm) // XOP
ASMJIT_INST_4i(vpcomd, Vpcomd, Xmm, Xmm, Xmm, Imm) // XOP
@@ -5154,18 +3403,12 @@ public:
ASMJIT_INST_4i(vpcomuq, Vpcomuq, Xmm, Xmm, Mem, Imm) // XOP
ASMJIT_INST_4i(vpcomuw, Vpcomuw, Xmm, Xmm, Xmm, Imm) // XOP
ASMJIT_INST_4i(vpcomuw, Vpcomuw, Xmm, Xmm, Mem, Imm) // XOP
- ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Xmm, Xmm, Xmm, Xmm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Xmm, Xmm, Mem, Xmm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Xmm, Xmm, Xmm, Mem, Imm) // XOP
- ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Ymm, Ymm, Ymm, Ymm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Ymm, Ymm, Mem, Ymm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Ymm, Ymm, Ymm, Mem, Imm) // XOP
- ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Xmm, Xmm, Xmm, Xmm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Xmm, Xmm, Mem, Xmm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Xmm, Xmm, Xmm, Mem, Imm) // XOP
- ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Ymm, Ymm, Ymm, Ymm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Ymm, Ymm, Mem, Ymm, Imm) // XOP
- ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Ymm, Ymm, Ymm, Mem, Imm) // XOP
+ ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Vec, Vec, Vec, Vec, Imm) // XOP
+ ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Vec, Vec, Mem, Vec, Imm) // XOP
+ ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, Vec, Vec, Vec, Mem, Imm) // XOP
+ ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Vec, Vec, Vec, Vec, Imm) // XOP
+ ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Vec, Vec, Mem, Vec, Imm) // XOP
+ ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, Vec, Vec, Vec, Mem, Imm) // XOP
ASMJIT_INST_2x(vphaddbd, Vphaddbd, Xmm, Xmm) // XOP
ASMJIT_INST_2x(vphaddbd, Vphaddbd, Xmm, Mem) // XOP
ASMJIT_INST_2x(vphaddbq, Vphaddbq, Xmm, Xmm) // XOP
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86features.cpp b/3rdparty/asmjit/src/asmjit/x86/x86features.cpp
index 6ee5772374b..7c9505da197 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86features.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86features.cpp
@@ -106,22 +106,25 @@ static inline void simplifyCpuVendor(CpuInfo& cpu, uint32_t d0, uint32_t d1, uin
}
static inline void simplifyCpuBrand(char* s) noexcept {
- // Used to always clear the current character to ensure that the result
- // doesn't contain garbage after the new zero terminator.
char* d = s;
+ char c = s[0];
char prev = 0;
- char curr = s[0];
+
+ // Used to always clear the current character to ensure that the result
+ // doesn't contain garbage after a new null terminator is placed at the end.
s[0] = '\0';
for (;;) {
- if (curr == 0)
+ if (!c)
break;
- if (!(curr == ' ' && (prev == '@' || s[1] == ' ' || s[1] == '@')))
- *d++ = prev = curr;
+ if (!(c == ' ' && (prev == '@' || s[1] == ' ' || s[1] == '@'))) {
+ *d++ = c;
+ prev = c;
+ }
- curr = *++s;
+ c = *++s;
s[0] = '\0';
}
@@ -136,7 +139,9 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
Features& features = cpu._features.as<Features>();
cpu.reset();
- cpu._archInfo.init(ArchInfo::kIdHost);
+ cpu._arch = Environment::kArchHost;
+ cpu._subArch = Environment::kSubArchUnknown;
+ cpu._reserved = 0;
cpu._maxLogicalProcessors = 1;
features.add(Features::kI486);
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86features.h b/3rdparty/asmjit/src/asmjit/x86/x86features.h
index d73c063877f..b26b52454b1 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86features.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86features.h
@@ -40,6 +40,8 @@ class Features : public BaseFeatures {
public:
//! CPU feature ID.
enum Id : uint32_t {
+ // @EnumValuesBegin{"enum": "x86::Features::Id"}@
+
kNone = 0, //!< No feature (never set, used internally).
kMT, //!< CPU has multi-threading capabilities.
@@ -145,6 +147,8 @@ public:
kXSAVEOPT, //!< CPU has XSAVEOPT.
kXSAVES, //!< CPU has XSAVES.
+ // @EnumValuesEnd@
+
kCount //!< Count of X86 CPU features.
};
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86logging.cpp b/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
index cfb91dbf596..06553e401e0 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86logging.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
@@ -26,8 +26,9 @@
#include "../core/misc_p.h"
#include "../core/support.h"
+#include "../x86/x86features.h"
+#include "../x86/x86formatter_p.h"
#include "../x86/x86instdb_p.h"
-#include "../x86/x86logging_p.h"
#include "../x86/x86operand.h"
#ifndef ASMJIT_NO_COMPILER
@@ -37,7 +38,7 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// ============================================================================
-// [asmjit::x86::LoggingInternal - Constants]
+// [asmjit::x86::FormatterInternal - Constants]
// ============================================================================
struct RegFormatInfo {
@@ -196,56 +197,181 @@ static const char* x86GetAddressSizeString(uint32_t size) noexcept {
}
// ============================================================================
-// [asmjit::x86::LoggingInternal - Format Operand]
+// [asmjit::x86::FormatterInternal - Format Feature]
// ============================================================================
-ASMJIT_FAVOR_SIZE Error LoggingInternal::formatOperand(
+Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept {
+ // @EnumStringBegin{"enum": "x86::Features::Id", "output": "sFeature", "strip": "k"}@
+ static const char sFeatureString[] =
+ "None\0"
+ "MT\0"
+ "NX\0"
+ "3DNOW\0"
+ "3DNOW2\0"
+ "ADX\0"
+ "AESNI\0"
+ "ALTMOVCR8\0"
+ "AVX\0"
+ "AVX2\0"
+ "AVX512_4FMAPS\0"
+ "AVX512_4VNNIW\0"
+ "AVX512_BF16\0"
+ "AVX512_BITALG\0"
+ "AVX512_BW\0"
+ "AVX512_CDI\0"
+ "AVX512_DQ\0"
+ "AVX512_ERI\0"
+ "AVX512_F\0"
+ "AVX512_IFMA\0"
+ "AVX512_PFI\0"
+ "AVX512_VBMI\0"
+ "AVX512_VBMI2\0"
+ "AVX512_VL\0"
+ "AVX512_VNNI\0"
+ "AVX512_VP2INTERSECT\0"
+ "AVX512_VPOPCNTDQ\0"
+ "BMI\0"
+ "BMI2\0"
+ "CLDEMOTE\0"
+ "CLFLUSH\0"
+ "CLFLUSHOPT\0"
+ "CLWB\0"
+ "CLZERO\0"
+ "CMOV\0"
+ "CMPXCHG16B\0"
+ "CMPXCHG8B\0"
+ "ENCLV\0"
+ "ENQCMD\0"
+ "ERMS\0"
+ "F16C\0"
+ "FMA\0"
+ "FMA4\0"
+ "FPU\0"
+ "FSGSBASE\0"
+ "FXSR\0"
+ "FXSROPT\0"
+ "GEODE\0"
+ "GFNI\0"
+ "HLE\0"
+ "I486\0"
+ "LAHFSAHF\0"
+ "LWP\0"
+ "LZCNT\0"
+ "MMX\0"
+ "MMX2\0"
+ "MONITOR\0"
+ "MONITORX\0"
+ "MOVBE\0"
+ "MOVDIR64B\0"
+ "MOVDIRI\0"
+ "MPX\0"
+ "MSR\0"
+ "MSSE\0"
+ "OSXSAVE\0"
+ "PCLMULQDQ\0"
+ "PCOMMIT\0"
+ "PCONFIG\0"
+ "POPCNT\0"
+ "PREFETCHW\0"
+ "PREFETCHWT1\0"
+ "RDPID\0"
+ "RDRAND\0"
+ "RDSEED\0"
+ "RDTSC\0"
+ "RDTSCP\0"
+ "RTM\0"
+ "SHA\0"
+ "SKINIT\0"
+ "SMAP\0"
+ "SMEP\0"
+ "SMX\0"
+ "SSE\0"
+ "SSE2\0"
+ "SSE3\0"
+ "SSE4_1\0"
+ "SSE4_2\0"
+ "SSE4A\0"
+ "SSSE3\0"
+ "SVM\0"
+ "TBM\0"
+ "TSX\0"
+ "VAES\0"
+ "VMX\0"
+ "VPCLMULQDQ\0"
+ "WAITPKG\0"
+ "WBNOINVD\0"
+ "XOP\0"
+ "XSAVE\0"
+ "XSAVEC\0"
+ "XSAVEOPT\0"
+ "XSAVES\0"
+ "<Unknown>\0";
+
+ static const uint16_t sFeatureIndex[] = {
+ 0, 5, 8, 11, 17, 24, 28, 34, 44, 48, 53, 67, 81, 93, 107, 117, 128, 138,
+ 149, 158, 170, 181, 193, 206, 216, 228, 248, 265, 269, 274, 283, 291, 302,
+ 307, 314, 319, 330, 340, 346, 353, 358, 363, 367, 372, 376, 385, 390, 398,
+ 404, 409, 413, 418, 427, 431, 437, 441, 446, 454, 463, 469, 479, 487, 491,
+ 495, 500, 508, 518, 526, 534, 541, 551, 563, 569, 576, 583, 589, 596, 600,
+ 604, 611, 616, 621, 625, 629, 634, 639, 646, 653, 659, 665, 669, 673, 677,
+ 682, 686, 697, 705, 714, 718, 724, 731, 740, 747
+ };
+ // @EnumStringEnd@
+
+ return sb.append(sFeatureString + sFeatureIndex[Support::min<uint32_t>(featureId, x86::Features::kCount)]);
+}
+
+// ============================================================================
+// [asmjit::x86::FormatterInternal - Format Operand]
+// ============================================================================
+
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
String& sb,
uint32_t flags,
const BaseEmitter* emitter,
- uint32_t archId,
+ uint32_t arch,
const Operand_& op) noexcept {
if (op.isReg())
- return formatRegister(sb, flags, emitter, archId, op.as<BaseReg>().type(), op.as<BaseReg>().id());
+ return formatRegister(sb, flags, emitter, arch, op.as<BaseReg>().type(), op.as<BaseReg>().id());
if (op.isMem()) {
const Mem& m = op.as<Mem>();
- ASMJIT_PROPAGATE(sb.appendString(x86GetAddressSizeString(m.size())));
+ ASMJIT_PROPAGATE(sb.append(x86GetAddressSizeString(m.size())));
// Segment override prefix.
uint32_t seg = m.segmentId();
if (seg != SReg::kIdNone && seg < SReg::kIdCount)
- ASMJIT_PROPAGATE(sb.appendFormat("%s:", x86RegFormatInfo.nameStrings + 224 + seg * 4));
+ ASMJIT_PROPAGATE(sb.appendFormat("%s:", x86RegFormatInfo.nameStrings + 224 + size_t(seg) * 4));
- ASMJIT_PROPAGATE(sb.appendChar('['));
+ ASMJIT_PROPAGATE(sb.append('['));
switch (m.addrType()) {
- case BaseMem::kAddrTypeAbs: ASMJIT_PROPAGATE(sb.appendString("abs ")); break;
- case BaseMem::kAddrTypeRel: ASMJIT_PROPAGATE(sb.appendString("rel ")); break;
+ case BaseMem::kAddrTypeAbs: ASMJIT_PROPAGATE(sb.append("abs ")); break;
+ case BaseMem::kAddrTypeRel: ASMJIT_PROPAGATE(sb.append("rel ")); break;
}
char opSign = '\0';
if (m.hasBase()) {
opSign = '+';
if (m.hasBaseLabel()) {
- ASMJIT_PROPAGATE(Logging::formatLabel(sb, flags, emitter, m.baseId()));
+ ASMJIT_PROPAGATE(Formatter::formatLabel(sb, flags, emitter, m.baseId()));
}
else {
uint32_t modifiedFlags = flags;
if (m.isRegHome()) {
- ASMJIT_PROPAGATE(sb.appendString("&"));
+ ASMJIT_PROPAGATE(sb.append("&"));
modifiedFlags &= ~FormatOptions::kFlagRegCasts;
}
- ASMJIT_PROPAGATE(formatRegister(sb, modifiedFlags, emitter, archId, m.baseType(), m.baseId()));
+ ASMJIT_PROPAGATE(formatRegister(sb, modifiedFlags, emitter, arch, m.baseType(), m.baseId()));
}
}
if (m.hasIndex()) {
if (opSign)
- ASMJIT_PROPAGATE(sb.appendChar(opSign));
+ ASMJIT_PROPAGATE(sb.append(opSign));
opSign = '+';
- ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, archId, m.indexType(), m.indexId()));
+ ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, m.indexType(), m.indexId()));
if (m.hasShift())
ASMJIT_PROPAGATE(sb.appendFormat("*%u", 1 << m.shift()));
}
@@ -258,26 +384,26 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatOperand(
}
if (opSign)
- ASMJIT_PROPAGATE(sb.appendChar(opSign));
+ ASMJIT_PROPAGATE(sb.append(opSign));
uint32_t base = 10;
if ((flags & FormatOptions::kFlagHexOffsets) != 0 && off > 9) {
- ASMJIT_PROPAGATE(sb.appendString("0x", 2));
+ ASMJIT_PROPAGATE(sb.append("0x", 2));
base = 16;
}
ASMJIT_PROPAGATE(sb.appendUInt(off, base));
}
- return sb.appendChar(']');
+ return sb.append(']');
}
if (op.isImm()) {
const Imm& i = op.as<Imm>();
- int64_t val = i.i64();
+ int64_t val = i.value();
if ((flags & FormatOptions::kFlagHexImms) != 0 && uint64_t(val) > 9) {
- ASMJIT_PROPAGATE(sb.appendString("0x", 2));
+ ASMJIT_PROPAGATE(sb.append("0x", 2));
return sb.appendUInt(uint64_t(val), 16);
}
else {
@@ -286,14 +412,14 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatOperand(
}
if (op.isLabel()) {
- return Logging::formatLabel(sb, flags, emitter, op.id());
+ return Formatter::formatLabel(sb, flags, emitter, op.id());
}
- return sb.appendString("<None>");
+ return sb.append("<None>");
}
// ============================================================================
-// [asmjit::x86::LoggingInternal - Format Immediate (Extension)]
+// [asmjit::x86::FormatterInternal - Format Immediate (Extension)]
// ============================================================================
static constexpr char kImmCharStart = '{';
@@ -312,22 +438,22 @@ struct ImmBits {
char text[48 - 3];
};
-ASMJIT_FAVOR_SIZE static Error LoggingInternal_formatImmShuf(String& sb, uint32_t u8, uint32_t bits, uint32_t count) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmShuf(String& sb, uint32_t u8, uint32_t bits, uint32_t count) noexcept {
uint32_t mask = (1 << bits) - 1;
for (uint32_t i = 0; i < count; i++, u8 >>= bits) {
uint32_t value = u8 & mask;
- ASMJIT_PROPAGATE(sb.appendChar(i == 0 ? kImmCharStart : kImmCharOr));
+ ASMJIT_PROPAGATE(sb.append(i == 0 ? kImmCharStart : kImmCharOr));
ASMJIT_PROPAGATE(sb.appendUInt(value));
}
if (kImmCharEnd)
- ASMJIT_PROPAGATE(sb.appendChar(kImmCharEnd));
+ ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE static Error LoggingInternal_formatImmBits(String& sb, uint32_t u8, const ImmBits* bits, uint32_t count) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint32_t u8, const ImmBits* bits, uint32_t count) noexcept {
uint32_t n = 0;
char buf[64];
@@ -354,33 +480,33 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_formatImmBits(String& sb, uint32_
if (!str[0])
continue;
- ASMJIT_PROPAGATE(sb.appendChar(++n == 1 ? kImmCharStart : kImmCharOr));
- ASMJIT_PROPAGATE(sb.appendString(str));
+ ASMJIT_PROPAGATE(sb.append(++n == 1 ? kImmCharStart : kImmCharOr));
+ ASMJIT_PROPAGATE(sb.append(str));
}
if (n && kImmCharEnd)
- ASMJIT_PROPAGATE(sb.appendChar(kImmCharEnd));
+ ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE static Error LoggingInternal_formatImmText(String& sb, uint32_t u8, uint32_t bits, uint32_t advance, const char* text, uint32_t count = 1) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmText(String& sb, uint32_t u8, uint32_t bits, uint32_t advance, const char* text, uint32_t count = 1) noexcept {
uint32_t mask = (1u << bits) - 1;
uint32_t pos = 0;
for (uint32_t i = 0; i < count; i++, u8 >>= bits, pos += advance) {
uint32_t value = (u8 & mask) + pos;
- ASMJIT_PROPAGATE(sb.appendChar(i == 0 ? kImmCharStart : kImmCharOr));
- ASMJIT_PROPAGATE(sb.appendString(Support::findPackedString(text, value)));
+ ASMJIT_PROPAGATE(sb.append(i == 0 ? kImmCharStart : kImmCharOr));
+ ASMJIT_PROPAGATE(sb.append(Support::findPackedString(text, value)));
}
if (kImmCharEnd)
- ASMJIT_PROPAGATE(sb.appendChar(kImmCharEnd));
+ ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
String& sb,
uint32_t flags,
uint32_t instId,
@@ -456,51 +582,51 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
{ 0x08u, 3, ImmBits::kModeLookup, "\0" "INEXACT\0" }
};
- uint32_t u8 = imm.u8();
+ uint32_t u8 = imm.valueAs<uint8_t>();
switch (instId) {
case Inst::kIdVblendpd:
case Inst::kIdBlendpd:
- return LoggingInternal_formatImmShuf(sb, u8, 1, vecSize / 8);
+ return FormatterInternal_formatImmShuf(sb, u8, 1, vecSize / 8);
case Inst::kIdVblendps:
case Inst::kIdBlendps:
- return LoggingInternal_formatImmShuf(sb, u8, 1, vecSize / 4);
+ return FormatterInternal_formatImmShuf(sb, u8, 1, vecSize / 4);
case Inst::kIdVcmppd:
case Inst::kIdVcmpps:
case Inst::kIdVcmpsd:
case Inst::kIdVcmpss:
- return LoggingInternal_formatImmText(sb, u8, 5, 0, vcmpx);
+ return FormatterInternal_formatImmText(sb, u8, 5, 0, vcmpx);
case Inst::kIdCmppd:
case Inst::kIdCmpps:
case Inst::kIdCmpsd:
case Inst::kIdCmpss:
- return LoggingInternal_formatImmText(sb, u8, 3, 0, vcmpx);
+ return FormatterInternal_formatImmText(sb, u8, 3, 0, vcmpx);
case Inst::kIdVdbpsadbw:
- return LoggingInternal_formatImmShuf(sb, u8, 2, 4);
+ return FormatterInternal_formatImmShuf(sb, u8, 2, 4);
case Inst::kIdVdppd:
case Inst::kIdVdpps:
case Inst::kIdDppd:
case Inst::kIdDpps:
- return LoggingInternal_formatImmShuf(sb, u8, 1, 8);
+ return FormatterInternal_formatImmShuf(sb, u8, 1, 8);
case Inst::kIdVmpsadbw:
case Inst::kIdMpsadbw:
- return LoggingInternal_formatImmBits(sb, u8, vmpsadbw, Support::min<uint32_t>(vecSize / 8, 4));
+ return FormatterInternal_formatImmBits(sb, u8, vmpsadbw, Support::min<uint32_t>(vecSize / 8, 4));
case Inst::kIdVpblendw:
case Inst::kIdPblendw:
- return LoggingInternal_formatImmShuf(sb, u8, 1, 8);
+ return FormatterInternal_formatImmShuf(sb, u8, 1, 8);
case Inst::kIdVpblendd:
- return LoggingInternal_formatImmShuf(sb, u8, 1, Support::min<uint32_t>(vecSize / 4, 8));
+ return FormatterInternal_formatImmShuf(sb, u8, 1, Support::min<uint32_t>(vecSize / 4, 8));
case Inst::kIdVpclmulqdq:
case Inst::kIdPclmulqdq:
- return LoggingInternal_formatImmBits(sb, u8, vpclmulqdq, ASMJIT_ARRAY_SIZE(vpclmulqdq));
+ return FormatterInternal_formatImmBits(sb, u8, vpclmulqdq, ASMJIT_ARRAY_SIZE(vpclmulqdq));
case Inst::kIdVroundpd:
case Inst::kIdVroundps:
@@ -510,57 +636,57 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
case Inst::kIdRoundps:
case Inst::kIdRoundsd:
case Inst::kIdRoundss:
- return LoggingInternal_formatImmBits(sb, u8, vroundxx, ASMJIT_ARRAY_SIZE(vroundxx));
+ return FormatterInternal_formatImmBits(sb, u8, vroundxx, ASMJIT_ARRAY_SIZE(vroundxx));
case Inst::kIdVshufpd:
case Inst::kIdShufpd:
- return LoggingInternal_formatImmText(sb, u8, 1, 2, vshufpd, Support::min<uint32_t>(vecSize / 8, 8));
+ return FormatterInternal_formatImmText(sb, u8, 1, 2, vshufpd, Support::min<uint32_t>(vecSize / 8, 8));
case Inst::kIdVshufps:
case Inst::kIdShufps:
- return LoggingInternal_formatImmText(sb, u8, 2, 4, vshufps, 4);
+ return FormatterInternal_formatImmText(sb, u8, 2, 4, vshufps, 4);
case Inst::kIdVcvtps2ph:
- return LoggingInternal_formatImmBits(sb, u8, vroundxx, 1);
+ return FormatterInternal_formatImmBits(sb, u8, vroundxx, 1);
case Inst::kIdVperm2f128:
case Inst::kIdVperm2i128:
- return LoggingInternal_formatImmBits(sb, u8, vperm2x128, ASMJIT_ARRAY_SIZE(vperm2x128));
+ return FormatterInternal_formatImmBits(sb, u8, vperm2x128, ASMJIT_ARRAY_SIZE(vperm2x128));
case Inst::kIdVpermilpd:
- return LoggingInternal_formatImmShuf(sb, u8, 1, vecSize / 8);
+ return FormatterInternal_formatImmShuf(sb, u8, 1, vecSize / 8);
case Inst::kIdVpermilps:
- return LoggingInternal_formatImmShuf(sb, u8, 2, 4);
+ return FormatterInternal_formatImmShuf(sb, u8, 2, 4);
case Inst::kIdVpshufd:
case Inst::kIdPshufd:
- return LoggingInternal_formatImmShuf(sb, u8, 2, 4);
+ return FormatterInternal_formatImmShuf(sb, u8, 2, 4);
case Inst::kIdVpshufhw:
case Inst::kIdVpshuflw:
case Inst::kIdPshufhw:
case Inst::kIdPshuflw:
case Inst::kIdPshufw:
- return LoggingInternal_formatImmShuf(sb, u8, 2, 4);
+ return FormatterInternal_formatImmShuf(sb, u8, 2, 4);
case Inst::kIdVfixupimmpd:
case Inst::kIdVfixupimmps:
case Inst::kIdVfixupimmsd:
case Inst::kIdVfixupimmss:
- return LoggingInternal_formatImmBits(sb, u8, vfixupimmxx, ASMJIT_ARRAY_SIZE(vfixupimmxx));
+ return FormatterInternal_formatImmBits(sb, u8, vfixupimmxx, ASMJIT_ARRAY_SIZE(vfixupimmxx));
case Inst::kIdVfpclasspd:
case Inst::kIdVfpclassps:
case Inst::kIdVfpclasssd:
case Inst::kIdVfpclassss:
- return LoggingInternal_formatImmBits(sb, u8, vfpclassxx, ASMJIT_ARRAY_SIZE(vfpclassxx));
+ return FormatterInternal_formatImmBits(sb, u8, vfpclassxx, ASMJIT_ARRAY_SIZE(vfpclassxx));
case Inst::kIdVgetmantpd:
case Inst::kIdVgetmantps:
case Inst::kIdVgetmantsd:
case Inst::kIdVgetmantss:
- return LoggingInternal_formatImmBits(sb, u8, vgetmantxx, ASMJIT_ARRAY_SIZE(vgetmantxx));
+ return FormatterInternal_formatImmBits(sb, u8, vgetmantxx, ASMJIT_ARRAY_SIZE(vgetmantxx));
case Inst::kIdVpcmpb:
case Inst::kIdVpcmpd:
@@ -570,7 +696,7 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
case Inst::kIdVpcmpud:
case Inst::kIdVpcmpuq:
case Inst::kIdVpcmpuw:
- return LoggingInternal_formatImmText(sb, u8, 3, 0, vpcmpx);
+ return FormatterInternal_formatImmText(sb, u8, 3, 0, vpcmpx);
case Inst::kIdVpcomb:
case Inst::kIdVpcomd:
@@ -580,21 +706,21 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
case Inst::kIdVpcomud:
case Inst::kIdVpcomuq:
case Inst::kIdVpcomuw:
- return LoggingInternal_formatImmText(sb, u8, 3, 0, vpcomx);
+ return FormatterInternal_formatImmText(sb, u8, 3, 0, vpcomx);
case Inst::kIdVpermq:
case Inst::kIdVpermpd:
- return LoggingInternal_formatImmShuf(sb, u8, 2, 4);
+ return FormatterInternal_formatImmShuf(sb, u8, 2, 4);
case Inst::kIdVpternlogd:
case Inst::kIdVpternlogq:
- return LoggingInternal_formatImmShuf(sb, u8, 1, 8);
+ return FormatterInternal_formatImmShuf(sb, u8, 1, 8);
case Inst::kIdVrangepd:
case Inst::kIdVrangeps:
case Inst::kIdVrangesd:
case Inst::kIdVrangess:
- return LoggingInternal_formatImmBits(sb, u8, vrangexx, ASMJIT_ARRAY_SIZE(vrangexx));
+ return FormatterInternal_formatImmBits(sb, u8, vrangexx, ASMJIT_ARRAY_SIZE(vrangexx));
case Inst::kIdVreducepd:
case Inst::kIdVreduceps:
@@ -604,7 +730,7 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
case Inst::kIdVrndscaleps:
case Inst::kIdVrndscalesd:
case Inst::kIdVrndscaless:
- return LoggingInternal_formatImmBits(sb, u8, vreducexx_vrndscalexx, ASMJIT_ARRAY_SIZE(vreducexx_vrndscalexx));
+ return FormatterInternal_formatImmBits(sb, u8, vreducexx_vrndscalexx, ASMJIT_ARRAY_SIZE(vreducexx_vrndscalexx));
case Inst::kIdVshuff32x4:
case Inst::kIdVshuff64x2:
@@ -612,7 +738,7 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
case Inst::kIdVshufi64x2: {
uint32_t count = Support::max<uint32_t>(vecSize / 16, 2u);
uint32_t bits = count <= 2 ? 1u : 2u;
- return LoggingInternal_formatImmShuf(sb, u8, bits, count);
+ return FormatterInternal_formatImmShuf(sb, u8, bits, count);
}
default:
@@ -621,11 +747,11 @@ ASMJIT_FAVOR_SIZE static Error LoggingInternal_explainConst(
}
// ============================================================================
-// [asmjit::x86::LoggingInternal - Format Register]
+// [asmjit::x86::FormatterInternal - Format Register]
// ============================================================================
-ASMJIT_FAVOR_SIZE Error LoggingInternal::formatRegister(String& sb, uint32_t flags, const BaseEmitter* emitter, uint32_t archId, uint32_t rType, uint32_t rId) noexcept {
- DebugUtils::unused(archId);
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, uint32_t flags, const BaseEmitter* emitter, uint32_t arch, uint32_t rType, uint32_t rId) noexcept {
+ DebugUtils::unused(arch);
const RegFormatInfo& info = x86RegFormatInfo;
#ifndef ASMJIT_NO_COMPILER
@@ -638,7 +764,7 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatRegister(String& sb, uint32_t fla
const char* name = vReg->name();
if (name && name[0] != '\0')
- ASMJIT_PROPAGATE(sb.appendString(name));
+ ASMJIT_PROPAGATE(sb.append(name));
else
ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(rId))));
@@ -660,7 +786,7 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatRegister(String& sb, uint32_t fla
const RegFormatInfo::NameEntry& nameEntry = info.nameEntries[rType];
if (rId < nameEntry.specialCount)
- return sb.appendString(info.nameStrings + nameEntry.specialIndex + rId * 4);
+ return sb.append(info.nameStrings + nameEntry.specialIndex + rId * 4);
if (rId < nameEntry.count)
return sb.appendFormat(info.nameStrings + nameEntry.formatIndex, unsigned(rId));
@@ -674,15 +800,15 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatRegister(String& sb, uint32_t fla
}
// ============================================================================
-// [asmjit::x86::LoggingInternal - Format Instruction]
+// [asmjit::x86::FormatterInternal - Format Instruction]
// ============================================================================
-ASMJIT_FAVOR_SIZE Error LoggingInternal::formatInstruction(
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
String& sb,
uint32_t flags,
const BaseEmitter* emitter,
- uint32_t archId,
- const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept {
+ uint32_t arch,
+ const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept {
uint32_t instId = inst.id();
uint32_t options = inst.options();
@@ -690,21 +816,21 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatInstruction(
// Format instruction options and instruction mnemonic.
if (instId < Inst::_kIdCount) {
// SHORT|LONG options.
- if (options & Inst::kOptionShortForm) ASMJIT_PROPAGATE(sb.appendString("short "));
- if (options & Inst::kOptionLongForm) ASMJIT_PROPAGATE(sb.appendString("long "));
+ if (options & Inst::kOptionShortForm) ASMJIT_PROPAGATE(sb.append("short "));
+ if (options & Inst::kOptionLongForm) ASMJIT_PROPAGATE(sb.append("long "));
// LOCK|XACQUIRE|XRELEASE options.
- if (options & Inst::kOptionXAcquire) ASMJIT_PROPAGATE(sb.appendString("xacquire "));
- if (options & Inst::kOptionXRelease) ASMJIT_PROPAGATE(sb.appendString("xrelease "));
- if (options & Inst::kOptionLock) ASMJIT_PROPAGATE(sb.appendString("lock "));
+ if (options & Inst::kOptionXAcquire) ASMJIT_PROPAGATE(sb.append("xacquire "));
+ if (options & Inst::kOptionXRelease) ASMJIT_PROPAGATE(sb.append("xrelease "));
+ if (options & Inst::kOptionLock) ASMJIT_PROPAGATE(sb.append("lock "));
// REP|REPNE options.
if (options & (Inst::kOptionRep | Inst::kOptionRepne)) {
- sb.appendString((options & Inst::kOptionRep) ? "rep " : "repnz ");
+ sb.append((options & Inst::kOptionRep) ? "rep " : "repnz ");
if (inst.hasExtraReg()) {
- ASMJIT_PROPAGATE(sb.appendString("{"));
- ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, archId, inst.extraReg().toReg<BaseReg>()));
- ASMJIT_PROPAGATE(sb.appendString("} "));
+ ASMJIT_PROPAGATE(sb.append("{"));
+ ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, inst.extraReg().toReg<BaseReg>()));
+ ASMJIT_PROPAGATE(sb.append("} "));
}
}
@@ -715,23 +841,23 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatInstruction(
Inst::kOptionOpCodeB |
Inst::kOptionOpCodeW ;
if (options & kRXBWMask) {
- sb.appendString("rex.");
- if (options & Inst::kOptionOpCodeR) sb.appendChar('r');
- if (options & Inst::kOptionOpCodeX) sb.appendChar('x');
- if (options & Inst::kOptionOpCodeB) sb.appendChar('b');
- if (options & Inst::kOptionOpCodeW) sb.appendChar('w');
- sb.appendChar(' ');
+ sb.append("rex.");
+ if (options & Inst::kOptionOpCodeR) sb.append('r');
+ if (options & Inst::kOptionOpCodeX) sb.append('x');
+ if (options & Inst::kOptionOpCodeB) sb.append('b');
+ if (options & Inst::kOptionOpCodeW) sb.append('w');
+ sb.append(' ');
}
else {
- ASMJIT_PROPAGATE(sb.appendString("rex "));
+ ASMJIT_PROPAGATE(sb.append("rex "));
}
}
// VEX|EVEX options.
- if (options & Inst::kOptionVex3) ASMJIT_PROPAGATE(sb.appendString("vex3 "));
- if (options & Inst::kOptionEvex) ASMJIT_PROPAGATE(sb.appendString("evex "));
+ if (options & Inst::kOptionVex3) ASMJIT_PROPAGATE(sb.append("vex3 "));
+ if (options & Inst::kOptionEvex) ASMJIT_PROPAGATE(sb.append("evex "));
- ASMJIT_PROPAGATE(InstAPI::instIdToString(archId, instId, sb));
+ ASMJIT_PROPAGATE(InstAPI::instIdToString(arch, instId, sb));
}
else {
ASMJIT_PROPAGATE(sb.appendFormat("[InstId=#%u]", unsigned(instId)));
@@ -741,29 +867,29 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatInstruction(
const Operand_& op = operands[i];
if (op.isNone()) break;
- ASMJIT_PROPAGATE(sb.appendString(i == 0 ? " " : ", "));
- ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, archId, op));
+ ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
+ ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, op));
if (op.isImm() && (flags & FormatOptions::kFlagExplainImms)) {
uint32_t vecSize = 16;
for (uint32_t j = 0; j < opCount; j++)
if (operands[j].isReg())
vecSize = Support::max<uint32_t>(vecSize, operands[j].size());
- ASMJIT_PROPAGATE(LoggingInternal_explainConst(sb, flags, instId, vecSize, op.as<Imm>()));
+ ASMJIT_PROPAGATE(FormatterInternal_explainConst(sb, flags, instId, vecSize, op.as<Imm>()));
}
// Support AVX-512 masking - {k}{z}.
if (i == 0) {
if (inst.extraReg().group() == Reg::kGroupKReg) {
- ASMJIT_PROPAGATE(sb.appendString(" {"));
- ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, archId, inst.extraReg().type(), inst.extraReg().id()));
- ASMJIT_PROPAGATE(sb.appendChar('}'));
+ ASMJIT_PROPAGATE(sb.append(" {"));
+ ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, inst.extraReg().type(), inst.extraReg().id()));
+ ASMJIT_PROPAGATE(sb.append('}'));
if (options & Inst::kOptionZMask)
- ASMJIT_PROPAGATE(sb.appendString("{z}"));
+ ASMJIT_PROPAGATE(sb.append("{z}"));
}
else if (options & Inst::kOptionZMask) {
- ASMJIT_PROPAGATE(sb.appendString(" {z}"));
+ ASMJIT_PROPAGATE(sb.append(" {z}"));
}
}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86logging_p.h b/3rdparty/asmjit/src/asmjit/x86/x86formatter_p.h
index c0d7d16e3f2..d7d58e42d67 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86logging_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86formatter_p.h
@@ -21,52 +21,60 @@
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
-#ifndef ASMJIT_X86_X86LOGGING_P_H_INCLUDED
-#define ASMJIT_X86_X86LOGGING_P_H_INCLUDED
+#ifndef ASMJIT_X86_X86FORMATTER_P_H_INCLUDED
+#define ASMJIT_X86_X86FORMATTER_P_H_INCLUDED
#include "../core/api-config.h"
#ifndef ASMJIT_NO_LOGGING
-#include "../core/logging.h"
+#include "../core/formatter.h"
#include "../core/string.h"
#include "../x86/x86globals.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
+//! \cond INTERNAL
//! \addtogroup asmjit_x86
//! \{
// ============================================================================
-// [asmjit::x86::LoggingInternal]
+// [asmjit::x86::FormatterInternal]
// ============================================================================
-namespace LoggingInternal {
- Error formatRegister(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- uint32_t regType,
- uint32_t regId) noexcept;
+namespace FormatterInternal {
- Error formatOperand(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- const Operand_& op) noexcept;
+Error formatFeature(
+ String& sb,
+ uint32_t featureId) noexcept;
- Error formatInstruction(
- String& sb,
- uint32_t flags,
- const BaseEmitter* emitter,
- uint32_t archId,
- const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept;
-};
+Error formatRegister(
+ String& sb,
+ uint32_t flags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ uint32_t regType,
+ uint32_t regId) noexcept;
+
+Error formatOperand(
+ String& sb,
+ uint32_t flags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ const Operand_& op) noexcept;
+
+Error formatInstruction(
+ String& sb,
+ uint32_t flags,
+ const BaseEmitter* emitter,
+ uint32_t arch,
+ const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;
+
+} // {FormatterInternal}
//! \}
+//! \endcond
ASMJIT_END_SUB_NAMESPACE
#endif // !ASMJIT_NO_LOGGING
-#endif // ASMJIT_X86_X86LOGGING_P_H_INCLUDED
+#endif // ASMJIT_X86_X86FORMATTER_P_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86globals.h b/3rdparty/asmjit/src/asmjit/x86/x86globals.h
index dca2b95732c..f7d258f3b62 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86globals.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86globals.h
@@ -1652,14 +1652,14 @@ namespace Condition {
kUnsignedGT = kA, //!< Unsigned `a > b`.
kUnsignedGE = kAE, //!< Unsigned `a >= b`.
- kZero = kZ,
- kNotZero = kNZ,
+ kZero = kZ, //!< Zero flag.
+ kNotZero = kNZ, //!< Non-zero flag.
- kNegative = kS,
- kPositive = kNS,
+ kNegative = kS, //!< Sign flag.
+ kPositive = kNS, //!< No sign flag.
- kParityEven = kP,
- kParityOdd = kPO
+ kParityEven = kP, //!< Even parity flag.
+ kParityOdd = kPO //!< Odd parity flag.
};
static constexpr uint8_t reverseTable[kCount] = {
@@ -1696,54 +1696,92 @@ namespace Condition {
// [asmjit::x86::FpuWord]
// ============================================================================
-//! FPU control and status word.
+//! FPU control and status words.
namespace FpuWord {
//! FPU status word.
enum Status : uint32_t {
+ //! Invalid operation.
kStatusInvalid = 0x0001u,
+ //! Denormalized operand.
kStatusDenormalized = 0x0002u,
+ //! Division by zero.
kStatusDivByZero = 0x0004u,
+ //! Overflown.
kStatusOverflow = 0x0008u,
+ //! Underflown.
kStatusUnderflow = 0x0010u,
+ //! Precision lost.
kStatusPrecision = 0x0020u,
+ //! Stack fault.
kStatusStackFault = 0x0040u,
+ //! Interrupt.
kStatusInterrupt = 0x0080u,
+ //! C0 flag.
kStatusC0 = 0x0100u,
+ //! C1 flag.
kStatusC1 = 0x0200u,
+ //! C2 flag.
kStatusC2 = 0x0400u,
+ //! Top of the stack.
kStatusTop = 0x3800u,
+ //! C3 flag.
kStatusC3 = 0x4000u,
+ //! FPU is busy.
kStatusBusy = 0x8000u
};
//! FPU control word.
enum Control : uint32_t {
- // Bits 0-5.
+ // [Bits 0-5]
+
+ //! Exception mask (0x3F).
kControlEM_Mask = 0x003Fu,
+ //! Invalid operation exception.
kControlEM_Invalid = 0x0001u,
+ //! Denormalized operand exception.
kControlEM_Denormal = 0x0002u,
+ //! Division by zero exception.
kControlEM_DivByZero = 0x0004u,
+ //! Overflow exception.
kControlEM_Overflow = 0x0008u,
+ //! Underflow exception.
kControlEM_Underflow = 0x0010u,
+ //! Inexact operation exception.
kControlEM_Inexact = 0x0020u,
- // Bits 8-9.
+ // [Bits 8-9]
+
+ //! Precision control mask.
kControlPC_Mask = 0x0300u,
+ //! Single precision (24 bits).
kControlPC_Float = 0x0000u,
+ //! Reserved.
kControlPC_Reserved = 0x0100u,
+ //! Double precision (53 bits).
kControlPC_Double = 0x0200u,
+ //! Extended precision (64 bits).
kControlPC_Extended = 0x0300u,
- // Bits 10-11.
+ // [Bits 10-11]
+
+ //! Rounding control mask.
kControlRC_Mask = 0x0C00u,
+ //! Round to nearest even.
kControlRC_Nearest = 0x0000u,
+ //! Round down (floor).
kControlRC_Down = 0x0400u,
+ //! Round up (ceil).
kControlRC_Up = 0x0800u,
+ //! Round towards zero (truncate).
kControlRC_Truncate = 0x0C00u,
- // Bit 12.
+ // [Bit 12]
+
+ //! Infinity control.
kControlIC_Mask = 0x1000u,
+ //! Projective (not supported on X64).
kControlIC_Projective = 0x0000u,
+ //! Affine (default).
kControlIC_Affine = 0x1000u
};
}
@@ -1760,26 +1798,39 @@ namespace Status {
// [Architecture Neutral Flags - 0x000000FF]
// ------------------------------------------------------------------------
- kCF = 0x00000001u, //!< Carry flag.
- kOF = 0x00000002u, //!< Signed overflow flag.
- kSF = 0x00000004u, //!< Sign flag (negative/sign, if set).
- kZF = 0x00000008u, //!< Zero and/or equality flag (1 if zero/equal).
+ //! Carry flag.
+ kCF = 0x00000001u,
+ //! Signed overflow flag.
+ kOF = 0x00000002u,
+ //! Sign flag (negative/sign, if set).
+ kSF = 0x00000004u,
+ //! Zero and/or equality flag (1 if zero/equal).
+ kZF = 0x00000008u,
// ------------------------------------------------------------------------
// [Architecture Specific Flags - 0xFFFFFF00]
// ------------------------------------------------------------------------
- kAF = 0x00000100u, //!< Adjust flag.
- kPF = 0x00000200u, //!< Parity flag.
- kDF = 0x00000400u, //!< Direction flag.
- kIF = 0x00000800u, //!< Interrupt enable flag.
-
- kAC = 0x00001000u, //!< Alignment check.
-
- kC0 = 0x00010000u, //!< FPU C0 status flag.
- kC1 = 0x00020000u, //!< FPU C1 status flag.
- kC2 = 0x00040000u, //!< FPU C2 status flag.
- kC3 = 0x00080000u //!< FPU C3 status flag.
+ //! Adjust flag.
+ kAF = 0x00000100u,
+ //! Parity flag.
+ kPF = 0x00000200u,
+ //! Direction flag.
+ kDF = 0x00000400u,
+ //! Interrupt enable flag.
+ kIF = 0x00000800u,
+
+ //! Alignment check.
+ kAC = 0x00001000u,
+
+ //! FPU C0 status flag.
+ kC0 = 0x00010000u,
+ //! FPU C1 status flag.
+ kC1 = 0x00020000u,
+ //! FPU C2 status flag.
+ kC2 = 0x00040000u,
+ //! FPU C3 status flag.
+ kC3 = 0x00080000u
};
}
@@ -1834,12 +1885,18 @@ namespace Predicate {
//! A predicate used by ROUND[PD|PS|SD|SS] instructions.
enum Round : uint32_t {
- kRoundNearest = 0x00u, //!< Round to nearest (even).
- kRoundDown = 0x01u, //!< Round to down toward -INF (floor),
- kRoundUp = 0x02u, //!< Round to up toward +INF (ceil).
- kRoundTrunc = 0x03u, //!< Round toward zero (truncate).
- kRoundCurrent = 0x04u, //!< Round to the current rounding mode set (ignores other RC bits).
- kRoundInexact = 0x08u //!< Avoids inexact exception, if set.
+ //! Round to nearest (even).
+ kRoundNearest = 0x00u,
+ //! Round to down toward -INF (floor),
+ kRoundDown = 0x01u,
+ //! Round to up toward +INF (ceil).
+ kRoundUp = 0x02u,
+ //! Round toward zero (truncate).
+ kRoundTrunc = 0x03u,
+ //! Round to the current rounding mode set (ignores other RC bits).
+ kRoundCurrent = 0x04u,
+ //! Avoids inexact exception, if set.
+ kRoundInexact = 0x08u
};
//! A predicate used by VCMP[PD|PS|SD|SS] instructions.
@@ -1998,25 +2055,46 @@ namespace Predicate {
//! Bitwise ternary logic between 3 operands introduced by AVX-512.
namespace TLog {
//! A predicate that can be used to create a common predicate for VPTERNLOG[D|Q].
+ //!
+ //! There are 3 inputs to the instruction (\ref kA, \ref kB, \ref kC), and
+ //! ternary logic can define any combination that would be performed on these
+ //! 3 inputs to get the desired output - any combination of AND, OR, XOR, NOT.
enum Operator : uint32_t {
- k0 = 0x00u, //!< 0 value.
- k1 = 0xFFu, //!< 1 value.
- kA = 0xF0u, //!< A value.
- kB = 0xCCu, //!< B value.
- kC = 0xAAu, //!< C value.
- kNotA = kA ^ k1, //!< `!A` expression.
- kNotB = kB ^ k1, //!< `!B` expression.
- kNotC = kC ^ k1, //!< `!C` expression.
-
- kAB = kA & kB, //!< `A & B` expression.
- kAC = kA & kC, //!< `A & C` expression.
- kBC = kB & kC, //!< `B & C` expression.
- kNotAB = kAB ^ k1, //!< `!(A & B)` expression.
- kNotAC = kAC ^ k1, //!< `!(A & C)` expression.
- kNotBC = kBC ^ k1, //!< `!(B & C)` expression.
-
- kABC = kAB & kC, //!< `A & B & C` expression.
- kNotABC = kABC ^ k1 //!< `!(A & B & C)` expression.
+ //! 0 value.
+ k0 = 0x00u,
+ //! 1 value.
+ k1 = 0xFFu,
+ //! A value.
+ kA = 0xF0u,
+ //! B value.
+ kB = 0xCCu,
+ //! C value.
+ kC = 0xAAu,
+
+ //! `!A` expression.
+ kNotA = kA ^ k1,
+ //! `!B` expression.
+ kNotB = kB ^ k1,
+ //! `!C` expression.
+ kNotC = kC ^ k1,
+
+ //! `A & B` expression.
+ kAB = kA & kB,
+ //! `A & C` expression.
+ kAC = kA & kC,
+ //! `B & C` expression.
+ kBC = kB & kC,
+ //! `!(A & B)` expression.
+ kNotAB = kAB ^ k1,
+ //! `!(A & C)` expression.
+ kNotAC = kAC ^ k1,
+ //! `!(B & C)` expression.
+ kNotBC = kBC ^ k1,
+
+ //! `A & B & C` expression.
+ kABC = kAB & kC,
+ //! `!(A & B & C)` expression.
+ kNotABC = kABC ^ k1
};
//! Creates an immediate that can be used by VPTERNLOG[D|Q] instructions.
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp b/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp
index 6c5e28be46a..82f782e0fc6 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp
@@ -58,18 +58,18 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// ============================================================================
#ifndef ASMJIT_NO_TEXT
-Error InstInternal::instIdToString(uint32_t archId, uint32_t instId, String& output) noexcept {
- DebugUtils::unused(archId);
+Error InstInternal::instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept {
+ DebugUtils::unused(arch);
if (ASMJIT_UNLIKELY(!Inst::isDefinedId(instId)))
return DebugUtils::errored(kErrorInvalidInstruction);
const InstDB::InstInfo& info = InstDB::infoById(instId);
- return output.appendString(InstDB::_nameData + info._nameDataIndex);
+ return output.append(InstDB::_nameData + info._nameDataIndex);
}
-uint32_t InstInternal::stringToInstId(uint32_t archId, const char* s, size_t len) noexcept {
- DebugUtils::unused(archId);
+uint32_t InstInternal::stringToInstId(uint32_t arch, const char* s, size_t len) noexcept {
+ DebugUtils::unused(arch);
if (ASMJIT_UNLIKELY(!s))
return Inst::kIdNone;
@@ -235,18 +235,18 @@ static ASMJIT_INLINE bool x86CheckOSig(const InstDB::OpSignature& op, const Inst
return true;
}
-ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept {
- // Only called when `archId` matches X86 family.
- ASMJIT_ASSERT(ArchInfo::isX86Family(archId));
+ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept {
+ // Only called when `arch` matches X86 family.
+ ASMJIT_ASSERT(Environment::isFamilyX86(arch));
const X86ValidationData* vd;
- if (archId == ArchInfo::kIdX86)
+ if (arch == Environment::kArchX86)
vd = &_x86ValidationData;
else
vd = &_x64ValidationData;
uint32_t i;
- uint32_t mode = InstDB::modeFromArchId(archId);
+ uint32_t mode = InstDB::modeFromArch(arch);
// Get the instruction data.
uint32_t instId = inst.id();
@@ -328,7 +328,6 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst&
// that the register is virtual and its index will be assigned later
// by the register allocator. We must pass unless asked to disallow
// virtual registers.
- // TODO: We need an option to refuse virtual regs here.
uint32_t regId = op.id();
if (regId < Operand::kVirtIdMin) {
if (ASMJIT_UNLIKELY(regId >= 32))
@@ -341,6 +340,8 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst&
combinedRegMask |= regMask;
}
else {
+ if (!(validationFlags & InstAPI::kValidationFlagVirtRegs))
+ return DebugUtils::errored(kErrorIllegalVirtReg);
regMask = 0xFFFFFFFFu;
}
break;
@@ -393,6 +394,9 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst&
// memory operand. Basically only usable for string instructions and other
// instructions where memory operand is implicit and has 'seg:[reg]' form.
if (baseId < Operand::kVirtIdMin) {
+ if (ASMJIT_UNLIKELY(baseId >= 32))
+ return DebugUtils::errored(kErrorInvalidPhysId);
+
// Physical base id.
regMask = Support::bitMask(baseId);
combinedRegMask |= regMask;
@@ -400,6 +404,8 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst&
else {
// Virtual base id - fill the whole mask for implicit mem validation.
// The register is not assigned yet, so we cannot predict the phys id.
+ if (!(validationFlags & InstAPI::kValidationFlagVirtRegs))
+ return DebugUtils::errored(kErrorIllegalVirtReg);
regMask = 0xFFFFFFFFu;
}
@@ -461,8 +467,16 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst&
return DebugUtils::errored(kErrorInvalidAddress);
uint32_t indexId = m.indexId();
- if (indexId < Operand::kVirtIdMin)
+ if (indexId < Operand::kVirtIdMin) {
+ if (ASMJIT_UNLIKELY(indexId >= 32))
+ return DebugUtils::errored(kErrorInvalidPhysId);
+
combinedRegMask |= Support::bitMask(indexId);
+ }
+ else {
+ if (!(validationFlags & InstAPI::kValidationFlagVirtRegs))
+ return DebugUtils::errored(kErrorIllegalVirtReg);
+ }
// Only used for implicit memory operands having 'seg:[reg]' form, so clear it.
regMask = 0;
@@ -490,7 +504,7 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst&
}
case Operand::kOpImm: {
- uint64_t immValue = op.as<Imm>().u64();
+ uint64_t immValue = op.as<Imm>().valueAs<uint64_t>();
uint32_t immFlags = 0;
if (int64_t(immValue) >= 0) {
@@ -574,7 +588,9 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t archId, const BaseInst&
}
else {
// Illegal use of a high 8-bit register with REX prefix.
- if (ASMJIT_UNLIKELY((combinedOpFlags & InstDB::kOpGpbHi) != 0 && (combinedRegMask & 0xFFFFFF00u) != 0))
+ bool hasREX = inst.hasOption(Inst::kOptionRex) ||
+ ((combinedRegMask & 0xFFFFFF00u) != 0);
+ if (ASMJIT_UNLIKELY(hasREX && (combinedOpFlags & InstDB::kOpGpbHi) != 0))
return DebugUtils::errored(kErrorInvalidUseOfGpbHi);
}
@@ -761,12 +777,6 @@ static const uint64_t rwRegGroupByteMask[Reg::kGroupCount] = {
0x00000000000000FFu // RIP.
};
-// TODO: Make universal.
-static ASMJIT_INLINE uint32_t gpRegSizeByArchId(uint32_t archId) noexcept {
- static const uint8_t table[] = { 0, 4, 8, 4, 8 };
- return table[archId];
-}
-
static ASMJIT_INLINE void rwZeroExtendGp(OpRWInfo& opRwInfo, const Gp& reg, uint32_t nativeGpSize) noexcept {
ASMJIT_ASSERT(BaseReg::isGp(reg.as<Operand>()));
if (reg.size() + 4 == nativeGpSize) {
@@ -793,11 +803,11 @@ static ASMJIT_INLINE void rwZeroExtendNonVec(OpRWInfo& opRwInfo, const Reg& reg)
}
}
-Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, InstRWInfo& out) noexcept {
+Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
using namespace Status;
- // Only called when `archId` matches X86 family.
- ASMJIT_ASSERT(ArchInfo::isX86Family(archId));
+ // Only called when `arch` matches X86 family.
+ ASMJIT_ASSERT(Environment::isFamilyX86(arch));
// Get the instruction data.
uint32_t instId = inst.id();
@@ -817,14 +827,14 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
const InstDB::RWInfo& instRwInfo = InstDB::rwInfo[InstDB::rwInfoIndex[instId * 2u + uint32_t(opCount != 2)]];
const InstDB::RWInfoRm& instRmInfo = InstDB::rwInfoRm[instRwInfo.rmInfo];
- out._instFlags = 0;
- out._opCount = uint8_t(opCount);
- out._rmFeature = instRmInfo.rmFeature;
- out._extraReg.reset();
- out._readFlags = rwFlags.readFlags;
- out._writeFlags = rwFlags.writeFlags;
+ out->_instFlags = 0;
+ out->_opCount = uint8_t(opCount);
+ out->_rmFeature = instRmInfo.rmFeature;
+ out->_extraReg.reset();
+ out->_readFlags = rwFlags.readFlags;
+ out->_writeFlags = rwFlags.writeFlags;
- uint32_t nativeGpSize = gpRegSizeByArchId(archId);
+ uint32_t nativeGpSize = Environment::registerSizeFromArch(arch);
constexpr uint32_t R = OpRWInfo::kRead;
constexpr uint32_t W = OpRWInfo::kWrite;
@@ -839,7 +849,7 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
uint32_t rmMaxSize = 0;
for (i = 0; i < opCount; i++) {
- OpRWInfo& op = out._operands[i];
+ OpRWInfo& op = out->_operands[i];
const Operand_& srcOp = operands[i];
const InstDB::RWInfoOp& rwOpData = InstDB::rwInfoOp[instRwInfo.opInfoIndex[i]];
@@ -893,7 +903,7 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
do {
i = it.next();
- OpRWInfo& op = out._operands[i];
+ OpRWInfo& op = out->_operands[i];
op.addOpFlags(RegM);
switch (instRmInfo.category) {
@@ -932,38 +942,38 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
const Reg& o1 = operands[1].as<Reg>();
if (o0.isGp() && o1.isGp()) {
- out._operands[0].reset(W | RegM, operands[0].size());
- out._operands[1].reset(R | RegM, operands[1].size());
+ out->_operands[0].reset(W | RegM, operands[0].size());
+ out->_operands[1].reset(R | RegM, operands[1].size());
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
return kErrorOk;
}
if (o0.isGp() && o1.isSReg()) {
- out._operands[0].reset(W | RegM, nativeGpSize);
- out._operands[0].setRmSize(2);
- out._operands[1].reset(R, 2);
+ out->_operands[0].reset(W | RegM, nativeGpSize);
+ out->_operands[0].setRmSize(2);
+ out->_operands[1].reset(R, 2);
return kErrorOk;
}
if (o0.isSReg() && o1.isGp()) {
- out._operands[0].reset(W, 2);
- out._operands[1].reset(R | RegM, 2);
- out._operands[1].setRmSize(2);
+ out->_operands[0].reset(W, 2);
+ out->_operands[1].reset(R | RegM, 2);
+ out->_operands[1].setRmSize(2);
return kErrorOk;
}
if (o0.isGp() && (o1.isCReg() || o1.isDReg())) {
- out._operands[0].reset(W, nativeGpSize);
- out._operands[1].reset(R, nativeGpSize);
- out._writeFlags = kOF | kSF | kZF | kAF | kPF | kCF;
+ out->_operands[0].reset(W, nativeGpSize);
+ out->_operands[1].reset(R, nativeGpSize);
+ out->_writeFlags = kOF | kSF | kZF | kAF | kPF | kCF;
return kErrorOk;
}
if ((o0.isCReg() || o0.isDReg()) && o1.isGp()) {
- out._operands[0].reset(W, nativeGpSize);
- out._operands[1].reset(R, nativeGpSize);
- out._writeFlags = kOF | kSF | kZF | kAF | kPF | kCF;
+ out->_operands[0].reset(W, nativeGpSize);
+ out->_operands[1].reset(R, nativeGpSize);
+ out->_writeFlags = kOF | kSF | kZF | kAF | kPF | kCF;
return kErrorOk;
}
}
@@ -974,18 +984,18 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
if (o0.isGp()) {
if (!o1.isOffset64Bit())
- out._operands[0].reset(W, o0.size());
+ out->_operands[0].reset(W, o0.size());
else
- out._operands[0].reset(W | RegPhys, o0.size(), Gp::kIdAx);
+ out->_operands[0].reset(W | RegPhys, o0.size(), Gp::kIdAx);
- out._operands[1].reset(R | MibRead, o0.size());
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
+ out->_operands[1].reset(R | MibRead, o0.size());
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
return kErrorOk;
}
if (o0.isSReg()) {
- out._operands[0].reset(W, 2);
- out._operands[1].reset(R, 2);
+ out->_operands[0].reset(W, 2);
+ out->_operands[1].reset(R, 2);
return kErrorOk;
}
}
@@ -995,34 +1005,34 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
const Reg& o1 = operands[1].as<Reg>();
if (o1.isGp()) {
- out._operands[0].reset(W | MibRead, o1.size());
+ out->_operands[0].reset(W | MibRead, o1.size());
if (!o0.isOffset64Bit())
- out._operands[1].reset(R, o1.size());
+ out->_operands[1].reset(R, o1.size());
else
- out._operands[1].reset(R | RegPhys, o1.size(), Gp::kIdAx);
+ out->_operands[1].reset(R | RegPhys, o1.size(), Gp::kIdAx);
return kErrorOk;
}
if (o1.isSReg()) {
- out._operands[0].reset(W | MibRead, 2);
- out._operands[1].reset(R, 2);
+ out->_operands[0].reset(W | MibRead, 2);
+ out->_operands[1].reset(R, 2);
return kErrorOk;
}
}
if (Reg::isGp(operands[0]) && operands[1].isImm()) {
const Reg& o0 = operands[0].as<Reg>();
- out._operands[0].reset(W | RegM, o0.size());
- out._operands[1].reset();
+ out->_operands[0].reset(W | RegM, o0.size());
+ out->_operands[1].reset();
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
return kErrorOk;
}
if (operands[0].isMem() && operands[1].isImm()) {
const Reg& o0 = operands[0].as<Reg>();
- out._operands[0].reset(W | MibRead, o0.size());
- out._operands[1].reset();
+ out->_operands[0].reset(W | MibRead, o0.size());
+ out->_operands[1].reset();
return kErrorOk;
}
}
@@ -1040,51 +1050,51 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
if (opCount == 2) {
if (operands[0].isReg() && operands[1].isImm()) {
- out._operands[0].reset(X, operands[0].size());
- out._operands[1].reset();
+ out->_operands[0].reset(X, operands[0].size());
+ out->_operands[1].reset();
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
return kErrorOk;
}
if (Reg::isGpw(operands[0]) && operands[1].size() == 1) {
// imul ax, r8/m8 <- AX = AL * r8/m8
- out._operands[0].reset(X | RegPhys, 2, Gp::kIdAx);
- out._operands[0].setReadByteMask(Support::lsbMask<uint64_t>(1));
- out._operands[1].reset(R | RegM, 1);
+ out->_operands[0].reset(X | RegPhys, 2, Gp::kIdAx);
+ out->_operands[0].setReadByteMask(Support::lsbMask<uint64_t>(1));
+ out->_operands[1].reset(R | RegM, 1);
}
else {
// imul r?, r?/m?
- out._operands[0].reset(X, operands[0].size());
- out._operands[1].reset(R | RegM, operands[0].size());
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
+ out->_operands[0].reset(X, operands[0].size());
+ out->_operands[1].reset(R | RegM, operands[0].size());
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
}
if (operands[1].isMem())
- out._operands[1].addOpFlags(MibRead);
+ out->_operands[1].addOpFlags(MibRead);
return kErrorOk;
}
if (opCount == 3) {
if (operands[2].isImm()) {
- out._operands[0].reset(W, operands[0].size());
- out._operands[1].reset(R | RegM, operands[1].size());
- out._operands[2].reset();
+ out->_operands[0].reset(W, operands[0].size());
+ out->_operands[1].reset(R | RegM, operands[1].size());
+ out->_operands[2].reset();
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
if (operands[1].isMem())
- out._operands[1].addOpFlags(MibRead);
+ out->_operands[1].addOpFlags(MibRead);
return kErrorOk;
}
else {
- out._operands[0].reset(W | RegPhys, operands[0].size(), Gp::kIdDx);
- out._operands[1].reset(X | RegPhys, operands[1].size(), Gp::kIdAx);
- out._operands[2].reset(R | RegM, operands[2].size());
+ out->_operands[0].reset(W | RegPhys, operands[0].size(), Gp::kIdDx);
+ out->_operands[1].reset(X | RegPhys, operands[1].size(), Gp::kIdAx);
+ out->_operands[2].reset(R | RegM, operands[2].size());
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
- rwZeroExtendGp(out._operands[1], operands[1].as<Gp>(), nativeGpSize);
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
+ rwZeroExtendGp(out->_operands[1], operands[1].as<Gp>(), nativeGpSize);
if (operands[2].isMem())
- out._operands[2].addOpFlags(MibRead);
+ out->_operands[2].addOpFlags(MibRead);
return kErrorOk;
}
}
@@ -1097,16 +1107,16 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
// 2 or 3 operands that are use `kCategoryGeneric`.
if (opCount == 2) {
if (BaseReg::isVec(operands[0]) && operands[1].isMem()) {
- out._operands[0].reset(W, 8);
- out._operands[0].setWriteByteMask(Support::lsbMask<uint64_t>(8) << 8);
- out._operands[1].reset(R | MibRead, 8);
+ out->_operands[0].reset(W, 8);
+ out->_operands[0].setWriteByteMask(Support::lsbMask<uint64_t>(8) << 8);
+ out->_operands[1].reset(R | MibRead, 8);
return kErrorOk;
}
if (operands[0].isMem() && BaseReg::isVec(operands[1])) {
- out._operands[0].reset(W | MibRead, 8);
- out._operands[1].reset(R, 8);
- out._operands[1].setReadByteMask(Support::lsbMask<uint64_t>(8) << 8);
+ out->_operands[0].reset(W | MibRead, 8);
+ out->_operands[1].reset(R, 8);
+ out->_operands[1].setReadByteMask(Support::lsbMask<uint64_t>(8) << 8);
return kErrorOk;
}
}
@@ -1117,18 +1127,18 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
// Special case for 'vmaskmovpd|vmaskmovps|vpmaskmovd|vpmaskmovq' instructions.
if (opCount == 3) {
if (BaseReg::isVec(operands[0]) && BaseReg::isVec(operands[1]) && operands[2].isMem()) {
- out._operands[0].reset(W, operands[0].size());
- out._operands[1].reset(R, operands[1].size());
- out._operands[2].reset(R | MibRead, operands[1].size());
+ out->_operands[0].reset(W, operands[0].size());
+ out->_operands[1].reset(R, operands[1].size());
+ out->_operands[2].reset(R | MibRead, operands[1].size());
- rwZeroExtendAvxVec(out._operands[0], operands[0].as<Vec>());
+ rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
return kErrorOk;
}
if (operands[0].isMem() && BaseReg::isVec(operands[1]) && BaseReg::isVec(operands[2])) {
- out._operands[0].reset(X | MibRead, operands[1].size());
- out._operands[1].reset(R, operands[1].size());
- out._operands[2].reset(R, operands[2].size());
+ out->_operands[0].reset(X | MibRead, operands[1].size());
+ out->_operands[1].reset(R, operands[1].size());
+ out->_operands[2].reset(R, operands[2].size());
return kErrorOk;
}
}
@@ -1145,11 +1155,11 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
uint32_t o0Size = operands[0].size();
uint32_t o1Size = o0Size == 16 ? 8 : o0Size;
- out._operands[0].reset(W, o0Size);
- out._operands[1].reset(R | RegM, o1Size);
- out._operands[1]._readByteMask &= 0x00FF00FF00FF00FFu;
+ out->_operands[0].reset(W, o0Size);
+ out->_operands[1].reset(R | RegM, o1Size);
+ out->_operands[1]._readByteMask &= 0x00FF00FF00FF00FFu;
- rwZeroExtendAvxVec(out._operands[0], operands[0].as<Vec>());
+ rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
return kErrorOk;
}
@@ -1157,10 +1167,10 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
uint32_t o0Size = operands[0].size();
uint32_t o1Size = o0Size == 16 ? 8 : o0Size;
- out._operands[0].reset(W, o0Size);
- out._operands[1].reset(R | MibRead, o1Size);
+ out->_operands[0].reset(W, o0Size);
+ out->_operands[1].reset(R | MibRead, o1Size);
- rwZeroExtendAvxVec(out._operands[0], operands[0].as<Vec>());
+ rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
return kErrorOk;
}
}
@@ -1172,9 +1182,9 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
// Special case for 'vmovmskpd|vmovmskps' instructions.
if (opCount == 2) {
if (BaseReg::isGp(operands[0]) && BaseReg::isVec(operands[1])) {
- out._operands[0].reset(W, 1);
- out._operands[0].setExtendByteMask(Support::lsbMask<uint32_t>(nativeGpSize - 1) << 1);
- out._operands[1].reset(R, operands[1].size());
+ out->_operands[0].reset(W, 1);
+ out->_operands[0].setExtendByteMask(Support::lsbMask<uint32_t>(nativeGpSize - 1) << 1);
+ out->_operands[1].reset(R, operands[1].size());
return kErrorOk;
}
}
@@ -1208,32 +1218,32 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
if (opCount >= 3) {
if (opCount > 3)
return DebugUtils::errored(kErrorInvalidInstruction);
- out._operands[2].reset();
+ out->_operands[2].reset();
}
if (operands[0].isReg() && operands[1].isReg()) {
uint32_t size1 = operands[1].size();
uint32_t size0 = size1 >> shift;
- out._operands[0].reset(W, size0);
- out._operands[1].reset(R, size1);
+ out->_operands[0].reset(W, size0);
+ out->_operands[1].reset(R, size1);
if (instRmInfo.rmOpsMask & 0x1) {
- out._operands[0].addOpFlags(RegM);
- out._operands[0].setRmSize(size0);
+ out->_operands[0].addOpFlags(RegM);
+ out->_operands[0].setRmSize(size0);
}
if (instRmInfo.rmOpsMask & 0x2) {
- out._operands[1].addOpFlags(RegM);
- out._operands[1].setRmSize(size1);
+ out->_operands[1].addOpFlags(RegM);
+ out->_operands[1].setRmSize(size1);
}
// Handle 'pmovmskb|vpmovmskb'.
if (BaseReg::isGp(operands[0]))
- rwZeroExtendGp(out._operands[0], operands[0].as<Gp>(), nativeGpSize);
+ rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
if (BaseReg::isVec(operands[0]))
- rwZeroExtendAvxVec(out._operands[0], operands[0].as<Vec>());
+ rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
return kErrorOk;
}
@@ -1242,8 +1252,8 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
uint32_t size1 = operands[1].size() ? operands[1].size() : uint32_t(16);
uint32_t size0 = size1 >> shift;
- out._operands[0].reset(W, size0);
- out._operands[1].reset(R | MibRead, size1);
+ out->_operands[0].reset(W, size0);
+ out->_operands[1].reset(R | MibRead, size1);
return kErrorOk;
}
@@ -1251,8 +1261,8 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
uint32_t size1 = operands[1].size();
uint32_t size0 = size1 >> shift;
- out._operands[0].reset(W | MibRead, size0);
- out._operands[1].reset(R, size1);
+ out->_operands[0].reset(W | MibRead, size0);
+ out->_operands[1].reset(R, size1);
return kErrorOk;
}
}
@@ -1285,30 +1295,30 @@ Error InstInternal::queryRWInfo(uint32_t archId, const BaseInst& inst, const Ope
if (opCount >= 3) {
if (opCount > 3)
return DebugUtils::errored(kErrorInvalidInstruction);
- out._operands[2].reset();
+ out->_operands[2].reset();
}
uint32_t size0 = operands[0].size();
uint32_t size1 = size0 >> shift;
- out._operands[0].reset(W, size0);
- out._operands[1].reset(R, size1);
+ out->_operands[0].reset(W, size0);
+ out->_operands[1].reset(R, size1);
if (operands[0].isReg() && operands[1].isReg()) {
if (instRmInfo.rmOpsMask & 0x1) {
- out._operands[0].addOpFlags(RegM);
- out._operands[0].setRmSize(size0);
+ out->_operands[0].addOpFlags(RegM);
+ out->_operands[0].setRmSize(size0);
}
if (instRmInfo.rmOpsMask & 0x2) {
- out._operands[1].addOpFlags(RegM);
- out._operands[1].setRmSize(size1);
+ out->_operands[1].addOpFlags(RegM);
+ out->_operands[1].setRmSize(size1);
}
return kErrorOk;
}
if (operands[0].isReg() && operands[1].isMem()) {
- out._operands[1].addOpFlags(MibRead);
+ out->_operands[1].addOpFlags(MibRead);
return kErrorOk;
}
}
@@ -1334,7 +1344,7 @@ struct RegAnalysis {
}
};
-static RegAnalysis InstInternal_regAnalysis(const Operand_* operands, uint32_t opCount) noexcept {
+static RegAnalysis InstInternal_regAnalysis(const Operand_* operands, size_t opCount) noexcept {
uint32_t mask = 0;
uint32_t highVecUsed = 0;
@@ -1359,10 +1369,10 @@ static RegAnalysis InstInternal_regAnalysis(const Operand_* operands, uint32_t o
return RegAnalysis { mask, highVecUsed };
}
-Error InstInternal::queryFeatures(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, BaseFeatures& out) noexcept {
- // Only called when `archId` matches X86 family.
- DebugUtils::unused(archId);
- ASMJIT_ASSERT(ArchInfo::isX86Family(archId));
+Error InstInternal::queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept {
+ // Only called when `arch` matches X86 family.
+ DebugUtils::unused(arch);
+ ASMJIT_ASSERT(Environment::isFamilyX86(arch));
// Get the instruction data.
uint32_t instId = inst.id();
@@ -1378,12 +1388,12 @@ Error InstInternal::queryFeatures(uint32_t archId, const BaseInst& inst, const O
const uint8_t* fEnd = tableB.featuresEnd();
// Copy all features to `out`.
- out.reset();
+ out->reset();
do {
uint32_t feature = fData[0];
if (!feature)
break;
- out.add(feature);
+ out->add(feature);
} while (++fData != fEnd);
// Since AsmJit aggregates instructions that share the same name we have to
@@ -1392,19 +1402,19 @@ Error InstInternal::queryFeatures(uint32_t archId, const BaseInst& inst, const O
RegAnalysis regAnalysis = InstInternal_regAnalysis(operands, opCount);
// Handle MMX vs SSE overlap.
- if (out.has(Features::kMMX) || out.has(Features::kMMX2)) {
+ if (out->has(Features::kMMX) || out->has(Features::kMMX2)) {
// Only instructions defined by SSE and SSE2 overlap. Instructions
// introduced by newer instruction sets like SSE3+ don't state MMX as
// they require SSE3+.
- if (out.has(Features::kSSE) || out.has(Features::kSSE2)) {
+ if (out->has(Features::kSSE) || out->has(Features::kSSE2)) {
if (!regAnalysis.hasRegType(Reg::kTypeXmm)) {
// The instruction doesn't use XMM register(s), thus it's MMX/MMX2 only.
- out.remove(Features::kSSE);
- out.remove(Features::kSSE2);
+ out->remove(Features::kSSE);
+ out->remove(Features::kSSE2);
}
else {
- out.remove(Features::kMMX);
- out.remove(Features::kMMX2);
+ out->remove(Features::kMMX);
+ out->remove(Features::kMMX2);
}
// Special case: PEXTRW instruction is MMX/SSE2 instruction. However,
@@ -1414,34 +1424,34 @@ Error InstInternal::queryFeatures(uint32_t archId, const BaseInst& inst, const O
// can extract directly to memory. This instruction is, of course, not
// compatible with MMX/SSE2 and would #UD if SSE4.1 is not supported.
if (instId == Inst::kIdPextrw) {
- ASMJIT_ASSERT(out.has(Features::kSSE2));
- ASMJIT_ASSERT(out.has(Features::kSSE4_1));
+ ASMJIT_ASSERT(out->has(Features::kSSE2));
+ ASMJIT_ASSERT(out->has(Features::kSSE4_1));
if (opCount >= 1 && operands[0].isMem())
- out.remove(Features::kSSE2);
+ out->remove(Features::kSSE2);
else
- out.remove(Features::kSSE4_1);
+ out->remove(Features::kSSE4_1);
}
}
}
// Handle PCLMULQDQ vs VPCLMULQDQ.
- if (out.has(Features::kVPCLMULQDQ)) {
+ if (out->has(Features::kVPCLMULQDQ)) {
if (regAnalysis.hasRegType(Reg::kTypeZmm) || Support::bitTest(options, Inst::kOptionEvex)) {
// AVX512_F & VPCLMULQDQ.
- out.remove(Features::kAVX, Features::kPCLMULQDQ);
+ out->remove(Features::kAVX, Features::kPCLMULQDQ);
}
else if (regAnalysis.hasRegType(Reg::kTypeYmm)) {
- out.remove(Features::kAVX512_F, Features::kAVX512_VL);
+ out->remove(Features::kAVX512_F, Features::kAVX512_VL);
}
else {
// AVX & PCLMULQDQ.
- out.remove(Features::kAVX512_F, Features::kAVX512_VL, Features::kVPCLMULQDQ);
+ out->remove(Features::kAVX512_F, Features::kAVX512_VL, Features::kVPCLMULQDQ);
}
}
// Handle AVX vs AVX2 overlap.
- if (out.has(Features::kAVX) && out.has(Features::kAVX2)) {
+ if (out->has(Features::kAVX) && out->has(Features::kAVX2)) {
bool isAVX2 = true;
// Special case: VBROADCASTSS and VBROADCASTSD were introduced in AVX, but
// only version that uses memory as a source operand. AVX2 then added support
@@ -1459,15 +1469,15 @@ Error InstInternal::queryFeatures(uint32_t archId, const BaseInst& inst, const O
}
if (isAVX2)
- out.remove(Features::kAVX);
+ out->remove(Features::kAVX);
else
- out.remove(Features::kAVX2);
+ out->remove(Features::kAVX2);
}
// Handle AVX|AVX2|FMA|F16C vs AVX512 overlap.
- if (out.has(Features::kAVX) || out.has(Features::kAVX2) || out.has(Features::kFMA) || out.has(Features::kF16C)) {
+ if (out->has(Features::kAVX) || out->has(Features::kAVX2) || out->has(Features::kFMA) || out->has(Features::kF16C)) {
// Only AVX512-F|BW|DQ allow to encode AVX/AVX2/FMA/F16C instructions
- if (out.has(Features::kAVX512_F) || out.has(Features::kAVX512_BW) || out.has(Features::kAVX512_DQ)) {
+ if (out->has(Features::kAVX512_F) || out->has(Features::kAVX512_BW) || out->has(Features::kAVX512_DQ)) {
uint32_t hasEvex = options & (Inst::kOptionEvex | Inst::_kOptionAvx512Mask);
uint32_t hasKMask = inst.extraReg().type() == Reg::kTypeKReg;
uint32_t hasKOrZmm = regAnalysis.regTypeMask & Support::bitMask(Reg::kTypeZmm, Reg::kTypeKReg);
@@ -1500,15 +1510,15 @@ Error InstInternal::queryFeatures(uint32_t archId, const BaseInst& inst, const O
}
if (!(hasEvex | mustUseEvex | hasKMask | hasKOrZmm | regAnalysis.highVecUsed))
- out.remove(Features::kAVX512_F, Features::kAVX512_BW, Features::kAVX512_DQ, Features::kAVX512_VL);
+ out->remove(Features::kAVX512_F, Features::kAVX512_BW, Features::kAVX512_DQ, Features::kAVX512_VL);
else
- out.remove(Features::kAVX, Features::kAVX2, Features::kFMA, Features::kF16C);
+ out->remove(Features::kAVX, Features::kAVX2, Features::kFMA, Features::kF16C);
}
}
// Clear AVX512_VL if ZMM register is used.
if (regAnalysis.hasRegType(Reg::kTypeZmm))
- out.remove(Features::kAVX512_VL);
+ out->remove(Features::kAVX512_VL);
}
return kErrorOk;
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h b/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h
index 0389cf562a9..83b3f77cf6d 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h
@@ -36,17 +36,17 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
namespace InstInternal {
#ifndef ASMJIT_NO_TEXT
-Error instIdToString(uint32_t archId, uint32_t instId, String& output) noexcept;
-uint32_t stringToInstId(uint32_t archId, const char* s, size_t len) noexcept;
+Error instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept;
+uint32_t stringToInstId(uint32_t arch, const char* s, size_t len) noexcept;
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_VALIDATION
-Error validate(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept;
+Error validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept;
#endif // !ASMJIT_NO_VALIDATION
#ifndef ASMJIT_NO_INTROSPECTION
-Error queryRWInfo(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, InstRWInfo& out) noexcept;
-Error queryFeatures(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, BaseFeatures& out) noexcept;
+Error queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
+Error queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept;
#endif // !ASMJIT_NO_INTROSPECTION
} // {InstInternal}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp b/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp
index 2d4855848f8..72ad0989c26 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp
@@ -537,7 +537,7 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
INST(Movsldup , ExtRm , O(F30F00,12,_,_,_,_,_,_ ), 0 , 6 , 0 , 6179 , 5 , 6 ), // #440
INST(Movss , ExtMov , O(F30F00,10,_,_,_,_,_,_ ), O(F30F00,11,_,_,_,_,_,_ ), 6 , 61 , 6189 , 124, 5 ), // #441
INST(Movsx , X86MovsxMovzx , O(000F00,BE,_,_,x,_,_,_ ), 0 , 4 , 0 , 1962 , 125, 0 ), // #442
- INST(Movsxd , X86Rm , O(000000,63,_,_,1,_,_,_ ), 0 , 20 , 0 , 1968 , 126, 0 ), // #443
+ INST(Movsxd , X86Rm , O(000000,63,_,_,x,_,_,_ ), 0 , 0 , 0 , 1968 , 126, 0 ), // #443
INST(Movupd , ExtMov , O(660F00,10,_,_,_,_,_,_ ), O(660F00,11,_,_,_,_,_,_ ), 3 , 62 , 6196 , 107, 4 ), // #444
INST(Movups , ExtMov , O(000F00,10,_,_,_,_,_,_ ), O(000F00,11,_,_,_,_,_,_ ), 4 , 63 , 6204 , 107, 5 ), // #445
INST(Movzx , X86MovsxMovzx , O(000F00,B6,_,_,x,_,_,_ ), 0 , 4 , 0 , 1975 , 125, 0 ), // #446
@@ -1610,7 +1610,7 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
// ${MainOpcodeTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
const uint32_t InstDB::_mainOpcodeTable[] = {
- O(000000,00,0,0,0,0,0,_ ), // #0 [ref=55x]
+ O(000000,00,0,0,0,0,0,_ ), // #0 [ref=56x]
O(000000,00,2,0,0,0,0,_ ), // #1 [ref=4x]
O(660F38,00,0,0,0,0,0,_ ), // #2 [ref=42x]
O(660F00,00,0,0,0,0,0,_ ), // #3 [ref=38x]
@@ -1630,7 +1630,7 @@ const uint32_t InstDB::_mainOpcodeTable[] = {
V(000F38,00,2,0,0,0,0,_ ), // #17 [ref=1x]
V(000F38,00,1,0,0,0,0,_ ), // #18 [ref=1x]
O(660000,00,0,0,0,0,0,_ ), // #19 [ref=7x]
- O(000000,00,0,0,1,0,0,_ ), // #20 [ref=4x]
+ O(000000,00,0,0,1,0,0,_ ), // #20 [ref=3x]
O(000F01,00,0,0,0,0,0,_ ), // #21 [ref=25x]
O(000F00,00,7,0,0,0,0,_ ), // #22 [ref=5x]
O(660F00,00,7,0,0,0,0,_ ), // #23 [ref=2x]
@@ -1991,8 +1991,8 @@ const uint32_t InstDB::_altOpcodeTable[] = {
#define SINGLE_REG(VAL) InstDB::kSingleReg##VAL
const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ 0 , 0 , 0 , CONTROL(None) , SINGLE_REG(None), 0 }, // #0 [ref=1x]
- { 0 , 339, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #1 [ref=4x]
- { 0 , 340, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #2 [ref=2x]
+ { 0 , 341, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #1 [ref=4x]
+ { 0 , 342, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #2 [ref=2x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 16 , 12, CONTROL(None) , SINGLE_REG(None), 0 }, // #3 [ref=2x]
{ 0 , 151, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #4 [ref=2x]
{ F(Vec) , 70 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #5 [ref=54x]
@@ -2002,173 +2002,173 @@ const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ F(Lock)|F(XAcquire)|F(XRelease) , 28 , 11, CONTROL(None) , SINGLE_REG(RO) , 0 }, // #9 [ref=1x]
{ F(Vex) , 237, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #10 [ref=3x]
{ F(Vec) , 70 , 1 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #11 [ref=12x]
- { 0 , 341, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #12 [ref=1x]
+ { 0 , 343, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #12 [ref=1x]
{ F(Vex) , 239, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #13 [ref=5x]
{ F(Vex) , 151, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #14 [ref=12x]
- { F(Vec) , 342, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #15 [ref=4x]
+ { F(Vec) , 344, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #15 [ref=4x]
{ 0 , 241, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #16 [ref=3x]
- { F(Mib) , 343, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #17 [ref=1x]
- { 0 , 344, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #18 [ref=1x]
+ { F(Mib) , 345, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #17 [ref=1x]
+ { 0 , 346, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #18 [ref=1x]
{ 0 , 243, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #19 [ref=1x]
- { F(Mib) , 345, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #20 [ref=1x]
+ { F(Mib) , 347, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #20 [ref=1x]
{ 0 , 245, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #21 [ref=1x]
{ 0 , 150, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #22 [ref=35x]
- { 0 , 346, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #23 [ref=3x]
+ { 0 , 348, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #23 [ref=3x]
{ 0 , 114, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #24 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 114, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #25 [ref=3x]
{ F(Rep)|F(RepIgnored) , 247, 2 , CONTROL(Call) , SINGLE_REG(None), 0 }, // #26 [ref=1x]
- { 0 , 347, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #27 [ref=1x]
- { 0 , 348, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #28 [ref=2x]
- { 0 , 322, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #29 [ref=1x]
+ { 0 , 349, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #27 [ref=1x]
+ { 0 , 350, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #28 [ref=2x]
+ { 0 , 324, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #29 [ref=1x]
{ 0 , 257, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #30 [ref=74x]
- { 0 , 349, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #31 [ref=24x]
- { 0 , 350, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #32 [ref=1x]
+ { 0 , 351, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #31 [ref=24x]
+ { 0 , 352, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #32 [ref=1x]
{ 0 , 16 , 12, CONTROL(None) , SINGLE_REG(None), 0 }, // #33 [ref=1x]
- { F(Rep) , 351, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #34 [ref=1x]
- { F(Vec) , 352, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #35 [ref=2x]
- { F(Vec) , 353, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #36 [ref=3x]
+ { F(Rep) , 353, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #34 [ref=1x]
+ { F(Vec) , 354, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #35 [ref=2x]
+ { F(Vec) , 355, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #36 [ref=3x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 118, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #37 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 354, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #38 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 355, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #39 [ref=1x]
- { 0 , 356, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #40 [ref=1x]
- { 0 , 357, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #41 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 356, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #38 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 357, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #39 [ref=1x]
+ { 0 , 358, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #40 [ref=1x]
+ { 0 , 359, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #41 [ref=1x]
{ 0 , 249, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #42 [ref=1x]
- { F(Mmx)|F(Vec) , 358, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #43 [ref=2x]
- { F(Mmx)|F(Vec) , 359, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #44 [ref=2x]
- { F(Mmx)|F(Vec) , 360, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #45 [ref=2x]
- { F(Vec) , 361, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #46 [ref=2x]
- { F(Vec) , 362, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #47 [ref=2x]
- { F(Vec) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #48 [ref=2x]
- { 0 , 364, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #49 [ref=1x]
- { 0 , 365, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #50 [ref=2x]
+ { F(Mmx)|F(Vec) , 360, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #43 [ref=2x]
+ { F(Mmx)|F(Vec) , 361, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #44 [ref=2x]
+ { F(Mmx)|F(Vec) , 362, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #45 [ref=2x]
+ { F(Vec) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #46 [ref=2x]
+ { F(Vec) , 364, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #47 [ref=2x]
+ { F(Vec) , 365, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #48 [ref=2x]
+ { 0 , 366, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #49 [ref=1x]
+ { 0 , 367, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #50 [ref=2x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 251, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #51 [ref=2x]
{ 0 , 39 , 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #52 [ref=3x]
{ F(Mmx) , 257, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #53 [ref=1x]
{ 0 , 253, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #54 [ref=2x]
- { 0 , 366, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #55 [ref=1x]
- { F(Vec) , 367, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #56 [ref=2x]
+ { 0 , 368, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #55 [ref=1x]
+ { F(Vec) , 369, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #56 [ref=2x]
{ F(Vec) , 255, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #57 [ref=1x]
{ F(FpuM32)|F(FpuM64) , 153, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #58 [ref=6x]
{ 0 , 257, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #59 [ref=9x]
- { F(FpuM80) , 368, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #60 [ref=2x]
+ { F(FpuM80) , 370, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #60 [ref=2x]
{ 0 , 258, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #61 [ref=13x]
{ F(FpuM32)|F(FpuM64) , 259, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #62 [ref=2x]
- { F(FpuM16)|F(FpuM32) , 369, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #63 [ref=9x]
- { F(FpuM16)|F(FpuM32)|F(FpuM64) , 370, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #64 [ref=3x]
- { F(FpuM32)|F(FpuM64)|F(FpuM80) , 371, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #65 [ref=2x]
- { F(FpuM16) , 372, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #66 [ref=3x]
- { F(FpuM16) , 373, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #67 [ref=2x]
+ { F(FpuM16)|F(FpuM32) , 371, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #63 [ref=9x]
+ { F(FpuM16)|F(FpuM32)|F(FpuM64) , 372, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #64 [ref=3x]
+ { F(FpuM32)|F(FpuM64)|F(FpuM80) , 373, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #65 [ref=2x]
+ { F(FpuM16) , 374, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #66 [ref=3x]
+ { F(FpuM16) , 375, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #67 [ref=2x]
{ F(FpuM32)|F(FpuM64) , 260, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #68 [ref=1x]
- { 0 , 374, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #69 [ref=2x]
+ { 0 , 376, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #69 [ref=2x]
{ 0 , 39 , 10, CONTROL(None) , SINGLE_REG(None), 0 }, // #70 [ref=1x]
- { 0 , 375, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #71 [ref=1x]
- { F(Rep) , 376, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #72 [ref=1x]
+ { 0 , 377, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #71 [ref=1x]
+ { F(Rep) , 378, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #72 [ref=1x]
{ F(Vec) , 261, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #73 [ref=1x]
- { 0 , 377, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #74 [ref=2x]
- { 0 , 378, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #75 [ref=8x]
+ { 0 , 379, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #74 [ref=2x]
+ { 0 , 380, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #75 [ref=8x]
{ 0 , 263, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #76 [ref=3x]
{ 0 , 265, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #77 [ref=1x]
{ 0 , 257, 1 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #78 [ref=3x]
- { 0 , 379, 1 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #79 [ref=1x]
+ { 0 , 381, 1 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #79 [ref=1x]
{ F(Rep)|F(RepIgnored) , 267, 2 , CONTROL(Branch) , SINGLE_REG(None), 0 }, // #80 [ref=30x]
{ F(Rep)|F(RepIgnored) , 269, 2 , CONTROL(Branch) , SINGLE_REG(None), 0 }, // #81 [ref=1x]
{ F(Rep)|F(RepIgnored) , 271, 2 , CONTROL(Jump) , SINGLE_REG(None), 0 }, // #82 [ref=1x]
- { F(Vec)|F(Vex) , 380, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #83 [ref=27x]
+ { F(Vec)|F(Vex) , 382, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #83 [ref=27x]
{ F(Vec)|F(Vex) , 273, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #84 [ref=1x]
{ F(Vec)|F(Vex) , 275, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #85 [ref=1x]
{ F(Vec)|F(Vex) , 277, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #86 [ref=1x]
{ F(Vec)|F(Vex) , 279, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #87 [ref=1x]
- { F(Vec)|F(Vex) , 381, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #88 [ref=12x]
- { F(Vec)|F(Vex) , 382, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #89 [ref=8x]
- { 0 , 383, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #90 [ref=2x]
+ { F(Vec)|F(Vex) , 383, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #88 [ref=12x]
+ { F(Vec)|F(Vex) , 384, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #89 [ref=8x]
+ { 0 , 385, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #90 [ref=2x]
{ 0 , 281, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #91 [ref=1x]
{ F(Vec) , 192, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #92 [ref=2x]
- { 0 , 384, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #93 [ref=2x]
+ { 0 , 386, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #93 [ref=2x]
{ 0 , 283, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #94 [ref=2x]
- { 0 , 385, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #95 [ref=1x]
+ { 0 , 387, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #95 [ref=1x]
{ 0 , 156, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #96 [ref=3x]
- { 0 , 386, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #97 [ref=5x]
- { F(Vex) , 387, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #98 [ref=2x]
- { F(Rep) , 388, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #99 [ref=1x]
+ { 0 , 388, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #97 [ref=5x]
+ { F(Vex) , 389, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #98 [ref=2x]
+ { F(Rep) , 390, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #99 [ref=1x]
{ 0 , 269, 2 , CONTROL(Branch) , SINGLE_REG(None), 0 }, // #100 [ref=3x]
{ 0 , 285, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #101 [ref=1x]
- { F(Vex) , 389, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #102 [ref=2x]
- { F(Vec) , 390, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #103 [ref=1x]
- { F(Mmx) , 391, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #104 [ref=1x]
- { 0 , 392, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #105 [ref=2x]
+ { F(Vex) , 391, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #102 [ref=2x]
+ { F(Vec) , 392, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #103 [ref=1x]
+ { F(Mmx) , 393, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #104 [ref=1x]
+ { 0 , 394, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #105 [ref=2x]
{ F(XRelease) , 0 , 16, CONTROL(None) , SINGLE_REG(None), 0 }, // #106 [ref=1x]
{ F(Vec) , 70 , 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #107 [ref=6x]
{ 0 , 64 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #108 [ref=1x]
{ F(Mmx)|F(Vec) , 287, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #109 [ref=1x]
- { 0 , 393, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #110 [ref=1x]
+ { 0 , 395, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #110 [ref=1x]
{ 0 , 68 , 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #111 [ref=2x]
- { F(Mmx)|F(Vec) , 394, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #112 [ref=1x]
+ { F(Mmx)|F(Vec) , 396, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #112 [ref=1x]
{ F(Vec) , 256, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #113 [ref=2x]
{ F(Vec) , 198, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #114 [ref=4x]
- { F(Vec) , 395, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #115 [ref=2x]
+ { F(Vec) , 397, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #115 [ref=2x]
{ F(Vec) , 71 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #116 [ref=3x]
- { F(Mmx) , 396, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #117 [ref=1x]
+ { F(Mmx) , 398, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #117 [ref=1x]
{ F(Vec) , 98 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #118 [ref=1x]
{ F(Vec) , 201, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #119 [ref=1x]
{ F(Mmx)|F(Vec) , 94 , 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #120 [ref=1x]
- { F(Mmx)|F(Vec) , 397, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #121 [ref=1x]
- { F(Rep) , 398, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #122 [ref=1x]
+ { F(Mmx)|F(Vec) , 399, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #121 [ref=1x]
+ { F(Rep) , 400, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #122 [ref=1x]
{ F(Vec) , 97 , 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #123 [ref=1x]
{ F(Vec) , 289, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #124 [ref=1x]
{ 0 , 291, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #125 [ref=2x]
- { 0 , 399, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #126 [ref=1x]
- { F(Vex) , 293, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #127 [ref=1x]
- { 0 , 400, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #128 [ref=1x]
- { 0 , 401, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #129 [ref=1x]
+ { 0 , 293, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #126 [ref=1x]
+ { F(Vex) , 295, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #127 [ref=1x]
+ { 0 , 401, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #128 [ref=1x]
+ { 0 , 402, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #129 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 252, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #130 [ref=2x]
- { 0 , 295, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #131 [ref=1x]
+ { 0 , 297, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #131 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 16 , 12, CONTROL(None) , SINGLE_REG(RO) , 0 }, // #132 [ref=1x]
- { 0 , 402, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #133 [ref=1x]
- { F(Rep) , 403, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #134 [ref=1x]
- { F(Mmx)|F(Vec) , 297, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #135 [ref=40x]
- { F(Mmx)|F(Vec) , 299, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #136 [ref=1x]
- { F(Mmx)|F(Vec) , 297, 2 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #137 [ref=6x]
- { F(Mmx)|F(Vec) , 297, 2 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #138 [ref=16x]
- { F(Mmx) , 297, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #139 [ref=26x]
+ { 0 , 403, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #133 [ref=1x]
+ { F(Rep) , 404, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #134 [ref=1x]
+ { F(Mmx)|F(Vec) , 299, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #135 [ref=40x]
+ { F(Mmx)|F(Vec) , 301, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #136 [ref=1x]
+ { F(Mmx)|F(Vec) , 299, 2 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #137 [ref=6x]
+ { F(Mmx)|F(Vec) , 299, 2 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #138 [ref=16x]
+ { F(Mmx) , 299, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #139 [ref=26x]
{ F(Vec) , 70 , 1 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #140 [ref=4x]
- { F(Vec) , 404, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #141 [ref=1x]
- { F(Vec) , 405, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #142 [ref=1x]
- { F(Vec) , 406, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #143 [ref=1x]
- { F(Vec) , 407, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #144 [ref=1x]
- { F(Vec) , 408, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #145 [ref=1x]
- { F(Vec) , 409, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #146 [ref=1x]
- { F(Mmx)|F(Vec) , 301, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #147 [ref=1x]
- { F(Vec) , 410, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #148 [ref=1x]
- { F(Vec) , 411, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #149 [ref=1x]
- { F(Vec) , 412, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #150 [ref=1x]
- { F(Mmx)|F(Vec) , 413, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #151 [ref=1x]
- { F(Mmx)|F(Vec) , 414, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #152 [ref=1x]
+ { F(Vec) , 405, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #141 [ref=1x]
+ { F(Vec) , 406, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #142 [ref=1x]
+ { F(Vec) , 407, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #143 [ref=1x]
+ { F(Vec) , 408, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #144 [ref=1x]
+ { F(Vec) , 409, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #145 [ref=1x]
+ { F(Vec) , 410, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #146 [ref=1x]
+ { F(Mmx)|F(Vec) , 303, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #147 [ref=1x]
+ { F(Vec) , 411, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #148 [ref=1x]
+ { F(Vec) , 412, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #149 [ref=1x]
+ { F(Vec) , 413, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #150 [ref=1x]
+ { F(Mmx)|F(Vec) , 414, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #151 [ref=1x]
+ { F(Mmx)|F(Vec) , 415, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #152 [ref=1x]
{ F(Vec) , 225, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #153 [ref=2x]
{ 0 , 122, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #154 [ref=1x]
- { 0 , 379, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #155 [ref=6x]
- { F(Mmx) , 299, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #156 [ref=1x]
- { F(Mmx)|F(Vec) , 303, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #157 [ref=8x]
- { F(Vec) , 415, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #158 [ref=2x]
+ { 0 , 381, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #155 [ref=6x]
+ { F(Mmx) , 301, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #156 [ref=1x]
+ { F(Mmx)|F(Vec) , 305, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #157 [ref=8x]
+ { F(Vec) , 416, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #158 [ref=2x]
{ 0 , 126, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #159 [ref=1x]
- { 0 , 416, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #160 [ref=8x]
- { 0 , 417, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #161 [ref=4x]
- { 0 , 418, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #162 [ref=6x]
- { 0 , 305, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #163 [ref=1x]
- { F(Rep)|F(RepIgnored) , 307, 2 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #164 [ref=1x]
- { F(Vex) , 309, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #165 [ref=1x]
+ { 0 , 417, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #160 [ref=8x]
+ { 0 , 418, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #161 [ref=4x]
+ { 0 , 419, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #162 [ref=6x]
+ { 0 , 307, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #163 [ref=1x]
+ { F(Rep)|F(RepIgnored) , 309, 2 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #164 [ref=1x]
+ { F(Vex) , 311, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #165 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 16 , 12, CONTROL(None) , SINGLE_REG(WO) , 0 }, // #166 [ref=3x]
- { F(Rep) , 419, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #167 [ref=1x]
- { 0 , 420, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #168 [ref=30x]
+ { F(Rep) , 420, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #167 [ref=1x]
+ { 0 , 421, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #168 [ref=30x]
{ 0 , 159, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #169 [ref=2x]
- { 0 , 421, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #170 [ref=3x]
- { F(Rep) , 422, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #171 [ref=1x]
+ { 0 , 422, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #170 [ref=3x]
+ { F(Rep) , 423, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #171 [ref=1x]
{ 0 , 57 , 7 , CONTROL(None) , SINGLE_REG(None), 0 }, // #172 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ) , 423, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #173 [ref=4x]
- { F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ) , 424, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #174 [ref=2x]
+ { F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ) , 424, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #173 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ) , 425, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #174 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #175 [ref=22x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #176 [ref=22x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE) , 425, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #177 [ref=18x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #178 [ref=17x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #177 [ref=18x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #178 [ref=17x]
{ F(Vec)|F(Vex) , 162, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #179 [ref=15x]
{ F(Vec)|F(Vex)|F(Evex) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #180 [ref=5x]
{ F(Vec)|F(Vex) , 70 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #181 [ref=17x]
@@ -2183,136 +2183,136 @@ const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #190 [ref=16x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #191 [ref=19x]
{ F(Vec)|F(Vex) , 165, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #192 [ref=6x]
- { F(Vec)|F(Vex) , 311, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #193 [ref=3x]
- { F(Vec)|F(Vex) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #194 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 428, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #195 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 429, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #196 [ref=4x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 430, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #197 [ref=4x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 431, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #198 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 428, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #199 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 432, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #200 [ref=1x]
+ { F(Vec)|F(Vex) , 313, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #193 [ref=3x]
+ { F(Vec)|F(Vex) , 428, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #194 [ref=2x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 429, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #195 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 430, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #196 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 431, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #197 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 432, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #198 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 429, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #199 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 433, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #200 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64) , 168, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #201 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32) , 168, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #202 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 433, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #203 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 434, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #204 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 434, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #203 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 435, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #204 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 97 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #205 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 222, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #206 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 171, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #207 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 174, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #208 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #209 [ref=3x]
- { F(Vec)|F(Evex)|F(Avx512KZ_B32) , 313, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #210 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 313, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #211 [ref=2x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_B32) , 315, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #210 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 315, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #211 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #212 [ref=4x]
- { F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 313, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #213 [ref=3x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 315, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #213 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 174, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #214 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 174, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #215 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 180, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #216 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 174, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #217 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #218 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 361, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #219 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512ER_SAE) , 361, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #220 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 435, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #221 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #222 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #223 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512ER_SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #224 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64) , 313, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #225 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #219 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512ER_SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #220 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 436, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #221 [ref=2x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #222 [ref=3x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 365, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #223 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512ER_SAE) , 365, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #224 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64) , 315, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #225 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #226 [ref=3x]
- { F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 313, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #227 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 315, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #227 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #228 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 174, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #229 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #230 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 361, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #231 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512SAE) , 361, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #232 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #233 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #234 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #231 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512SAE) , 363, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #232 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 365, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #233 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512SAE) , 365, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #234 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 174, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #235 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512ER_SAE) , 435, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #236 [ref=2x]
+ { F(Vec)|F(Evex)|F(Avx512ER_SAE) , 436, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #236 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 165, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #237 [ref=3x]
{ F(Vec)|F(Vex) , 165, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #238 [ref=9x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 74 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #239 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 74 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #240 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #241 [ref=9x]
{ F(Vec)|F(Vex) , 181, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #242 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 436, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #243 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 437, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #243 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 182, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #244 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex) , 367, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #245 [ref=2x]
+ { F(Vec)|F(Vex)|F(Evex) , 369, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #245 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 165, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #246 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 165, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #247 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 437, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #248 [ref=4x]
- { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #249 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #248 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 439, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #249 [ref=4x]
{ F(Vec)|F(Vex) , 130, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #250 [ref=13x]
- { F(Vec)|F(Vex) , 315, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #251 [ref=4x]
- { F(Vec)|F(Vex) , 317, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #252 [ref=4x]
- { F(Vec)|F(Evex)|F(Avx512K_B64) , 439, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #253 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512K_B32) , 439, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #254 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512K) , 440, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #255 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512K) , 441, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #256 [ref=1x]
+ { F(Vec)|F(Vex) , 317, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #251 [ref=4x]
+ { F(Vec)|F(Vex) , 319, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #252 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512K_B64) , 440, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #253 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512K_B32) , 440, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #254 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512K) , 441, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #255 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512K) , 442, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #256 [ref=1x]
{ F(Vec)|F(Vex) , 177, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #257 [ref=7x]
{ F(Vec)|F(Vex) , 97 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #258 [ref=1x]
{ F(Vec)|F(Vex) , 222, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #259 [ref=1x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 99 , 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #260 [ref=2x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 104, 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #261 [ref=2x]
- { F(Vsib)|F(Evex)|F(Avx512K) , 442, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #262 [ref=4x]
- { F(Vsib)|F(Evex)|F(Avx512K) , 443, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #263 [ref=4x]
- { F(Vsib)|F(Evex)|F(Avx512K) , 444, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #264 [ref=8x]
+ { F(Vsib)|F(Evex)|F(Avx512K) , 443, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #262 [ref=4x]
+ { F(Vsib)|F(Evex)|F(Avx512K) , 444, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #263 [ref=4x]
+ { F(Vsib)|F(Evex)|F(Avx512K) , 445, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #264 [ref=8x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 109, 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #265 [ref=2x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 134, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #266 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 425, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #267 [ref=3x]
- { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #268 [ref=3x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #267 [ref=3x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #268 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 183, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #269 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 183, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #270 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 165, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #271 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #272 [ref=22x]
- { F(Vec)|F(Vex) , 319, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #273 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 319, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #274 [ref=4x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 445, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #275 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex) , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #276 [ref=1x]
+ { F(Vec)|F(Vex) , 321, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #273 [ref=2x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 321, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #274 [ref=4x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 446, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #275 [ref=4x]
+ { F(Vec)|F(Vex)|F(Evex) , 439, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #276 [ref=1x]
{ F(Vec)|F(Vex) , 192, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #277 [ref=1x]
- { F(Vex) , 384, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #278 [ref=2x]
- { F(Vec)|F(Vex) , 390, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #279 [ref=1x]
+ { F(Vex) , 386, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #278 [ref=2x]
+ { F(Vec)|F(Vex) , 392, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #279 [ref=1x]
{ F(Vec)|F(Vex) , 138, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #280 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #281 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #282 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 425, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #283 [ref=2x]
- { 0 , 446, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #284 [ref=4x]
- { 0 , 321, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #285 [ref=3x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #283 [ref=2x]
+ { 0 , 447, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #284 [ref=4x]
+ { 0 , 323, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #285 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 70 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #286 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex) , 323, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #287 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex) , 325, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #287 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 186, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #288 [ref=1x]
{ F(Vec)|F(Vex) , 70 , 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #289 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 70 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #290 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex) , 200, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #291 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex) , 325, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #292 [ref=4x]
- { F(Vec)|F(Vex) , 447, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #293 [ref=3x]
+ { F(Vec)|F(Vex)|F(Evex) , 327, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #292 [ref=4x]
+ { F(Vec)|F(Vex) , 448, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #293 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex) , 189, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #294 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex) , 192, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #295 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex) , 195, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #296 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 198, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #297 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #298 [ref=5x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 201, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #299 [ref=1x]
- { 0 , 327, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #300 [ref=1x]
- { 0 , 329, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #301 [ref=1x]
+ { 0 , 329, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #300 [ref=1x]
+ { 0 , 331, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #301 [ref=1x]
{ F(Vec)|F(Vex) , 162, 2 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #302 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 162, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #303 [ref=2x]
{ F(Vec)|F(Vex) , 162, 2 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #304 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 162, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #305 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 162, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #306 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 162, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #307 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 448, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #308 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 449, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #309 [ref=1x]
- { F(Vec)|F(Evex) , 450, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #310 [ref=6x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 449, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #308 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 450, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #309 [ref=1x]
+ { F(Vec)|F(Evex) , 451, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #310 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 204, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #311 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 451, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #312 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 452, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #312 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex) , 165, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #313 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512K) , 207, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #314 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512K_B32) , 207, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #315 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512K) , 210, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #316 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B32) , 210, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #317 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B64) , 210, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #318 [ref=2x]
- { F(Vec)|F(Vex) , 404, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #319 [ref=1x]
- { F(Vec)|F(Vex) , 405, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #320 [ref=1x]
- { F(Vec)|F(Vex) , 406, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #321 [ref=1x]
- { F(Vec)|F(Vex) , 407, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #322 [ref=1x]
+ { F(Vec)|F(Vex) , 405, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #319 [ref=1x]
+ { F(Vec)|F(Vex) , 406, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #320 [ref=1x]
+ { F(Vec)|F(Vex) , 407, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #321 [ref=1x]
+ { F(Vec)|F(Vex) , 408, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #322 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512K_B64) , 207, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #323 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #324 [ref=6x]
{ F(Vec)|F(Vex) , 166, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #325 [ref=2x]
@@ -2320,17 +2320,17 @@ const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ F(Vec)|F(Vex) , 142, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #327 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 76 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #328 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 146, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #329 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex) , 408, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #330 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex) , 409, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #331 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex) , 452, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #332 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 453, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #333 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 454, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #334 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 455, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #335 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 456, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #336 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex) , 409, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #330 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex) , 410, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #331 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex) , 453, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #332 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 454, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #333 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 455, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #334 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 456, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #335 [ref=1x]
+ { F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 457, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #336 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #337 [ref=4x]
- { F(Vec)|F(Vex) , 311, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #338 [ref=12x]
+ { F(Vec)|F(Vex) , 313, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #338 [ref=12x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 162, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #339 [ref=8x]
- { F(Vec)|F(Evex) , 457, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #340 [ref=4x]
+ { F(Vec)|F(Evex) , 458, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #340 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 213, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #341 [ref=6x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 216, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #342 [ref=9x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 219, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #343 [ref=3x]
@@ -2340,11 +2340,11 @@ const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ F(Vec)|F(Vex) , 130, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #347 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 183, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #348 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 183, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #349 [ref=3x]
- { F(Vec)|F(Vex) , 331, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #350 [ref=4x]
+ { F(Vec)|F(Vex) , 333, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #350 [ref=4x]
{ F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 228, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #351 [ref=3x]
- { F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 333, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #352 [ref=2x]
+ { F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 335, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #352 [ref=2x]
{ F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 231, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #353 [ref=2x]
- { F(Vec)|F(Vex) , 335, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #354 [ref=8x]
+ { F(Vec)|F(Vex) , 337, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #354 [ref=8x]
{ F(Vec)|F(Evex)|F(Avx512K) , 234, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #355 [ref=5x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 183, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #356 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 183, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #357 [ref=2x]
@@ -2358,19 +2358,19 @@ const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 162, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #365 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512K_B32) , 234, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #366 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512K_B64) , 234, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #367 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 425, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #368 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #369 [ref=2x]
- { F(Vec)|F(Vex) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #370 [ref=2x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 437, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #371 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512KZ) , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #372 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #368 [ref=2x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #369 [ref=2x]
+ { F(Vec)|F(Vex) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #370 [ref=2x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #371 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512KZ) , 439, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #372 [ref=1x]
{ F(Vec)|F(Vex) , 183, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #373 [ref=2x]
- { F(Vec)|F(Vex) , 437, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #374 [ref=1x]
- { F(Vec)|F(Vex) , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #375 [ref=1x]
+ { F(Vec)|F(Vex) , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #374 [ref=1x]
+ { F(Vec)|F(Vex) , 439, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #375 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #376 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 162, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #377 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE) , 425, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #378 [ref=1x]
- { F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #379 [ref=1x]
- { F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 337, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #380 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE) , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #378 [ref=1x]
+ { F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #379 [ref=1x]
+ { F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 339, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #380 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 166, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #381 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 166, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #382 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 165, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #383 [ref=1x]
@@ -2378,10 +2378,10 @@ const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 177, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #385 [ref=1x]
{ F(Vec)|F(Vex) , 257, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #386 [ref=2x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 49 , 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #387 [ref=1x]
- { 0 , 458, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #388 [ref=1x]
+ { 0 , 459, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #388 [ref=1x]
{ F(Lock)|F(XAcquire) , 49 , 8 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #389 [ref=1x]
- { 0 , 459, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #390 [ref=6x]
- { 0 , 460, 1 , CONTROL(None) , SINGLE_REG(None), 0 } // #391 [ref=6x]
+ { 0 , 460, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #390 [ref=6x]
+ { 0 , 461, 1 , CONTROL(None) , SINGLE_REG(None), 0 } // #391 [ref=6x]
};
#undef SINGLE_REG
#undef CONTROL
@@ -3070,174 +3070,175 @@ const InstDB::InstSignature InstDB::_instSignatureTable[] = {
ROW(2, 1, 1, 0, 29 , 45 , 0 , 0 , 0 , 0 ), // {m32|mem, xmm}
ROW(2, 1, 1, 0, 4 , 9 , 0 , 0 , 0 , 0 ), // #291 {r16, r8lo|r8hi|m8}
ROW(2, 1, 1, 0, 114, 115, 0 , 0 , 0 , 0 ), // {r32|r64, r8lo|r8hi|m8|r16|m16}
- ROW(4, 1, 1, 1, 6 , 6 , 28 , 35 , 0 , 0 ), // #293 {r32, r32, r32|m32|mem, <edx>}
+ ROW(2, 0, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #293 {r16, r16|m16|mem}
+ ROW(2, 0, 1, 0, 114, 28 , 0 , 0 , 0 , 0 ), // {r32|r64, r32|m32|mem}
+ ROW(4, 1, 1, 1, 6 , 6 , 28 , 35 , 0 , 0 ), // #295 {r32, r32, r32|m32|mem, <edx>}
ROW(4, 0, 1, 1, 8 , 8 , 15 , 37 , 0 , 0 ), // {r64, r64, r64|m64|mem, <rdx>}
- ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #295 {}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #297 {}
ROW(1, 1, 1, 0, 116, 0 , 0 , 0 , 0 , 0 ), // {r16|m16|r32|m32}
- ROW(2, 1, 1, 0, 57 , 117, 0 , 0 , 0 , 0 ), // #297 {mm, mm|m64|mem}
+ ROW(2, 1, 1, 0, 57 , 117, 0 , 0 , 0 , 0 ), // #299 {mm, mm|m64|mem}
ROW(2, 1, 1, 0, 45 , 46 , 0 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem}
- ROW(3, 1, 1, 0, 57 , 117, 10 , 0 , 0 , 0 ), // #299 {mm, mm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 57 , 117, 10 , 0 , 0 , 0 ), // #301 {mm, mm|m64|mem, i8|u8}
ROW(3, 1, 1, 0, 45 , 46 , 10 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem, i8|u8}
- ROW(3, 1, 1, 0, 6 , 59 , 10 , 0 , 0 , 0 ), // #301 {r32, mm|xmm, i8|u8}
+ ROW(3, 1, 1, 0, 6 , 59 , 10 , 0 , 0 , 0 ), // #303 {r32, mm|xmm, i8|u8}
ROW(3, 1, 1, 0, 21 , 45 , 10 , 0 , 0 , 0 ), // {m16|mem, xmm, i8|u8}
- ROW(2, 1, 1, 0, 57 , 118, 0 , 0 , 0 , 0 ), // #303 {mm, i8|u8|mm|m64|mem}
+ ROW(2, 1, 1, 0, 57 , 118, 0 , 0 , 0 , 0 ), // #305 {mm, i8|u8|mm|m64|mem}
ROW(2, 1, 1, 0, 45 , 54 , 0 , 0 , 0 , 0 ), // {xmm, i8|u8|xmm|m128|mem}
- ROW(1, 1, 0, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #305 {r32}
+ ROW(1, 1, 0, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #307 {r32}
ROW(1, 0, 1, 0, 8 , 0 , 0 , 0 , 0 , 0 ), // {r64}
- ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #307 {}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #309 {}
ROW(1, 1, 1, 0, 119, 0 , 0 , 0 , 0 , 0 ), // {u16}
- ROW(3, 1, 1, 0, 6 , 28 , 10 , 0 , 0 , 0 ), // #309 {r32, r32|m32|mem, i8|u8}
+ ROW(3, 1, 1, 0, 6 , 28 , 10 , 0 , 0 , 0 ), // #311 {r32, r32|m32|mem, i8|u8}
ROW(3, 0, 1, 0, 8 , 15 , 10 , 0 , 0 , 0 ), // {r64, r64|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 45 , 45 , 46 , 45 , 0 , 0 ), // #311 {xmm, xmm, xmm|m128|mem, xmm}
+ ROW(4, 1, 1, 0, 45 , 45 , 46 , 45 , 0 , 0 ), // #313 {xmm, xmm, xmm|m128|mem, xmm}
ROW(4, 1, 1, 0, 48 , 48 , 49 , 48 , 0 , 0 ), // {ymm, ymm, ymm|m256|mem, ymm}
- ROW(2, 1, 1, 0, 45 , 120, 0 , 0 , 0 , 0 ), // #313 {xmm, xmm|m128|ymm|m256}
+ ROW(2, 1, 1, 0, 45 , 120, 0 , 0 , 0 , 0 ), // #315 {xmm, xmm|m128|ymm|m256}
ROW(2, 1, 1, 0, 48 , 52 , 0 , 0 , 0 , 0 ), // {ymm, zmm|m512|mem}
- ROW(4, 1, 1, 0, 45 , 45 , 45 , 60 , 0 , 0 ), // #315 {xmm, xmm, xmm, xmm|m64|mem}
+ ROW(4, 1, 1, 0, 45 , 45 , 45 , 60 , 0 , 0 ), // #317 {xmm, xmm, xmm, xmm|m64|mem}
ROW(4, 1, 1, 0, 45 , 45 , 30 , 45 , 0 , 0 ), // {xmm, xmm, m64|mem, xmm}
- ROW(4, 1, 1, 0, 45 , 45 , 45 , 87 , 0 , 0 ), // #317 {xmm, xmm, xmm, xmm|m32|mem}
+ ROW(4, 1, 1, 0, 45 , 45 , 45 , 87 , 0 , 0 ), // #319 {xmm, xmm, xmm, xmm|m32|mem}
ROW(4, 1, 1, 0, 45 , 45 , 29 , 45 , 0 , 0 ), // {xmm, xmm, m32|mem, xmm}
- ROW(4, 1, 1, 0, 48 , 48 , 46 , 10 , 0 , 0 ), // #319 {ymm, ymm, xmm|m128|mem, i8|u8}
+ ROW(4, 1, 1, 0, 48 , 48 , 46 , 10 , 0 , 0 ), // #321 {ymm, ymm, xmm|m128|mem, i8|u8}
ROW(4, 1, 1, 0, 51 , 51 , 46 , 10 , 0 , 0 ), // {zmm, zmm, xmm|m128|mem, i8|u8}
- ROW(1, 1, 0, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #321 {<eax>}
- ROW(1, 0, 1, 1, 38 , 0 , 0 , 0 , 0 , 0 ), // #322 {<rax>}
- ROW(2, 1, 1, 0, 28 , 45 , 0 , 0 , 0 , 0 ), // #323 {r32|m32|mem, xmm}
+ ROW(1, 1, 0, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #323 {<eax>}
+ ROW(1, 0, 1, 1, 38 , 0 , 0 , 0 , 0 , 0 ), // #324 {<rax>}
+ ROW(2, 1, 1, 0, 28 , 45 , 0 , 0 , 0 , 0 ), // #325 {r32|m32|mem, xmm}
ROW(2, 1, 1, 0, 45 , 28 , 0 , 0 , 0 , 0 ), // {xmm, r32|m32|mem}
- ROW(2, 1, 1, 0, 30 , 45 , 0 , 0 , 0 , 0 ), // #325 {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 30 , 45 , 0 , 0 , 0 , 0 ), // #327 {m64|mem, xmm}
ROW(3, 1, 1, 0, 45 , 45 , 30 , 0 , 0 , 0 ), // {xmm, xmm, m64|mem}
- ROW(2, 1, 0, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // #327 {r32|m32|mem, r32}
+ ROW(2, 1, 0, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // #329 {r32|m32|mem, r32}
ROW(2, 0, 1, 0, 15 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
- ROW(2, 1, 0, 0, 6 , 28 , 0 , 0 , 0 , 0 ), // #329 {r32, r32|m32|mem}
+ ROW(2, 1, 0, 0, 6 , 28 , 0 , 0 , 0 , 0 ), // #331 {r32, r32|m32|mem}
ROW(2, 0, 1, 0, 8 , 15 , 0 , 0 , 0 , 0 ), // {r64, r64|m64|mem}
- ROW(3, 1, 1, 0, 45 , 45 , 54 , 0 , 0 , 0 ), // #331 {xmm, xmm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 45 , 45 , 54 , 0 , 0 , 0 ), // #333 {xmm, xmm, xmm|m128|mem|i8|u8}
ROW(3, 1, 1, 0, 45 , 47 , 121, 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8|xmm}
- ROW(2, 1, 1, 0, 74 , 45 , 0 , 0 , 0 , 0 ), // #333 {vm64x|vm64y, xmm}
+ ROW(2, 1, 1, 0, 74 , 45 , 0 , 0 , 0 , 0 ), // #335 {vm64x|vm64y, xmm}
ROW(2, 1, 1, 0, 66 , 48 , 0 , 0 , 0 , 0 ), // {vm64z, ymm}
- ROW(3, 1, 1, 0, 45 , 45 , 46 , 0 , 0 , 0 ), // #335 {xmm, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 45 , 45 , 46 , 0 , 0 , 0 ), // #337 {xmm, xmm, xmm|m128|mem}
ROW(3, 1, 1, 0, 45 , 47 , 45 , 0 , 0 , 0 ), // {xmm, m128|mem, xmm}
- ROW(2, 1, 1, 0, 61 , 86 , 0 , 0 , 0 , 0 ), // #337 {vm32x, xmm|ymm}
+ ROW(2, 1, 1, 0, 61 , 86 , 0 , 0 , 0 , 0 ), // #339 {vm32x, xmm|ymm}
ROW(2, 1, 1, 0, 62 , 51 , 0 , 0 , 0 , 0 ), // {vm32y, zmm}
- ROW(1, 1, 0, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #339 {<ax>}
- ROW(2, 1, 0, 1, 33 , 10 , 0 , 0 , 0 , 0 ), // #340 {<ax>, i8|u8}
- ROW(2, 1, 0, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // #341 {r16|m16|mem, r16}
- ROW(3, 1, 1, 1, 45 , 46 , 122, 0 , 0 , 0 ), // #342 {xmm, xmm|m128|mem, <xmm0>}
- ROW(2, 1, 1, 0, 89 , 123, 0 , 0 , 0 , 0 ), // #343 {bnd, mib}
- ROW(2, 1, 1, 0, 89 , 91 , 0 , 0 , 0 , 0 ), // #344 {bnd, mem}
- ROW(2, 1, 1, 0, 123, 89 , 0 , 0 , 0 , 0 ), // #345 {mib, bnd}
- ROW(1, 1, 1, 0, 124, 0 , 0 , 0 , 0 , 0 ), // #346 {r16|r32|r64}
- ROW(1, 1, 1, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #347 {<ax>}
- ROW(2, 1, 1, 2, 35 , 36 , 0 , 0 , 0 , 0 ), // #348 {<edx>, <eax>}
- ROW(1, 1, 1, 0, 91 , 0 , 0 , 0 , 0 , 0 ), // #349 {mem}
- ROW(1, 1, 1, 1, 125, 0 , 0 , 0 , 0 , 0 ), // #350 {<ds:[memBase|zax]>}
- ROW(2, 1, 1, 2, 126, 127, 0 , 0 , 0 , 0 ), // #351 {<ds:[memBase|zsi]>, <es:[memBase|zdi]>}
- ROW(3, 1, 1, 0, 45 , 60 , 10 , 0 , 0 , 0 ), // #352 {xmm, xmm|m64|mem, i8|u8}
- ROW(3, 1, 1, 0, 45 , 87 , 10 , 0 , 0 , 0 ), // #353 {xmm, xmm|m32|mem, i8|u8}
- ROW(5, 0, 1, 4, 47 , 37 , 38 , 128, 129, 0 ), // #354 {m128|mem, <rdx>, <rax>, <rcx>, <rbx>}
- ROW(5, 1, 1, 4, 30 , 35 , 36 , 99 , 130, 0 ), // #355 {m64|mem, <edx>, <eax>, <ecx>, <ebx>}
- ROW(4, 1, 1, 4, 36 , 130, 99 , 35 , 0 , 0 ), // #356 {<eax>, <ebx>, <ecx>, <edx>}
- ROW(2, 0, 1, 2, 37 , 38 , 0 , 0 , 0 , 0 ), // #357 {<rdx>, <rax>}
- ROW(2, 1, 1, 0, 57 , 46 , 0 , 0 , 0 , 0 ), // #358 {mm, xmm|m128|mem}
- ROW(2, 1, 1, 0, 45 , 117, 0 , 0 , 0 , 0 ), // #359 {xmm, mm|m64|mem}
- ROW(2, 1, 1, 0, 57 , 60 , 0 , 0 , 0 , 0 ), // #360 {mm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 114, 60 , 0 , 0 , 0 , 0 ), // #361 {r32|r64, xmm|m64|mem}
- ROW(2, 1, 1, 0, 45 , 131, 0 , 0 , 0 , 0 ), // #362 {xmm, r32|m32|mem|r64|m64}
- ROW(2, 1, 1, 0, 114, 87 , 0 , 0 , 0 , 0 ), // #363 {r32|r64, xmm|m32|mem}
- ROW(2, 1, 1, 2, 34 , 33 , 0 , 0 , 0 , 0 ), // #364 {<dx>, <ax>}
- ROW(1, 1, 1, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #365 {<eax>}
- ROW(2, 1, 1, 0, 12 , 10 , 0 , 0 , 0 , 0 ), // #366 {i16|u16, i8|u8}
- ROW(3, 1, 1, 0, 28 , 45 , 10 , 0 , 0 , 0 ), // #367 {r32|m32|mem, xmm, i8|u8}
- ROW(1, 1, 1, 0, 80 , 0 , 0 , 0 , 0 , 0 ), // #368 {m80|mem}
- ROW(1, 1, 1, 0, 132, 0 , 0 , 0 , 0 , 0 ), // #369 {m16|m32}
- ROW(1, 1, 1, 0, 133, 0 , 0 , 0 , 0 , 0 ), // #370 {m16|m32|m64}
- ROW(1, 1, 1, 0, 134, 0 , 0 , 0 , 0 , 0 ), // #371 {m32|m64|m80|st}
- ROW(1, 1, 1, 0, 21 , 0 , 0 , 0 , 0 , 0 ), // #372 {m16|mem}
- ROW(1, 1, 1, 0, 135, 0 , 0 , 0 , 0 , 0 ), // #373 {ax|m16|mem}
- ROW(1, 0, 1, 0, 91 , 0 , 0 , 0 , 0 , 0 ), // #374 {mem}
- ROW(2, 1, 1, 0, 136, 137, 0 , 0 , 0 , 0 ), // #375 {al|ax|eax, i8|u8|dx}
- ROW(2, 1, 1, 0, 138, 139, 0 , 0 , 0 , 0 ), // #376 {es:[memBase|zdi], dx}
- ROW(1, 1, 1, 0, 10 , 0 , 0 , 0 , 0 , 0 ), // #377 {i8|u8}
- ROW(0, 1, 0, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #378 {}
- ROW(0, 0, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #379 {}
- ROW(3, 1, 1, 0, 84 , 84 , 84 , 0 , 0 , 0 ), // #380 {k, k, k}
- ROW(2, 1, 1, 0, 84 , 84 , 0 , 0 , 0 , 0 ), // #381 {k, k}
- ROW(3, 1, 1, 0, 84 , 84 , 10 , 0 , 0 , 0 ), // #382 {k, k, i8|u8}
- ROW(1, 1, 1, 1, 140, 0 , 0 , 0 , 0 , 0 ), // #383 {<ah>}
- ROW(1, 1, 1, 0, 29 , 0 , 0 , 0 , 0 , 0 ), // #384 {m32|mem}
- ROW(2, 1, 1, 0, 124, 141, 0 , 0 , 0 , 0 ), // #385 {r16|r32|r64, mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
- ROW(1, 1, 1, 0, 27 , 0 , 0 , 0 , 0 , 0 ), // #386 {r16|m16|mem}
- ROW(1, 1, 1, 0, 114, 0 , 0 , 0 , 0 , 0 ), // #387 {r32|r64}
- ROW(2, 1, 1, 2, 142, 126, 0 , 0 , 0 , 0 ), // #388 {<al|ax|eax|rax>, <ds:[memBase|zsi]>}
- ROW(3, 1, 1, 0, 114, 28 , 14 , 0 , 0 , 0 ), // #389 {r32|r64, r32|m32|mem, i32|u32}
- ROW(3, 1, 1, 1, 45 , 45 , 143, 0 , 0 , 0 ), // #390 {xmm, xmm, <ds:[memBase|zdi]>}
- ROW(3, 1, 1, 1, 57 , 57 , 143, 0 , 0 , 0 ), // #391 {mm, mm, <ds:[memBase|zdi]>}
- ROW(3, 1, 1, 3, 125, 99 , 35 , 0 , 0 , 0 ), // #392 {<ds:[memBase|zax]>, <ecx>, <edx>}
- ROW(2, 1, 1, 0, 97 , 53 , 0 , 0 , 0 , 0 ), // #393 {es:[memBase], m512|mem}
- ROW(2, 1, 1, 0, 57 , 45 , 0 , 0 , 0 , 0 ), // #394 {mm, xmm}
- ROW(2, 1, 1, 0, 6 , 45 , 0 , 0 , 0 , 0 ), // #395 {r32, xmm}
- ROW(2, 1, 1, 0, 30 , 57 , 0 , 0 , 0 , 0 ), // #396 {m64|mem, mm}
- ROW(2, 1, 1, 0, 45 , 57 , 0 , 0 , 0 , 0 ), // #397 {xmm, mm}
- ROW(2, 1, 1, 2, 127, 126, 0 , 0 , 0 , 0 ), // #398 {<es:[memBase|zdi]>, <ds:[memBase|zsi]>}
- ROW(2, 0, 1, 0, 8 , 28 , 0 , 0 , 0 , 0 ), // #399 {r64, r32|m32|mem}
- ROW(2, 1, 1, 2, 36 , 99 , 0 , 0 , 0 , 0 ), // #400 {<eax>, <ecx>}
- ROW(3, 1, 1, 3, 36 , 99 , 130, 0 , 0 , 0 ), // #401 {<eax>, <ecx>, <ebx>}
- ROW(2, 1, 1, 0, 144, 136, 0 , 0 , 0 , 0 ), // #402 {u8|dx, al|ax|eax}
- ROW(2, 1, 1, 0, 139, 145, 0 , 0 , 0 , 0 ), // #403 {dx, ds:[memBase|zsi]}
- ROW(6, 1, 1, 3, 45 , 46 , 10 , 99 , 36 , 35 ), // #404 {xmm, xmm|m128|mem, i8|u8, <ecx>, <eax>, <edx>}
- ROW(6, 1, 1, 3, 45 , 46 , 10 , 122, 36 , 35 ), // #405 {xmm, xmm|m128|mem, i8|u8, <xmm0>, <eax>, <edx>}
- ROW(4, 1, 1, 1, 45 , 46 , 10 , 99 , 0 , 0 ), // #406 {xmm, xmm|m128|mem, i8|u8, <ecx>}
- ROW(4, 1, 1, 1, 45 , 46 , 10 , 122, 0 , 0 ), // #407 {xmm, xmm|m128|mem, i8|u8, <xmm0>}
- ROW(3, 1, 1, 0, 109, 45 , 10 , 0 , 0 , 0 ), // #408 {r32|m8|mem|r8lo|r8hi|r16, xmm, i8|u8}
- ROW(3, 0, 1, 0, 15 , 45 , 10 , 0 , 0 , 0 ), // #409 {r64|m64|mem, xmm, i8|u8}
- ROW(3, 1, 1, 0, 45 , 109, 10 , 0 , 0 , 0 ), // #410 {xmm, r32|m8|mem|r8lo|r8hi|r16, i8|u8}
- ROW(3, 1, 1, 0, 45 , 28 , 10 , 0 , 0 , 0 ), // #411 {xmm, r32|m32|mem, i8|u8}
- ROW(3, 0, 1, 0, 45 , 15 , 10 , 0 , 0 , 0 ), // #412 {xmm, r64|m64|mem, i8|u8}
- ROW(3, 1, 1, 0, 59 , 113, 10 , 0 , 0 , 0 ), // #413 {mm|xmm, r32|m16|mem|r16, i8|u8}
- ROW(2, 1, 1, 0, 6 , 59 , 0 , 0 , 0 , 0 ), // #414 {r32, mm|xmm}
- ROW(2, 1, 1, 0, 45 , 10 , 0 , 0 , 0 , 0 ), // #415 {xmm, i8|u8}
- ROW(2, 1, 1, 0, 31 , 81 , 0 , 0 , 0 , 0 ), // #416 {r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, cl|i8|u8}
- ROW(1, 0, 1, 0, 114, 0 , 0 , 0 , 0 , 0 ), // #417 {r32|r64}
- ROW(3, 1, 1, 3, 35 , 36 , 99 , 0 , 0 , 0 ), // #418 {<edx>, <eax>, <ecx>}
- ROW(2, 1, 1, 2, 142, 127, 0 , 0 , 0 , 0 ), // #419 {<al|ax|eax|rax>, <es:[memBase|zdi]>}
- ROW(1, 1, 1, 0, 1 , 0 , 0 , 0 , 0 , 0 ), // #420 {r8lo|r8hi|m8|mem}
- ROW(1, 1, 1, 0, 146, 0 , 0 , 0 , 0 , 0 ), // #421 {r16|m16|mem|r32|r64}
- ROW(2, 1, 1, 2, 127, 142, 0 , 0 , 0 , 0 ), // #422 {<es:[memBase|zdi]>, <al|ax|eax|rax>}
- ROW(6, 1, 1, 0, 51 , 51 , 51 , 51 , 51 , 47 ), // #423 {zmm, zmm, zmm, zmm, zmm, m128|mem}
- ROW(6, 1, 1, 0, 45 , 45 , 45 , 45 , 45 , 47 ), // #424 {xmm, xmm, xmm, xmm, xmm, m128|mem}
- ROW(3, 1, 1, 0, 45 , 45 , 60 , 0 , 0 , 0 ), // #425 {xmm, xmm, xmm|m64|mem}
- ROW(3, 1, 1, 0, 45 , 45 , 87 , 0 , 0 , 0 ), // #426 {xmm, xmm, xmm|m32|mem}
- ROW(2, 1, 1, 0, 48 , 47 , 0 , 0 , 0 , 0 ), // #427 {ymm, m128|mem}
- ROW(2, 1, 1, 0, 147, 60 , 0 , 0 , 0 , 0 ), // #428 {ymm|zmm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 147, 47 , 0 , 0 , 0 , 0 ), // #429 {ymm|zmm, m128|mem}
- ROW(2, 1, 1, 0, 51 , 50 , 0 , 0 , 0 , 0 ), // #430 {zmm, m256|mem}
- ROW(2, 1, 1, 0, 148, 60 , 0 , 0 , 0 , 0 ), // #431 {xmm|ymm|zmm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 148, 87 , 0 , 0 , 0 , 0 ), // #432 {xmm|ymm|zmm, m32|mem|xmm}
- ROW(4, 1, 1, 0, 82 , 45 , 60 , 10 , 0 , 0 ), // #433 {xmm|k, xmm, xmm|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 82 , 45 , 87 , 10 , 0 , 0 ), // #434 {xmm|k, xmm, xmm|m32|mem, i8|u8}
- ROW(3, 1, 1, 0, 45 , 45 , 131, 0 , 0 , 0 ), // #435 {xmm, xmm, r32|m32|mem|r64|m64}
- ROW(3, 1, 1, 0, 46 , 147, 10 , 0 , 0 , 0 ), // #436 {xmm|m128|mem, ymm|zmm, i8|u8}
- ROW(4, 1, 1, 0, 45 , 45 , 60 , 10 , 0 , 0 ), // #437 {xmm, xmm, xmm|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 45 , 45 , 87 , 10 , 0 , 0 ), // #438 {xmm, xmm, xmm|m32|mem, i8|u8}
- ROW(3, 1, 1, 0, 84 , 149, 10 , 0 , 0 , 0 ), // #439 {k, xmm|m128|ymm|m256|zmm|m512, i8|u8}
- ROW(3, 1, 1, 0, 84 , 60 , 10 , 0 , 0 , 0 ), // #440 {k, xmm|m64|mem, i8|u8}
- ROW(3, 1, 1, 0, 84 , 87 , 10 , 0 , 0 , 0 ), // #441 {k, xmm|m32|mem, i8|u8}
- ROW(1, 1, 1, 0, 62 , 0 , 0 , 0 , 0 , 0 ), // #442 {vm32y}
- ROW(1, 1, 1, 0, 63 , 0 , 0 , 0 , 0 , 0 ), // #443 {vm32z}
- ROW(1, 1, 1, 0, 66 , 0 , 0 , 0 , 0 , 0 ), // #444 {vm64z}
- ROW(4, 1, 1, 0, 51 , 51 , 49 , 10 , 0 , 0 ), // #445 {zmm, zmm, ymm|m256|mem, i8|u8}
- ROW(1, 1, 1, 0, 30 , 0 , 0 , 0 , 0 , 0 ), // #446 {m64|mem}
- ROW(2, 1, 1, 0, 6 , 86 , 0 , 0 , 0 , 0 ), // #447 {r32, xmm|ymm}
- ROW(2, 1, 1, 0, 148, 150, 0 , 0 , 0 , 0 ), // #448 {xmm|ymm|zmm, xmm|m8|mem|r32|r8lo|r8hi|r16}
- ROW(2, 1, 1, 0, 148, 151, 0 , 0 , 0 , 0 ), // #449 {xmm|ymm|zmm, xmm|m32|mem|r32}
- ROW(2, 1, 1, 0, 148, 84 , 0 , 0 , 0 , 0 ), // #450 {xmm|ymm|zmm, k}
- ROW(2, 1, 1, 0, 148, 152, 0 , 0 , 0 , 0 ), // #451 {xmm|ymm|zmm, xmm|m16|mem|r32|r16}
- ROW(3, 1, 1, 0, 113, 45 , 10 , 0 , 0 , 0 ), // #452 {r32|m16|mem|r16, xmm, i8|u8}
- ROW(4, 1, 1, 0, 45 , 45 , 109, 10 , 0 , 0 ), // #453 {xmm, xmm, r32|m8|mem|r8lo|r8hi|r16, i8|u8}
- ROW(4, 1, 1, 0, 45 , 45 , 28 , 10 , 0 , 0 ), // #454 {xmm, xmm, r32|m32|mem, i8|u8}
- ROW(4, 0, 1, 0, 45 , 45 , 15 , 10 , 0 , 0 ), // #455 {xmm, xmm, r64|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 45 , 45 , 113, 10 , 0 , 0 ), // #456 {xmm, xmm, r32|m16|mem|r16, i8|u8}
- ROW(2, 1, 1, 0, 84 , 148, 0 , 0 , 0 , 0 ), // #457 {k, xmm|ymm|zmm}
- ROW(1, 1, 1, 0, 102, 0 , 0 , 0 , 0 , 0 ), // #458 {rel16|rel32}
- ROW(3, 1, 1, 2, 91 , 35 , 36 , 0 , 0 , 0 ), // #459 {mem, <edx>, <eax>}
- ROW(3, 0, 1, 2, 91 , 35 , 36 , 0 , 0 , 0 ) // #460 {mem, <edx>, <eax>}
+ ROW(1, 1, 0, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #341 {<ax>}
+ ROW(2, 1, 0, 1, 33 , 10 , 0 , 0 , 0 , 0 ), // #342 {<ax>, i8|u8}
+ ROW(2, 1, 0, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // #343 {r16|m16|mem, r16}
+ ROW(3, 1, 1, 1, 45 , 46 , 122, 0 , 0 , 0 ), // #344 {xmm, xmm|m128|mem, <xmm0>}
+ ROW(2, 1, 1, 0, 89 , 123, 0 , 0 , 0 , 0 ), // #345 {bnd, mib}
+ ROW(2, 1, 1, 0, 89 , 91 , 0 , 0 , 0 , 0 ), // #346 {bnd, mem}
+ ROW(2, 1, 1, 0, 123, 89 , 0 , 0 , 0 , 0 ), // #347 {mib, bnd}
+ ROW(1, 1, 1, 0, 124, 0 , 0 , 0 , 0 , 0 ), // #348 {r16|r32|r64}
+ ROW(1, 1, 1, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #349 {<ax>}
+ ROW(2, 1, 1, 2, 35 , 36 , 0 , 0 , 0 , 0 ), // #350 {<edx>, <eax>}
+ ROW(1, 1, 1, 0, 91 , 0 , 0 , 0 , 0 , 0 ), // #351 {mem}
+ ROW(1, 1, 1, 1, 125, 0 , 0 , 0 , 0 , 0 ), // #352 {<ds:[memBase|zax]>}
+ ROW(2, 1, 1, 2, 126, 127, 0 , 0 , 0 , 0 ), // #353 {<ds:[memBase|zsi]>, <es:[memBase|zdi]>}
+ ROW(3, 1, 1, 0, 45 , 60 , 10 , 0 , 0 , 0 ), // #354 {xmm, xmm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 45 , 87 , 10 , 0 , 0 , 0 ), // #355 {xmm, xmm|m32|mem, i8|u8}
+ ROW(5, 0, 1, 4, 47 , 37 , 38 , 128, 129, 0 ), // #356 {m128|mem, <rdx>, <rax>, <rcx>, <rbx>}
+ ROW(5, 1, 1, 4, 30 , 35 , 36 , 99 , 130, 0 ), // #357 {m64|mem, <edx>, <eax>, <ecx>, <ebx>}
+ ROW(4, 1, 1, 4, 36 , 130, 99 , 35 , 0 , 0 ), // #358 {<eax>, <ebx>, <ecx>, <edx>}
+ ROW(2, 0, 1, 2, 37 , 38 , 0 , 0 , 0 , 0 ), // #359 {<rdx>, <rax>}
+ ROW(2, 1, 1, 0, 57 , 46 , 0 , 0 , 0 , 0 ), // #360 {mm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 45 , 117, 0 , 0 , 0 , 0 ), // #361 {xmm, mm|m64|mem}
+ ROW(2, 1, 1, 0, 57 , 60 , 0 , 0 , 0 , 0 ), // #362 {mm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 114, 60 , 0 , 0 , 0 , 0 ), // #363 {r32|r64, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 45 , 131, 0 , 0 , 0 , 0 ), // #364 {xmm, r32|m32|mem|r64|m64}
+ ROW(2, 1, 1, 0, 114, 87 , 0 , 0 , 0 , 0 ), // #365 {r32|r64, xmm|m32|mem}
+ ROW(2, 1, 1, 2, 34 , 33 , 0 , 0 , 0 , 0 ), // #366 {<dx>, <ax>}
+ ROW(1, 1, 1, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #367 {<eax>}
+ ROW(2, 1, 1, 0, 12 , 10 , 0 , 0 , 0 , 0 ), // #368 {i16|u16, i8|u8}
+ ROW(3, 1, 1, 0, 28 , 45 , 10 , 0 , 0 , 0 ), // #369 {r32|m32|mem, xmm, i8|u8}
+ ROW(1, 1, 1, 0, 80 , 0 , 0 , 0 , 0 , 0 ), // #370 {m80|mem}
+ ROW(1, 1, 1, 0, 132, 0 , 0 , 0 , 0 , 0 ), // #371 {m16|m32}
+ ROW(1, 1, 1, 0, 133, 0 , 0 , 0 , 0 , 0 ), // #372 {m16|m32|m64}
+ ROW(1, 1, 1, 0, 134, 0 , 0 , 0 , 0 , 0 ), // #373 {m32|m64|m80|st}
+ ROW(1, 1, 1, 0, 21 , 0 , 0 , 0 , 0 , 0 ), // #374 {m16|mem}
+ ROW(1, 1, 1, 0, 135, 0 , 0 , 0 , 0 , 0 ), // #375 {ax|m16|mem}
+ ROW(1, 0, 1, 0, 91 , 0 , 0 , 0 , 0 , 0 ), // #376 {mem}
+ ROW(2, 1, 1, 0, 136, 137, 0 , 0 , 0 , 0 ), // #377 {al|ax|eax, i8|u8|dx}
+ ROW(2, 1, 1, 0, 138, 139, 0 , 0 , 0 , 0 ), // #378 {es:[memBase|zdi], dx}
+ ROW(1, 1, 1, 0, 10 , 0 , 0 , 0 , 0 , 0 ), // #379 {i8|u8}
+ ROW(0, 1, 0, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #380 {}
+ ROW(0, 0, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #381 {}
+ ROW(3, 1, 1, 0, 84 , 84 , 84 , 0 , 0 , 0 ), // #382 {k, k, k}
+ ROW(2, 1, 1, 0, 84 , 84 , 0 , 0 , 0 , 0 ), // #383 {k, k}
+ ROW(3, 1, 1, 0, 84 , 84 , 10 , 0 , 0 , 0 ), // #384 {k, k, i8|u8}
+ ROW(1, 1, 1, 1, 140, 0 , 0 , 0 , 0 , 0 ), // #385 {<ah>}
+ ROW(1, 1, 1, 0, 29 , 0 , 0 , 0 , 0 , 0 ), // #386 {m32|mem}
+ ROW(2, 1, 1, 0, 124, 141, 0 , 0 , 0 , 0 ), // #387 {r16|r32|r64, mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+ ROW(1, 1, 1, 0, 27 , 0 , 0 , 0 , 0 , 0 ), // #388 {r16|m16|mem}
+ ROW(1, 1, 1, 0, 114, 0 , 0 , 0 , 0 , 0 ), // #389 {r32|r64}
+ ROW(2, 1, 1, 2, 142, 126, 0 , 0 , 0 , 0 ), // #390 {<al|ax|eax|rax>, <ds:[memBase|zsi]>}
+ ROW(3, 1, 1, 0, 114, 28 , 14 , 0 , 0 , 0 ), // #391 {r32|r64, r32|m32|mem, i32|u32}
+ ROW(3, 1, 1, 1, 45 , 45 , 143, 0 , 0 , 0 ), // #392 {xmm, xmm, <ds:[memBase|zdi]>}
+ ROW(3, 1, 1, 1, 57 , 57 , 143, 0 , 0 , 0 ), // #393 {mm, mm, <ds:[memBase|zdi]>}
+ ROW(3, 1, 1, 3, 125, 99 , 35 , 0 , 0 , 0 ), // #394 {<ds:[memBase|zax]>, <ecx>, <edx>}
+ ROW(2, 1, 1, 0, 97 , 53 , 0 , 0 , 0 , 0 ), // #395 {es:[memBase], m512|mem}
+ ROW(2, 1, 1, 0, 57 , 45 , 0 , 0 , 0 , 0 ), // #396 {mm, xmm}
+ ROW(2, 1, 1, 0, 6 , 45 , 0 , 0 , 0 , 0 ), // #397 {r32, xmm}
+ ROW(2, 1, 1, 0, 30 , 57 , 0 , 0 , 0 , 0 ), // #398 {m64|mem, mm}
+ ROW(2, 1, 1, 0, 45 , 57 , 0 , 0 , 0 , 0 ), // #399 {xmm, mm}
+ ROW(2, 1, 1, 2, 127, 126, 0 , 0 , 0 , 0 ), // #400 {<es:[memBase|zdi]>, <ds:[memBase|zsi]>}
+ ROW(2, 1, 1, 2, 36 , 99 , 0 , 0 , 0 , 0 ), // #401 {<eax>, <ecx>}
+ ROW(3, 1, 1, 3, 36 , 99 , 130, 0 , 0 , 0 ), // #402 {<eax>, <ecx>, <ebx>}
+ ROW(2, 1, 1, 0, 144, 136, 0 , 0 , 0 , 0 ), // #403 {u8|dx, al|ax|eax}
+ ROW(2, 1, 1, 0, 139, 145, 0 , 0 , 0 , 0 ), // #404 {dx, ds:[memBase|zsi]}
+ ROW(6, 1, 1, 3, 45 , 46 , 10 , 99 , 36 , 35 ), // #405 {xmm, xmm|m128|mem, i8|u8, <ecx>, <eax>, <edx>}
+ ROW(6, 1, 1, 3, 45 , 46 , 10 , 122, 36 , 35 ), // #406 {xmm, xmm|m128|mem, i8|u8, <xmm0>, <eax>, <edx>}
+ ROW(4, 1, 1, 1, 45 , 46 , 10 , 99 , 0 , 0 ), // #407 {xmm, xmm|m128|mem, i8|u8, <ecx>}
+ ROW(4, 1, 1, 1, 45 , 46 , 10 , 122, 0 , 0 ), // #408 {xmm, xmm|m128|mem, i8|u8, <xmm0>}
+ ROW(3, 1, 1, 0, 109, 45 , 10 , 0 , 0 , 0 ), // #409 {r32|m8|mem|r8lo|r8hi|r16, xmm, i8|u8}
+ ROW(3, 0, 1, 0, 15 , 45 , 10 , 0 , 0 , 0 ), // #410 {r64|m64|mem, xmm, i8|u8}
+ ROW(3, 1, 1, 0, 45 , 109, 10 , 0 , 0 , 0 ), // #411 {xmm, r32|m8|mem|r8lo|r8hi|r16, i8|u8}
+ ROW(3, 1, 1, 0, 45 , 28 , 10 , 0 , 0 , 0 ), // #412 {xmm, r32|m32|mem, i8|u8}
+ ROW(3, 0, 1, 0, 45 , 15 , 10 , 0 , 0 , 0 ), // #413 {xmm, r64|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 59 , 113, 10 , 0 , 0 , 0 ), // #414 {mm|xmm, r32|m16|mem|r16, i8|u8}
+ ROW(2, 1, 1, 0, 6 , 59 , 0 , 0 , 0 , 0 ), // #415 {r32, mm|xmm}
+ ROW(2, 1, 1, 0, 45 , 10 , 0 , 0 , 0 , 0 ), // #416 {xmm, i8|u8}
+ ROW(2, 1, 1, 0, 31 , 81 , 0 , 0 , 0 , 0 ), // #417 {r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, cl|i8|u8}
+ ROW(1, 0, 1, 0, 114, 0 , 0 , 0 , 0 , 0 ), // #418 {r32|r64}
+ ROW(3, 1, 1, 3, 35 , 36 , 99 , 0 , 0 , 0 ), // #419 {<edx>, <eax>, <ecx>}
+ ROW(2, 1, 1, 2, 142, 127, 0 , 0 , 0 , 0 ), // #420 {<al|ax|eax|rax>, <es:[memBase|zdi]>}
+ ROW(1, 1, 1, 0, 1 , 0 , 0 , 0 , 0 , 0 ), // #421 {r8lo|r8hi|m8|mem}
+ ROW(1, 1, 1, 0, 146, 0 , 0 , 0 , 0 , 0 ), // #422 {r16|m16|mem|r32|r64}
+ ROW(2, 1, 1, 2, 127, 142, 0 , 0 , 0 , 0 ), // #423 {<es:[memBase|zdi]>, <al|ax|eax|rax>}
+ ROW(6, 1, 1, 0, 51 , 51 , 51 , 51 , 51 , 47 ), // #424 {zmm, zmm, zmm, zmm, zmm, m128|mem}
+ ROW(6, 1, 1, 0, 45 , 45 , 45 , 45 , 45 , 47 ), // #425 {xmm, xmm, xmm, xmm, xmm, m128|mem}
+ ROW(3, 1, 1, 0, 45 , 45 , 60 , 0 , 0 , 0 ), // #426 {xmm, xmm, xmm|m64|mem}
+ ROW(3, 1, 1, 0, 45 , 45 , 87 , 0 , 0 , 0 ), // #427 {xmm, xmm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 48 , 47 , 0 , 0 , 0 , 0 ), // #428 {ymm, m128|mem}
+ ROW(2, 1, 1, 0, 147, 60 , 0 , 0 , 0 , 0 ), // #429 {ymm|zmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 147, 47 , 0 , 0 , 0 , 0 ), // #430 {ymm|zmm, m128|mem}
+ ROW(2, 1, 1, 0, 51 , 50 , 0 , 0 , 0 , 0 ), // #431 {zmm, m256|mem}
+ ROW(2, 1, 1, 0, 148, 60 , 0 , 0 , 0 , 0 ), // #432 {xmm|ymm|zmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 148, 87 , 0 , 0 , 0 , 0 ), // #433 {xmm|ymm|zmm, m32|mem|xmm}
+ ROW(4, 1, 1, 0, 82 , 45 , 60 , 10 , 0 , 0 ), // #434 {xmm|k, xmm, xmm|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 82 , 45 , 87 , 10 , 0 , 0 ), // #435 {xmm|k, xmm, xmm|m32|mem, i8|u8}
+ ROW(3, 1, 1, 0, 45 , 45 , 131, 0 , 0 , 0 ), // #436 {xmm, xmm, r32|m32|mem|r64|m64}
+ ROW(3, 1, 1, 0, 46 , 147, 10 , 0 , 0 , 0 ), // #437 {xmm|m128|mem, ymm|zmm, i8|u8}
+ ROW(4, 1, 1, 0, 45 , 45 , 60 , 10 , 0 , 0 ), // #438 {xmm, xmm, xmm|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 45 , 45 , 87 , 10 , 0 , 0 ), // #439 {xmm, xmm, xmm|m32|mem, i8|u8}
+ ROW(3, 1, 1, 0, 84 , 149, 10 , 0 , 0 , 0 ), // #440 {k, xmm|m128|ymm|m256|zmm|m512, i8|u8}
+ ROW(3, 1, 1, 0, 84 , 60 , 10 , 0 , 0 , 0 ), // #441 {k, xmm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 84 , 87 , 10 , 0 , 0 , 0 ), // #442 {k, xmm|m32|mem, i8|u8}
+ ROW(1, 1, 1, 0, 62 , 0 , 0 , 0 , 0 , 0 ), // #443 {vm32y}
+ ROW(1, 1, 1, 0, 63 , 0 , 0 , 0 , 0 , 0 ), // #444 {vm32z}
+ ROW(1, 1, 1, 0, 66 , 0 , 0 , 0 , 0 , 0 ), // #445 {vm64z}
+ ROW(4, 1, 1, 0, 51 , 51 , 49 , 10 , 0 , 0 ), // #446 {zmm, zmm, ymm|m256|mem, i8|u8}
+ ROW(1, 1, 1, 0, 30 , 0 , 0 , 0 , 0 , 0 ), // #447 {m64|mem}
+ ROW(2, 1, 1, 0, 6 , 86 , 0 , 0 , 0 , 0 ), // #448 {r32, xmm|ymm}
+ ROW(2, 1, 1, 0, 148, 150, 0 , 0 , 0 , 0 ), // #449 {xmm|ymm|zmm, xmm|m8|mem|r32|r8lo|r8hi|r16}
+ ROW(2, 1, 1, 0, 148, 151, 0 , 0 , 0 , 0 ), // #450 {xmm|ymm|zmm, xmm|m32|mem|r32}
+ ROW(2, 1, 1, 0, 148, 84 , 0 , 0 , 0 , 0 ), // #451 {xmm|ymm|zmm, k}
+ ROW(2, 1, 1, 0, 148, 152, 0 , 0 , 0 , 0 ), // #452 {xmm|ymm|zmm, xmm|m16|mem|r32|r16}
+ ROW(3, 1, 1, 0, 113, 45 , 10 , 0 , 0 , 0 ), // #453 {r32|m16|mem|r16, xmm, i8|u8}
+ ROW(4, 1, 1, 0, 45 , 45 , 109, 10 , 0 , 0 ), // #454 {xmm, xmm, r32|m8|mem|r8lo|r8hi|r16, i8|u8}
+ ROW(4, 1, 1, 0, 45 , 45 , 28 , 10 , 0 , 0 ), // #455 {xmm, xmm, r32|m32|mem, i8|u8}
+ ROW(4, 0, 1, 0, 45 , 45 , 15 , 10 , 0 , 0 ), // #456 {xmm, xmm, r64|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 45 , 45 , 113, 10 , 0 , 0 ), // #457 {xmm, xmm, r32|m16|mem|r16, i8|u8}
+ ROW(2, 1, 1, 0, 84 , 148, 0 , 0 , 0 , 0 ), // #458 {k, xmm|ymm|zmm}
+ ROW(1, 1, 1, 0, 102, 0 , 0 , 0 , 0 , 0 ), // #459 {rel16|rel32}
+ ROW(3, 1, 1, 2, 91 , 35 , 36 , 0 , 0 , 0 ), // #460 {mem, <edx>, <eax>}
+ ROW(3, 0, 1, 2, 91 , 35 , 36 , 0 , 0 , 0 ) // #461 {mem, <edx>, <eax>}
};
#undef ROW
@@ -3451,104 +3452,104 @@ const uint8_t InstDB::rwInfoIndex[Inst::_kIdCount * 2] = {
0, 81, 0, 36, 0, 112, 0, 111, 0, 86, 0, 110, 0, 110, 0, 113, 0, 114, 0, 114,
0, 115, 0, 116, 0, 116, 0, 117, 0, 117, 0, 97, 0, 97, 0, 111, 0, 97, 0, 97, 0,
116, 0, 116, 0, 118, 0, 82, 0, 86, 0, 119, 0, 82, 0, 7, 0, 7, 0, 81, 0, 120,
- 0, 121, 0, 110, 0, 110, 0, 120, 0, 0, 4, 49, 122, 4, 0, 4, 0, 5, 0, 6, 0, 0,
- 123, 124, 0, 0, 125, 0, 48, 0, 126, 0, 48, 2, 0, 4, 0, 4, 0, 127, 0, 128, 0, 11,
+ 0, 11, 0, 110, 0, 110, 0, 120, 0, 0, 4, 49, 121, 4, 0, 4, 0, 5, 0, 6, 0, 0, 122,
+ 123, 0, 0, 124, 0, 48, 0, 125, 0, 48, 2, 0, 4, 0, 4, 0, 126, 0, 127, 0, 11,
0, 11, 0, 11, 0, 3, 0, 3, 0, 4, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
- 3, 0, 3, 0, 0, 3, 3, 0, 3, 0, 0, 0, 3, 0, 129, 0, 3, 0, 0, 12, 0, 4, 0, 4, 3,
- 0, 3, 0, 4, 0, 3, 0, 0, 130, 0, 131, 3, 0, 3, 0, 4, 0, 3, 0, 0, 132, 0, 133,
- 0, 0, 0, 8, 0, 8, 0, 134, 0, 52, 0, 135, 0, 136, 39, 0, 39, 0, 129, 0, 129, 0,
- 129, 0, 129, 0, 129, 0, 129, 0, 129, 0, 129, 0, 129, 0, 129, 0, 39, 0, 129,
- 0, 129, 0, 129, 0, 39, 0, 39, 0, 129, 0, 129, 0, 129, 0, 3, 0, 3, 0, 3, 0, 137,
- 0, 3, 0, 3, 0, 3, 0, 39, 0, 39, 0, 0, 138, 0, 72, 0, 139, 0, 140, 3, 0, 3, 0,
- 4, 0, 4, 0, 3, 0, 3, 0, 4, 0, 4, 0, 4, 0, 4, 0, 3, 0, 3, 0, 4, 0, 4, 0, 141,
- 0, 142, 0, 143, 0, 36, 0, 36, 0, 36, 0, 142, 0, 142, 0, 143, 0, 36, 0, 36, 0,
- 36, 0, 142, 0, 4, 0, 3, 0, 129, 0, 3, 0, 3, 0, 4, 0, 3, 0, 3, 0, 0, 144, 0, 0,
+ 3, 0, 3, 0, 0, 3, 3, 0, 3, 0, 0, 0, 3, 0, 128, 0, 3, 0, 0, 12, 0, 4, 0, 4, 3,
+ 0, 3, 0, 4, 0, 3, 0, 0, 129, 0, 130, 3, 0, 3, 0, 4, 0, 3, 0, 0, 131, 0, 132,
+ 0, 0, 0, 8, 0, 8, 0, 133, 0, 52, 0, 134, 0, 135, 39, 0, 39, 0, 128, 0, 128, 0,
+ 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 39, 0, 128, 0,
+ 128, 0, 128, 0, 39, 0, 39, 0, 128, 0, 128, 0, 128, 0, 3, 0, 3, 0, 3, 0, 136,
+ 0, 3, 0, 3, 0, 3, 0, 39, 0, 39, 0, 0, 137, 0, 72, 0, 138, 0, 139, 3, 0, 3, 0,
+ 4, 0, 4, 0, 3, 0, 3, 0, 4, 0, 4, 0, 4, 0, 4, 0, 3, 0, 3, 0, 4, 0, 4, 0, 140,
+ 0, 141, 0, 142, 0, 36, 0, 36, 0, 36, 0, 141, 0, 141, 0, 142, 0, 36, 0, 36, 0,
+ 36, 0, 141, 0, 4, 0, 3, 0, 128, 0, 3, 0, 3, 0, 4, 0, 3, 0, 3, 0, 0, 143, 0, 0,
0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24,
- 0, 24, 3, 0, 3, 0, 0, 7, 0, 7, 0, 7, 0, 39, 3, 0, 3, 0, 3, 0, 3, 0, 54, 0,
- 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 54, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
- 3, 0, 3, 0, 3, 0, 39, 0, 145, 0, 3, 0, 3, 0, 4, 0, 3, 0, 3, 0, 3, 0, 4, 0, 3,
- 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 147, 0, 7, 0, 148, 0, 147, 0,
- 0, 149, 0, 149, 0, 150, 0, 149, 0, 150, 0, 149, 0, 149, 151, 0, 0, 152, 0, 0,
- 147, 0, 147, 0, 0, 11, 0, 7, 0, 7, 0, 38, 0, 148, 0, 0, 7, 0, 148, 0, 0, 153,
- 147, 0, 147, 0, 0, 10, 2, 0, 154, 0, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0,
- 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155,
- 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 155,
- 0, 155, 0, 155, 0, 155, 0, 155, 0, 155, 0, 0, 0, 64, 4, 0, 4, 0, 4, 0, 0, 4,
- 4, 0, 4, 0, 0, 12, 147, 0, 0, 156, 0, 10, 147, 0, 0, 156, 0, 10, 0, 4, 0, 4,
- 0, 64, 0, 47, 0, 157, 0, 149, 0, 157, 7, 0, 7, 0, 38, 0, 148, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 158, 159, 0, 0, 157, 2, 0, 4, 0, 4, 0, 5, 0, 6, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 19, 0, 11, 0, 11, 0, 31, 0, 32, 0,
- 0, 0, 4, 0, 4, 0, 4, 0, 4, 0, 0, 160, 0, 161, 0, 160, 0, 161, 0, 8, 0, 8, 0, 162,
- 0, 163, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 7, 0, 0, 7, 0, 8, 0, 8, 0, 8,
- 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 164, 0, 164,
- 165, 0, 40, 0, 166, 0, 167, 0, 166, 0, 167, 0, 165, 0, 40, 0, 166, 0, 167,
- 0, 166, 0, 167, 0, 168, 0, 169, 0, 0, 8, 0, 8, 0, 170, 0, 171, 31, 0, 32, 0,
- 172, 0, 172, 0, 173, 0, 11, 0, 0, 8, 120, 0, 174, 0, 174, 0, 11, 0, 174, 0, 11,
- 0, 173, 0, 11, 0, 173, 0, 0, 175, 173, 0, 11, 0, 173, 0, 11, 0, 174, 0, 40,
- 0, 0, 176, 40, 0, 0, 177, 0, 178, 0, 179, 45, 0, 45, 0, 174, 0, 11, 0, 174, 0,
- 11, 0, 11, 0, 173, 0, 11, 0, 173, 0, 40, 0, 40, 0, 45, 0, 45, 0, 173, 0, 11,
- 0, 11, 0, 174, 0, 0, 177, 0, 178, 0, 8, 0, 8, 0, 8, 0, 162, 0, 163, 0, 8, 0, 180,
- 0, 8, 0, 101, 0, 101, 181, 0, 181, 0, 11, 0, 11, 0, 0, 182, 0, 183, 0, 184,
- 0, 183, 0, 184, 0, 182, 0, 183, 0, 184, 0, 183, 0, 184, 0, 52, 0, 185, 0, 185,
- 0, 186, 0, 187, 0, 185, 0, 185, 0, 188, 0, 189, 0, 185, 0, 185, 0, 188, 0,
- 189, 0, 185, 0, 185, 0, 188, 0, 189, 0, 190, 0, 190, 0, 191, 0, 192, 0, 185, 0,
- 185, 0, 185, 0, 185, 0, 185, 0, 185, 0, 190, 0, 190, 0, 185, 0, 185, 0, 188,
- 0, 189, 0, 185, 0, 185, 0, 188, 0, 189, 0, 185, 0, 185, 0, 188, 0, 189, 0, 185,
- 0, 185, 0, 185, 0, 185, 0, 185, 0, 185, 0, 190, 0, 190, 0, 190, 0, 190, 0,
- 191, 0, 192, 0, 185, 0, 185, 0, 188, 0, 189, 0, 185, 0, 185, 0, 188, 0, 189, 0,
- 185, 0, 185, 0, 188, 0, 189, 0, 190, 0, 190, 0, 191, 0, 192, 0, 185, 0, 185,
- 0, 188, 0, 189, 0, 185, 0, 185, 0, 188, 0, 189, 0, 185, 0, 185, 0, 193, 0, 194,
- 0, 190, 0, 190, 0, 191, 0, 192, 0, 195, 0, 195, 0, 39, 0, 121, 11, 0, 11, 0,
+ 0, 24, 3, 0, 3, 0, 0, 7, 0, 7, 0, 7, 0, 39, 3, 0, 3, 0, 3, 0, 3, 0, 54, 0, 3,
+ 0, 3, 0, 3, 0, 3, 0, 3, 0, 54, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 39, 0, 144, 0, 3, 0, 3, 0, 4, 0, 3, 0, 3, 0, 3, 0, 4, 0, 3,
+ 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 146, 0, 7, 0, 147, 0, 146, 0, 0,
+ 148, 0, 148, 0, 149, 0, 148, 0, 149, 0, 148, 0, 148, 150, 0, 0, 151, 0, 0, 146,
+ 0, 146, 0, 0, 11, 0, 7, 0, 7, 0, 38, 0, 147, 0, 0, 7, 0, 147, 0, 0, 152, 146,
+ 0, 146, 0, 0, 10, 2, 0, 153, 0, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0,
+ 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154,
+ 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 154,
+ 0, 154, 0, 154, 0, 154, 0, 154, 0, 154, 0, 0, 0, 64, 4, 0, 4, 0, 4, 0, 0, 4,
+ 4, 0, 4, 0, 0, 12, 146, 0, 0, 155, 0, 10, 146, 0, 0, 155, 0, 10, 0, 4, 0, 4,
+ 0, 64, 0, 47, 0, 156, 0, 148, 0, 156, 7, 0, 7, 0, 38, 0, 147, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 157, 158, 0, 0, 156, 2, 0, 4, 0, 4, 0, 5, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 19, 0, 11, 0, 11, 0, 31, 0, 32, 0, 0,
+ 0, 4, 0, 4, 0, 4, 0, 4, 0, 0, 159, 0, 160, 0, 159, 0, 160, 0, 8, 0, 8, 0, 161,
+ 0, 162, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 7, 0, 0, 7, 0, 8, 0, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 163, 0, 163,
+ 164, 0, 40, 0, 165, 0, 166, 0, 165, 0, 166, 0, 164, 0, 40, 0, 165, 0, 166,
+ 0, 165, 0, 166, 0, 167, 0, 168, 0, 0, 8, 0, 8, 0, 169, 0, 170, 31, 0, 32, 0, 171,
+ 0, 171, 0, 172, 0, 11, 0, 0, 8, 120, 0, 173, 0, 173, 0, 11, 0, 173, 0, 11,
+ 0, 172, 0, 11, 0, 172, 0, 0, 174, 172, 0, 11, 0, 172, 0, 11, 0, 173, 0, 40, 0,
+ 0, 175, 40, 0, 0, 176, 0, 177, 0, 178, 45, 0, 45, 0, 173, 0, 11, 0, 173, 0,
+ 11, 0, 11, 0, 172, 0, 11, 0, 172, 0, 40, 0, 40, 0, 45, 0, 45, 0, 172, 0, 11, 0,
+ 11, 0, 173, 0, 0, 176, 0, 177, 0, 8, 0, 8, 0, 8, 0, 161, 0, 162, 0, 8, 0, 179,
+ 0, 8, 0, 101, 0, 101, 180, 0, 180, 0, 11, 0, 11, 0, 0, 181, 0, 182, 0, 183,
+ 0, 182, 0, 183, 0, 181, 0, 182, 0, 183, 0, 182, 0, 183, 0, 52, 0, 184, 0, 184,
+ 0, 185, 0, 186, 0, 184, 0, 184, 0, 187, 0, 188, 0, 184, 0, 184, 0, 187, 0, 188,
+ 0, 184, 0, 184, 0, 187, 0, 188, 0, 189, 0, 189, 0, 190, 0, 191, 0, 184, 0,
+ 184, 0, 184, 0, 184, 0, 184, 0, 184, 0, 189, 0, 189, 0, 184, 0, 184, 0, 187,
+ 0, 188, 0, 184, 0, 184, 0, 187, 0, 188, 0, 184, 0, 184, 0, 187, 0, 188, 0, 184,
+ 0, 184, 0, 184, 0, 184, 0, 184, 0, 184, 0, 189, 0, 189, 0, 189, 0, 189, 0, 190,
+ 0, 191, 0, 184, 0, 184, 0, 187, 0, 188, 0, 184, 0, 184, 0, 187, 0, 188, 0,
+ 184, 0, 184, 0, 187, 0, 188, 0, 189, 0, 189, 0, 190, 0, 191, 0, 184, 0, 184,
+ 0, 187, 0, 188, 0, 184, 0, 184, 0, 187, 0, 188, 0, 184, 0, 184, 0, 192, 0, 193,
+ 0, 189, 0, 189, 0, 190, 0, 191, 0, 194, 0, 194, 0, 39, 0, 195, 11, 0, 11, 0,
39, 0, 196, 0, 99, 197, 99, 198, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0,
- 24, 0, 24, 99, 198, 99, 199, 11, 0, 11, 0, 0, 200, 0, 201, 0, 11, 0, 11, 0,
- 200, 0, 201, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 202, 0, 203, 0, 204,
- 0, 203, 0, 204, 0, 202, 0, 203, 0, 204, 0, 203, 0, 204, 0, 163, 111, 0, 0, 98,
- 0, 106, 0, 205, 0, 205, 0, 8, 0, 8, 0, 162, 0, 163, 0, 0, 0, 206, 0, 0, 0, 8,
- 0, 8, 0, 162, 0, 163, 0, 0, 0, 207, 0, 0, 208, 0, 208, 0, 81, 0, 209, 0, 208,
+ 24, 0, 24, 99, 198, 99, 199, 11, 0, 11, 0, 0, 200, 0, 201, 0, 11, 0, 11, 0, 200,
+ 0, 201, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 202, 0, 203, 0, 204,
+ 0, 203, 0, 204, 0, 202, 0, 203, 0, 204, 0, 203, 0, 204, 0, 162, 111, 0, 0, 98,
+ 0, 106, 0, 205, 0, 205, 0, 8, 0, 8, 0, 161, 0, 162, 0, 0, 0, 206, 0, 0, 0, 8,
+ 0, 8, 0, 161, 0, 162, 0, 0, 0, 207, 0, 0, 208, 0, 208, 0, 81, 0, 209, 0, 208,
0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 0, 210, 211, 212,
211, 212, 0, 213, 116, 214, 116, 214, 215, 0, 216, 0, 111, 0, 111, 0, 111, 0,
111, 0, 217, 0, 116, 218, 11, 0, 11, 0, 118, 219, 208, 0, 208, 0, 0, 8, 0, 220,
- 0, 206, 172, 0, 0, 0, 0, 221, 0, 207, 0, 8, 0, 8, 0, 162, 0, 163, 222, 0, 0,
- 220, 0, 8, 0, 8, 0, 223, 0, 223, 11, 0, 11, 0, 11, 0, 11, 0, 0, 8, 0, 8, 0,
- 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0,
- 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 164, 0, 8, 224, 0, 45, 0, 225, 0, 225,
- 0, 40, 0, 226, 0, 0, 8, 0, 190, 0, 227, 0, 227, 0, 8, 0, 8, 0, 8, 0, 8, 0,
- 130, 0, 131, 0, 8, 0, 8, 0, 8, 0, 8, 0, 132, 0, 133, 0, 227, 0, 227, 0, 227, 0,
- 227, 0, 227, 0, 227, 0, 180, 0, 180, 172, 0, 172, 0, 172, 0, 172, 0, 0, 180,
- 0, 180, 0, 180, 0, 180, 0, 180, 0, 180, 11, 0, 11, 0, 0, 185, 0, 185, 0, 185,
- 0, 185, 0, 228, 0, 228, 0, 8, 0, 8, 0, 8, 0, 185, 0, 8, 0, 8, 0, 185, 0, 185,
- 0, 190, 0, 190, 0, 229, 0, 229, 0, 229, 0, 8, 0, 229, 0, 8, 0, 185, 0, 185, 0,
- 185, 0, 185, 0, 185, 0, 8, 11, 0, 11, 0, 11, 0, 11, 0, 0, 134, 0, 52, 0, 135,
+ 0, 206, 171, 0, 0, 0, 0, 221, 0, 207, 0, 8, 0, 8, 0, 161, 0, 162, 222, 0, 0,
+ 220, 0, 8, 0, 8, 0, 223, 0, 223, 11, 0, 11, 0, 11, 0, 11, 0, 0, 8, 0, 8, 0, 8,
+ 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8,
+ 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 163, 0, 8, 224, 0, 45, 0, 225, 0, 225,
+ 0, 40, 0, 226, 0, 0, 8, 0, 189, 0, 227, 0, 227, 0, 8, 0, 8, 0, 8, 0, 8, 0, 129,
+ 0, 130, 0, 8, 0, 8, 0, 8, 0, 8, 0, 131, 0, 132, 0, 227, 0, 227, 0, 227, 0,
+ 227, 0, 227, 0, 227, 0, 179, 0, 179, 171, 0, 171, 0, 171, 0, 171, 0, 0, 179,
+ 0, 179, 0, 179, 0, 179, 0, 179, 0, 179, 11, 0, 11, 0, 0, 184, 0, 184, 0, 184,
+ 0, 184, 0, 228, 0, 228, 0, 8, 0, 8, 0, 8, 0, 184, 0, 8, 0, 8, 0, 184, 0, 184,
+ 0, 189, 0, 189, 0, 229, 0, 229, 0, 229, 0, 8, 0, 229, 0, 8, 0, 184, 0, 184, 0,
+ 184, 0, 184, 0, 184, 0, 8, 11, 0, 11, 0, 11, 0, 11, 0, 0, 133, 0, 52, 0, 134,
0, 230, 99, 198, 99, 197, 99, 199, 99, 198, 7, 0, 7, 0, 7, 0, 0, 8, 7, 0, 0,
- 8, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 0, 8, 7, 0, 7, 0, 137, 0, 7, 0, 0, 8,
- 7, 0, 0, 8, 0, 8, 7, 0, 0, 231, 0, 163, 0, 162, 0, 232, 11, 0, 11, 0, 0, 233,
- 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233,
- 0, 233, 0, 185, 0, 185, 0, 8, 0, 8, 0, 205, 0, 205, 0, 8, 0, 8, 0, 8, 0, 8,
- 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 234, 0,
- 234, 0, 235, 0, 175, 0, 225, 0, 225, 0, 225, 0, 225, 0, 141, 0, 234, 0, 236,
- 0, 175, 0, 235, 0, 235, 0, 175, 0, 236, 0, 175, 0, 235, 0, 175, 0, 237, 0, 238,
- 0, 173, 0, 173, 0, 173, 0, 237, 0, 235, 0, 175, 0, 236, 0, 175, 0, 235, 0,
- 175, 0, 234, 0, 175, 0, 237, 0, 238, 0, 173, 0, 173, 0, 173, 0, 237, 0, 0, 8,
- 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 11, 0, 11, 0, 11, 0, 11, 0, 0,
+ 8, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 0, 8, 7, 0, 7, 0, 136, 0, 7, 0, 0, 8, 7,
+ 0, 0, 8, 0, 8, 7, 0, 0, 231, 0, 162, 0, 161, 0, 232, 11, 0, 11, 0, 0, 233, 0,
+ 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233, 0, 233,
+ 0, 233, 0, 184, 0, 184, 0, 8, 0, 8, 0, 205, 0, 205, 0, 8, 0, 8, 0, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 234, 0,
+ 234, 0, 235, 0, 174, 0, 225, 0, 225, 0, 225, 0, 225, 0, 140, 0, 234, 0, 236,
+ 0, 174, 0, 235, 0, 235, 0, 174, 0, 236, 0, 174, 0, 235, 0, 174, 0, 237, 0, 238,
+ 0, 172, 0, 172, 0, 172, 0, 237, 0, 235, 0, 174, 0, 236, 0, 174, 0, 235, 0, 174,
+ 0, 234, 0, 174, 0, 237, 0, 238, 0, 172, 0, 172, 0, 172, 0, 237, 0, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 11, 0, 11, 0, 11, 0, 11, 0, 0,
8, 0, 8, 0, 8, 0, 239, 0, 11, 0, 11, 0, 8, 0, 8, 0, 11, 0, 11, 0, 8, 0, 8, 0,
240, 0, 240, 0, 240, 0, 240, 0, 8, 111, 0, 111, 0, 241, 0, 111, 0, 0, 240, 0,
- 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 8, 0, 8, 0, 185, 0, 185, 0, 185, 0, 8,
- 0, 240, 0, 240, 0, 8, 0, 8, 0, 185, 0, 185, 0, 185, 0, 8, 0, 8, 0, 227, 0, 11,
+ 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 8, 0, 8, 0, 184, 0, 184, 0, 184, 0, 8,
+ 0, 240, 0, 240, 0, 8, 0, 8, 0, 184, 0, 184, 0, 184, 0, 8, 0, 8, 0, 227, 0, 11,
0, 11, 0, 11, 0, 8, 0, 8, 0, 8, 0, 242, 0, 243, 0, 242, 0, 8, 0, 8, 0, 8, 0,
242, 0, 242, 0, 242, 0, 8, 0, 8, 0, 8, 0, 242, 0, 242, 0, 243, 0, 242, 0, 8,
- 0, 8, 0, 8, 0, 242, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 185, 0,
- 185, 222, 0, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227,
+ 0, 8, 0, 8, 0, 242, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 184, 0,
+ 184, 222, 0, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227, 0, 227,
0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8,
- 0, 200, 0, 201, 11, 0, 11, 0, 0, 200, 0, 201, 181, 0, 181, 0, 0, 200, 0, 201,
+ 0, 200, 0, 201, 11, 0, 11, 0, 0, 200, 0, 201, 180, 0, 180, 0, 0, 200, 0, 201,
11, 0, 0, 201, 0, 11, 0, 11, 0, 200, 0, 201, 0, 11, 0, 11, 0, 200, 0, 201, 0,
- 11, 0, 11, 0, 200, 0, 201, 11, 0, 11, 0, 0, 200, 0, 201, 181, 0, 181, 0, 0, 200,
- 0, 201, 11, 0, 0, 201, 0, 8, 0, 8, 0, 162, 0, 163, 111, 0, 111, 0, 0, 24,
- 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 111, 0, 241, 0, 0, 8, 0, 8, 0,
- 8, 0, 8, 0, 8, 0, 8, 11, 0, 11, 0, 0, 200, 0, 201, 0, 158, 0, 8, 0, 8, 0, 162,
- 0, 163, 222, 0, 222, 0, 31, 0, 32, 0, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 102, 0, 102, 0, 244, 0, 0, 245, 0, 0, 0, 246, 0, 0,
- 0, 0, 150, 0, 0, 2, 0, 4, 0, 4, 0, 0, 247, 0, 247, 0, 247, 0, 247, 0, 248, 0,
- 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 244, 0, 0
+ 11, 0, 11, 0, 200, 0, 201, 11, 0, 11, 0, 0, 200, 0, 201, 180, 0, 180, 0, 0, 200,
+ 0, 201, 11, 0, 0, 201, 0, 8, 0, 8, 0, 161, 0, 162, 111, 0, 111, 0, 0, 24, 0,
+ 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 111, 0, 241, 0, 0, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 11, 0, 11, 0, 0, 200, 0, 201, 0, 157, 0, 8, 0, 8, 0, 161,
+ 0, 162, 222, 0, 222, 0, 31, 0, 32, 0, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 102, 0, 102, 0, 244, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0,
+ 0, 149, 0, 0, 2, 0, 4, 0, 4, 0, 0, 247, 0, 247, 0, 247, 0, 247, 0, 248, 0, 248,
+ 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 244, 0, 0
};
const InstDB::RWInfo InstDB::rwInfo[] = {
@@ -3563,7 +3564,7 @@ const InstDB::RWInfo InstDB::rwInfo[] = {
{ InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 0 , 0 , 0 } }, // #8 [ref=186x]
{ InstDB::RWInfo::kCategoryGeneric , 7 , { 12, 13, 0 , 0 , 0 , 0 } }, // #9 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 3 , 0 , 0 , 0 } }, // #10 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #11 [ref=80x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #11 [ref=81x]
{ InstDB::RWInfo::kCategoryGeneric , 3 , { 4 , 5 , 14, 0 , 0 , 0 } }, // #12 [ref=4x]
{ InstDB::RWInfo::kCategoryGeneric , 2 , { 5 , 3 , 0 , 0 , 0 , 0 } }, // #13 [ref=3x]
{ InstDB::RWInfo::kCategoryGeneric , 8 , { 10, 3 , 0 , 0 , 0 , 0 } }, // #14 [ref=2x]
@@ -3673,81 +3674,81 @@ const InstDB::RWInfo InstDB::rwInfo[] = {
{ InstDB::RWInfo::kCategoryGeneric , 28, { 42, 9 , 0 , 0 , 0 , 0 } }, // #118 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 20, 19, 0 , 0 , 0 , 0 } }, // #119 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 14, { 11, 3 , 0 , 0 , 0 , 0 } }, // #120 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 34, 9 , 0 , 0 , 0 , 0 } }, // #121 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 59, 41, 3 , 0 , 0 , 0 } }, // #122 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 11, 3 , 60, 0 , 0 } }, // #123 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 28, 0 , 0 , 0 , 0 } }, // #124 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 28, 29, 0 , 0 , 0 } }, // #125 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #126 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 50, 21, 0 , 0 , 0 , 0 } }, // #127 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 50, 61, 0 , 0 , 0 , 0 } }, // #128 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 25, 7 , 0 , 0 , 0 , 0 } }, // #129 [ref=18x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 62, 16, 56 } }, // #130 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 63, 16, 56 } }, // #131 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 62, 0 , 0 } }, // #132 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 63, 0 , 0 } }, // #133 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 31, { 53, 5 , 0 , 0 , 0 , 0 } }, // #134 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 32, { 34, 5 , 0 , 0 , 0 , 0 } }, // #135 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 33, { 47, 3 , 0 , 0 , 0 , 0 } }, // #136 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 64, 5 , 0 , 0 , 0 , 0 } }, // #137 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 15, { 4 , 39, 0 , 0 , 0 , 0 } }, // #138 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 4 , 7 , 0 , 0 , 0 , 0 } }, // #139 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 2 , 13, 0 , 0 , 0 , 0 } }, // #140 [ref=1x]
- { InstDB::RWInfo::kCategoryVmov1_8 , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #141 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 10, 9 , 0 , 0 , 0 , 0 } }, // #142 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 10, 13, 0 , 0 , 0 , 0 } }, // #143 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 65, 0 , 0 , 0 , 0 , 0 } }, // #144 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 0 , 0 , 0 } }, // #145 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 60, 0 , 0 , 0 , 0 , 0 } }, // #146 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 66, 0 , 0 , 0 , 0 } }, // #147 [ref=8x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 36, 9 , 0 , 0 , 0 , 0 } }, // #148 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 0 , 0 , 0 , 0 , 0 } }, // #149 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 15, 67, 28, 0 , 0 , 0 } }, // #150 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 15, 67, 0 , 0 , 0 , 0 } }, // #151 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 15, 67, 62, 0 , 0 , 0 } }, // #152 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 68, 0 , 0 , 0 , 0 , 0 } }, // #153 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 21, 20, 0 , 0 , 0 , 0 } }, // #154 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 31, { 69, 0 , 0 , 0 , 0 , 0 } }, // #155 [ref=30x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 3 , 66, 0 , 0 , 0 } }, // #156 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 34, { 11, 0 , 0 , 0 , 0 , 0 } }, // #157 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 28, { 42, 0 , 0 , 0 , 0 , 0 } }, // #158 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 20, 21, 0 , 0 , 0 , 0 } }, // #159 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 70, 43, 43, 43, 43, 5 } }, // #160 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 4 , 5 , 5 , 5 , 5 , 5 } }, // #161 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 10, 5 , 7 , 0 , 0 , 0 } }, // #162 [ref=8x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 5 , 9 , 0 , 0 , 0 } }, // #163 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 3 , 0 , 0 } }, // #164 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 71, 5 , 0 , 0 , 0 , 0 } }, // #165 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 11, 5 , 0 , 0 , 0 , 0 } }, // #166 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 72, 73, 0 , 0 , 0 , 0 } }, // #167 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 38, { 11, 7 , 0 , 0 , 0 , 0 } }, // #168 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 39, { 11, 9 , 0 , 0 , 0 , 0 } }, // #169 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 11, 5 , 7 , 0 , 0 , 0 } }, // #170 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 11, 5 , 9 , 0 , 0 , 0 } }, // #171 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 11, 3 , 0 , 0 , 0 , 0 } }, // #172 [ref=7x]
- { InstDB::RWInfo::kCategoryVmov2_1 , 40, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #173 [ref=14x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 14, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #174 [ref=7x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 41, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #175 [ref=10x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 10, 74, 7 , 0 , 0 , 0 } }, // #176 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 57, 3 , 0 , 0 , 0 } }, // #177 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 74, 3 , 0 , 0 , 0 } }, // #178 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 57, 9 , 0 , 0 , 0 } }, // #179 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 43, { 10, 5 , 5 , 0 , 0 , 0 } }, // #180 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 44, { 72, 43, 0 , 0 , 0 , 0 } }, // #181 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 45, { 10, 73, 0 , 0 , 0 , 0 } }, // #182 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 45, { 10, 3 , 0 , 0 , 0 , 0 } }, // #183 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 46, { 71, 43, 0 , 0 , 0 , 0 } }, // #184 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 2 , 3 , 3 , 0 , 0 , 0 } }, // #185 [ref=60x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 4 , 57, 7 , 0 , 0 , 0 } }, // #186 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 4 , 74, 9 , 0 , 0 , 0 } }, // #187 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 6 , 7 , 7 , 0 , 0 , 0 } }, // #188 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 8 , 9 , 9 , 0 , 0 , 0 } }, // #189 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 47, { 11, 3 , 3 , 3 , 0 , 0 } }, // #190 [ref=15x]
- { InstDB::RWInfo::kCategoryGeneric , 48, { 34, 7 , 7 , 7 , 0 , 0 } }, // #191 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 49, { 42, 9 , 9 , 9 , 0 , 0 } }, // #192 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 25, 7 , 7 , 0 , 0 , 0 } }, // #193 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 75, 9 , 9 , 0 , 0 , 0 } }, // #194 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 14, { 34, 3 , 0 , 0 , 0 , 0 } }, // #195 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 59, 41, 3 , 0 , 0 , 0 } }, // #121 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 11, 3 , 60, 0 , 0 } }, // #122 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 28, 0 , 0 , 0 , 0 } }, // #123 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 28, 29, 0 , 0 , 0 } }, // #124 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #125 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 50, 21, 0 , 0 , 0 , 0 } }, // #126 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 50, 61, 0 , 0 , 0 , 0 } }, // #127 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 25, 7 , 0 , 0 , 0 , 0 } }, // #128 [ref=18x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 62, 16, 56 } }, // #129 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 63, 16, 56 } }, // #130 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 62, 0 , 0 } }, // #131 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 63, 0 , 0 } }, // #132 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 31, { 53, 5 , 0 , 0 , 0 , 0 } }, // #133 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 32, { 34, 5 , 0 , 0 , 0 , 0 } }, // #134 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 33, { 47, 3 , 0 , 0 , 0 , 0 } }, // #135 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 64, 5 , 0 , 0 , 0 , 0 } }, // #136 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 4 , 39, 0 , 0 , 0 , 0 } }, // #137 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 4 , 7 , 0 , 0 , 0 , 0 } }, // #138 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 2 , 13, 0 , 0 , 0 , 0 } }, // #139 [ref=1x]
+ { InstDB::RWInfo::kCategoryVmov1_8 , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #140 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 10, 9 , 0 , 0 , 0 , 0 } }, // #141 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 10, 13, 0 , 0 , 0 , 0 } }, // #142 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 65, 0 , 0 , 0 , 0 , 0 } }, // #143 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 0 , 0 , 0 } }, // #144 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 60, 0 , 0 , 0 , 0 , 0 } }, // #145 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 66, 0 , 0 , 0 , 0 } }, // #146 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 36, 9 , 0 , 0 , 0 , 0 } }, // #147 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 0 , 0 , 0 , 0 , 0 } }, // #148 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 15, 67, 28, 0 , 0 , 0 } }, // #149 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 15, 67, 0 , 0 , 0 , 0 } }, // #150 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 15, 67, 62, 0 , 0 , 0 } }, // #151 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 68, 0 , 0 , 0 , 0 , 0 } }, // #152 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 21, 20, 0 , 0 , 0 , 0 } }, // #153 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 31, { 69, 0 , 0 , 0 , 0 , 0 } }, // #154 [ref=30x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 3 , 66, 0 , 0 , 0 } }, // #155 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 34, { 11, 0 , 0 , 0 , 0 , 0 } }, // #156 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 28, { 42, 0 , 0 , 0 , 0 , 0 } }, // #157 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 20, 21, 0 , 0 , 0 , 0 } }, // #158 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 70, 43, 43, 43, 43, 5 } }, // #159 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 4 , 5 , 5 , 5 , 5 , 5 } }, // #160 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 10, 5 , 7 , 0 , 0 , 0 } }, // #161 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 5 , 9 , 0 , 0 , 0 } }, // #162 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 3 , 0 , 0 } }, // #163 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 71, 5 , 0 , 0 , 0 , 0 } }, // #164 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 11, 5 , 0 , 0 , 0 , 0 } }, // #165 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 72, 73, 0 , 0 , 0 , 0 } }, // #166 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 11, 7 , 0 , 0 , 0 , 0 } }, // #167 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 39, { 11, 9 , 0 , 0 , 0 , 0 } }, // #168 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 11, 5 , 7 , 0 , 0 , 0 } }, // #169 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 11, 5 , 9 , 0 , 0 , 0 } }, // #170 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 11, 3 , 0 , 0 , 0 , 0 } }, // #171 [ref=7x]
+ { InstDB::RWInfo::kCategoryVmov2_1 , 40, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #172 [ref=14x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 14, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #173 [ref=7x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 41, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #174 [ref=10x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 10, 74, 7 , 0 , 0 , 0 } }, // #175 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 57, 3 , 0 , 0 , 0 } }, // #176 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 74, 3 , 0 , 0 , 0 } }, // #177 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 57, 9 , 0 , 0 , 0 } }, // #178 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 43, { 10, 5 , 5 , 0 , 0 , 0 } }, // #179 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 44, { 72, 43, 0 , 0 , 0 , 0 } }, // #180 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 45, { 10, 73, 0 , 0 , 0 , 0 } }, // #181 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 45, { 10, 3 , 0 , 0 , 0 , 0 } }, // #182 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 46, { 71, 43, 0 , 0 , 0 , 0 } }, // #183 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 2 , 3 , 3 , 0 , 0 , 0 } }, // #184 [ref=60x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 4 , 57, 7 , 0 , 0 , 0 } }, // #185 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 4 , 74, 9 , 0 , 0 , 0 } }, // #186 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 6 , 7 , 7 , 0 , 0 , 0 } }, // #187 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 8 , 9 , 9 , 0 , 0 , 0 } }, // #188 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 47, { 11, 3 , 3 , 3 , 0 , 0 } }, // #189 [ref=15x]
+ { InstDB::RWInfo::kCategoryGeneric , 48, { 34, 7 , 7 , 7 , 0 , 0 } }, // #190 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 49, { 42, 9 , 9 , 9 , 0 , 0 } }, // #191 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 25, 7 , 7 , 0 , 0 , 0 } }, // #192 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 75, 9 , 9 , 0 , 0 , 0 } }, // #193 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 34, 3 , 0 , 0 , 0 , 0 } }, // #194 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 34, 9 , 0 , 0 , 0 , 0 } }, // #195 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 5 , { 42, 9 , 0 , 0 , 0 , 0 } }, // #196 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 8 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #197 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #198 [ref=4x]
@@ -3807,15 +3808,15 @@ const InstDB::RWInfoOp InstDB::rwInfoOp[] = {
{ 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, 0 }, // #0 [ref=14957x]
{ 0x0000000000000003u, 0x0000000000000003u, 0x00, { 0 }, OpRWInfo::kRW | OpRWInfo::kRegPhysId }, // #1 [ref=10x]
{ 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #2 [ref=217x]
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #3 [ref=978x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #3 [ref=979x]
{ 0x000000000000FFFFu, 0x000000000000FFFFu, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #4 [ref=92x]
{ 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #5 [ref=305x]
{ 0x00000000000000FFu, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kRW }, // #6 [ref=18x]
{ 0x00000000000000FFu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #7 [ref=181x]
{ 0x000000000000000Fu, 0x000000000000000Fu, 0xFF, { 0 }, OpRWInfo::kRW }, // #8 [ref=18x]
- { 0x000000000000000Fu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #9 [ref=130x]
+ { 0x000000000000000Fu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #9 [ref=129x]
{ 0x0000000000000000u, 0x000000000000FFFFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #10 [ref=160x]
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #11 [ref=415x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #11 [ref=416x]
{ 0x0000000000000003u, 0x0000000000000003u, 0xFF, { 0 }, OpRWInfo::kRW }, // #12 [ref=1x]
{ 0x0000000000000003u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #13 [ref=34x]
{ 0x000000000000FFFFu, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #14 [ref=4x]
@@ -3838,7 +3839,7 @@ const InstDB::RWInfoOp InstDB::rwInfoOp[] = {
{ 0x000000000000000Fu, 0x000000000000000Fu, 0x01, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #31 [ref=1x]
{ 0x0000000000000000u, 0x00000000000000FFu, 0x02, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #32 [ref=1x]
{ 0x00000000000000FFu, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #33 [ref=1x]
- { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #34 [ref=76x]
+ { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #34 [ref=75x]
{ 0x0000000000000000u, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kWrite }, // #35 [ref=6x]
{ 0x0000000000000000u, 0x000000000000000Fu, 0xFF, { 0 }, OpRWInfo::kWrite }, // #36 [ref=6x]
{ 0x0000000000000000u, 0x0000000000000003u, 0x02, { 0 }, OpRWInfo::kWrite | OpRWInfo::kRegPhysId }, // #37 [ref=1x]
@@ -3886,10 +3887,10 @@ const InstDB::RWInfoOp InstDB::rwInfoOp[] = {
const InstDB::RWInfoRm InstDB::rwInfoRm[] = {
{ InstDB::RWInfoRm::kCategoryNone , 0x00, 0 , 0, 0 }, // #0 [ref=1809x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x03, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #1 [ref=8x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , 0, 0 }, // #2 [ref=193x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , 0, 0 }, // #2 [ref=194x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x02, 16, 0, 0 }, // #3 [ref=122x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x02, 8 , 0, 0 }, // #4 [ref=66x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x02, 4 , 0, 0 }, // #5 [ref=34x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x02, 4 , 0, 0 }, // #5 [ref=33x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , 0, 0 }, // #6 [ref=270x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 2 , 0, 0 }, // #7 [ref=9x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x00, 0 , 0, 0 }, // #8 [ref=60x]
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instdb.h b/3rdparty/asmjit/src/asmjit/x86/x86instdb.h
index d03b87035c3..6bc2af5000a 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instdb.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instdb.h
@@ -46,9 +46,9 @@ enum Mode : uint32_t {
kModeAny = 0x03u //!< Both X86 and X64 modes supported.
};
-static constexpr uint32_t modeFromArchId(uint32_t archId) noexcept {
- return archId == ArchInfo::kIdX86 ? kModeX86 :
- archId == ArchInfo::kIdX64 ? kModeX64 : kModeNone;
+static constexpr uint32_t modeFromArch(uint32_t arch) noexcept {
+ return arch == Environment::kArchX86 ? kModeX86 :
+ arch == Environment::kArchX64 ? kModeX64 : kModeNone;
}
// ============================================================================
@@ -142,12 +142,6 @@ enum MemFlags : uint32_t {
enum Flags : uint32_t {
kFlagNone = 0x00000000u, //!< No flags.
- // TODO: Deprecated
- // ----------------
-
- kFlagVolatile = 0x00000040u,
- kFlagPrivileged = 0x00000080u, //!< This is a privileged operation that cannot run in user mode.
-
// Instruction Family
// ------------------
//
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86internal.cpp b/3rdparty/asmjit/src/asmjit/x86/x86internal.cpp
index a35b0d34e33..062525f5982 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86internal.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86internal.cpp
@@ -24,7 +24,7 @@
#include "../core/api-build_p.h"
#ifdef ASMJIT_BUILD_X86
-#include "../core/logging.h"
+#include "../core/formatter.h"
#include "../core/string.h"
#include "../core/support.h"
#include "../core/type.h"
@@ -67,11 +67,9 @@ static inline uint32_t x86KmovFromSize(uint32_t size) noexcept {
// [asmjit::X86Internal - FuncDetail]
// ============================================================================
-ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const FuncSignature& sign, uint32_t gpSize) noexcept {
- DebugUtils::unused(sign);
-
+ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept {
const CallConv& cc = func.callConv();
- uint32_t archId = cc.archId();
+ uint32_t arch = cc.arch();
uint32_t stackOffset = cc._spillZoneSize;
uint32_t i;
@@ -82,7 +80,7 @@ ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const Func
switch (typeId) {
case Type::kIdI64:
case Type::kIdU64: {
- if (archId == ArchInfo::kIdX86) {
+ if (Environment::is32Bit(arch)) {
// Convert a 64-bit return value to two 32-bit return values.
func._retCount = 2;
typeId -= 2;
@@ -114,7 +112,7 @@ ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const Func
case Type::kIdF32:
case Type::kIdF64: {
- uint32_t regType = (archId == ArchInfo::kIdX86) ? Reg::kTypeSt : Reg::kTypeXmm;
+ uint32_t regType = Environment::is32Bit(arch) ? Reg::kTypeSt : Reg::kTypeXmm;
func._rets[0].initReg(regType, 0, typeId);
break;
}
@@ -127,9 +125,9 @@ ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const Func
case Type::kIdMmx32:
case Type::kIdMmx64: {
- // MM registers are returned through XMM or GPQ (Win64).
+ // MM registers are returned through XMM (SystemV) or GPQ (Win64).
uint32_t regType = Reg::kTypeMm;
- if (archId != ArchInfo::kIdX86)
+ if (Environment::is64Bit(arch))
regType = cc.strategy() == CallConv::kStrategyDefault ? Reg::kTypeXmm : Reg::kTypeGpq;
func._rets[0].initReg(regType, 0, typeId);
@@ -143,90 +141,156 @@ ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const Func
}
}
- if (cc.strategy() == CallConv::kStrategyDefault) {
- uint32_t gpzPos = 0;
- uint32_t vecPos = 0;
-
- for (i = 0; i < argCount; i++) {
- FuncValue& arg = func._args[i];
- uint32_t typeId = arg.typeId();
-
- if (Type::isInt(typeId)) {
- uint32_t regId = gpzPos < CallConv::kMaxRegArgsPerGroup ? cc._passedOrder[Reg::kGroupGp].id[gpzPos] : uint8_t(BaseReg::kIdBad);
- if (regId != BaseReg::kIdBad) {
- uint32_t regType = (typeId <= Type::kIdU32) ? Reg::kTypeGpd : Reg::kTypeGpq;
- arg.assignRegData(regType, regId);
- func.addUsedRegs(Reg::kGroupGp, Support::bitMask(regId));
- gpzPos++;
- }
- else {
- uint32_t size = Support::max<uint32_t>(Type::sizeOf(typeId), gpSize);
- arg.assignStackOffset(int32_t(stackOffset));
- stackOffset += size;
- }
- continue;
- }
+ switch (cc.strategy()) {
+ case CallConv::kStrategyDefault: {
+ uint32_t gpzPos = 0;
+ uint32_t vecPos = 0;
+
+ for (i = 0; i < argCount; i++) {
+ FuncValue& arg = func._args[i];
+ uint32_t typeId = arg.typeId();
- if (Type::isFloat(typeId) || Type::isVec(typeId)) {
- uint32_t regId = vecPos < CallConv::kMaxRegArgsPerGroup ? cc._passedOrder[Reg::kGroupVec].id[vecPos] : uint8_t(BaseReg::kIdBad);
+ if (Type::isInt(typeId)) {
+ uint32_t regId = BaseReg::kIdBad;
- // If this is a float, but `floatByVec` is false, we have to pass by stack.
- if (Type::isFloat(typeId) && !cc.hasFlag(CallConv::kFlagPassFloatsByVec))
- regId = BaseReg::kIdBad;
+ if (gpzPos < CallConv::kMaxRegArgsPerGroup)
+ regId = cc._passedOrder[Reg::kGroupGp].id[gpzPos];
- if (regId != BaseReg::kIdBad) {
- arg.initTypeId(typeId);
- arg.assignRegData(x86VecTypeIdToRegType(typeId), regId);
- func.addUsedRegs(Reg::kGroupVec, Support::bitMask(regId));
- vecPos++;
+ if (regId != BaseReg::kIdBad) {
+ uint32_t regType = (typeId <= Type::kIdU32) ? Reg::kTypeGpd : Reg::kTypeGpq;
+ arg.assignRegData(regType, regId);
+ func.addUsedRegs(Reg::kGroupGp, Support::bitMask(regId));
+ gpzPos++;
+ }
+ else {
+ uint32_t size = Support::max<uint32_t>(Type::sizeOf(typeId), registerSize);
+ arg.assignStackOffset(int32_t(stackOffset));
+ stackOffset += size;
+ }
+ continue;
}
- else {
- uint32_t size = Type::sizeOf(typeId);
- arg.assignStackOffset(int32_t(stackOffset));
- stackOffset += size;
+
+ if (Type::isFloat(typeId) || Type::isVec(typeId)) {
+ uint32_t regId = BaseReg::kIdBad;
+
+ if (vecPos < CallConv::kMaxRegArgsPerGroup)
+ regId = cc._passedOrder[Reg::kGroupVec].id[vecPos];
+
+ if (Type::isFloat(typeId)) {
+ // If this is a float, but `kFlagPassFloatsByVec` is false, we have
+ // to use stack instead. This should be only used by 32-bit calling
+ // conventions.
+ if (!cc.hasFlag(CallConv::kFlagPassFloatsByVec))
+ regId = BaseReg::kIdBad;
+ }
+ else {
+ // Pass vector registers via stack if this is a variable arguments
+ // function. This should be only used by 32-bit calling conventions.
+ if (signature.hasVarArgs() && cc.hasFlag(CallConv::kFlagPassVecByStackIfVA))
+ regId = BaseReg::kIdBad;
+ }
+
+ if (regId != BaseReg::kIdBad) {
+ arg.initTypeId(typeId);
+ arg.assignRegData(x86VecTypeIdToRegType(typeId), regId);
+ func.addUsedRegs(Reg::kGroupVec, Support::bitMask(regId));
+ vecPos++;
+ }
+ else {
+ uint32_t size = Type::sizeOf(typeId);
+ arg.assignStackOffset(int32_t(stackOffset));
+ stackOffset += size;
+ }
+ continue;
}
- continue;
}
+ break;
}
- }
- if (cc.strategy() == CallConv::kStrategyWin64) {
- for (i = 0; i < argCount; i++) {
- FuncValue& arg = func._args[i];
+ case CallConv::kStrategyX64Windows:
+ case CallConv::kStrategyX64VectorCall: {
+ // Both X64 and VectorCall behave similarly - arguments are indexed
+ // from left to right. The position of the argument determines in
+ // which register the argument is allocated, so it's either GP or
+ // one of XMM/YMM/ZMM registers.
+ //
+ // [ X64 ] [VecCall]
+ // Index: #0 #1 #2 #3 #4 #5
+ //
+ // GP : RCX RDX R8 R9
+ // VEC : XMM0 XMM1 XMM2 XMM3 XMM4 XMM5
+ //
+ // For example function `f(int a, double b, int c, double d)` will be:
+ //
+ // (a) (b) (c) (d)
+ // RCX XMM1 R8 XMM3
+ //
+ // Unused vector registers are used by HVA.
+
+ bool isVectorCall = (cc.strategy() == CallConv::kStrategyX64VectorCall);
+
+ for (i = 0; i < argCount; i++) {
+ FuncValue& arg = func._args[i];
+
+ uint32_t typeId = arg.typeId();
+ uint32_t size = Type::sizeOf(typeId);
+
+ if (Type::isInt(typeId) || Type::isMmx(typeId)) {
+ uint32_t regId = BaseReg::kIdBad;
+
+ if (i < CallConv::kMaxRegArgsPerGroup)
+ regId = cc._passedOrder[Reg::kGroupGp].id[i];
+
+ if (regId != BaseReg::kIdBad) {
+ uint32_t regType = (size <= 4 && !Type::isMmx(typeId)) ? Reg::kTypeGpd : Reg::kTypeGpq;
+ arg.assignRegData(regType, regId);
+ func.addUsedRegs(Reg::kGroupGp, Support::bitMask(regId));
+ }
+ else {
+ arg.assignStackOffset(int32_t(stackOffset));
+ stackOffset += 8;
+ }
+ continue;
+ }
- uint32_t typeId = arg.typeId();
- uint32_t size = Type::sizeOf(typeId);
+ if (Type::isFloat(typeId) || Type::isVec(typeId)) {
+ uint32_t regId = BaseReg::kIdBad;
- if (Type::isInt(typeId) || Type::isMmx(typeId)) {
- uint32_t regId = i < CallConv::kMaxRegArgsPerGroup ? cc._passedOrder[Reg::kGroupGp].id[i] : uint8_t(BaseReg::kIdBad);
- if (regId != BaseReg::kIdBad) {
- uint32_t regType = (size <= 4 && !Type::isMmx(typeId)) ? Reg::kTypeGpd : Reg::kTypeGpq;
- arg.assignRegData(regType, regId);
- func.addUsedRegs(Reg::kGroupGp, Support::bitMask(regId));
- }
- else {
- arg.assignStackOffset(int32_t(stackOffset));
- stackOffset += gpSize;
- }
- continue;
- }
+ if (i < CallConv::kMaxRegArgsPerGroup)
+ regId = cc._passedOrder[Reg::kGroupVec].id[i];
- if (Type::isFloat(typeId) || Type::isVec(typeId)) {
- uint32_t regId = BaseReg::kIdBad;
- if (i < CallConv::kMaxRegArgsPerGroup)
- regId = cc._passedOrder[Reg::kGroupVec].id[i];
+ if (regId != BaseReg::kIdBad) {
+ // X64-ABI doesn't allow vector types (XMM|YMM|ZMM) to be passed
+ // via registers, however, VectorCall was designed for that purpose.
+ if (Type::isFloat(typeId) || isVectorCall) {
+ uint32_t regType = x86VecTypeIdToRegType(typeId);
+ arg.assignRegData(regType, regId);
+ func.addUsedRegs(Reg::kGroupVec, Support::bitMask(regId));
+ continue;
+ }
+ }
- if (regId != BaseReg::kIdBad && (Type::isFloat(typeId) || cc.hasFlag(CallConv::kFlagVectorCall))) {
- uint32_t regType = x86VecTypeIdToRegType(typeId);
- arg.assignRegData(regType, regId);
- func.addUsedRegs(Reg::kGroupVec, Support::bitMask(regId));
- }
- else {
- arg.assignStackOffset(int32_t(stackOffset));
- stackOffset += 8; // Always 8 bytes (float/double).
+ // Passed via stack if the argument is float/double or indirectly.
+ // The trap is - if the argument is passed indirectly, the address
+ // can be passed via register, if the argument's index has GP one.
+ if (Type::isFloat(typeId)) {
+ arg.assignStackOffset(int32_t(stackOffset));
+ }
+ else {
+ uint32_t gpRegId = cc._passedOrder[Reg::kGroupGp].id[i];
+ if (gpRegId != BaseReg::kIdBad)
+ arg.assignRegData(Reg::kTypeGpq, gpRegId);
+ else
+ arg.assignStackOffset(int32_t(stackOffset));
+ arg.addFlags(FuncValue::kFlagIsIndirect);
+ }
+
+ // Always 8 bytes (float/double/pointer).
+ stackOffset += 8;
+ continue;
}
- continue;
}
+ break;
}
}
@@ -238,14 +302,14 @@ ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const Func
// [asmjit::X86FuncArgsContext]
// ============================================================================
-static RegInfo x86GetRegForMemToMemMove(uint32_t archId, uint32_t dstTypeId, uint32_t srcTypeId) noexcept {
+static RegInfo x86GetRegForMemToMemMove(uint32_t arch, uint32_t dstTypeId, uint32_t srcTypeId) noexcept {
uint32_t dstSize = Type::sizeOf(dstTypeId);
uint32_t srcSize = Type::sizeOf(srcTypeId);
uint32_t maxSize = Support::max<uint32_t>(dstSize, srcSize);
- uint32_t gpSize = archId == ArchInfo::kIdX86 ? 4 : 8;
+ uint32_t regSize = Environment::registerSizeFromArch(arch);
uint32_t signature = 0;
- if (maxSize <= gpSize || (Type::isInt(dstTypeId) && Type::isInt(srcTypeId)))
+ if (maxSize <= regSize || (Type::isInt(dstTypeId) && Type::isInt(srcTypeId)))
signature = maxSize <= 4 ? Gpd::kSignature : Gpq::kSignature;
else if (maxSize <= 16)
signature = Xmm::kSignature;
@@ -360,7 +424,7 @@ public:
uint8_t _physToVarId[32]; //!< Physical ID to variable ID mapping.
};
- uint8_t _archId;
+ uint8_t _arch;
bool _hasStackSrc; //!< Has arguments passed via stack (SRC).
bool _hasPreservedFP; //!< Has preserved frame-pointer (FP).
uint8_t _stackDstMask; //!< Has arguments assigned to stack (DST).
@@ -372,12 +436,12 @@ public:
X86FuncArgsContext() noexcept;
- inline uint32_t archId() const noexcept { return _archId; }
+ inline uint32_t arch() const noexcept { return _arch; }
inline uint32_t varCount() const noexcept { return _varCount; }
- inline Var& var(uint32_t varId) noexcept { return _vars[varId]; }
- inline const Var& var(uint32_t varId) const noexcept { return _vars[varId]; }
- inline uint32_t indexOf(const Var* var) const noexcept { return uint32_t((size_t)(var - _vars)); }
+ inline Var& var(size_t varId) noexcept { return _vars[varId]; }
+ inline const Var& var(size_t varId) const noexcept { return _vars[varId]; }
+ inline size_t indexOf(const Var* var) const noexcept { return (size_t)(var - _vars); }
Error initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args) noexcept;
Error markScratchRegs(FuncFrame& frame) noexcept;
@@ -386,7 +450,7 @@ public:
};
X86FuncArgsContext::X86FuncArgsContext() noexcept {
- _archId = ArchInfo::kIdNone;
+ _arch = Environment::kArchUnknown;
_varCount = 0;
_hasStackSrc = false;
_hasPreservedFP = false;
@@ -405,11 +469,11 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::initWorkData(const FuncFrame& frame,
uint32_t i;
const FuncDetail& func = *args.funcDetail();
- // Initialize ArchType.
- uint32_t archId = func.callConv().archId();
- uint32_t archRegCount = (archId == ArchInfo::kIdX86) ? 8 : 16;
+ // Initialize Architecture.
+ uint32_t arch = func.callConv().arch();
+ uint32_t archRegCount = Environment::is32Bit(arch) ? 8 : 16;
- _archId = uint8_t(archId);
+ _arch = uint8_t(arch);
// Initialize `_archRegs`.
_workData[Reg::kGroupGp ]._archRegs = Support::lsbMask<uint32_t>(archRegCount) & ~Support::bitMask(Gp::kIdSp);
@@ -424,7 +488,8 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::initWorkData(const FuncFrame& frame,
uint32_t varId = 0;
for (i = 0; i < kFuncArgCountLoHi; i++) {
const FuncValue& dst_ = args.arg(i);
- if (!dst_.isAssigned()) continue;
+ if (!dst_.isAssigned())
+ continue;
const FuncValue& src_ = func.arg(i);
if (ASMJIT_UNLIKELY(!src_.isAssigned()))
@@ -440,6 +505,10 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::initWorkData(const FuncFrame& frame,
uint32_t dstId = BaseReg::kIdBad;
WorkData* dstWd = nullptr;
+ // Not supported.
+ if (src.isIndirect())
+ return DebugUtils::errored(kErrorInvalidAssignment);
+
if (dst.isReg()) {
uint32_t dstType = dst.regType();
if (ASMJIT_UNLIKELY(dstType >= Reg::kTypeCount))
@@ -471,7 +540,7 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::initWorkData(const FuncFrame& frame,
if (!dst.hasTypeId())
dst.setTypeId(src.typeId());
- RegInfo regInfo = x86GetRegForMemToMemMove(archId, dst.typeId(), src.typeId());
+ RegInfo regInfo = x86GetRegForMemToMemMove(arch, dst.typeId(), src.typeId());
if (ASMJIT_UNLIKELY(!regInfo.isValid()))
return DebugUtils::errored(kErrorInvalidState);
_stackDstMask = uint8_t(_stackDstMask | Support::bitMask(regInfo.group()));
@@ -530,8 +599,8 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::initWorkData(const FuncFrame& frame,
}
if (saRegRequired) {
- uint32_t ptrTypeId = (archId == ArchInfo::kIdX86) ? Type::kIdU32 : Type::kIdU64;
- uint32_t ptrRegType = (archId == ArchInfo::kIdX86) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64;
+ uint32_t ptrTypeId = Environment::is32Bit(arch) ? Type::kIdU32 : Type::kIdU64;
+ uint32_t ptrRegType = Environment::is32Bit(arch) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64;
_saVarId = uint8_t(varId);
_hasPreservedFP = frame.hasPreservedFP();
@@ -622,7 +691,7 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markScratchRegs(FuncFrame& frame) no
if (!groupMask)
return kErrorOk;
- // selects one dirty register per affected group that can be used as a scratch register.
+ // Selects one dirty register per affected group that can be used as a scratch register.
for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
if (Support::bitTest(groupMask, group)) {
WorkData& wd = _workData[group];
@@ -632,15 +701,18 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markScratchRegs(FuncFrame& frame) no
uint32_t regs = workRegs & ~(wd.usedRegs() | wd._dstShuf);
// If that didn't work out pick some register which is not in 'used'.
- if (!regs) regs = workRegs & ~wd.usedRegs();
+ if (!regs)
+ regs = workRegs & ~wd.usedRegs();
// If that didn't work out pick any other register that is allocable.
// This last resort case will, however, result in marking one more
// register dirty.
- if (!regs) regs = wd.archRegs() & ~workRegs;
+ if (!regs)
+ regs = wd.archRegs() & ~workRegs;
// If that didn't work out we will have to use XORs instead of MOVs.
- if (!regs) continue;
+ if (!regs)
+ continue;
uint32_t regMask = Support::blsi(regs);
wd._workRegs |= regMask;
@@ -652,7 +724,6 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markScratchRegs(FuncFrame& frame) no
}
ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markStackArgsReg(FuncFrame& frame) noexcept {
- // TODO: Validate, improve...
if (_saVarId != kVarIdNone) {
const Var& var = _vars[_saVarId];
frame.setSARegId(var.cur.regId());
@@ -670,14 +741,14 @@ ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markStackArgsReg(FuncFrame& frame) n
// ============================================================================
ASMJIT_FAVOR_SIZE Error X86Internal::initFuncFrame(FuncFrame& frame, const FuncDetail& func) noexcept {
- uint32_t archId = func.callConv().archId();
+ uint32_t arch = func.callConv().arch();
// Initializing FuncFrame means making a copy of some properties of `func`.
// Properties like `_localStackSize` will be set by the user before the frame
// is finalized.
frame.reset();
- frame._archId = uint8_t(archId);
+ frame._arch = uint8_t(arch);
frame._spRegId = Gp::kIdSp;
frame._saRegId = Gp::kIdBad;
@@ -710,7 +781,7 @@ ASMJIT_FAVOR_SIZE Error X86Internal::initFuncFrame(FuncFrame& frame, const FuncD
}
ASMJIT_FAVOR_SIZE Error X86Internal::finalizeFuncFrame(FuncFrame& frame) noexcept {
- uint32_t gpSize = frame.archId() == ArchInfo::kIdX86 ? 4 : 8;
+ uint32_t registerSize = Environment::registerSizeFromArch(frame.arch());
// The final stack alignment must be updated accordingly to call and local stack alignments.
uint32_t stackAlignment = frame._finalStackAlignment;
@@ -746,7 +817,7 @@ ASMJIT_FAVOR_SIZE Error X86Internal::finalizeFuncFrame(FuncFrame& frame) noexcep
frame._saRegId = uint8_t(saRegId);
// Setup stack size used to save preserved registers.
- frame._gpSaveSize = uint16_t(Support::popcnt(frame.savedRegs(Reg::kGroupGp )) * gpSize);
+ frame._gpSaveSize = uint16_t(Support::popcnt(frame.savedRegs(Reg::kGroupGp )) * registerSize);
frame._nonGpSaveSize = uint16_t(Support::popcnt(frame.savedRegs(Reg::kGroupVec )) * vecSize +
Support::popcnt(frame.savedRegs(Reg::kGroupMm )) * 8 +
Support::popcnt(frame.savedRegs(Reg::kGroupKReg)) * 8);
@@ -772,15 +843,15 @@ ASMJIT_FAVOR_SIZE Error X86Internal::finalizeFuncFrame(FuncFrame& frame) noexcep
// Calculate if dynamic alignment (DA) slot (stored as offset relative to SP) is required and its offset.
if (hasDA && !hasFP) {
frame._daOffset = v; // Store 'daOffset' <- DA pointer would be stored here.
- v += gpSize; // Count 'daOffset'.
+ v += registerSize; // Count 'daOffset'.
}
else {
frame._daOffset = FuncFrame::kTagInvalidOffset;
}
// The return address should be stored after GP save/restore regs. It has
- // the same size as `gpSize` (basically the native register/pointer size).
- // We don't adjust it now as `v` now contains the exact size that the
+ // the same size as `registerSize` (basically the native register/pointer
+ // size). We don't adjust it now as `v` now contains the exact size that the
// function requires to adjust (call frame + stack frame, vec stack size).
// The stack (if we consider this size) is misaligned now, as it's always
// aligned before the function call - when `call()` is executed it pushes
@@ -788,27 +859,27 @@ ASMJIT_FAVOR_SIZE Error X86Internal::finalizeFuncFrame(FuncFrame& frame) noexcep
// (depending on the architecture). So count number of bytes needed to align
// it up to the function's CallFrame (the beginning).
if (v || frame.hasFuncCalls())
- v += Support::alignUpDiff(v + frame.gpSaveSize() + gpSize, stackAlignment);
+ v += Support::alignUpDiff(v + frame.gpSaveSize() + registerSize, stackAlignment);
frame._gpSaveOffset = v; // Store 'gpSaveOffset' <- Function's GP Save/Restore starts here.
frame._stackAdjustment = v; // Store 'stackAdjustment' <- SA used by 'add zsp, SA' and 'sub zsp, SA'.
v += frame._gpSaveSize; // Count 'gpSaveSize' <- Function's GP Save/Restore ends here.
- v += gpSize; // Count 'ReturnAddress' <- As CALL pushes onto stack.
+ v += registerSize; // Count 'ReturnAddress' <- As CALL pushes onto stack.
// If the function performs dynamic stack alignment then the stack-adjustment must be aligned.
if (hasDA)
frame._stackAdjustment = Support::alignUp(frame._stackAdjustment, stackAlignment);
uint32_t saInvOff = FuncFrame::kTagInvalidOffset;
- uint32_t saTmpOff = gpSize + frame._gpSaveSize;
+ uint32_t saTmpOff = registerSize + frame._gpSaveSize;
// Calculate where the function arguments start relative to SP.
frame._saOffsetFromSP = hasDA ? saInvOff : v;
// Calculate where the function arguments start relative to FP or user-provided register.
- frame._saOffsetFromSA = hasFP ? gpSize * 2 // Return address + frame pointer.
- : saTmpOff; // Return address + all saved GP regs.
+ frame._saOffsetFromSA = hasFP ? registerSize * 2 // Return address + frame pointer.
+ : saTmpOff; // Return address + all saved GP regs.
return kErrorOk;
}
@@ -943,7 +1014,8 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
const Operand_& src_, uint32_t srcTypeId, bool avxEnabled, const char* comment) {
// Deduce optional `dstTypeId`, which may be `Type::kIdVoid` in some cases.
- if (!dstTypeId) dstTypeId = opData.archRegs.regTypeToTypeId[dst_.type()];
+ if (!dstTypeId)
+ dstTypeId = opData.archRegs.regTypeToTypeId[dst_.type()];
// Invalid or abstract TypeIds are not allowed.
ASMJIT_ASSERT(Type::isValid(dstTypeId) && !Type::isAbstract(dstTypeId));
@@ -969,11 +1041,13 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
typeOp == ((Type::kIdI32 << 8) | Type::kIdI8 ) ||
typeOp == ((Type::kIdI32 << 8) | Type::kIdI16) ||
typeOp == ((Type::kIdI64 << 8) | Type::kIdI8 ) ||
- typeOp == ((Type::kIdI64 << 8) | Type::kIdI16)) break;
+ typeOp == ((Type::kIdI64 << 8) | Type::kIdI16))
+ break;
// Sign extend by using 'movsxd'.
instId = Inst::kIdMovsxd;
- if (typeOp == ((Type::kIdI64 << 8) | Type::kIdI32)) break;
+ if (typeOp == ((Type::kIdI64 << 8) | Type::kIdI32))
+ break;
}
if (Type::isInt(srcTypeId) || src_.isMem()) {
@@ -991,7 +1065,8 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
dst.setSignature(srcSize == 4 ? Reg::signatureOfT<Reg::kTypeGpd>()
: Reg::signatureOfT<Reg::kTypeGpq>());
- if (src.isReg()) src.setSignature(dst.signature());
+ if (src.isReg())
+ src.setSignature(dst.signature());
}
break;
}
@@ -1003,7 +1078,8 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
if (Type::isMmx(srcTypeId)) {
// 64-bit move.
instId = Inst::kIdMovq;
- if (srcSize == 8) break;
+ if (srcSize == 8)
+ break;
// 32-bit move.
instId = Inst::kIdMovd;
@@ -1021,7 +1097,8 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
if (Type::isVec(srcTypeId)) {
// 64-bit move.
instId = avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
- if (srcSize == 8) break;
+ if (srcSize == 8)
+ break;
// 32-bit move.
instId = avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
@@ -1036,19 +1113,23 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
if (Type::isInt(srcTypeId) || src.isMem()) {
// 64-bit move.
- if (srcSize == 8) break;
+ if (srcSize == 8)
+ break;
// 32-bit move.
instId = Inst::kIdMovd;
- if (src.isReg()) src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ if (src.isReg())
+ src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
break;
}
- if (Type::isMmx(srcTypeId)) break;
+ if (Type::isMmx(srcTypeId))
+ break;
// This will hurt if `avxEnabled`.
instId = Inst::kIdMovdq2q;
- if (Type::isVec(srcTypeId)) break;
+ if (Type::isVec(srcTypeId))
+break;
}
if (Type::isMask(dstTypeId)) {
@@ -1056,7 +1137,8 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
if (Type::isInt(srcTypeId) || Type::isMask(srcTypeId) || src.isMem()) {
instId = x86KmovFromSize(srcSize);
- if (Reg::isGp(src) && srcSize <= 4) src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ if (Reg::isGp(src) && srcSize <= 4)
+ src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
break;
}
}
@@ -1112,7 +1194,8 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
// 32-bit move.
if (srcSize <= 4) {
instId = avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
- if (src.isReg()) src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ if (src.isReg())
+ src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
break;
}
@@ -1125,10 +1208,14 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(Emitter* emitter,
if (Reg::isVec(src) || src.isMem()) {
instId = avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps;
- uint32_t sign = Reg::signatureOfVecBySize(srcSize);
- dst.setSignature(sign);
- if (src.isReg()) src.setSignature(sign);
+ if (src.isMem() && srcSize < emitter->environment().stackAlignment())
+ instId = avxEnabled ? Inst::kIdVmovups : Inst::kIdMovups;
+
+ uint32_t signature = Reg::signatureOfVecBySize(srcSize);
+ dst.setSignature(signature);
+ if (src.isReg())
+ src.setSignature(signature);
break;
}
}
@@ -1249,7 +1336,7 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitEpilog(Emitter* emitter, const FuncFram
uint32_t i;
uint32_t regId;
- uint32_t gpSize = emitter->gpSize();
+ uint32_t registerSize = emitter->registerSize();
uint32_t gpSaved = frame.savedRegs(Reg::kGroupGp);
Gp zsp = emitter->zsp(); // ESP|RSP register.
@@ -1287,7 +1374,7 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitEpilog(Emitter* emitter, const FuncFram
if (frame.hasPreservedFP()) {
// Emit 'mov zsp, zbp' or 'lea zsp, [zbp - x]'
- int32_t count = int32_t(frame.gpSaveSize() - gpSize);
+ int32_t count = int32_t(frame.gpSaveSize() - registerSize);
if (!count)
ASMJIT_PROPAGATE(emitter->mov(zsp, zbp));
else
@@ -1338,24 +1425,28 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitEpilog(Emitter* emitter, const FuncFram
// ============================================================================
#ifdef ASMJIT_DUMP_ARGS_ASSIGNMENT
-static void dumpFuncValue(String& sb, uint32_t archId, const FuncValue& value) noexcept {
- Logging::formatTypeId(sb, value.typeId());
- sb.appendChar('@');
- if (value.isReg()) {
- Logging::formatRegister(sb, 0, nullptr, archId, value.regType(), value.regId());
- }
- else if (value.isStack()) {
+static void dumpFuncValue(String& sb, uint32_t arch, const FuncValue& value) noexcept {
+ Formatter::formatTypeId(sb, value.typeId());
+ sb.append('@');
+
+ if (value.isIndirect())
+ sb.append('[');
+
+ if (value.isReg())
+ Formatter::formatRegister(sb, 0, nullptr, arch, value.regType(), value.regId());
+ else if (value.isStack())
sb.appendFormat("[%d]", value.stackOffset());
- }
- else {
- sb.appendString("<none>");
- }
+ else
+ sb.append("<none>");
+
+ if (value.isIndirect())
+ sb.append(']');
}
static void dumpAssignment(String& sb, const X86FuncArgsContext& ctx) noexcept {
typedef X86FuncArgsContext::Var Var;
- uint32_t archId = ctx.archId();
+ uint32_t arch = ctx.arch();
uint32_t varCount = ctx.varCount();
for (uint32_t i = 0; i < varCount; i++) {
@@ -1364,14 +1455,14 @@ static void dumpAssignment(String& sb, const X86FuncArgsContext& ctx) noexcept {
const FuncValue& cur = var.cur;
sb.appendFormat("Var%u: ", i);
- dumpFuncValue(sb, archId, dst);
- sb.appendString(" <- ");
- dumpFuncValue(sb, archId, cur);
+ dumpFuncValue(sb, arch, dst);
+ sb.append(" <- ");
+ dumpFuncValue(sb, arch, cur);
if (var.isDone())
- sb.appendString(" {Done}");
+ sb.append(" {Done}");
- sb.appendChar('\n');
+ sb.append('\n');
}
}
#endif
@@ -1398,7 +1489,7 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgsAssignment(Emitter* emitter, const
}
#endif
- uint32_t archId = ctx.archId();
+ uint32_t arch = ctx.arch();
uint32_t varCount = ctx._varCount;
WorkData* workData = ctx._workData;
@@ -1415,6 +1506,8 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgsAssignment(Emitter* emitter, const
saRegId = saVarId < varCount ? ctx._vars[saVarId].cur.regId() : frame.saRegId();
}
+ RegInfo gpRegInfo = emitter->_gpRegInfo;
+
// --------------------------------------------------------------------------
// Register to stack and stack to stack moves must be first as now we have
// the biggest chance of having as many as possible unassigned registers.
@@ -1427,24 +1520,42 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgsAssignment(Emitter* emitter, const
for (uint32_t varId = 0; varId < varCount; varId++) {
Var& var = ctx._vars[varId];
- if (!var.out.isStack()) continue;
- ASMJIT_ASSERT(var.cur.isReg() || var.cur.isStack());
+ if (!var.out.isStack())
+ continue;
+
+ FuncValue& cur = var.cur;
+ FuncValue& out = var.out;
+
+ ASMJIT_ASSERT(cur.isReg() || cur.isStack());
Reg reg;
- if (var.cur.isReg()) {
- WorkData& wd = workData[Reg::groupOf(var.cur.regType())];
- uint32_t rId = var.cur.regId();
+ Mem dstStackPtr = baseStackPtr.cloneAdjusted(out.stackOffset());
+ Mem srcStackPtr = baseArgPtr.cloneAdjusted(cur.stackOffset());
+
+ if (cur.isIndirect()) {
+ if (cur.isStack()) {
+ // TODO: Indirect stack.
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ }
+ else {
+ srcStackPtr = ptr(Gp(gpRegInfo.signature(), cur.regId()));
+ }
+ }
+
+ if (cur.isReg() && !cur.isIndirect()) {
+ WorkData& wd = workData[Reg::groupOf(cur.regType())];
+ uint32_t rId = cur.regId();
- reg.setSignatureAndId(Reg::signatureOf(var.cur.regType()), rId);
+ reg.setSignatureAndId(Reg::signatureOf(cur.regType()), rId);
wd.unassign(varId, rId);
}
else {
// Stack to reg move - tricky since we move stack to stack we can decide which
// register to use. In general we follow the rule that IntToInt moves will use
- // GP regs with possibility to sign or zero extend, and all other moves will
+ // GP regs with possibility to signature or zero extend, and all other moves will
// either use GP or VEC regs depending on the size of the move.
- RegInfo rInfo = x86GetRegForMemToMemMove(archId, var.out.typeId(), var.cur.typeId());
+ RegInfo rInfo = x86GetRegForMemToMemMove(arch, out.typeId(), cur.typeId());
if (ASMJIT_UNLIKELY(!rInfo.isValid()))
return DebugUtils::errored(kErrorInvalidState);
@@ -1456,54 +1567,42 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgsAssignment(Emitter* emitter, const
uint32_t rId = Support::ctz(availableRegs);
reg.setSignatureAndId(rInfo.signature(), rId);
- ASMJIT_PROPAGATE(
- emitArgMove(emitter,
- reg,
- var.out.typeId(),
- baseArgPtr.cloneAdjusted(var.cur.stackOffset()),
- var.cur.typeId(),
- avxEnabled));
+ ASMJIT_PROPAGATE(emitArgMove(emitter, reg, out.typeId(), srcStackPtr, cur.typeId(), avxEnabled));
}
- // Register to stack move.
- ASMJIT_PROPAGATE(
- emitRegMove(emitter, baseStackPtr.cloneAdjusted(var.out.stackOffset()), reg, var.cur.typeId(), avxEnabled));
+ if (cur.isIndirect() && cur.isReg())
+ workData[BaseReg::kGroupGp].unassign(varId, cur.regId());
+ // Register to stack move.
+ ASMJIT_PROPAGATE(emitRegMove(emitter, dstStackPtr, reg, cur.typeId(), avxEnabled));
var.markDone();
}
}
// --------------------------------------------------------------------------
- // Shuffle all registers that are currently assigned accordingly to the assignment.
+ // Shuffle all registers that are currently assigned accordingly to target
+ // assignment.
// --------------------------------------------------------------------------
uint32_t workFlags = kWorkNone;
for (;;) {
for (uint32_t varId = 0; varId < varCount; varId++) {
Var& var = ctx._vars[varId];
- if (var.isDone() || !var.cur.isReg()) continue;
+ if (var.isDone() || !var.cur.isReg())
+ continue;
- uint32_t curType = var.cur.regType();
- uint32_t outType = var.out.regType();
+ FuncValue& cur = var.cur;
+ FuncValue& out = var.out;
- uint32_t curGroup = Reg::groupOf(curType);
- uint32_t outGroup = Reg::groupOf(outType);
+ uint32_t curGroup = Reg::groupOf(cur.regType());
+ uint32_t outGroup = Reg::groupOf(out.regType());
- uint32_t curId = var.cur.regId();
- uint32_t outId = var.out.regId();
+ uint32_t curId = cur.regId();
+ uint32_t outId = out.regId();
if (curGroup != outGroup) {
- ASMJIT_ASSERT(false);
-
- // Requires a conversion between two register groups.
- if (workData[outGroup]._numSwaps) {
- // TODO: Postponed
- workFlags |= kWorkPending;
- }
- else {
- // TODO:
- workFlags |= kWorkPending;
- }
+ // TODO: Conversion is not supported.
+ return DebugUtils::errored(kErrorInvalidAssignment);
}
else {
WorkData& wd = workData[outGroup];
@@ -1511,13 +1610,13 @@ ASMJIT_FAVOR_SIZE Error X86Internal::emitArgsAssignment(Emitter* emitter, const
EmitMove:
ASMJIT_PROPAGATE(
emitArgMove(emitter,
- Reg::fromTypeAndId(outType, outId), var.out.typeId(),
- Reg::fromTypeAndId(curType, curId), var.cur.typeId(), avxEnabled));
+ Reg::fromTypeAndId(out.regType(), outId), out.typeId(),
+ Reg::fromTypeAndId(cur.regType(), curId), cur.typeId(), avxEnabled));
wd.reassign(varId, outId, curId);
- var.cur.initReg(outType, outId, var.out.typeId());
+ cur.initReg(out.regType(), outId, out.typeId());
- if (outId == var.out.regId())
+ if (outId == out.regId())
var.markDone();
workFlags |= kWorkDidSome | kWorkPending;
}
@@ -1528,13 +1627,13 @@ EmitMove:
if (!altVar.out.isInitialized() || (altVar.out.isReg() && altVar.out.regId() == curId)) {
// Swap operation is possible only between two GP registers.
if (curGroup == Reg::kGroupGp) {
- uint32_t highestType = Support::max(var.cur.regType(), altVar.cur.regType());
+ uint32_t highestType = Support::max(cur.regType(), altVar.cur.regType());
uint32_t signature = highestType == Reg::kTypeGpq ? Reg::signatureOfT<Reg::kTypeGpq>()
: Reg::signatureOfT<Reg::kTypeGpd>();
ASMJIT_PROPAGATE(emitter->emit(Inst::kIdXchg, Reg(signature, outId), Reg(signature, curId)));
wd.swap(varId, curId, altId, outId);
- var.cur.setRegId(outId);
+ cur.setRegId(outId);
var.markDone();
altVar.cur.setRegId(curId);
@@ -1590,7 +1689,8 @@ EmitMove:
for (uint32_t iter = 0; iter < iterCount; iter++) {
for (uint32_t varId = 0; varId < varCount; varId++) {
Var& var = ctx._vars[varId];
- if (var.isDone()) continue;
+ if (var.isDone())
+ continue;
if (var.cur.isStack()) {
ASMJIT_ASSERT(var.out.isReg());
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86internal_p.h b/3rdparty/asmjit/src/asmjit/x86/x86internal_p.h
index a1b76963f2a..d4ea8e1f9bf 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86internal_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86internal_p.h
@@ -43,10 +43,10 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! X86 utilities used at multiple places, not part of public API, not exported.
struct X86Internal {
//! Initialize `FuncDetail` (X86 specific).
- static Error initFuncDetail(FuncDetail& func, const FuncSignature& sign, uint32_t gpSize) noexcept;
+ static Error initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept;
//! Initialize `FuncFrame` (X86 specific).
- static Error initFuncFrame(FuncFrame& frame, const FuncDetail& func) noexcept;
+ static Error initFuncFrame(FuncFrame& frame, const FuncDetail& signature) noexcept;
//! Finalize `FuncFrame` (X86 specific).
static Error finalizeFuncFrame(FuncFrame& frame) noexcept;
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h b/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h
index 69cafe5be7c..164b26c1dea 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h
@@ -24,8 +24,6 @@
#ifndef ASMJIT_X86_X86OPCODE_P_H_INCLUDED
#define ASMJIT_X86_X86OPCODE_P_H_INCLUDED
-#include "../core/logging.h"
-#include "../core/string.h"
#include "../x86/x86globals.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86operand.h b/3rdparty/asmjit/src/asmjit/x86/x86operand.h
index 7e220214271..ccbe87e9ea3 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86operand.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86operand.h
@@ -31,6 +31,58 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
+#define ASMJIT_MEM_PTR(FUNC, SIZE) \
+ static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept { \
+ return Mem(base, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+ return Mem(base, index, shift, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+ return Mem(base, index, shift, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept { \
+ return Mem(base, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+ return Mem(base, index, shift, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept { \
+ return Mem(rip_, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(uint64_t base) noexcept { \
+ return Mem(base, SIZE); \
+ } \
+ static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE); \
+ } \
+ static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE); \
+ } \
+ \
+ static constexpr Mem FUNC##_abs(uint64_t base) noexcept { \
+ return Mem(base, SIZE, BaseMem::kSignatureMemAbs); \
+ } \
+ static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
+ } \
+ static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
+ } \
+ \
+ static constexpr Mem FUNC##_rel(uint64_t base) noexcept { \
+ return Mem(base, SIZE, BaseMem::kSignatureMemRel); \
+ } \
+ static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
+ } \
+ static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
+ }
+
+//! \addtogroup asmjit_x86
+//! \{
+
// ============================================================================
// [Forward Declarations]
// ============================================================================
@@ -58,11 +110,8 @@ class St;
class Bnd;
class Rip;
-//! \addtogroup asmjit_x86
-//! \{
-
// ============================================================================
-// [asmjit::x86::RegTraits]
+// [asmjit::x86::Reg]
// ============================================================================
//! Register traits (X86).
@@ -96,10 +145,6 @@ ASMJIT_DEFINE_REG_TRAITS(Bnd , BaseReg::kTypeCustom + 4, BaseReg::kGroupVirt +
ASMJIT_DEFINE_REG_TRAITS(Rip , BaseReg::kTypeIP , BaseReg::kGroupVirt + 5, 0 , 1 , Type::kIdVoid );
//! \endcond
-// ============================================================================
-// [asmjit::x86::Reg]
-// ============================================================================
-
//! Register (X86).
class Reg : public BaseReg {
public:
@@ -403,6 +448,303 @@ inline Ymm Vec::ymm() const noexcept { return Ymm(id()); }
inline Zmm Vec::zmm() const noexcept { return Zmm(id()); }
//! \endcond
+//! \namespace asmjit::x86::regs
+//!
+//! Registers provided by X86 and X64 ISAs are in both `asmjit::x86` and
+//! `asmjit::x86::regs` namespaces so they can be included with using directive.
+//! For example `using namespace asmjit::x86::regs` would include all registers,
+//! but not other X86-specific API, whereas `using namespace asmjit::x86` would
+//! include everything X86-specific.
+#ifndef _DOXYGEN
+namespace regs {
+#endif
+
+//! Creates an 8-bit low GPB register operand.
+static constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
+//! Creates an 8-bit low GPB register operand.
+static constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
+//! Creates an 8-bit high GPB register operand.
+static constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
+//! Creates a 16-bit GPW register operand.
+static constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
+//! Creates a 32-bit GPD register operand.
+static constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
+//! Creates a 64-bit GPQ register operand (64-bit).
+static constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
+//! Creates a 128-bit XMM register operand.
+static constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
+//! Creates a 256-bit YMM register operand.
+static constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
+//! Creates a 512-bit ZMM register operand.
+static constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
+//! Creates a 64-bit Mm register operand.
+static constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
+//! Creates a 64-bit K register operand.
+static constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
+//! Creates a 32-bit or 64-bit control register operand.
+static constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
+//! Creates a 32-bit or 64-bit debug register operand.
+static constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
+//! Creates an 80-bit st register operand.
+static constexpr St st(uint32_t rId) noexcept { return St(rId); }
+//! Creates a 128-bit bound register operand.
+static constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
+
+static constexpr Gp al = Gp(GpbLo::kSignature, Gp::kIdAx);
+static constexpr Gp bl = Gp(GpbLo::kSignature, Gp::kIdBx);
+static constexpr Gp cl = Gp(GpbLo::kSignature, Gp::kIdCx);
+static constexpr Gp dl = Gp(GpbLo::kSignature, Gp::kIdDx);
+static constexpr Gp spl = Gp(GpbLo::kSignature, Gp::kIdSp);
+static constexpr Gp bpl = Gp(GpbLo::kSignature, Gp::kIdBp);
+static constexpr Gp sil = Gp(GpbLo::kSignature, Gp::kIdSi);
+static constexpr Gp dil = Gp(GpbLo::kSignature, Gp::kIdDi);
+static constexpr Gp r8b = Gp(GpbLo::kSignature, Gp::kIdR8);
+static constexpr Gp r9b = Gp(GpbLo::kSignature, Gp::kIdR9);
+static constexpr Gp r10b = Gp(GpbLo::kSignature, Gp::kIdR10);
+static constexpr Gp r11b = Gp(GpbLo::kSignature, Gp::kIdR11);
+static constexpr Gp r12b = Gp(GpbLo::kSignature, Gp::kIdR12);
+static constexpr Gp r13b = Gp(GpbLo::kSignature, Gp::kIdR13);
+static constexpr Gp r14b = Gp(GpbLo::kSignature, Gp::kIdR14);
+static constexpr Gp r15b = Gp(GpbLo::kSignature, Gp::kIdR15);
+
+static constexpr Gp ah = Gp(GpbHi::kSignature, Gp::kIdAx);
+static constexpr Gp bh = Gp(GpbHi::kSignature, Gp::kIdBx);
+static constexpr Gp ch = Gp(GpbHi::kSignature, Gp::kIdCx);
+static constexpr Gp dh = Gp(GpbHi::kSignature, Gp::kIdDx);
+
+static constexpr Gp ax = Gp(Gpw::kSignature, Gp::kIdAx);
+static constexpr Gp bx = Gp(Gpw::kSignature, Gp::kIdBx);
+static constexpr Gp cx = Gp(Gpw::kSignature, Gp::kIdCx);
+static constexpr Gp dx = Gp(Gpw::kSignature, Gp::kIdDx);
+static constexpr Gp sp = Gp(Gpw::kSignature, Gp::kIdSp);
+static constexpr Gp bp = Gp(Gpw::kSignature, Gp::kIdBp);
+static constexpr Gp si = Gp(Gpw::kSignature, Gp::kIdSi);
+static constexpr Gp di = Gp(Gpw::kSignature, Gp::kIdDi);
+static constexpr Gp r8w = Gp(Gpw::kSignature, Gp::kIdR8);
+static constexpr Gp r9w = Gp(Gpw::kSignature, Gp::kIdR9);
+static constexpr Gp r10w = Gp(Gpw::kSignature, Gp::kIdR10);
+static constexpr Gp r11w = Gp(Gpw::kSignature, Gp::kIdR11);
+static constexpr Gp r12w = Gp(Gpw::kSignature, Gp::kIdR12);
+static constexpr Gp r13w = Gp(Gpw::kSignature, Gp::kIdR13);
+static constexpr Gp r14w = Gp(Gpw::kSignature, Gp::kIdR14);
+static constexpr Gp r15w = Gp(Gpw::kSignature, Gp::kIdR15);
+
+static constexpr Gp eax = Gp(Gpd::kSignature, Gp::kIdAx);
+static constexpr Gp ebx = Gp(Gpd::kSignature, Gp::kIdBx);
+static constexpr Gp ecx = Gp(Gpd::kSignature, Gp::kIdCx);
+static constexpr Gp edx = Gp(Gpd::kSignature, Gp::kIdDx);
+static constexpr Gp esp = Gp(Gpd::kSignature, Gp::kIdSp);
+static constexpr Gp ebp = Gp(Gpd::kSignature, Gp::kIdBp);
+static constexpr Gp esi = Gp(Gpd::kSignature, Gp::kIdSi);
+static constexpr Gp edi = Gp(Gpd::kSignature, Gp::kIdDi);
+static constexpr Gp r8d = Gp(Gpd::kSignature, Gp::kIdR8);
+static constexpr Gp r9d = Gp(Gpd::kSignature, Gp::kIdR9);
+static constexpr Gp r10d = Gp(Gpd::kSignature, Gp::kIdR10);
+static constexpr Gp r11d = Gp(Gpd::kSignature, Gp::kIdR11);
+static constexpr Gp r12d = Gp(Gpd::kSignature, Gp::kIdR12);
+static constexpr Gp r13d = Gp(Gpd::kSignature, Gp::kIdR13);
+static constexpr Gp r14d = Gp(Gpd::kSignature, Gp::kIdR14);
+static constexpr Gp r15d = Gp(Gpd::kSignature, Gp::kIdR15);
+
+static constexpr Gp rax = Gp(Gpq::kSignature, Gp::kIdAx);
+static constexpr Gp rbx = Gp(Gpq::kSignature, Gp::kIdBx);
+static constexpr Gp rcx = Gp(Gpq::kSignature, Gp::kIdCx);
+static constexpr Gp rdx = Gp(Gpq::kSignature, Gp::kIdDx);
+static constexpr Gp rsp = Gp(Gpq::kSignature, Gp::kIdSp);
+static constexpr Gp rbp = Gp(Gpq::kSignature, Gp::kIdBp);
+static constexpr Gp rsi = Gp(Gpq::kSignature, Gp::kIdSi);
+static constexpr Gp rdi = Gp(Gpq::kSignature, Gp::kIdDi);
+static constexpr Gp r8 = Gp(Gpq::kSignature, Gp::kIdR8);
+static constexpr Gp r9 = Gp(Gpq::kSignature, Gp::kIdR9);
+static constexpr Gp r10 = Gp(Gpq::kSignature, Gp::kIdR10);
+static constexpr Gp r11 = Gp(Gpq::kSignature, Gp::kIdR11);
+static constexpr Gp r12 = Gp(Gpq::kSignature, Gp::kIdR12);
+static constexpr Gp r13 = Gp(Gpq::kSignature, Gp::kIdR13);
+static constexpr Gp r14 = Gp(Gpq::kSignature, Gp::kIdR14);
+static constexpr Gp r15 = Gp(Gpq::kSignature, Gp::kIdR15);
+
+static constexpr Xmm xmm0 = Xmm(0);
+static constexpr Xmm xmm1 = Xmm(1);
+static constexpr Xmm xmm2 = Xmm(2);
+static constexpr Xmm xmm3 = Xmm(3);
+static constexpr Xmm xmm4 = Xmm(4);
+static constexpr Xmm xmm5 = Xmm(5);
+static constexpr Xmm xmm6 = Xmm(6);
+static constexpr Xmm xmm7 = Xmm(7);
+static constexpr Xmm xmm8 = Xmm(8);
+static constexpr Xmm xmm9 = Xmm(9);
+static constexpr Xmm xmm10 = Xmm(10);
+static constexpr Xmm xmm11 = Xmm(11);
+static constexpr Xmm xmm12 = Xmm(12);
+static constexpr Xmm xmm13 = Xmm(13);
+static constexpr Xmm xmm14 = Xmm(14);
+static constexpr Xmm xmm15 = Xmm(15);
+static constexpr Xmm xmm16 = Xmm(16);
+static constexpr Xmm xmm17 = Xmm(17);
+static constexpr Xmm xmm18 = Xmm(18);
+static constexpr Xmm xmm19 = Xmm(19);
+static constexpr Xmm xmm20 = Xmm(20);
+static constexpr Xmm xmm21 = Xmm(21);
+static constexpr Xmm xmm22 = Xmm(22);
+static constexpr Xmm xmm23 = Xmm(23);
+static constexpr Xmm xmm24 = Xmm(24);
+static constexpr Xmm xmm25 = Xmm(25);
+static constexpr Xmm xmm26 = Xmm(26);
+static constexpr Xmm xmm27 = Xmm(27);
+static constexpr Xmm xmm28 = Xmm(28);
+static constexpr Xmm xmm29 = Xmm(29);
+static constexpr Xmm xmm30 = Xmm(30);
+static constexpr Xmm xmm31 = Xmm(31);
+
+static constexpr Ymm ymm0 = Ymm(0);
+static constexpr Ymm ymm1 = Ymm(1);
+static constexpr Ymm ymm2 = Ymm(2);
+static constexpr Ymm ymm3 = Ymm(3);
+static constexpr Ymm ymm4 = Ymm(4);
+static constexpr Ymm ymm5 = Ymm(5);
+static constexpr Ymm ymm6 = Ymm(6);
+static constexpr Ymm ymm7 = Ymm(7);
+static constexpr Ymm ymm8 = Ymm(8);
+static constexpr Ymm ymm9 = Ymm(9);
+static constexpr Ymm ymm10 = Ymm(10);
+static constexpr Ymm ymm11 = Ymm(11);
+static constexpr Ymm ymm12 = Ymm(12);
+static constexpr Ymm ymm13 = Ymm(13);
+static constexpr Ymm ymm14 = Ymm(14);
+static constexpr Ymm ymm15 = Ymm(15);
+static constexpr Ymm ymm16 = Ymm(16);
+static constexpr Ymm ymm17 = Ymm(17);
+static constexpr Ymm ymm18 = Ymm(18);
+static constexpr Ymm ymm19 = Ymm(19);
+static constexpr Ymm ymm20 = Ymm(20);
+static constexpr Ymm ymm21 = Ymm(21);
+static constexpr Ymm ymm22 = Ymm(22);
+static constexpr Ymm ymm23 = Ymm(23);
+static constexpr Ymm ymm24 = Ymm(24);
+static constexpr Ymm ymm25 = Ymm(25);
+static constexpr Ymm ymm26 = Ymm(26);
+static constexpr Ymm ymm27 = Ymm(27);
+static constexpr Ymm ymm28 = Ymm(28);
+static constexpr Ymm ymm29 = Ymm(29);
+static constexpr Ymm ymm30 = Ymm(30);
+static constexpr Ymm ymm31 = Ymm(31);
+
+static constexpr Zmm zmm0 = Zmm(0);
+static constexpr Zmm zmm1 = Zmm(1);
+static constexpr Zmm zmm2 = Zmm(2);
+static constexpr Zmm zmm3 = Zmm(3);
+static constexpr Zmm zmm4 = Zmm(4);
+static constexpr Zmm zmm5 = Zmm(5);
+static constexpr Zmm zmm6 = Zmm(6);
+static constexpr Zmm zmm7 = Zmm(7);
+static constexpr Zmm zmm8 = Zmm(8);
+static constexpr Zmm zmm9 = Zmm(9);
+static constexpr Zmm zmm10 = Zmm(10);
+static constexpr Zmm zmm11 = Zmm(11);
+static constexpr Zmm zmm12 = Zmm(12);
+static constexpr Zmm zmm13 = Zmm(13);
+static constexpr Zmm zmm14 = Zmm(14);
+static constexpr Zmm zmm15 = Zmm(15);
+static constexpr Zmm zmm16 = Zmm(16);
+static constexpr Zmm zmm17 = Zmm(17);
+static constexpr Zmm zmm18 = Zmm(18);
+static constexpr Zmm zmm19 = Zmm(19);
+static constexpr Zmm zmm20 = Zmm(20);
+static constexpr Zmm zmm21 = Zmm(21);
+static constexpr Zmm zmm22 = Zmm(22);
+static constexpr Zmm zmm23 = Zmm(23);
+static constexpr Zmm zmm24 = Zmm(24);
+static constexpr Zmm zmm25 = Zmm(25);
+static constexpr Zmm zmm26 = Zmm(26);
+static constexpr Zmm zmm27 = Zmm(27);
+static constexpr Zmm zmm28 = Zmm(28);
+static constexpr Zmm zmm29 = Zmm(29);
+static constexpr Zmm zmm30 = Zmm(30);
+static constexpr Zmm zmm31 = Zmm(31);
+
+static constexpr Mm mm0 = Mm(0);
+static constexpr Mm mm1 = Mm(1);
+static constexpr Mm mm2 = Mm(2);
+static constexpr Mm mm3 = Mm(3);
+static constexpr Mm mm4 = Mm(4);
+static constexpr Mm mm5 = Mm(5);
+static constexpr Mm mm6 = Mm(6);
+static constexpr Mm mm7 = Mm(7);
+
+static constexpr KReg k0 = KReg(0);
+static constexpr KReg k1 = KReg(1);
+static constexpr KReg k2 = KReg(2);
+static constexpr KReg k3 = KReg(3);
+static constexpr KReg k4 = KReg(4);
+static constexpr KReg k5 = KReg(5);
+static constexpr KReg k6 = KReg(6);
+static constexpr KReg k7 = KReg(7);
+
+static constexpr SReg no_seg = SReg(SReg::kIdNone);
+static constexpr SReg es = SReg(SReg::kIdEs);
+static constexpr SReg cs = SReg(SReg::kIdCs);
+static constexpr SReg ss = SReg(SReg::kIdSs);
+static constexpr SReg ds = SReg(SReg::kIdDs);
+static constexpr SReg fs = SReg(SReg::kIdFs);
+static constexpr SReg gs = SReg(SReg::kIdGs);
+
+static constexpr CReg cr0 = CReg(0);
+static constexpr CReg cr1 = CReg(1);
+static constexpr CReg cr2 = CReg(2);
+static constexpr CReg cr3 = CReg(3);
+static constexpr CReg cr4 = CReg(4);
+static constexpr CReg cr5 = CReg(5);
+static constexpr CReg cr6 = CReg(6);
+static constexpr CReg cr7 = CReg(7);
+static constexpr CReg cr8 = CReg(8);
+static constexpr CReg cr9 = CReg(9);
+static constexpr CReg cr10 = CReg(10);
+static constexpr CReg cr11 = CReg(11);
+static constexpr CReg cr12 = CReg(12);
+static constexpr CReg cr13 = CReg(13);
+static constexpr CReg cr14 = CReg(14);
+static constexpr CReg cr15 = CReg(15);
+
+static constexpr DReg dr0 = DReg(0);
+static constexpr DReg dr1 = DReg(1);
+static constexpr DReg dr2 = DReg(2);
+static constexpr DReg dr3 = DReg(3);
+static constexpr DReg dr4 = DReg(4);
+static constexpr DReg dr5 = DReg(5);
+static constexpr DReg dr6 = DReg(6);
+static constexpr DReg dr7 = DReg(7);
+static constexpr DReg dr8 = DReg(8);
+static constexpr DReg dr9 = DReg(9);
+static constexpr DReg dr10 = DReg(10);
+static constexpr DReg dr11 = DReg(11);
+static constexpr DReg dr12 = DReg(12);
+static constexpr DReg dr13 = DReg(13);
+static constexpr DReg dr14 = DReg(14);
+static constexpr DReg dr15 = DReg(15);
+
+static constexpr St st0 = St(0);
+static constexpr St st1 = St(1);
+static constexpr St st2 = St(2);
+static constexpr St st3 = St(3);
+static constexpr St st4 = St(4);
+static constexpr St st5 = St(5);
+static constexpr St st6 = St(6);
+static constexpr St st7 = St(7);
+
+static constexpr Bnd bnd0 = Bnd(0);
+static constexpr Bnd bnd1 = Bnd(1);
+static constexpr Bnd bnd2 = Bnd(2);
+static constexpr Bnd bnd3 = Bnd(3);
+
+static constexpr Rip rip = Rip(0);
+
+#ifndef _DOXYGEN
+} // {regs}
+
+// Make `x86::regs` accessible through `x86` namespace as well.
+using namespace regs;
+#endif
+
// ============================================================================
// [asmjit::x86::Mem]
// ============================================================================
@@ -552,328 +894,6 @@ public:
inline Mem& operator=(const Mem& other) noexcept = default;
};
-// ============================================================================
-// [asmjit::x86::OpData]
-// ============================================================================
-
-struct OpData {
- //! Information about all architecture registers.
- ArchRegs archRegs;
-};
-ASMJIT_VARAPI const OpData opData;
-
-//! \cond
-// ... Reg methods that require `opData`.
-inline uint32_t Reg::groupOf(uint32_t rType) noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return opData.archRegs.regInfo[rType].group();
-}
-
-inline uint32_t Reg::typeIdOf(uint32_t rType) noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return opData.archRegs.regTypeToTypeId[rType];
-}
-
-inline uint32_t Reg::signatureOf(uint32_t rType) noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return opData.archRegs.regInfo[rType].signature();
-}
-//! \endcond
-
-// ============================================================================
-// [asmjit::x86::regs]
-// ============================================================================
-
-namespace regs {
-
-//! Creates an 8-bit low GPB register operand.
-static constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
-//! Creates an 8-bit low GPB register operand.
-static constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
-//! Creates an 8-bit high GPB register operand.
-static constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
-//! Creates a 16-bit GPW register operand.
-static constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
-//! Creates a 32-bit GPD register operand.
-static constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
-//! Creates a 64-bit GPQ register operand (64-bit).
-static constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
-//! Creates a 128-bit XMM register operand.
-static constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
-//! Creates a 256-bit YMM register operand.
-static constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
-//! Creates a 512-bit ZMM register operand.
-static constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
-//! Creates a 64-bit Mm register operand.
-static constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
-//! Creates a 64-bit K register operand.
-static constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
-//! Creates a 32-bit or 64-bit control register operand.
-static constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
-//! Creates a 32-bit or 64-bit debug register operand.
-static constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
-//! Creates an 80-bit st register operand.
-static constexpr St st(uint32_t rId) noexcept { return St(rId); }
-//! Creates a 128-bit bound register operand.
-static constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
-
-static constexpr Gp al(GpbLo::kSignature, Gp::kIdAx);
-static constexpr Gp bl(GpbLo::kSignature, Gp::kIdBx);
-static constexpr Gp cl(GpbLo::kSignature, Gp::kIdCx);
-static constexpr Gp dl(GpbLo::kSignature, Gp::kIdDx);
-static constexpr Gp spl(GpbLo::kSignature, Gp::kIdSp);
-static constexpr Gp bpl(GpbLo::kSignature, Gp::kIdBp);
-static constexpr Gp sil(GpbLo::kSignature, Gp::kIdSi);
-static constexpr Gp dil(GpbLo::kSignature, Gp::kIdDi);
-static constexpr Gp r8b(GpbLo::kSignature, Gp::kIdR8);
-static constexpr Gp r9b(GpbLo::kSignature, Gp::kIdR9);
-static constexpr Gp r10b(GpbLo::kSignature, Gp::kIdR10);
-static constexpr Gp r11b(GpbLo::kSignature, Gp::kIdR11);
-static constexpr Gp r12b(GpbLo::kSignature, Gp::kIdR12);
-static constexpr Gp r13b(GpbLo::kSignature, Gp::kIdR13);
-static constexpr Gp r14b(GpbLo::kSignature, Gp::kIdR14);
-static constexpr Gp r15b(GpbLo::kSignature, Gp::kIdR15);
-
-static constexpr Gp ah(GpbHi::kSignature, Gp::kIdAx);
-static constexpr Gp bh(GpbHi::kSignature, Gp::kIdBx);
-static constexpr Gp ch(GpbHi::kSignature, Gp::kIdCx);
-static constexpr Gp dh(GpbHi::kSignature, Gp::kIdDx);
-
-static constexpr Gp ax(Gpw::kSignature, Gp::kIdAx);
-static constexpr Gp bx(Gpw::kSignature, Gp::kIdBx);
-static constexpr Gp cx(Gpw::kSignature, Gp::kIdCx);
-static constexpr Gp dx(Gpw::kSignature, Gp::kIdDx);
-static constexpr Gp sp(Gpw::kSignature, Gp::kIdSp);
-static constexpr Gp bp(Gpw::kSignature, Gp::kIdBp);
-static constexpr Gp si(Gpw::kSignature, Gp::kIdSi);
-static constexpr Gp di(Gpw::kSignature, Gp::kIdDi);
-static constexpr Gp r8w(Gpw::kSignature, Gp::kIdR8);
-static constexpr Gp r9w(Gpw::kSignature, Gp::kIdR9);
-static constexpr Gp r10w(Gpw::kSignature, Gp::kIdR10);
-static constexpr Gp r11w(Gpw::kSignature, Gp::kIdR11);
-static constexpr Gp r12w(Gpw::kSignature, Gp::kIdR12);
-static constexpr Gp r13w(Gpw::kSignature, Gp::kIdR13);
-static constexpr Gp r14w(Gpw::kSignature, Gp::kIdR14);
-static constexpr Gp r15w(Gpw::kSignature, Gp::kIdR15);
-
-static constexpr Gp eax(Gpd::kSignature, Gp::kIdAx);
-static constexpr Gp ebx(Gpd::kSignature, Gp::kIdBx);
-static constexpr Gp ecx(Gpd::kSignature, Gp::kIdCx);
-static constexpr Gp edx(Gpd::kSignature, Gp::kIdDx);
-static constexpr Gp esp(Gpd::kSignature, Gp::kIdSp);
-static constexpr Gp ebp(Gpd::kSignature, Gp::kIdBp);
-static constexpr Gp esi(Gpd::kSignature, Gp::kIdSi);
-static constexpr Gp edi(Gpd::kSignature, Gp::kIdDi);
-static constexpr Gp r8d(Gpd::kSignature, Gp::kIdR8);
-static constexpr Gp r9d(Gpd::kSignature, Gp::kIdR9);
-static constexpr Gp r10d(Gpd::kSignature, Gp::kIdR10);
-static constexpr Gp r11d(Gpd::kSignature, Gp::kIdR11);
-static constexpr Gp r12d(Gpd::kSignature, Gp::kIdR12);
-static constexpr Gp r13d(Gpd::kSignature, Gp::kIdR13);
-static constexpr Gp r14d(Gpd::kSignature, Gp::kIdR14);
-static constexpr Gp r15d(Gpd::kSignature, Gp::kIdR15);
-
-static constexpr Gp rax(Gpq::kSignature, Gp::kIdAx);
-static constexpr Gp rbx(Gpq::kSignature, Gp::kIdBx);
-static constexpr Gp rcx(Gpq::kSignature, Gp::kIdCx);
-static constexpr Gp rdx(Gpq::kSignature, Gp::kIdDx);
-static constexpr Gp rsp(Gpq::kSignature, Gp::kIdSp);
-static constexpr Gp rbp(Gpq::kSignature, Gp::kIdBp);
-static constexpr Gp rsi(Gpq::kSignature, Gp::kIdSi);
-static constexpr Gp rdi(Gpq::kSignature, Gp::kIdDi);
-static constexpr Gp r8(Gpq::kSignature, Gp::kIdR8);
-static constexpr Gp r9(Gpq::kSignature, Gp::kIdR9);
-static constexpr Gp r10(Gpq::kSignature, Gp::kIdR10);
-static constexpr Gp r11(Gpq::kSignature, Gp::kIdR11);
-static constexpr Gp r12(Gpq::kSignature, Gp::kIdR12);
-static constexpr Gp r13(Gpq::kSignature, Gp::kIdR13);
-static constexpr Gp r14(Gpq::kSignature, Gp::kIdR14);
-static constexpr Gp r15(Gpq::kSignature, Gp::kIdR15);
-
-static constexpr Xmm xmm0(0);
-static constexpr Xmm xmm1(1);
-static constexpr Xmm xmm2(2);
-static constexpr Xmm xmm3(3);
-static constexpr Xmm xmm4(4);
-static constexpr Xmm xmm5(5);
-static constexpr Xmm xmm6(6);
-static constexpr Xmm xmm7(7);
-static constexpr Xmm xmm8(8);
-static constexpr Xmm xmm9(9);
-static constexpr Xmm xmm10(10);
-static constexpr Xmm xmm11(11);
-static constexpr Xmm xmm12(12);
-static constexpr Xmm xmm13(13);
-static constexpr Xmm xmm14(14);
-static constexpr Xmm xmm15(15);
-static constexpr Xmm xmm16(16);
-static constexpr Xmm xmm17(17);
-static constexpr Xmm xmm18(18);
-static constexpr Xmm xmm19(19);
-static constexpr Xmm xmm20(20);
-static constexpr Xmm xmm21(21);
-static constexpr Xmm xmm22(22);
-static constexpr Xmm xmm23(23);
-static constexpr Xmm xmm24(24);
-static constexpr Xmm xmm25(25);
-static constexpr Xmm xmm26(26);
-static constexpr Xmm xmm27(27);
-static constexpr Xmm xmm28(28);
-static constexpr Xmm xmm29(29);
-static constexpr Xmm xmm30(30);
-static constexpr Xmm xmm31(31);
-
-static constexpr Ymm ymm0(0);
-static constexpr Ymm ymm1(1);
-static constexpr Ymm ymm2(2);
-static constexpr Ymm ymm3(3);
-static constexpr Ymm ymm4(4);
-static constexpr Ymm ymm5(5);
-static constexpr Ymm ymm6(6);
-static constexpr Ymm ymm7(7);
-static constexpr Ymm ymm8(8);
-static constexpr Ymm ymm9(9);
-static constexpr Ymm ymm10(10);
-static constexpr Ymm ymm11(11);
-static constexpr Ymm ymm12(12);
-static constexpr Ymm ymm13(13);
-static constexpr Ymm ymm14(14);
-static constexpr Ymm ymm15(15);
-static constexpr Ymm ymm16(16);
-static constexpr Ymm ymm17(17);
-static constexpr Ymm ymm18(18);
-static constexpr Ymm ymm19(19);
-static constexpr Ymm ymm20(20);
-static constexpr Ymm ymm21(21);
-static constexpr Ymm ymm22(22);
-static constexpr Ymm ymm23(23);
-static constexpr Ymm ymm24(24);
-static constexpr Ymm ymm25(25);
-static constexpr Ymm ymm26(26);
-static constexpr Ymm ymm27(27);
-static constexpr Ymm ymm28(28);
-static constexpr Ymm ymm29(29);
-static constexpr Ymm ymm30(30);
-static constexpr Ymm ymm31(31);
-
-static constexpr Zmm zmm0(0);
-static constexpr Zmm zmm1(1);
-static constexpr Zmm zmm2(2);
-static constexpr Zmm zmm3(3);
-static constexpr Zmm zmm4(4);
-static constexpr Zmm zmm5(5);
-static constexpr Zmm zmm6(6);
-static constexpr Zmm zmm7(7);
-static constexpr Zmm zmm8(8);
-static constexpr Zmm zmm9(9);
-static constexpr Zmm zmm10(10);
-static constexpr Zmm zmm11(11);
-static constexpr Zmm zmm12(12);
-static constexpr Zmm zmm13(13);
-static constexpr Zmm zmm14(14);
-static constexpr Zmm zmm15(15);
-static constexpr Zmm zmm16(16);
-static constexpr Zmm zmm17(17);
-static constexpr Zmm zmm18(18);
-static constexpr Zmm zmm19(19);
-static constexpr Zmm zmm20(20);
-static constexpr Zmm zmm21(21);
-static constexpr Zmm zmm22(22);
-static constexpr Zmm zmm23(23);
-static constexpr Zmm zmm24(24);
-static constexpr Zmm zmm25(25);
-static constexpr Zmm zmm26(26);
-static constexpr Zmm zmm27(27);
-static constexpr Zmm zmm28(28);
-static constexpr Zmm zmm29(29);
-static constexpr Zmm zmm30(30);
-static constexpr Zmm zmm31(31);
-
-static constexpr Mm mm0(0);
-static constexpr Mm mm1(1);
-static constexpr Mm mm2(2);
-static constexpr Mm mm3(3);
-static constexpr Mm mm4(4);
-static constexpr Mm mm5(5);
-static constexpr Mm mm6(6);
-static constexpr Mm mm7(7);
-
-static constexpr KReg k0(0);
-static constexpr KReg k1(1);
-static constexpr KReg k2(2);
-static constexpr KReg k3(3);
-static constexpr KReg k4(4);
-static constexpr KReg k5(5);
-static constexpr KReg k6(6);
-static constexpr KReg k7(7);
-
-static constexpr SReg no_seg(SReg::kIdNone);
-static constexpr SReg es(SReg::kIdEs);
-static constexpr SReg cs(SReg::kIdCs);
-static constexpr SReg ss(SReg::kIdSs);
-static constexpr SReg ds(SReg::kIdDs);
-static constexpr SReg fs(SReg::kIdFs);
-static constexpr SReg gs(SReg::kIdGs);
-
-static constexpr CReg cr0(0);
-static constexpr CReg cr1(1);
-static constexpr CReg cr2(2);
-static constexpr CReg cr3(3);
-static constexpr CReg cr4(4);
-static constexpr CReg cr5(5);
-static constexpr CReg cr6(6);
-static constexpr CReg cr7(7);
-static constexpr CReg cr8(8);
-static constexpr CReg cr9(9);
-static constexpr CReg cr10(10);
-static constexpr CReg cr11(11);
-static constexpr CReg cr12(12);
-static constexpr CReg cr13(13);
-static constexpr CReg cr14(14);
-static constexpr CReg cr15(15);
-
-static constexpr DReg dr0(0);
-static constexpr DReg dr1(1);
-static constexpr DReg dr2(2);
-static constexpr DReg dr3(3);
-static constexpr DReg dr4(4);
-static constexpr DReg dr5(5);
-static constexpr DReg dr6(6);
-static constexpr DReg dr7(7);
-static constexpr DReg dr8(8);
-static constexpr DReg dr9(9);
-static constexpr DReg dr10(10);
-static constexpr DReg dr11(11);
-static constexpr DReg dr12(12);
-static constexpr DReg dr13(13);
-static constexpr DReg dr14(14);
-static constexpr DReg dr15(15);
-
-static constexpr St st0(0);
-static constexpr St st1(1);
-static constexpr St st2(2);
-static constexpr St st3(3);
-static constexpr St st4(4);
-static constexpr St st5(5);
-static constexpr St st6(6);
-static constexpr St st7(7);
-
-static constexpr Bnd bnd0(0);
-static constexpr Bnd bnd1(1);
-static constexpr Bnd bnd2(2);
-static constexpr Bnd bnd3(3);
-
-static constexpr Rip rip(0);
-
-} // {regs}
-
-// Make `x86::regs` accessible through `x86` namespace as well.
-using namespace regs;
-
-// ============================================================================
-// [asmjit::x86::ptr]
-// ============================================================================
-
//! Creates `[base.reg + offset]` memory operand.
static constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, offset, size);
@@ -944,70 +964,6 @@ static constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0
return Mem(base, index, shift, size, BaseMem::kSignatureMemRel);
}
-#define ASMJIT_MEM_PTR(FUNC, SIZE) \
- /*! Creates `[base + offset]` memory operand. */ \
- static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept { \
- return Mem(base, offset, SIZE); \
- } \
- /*! Creates `[base + (index << shift) + offset]` memory operand. */ \
- static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- /*! Creates `[base + (vec_index << shift) + offset]` memory operand. */ \
- static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- /*! Creates `[base + offset]` memory operand. */ \
- static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept { \
- return Mem(base, offset, SIZE); \
- } \
- /*! Creates `[base + (index << shift) + offset]` memory operand. */ \
- static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- /*! Creates `[rip + offset]` memory operand. */ \
- static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept { \
- return Mem(rip_, offset, SIZE); \
- } \
- /*! Creates `[ptr]` memory operand. */ \
- static constexpr Mem FUNC(uint64_t base) noexcept { \
- return Mem(base, SIZE); \
- } \
- /*! Creates `[base + (index << shift) + offset]` memory operand. */ \
- static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE); \
- } \
- /*! Creates `[base + (vec_index << shift) + offset]` memory operand. */ \
- static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE); \
- } \
- \
- /*! Creates `[base + offset]` memory operand (absolute). */ \
- static constexpr Mem FUNC##_abs(uint64_t base) noexcept { \
- return Mem(base, SIZE, BaseMem::kSignatureMemAbs); \
- } \
- /*! Creates `[base + (index << shift) + offset]` memory operand (absolute). */ \
- static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
- } \
- /*! Creates `[base + (vec_index << shift) + offset]` memory operand (absolute). */ \
- static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
- } \
- \
- /*! Creates `[base + offset]` memory operand (relative). */ \
- static constexpr Mem FUNC##_rel(uint64_t base) noexcept { \
- return Mem(base, SIZE, BaseMem::kSignatureMemRel); \
- } \
- /*! Creates `[base + (index << shift) + offset]` memory operand (relative). */ \
- static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
- } \
- /*! Creates `[base + (vec_index << shift) + offset]` memory operand (relative). */ \
- static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
- }
-
// Definition of memory operand constructors that use platform independent naming.
ASMJIT_MEM_PTR(ptr_8, 1)
ASMJIT_MEM_PTR(ptr_16, 2)
@@ -1032,7 +988,33 @@ ASMJIT_MEM_PTR(xmmword_ptr, 16)
ASMJIT_MEM_PTR(ymmword_ptr, 32)
ASMJIT_MEM_PTR(zmmword_ptr, 64)
-#undef ASMJIT_MEM_PTR
+// ============================================================================
+// [asmjit::x86::OpData]
+// ============================================================================
+
+struct OpData {
+ //! Information about all architecture registers.
+ ArchRegs archRegs;
+};
+ASMJIT_VARAPI const OpData opData;
+
+//! \cond
+// ... Reg methods that require `opData`.
+inline uint32_t Reg::groupOf(uint32_t rType) noexcept {
+ ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
+ return opData.archRegs.regInfo[rType].group();
+}
+
+inline uint32_t Reg::typeIdOf(uint32_t rType) noexcept {
+ ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
+ return opData.archRegs.regTypeToTypeId[rType];
+}
+
+inline uint32_t Reg::signatureOf(uint32_t rType) noexcept {
+ ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
+ return opData.archRegs.regInfo[rType].signature();
+}
+//! \endcond
//! \}
@@ -1043,7 +1025,6 @@ ASMJIT_END_SUB_NAMESPACE
// ============================================================================
//! \cond INTERNAL
-
ASMJIT_BEGIN_NAMESPACE
ASMJIT_DEFINE_TYPE_ID(x86::Gpb, kIdI8);
ASMJIT_DEFINE_TYPE_ID(x86::Gpw, kIdI16);
@@ -1054,7 +1035,8 @@ ASMJIT_DEFINE_TYPE_ID(x86::Xmm, kIdI32x4);
ASMJIT_DEFINE_TYPE_ID(x86::Ymm, kIdI32x8);
ASMJIT_DEFINE_TYPE_ID(x86::Zmm, kIdI32x16);
ASMJIT_END_NAMESPACE
-
//! \endcond
+#undef ASMJIT_MEM_PTR
+
#endif // ASMJIT_X86_X86OPERAND_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp b/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp
index cd6ebb5d6d5..6cbb0064388 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp
@@ -91,14 +91,14 @@ static ASMJIT_INLINE uint32_t raMemIndexRwFlags(uint32_t flags) noexcept {
class X86RACFGBuilder : public RACFGBuilder<X86RACFGBuilder> {
public:
- uint32_t _archId;
+ uint32_t _arch;
bool _is64Bit;
bool _avxEnabled;
inline X86RACFGBuilder(X86RAPass* pass) noexcept
: RACFGBuilder<X86RACFGBuilder>(pass),
- _archId(pass->cc()->archId()),
- _is64Bit(pass->gpSize() == 8),
+ _arch(pass->cc()->arch()),
+ _is64Bit(pass->registerSize() == 8),
_avxEnabled(pass->_avxEnabled) {
}
@@ -110,12 +110,13 @@ public:
Error onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder& ib) noexcept;
- Error onBeforeCall(FuncCallNode* call) noexcept;
- Error onCall(FuncCallNode* call, RAInstBuilder& ib) noexcept;
+ Error onBeforeInvoke(InvokeNode* invokeNode) noexcept;
+ Error onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept;
- Error moveImmToRegArg(FuncCallNode* call, const FuncValue& arg, const Imm& imm_, BaseReg* out) noexcept;
- Error moveImmToStackArg(FuncCallNode* call, const FuncValue& arg, const Imm& imm_) noexcept;
- Error moveRegToStackArg(FuncCallNode* call, const FuncValue& arg, const BaseReg& reg) noexcept;
+ Error moveVecToPtr(InvokeNode* invokeNode, const FuncValue& arg, const Vec& src, BaseReg* out) noexcept;
+ Error moveImmToRegArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_, BaseReg* out) noexcept;
+ Error moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_) noexcept;
+ Error moveRegToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const BaseReg& reg) noexcept;
Error onBeforeRet(FuncRetNode* funcRet) noexcept;
Error onRet(FuncRetNode* funcRet, RAInstBuilder& ib) noexcept;
@@ -132,7 +133,7 @@ Error X86RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuild
if (Inst::isDefinedId(instId)) {
uint32_t opCount = inst->opCount();
const Operand* opArray = inst->operands();
- ASMJIT_PROPAGATE(InstInternal::queryRWInfo(_archId, inst->baseInst(), opArray, opCount, rwInfo));
+ ASMJIT_PROPAGATE(InstInternal::queryRWInfo(_arch, inst->baseInst(), opArray, opCount, &rwInfo));
const InstDB::InstInfo& instInfo = InstDB::infoById(instId);
bool hasGpbHiConstraint = false;
@@ -343,10 +344,10 @@ Error X86RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuild
if (singleRegOps == opCount) {
singleRegCase = instInfo.singleRegCase();
}
- else if (opCount == 2 && inst->opType(1).isImm()) {
+ else if (opCount == 2 && inst->op(1).isImm()) {
// Handle some tricks used by X86 asm.
- const BaseReg& reg = inst->opType(0).as<BaseReg>();
- const Imm& imm = inst->opType(1).as<Imm>();
+ const BaseReg& reg = inst->op(0).as<BaseReg>();
+ const Imm& imm = inst->op(1).as<Imm>();
const RAWorkReg* workReg = _pass->workRegById(ib[0]->workId());
uint32_t workRegSize = workReg->info().size();
@@ -355,7 +356,7 @@ Error X86RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuild
case Inst::kIdOr: {
// Sets the value of the destination register to -1, previous content unused.
if (reg.size() >= 4 || reg.size() >= workRegSize) {
- if (imm.i64() == -1 || imm.u64() == raImmMaskFromSize(reg.size()))
+ if (imm.value() == -1 || imm.valueAs<uint64_t>() == raImmMaskFromSize(reg.size()))
singleRegCase = InstDB::kSingleRegWO;
}
ASMJIT_FALLTHROUGH;
@@ -372,7 +373,7 @@ Error X86RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuild
case Inst::kIdXor: {
// Updates [E|R]FLAGS without changing the content.
if (reg.size() != 4 || reg.size() >= workRegSize) {
- if (imm.u64() == 0)
+ if (imm.value() == 0)
singleRegCase = InstDB::kSingleRegRO;
}
break;
@@ -402,20 +403,23 @@ Error X86RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuild
// [asmjit::x86::X86RACFGBuilder - OnCall]
// ============================================================================
-Error X86RACFGBuilder::onBeforeCall(FuncCallNode* call) noexcept {
- uint32_t argCount = call->argCount();
- uint32_t retCount = call->retCount();
- const FuncDetail& fd = call->detail();
+Error X86RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
+ uint32_t argCount = invokeNode->argCount();
+ uint32_t retCount = invokeNode->retCount();
+ const FuncDetail& fd = invokeNode->detail();
- cc()->_setCursor(call->prev());
+ cc()->_setCursor(invokeNode->prev());
- for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
- for (uint32_t argHi = 0; argHi <= kFuncArgHi; argHi += kFuncArgHi) {
- if (!fd.hasArg(argIndex + argHi))
+ uint32_t nativeRegType = cc()->_gpRegInfo.type();
+
+ for (uint32_t loIndex = 0; loIndex < argCount; loIndex++) {
+ for (uint32_t hiIndex = 0; hiIndex <= kFuncArgHi; hiIndex += kFuncArgHi) {
+ uint32_t argIndex = loIndex + hiIndex;
+ if (!fd.hasArg(argIndex))
continue;
- const FuncValue& arg = fd.arg(argIndex + argHi);
- const Operand& op = call->arg(argIndex + argHi);
+ const FuncValue& arg = fd.arg(argIndex);
+ const Operand& op = invokeNode->arg(argIndex);
if (op.isNone())
continue;
@@ -429,35 +433,64 @@ Error X86RACFGBuilder::onBeforeCall(FuncCallNode* call) noexcept {
uint32_t regGroup = workReg->group();
uint32_t argGroup = Reg::groupOf(arg.regType());
- if (regGroup != argGroup) {
- // TODO:
- ASMJIT_ASSERT(false);
+ if (arg.isIndirect()) {
+ if (reg.isGp()) {
+ if (reg.type() != nativeRegType)
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ // It's considered allocated if this is an indirect argument and the user used GP.
+ continue;
+ }
+
+ BaseReg indirectReg;
+ moveVecToPtr(invokeNode, arg, reg.as<Vec>(), &indirectReg);
+ invokeNode->_args[argIndex] = indirectReg;
+ }
+ else {
+ if (regGroup != argGroup) {
+ // TODO: Conversion is not supported.
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ }
}
}
else {
- ASMJIT_PROPAGATE(moveRegToStackArg(call, arg, op.as<BaseReg>()));
+ if (arg.isIndirect()) {
+ if (reg.isGp()) {
+ if (reg.type() != nativeRegType)
+ return DebugUtils::errored(kErrorInvalidAssignment);
+
+ ASMJIT_PROPAGATE(moveRegToStackArg(invokeNode, arg, reg));
+ continue;
+ }
+
+ BaseReg indirectReg;
+ moveVecToPtr(invokeNode, arg, reg.as<Vec>(), &indirectReg);
+ ASMJIT_PROPAGATE(moveRegToStackArg(invokeNode, arg, indirectReg));
+ }
+ else {
+ ASMJIT_PROPAGATE(moveRegToStackArg(invokeNode, arg, reg));
+ }
}
}
else if (op.isImm()) {
if (arg.isReg()) {
BaseReg reg;
- ASMJIT_PROPAGATE(moveImmToRegArg(call, arg, op.as<Imm>(), &reg));
- call->_args[argIndex + argHi] = reg;
+ ASMJIT_PROPAGATE(moveImmToRegArg(invokeNode, arg, op.as<Imm>(), &reg));
+ invokeNode->_args[argIndex] = reg;
}
else {
- ASMJIT_PROPAGATE(moveImmToStackArg(call, arg, op.as<Imm>()));
+ ASMJIT_PROPAGATE(moveImmToStackArg(invokeNode, arg, op.as<Imm>()));
}
}
}
}
- cc()->_setCursor(call);
+ cc()->_setCursor(invokeNode);
if (fd.hasFlag(CallConv::kFlagCalleePopsStack))
ASMJIT_PROPAGATE(cc()->sub(cc()->zsp(), fd.argStackSize()));
for (uint32_t retIndex = 0; retIndex < retCount; retIndex++) {
const FuncValue& ret = fd.ret(retIndex);
- const Operand& op = call->ret(retIndex);
+ const Operand& op = invokeNode->ret(retIndex);
if (op.isReg()) {
const Reg& reg = op.as<Reg>();
@@ -500,15 +533,15 @@ Error X86RACFGBuilder::onBeforeCall(FuncCallNode* call) noexcept {
uint32_t retGroup = Reg::groupOf(ret.regType());
if (regGroup != retGroup) {
- // TODO:
- ASMJIT_ASSERT(false);
+ // TODO: Conversion is not supported.
+ return DebugUtils::errored(kErrorInvalidAssignment);
}
}
}
}
}
- // This block has function call(s).
+ // This block has function invokeNode(s).
_curBlock->addFlags(RABlock::kFlagHasFuncCalls);
_pass->func()->frame().addAttributes(FuncFrame::kAttrHasFuncCalls);
_pass->func()->frame().updateCallStackSize(fd.argStackSize());
@@ -516,10 +549,10 @@ Error X86RACFGBuilder::onBeforeCall(FuncCallNode* call) noexcept {
return kErrorOk;
}
-Error X86RACFGBuilder::onCall(FuncCallNode* call, RAInstBuilder& ib) noexcept {
- uint32_t argCount = call->argCount();
- uint32_t retCount = call->retCount();
- const FuncDetail& fd = call->detail();
+Error X86RACFGBuilder::onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept {
+ uint32_t argCount = invokeNode->argCount();
+ uint32_t retCount = invokeNode->retCount();
+ const FuncDetail& fd = invokeNode->detail();
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
for (uint32_t argHi = 0; argHi <= kFuncArgHi; argHi += kFuncArgHi) {
@@ -527,7 +560,7 @@ Error X86RACFGBuilder::onCall(FuncCallNode* call, RAInstBuilder& ib) noexcept {
continue;
const FuncValue& arg = fd.arg(argIndex + argHi);
- const Operand& op = call->arg(argIndex + argHi);
+ const Operand& op = invokeNode->arg(argIndex + argHi);
if (op.isNone())
continue;
@@ -537,7 +570,13 @@ Error X86RACFGBuilder::onCall(FuncCallNode* call, RAInstBuilder& ib) noexcept {
RAWorkReg* workReg;
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
- if (arg.isReg()) {
+ if (arg.isIndirect()) {
+ uint32_t regGroup = workReg->group();
+ if (regGroup != BaseReg::kGroupGp)
+ return DebugUtils::errored(kErrorInvalidState);
+ ASMJIT_PROPAGATE(ib.addCallArg(workReg, arg.regId()));
+ }
+ else if (arg.isReg()) {
uint32_t regGroup = workReg->group();
uint32_t argGroup = Reg::groupOf(arg.regType());
@@ -551,7 +590,7 @@ Error X86RACFGBuilder::onCall(FuncCallNode* call, RAInstBuilder& ib) noexcept {
for (uint32_t retIndex = 0; retIndex < retCount; retIndex++) {
const FuncValue& ret = fd.ret(retIndex);
- const Operand& op = call->ret(retIndex);
+ const Operand& op = invokeNode->ret(retIndex);
// Not handled here...
if (ret.regType() == Reg::kTypeSt)
@@ -586,11 +625,62 @@ Error X86RACFGBuilder::onCall(FuncCallNode* call, RAInstBuilder& ib) noexcept {
}
// ============================================================================
+// [asmjit::x86::X86RACFGBuilder - MoveVecToPtr]
+// ============================================================================
+
+static uint32_t x86VecRegSignatureBySize(uint32_t size) noexcept {
+ if (size >= 64)
+ return Zmm::kSignature;
+ else if (size >= 32)
+ return Ymm::kSignature;
+ else
+ return Xmm::kSignature;
+}
+
+Error X86RACFGBuilder::moveVecToPtr(InvokeNode* invokeNode, const FuncValue& arg, const Vec& src, BaseReg* out) noexcept {
+ DebugUtils::unused(invokeNode);
+ ASMJIT_ASSERT(arg.isReg());
+
+ uint32_t argSize = Type::sizeOf(arg.typeId());
+ if (argSize == 0)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ if (argSize < 16)
+ argSize = 16;
+
+ uint32_t argStackOffset = Support::alignUp(invokeNode->detail()._argStackSize, argSize);
+ _funcNode->frame().updateCallStackAlignment(argSize);
+ invokeNode->detail()._argStackSize = argStackOffset + argSize;
+
+ Vec vecReg(x86VecRegSignatureBySize(argSize), src.id());
+ Mem vecPtr = ptr(_pass->_sp.as<Gp>(), int32_t(argStackOffset));
+
+ uint32_t vMovInstId = choose(Inst::kIdMovaps, Inst::kIdVmovaps);
+ if (argSize > 16)
+ vMovInstId = Inst::kIdVmovaps;
+
+ ASMJIT_PROPAGATE(cc()->_newReg(out, cc()->_gpRegInfo.type(), nullptr));
+
+ VirtReg* vReg = cc()->virtRegById(out->id());
+ vReg->setWeight(RAPass::kCallArgWeight);
+
+ ASMJIT_PROPAGATE(cc()->lea(out->as<Gp>(), vecPtr));
+ ASMJIT_PROPAGATE(cc()->emit(vMovInstId, ptr(out->as<Gp>()), vecReg));
+
+ if (arg.isStack()) {
+ Mem stackPtr = ptr(_pass->_sp.as<Gp>(), arg.stackOffset());
+ ASMJIT_PROPAGATE(cc()->mov(stackPtr, out->as<Gp>()));
+ }
+
+ return kErrorOk;
+}
+
+// ============================================================================
// [asmjit::x86::X86RACFGBuilder - MoveImmToRegArg]
// ============================================================================
-Error X86RACFGBuilder::moveImmToRegArg(FuncCallNode* call, const FuncValue& arg, const Imm& imm_, BaseReg* out) noexcept {
- DebugUtils::unused(call);
+Error X86RACFGBuilder::moveImmToRegArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_, BaseReg* out) noexcept {
+ DebugUtils::unused(invokeNode);
ASMJIT_ASSERT(arg.isReg());
Imm imm(imm_);
@@ -620,10 +710,10 @@ MovU32:
break;
default:
- return DebugUtils::errored(kErrorInvalidState);
+ return DebugUtils::errored(kErrorInvalidAssignment);
}
- ASMJIT_PROPAGATE(cc()->_newReg(*out, rTypeId, nullptr));
+ ASMJIT_PROPAGATE(cc()->_newReg(out, rTypeId, nullptr));
cc()->virtRegById(out->id())->setWeight(RAPass::kCallArgWeight);
return cc()->mov(out->as<x86::Gp>(), imm);
@@ -633,14 +723,14 @@ MovU32:
// [asmjit::x86::X86RACFGBuilder - MoveImmToStackArg]
// ============================================================================
-Error X86RACFGBuilder::moveImmToStackArg(FuncCallNode* call, const FuncValue& arg, const Imm& imm_) noexcept {
- DebugUtils::unused(call);
+Error X86RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_) noexcept {
+ DebugUtils::unused(invokeNode);
ASMJIT_ASSERT(arg.isStack());
- Mem mem = ptr(_pass->_sp.as<Gp>(), arg.stackOffset());
+ Mem stackPtr = ptr(_pass->_sp.as<Gp>(), arg.stackOffset());
Imm imm[2];
- mem.setSize(4);
+ stackPtr.setSize(4);
imm[0] = imm_;
uint32_t nMovs = 0;
@@ -669,23 +759,23 @@ MovU32:
case Type::kIdMmx32:
case Type::kIdMmx64:
if (_is64Bit && imm[0].isInt32()) {
- mem.setSize(8);
+ stackPtr.setSize(8);
nMovs = 1;
break;
}
- imm[1].setU32(imm[0].u32Hi());
+ imm[1].setValue(imm[0].uint32Hi());
imm[0].zeroExtend32Bits();
nMovs = 2;
break;
default:
- return DebugUtils::errored(kErrorInvalidState);
+ return DebugUtils::errored(kErrorInvalidAssignment);
}
for (uint32_t i = 0; i < nMovs; i++) {
- ASMJIT_PROPAGATE(cc()->mov(mem, imm[i]));
- mem.addOffsetLo32(int32_t(mem.size()));
+ ASMJIT_PROPAGATE(cc()->mov(stackPtr, imm[i]));
+ stackPtr.addOffsetLo32(int32_t(stackPtr.size()));
}
return kErrorOk;
@@ -695,15 +785,15 @@ MovU32:
// [asmjit::x86::X86RACFGBuilder - MoveRegToStackArg]
// ============================================================================
-Error X86RACFGBuilder::moveRegToStackArg(FuncCallNode* call, const FuncValue& arg, const BaseReg& reg) noexcept {
- DebugUtils::unused(call);
+Error X86RACFGBuilder::moveRegToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const BaseReg& reg) noexcept {
+ DebugUtils::unused(invokeNode);
ASMJIT_ASSERT(arg.isStack());
- Mem mem = ptr(_pass->_sp.as<Gp>(), arg.stackOffset());
+ Mem stackPtr = ptr(_pass->_sp.as<Gp>(), arg.stackOffset());
Reg r0, r1;
VirtReg* vr = cc()->virtRegById(reg.id());
- uint32_t gpSize = cc()->gpSize();
+ uint32_t registerSize = cc()->registerSize();
uint32_t instId = 0;
uint32_t dstTypeId = arg.typeId();
@@ -812,75 +902,89 @@ Error X86RACFGBuilder::moveRegToStackArg(FuncCallNode* call, const FuncValue& ar
break;
default:
- // TODO: Vector types by stack.
+ if (Type::isVec(dstTypeId) && reg.as<Reg>().isVec()) {
+ stackPtr.setSize(Type::sizeOf(dstTypeId));
+ uint32_t vMovInstId = choose(Inst::kIdMovaps, Inst::kIdVmovaps);
+
+ if (Type::isVec128(dstTypeId))
+ r0.setRegT<Reg::kTypeXmm>(reg.id());
+ else if (Type::isVec256(dstTypeId))
+ r0.setRegT<Reg::kTypeYmm>(reg.id());
+ else if (Type::isVec512(dstTypeId))
+ r0.setRegT<Reg::kTypeZmm>(reg.id());
+ else
+ break;
+
+ return cc()->emit(vMovInstId, stackPtr, r0);
+ }
break;
}
- return DebugUtils::errored(kErrorInvalidState);
+ return DebugUtils::errored(kErrorInvalidAssignment);
// Extend+Move Gp.
ExtendMovGpD:
- mem.setSize(4);
+ stackPtr.setSize(4);
r0.setRegT<Reg::kTypeGpd>(reg.id());
ASMJIT_PROPAGATE(cc()->emit(instId, r0, r1));
- ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, mem, r0));
+ ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, stackPtr, r0));
return kErrorOk;
ExtendMovGpXQ:
- if (gpSize == 8) {
- mem.setSize(8);
+ if (registerSize == 8) {
+ stackPtr.setSize(8);
r0.setRegT<Reg::kTypeGpq>(reg.id());
ASMJIT_PROPAGATE(cc()->emit(instId, r0, r1));
- ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, mem, r0));
+ ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, stackPtr, r0));
}
else {
- mem.setSize(4);
+ stackPtr.setSize(4);
r0.setRegT<Reg::kTypeGpd>(reg.id());
ASMJIT_PROPAGATE(cc()->emit(instId, r0, r1));
ExtendMovGpDQ:
- ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, mem, r0));
- mem.addOffsetLo32(4);
- ASMJIT_PROPAGATE(cc()->emit(Inst::kIdAnd, mem, 0));
+ ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, stackPtr, r0));
+ stackPtr.addOffsetLo32(4);
+ ASMJIT_PROPAGATE(cc()->emit(Inst::kIdAnd, stackPtr, 0));
}
return kErrorOk;
ZeroExtendGpDQ:
- mem.setSize(4);
+ stackPtr.setSize(4);
r0.setRegT<Reg::kTypeGpd>(reg.id());
goto ExtendMovGpDQ;
MovGpD:
- mem.setSize(4);
+ stackPtr.setSize(4);
r0.setRegT<Reg::kTypeGpd>(reg.id());
- return cc()->emit(Inst::kIdMov, mem, r0);
+ return cc()->emit(Inst::kIdMov, stackPtr, r0);
MovGpQ:
- mem.setSize(8);
+ stackPtr.setSize(8);
r0.setRegT<Reg::kTypeGpq>(reg.id());
- return cc()->emit(Inst::kIdMov, mem, r0);
+ return cc()->emit(Inst::kIdMov, stackPtr, r0);
MovMmD:
- mem.setSize(4);
+ stackPtr.setSize(4);
r0.setRegT<Reg::kTypeMm>(reg.id());
- return cc()->emit(choose(Inst::kIdMovd, Inst::kIdVmovd), mem, r0);
+ return cc()->emit(choose(Inst::kIdMovd, Inst::kIdVmovd), stackPtr, r0);
MovMmQ:
- mem.setSize(8);
+ stackPtr.setSize(8);
r0.setRegT<Reg::kTypeMm>(reg.id());
- return cc()->emit(choose(Inst::kIdMovq, Inst::kIdVmovq), mem, r0);
+ return cc()->emit(choose(Inst::kIdMovq, Inst::kIdVmovq), stackPtr, r0);
MovXmmD:
- mem.setSize(4);
+ stackPtr.setSize(4);
r0.setRegT<Reg::kTypeXmm>(reg.id());
- return cc()->emit(choose(Inst::kIdMovss, Inst::kIdVmovss), mem, r0);
+ return cc()->emit(choose(Inst::kIdMovss, Inst::kIdVmovss), stackPtr, r0);
MovXmmQ:
- mem.setSize(8);
+ stackPtr.setSize(8);
r0.setRegT<Reg::kTypeXmm>(reg.id());
- return cc()->emit(choose(Inst::kIdMovlps, Inst::kIdVmovlps), mem, r0);
+ return cc()->emit(choose(Inst::kIdMovlps, Inst::kIdVmovlps), stackPtr, r0);
}
// ============================================================================
@@ -997,8 +1101,8 @@ X86RAPass::~X86RAPass() noexcept {}
// ============================================================================
void X86RAPass::onInit() noexcept {
- uint32_t archId = cc()->archId();
- uint32_t baseRegCount = archId == ArchInfo::kIdX86 ? 8u : 16u;
+ uint32_t arch = cc()->arch();
+ uint32_t baseRegCount = Environment::is32Bit(arch) ? 8u : 16u;
_archRegsInfo = &opData.archRegs;
_archTraits[Reg::kGroupGp] |= RAArchTraits::kHasSwap;
@@ -1117,13 +1221,13 @@ Error X86RAPass::onEmitJump(const Label& label) noexcept {
return cc()->jmp(label);
}
-Error X86RAPass::onEmitPreCall(FuncCallNode* call) noexcept {
- if (call->detail().hasVarArgs()) {
- uint32_t argCount = call->argCount();
- const FuncDetail& fd = call->detail();
+Error X86RAPass::onEmitPreCall(InvokeNode* invokeNode) noexcept {
+ if (invokeNode->detail().hasVarArgs() && cc()->is64Bit()) {
+ uint32_t argCount = invokeNode->argCount();
+ const FuncDetail& fd = invokeNode->detail();
- switch (call->detail().callConv().id()) {
- case CallConv::kIdX86SysV64: {
+ switch (invokeNode->detail().callConv().id()) {
+ case CallConv::kIdX64SystemV: {
// AL register contains the number of arguments passed in XMM register(s).
uint32_t n = 0;
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
@@ -1144,7 +1248,7 @@ Error X86RAPass::onEmitPreCall(FuncCallNode* call) noexcept {
break;
}
- case CallConv::kIdX86Win64: {
+ case CallConv::kIdX64Windows: {
// Each double-precision argument passed in XMM must be also passed in GP.
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
for (uint32_t argHi = 0; argHi <= kFuncArgHi; argHi += kFuncArgHi) {
@@ -1161,6 +1265,9 @@ Error X86RAPass::onEmitPreCall(FuncCallNode* call) noexcept {
}
break;
}
+
+ default:
+ return DebugUtils::errored(kErrorInvalidState);
}
}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h b/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h
index 4fa688b41a3..99093ab69f8 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h
@@ -37,12 +37,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \cond INTERNAL
-//! \defgroup asmjit_x86_ra X86 RA
-//! \ingroup asmjit_x86
-//!
//! \brief X86/X64 register allocation.
-//! \addtogroup asmjit_x86_ra
+//! \addtogroup asmjit_ra
//! \{
// ============================================================================
@@ -106,7 +103,7 @@ public:
Error onEmitSave(uint32_t workId, uint32_t srcPhysId) noexcept override;
Error onEmitJump(const Label& label) noexcept override;
- Error onEmitPreCall(FuncCallNode* node) noexcept override;
+ Error onEmitPreCall(InvokeNode* invokeNode) noexcept override;
};
//! \}