mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-04-25 17:25:17 +02:00
Merge remote-tracking branch 'origin/Ghidra_12.1'
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
0
Ghidra/Processors/Hexagon/Module.manifest
Executable file
0
Ghidra/Processors/Hexagon/Module.manifest
Executable file
35
Ghidra/Processors/Hexagon/build.gradle
Executable file
35
Ghidra/Processors/Hexagon/build.gradle
Executable 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"
|
||||
]
|
||||
16
Ghidra/Processors/Hexagon/certification.manifest
Executable file
16
Ghidra/Processors/Hexagon/certification.manifest
Executable 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|
|
||||
5
Ghidra/Processors/Hexagon/data/languages/Hexagon.opinion
Executable file
5
Ghidra/Processors/Hexagon/data/languages/Hexagon.opinion
Executable file
@@ -0,0 +1,5 @@
|
||||
<opinions>
|
||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
|
||||
<constraint primary="164" processor="Hexagon" size="32" />
|
||||
</constraint>
|
||||
</opinions>
|
||||
154
Ghidra/Processors/Hexagon/data/languages/hexagon.cspec
Executable file
154
Ghidra/Processors/Hexagon/data/languages/hexagon.cspec
Executable 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>
|
||||
19
Ghidra/Processors/Hexagon/data/languages/hexagon.dwarf
Normal file
19
Ghidra/Processors/Hexagon/data/languages/hexagon.dwarf
Normal 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>
|
||||
17
Ghidra/Processors/Hexagon/data/languages/hexagon.ldefs
Executable file
17
Ghidra/Processors/Hexagon/data/languages/hexagon.ldefs
Executable 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>
|
||||
439
Ghidra/Processors/Hexagon/data/languages/hexagon.pspec
Executable file
439
Ghidra/Processors/Hexagon/data/languages/hexagon.pspec
Executable 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>
|
||||
17384
Ghidra/Processors/Hexagon/data/languages/hexagon.sinc
Executable file
17384
Ghidra/Processors/Hexagon/data/languages/hexagon.sinc
Executable file
File diff suppressed because it is too large
Load Diff
888
Ghidra/Processors/Hexagon/data/languages/hexagon.slaspec
Executable file
888
Ghidra/Processors/Hexagon/data/languages/hexagon.slaspec
Executable 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"
|
||||
|
||||
872
Ghidra/Processors/Hexagon/data/languages/hexagon_float.sinc
Normal file
872
Ghidra/Processors/Hexagon/data/languages/hexagon_float.sinc
Normal 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
|
||||
6537
Ghidra/Processors/Hexagon/data/languages/hexagon_hvx.sinc
Normal file
6537
Ghidra/Processors/Hexagon/data/languages/hexagon_hvx.sinc
Normal file
File diff suppressed because it is too large
Load Diff
618
Ghidra/Processors/Hexagon/data/languages/hexagon_hvx.txt
Normal file
618
Ghidra/Processors/Hexagon/data/languages/hexagon_hvx.txt
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
648
Ghidra/Processors/Hexagon/data/languages/hexagon_left.sinc
Normal file
648
Ghidra/Processors/Hexagon/data/languages/hexagon_left.sinc
Normal 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;
|
||||
}
|
||||
776
Ghidra/Processors/Hexagon/data/languages/hexagon_right.sinc
Normal file
776
Ghidra/Processors/Hexagon/data/languages/hexagon_right.sinc
Normal 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;
|
||||
}
|
||||
72
Ghidra/Processors/Hexagon/data/patterns/Hexagon_patterns.xml
Executable file
72
Ghidra/Processors/Hexagon/data/patterns/Hexagon_patterns.xml
Executable 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>
|
||||
5
Ghidra/Processors/Hexagon/data/patterns/patternconstraints.xml
Executable file
5
Ghidra/Processors/Hexagon/data/patterns/patternconstraints.xml
Executable file
@@ -0,0 +1,5 @@
|
||||
<patternconstraints>
|
||||
<language id="Hexagon:LE:32:*">
|
||||
<patternfile>Hexagon_patterns.xml</patternfile>
|
||||
</language>
|
||||
</patternconstraints>
|
||||
1201
Ghidra/Processors/Hexagon/developer_scripts/VerifyHexagonTestVectors.java
Executable file
1201
Ghidra/Processors/Hexagon/developer_scripts/VerifyHexagonTestVectors.java
Executable file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user