Merge remote-tracking branch 'origin/Ghidra_12.1'

This commit is contained in:
ghidra1
2026-03-23 15:40:39 -04:00
41 changed files with 33990 additions and 0 deletions

View File

@@ -1,7 +1,12 @@
MODULE FILE LICENSE: pypkg/dist/capstone-5.0.6-py3-none-win_amd64.whl BSD-3-CAPSTONE
MODULE FILE LICENSE: pypkg/dist/comtypes-1.4.13-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/pybag-2.2.16-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/pywin32-311-cp39-cp39-win_amd64.whl Python Software Foundation License
MODULE FILE LICENSE: pypkg/dist/pywin32-311-cp310-cp310-win_amd64.whl Python Software Foundation License
MODULE FILE LICENSE: pypkg/dist/pywin32-311-cp311-cp311-win_amd64.whl Python Software Foundation License
MODULE FILE LICENSE: pypkg/dist/pywin32-311-cp312-cp312-win_amd64.whl Python Software Foundation License
MODULE FILE LICENSE: pypkg/dist/pywin32-311-cp313-cp313-win_amd64.whl Python Software Foundation License
MODULE FILE LICENSE: pypkg/dist/pywin32-311-cp314-cp314-win_amd64.whl Python Software Foundation License
MODULE FILE LICENSE: pypkg/dist/win32more-0.7.0-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/win32more_appsdk-0.7.3-py2.py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/win32more_core-0.7.0-py2.py3-none-any.whl MIT

View File

@@ -84,7 +84,12 @@ task prebuildTlb(type: Copy) {
distributePyDep("pybag-2.2.16-py3-none-any.whl")
distributePyDep("capstone-5.0.6-py3-none-win_amd64.whl")
distributePyDep("comtypes-1.4.13-py3-none-any.whl")
distributePyDep("pywin32-311-cp39-cp39-win_amd64.whl")
distributePyDep("pywin32-311-cp310-cp310-win_amd64.whl")
distributePyDep("pywin32-311-cp311-cp311-win_amd64.whl")
distributePyDep("pywin32-311-cp312-cp312-win_amd64.whl")
distributePyDep("pywin32-311-cp313-cp313-win_amd64.whl")
distributePyDep("pywin32-311-cp314-cp314-win_amd64.whl")
distributePyDep("win32more-0.7.0-py3-none-any.whl")
distributePyDep("win32more_appsdk-0.7.3-py2.py3-none-any.whl")
distributePyDep("win32more_core-0.7.0-py2.py3-none-any.whl")

View File

View File

@@ -0,0 +1,35 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
apply plugin: 'eclipse'
eclipse.project.name = 'Processors Hexagon'
dependencies {
api project(":BytePatterns")
api project(":Emulation")
testImplementation project(path: ':SoftwareModeling', configuration: 'testArtifacts')
testImplementation project(path: ':Emulation', configuration: 'testArtifacts')
}
sleighCompileOptions = [
"-l",
"-t"
]

View File

@@ -0,0 +1,16 @@
##VERSION: 2.0
Module.manifest||GHIDRA||||END|
data/languages/Hexagon.opinion||GHIDRA||||END|
data/languages/hexagon.cspec||GHIDRA||||END|
data/languages/hexagon.dwarf||GHIDRA||||END|
data/languages/hexagon.ldefs||GHIDRA||||END|
data/languages/hexagon.pspec||GHIDRA||||END|
data/languages/hexagon.sinc||GHIDRA||||END|
data/languages/hexagon.slaspec||GHIDRA||||END|
data/languages/hexagon_float.sinc||GHIDRA||||END|
data/languages/hexagon_hvx.sinc||GHIDRA||||END|
data/languages/hexagon_hvx.txt||GHIDRA|exclude|||END|
data/languages/hexagon_left.sinc||GHIDRA||||END|
data/languages/hexagon_right.sinc||GHIDRA||||END|
data/patterns/Hexagon_patterns.xml||GHIDRA||||END|
data/patterns/patternconstraints.xml||GHIDRA||||END|

View File

@@ -0,0 +1,5 @@
<opinions>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="164" processor="Hexagon" size="32" />
</constraint>
</opinions>

View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="8" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<char_type signed="false" />
<pointer_size value="4" />
<wchar_size value="4" />
<short_size value="2" />
<integer_size value="4" />
<long_size value="4" />
<long_long_size value="8" />
<float_size value="4" />
<double_size value="8" />
<long_double_size value="8" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
<range space="register" first="0x800" last="0x8ff" /> <!-- Registers: S0-S63 -->
</global>
<stackpointer register="SP" space="ram"/>
<prefersplit style="inhalf">
<register name="R1R0_"/>
<register name="R1R0"/>
<register name="R3R2_"/>
<register name="R3R2"/>
<register name="R5R4_"/>
<register name="R5R4"/>
<register name="R7R6_"/>
<register name="R7R6"/>
<register name="R9R8_"/>
<register name="R9R8"/>
<register name="R11R10_"/>
<register name="R11R10"/>
<register name="R13R12_"/>
<register name="R13R12"/>
<register name="R15R14_"/>
<register name="R15R14"/>
<register name="R17R16_"/>
<register name="R17R16"/>
<register name="R19R18_"/>
<register name="R19R18"/>
<register name="R21R20_"/>
<register name="R21R20"/>
<register name="R23R22_"/>
<register name="R23R22"/>
<register name="R25R24_"/>
<register name="R25R24"/>
</prefersplit>
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="4">
<register name="R0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="R1"/>
</pentry>
<pentry minsize="5" maxsize="8">
<register name="R1R0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="R2"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="R3"/>
</pentry>
<pentry minsize="5" maxsize="8">
<register name="R3R2"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="R4"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="R5"/>
</pentry>
<pentry minsize="5" maxsize="8">
<register name="R5R4"/>
</pentry>
<pentry minsize="1" maxsize="500" align="1"> <!-- unable to stipulate alignment properly - see ABI spec -->
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8">
<register name="R1R0"/>
</pentry>
</output>
<unaffected>
<register name="R16"/>
<register name="R17"/>
<register name="R18"/>
<register name="R19"/>
<register name="R20"/>
<register name="R21"/>
<register name="R22"/>
<register name="R23"/>
<register name="R24"/>
<register name="R25"/>
<register name="R26"/>
<register name="R27"/>
<register name="SP"/>
<register name="FP"/>
<register name="LC0"/>
<register name="LC1"/>
<register name="SA0"/>
<register name="SA1"/>
<register name="P3P0"/>
<register name="M0"/>
<register name="M1"/>
<register name="GP"/>
<register name="UGP"/>
<register name="FP"/>
</unaffected>
</prototype>
</default_proto>
<!-- Injections for various compiler helper functions -->
<callfixup name="prolog_save_regs">
<pcode><body>
<![CDATA[
ptr:4 = 0; # can't handle empty pcode
]]>
</body></pcode>
</callfixup>
<callfixup name="prolog_restore_regs">
<pcode><body>
<![CDATA[
ptr:4 = FP;
FP = *[ram]:4 ptr;
ptr = ptr + 4;
LR = *[ram]:4 ptr;
SP = ptr + 4;
]]>
</body></pcode>
</callfixup>
</compiler_spec>

View File

@@ -0,0 +1,19 @@
<dwarf>
<register_mappings>
<register_mapping dwarf="0" ghidra="R0" auto_count="29"/> <!-- R0..R28 -->
<register_mapping dwarf="29" ghidra="SP" stackpointer="true"/> <!-- R29 -->
<register_mapping dwarf="30" ghidra="FP"/> <!-- R30 -->
<register_mapping dwarf="31" ghidra="LR"/> <!-- R31 -->
<register_mapping dwarf="32" ghidra="GP"/>
<register_mapping dwarf="33" ghidra="UGP"/>
<register_mapping dwarf="34" ghidra="SA0"/>
<register_mapping dwarf="35" ghidra="LC1"/>
<register_mapping dwarf="36" ghidra="M0"/>
<register_mapping dwarf="37" ghidra="M1"/>
<register_mapping dwarf="38" ghidra="P3P0"/>
<register_mapping dwarf="39" ghidra="PC"/>
<!-- <register_mapping dwarf="40" ghidra="CAUSE"/> **not implemented** -->
<!-- <register_mapping dwarf="41" ghidra="BADVA"/> **not implemented** -->
</register_mappings>
<call_frame_cfa value="0"/>
</dwarf>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="Hexagon"
endian="little"
size="32"
variant="default"
version="2.4"
slafile="hexagon.sla"
processorspec="hexagon.pspec"
id="Hexagon:LE:32:default">
<description>Qualcomm Hexagon V69 processor (QDSP6) 32-bit little-endian</description>
<compiler name="default" spec="hexagon.cspec" id="default"/>
<external_name tool="gnu" name="0x18:0x5"/>
<external_name tool="DWARF.register.mapping.file" name="hexagon.dwarf"/>
</language>
</language_definitions>

View File

@@ -0,0 +1,439 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="parallelInstructionHelperClass" value="ghidra.app.util.viewer.field.HexagonParallelInstructionHelper"/>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.HexagonEmulateInstructionStateModifier"/>
<property key="useropLibs" value="hexagon"/>
<property key="resetContextOnUpgrade" value="true" />
</properties>
<programcounter register="PC"/>
<volatile outputop="writeSReg" inputop="readSReg">
<range space="register" first="0x238" last="0x23f"/> <!-- Register: UPCYCLE -->
<range space="register" first="0x800" last="0x8ff"/> <!-- Registers: S0-S63 -->
</volatile>
<context_data>
<context_set space="ram">
<set name="packetOffset" val="0"/>
</context_set>
<tracked_set space="ram">
<set name="USR" val="0"/>
<set name="FRAMEKEY" val="0"/>
</tracked_set>
</context_data>
<register_data>
<register name="R1R0_" group="SHADOW" hidden="true"/>
<register name="R3R2_" group="SHADOW" hidden="true"/>
<register name="R5R4_" group="SHADOW" hidden="true"/>
<register name="R7R6_" group="SHADOW" hidden="true"/>
<register name="R9R8_" group="SHADOW" hidden="true"/>
<register name="R11R10_" group="SHADOW" hidden="true"/>
<register name="R13R12_" group="SHADOW" hidden="true"/>
<register name="R15R14_" group="SHADOW" hidden="true"/>
<register name="R17R16_" group="SHADOW" hidden="true"/>
<register name="R19R18_" group="SHADOW" hidden="true"/>
<register name="R21R20_" group="SHADOW" hidden="true"/>
<register name="R23R22_" group="SHADOW" hidden="true"/>
<register name="R25R24_" group="SHADOW" hidden="true"/>
<register name="R27R26_" group="SHADOW" hidden="true"/>
<register name="R29R28_" group="SHADOW" hidden="true"/>
<register name="R31R30_" group="SHADOW" hidden="true"/>
<register name="R0.new" group="SHADOW" hidden="true"/>
<register name="R1.new" group="SHADOW" hidden="true"/>
<register name="R2.new" group="SHADOW" hidden="true"/>
<register name="R3.new" group="SHADOW" hidden="true"/>
<register name="R4.new" group="SHADOW" hidden="true"/>
<register name="R5.new" group="SHADOW" hidden="true"/>
<register name="R6.new" group="SHADOW" hidden="true"/>
<register name="R7.new" group="SHADOW" hidden="true"/>
<register name="R8.new" group="SHADOW" hidden="true"/>
<register name="R9.new" group="SHADOW" hidden="true"/>
<register name="R10.new" group="SHADOW" hidden="true"/>
<register name="R11.new" group="SHADOW" hidden="true"/>
<register name="R12.new" group="SHADOW" hidden="true"/>
<register name="R13.new" group="SHADOW" hidden="true"/>
<register name="R14.new" group="SHADOW" hidden="true"/>
<register name="R15.new" group="SHADOW" hidden="true"/>
<register name="R16.new" group="SHADOW" hidden="true"/>
<register name="R17.new" group="SHADOW" hidden="true"/>
<register name="R18.new" group="SHADOW" hidden="true"/>
<register name="R19.new" group="SHADOW" hidden="true"/>
<register name="R20.new" group="SHADOW" hidden="true"/>
<register name="R21.new" group="SHADOW" hidden="true"/>
<register name="R22.new" group="SHADOW" hidden="true"/>
<register name="R23.new" group="SHADOW" hidden="true"/>
<register name="R24.new" group="SHADOW" hidden="true"/>
<register name="R25.new" group="SHADOW" hidden="true"/>
<register name="R26.new" group="SHADOW" hidden="true"/>
<register name="R27.new" group="SHADOW" hidden="true"/>
<register name="R28.new" group="SHADOW" hidden="true"/>
<register name="SP.new" group="SHADOW" hidden="true"/>
<register name="FP.new" group="SHADOW" hidden="true"/>
<register name="LR.new" group="SHADOW" hidden="true"/>
<register name="R0.L_" group="SHADOW" hidden="true"/>
<register name="R0.H_" group="SHADOW" hidden="true"/>
<register name="R1.L_" group="SHADOW" hidden="true"/>
<register name="R1.H_" group="SHADOW" hidden="true"/>
<register name="R2.L_" group="SHADOW" hidden="true"/>
<register name="R2.H_" group="SHADOW" hidden="true"/>
<register name="R3.L_" group="SHADOW" hidden="true"/>
<register name="R3.H_" group="SHADOW" hidden="true"/>
<register name="R4.L_" group="SHADOW" hidden="true"/>
<register name="R4.H_" group="SHADOW" hidden="true"/>
<register name="R5.L_" group="SHADOW" hidden="true"/>
<register name="R5.H_" group="SHADOW" hidden="true"/>
<register name="R6.L_" group="SHADOW" hidden="true"/>
<register name="R6.H_" group="SHADOW" hidden="true"/>
<register name="R7.L_" group="SHADOW" hidden="true"/>
<register name="R7.H_" group="SHADOW" hidden="true"/>
<register name="R8.L_" group="SHADOW" hidden="true"/>
<register name="R8.H_" group="SHADOW" hidden="true"/>
<register name="R9.L_" group="SHADOW" hidden="true"/>
<register name="R9.H_" group="SHADOW" hidden="true"/>
<register name="R10.L_" group="SHADOW" hidden="true"/>
<register name="R10.H_" group="SHADOW" hidden="true"/>
<register name="R11.L_" group="SHADOW" hidden="true"/>
<register name="R11.H_" group="SHADOW" hidden="true"/>
<register name="R12.L_" group="SHADOW" hidden="true"/>
<register name="R12.H_" group="SHADOW" hidden="true"/>
<register name="R13.L_" group="SHADOW" hidden="true"/>
<register name="R13.H_" group="SHADOW" hidden="true"/>
<register name="R14.L_" group="SHADOW" hidden="true"/>
<register name="R14.H_" group="SHADOW" hidden="true"/>
<register name="R15.L_" group="SHADOW" hidden="true"/>
<register name="R15.H_" group="SHADOW" hidden="true"/>
<register name="R16.L_" group="SHADOW" hidden="true"/>
<register name="R16.H_" group="SHADOW" hidden="true"/>
<register name="R17.L_" group="SHADOW" hidden="true"/>
<register name="R17.H_" group="SHADOW" hidden="true"/>
<register name="R18.L_" group="SHADOW" hidden="true"/>
<register name="R18.H_" group="SHADOW" hidden="true"/>
<register name="R19.L_" group="SHADOW" hidden="true"/>
<register name="R19.H_" group="SHADOW" hidden="true"/>
<register name="R20.L_" group="SHADOW" hidden="true"/>
<register name="R20.H_" group="SHADOW" hidden="true"/>
<register name="R21.L_" group="SHADOW" hidden="true"/>
<register name="R21.H_" group="SHADOW" hidden="true"/>
<register name="R22.L_" group="SHADOW" hidden="true"/>
<register name="R22.H_" group="SHADOW" hidden="true"/>
<register name="R23.L_" group="SHADOW" hidden="true"/>
<register name="R23.H_" group="SHADOW" hidden="true"/>
<register name="R24.L_" group="SHADOW" hidden="true"/>
<register name="R24.H_" group="SHADOW" hidden="true"/>
<register name="R25.L_" group="SHADOW" hidden="true"/>
<register name="R25.H_" group="SHADOW" hidden="true"/>
<register name="R26.L_" group="SHADOW" hidden="true"/>
<register name="R26.H_" group="SHADOW" hidden="true"/>
<register name="R27.L_" group="SHADOW" hidden="true"/>
<register name="R27.H_" group="SHADOW" hidden="true"/>
<register name="R28.L_" group="SHADOW" hidden="true"/>
<register name="R28.H_" group="SHADOW" hidden="true"/>
<register name="R29.L_" group="SHADOW" hidden="true"/>
<register name="R29.H_" group="SHADOW" hidden="true"/>
<register name="R30.L_" group="SHADOW" hidden="true"/>
<register name="R30.H_" group="SHADOW" hidden="true"/>
<register name="R31.L_" group="SHADOW" hidden="true"/>
<register name="R31.H_" group="SHADOW" hidden="true"/>
<register name="C1C0" group="Control" hidden="true"/>
<register name="C3C2" group="Control" hidden="true"/>
<register name="C5C4" group="Control" hidden="true"/>
<register name="C7C6" group="Control" hidden="true"/>
<register name="C9C8" group="Control" hidden="true"/>
<register name="C11C10" group="Control" hidden="true"/>
<register name="C13C12" group="Control" hidden="true"/>
<register name="UPCYCLE" group="Control"/>
<register name="C17C16" group="Control" hidden="true"/>
<register name="PKTCOUNT" group="Control"/>
<register name="C21C20" group="Control" hidden="true"/>
<register name="C23C22" group="Control" hidden="true"/>
<register name="C25C24" group="Control" hidden="true"/>
<register name="C27C26" group="Control" hidden="true"/>
<register name="C29C28" group="Control" hidden="true"/>
<register name="UTIMER" group="Control"/>
<register name="C1C0_" group="SHADOW" hidden="true"/>
<register name="C3C2_" group="SHADOW" hidden="true"/>
<register name="C5C4_" group="SHADOW" hidden="true"/>
<register name="C7C6_" group="SHADOW" hidden="true"/>
<register name="C9C8_" group="SHADOW" hidden="true"/>
<register name="C11C10_" group="SHADOW" hidden="true"/>
<register name="C13C12_" group="SHADOW" hidden="true"/>
<register name="UPCYCLE_" group="SHADOW" hidden="true"/>
<register name="C17C16_" group="SHADOW" hidden="true"/>
<register name="PKTCOUNT_" group="SHADOW" hidden="true"/>
<register name="C21C20_" group="SHADOW" hidden="true"/>
<register name="C23C22_" group="SHADOW" hidden="true"/>
<register name="C25C24_" group="SHADOW" hidden="true"/>
<register name="C27C26_" group="SHADOW" hidden="true"/>
<register name="C29C28_" group="SHADOW" hidden="true"/>
<register name="UTIMER_" group="SHADOW" hidden="true"/>
<register name="ReturnAddr" group="SHADOW" hidden="true"/>
<register name="SA0" group="Control"/>
<register name="LC0" group="Control"/>
<register name="SA1" group="Control"/>
<register name="LC1" group="Control"/>
<register name="P3P0" group="Control"/>
<register name="C5" group="Control" hidden="true"/>
<register name="M0" group="Control"/>
<register name="M1" group="Control"/>
<register name="USR" group="Control"/>
<register name="PC" group="Control"/>
<register name="UGP" group="Control"/>
<register name="GP" group="Control"/>
<register name="CS0" group="Control"/>
<register name="CS1" group="Control"/>
<register name="UPCYCLELO" group="Control"/>
<register name="UPCYCLEHI" group="Control"/>
<register name="FRAMELIMIT" group="Control"/>
<register name="FRAMEKEY" group="Control"/>
<register name="PKTCOUNTLO" group="Control"/>
<register name="PKTCOUNTHI" group="Control"/>
<register name="C20" group="Control" hidden="true"/>
<register name="C21" group="Control" hidden="true"/>
<register name="C22" group="Control" hidden="true"/>
<register name="C23" group="Control" hidden="true"/>
<register name="C24" group="Control" hidden="true"/>
<register name="C25" group="Control" hidden="true"/>
<register name="C26" group="Control" hidden="true"/>
<register name="C27" group="Control" hidden="true"/>
<register name="C28" group="Control" hidden="true"/>
<register name="C29" group="Control" hidden="true"/>
<register name="UTIMERLO" group="Control"/>
<register name="UTIMERHI" group="Control"/>
<register name="SA0_" group="SHADOW" hidden="true"/>
<register name="LC0_" group="SHADOW" hidden="true"/>
<register name="SA1_" group="SHADOW" hidden="true"/>
<register name="LC1_" group="SHADOW" hidden="true"/>
<register name="P3P0_" group="SHADOW" hidden="true"/>
<register name="M0_" group="SHADOW" hidden="true"/>
<register name="M1_" group="SHADOW" hidden="true"/>
<register name="USR_" group="SHADOW" hidden="true"/>
<register name="PC_" group="SHADOW" hidden="true"/>
<register name="UGP_" group="SHADOW" hidden="true"/>
<register name="GP_" group="SHADOW" hidden="true"/>
<register name="CS0_" group="SHADOW" hidden="true"/>
<register name="CS1_" group="SHADOW" hidden="true"/>
<register name="UPCYCLELO_" group="SHADOW" hidden="true"/>
<register name="UPCYCLEHI_" group="SHADOW" hidden="true"/>
<register name="FRAMELIMIT_" group="SHADOW" hidden="true"/>
<register name="FRAMEKEY_" group="SHADOW" hidden="true"/>
<register name="PKTCOUNTLO_" group="SHADOW" hidden="true"/>
<register name="PKTCOUNTHI_" group="SHADOW" hidden="true"/>
<register name="C20_" group="SHADOW" hidden="true"/>
<register name="C21_" group="SHADOW" hidden="true"/>
<register name="C22_" group="SHADOW" hidden="true"/>
<register name="C23_" group="SHADOW" hidden="true"/>
<register name="C24_" group="SHADOW" hidden="true"/>
<register name="C25_" group="SHADOW" hidden="true"/>
<register name="C26_" group="SHADOW" hidden="true"/>
<register name="C27_" group="SHADOW" hidden="true"/>
<register name="C28_" group="SHADOW" hidden="true"/>
<register name="C29_" group="SHADOW" hidden="true"/>
<register name="UTIMERLO_" group="SHADOW" hidden="true"/>
<register name="UTIMERHI_" group="SHADOW" hidden="true"/>
<register name="P3.new" group="SHADOW" hidden="true"/>
<register name="P2.new" group="SHADOW" hidden="true"/>
<register name="P1.new" group="SHADOW" hidden="true"/>
<register name="P0.new" group="SHADOW" hidden="true"/>
<register name="G1G0" group="Guest" hidden="true"/>
<register name="G3G2" group="Guest" hidden="true"/>
<register name="G5G4" group="Guest" hidden="true"/>
<register name="G7G6" group="Guest" hidden="true"/>
<register name="G9G8" group="Guest" hidden="true"/>
<register name="G11G10" group="Guest" hidden="true"/>
<register name="G13G12" group="Guest" hidden="true"/>
<register name="G15G14" group="Guest" hidden="true"/>
<register name="G17G16" group="Guest" hidden="true"/>
<register name="G19G18" group="Guest" hidden="true"/>
<register name="G21G20" group="Guest" hidden="true"/>
<register name="G23G22" group="Guest" hidden="true"/>
<register name="G25G24" group="Guest" hidden="true"/>
<register name="G27G26" group="Guest" hidden="true"/>
<register name="G29G28" group="Guest" hidden="true"/>
<register name="G31G30" group="Guest" hidden="true"/>
<register name="G0" group="Guest"/>
<register name="G1" group="Guest"/>
<register name="G2" group="Guest"/>
<register name="G3" group="Guest"/>
<register name="G4" group="Guest" hidden="true"/>
<register name="G5" group="Guest" hidden="true"/>
<register name="G6" group="Guest" hidden="true"/>
<register name="G7" group="Guest" hidden="true"/>
<register name="G8" group="Guest" hidden="true"/>
<register name="G9" group="Guest" hidden="true"/>
<register name="G10" group="Guest" hidden="true"/>
<register name="G11" group="Guest" hidden="true"/>
<register name="G12" group="Guest" hidden="true"/>
<register name="G13" group="Guest" hidden="true"/>
<register name="G14" group="Guest" hidden="true"/>
<register name="G15" group="Guest" hidden="true"/>
<!-- naming of G16-G19 inconsistent between LLVM and V62 ref manual -->
<register name="G16" rename="GPMUCNT4" group="Guest"/>
<register name="G17" rename="GPMUCNT5" group="Guest"/>
<register name="G18" rename="GPMUCNT6" group="Guest"/>
<register name="G19" rename="GPMUCNT7" group="Guest"/>
<register name="G20" group="Guest" hidden="true"/>
<register name="G21" group="Guest" hidden="true"/>
<register name="G22" group="Guest" hidden="true"/>
<register name="G23" group="Guest" hidden="true"/>
<register name="G24" rename="GPCYCLELO" group="Guest"/>
<register name="G25" rename="GPCYCLEHI" group="Guest"/>
<register name="G26" rename="GPMUCNT0" group="Guest"/>
<register name="G27" rename="GPMUCNT1" group="Guest"/>
<register name="G28" rename="GPMUCNT2" group="Guest"/>
<register name="G29" rename="GPMUCNT3" group="Guest"/>
<register name="G30" group="Guest" hidden="true"/>
<register name="G31" group="Guest" hidden="true"/>
<register name="S1S0" group="Supervisor" hidden="true"/>
<register name="S3S2" group="Supervisor" hidden="true"/>
<register name="S5S4" group="Supervisor" hidden="true"/>
<register name="S7S6" group="Supervisor" hidden="true"/>
<register name="S9S8" group="Supervisor" hidden="true"/>
<register name="S11S10" group="Supervisor" hidden="true"/>
<register name="S13S12" group="Supervisor" hidden="true"/>
<register name="S15S14" group="Supervisor" hidden="true"/>
<register name="S17S16" group="Supervisor" hidden="true"/>
<register name="S19S18" group="Supervisor" hidden="true"/>
<register name="S21S20" group="Supervisor" hidden="true"/>
<register name="S23S22" group="Supervisor" hidden="true"/>
<register name="S25S24" group="Supervisor" hidden="true"/>
<register name="S27S26" group="Supervisor" hidden="true"/>
<register name="S29S28" group="Supervisor" hidden="true"/>
<register name="S31S30" group="Supervisor" hidden="true"/>
<register name="S33S32" group="Supervisor" hidden="true"/>
<register name="S35S34" group="Supervisor" hidden="true"/>
<register name="S37S36" group="Supervisor" hidden="true"/>
<register name="S39S38" group="Supervisor" hidden="true"/>
<register name="S41S40" group="Supervisor" hidden="true"/>
<register name="S43S42" group="Supervisor" hidden="true"/>
<register name="S45S44" group="Supervisor" hidden="true"/>
<register name="S47S46" group="Supervisor" hidden="true"/>
<register name="S49S48" group="Supervisor" hidden="true"/>
<register name="S51S50" group="Supervisor" hidden="true"/>
<register name="S53S52" group="Supervisor" hidden="true"/>
<register name="S55S54" group="Supervisor" hidden="true"/>
<register name="S57S56" group="Supervisor" hidden="true"/>
<register name="S59S58" group="Supervisor" hidden="true"/>
<register name="S61S60" group="Supervisor" hidden="true"/>
<register name="S63S62" group="Supervisor" hidden="true"/>
<register name="S0" rename="SGP0" group="Supervisor"/>
<register name="S1" rename="SGP1" group="Supervisor"/>
<register name="S2" rename="STID" group="Supervisor"/>
<register name="S3" rename="ELR" group="Supervisor"/>
<register name="S4" rename="BADVA0" group="Supervisor"/>
<register name="S5" rename="BADVA1" group="Supervisor"/>
<register name="S6" rename="SSR" group="Supervisor"/>
<register name="S7" rename="CCR" group="Supervisor"/>
<register name="S8" rename="HTID" group="Supervisor"/>
<register name="S9" rename="BADVA" group="Supervisor"/>
<register name="S10" rename="IMASK" group="Supervisor"/>
<register name="S11" group="Supervisor" hidden="true"/>
<register name="S12" group="Supervisor" hidden="true"/>
<register name="S13" group="Supervisor" hidden="true"/>
<register name="S14" group="Supervisor" hidden="true"/>
<register name="S15" group="Supervisor" hidden="true"/>
<register name="S16" rename="EVB" group="Supervisor"/>
<register name="S17" rename="MODECTL" group="Supervisor"/>
<register name="S18" rename="SYSCFG" group="Supervisor"/>
<register name="S19" group="Supervisor"/>
<register name="S20" rename="IPEND" group="Supervisor"/>
<register name="S21" rename="VID" group="Supervisor"/>
<register name="S22" rename="IAD" group="Supervisor"/>
<register name="S23" group="Supervisor"/>
<register name="S24" rename="IEL" group="Supervisor"/>
<register name="S25" group="Supervisor"/>
<register name="S26" rename="IAHL" group="Supervisor"/>
<register name="S27" rename="CFGBASE" group="Supervisor"/>
<register name="S28" rename="DIAG" group="Supervisor"/>
<register name="S29" rename="REV" group="Supervisor"/>
<register name="S30" rename="PCYCLELO" group="Supervisor"/>
<register name="S31" rename="PCYCLEHI" group="Supervisor"/>
<register name="S32" rename="ISDBST" group="Supervisor"/>
<register name="S33" rename="ISDBCFG0" group="Supervisor"/>
<register name="S34" rename="ISDBCFG1" group="Supervisor"/>
<register name="S35" group="Supervisor" hidden="true"/>
<register name="S36" rename="BRKPTPC0" group="Supervisor"/>
<register name="S37" rename="BRKPTCFG0" group="Supervisor"/>
<register name="S38" rename="BRKPTPC1" group="Supervisor"/>
<register name="S39" rename="BRKPTCFG1" group="Supervisor"/>
<register name="S40" rename="ISDBMBXIN" group="Supervisor"/>
<register name="S41" rename="ISDBMBXOUT" group="Supervisor"/>
<register name="S42" rename="ISDBEN" group="Supervisor"/>
<register name="S43" rename="ISDBGPR" group="Supervisor"/>
<register name="S44" group="Supervisor" hidden="true"/>
<register name="S45" group="Supervisor"/>
<register name="S46" group="Supervisor" hidden="true"/>
<register name="S47" group="Supervisor" hidden="true"/>
<register name="S48" rename="PMUCNT0" group="Supervisor"/>
<register name="S49" rename="PMUCNT1" group="Supervisor"/>
<register name="S50" rename="PMUCNT2" group="Supervisor"/>
<register name="S51" rename="PMUCNT3" group="Supervisor"/>
<register name="S52" rename="PMUEVTCFG" group="Supervisor"/>
<register name="S53" rename="PMUCFG" group="Supervisor"/>
<register name="S54" group="Supervisor" hidden="true"/>
<register name="S55" group="Supervisor" hidden="true"/>
<register name="S56" group="Supervisor" hidden="true"/>
<register name="S57" group="Supervisor" hidden="true"/>
<register name="S58" group="Supervisor" hidden="true"/>
<register name="S59" group="Supervisor" hidden="true"/>
<register name="S60" group="Supervisor" hidden="true"/>
<!-- uncertain where the naming of S61-S63 originated -->
<register name="S61" rename="ACC0" group="Supervisor"/>
<register name="S62" rename="ACC1" group="Supervisor"/>
<register name="S63" rename="CHICKEN" group="Supervisor"/>
<!-- HVX Vector Registers - Lane sizes .b .h .w -->
<register name="V1V0" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V3V2" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V5V4" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V7V6" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V9V8" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V11V10" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V13V12" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V15V14" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V17V16" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V19V18" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V21V20" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V23V22" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V25V24" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V27V26" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V29V28" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V31V30" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V1V0_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V3V2_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V5V4_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V7V6_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V9V8_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V11V10_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V13V12_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V15V14_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V17V16_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V19V18_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V21V20_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V23V22_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V25V24_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V27V26_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V29V28_" group="SVE" vector_lane_sizes="1,2,4"/>
<register name="V31V30_" group="SVE" vector_lane_sizes="1,2,4"/>
</register_data>
</processor_spec>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,888 @@
# Qualcomm Hexagon (V73) and HVX (V69)
## KNOWN ISSUES
# 1. Shift amounts may be positive or negative, however in some cases no special handling
# is provided for negative shift amounts.
# 2. There are many complex instructions with unimplemented pcode or simple custom pcodeops
#
## NOTES
# 1. Implementation includes V73 system registers, instruction set may be incomplete
# 2. HVX vector register size is 128-bytes (see defines below), paired size is 256-bytes
#
## VERSIONS
# 1.x - preliminary versions (pre-release)
# 2.0 - initial release
# 2.1 - added support for conditional commit of modifying operands, e.g. (r0++#4) (r0=#4)
# 2.2 - TBD (research change history)
# 2.3 - Added missing instructions and corrected invalid DF instructions. The disabled
# ADD_DP_OPS property has been used to contain these although they may be removed
# in the future.
# 2.4 - Added EXEC_COND crossbuild (12.0.1) and added HVX support (12.0.2)
#
@define HVX_VECTOR_SIZE "128"
@define HVX_VECTOR_PAIR_SIZE "256"
@define HVX_VECTOR_BASE "0x2000"
@define HVX_VECTOR_TMP_BASE "0x3000"
@define HVX_PREDICATE_SIZE "16"
define endian=little;
define alignment=4;
define space ram type=ram_space size=4 default;
define space register type=register_space size=4;
# General purpose registers
# Register aliases have been used for R29(SP), R30(FP) and R31(LR)
define register offset=0 size=8 [ R1R0 R3R2 R5R4 R7R6 R9R8 R11R10 R13R12 R15R14
R17R16 R19R18 R21R20 R23R22 R25R24 R27R26 R29R28 R31R30 ];
define register offset=0 size=4 [ R0 R1 R2 R3 R4 R5 R6 R7
R8 R9 R10 R11 R12 R13 R14 R15
R16 R17 R18 R19 R20 R21 R22 R23
R24 R25 R26 R27 R28 SP FP LR ];
define register offset=0 size=2 [ R0.L R0.H R1.L R1.H R2.L R2.H R3.L R3.H
R4.L R4.H R5.L R5.H R6.L R6.H R7.L R7.H
R8.L R8.H R9.L R9.H R10.L R10.H R11.L R11.H
R12.L R12.H R13.L R13.H R14.L R14.H R15.L R15.H
R16.L R16.H R17.L R17.H R18.L R18.H R19.L R19.H
R20.L R20.H R21.L R21.H R22.L R22.H R23.L R23.H
R24.L R24.H R25.L R25.H R26.L R26.H R27.L R27.H
R28.L R28.H R29.L R29.H R30.L R30.H R31.L R31.H ];
# General purpose shadow registers (used to delay register writes until end of instruction packet)
define register offset=0x100 size=8 [ R1R0_ R3R2_ R5R4_ R7R6_ R9R8_ R11R10_ R13R12_ R15R14_
R17R16_ R19R18_ R21R20_ R23R22_ R25R24_ R27R26_ R29R28_ R31R30_ ];
define register offset=0x100 size=4 [ R0.new R1.new R2.new R3.new R4.new R5.new R6.new R7.new
R8.new R9.new R10.new R11.new R12.new R13.new R14.new R15.new
R16.new R17.new R18.new R19.new R20.new R21.new R22.new R23.new
R24.new R25.new R26.new R27.new R28.new SP.new FP.new LR.new ];
define register offset=0x100 size=2 [ R0.L_ R0.H_ R1.L_ R1.H_ R2.L_ R2.H_ R3.L_ R3.H_
R4.L_ R4.H_ R5.L_ R5.H_ R6.L_ R6.H_ R7.L_ R7.H_
R8.L_ R8.H_ R9.L_ R9.H_ R10.L_ R10.H_ R11.L_ R11.H_
R12.L_ R12.H_ R13.L_ R13.H_ R14.L_ R14.H_ R15.L_ R15.H_
R16.L_ R16.H_ R17.L_ R17.H_ R18.L_ R18.H_ R19.L_ R19.H_
R20.L_ R20.H_ R21.L_ R21.H_ R22.L_ R22.H_ R23.L_ R23.H_
R24.L_ R24.H_ R25.L_ R25.H_ R26.L_ R26.H_ R27.L_ R27.H_
R28.L_ R28.H_ R29.L_ R29.H_ R30.L_ R30.H_ R31.L_ R31.H_ ];
# Control registers (range C16-C31 not defined by V5/V55)
# TODO: Check Control register naming across versions - with only one variant not sure how we handle this
define register offset=0x200 size=8 [ C1C0 C3C2 C5C4 C7C6 C9C8 C11C10 C13C12 UPCYCLE
C17C16 PKTCOUNT C21C20 C23C22 C25C24 C27C26 C29C28 UTIMER ];
define register offset=0x200 size=4 [ SA0 LC0 SA1 LC1 P3P0 C5 M0 M1
USR PC UGP GP CS0 CS1 UPCYCLELO UPCYCLEHI
FRAMELIMIT FRAMEKEY PKTCOUNTLO PKTCOUNTHI C20 C21 C22 C23
C24 C25 C26 C27 C28 C29 UTIMERLO UTIMERHI ];
define register offset=0x210 size=1 [ P3 P2 P1 P0 ]; # corresponds to P3P0
# TODO: Do ALL of the control registers need shadows for writing/flushing ??
define register offset=0x300 size=8 [ C1C0_ C3C2_ C5C4_ C7C6_ C9C8_ C11C10_ C13C12_ UPCYCLE_
C17C16_ PKTCOUNT_ C21C20_ C23C22_ C25C24_ C27C26_ C29C28_ UTIMER_ ];
define register offset=0x300 size=4 [ SA0_ LC0_ SA1_ LC1_ P3P0_ C5_ M0_ M1_
USR_ PC_ UGP_ GP_ CS0_ CS1_ UPCYCLELO_ UPCYCLEHI_
FRAMELIMIT_ FRAMEKEY_ PKTCOUNTLO_ PKTCOUNTHI_ C20_ C21_ C22_ C23_
C24_ C25_ C26_ C27_ C28_ C29_ UTIMERLO_ UTIMERHI_ ]; # shadow versions
define register offset=0x310 size=1 [ P3.new P2.new P1.new P0.new ]; # new/shadow versions, corresponds to P3P0_
# Guest Registers (see pspec for renaming)
# TODO: Do all guest registers need shadows for writing/flushing ??
define register offset=0x400 size=8 [ G1G0 G3G2 G5G4 G7G6 G9G8 G11G10 G13G12 G15G14
G17G16 G19G18 G21G20 G23G22 G25G24 G27G26 G29G28 G31G30 ];
define register offset=0x400 size=4 [ G0 G1 G2 G3 G4 G5 G6 G7 G8 G9 G10 G11 G12 G13 G14 G15
G16 G17 G18 G19 G20 G21 G22 G23 G24 G25 G26 G27 G28 G29 G30 G31 ];
# System Registers (see pspec for renaming)
# TODO: Do all system registers need shadows for writing/flushing ??
define register offset=0x800 size=8 [ S1S0 S3S2 S5S4 S7S6 S9S8 S11S10 S13S12 S15S14
S17S16 S19S18 S21S20 S23S22 S25S24 S27S26 S29S28 S31S30
S33S32 S35S34 S37S36 S39S38 S41S40 S43S42 S45S44 S47S46
S49S48 S51S50 S53S52 S55S54 S57S56 S59S58 S61S60 S63S62 ];
define register offset=0x800 size=4 [ S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15
S16 S17 S18 S19 S20 S21 S22 S23 S24 S25 S26 S27 S28 S29 S30 S31
S32 S33 S34 S35 S36 S37 S38 S39 S40 S41 S42 S43 S44 S45 S46 S47
S48 S49 S50 S51 S52 S53 S54 S55 S56 S57 S58 S59 S60 S61 S62 S63 ];
# System register mappings (may differ with version)
@define ELR "S3"
@define SSR "S6"
@define CAUSE "S6[0,8]" # SSR bits 0..7, Exception/Trap Cause
# Hidden language registers
# ConditionReg: The condition register set by various
# conditional subconstructors which should be built within the
# appropriate <<COMMIT_COND>> or <<FLOW>> pcode section for an instruction
# immediately before using the ConditionReg value.
#
# WARNING! This may present a limitation if multiple condition/predicate
# registers are utilized within a single execute packet.
#
# <<COMMIT_COND>>
# build PuCondXYZ;
# if (ConditionReg == 0) goto <nocommit>;
# rd5 = rd5_;
# <nocommit>
define register offset=0x1000 size=1 [ ConditionReg ];
# ReturnAddr: This register is updated with inst_next for use within the <<FLOW>> section
# to facilitate LR assignment prior to a CALL flow.
define register offset=0x1004 size=4 [ ReturnAddr ];
define register offset=$(HVX_VECTOR_BASE) size=$(HVX_VECTOR_PAIR_SIZE)
[ V1V0 V3V2 V5V4 V7V6 V9V8 V11V10 V13V12 V15V14
V17V16 V19V18 V21V20 V23V22 V25V24 V27V26 V29V28 V31V30 ];
define register offset=$(HVX_VECTOR_BASE) size=$(HVX_VECTOR_SIZE)
[ V0 V1 V2 V3 V4 V5 V6 V7
V8 V9 V10 V11 V12 V13 V14 V15
V16 V17 V18 V19 V20 V21 V22 V23
V24 V25 V26 V27 V28 V29 V30 V31 ];
#
# HVX vector temporary / shadow registers
#
define register offset=$(HVX_VECTOR_TMP_BASE) size=$(HVX_VECTOR_PAIR_SIZE)
[ V1V0_ V3V2_ V5V4_ V7V6_ V9V8_ V11V10_ V13V12_ V15V14_
V17V16_ V19V18_ V21V20_ V23V22_ V25V24_ V27V26_ V29V28_ V31V30_ ];
define register offset=$(HVX_VECTOR_TMP_BASE) size=$(HVX_VECTOR_SIZE)
[ V0.new V1.new V2.new V3.new V4.new V5.new V6.new V7.new
V8.new V9.new V10.new V11.new V12.new V13.new V14.new V15.new
V16.new V17.new V18.new V19.new V20.new V21.new V22.new V23.new
V24.new V25.new V26.new V27.new V28.new V29.new V30.new V31.new ];
#
# HVX Predicate Registers (four predicate registers, each having 1-bit per byte of a vector register)
#
define register offset=0x4000 size=$(HVX_PREDICATE_SIZE) [ Q0 Q1 Q2 Q3 ];
#
# Define context bits
#
define register offset=0x5000 size=12 contextreg;
define context contextreg
# Stored context bits
immext = (0,25) noflow # unshifted extended immediate value (26-bits << 6)
simmext = (0,25) signed noflow # unshifted extended immediate value (26-bits << 6)
immexted = (26,26) noflow # flag indicating previous instr was immext
packetOffset = (27,28) noflow # instruction number within packet (distance from start of packet)
# The packetOffset is set prior to the actual instruction decode phase
packetOffset0 = (28,28) noflow # packetOffset bit-0 (lsb)
packetOffset1 = (27,27) noflow # packetOffset bit-1 (msb)
useLoopCfg = (29,29) noflow # indicates body of h/w loop where LPCFG!=0
unused1 = (30,31) # Required to prevent field split across 32-bit integer boundary
# NOTE: bulk packetBits used to simplify context propogation
packetBits = (32,63) noflow # allows bulk propagation (part 1 of 2)
#--- start of auto-propogated packetBits (all sub-fields must be noflow) ---
parse1 = (32,33) noflow #(keep) parse value for first instruction in packet (used for end of loop detection)
parse2 = (34,35) noflow #(keep) parse value for second instruction in packet (used for end of loop detection)
# Ns8 / Os8 new register operand tracking
nreg0 = (36,40) noflow #(keep) slot-0 assigned reg (raw reg-number)
nreg1 = (41,45) noflow #(keep) slot-1 assigned reg (raw reg-number)
nreg2 = (46,50) noflow #(keep) slot-2 assigned reg (raw reg-number)
removed1 = (51,55) noflow # no longer used - available for reuse
# xreg - tracks immext use required for Ns8 and Os8 new register tracking
xreg = (56,60) noflow #(keep) slot reduction count when identifying nreg assignment slot
unused2 = (61,63) noflow # Required to prevent field split across 32-bit integer boundary
#--- end of auto-propogated packetBits ---
# Transient context bits
phase = (64,66) #(keep) 3-bit instruction parse phase (used by :^instruction)
# (keep) Localized transient context bits which may utilize overlapping regions in some controlled cases
tmpCtx3 = (67,69) # Temporary 3-bit context storage
tmpCtx2 = (67,68) # Temporary 2-bit context storage
nregSlot = (67,68) # computed nreg/vnreg slot derived from upper 2-bits of 3-bit Ns8 or Os8 encoding
shift = (67,68) # memory address shift factor (0-3)
# Ns8 and Os8 .new register decode assist
nregr = (69,73) # computed new register 5-bit index (raw reg-number)
nreg = (69,73) # computed new scalar register (attached) - R0..R31
nreg_ = (69,73) # computed new scalar shadow register (attached) - R0_..R31_
vnreg = (69,73) # computed new vector register (attached) - V0..V31
vnreg_ = (69,73) # computed new vector shadow register (attached) - V0_..V31_
cond = (74,74) # set if instruction is conditional with complex operand and ConditionReg will be set
# (not used by packed instructions)
unused3 = (75,95)
;
# USR Register Fields
@define LPCFG "USR[8,2]"
@define LPCFG_ "USR_[8,2]"
@define OVF "USR[0,1]"
@define OVF_ "USR_[0,1]"
# Tokens
define token instr (32)
iclass = (28,31) # instruction class (see page 118)
iclass3031 = (30,31)
iclass2931 = (29,31)
iclass2829 = (28,29)
iclass31 = (31,31)
iclass30 = (30,30)
iclass29 = (29,29)
iclass28 = (28,28)
parse = (14,15) # packet/loop bits (01/10-not end of packet, 11-end of packet, 00-EE instruction)
parse_0 = (14,14)
parse_1 = (15,15)
op2627 = (26,27)
op2527 = (25,27)
op2427 = (24,27)
op2426 = (24,26)
op2327 = (23,27)
op2326 = (23,26)
op2324 = (23,24)
op2227 = (22,27)
op2224 = (22,24)
op2223 = (22,23)
op2127 = (21,27)
op2125 = (21,25)
op2124 = (21,24)
op2123 = (21,23)
op2122 = (21,22)
op1920 = (19,20)
op1820 = (18,20)
op1827 = (18,27)
op1720 = (17,20)
op1620 = (16,20)
op1617 = (16,17)
op1213 = (12,13)
op1113 = (11,13)
op1112 = (11,12)
op1013 = (10,13)
op1012 = (10,12)
op1011 = (10,11)
op0913 = (9,13)
op0912 = (9,12)
op0911 = (9,11)
op0910 = (9,10)
op0813 = (8,13)
op0812 = (8,12)
op0810 = (8,10)
op0809 = (8,9)
op0613 = (6,13)
op0612 = (6,12)
op0607 = (6,7)
op0513 = (5,13)
op0512 = (5,12)
op0508 = (5,8)
op0507 = (5,7)
op0506 = (5,6)
op0412 = (4,12)
op0306 = (3,6)
op0304 = (3,4)
op0213 = (2,13)
op0207 = (2,7)
op0205 = (2,5)
op0204 = (2,4)
op0013 = (0,13)
op0007 = (0,7)
op0004 = (0,4)
op0002 = (0,2)
op0001 = (0,1)
op27 = (27,27)
op26 = (26,26)
op25 = (25,25)
op24 = (24,24)
op23 = (23,23)
op22 = (22,22)
op21 = (21,21)
op20 = (20,20)
op19 = (19,19)
op18 = (18,18)
op16 = (16,16)
op13 = (13,13)
op12 = (12,12)
op11 = (11,11)
op10 = (10,10)
op8 = (8,8)
op7 = (7,7)
op6 = (6,6)
op5 = (5,5)
op4 = (4,4)
op3 = (3,3)
op2 = (2,2)
op1 = (1,1)
op0 = (0,0)
s2526 = (25,26) signed
s2223 = (22,23) signed
s22 = (22,22) signed
s2127 = (21,27) signed
s2122 = (21,22) signed
s21 = (21,21) signed
s2026 = (20,26) signed
s2021 = (20,21) signed
s1924 = (19,24) signed
s1624 = (16,24) signed
s1622 = (16,22) signed
s1620 = (16,20) signed
s1619 = (16,19) signed
s13 = (13,13) signed
s0813 = (8,13) signed
s0812 = (8,12) signed
s0810 = (8,10) signed
s0712 = (7,12) signed
s0513 = (5,13) signed
s0512 = (5,12) signed
s0508 = (5,8) signed
s0410 = (4,10) signed
s0308 = (3,8) signed
s0306 = (3,6) signed
i2526 = (25,26)
i2427 = (24,27)
i2426 = (24,26)
i24 = (24,24)
i2223 = (22,23)
i2127 = (21,27)
i2123 = (21,23)
i2122 = (21,22)
i2025 = (20,25)
i2024 = (20,24)
i1923 = (19,23)
i1627 = (16,27)
i1620 = (16,20)
i1619 = (16,19)
i1617 = (16,17)
i13 = (13,13)
i1213 = (12,13)
i9 = (9,9)
i0813 = (8,13)
i0812 = (8,12)
i0811 = (8,11)
i0810 = (8,10)
i8 = (8,8)
i0712 = (7,12)
i0513 = (5,13)
i0512 = (5,12)
i0511 = (5,11)
i0510 = (5,10)
i0509 = (5,9)
i0507 = (5,7)
i0506 = (5,6)
i5 = (5,5)
i0409 = (4,9)
i0408 = (4,8)
i0307 = (3,7)
i0306 = (3,6)
i0304 = (3,4)
i3 = (3,3)
i0204 = (2,4)
i0113 = (1,13)
i0111 = (1,11)
i0107 = (1,7)
i1 = (1,1)
i0013 = (0,13)
i0010 = (0,10)
i0007 = (0,7)
i0006 = (0,6)
i0005 = (0,5)
i0004 = (0,4)
i0003 = (0,3)
i0001 = (0,1)
pu2324 = (23,24) # 8-bit predicate reg
pu2122 = (21,22) # 8-bit predicate reg
pu2122_ = (21,22) # 8-bit predicate reg (shadow)
pu2122name = (21,22) # 8-bit predicate reg (name)
pu1617 = (16,17) # 8-bit predicate reg
pu1112 = (11,12) # 8-bit predicate reg
pu1112_ = (11,12) # 8-bit predicate reg (shadow)
pu1112name = (11,12) # 8-bit predicate reg (name)
pu0910 = (9,10) # 8-bit predicate reg
pu0910_ = (9,10) # 8-bit predicate reg (shadow)
pu0910name = (9,10) # 8-bit predicate reg (name)
pu0809 = (8,9) # 8-bit predicate reg
pu0809_ = (8,9) # 8-bit predicate reg (shadow)
pu0809name = (8,9) # 8-bit predicate reg (name)
pu0607 = (6,7) # 8-bit predicate reg
pu0506 = (5,6) # 8-bit predicate reg
pu0506_ = (5,6) # 8-bit predicate reg (shadow)
pu0506name = (5,6) # 8-bit predicate reg (name)
pu0001 = (0,1) # 8-bit predicate reg
pu0001_ = (0,1) # 8-bit predicate reg (shadow)
pu0001name = (0,1) # 8-bit predicate reg (name)
pu25 = (25,25) # P0/P1
pu25_ = (25,25) # P0.new/P1.new
pu25name = (25,25) # P0/P1 (name)
pu12 = (12,12) # P0/P1
pu12_ = (12,12) # P0.new/P1.new
pu12name = (12,12) # P0/P1 (name)
qv0001 = (0,1) # HVX Vector predicate reg (Q0..Q3)
qv0506 = (5,6) # HVX Vector predicate reg (Q0..Q3)
qv0809 = (8,9) # HVX Vector predicate reg (Q0..Q3)
qv1112 = (11,12) # HVX Vector predicate reg (Q0..Q3)
qv2223 = (22,23) # HVX Vector predicate reg (Q0..Q3)
mu = (13,13) # M0/M1 reg
cs5 = (16,20) # 32-bit control reg
css5 = (16,20) # dual 32-bit control reg
gs5 = (16,20) # 32-bit guest reg
gss5 = (16,20) # dual 32-bit guest reg
rs5 = (16,20) # 32-bit general reg
rs5H = (16,20) # 16-bit general reg (high halfword)
rs5L = (16,20) # 16-bit general reg (low halfword)
rss5 = (16,20) # 64-bit general reg
rss5h = (16,20) # 32-bit high reg for rss5
rxx5 = (16,20) # 64-bit general reg
rxx5_ = (16,20) # 64-bit general reg (shadow)
rx5 = (16,20) # 32-bit general reg
rx5_ = (16,20) # 32-bit general reg (shadow)
rf5 = (16,20) # 32-bit general reg
rf5_ = (16,20) # 32-bit general reg (shadow)
rx5H = (16,20) # 16-bit general reg (high halfword)
rx5H_ = (16,20) # 16-bit general reg (high halfword, shadow)
rx5L = (16,20) # 16-bit general reg (low halfword)
rx5L_ = (16,20) # 16-bit general reg (low halfword, shadow)
rtt5 = (8,12) # 64-bit general reg
rtt5h = (8,12) # 32-bit high reg for rtt5
rt5 = (8,12) # 32-bit general reg
rt5H = (8,12) # 16-bit general reg (high halfword)
rt5L = (8,12) # 16-bit general reg (low halfword)
rd0812 = (8,12) # 32-bit general reg
rd0812_ = (8,12) # 32-bit general reg (shadow)
rdd0812 = (8,12) # 64-bit general reg
rdd0812_ = (8,12) # 64-bit general reg (shadow)
rd5 = (0,4) # 32-bit general reg
rd5_ = (0,4) # 32-bit general reg (shadow)
rdd5 = (0,4) # 64-bit general reg
rdd5_ = (0,4) # 64-bit general reg (shadow)
rdd5h = (0,4) # hi (odd) 32-bit reg of a 64-bit general reg (use rd5 for lo/even)
rdd5h_ = (0,4) # hi (odd) 32-bit reg of a 64-bit general reg (use rd5 for lo/even) (shadow)
rt1618 = (16,18) # 32-bit general reg (r0..r7)
cd5 = (0,4) # 32-bit control reg
cd5_ = (0,4) # 32-bit control reg (shadow)
cdd5 = (0,4) # dual 32-bit control reg
cdd5_ = (0,4) # dual 32-bit control reg (shadow)
gd5 = (0,4) # 32-bit guest reg
gdd5 = (0,4) # dual 32-bit guest regs
ru5 = (0,4) # 32-bit control reg
ruu5 = (0,4) # 64-bit general reg
ru5H = (0,4) # 16-bit general reg (high halfword)
ru5L = (0,4) # 16-bit general reg (low halfword)
vdd5 = (0,4) # HVX vector register pair
vdd5_ = (0,4) # HVX vector register pair (shadow)
vss5 = (0,4) # HVX vector register pair
vuu5 = (8,12) # HVX vector register pair
# vuu5_ = (8,12) # HVX vector register pair (shadow)
vvv5 = (16,20) # HVX vector register pair
# vvv5_ = (16,20) # HVX vector register pair (shadow)
vd5 = (0,4) # HVX vector register
vd5_ = (0,4) # HVX vector register (shadow)
vs5 = (0,4) # HVX vector register
# vs5_ = (0,4) # HVX vector register (shadow)
vu5 = (8,12) # HVX vector register
# vu5_ = (8,12) # HVX vector register (shadow)
vv5 = (16,20) # HVX vector register
# vv5_ = (16,20) # HVX vector register (shadow)
vz5 = (19,23) # HVX vector register
# vz5_ = (19,23) # HVX vector register (shadow)
nreg_1618 = (16,18) # Ns8 32-bit general register .new (3-bit encoded)
nreg_0810 = (8,10) # Ns8 32-bit general register .new (3-bit encoded)
nreg_0002 = (0,2) # Ns8 32-bit general register or Os8 vector .new (3-bit encoded)
nreg_0002lsb = (0,0) # lsb of 3-bit encoding for alternate .new register use
sd6 = (0,5) # supervisory register (assumed to be 32-bits each)
sdd6 = (0,5) # supervisory register (assumed to be 64-bits each)
ss6 = (16,21) # supervisory register (assumed to be 32-bits each)
sss6 = (16,21) # supervisory register (assumed to be 64-bits each)
# duplex/packed fields - PP mode
rs4p = (16,19) # 16-bit general reg
rt4p = (8,11) # 16-bit general reg
rd0811 = (8,11) # 16-bit general reg
rd0811_ = (8,11) # 16-bit general reg (shadow)
rd1619 = (16,19) # 16-bit general reg
rd1619_ = (16,19) # 16-bit general reg (shadow)
# duplex/packed fields - left side (register attachments are somewhat assumed)
rdd3l = (16,18) # 64-bit general reg
rdd3l_ = (16,18) # 64-bit general reg (shadow)
rtt3l = (16,18) # 64-bit general reg
rd4l = (16,19) # 32-bit general reg
rd4l_ = (16,19) # 32-bit general reg (shadow)
rt4l = (16,19) # 32-bit general reg
rs4l = (20,23) # 32-bit general reg
# duplex/packed fields - right side (register attachments are somewhat assumed)
rdd3r = (0,2) # 64-bit general reg
rdd3r_ = (0,2) # 64-bit general reg
rtt3r = (0,2) # 64-bit general reg
rd4r = (0,3) # 32-bit general reg
rd4r_ = (0,3) # 32-bit general reg (shadow)
rs4r = (4,7) # 32-bit general reg
rt4r = (0,3) # 32-bit general reg
;
#
# Attach statements
#
# 64-bit reg selector is 5-bits - the LS bit must always be 0 (even reg)
attach variables [ rdd5 rxx5 rss5 rtt5 ruu5 rdd0812 ]
[ R1R0 _ R3R2 _ R5R4 _ R7R6 _ R9R8 _ R11R10 _ R13R12 _ R15R14 _
R17R16 _ R19R18 _ R21R20 _ R23R22 _ R25R24 _ R27R26 _ R29R28 _ R31R30 _ ];
attach variables [ rdd5_ rxx5_ rdd0812_ ]
[ R1R0_ _ R3R2_ _ R5R4_ _ R7R6_ _ R9R8_ _ R11R10_ _ R13R12_ _ R15R14_ _
R17R16_ _ R19R18_ _ R21R20_ _ R23R22_ _ R25R24_ _ R27R26_ _ R29R28_ _ R31R30_ _];
# Access to high word reg of specified long word rtt5, rt5 can be used for low word reg
attach variables [ rtt5h rss5h ]
[ R1 _ R3 _ R5 _ R7 _ R9 _ R11 _ R13 _ R15 _ R17 _ R19 _ R21 _ R23 _ R25 _ R27 _ SP _ LR _ ];
# Access to high word reg of specified long word rdd5, rd5 can be used for low word reg
attach variables [ rdd5h ]
[ R1 _ R3 _ R5 _ R7 _
R9 _ R11 _ R13 _ R15 _
R17 _ R19 _ R21 _ R23 _
R25 _ R27 _ SP _ LR _ ];
attach variables [ rdd5h_ ]
[ R1.new _ R3.new _ R5.new _ R7.new _
R9.new _ R11.new _ R13.new _ R15.new _
R17.new _ R19.new _ R21.new _ R23.new _
R25.new _ R27.new _ SP.new _ LR.new _ ];
attach variables [ rdd3l rtt3l rdd3r rtt3r ]
[ R1R0 R3R2 R5R4 R7R6 R17R16 R19R18 R21R20 R23R22 ];
attach variables [ rdd3l_ rdd3r_ ]
[ R1R0_ R3R2_ R5R4_ R7R6_ R17R16_ R19R18_ R21R20_ R23R22_ ];
attach variables [ rd5 rd0812 rs5 rt5 ru5 rx5 rf5 nreg ]
[ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 SP FP LR ];
attach variables [ rt1618 ]
[ R0 R1 R2 R3 R4 R5 R6 R7 ];
attach variables [ rd5_ rd0812_ rx5_ rf5_ nreg_ ]
[ R0.new R1.new R2.new R3.new R4.new R5.new R6.new R7.new
R8.new R9.new R10.new R11.new R12.new R13.new R14.new R15.new
R16.new R17.new R18.new R19.new R20.new R21.new R22.new R23.new
R24.new R25.new R26.new R27.new R28.new SP.new FP.new LR.new ];
attach variables [ rx5H rs5H rt5H ru5H ]
[ R0.H R1.H R2.H R3.H R4.H R5.H R6.H R7.H
R8.H R9.H R10.H R11.H R12.H R13.H R14.H R15.H
R16.H R17.H R18.H R19.H R20.H R21.H R22.H R23.H
R24.H R25.H R26.H R27.H R28.H R29.H R30.H R31.H ];
attach variables [ rx5H_ ]
[ R0.H_ R1.H_ R2.H_ R3.H_ R4.H_ R5.H_ R6.H_ R7.H_
R8.H_ R9.H_ R10.H_ R11.H_ R12.H_ R13.H_ R14.H_ R15.H_
R16.H_ R17.H_ R18.H_ R19.H_ R20.H_ R21.H_ R22.H_ R23.H_
R24.H_ R25.H_ R26.H_ R27.H_ R28.H_ R29.H_ R30.H_ R31.H_ ];
attach variables [ rx5L rs5L rt5L ru5L ]
[ R0.L R1.L R2.L R3.L R4.L R5.L R6.L R7.L
R8.L R9.L R10.L R11.L R12.L R13.L R14.L R15.L
R16.L R17.L R18.L R19.L R20.L R21.L R22.L R23.L
R24.L R25.L R26.L R27.L R28.L R29.L R30.L R31.L ];
attach variables [ rx5L_ ]
[ R0.L_ R1.L_ R2.L_ R3.L_ R4.L_ R5.L_ R6.L_ R7.L_
R8.L_ R9.L_ R10.L_ R11.L_ R12.L_ R13.L_ R14.L_ R15.L_
R16.L_ R17.L_ R18.L_ R19.L_ R20.L_ R21.L_ R22.L_ R23.L_
R24.L_ R25.L_ R26.L_ R27.L_ R28.L_ R29.L_ R30.L_ R31.L_ ];
attach variables [ rs4p rt4p rs4l rt4l rs4r rd4l rd4r rt4r rd0811 rd1619 ]
[ R0 R1 R2 R3 R4 R5 R6 R7 R16 R17 R18 R19 R20 R21 R22 R23];
attach variables [ rd4l_ rd4r_ rd0811_ rd1619_ ]
[ R0.new R1.new R2.new R3.new R4.new R5.new R6.new R7.new
R16.new R17.new R18.new R19.new R20.new R21.new R22.new R23.new];
attach variables [ cd5 cs5 ]
[ SA0 LC0 SA1 LC1 P3P0 C5 M0 M1
USR PC UGP GP CS0 CS1 UPCYCLELO UPCYCLEHI
FRAMELIMIT FRAMEKEY PKTCOUNTLO PKTCOUNTHI C20 C21 C22 C23
C24 C25 C26 C27 C28 C29 UTIMERLO UTIMERHI ];
attach variables [ cd5_ ]
[ SA0_ LC0_ SA1_ LC1_ P3P0_ C5_ M0_ M1_
USR_ PC UGP_ GP_ CS0_ CS1_ UPCYCLELO_ UPCYCLEHI_
FRAMELIMIT_ FRAMEKEY_ PKTCOUNTLO_ PKTCOUNTHI_ C20_ C21_ C22_ C23_
C24_ C25_ C26_ C27_ C28_ C29_ UTIMERLO_ UTIMERHI_ ];
attach variables [ css5 cdd5 ]
[ C1C0 _ C3C2 _ C5C4 _ C7C6 _
C9C8 _ C11C10 _ C13C12 _ UPCYCLE _
C17C16 _ PKTCOUNT _ C21C20 _ C23C22 _
C25C24 _ C27C26 _ C29C28 _ UTIMER _ ];
attach variables [ cdd5_ ]
[ C1C0_ _ C3C2_ _ C5C4_ _ C7C6_ _
C9C8_ _ C11C10_ _ C13C12_ _ UPCYCLE_ _
C17C16_ _ PKTCOUNT_ _ C21C20_ _ C23C22_ _
C25C24_ _ C27C26_ _ C29C28_ _ UTIMER_ _ ];
attach variables [ mu ] [ M0 M1 ];
attach variables [ pu12 pu25 ] [ P0 P1 ];
attach variables [ pu12_ pu25_ ] [ P0.new P1.new ];
attach names [ pu12name pu25name ] [ "P0" "P1" ];
attach variables [ pu0001 pu0506 pu0607 pu0809 pu1112 pu0910 pu1617 pu2122 pu2324 ] [ P0 P1 P2 P3 ];
attach variables [ pu0001_ pu0506_ pu0809_ pu0910_ pu1112_ pu2122_ ] [ P0.new P1.new P2.new P3.new ];
attach names [ pu0001name pu0506name pu0809name pu1112name pu0910name pu2122name ] [ "P0" "P1" "P2" "P3" ];
attach variables [ qv0001 qv0506 qv0809 qv1112 qv2223 ] [ Q0 Q1 Q2 Q3 ];
attach variables [ ss6 sd6 ] # TODO: Shadow reg's not implemented for system regs
[ S0 S1 S2 S3 S4 S5 S6 S7
S8 S9 S10 S11 S12 S13 S14 S15
S16 S17 S18 S19 S20 S21 S22 S23
S24 S25 S26 S27 S28 S29 S30 S31
S32 S33 S34 S35 S36 S37 S38 S39
S40 S41 S42 S43 S44 S45 S46 S47
S48 S49 S50 S51 S52 S53 S54 S55
S56 S57 S58 S59 S60 S61 S62 S63 ];
attach variables [ sss6 sdd6 ] # TODO: Shadow reg's not implemented for system regs
[ S1S0 _ S3S2 _ S5S4 _ S7S6 _
S9S8 _ S11S10 _ S13S12 _ S15S14 _
S17S16 _ S19S18 _ S21S20 _ S23S22 _
S25S24 _ S27S26 _ S29S28 _ S31S30 _
S33S32 _ S35S34 _ S37S36 _ S39S38 _
S41S40 _ S43S42 _ S45S44 _ S47S46 _
S49S48 _ S51S50 _ S53S52 _ S55S54 _
S57S56 _ S59S58 _ S61S60 _ S63S62 _ ];
attach variables [ gss5 gdd5 ] [ # TODO: Shadow reg's not implemented for guest regs
G1G0 _ G3G2 _ G5G4 _ G7G6 _
G9G8 _ G11G10 _ G13G12 _ G15G14 _
G17G16 _ G19G18 _ G21G20 _ G23G22 _
G25G24 _ G27G26 _ G29G28 _ G31G30 _ ];
attach variables [ gs5 gd5 ] [ # TODO: Shadow reg's not implemented for guest regs
G0 G1 G2 G3 G4 G5 G6 G7
G8 G9 G10 G11 G12 G13 G14 G15
G16 G17 G18 G19 G20 G21 G22 G23
G24 G25 G26 G27 G28 G29 G30 G31 ];
#
# HVX vector registers
#
# NOTE: HVX Vector register access size and signedness are generally indicated by a
# suffix in assembly source, e.g., .b .ub .h .uh .w.uw
# We currently do not name lane-access registers and rely on lane access sizes as
# defined by the pspec.
# double-vector reg selector is 5-bits - the LS bit must always be 0 (even reg)
attach variables [ vdd5 vss5 vuu5 vvv5 ]
[ V1V0 _ V3V2 _ V5V4 _ V7V6 _ V9V8 _ V11V10 _ V13V12 _ V15V14 _
V17V16 _ V19V18 _ V21V20 _ V23V22 _ V25V24 _ V27V26 _ V29V28 _ V31V30 _ ];
attach variables [ vd5 vs5 vu5 vv5 vz5 vnreg ]
[ V0 V1 V2 V3 V4 V5 V6 V7
V8 V9 V10 V11 V12 V13 V14 V15
V16 V17 V18 V19 V20 V21 V22 V23
V24 V25 V26 V27 V28 V29 V30 V31 ];
attach variables [ vdd5_ ] # TODO: Removed vuu5_ vvv5_
[ V1V0_ _ V3V2_ _ V5V4_ _ V7V6_ _ V9V8_ _ V11V10_ _ V13V12_ _ V15V14_ _
V17V16_ _ V19V18_ _ V21V20_ _ V23V22_ _ V25V24_ _ V27V26_ _ V29V28_ _ V31V30_ _ ];
attach variables [ vd5_ vnreg_ ] # TODO: Removed vs5_ vu5_ vv5_ vz5_
[ V0.new V1.new V2.new V3.new V4.new V5.new V6.new V7.new
V8.new V9.new V10.new V11.new V12.new V13.new V14.new V15.new
V16.new V17.new V18.new V19.new V20.new V21.new V22.new V23.new
V24.new V25.new V26.new V27.new V28.new V29.new V30.new V31.new ];
#
# Ns8 .new scalar register support
#
# The assigned register must be written to the nreg slot which corresponds to
# the packet slot minus the xreg value. The xreg value is incremented
# anytime an immext instruction is encountered within the packet.
# Assumptions:
# 1. Packet contains 4 instruction slots
# 2. Use of Rx.new will always be the last instruction within a packet
# 3. At most 2 immext instructions may exist in packet
# 4. Two adjacent immext instructions not allowed
# 5. left/right EE instructions are of no concern (they are always last in packet)
# 6. 64-bit scalar register destination is not allowed but we do not prevent it
# 7. New value store context may be shared for scalar and vector register use since
# only one or the other will be forwarded by any one instruction.
# Set appropriate nreg based upon packetOffset less number of preceeding immext ops
# Cases have been optimized based upon valid placement of immext within packet
# Set appropriate new value store index 'nreg#' using default destination register field rd5_
# This new value store subconstructor can be shared with vd5_ and vdd5_, which all use the
# same token bit range (00,04).
SetNRegRd5: is packetOffset=0 & rd5_ [ nreg0=rd5_; ] { }
SetNRegRd5: is packetOffset=1 & rd5_ [ nreg1=rd5_; ] { }
SetNRegRd5: is packetOffset=1 & xreg=1 & rd5_ [ nreg0=rd5_; ] { }
SetNRegRd5: is packetOffset=2 & rd5_ [ nreg2=rd5_; ] { }
SetNRegRd5: is packetOffset=2 & xreg=1 & rd5_ [ nreg1=rd5_; ] { }
SetNRegRd5: is packetOffset=3 { } # no need to retain new value register for last instruction
# Set appropriate nreg using rx5_
SetNRegRx5: is packetOffset=0 & rx5_ [ nreg0=rx5_; ] { }
SetNRegRx5: is packetOffset=1 & rx5_ [ nreg1=rx5_; ] { }
SetNRegRx5: is packetOffset=1 & xreg=1 & rx5_ [ nreg0=rx5_; ] { }
SetNRegRx5: is packetOffset=2 & rx5_ [ nreg2=rx5_; ] { }
SetNRegRx5: is packetOffset=2 & xreg=1 & rx5_ [ nreg1=rx5_; ] { }
SetNRegRx5: is packetOffset=3 { } # no need to retain new value register for last instruction
# Set appropriate nreg using rd0812_
SetNRegRd0812: is packetOffset=0 & rd0812_ [ nreg0=rd0812_; ] { }
SetNRegRd0812: is packetOffset=1 & rd0812_ [ nreg1=rd0812_; ] { }
SetNRegRd0812: is packetOffset=1 & xreg=1 & rd0812_ [ nreg0=rd0812_; ] { }
SetNRegRd0812: is packetOffset=2 & rd0812_ [ nreg2=rd0812_; ] { }
SetNRegRd0812: is packetOffset=2 & xreg=1 & rd0812_ [ nreg1=rd0812_; ] { }
SetNRegRd0812: is packetOffset=3 { } # no need to retain new value register for last instruction
# TODO: If needed, add SetNReg for: Re32 Rx32 Rd16 Re16 Rx16 Ry16 Rd8
# Compute new value store index context 'nregr' based upon 'nregSlot' and appropriate 'nreg#' context.
# This subcontructor may be shared by both Ns8 (new scalar reg) and Os8 (new vector reg) decode since
# they share the underlying new value index 'nreg#' context storage.
# NOTE: The nregSlot must preceed the current packetOffset
GetNReg: is nregSlot=0 & (packetOffset0=1 | packetOffset1=1) & nreg0 [ nregr = nreg0; ] { }
GetNReg: is nregSlot=1 & packetOffset1=1 & nreg1 [ nregr = nreg1; ] { }
GetNReg: is nregSlot=2 & packetOffset=3 & nreg2 [ nregr = nreg2; ] { }
# Decode 3-bit encoded Ns8 .new register, setting nregSlot (lsb of 3-bit nreg field ignored)
# and return appropriate nreg (R0.new - R31.new). The nregSlot must refer to a previous
# instruction slot within the same execute packet.
#
# NOTE: Since the non-shadow register location is returned (while .new is displayed) is is assumed
# that the location will not be read until the <<COMMIT>> phase or later
Nreg1618: nreg_ is GetNReg & nreg_ & nreg & nreg_1618 [ nregSlot = packetOffset - xreg - (nreg_1618 >> 1); ] { export nreg; }
Nreg0810: nreg_ is GetNReg & nreg_ & nreg & nreg_0810 [ nregSlot = packetOffset - xreg - (nreg_0810 >> 1); ] { export nreg; }
Nreg0002: nreg_ is GetNReg & nreg_ & nreg & nreg_0002 [ nregSlot = packetOffset - xreg - (nreg_0002 >> 1); ] { export nreg; }
#
# HVX Os8 .new vector register support
# Employs the same strategy as the Ns8 above with some context fields sharing use for both Os8 and Ns8
#
# NOTE: More investigation is needed for the correct 3-bit Os8 encoding. Some information suggests
# that bits identify the specific pipeline which produced the vector result and is not based on
# packetOffset as originally believed.
# Set appropriate new value index 'nregr' using vd5_ or vdd5_ (same as rd5_ field)
SetVNRegVd5: is SetNRegRd5 { }
# Compute Os8 new value store index 'nregr' based upon 'nregSlot' when Os8 lsb is '0'.
# NOTE: We can share GetNReg use with Ns8 decode for this case.
GetVNReg: is GetNReg { }
# Compute alternate Os8 new value store index 'nregr' based upon 'nregSlot' when Os8 lsb is '1'.
# This will produce a new value store index that corresponds to the other vector register within
# the same pair (e.g., if vnreg# indicates V0 index, V1 index will be use by inverting lsb for 'nregr')
# NOTE: The nregSlot must preceed the current packetOffset
GetVNAltReg: is nregSlot=0 & (packetOffset0=1 | packetOffset1=1) & nreg0 [ nregr = nreg0 ^ 1; ] { }
GetVNAltReg: is nregSlot=1 & packetOffset1=1 & nreg1 [ nregr = nreg1 ^ 1; ] { }
GetVNAltReg: is nregSlot=2 & packetOffset=3 & nreg2 [ nregr = nreg2 ^ 1; ] { }
# Decode 3-bit encoded Os8 .new vector register, setting nregSlot (lsb of 3-bit nreg field ignored)
# and return appropriate vnreg (V0.new - V31.new). The nregSlot must refer to a previous
# instruction slot within the same execute packet.
#
# NOTE: Since the non-shadow register location is returned (while .new is displayed) is is assumed
# that the location will not be read until the <<COMMIT>> phase or later
# The lsb of 3-bit Os8 field indicates an alternate register. It appears to have two cases:
# 1) register pair: if '1' .new corresponds to the other register in the aligned pair (GetVNAltReg)
# 2) dual independent registers: Vx(0), Vy(1) use case (not yet supported)
VNreg0002: vnreg_ is GetVNReg & vnreg_ & vnreg & nreg_0002lsb=0 & nreg_0002 [ nregSlot = packetOffset - xreg - (nreg_0002 >> 1); ] { export vnreg; }
VNreg0002: vnreg_ is GetVNAltReg & vnreg_ & vnreg & nreg_0002lsb=1 & nreg_0002 [ nregSlot = packetOffset - xreg - (nreg_0002 >> 1); ] { export vnreg; }
#
# General Instruction Set parse and execute packet and crossbuild constructors
#
@include "hexagon.sinc"
#
# Packed/Duplex 'EE' Instruction Set
# 29..31 Instruction Class
# 14..15 PP parse bits
# 00..12 Right sub-instruction (Slot-0)
# 16..28 Left sub-instruction (Slot-1)
#
@include "hexagon_left.sinc"
@include "hexagon_right.sinc"
#
# Floating Point Instruction Set
#
@include "hexagon_float.sinc"
#
# Vector Instruction Set (HVX extension)
#
@include "hexagon_hvx.sinc"

View File

@@ -0,0 +1,872 @@
#
# Floating Point Instructions
# Added with V5x:
# convert_sf2d, convert_sf2df, convert_sf2ud, convert_sf2uw, convert_sf2w
# convert_d2sf, convert_ud2sf, convert_uw2sf, convert_w2sf
# convert_df2d, convert_df2sf, convert_df2ud, convert_df2uw, convert_df2w
# convert_d2df, convert_ud2df, convert_uw2df, convert_w2df
# sfadd, sfclass, sfcmp.*, sffixupd, sffixupn, sffixupr, sfmake, sfmax, sfmin, sfmpy, sfsub
# dfclass, dfcmp.*, dfmake
# Added with V65:
# sfinvsqrta, sfrecipa
# Added with V66:
# dfadd, dfsub
# Added with V67:
# dfmax, dfmin, dfmpyfix, dfmpyhh, dfmpylh, dfmpyll
#
# See bottom of this file for additional instruction patterns found within QEMU source code.
# Use of the undocumented double-precission floating instructions are disabled by default
# due to conflicts with V6 instructions. The option ADD_DP_OPS must be defined to
# to enable the use of these undocumented instructions which will disable the use of
# corresponding V6 instructions which conflict.
#
define pcodeop convertFloat2UInt;
define pcodeop chopFloat2UInt;
#
# V5x Floating Point Instructions
#
# (v5,8) convert_sf2d -- "Rdd = convert_sf2d ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 0 1 + + s s s s s P P + + + + + + 1 0 0 d d d d d
:convert_sf2d Rdd5,rs5 EndPacket is iclass=8 & op2127=0x24 & op0813=0 & op0507=4 & rs5 & Rdd5 & $(END_PACKET) {
# TODO: Rounding mode and other exceptional conditions are not implemented
Rdd5 = trunc(rs5);
build EndPacket;
}
# (v5,8) convert_sf2d -- "Rdd = convert_sf2d ( Rs ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 0 1 + + s s s s s P P + + + + + + 1 1 0 d d d d d
:convert_sf2d^":chop" Rdd5,rs5 EndPacket is iclass=8 & op2127=0x24 & op0813=0 & op0507=6 & rs5 & Rdd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
Rdd5 = trunc(rs5);
build EndPacket;
}
# (v5,8) convert_sf2df -- "Rdd = convert_sf2df ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 0 1 + + s s s s s P P + + + + + + 0 0 0 d d d d d
:convert_sf2df Rdd5,rs5 EndPacket is iclass=8 & op2127=0x24 & op0813=0 & op0507=0 & rs5 & Rdd5 & $(END_PACKET) {
Rdd5 = float2float(rs5);
build EndPacket;
}
# (v5,8) convert_sf2ud -- "Rdd = convert_sf2ud ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 0 1 + + s s s s s P P + + + + + + 0 1 1 d d d d d
:convert_sf2ud Rdd5,rs5 EndPacket is iclass=8 & op2127=0x24 & op0813=0 & op0507=3 & rs5 & Rdd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
float:4 = float2float(rs5);
Rdd5 = convertFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_sf2ud -- "Rdd = convert_sf2ud ( Rs ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 0 1 + + s s s s s P P + + + + + + 1 0 1 d d d d d
:convert_sf2ud^":chop" Rdd5,rs5 EndPacket is iclass=8 & op2127=0x24 & op0813=0 & op0507=5 & rs5 & Rdd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
float:4 = float2float(rs5);
Rdd5 = chopFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_sf2uw -- "Rd = convert_sf2uw ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 0 1 1 s s s s s P P + + + + + + 0 0 0 d d d d d
:convert_sf2uw Rd5,rs5 EndPacket is iclass=8 & op2127=0x5b & op0813=0 & op0507=0 & rs5 & Rd5 & $(END_PACKET) {
# TODO: Rounding mode and other exceptional conditions are not implemented
float:4 = float2float(rs5);
Rd5 = convertFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_sf2uw -- "Rd = convert_sf2uw ( Rs ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 0 1 1 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_sf2uw^":chop" Rd5,rs5 EndPacket is iclass=8 & op2127=0x5b & op0813=0 & op0507=1 & rs5 & Rd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
float:4 = float2float(rs5);
Rd5 = chopFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_sf2w -- "Rd = convert_sf2w ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 1 0 0 s s s s s P P + + + + + + 0 0 0 d d d d d
:convert_sf2w Rd5,rs5 EndPacket is iclass=8 & op2127=0x5c & op0813=0 & op0507=0 & rs5 & Rd5 & $(END_PACKET) {
# TODO: Rounding mode and other exceptional conditions are not implemented
Rd5 = trunc(rs5);
build EndPacket;
}
# (v5,8) convert_sf2w -- "Rd = convert_sf2w ( Rs ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 1 0 0 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_sf2w^":chop" Rd5,rs5 EndPacket is iclass=8 & op2127=0x5c & op0813=0 & op0507=1 & rs5 & Rd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
Rd5 = trunc(rs5);
build EndPacket;
}
# (v5,8) convert_d2sf -- "Rd = convert_d2sf ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 0 0 0 1 0 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_d2sf Rd5,rss5 EndPacket is iclass=8 & op2127=0x42 & op0813=0 & op0507=1 & rss5 & Rd5 & $(END_PACKET) {
Rd5 = int2float(rss5);
build EndPacket;
}
# (v5,8) convert_ud2sf -- "Rd = convert_ud2sf ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 0 0 0 0 1 s s s s s P P + + + + + + 0 0 1 d d d d d
# TODO: we do not have an unsigned int2float - could zext but not with 8-byte reg if we want to emulate
define pcodeop convertUInt2float;
:convert_ud2sf Rd5,rss5 EndPacket is iclass=8 & op2127=0x41 & op0813=0 & op0507=1 & rss5 & Rd5 & $(END_PACKET) {
tmp:9 = zext(rss5);
Rd5 = int2float(tmp);
build EndPacket;
}
# (v5,8) convert_uw2sf -- "Rd = convert_uw2sf ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 0 0 1 s s s s s P P + + + + + + 0 0 0 d d d d d
:convert_uw2sf Rd5,rs5 EndPacket is iclass=8 & op2127=0x59 & op0813=0 & op0507=0 & rs5 & Rd5 & $(END_PACKET) {
tmp:8 = zext(rs5);
Rd5 = int2float(tmp);
build EndPacket;
}
# (v5,8) convert_w2sf -- "Rd = convert_w2sf ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 0 1 0 s s s s s P P + + + + + + 0 0 0 d d d d d
:convert_w2sf Rd5,rs5 EndPacket is iclass=8 & op2127=0x5a & op0813=0 & op0507=0 & rs5 & Rd5 & $(END_PACKET) {
Rd5 = int2float(rs5);
build EndPacket;
}
# (v5,8) convert_df2d -- "Rdd = convert_df2d ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 0 + + + + + 0 0 0 d d d d d
:convert_df2d Rdd5,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0 & op0507=0 & rss5 & Rdd5 & $(END_PACKET) {
# TODO: Rounding mode and other exceptional conditions are not implemented
Rdd5 = trunc(rss5);
build EndPacket;
}
# (v5,8) convert_df2d -- "Rdd = convert_df2d ( Rss ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 0 + + + + + 1 1 0 d d d d d
:convert_df2d^":chop" Rdd5,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0 & op0507=6 & rss5 & Rdd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
Rdd5 = trunc(rss5);
build EndPacket;
}
# (v5,8) convert_df2sf -- "Rd = convert_df2sf ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 0 0 0 0 0 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_df2sf Rd5,rss5 EndPacket is iclass=8 & op2127=0x40 & op0813=0 & op0507=1 & rss5 & Rd5 & $(END_PACKET) {
Rd5 = float2float(rss5);
build EndPacket;
}
# (v5,8) convert_df2ud -- "Rdd = convert_df2ud ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 0 + + + + + 0 0 1 d d d d d
:convert_df2ud Rdd5,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0 & op0507=1 & rss5 & Rdd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
float:8 = float2float(rss5);
Rdd5 = convertFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_df2ud -- "Rdd = convert_df2ud ( Rss ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 0 + + + + + 1 1 1 d d d d d
:convert_df2ud^":chop" Rdd5,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0 & op0507=7 & rss5 & Rdd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
float:8 = float2float(rss5);
Rdd5 = chopFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_df2uw -- "Rd = convert_df2uw ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 0 0 0 1 1 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_df2uw Rd5,rss5 EndPacket is iclass=8 & op2127=0x43 & op0813=0 & op0507=1 & rss5 & Rd5 & $(END_PACKET) {
# TODO: Rounding mode and other exceptional conditions are not implemented
float:8 = float2float(rss5);
Rd5 = convertFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_df2uw -- "Rd = convert_df2uw ( Rss ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 0 0 1 0 1 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_df2uw^":chop" Rd5,rss5 EndPacket is iclass=8 & op2127=0x45 & op0813=0 & op0507=1 & rss5 & Rd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
float:8 = float2float(rss5);
Rd5 = chopFloat2UInt(float);
build EndPacket;
}
# (v5,8) convert_df2w -- "Rd = convert_df2w ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 0 0 1 0 0 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_df2w Rd5,rss5 EndPacket is iclass=8 & op2127=0x44 & op0813=0 & op0507=1 & rss5 & Rd5 & $(END_PACKET) {
# TODO: Rounding mode and other exceptional conditions are not implemented
Rd5 = trunc(rss5);
build EndPacket;
}
# (v5,8) convert_df2w -- "Rd = convert_df2w ( Rss ) :chop"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 0 0 1 1 1 s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_df2w^":chop" Rd5,rss5 EndPacket is iclass=8 & op2127=0x47 & op0813=0 & op0507=1 & rss5 & Rd5 & $(END_PACKET) {
# TODO: Exceptional conditions are not implemented
Rd5 = trunc(rss5);
build EndPacket;
}
# (v5,8) convert_d2df -- "Rdd = convert_d2df ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 0 + + + + + 0 1 1 d d d d d
:convert_d2df Rdd5,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0 & op0507=3 & rss5 & Rdd5 & $(END_PACKET) {
Rdd5 = int2float(rss5);
build EndPacket;
}
# (v5,8) convert_ud2df -- "Rdd = convert_ud2df ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 0 + + + + + 0 1 0 d d d d d
:convert_ud2df Rdd5,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0 & op0507=2 & rss5 & Rdd5 & $(END_PACKET) {
tmp:9 = zext(rss5);
Rdd5 = int2float(tmp);
build EndPacket;
}
# (v5,8) convert_uw2df -- "Rdd = convert_uw2df ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 0 1 + + s s s s s P P + + + + + + 0 0 1 d d d d d
:convert_uw2df Rdd5,rs5 EndPacket is iclass=8 & op2127=0x24 & op0813=0 & op0507=1 & rs5 & Rdd5 & $(END_PACKET) {
tmp:9 = zext(rs5);
Rdd5 = int2float(tmp);
build EndPacket;
}
# (v5,8) convert_w2df -- "Rdd = convert_w2df ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 0 1 + + s s s s s P P + + + + + + 0 1 0 d d d d d
:convert_w2df Rdd5,rs5 EndPacket is iclass=8 & op2127=0x24 & op0813=0 & op0507=2 & rs5 & Rdd5 & $(END_PACKET) {
Rdd5 = int2float(rs5);
build EndPacket;
}
# (v5,14) sfadd -- "Rd = sfadd ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 0 0 0 s s s s s P P 0 t t t t t 0 0 0 d d d d d
:sfadd Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x58 & op13=0 & op0507=0 & rs5 & rt5 & Rd5 & $(END_PACKET) {
Rd5 = rs5 f+ rt5;
build EndPacket;
}
# (v5,8) sfclass -- "Pd = sfclass ( Rs, #u5 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 1 0 1 1 1 1 s s s s s P P 0 i i i i i + + + + + + d d
define pcodeop isClassifiedFloat;
:sfclass Pd2,rs5,Uimm8_0812 EndPacket is iclass=8 & op2127=0x2f & op13=0 & op0207=0 & Uimm8_0812 & rs5 & Pd2 & $(END_PACKET) {
float:4 = float2float(rs5);
bool:1 = isClassifiedFloat(float,Uimm8_0812);
Pd2 = Pd2 & ((bool != 0) * 0xff);
build EndPacket;
}
# (v5,12) sfcmp.ge -- "Pd = sfcmp.ge ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 0 0 1 1 1 1 1 1 s s s s s P P + t t t t t 0 0 0 + + + d d
:sfcmp.ge Pd2,rs5,rt5 EndPacket is iclass=12 & op2127=0x3f & op13=0 & op0507=0 & op0204=0 & rs5 & rt5 & Pd2 & $(END_PACKET) {
Pd2 = Pd2 & ((rt5 f<= rs5) * 0xff);
build EndPacket;
}
# (v5,12) sfcmp.uo -- "Pd = sfcmp.uo ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 0 0 1 1 1 1 1 1 s s s s s P P + t t t t t 0 0 1 + + + d d
:sfcmp.uo Pd2,rs5,rt5 EndPacket is iclass=12 & op2127=0x3f & op13=0 & op0507=1 & op0204=0 & rs5 & rt5 & Pd2 & $(END_PACKET) {
float1:4 = float2float(rs5);
float2:4 = float2float(rt5);
bool:1 = nan(float1) || nan(float2);
Pd2 = Pd2 & ((bool != 0) * 0xff);
build EndPacket;
}
# (v5,12) sfcmp.eq -- "Pd = sfcmp.eq ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 0 0 1 1 1 1 1 1 s s s s s P P + t t t t t 0 1 1 + + + d d
:sfcmp.eq Pd2,rs5,rt5 EndPacket is iclass=12 & op2127=0x3f & op13=0 & op0507=3 & op0204=0 & rs5 & rt5 & Pd2 & $(END_PACKET) {
Pd2 = Pd2 & ((rt5 f== rs5) * 0xff);
build EndPacket;
}
# (v5,12) sfcmp.gt -- "Pd = sfcmp.gt ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 0 0 1 1 1 1 1 1 s s s s s P P + t t t t t 1 0 0 + + + d d
:sfcmp.gt Pd2,rs5,rt5 EndPacket is iclass=12 & op2127=0x3f & op13=0 & op0507=4 & op0204=0 & rs5 & rt5 & Pd2 & $(END_PACKET) {
Pd2 = Pd2 & ((rs5 f> rt5) * 0xff);
build EndPacket;
}
# (v5,14) sffixupd -- "Rd = sffixupd ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 1 1 0 s s s s s P P 0 t t t t t 0 0 1 d d d d d
define pcodeop sffixupd;
:sffixupd Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x5e & op13=0 & op0507=1 & rs5 & rt5 & Rd5 & $(END_PACKET) {
Rd5 = sffixupd(rs5, rt5);
build EndPacket;
}
# (v5,14) sffixupn -- "Rd = sffixupn ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 1 1 0 s s s s s P P 0 t t t t t 0 0 0 d d d d d
define pcodeop sffixupn;
:sffixupn Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x5e & op13=0 & op0507=0 & rs5 & rt5 & Rd5 & $(END_PACKET) {
Rd5 = sffixupn(rs5, rt5);
build EndPacket;
}
# (v5,8) sffixupr -- "Rd = sffixupr ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 1 0 1 s s s s s P P + + + + + + 0 0 0 d d d d d
define pcodeop sffixupr;
:sffixupr Rd5,rs5 EndPacket is iclass=8 & op2127=0x5d & op0813=0 & op0507=0 & rs5 & Rd5 & $(END_PACKET) {
Rd5 = sffixupr(rs5);
build EndPacket;
}
# (v5,13) sfmake -- "Rd = sfmake ( #u10 ) :neg"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 0 1 1 0 0 1 i + + + + + P P i i i i i i i i i d d d d d
:sfmake^":neg" Rd5,Uimm16_21_0513 EndPacket is iclass=13 & op2227=0x19 & op1620=0 & Uimm16_21_0513 & Rd5 & $(END_PACKET) {
Rd5 = int2float(-Uimm16_21_0513); # TODO: assumed functionality
build EndPacket;
}
# (v5,13) sfmake -- "Rd = sfmake ( #u10 ) :pos"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 0 1 1 0 0 0 i + + + + + P P i i i i i i i i i d d d d d
:sfmake^":pos" Rd5,Uimm16_21_0513 EndPacket is iclass=13 & op2227=0x18 & op1620=0 & Uimm16_21_0513 & Rd5 & $(END_PACKET) {
Rd5 = int2float(Uimm16_21_0513); # TODO: assumed functionality
build EndPacket;
}
# (v5,14) sfmax -- "Rd = sfmax ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 1 0 0 s s s s s P P 0 t t t t t 0 0 0 d d d d d
:sfmax Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x5c & op13=0 & op0507=0 & rs5 & rt5 & Rd5 & $(END_PACKET) {
if (nan(rs5) || (rs5 f< rt5)) goto <useRt>;
Rd5 = rs5;
goto <done>;
<useRt>
Rd5 = rt5;
<done>
build EndPacket;
}
# (v5,14) sfmin -- "Rd = sfmin ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 1 0 0 s s s s s P P 0 t t t t t 0 0 1 d d d d d
:sfmin Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x5c & op13=0 & op0507=1 & rs5 & rt5 & Rd5 & $(END_PACKET) {
if (nan(rs5) || (rt5 f< rs5)) goto <useRt>;
Rd5 = rs5;
goto <done>;
<useRt>
Rd5 = rt5;
<done>
build EndPacket;
}
# (v5,14) sfmpy -- "Rd = sfmpy ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 0 1 0 s s s s s P P 0 t t t t t 0 0 0 d d d d d
:sfmpy Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x5a & op13=0 & op0507=0 & rs5 & rt5 & Rd5 & $(END_PACKET) {
Rd5 = rs5 f* rt5;
build EndPacket;
}
# (v5,14) sfmpy+= -- "Rx += sfmpy ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 1 1 1 0 0 0 s s s s s P P 0 t t t t t 1 0 0 x x x x x
:sfmpy+= Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x78 & op13=0 & op0507=4 & rs5 & rt5 & Rd5 & rd5 & $(END_PACKET) {
Rd5 = rd5 f+ (rs5 f* rt5);
build EndPacket;
}
# (v5,14) sfmpy+= -- "Rx += sfmpy ( Rs, Rt, Pu ) :scale"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 1 1 1 0 1 1 s s s s s P P 0 t t t t t 1 u u x x x x x
:sfmpy+=^":scale" Rd5,rs5,rt5,pu0506 EndPacket is iclass=14 & op2127=0x7b & op13=0 & op7=1 & pu0506 & rs5 & rt5 & Rd5 & rd5 & $(END_PACKET) {
Rd5 = multiplyAddScale(Rd5, rs5, rt5);
build EndPacket;
}
# (v5,14) sfmpy-= -- "Rx -= sfmpy ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 1 1 1 0 0 0 s s s s s P P 0 t t t t t 1 0 1 x x x x x
:sfmpy-= Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x78 & op13=0 & op0507=5 & rs5 & rt5 & Rd5 & rd5 & $(END_PACKET) {
Rd5 = rd5 f- (rs5 f* rt5);
build EndPacket;
}
# (v5,14) sfmpy+= -- "Rx += sfmpy ( Rs, Rt ) :lib"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 1 1 1 0 0 0 s s s s s P P 0 t t t t t 1 1 0 x x x x x
:sfmpy+=^":lib" Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x78 & op13=0 & op0507=6 & rs5 & rt5 & Rd5 & rd5 & $(END_PACKET) {
Rd5 = rd5 f+ (rs5 f* rt5);
build EndPacket;
}
# (v5,14) sfmpy-= -- "Rx -= sfmpy ( Rs, Rt ) :lib"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 1 1 1 0 0 0 s s s s s P P 0 t t t t t 1 1 1 x x x x x
:sfmpy-=^":lib" Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x78 & op13=0 & op0507=7 & rs5 & rt5 & Rd5 & rd5 & $(END_PACKET) {
Rd5 = rd5 f- (rs5 f* rt5);
build EndPacket;
}
# (v5,14) sfsub -- "Rd = sfsub ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 0 0 0 s s s s s P P 0 t t t t t 0 0 1 d d d d d
:sfsub Rd5,rs5,rt5 EndPacket is iclass=14 & op2127=0x58 & op13=0 & op0507=1 & rs5 & rt5 & Rd5 & $(END_PACKET) {
Rd5 = rs5 f- rt5;
build EndPacket;
}
# (v5,13) dfclass -- "Pd = dfclass ( Rss, #u5 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 1 1 0 0 1 0 0 s s s s s P P + 0 0 0 i i i i i 1 0 + d d
:dfclass Pd2,rss5,Uimm8_0509 EndPacket is iclass=13 & op2127=0x64 & op1013=0 & op0204=4 & Uimm8_0509 & rss5 & Pd2 & $(END_PACKET) {
float:8 = float2float(rss5);
result:1 = isClassifiedFloat(float,Uimm8_0509);
Pd2 = Pd2 & result;
build EndPacket;
}
# (v5,13) dfcmp.eq -- "Pd = dfcmp.eq ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 0 0 1 0 1 1 1 s s s s s P P + t t t t t 0 0 0 + + + d d
:dfcmp.eq Pd2,rss5,rtt5 EndPacket is iclass=13 & op2127=0x17 & op13=0 & op0507=0 & op0204=0 & rss5 & rtt5 & Pd2 & $(END_PACKET) {
Pd2 = Pd2 & ((rtt5 f== rss5) * 0xff);
build EndPacket;
}
# (v5,13) dfcmp.gt -- "Pd = dfcmp.gt ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 0 0 1 0 1 1 1 s s s s s P P + t t t t t 0 0 1 + + + d d
:dfcmp.gt Pd2,rss5,rtt5 EndPacket is iclass=13 & op2127=0x17 & op13=0 & op0507=1 & op0204=0 & rss5 & rtt5 & Pd2 & $(END_PACKET) {
Pd2 = Pd2 & ((rss5 f> rtt5) * 0xff);
build EndPacket;
}
# (v5,13) dfcmp.ge -- "Pd = dfcmp.ge ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 0 0 1 0 1 1 1 s s s s s P P + t t t t t 0 1 0 + + + d d
:dfcmp.ge Pd2,rss5,rtt5 EndPacket is iclass=13 & op2127=0x17 & op13=0 & op0507=2 & op0204=0 & rss5 & rtt5 & Pd2 & $(END_PACKET) {
Pd2 = Pd2 & ((rtt5 f<= rss5) * 0xff);
build EndPacket;
}
# (v5,13) dfcmp.uo -- "Pd = dfcmp.uo ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 0 0 1 0 1 1 1 s s s s s P P + t t t t t 0 1 1 + + + d d
:dfcmp.uo Pd2,rss5,rtt5 EndPacket is iclass=13 & op2127=0x17 & op13=0 & op0507=3 & op0204=0 & rss5 & rtt5 & Pd2 & $(END_PACKET) {
float1:8 = float2float(rss5);
float2:8 = float2float(rtt5);
bool:1 = nan(float1) || nan(float2);
Pd2 = Pd2 & ((bool != 0) * 0xff);
build EndPacket;
}
# (v5,13) dfmake -- "Rdd = dfmake ( #u10 ) :neg"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 1 0 0 1 0 1 i + + + + + P P i i i i i i i i i d d d d d
:dfmake^":neg" Rdd5,Uimm16_21_0513 EndPacket is iclass=13 & op2227=0x25 & op1620=0 & Uimm16_21_0513 & Rdd5 & $(END_PACKET) {
Rdd5 = int2float(-Uimm16_21_0513); # TODO: assumed functionality
build EndPacket;
}
# (v5,13) dfmake -- "Rdd = dfmake ( #u10 ) :pos"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 1 1 0 0 1 0 0 i + + + + + P P i i i i i i i i i d d d d d
:dfmake^":pos" Rdd5,Uimm16_21_0513 EndPacket is iclass=13 & op2227=0x24 & op1620=0 & Uimm16_21_0513 & Rdd5 & $(END_PACKET) {
Rdd5 = int2float(Uimm16_21_0513); # TODO: assumed functionality
build EndPacket;
}
#
# V65 Floating Point Instructions
#
# (v65,8) sfinvsqrta -- "Rd,Pe = sfinvsqrta ( Rs )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 1 0 1 1 1 1 1 s s s s s P P + + + + + + 0 e e d d d d d
:sfinvsqrta Rd5,pu0506,rs5 EndPacket is iclass=8 & op2127=0x5f & op0813=0 & op7=0 & pu0506_ & pu0506 & rs5 & Rd5 & $(END_PACKET)
unimpl
# (v65,14) sfrecipa -- "Rd,Pe = sfrecipa ( Rs, Rt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 1 1 1 1 s s s s s P P 0 t t t t t 1 e e d d d d d
:sfrecipa Rd5,Pd0506,rs5,rt5 EndPacket is iclass=14 & op2127=0x5f & op13=0 & op7=1 & Pd0506 & rs5 & rt5 & Rd5 & $(END_PACKET) {
src1:4 = rs5;
src2:4 = rt5;
Rd5 = reciprocal(src1, src2);
Pd0506 = Pd0506 & reciprocalAdjust(src1, src2);
build EndPacket;
}
#
# V66 Floating Point Instructions
#
# (v66,14) dfadd -- "Rdd = dfadd ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 0 0 0 s s s s s P P 0 t t t t t 0 1 1 d d d d d
:dfadd Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x40 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET) {
Rdd5 = rss5 f+ rtt5;
build EndPacket;
}
# (v66,14) dfsub -- "Rdd = dfsub ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 1 0 0 s s s s s P P 0 t t t t t 0 1 1 d d d d d
:dfsub Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x44 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET) {
Rdd5 = rss5 f- rtt5;
build EndPacket;
}
#
# V67 Floating Point Instructions
#
# (v67,14) dfmax -- "Rdd = dfmax ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 0 0 1 s s s s s P P 0 t t t t t 0 1 1 d d d d d
:dfmax Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x41 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET) {
if (nan(rss5) || (rss5 f< rtt5)) goto <useRt>;
Rdd5 = rss5;
goto <done>;
<useRt>
Rdd5 = rtt5;
<done>
build EndPacket;
}
# (v67,14) dfmin -- "Rdd = dfmin ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 1 1 0 s s s s s P P 0 t t t t t 0 1 1 d d d d d
:dfmin Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x46 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET) {
if (nan(rss5) || (rtt5 f< rss5)) goto <useRt>;
Rdd5 = rss5;
goto <done>;
<useRt>
Rdd5 = rtt5;
<done>
build EndPacket;
}
# (v5,14) c -- "Rdd = dfmpyfix ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 0 1 0 s s s s s P P 0 t t t t t 0 1 1 d d d d d
define pcodeop dfmpyfix;
:dfmpyfix Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x42 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET) {
Rdd5 = dfmpyfix(rss5, rtt5);
build EndPacket;
}
@ifndef ADD_DP_OPS
# (v67,14) dfmpyhh+= -- "Rxx += dfmpyhh ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 1 0 0 s s s s s P P 0 t t t t t 0 1 1 x x x x x
define pcodeop dfmpyhh;
:dfmpyhh+= Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x54 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET) {
Rdd5 = dfmpyhh(rdd5, rss5, rtt5);
build EndPacket;
}
# (v67,14) dfmpylh+= -- "Rxx += dfmpylh ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 0 0 0 s s s s s P P 0 t t t t t 0 1 1 x x x x x
define pcodeop dfmpylh;
:dfmpylh+= Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x50 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET) {
Rdd5 = dfmpylh(rdd5, rss5, rtt5);
build EndPacket;
}
# (v5,14) dfmpyll -- "Rdd = dfmpyll ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 1 0 1 s s s s s P P 0 t t t t t 0 1 1 d d d d d
define pcodeop dfmpyll;
:dfmpyll Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x45 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET) {
Rdd5 = dfmpyll(rss5, rtt5);
build EndPacket;
}
@endif # not ADD_DP_OPS
#############################################################################################################
#
# WARNING: The following instructions were discovered within various QEMU revisions not associated with a
# specific processor version that we have been able to identify. These instructions are for experimental
# use only and may be intended for QEMU development testing only.
#
#############################################################################################################
@ifdef ADD_DP_OPS
# (??,14) dffixupn -- "Rdd = dffixupn ( Rss, Rtt )"
# NOTE: replaces V67 dfmpyll
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 1 0 1 s s s s s P P 0 t t t t t 0 1 1 d d d d d
define pcodeop dffixupn;
:dffixupn Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x45 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET) {
Rdd5 = dffixupn(rss5, rtt5);
build EndPacket;
}
# (??,14) dffixupd -- "Rdd = dffixupd ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 0 1 1 s s s s s P P 0 t t t t t 0 1 1 d d d d d
define pcodeop dffixupd;
:dffixupd Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x43 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & $(END_PACKET){
Rdd5 = dffixupd(rss5, rtt5);
build EndPacket;
}
# (??,14) dfrecipa -- "Rdd,Pe = dfrecipa ( Rss, Rtt )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 0 1 1 1 s s s s s P P 0 t t t t t 0 e e d d d d d
:dfrecipa Rdd5,pu0506,rss5,rtt5 EndPacket is iclass=14 & op2127=0x47 & op13=0 & op7=0 & pu0506_ & pu0506 & rss5 & rtt5 & Rdd5 & $(END_PACKET)
unimpl
# (??,14) dfmpyhh -- "Rdd += dfmpyhh ( Rss, Rtt )"
# NOTE: unexplained redfinition of V67 dfmpyhh +=
# NOTE: conflicts with dfmpy+= :lib (see below)
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 0 1 0 s s s s s P P 0 t t t t t 0 1 1 x x x x x
# :dfmpyhh+= Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x52 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET)
# unimpl
# (??,14) dfmpy+= -- "Rxx += dfmpy ( Rss, Rtt )"
# NOTE: replaces V67 dfmpylh +=
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 0 0 0 s s s s s P P 0 t t t t t 0 1 1 x x x x x
:dfmpy+= Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x50 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET) {
Rdd5 = rdd5 f+ (rss5 f* rtt5);
build EndPacket;
}
# (??,14) dfmpy-= -- "Rxx -= dfmpy ( Rss, Rtt )"
# NOTE: replaces V67 dfmpyhh +=
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 1 0 0 s s s s s P P 0 t t t t t 0 1 1 x x x x x
:dfmpy-= Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x54 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET) {
Rdd5 = rdd5 f- (rss5 f* rtt5);
build EndPacket;
}
# (??,14) dfmpy+= -- "Rxx += dfmpy ( Rss, Rtt ) :lib"
# NOTE: conflicts with replacement above for dfmpyhh +=
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 0 1 0 s s s s s P P 0 t t t t t 0 1 1 x x x x x
:dfmpy+=^":lib" Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x52 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET) {
Rdd5 = rdd5 f+ (rss5 f* rtt5);
build EndPacket;
}
# (??,14) dfmpy-= -- "Rxx -= dfmpy ( Rss, Rtt ) :lib"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 1 1 0 s s s s s P P 0 t t t t t 0 1 1 x x x x x
:dfmpy-=^":lib" Rdd5,rss5,rtt5 EndPacket is iclass=14 & op2127=0x56 & op13=0 & op0507=3 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET) {
Rdd5 = rdd5 f- (rss5 f* rtt5);
build EndPacket;
}
# (??,14) dfmpy+= -- "Rxx += dfmpy ( Rss, Rtt, Pu ) :scale"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 0 1 1 1 s s s s s P P 0 t t t t t 0 u u x x x x x
:dfmpy+=^":scale" Rdd5,rss5,rtt5,pu0506 EndPacket is iclass=14 & op2127=0x57 & op13=0 & op7=0 & pu0506 & rss5 & rtt5 & Rdd5 & rdd5 & $(END_PACKET) {
Rdd5 = multiplyAddScale(Rdd5, rss5, rtt5);
build EndPacket;
}
# (??,8) dffixupr -- "Rdd = dffixupr ( Rss )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 0 + + + + + 1 0 0 d d d d d
define pcodeop dffixupr;
:dffixupr Rdd5,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0 & op0507=4 & rss5 & Rdd5 & $(END_PACKET) {
Rdd5 = dffixupr(rss5);
build EndPacket;
}
# (??,8) dfinvsqrta -- "Rdd32 , Pe4 = dfinvsqrta ( Rss32 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 0 0 0 0 0 1 1 1 s s s s s P P 1 + + + + + 0 e e d d d d d
:dfinvsqrta Rdd5,pu0506,rss5 EndPacket is iclass=8 & op2127=0x07 & op0813=0x20 & op7=0 & pu0506_ & pu0506 & rss5 & Rdd5 & $(END_PACKET)
unimpl
@endif # ADD_DP_OPS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,618 @@
Hexagon V69 HVX instruction patterns
0 0 0 1 1 1 1 0 - - 0 - - 0 0 0 P P 1 - 0 0 1 0 1 0 0 - - - - - vwhist256
0 0 0 1 1 1 1 0 - - 0 - - 0 0 0 P P 1 - 0 0 1 1 1 0 0 - - - - - vwhist256:sat
0 0 0 1 1 1 1 0 - - 0 - - 0 0 0 P P 1 - 0 1 0 - 1 0 0 - - - - - vwhist128
0 0 0 1 1 1 1 0 - - 0 - - 0 0 0 P P 1 - 0 1 1 i 1 0 0 - - - - - vwhist128(#u1)
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 - - 0 1 0 1 0 0 - - - - - vwhist256(Qv4)
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 - - 0 1 1 1 0 0 - - - - - vwhist256(Qv4):sat
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 - - 1 0 - 1 0 0 - - - - - vwhist128(Qv4)
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 - - 1 1 i 1 0 0 - - - - - vwhist128(Qv4,#u1)
0 0 0 1 1 1 1 0 t t 0 - - - 1 1 P P 0 - - - s s 0 0 0 0 0 0 d d Qd4=and(Qs4,Qt4)
0 0 0 1 1 1 1 0 t t 0 - - - 1 1 P P 0 - - - s s 0 0 0 0 0 1 d d Qd4=or(Qs4,Qt4)
0 0 0 1 1 1 1 0 t t 0 - - - 1 1 P P 0 - - - s s 0 0 0 0 1 1 d d Qd4=xor(Qs4,Qt4)
0 0 0 1 1 1 1 0 t t 0 - - - 1 1 P P 0 - - - s s 0 0 0 1 0 0 d d Qd4=or(Qs4,!Qt4)
0 0 0 1 1 1 1 0 t t 0 - - - 1 1 P P 0 - - - s s 0 0 0 1 0 1 d d Qd4=and(Qs4,!Qt4)
0 0 0 1 1 1 1 0 t t 0 - - - 1 1 P P 0 - - - s s 0 0 0 1 1 0 d d Qd4.b=vshuffe(Qs4.h,Qt4.h)
0 0 0 1 1 1 1 0 t t 0 - - - 1 1 P P 0 - - - s s 0 0 0 1 1 1 d d Qd4.h=vshuffe(Qs4.w,Qt4.
0 0 0 1 1 0 1 0 0 1 0 v v v v v P P - u u u u u - s s d d d d d if (!Ps) Vdd=vcombine(Vu,Vv)
0 0 0 1 1 0 1 0 0 1 1 v v v v v P P - u u u u u - s s d d d d d if (Ps) Vdd=vcombine(Vu,Vv)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vdd=vcombine(Vu,Vv)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vdd.h=vshuffoe(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vdd.b=vshuffoe(Vu.b,Vv.b)
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 1 u u u u u - t t d d d d d Vdd=vswap(Qt4,Vu,Vv)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 0 0 1 d d d d d Vdd.uh=vzxt(Vu.ub)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 0 1 0 d d d d d Vdd.uw=vzxt(Vu.uh)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 0 1 1 d d d d d Vdd.h=vsxt(Vu.b)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 1 0 0 d d d d d Vdd.w=vsxt(Vu.h)
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vdd.b=vadd(Vuu.b,Vvv.b)
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vdd.h=vadd(Vuu.h,Vvv.h)
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vdd.w=vadd(Vuu.w,Vvv.w)
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vdd.ub=vadd(Vuu.ub,Vvv.ub):sat
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vdd.uh=vadd(Vuu.uh,Vvv.uh):sat
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vdd.h=vadd(Vuu.h,Vvv.h):sat
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vdd.w=vadd(Vuu.w,Vvv.w):sat
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vdd.b=vsub(Vuu.b,Vvv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vdd.h=vsub(Vuu.h,Vvv.h)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vdd.w=vsub(Vuu.w,Vvv.w)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vdd.ub=vsub(Vuu.ub,Vvv.ub):sat
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vdd.uh=vsub(Vuu.uh,Vvv.uh):sat
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vdd.h=vsub(Vuu.h,Vvv.h):sat
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vdd.w=vsub(Vuu.w,Vvv.w):sat
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vdd.b=vadd(Vuu.b,Vvv.b):sat
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vdd.b=vsub(Vuu.b,Vvv.b):sat
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vdd.uw=vadd(Vuu.uw,Vvv.uw):sat
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vdd.uw=vsub(Vuu.uw,Vvv.uw):sat
0 0 0 1 1 1 1 0 - - 0 - - - 1 1 P P 0 - - - s s 0 0 0 0 1 0 d d Qd4=not(Qs4)
0 0 0 1 1 1 1 0 v v 0 - - 0 1 1 P P 1 u u u u u 0 0 0 d d d d d Vd=vand(Qv4,Vu)
0 0 0 1 1 1 1 0 v v 0 - - 0 1 1 P P 1 u u u u u 0 0 1 d d d d d Vd=vand(!Qv4,Vu)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.ub=vmin(Vu.ub,Vv.ub)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.uh=vmin(Vu.uh,Vv.uh)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.h=vmin(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.w=vmin(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.ub=vmax(Vu.ub,Vv.ub)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.uh=vmax(Vu.uh,Vv.uh)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.h=vmax(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.w=vmax(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.b=vmin(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.b=vmax(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 1 u u u u u 0 0 1 d d d d d Vd.sf=vmax(Vu.sf,Vv.sf)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 1 u u u u u 0 1 0 d d d d d Vd.sf=vmin(Vu.sf,Vv.sf)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 1 u u u u u 0 1 1 d d d d d Vd.hf=vmax(Vu.hf,Vv.hf)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 1 u u u u u 1 0 0 d d d d d Vd.hf=vmin(Vu.hf,Vv.hf)
0 0 0 1 1 1 1 0 - - 0 - - - 0 0 P P 0 u u u u u 0 0 0 d d d d d Vd.h=vabs(Vu.h)
0 0 0 1 1 1 1 0 - - 0 - - - 0 0 P P 0 u u u u u 0 0 1 d d d d d Vd.h=vabs(Vu.h):sat
0 0 0 1 1 1 1 0 - - 0 - - - 0 0 P P 0 u u u u u 0 1 0 d d d d d Vd.w=vabs(Vu.w)
0 0 0 1 1 1 1 0 - - 0 - - - 0 0 P P 0 u u u u u 0 1 1 d d d d d Vd.w=vabs(Vu.w):sat
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 1 0 0 d d d d d Vd.b=vabs(Vu.b)
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 1 0 1 d d d d d Vd.b=vabs(Vu.b):sat
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.w=vadd(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.ub=vadd(Vu.ub,Vv.ub):sat
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.uh=vadd(Vu.uh,Vv.uh):sat
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.h=vadd(Vu.h,Vv.h):sat
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.w=vadd(Vu.w,Vv.w):sat
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.b=vsub(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.h=vsub(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.w=vsub(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.ub=vsub(Vu.ub,Vv.ub):sat
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.uh=vsub(Vu.uh,Vv.uh):sat
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.h=vsub(Vu.h,Vv.h):sat
0 0 0 1 1 1 0 0 0 1 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.w=vsub(Vu.w,Vv.w):sat
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.ub=vadd(Vu.ub,Vv.b):sat
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.ub=vsub(Vu.ub,Vv.b):sat
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.b=vadd(Vu.b,Vv.b):sat
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.b=vsub(Vu.b,Vv.b):sat
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.uw=vadd(Vu.uw,Vv.uw):sat
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.b=vadd(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.h=vadd(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.uw=vsub(Vu.uw,Vv.uw):sat
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 1 u u u u u 0 x x d d d d d Vd.w=vadd(Vu.w,Vv.w,Qx4):carry
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 1 u u u u u 1 x x d d d d d Vd.w=vsub(Vu.w,Vv.w,Qx4):carry
0 0 0 1 1 1 0 1 1 0 0 v v v v v P P 1 u u u u u 0 s s d d d d d Vd.w=vadd(Vu.w,Vv.w,Qs4):carry:sat
0 0 0 1 1 1 0 1 1 0 1 v v v v v P P 1 u u u u u 0 e e d d d d d Vd.w,Qe4=vadd(Vu.w,Vv.w):carry
0 0 0 1 1 1 0 1 1 0 1 v v v v v P P 1 u u u u u 1 e e d d d d d Vd.w,Qe4=vsub(Vu.w,Vv.w):carry
1 1 0 0 0 0 1 0 1 1 0 s s s s s P P - t t t t t - x x d d d d d Rdd=add(Rss,Rtt,Px):carry
1 1 0 0 0 0 1 0 1 1 1 s s s s s P P - t t t t t - x x d d d d d Rdd=sub(Rss,Rtt,Px):carry
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd=vand(Vu,Vv)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd=vor(Vu,Vv)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd=vxor(Vu,Vv)
0 0 0 1 1 1 1 0 - - 0 - - - 0 0 P P 0 u u u u u 1 0 0 d d d d d Vd=vnot(Vu)
0 0 0 1 1 0 1 0 0 0 0 - - - - - P P - u u u u u - s s d d d d d if (Ps) Vd=Vu
0 0 0 1 1 0 1 0 0 0 1 - - - - - P P - u u u u u - s s d d d d d if (!Ps) Vd=Vu
0 0 0 1 1 1 1 0 - - 0 - - 0 1 1 P P 1 u u u u u 1 1 1 d d d d d Vd=Vu
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 1 1 0 d d d d d Vd.tmp=Vu
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vdd.tmp=vcombine(Vu,Vv)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.ub=vavg(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.uh=vavg(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.h=vavg(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.w=vavg(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.b=vnavg(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.h=vnavg(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.w=vnavg(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.ub=vavg(Vu.ub,Vv.ub):rnd
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.uh=vavg(Vu.uh,Vv.uh):rnd
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.h=vavg(Vu.h,Vv.h):rnd
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.w=vavg(Vu.w,Vv.w):rnd
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 1 u u u u u 0 1 0 d d d d d Vd.uw=vavg(Vu.uw,Vv.uw)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 1 u u u u u 0 1 1 d d d d d Vd.uw=vavg(Vu.uw,Vv.uw):rnd
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 1 u u u u u 1 0 0 d d d d d Vd.b=vavg(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 1 u u u u u 1 0 1 d d d d d Vd.b=vavg(Vu.b,Vv.b):rnd
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 1 u u u u u 1 1 0 d d d d d Vd.b=vnavg(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 0 0 0 0 x x Qx4&=vcmp.eq(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 0 0 0 1 x x Qx4&=vcmp.eq(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 0 0 1 0 x x Qx4&=vcmp.eq(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 0 1 0 0 x x Qx4&=vcmp.gt(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 0 1 0 1 x x Qx4&=vcmp.gt(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 0 1 1 0 x x Qx4&=vcmp.gt(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 1 0 0 0 x x Qx4&=vcmp.gt(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 1 0 0 1 x x Qx4&=vcmp.gt(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 1 0 1 0 x x Qx4&=vcmp.gt(Vu.uw,Vv.uw)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 1 1 0 0 x x Qx4|=vcmp.gt(Vu.sf,Vv.sf)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 0 1 1 0 1 x x Qx4|=vcmp.gt(Vu.hf,Vv.hf)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 0 0 0 0 x x Qx4|=vcmp.eq(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 0 0 0 1 x x Qx4|=vcmp.eq(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 0 0 1 0 x x Qx4|=vcmp.eq(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 0 1 0 0 x x Qx4|=vcmp.gt(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 0 1 0 1 x x Qx4|=vcmp.gt(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 0 1 1 0 x x Qx4|=vcmp.gt(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 1 0 0 0 x x Qx4|=vcmp.gt(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 1 0 0 1 x x Qx4|=vcmp.gt(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 1 0 1 0 x x Qx4|=vcmp.gt(Vu.uw,Vv.uw)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 1 1 0 0 d d Qd4=vcmp.gt(Vu.sf,Vv.sf)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 0 1 1 1 0 1 d d Qd4=vcmp.gt(Vu.hf,Vv.hf)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 0 0 0 0 x x Qx4^=vcmp.eq(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 0 0 0 1 x x Qx4^=vcmp.eq(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 0 0 1 0 x x Qx4^=vcmp.eq(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 0 1 0 0 x x Qx4^=vcmp.gt(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 0 1 0 1 x x Qx4^=vcmp.gt(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 0 1 1 0 x x Qx4^=vcmp.gt(Vu.w,Vv.w)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 1 0 0 0 x x Qx4^=vcmp.gt(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 1 0 0 1 x x Qx4^=vcmp.gt(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 0 1 0 1 0 x x Qx4^=vcmp.gt(Vu.uw,Vv.uw)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 1 0 0 1 0 x x Qx4&=vcmp.gt(Vu.sf,Vv.sf)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 1 0 0 1 1 x x Qx4&=vcmp.gt(Vu.hf,Vv.hf)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 1 1 0 1 0 x x Qx4^=vcmp.gt(Vu.sf,Vv.sf)
0 0 0 1 1 1 0 0 1 0 0 v v v v v P P 1 u u u u u 1 1 1 0 1 1 x x Qx4^=vcmp.gt(Vu.hf,Vv.hf)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 0 0 0 0 d d Qd4=vcmp.eq(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 0 0 0 1 d d Qd4=vcmp.eq(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 0 0 1 0 d d Qd4=vcmp.eq(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 0 1 0 0 d d Qd4=vcmp.gt(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 0 1 0 1 d d Qd4=vcmp.gt(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 0 1 1 0 d d Qd4=vcmp.gt(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 1 0 0 0 d d Qd4=vcmp.gt(Vu.ub,Vv.ub)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 1 0 0 1 d d Qd4=vcmp.gt(Vu.uh,Vv.uh)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 0 u u u u u 0 0 1 0 1 0 d d Qd4=vcmp.gt(Vu.uw,Vv.uw)
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 0 0 0 x x x x x if (Qv4) Vx.b+=Vu.b
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 0 0 1 x x x x x if (Qv4) Vx.h+=Vu.h
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 0 1 0 x x x x x if (Qv4) Vx.w+=Vu.w
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 0 1 1 x x x x x if (!Qv4) Vx.b+=Vu.b
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 1 0 0 x x x x x if (!Qv4) Vx.h+=Vu.h
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 1 0 1 x x x x x if (!Qv4) Vx.w+=Vu.w
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 1 1 0 x x x x x if (Qv4) Vx.b-=Vu.b
0 0 0 1 1 1 1 0 v v 0 - - 0 0 1 P P 1 u u u u u 1 1 1 x x x x x if (Qv4) Vx.h-=Vu.h
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 u u u u u 0 0 0 x x x x x if (Qv4) Vx.w-=Vu.w
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 u u u u u 0 0 1 x x x x x if (!Qv4) Vx.b-=Vu.b
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 u u u u u 0 1 0 x x x x x if (!Qv4) Vx.h-=Vu.h
0 0 0 1 1 1 1 0 v v 0 - - 0 1 0 P P 1 u u u u u 0 1 1 x x x x x if (!Qv4) Vx.w-=Vu.w
0 0 0 1 1 1 1 0 1 1 1 v v v v v P P 1 u u u u u - t t d d d d d Vd=vmux(Qt4,Vu,Vv)
0 0 0 1 1 1 0 1 1 0 0 v v v v v P P 1 u u u u u 1 1 1 d d d d d Vd.w=vsatdw(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.uh=vsat(Vu.uw,Vv.uw)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.ub=vsat(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.h=vsat(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.b=vshuffe(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.b=vshuffo(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.h=vshuffe(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.h=vshuffo(Vu.h,Vv.h)
1 0 0 1 0 0 1 0 0 0 0 s s s s s P P 0 u u u u u 0 0 1 d d d d d Rd=vextract(Vu,Rs)
0 0 1 0 1 1 1 1 0 0 0 t t t t t P P u - - 0 1 0 - - - v v v v v vtmp.h=vgather(Rt,Mu,Vvv.w).h
0 0 1 0 1 1 1 1 0 0 0 t t t t t P P u - - 1 1 0 - s s v v v v v if (Qs4) vtmp.h=vgather(Rt,Mu,Vvv.w).h
0 0 1 0 1 1 1 1 0 0 0 t t t t t P P u - - 0 0 0 - - - v v v v v vtmp.w=vgather(Rt,Mu,Vv.w).w
0 0 1 0 1 1 1 1 0 0 0 t t t t t P P u - - 0 0 1 - - - v v v v v vtmp.h=vgather(Rt,Mu,Vv.h).h
0 0 1 0 1 1 1 1 0 0 0 t t t t t P P u - - 1 0 0 - s s v v v v v if (Qs4) vtmp.w=vgather(Rt,Mu,Vv.w).w
0 0 1 0 1 1 1 1 0 0 0 t t t t t P P u - - 1 0 1 - s s v v v v v if (Qs4) vtmp.h=vgather(Rt,Mu,Vv.h).h
0 0 1 0 1 0 0 0 0 0 0 t t t t t P P i 0 0 i i i 0 0 0 d d d d d Vd=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 0 1 0 t t t t t P P i 0 0 i i i 0 0 0 d d d d d Vd=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 0 1 0 d d d d d if (Pv) Vd=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 0 1 1 d d d d d if (!Pv) Vd=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 0 1 0 d d d d d if (Pv) Vd=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 0 1 1 d d d d d if (!Pv) Vd=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 1 0 0 0 x x x x x P P - 0 0 i i i 0 0 0 d d d d d Vd=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 0 1 0 x x x x x P P - 0 0 i i i 0 0 0 d d d d d Vd=vmem(Rx++#s3):nt
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 0 1 0 d d d d d if (Pv) Vd=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 0 1 1 d d d d d if (!Pv) Vd=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 0 1 0 d d d d d if (Pv) Vd=vmem(Rx++#s3):nt
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 0 1 1 d d d d d if (!Pv) Vd=vmem(Rx++#s3):nt
0 0 1 0 1 0 1 1 0 0 0 x x x x x P P u 0 0 - - - 0 0 0 d d d d d Vd=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 0 1 0 x x x x x P P u 0 0 - - - 0 0 0 d d d d d Vd=vmem(Rx++Mu):nt
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 0 1 0 d d d d d if (Pv) Vd=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 0 1 1 d d d d d if (!Pv) Vd=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 0 1 0 d d d d d if (Pv) Vd=vmem(Rx++Mu):nt
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 0 1 1 d d d d d if (!Pv) Vd=vmem(Rx++Mu):nt
0 0 1 0 1 0 0 0 0 0 0 t t t t t P P i 0 0 i i i 0 0 1 d d d d d Vd.cur=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 0 1 0 t t t t t P P i 0 0 i i i 0 0 1 d d d d d Vd.cur=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 1 0 0 d d d d d if (Pv) Vd.cur=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 1 0 1 d d d d d if (!Pv) Vd.cur=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 1 0 0 d d d d d if (Pv) Vd.cur=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 1 0 1 d d d d d if (!Pv) Vd.cur=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 1 0 0 0 x x x x x P P - 0 0 i i i 0 0 1 d d d d d Vd.cur=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 0 1 0 x x x x x P P - 0 0 i i i 0 0 1 d d d d d Vd.cur=vmem(Rx++#s3):nt
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 1 0 0 d d d d d if (Pv) Vd.cur=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 1 0 1 d d d d d if (!Pv) Vd.cur=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 1 0 0 d d d d d if (Pv) Vd.cur=vmem(Rx++#s3):nt
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 1 0 1 d d d d d if (!Pv) Vd.cur=vmem(Rx++#s3):nt
0 0 1 0 1 0 1 1 0 0 0 x x x x x P P u 0 0 - - - 0 0 1 d d d d d Vd.cur=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 0 1 0 x x x x x P P u 0 0 - - - 0 0 1 d d d d d Vd.cur=vmem(Rx++Mu):nt
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 1 0 0 d d d d d if (Pv) Vd.cur=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 1 0 1 d d d d d if (!Pv) Vd.cur=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 1 0 0 d d d d d if (Pv) Vd.cur=vmem(Rx++Mu):nt
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 1 0 1 d d d d d if (!Pv) Vd.cur=vmem(Rx++Mu):nt
0 0 1 0 1 0 0 0 0 0 0 t t t t t P P i 0 0 i i i 0 1 0 d d d d d Vd.tmp=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 0 1 0 t t t t t P P i 0 0 i i i 0 1 0 d d d d d Vd.tmp=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 1 1 0 d d d d d if (Pv) Vd.tmp=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 1 1 1 d d d d d if (!Pv) Vd.tmp=vmem(Rt+#s4)
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 1 1 0 d d d d d if (Pv) Vd.tmp=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 1 1 1 d d d d d if (!Pv) Vd.tmp=vmem(Rt+#s4):nt
0 0 1 0 1 0 0 1 0 0 0 x x x x x P P - 0 0 i i i 0 1 0 d d d d d Vd.tmp=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 0 1 0 x x x x x P P - 0 0 i i i 0 1 0 d d d d d Vd.tmp=vmem(Rx++#s3):nt
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 1 1 0 d d d d d if (Pv) Vd.tmp=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 1 1 1 d d d d d if (!Pv) Vd.tmp=vmem(Rx++#s3)
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 1 1 0 d d d d d if (Pv) Vd.tmp=vmem(Rx++#s3):nt
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 1 1 1 d d d d d if (!Pv) Vd.tmp=vmem(Rx++#s3):nt
0 0 1 0 1 0 1 1 0 0 0 x x x x x P P u 0 0 - - - 0 1 0 d d d d d Vd.tmp=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 0 1 0 x x x x x P P u 0 0 - - - 0 1 0 d d d d d Vd.tmp=vmem(Rx++Mu):nt
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 1 1 0 d d d d d if (Pv) Vd.tmp=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 1 1 1 d d d d d if (!Pv) Vd.tmp=vmem(Rx++Mu)
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 1 1 0 d d d d d if (Pv) Vd.tmp=vmem(Rx++Mu):nt
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 1 1 1 d d d d d if (!Pv) Vd.tmp=vmem(Rx++Mu):nt
0 0 1 0 1 0 0 0 0 0 0 t t t t t P P i 0 0 i i i 1 1 1 d d d d d Vd=vmemu(Rt+#s4)
0 0 1 0 1 0 0 1 0 0 0 x x x x x P P - 0 0 i i i 1 1 1 d d d d d Vd=vmemu(Rx++#s3)
0 0 1 0 1 0 1 1 0 0 0 x x x x x P P u 0 0 - - - 1 1 1 d d d d d Vd=vmemu(Rx++Mu)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 1 u u u u u 0 i i x x x x x Vxx.w+=v6mpy(Vuu.ub,Vvv.b,#u2):v
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 1 u u u u u 1 i i x x x x x Vxx.w+=v6mpy(Vuu.ub,Vvv.b,#u2):h
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 1 u u u u u 0 i i d d d d d Vdd.w=v6mpy(Vuu.ub,Vvv.b,#u2):v
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 1 u u u u u 1 i i d d d d d Vdd.w=v6mpy(Vuu.ub,Vvv.b,#u2):h
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 1 u u u u u 0 1 0 x x x x x Vxx.w+=vadd(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 1 u u u u u 1 0 0 x x x x x Vxx.w+=vadd(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 1 u u u u u 1 0 1 x x x x x Vxx.h+=vadd(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vdd.h=vadd(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vdd.w=vadd(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vdd.w=vadd(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vdd.h=vsub(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vdd.w=vsub(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 1 0 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vdd.w=vsub(Vu.h,Vv.h)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 1 1 1 d d d d d Vdd.h=vdmpy(Vuu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 1 1 1 x x x x x Vxx.h+=vdmpy(Vuu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 0 0 1 d d d d d Vd.w=vdmpy(Vuu.h,Rt.uh,#1):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 0 1 1 d d d d d Vd.w=vdmpy(Vuu.h,Rt.h):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 1 0 0 d d d d d Vdd.w=vdmpy(Vuu.h,Rt.b)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 0 0 1 x x x x x Vx.w+=vdmpy(Vuu.h,Rt.uh,#1):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 0 1 0 x x x x x Vx.w+=vdmpy(Vuu.h,Rt.h):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 1 0 0 x x x x x Vxx.w+=vdmpy(Vuu.h,Rt.b)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 1 u u u u u 0 1 1 x x x x x Vx.w+=vdmpy(Vu.h,Vv.h):sat
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 1 0 0 d d d d d Vd.h=vlut4(Vu.uh,Rtt.h)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 1 0 0 x x x x x Vx.h=vmpa(Vx.h,Vu.h,Rtt.h):sat
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 1 0 1 x x x x x Vx.h=vmpa(Vx.h,Vu.uh,Rtt.uh):sat
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 1 1 0 x x x x x Vx.h=vmps(Vx.h,Vu.uh,Rtt.uh):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 1 1 0 d d d d d Vdd.h=vmpa(Vuu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 1 1 1 d d d d d Vdd.w=vmpa(Vuu.h,Rt.b)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 1 1 0 x x x x x Vxx.h+=vmpa(Vuu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 1 1 1 x x x x x Vxx.w+=vmpa(Vuu.h,Rt.b)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 0 1 1 d d d d d Vdd.h=vmpa(Vuu.ub,Rt.ub)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 0 u u u u u 1 0 1 d d d d d Vdd.w=vmpa(Vuu.uh,Rt.b)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 0 1 0 x x x x x Vxx.w+=vmpa(Vuu.uh,Rt.b)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 1 u u u u u 1 0 0 x x x x x Vxx.h+=vmpa(Vuu.ub,Rt.ub)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vdd.h=vmpa(Vuu.ub,Vvv.b)
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vdd.h=vmpa(Vuu.ub,Vvv.ub)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 1 0 1 d d d d d Vdd.h=vmpy(Vu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 1 0 1 x x x x x Vxx.h+=vmpy(Vu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 0 u u u u u 0 0 0 d d d d d Vdd.w=vmpy(Vu.h,Rt.h)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 0 u u u u u 0 1 1 d d d d d Vdd.uw=vmpy(Vu.uh,Rt.uh)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 1 u u u u u 0 0 0 x x x x x Vxx.w+=vmpy(Vu.h,Rt.h):sat
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 1 u u u u u 0 0 1 x x x x x Vxx.uw+=vmpy(Vu.uh,Rt.uh)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 0 0 0 x x x x x Vxx.uh+=vmpy(Vu.ub,Rt.ub)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 1 u u u u u 1 1 0 x x x x x Vxx.w+=vmpy(Vu.h,Rt.h)
0 0 0 1 1 0 0 1 1 1 0 t t t t t P P 0 u u u u u 0 0 0 d d d d d Vdd.uh=vmpy(Vu.ub,Rt.ub)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vdd.h=vmpy(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vdd.uh=vmpy(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vdd.h=vmpy(Vu.ub,Vv.b)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 1 u u u u u 1 0 0 x x x x x Vxx.h+=vmpy(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 1 u u u u u 1 0 1 x x x x x Vxx.uh+=vmpy(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 1 u u u u u 1 1 0 x x x x x Vxx.h+=vmpy(Vu.ub,Vv.b)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vdd.uw=vmpy(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 1 u u u u u 0 0 0 x x x x x Vxx.uw+=vmpy(Vu.uh,Vv.uh)
0 0 0 1 1 1 1 1 1 0 0 v v v v v P P 1 u u u u u 0 0 0 d d d d d Vdd.qf32=vmpy(Vu.qf16,Vv.hf)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 1 u u u u u 0 1 1 d d d d d Vd.qf16=vmpy(Vu.qf16,Vv.qf16)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 1 u u u u u 1 0 0 d d d d d Vd.qf16=vmpy(Vu.hf,Vv.hf)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 1 u u u u u 1 0 1 d d d d d Vd.qf16=vmpy(Vu.qf16,Vv.hf)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 1 u u u u u 1 1 0 d d d d d Vdd.qf32=vmpy(Vu.qf16,Vv.qf16)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 1 u u u u u 1 1 1 d d d d d Vdd.qf32=vmpy(Vu.hf,Vv.hf)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.h=vmpyi(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 1 u u u u u 1 0 0 x x x x x Vx.h+=vmpyi(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 1 u u u u u 1 0 1 x x x x x Vx.w+=vmpyie(Vu.w,Vv.uh)
0 0 0 1 1 1 0 0 0 1 0 v v v v v P P 1 u u u u u 0 0 0 x x x x x Vx.w+=vmpyie(Vu.w,Vv.h)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.w=vmpyie(Vu.w,Vv.uh)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.w=vmpyio(Vu.w,Vv.h)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 1 u u u u u 0 1 1 x x x x x Vx.w+=vmpyi(Vu.w,Rt.h)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 0 u u u u u 1 1 1 d d d d d Vd.w=vmpyi(Vu.w,Rt.h)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 1 u u u u u 0 0 0 d d d d d Vd.qf32=vmpy(Vu.qf32,Vv.qf32)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 1 u u u u u 0 0 1 d d d d d Vd.qf32=vmpy(Vu.sf,Vv.sf)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 1 u u u u u 0 1 1 x x x x x Vxx+=vmpyo(Vu.w,Vv.h)
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 1 u u u u u 1 1 0 x x x x x Vx.w+=vmpyo(Vu.w,Vv.h):<<1:sat:shift
0 0 0 1 1 1 0 0 0 0 1 v v v v v P P 1 u u u u u 1 1 1 x x x x x Vx.w+=vmpyo(Vu.w,Vv.h):<<1:rnd:sat:shift
0 0 0 1 1 1 1 0 1 0 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vdd=vmpye(Vu.w,Vv.uh)
0 0 0 1 1 1 1 1 0 1 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.w=vmpyo(Vu.w,Vv.h):<<1:rnd:sat
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.w=vmpye(Vu.w,Vv.uh)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.w=vmpyo(Vu.w,Vv.h):<<1:sat
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 0 u u u u u 1 0 i d d d d d Vdd.w=vrmpy(Vuu.ub,Rt.b,#u1)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 1 u u u u u 1 0 i x x x x x Vxx.w+=vrmpy(Vuu.ub,Rt.b,#u1)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 u u u u u 1 1 i x x x x x Vxx.uw+=vrmpy(Vuu.ub,Rt.ub,#u1)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 u u u u u 1 1 i d d d d d Vdd.uw=vrmpy(Vuu.ub,Rt.ub,#u1)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 1 u u u u u 0 0 0 x x x x x Vx.uw+=vrmpy(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 1 u u u u u 0 0 1 x x x x x Vx.w+=vrmpy(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 1 u u u u u 0 1 0 x x x x x Vx.w+=vrmpy(Vu.ub,Vv.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 0 0 0 d d d d d Vdd.h=vtmpy(Vuu.b,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 0 0 1 d d d d d Vdd.h=vtmpy(Vuu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 0 0 0 x x x x x Vxx.h+=vtmpy(Vuu.b,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 0 0 1 x x x x x Vxx.h+=vtmpy(Vuu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 0 1 0 x x x x x Vxx.w+=vtmpy(Vuu.h,Rt.b)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 u u u u u 1 0 0 d d d d d Vdd.w=vtmpy(Vuu.h,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 1 0 1 d d d d d Vdd.uw=vdsad(Vuu.uh,Rt.uh)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 u u u u u 0 0 0 x x x x x Vxx.uw+=vdsad(Vuu.uh,Rt.uh)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 0 u u u u u 1 1 i d d d d d Vdd.uw=vrsad(Vuu.ub,Rt.ub,#u1)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 1 u u u u u 1 1 i x x x x x Vxx.uw+=vrsad(Vuu.ub,Rt.ub,#u1)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 0 1 0 d d d d d Vd.w=vdmpy(Vu.h,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 1 1 0 d d d d d Vd.h=vdmpy(Vu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 0 1 1 x x x x x Vx.w+=vdmpy(Vu.h,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 1 1 0 x x x x x Vx.h+=vdmpy(Vu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 0 0 0 d d d d d Vd.w=vdmpy(Vu.h,Rt.uh):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 0 u u u u u 0 1 0 d d d d d Vd.w=vdmpy(Vu.h,Rt.h):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 0 0 0 x x x x x Vx.w+=vdmpy(Vu.h,Rt.uh):sat
0 0 0 1 1 0 0 1 0 0 1 t t t t t P P 1 u u u u u 0 1 1 x x x x x Vx.w+=vdmpy(Vu.h,Rt.h):sat
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.w=vdmpy(Vu.h,Vv.h):sat
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 0 u u u u u 0 0 1 d d d d d Vd.h=vmpy(Vu.h,Rt.h):<<1:sat
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 0 u u u u u 0 1 0 d d d d d Vd.h=vmpy(Vu.h,Rt.h):<<1:md:sat
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 1 u u u u u 1 1 1 d d d d d Vd.uh=vmpy(Vu.uh,Vv.uh):>>16
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.w=vmpyieo(Vu.h,Vv.h)
0 0 0 1 1 0 0 1 0 1 0 t t t t t P P 1 u u u u u 0 1 0 x x x x x Vx.w+=vmpyi(Vu.w,Rt.b)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 0 0 0 d d d d d Vd.h=vmpyi(Vu.h,Rt.b)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 u u u u u 0 0 1 x x x x x Vx.h+=vmpyi(Vu.h,Rt.b)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 0 u u u u u 1 1 0 d d d d d Vd.w=vmpyi(Vu.w,Rt.ub)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 0 0 1 x x x x x Vx.w+=vmpyi(Vu.w,Rt.ub)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 u u u u u 0 0 0 d d d d d Vd.w=vmpyi(Vu.w,Rt.b)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 0 1 0 d d d d d Vd.uw=vmpye(Vu.uh,Rt.uh)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 0 1 1 x x x x x Vx.uw+=vmpye(Vu.uh,Rt.uh)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 0 1 1 d d d d d Vd.uw=vrmpy(Vu.ub,Rt.ub)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 0 u u u u u 1 0 0 d d d d d Vd.w=vrmpy(Vu.ub,Rt.b)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 1 0 0 x x x x x Vx.uw+=vrmpy(Vu.ub,Rt.ub)
0 0 0 1 1 0 0 1 0 0 0 t t t t t P P 1 u u u u u 1 0 1 x x x x x Vx.w+=vrmpy(Vu.ub,Rt.b)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.uw=vrmpy(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.w=vrmpy(Vu.b,Vv.b)
0 0 0 1 1 1 0 0 0 0 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.w=vrmpy(Vu.ub,Vv.b)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 - - - - 0 0 0 1 d d d d d Vd=vsplat(Rt)
0 0 0 1 1 0 0 1 1 1 0 t t t t t P P 0 - - - - - 0 0 1 d d d d d Vd.h=vsplat(Rt)
0 0 0 1 1 0 0 1 1 1 0 t t t t t P P 0 - - - - - 0 1 0 d d d d d Vd.b=vsplat(Rt)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 u u u u u 1 0 0 - - - x x Qx4|=vand(Vu,Rt)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 u u u u u 0 1 0 - 1 0 d d Qd4=vand(Vu,Rt)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 - - 0 u u 0 1 1 x x x x x Vx|=vand(Qu4,Rt)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 - - 1 u u 0 1 1 x x x x x Vx|=vand(!Qu4,Rt)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 - - 0 u u 1 0 1 d d d d d Vd=vand(Qu4,Rt)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 - - 1 u u 1 0 1 d d d d d Vd=vand(!Qu4,Rt)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.ub=vabsdiff(Vu.ub,Vv.ub)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.uh=vabsdiff(Vu.h,Vv.h)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.uh=vabsdiff(Vu.uh,Vv.uh)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.uw=vabsdiff(Vu.w,Vv.w)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 1 - - - - - 0 0 1 x x x x x Vx.w=vinsert(Rt)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 0 0 1 d d d d d Vd=vror(Vu,Rt)
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 0 0 0 d d d d d Vd=valign(Vu,Vv,Rt)
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 0 0 1 d d d d d Vd=vlalign(Vu,Vv,Rt)
0 0 0 1 1 1 1 0 0 0 1 v v v v v P P 1 u u u u u i i i d d d d d Vd=valign(Vu,Vv,#u3)
0 0 0 1 1 1 1 0 0 1 1 v v v v v P P 1 u u u u u i i i d d d d d Vd=vlalign(Vu,Vv,#u3)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd=vdelta(Vu,Vv)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd=vrdelta(Vu,Vv)
0 0 0 1 1 1 1 0 - - 0 - - - 0 0 P P 0 u u u u u 1 1 0 d d d d d Vd.h=vdeal(Vu.h)
0 0 0 1 1 1 1 0 - - 0 - - - 0 0 P P 0 u u u u u 1 1 1 d d d d d Vd.b=vdeal(Vu.b)
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 1 1 1 d d d d d Vd.h=vshuff(Vu.h)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 0 0 0 d d d d d Vd.b=vshuff(Vu.b)
0 0 0 1 1 1 1 1 0 0 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.b=vdeale(Vu.b,Vv.b)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.b=vpacke(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.h=vpacke(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.ub=vpack(Vu.h,Vv.h):sat
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.b=vpack(Vu.h,Vv.h):sat
0 0 0 1 1 1 1 1 1 1 0 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.uh=vpack(Vu.w,Vv.w):sat
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.h=vpack(Vu.w,Vv.w):sat
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.b=vpacko(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.h=vpacko(Vu.w,Vv.w)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 - - - - - 0 1 0 - 0 1 d d Qd4=vsetq(Rt)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 0 - - - - - 0 1 0 - 1 1 d d Qd4=vsetq2(Rt)
0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 0 1 1 d d d d d Vd.b=vlut32(Vu.b,Vv.b,Rt):nomatch
0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 0 0 1 d d d d d Vd.b=vlut32(Vu.b,Vv.b,Rt)
0 0 0 1 1 1 1 0 0 0 1 v v v v v P P 0 u u u u u i i i d d d d d Vd.b=vlut32(Vu.b,Vv.b,#u3)
0 0 0 1 1 0 1 0 1 0 1 v v v v v P P 1 u u u u u 1 1 1 x x x x x Vxx.w=vasrinto(Vu.w,Vv.w)
0 0 0 1 1 0 0 1 1 1 1 t t t t t P P 1 y y y y y 0 0 1 x x x x x vshuff(Vy,Vx,Rt)
0 0 0 1 1 0 0 1 1 1 1 t t t t t P P 1 y y y y y 0 1 0 x x x x x vdeal(Vy,Vx,Rt)
0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 0 1 1 d d d d d Vdd=vshuff(Vu,Vv,Rt)
0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 1 0 0 d d d d d Vdd=vdeal(Vu,Vv,Rt)
0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 1 0 0 d d d d d Vdd.h=vlut16(Vu.b,Vv.h,Rt):nomatch
0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 1 0 1 x x x x x Vx.b|=vlut32(Vu.b,Vv.b,Rt)
0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 1 1 0 d d d d d Vdd.h=vlut16(Vu.b,Vv.h,Rt)
0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 1 1 1 x x x x x Vxx.h|=vlut16(Vu.b,Vv.h,Rt)
0 0 0 1 1 1 0 0 1 1 0 v v v v v P P 1 u u u u u i i i x x x x x Vx.b|=vlut32(Vu.b,Vv.b,#u3)
0 0 0 1 1 1 0 0 1 1 1 v v v v v P P 1 u u u u u i i i x x x x x Vxx.h|=vlut16(Vu.b,Vv.h,#u3)
0 0 0 1 1 1 1 0 0 1 1 v v v v v P P 0 u u u u u i i i d d d d d Vdd.h=vlut16(Vu.b,Vv.h,#u3)
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 0 0 0 d d d d d Vdd.uh=vunpack(Vu.ub)
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 0 0 1 d d d d d Vdd.uw=vunpack(Vu.uh)
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 0 1 0 d d d d d Vdd.h=vunpack(Vu.b)
0 0 0 1 1 1 1 0 - - 0 - - - 0 1 P P 0 u u u u u 0 1 1 d d d d d Vdd.w=vunpack(Vu.h)
0 0 0 1 1 1 1 0 - - 0 - - 0 0 0 P P 1 u u u u u 0 0 0 x x x x x Vxx.h|=vunpacko(Vu.b)
0 0 0 1 1 1 1 0 - - 0 - - 0 0 0 P P 1 u u u u u 0 0 1 x x x x x Vxx.w|=vunpacko(Vu.h)
0 0 1 0 1 1 1 1 0 0 1 t t t t t P P u v v v v v 0 1 0 w w w w w vscatter(Rt,Mu,Vvv.w).h=Vw32
0 0 1 0 1 1 1 1 0 0 1 t t t t t P P u v v v v v 1 1 0 w w w w w vscatter(Rt,Mu,Vvv.w).h+=Vw32
0 0 1 0 1 1 1 1 1 0 1 t t t t t P P u v v v v v 0 s s w w w w w if (Qs4) vscatter(Rt,Mu,Vvv.w).h=Vw32
0 0 1 0 1 1 1 1 0 0 1 t t t t t P P u v v v v v 0 0 0 w w w w w vscatter(Rt,Mu,Vv.w).w=Vw32
0 0 1 0 1 1 1 1 0 0 1 t t t t t P P u v v v v v 0 0 1 w w w w w vscatter(Rt,Mu,Vv.h).h=Vw32
0 0 1 0 1 1 1 1 0 0 1 t t t t t P P u v v v v v 1 0 0 w w w w w vscatter(Rt,Mu,Vv.w).w+=Vw32
0 0 1 0 1 1 1 1 0 0 1 t t t t t P P u v v v v v 1 0 1 w w w w w vscatter(Rt,Mu,Vv.h).h+=Vw32
0 0 1 0 1 1 1 1 1 0 0 t t t t t P P u v v v v v 0 s s w w w w w if (Qs4) vscatter(Rt,Mu,Vv.w).w=Vw32
0 0 1 0 1 1 1 1 1 0 0 t t t t t P P u v v v v v 1 s s w w w w w if (Qs4) vscatter(Rt,Mu,Vv.h).h=Vw32
0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 0 0 0 d d d d d Vd.b=vasr(Vu.h,Vv.h,Rt):sat
0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 0 0 1 d d d d d Vd.uh=vasr(Vu.uw,Vv.uw,Rt):rnd:sat
0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 0 1 0 d d d d d Vd.uh=vasr(Vu.w,Vv.w,Rt):rnd:sat
0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 1 1 1 d d d d d Vd.ub=vasr(Vu.uh,Vv.uh,Rt):rnd:sat
0 0 0 1 1 0 0 0 v v v v v t t t P P 1 u u u u u 1 0 0 d d d d d Vd.uh=vasr(Vu.uw,Vv.uw,Rt):sat
0 0 0 1 1 0 0 0 v v v v v t t t P P 1 u u u u u 1 0 1 d d d d d Vd.ub=vasr(Vu.uh,Vv.uh,Rt):sat
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 0 1 0 d d d d d Vd.h=vasr(Vu.w,Vv.w,Rt)
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 0 1 1 d d d d d Vd.h=vasr(Vu.w,Vv.w,Rt):sat
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 0 0 d d d d d Vd.h=vasr(Vu.w,Vv.w,Rt):rnd:sat
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 0 1 d d d d d Vd.uh=vasr(Vu.w,Vv.w,Rt):sat
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 1 0 d d d d d Vd.ub=vasr(Vu.h,Vv.h,Rt):sat
0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 1 1 d d d d d Vd.ub=vasr(Vu.h,Vv.h,Rt):rnd:sat
0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 0 0 0 d d d d d Vd.b=vasr(Vu.h,Vv.h,Rt):rnd:sat
0 0 0 1 1 1 1 0 v v 0 - - 0 1 1 P P 1 - - 0 0 0 0 1 0 d d d d d Vd.b=prefixsum(Qv4)
0 0 0 1 1 1 1 0 v v 0 - - 0 1 1 P P 1 - - 0 0 1 0 1 0 d d d d d Vd.h=prefixsum(Qv4)
0 0 0 1 1 1 1 0 v v 0 - - 0 1 1 P P 1 - - 0 1 0 0 1 0 d d d d d Vd.w=prefixsum(Qv4)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 1 u u u u u 0 1 0 d d d d d Vd.qf16=vadd(Vu.qf16,Vv.qf16)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 1 u u u u u 0 1 1 d d d d d Vd.qf16=vadd(Vu.hf,Vv.hf)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 1 u u u u u 1 0 0 d d d d d Vd.qf16=vadd(Vu.qf16,Vv.hf)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 1 u u u u u 0 0 0 d d d d d Vd.qf32=vadd(Vu.qf32,Vv.qf32)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 1 u u u u u 0 0 1 d d d d d Vd.qf32=vadd(Vu.sf,Vv.sf)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 1 u u u u u 0 1 0 d d d d d Vd.qf32=vadd(Vu.qf32,Vv.sf)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 u u u u u 0 1 0 x x x x x Vx.w+=vasl(Vu.w,Rt)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 1 u u u u u 1 0 1 x x x x x Vx.w+=vasr(Vu.w,Rt)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 1 u u u u u 1 1 1 x x x x x Vx.h+=vasr(Vu.h,Rt)
0 0 0 1 1 0 0 1 1 0 1 t t t t t P P 1 u u u u u 1 0 1 x x x x x Vx.h+=vasl(Vu.h,Rt)
# 0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 0 0 0 d d d d d Vd.b=vasr(Vu.h,Vv.h,Rt):sat
# 0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 0 0 1 d d d d d Vd.uh=vasr(Vu.uw,Vv.uw,Rt):rnd:sat
# 0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 0 1 0 d d d d d Vd.uh=vasr(Vu.w,Vv.w,Rt):rnd:sat
# 0 0 0 1 1 0 0 0 v v v v v t t t P P 0 u u u u u 1 1 1 d d d d d Vd.ub=vasr(Vu.uh,Vv.uh,Rt):rnd:sat
# 0 0 0 1 1 0 0 0 v v v v v t t t P P 1 u u u u u 1 0 0 d d d d d Vd.uh=vasr(Vu.uw,Vv.uw,Rt):sat
# 0 0 0 1 1 0 0 0 v v v v v t t t P P 1 u u u u u 1 0 1 d d d d d Vd.ub=vasr(Vu.uh,Vv.uh,Rt):sat
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 1 0 1 d d d d d Vd.w=vasr(Vu.w,Rt)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 1 1 0 d d d d d Vd.h=vasr(Vu.h,Rt)
0 0 0 1 1 0 0 1 0 1 1 t t t t t P P 0 u u u u u 1 1 1 d d d d d Vd.w=vasl(Vu.w,Rt)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 0 u u u u u 0 0 0 d d d d d Vd.h=vasl(Vu.h,Rt)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 0 u u u u u 0 0 1 d d d d d Vd.uw=vlsr(Vu.uw,Rt)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 0 u u u u u 0 1 0 d d d d d Vd.uh=vlsr(Vu.uh,Rt)
0 0 0 1 1 0 0 1 1 0 0 t t t t t P P 0 u u u u u 0 1 1 d d d d d Vd.ub=vlsr(Vu.ub,Rt)
# 0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 0 1 0 d d d d d Vd.h=vasr(Vu.w,Vv.w,Rt)
# 0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 0 1 1 d d d d d Vd.h=vasr(Vu.w,Vv.w,Rt):sat
# 0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 0 0 d d d d d Vd.h=vasr(Vu.w,Vv.w,Rt):rnd:sat
# 0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 0 1 d d d d d Vd.uh=vasr(Vu.w,Vv.w,Rt):sat
# 0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 1 0 d d d d d Vd.ub=vasr(Vu.h,Vv.h,Rt):sat
# 0 0 0 1 1 0 1 1 v v v v v t t t P P 0 u u u u u 1 1 1 d d d d d Vd.ub=vasr(Vu.h,Vv.h,Rt):rnd:sat
# 0 0 0 1 1 0 1 1 v v v v v t t t P P 1 u u u u u 0 0 0 d d d d d Vd.b=vasr(Vu.h,Vv.h,Rt):rnd:sat
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.w=vasr(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.w=vlsr(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.h=vlsr(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.h=vasr(Vu.h,Vv.h)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.w=vasl(Vu.w,Vv.w)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.h=vasl(Vu.h,Vv.h)
0 0 0 1 1 1 0 1 0 0 0 v v v v v P P 0 u u u u u 0 0 0 d d d d d Vd.uh=vasr(Vuu.w,Vv.uh):sat
0 0 0 1 1 1 0 1 0 0 0 v v v v v P P 0 u u u u u 0 0 1 d d d d d Vd.uh=vasr(Vuu.w,Vv.uh):rnd:sat
0 0 0 1 1 1 0 1 0 0 0 v v v v v P P 0 u u u u u 0 1 0 d d d d d Vd.ub=vasr(Vuu.uh,Vv.ub):sat
0 0 0 1 1 1 0 1 0 0 0 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.ub=vasr(Vuu.uh,Vv.ub):rnd:sat
0 0 0 1 1 1 1 0 - - 0 - - 1 0 0 P P 1 u u u u u 0 0 0 d d d d d Vd.sf=Vu.qf32
0 0 0 1 1 1 1 0 - - 0 - - 1 0 0 P P 1 u u u u u 0 1 1 d d d d d Vd.hf=Vu.qf16
0 0 0 1 1 1 1 0 - - 0 - - 1 0 0 P P 1 u u u u u 1 1 0 d d d d d Vd.hf=Vuu.qf32
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.h=vround(Vu.w,Vv.w):sat
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 1 0 1 d d d d d Vd.uh=vround(Vu.w,Vv.w):sat
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 1 1 0 d d d d d Vd.b=vround(Vu.h,Vv.h):sat
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 0 u u u u u 1 1 1 d d d d d Vd.ub=vround(Vu.h,Vv.h):sat
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 0 u u u u u 0 1 1 d d d d d Vd.ub=vround(Vu.uh,Vv.uh):sat
0 0 0 1 1 1 1 1 1 1 1 v v v v v P P 0 u u u u u 1 0 0 d d d d d Vd.uh=vround(Vu.uw,Vv.uw):sat
0 0 0 1 1 0 1 0 1 0 0 v v v v v P P 1 u u u u u 1 1 1 d d d d d Vd.uw=vrotr(Vu.uw,Vv.uw)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 1 u u u u u 1 0 1 d d d d d Vd.qf16=vsub(Vu.qf16,Vv.qf16)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 1 u u u u u 1 1 0 d d d d d Vd.qf16=vsub(Vu.hf,Vv.hf)
0 0 0 1 1 1 1 1 0 1 1 v v v v v P P 1 u u u u u 1 1 1 d d d d d Vd.qf16=vsub(Vu.qf16,Vv.hf)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 1 u u u u u 0 1 1 d d d d d Vd.qf32=vsub(Vu.qf32,Vv.qf32)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 1 u u u u u 1 0 0 d d d d d Vd.qf32=vsub(Vu.sf,Vv.sf)
0 0 0 1 1 1 1 1 1 0 1 v v v v v P P 1 u u u u u 1 0 1 d d d d d Vd.qf32=vsub(Vu.qf32,Vv.sf)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 1 0 1 d d d d d Vd.uw=vcl0(Vu.uw)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 1 1 0 d d d d d Vd.h=vpopcount(Vu.h)
0 0 0 1 1 1 1 0 - - 0 - - - 1 0 P P 0 u u u u u 1 1 1 d d d d d Vd.uh=vcl0(Vu.uh)
0 0 0 1 1 1 1 0 - - 0 - - - 1 1 P P 0 u u u u u 1 0 0 d d d d d Vd.w=vnormamt(Vu.w)
0 0 0 1 1 1 1 0 - - 0 - - - 1 1 P P 0 u u u u u 1 0 1 d d d d d Vd.h=vnormamt(Vu.h)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 1 u u u u u 0 0 0 d d d d d Vd.h=vadd(vclb(Vu.h),Vv.h)
0 0 0 1 1 1 1 1 0 0 0 v v v v v P P 1 u u u u u 0 0 1 d d d d d Vd.w=vadd(vclb(Vu.w),Vv.w)
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 0 0 0 s s s s s if (Qv4) vmem(Rt+#s4)=Vs
0 0 1 0 1 0 0 0 1 0 0 t t t t t P P i v v i i i 0 0 1 s s s s s if (!Qv4) vmem(Rt+#s4)=Vs
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 0 0 0 s s s s s if (Qv4) vmem(Rt+#s4):nt=Vs
0 0 1 0 1 0 0 0 1 1 0 t t t t t P P i v v i i i 0 0 1 s s s s s if (!Qv4) vmem(Rt+#s4):nt=Vs
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 0 0 0 s s s s s if (Qv4) vmem(Rx++#s3)=Vs
0 0 1 0 1 0 0 1 1 0 0 x x x x x P P - v v i i i 0 0 1 s s s s s if (!Qv4) vmem(Rx++#s3)=Vs
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 0 0 0 s s s s s if (Qv4) vmem(Rx++#s3):nt=Vs
0 0 1 0 1 0 0 1 1 1 0 x x x x x P P - v v i i i 0 0 1 s s s s s if (!Qv4) vmem(Rx++#s3):nt=Vs
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 0 0 0 s s s s s if (Qv4) vmem(Rx++Mu)=Vs
0 0 1 0 1 0 1 1 1 0 0 x x x x x P P u v v - - - 0 0 1 s s s s s if (!Qv4) vmem(Rx++Mu)=Vs
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 0 0 0 s s s s s if (Qv4) vmem(Rx++Mu):nt=Vs
0 0 1 0 1 0 1 1 1 1 0 x x x x x P P u v v - - - 0 0 1 s s s s s if (!Qv4) vmem(Rx++Mu):nt=Vs
0 0 1 0 1 0 0 0 0 0 1 t t t t t P P i - - i i i 0 0 1 - 0 s s s vmem(Rt+#s4)=Os8.new
0 0 1 0 1 0 0 0 0 1 1 t t t t t P P i - - i i i 0 0 1 - - s s s vmem(Rt+#s4):nt=Os8.new
0 0 1 0 1 0 0 0 1 0 1 t t t t t P P i v v i i i 0 1 0 0 0 s s s if (Pv) vmem(Rt+#s4)=Os8.new
0 0 1 0 1 0 0 0 1 0 1 t t t t t P P i v v i i i 0 1 1 0 1 s s s if (!Pv) vmem(Rt+#s4)=Os8.new
0 0 1 0 1 0 0 0 1 1 1 t t t t t P P i v v i i i 0 1 0 1 0 s s s if (Pv) vmem(Rt+#s4):nt=Os8.new
0 0 1 0 1 0 0 0 1 1 1 t t t t t P P i v v i i i 0 1 1 1 1 s s s if (!Pv) vmem(Rt+#s4):nt=Os8.new
0 0 1 0 1 0 0 1 0 0 1 x x x x x P P - - - i i i 0 0 1 - 0 s s s vmem(Rx++#s3)=Os8.new
0 0 1 0 1 0 0 1 0 1 1 x x x x x P P - - - i i i 0 0 1 - - s s s vmem(Rx++#s3):nt=Os8.new
0 0 1 0 1 0 0 1 1 0 1 x x x x x P P - v v i i i 0 1 0 0 0 s s s if (Pv) vmem(Rx++#s3)=Os8.new
0 0 1 0 1 0 0 1 1 0 1 x x x x x P P - v v i i i 0 1 1 0 1 s s s if (!Pv) vmem(Rx++#s3)=Os8.new
0 0 1 0 1 0 0 1 1 1 1 x x x x x P P - v v i i i 0 1 0 1 0 s s s if (Pv) vmem(Rx++#s3):nt=Os8.new
0 0 1 0 1 0 0 1 1 1 1 x x x x x P P - v v i i i 0 1 1 1 1 s s s if (!Pv) vmem(Rx++#s3):nt=Os8.new
0 0 1 0 1 0 1 1 0 0 1 x x x x x P P u - - - - - 0 0 1 - 0 s s s vmem(Rx++Mu)=Os8.new
0 0 1 0 1 0 1 1 0 1 1 x x x x x P P u - - - - - 0 0 1 - - s s s vmem(Rx++Mu):nt=Os8.new
0 0 1 0 1 0 1 1 1 0 1 x x x x x P P u v v - - - 0 1 0 0 0 s s s if (Pv) vmem(Rx++Mu)=Os8.new
0 0 1 0 1 0 1 1 1 0 1 x x x x x P P u v v - - - 0 1 1 0 1 s s s if (!Pv) vmem(Rx++Mu)=Os8.new
0 0 1 0 1 0 1 1 1 1 1 x x x x x P P u v v - - - 0 1 0 1 0 s s s if (Pv) vmem(Rx++Mu):nt=Os8.new
0 0 1 0 1 0 1 1 1 1 1 x x x x x P P u v v - - - 0 1 1 1 1 s s s if (!Pv) vmem(Rx++Mu):nt=Os8.ne
0 0 1 0 1 0 0 0 0 0 1 t t t t t P P i - - i i i 0 0 0 s s s s s vmem(Rt+#s4)=Vs
0 0 1 0 1 0 0 0 0 1 1 t t t t t P P i - - i i i 0 0 0 s s s s s vmem(Rt+#s4):nt=Vs
0 0 1 0 1 0 0 0 1 0 1 t t t t t P P i v v i i i 0 0 0 s s s s s if (Pv) vmem(Rt+#s4)=Vs
0 0 1 0 1 0 0 0 1 0 1 t t t t t P P i v v i i i 0 0 1 s s s s s if (!Pv) vmem(Rt+#s4)=Vs
0 0 1 0 1 0 0 0 1 1 1 t t t t t P P i v v i i i 0 0 0 s s s s s if (Pv) vmem(Rt+#s4):nt=Vs
0 0 1 0 1 0 0 0 1 1 1 t t t t t P P i v v i i i 0 0 1 s s s s s if (!Pv) vmem(Rt+#s4):nt=Vs
0 0 1 0 1 0 0 1 0 0 1 x x x x x P P - - - i i i 0 0 0 s s s s s vmem(Rx++#s3)=Vs
0 0 1 0 1 0 0 1 0 1 1 x x x x x P P - - - i i i 0 0 0 s s s s s vmem(Rx++#s3):nt=Vs
0 0 1 0 1 0 0 1 1 0 1 x x x x x P P - v v i i i 0 0 0 s s s s s if (Pv) vmem(Rx++#s3)=Vs
0 0 1 0 1 0 0 1 1 0 1 x x x x x P P - v v i i i 0 0 1 s s s s s if (!Pv) vmem(Rx++#s3)=Vs
0 0 1 0 1 0 0 1 1 1 1 x x x x x P P - v v i i i 0 0 0 s s s s s if (Pv) vmem(Rx++#s3):nt=Vs
0 0 1 0 1 0 0 1 1 1 1 x x x x x P P - v v i i i 0 0 1 s s s s s if (!Pv) vmem(Rx++#s3):nt=Vs
0 0 1 0 1 0 1 1 0 0 1 x x x x x P P u - - - - - 0 0 0 s s s s s vmem(Rx++Mu)=Vs
0 0 1 0 1 0 1 1 0 1 1 x x x x x P P u - - - - - 0 0 0 s s s s s vmem(Rx++Mu):nt=Vs
0 0 1 0 1 0 1 1 1 0 1 x x x x x P P u v v - - - 0 0 0 s s s s s if (Pv) vmem(Rx++Mu)=Vs
0 0 1 0 1 0 1 1 1 0 1 x x x x x P P u v v - - - 0 0 1 s s s s s if (!Pv) vmem(Rx++Mu)=Vs
0 0 1 0 1 0 1 1 1 1 1 x x x x x P P u v v - - - 0 0 0 s s s s s if (Pv) vmem(Rx++Mu):nt=Vs
0 0 1 0 1 0 1 1 1 1 1 x x x x x P P u v v - - - 0 0 1 s s s s s if (!Pv) vmem(Rx++Mu):nt=Vs
0 0 1 0 1 0 0 0 0 0 1 t t t t t P P i - - i i i 1 1 1 s s s s s vmemu(Rt+#s4)=Vs
0 0 1 0 1 0 0 0 1 0 1 t t t t t P P i v v i i i 1 1 0 s s s s s if (Pv) vmemu(Rt+#s4)=Vs
0 0 1 0 1 0 0 0 1 0 1 t t t t t P P i v v i i i 1 1 1 s s s s s if (!Pv) vmemu(Rt+#s4)=Vs
0 0 1 0 1 0 0 1 0 0 1 x x x x x P P - - - i i i 1 1 1 s s s s s vmemu(Rx++#s3)=Vs
0 0 1 0 1 0 0 1 1 0 1 x x x x x P P - v v i i i 1 1 0 s s s s s if (Pv) vmemu(Rx++#s3)=Vs
0 0 1 0 1 0 0 1 1 0 1 x x x x x P P - v v i i i 1 1 1 s s s s s if (!Pv) vmemu(Rx++#s3)=Vs
0 0 1 0 1 0 1 1 0 0 1 x x x x x P P u - - - - - 1 1 1 s s s s s vmemu(Rx++Mu)=Vs
0 0 1 0 1 0 1 1 1 0 1 x x x x x P P u v v - - - 1 1 0 s s s s s if (Pv) vmemu(Rx++Mu)=Vs
0 0 1 0 1 0 1 1 1 0 1 x x x x x P P u v v - - - 1 1 1 s s s s s if (!Pv) vmemu(Rx++Mu)=Vs
0 0 1 0 1 0 0 0 0 0 1 t t t t t P P i - - i i i 0 0 1 - 1 - - - vmem(Rt+#s4):scatter_release
0 0 1 0 1 0 0 1 0 0 1 x x x x x P P - - - i i i 0 0 1 - 1 - - - vmem(Rx++#s3):scatter_release
0 0 1 0 1 0 1 1 0 0 1 x x x x x P P u - - - - - 0 0 1 - 1 - - - vmem(Rx++Mu):scatter_release

View File

@@ -0,0 +1,648 @@
#
# First/Left Packed 'EE' Instructions
# NOTE: It may be that Left-side patterns can ignore bits 0-12
#
# (v4,left,5,7) add -- "Rd16 = add ( Rs16 , #-1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 0 1 1 s s s s d d d d - - - - - - - - - - - - - - - -
:add Rd4l,rs4l,MinusOne EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=3 & Rd4l & MinusOne & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l - 1;
build EndPackedLeft;
}
# (v4,left,3) add -- "Rd16 = add ( Ru16 , #-1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 0 1 1 u u u u d d d d - - 1 - - - - - - - - - - - - -
:add Rd4l,rs4l,MinusOne EndPackedLeft is iclass=3 & op2427=3 & op13=1 & Rd4l & MinusOne & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l - 1;
build EndPackedLeft;
}
# (v4,left,5,7) add -- "Rd16 = add ( Rs16 , #1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 0 0 1 s s s s d d d d - - - - - - - - - - - - - - - -
:add Rd4l,rs4l,One EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=1 & Rd4l & One & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l + 1;
build EndPackedLeft;
}
# (v4,left,3) add -- "Rd16 = add ( Ru16 , #1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 0 0 1 u u u u d d d d - - 1 - - - - - - - - - - - - -
:add Rd4l,rs4l,One EndPackedLeft is iclass=3 & op2427=1 & op13=1 & Rd4l & One & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l + 1;
build EndPackedLeft;
}
# (v4,left,2) add -- "Rd16 = add ( Sp , #U6:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 1 1 I I I I I I d d d d - - 1 - - - - - - - - - - - - -
:add Rd4l,SP,Uimm8_2025_shift2 EndPackedLeft is iclass=2 & op2627=3 & op13=1 & Rd4l & SP & Uimm8_2025_shift2 & $(END_PACKED_LEFT) {
Rd4l = SP + zext(Uimm8_2025_shift2);
build EndPackedLeft;
}
# (v4,left,4,6) add -- "Rd16 = add ( Sp , #u6:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 0 1 1 i i i i i i d d d d - - - - - - - - - - - - - - - -
:add Rd4l,SP,Uimm8_2025_shift2 EndPackedLeft is iclass3031=1 & iclass28=0 & op2627=3 & Rd4l & SP & Uimm8_2025_shift2 & $(END_PACKED_LEFT) {
Rd4l = SP + zext(Uimm8_2025_shift2);
build EndPackedLeft;
}
# (v4,left,3) add -- "Rx16 = add ( Rs16 , Rx16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 0 0 0 s s s s x x x x - - 1 - - - - - - - - - - - - -
:add Rd4l,rs4l,rd4l EndPackedLeft is iclass=3 & op2427=8 & op13=1 & Rd4l & rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l + rd4l;
build EndPackedLeft;
}
# (v4,left,5,7) add -- "Rx16 = add ( Rs16 , Rx16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 0 0 0 s s s s x x x x - - - - - - - - - - - - - - - -
:add Rd4l,rs4l,rd4l EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=8 & Rd4l & rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l + rd4l;
build EndPackedLeft;
}
# (v4,left,2) add -- "Rx16 = add ( Rx16 , #S7x )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 0 I I I I I I I x x x x - - 1 - - - - - - - - - - - - -
:add Rd4l,rd4l,Simm32_2026x EndPackedLeft is iclass=2 & op27=0 & op13=1 & Rd4l & rd4l & Simm32_2026x & $(END_PACKED_LEFT) {
Rd4l = rd4l + Simm32_2026x;
build EndPackedLeft;
}
# (v4,left,4,6) add -- "Rx16 = add ( Rx16 , #S7x )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 0 0 I I I I I I I x x x x - - - - - - - - - - - - - - - -
:add Rd4l,rd4l,Simm32_2026x EndPackedLeft is iclass3031=1 & iclass28=0 & op27=0 & Rd4l & rd4l & Simm32_2026x & $(END_PACKED_LEFT) {
Rd4l = rd4l + Simm32_2026x;
build EndPackedLeft;
}
# (v4,left,5,7) and -- "Rd16 = and ( Rs16 , #1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 0 1 0 s s s s d d d d - - - - - - - - - - - - - - - -
:and Rd4l,rs4l,One EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=2 & Rd4l & One & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l & 1;
build EndPackedLeft;
}
# (v4,left,5,7) and -- "Rd16 = and ( Rs16 , #255 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 1 1 1 s s s s d d d d - - - - - - - - - - - - - - - -
:and Rd4l,rs4l,FF EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=7 & Rd4l & FF & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l & 0xff;
build EndPackedLeft;
}
# (v4,left,3) and -- "Rd16 = and ( Ru16 , #1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 0 1 0 u u u u d d d d - - 1 - - - - - - - - - - - - -
:and Rd4l,rs4l,One EndPackedLeft is iclass=3 & op2427=2 & op13=1 & Rd4l & One & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l & 1;
build EndPackedLeft;
}
# (v4,left,3) and -- "Rd16 = and ( Ru16 , #255 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 1 1 1 u u u u d d d d - - 1 - - - - - - - - - - - - -
:and Rd4l,rs4l,FF EndPackedLeft is iclass=3 & op2427=7 & op13=1 & Rd4l & FF & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l & 0xff;
build EndPackedLeft;
}
# (v4,left,5,7) assign -- "Rd16 = #-1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 0 1 + + 0 + + d d d d - - - - - - - - - - - - - - - -
:assign Rd4l,MinusOne EndPackedLeft is iclass3031=1 & iclass28=1 & op2127=0x50 & op20=0 & Rd4l & MinusOne & $(END_PACKED_LEFT) {
Rd4l = -1;
build EndPackedLeft;
}
# (v4,left,2) assign -- "Rd16 = #U6x"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 1 0 I I I I I I d d d d - - 1 - - - - - - - - - - - - -
:assign Rd4l,Uimm32_2025x EndPackedLeft is iclass=2 & op2627=2 & op13=1 & Rd4l & Uimm32_2025x & $(END_PACKED_LEFT) {
Rd4l = Uimm32_2025x;
build EndPackedLeft;
}
# (v4,left,4,6) assign -- "Rd16 = #U6x"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 0 1 0 I I I I I I d d d d - - - - - - - - - - - - - - - -
:assign Rd4l,Uimm32_2025x EndPackedLeft is iclass3031=1 & iclass28=0 & op2627=2 & Rd4l & Uimm32_2025x & $(END_PACKED_LEFT) {
Rd4l = Uimm32_2025x;
build EndPackedLeft;
}
# (v4,left,5,7) assign -- "Rd16 = Rs16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 0 0 0 s s s s d d d d - - - - - - - - - - - - - - - -
:assign Rd4l,rs4l EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=0 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l;
build EndPackedLeft;
}
# (v4,left,3) assign -- "Rd16 = Ru16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 0 0 0 u u u u d d d d - - 1 1 - - - - - - - - - - - -
:assign Rd4l,rs4l EndPackedLeft is iclass=3 & op2427=0 & op13=1 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l;
build EndPackedLeft;
}
# (v4,left,3) assign -- "Re16 = #-1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 0 1 + + 0 + + e e e e - - 1 - - - - - - - - - - - - -
:assign Rd4l,MinusOne EndPackedLeft is iclass=3 & op2127=0x50 & op20=0 & op13=1 & Rd4l & MinusOne & $(END_PACKED_LEFT) {
Rd4l = -1;
build EndPackedLeft;
}
# (v4,left,5,7) assign -- "if ( ! p0 ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 0 1 + + 1 1 1 d d d d - - - - - - - - - - - - - - - -
#
# (v4,left,5,7) assign -- "if ( ! p0 .new ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 0 1 + + 1 0 1 d d d d - - - - - - - - - - - - - - - -
#
# (v4,left,5,7) assign -- "if ( p0 ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 0 1 + + 1 1 0 d d d d - - - - - - - - - - - - - - - -
#
# (v4,left,5,7) assign -- "if ( p0 .new ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 0 1 + + 1 0 0 d d d d - - - - - - - - - - - - - - - -
:assign^P0Cond_N21_S20 rd4l,Zero EndPackedLeft is iclass3031=1 & iclass28=1 & op2227=0x29 & rd4l & P0Cond_N21_S20 & Zero & $(END_PACKED_LEFT) {
build P0Cond_N21_S20;
build EndPackedLeft;
<<COMMIT_COND>>
if (ConditionReg == 0) goto <nocommit>;
rd4l = 0;
<nocommit>
}
# (v4,left,3) assign -- "if ( ! p0 ) Re16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 0 1 + + 1 1 1 e e e e - - 1 - - - - - - - - - - - - -
#
# (v4,left,3) assign -- "if ( ! p0 .new ) Re16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 0 1 + + 1 0 1 e e e e - - 1 - - - - - - - - - - - - -
#
# (v4,left,3) assign -- "if ( p0 ) Re16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 0 1 + + 1 1 0 e e e e - - 1 - - - - - - - - - - - - -
#
# (v4,left,3) assign -- "if ( p0 .new ) Re16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 0 1 + + 1 0 0 e e e e - - 1 - - - - - - - - - - - - -
:assign^P0Cond_N21_S20 rd4l,Zero EndPackedLeft is iclass=3 & op2227=0x29 & op13=1 & rd4l & P0Cond_N21_S20 & Zero & $(END_PACKED_LEFT) {
build P0Cond_N21_S20;
build EndPackedLeft;
<<COMMIT_COND>>
if (ConditionReg == 0) goto <nocommit>;
rd4l = 0;
<nocommit>
}
# (v4,left,3) cmp.eq -- "p0 = cmp.eq ( Rs16 , #U2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 0 0 1 s s s s - - I I - - 1 - - - - - - - - - - - - -
:cmp.eq P0dest,rs4l,Uimm2_1617 EndPackedLeft is iclass=3 & op2427=9 & op13=1 & P0dest & rs4l & Uimm2_1617 & $(END_PACKED_LEFT) {
bool:1 = (rs4l == zext(Uimm2_1617));
P0dest = P0dest & (bool * 0xff);
build EndPackedLeft;
}
# (v4,left,5,7) cmp.eq -- "p0 = cmp.eq ( Rs16 , #U2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 0 0 1 s s s s - - I I - - - - - - - - - - - - - - - -
:cmp.eq P0dest,rs4l,Uimm2_1617 EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=9 & P0dest & rs4l & Uimm2_1617 & $(END_PACKED_LEFT) {
bool:1 = (rs4l == zext(Uimm2_1617));
P0dest = P0dest & (bool * 0xff);
build EndPackedLeft;
}
# (v4,left,5,7) combine -- "Rdd8 = combine ( #n2 , #u2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 1 + 0 + i i n n d d d - - - - - - - - - - - - - - - -
:combine Rdd3l,Uimm2_1920,Uimm2_2122 EndPackedLeft is iclass3031=1 & iclass28=1 & op2327=0x18 & Uimm2_1920 & Uimm2_2122 & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = (zext(Uimm2_1920) << 32) + zext(Uimm2_2122);
build EndPackedLeft;
}
# Simplification: "Rdd8 = #u2"
:assign Rdd3l,Uimm2_2122 EndPackedLeft is iclass3031=1 & iclass28=1 & op2327=0x18 & op1920=0 & Uimm2_2122 & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = zext(Uimm2_2122);
build EndPackedLeft;
}
# (v4,left,3) combine -- "Rdd8 = combine ( #n2 , #u2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 1 + 0 + i i n n d d d - - 1 - - - - - - - - - - - - -
:combine Rdd3l,Uimm2_1920,Uimm2_2122 EndPackedLeft is iclass=3 & op2327=0x18 & op13=1 & Uimm2_1920 & Uimm2_2122 & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = (zext(Uimm2_1920) << 32) + zext(Uimm2_2122);
build EndPackedLeft;
}
# Simplification: "Rdd8 = #u2"
:assign Rdd3l,Uimm2_2122 EndPackedLeft is iclass=3 & op2327=0x18 & op1920=0 & op13=1 & Uimm2_2122 & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = zext(Uimm2_2122);
build EndPackedLeft;
}
# (v4,left,5,7) combine -- "Rdd8 = combine ( #0 , Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 1 + 1 s s s s 0 d d d - - - - - - - - - - - - - - - -
:combine Rdd3l,Zero,rs4l EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=13 & op19=0 & rs4l & Zero & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = zext(rs4l);
build EndPackedLeft;
}
# (v4,left,3) combine -- "Ree8 = combine ( #0 , Ru16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 1 + 1 u u u u 0 e e e - - 1 - - - - - - - - - - - - -
:combine Rdd3l,Zero,rs4l EndPackedLeft is iclass=3 & op2427=13 & op19=0 & op13=1 & rs4l & Zero & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = zext(rs4l);
build EndPackedLeft;
}
# (v4,left,5,7) combine -- "Rdd8 = combine ( Rs16 , #0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 1 1 + 1 s s s s 1 d d d - - - - - - - - - - - - - - - -
:combine Rdd3l,rs4l,Zero EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=13 & op19=1 & rs4l & Zero & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = zext(rs4l) << 32;
build EndPackedLeft;
}
# (v4,left,3) combine -- "Ree8 = combine ( Ru16 , #0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 1 + 1 u u u u 1 e e e - - 1 - - - - - - - - - - - - -
:combine Rdd3l,rs4l,Zero EndPackedLeft is iclass=3 & op2427=13 & op19=1 & op13=1 & rs4l & Zero & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = zext(rs4l) << 32;
build EndPackedLeft;
}
# (v4,left,3) deallocframe -- "deallocframe"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 1 1 1 0 0 - - - 0 - - - - 0 - - - - - - - - - - - - -
:deallocframe EndPackedLeft is iclass=3 & op2227=0x3c & op18=0 & op13=0 & $(END_PACKED_LEFT) {
build EndPackedLeft;
<<COMMIT>>
deallocframe(FP);
}
# (v4,left,9,13) deallocframe -- "deallocframe"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 1 1 1 1 1 0 0 - - - 0 - - - - 1 - - - - - - - - - - - - -
:deallocframe EndPackedLeft is iclass31=1 & iclass2829=1 & op2227=0x3c & op18=0 & op13=1 & $(END_PACKED_LEFT) {
build EndPackedLeft;
<<COMMIT>>
deallocframe(FP);
}
# (v4,left,9,13) memb -- "Rd16 = memb ( Ru16 + #U3:0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 1 0 I I I u u u u d d d d - - 1 - - - - - - - - - - - - -
:memb Rd4l,MemRsRelU3Lb EndPackedLeft is iclass31=1 & iclass2829=1 & op27=0 & op13=1 & MemRsRelU3Lb & Rd4l & $(END_PACKED_LEFT) {
Rd4l = sext(MemRsRelU3Lb);
build EndPackedLeft;
}
# (v4,left,3) memb -- "Rd16 = memb ( Rs16 + #u3:0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 i i i s s s s d d d d - - 0 - - - - - - - - - - - - -
:memb Rd4l,MemRsRelU3Lb EndPackedLeft is iclass=3 & op27=0 & op13=0 & MemRsRelU3Lb & Rd4l & $(END_PACKED_LEFT) {
Rd4l = sext(MemRsRelU3Lb);
build EndPackedLeft;
}
# (v4,left,15) memb -- "memb ( Rs16 + #U4:0 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 1 0 0 1 n s s s s I I I I - - 0 - - - - - - - - - - - - -
:memb StMemRsRelC15Lb,Uimm1_24 EndPackedLeft is iclass=15 & op2527=1 & op13=0 & StMemRsRelC15Lb & Uimm1_24 & $(END_PACKED_LEFT) {
StMemRsRelC15Lb = Uimm1_24;
build EndPackedLeft;
}
# (v4,left,11) memb -- "memb ( Rs16 + #U4:0 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 1 I I I I s s s s t t t t - - - - - - - - - - - - - - - -
:memb MemRsRelU4Lb,rt4l EndPackedLeft is iclass=11 & MemRsRelU4Lb & rt4l & $(END_PACKED_LEFT) {
MemRsRelU4Lb = rt4l:1;
build EndPackedLeft;
}
# (v4,left,9,13) memd -- "Rdd8 = memd ( Sp + #U5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 1 1 1 1 0 I I I I I d d d - - 1 - - - - - - - - - - - - -
:memd Rdd3l,MemSpRelU5Ld EndPackedLeft is iclass31=1 & iclass2829=1 & op2427=14 & op13=1 & MemSpRelU5Ld & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = MemSpRelU5Ld;
build EndPackedLeft;
}
# (v4,left,3) memd -- "Rdd8 = memd ( Sp + #u5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 1 1 0 i i i i i d d d - - 0 - - - - - - - - - - - - -
:memd Rdd3l,MemSpRelU5Ld EndPackedLeft is iclass=3 & op2427=14 & op13=0 & MemSpRelU5Ld & Rdd3l & $(END_PACKED_LEFT) {
Rdd3l = MemSpRelU5Ld;
build EndPackedLeft;
}
# (v4,left,14) memd -- "memd ( Sp + #S6:3 ) = Rtt8"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 1 I I I I I I t t t - - 0 - - - - - - - - - - - - -
:memd MemSpRelS6Ld,rtt3l EndPackedLeft is iclass=14 & op2527=5 & op13=0 & MemSpRelS6Ld & rtt3l & $(END_PACKED_LEFT) {
MemSpRelS6Ld = rtt3l;
build EndPackedLeft;
}
# (v4,left,8,12) memh -- "Rd16 = memh ( Rs16 + #U3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 0 0 I I I s s s s d d d d - - 1 - - - - - - - - - - - - -
:memh Rd4l,MemRsRelU3Lh EndPackedLeft is iclass31=1 & iclass2829=0 & op27=0 & op13=1 & MemRsRelU3Lh & Rd4l & $(END_PACKED_LEFT) {
Rd4l = sext(MemRsRelU3Lh);
build EndPackedLeft;
}
# (v4,left,2) memh -- "Rd16 = memh ( Rs16 + #u3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 0 i i i s s s s d d d d - - 0 - - - - - - - - - - - - -
:memh Rd4l,MemRsRelU3Lh EndPackedLeft is iclass=2 & op27=0 & op13=0 & MemRsRelU3Lh & Rd4l & $(END_PACKED_LEFT) {
Rd4l = sext(MemRsRelU3Lh);
build EndPackedLeft;
}
# (v4,left,14) memh -- "memh ( Rs16 + #U3:1 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 0 I I I s s s s t t t t - - 0 - - - - - - - - - - - - -
:memh MemRsRelU3Lh,rt4l EndPackedLeft is iclass=14 & op27=0 & op13=0 & MemRsRelU3Lh & rt4l & $(END_PACKED_LEFT) {
MemRsRelU3Lh = rt4l:2;
build EndPackedLeft;
}
# (v4,left,1) memub -- "Rd16 = memub ( Rs16 + #u4:0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 0 1 i i i i s s s s d d d d - - - - - - - - - - - - - - - -
:memub Rd4l,MemRsRelU4Lb EndPackedLeft is iclass=1 & MemRsRelU4Lb & Rd4l & $(END_PACKED_LEFT) {
Rd4l = zext(MemRsRelU4Lb);
build EndPackedLeft;
}
# (v4,left,9,13) memub -- "Rd16 = memub ( Ru16 + #U4:0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 1 I I I I u u u u d d d d - - 0 - - - - - - - - - - - - -
:memub Rd4l,MemRsRelU4Lb EndPackedLeft is iclass31=1 & iclass2829=1 & op13=0 & MemRsRelU4Lb & Rd4l & $(END_PACKED_LEFT) {
Rd4l = zext(MemRsRelU4Lb);
build EndPackedLeft;
}
# (v4,left,2) memuh -- "Rd16 = memuh ( Rs16 + #u3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 1 i i i s s s s d d d d - - 0 - - - - - - - - - - - - -
:memuh Rd4l,MemRsRelU3Lh EndPackedLeft is iclass=2 & op27=1 & op13=0 & MemRsRelU3Lh & Rd4l & $(END_PACKED_LEFT) {
Rd4l = zext(MemRsRelU3Lh);
build EndPackedLeft;
}
# (v4,left,8,12) memuh -- "Rd16 = memuh ( Ru16 + #U3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 0 1 I I I u u u u d d d d - - 1 - - - - - - - - - - - - -
:memuh Rd4l,MemRsRelU3Lh EndPackedLeft is iclass31=1 & iclass2829=0 & op27=1 & op13=1 & MemRsRelU3Lh & Rd4l & $(END_PACKED_LEFT) {
Rd4l = zext(MemRsRelU3Lh);
build EndPackedLeft;
}
# (v4,left,0) memw -- "Rd16 = memw ( Rs16 + #u4:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 0 0 i i i i s s s s d d d d - - - - - - - - - - - - - - - -
:memw Rd4l,MemRsRelU4Lw EndPackedLeft is iclass=0 & MemRsRelU4Lw & Rd4l & $(END_PACKED_LEFT) {
Rd4l = MemRsRelU4Lw;
build EndPackedLeft;
}
# (v4,left,8,12) memw -- "Rd16 = memw ( Ru16 + #U4:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 0 I I I I u u u u d d d d - - 0 - - - - - - - - - - - - -
:memw Rd4l,MemRsRelU4Lw EndPackedLeft is iclass31=1 & iclass2829=0 & op13=0 & MemRsRelU4Lw & Rd4l & $(END_PACKED_LEFT) {
Rd4l = MemRsRelU4Lw;
build EndPackedLeft;
}
# (v4,left,9,13) memw -- "Rd16 = memw ( Sp + #U5:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 - 0 1 1 1 0 I I I I I d d d d - - 1 - - - - - - - - - - - - -
:memw Rd4l,MemSpRelU5Lw EndPackedLeft is iclass31=1 & iclass2829=1 & op2527=6 & op13=1 & MemSpRelU5Lw & Rd4l & $(END_PACKED_LEFT) {
Rd4l = MemSpRelU5Lw;
build EndPackedLeft;
}
# (v4,left,3) memw -- "Rd16 = memw ( Sp + #u5:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 1 1 0 i i i i i d d d d - - 0 - - - - - - - - - - - - -
:memw Rd4l,MemSpRelU5Lw EndPackedLeft is iclass=3 & op2527=6 & op13=0 & MemSpRelU5Lw & Rd4l & $(END_PACKED_LEFT) {
Rd4l = MemSpRelU5Lw;
build EndPackedLeft;
}
# (v4,left,15) memw -- "memw ( Rs16 + #U4:2 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 1 0 0 0 n s s s s I I I I - - 0 - - - - - - - - - - - - -
:memw StMemRsRelC15Lw,Uimm1_24 EndPackedLeft is iclass=15 & op2527=0 & op13=0 & StMemRsRelC15Lw & Uimm1_24 & $(END_PACKED_LEFT) {
StMemRsRelC15Lw = zext(Uimm1_24);
build EndPackedLeft;
}
# (v4,left,10) memw -- "memw ( Rs16 + #U4:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 0 I I I I s s s s t t t t - - - - - - - - - - - - - - - -
:memw MemRsRelU4Lw,rt4l EndPackedLeft is iclass=10 & MemRsRelU4Lw & rt4l & $(END_PACKED_LEFT) {
MemRsRelU4Lw = rt4l;
build EndPackedLeft;
}
# (v4,left,14) memw -- "memw ( Sp + #U5:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 0 1 0 0 I I I I I t t t t - - 0 - - - - - - - - - - - - -
:memw MemSpRelU5Lw,rt4l EndPackedLeft is iclass=14 & op2527=4 & op13=0 & MemSpRelU5Lw & rt4l & $(END_PACKED_LEFT) {
MemSpRelU5Lw = rt4l;
build EndPackedLeft;
}
# (v4,left,5,7) sxtb -- "Rd16 = sxtb ( Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 1 0 1 s s s s d d d d - - - - - - - - - - - - - - - -
:sxtb Rd4l,rs4l EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=5 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = (rs4l << 24) s>> 24;
build EndPackedLeft;
}
# (v4,left,3) sxtb -- "Rd16 = sxtb ( Ru16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 1 0 1 u u u u d d d d - - 1 - - - - - - - - - - - - -
:sxtb Rd4l,rs4l EndPackedLeft is iclass=3 & op2427=5 & op13=1 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = (rs4l << 24) s>> 24;
build EndPackedLeft;
}
# (v4,left,5,7) sxth -- "Rd16 = sxth ( Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 1 0 0 s s s s d d d d - - - - - - - - - - - - - - - -
:sxth Rd4l,rs4l EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=4 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = (rs4l << 16) s>> 16;
build EndPackedLeft;
}
# (v4,left,3) sxth -- "Rd16 = sxth ( Ru16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 1 0 0 u u u u d d d d - - 1 - - - - - - - - - - - - -
:sxth Rd4l,rs4l EndPackedLeft is iclass=3 & op2427=4 & op13=1 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = (rs4l << 16) s>> 16;
build EndPackedLeft;
}
# (v4,left,5,7) zxth -- "Rd16 = zxth ( Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 - 1 0 1 1 0 s s s s d d d d - - - - - - - - - - - - - - - -
:zxth Rd4l,rs4l EndPackedLeft is iclass3031=1 & iclass28=1 & op2427=6 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l & 0xffff;
build EndPackedLeft;
}
# (v4,left,3) zxth -- "Rd16 = zxth ( Ru16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 1 0 1 1 0 u u u u d d d d - - 1 - - - - - - - - - - - - -
:zxth Rd4l,rs4l EndPackedLeft is iclass=3 & op2427=6 & op13=1 & Rd4l & rs4l & $(END_PACKED_LEFT) {
Rd4l = rs4l & 0xffff;
build EndPackedLeft;
}

View File

@@ -0,0 +1,776 @@
#
# Second/Right Packed 'EE' Instructions
#
# (v4,right,2,3) add -- "Rd16 = add ( Rs16 , #-1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 0 1 1 s s s s d d d d
:add Rd4r,rs4r,MinusOne EndPackedRight is iclass2931=1 & op0813=0x33 & Rd4r & MinusOne & rs4r & $(END_PACKED_RIGHT) {
Rd4r = rs4r - 1;
build EndPackedRight;
}
# (v4,right,2,3) add -- "Rd16 = add ( Rs16 , #1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 0 0 1 s s s s d d d d
:add Rd4r,rs4r,One EndPackedRight is iclass2931=1 & op0813=0x31 & Rd4r & One & rs4r & $(END_PACKED_RIGHT) {
Rd4r = rs4r + 1;
build EndPackedRight;
}
# (v4,right,2) add -- "Rd16 = add ( Sp , #u6:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 - - - - - - - - - - - - - - 1 0 1 1 i i i i i i d d d d
:add Rd4r,SP,Uimm8_0409_shift2 EndPackedRight is iclass=2 & op1013=11 & Rd4r & SP & Uimm8_0409_shift2 & $(END_PACKED_RIGHT) {
Rd4r = SP + zext(Uimm8_0409_shift2);
build EndPackedRight;
}
# (v4,right,2,3) add -- "Rx16 = add ( Rs16 , Rx16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 0 0 0 s s s s x x x x
:add Rd4r,rs4r,rd4r EndPackedRight is iclass2931=1 & op0813=0x38 & Rd4r & rd4r & rs4r & $(END_PACKED_RIGHT) {
Rd4r = rs4r + rd4r;
build EndPackedRight;
}
# (v4,right,2) add -- "Rx16 = add ( Rx16 , #s7 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 - - - - - - - - - - - - - - 1 0 0 i i i i i i i x x x x
:add Rd4r,rd4r,Simm8_0410 EndPackedRight is iclass=2 & op1113=4 & Rd4r & rd4r & Simm8_0410 & $(END_PACKED_RIGHT) {
Rd4r = rd4r + sext(Simm8_0410);
build EndPackedRight;
}
# (v4,right,6,7) allocframe -- "allocframe ( #u5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 1 1 1 1 0 i i i i i - - - -
#
# (v4,right,10,11) allocframe -- "allocframe ( #u5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 1 1 1 1 0 i i i i i - - - -
:allocframe Uimm8_0408_shift3 EndPackedRight is (iclass2931=3 | iclass2931=5) & op0913=0x1e & Uimm8_0408_shift3 & $(END_PACKED_RIGHT) {
allocframe(SP, Uimm8_0408_shift3);
build EndPackedRight;
}
# (v4,right,12,13) allocframe -- "allocframe ( #u5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 - - - - - - - - - - - - - - - - 1 1 1 0 i i i i i - - - -
:allocframe Uimm8_0408_shift3 EndPackedRight is iclass2931=6 & op0912=14 & Uimm8_0408_shift3 & $(END_PACKED_RIGHT) {
allocframe(SP, Uimm8_0408_shift3);
build EndPackedRight;
}
# (v4,right,14,15) allocframe -- "allocframe ( #u5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 - - - - - - - - - - - - - - - 0 1 1 1 0 i i i i i - - - -
:allocframe Uimm8_0408_shift3 EndPackedRight is iclass2931=7 & op0913=0x0e & Uimm8_0408_shift3 & $(END_PACKED_RIGHT) {
allocframe(SP, Uimm8_0408_shift3);
build EndPackedRight;
}
# (v4,right,2,3) and -- "Rd16 = and ( Rs16 , #1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 0 1 0 s s s s d d d d
:and Rd4r,rs4r,One EndPackedRight is iclass2931=1 & op0813=0x32 & Rd4r & One & rs4r & $(END_PACKED_RIGHT) {
Rd4r = rs4r & 1;
build EndPackedRight;
}
# (v4,right,2,3) and -- "Rd16 = and ( Rs16 , #255 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 1 1 1 s s s s d d d d
:and Rd4r,rs4r,FF EndPackedRight is iclass2931=1 & op0813=0x37 & Rd4r & FF & rs4r & $(END_PACKED_RIGHT) {
Rd4r = rs4r & 0xff;
build EndPackedRight;
}
# (v4,right,2,3) assign -- "Rd16 = #-1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 0 1 + + 0 + + d d d d
:assign Rd4r,MinusOne EndPackedRight is iclass2931=1 & op13=1 & op0412=0x1a0 & Rd4r & MinusOne & $(END_PACKED_RIGHT) {
Rd4r = -1;
build EndPackedRight;
}
# (v4,right,2) assign -- "Rd16 = #u6"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 - - - - - - - - - - - - - - 1 0 1 0 i i i i i i d d d d
:assign Rd4r,Uimm8_0409 EndPackedRight is iclass=2 & op1013=10 & Rd4r & Uimm8_0409 & $(END_PACKED_RIGHT) {
Rd4r = zext(Uimm8_0409);
build EndPackedRight;
}
# (v4,right,2,3) assign -- "Rd16 = Rs16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 0 0 0 s s s s d d d d
:assign Rd4r,rs4r EndPackedRight is iclass2931=1 & op13=1 & op0812=0x10 & Rd4r & rs4r & $(END_PACKED_RIGHT) {
Rd4r = rs4r;
build EndPackedRight;
}
# (v4,right,2,3) assign -- "if ( ! p0 ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 0 1 + + 1 1 1 d d d d
#
# (v4,right,2,3) assign -- "if ( ! p0 .new ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 0 1 + + 1 0 1 d d d d
#
# (v4,right,2,3) assign -- "if ( p0 ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 0 1 + + 1 1 0 d d d d
#
# (v4,right,2,3) assign -- "if ( p0 .new ) Rd16 = #0"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 0 1 + + 1 0 0 d d d d
:assign^P0Cond_N05_S04 rd4r,Zero EndPackedRight is iclass2931=1 & op13=1 & op0612=0x69 & rd4r & Zero & P0Cond_N05_S04 & $(END_PACKED_RIGHT) {
build P0Cond_N05_S04;
build EndPackedRight;
<<COMMIT_COND>>
if (ConditionReg == 0) goto <nocommit>;
rd4r = 0;
<nocommit>
}
# (v4,right,2,3) cmp.eq -- "p0 = cmp.eq ( Rs16 , #u2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 0 0 1 s s s s - - i i
:cmp.eq P0,rs4r,Uimm8_0001 EndPackedRight is iclass2931=1 & op13=1 & op0812=0x19 & P0 & rs4r & Uimm8_0001 & $(END_PACKED_RIGHT) {
bool:1 = (rs4r == zext(Uimm8_0001));
P0.new = P0.new & (bool * 0xff);
build EndPackedRight;
<<COMMIT>>
P0 = P0.new;
}
# (v4,right,2,3) combine -- "Rdd8 = combine ( #n2 , #u2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 1 + 0 - i i n n d d d
:combine Rdd3r,Uimm2_0304,Uimm2_0506 EndPackedRight is iclass2931=1 & op0813=0x3c & Uimm2_0304 & Uimm2_0506 & Rdd3r & Zero & $(END_PACKED_RIGHT) {
Rdd3r = (zext(Uimm2_0304) << 32) + zext(Uimm2_0506);
build EndPackedRight;
}
# (v4,right,2,3) combine -- "Rdd8 = combine ( #0 , Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 1 + 1 s s s s 0 d d d
:combine Rdd3r,Zero,rs4r EndPackedRight is iclass2931=1 & op0813=0x3d & op3=0 & rs4r & Rdd3r & Zero & $(END_PACKED_RIGHT) {
Rdd3r = zext(rs4r);
build EndPackedRight;
}
# (v4,right,2,3) combine -- "Rdd8 = combine ( Rs16 , #0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 1 1 + 1 s s s s 1 d d d
:combine Rdd3r,rs4r,Zero EndPackedRight is iclass2931=1 & op0813=0x3d & op3=1 & rs4r & Rdd3r & Zero & $(END_PACKED_RIGHT) {
Rdd3r = zext(rs4r) << 32;
build EndPackedRight;
}
# (v4,right,0,1,4,5) dealloc_return -- "dealloc_return"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 0 1 - - - 0 - -
:dealloc_return EndPackedRight is iclass31=0 & iclass29=0 & op13=1 & op0612=0x7d & op2=0 & $(END_PACKED_RIGHT) {
build EndPackedRight;
<<FLOW>>
deallocframe(FP);
return [LR];
}
# (v4,right,2,3) dealloc_return -- "dealloc_return"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 0 1 - - - 0 - -
:dealloc_return EndPackedRight is iclass2931=1 & op13=0 & op0612=0x7d & op2=0 & $(END_PACKED_RIGHT) {
build EndPackedRight;
<<FLOW>>
deallocframe(FP);
return [LR];
}
# (v4,right,0,1,4,5) dealloc_return -- "if ( ! p0 ) dealloc_return"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 0 1 - - - 1 0 1
#
# (v4,right,0,1,4,5) dealloc_return:nt -- "if ( ! p0 .new ) dealloc_return:nt"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 0 1 - - - 1 1 1
#
# (v4,right,0,1,4,5) dealloc_return -- "if ( p0 ) dealloc_return"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 0 1 - - - 1 0 0
#
# (v4,right,0,1,4,5) dealloc_return:nt -- "if ( p0 .new ) dealloc_return:nt"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 0 1 - - - 1 1 0
:dealloc_return^FlowP0Cond_N01_S00^NotTaken01 EndPackedRight is iclass31=0 & iclass29=0 & op13=1 & op0612=0x7d & op2=1 & FlowP0Cond_N01_S00 & NotTaken01 & $(END_PACKED_RIGHT) {
build FlowP0Cond_N01_S00;
build EndPackedRight;
<<FLOW>>
if (ConditionReg == 0) goto <non_flow>;
deallocframe(FP);
return [LR];
<non_flow>
}
# (v4,right,2,3) dealloc_return -- "if ( ! p0 ) dealloc_return"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 0 1 - - - 1 0 1
#
# (v4,right,2,3) dealloc_return:nt -- "if ( ! p0 .new ) dealloc_return:nt"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 0 1 - - - 1 1 1
#
# (v4,right,2,3) dealloc_return -- "if ( p0 ) dealloc_return"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 0 1 - - - 1 0 0
#
# (v4,right,2,3) dealloc_return:nt -- "if ( p0 .new ) dealloc_return:nt"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 0 1 - - - 1 1 0
:dealloc_return^FlowP0Cond_N01_S00^NotTaken01 EndPackedRight is iclass2931=1 & op13=0 & op0612=0x7d & op2=1 & FlowP0Cond_N01_S00 & NotTaken01 & $(END_PACKED_RIGHT) {
build FlowP0Cond_N01_S00;
build EndPackedRight;
<<FLOW>>
if (ConditionReg == 0) goto <non_flow>;
deallocframe(FP);
return [LR];
<non_flow>
}
# (v4,right,0,1,4,5) deallocframe -- "deallocframe"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 0 0 - - - 0 - -
:deallocframe EndPackedRight is iclass31=0 & iclass29=0 & op13=1 & op0612=0x7c & op2=0 & $(END_PACKED_RIGHT) {
build EndPackedRight;
<<COMMIT>>
deallocframe(FP);
}
# (v4,right,2,3) deallocframe -- "deallocframe"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 0 0 - - - 0 - -
:deallocframe EndPackedRight is iclass2931=1 & op13=0 & op0612=0x7c & op2=0 & $(END_PACKED_RIGHT) {
build EndPackedRight;
<<COMMIT>>
deallocframe(FP);
}
# (v4,right,0,1,4,5) jumpr -- "jumpr Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 1 1 - - - 0 - -
:jumpr LR EndPackedRight is iclass31=0 & iclass29=0 & op13=1 & op0612=0x7f & op2=0 & LR & $(END_PACKED_RIGHT) {
dest:4 = LR;
build EndPackedRight;
<<FLOW>>
return [dest];
}
# (v4,right,2,3) jumpr -- "jumpr Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 1 1 - - - 0 - -
:jumpr LR EndPackedRight is iclass2931=1 & op13=0 & op0612=0x7f & op2=0 & LR & $(END_PACKED_RIGHT) {
dest:4 = LR;
build EndPackedRight;
<<FLOW>>
return [dest];
}
# (v4,right,0,1,4,5) jumpr -- "if ( ! p0 ) jumpr Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 1 1 - - - 1 0 1
#
# (v4,right,0,1,4,5) jumpr:nt -- "if ( ! p0 .new ) jumpr:nt Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 1 1 - - - 1 1 1
#
# (v4,right,0,1,4,5) jumpr -- "if ( p0 ) jumpr Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 1 1 - - - 1 0 0
#
# (v4,right,0,1,4,5) jumpr:nt -- "if ( p0 .new ) jumpr:nt Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 1 1 1 - - - 1 1 0
# Conditional Return
:jumpr^FlowP0Cond_N01_S00^NotTaken01 LR EndPackedRight is iclass31=0 & iclass29=0 & op13=1 & op0612=0x7f & op2=1 & FlowP0Cond_N01_S00 & NotTaken01 & LR & $(END_PACKED_RIGHT) {
dest:4 = LR;
build FlowP0Cond_N01_S00;
build EndPackedRight;
<<FLOW>>
if (ConditionReg == 0) goto <non_flow>;
return [dest];
<non_flow>
}
# (v4,right,2,3) jumpr -- "if ( ! p0 ) jumpr Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 1 1 - - - 1 0 1
#
# (v4,right,2,3) jumpr:nt -- "if ( ! p0 .new ) jumpr:nt Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 1 1 - - - 1 1 1
#
# (v4,right,2,3) jumpr -- "if ( p0 ) jumpr Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 1 1 - - - 1 0 0
#
# (v4,right,2,3) jumpr:nt -- "if ( p0 .new ) jumpr:nt Lr"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 1 1 1 - - - 1 1 0
:jumpr^FlowP0Cond_N01_S00^NotTaken01 LR EndPackedRight is iclass2931=1 & op13=0 & op0612=0x7f & op2=1 & FlowP0Cond_N01_S00 & NotTaken01 & LR & $(END_PACKED_RIGHT) {
dest:4 = LR;
build FlowP0Cond_N01_S00;
build EndPackedRight;
<<FLOW>>
if (ConditionReg == 0) goto <non_flow>;
return [dest];
<non_flow>
}
# (v4,right,0,1,4,5) memb -- "Rd16 = memb ( Rs16 + #u3:0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 0 i i i s s s s d d d d
:memb Rd4r,MemRsRelU3Rb EndPackedRight is iclass31=0 & iclass29=0 & op1113=6 & MemRsRelU3Rb & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = sext(MemRsRelU3Rb);
build EndPackedRight;
}
# (v4,right,2,3) memb -- "Rd16 = memb ( Rs16 + #u3:0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 0 i i i s s s s d d d d
:memb Rd4r,MemRsRelU3Rb EndPackedRight is iclass2931=1 & op1113=2 & MemRsRelU3Rb & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = sext(MemRsRelU3Rb);
build EndPackedRight;
}
# (v4,right,6,7) memb -- "memb ( Rs16 + #u4:0 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 1 1 0 0 1 n s s s s i i i i
#
# (v4,right,10,11) memb -- "memb ( Rs16 + #u4:0 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 1 1 0 0 1 n s s s s i i i i
:memb MemRsRelU4Rnb,Uimm1_08 EndPackedRight is (iclass2931=3 | iclass2931=5) & op0913=0x19 & MemRsRelU4Rnb & Uimm1_08 & $(END_PACKED_RIGHT) {
MemRsRelU4Rnb = Uimm1_08;
build EndPackedRight;
}
# (v4,right,12,13) memb -- "memb ( Rs16 + #u4:0 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 - - - - - - - - - - - - - - - - 1 0 0 1 n s s s s i i i i
:memb MemRsRelU4Rnb,Uimm1_08 EndPackedRight is iclass2931=6 & op0912=9 & MemRsRelU4Rnb & Uimm1_08 & $(END_PACKED_RIGHT) {
MemRsRelU4Rnb = Uimm1_08;
build EndPackedRight;
}
# (v4,right,14,15) memb -- "memb ( Rs16 + #u4:0 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 - - - - - - - - - - - - - - - 0 1 0 0 1 n s s s s i i i i
:memb MemRsRelU4Rnb,Uimm1_08 EndPackedRight is iclass2931=7 & op0913=9 & MemRsRelU4Rnb & Uimm1_08 & $(END_PACKED_RIGHT) {
MemRsRelU4Rnb = Uimm1_08;
build EndPackedRight;
}
# (v4,right,6,7) memb -- "memb ( Rs16 + #u4:0 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 0 1 i i i i s s s s t t t t
#
# (v4,right,10,11) memb -- "memb ( Rs16 + #u4:0 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 0 1 i i i i s s s s t t t t
:memb MemRsRelU4Rb,rt4r EndPackedRight is (iclass2931=3 | iclass2931=5) & op1213=1 & MemRsRelU4Rb & rt4r & $(END_PACKED_RIGHT) {
MemRsRelU4Rb = rt4r:1;
build EndPackedRight;
}
# (v4,right,8,9) memb -- "memb ( Rs16 + #u4:0 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 - - - - - - - - - - - - - - - - 1 i i i i s s s s t t t t
:memb MemRsRelU4Rb,rt4r EndPackedRight is iclass2931=4 & op12=1 & MemRsRelU4Rb & rt4r & $(END_PACKED_RIGHT) {
MemRsRelU4Rb = rt4r:1;
build EndPackedRight;
}
# (v4,right,0,1,4,5) memd -- "Rdd8 = memd ( Sp + #u5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 1 0 i i i i i d d d
:memd Rdd3r,MemSpRelU5Rd EndPackedRight is iclass31=0 & iclass29=0 & op0813=0x3e & MemSpRelU5Rd & Rdd3r & $(END_PACKED_RIGHT) {
Rdd3r = MemSpRelU5Rd;
build EndPackedRight;
}
# (v4,right,2,3) memd -- "Rdd8 = memd ( Sp + #u5:3 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 1 0 i i i i i d d d
:memd Rdd3r,MemSpRelU5Rd EndPackedRight is iclass2931=1 & op0813=0x1e & MemSpRelU5Rd & Rdd3r & $(END_PACKED_RIGHT) {
Rdd3r = MemSpRelU5Rd;
build EndPackedRight;
}
# (v4,right,6,7) memd -- "memd ( Sp + #s6:3 ) = Rtt8"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 1 0 1 0 1 i i i i i i t t t
#
# (v4,right,10,11) memd -- "memd ( Sp + #s6:3 ) = Rtt8"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 1 0 1 0 1 i i i i i i t t t
:memd MemSpRelS6Rd,rtt3r EndPackedRight is (iclass2931=3 | iclass2931=5) & op0913=0x15 & MemSpRelS6Rd & rtt3r & $(END_PACKED_RIGHT) {
MemSpRelS6Rd = rtt3r;
build EndPackedRight;
}
# (v4,right,12,13) memd -- "memd ( Sp + #s6:3 ) = Rtt8"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 - - - - - - - - - - - - - - - - 0 1 0 1 i i i i i i t t t
:memd MemSpRelS6Rd,rtt3r EndPackedRight is iclass2931=6 & op0912=5 & MemSpRelS6Rd & rtt3r & $(END_PACKED_RIGHT) {
MemSpRelS6Rd = rtt3r;
build EndPackedRight;
}
# (v4,right,14,15) memd -- "memd ( Sp + #s6:3 ) = Rtt8"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 - - - - - - - - - - - - - - - 0 0 1 0 1 i i i i i i t t t
:memd MemSpRelS6Rd,rtt3r EndPackedRight is iclass2931=7 & op0913=0x05 & MemSpRelS6Rd & rtt3r & $(END_PACKED_RIGHT) {
MemSpRelS6Rd = rtt3r;
build EndPackedRight;
}
# (v4,right,0,1,4,5) memh -- "Rd16 = memh ( Rs16 + #u3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 0 0 i i i s s s s d d d d
:memh Rd4r,MemRsRelU3Rh EndPackedRight is iclass31=0 & iclass29=0 & op1113=4 & MemRsRelU3Rh & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = sext(MemRsRelU3Rh);
build EndPackedRight;
}
# (v4,right,2) memh -- "Rd16 = memh ( Rs16 + #u3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 - - - - - - - - - - - - - - 0 0 0 i i i s s s s d d d d
:memh Rd4r,MemRsRelU3Rh EndPackedRight is iclass=2 & op1113=0 & MemRsRelU3Rh & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = sext(MemRsRelU3Rh);
build EndPackedRight;
}
# (v4,right,6,7) memh -- "memh ( Rs16 + #u3:1 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 1 0 0 i i i s s s s t t t t
#
# (v4,right,10,11) memh -- "memh ( Rs16 + #u3:1 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 1 0 0 i i i s s s s t t t t
:memh MemRsRelU3Rh,rt4r EndPackedRight is (iclass2931=3 | iclass2931=5) & op1113=4 & MemRsRelU3Rh & rt4r & $(END_PACKED_RIGHT) {
MemRsRelU3Rh = rt4r:2;
build EndPackedRight;
}
# (v4,right,12,13) memh -- "memh ( Rs16 + #u3:1 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 - - - - - - - - - - - - - - - - 0 0 i i i s s s s t t t t
:memh MemRsRelU3Rh,rt4r EndPackedRight is iclass2931=6 & op1112=0 & MemRsRelU3Rh & rt4r & $(END_PACKED_RIGHT) {
MemRsRelU3Rh = rt4r:2;
build EndPackedRight;
}
# (v4,right,14,15) memh -- "memh ( Rs16 + #u3:1 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 - - - - - - - - - - - - - - - 0 0 0 i i i s s s s t t t t
:memh MemRsRelU3Rh,rt4r EndPackedRight is iclass2931=7 & op1113=0 & MemRsRelU3Rh & rt4r & $(END_PACKED_RIGHT) {
MemRsRelU3Rh = rt4r:2;
build EndPackedRight;
}
# (v4,right,0,1,4,5) memub -- "Rd16 = memub ( Rs16 + #u4:0 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 0 1 i i i i s s s s d d d d
:memub Rd4r,MemRsRelU4Rb EndPackedRight is iclass31=0 & iclass29=0 & op1213=1 & MemRsRelU4Rb & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = zext(MemRsRelU4Rb);
build EndPackedRight;
}
# (v4,right,0,1,4,5) memuh -- "Rd16 = memuh ( Rs16 + #u3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 0 1 i i i s s s s d d d d
:memuh Rd4r,MemRsRelU3Rh EndPackedRight is iclass31=0 & iclass29=0 & op1113=5 & MemRsRelU3Rh & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = zext(MemRsRelU3Rh);
build EndPackedRight;
}
# (v4,right,2) memuh -- "Rd16 = memuh ( Rs16 + #u3:1 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 0 - - - - - - - - - - - - - - 0 0 1 i i i s s s s d d d d
:memuh Rd4r,MemRsRelU3Rh EndPackedRight is iclass=2 & op1113=1 & MemRsRelU3Rh & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = zext(MemRsRelU3Rh);
build EndPackedRight;
}
# (v4,right,0,1,4,5) memw -- "Rd16 = memw ( Rs16 + #u4:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 0 0 i i i i s s s s d d d d
:memw Rd4r,MemRsRelU4Rw EndPackedRight is iclass31=0 & iclass29=0 & op1213=0 & MemRsRelU4Rw & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = MemRsRelU4Rw;
build EndPackedRight;
}
# (v4,right,6,7) memw -- "memw ( Rs16 + #u4:2 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 1 1 0 0 0 n s s s s i i i i
#
# (v4,right,10,11) memw -- "memw ( Rs16 + #u4:2 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 1 1 0 0 0 n s s s s i i i i
:memw StMemRsRelC15Rw,Uimm1_08 EndPackedRight is (iclass2931=3 | iclass2931=5) & op13=1 & op0912=8 & StMemRsRelC15Rw & Uimm1_08 & $(END_PACKED_RIGHT) {
StMemRsRelC15Rw = zext(Uimm1_08);
build EndPackedRight;
}
# (v4,right,12,13) memw -- "memw ( Rs16 + #u4:2 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 - - - - - - - - - - - - - - - - 1 0 0 0 n s s s s i i i i
:memw StMemRsRelC15Rw,Uimm1_08 EndPackedRight is iclass2931=6 & op0912=8 & StMemRsRelC15Rw & Uimm1_08 & $(END_PACKED_RIGHT) {
StMemRsRelC15Rw = zext(Uimm1_08);
build EndPackedRight;
}
# (v4,right,14,15) memw -- "memw ( Rs16 + #u4:2 ) = #n1"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 - - - - - - - - - - - - - - - 0 1 0 0 0 n s s s s i i i i
:memw StMemRsRelC15Rw,Uimm1_08 EndPackedRight is iclass2931=7 & op13=0 & op0912=8 & StMemRsRelC15Rw & Uimm1_08 & $(END_PACKED_RIGHT) {
StMemRsRelC15Rw = zext(Uimm1_08);
build EndPackedRight;
}
# (v4,right,8,9) memw -- "memw ( Rs16 + #u4:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 0 - - - - - - - - - - - - - - - - 0 i i i i s s s s t t t t
:memw MemRsRelU4Rw,rt4r EndPackedRight is iclass2931=4 & op12=0 & MemRsRelU4Rw & rt4r & $(END_PACKED_RIGHT) {
MemRsRelU4Rw = rt4r;
build EndPackedRight;
}
# (v4,right,6,7) memw -- "memw ( Rs16 + #u4:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 0 0 i i i i s s s s t t t t
#
# (v4,right,10,11) memw -- "memw ( Rs16 + #u4:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 0 0 i i i i s s s s t t t t
:memw MemRsRelU4Rw,rt4r EndPackedRight is (iclass2931=5 | iclass2931=3) & op1213=0 & MemRsRelU4Rw & rt4r & $(END_PACKED_RIGHT) {
MemRsRelU4Rw = rt4r;
build EndPackedRight;
}
# (v4,right,0,1,4,5) memw -- "Rd16 = memw ( Sp + #u5:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 - 0 - - - - - - - - - - - - - - - 1 1 1 1 0 i i i i i d d d d
:memw Rd4r,MemSpRelU5Rw EndPackedRight is iclass31=0 & iclass29=0 & op0913=0x1e & MemSpRelU5Rw & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = MemSpRelU5Rw;
build EndPackedRight;
}
# (v4,right,2,3) memw -- "Rd16 = memw ( Sp + #u5:2 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 0 1 1 1 0 i i i i i d d d d
:memw Rd4r,MemSpRelU5Rw EndPackedRight is iclass2931=1 & op0913=0x0e & MemSpRelU5Rw & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = MemSpRelU5Rw;
build EndPackedRight;
}
# (v4,right,6,7) memw -- "memw ( Sp + #u5:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 1 1 - - - - - - - - - - - - - - - 1 0 1 0 0 i i i i i t t t t
#
# (v4,right,10,11) memw -- "memw ( Sp + #u5:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 0 1 - - - - - - - - - - - - - - - 1 0 1 0 0 i i i i i t t t t
:memw MemSpRelU5Rw,rt4r EndPackedRight is (iclass2931=3 | iclass2931=5) & op0913=0x14 & MemSpRelU5Rw & rt4r & $(END_PACKED_RIGHT) {
MemSpRelU5Rw = rt4r;
build EndPackedRight;
}
# (v4,right,12,13) memw -- "memw ( Sp + #u5:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 0 - - - - - - - - - - - - - - - - 0 1 0 0 i i i i i t t t t
:memw MemSpRelU5Rw,rt4r EndPackedRight is iclass2931=6 & op0912=4 & MemSpRelU5Rw & rt4r & $(END_PACKED_RIGHT) {
MemSpRelU5Rw = rt4r;
build EndPackedRight;
}
# (v4,right,14,15) memw -- "memw ( Sp + #u5:2 ) = Rt16"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 1 1 1 - - - - - - - - - - - - - - - 0 0 1 0 0 i i i i i t t t t
:memw MemSpRelU5Rw,rt4r EndPackedRight is iclass2931=7 & op0913=0x04 & MemSpRelU5Rw & rt4r & $(END_PACKED_RIGHT) {
MemSpRelU5Rw = rt4r;
build EndPackedRight;
}
# (v4,right,2,3) sxtb -- "Rd16 = sxtb ( Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 1 0 1 s s s s d d d d
:sxtb Rd4r,rs4r EndPackedRight is iclass2931=1 & op0813=0x35 & rs4r & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = (rs4r << 24) s>> 24;
build EndPackedRight;
}
# (v4,right,2,3) sxth -- "Rd16 = sxth ( Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 1 0 0 s s s s d d d d
:sxth Rd4r,rs4r EndPackedRight is iclass2931=1 & op0813=0x34 & rs4r & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = (rs4r << 16) s>> 16;
build EndPackedRight;
}
# (v4,right,2,3) zxth -- "Rd16 = zxth ( Rs16 )"
# _________________________________________________________________________________________________
# |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# 0 0 1 - - - - - - - - - - - - - - - 1 1 0 1 1 0 s s s s d d d d
:zxth Rd4r,rs4r EndPackedRight is iclass2931=1 & op0813=0x36 & rs4r & Rd4r & $(END_PACKED_RIGHT) {
Rd4r = rs4r & 0xffff;
build EndPackedRight;
}

View File

@@ -0,0 +1,72 @@
<patternlist>
<patternpairs>
<prepatterns>
<data>01000000 00111111 ........ 0.0..... </data> <!-- packed EE dealloc_return -->
<data>01000000 00011111 ........ 001..... </data> <!-- packed EE dealloc_return -->
<data>11000000 00111111 ........ 0.0..... </data> <!-- packed EE jumpr LR -->
<data>11000000 00011111 ........ 001..... </data> <!-- packed EE jumpr LR -->
<data>00011110 11000000 00011110 10010110 </data> <!-- PP dealloc_return, last -->
<data>00011110 01000000 00011110 10010110 ........ 11...... ........ ........ </data> <!-- PP dealloc_return, 2nd to last -->
<data>00011110 01000000 00011110 10010110 ........ 00...... ........ ........ </data> <!-- PP dealloc_return, 2nd to last -->
<data>00011110 01000000 00011110 10010110 ........ 01...... ........ ........ ........ 11...... ........ ........ </data> <!-- PP dealloc_return, 3rd to last -->
<data>00011110 01000000 00011110 10010110 ........ 01...... ........ ........ ........ 00...... ........ ........ </data> <!-- PP dealloc_return, 3rd to last -->
<data>00011110 01000000 00011110 10010110 ........ 01...... ........ ........ ........ 01...... ........ ........ ........ 11...... ........ ........ </data> <!-- PP dealloc_return 4th to last -->
<data>.......0 11...... ........ 0101100. </data> <!-- PP jump, last -->
<data>.......0 01...... ........ 0101100. ........ 11...... ........ ........ </data> <!-- PP jump, 2nd to last -->
<data>.......0 01...... ........ 0101100. ........ 00...... ........ ........ </data> <!-- PP jump, 2nd to last -->
<data>.......0 01...... ........ 0101100. ........ 01...... ........ ........ ........ 11...... ........ ........ </data> <!-- PP jump, 3rd to last -->
<data>.......0 01...... ........ 0101100. ........ 01...... ........ ........ ........ 00...... ........ ........ </data> <!-- PP jump, 3rd to last -->
<data>.......0 01...... ........ 0101100. ........ 01...... ........ ........ ........ 01...... ........ ........ ........ 11...... ........ ........ </data> <!-- PP jump 4th to last -->
<data>00000000 01000000 100..... 01010010 </data> <!-- PP jumpr, last -->
<data>00000000 01000000 100..... 01010010 ........ 11...... ........ ........ </data> <!-- PP jumpr, 2nd to last -->
<data>00000000 01000000 100..... 01010010 ........ 00...... ........ ........ </data> <!-- PP jumpr, 2nd to last -->
<data>00000000 01000000 100..... 01010010 ........ 01...... ........ ........ ........ 11...... ........ ........ </data> <!-- PP jumpr, 3rd to last -->
<data>00000000 01000000 100..... 01010010 ........ 01...... ........ ........ ........ 00...... ........ ........ </data> <!-- PP jumpr, 3rd to last -->
<data>00000000 01000000 100..... 01010010 ........ 01...... ........ ........ ........ 01...... ........ ........ ........ 11...... ........ ........ </data> <!-- PP jumpr 4th to last -->
</prepatterns>
<postpatterns>
<!-- First Instruction in Packet -->
<data>........ .1000... 10011101 10100000 </data> <!-- allocframe (v2,10) - 1st in packet -->
<data>....0000 0011110. ........ 011..... </data> <!-- allocframe (v4,right,6,7) - 1 of 1 in packet -->
<data>....0000 0011110. ........ 101..... </data> <!-- allocframe (v4,right,10,11) - 1 of 1 in packet -->
<data>....0000 00.1110. ........ 110..... </data> <!-- allocframe (v4,right,12,13) - 1 of 1 in packet -->
<data>....0000 0001110. ........ 111..... </data> <!-- allocframe (v4,right,14,15) - 1 of 1 in packet -->
<!-- Second Instruction in Packet -->
<data>........ 01...... ........ ........ ........ .1000... 10011101 10100000 </data> <!-- allocframe (v2,10) - 2nd in packet -->
<data>........ 01...... ........ ........ ....0000 0011110. ........ 011..... </data> <!-- allocframe (v4,right,6,7) - 2 of 2 in packet -->
<data>........ 01...... ........ ........ ....0000 0011110. ........ 101..... </data> <!-- allocframe (v4,right,10,11) - 2 of 2 in packet -->
<data>........ 01...... ........ ........ ....0000 00.1110. ........ 110..... </data> <!-- allocframe (v4,right,12,13) - 2 of 2 in packet -->
<data>........ 01...... ........ ........ ....0000 0001110. ........ 111..... </data> <!-- allocframe (v4,right,14,15) - 2 of 2 in packet -->
<!-- Third Instruction in Packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ........ .1000... 10011101 10100000 </data> <!-- allocframe (v2,10) - 3rd in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 0011110. ........ 011..... </data> <!-- allocframe (v4,right,6,7) - 3 of 3 in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 0011110. ........ 101..... </data> <!-- allocframe (v4,right,10,11) - 3 of 3 in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 00.1110. ........ 110..... </data> <!-- allocframe (v4,right,12,13) - 3 of 3 in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 0001110. ........ 111..... </data> <!-- allocframe (v4,right,14,15) - 3 of 3 in packet -->
<!-- Fourth Instruction in Packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ........ 01...... ........ ........ ........ 11000... 10011101 10100000 </data> <!-- allocframe (v2,10) - 4th in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 0011110. ........ 011..... </data> <!-- allocframe (v4,right,6,7) - 4 of 4 in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 0011110. ........ 101..... </data> <!-- allocframe (v4,right,10,11) - 4 of 4 in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 00.1110. ........ 110..... </data> <!-- allocframe (v4,right,12,13) - 4 of 4 in packet -->
<data>........ 01...... ........ ........ ........ 01...... ........ ........ ........ 01...... ........ ........ ....0000 0001110. ........ 111..... </data> <!-- allocframe (v4,right,14,15) - 4 of 4 in packet -->
<funcstart validcode="8" />
</postpatterns>
</patternpairs>
</patternlist>

View File

@@ -0,0 +1,5 @@
<patternconstraints>
<language id="Hexagon:LE:32:*">
<patternfile>Hexagon_patterns.xml</patternfile>
</language>
</patternconstraints>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.analysis;
import ghidra.app.services.AnalysisPriority;
import ghidra.app.util.viewer.field.HexagonParallelInstructionHelper;
import ghidra.program.model.address.*;
import ghidra.program.model.data.DataType;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.scalar.Scalar;
import ghidra.program.model.symbol.*;
import ghidra.program.util.SymbolicPropogator;
import ghidra.program.util.VarnodeContext;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class HexagonAnalyzer extends ConstantPropagationAnalyzer {
private final static String PROCESSOR_NAME = "Hexagon";
private Register r25Register;
private Register lrRegister;
private Register lrNewRegister;
HexagonParallelInstructionHelper helper = new HexagonParallelInstructionHelper();
protected int pass;
public HexagonAnalyzer() {
super(PROCESSOR_NAME);
setPriority(AnalysisPriority.CODE_ANALYSIS.after());
}
@Override
public boolean canAnalyze(Program program) {
Language language = program.getLanguage();
r25Register = program.getRegister("R25");
lrRegister = program.getRegister("LR");
lrNewRegister = program.getRegister("LR.new");
if (language.getProcessor().equals(Processor.findOrPossiblyCreateProcessor("Hexagon")) &&
r25Register != null && lrRegister != null && lrNewRegister != null) {
return true;
}
return false;
}
@Override
public AddressSetView flowConstants(final Program program, Address flowStart,
AddressSetView flowSet, final SymbolicPropogator symEval, final TaskMonitor monitor)
throws CancelledException {
// follow all flows building up context
// use context to fill out addresses on certain instructions
ConstantPropagationContextEvaluator eval =
new ConstantPropagationContextEvaluator(monitor, trustWriteMemOption) {
@Override
public boolean evaluateContext(VarnodeContext context, Instruction instr) {
// if (instr.getMnemonicString().equals("assign")) {
// Register destReg = instr.getRegister(0);
// if (destReg.getBitLength() == 16) {
// String regName = destReg.getName();
// Register shadowDest =
// program.getRegister(regName.substring(0, regName.length() - 1));
// Scalar s = instr.getScalar(1);
// if (s != null) {
// context.setValue(shadowDest, s.getBigInteger());
// }
// context.propogateResults(true);
// BigInteger rval = context.getValue(program.getRegister("R0"), false);
// Msg.info(this, rval == null ? "NULL" : rval.toString(16));
// rval = context.getValue(program.getRegister("R0.L"), false);
// Msg.info(this, rval == null ? "NULL" : rval.toString(16));
// rval = context.getValue(program.getRegister("R0.H"), false);
// Msg.info(this, rval == null ? "NULL" : rval.toString(16));
// }
// }
FlowType ftype = instr.getFlowType();
if (ftype.isComputed() && ftype.isJump()) {
// TODO: MUST get the value... of the PC????
Varnode destVal = null; // context.getRegisterVarnodeValue(indirectFlowDestReg);
if (destVal != null) {
if (isLinkRegister(context, destVal)) {
// need to set the return override
instr.setFlowOverride(FlowOverride.RETURN);
}
}
}
return false;
}
private boolean isLinkRegister(VarnodeContext context, Varnode destVal) {
Address destAddr = destVal.getAddress();
if (destVal.isRegister()) {
return (destAddr.equals(lrRegister.getAddress()) ||
destAddr.equals(lrNewRegister.getAddress()));
}
else if (context.isSymbol(destVal) && destAddr.getOffset() == 0) {
String symbolSpaceName = destAddr.getAddressSpace().getName();
return (symbolSpaceName.equals(lrRegister.getName()) ||
symbolSpaceName.equals(lrNewRegister.getName()));
}
return false;
}
@Override
public boolean evaluateReference(VarnodeContext context, Instruction instr,
int pcodeop, Address address, int size, DataType dataType,
RefType refType) {
if (address.isExternalAddress()) {
return true;
}
// do super check, then do our own checks
if (!super.evaluateReference(context, instr, pcodeop, address, size, dataType,
refType)) {
return false;
}
if (refType.isData()) {
// // for instruction with more operands than two, will be a dual instruction
// // can only do this for single instructions.
// // Only way to tell if has a third operand and is not an empty string!
// List<Object> opRepList = instr.getDefaultOperandRepresentationList(2);
// if (opRepList != null && opRepList.size() != 0) {
// return true;
// }
// TODO: need to do this better.
// Maybe take a look at the register values to tag things on for read/write
// all Reads should be in (). Writes should be in () on the left side.
if (refType.isWrite()) {
// goes on first operand
instr.addOperandReference(0, address, refType, SourceType.ANALYSIS);
return false;
}
else if (refType.isRead()) {
// goes on second operand
instr.addOperandReference(1, address, refType, SourceType.ANALYSIS);
return false;
}
}
// look backward for a good assign instruction that has this as a constant
// want to markup there if we find one.
return markupParallelInstruction(instr, refType, address);
}
/**
* For parallel instruction effects, look back to see if there is a constant in the parallel chain
* to match this target address.
*
* @return true to just mark it up anywhere, false if we actually put the reference on here.
*/
private boolean markupParallelInstruction(Instruction instr, RefType refType,
Address address) {
Instruction prevInst = instr;
int count = 0;
while (helper.isParallelInstruction(prevInst) && count++ < 5) {
Address fallFrom = prevInst.getFallFrom();
if (fallFrom == null)
break;
prevInst = program.getListing().getInstructionAt(fallFrom);
if (prevInst == null)
break;
int numOps = prevInst.getNumOperands();
for (int i = 0; i < numOps; i++) {
Scalar scalar = prevInst.getScalar(i);
if (scalar == null)
continue;
long unsignedValue = scalar.getUnsignedValue();
if (unsignedValue == address.getOffset()) {
// found the value, mark it up
prevInst.addOperandReference(i, address, refType,
SourceType.ANALYSIS);
return false;
}
}
}
return true; // just go ahead and mark up the instruction
}
@Override
public boolean evaluateDestination(VarnodeContext context,
Instruction instruction) {
FlowType flowType = instruction.getFlowType();
if (!flowType.isJump()) {
return false;
}
// TODO: if this is a switch stmt, add to destSet
Reference[] refs = instruction.getReferencesFrom();
if (refs.length <= 0 ||
(refs.length == 1 && refs[0].getReferenceType().isData())) {
destSet.addRange(instruction.getMinAddress(), instruction.getMinAddress());
}
return false;
}
};
eval.setTrustWritableMemory(trustWriteMemOption)
.setMinSpeculativeOffset(minSpeculativeRefAddress)
.setMaxSpeculativeOffset(maxSpeculativeRefAddress)
.setMinStoreLoadOffset(minStoreLoadRefAddress)
.setCreateComplexDataFromPointers(createComplexDataFromPointers);
AddressSet resultSet = symEval.flowConstants(flowStart, flowSet, eval, true, monitor);
return resultSet;
}
}

View File

@@ -0,0 +1,288 @@
/* ###
* IP: GHIDRA
* NOTE: Need to review if these patterns are any indicators of code/original binary, even the address examples
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.analysis;
import ghidra.app.cmd.function.CreateFunctionCmd;
import ghidra.app.services.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.framework.options.Options;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.lang.IncompatibleMaskException;
import ghidra.program.model.lang.MaskImpl;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.DumbMemBufferImpl;
import ghidra.program.model.symbol.SourceType;
import ghidra.util.Msg;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
public class HexagonPrologEpilogAnalyzer extends AbstractAnalyzer {
private static final String NAME = "Hexagon Prolog/Epilog Functions";
private static final String DESCRIPTION =
"Detects common Prolog/Epilog functions used within Hexagon code and marks them as inline";
private final static String PROCESSOR_NAME = "Hexagon";
private final static String OPTION_NAME_FIXUP_FUNCTIONS = "Prolog/Epilog Function Fixup";
private static final String OPTION_DESCRIPTION_FIXUP_FUNCTIONS =
"Select fixup type which should be applied to Prolog functions (save registers) and Epilog functions (restore registers and dealloc frame).";
public enum FIXUP_TYPES {
Name_Only, Inline, Call_Fixup
}
private FIXUP_TYPES fixupType = FIXUP_TYPES.Call_Fixup;
// Call fixup names as defined in cspec
private final static String CALL_FIXUP_PROLOG_NAME = "prolog_save_regs";
private final static String CALL_FIXUP_EPILOG_NAME = "prolog_restore_regs";
// TODO: These patterns may be incomplete
private static InstructionMaskValue NOP = new InstructionMaskValue(0xffff3fff, 0x7f000000); // nop - ignore parse bits
private static InstructionMaskValue JUMPR_LR = new InstructionMaskValue(0xffff3fff, 0x529f0000); // jumpr lr - ignore parse bits
private static InstructionMaskValue JUMP = new InstructionMaskValue(0xfe000001, 0x58000000); // jump - ignore parse bits
private static InstructionMaskValue MEMD_PUSH =
new InstructionMaskValue(0xfdff0000, 0xa5de0000); // memd (FP+#-nn),<rtt5> - ignore parse bits
private static InstructionMaskValue MEMD_POP = new InstructionMaskValue(0xfdff0000, 0x95de0000); // memd <rdd5>,(FP+#-nn) - ignore parse bits
private static InstructionMaskValue DEALLOCFRAME = new InstructionMaskValue(0xffff3fff,
0x901e001e); // deallocframe - ignore parse bits
private static InstructionMaskValue DEALLOC_RETURN = new InstructionMaskValue(0xffff3fff,
0x961e001e); // deallocreturn - ignore parse bits
public HexagonPrologEpilogAnalyzer() {
super(NAME, DESCRIPTION, AnalyzerType.FUNCTION_ANALYZER);
setDefaultEnablement(true);
setPriority(AnalysisPriority.CODE_ANALYSIS.before());
}
@Override
public boolean canAnalyze(Program program) {
if (!PROCESSOR_NAME.equals(program.getLanguage().getProcessor().toString())) {
return false;
}
return true;
}
private boolean setPrologEpilog(Program program, Address entryPoint, boolean isProlog,
TaskMonitor monitor) {
Listing listing = program.getListing();
Function function = listing.getFunctionAt(entryPoint);
if (function == null) {
CreateFunctionCmd cmd = new CreateFunctionCmd(entryPoint);
if (!cmd.applyTo(program, monitor)) {
return false;
}
function = cmd.getFunction();
}
else if (function.isInline()) {
return true;
}
setPrologEpilog(function, isProlog);
return true;
}
private void setPrologEpilog(Function function, boolean isProlog) {
if (fixupType == FIXUP_TYPES.Inline) {
function.setInline(true);
Msg.info(this, "Set inline " + (isProlog ? "prolog" : "epilog") + " function at " +
function.getEntryPoint());
}
else if (fixupType == FIXUP_TYPES.Call_Fixup) {
function.setCallFixup(isProlog ? CALL_FIXUP_PROLOG_NAME : CALL_FIXUP_EPILOG_NAME);
Msg.info(this, "Set call-fixup " + (isProlog ? "prolog" : "epilog") + " function at " +
function.getEntryPoint());
}
if (function.getSymbol().getSource() == SourceType.DEFAULT) {
String name = isProlog ? "prolog_save_regs@" : "epilog_restore_regs@";
try {
function.setName(name + function.getEntryPoint(), SourceType.ANALYSIS);
}
catch (DuplicateNameException e) {
// ignore
}
catch (InvalidInputException e) {
throw new AssertException(e);
}
}
}
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
monitor.setMessage("Find Prologs and Epilogs...");
monitor.initialize(set.getNumAddresses());
int cnt = 0;
for (Function function : program.getListing().getFunctions(set, true)) {
monitor.checkCancelled();
monitor.setProgress(++cnt);
if (function.isInline() || function.getCallFixup() != null) {
continue;
}
if (isProlog(program, function.getEntryPoint(), true, monitor)) {
setPrologEpilog(function, true);
}
else if (isEpilog(program, function.getEntryPoint(), true, monitor)) {
setPrologEpilog(function, false);
}
}
return true;
}
private boolean isProlog(Program program, Address entryPoint, boolean recurseOk,
TaskMonitor monitor) throws CancelledException {
DumbMemBufferImpl mem = new DumbMemBufferImpl(program.getMemory(), entryPoint);
int memdCnt = 0;
boolean returnPending = false;
byte[] bytes = new byte[4];
for (int i = 0; i < 5; i++) {
if (mem.getBytes(bytes, i * 4) != 4) {
return false;
}
if (NOP.isMatch(bytes)) {
// ignore
}
else if (JUMPR_LR.isMatch(bytes)) {
returnPending = true;
}
else if (JUMP.isMatch(bytes)) {
if (!recurseOk ||
!hasContinuationFunction(program, entryPoint.add(i * 4), true, monitor)) {
return false;
}
returnPending = true;
}
else if (MEMD_PUSH.isMatch(bytes)) {
++memdCnt;
}
else {
return false; // unexpected instruction for prolog
}
if (returnPending && ((bytes[1] & 0x0c0) == 0x0c0)) {
break; // return pending and at end of parallel group
}
}
return (memdCnt != 0);
}
private boolean isEpilog(Program program, Address entryPoint, boolean recurseOk,
TaskMonitor monitor) throws CancelledException {
DumbMemBufferImpl mem = new DumbMemBufferImpl(program.getMemory(), entryPoint);
int memdCnt = 0;
boolean returnPending = false;
byte[] bytes = new byte[4];
for (int i = 0; i < 5; i++) {
if (mem.getBytes(bytes, i * 4) != 4) {
return false;
}
if (NOP.isMatch(bytes)) {
// ignore
}
else if (JUMPR_LR.isMatch(bytes) || DEALLOC_RETURN.isMatch(bytes)) {
returnPending = true;
}
else if (JUMP.isMatch(bytes)) {
if (!recurseOk ||
!hasContinuationFunction(program, entryPoint.add(i * 4), false, monitor)) {
return false;
}
returnPending = true;
}
else if (MEMD_POP.isMatch(bytes)) {
++memdCnt;
}
else if (DEALLOCFRAME.isMatch(bytes)) {
// ignore
}
else {
return false; // unexpected instruction for prolog
}
if (returnPending && ((bytes[1] & 0x0c0) == 0x0c0)) {
break; // return pending and at end of parallel group
}
}
return (memdCnt != 0);
}
private boolean hasContinuationFunction(Program program, Address jumpFromAddr,
boolean checkProlog, TaskMonitor monitor) throws CancelledException {
Listing listing = program.getListing();
Instruction instr = listing.getInstructionAt(jumpFromAddr);
if (instr == null) {
// unable to continue without instruction at jumpFromAddr
return false;
}
Address destAddr = instr.getAddress(0);
if (destAddr == null) {
return false;
}
if (checkProlog) {
return (isProlog(program, destAddr, false, monitor) && setPrologEpilog(program,
destAddr, true, monitor));
}
return (isEpilog(program, destAddr, false, monitor) && setPrologEpilog(program, destAddr,
false, monitor));
}
@Override
public void registerOptions(Options options, Program program) {
options.registerOption(OPTION_NAME_FIXUP_FUNCTIONS, FIXUP_TYPES.Name_Only, null,
OPTION_DESCRIPTION_FIXUP_FUNCTIONS);
}
@Override
public void optionsChanged(Options options, Program program) {
fixupType = options.getEnum(OPTION_NAME_FIXUP_FUNCTIONS, FIXUP_TYPES.Name_Only);
}
private static class InstructionMaskValue {
private MaskImpl mask;
private byte[] valueBytes;
InstructionMaskValue(int maskValue, int value) {
mask = new MaskImpl(getBytes(maskValue));
valueBytes = getBytes(value);
}
public boolean isMatch(byte[] bytes) {
try {
return mask.equalMaskedValue(bytes, valueBytes);
}
catch (IncompatibleMaskException e) {
throw new AssertException(e);
}
}
}
private static byte[] getBytes(int value) {
byte[] bytes = new byte[4];
// TODO: Order may need to change !!
bytes[0] = (byte) value;
bytes[1] = (byte) (value >> 8);
bytes[2] = (byte) (value >> 16);
bytes[3] = (byte) (value >> 24);
return bytes;
}
}

View File

@@ -0,0 +1,292 @@
/* ###
* IP: GHIDRA
* NOTE: Need to review if these patterns are any indicators of code/original binary, even the address examples
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.analysis;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.cmd.function.CreateFunctionCmd;
import ghidra.app.services.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.*;
import ghidra.program.util.SymbolicPropogator;
import ghidra.util.bytesearch.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class HexagonThunkAnalyzer extends AbstractAnalyzer {
private static final String NAME = "Hexagon Thunks";
private static final String DESCRIPTION =
"Detects common Thunk pattern used within Hexagon code";
/**
* <code>THUNK_PATTERN1</code>
* <pre>
* 1d 7f fd bf add SP,SP,#-0x8
* fe fc 9d a7 || memw (SP+#-0x8),R28
* aa ca bc 72 assign R28.H,#0x8aaa
* aa cb bc 71 assign R28.L,#0x8baa
* 1d 41 1d b0 add SP,SP,#0x8
* 00 40 9c 52 || jumpr R28
* 1c c0 9d 91 || memw R28,(SP)
* </pre>
*/
private static final String THUNK_PATTERN1 =
"0x1d7ffdbf 0xfefc9da7 " + "..................11110001110010 " // first assign .H
+ "..................11110001110001 " // second assign .L
+ "0x1d411db0 0x00409c52 0x1cc09d91";
private final static String PROCESSOR_NAME = "Hexagon";
private BulkPatternSearcher<Pattern> sequenceSearchState;
public HexagonThunkAnalyzer() {
super(NAME, DESCRIPTION, AnalyzerType.INSTRUCTION_ANALYZER);
setDefaultEnablement(true);
setPriority(AnalysisPriority.CODE_ANALYSIS.before());
}
@Override
public boolean canAnalyze(Program program) {
if (!PROCESSOR_NAME.equals(program.getLanguage().getProcessor().toString())) {
return false;
}
return true;
}
private BulkPatternSearcher<Pattern> getSequenceSearchState() {
if (sequenceSearchState == null) {
List<Pattern> thunkPatterns = new ArrayList<Pattern>();
thunkPatterns.add(new Pattern(new DittedBitSequence(THUNK_PATTERN1), 0,
new PostRule[0], new MatchAction[0]));
sequenceSearchState = new BulkPatternSearcher<Pattern>(thunkPatterns);
}
return sequenceSearchState;
}
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
monitor.setMessage("Search for Thunks...");
BulkPatternSearcher<Pattern> searchState = getSequenceSearchState();
long numAddrs = 0;
monitor.initialize(set.getNumAddresses());
MemoryBlock[] blocks = program.getMemory().getBlocks();
for (int i = 0; i < blocks.length; ++i) {
monitor.setProgress(numAddrs);
MemoryBlock block = blocks[i];
numAddrs += block.getSize();
try {
if (set.intersects(block.getStart(), block.getEnd())) {
searchBlock(searchState, program, block, set, monitor, log);
}
}
catch (IOException e) {
log.appendMsg("Unable to scan block " + block.getName() + " for function starts");
}
}
return true;
}
private void searchBlock(BulkPatternSearcher<Pattern> searchState, Program program,
MemoryBlock block,
AddressSetView restrictSet, TaskMonitor monitor, MessageLog log) throws IOException,
CancelledException {
// if no restricted set, make restrict set the full block
AddressSet doneSet = new AddressSet(restrictSet);
if (doneSet.isEmpty()) {
doneSet.addRange(block.getStart(), block.getEnd());
}
doneSet = doneSet.intersectRange(block.getStart(), block.getEnd());
long currentProgress = monitor.getProgress();
// pull each range off the restricted set
AddressRangeIterator addressRanges = doneSet.getAddressRanges();
while (addressRanges.hasNext()) {
monitor.checkCancelled();
AddressRange addressRange = addressRanges.next();
monitor.setProgress(currentProgress);
currentProgress += addressRange.getLength();
ArrayList<Match<Pattern>> mymatches = new ArrayList<>();
Address blockStartAddr = block.getStart();
long blockOffset = addressRange.getMinAddress().subtract(blockStartAddr);
if (blockOffset <= 0) {
// don't go before the block start
blockOffset = 0;
}
// compute number of bytes in the range + 1, and don't search more than that.
long maxBlockSearchLength =
addressRange.getMaxAddress().subtract(blockStartAddr) - blockOffset + 1;
InputStream data = block.getData();
data.skip(blockOffset);
searchState.search(data, maxBlockSearchLength, mymatches, monitor);
monitor.checkCancelled();
// TODO: DANGER there is much offset<-->address calculation here
// should be OK, since they are all relative to the block.
for (int i = 0; i < mymatches.size(); ++i) {
monitor.checkCancelled();
Match<Pattern> match = mymatches.get(i);
Pattern pattern = match.getPattern();
long offset = blockOffset + match.getStart() + pattern.getMarkOffset();
Address addr = blockStartAddr.add(offset);
createThunk(program, addr, monitor, log);
}
}
}
private Address getThunkDestination(Function thunk, AddressSetView body) {
Listing listing = thunk.getProgram().getListing();
Instruction lastInstr = listing.getInstructionContaining(body.getMaxAddress());
if (lastInstr == null) {
return null;
}
FlowType flowType = lastInstr.getFlowType();
if (!flowType.isCall() && !flowType.isJump()) {
return null;
}
Reference flowRef = null;
for (Reference ref : lastInstr.getReferencesFrom()) {
RefType refType = ref.getReferenceType();
if (!refType.isFlow()) {
continue;
}
if (flowRef != null) {
return null;
}
if (!refType.isCall() && !refType.isJump()) {
return null;
}
flowRef = ref;
}
return flowRef != null ? flowRef.getToAddress() : null;
}
private void createThunk(Program program, Address addr, TaskMonitor monitor, MessageLog log)
throws CancelledException {
// check existing function first
Function func = program.getFunctionManager().getFunctionAt(addr);
if (func != null && func.isThunk()) {
return;
}
// no instruction, ignore it
Instruction instruction = program.getListing().getInstructionAt(addr);
if (instruction == null) {
return;
}
// don't know a body, make a dummy
AddressSet body;
body = new AddressSet(addr, addr.add(27));
// first get function to destination
// use the symbolic propagator to lay down the reference (restricted to this body).
SymbolicPropogator symEval = new SymbolicPropogator(program);
symEval.flowConstants(addr, body, null, true, monitor);
// if the found snippet is fallen into, at least get the to ref, so if
// this is found to be a thunk later, the reference is already there.
// instruction falling into it, not a thunk
// instruction must not be a jump to this location either.
Address fallFrom = instruction.getFallFrom();
if (fallFrom != null) {
Instruction fromInstr = program.getListing().getInstructionAt(fallFrom);
if (fromInstr != null) {
FlowType flowType = fromInstr.getFlowType();
if (!flowType.isJump() || flowType.isConditional()) {
return;
}
Reference[] referencesFrom = fromInstr.getReferencesFrom();
for (int i = 0; i < referencesFrom.length; i++) {
if (!referencesFrom.equals(addr)) {
return;
}
}
}
}
// Then create the body.
if (func == null) {
// must create it
CreateFunctionCmd createFunctionCmd =
new CreateFunctionCmd(null, addr, body, SourceType.ANALYSIS);
createFunctionCmd.applyTo(program);
func = program.getFunctionManager().getFunctionAt(addr);
}
if (func == null) {
return;
}
Address thunkDest = getThunkDestination(func, body);
if (thunkDest == null) {
return;
}
Listing listing = func.getProgram().getListing();
FunctionManager funcMgr = func.getProgram().getFunctionManager();
Function thunkedFunc = funcMgr.getFunctionAt(thunkDest);
if (thunkedFunc == null) {
Instruction instr = listing.getInstructionAt(thunkDest);
if (instr == null) {
return;
}
CreateFunctionCmd cmd = new CreateFunctionCmd(thunkDest);
cmd.applyTo(func.getProgram());
thunkedFunc = funcMgr.getFunctionAt(thunkDest);
if (thunkedFunc == null) {
return;
}
}
func.setThunkedFunction(thunkedFunc);
}
}

View File

@@ -0,0 +1,190 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.analysis;
import ghidra.app.services.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashSet;
public class HexagonUnsupportSemanticAnalyzer extends AbstractAnalyzer {
private static final String NAME = "Hexagon Unsupported Semantic Check";
private static final String DESCRIPTION =
"Detects and bookmarks instruction packets which read a predicate register before it is written";
private final static String PROCESSOR_NAME = "Hexagon";
private final static String BOOKMARK_CATEGORY_NAME = "Unsupported Semantics";
private static final String[] predicateNames = new String[] { "P0", "P1", "P2", "P3" };
private Register packetOffsetRegister;
private HashSet<Register> pNewRegisters = new HashSet<Register>();
public HexagonUnsupportSemanticAnalyzer() {
super(NAME, DESCRIPTION, AnalyzerType.INSTRUCTION_ANALYZER);
setDefaultEnablement(true);
setSupportsOneTimeAnalysis();
setPriority(AnalysisPriority.CODE_ANALYSIS);
}
@Override
public boolean canAnalyze(Program program) {
if (!PROCESSOR_NAME.equals(program.getLanguage().getProcessor().toString())) {
return false;
}
packetOffsetRegister = program.getRegister("packetOffset");
for (int i = 0; i < predicateNames.length; i++) {
Register predReg = program.getRegister(predicateNames[i] + ".new");
pNewRegisters.add(predReg);
}
return true;
}
private boolean isStartOfPacket(Instruction instruction) {
BigInteger value = instruction.getValue(packetOffsetRegister, false);
return value == null || (value.intValue() == 0);
}
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
for (AddressRange range : set) {
added(program, range.getMinAddress(), range.getMaxAddress(), monitor, log);
}
return true;
}
private Address getStartOfPacket(Program program, Address instrAddr) {
Listing listing = program.getListing();
// assume we will only get aligned address
Instruction instr = listing.getInstructionAt(instrAddr);
try {
while (instr != null && !isStartOfPacket(instr)) {
Address prevAddr = instrAddr.subtractNoWrap(4);
instr = listing.getInstructionAt(prevAddr);
if (instr != null) {
instrAddr = instr.getAddress();
}
}
}
catch (AddressOverflowException e) {
// ignore
}
return instrAddr;
}
private int getPredicateNumber(Register preg) {
return preg.getName().charAt(1) - 0x30;
}
private void added(Program program, Address minAddr, Address maxAddr, TaskMonitor monitor,
MessageLog log) {
Listing listing = program.getListing();
boolean[] predWasWritten = new boolean[predicateNames.length];
Arrays.fill(predWasWritten, false);
Address instrAddr = getStartOfPacket(program, minAddr); // find start of packet
Instruction instr = listing.getInstructionAt(instrAddr);
// skip past empty regions
if (instr == null) {
instr = listing.getInstructionAfter(instrAddr);
if (instr == null) {
return;
}
}
instrAddr = instr.getAddress();
while (instr != null && (instrAddr.compareTo(maxAddr) <= 0 || !isStartOfPacket(instr))) {
if (isStartOfPacket(instr)) {
Arrays.fill(predWasWritten, false);
}
for (PcodeOp op : instr.getPcode()) {
for (Varnode in : op.getInputs()) {
if (in.isRegister() && in.getSize() == 1) {
Register reg = program.getRegister(in.getAddress(), 1);
if (pNewRegisters.contains(reg)) {
int index = getPredicateNumber(reg);
if (!predWasWritten[index]) {
markUnsupportPredicateRead(instr, reg);
}
}
}
}
Varnode out = op.getOutput();
if (out != null && out.isRegister() && out.getSize() == 1) {
Register reg = program.getRegister(out.getAddress(), 1);
if (pNewRegisters.contains(reg)) {
// We ignore write to P3P0_ since this should only occur for packet initialization
int index = getPredicateNumber(reg);
predWasWritten[index] = true;
}
}
}
try {
instrAddr = instrAddr.addNoWrap(4);
}
catch (AddressOverflowException e) {
break;
}
instr = listing.getInstructionAt(instrAddr);
if (instr == null) {
// skip past empty regions
instr = listing.getInstructionAfter(instrAddr);
if (instr != null) {
instrAddr = instr.getAddress();
Arrays.fill(predWasWritten, false);
}
}
}
}
private void markUnsupportPredicateRead(Instruction instr, Register predReg) {
instr.getProgram().getBookmarkManager().setBookmark(instr.getAddress(),
BookmarkType.WARNING, BOOKMARK_CATEGORY_NAME,
"Predicate " + predReg.getName() + " read before written");
}
@Override
public boolean removed(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
program.getBookmarkManager().removeBookmarks(set, BookmarkType.WARNING,
BOOKMARK_CATEGORY_NAME, monitor);
return true;
}
}

View File

@@ -0,0 +1,71 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.elf;
public class Hexagon_ElfConstants {
// Hexagon-specific e_flags
// Object processor version flags, bits[11:0]
public static final int EF_HEXAGON_MACH_V2 = 0x00000001; // Hexagon V2
public static final int EF_HEXAGON_MACH_V3 = 0x00000002; // Hexagon V3
public static final int EF_HEXAGON_MACH_V4 = 0x00000003; // Hexagon V4
public static final int EF_HEXAGON_MACH_V5 = 0x00000004; // Hexagon V5
public static final int EF_HEXAGON_MACH_V55 = 0x00000005; // Hexagon V55
public static final int EF_HEXAGON_MACH_V60 = 0x00000060; // Hexagon V60
public static final int EF_HEXAGON_MACH_V62 = 0x00000062; // Hexagon V62
public static final int EF_HEXAGON_MACH_V65 = 0x00000065; // Hexagon V65
public static final int EF_HEXAGON_MACH_V66 = 0x00000066; // Hexagon V66
public static final int EF_HEXAGON_MACH_V67 = 0x00000067; // Hexagon V67
public static final int EF_HEXAGON_MACH_V67T = 0x00008067; // Hexagon V67T
public static final int EF_HEXAGON_MACH_V68 = 0x00000068; // Hexagon V68
public static final int EF_HEXAGON_MACH_V69 = 0x00000069; // Hexagon V69
public static final int EF_HEXAGON_MACH_V71 = 0x00000071; // Hexagon V71
public static final int EF_HEXAGON_MACH_V71T = 0x00008071; // Hexagon V71T
public static final int EF_HEXAGON_MACH_V73 = 0x00000073; // Hexagon V73
public static final int EF_HEXAGON_MACH = 0x000003ff; // Hexagon V..
// Highest ISA version flags
public static final int EF_HEXAGON_ISA_MACH = 0x00000000; // Same as specified in bits[11:0] of e_flags
public static final int EF_HEXAGON_ISA_V2 = 0x00000010; // Hexagon V2 ISA
public static final int EF_HEXAGON_ISA_V3 = 0x00000020; // Hexagon V3 ISA
public static final int EF_HEXAGON_ISA_V4 = 0x00000030; // Hexagon V4 ISA
public static final int EF_HEXAGON_ISA_V5 = 0x00000040; // Hexagon V5 ISA
public static final int EF_HEXAGON_ISA_V55 = 0x00000050; // Hexagon V55 ISA
public static final int EF_HEXAGON_ISA_V60 = 0x00000060; // Hexagon V60 ISA
public static final int EF_HEXAGON_ISA_V62 = 0x00000062; // Hexagon V62 ISA
public static final int EF_HEXAGON_ISA_V65 = 0x00000065; // Hexagon V65 ISA
public static final int EF_HEXAGON_ISA_V66 = 0x00000066; // Hexagon V66 ISA
public static final int EF_HEXAGON_ISA_V67 = 0x00000067; // Hexagon V67 ISA
public static final int EF_HEXAGON_ISA_V68 = 0x00000068; // Hexagon V68 ISA
public static final int EF_HEXAGON_ISA_V69 = 0x00000069; // Hexagon V69 ISA
public static final int EF_HEXAGON_ISA_V71 = 0x00000071; // Hexagon V71 ISA
public static final int EF_HEXAGON_ISA_V73 = 0x00000073; // Hexagon V73 ISA
public static final int EF_HEXAGON_ISA_V75 = 0x00000075; // Hexagon V75 ISA
public static final int EF_HEXAGON_ISA = 0x000003ff; // Hexagon V.. ISA
// Hexagon-specific section indexes for common small data
public static final int SHN_HEXAGON_SCOMMON = 0xff00; // Other access sizes
public static final int SHN_HEXAGON_SCOMMON_1 = 0xff01; // Byte-sized access
public static final int SHN_HEXAGON_SCOMMON_2 = 0xff02; // Half-word-sized access
public static final int SHN_HEXAGON_SCOMMON_4 = 0xff03; // Word-sized access
public static final int SHN_HEXAGON_SCOMMON_8 = 0xff04; // Double-word-size access
private Hexagon_ElfConstants() {
// no construct
}
}

View File

@@ -0,0 +1,74 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.elf.extend;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.bin.format.elf.ElfDynamicType.ElfDynamicValueType;
import ghidra.program.model.lang.Language;
public class Hexagon_ElfExtension extends ElfExtension {
// Elf Program Header Extensions
public static final ElfProgramHeaderType PT_ARM_EXIDX =
new ElfProgramHeaderType(0x70000000, "PT_ARM_EXIDX", "Frame unwind information");
// Elf Section Header Extensions
public static final ElfSectionHeaderType SHT_ARM_EXIDX =
new ElfSectionHeaderType(0x70000001, "SHT_ARM_EXIDX", "Exception Index table");
public static final ElfSectionHeaderType SHT_ARM_PREEMPTMAP = new ElfSectionHeaderType(
0x70000002, "SHT_ARM_PREEMPTMAP", "BPABI DLL dynamic linking preemption map");
public static final ElfSectionHeaderType SHT_ARM_ATTRIBUTES = new ElfSectionHeaderType(
0x70000003, "SHT_ARM_ATTRIBUTES", "Object file compatibility attributes");
public static final ElfSectionHeaderType SHT_ARM_DEBUGOVERLAY =
new ElfSectionHeaderType(0x70000004, "SHT_ARM_DEBUGOVERLAY", "See DBGOVL for details");
public static final ElfSectionHeaderType SHT_ARM_OVERLAYSECTION =
new ElfSectionHeaderType(0x70000005, "SHT_ARM_OVERLAYSECTION",
"See Debugging Overlaid Programs (DBGOVL) for details");
// Elf Dynamic Type Extensions
// DT_HEXAGON_SYMSZ: This value is equivalent to the value of DT_SYMENT multiplied by the value
// field "nchain" in the hash table pointed to by DT_HASH.
public static final ElfDynamicType DT_HEXAGON_SYMSZ =
new ElfDynamicType(0x70000000, "DT_HEXAGON_SYMSZ",
"Size in bytes of the DT_SYMTAB symbol table ", ElfDynamicValueType.VALUE);
// DT_HEXAGON_VER: Currently can be a value of 2 or 3. Hexagon ABI requires a value of 3
// although the default is 2.
public static final ElfDynamicType DT_HEXAGON_VER = new ElfDynamicType(0x70000001,
"DT_HEXAGON_VER", "Version of interface with dynamic linker", ElfDynamicValueType.VALUE);
public static final ElfDynamicType DT_HEXAGON_PLT = new ElfDynamicType(0x70000002,
"DT_HEXAGON_PLT", "Image offset of the PLT", ElfDynamicValueType.VALUE);
@Override
public boolean canHandle(ElfHeader elf) {
return elf.e_machine() == ElfConstants.EM_HEXAGON;
}
@Override
public boolean canHandle(ElfLoadHelper elfLoadHelper) {
Language language = elfLoadHelper.getProgram().getLanguage();
return canHandle(elfLoadHelper.getElfHeader()) &&
"Hexagon".equals(language.getProcessor().toString());
}
@Override
public String getDataTypeSuffix() {
return "_Hexagon";
}
}

View File

@@ -0,0 +1,34 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.elf.extend;
public class Hexagon_ElfProgramHeaderConstants {
public static final int EF_HEXAGON_MACH_V4 = 0x3; // Hexagon V4
public static final int EF_HEXAGON_MACH_V5 = 0x4; // Hexagon V5
public static final int EF_HEXAGON_MACH_V55 = 0x5; // Hexagon V55
public static final int EF_HEXAGON_MACH_V60 = 0x60; // Hexagon V60
public static final int EF_HEXAGON_MACH_V61 = 0x61; // Hexagon V61
public static final int EF_HEXAGON_MACH_V62 = 0x62; // Hexagon V62
public static final int EF_HEXAGON_MACH_V65 = 0x65; // Hexagon V65
public static final int EF_HEXAGON_MACH_V66 = 0x66; // Hexagon V66
public static final int EF_HEXAGON_MACH_V67 = 0x67; // Hexagon V67
public static final int EF_HEXAGON_MACH_V67T = 0x8067; // Hexagon V67 Small Core (V67t)
public static final int EF_HEXAGON_MACH_V68 = 0x68; // Hexagon V68
public static final int EF_HEXAGON_MACH_V69 = 0x69; // Hexagon V69
public static final int EF_HEXAGON_MACH_V71 = 0x71; // Hexagon V71
}

View File

@@ -0,0 +1,219 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.elf.relocation;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.reloc.RelocationResult;
public class Hexagon_ElfRelocationHandler
extends AbstractElfRelocationHandler<Hexagon_ElfRelocationType, ElfRelocationContext<?>> {
/**
* Constructor
*/
public Hexagon_ElfRelocationHandler() {
super(Hexagon_ElfRelocationType.class);
}
@Override
public boolean canRelocate(ElfHeader elf) {
return elf.e_machine() == ElfConstants.EM_HEXAGON;
}
@Override
public int getRelrRelocationType() {
return Hexagon_ElfRelocationType.R_HEXAGON_RELATIVE.typeId;
}
@Override
protected RelocationResult relocate(ElfRelocationContext<?> elfRelocationContext,
ElfRelocation relocation, Hexagon_ElfRelocationType type, Address relocationAddress,
ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName)
throws MemoryAccessException {
Program program = elfRelocationContext.getProgram();
Memory memory = program.getMemory();
MessageLog log = elfRelocationContext.getLog();
long addend = relocation.getAddend();
long offset = (int) relocationAddress.getOffset();
int symbolIndex = relocation.getSymbolIndex();
int byteLength = 4; // applied relocation length
// Handle relative relocations that do not require symbolAddr or symbolValue
switch (type) {
case R_HEXAGON_RELATIVE:
long imageBaseAdjustment = elfRelocationContext.getImageBaseWordAdjustmentOffset();
int value = (int) (addend + imageBaseAdjustment);
memory.setInt(relocationAddress, value);
return new RelocationResult(Status.APPLIED, byteLength);
case R_HEXAGON_COPY:
markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex,
elfSymbol.getSize(), elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
default:
break;
}
// Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below
if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) {
return RelocationResult.FAILURE;
}
int value = (int) (symbolValue + addend);
int memValue = memory.getInt(relocationAddress);
switch (type) {
case R_HEXAGON_B22_PCREL:
int dist =
(int) (Integer.toUnsignedLong(value) - Integer.toUnsignedLong((int) offset));
if ((dist < -0x00800000) || (dist >= 0x00800000)) {
return RelocationResult.FAILURE;
}
memValue &= ~0x01ff3fff;
memValue |= 0x00003fff & dist;
memValue |= 0x01ff0000 & (dist << 2);
memory.setInt(relocationAddress, memValue);
break;
// break;
// case R_HEXAGON_B15_PCREL:
// break;
// case R_HEXAGON_B7_PCREL:
// break;
case R_HEXAGON_HI16:
value = (value >> 16) & 0xffff;
/* fallthrough */
case R_HEXAGON_LO16:
memValue &= ~0x00c03fff;
memValue |= value & 0x3fff;
memValue |= (value & 0xc000) << 8;
memory.setInt(relocationAddress, memValue);
break;
case R_HEXAGON_32:
memory.setInt(relocationAddress, value);
if (symbolIndex != 0 && addend != 0 && !elfSymbol.isSection()) {
warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName,
addend, elfRelocationContext.getLog());
applyComponentOffsetPointer(program, relocationAddress, addend);
}
break;
case R_HEXAGON_16:
memory.setShort(relocationAddress, (short) value);
byteLength = 2;
break;
case R_HEXAGON_8:
memory.setByte(relocationAddress, (byte) value);
byteLength = 1;
break;
// case R_HEXAGON_GPREL16_0:
// break;
// case R_HEXAGON_GPREL16_1:
// break;
// case R_HEXAGON_GPREL16_2:
// break;
// case R_HEXAGON_GPREL16_3:
// break;
// case R_HEXAGON_HL16:
// break;
// case R_HEXAGON_B13_PCREL:
// break;
// case R_HEXAGON_B9_PCREL:
// break;
// case R_HEXAGON_B32_PCREL_X:
// break;
// case R_HEXAGON_32_6_X:
// break;
// case R_HEXAGON_B22_PCREL_X:
// break;
// case R_HEXAGON_B15_PCREL_X:
// break;
// case R_HEXAGON_B13_PCREL_X:
// break;
// case R_HEXAGON_B9_PCREL_X:
// break;
// case R_HEXAGON_B7_PCREL_X:
// break;
// case R_HEXAGON_16_X:
// break;
// case R_HEXAGON_12_X:
// break;
// case R_HEXAGON_11_X:
// break;
// case R_HEXAGON_10_X:
// break;
// case R_HEXAGON_9_X:
// break;
// case R_HEXAGON_8_X:
// break;
// case R_HEXAGON_7_X:
// break;
// case R_HEXAGON_6_X:
// break;
case R_HEXAGON_32_PCREL:
dist = (int) (Integer.toUnsignedLong(value) - Integer.toUnsignedLong((int) offset));
memory.setInt(relocationAddress, dist);
break;
case R_HEXAGON_GLOB_DAT:
case R_HEXAGON_JMP_SLOT: {
memory.setInt(relocationAddress, value);
break;
}
// case R_HEXAGON_PLT_B22_PCREL:
// break;
// case R_HEXAGON_GOTOFF_LO16:
// break;
// case R_HEXAGON_GOTOFF_HI16:
// break;
// case R_HEXAGON_GOTOFF_32:
// break;
// case R_HEXAGON_GOT_LO16:
// break; // TODO: See MIPS for similar HI/LO approach
// case R_HEXAGON_GOT_HI16:
// break; // TODO: See MIPS for similar HI/LO approach
// case R_HEXAGON_GOT_32:
// break;
// case R_HEXAGON_GOT_16:
// break;
default:
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, log);
return RelocationResult.UNSUPPORTED;
}
return new RelocationResult(Status.APPLIED, byteLength);
}
}

View File

@@ -0,0 +1,151 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.elf.relocation;
public enum Hexagon_ElfRelocationType implements ElfRelocationType {
/**
* NOTES:
* 1. The GP register is set to the starting address of the process's small data area,
* as referenced by the program symbol, "_SDA_BASE_".
*
*
*/
/* V2 */
R_HEXAGON_NONE(0),
R_HEXAGON_B22_PCREL(1),
R_HEXAGON_B15_PCREL(2),
R_HEXAGON_B7_PCREL(3),
R_HEXAGON_LO16(4),
R_HEXAGON_HI16(5),
R_HEXAGON_32(6),
R_HEXAGON_16(7),
R_HEXAGON_8(8),
R_HEXAGON_GPREL16_0(9),
R_HEXAGON_GPREL16_1(10),
R_HEXAGON_GPREL16_2(11),
R_HEXAGON_GPREL16_3(12),
R_HEXAGON_HL16(13),
/* V3 */
R_HEXAGON_B13_PCREL(14),
/* V4 */
R_HEXAGON_B9_PCREL(15),
/* V4 (extenders) */
R_HEXAGON_B32_PCREL_X(16),
R_HEXAGON_32_6_X(17),
/* V4 (extended) */
R_HEXAGON_B22_PCREL_X(18),
R_HEXAGON_B15_PCREL_X(19),
R_HEXAGON_B13_PCREL_X(20),
R_HEXAGON_B9_PCREL_X(21),
R_HEXAGON_B7_PCREL_X(22),
R_HEXAGON_16_X(23),
R_HEXAGON_12_X(24),
R_HEXAGON_11_X(25),
R_HEXAGON_10_X(26),
R_HEXAGON_9_X(27),
R_HEXAGON_8_X(28),
R_HEXAGON_7_X(29),
R_HEXAGON_6_X(30),
/* V2 PIC */
R_HEXAGON_32_PCREL(31),
R_HEXAGON_COPY(32),
R_HEXAGON_GLOB_DAT(33),
R_HEXAGON_JMP_SLOT(34),
R_HEXAGON_RELATIVE(35),
R_HEXAGON_PLT_B22_PCREL(36),
R_HEXAGON_GOTOFF_LO16(37),
R_HEXAGON_GOTOFF_HI16(38),
R_HEXAGON_GOTOFF_32(39),
R_HEXAGON_GOT_LO16(40),
R_HEXAGON_GOT_HI16(41),
R_HEXAGON_GOT_32(42),
R_HEXAGON_GOT_16(43),
R_HEXAGON_DTPMOD_32(44),
R_HEXAGON_DTPREL_LO16(45),
R_HEXAGON_DTPREL_HI16(46),
R_HEXAGON_DTPREL_32(47),
R_HEXAGON_DTPREL_16(48),
R_HEXAGON_GD_PLT_B22_PCREL(49),
R_HEXAGON_GD_GOT_LO16(50),
R_HEXAGON_GD_GOT_HI16(51),
R_HEXAGON_GD_GOT_32(52),
R_HEXAGON_GD_GOT_16(53),
R_HEXAGON_IE_LO16(54),
R_HEXAGON_IE_HI16(55),
R_HEXAGON_IE_32(56),
R_HEXAGON_IE_GOT_LO16(57),
R_HEXAGON_IE_GOT_HI16(58),
R_HEXAGON_IE_GOT_32(59),
R_HEXAGON_IE_GOT_16(60),
R_HEXAGON_TPREL_LO16(61),
R_HEXAGON_TPREL_HI16(62),
R_HEXAGON_TPREL_32(63),
R_HEXAGON_TPREL_16(64),
R_HEXAGON_6_PCREL_X(65),
R_HEXAGON_GOTREL_32_6_X(66),
R_HEXAGON_GOTREL_16_X(67),
R_HEXAGON_GOTREL_11_X(68),
R_HEXAGON_GOT_32_6_X(69),
R_HEXAGON_GOT_16_X(70),
R_HEXAGON_GOT_11_X(71),
R_HEXAGON_DTPREL_32_6_X(72),
R_HEXAGON_DTPREL_16_X(73),
R_HEXAGON_DTPREL_11_X(74),
R_HEXAGON_GD_GOT_32_6_X(75),
R_HEXAGON_GD_GOT_16_X(76),
R_HEXAGON_GD_GOT_11_X(77),
R_HEXAGON_IE_32_6_X(78),
R_HEXAGON_IE_16_X(79),
R_HEXAGON_IE_GOT_32_6_X(80),
R_HEXAGON_IE_GOT_16_X(81),
R_HEXAGON_IE_GOT_11_X(82),
R_HEXAGON_TPREL_32_6_X(83),
R_HEXAGON_TPREL_16_X(84),
R_HEXAGON_TPREL_11_X(85),
R_HEXAGON_LD_PLT_B22_PCREL(86),
R_HEXAGON_LD_GOT_LO16(87),
R_HEXAGON_LD_GOT_HI16(88),
R_HEXAGON_LD_GOT_32(89),
R_HEXAGON_LD_GOT_16(90),
R_HEXAGON_LD_GOT_32_6_X(91),
R_HEXAGON_LD_GOT_16_X(92),
R_HEXAGON_LD_GOT_11_X(93),
R_HEXAGON_23_REG(94),
R_HEXAGON_GD_PLT_B22_PCREL_X(95),
R_HEXAGON_GD_PLT_B32_PCREL_X(96),
R_HEXAGON_LD_PLT_B22_PCREL_X(97),
R_HEXAGON_LD_PLT_B32_PCREL_X(98),
R_HEXAGON_27_REG(99);
public final int typeId;
private Hexagon_ElfRelocationType(int typeId) {
this.typeId = typeId;
}
@Override
public int typeId() {
return typeId;
}
}

View File

@@ -0,0 +1,63 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.viewer.field;
import ghidra.program.model.lang.ParallelInstructionLanguageHelper;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.Instruction;
import java.math.BigInteger;
public class HexagonParallelInstructionHelper implements ParallelInstructionLanguageHelper {
public HexagonParallelInstructionHelper() {
}
@Override
public String getMnemonicPrefix(Instruction instr) {
if (isParallelInstruction(instr)) {
return "||";
}
return null;
}
@Override
public boolean isParallelInstruction(Instruction instruction) {
Register packetOffsetReg = instruction.getRegister("packetOffset");
if (packetOffsetReg == null) {
return false;
}
BigInteger value = instruction.getValue(packetOffsetReg, false);
return value.intValue() != 0;
}
@Override
public boolean isEndOfParallelInstructionGroup(Instruction instruction) {
try {
byte[] bytes = instruction.getBytes();
// assume little endian'
// End of packet instruction will have PP='11' or EE='00'
int bits = (bytes[1] & 0xC0) >> 6;
return (bits == 0 || bits == 3);
}
catch (Exception e) {
// ignore
}
return true;
}
}

View File

@@ -0,0 +1,697 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.emulation;
import java.math.BigInteger;
import java.util.function.Function;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.OpBehaviorOther;
import ghidra.pcode.error.LowlevelError;
import ghidra.pcode.floatformat.*;
import ghidra.pcode.memstate.MemoryState;
import ghidra.pcode.utils.Utils;
import ghidra.program.model.pcode.Varnode;
@Deprecated(forRemoval = true, since = "12.1")
public class HexagonEmulateInstructionStateModifier extends EmulateInstructionStateModifier {
private static final FloatFormat fp64Format = FloatFormatFactory.getFloatFormat(8);
private static final int FP64_BIAS = 1023;
private static final int FP64_MANTISSA_BITS = 52;
private static final int FP64_INFINITY_EXP = 0x7ff;
public HexagonEmulateInstructionStateModifier(Emulate emu) {
super(emu);
registerPcodeOpBehavior("min", new SignedMinimumOpBehavior());
registerPcodeOpBehavior("vlslh", new VectorLogicalShiftLeftOpBehavior("vlslh", 16, 7));
registerPcodeOpBehavior("vlsrh", new VectorLogicalShiftRightOpBehavior("vlsrh", 16, 7));
registerPcodeOpBehavior("vlslw", new VectorLogicalShiftLeftOpBehavior("vlslw", 32, 7));
registerPcodeOpBehavior("vlsrw", new VectorLogicalShiftRightOpBehavior("vlsrw", 32, 7));
registerPcodeOpBehavior("vmux", new VectorMultiplexOpBehavior());
registerPcodeOpBehavior("vabsh", new VectorAbsoluteValueOpBehavior("vabsh", 16));
registerPcodeOpBehavior("vabsw", new VectorAbsoluteValueOpBehavior("vabsw", 32));
registerPcodeOpBehavior("dfmpyfix", new DFMultiplyFixOpBehavior());
registerPcodeOpBehavior("dfmpyhh", new DFMultiplyHHOpBehavior());
registerPcodeOpBehavior("dfmpylh", new DFMultiplyLHOpBehavior());
registerPcodeOpBehavior("dfmpyll", new DFMultiplyLLOpBehavior());
registerPcodeOpBehavior("isClassifiedFloat", new ClassifyFloatOpBehavior());
}
private static final long FP_ZERO_CLASS_MASK = 0x01;
private static final long FP_NORMAL_CLASS_MASK = 0x02;
private static final long FP_SUBNORMAL_CLASS_MASK = 0x04;
private static final long FP_INFINITE_CLASS_MASK = 0x08;
private static final long FP_NAN_CLASS_MASK = 0x10;
private class ClassifyFloatOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
if (out == null) {
throw new LowlevelError(
"isClassifiedFloat: missing required output (predicate-storage)");
}
if (inputs.length != 2) {
throw new LowlevelError(
"isClassifiedFloat: requires two inputs (float-storage, constant-float-class-mask)");
}
MemoryState memoryState = e.getMemoryState();
Varnode in1 = inputs[0]; // float value
if (in1.isConstant()) {
throw new LowlevelError("isClassifiedFloat: first input must not be constant");
}
if (in1.getSize() != 4 && in1.getSize() != 8) {
throw new LowlevelError(
"isClassifiedFloat: invalid float size of " + in1.getSize());
}
Varnode in2 = inputs[1]; // constant float-classification
if (!in2.isConstant()) {
throw new LowlevelError("isClassifiedFloat: second input must be constant");
}
FloatFormat floatFormat = FloatFormatFactory.getFloatFormat(in1.getSize());
BigFloat bigFloat = floatFormat.decodeBigFloat(memoryState.getValue(in1));
int floatClass = (int) in2.getOffset();
boolean result = false;
if ((floatClass & FP_ZERO_CLASS_MASK) != 0 && bigFloat.isZero()) {
result = true;
}
if ((floatClass & FP_NORMAL_CLASS_MASK) != 0 && bigFloat.isNormal()) {
result = true;
}
if ((floatClass & FP_SUBNORMAL_CLASS_MASK) != 0 && bigFloat.isDenormal()) {
result = true;
}
if ((floatClass & FP_INFINITE_CLASS_MASK) != 0 && bigFloat.isInfinite()) {
result = true;
}
if ((floatClass & FP_NAN_CLASS_MASK) != 0 && bigFloat.isNaN()) {
result = true;
}
memoryState.setValue(out, result ? 0xff : 0);
}
}
/**
* out = min(in1,in2) where in1/in2 may be constant
*/
private class SignedMinimumOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
if (out == null) {
throw new LowlevelError("min: missing required output");
}
if (inputs.length != 2) {
throw new LowlevelError("min: requires two inputs");
}
MemoryState memoryState = e.getMemoryState();
Varnode in1 = inputs[0];
Varnode in2 = inputs[1];
long value1 = in1.isConstant() ? in1.getOffset() : memoryState.getValue(in1);
value1 = Utils.sign_extend(value1, in1.getSize(), 8);
long value2 = in2.isConstant() ? in2.getOffset() : memoryState.getValue(in2);
value2 = Utils.sign_extend(value2, in2.getSize(), 8);
// TODO: Unsure if min operation is signed or unsigned
memoryState.setValue(out, Math.min(value1, value2));
}
}
/**
* Rdd = vmux(Pn,Rss,Rtt)
*/
private class VectorMultiplexOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
if (out == null) {
throw new LowlevelError("vmux: missing required double-word output (Rdd)");
}
if (inputs.length != 3) {
throw new LowlevelError("vmux: requires three inputs");
}
MemoryState memoryState = e.getMemoryState();
Varnode in1 = inputs[0];
Varnode in2 = inputs[1];
Varnode in3 = inputs[2];
if (out.getSize() != 8 || in2.getSize() != 8 || in3.getSize() != 8) {
throw new LowlevelError(
"vmux: multiplexed input and output sizes must be double-word");
}
long predicate = in1.isConstant() ? in1.getOffset() : memoryState.getValue(in1);
long value2 = in2.isConstant() ? in2.getOffset() : memoryState.getValue(in2);
long value3 = in3.isConstant() ? in3.getOffset() : memoryState.getValue(in3);
long result = 0;
for (int i = 0; i < 8; i++) {
long byteValue = ((predicate & 1) != 0 ? value2 : value3) & 0x0ff;
result |= byteValue << (i * 8);
predicate >>= 1;
value2 >>= 8;
value3 >>= 8;
}
memoryState.setValue(out, result);
}
}
private abstract class VectorOpBehavior implements OpBehaviorOther {
protected final String opName;
protected final int slotBitSize;
protected final long slotMask;
VectorOpBehavior(String opName, int slotBitSize) {
this.opName = opName;
this.slotBitSize = slotBitSize;
slotMask = ~(-1L << slotBitSize);
}
protected void evaluate(MemoryState memoryState, Varnode out, long[] inputs,
Function<Integer, Long> opFunction) {
if (out == null) {
throw new LowlevelError(opName + ": missing required double-word output (Rdd)");
}
if (out.getSize() != 8) {
throw new LowlevelError(opName + ": output size must be double-word");
}
long result = 0;
for (int slot = (64 / slotBitSize) - 1; slot >= 0; slot--) {
result <<= slotBitSize;
result |= opFunction.apply(slot) & slotMask;
}
memoryState.setValue(out, result);
}
}
private class VectorLogicalShiftRightOpBehavior extends VectorOpBehavior {
private final int shiftBitSize;
VectorLogicalShiftRightOpBehavior(String opName, int slotBitSize, int shiftBitSize) {
super(opName, slotBitSize);
this.shiftBitSize = shiftBitSize;
}
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
if (inputs.length != 2) {
throw new LowlevelError(opName + ": requires two inputs");
}
MemoryState memoryState = e.getMemoryState();
long source = memoryState.getValue(inputs[0]);
// signed shift value (negative value is left shift)
long shiftValue =
inputs[1].isConstant() ? inputs[1].getOffset() : memoryState.getValue(inputs[1]);
int s = 64 - shiftBitSize;
shiftValue = (shiftValue << s) >> s; // sign-extend shift value
final long shift = shiftValue;
evaluate(memoryState, out, new long[] { source, shift }, slot -> {
long r = 0;
if (Math.abs(shift) < 64) {
int slotShift = slot * slotBitSize;
r = (source >> slotShift) & slotMask;
if (shift < 0) {
r <<= -shift;
}
else {
r >>>= shift;
}
r &= slotMask;
}
return r;
});
}
}
private class VectorLogicalShiftLeftOpBehavior extends VectorOpBehavior {
private final int shiftBitSize;
VectorLogicalShiftLeftOpBehavior(String opName, int slotBitSize, int shiftBitSize) {
super(opName, slotBitSize);
this.shiftBitSize = shiftBitSize;
}
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
if (inputs.length != 2) {
throw new LowlevelError(opName + ": requires two inputs");
}
MemoryState memoryState = e.getMemoryState();
long source = memoryState.getValue(inputs[0]);
// signed shift value (negative value is right shift)
long shiftValue =
inputs[1].isConstant() ? inputs[1].getOffset() : memoryState.getValue(inputs[1]);
int s = 64 - shiftBitSize;
shiftValue = (shiftValue << s) >> s; // sign-extend shift value
final long shift = shiftValue;
evaluate(memoryState, out, new long[] { source, shift }, slot -> {
long r = 0;
if (Math.abs(shift) < 64) {
int slotShift = slot * slotBitSize;
r = (source >> slotShift) & slotMask;
if (shift < 0) {
r >>>= -shift;
}
else {
r <<= shift;
}
r &= slotMask;
}
return r;
});
}
}
private class VectorAbsoluteValueOpBehavior extends VectorOpBehavior {
private final long signBitMask;
VectorAbsoluteValueOpBehavior(String opName, int slotBitSize) {
super(opName, slotBitSize);
signBitMask = 1 << (slotBitSize - 1);
}
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
if (inputs.length != 1) {
throw new LowlevelError(opName + ": requires one input");
}
MemoryState memoryState = e.getMemoryState();
long source = memoryState.getValue(inputs[0]);
evaluate(memoryState, out, new long[] { source }, slot -> {
int slotShift = slot * slotBitSize;
long r = (source >> slotShift) & slotMask;
if ((r & signBitMask) != 0) {
r = (~r + 1) & slotMask; // negate with 2's complement
}
return r;
});
}
}
private class DFMultiplyFixOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
if (out == null || out.getSize() != 8) {
throw new LowlevelError("dfmpyfix: requires 8-byte output");
}
if (inputs.length != 2) {
throw new LowlevelError("dfmpyfix: requires two inputs");
}
for (int i = 0; i < 2; i++) {
if (inputs[i].getSize() != 8) {
throw new LowlevelError("dfmpyhh: requires two 8-byte inputs");
}
}
MemoryState memoryState = e.getMemoryState();
long rss = memoryState.getValue(inputs[0]);
long rtt = memoryState.getValue(inputs[1]);
BigFloat rssBf = fp64Format.decodeBigFloat(rss);
BigFloat rttBf = fp64Format.decodeBigFloat(rtt);
long result = rss;
if (!rssBf.isNormal() && (getExponent(rtt, rttBf) >= 512) && rttBf.isNormal()) {
rssBf.mul(fp64Format.decodeBigFloat(0x4330000000000000L));
result = fp64Format.getEncoding(rssBf).longValue();
}
else if (!rttBf.isNormal() && (getExponent(rss, rssBf) >= 512) && rssBf.isNormal()) {
rssBf.mul(fp64Format.decodeBigFloat(0x3cb0000000000000L));
result = fp64Format.getEncoding(rssBf).longValue();
}
memoryState.setValue(out, result);
}
}
private class DFMultiplyHHOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
// Multiply high*high and accumulate with L*H value
if (out == null || out.getSize() != 8) {
throw new LowlevelError("dfmpyhh: requires 8-byte output");
}
if (inputs.length != 3) {
throw new LowlevelError("dfmpyhh: requires three inputs");
}
for (int i = 0; i < 3; i++) {
if (inputs[i].getSize() != 8) {
throw new LowlevelError("dfmpyhh: requires three 8-byte inputs");
}
}
MemoryState memoryState = e.getMemoryState();
long rdd = memoryState.getValue(inputs[0]); // accumulated
long rss = memoryState.getValue(inputs[1]);
long rtt = memoryState.getValue(inputs[2]);
BigFloat rssBf = fp64Format.decodeBigFloat(rss);
BigFloat rttBf = fp64Format.decodeBigFloat(rtt);
long result;
if (rssBf.isZero() || rssBf.isNaN() || rssBf.isInfinite() || rttBf.isZero() ||
rttBf.isNaN() || rttBf.isInfinite()) {
result = fp64Format.getEncoding(BigFloat.mul(rssBf, rttBf)).longValue();
}
else {
FPAccumulator x = new FPAccumulator();
x.sticky = (rdd & 1) != 0;
x.mant = toUnsignedBigInteger(rdd >> 1);
long prod = (getMantissa(rss, rssBf) >>> 32) * (getMantissa(rtt, rttBf) >>> 32);
x.mant = toUnsignedBigInteger(prod).multiply(toUnsignedBigInteger(0x100000000L))
.add(x.mant);
x.exp = getExponent(rss, rssBf) + getExponent(rtt, rttBf) - FP64_BIAS - 20;
if (!rssBf.isNormal() || !rttBf.isNormal()) {
// crush to inexact zero
x.sticky = true;
x.exp = -4096;
}
x.negative = isNegative(rss) ^ isNegative(rtt);
result = round(x);
}
memoryState.setValue(out, result);
}
}
private static class FPAccumulator {
BigInteger mant = BigInteger.ZERO;
int exp;
boolean negative;
boolean guard;
boolean round;
boolean sticky;
}
private static BigInteger toUnsignedBigInteger(long ulong) {
if (ulong >= 0L) {
return BigInteger.valueOf(ulong);
}
int upper = (int) (ulong >>> 32);
int lower = (int) ulong;
return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32)
.add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
}
private static boolean isNegative(long f64) {
return f64 < 0;
}
private static int getExponent(long f64, BigFloat f) {
int exp = (int) (f64 >> FP64_MANTISSA_BITS) & 0x7ff;
if (f.isNormal()) {
return exp;
}
if (f.isDenormal()) {
return exp + 1;
}
return -1;
}
private static long getMantissa(long f64, BigFloat f) {
int shift = 64 - FP64_MANTISSA_BITS;
long aMant = (f64 << shift) >>> shift;
if (f.isNormal()) {
aMant |= (1L << FP64_MANTISSA_BITS);
}
else if (f.isZero()) {
aMant = 0L;
}
else if (!f.isDenormal()) {
aMant = ~0L;
}
return aMant;
}
private static long getLo64(BigInteger b) {
return b.longValue();
}
private static long getHi64(BigInteger b) {
return b.shiftRight(64).longValue();
}
/**
* Perform normalization and rounding of FP64 accumulator value.
*
* @param x accumulator
* @return encoded fp64 value
*/
private static long round(FPAccumulator x) {
if ((x.sticky || x.round || x.guard) && x.mant.equals(BigInteger.ZERO)) {
return fp64Format.getZeroEncoding(false);
}
while (getHi64(x.mant) != 0 || (getLo64(x.mant) >>> (FP64_MANTISSA_BITS + 1) != 0)) {
normalizeRight(x, 1);
}
while ((getLo64(x.mant) & (1L << FP64_MANTISSA_BITS)) == 0) {
normalizeLeft(x);
}
while (x.exp <= 0) {
normalizeRight(x, 1 - x.exp);
// if (x.sticky || x.round || x.guard) {
// // raise underflow
// }
}
if (getLo64(x.mant) >> (FP64_MANTISSA_BITS + 1) != 0) {
normalizeRight(x, 1);
}
if (x.exp >= FP64_INFINITY_EXP) {
return fp64Format.getInfinityEncoding(x.negative);
}
long f64 = 0;
if (x.negative) {
f64 = Long.MIN_VALUE;
}
if ((getLo64(x.mant) & (1L << FP64_MANTISSA_BITS)) != 0) {
f64 |= ((long) x.exp) << FP64_MANTISSA_BITS;
}
f64 |= getLo64(x.mant) & 0xfffffffffffffL;
return f64;
}
private static void normalizeLeft(FPAccumulator x) {
x.exp--;
x.mant = x.mant.shiftLeft(1);
if (x.guard) {
x.mant = x.mant.or(BigInteger.ONE);
}
x.guard = x.round;
x.round = x.sticky;
}
private static void normalizeRight(FPAccumulator a, int n) {
if (n > 130) {
a.sticky |= a.round | a.guard | (a.mant.compareTo(BigInteger.ZERO) == 0);
a.guard = a.round = false;
a.mant = BigInteger.ZERO;
a.exp += n;
return;
}
while (n >= 64) {
a.sticky |= a.round | a.guard | (getLo64(a.mant) != 0);
a.guard = ((getLo64(a.mant) >> 63) & 1) != 0;
a.round = ((getLo64(a.mant) >> 62) & 1) != 0;
a.mant = toUnsignedBigInteger(getHi64(a.mant));
a.exp += 64;
n -= 64;
}
while (n > 0) {
a.exp++;
a.sticky |= a.round;
a.round = a.guard;
a.guard = (getLo64(a.mant) & 1) != 0;
a.mant = a.mant.shiftRight(1);
n--;
}
}
public static void main(String[] args) {
long expect = 0x4023b81d7dbf4880L;
long rdd = 0x00202752200f06f7L; // memoryState.getValue(inputs[1]); // accumulated
long rss = 0x40091eb851eb851fL;
long rtt = 0x40091eb851eb851fL;
BigFloat expBf = fp64Format.decodeBigFloat(expect);
BigFloat rddBf = fp64Format.decodeBigFloat(rdd);
BigFloat rssBf = fp64Format.decodeBigFloat(rss);
BigFloat rttBf = fp64Format.decodeBigFloat(rtt);
BigFloat expProdBf = BigFloat.sub(expBf, rddBf);
System.out.println("expectProd=" + fp64Format.round(expProdBf).toString());
System.out.println("rss=" + fp64Format.round(rssBf).toString());
System.out.println("rtt=" + fp64Format.round(rttBf).toString());
FPAccumulator x = new FPAccumulator();
x.sticky = (rdd & 1) != 0;
x.mant = toUnsignedBigInteger(rdd >> 1);
long prod = (getMantissa(rss, rssBf) >>> 32) * (getMantissa(rtt, rttBf) >>> 32);
x.mant =
toUnsignedBigInteger(prod).multiply(toUnsignedBigInteger(0x100000000L)).add(x.mant);
x.exp = getExponent(rss, rssBf) + getExponent(rtt, rttBf) - FP64_BIAS - 20;
if (!rssBf.isNormal() || !rttBf.isNormal()) {
// crush to inexact zero
x.sticky = true;
x.exp = -4096;
}
x.negative = isNegative(rss) ^ isNegative(rtt);
long result = round(x);
BigFloat resultBf = fp64Format.decodeBigFloat(result);
System.out.println("result=" + fp64Format.round(resultBf).toString());
System.out.println("expected=" + fp64Format.round(expBf).toString());
System.out.println(
"result: 0x" + Long.toHexString(result) + " Expected: 0x" + Long.toHexString(expect));
}
private class DFMultiplyLHOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
// Multiply low*high and accumulate
// Rdd32 += (Rss.uw[0] * (0x00100000 | zxt 20->64 (Rtt.uw[1]))) << 1;
if (out == null || out.getSize() != 8) {
throw new LowlevelError("dfmpylh: requires 8-byte output");
}
if (inputs.length != 3) {
throw new LowlevelError("dfmpylh: requires three inputs");
}
for (int i = 0; i < 3; i++) {
if (inputs[i].getSize() != 8) {
throw new LowlevelError("dfmpylh: requires three 8-byte inputs");
}
}
MemoryState memoryState = e.getMemoryState();
long rdd = memoryState.getValue(inputs[0]); // accumulated
long rssLo = memoryState.getValue(inputs[1]) & 0xffffffffL; // Rss.uw[0]
long rttHi = memoryState.getValue(inputs[2]) >>> 32; // Rtt.uw[1]
long prod = (rssLo * (0x00100000L | (rttHi & 0xfffffL))) << 1;
long result = rdd + prod;
memoryState.setValue(out, result);
}
}
private class DFMultiplyLLOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate e, Varnode out, Varnode[] inputs) {
// Multiply low*low and shift off low 32 bits into sticky (in MSB)
if (out == null || out.getSize() != 8) {
throw new LowlevelError("dfmpyll: requires 8-byte output");
}
if (inputs.length != 2) {
throw new LowlevelError("dfmpyll: requires two inputs");
}
for (int i = 0; i < 2; i++) {
if (inputs[i].getSize() != 8) {
throw new LowlevelError("dfmpyll: requires two 8-byte inputs");
}
}
MemoryState memoryState = e.getMemoryState();
long rssLo = memoryState.getValue(inputs[0]) & 0xffffffffL;
long rttLo = memoryState.getValue(inputs[1]) & 0xffffffffL;
long prod = rssLo * rttLo;
long result = (prod >>> 32) << 1;
if ((prod & 0xffffffffL) != 0) {
result |= 1;
}
memoryState.setValue(out, result);
}
}
}

View File

@@ -0,0 +1,56 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.emulation;
public enum HexagonFp32 {
;
public static final int FP32_FRAC_POS = 0;
public static final int FP32_FRAC_SIZE = 23;
public static final int FP32_FRAC_MASK = ((1 << FP32_FRAC_SIZE) - 1) << FP32_FRAC_POS;
public static final int FP32_EXP_POS = FP32_FRAC_POS + FP32_FRAC_SIZE;
public static final int FP32_EXP_SIZE = 8;
public static final int FP32_EXP_MASK = ((1 << FP32_EXP_SIZE) - 1) << FP32_EXP_POS;
public static final int FP32_SIGN_POS = FP32_EXP_POS + FP32_EXP_SIZE;
public static final int FP32_BIAS = (1 << FP32_EXP_SIZE - 1) - 1;
static int maskFp32Exponent(int valueBits) {
return FP32_EXP_MASK & valueBits;
}
static int maskFp32Fraction(int valueBits) {
return FP32_FRAC_MASK & valueBits;
}
static boolean isFp32Zero(int exp, int frac) {
return exp == 0 && frac == 0;
}
static boolean isFp32Normal(int exp, int frac) {
return exp != 0 && exp != FP32_EXP_MASK;
}
static boolean isFp32Subnormal(int exp, int frac) {
return exp == 0 && frac != 0;
}
static boolean isFp32Infinite(int exp, int frac) {
return exp == FP32_EXP_MASK && frac == 0;
}
static boolean isFp32Nan(int exp, int frac) {
return exp == FP32_EXP_MASK && frac != 0;
}
}

View File

@@ -0,0 +1,229 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.emulation;
public enum HexagonFp64 {
;
public static final int FP64_FRAC_POS = 0;
public static final int FP64_FRAC_SIZE = 52;
public static final long FP64_FRAC_MASK = ((1L << FP64_FRAC_SIZE) - 1) << FP64_FRAC_POS;
public static final int FP64_EXP_POS = FP64_FRAC_POS + FP64_FRAC_SIZE;
public static final int FP64_EXP_SIZE = 11;
public static final long FP64_EXP_MASK = ((1L << FP64_EXP_SIZE) - 1) << FP64_EXP_POS;
public static final int FP64_SIGN_POS = FP64_EXP_POS + FP64_EXP_SIZE;
public static final int FP64_BIAS = (1 << FP64_EXP_SIZE - 1) - 1;
public static final int FP64_EXP_INF = (int) (FP64_EXP_MASK >>> FP64_EXP_POS);
static long maskFp64Exponent(long valueBits) {
return FP64_EXP_MASK & valueBits;
}
static long maskFp64Fraction(long valueBits) {
return FP64_FRAC_MASK & valueBits;
}
static boolean isFp64Zero(long exp, long frac) {
return exp == 0 && frac == 0;
}
static boolean isFp64Normal(long exp, long frac) {
return exp != 0 && exp != FP64_EXP_MASK;
}
static boolean isFp64Subnormal(long exp, long frac) {
return exp == 0 && frac != 0;
}
static boolean isFp64Infinite(long exp, long frac) {
return exp == FP64_EXP_MASK && frac == 0;
}
static boolean isFp64Nan(long exp, long frac) {
return exp == FP64_EXP_MASK && frac != 0;
}
static boolean isFp64Negative(long bits) {
return bits < 0;
}
static long getFp64Fraction(long exp, long frac) {
// Note: No additional shifting of frac necessary, as FP64_FRAC_POS = 0
if (isFp64Normal(exp, frac)) {
return frac | (1L << FP64_FRAC_SIZE);
}
if (isFp64Zero(exp, frac)) {
return 0L;
}
if (!isFp64Subnormal(exp, frac)) {
return -1L;
}
return frac;
}
static int getFp64Exponent(long exp, long frac) {
if (isFp64Normal(exp, frac)) {
return (int) (exp >>> FP64_EXP_POS);
}
if (isFp64Subnormal(exp, frac)) {
return (int) (exp >>> FP64_EXP_POS) + 1;
}
return -1;
}
static long encSign(boolean negative) {
return negative ? Long.MIN_VALUE : 0;
}
static long encExp(int exp, long mantUpper) {
if ((mantUpper >>> (FP64_FRAC_SIZE - 32)) == 0) {
return 0;
}
return Integer.toUnsignedLong(exp) << FP64_EXP_POS;
}
static long encFrac(long mantUpper, int mantLower) {
return ((mantUpper << 32) | Integer.toUnsignedLong(mantLower)) & FP64_FRAC_MASK;
}
public static long dfmpyhh(long rdd, long rss, long rtt) {
long expRss = maskFp64Exponent(rss);
long fracRss = maskFp64Fraction(rss);
long expRtt = maskFp64Exponent(rtt);
long fracRtt = maskFp64Fraction(rtt);
if (isFp64Zero(expRss, fracRss) || isFp64Nan(expRss, fracRss) ||
isFp64Infinite(expRss, fracRss) ||
isFp64Zero(expRtt, fracRtt) || isFp64Nan(expRtt, fracRtt) ||
isFp64Infinite(expRtt, fracRtt)) {
return Double.doubleToRawLongBits(
Double.longBitsToDouble(rss) * Double.longBitsToDouble(rtt));
}
// Read Accumulated from rdd
boolean sticky = (rdd & 1) != 0;
int mantLower = (int) (rdd >> 1);
long mantUpper = rdd >> 33;
long prod = (getFp64Fraction(expRss, fracRss) >>> 32) *
(getFp64Fraction(expRtt, fracRtt) >>> 32);
mantUpper += prod;
int exp = getFp64Exponent(expRss, fracRss) + getFp64Exponent(expRtt, fracRtt) -
FP64_BIAS - 20;
if (!isFp64Normal(expRss, fracRss) || !isFp64Normal(expRtt, fracRtt)) {
// Crush to inexact 0
sticky = true;
exp = -4096;
}
boolean negative = isFp64Negative(rss) ^ isFp64Negative(rtt);
// round
boolean round = false;
boolean guard = false;
if (sticky && mantLower == 0 && mantUpper == 0) {
return Double.doubleToRawLongBits(0.0);
}
// normalize right for fraction
// 32 is size of mantLower
for (; mantUpper >>> (FP64_FRAC_SIZE + 1 - 32) != 0; exp++) {
sticky |= round;
round = guard;
guard = (mantLower & 1) != 0;
mantLower >>>= 1;
mantLower |= (mantUpper << 63) >>> 32;
mantUpper >>>= 1;
}
// (else) normalize left for fraction
for (; (mantUpper & (1L << FP64_FRAC_SIZE - 32)) == 0; exp--) {
mantUpper <<= 1;
mantUpper |= mantLower >>> 31;
mantLower <<= 1;
mantLower |= guard ? 1 : 0;
guard = round;
round = sticky;
}
// normalize right for exponent
if (1 - exp > 130) { // if (exp < -129)
sticky |= round | guard | (mantLower == 0 && mantUpper == 0);
guard = false;
round = false;
exp = 1;
}
for (; 1 - exp >= 64; exp += 64) { // while (exp <= -63)
// Can this be re-specialized to this 64|32-bit split?
sticky |= round | guard | (mantLower == 0 && (mantUpper & 0x0_ffff_ffffL) == 0);
guard = (mantUpper >>> 31) != 0;
round = (mantUpper >>> 30) != 0;
/**
* effective shift right 64 bits
*
* | ----- long upper ---- | int lower |
*
* |BB:AA:99:88:77:66:55:44|33:22:11:00|
*
* |00:00:00:00:00:00:00:00|BB:AA:99:88|
*/
mantLower = (int) (mantUpper >>> 32);
mantUpper = 0;
}
for (; 1 - exp >= 0; exp++) {
sticky |= round;
round = guard;
guard = (mantLower & 1) != 0;
mantLower >>>= 1;
mantLower |= (mantUpper << 63) >>> 32;
mantUpper >>>= 1;
}
// one more normalize right for fraction
if (mantUpper >>> (FP64_FRAC_SIZE + 1 - 32) != 0) {
sticky |= round;
round = guard;
guard = (mantLower & 1) != 0;
mantLower >>>= 1;
mantLower |= (mantUpper << 63) >>> 32;
mantUpper >>>= 1;
exp++;
}
if (exp >= FP64_EXP_INF) {
return Double.doubleToRawLongBits(negative
? Double.NEGATIVE_INFINITY
: Double.POSITIVE_INFINITY);
}
return encSign(negative) | encExp(exp, mantUpper) | encFrac(mantUpper, mantLower);
}
public static long dfmpyfix(long rss, long rtt) {
long expRss = maskFp64Exponent(rss);
long fracRss = maskFp64Fraction(rss);
long expRtt = maskFp64Exponent(rtt);
long fracRtt = maskFp64Exponent(rtt);
if (!isFp64Normal(expRss, fracRss) && isFp64Normal(expRtt, fracRtt) &&
expRtt >= (512 << FP64_EXP_POS)) {
return Double.doubleToRawLongBits(Double.longBitsToDouble(rss) * 0x1.0p52);
}
if (!isFp64Normal(expRtt, fracRtt) && isFp64Normal(expRss, fracRss) &&
expRss >= (512 << FP64_EXP_POS)) {
return Double.doubleToRawLongBits(Double.longBitsToDouble(rss) * 0x1.0p-52);
}
return rss;
}
}

View File

@@ -0,0 +1,210 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.emulation;
import java.util.function.Function;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.pcode.error.LowlevelError;
import ghidra.pcode.exec.*;
import ghidra.pcode.exec.PcodeUseropLibraryFactory.UseropLibrary;
import ghidra.program.model.pcode.Varnode;
@UseropLibrary("hexagon")
public class HexagonPcodeUseropLibraryFactory implements PcodeUseropLibraryFactory {
@Override
public <T> PcodeUseropLibrary<T> create(SleighLanguage language,
PcodeArithmetic<T> arithmetic) {
return new HexagonPcodeUseropLibrary<T>(language);
}
public static class HexagonPcodeUseropLibrary<T> extends AnnotatedPcodeUseropLibrary<T> {
private static final int FP_ZERO_CLASS_MASK = 0x01;
private static final int FP_NORMAL_CLASS_MASK = 0x02;
private static final int FP_SUBNORMAL_CLASS_MASK = 0x04;
private static final int FP_INFINITE_CLASS_MASK = 0x08;
private static final int FP_NAN_CLASS_MASK = 0x10;
public HexagonPcodeUseropLibrary(SleighLanguage language) {
SleighPcodeUseropDefinition.Factory factory =
new SleighPcodeUseropDefinition.Factory(language);
putOp(factory.define("min").params("a", "b").body(args -> """
if (a s<= b) goto <take_a>;
__op_output = b;
goto <done>;
<take_a>
__op_output = a;
<done>
""").build());
putOp(factory.define("vlslh")
.params("source", "shift")
.body(args -> genVecShift(args.get(0), 16, "<<", ">>"))
.build());
putOp(factory.define("vlsrh")
.params("source", "shift")
.body(args -> genVecShift(args.get(0), 16, ">>", "<<"))
.build());
putOp(factory.define("vlslw")
.params("source", "shift")
.body(args -> genVecShift(args.get(0), 32, "<<", ">>"))
.build());
putOp(factory.define("vlsrw")
.params("source", "shift")
.body(args -> genVecShift(args.get(0), 32, ">>", "<<"))
.build());
putOp(factory.define("vmux").params("sel", "a", "b").body(args -> """
local s:1;
local result:8;
""" + genVec(0, 8, 1, i -> """
s = ((sel >> %d) & 1) * 0xff;
result[%d,8] = (a[%d,8] & s) | (b[%d,8] & ~s);
""".formatted(i, 8 * i, 8 * i, 8 * i)) + """
__op_output = result;
""").build());
putOp(factory.define("vabsh").params("n").body(args -> genVecAbs(16)).build());
putOp(factory.define("vabsw").params("n").body(args -> genVecAbs(32)).build());
putOp(factory.define("dfmpylh").params("rdd", "rss", "rtt").body(args -> """
rss_lo:8 = rss & 0xffffffff;
rtt_hi:8 = rtt >> 32;
prod:8 = (rss_lo * (0x00100000 | (rtt_hi & 0xfffff))) << 1;
__op_output = rdd + prod;
""").build());
putOp(factory.define("dfmpyll").params("rss", "rtt").body(args -> """
rss_lo:8 = rss & 0xffffffff;
rtt_lo:8 = rtt & 0xffffffff;
prod:8 = rss_lo * rtt_lo;
result:8 = (prod >> 32) << 1;
if ((prod & 0xffffffff) == 0) goto <done>;
result = result + 1;
<done>
__op_output = result;
""").build());
putOp(factory.define("isClassifiedFloat")
.params("bits", "cls")
.body(args -> switch (args.get(1).getSize()) {
case 4 -> "__op_output = __isClassifiedFloat32(bits, cls);";
case 8 -> "__op_output = __isClassifiedFloat64(bits, cls);";
default -> throw new LowlevelError(
"isClassifiedFloat: invalid float size of " + args.get(0).getSize());
})
.build());
}
protected String genVec(int start, int stop, int step, Function<Integer, String> slot) {
StringBuffer buf = new StringBuffer();
for (int i = start; i < stop; i += step) {
buf.append(slot.apply(i));
}
return buf.toString();
}
protected String genVecShift(Varnode source, int slotSize, String posOp, String negOp) {
int regSize = source.getSize() * 8;
return """
s:1 = (shift[0,8] << 1) s>> 1;
if (s s< 0) goto <shift_neg>;
""" + genVec(0, regSize, slotSize, slot -> """
__op_output[%d,%d] = source[%d,%d] %s s;
""".formatted(slot, slotSize, slot, slotSize, posOp)) + """
goto <done>;
<shift_neg>
""" + genVec(0, regSize, slotSize, slot -> """
__op_output[%d,%d] = source[%d,%d] %s s;
""".formatted(slot, slotSize, slot, slotSize, negOp)) + """
<done>
""";
}
protected String genVecAbs(int slotSize) {
long signMask = Long.MIN_VALUE;
for (int i = 32; i >= slotSize; i >>>= 1) {
signMask |= (signMask >>> i);
}
long sm = signMask;
long mult = -1L >>> (64 - slotSize);
return """
s = n & 0x%x;
ones = s >> %d;
mask = ones * 0x%x;
inv = n ^ mask;
""".formatted(sm, slotSize - 1, mult) + genVec(0, 64, slotSize, slot -> """
__op_output[%d,%d] = inv[%d,%d] + ones[%d,%d];
""".formatted(slot, slotSize, slot, slotSize, slot, slotSize));
}
@PcodeUserop(functional = true)
public static int __isClassifiedFloat32(int valueBits, int cls) {
int exp = HexagonFp32.maskFp32Exponent(valueBits);
int frac = HexagonFp32.maskFp32Fraction(valueBits);
if ((cls & FP_ZERO_CLASS_MASK) != 0 && HexagonFp32.isFp32Zero(exp, frac)) {
return 0xff;
}
if ((cls & FP_NORMAL_CLASS_MASK) != 0 && HexagonFp32.isFp32Normal(exp, frac)) {
return 0xff;
}
if ((cls & FP_SUBNORMAL_CLASS_MASK) != 0 && HexagonFp32.isFp32Subnormal(exp, frac)) {
return 0xff;
}
if ((cls & FP_INFINITE_CLASS_MASK) != 0 && HexagonFp32.isFp32Infinite(exp, frac)) {
return 0xff;
}
if ((cls & FP_NAN_CLASS_MASK) != 0 && HexagonFp32.isFp32Nan(exp, frac)) {
return 0xff;
}
return 0;
}
@PcodeUserop(functional = true)
public static int __isClassifiedFloat64(long valueBits, int cls) {
long exp = HexagonFp64.maskFp64Exponent(valueBits);
long frac = HexagonFp64.maskFp64Fraction(valueBits);
if ((cls & FP_ZERO_CLASS_MASK) != 0 && HexagonFp64.isFp64Zero(exp, frac)) {
return 0xff;
}
if ((cls & FP_NORMAL_CLASS_MASK) != 0 && HexagonFp64.isFp64Normal(exp, frac)) {
return 0xff;
}
if ((cls & FP_SUBNORMAL_CLASS_MASK) != 0 && HexagonFp64.isFp64Subnormal(exp, frac)) {
return 0xff;
}
if ((cls & FP_INFINITE_CLASS_MASK) != 0 && HexagonFp64.isFp64Infinite(exp, frac)) {
return 0xff;
}
if ((cls & FP_NAN_CLASS_MASK) != 0 && HexagonFp64.isFp64Nan(exp, frac)) {
return 0xff;
}
return 0;
}
// LATER: Could/should this be done in Sleigh instead?
@PcodeUserop(functional = true)
public static long dfmpyfix(long rss, long rtt) {
return HexagonFp64.dfmpyfix(rss, rtt);
}
// LATER: Could/should this be done in Sleigh instead?
@PcodeUserop(functional = true)
public static long dfmpyhh(long rdd, long rss, long rtt) {
return HexagonFp64.dfmpyhh(rdd, rss, rtt);
}
}
}

View File

@@ -0,0 +1,115 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail;
import org.junit.Test;
import ghidra.app.util.PseudoInstruction;
import ghidra.pcode.emu.*;
import ghidra.pcode.exec.*;
import ghidra.pcode.exec.PcodeExecutorStatePiece.Reason;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.LanguageID;
import ghidra.program.model.lang.RegisterValue;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
import ghidra.util.NumericUtilities;
public class HexagonPcodeEmulatorTest extends AbstractGhidraHeadlessIntegrationTest {
@Test
public void testCunitSample() throws Throwable {
PcodeEmulator emu = new PcodeEmulator(
getLanguageService().getLanguage(new LanguageID("Hexagon:LE:32:default"))) {
@Override
protected BytesPcodeThread createThread(String name) {
return new BytesPcodeThread(name, this) {
@Override
protected PcodeThreadExecutor<byte[]> createExecutor() {
return new PcodeThreadExecutor<>(this) {
@Override
public void stepOp(PcodeOp op, PcodeFrame frame,
PcodeUseropLibrary<byte[]> library) {
//System.err.println(" StepOp: " + op);
super.stepOp(op, frame, library);
}
};
}
@Override
protected SleighInstructionDecoder createInstructionDecoder(
PcodeExecutorState<byte[]> sharedState) {
return new SleighInstructionDecoder(language, sharedState) {
@Override
public PseudoInstruction decodeInstruction(Address address,
RegisterValue context) {
PseudoInstruction instruction =
super.decodeInstruction(address, context);
//System.err.println("Decoded " + address + ": " + instruction);
return instruction;
}
};
}
};
}
};
PcodeThread<byte[]> thread = emu.newThread();
AddressSpace as = emu.getLanguage().getDefaultSpace();
byte[] code_db54 = NumericUtilities.convertStringToBytes("""
09c09da0284a000042c300782e4a000003c0007841e7007800c06270f9e29ea702c06370f8e39ea784c
e035a20c0c049ffe0dea742c0c049fee2dea7e2ffde97c4ffde97fbe0dea700c203f502c405f5f8c100
5afde0dea7a4ffde9702c07d7060ffde9700c0c2a121e8007802c0007820ff9e97f5e29ea7fcc9035a6
0c0c049f9e0dea722ffde97dcc1005a02c07d7004c1c04900c4c2a142e8007823ff9e97f8e0dea700c0
637001c06270a2fe9e9704ffde97dec9035a81e8007820ff9e9702ff9e972ace035a1ec01e96"""
.replaceAll("\\s+", ""));
emu.getSharedState().setVar(as, 0xdb54, code_db54.length, false, code_db54);
byte[] code_27a00 = NumericUtilities.convertStringToBytes("""
00478185004780850440c14326c0c1432e40205c004882754840c1416ac0c1412640005c00448275004
4c04408c6c04401458275024682758c40c141aec8c1430248c0a103cac0a100527f53204cc04029cec0
4000478275c440c191e6c0c14300409f520644c0a138c6c0401aefff59"""
.replaceAll("\\s+", ""));
emu.getSharedState().setVar(as, 0x27a00, code_27a00.length, false, code_27a00);
byte[] src = new byte[64];
for (int i = 0; i < src.length; i++) {
src[i] = (byte) (31 * i + 5);
}
emu.getSharedState().setVar(as, 0x10002000, src.length, false, src);
emu.addBreakpoint(as.getAddress(0xDEADBEEFL), "1:1");
//thread.getExecutor().executeSleigh("PC=0xdb54; SP=0x40000000;");
thread.getExecutor()
.executeSleigh("PC=0x27a00; SP=0x4000000; R0=0x10001000; R1=0x10002000; R2=" +
src.length + "; LR=0xDEADBEEF;");
thread.reInitialize();
try {
thread.run();
fail();
}
catch (InterruptPcodeExecutionException e) {
// We hit the breakpoint. Good.
}
byte[] dst = emu.getSharedState().getVar(as, 0x10001000, src.length, false, Reason.INSPECT);
assertArrayEquals(src, dst);
}
}

View File

@@ -0,0 +1,74 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolUtilities;
import ghidra.test.processors.support.EmulatorTestRunner;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Hexagon_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
/**
* Known Failures:
* - All nalign_i2,4,8 tests are known to fail since the llvm compiler for Hexagon
* produces code which handles reads and writes inconsistently and does not
* attempt to force use of byte read/write for non-aligned accesses. The processor
* H/W will throw an exception for unaligned accesses.
*/
private static final String LANGUAGE_ID = "Hexagon:LE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Hexagon_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
// Ignore known issues with alignment tests
addIgnoredTests(
// Alignment tests need to declare the char array with proper alignment
// since Hexagon will access char array in a char-aligned fashion for
// the various size.
"nalign_i2_Main",
"nalign_i4_Main",
"nalign_i8_Main");
}
@Override
protected void initializeState(EmulatorTestRunner testRunner, Program program)
throws Exception {
super.initializeState(testRunner, program);
testRunner.setRegister("SP", 0x40000000L); // stack, unused location
Symbol globalDataSym = SymbolUtilities.getLabelOrFunctionSymbol(program, "GLOBAL",
m -> {
/* ignore */ });
assertNotNull("GLOBAL data symbol not found", globalDataSym);
testRunner.setRegister("GP", globalDataSym.getAddress().getOffset());
}
@Override
protected String getProcessorDesignator() {
return "Hexagon_CLANG_LLVM_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter
.buildEmulatorTestSuite(Hexagon_O0_EmulatorTest.class);
}
}

View File

@@ -0,0 +1,62 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolUtilities;
import ghidra.test.processors.support.EmulatorTestRunner;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Hexagon_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "Hexagon:LE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Hexagon_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
addIgnoredTests(
// Hexagon Tools 8.5.10 LLVM compiler produces incorrect O3 optimized do/while loop code
"pcode_RolledDoWhileLoop_Main",
"pcode_Unrolled2DoWhileLoop_Main");
}
@Override
protected void initializeState(EmulatorTestRunner testRunner, Program program)
throws Exception {
super.initializeState(testRunner, program);
testRunner.setRegister("SP", 0x40000000L); // stack, unused location
Symbol globalDataSym = SymbolUtilities.getLabelOrFunctionSymbol(program, "GLOBAL",
m -> {
/* ignore */ });
assertNotNull("GLOBAL data symbol not found", globalDataSym);
testRunner.setRegister("GP", globalDataSym.getAddress().getOffset());
}
@Override
protected String getProcessorDesignator() {
return "Hexagon_CLANG_LLVM_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter
.buildEmulatorTestSuite(Hexagon_O3_EmulatorTest.class);
}
}

View File

@@ -0,0 +1,70 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.assembler.sleigh;
import java.math.BigInteger;
import org.junit.Test;
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyPatternBlock;
import ghidra.program.model.lang.LanguageID;
import ghidra.program.model.lang.RegisterValue;
public class HexagonAssemblyTest extends AbstractAssemblyTest {
@Override
protected LanguageID getLanguageID() {
return new LanguageID("Hexagon:LE:32:default");
}
String makeCtx(int packetOffset, long packetBits) {
RegisterValue ctxVal = new RegisterValue(lang.getContextBaseRegister());
ctxVal = ctxVal.assign(lang.getRegister("packetOffset"), BigInteger.valueOf(packetOffset));
ctxVal = ctxVal.assign(lang.getRegister("packetBits"), BigInteger.valueOf(packetBits));
return AssemblyPatternBlock.fromRegisterValue(ctxVal).fillMask().toString();
}
@Test
public void testAssemble_memb_R0_mR1() {
assertOneCompatRestExact("memb R0,(R1)", "00:40:01:91", 0x000c0000);
}
@Test
public void testAssemble_jump_if_t_cmp_eq_mR0new_n0_0xc0010() {
assertOneCompatRestExact("jump.if:t cmp.eq(R0.new,#0x0),0x000c0010", "0b:e0:02:24",
makeCtx(1, 0x40000000), 0x000c0000,
"jump.if:t cmp.eq(R0.new,#0x0),0x000c0010");
}
@Test
public void testAssemble_assign_R0_P0() {
assertOneCompatRestExact("assign R0,P0", "00:40:40:89", 0x000c0000);
}
@Test
public void testAssemble_cmp_gtu_P0_R1_n0x9__jump_if_P0new_t_0xc0010() {
assertOneCompatRestExact("cmp.gtu P0,R1,#0x9 ; jump.if(P0.new):t 0x000c0010", "0b:69:01:11",
makeCtx(1, 0x40000000), 0x000c0000,
"cmp.gtu P0,R1,#0x9 ; jump.if(P0.new):t 0x000c0010");
}
@Test
public void testAssemble_memw_mSP_n0x4_R0new() {
assertOneCompatRestExact("memw (SP+#0x4),R0.new", "01:d4:bd:a1",
makeCtx(2, 0x50000000), 0x000c0000,
"memw (SP+#0x4),R0.new");
}
}

View File

@@ -0,0 +1,237 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.emulation;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNotNull;
import java.util.Map;
import org.hamcrest.Matchers;
import org.junit.*;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.pcode.exec.*;
import ghidra.program.emulation.HexagonPcodeUseropLibraryFactory.HexagonPcodeUseropLibrary;
import ghidra.program.model.lang.LanguageID;
import ghidra.program.util.DefaultLanguageService;
public class HexagonPcodeUseropLibraryTest extends AbstractEmulationEquivalenceTest {
static final LanguageID LANGI_ID_HEXAGON = new LanguageID("Hexagon:LE:32:default");
static SleighLanguage HEXAGON;
@Before
public void setupHexagon() throws Exception {
if (HEXAGON == null) {
HEXAGON = (SleighLanguage) DefaultLanguageService.getLanguageService()
.getLanguage(LANGI_ID_HEXAGON);
}
}
@Test
public void testFoundById() {
PcodeUseropLibrary<byte[]> lib = PcodeUseropLibraryFactory
.createUseropLibraryFromId("hexagon", HEXAGON,
BytesPcodeArithmetic.forLanguage(HEXAGON));
assertThat(lib, Matchers.instanceOf(HexagonPcodeUseropLibrary.class));
}
@Test
public void testFoundByLang() {
PcodeUseropLibrary<byte[]> lib = PcodeUseropLibraryFactory
.createUseropLibraryForLanguage(HEXAGON, BytesPcodeArithmetic.forLanguage(HEXAGON));
assertNotNull(lib.getUserops().get("dfmpyfix"));
assertNotNull(lib.getUserops().get("dfmpyhh"));
}
@Test
public void testDfClass() throws Exception {
doTestEquiv(HEXAGON,
Map.ofEntries(
Map.entry("P3", "ffff"), // Kind of hacky, but Pd2 &= result
Map.entry("R1R0", "3ff0000000000000")),
buf -> buf.assemble("dfclass P3,R1R0,#0x2"), 1,
Map.ofEntries(
Map.entry("P3", "ff"),
Map.entry("PC", "400004"),
Map.entry("P0.new", "ff"),
Map.entry("P1.new", "ff"),
Map.entry("P2.new", "ff"),
Map.entry("P3.new", "ff"),
Map.entry("R1R0", "3ff0000000000000")));
}
@Test
public void testVMux() throws Exception {
doTestEquiv(HEXAGON,
Map.ofEntries(
Map.entry("P0", "96"),
Map.entry("R1R0", "aaaaaaaaaaaaaaaa"),
Map.entry("R9R8", "bbbbbbbbbbbbbbbb")),
buf -> buf.assemble("vmux R1R0,P0,R1R0,R9R8"), 1,
Map.ofEntries(
Map.entry("R1R0_", "aabbbbaabbaaaabb"),
Map.entry("P0", "96"),
Map.entry("PC", "400004"),
Map.entry("P0.new", "ff"),
Map.entry("P1.new", "ff"),
Map.entry("P2.new", "ff"),
Map.entry("P3.new", "ff"),
Map.entry("R1R0", "aaaaaaaaaaaaaaaa"),
Map.entry("R9R8", "bbbbbbbbbbbbbbbb")));
}
static final long DF_ANY = 0x3f80_0000_0000_0000L;
static final long DF_HEX_NAN = -1L;
static final long DF_MAX = Double.doubleToRawLongBits(Double.MAX_VALUE);
static final long DF_MIN = Double.doubleToRawLongBits(Double.MIN_NORMAL);
static final long DF_NEG_ONE = Double.doubleToRawLongBits(-1.0);
static final long DF_NEG_ZERO = Double.doubleToRawLongBits(-0.0);
static final long DF_ONE = Double.doubleToRawLongBits(1.0);
static final long DF_ONE_HH = 0x3ff0_01ff_8000_0000L;
static final long DF_QNAN = 0x7ff8_0000_0000_0000L;
static final long DF_SNAN = 0x7ff7_0000_0000_0000L;
static final long DF_ZERO = Double.doubleToRawLongBits(0.0);
protected void runTestDfmpyhh(long accNew, long accInit, long a, long b)
throws Exception {
doTestEquiv(HEXAGON,
Map.ofEntries(
Map.entry("R1R0", Long.toHexString(accInit)),
Map.entry("R3R2", Long.toHexString(a)),
Map.entry("R9R8", Long.toHexString(b))),
buf -> buf.assemble("dfmpyhh+= R1R0,R3R2,R9R8"), 1,
Map.ofEntries(
Map.entry("R1R0_", Long.toHexString(accNew)),
Map.entry("PC", "400004"),
Map.entry("P0.new", "ff"),
Map.entry("P1.new", "ff"),
Map.entry("P2.new", "ff"),
Map.entry("P3.new", "ff"),
Map.entry("R1R0", Long.toHexString(accInit)),
Map.entry("R3R2", Long.toHexString(a)),
Map.entry("R9R8", Long.toHexString(b))));
}
protected void runTestDfmpylh(long accNew, long accInit, long a, long b)
throws Exception {
doTestEquiv(HEXAGON,
Map.ofEntries(
Map.entry("R1R0", Long.toHexString(accInit)),
Map.entry("R3R2", Long.toHexString(a)),
Map.entry("R9R8", Long.toHexString(b))),
buf -> buf.assemble("dfmpylh+= R1R0,R3R2,R9R8"), 1,
Map.ofEntries(
Map.entry("R1R0_", Long.toHexString(accNew)),
Map.entry("PC", "400004"),
Map.entry("P0.new", "ff"),
Map.entry("P1.new", "ff"),
Map.entry("P2.new", "ff"),
Map.entry("P3.new", "ff"),
Map.entry("R1R0", Long.toHexString(accInit)),
Map.entry("R3R2", Long.toHexString(a)),
Map.entry("R9R8", Long.toHexString(b))));
}
protected void runTestDfmpyll(long accNew, long accInit, long a, long b)
throws Exception {
doTestEquiv(HEXAGON,
Map.ofEntries(
Map.entry("R1R0", Long.toHexString(accInit)),
Map.entry("R3R2", Long.toHexString(a)),
Map.entry("R9R8", Long.toHexString(b))),
buf -> buf.assemble("dfmpyll R1R0,R3R2,R9R8"), 1,
Map.ofEntries(
Map.entry("R1R0_", Long.toHexString(accNew)),
Map.entry("PC", "400004"),
Map.entry("P0.new", "ff"),
Map.entry("P1.new", "ff"),
Map.entry("P2.new", "ff"),
Map.entry("P3.new", "ff"),
Map.entry("R1R0", Long.toHexString(accInit)),
Map.entry("R3R2", Long.toHexString(a)),
Map.entry("R9R8", Long.toHexString(b))));
}
@Test
public void testDfmpyhhOnes() throws Exception {
runTestDfmpyhh(DF_ONE_HH, DF_ONE, DF_ONE, DF_ONE);
}
@Test
@Ignore
public void testDfmpyhhZeroAnyQNan() throws Exception {
runTestDfmpyhh(DF_HEX_NAN, DF_ZERO, DF_ANY, DF_QNAN);
}
@Test
@Ignore
public void testDfmpyhhZeroAnySNan() throws Exception {
runTestDfmpyhh(DF_HEX_NAN, DF_ZERO, DF_ANY, DF_SNAN);
}
@Test
@Ignore
public void testDfmpyhhZeroQNanSNan() throws Exception {
runTestDfmpyhh(DF_HEX_NAN, DF_ZERO, DF_QNAN, DF_SNAN);
}
@Test
@Ignore
public void testDfmpyhhZeroSNanQNan() throws Exception {
runTestDfmpyhh(DF_HEX_NAN, DF_ZERO, DF_SNAN, DF_QNAN);
}
@Test
public void testDfmpyhhMain() throws Exception {
runTestDfmpyhh(
0x4023_b81d_7dbf_4880L,
0x0020_2752_200f_06f7L,
0x4009_1eb8_51eb_851fL,
0x4009_1eb8_51eb_851fL);
}
@Test
public void testDfmpylhMins() throws Exception {
runTestDfmpylh(0x10_0000_0000_0000L, DF_MIN, DF_MIN, DF_MIN);
}
@Test
public void testDfmpylhNegOneMaxMin() throws Exception {
runTestDfmpylh(0xc00f_ffff_ffe0_0000L, DF_NEG_ONE, DF_MAX, DF_MIN);
}
@Test
public void testDfmpylhMaxZeroNegOne() throws Exception {
runTestDfmpylh(0x7fef_ffff_ffff_ffffL, DF_MAX, DF_ZERO, DF_NEG_ONE);
}
@Test
public void testDfmpyllMins() throws Exception {
runTestDfmpyll(0, -1L, DF_MIN, DF_MIN);
}
@Test
public void testDfmpyllNegOneMin() throws Exception {
runTestDfmpyll(0, -1L, DF_NEG_ONE, DF_MIN);
}
@Test
public void testDfmpyllMaxes() throws Exception {
runTestDfmpyll(0x1_ffff_fffdL, -1L, DF_MAX, DF_MAX);
}
}

View File

@@ -0,0 +1,906 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.model.pcode;
import static org.junit.Assert.*;
import org.apache.commons.lang3.StringUtils;
import org.junit.*;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.program.database.ProgramBuilder;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.ParallelInstructionLanguageHelper;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*;
import ghidra.test.AbstractProgramBasedTest;
public class PcodeEmitContextCrossBuildTest extends AbstractProgramBasedTest {
private ProgramBuilder builder;
private Address baseAddr;
private AddressSpace defaultSpace;
private Listing listing;
private SleighLanguage language;
private Address testUniqueInCrossbuildAddr;
private Address testCallotherOverrideSingletonPacketAddr;
private ParallelInstructionLanguageHelper parallelHelper;
private ReferenceManager refManager;
private Address func1Addr;
private Address testCallotherOverrideCrossbuildAddr;
private Address func2Addr;
private Address testFallthroughOverrideTerminalAddr;
private Address testFallthroughOverrideMidPacketAddr;
private Address testFlowOverrideSingletonCallAddr;
private Address testFlowOverrideCallInPacketAddr;
private Address testUniqueSubpieceAddr;
private Address testRegisterSubpieceAddr;
private static final int ASL_PLUS_INSTANCES = 16;
//singleton instruction packet whose pcode has exactly one varnode in the unique space
private static final String ASL_PLUS_TERMINAL_BYTES = "c0 c0 01 8e ";
// example of lower SUBPIECE use on unique
private static final String VASRW_BYTES = "44 c2 00 c5";
// example of lower SUBPIECE use on register
private static final String BOUNDSCHECK_BYTES = "a1 e2 02 d2";
private static final String ADDSAT_NON_TERMINAL_BYTES = "80 40 00 d5 ";
private static final String MEMW_LOCKED_NON_TERMINAL_BYTES = "00 42 b0 a0 ";
private static final String MEMW_LOCKED_TERMINAL_BYTES = "00 c2 b0 a0 ";
private static final String CALL_TERMINAL_BYTES = "c6 c7 00 5a ";
private static final String CALL_NON_TERMINAL_BYTES = "c4 47 00 5a ";
private static final String BASE_ADDRESS = "0x100000";
private static final String DEST_FUNC1_ADDR = "0x101000";
private static final String DEST_FUNC2_ADDR = "0x102000";
@Before
public void setup() throws Exception {
buildProgram();
initialize();
}
@Override
@After
public void tearDown() throws Exception {
env.dispose();
builder.dispose();
}
@Override
public Program getProgram() {
return program;
}
private void buildProgram() throws Exception {
builder = new ProgramBuilder("crossbuildEmitTest", "Hexagon:LE:32:default");
builder.createMemory(".text", BASE_ADDRESS, 0x10000);
builder.createEmptyFunction("func1", DEST_FUNC1_ADDR, 4, null);
builder.createEmptyFunction("func2", DEST_FUNC2_ADDR, 4, null);
//testUniqueAddresses
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ASL_PLUS_INSTANCES; i++) {
sb.append(ASL_PLUS_TERMINAL_BYTES);
}
//testUniqueInCrossbuild
sb.append(ASL_PLUS_TERMINAL_BYTES);
sb.append(ADDSAT_NON_TERMINAL_BYTES);
sb.append(ASL_PLUS_TERMINAL_BYTES);
//testCallotherOverrideSingletonPacket
sb.append(MEMW_LOCKED_TERMINAL_BYTES);
//testCallotherOverrideCrossbuild
sb.append(MEMW_LOCKED_NON_TERMINAL_BYTES);
sb.append(ASL_PLUS_TERMINAL_BYTES);
//testFallthroughOverrideTerminal
sb.append(ASL_PLUS_TERMINAL_BYTES);
sb.append(ASL_PLUS_TERMINAL_BYTES);
sb.append(ASL_PLUS_TERMINAL_BYTES);
//testFallthroughOverrideMidPacket
sb.append(MEMW_LOCKED_NON_TERMINAL_BYTES);
sb.append(ADDSAT_NON_TERMINAL_BYTES);
sb.append(ASL_PLUS_TERMINAL_BYTES);
sb.append(ASL_PLUS_TERMINAL_BYTES);
//testFlowOverrideSingleCall
sb.append(CALL_TERMINAL_BYTES);
//testFlowOverrideCallInPacket
//testSimpleCallReferenceOverride
sb.append(CALL_NON_TERMINAL_BYTES);
sb.append(ASL_PLUS_TERMINAL_BYTES);
// testUniqueSubpiece (access directly at sub-offset of unique varnode)
sb.append(VASRW_BYTES);
// testRegisterSubpiece
sb.append(BOUNDSCHECK_BYTES);
String byteString = sb.toString().trim();
builder.setBytes(BASE_ADDRESS, byteString);
int byteLength = (byteString.length() - StringUtils.countMatches(byteString, ' ')) / 2;
builder.disassemble(BASE_ADDRESS, byteLength, false);
program = builder.getProgram();
defaultSpace = program.getAddressFactory().getDefaultAddressSpace();
baseAddr = defaultSpace.getAddress(BASE_ADDRESS);
testUniqueInCrossbuildAddr = baseAddr.add(ASL_PLUS_INSTANCES * 4);
testCallotherOverrideSingletonPacketAddr = testUniqueInCrossbuildAddr.add(12);
listing = program.getListing();
language = (SleighLanguage) program.getLanguage();
parallelHelper = language.getParallelInstructionHelper();
refManager = program.getReferenceManager();
func1Addr = defaultSpace.getAddress(DEST_FUNC1_ADDR);
testCallotherOverrideCrossbuildAddr = testCallotherOverrideSingletonPacketAddr.add(4);
func2Addr = defaultSpace.getAddress(DEST_FUNC2_ADDR);
testFallthroughOverrideTerminalAddr = testCallotherOverrideCrossbuildAddr.add(8);
testFallthroughOverrideMidPacketAddr = testFallthroughOverrideTerminalAddr.add(12);
testFlowOverrideSingletonCallAddr = testFallthroughOverrideMidPacketAddr.add(16);
testFlowOverrideCallInPacketAddr = testFlowOverrideSingletonCallAddr.add(4);
testUniqueSubpieceAddr = testFlowOverrideCallInPacketAddr.add(8);
testRegisterSubpieceAddr = testUniqueSubpieceAddr.add(4);
}
/**
* Test that offsets of varnodes in the unique space are adjusted based on
* the unique allocation mask of the language and the address of an
* instruction.
*
00100000 c0 c0 01 8e asl+= R0,R1,#0x0
00100004 c0 c0 01 8e asl+= R0,R1,#0x0
00100008 c0 c0 01 8e asl+= R0,R1,#0x0
0010000c c0 c0 01 8e asl+= R0,R1,#0x0
00100010 c0 c0 01 8e asl+= R0,R1,#0x0
00100014 c0 c0 01 8e asl+= R0,R1,#0x0
00100018 c0 c0 01 8e asl+= R0,R1,#0x0
0010001c c0 c0 01 8e asl+= R0,R1,#0x0
00100020 c0 c0 01 8e asl+= R0,R1,#0x0
00100024 c0 c0 01 8e asl+= R0,R1,#0x0
00100028 c0 c0 01 8e asl+= R0,R1,#0x0
0010002c c0 c0 01 8e asl+= R0,R1,#0x0
00100030 c0 c0 01 8e asl+= R0,R1,#0x0
00100034 c0 c0 01 8e asl+= R0,R1,#0x0
00100038 c0 c0 01 8e asl+= R0,R1,#0x0
0010003c c0 c0 01 8e asl+= R0,R1,#0x0
*/
@Test
public void testUniqueAddresses() {
int uniqueMask = language.getUniqueAllocationMask();
assertEquals(0xff, uniqueMask);
for (int i = 0; i < ASL_PLUS_INSTANCES; ++i) {
//verify the test instruction
Instruction inst = listing.getInstructionAt(baseAddr.add(4 * i));
assertNotNull(inst);
assertEquals("asl+= R0,R1,#0x0", inst.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(inst));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(inst));
PcodeOp[] ops = inst.getPcode();
assertEquals(8, ops.length);
//verify the op with output in the unique space
PcodeOp shift = ops[4];
assertEquals(PcodeOp.INT_LEFT, shift.getOpcode());
Varnode shiftOut = shift.getOutput();
assertNotNull(shiftOut);
assertTrue(shiftOut.isUnique());
//verify that the address in the unique space has the adjustment
//or'd in
long actualOffset = shiftOut.getOffset();
long adjustment = (inst.getAddress().getOffset() & uniqueMask) << 8;
if (i == 0) {
assertTrue(adjustment == 0);
}
else {
assertTrue(adjustment != 0);
}
assertEquals(actualOffset, actualOffset | adjustment);
}
}
/**
* Tests that a unique defined in the main section of an instruction and used in a named
* section is correctly referenced in the pcode of a separate instruction that crossbuilds the
* named section.
*
00100040 c0 c0 01 8e asl+= R0,R1,#0x0
00100044 80 40 00 d5 add:sat R0,R0.L,R0.L
00100048 c0 c0 01 8e || asl+= R0,R1,#0x0
*/
@Test
public void testUniqueInCrossbuild() {
//verify the instructions used in the test
Instruction aslSingleton = listing.getInstructionAt(testUniqueInCrossbuildAddr);
Instruction addSat = listing.getInstructionAt(testUniqueInCrossbuildAddr.add(4));
Instruction aslPacket = listing.getInstructionAt(testUniqueInCrossbuildAddr.add(8));
assertNotNull(aslSingleton);
assertEquals("asl+= R0,R1,#0x0", aslSingleton.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(aslSingleton));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(aslSingleton));
assertNotNull(addSat);
assertEquals("add:sat R0,R0.L,R0.L", addSat.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(addSat));
assertFalse(parallelHelper.isEndOfParallelInstructionGroup(addSat));
assertNotNull(aslPacket);
assertEquals("asl+= R0,R1,#0x0", aslPacket.toString().trim());
assertTrue(parallelHelper.isParallelInstruction(aslPacket));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(aslPacket));
//grab the unique varnode which is the output of the SCARRY op in addSat
long uniqueOffset = -1;
long uniqueSize = 0;
for (PcodeOp op : addSat.getPcode()) {
if (op.getOpcode() == PcodeOp.INT_SCARRY) {
Varnode uniqueOut = op.getOutput();
assertTrue(uniqueOut.isUnique());
uniqueOffset = uniqueOut.getOffset();
uniqueSize = uniqueOut.getSize();
break;
}
}
//verify that we found the INT_SCARRY op
assertFalse(uniqueOffset == -1);
//verify that this varnode is an input to an op in the pcode for aslPacket
boolean foundIt = false;
for (PcodeOp op : aslPacket.getPcode()) {
if (op.getOpcode() == PcodeOp.INT_OR) {
Varnode uniqueIn = op.getInput(1);
assertTrue(uniqueIn.isUnique());
assertEquals(uniqueOffset, uniqueIn.getOffset());
assertEquals(uniqueSize, uniqueIn.getSize());
foundIt = true;
break;
}
}
assertTrue(foundIt);
//verify that the singleton asl instruction does not have an INT_OR op
//(so the INT_OR op must have come from a crossbuild from the add:sat instruction)
foundIt = false;
for (PcodeOp op : aslSingleton.getPcode()) {
if (op.getOpcode() == PcodeOp.INT_OR) {
foundIt = true;
}
}
assertFalse(foundIt);
}
/**
* Tests that a unique lower-subpiece (LE) on a COPY directly access the smaller portion
* of the unique varnode.
*
00100080 44 c2 00 c5 vasrw R4,R1R0,R2
*/
@Test
public void testUniqueSubpiece() {
// NOTE: Really need big-endian language to fully test
//verify the instructions used in the test
Instruction vasrwSingleton = listing.getInstructionAt(testUniqueSubpieceAddr);
assertNotNull(vasrwSingleton);
assertEquals("vasrw R4,R1R0,R2", vasrwSingleton.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(vasrwSingleton));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(vasrwSingleton));
//grab the unique varnode which is the input of the SCARRY op in addSat
long uniqueOffset = -1;
long uniqueSize = 0;
boolean foundIt = false;
for (PcodeOp op : vasrwSingleton.getPcode()) {
if (op.getOpcode() == PcodeOp.INT_ADD) {
Varnode uniqueOut = op.getOutput();
assertTrue(uniqueOut.isUnique());
uniqueOffset = uniqueOut.getOffset();
assertEquals(0, uniqueOffset & 0x7f);
uniqueSize = uniqueOut.getSize();
assertEquals(4, uniqueSize);
}
else if (uniqueOffset != -1 && op.getOpcode() == PcodeOp.COPY) {
Varnode uniqueIn = op.getInputs()[0];
assertTrue(uniqueIn.isUnique());
assertEquals(uniqueOffset, uniqueIn.getOffset());
assertEquals(2, uniqueIn.getSize());
foundIt = true;
break;
}
}
//verify that we found the INT_ADD and COPY ops
assertFalse(uniqueOffset == -1);
assertTrue(foundIt);
}
/**
* Tests that a register lower-subpiece (LE) on uses the SUBPIECE op properly
*
00100084 a1 e2 02 d2 boundscheck:raw:hi P1,R3R2,R3R2
*/
@Test
public void testRegisterSubpiece() {
// NOTE: Really need big-endian language to fully test
//verify the instructions used in the test
Instruction boundscheckSingleton = listing.getInstructionAt(testRegisterSubpieceAddr);
assertNotNull(boundscheckSingleton);
assertEquals("boundscheck:raw:hi P1,R3R2,R3R2", boundscheckSingleton.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(boundscheckSingleton));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(boundscheckSingleton));
//grab the unique varnode which is the input of the SCARRY op in addSat
long uniqueOffset = -1;
long uniqueSize = 0;
boolean foundIt = false;
for (PcodeOp op : boundscheckSingleton.getPcode()) {
if (op.getOpcode() == PcodeOp.SUBPIECE) {
// Check output
Varnode uniqueOut = op.getOutput();
assertTrue(uniqueOut.isUnique());
uniqueOffset = uniqueOut.getOffset();
assertEquals(0, uniqueOffset & 0x7f);
uniqueSize = uniqueOut.getSize();
assertEquals(4, uniqueSize);
// Check inputs
Varnode[] inputs = op.getInputs();
assertTrue(inputs[0].isRegister());
assertEquals(8, inputs[0].getOffset());
assertEquals(8, inputs[0].getSize());
assertTrue(inputs[1].isConstant());
assertEquals(4, inputs[1].getOffset());
assertEquals(4, inputs[1].getSize());
foundIt = true;
break;
}
}
//verify that we found the SUBPIECE op
assertFalse(uniqueOffset == -1);
assertTrue(foundIt);
}
/**
* Verify that a CALLOTHER_OVERRIDE_CALL reference modifies the
* first CALLOTHER op in a singleton instruction packet
*
0010004c 00 c2 b0 a0 memw_loc (R16,P0),R2
*/
@Test
public void testCallotherOverrideSingletonPacket() {
//verify the instruction used in the test
Instruction memw_locked_last =
listing.getInstructionAt(testCallotherOverrideSingletonPacketAddr);
assertNotNull(memw_locked_last);
assertEquals("memw_locked (R16,P0),R2", memw_locked_last.toString().trim());
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(memw_locked_last));
//verify that the pcode from the instruction doesn't change if you
//request overrides
PcodeOp[] memw_locked_last_original = memw_locked_last.getPcode();
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_locked_last_original,
memw_locked_last.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_locked_last_original,
memw_locked_last.getPcode(true)));
//apply a CALLOTHER_OVERRIDE_CALL reference
int id = program.startTransaction("test");
Reference overrideRef =
refManager.addMemoryReference(testCallotherOverrideSingletonPacketAddr, func1Addr,
RefType.CALLOTHER_OVERRIDE_CALL, SourceType.USER_DEFINED, -1);
refManager.setPrimary(overrideRef, true);
program.endTransaction(id, true);
//verify that the pcode doesn't change if you request no overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_locked_last_original,
memw_locked_last.getPcode()));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_locked_last_original,
memw_locked_last.getPcode(false)));
//verify that the first CALLOTHER op is changed to a CALL if you request overrides
PcodeOp[] memw_locked_last_overridden = memw_locked_last.getPcode(true);
assertEquals(memw_locked_last_original.length, memw_locked_last_overridden.length);
assertEquals(14, memw_locked_last_overridden.length);
for (int i = 0; i < 14; ++i) {
PcodeOp orig = memw_locked_last_original[i];
PcodeOp overridden = memw_locked_last_overridden[i];
if (i == 4) {
assertEquals(PcodeOp.CALLOTHER, orig.getOpcode());
assertEquals(PcodeOp.CALL, overridden.getOpcode());
}
else {
if (i == 12) {
//just to document that a second CALLOTHER op exists (and is unchanged)
assertEquals(PcodeOp.CALLOTHER, overridden.getOpcode());
}
assertTrue(PcodeEmitContextTest.equalPcodeOps(orig, overridden));
}
}
}
/**
* Tests applying CALLOTHER_OVERRIDE_CALL references to an instruction with two CALLOTHER
* ops, one in the main section and another in a named section. When this instruction is
* part of a packet, placing an overriding reference on the address corresponding to the
* main section will override the first (main) CALLOTHER, and placing a reference on the
* (separate) address corresponding to the named section will override the second CALLOTHER.
*
00100050 00 42 b0 a0 memw_loc (R16,P0),R2
00100054 c0 c0 01 8e || asl+= R0,R1,#0x0
*
*/
@Test
public void testCallotherOverrideCrossbuild() {
//verify the instructions used for the test
Instruction memw_locked_nonterminal =
listing.getInstructionAt(testCallotherOverrideCrossbuildAddr);
Instruction asl_plus_last =
listing.getInstructionAfter(testCallotherOverrideCrossbuildAddr);
assertNotNull(memw_locked_nonterminal);
assertEquals("memw_locked (R16,P0),R2", memw_locked_nonterminal.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(memw_locked_nonterminal));
assertFalse(parallelHelper.isEndOfParallelInstructionGroup(memw_locked_nonterminal));
assertNotNull(asl_plus_last);
assertEquals("asl+= R0,R1,#0x0", asl_plus_last.toString().trim());
assertTrue(parallelHelper.isParallelInstruction(asl_plus_last));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(asl_plus_last));
//verify that the pcode is the same whether or not you ask for overrides
PcodeOp[] memw_unmod = memw_locked_nonterminal.getPcode();
assertEquals(7, memw_unmod.length);
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode(true)));
PcodeOp[] asl_plus_unmod = asl_plus_last.getPcode();
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus_last.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus_last.getPcode(true)));
//apply override at the address of the main section
int id = program.startTransaction("test");
Reference overrideRefMain =
refManager.addMemoryReference(memw_locked_nonterminal.getAddress(), func1Addr,
RefType.CALLOTHER_OVERRIDE_CALL, SourceType.USER_DEFINED, -1);
refManager.setPrimary(overrideRefMain, true);
program.endTransaction(id, true);
//verify that the pcode does not change if you ask for no overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode()));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode(false)));
//verify that the callother op in the main section is changed but in named section
//it is not
PcodeOp[] memw_mod = memw_locked_nonterminal.getPcode(true);
assertEquals(memw_unmod.length, memw_mod.length);
for (int i = 0; i < memw_unmod.length; ++i) {
if (i == 4) {
assertEquals(PcodeOp.CALL, memw_mod[i].getOpcode());
assertEquals(func1Addr.getOffset(), memw_mod[i].getInput(0).getOffset());
assertTrue(memw_mod[i].getInput(0).isAddress());
assertEquals(PcodeOp.CALLOTHER, memw_unmod[i].getOpcode());
}
else {
assertTrue(PcodeEmitContextTest.equalPcodeOps(memw_unmod[i], memw_mod[i]));
}
}
assertEquals(10, asl_plus_unmod.length);
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus_last.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus_last.getPcode(true)));
//apply a second override at the address of the named section
id = program.startTransaction("test");
Reference overrideRefNamed = refManager.addMemoryReference(asl_plus_last.getAddress(),
func2Addr, RefType.CALLOTHER_OVERRIDE_CALL, SourceType.USER_DEFINED, -1);
refManager.setPrimary(overrideRefNamed, true);
program.endTransaction(id, true);
//verify no changes if you request no overrides
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus_last.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode(false)));
//verify that both CALLOTHER ops are changed if you do request overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_mod,
memw_locked_nonterminal.getPcode(true)));
PcodeOp[] asl_plus_mod = asl_plus_last.getPcode(true);
assertEquals(asl_plus_unmod.length, asl_plus_mod.length);
for (int i = 0; i < asl_plus_unmod.length; ++i) {
if (i == 8) {
assertEquals(PcodeOp.CALLOTHER, asl_plus_unmod[i].getOpcode());
assertEquals(PcodeOp.CALL, asl_plus_mod[i].getOpcode());
assertEquals(func2Addr.getOffset(), asl_plus_mod[i].getInput(0).getOffset());
assertTrue(asl_plus_mod[i].getInput(0).isAddress());
}
else {
assertTrue(PcodeEmitContextTest.equalPcodeOps(asl_plus_unmod[i], asl_plus_mod[i]));
}
}
//set the override at the address of the main section to non-primary
id = program.startTransaction("test");
refManager.setPrimary(overrideRefMain, false);
program.endTransaction(id, true);
//verify that the CALLOTHER in the main section is unchanged
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode()));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_unmod,
memw_locked_nonterminal.getPcode(true)));
//verify that the CALLOTHER op in the names section is unchanged if you
//request no overrides
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus_last.getPcode()));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus_last.getPcode(false)));
//verify the CALLOTHER op in the named section is changed if you request overrides
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_mod, asl_plus_last.getPcode(true)));
}
/**
* Tests that a fallthrough override applied to a singleton packet simply appends a
* BRANCH op.
*
00100058 c0 c0 01 8e asl+= R0,R1,#0x0
0010005c c0 c0 01 8e asl+= R0,R1,#0x0
00100060 c0 c0 01 8e asl+= R0,R1,#0x0
*/
@Test
public void testFallthroughOverrideTerminal() {
//verify the instruction used in the test
Instruction aslTerminal = listing.getInstructionAt(testFallthroughOverrideTerminalAddr);
assertNotNull(aslTerminal);
assertEquals("asl+= R0,R1,#0x0", aslTerminal.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(aslTerminal));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(aslTerminal));
//verify that asking for overrides has no effect on the pcode
PcodeOp[] asl_unmod = aslTerminal.getPcode();
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(asl_unmod, aslTerminal.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(asl_unmod, aslTerminal.getPcode(true)));
//apply a fallthrough override
int id = program.startTransaction("test");
aslTerminal.setFallThrough(aslTerminal.getAddress().add(8));
program.endTransaction(id, true);
//verify that pcode is unchanged if you request no overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(asl_unmod, aslTerminal.getPcode()));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(asl_unmod, aslTerminal.getPcode(false)));
//verify that if you request override a BRANCH op is appended to the pcode for the
//instruction and that there are no other changes
PcodeOp[] asl_mod = aslTerminal.getPcode(true);
assertEquals(asl_unmod.length + 1, asl_mod.length);
for (int i = 0; i < asl_unmod.length; ++i) {
assertTrue(PcodeEmitContextTest.equalPcodeOps(asl_unmod[i], asl_mod[i]));
}
PcodeOp appended = asl_mod[asl_mod.length - 1];
assertEquals(PcodeOp.BRANCH, appended.getOpcode());
assertTrue(appended.getInput(0).isAddress());
assertEquals(aslTerminal.getAddress().add(8).getOffset(), appended.getInput(0).getOffset());
}
/**
* Tests that a fallthrough override applied to an instruction in a packet appends
* a branch to the main section and does not change the pcode in a named section.
*
00100064 00 42 b0 a0 memw_loc (R16,P0),R2
00100068 80 40 00 d5 || add:sat R0,R0.L,R0.L
0010006c c0 c0 01 8e || asl+= R0,R1,#0x0
00100070 c0 c0 01 8e asl+= R0,R1,#0x0
*/
@Test
public void testFallthroughOverrideMidPacket() {
//verify the instructions used in the test
Instruction memw_locked = listing.getInstructionAt(testFallthroughOverrideMidPacketAddr);
assertNotNull(memw_locked);
assertEquals("memw_locked (R16,P0),R2", memw_locked.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(memw_locked));
assertFalse(parallelHelper.isEndOfParallelInstructionGroup(memw_locked));
Instruction addSat = listing.getInstructionAfter(memw_locked.getAddress());
assertNotNull(addSat);
assertEquals("add:sat R0,R0.L,R0.L", addSat.toString().trim());
assertTrue(parallelHelper.isParallelInstruction(addSat));
assertFalse(parallelHelper.isEndOfParallelInstructionGroup(addSat));
Instruction aslTerminal = listing.getInstructionAfter(addSat.getAddress());
assertNotNull(aslTerminal);
assertEquals("asl+= R0,R1,#0x0", aslTerminal.toString().trim());
assertTrue(parallelHelper.isParallelInstruction(aslTerminal));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(aslTerminal));
//verify that pcode unchanged when asking for overrides to be applied
PcodeOp[] memw_locked_unmod = memw_locked.getPcode();
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_locked_unmod,
memw_locked.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(memw_locked_unmod, memw_locked.getPcode(true)));
PcodeOp[] addSat_unmod = addSat.getPcode();
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(addSat_unmod, addSat.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(addSat_unmod, addSat.getPcode(true)));
PcodeOp[] aslTerminal_unmod = aslTerminal.getPcode();
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(aslTerminal_unmod,
aslTerminal.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(aslTerminal_unmod, aslTerminal.getPcode(true)));
//verify that the pcode for aslTerminal contains an "unlock" pcodeop (crossbuilt from memw_locked)
PcodeOp callother = aslTerminal_unmod[15];
assertEquals(PcodeOp.CALLOTHER, callother.getOpcode());
assertEquals("unlock",
language.getUserDefinedOpName((int) callother.getInput(0).getOffset()));
//apply the fallthrough override
int id = program.startTransaction("test");
memw_locked.setFallThrough(memw_locked.getAddress().add(12));
program.endTransaction(id, true);
//verify that pcode at address of main section is unchanged when overrides are not applied
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(memw_locked_unmod,
memw_locked.getPcode(false)));
//verify that the pcode at the address for the main section has a BRANCH appended when
//overrides are applied and is otherwise unchanged
PcodeOp[] memw_locked_mod = memw_locked.getPcode(true);
assertEquals(memw_locked_unmod.length + 1, memw_locked_mod.length);
for (int i = 0; i < memw_locked_unmod.length; ++i) {
assertTrue(
PcodeEmitContextTest.equalPcodeOps(memw_locked_unmod[i], memw_locked_mod[i]));
}
PcodeOp appended = memw_locked_mod[memw_locked_mod.length - 1];
assertEquals(PcodeOp.BRANCH, appended.getOpcode());
assertEquals(memw_locked.getAddress().add(12).getOffset(),
appended.getInput(0).getOffset());
assertTrue(appended.getInput(0).isAddress());
//verify that pcode at address where the named section is crossbuilt is unchanged
//whether or not overides are requested
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(aslTerminal_unmod, aslTerminal.getPcode()));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(aslTerminal_unmod,
aslTerminal.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(aslTerminal_unmod, aslTerminal.getPcode(true)));
}
/**
* Tests that a BRANCH override applied to a CALL instruction in a singleton
* packet replaes the CALL op with a BRANCH
*
00100074 c6 c7 00 5a call func1 undefined func1(void)
*/
@Test
public void testFlowOverrideSingletonCall() {
//verify the instructions used in the test
Instruction call = listing.getInstructionAt(testFlowOverrideSingletonCallAddr);
assertNotNull(call);
assertEquals("call 0x00101000", call.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(call));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(call));
//verify that the pcode is the same whether or not you request overrides
PcodeOp[] call_unmod = call.getPcode();
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(true)));
assertEquals(7, call_unmod.length);
//verify the CALL op exists
assertEquals(PcodeOp.CALL, call_unmod[6].getOpcode());
assertEquals(func1Addr, call_unmod[6].getInput(0).getAddress());
//apply the fallthrough override
int id = program.startTransaction("test");
call.setFlowOverride(FlowOverride.BRANCH);
program.endTransaction(id, true);
//verify that nothing changes if you ask for no overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(false)));
//verify that the CALL is changed to a BRANCH if you request overrides
//and there are no other changes
PcodeOp[] call_mod = call.getPcode(true);
assertEquals(call_unmod.length, call_mod.length);
for (int i = 0; i < call_mod.length - 1; i++) {
assertTrue(PcodeEmitContextTest.equalPcodeOps(call_unmod[i], call_mod[i]));
}
PcodeOp overridden = call_mod[6];
assertTrue(PcodeEmitContextTest.equalInputsAndOutput(overridden, call_unmod[6]));
assertEquals(PcodeOp.BRANCH, overridden.getOpcode());
}
/**
* Tests that to override the flow of a CALL instruction in a packet the flow override
* must be placed on the instruction where the CALL op is crossbuilt (which is not the "call"
* instruction in this example).
*
00100078 c4 47 00 5a call func1
0010007c c0 c0 01 8e || asl+= R0,R1,#0x0 undefined func1(void)
*/
@Test
public void testFlowOverrideCallInPacket() {
//verify the instructions used in the test
Instruction call = listing.getInstructionAt(testFlowOverrideCallInPacketAddr);
assertNotNull(call);
assertEquals("call 0x00101000", call.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(call));
assertFalse(parallelHelper.isEndOfParallelInstructionGroup(call));
Instruction asl_plus = listing.getInstructionAfter(call.getAddress());
assertNotNull(asl_plus);
assertEquals("asl+= R0,R1,#0x0", asl_plus.toString().trim());
assertTrue(parallelHelper.isParallelInstruction(asl_plus));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(asl_plus));
PcodeOp[] call_unmod = call.getPcode();
PcodeOp[] asl_plus_unmod = asl_plus.getPcode();
//verify that there are no changes if you ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(true)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(true)));
//apply a BRANCH override at the address of the call instruction. This should have
//no effect on the pcode, since the CALL op is in a named section and will be crossbuilt
//into the pcode of the next instruction
//(note that the associated action would be disabled in the gui for the call instruction)
int id = program.startTransaction("test");
call.setFlowOverride(FlowOverride.BRANCH);
program.endTransaction(id, true);
// verify no changes whether or not you ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(true)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(true)));
//apply a BRANCH override at the address of the asl instruction.
id = program.startTransaction("test");
asl_plus.setFlowOverride(FlowOverride.BRANCH);
program.endTransaction(id, true);
// verify no changes if you don't ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(false)));
//pcode for call instruction should not change if you ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(true)));
//verify that the CALL instruction becomes a BRANCH when overrides are requested
//and that there are no other changes
PcodeOp[] asl_plus_mod = asl_plus.getPcode(true);
assertEquals(asl_plus_unmod.length, asl_plus_mod.length);
for (int i = 0; i < asl_plus_unmod.length; ++i) {
PcodeOp mod = asl_plus_mod[i];
PcodeOp unmod = asl_plus_unmod[i];
if (i < (asl_plus_unmod.length - 1)) {
assertTrue(PcodeEmitContextTest.equalPcodeOps(unmod, mod));
}
else {
assertTrue(PcodeEmitContextTest.equalInputsAndOutput(unmod, mod));
assertEquals(PcodeOp.CALL, unmod.getOpcode());
assertEquals(PcodeOp.BRANCH, mod.getOpcode());
}
}
}
/**
* Tests that to override the destination of a CALL instruction in a packet a simple reference
* must be placed on the instruction where the CALL op is crossbuilt (which is not the "call"
* instruction in this example).
00100078 c4 47 00 5a call func1
0010007c c0 c0 01 8e || asl+= R0,R1,#0x0 undefined func1(void)
*/
@Test
public void testSimpleCallReferenceOverride() {
//verify the instructions used in the test
Instruction call = listing.getInstructionAt(testFlowOverrideCallInPacketAddr);
assertNotNull(call);
assertEquals("call 0x00101000", call.toString().trim());
assertFalse(parallelHelper.isParallelInstruction(call));
assertFalse(parallelHelper.isEndOfParallelInstructionGroup(call));
Instruction asl_plus = listing.getInstructionAfter(call.getAddress());
assertNotNull(asl_plus);
assertEquals("asl+= R0,R1,#0x0", asl_plus.toString().trim());
assertTrue(parallelHelper.isParallelInstruction(asl_plus));
assertTrue(parallelHelper.isEndOfParallelInstructionGroup(asl_plus));
PcodeOp[] call_unmod = call.getPcode();
PcodeOp[] asl_plus_unmod = asl_plus.getPcode();
//verify that there are no changes if you ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(true)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(true)));
//apply a simple overriding reference at the address of the call instruction
//verify that it has no effect on the Pcode, since the CALL op is crossbuilt to
//a different address
int id = program.startTransaction("test");
Reference simpleCallRef = refManager.addMemoryReference(call.getAddress(), func2Addr,
RefType.UNCONDITIONAL_CALL, SourceType.USER_DEFINED, -1);
//any default reference is primary, so need to set simpleCallRef to primary to unseat it
refManager.setPrimary(simpleCallRef, true);
program.endTransaction(id, true);
// verify no changes whether or not you ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(false)));
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(true)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(true)));
id = program.startTransaction("test");
simpleCallRef = refManager.addMemoryReference(asl_plus.getAddress(), func2Addr,
RefType.UNCONDITIONAL_CALL, SourceType.USER_DEFINED, -1);
//any default reference is primary, so need to set simpleCallRef to primary to unseat it
refManager.setPrimary(simpleCallRef, true);
program.endTransaction(id, true);
// verify no changes if you don't ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(false)));
assertTrue(
PcodeEmitContextTest.equalPcodeOpArrays(asl_plus_unmod, asl_plus.getPcode(false)));
//pcode for call instruction should not change if you ask for overrides
assertTrue(PcodeEmitContextTest.equalPcodeOpArrays(call_unmod, call.getPcode(true)));
//verify that the CALL target changes if overrides are requested
//and that there are no other changes
PcodeOp[] asl_plus_mod = asl_plus.getPcode(true);
assertEquals(asl_plus_unmod.length, asl_plus_mod.length);
for (int i = 0; i < asl_plus_unmod.length; ++i) {
PcodeOp mod = asl_plus_mod[i];
PcodeOp unmod = asl_plus_unmod[i];
if (i < (asl_plus_unmod.length - 1)) {
assertTrue(PcodeEmitContextTest.equalPcodeOps(unmod, mod));
}
else {
assertEquals(PcodeOp.CALL, unmod.getOpcode());
assertEquals(PcodeOp.CALL, mod.getOpcode());
assertEquals(func1Addr, unmod.getInput(0).getAddress());
assertEquals(func2Addr, mod.getInput(0).getAddress());
}
}
}
}

View File

@@ -253,12 +253,42 @@ ext.deps = [
sha256: "21546210748ba52e839e52112124b16ffab7d7fb68096493165fbc249e9023ad",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "pywin32-311-cp314-cp314-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl",
sha256: "3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "pywin32-311-cp313-cp313-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl",
sha256: "718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "pywin32-311-cp312-cp312-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl",
sha256: "b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "pywin32-311-cp311-cp311-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl",
sha256: "3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "pywin32-311-cp310-cp310-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/5e/bf/360243b1e953bd254a82f12653974be395ba880e7ec23e3731d9f73921cc/pywin32-311-cp310-cp310-win_amd64.whl",
sha256: "797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "pywin32-311-cp39-cp39-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/9f/8a/1403d0353f8c5a2f0829d2b1c4becbf9da2f0a4d040886404fc4a5431e4d/pywin32-311-cp39-cp39-win_amd64.whl",
sha256: "e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "win32more-0.7.0-py3-none-any.whl",
url: "https://files.pythonhosted.org/packages/92/3a/658eb3ba88f067662be280f8f1aec07a70c96bac77e9edc48b1be38e446b/win32more-0.7.0-py3-none-any.whl",