diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py b/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py
index 8bc78ab34e..7c98b33bed 100644
--- a/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py
+++ b/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py
@@ -20,7 +20,7 @@
PCodeTest.defaults.toolchain_root = '/local/ToolChains'
PCodeTest.defaults.build_root = '/local/build-pcodetest'
-PCodeTest.defaults.gcc_version = '7.3.0'
+PCodeTest.defaults.gcc_version = '9.2.0'
PCodeTest.defaults.skip_files = []
PCodeTest.defaults.export_root = os.getcwd() + '/../../../../../ghidra.bin/Ghidra/Test/TestResources/data/pcodetests/'
PCodeTest.defaults.pcodetest_src = os.getcwd() + '/c_src'
diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py
index be7f938095..a3972d852f 100644
--- a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py
+++ b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py
@@ -665,10 +665,20 @@ PCodeTest({
})
PCodeTest({
- 'name': 'Xtensa',
+ 'name': 'Xtensa_LE',
'build_all': 1,
'build_exe': 1,
- 'toolchain': 'Xtensa/xtensa-lx106-elf',
+ 'toolchain': 'Xtensa/xtensa-esp32-elf',
'language_id': 'Xtensa:LE:32:default',
- 'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-lx106-elf/%(gcc_version)s -lgcc',
+ 'gcc_version' : '8.4.0',
+ 'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-esp32-elf/%(gcc_version)s',
+})
+
+PCodeTest({
+ 'name': 'Xtensa_BE',
+ 'build_all': 1,
+ 'build_exe': 1,
+ 'toolchain': 'Xtensa/xtensa-elf',
+ 'language_id': 'Xtensa:BE:32:default',
+ 'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-elf/%(gcc_version)s',
})
diff --git a/Ghidra/Processors/Xtensa/build.gradle b/Ghidra/Processors/Xtensa/build.gradle
index 9dadac96d0..b52d6e1866 100644
--- a/Ghidra/Processors/Xtensa/build.gradle
+++ b/Ghidra/Processors/Xtensa/build.gradle
@@ -1,3 +1,18 @@
+/* ###
+ * 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/javaTestProject.gradle"
@@ -8,3 +23,7 @@ eclipse.project.name = 'Processors Xtensa'
dependencies {
api project(':Base')
}
+
+sleighCompileOptions = [
+ "-l"
+]
diff --git a/Ghidra/Processors/Xtensa/certification.manifest b/Ghidra/Processors/Xtensa/certification.manifest
index 8d447e56a9..11a527af56 100644
--- a/Ghidra/Processors/Xtensa/certification.manifest
+++ b/Ghidra/Processors/Xtensa/certification.manifest
@@ -1,20 +1,18 @@
##VERSION: 2.0
Module.manifest||GHIDRA||||END|
-build.gradle||GHIDRA||||END|
+data/languages/cust.sinc||GHIDRA||||END|
+data/languages/flix.sinc||GHIDRA||||END|
data/languages/xtensa.cspec||GHIDRA||||END|
data/languages/xtensa.dwarf||GHIDRA||||END|
data/languages/xtensa.ldefs||GHIDRA||||END|
data/languages/xtensa.opinion||GHIDRA||||END|
data/languages/xtensa.pspec||GHIDRA||||END|
-data/languages/xtensa.sinc||GHIDRA||||END|
-data/languages/xtensa.slaspec||GHIDRA||||END|
+data/languages/xtensaArch.sinc||GHIDRA||||END|
data/languages/xtensaInstructions.sinc||GHIDRA||||END|
+data/languages/xtensaMain.sinc||GHIDRA||||END|
+data/languages/xtensa_be.slaspec||GHIDRA||||END|
+data/languages/xtensa_depbits.sinc||GHIDRA||||END|
+data/languages/xtensa_le.slaspec||GHIDRA||||END|
data/manuals/xtensa.idx||GHIDRA||||END|
data/patterns/patternconstraints.xml||GHIDRA||||END|
data/patterns/xtensa_patterns.xml||GHIDRA||||END|
-src/main/help/help/topics/xtensa/help.html||GHIDRA||||END|
-src/main/help/help/TOC_Source.xml||GHIDRA||||END|
-src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java||GHIDRA||||END|
-src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java||GHIDRA||||END|
-src/test.processors/java/ghidra/test/processors/Xtensa_O0_EmulatorTest.java||GHIDRA||||END|
-src/test.processors/java/ghidra/test/processors/Xtensa_O3_EmulatorTest.java||GHIDRA||||END|
diff --git a/Ghidra/Processors/Xtensa/data/languages/cust.sinc b/Ghidra/Processors/Xtensa/data/languages/cust.sinc
new file mode 100644
index 0000000000..dc54f28bbe
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/data/languages/cust.sinc
@@ -0,0 +1,17 @@
+# Per the manual:
+# CUST0 and CUST1 opcode encodings shown in Table 7–193 are permanently reserved
+# for designer-defined opcodes. In the future, customers who use these spaces
+# exclusively for their own designer-defined opcodes will be able to add new
+# Tensilica-defined options without changing their opcodes or binary executables.
+
+define pcodeop cust0;
+
+:cust0 "{op2="^op2^", r="^ar^", s="^as^", t="^at^"}" is op0=0x0 & op1=0x6 & op2 & ar & as & at {
+ cust0();
+}
+
+define pcodeop cust1;
+
+:cust1 "{op2="^op2^", r="^ar^", s="^as^", t="^at^"}" is op0=0x0 & op1=0x7 & op2 & ar & as & at {
+ cust1();
+}
\ No newline at end of file
diff --git a/Ghidra/Processors/Xtensa/data/languages/flix.sinc b/Ghidra/Processors/Xtensa/data/languages/flix.sinc
new file mode 100644
index 0000000000..5a017ca640
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/data/languages/flix.sinc
@@ -0,0 +1,9 @@
+
+# FLIX (Flexible Length Instruction eXtension) is a Xtensa processor extension
+# that allows for variable-length, multi-op instructions with support from 4
+# 16 bytes. Customizable, if if found they should be flagged.
+
+define pcodeop flix;
+:FLIX u_4_23 is op0=0xe & u_4_23 {
+ flix();
+}
\ No newline at end of file
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa.cspec b/Ghidra/Processors/Xtensa/data/languages/xtensa.cspec
index 81a5b3a373..f502e71cce 100644
--- a/Ghidra/Processors/Xtensa/data/languages/xtensa.cspec
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensa.cspec
@@ -55,69 +55,15 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -125,6 +71,7 @@
+
@@ -135,11 +82,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa.ldefs b/Ghidra/Processors/Xtensa/data/languages/xtensa.ldefs
index 80c6e25721..295fea8ef0 100644
--- a/Ghidra/Processors/Xtensa/data/languages/xtensa.ldefs
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensa.ldefs
@@ -5,13 +5,28 @@
endian="little"
size="32"
variant="default"
- version="1.0"
- slafile="xtensa.sla"
+ version="4.0"
+ slafile="xtensa_le.sla"
processorspec="xtensa.pspec"
manualindexfile="../manuals/xtensa.idx"
id="Xtensa:LE:32:default">
Tensilica Xtensa 32-bit little-endian
+
+
+
+
+ Tensilica Xtensa 32-bit big-endian
+
+
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa.opinion b/Ghidra/Processors/Xtensa/data/languages/xtensa.opinion
index 3f2eae23ff..1e6ce11602 100644
--- a/Ghidra/Processors/Xtensa/data/languages/xtensa.opinion
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensa.opinion
@@ -1,6 +1,6 @@
-
-
+
+
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa.pspec b/Ghidra/Processors/Xtensa/data/languages/xtensa.pspec
index 114b5c47a8..721b2e437a 100644
--- a/Ghidra/Processors/Xtensa/data/languages/xtensa.pspec
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensa.pspec
@@ -2,4 +2,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa.sinc b/Ghidra/Processors/Xtensa/data/languages/xtensa.sinc
deleted file mode 100644
index 219302428c..0000000000
--- a/Ghidra/Processors/Xtensa/data/languages/xtensa.sinc
+++ /dev/null
@@ -1,469 +0,0 @@
-define endian=little;
-define alignment=1;
-
-define space ram type=ram_space size=4 default;
-define space register type=register_space size=4;
-
-# Special registers (SR). Not all are actually 32 bit, but for the sake of
-# simplicity they are here.
-define register offset=0x00 size=4 [ LBEG LEND LCOUNT SAR BR LITBASE ];
-define register offset=0x30 size=4 [ SCOMPARE1 ];
-define register offset=0x40 size=4 [ ACCLO ACCHI ];
-define register offset=0x80 size=4 [ M0 M1 M2 M3 ];
-define register offset=0x120 size=4 [ WindowBase WindowStart ];
-define register offset=0x14c size=4 [ PTEVADDR ];
-define register offset=0x164 size=4 [ MMID RASID ITLBCFG DTLBCFG ];
-define register offset=0x180 size=4 [ IBREAKENABLE ];
-define register offset=0x184 size=4 [ MEMCTL ];
-define register offset=0x188 size=4 [ CACHEATTR ATOMCTL ];
-define register offset=0x1a0 size=4 [ DDR ];
-define register offset=0x1a8 size=4 [ MEPC MEPS MESAVE MESR MECR MEVADDR ];
-define register offset=0x200 size=4 [ IBREAKA0 IBREAKA1 ];
-define register offset=0x240 size=4 [ DBREAKA0 DBREAKA1 ];
-define register offset=0x280 size=4 [ DBREAKC0 DBREAKC1 ];
-define register offset=0x2c4 size=4 [ EPC1 EPC2 EPC3 EPC4 EPC5 EPC6 EPC7 ];
-define register offset=0x300 size=4 [ DEPC ];
-define register offset=0x308 size=4 [ EPS2 EPS3 EPS4 EPS5 EPS6 EPS7 ];
-define register offset=0x344 size=4 [ EXCSAVE1 EXCSAVE2 EXCSAVE3 EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 ];
-define register offset=0x380 size=4 [ CPENABLE ];
-define register offset=0x384 size=4 [ INTERRUPT INTSET INTCLEAR INTENABLE ];
-define register offset=0x398 size=4 [ PS VECBASE EXCCAUSE DEBUGCAUSE CCOUNT PRID ICOUNT ICOUNTLEVEL EXCVADDR ];
-define register offset=0x3c0 size=4 [ CCOMPARE0 CCOMPARE1 CCOMPARE2 ];
-define register offset=0x3d0 size=4 [ MISC0 MISC1 MISC2 MISC3 ];
-
-# TODO: Register offsets *might* be firmware specific?
-
-# Address registers (AR).
-define register offset=0x8000 size=4 [
- a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
- i2 i3 i4 i5 i6 i7
- o2 o3 o4 o5 o6 o7
-];
-
-# Floating Point registers (FR + FCR (control) + FSR (status)).
-define register offset=0x8100 size=4 [
- f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
- fcr fsr
-];
-
-# Boolean registers (BR).
-define register offset=0x8200 size=1 [
- b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
-];
-
-# Program counter.
-# TODO: offset could also be 0x1300 or 0x8300
-define register offset=0x8300 size=4 [ pc ];
-
-# Shift amount register. (TODO: other special registers)
-# define register offset=0x2000 size=1 [ SAR ];
-
-define register offset=0x8400 size=4 contextreg;
-define context contextreg
- phase=(0,0)
- loopEnd=(1,1) noflow
-;
-
-# Regular 24-bit instruction.
-define token insn(24)
- # Named opcode/register fields.
- op2 = (20,23)
- ar = (12,15)
- fr = (12,15)
- br = (12,15)
- as = (8,11)
- fs = (8,11)
- bs = (8,11)
- sr = (8,15)
- at = (4,7)
- ft = (4,7)
- bt = (4,7)
- op1 = (16,19)
- op0 = (0,3)
-
- # Signed and unsigned immediates. Named [us]N_L_M, where u and s denote signedness, L and M the
- # least and most significant bit of the immediate in the instruction word, and N the length
- # (i.e. M-L+1).
- u3_21_23 = (21,23)
- u4_20_23 = (20,23)
- s8_16_23 = (16,23) signed
- u8_16_23 = (16,23)
- u12_12_23 = (12,23)
- s12_12_23 = (12,23) signed
- u16_8_23 = (8,23)
- s8_6_23 = (6,23) signed
- u1_20 = (20,20)
- u2_18_19 = (18,19)
- u3_17_19 = (17,19)
- u2_16_17 = (16,17)
- u1_16 = (16,16)
- u2_14_15 = (14,15)
- u3_13_15 = (13,15)
- u4_12_15 = (12,15)
- u8_8_15 = (8,15)
- u2_12_13 = (12,13)
- u1_12 = (12,12)
- u4_8_11 = (8,11)
- u8_4_11 = (4,11)
- s4_8_11 = (8,11) signed
- u2_6_7 = (6,7)
- u3_5_7 = (5,7)
- u4_4_7 = (4,7)
- s4_4_7 = (4,7)
- u2_4_5 = (4,5)
- u1_4 = (4,4)
-;
-
-# Narrow 16-bit instructions; fields are always prefixed with n_.
-define token narrowinsn(16)
- n_ar = (12,15)
- n_as = (8,11)
- n_at = (4,7)
- n_op0 = (0, 3)
-
- n_u4_12_15 = (12,15)
- n_s4_12_15 = (12,15) signed
- n_u4_8_11 = (8,11)
- n_u1_7 = (7,7)
- n_u2_6_7 = (6,7)
- n_u4_4_7 = (4,7)
- n_s3_4_6 = (4,6)
- n_u2_4_5 = (4,5)
-;
-
-define token opbyte (8)
- op0_8 = (0,7)
-;
-
-define token opword (16)
- op0_16 = (0,15)
-;
-
-attach variables [ sr ] [
-# 0x...0 0x...4 0x...8 0x...c
- LBEG LEND LCOUNT SAR # 0x0_
- BR LITBASE _ _ # 0x1_
- _ _ _ _ # 0x2_
- SCOMPARE1 _ _ _ # 0x3_
- ACCLO ACCHI _ _ # 0x4_
- _ _ _ _ # 0x5_
- _ _ _ _ # 0x6_
- _ _ _ _ # 0x7_
- M0 M1 M2 M3 # 0x8_
- _ _ _ _ # 0x9_
- _ _ _ _ # 0xa_
- _ _ _ _ # 0xb_
- _ _ _ _ # 0xc_
- _ _ _ _ # 0xd_
- _ _ _ _ # 0xe_
- _ _ _ _ # 0xf_
-# 0x...0 0x...4 0x...8 0x...c
- _ _ _ _ # 0x10_
- _ _ _ _ # 0x11_
- WindowBase WindowStart _ _ # 0x12_
- _ _ _ _ # 0x13_
- _ _ _ PTEVADDR # 0x14_
- _ _ _ _ # 0x15_
- _ MMID RASID ITLBCFG # 0x16_
- DTLBCFG _ _ _ # 0x17_
- IBREAKENABLE MEMCTL CACHEATTR ATOMCTL # 0x18_
- _ _ _ _ # 0x19_
- DDR _ MEPC MEPS # 0x1a_
- MESAVE MESR MECR MEVADDR # 0x1b_
- _ _ _ _ # 0x1c_
- _ _ _ _ # 0x1d_
- _ _ _ _ # 0x1e_
- _ _ _ _ # 0x1f_
-# 0x...0 0x...4 0x...8 0x...c
- IBREAKA0 IBREAKA1 _ _ # 0x20_
- _ _ _ _ # 0x21_
- _ _ _ _ # 0x22_
- _ _ _ _ # 0x23_
- DBREAKA0 DBREAKA1 _ _ # 0x24_
- _ _ _ _ # 0x25_
- _ _ _ _ # 0x26_
- _ _ _ _ # 0x27_
- DBREAKC0 DBREAKC1 _ _ # 0x28_
- _ _ _ _ # 0x29_
- _ _ _ _ # 0x2a_
- _ _ _ _ # 0x2b_
- _ EPC1 EPC2 EPC3 # 0x2c_
- EPC4 EPC5 EPC6 EPC7 # 0x2d_
- _ _ _ _ # 0x2e_
- _ _ _ _ # 0x2f_
-# 0x...0 0x...4 0x...8 0x...c
- DEPC _ EPS2 EPS3 # 0x30_
- EPS4 EPS5 EPS6 EPS7 # 0x31_
- _ _ _ _ # 0x32_
- _ _ _ _ # 0x33_
- _ EXCSAVE1 EXCSAVE2 EXCSAVE3 # 0x34_
- EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 # 0x35_
- _ _ _ _ # 0x36_
- _ _ _ _ # 0x37_
- CPENABLE INTERRUPT INTSET INTCLEAR # 0x38_
- INTENABLE _ PS VECBASE # 0x39_
- EXCCAUSE DEBUGCAUSE CCOUNT PRID # 0x3a_
- ICOUNT ICOUNTLEVEL EXCVADDR _ # 0x3b_
- CCOMPARE0 CCOMPARE1 CCOMPARE2 _ # 0x3c_
- MISC0 MISC1 MISC2 MISC3 # 0x3d_
- _ _ _ _ # 0x3e_
- _ _ _ _ # 0x3f_
-# 0x...0 0x...4 0x...8 0x...c
-];
-
-attach variables [ ar as at n_ar n_as n_at ] [
- a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
-];
-
-attach variables [ fr fs ft ] [
- f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
-];
-
-attach variables [ br bs bt ] [
- b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
-];
-
-attach variables [ u8_8_15 ] [
-# 0x...0 0x...4 0x...8 0x...c
- LBEG LEND LCOUNT SAR # 0x0_
- BR LITBASE _ _ # 0x1_
- _ _ _ _ # 0x2_
- SCOMPARE1 _ _ _ # 0x3_
- ACCLO ACCHI _ _ # 0x4_
- _ _ _ _ # 0x5_
- _ _ _ _ # 0x6_
- _ _ _ _ # 0x7_
- M0 M1 M2 M3 # 0x8_
- _ _ _ _ # 0x9_
- _ _ _ _ # 0xa_
- _ _ _ _ # 0xb_
- _ _ _ _ # 0xc_
- _ _ _ _ # 0xd_
- _ _ _ _ # 0xe_
- _ _ _ _ # 0xf_
-# 0x...0 0x...4 0x...8 0x...c
- _ _ _ _ # 0x10_
- _ _ _ _ # 0x11_
- WindowBase WindowStart _ _ # 0x12_
- _ _ _ _ # 0x13_
- _ _ _ PTEVADDR # 0x14_
- _ _ _ _ # 0x15_
- _ MMID RASID ITLBCFG # 0x16_
- DTLBCFG _ _ _ # 0x17_
- IBREAKENABLE MEMCTL CACHEATTR ATOMCTL # 0x18_
- _ _ _ _ # 0x19_
- DDR _ MEPC MEPS # 0x1a_
- MESAVE MESR MECR MEVADDR # 0x1b_
- _ _ _ _ # 0x1c_
- _ _ _ _ # 0x1d_
- _ _ _ _ # 0x1e_
- _ _ _ _ # 0x1f_
-# 0x...0 0x...4 0x...8 0x...c
- IBREAKA0 IBREAKA1 _ _ # 0x20_
- _ _ _ _ # 0x21_
- _ _ _ _ # 0x22_
- _ _ _ _ # 0x23_
- DBREAKA0 DBREAKA1 _ _ # 0x24_
- _ _ _ _ # 0x25_
- _ _ _ _ # 0x26_
- _ _ _ _ # 0x27_
- DBREAKC0 DBREAKC1 _ _ # 0x28_
- _ _ _ _ # 0x29_
- _ _ _ _ # 0x2a_
- _ _ _ _ # 0x2b_
- _ EPC1 EPC2 EPC3 # 0x2c_
- EPC4 EPC5 EPC6 EPC7 # 0x2d_
- _ _ _ _ # 0x2e_
- _ _ _ _ # 0x2f_
-# 0x...0 0x...4 0x...8 0x...c
- DEPC _ EPS2 EPS3 # 0x30_
- EPS4 EPS5 EPS6 EPS7 # 0x31_
- _ _ _ _ # 0x32_
- _ _ _ _ # 0x33_
- _ EXCSAVE1 EXCSAVE2 EXCSAVE3 # 0x34_
- EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 # 0x35_
- _ _ _ _ # 0x36_
- _ _ _ _ # 0x37_
- CPENABLE INTERRUPT INTSET INTCLEAR # 0x38_
- INTENABLE _ PS VECBASE # 0x39_
- EXCCAUSE DEBUGCAUSE CCOUNT PRID # 0x3a_
- ICOUNT ICOUNTLEVEL EXCVADDR _ # 0x3b_
- CCOMPARE0 CCOMPARE1 CCOMPARE2 _ # 0x3c_
- MISC0 MISC1 MISC2 MISC3 # 0x3d_
- _ _ _ _ # 0x3e_
- _ _ _ _ # 0x3f_
-# 0x...0 0x...4 0x...8 0x...c
-];
-
-# Various 32-bit pointers relative to PC. Any operands that are split across non-consecutive
-# bits are named foo_LL.LM_ML.MM, where LL is the least significant bits of the least
-# singificant operand half, LM the most significant bits of the least significant operand half, etc.
-
-urel_16_23: rel is u8_16_23 [ rel = inst_start + u8_16_23 + 4; ] { export *:4 rel; }
-
-srel_16_23: rel is s8_16_23 [ rel = inst_start + s8_16_23 + 4; ] { export *:4 rel; }
-
-srel_12_23: rel is s12_12_23 [ rel = inst_start + s12_12_23 + 4; ] { export *:4 rel; }
-
-srel_6_23: rel is s8_6_23 [ rel = inst_start + s8_6_23 + 4; ] { export *:4 rel; }
-
-urel_12_15_4_5: rel is n_u2_4_5 & n_u4_12_15 [
- rel = inst_start + ((n_u2_4_5 << 4) | n_u4_12_15) + 4;
-] { export *:4 rel; }
-
-srel_6_23_sb2: rel is s8_6_23 [
- rel = (inst_start & ~3) + ( s8_6_23 << 2 ) + 4;
-] { export *:4 rel; }
-
-srel_8_23_oex_sb2: rel is u16_8_23 [
- rel = ((inst_start + 3) & ~3) + ((u16_8_23 | 0xfffc0000) << 2);
- # Below might indicate firmware specific:
- # rel = 0x9fa000 + 0x40000 + ((u16_8_23 | 0xffff0000) << 2);
-] { export *:4 rel; }
-
-# Immediates split across the instruction.
-u5_8_11_20: tmp is u1_20 & u4_8_11 [ tmp = (u1_20 << 4) | u4_8_11; ] { export *[const]:1 tmp; }
-u5_4_7_20: tmp is u1_20 & u4_4_7 [ tmp = (u1_20 << 4) | u4_4_7; ] { export *[const]:1 tmp; }
-u5_8_11_16: tmp is u1_16 & u4_8_11 [ tmp = (u1_16 << 4) | u4_8_11; ] { export *[const]:1 tmp; }
-u5_4_7_12: tmp is u1_12 & u4_4_7 [ tmp = (u1_12 << 4) | u4_4_7; ] { export *[const]:1 tmp; }
-u5_8_11_4: tmp is u1_4 & u4_8_11 [ tmp = (u1_4 << 4) | u4_8_11; ] { export *[const]:1 tmp; }
-
-# Signed 12-bit (extended to 16) immediate, used by MOVI.
-s16_16_23_8_11: tmp is s4_8_11 & u8_16_23 [
- tmp = (s4_8_11 << 8) | u8_16_23;
-] { export *[const]:2 tmp; }
-
-# An “asymmetric” immediate from -32..95, used by MOVI.N.
-n_s8_12_15_4_6_asymm: tmp is n_s3_4_6 & n_s4_12_15 [
- tmp = ((((n_s3_4_6 & 7) << 4) | (n_s4_12_15 & 15)) |
- ((((n_s3_4_6 >> 2) & 1) & ((n_s3_4_6 >> 1) & 1)) << 7));
-] { export *[const]:1 tmp; }
-
-# Immediates shifted or with offset.
-s16_16_23_sb8: tmp is s8_16_23 [ tmp = s8_16_23 << 8; ] { export *[const]:2 tmp; }
-u15_12_23_sb3: tmp is u12_12_23 [ tmp = u12_12_23 << 3; ] { export *[const]:2 tmp; }
-u10_16_23_sb2: tmp is u8_16_23 [ tmp = u8_16_23 << 2; ] { export *[const]:2 tmp; }
-u9_16_23_sb1: tmp is u8_16_23 [ tmp = u8_16_23 << 1; ] { export *[const]:2 tmp; }
-u5_20_23_plus1: tmp is u4_20_23 [ tmp = u4_20_23 + 1; ] { export *[const]:1 tmp; }
-u8_20.23_sb4: tmp is u4_20_23 [ tmp = u4_20_23 << 4; ] { export *[const]:1 tmp; }
-u5_4_7_plus7: tmp is u4_4_7 [ tmp = u4_4_7 + 7; ] { export *[const]:1 tmp; }
-
-n_u6_12_15_sb2: tmp is n_u4_12_15 [ tmp = n_u4_12_15 << 2; ] { export *[const]:1 tmp; }
-
-# One-extended. FIXME: Verify this. Only used by [LS]32E (window extension), which aren’t yet
-# implemented.
-s5_12_15_oex: tmp is u4_12_15 [ tmp = (2 << u4_12_15) * -1; ] { export *[const]:2 tmp; }
-
-# Some 4-bit immediates with mappings that can’t be (easily) expressed in a single disassembly action.
-
-# n_u4_4_7 with 0 being -1, used by ADDI.N.
-n_s4_4_7_nozero: tmp is n_u4_4_7 = 0 [ tmp = -1; ] { export *[const]:4 tmp; }
-n_s4_4_7_nozero: tmp is n_u4_4_7 [ tmp = n_u4_4_7+0; ] { export *[const]:4 tmp; }
-
-# imm stored in sa for slli is 32-shift.
-# TODO why can't we use subtable output for this instead of repeating u5_4_7_20 calc?
-u5_4_7_20_slli: tmp is u1_20 & u4_4_7 [ tmp = 32 - ((u1_20 << 4) | u4_4_7); ] { export *[const]:1 tmp; }
-
-# B4CONST(ar) (Branch Immediate) encodings, pg. 41 f.
-r_b4const: tmp is ar = 0 [ tmp = 0xffffffff; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 1 [ tmp = 0x1; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
-r_b4const: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
-
-# B4CONSTU(ar) (Branch Unsigned Immediate) encodings, pg. 42.
-r_b4constu: tmp is ar = 0 [ tmp = 0x8000; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 1 [ tmp = 0x1000; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
-r_b4constu: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
-
-define pcodeop breakpoint;
-define pcodeop dhi;
-define pcodeop dhu;
-define pcodeop dhwb;
-define pcodeop dhwbi;
-define pcodeop dii;
-define pcodeop diu;
-define pcodeop diwb;
-define pcodeop diwbi;
-define pcodeop dpfl;
-define pcodeop dpfr;
-define pcodeop dpfro;
-define pcodeop dpfw;
-define pcodeop dpfwo;
-define pcodeop dsync;
-define pcodeop esync;
-define pcodeop excw;
-define pcodeop extw;
-define pcodeop idtlb;
-define pcodeop ihi;
-define pcodeop ihu;
-define pcodeop iii;
-define pcodeop iitlb;
-define pcodeop iiu;
-define pcodeop ill;
-define pcodeop ipf;
-define pcodeop ipfl;
-define pcodeop isync;
-define pcodeop acquire;
-define pcodeop ldct;
-define pcodeop lict;
-define pcodeop licw;
-define pcodeop memw;
-define pcodeop pdtlb;
-define pcodeop pitlb;
-define pcodeop rdtlb0;
-define pcodeop rdtlb1;
-define pcodeop rer;
-define pcodeop rfdd;
-define pcodeop rfde;
-define pcodeop rfdo;
-define pcodeop rfe;
-define pcodeop rfi;
-define pcodeop rfme;
-define pcodeop rfue;
-define pcodeop rfwo;
-define pcodeop rfwu;
-define pcodeop ritlb0;
-define pcodeop ritlb1;
-define pcodeop rsil;
-define pcodeop rsr; # TODO: Map known special registers.
-define pcodeop rsync;
-define pcodeop rur;
-define pcodeop s32c1i;
-define pcodeop release;
-define pcodeop sdct;
-define pcodeop sict;
-define pcodeop sicw;
-define pcodeop simcall;
-define pcodeop syscall;
-define pcodeop waiti;
-define pcodeop wdtlb;
-define pcodeop wer;
-define pcodeop witlb;
-define pcodeop wsr; # TODO: Map known special registers.
-define pcodeop wur;
-define pcodeop xsr;
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa.slaspec b/Ghidra/Processors/Xtensa/data/languages/xtensa.slaspec
deleted file mode 100644
index 523420d04f..0000000000
--- a/Ghidra/Processors/Xtensa/data/languages/xtensa.slaspec
+++ /dev/null
@@ -1,25 +0,0 @@
-@include "xtensa.sinc"
-
-# NOTE: This is quite a big hack; a real processor will compare nextPC to LEND on every ifetch.
-# As we only inject the branch-back check on addresses marked by loop insns, we may miss
-# strange things like loop registers being written directly or loop registers being overwritten
-# by a "nested" loop instruction. We also don't check CLOOPENABLE (PS.EXCM).
-# For code that hasn't been intentially crafted for anti-analysis this should be fine.
-:^instruction is phase=0 & loopEnd=1 & instruction [phase=1;] {
- if (LCOUNT == 0) goto ;
- LCOUNT = LCOUNT - 1;
- goto [LBEG];
-
- build instruction;
-}
-
-:^instruction is phase=0 & loopEnd=0 & instruction [phase=1;] {
- build instruction;
-}
-
-with : phase=1 {
-@include "xtensaInstructions.sinc"
-}
-
-# TODO: Evaluate
-# @include "xtensaTodo.sinc"
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensaArch.sinc b/Ghidra/Processors/Xtensa/data/languages/xtensaArch.sinc
new file mode 100644
index 0000000000..526f5bc590
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensaArch.sinc
@@ -0,0 +1,433 @@
+define endian=$(ENDIAN);
+define alignment=1;
+
+define space ram type=ram_space size=4 default;
+define space register type=register_space size=4;
+
+# Address registers (AR).
+define register offset=0x0000 size=4 [
+ a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
+];
+
+# Temporary Address registers (facilitates simplified CALL register swapping used by decompiler)
+define register offset=0x0080 size=4 [
+ t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11
+];
+
+# Floating Point registers
+define register offset=0x0100 size=4 [
+ f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
+];
+
+# Boolean registers (BR)
+define register offset=0x0200 size=1 [
+ b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
+];
+
+define register offset=0x0400 size=4 [
+user0 user1 user2 user3 user4 user5 user6 user7 user8 user9 user10 user11 user12 user13 user14 user15
+user16 user17 user18 user19 user20 user21 user22 user23 user24 user25 user26 user27 user28 user29 user30 user31
+user32 user33 user34 user35 user36 user37 user38 user39 user40 user41 user42 user43 user44 user45 user46 user47
+user48 user49 user50 user51 user52 user53 user54 user55 user56 user57 user58 user59 user60 user61 user62 user63
+user64 user65 user66 user67 user68 user69 user70 user71 user72 user73 user74 user75 user76 user77 user78 user79
+user80 user81 user82 user83 user84 user85 user86 user87 user88 user89 user90 user91 user92 user93 user94 user95
+user96 user97 user98 user99 user100 user101 user102 user103 user104 user105 user106 user107 user108 user109 user110 user111
+user112 user113 user114 user115 user116 user117 user118 user119 user120 user121 user122 user123 user124 user125 user126 user127
+user128 user129 user130 user131 user132 user133 user134 user135 user136 user137 user138 user139 user140 user141 user142 user143
+user144 user145 user146 user147 user148 user149 user150 user151 user152 user153 user154 user155 user156 user157 user158 user159
+user160 user161 user162 user163 user164 user165 user166 user167 user168 user169 user170 user171 user172 user173 user174 user175
+user176 user177 user178 user179 user180 user181 user182 user183 user184 user185 user186 user187 user188 user189 user190 user191
+user192 user193 user194 user195 user196 user197 user198 user199 user200 user201 user202 user203 user204 user205 user206 user207
+user208 user209 user210 user211 user212 user213 user214 user215 user216 user217 user218 user219 user220 user221 user222 user223
+user224 user225 user226 user227 user228 user229 user230 THREADPTR FCR FSR user234 user235 user236 user237 user238 user239
+user240 user241 user242 user243 user244 user245 user246 user247 user248 user249 user250 user251 user252 user253 user254 user255
+];
+
+# Program counter.
+define register offset=0x1000 size=4 [ pc ];
+
+define register offset=0x2000 size=4 [
+ LBEG LEND LCOUNT SAR BR LITBASE sr6 sr7 sr8 sr9 sr10 sr11 SCOMPARE1 sr13 sr14 sr15
+@if ENDIAN == "big"
+ACCHI ACCLO
+@else
+ACCLO ACCHI
+@endif
+ sr18 sr19 sr20 sr21 sr22 sr23 sr24 sr25 sr26 sr27 sr28 sr29 sr30 sr31
+ M0 M1 M2 M3 sr36 sr37 sr38 sr39 sr40 sr41 sr42 sr43 sr44 sr45 sr46 sr47
+ sr48 sr49 sr50 sr51 sr52 sr53 sr54 sr55 sr56 sr57 sr58 sr59 sr60 sr61 sr62 sr63
+ sr64 sr65 sr66 sr67 sr68 sr69 sr70 sr71 WindowBase WindowStart sr74 sr75 sr76 sr77 sr78 sr79
+ sr80 sr81 sr82 PTEVADDR sr84 sr85 sr86 sr87 sr88 MMID RASID ITLBCFG DTLBCFG sr93 sr94 sr95
+ IBREAKENABLE MEMCTL CACHEATTR ATOMCTL sr100 sr101 sr102 sr103 DDR sr105 MEPC MEPS MESAVE MESR MECR MEVADDR
+ sr112 sr113 sr114 sr115 sr116 sr117 sr118 sr119 sr120 sr121 sr122 sr123 sr124 sr125 sr126 sr127
+ IBREAKA0 IBREAKA1 sr130 sr131 sr132 sr133 sr134 sr135 sr136 sr137 sr138 sr139 sr140 sr141 sr142 sr143
+ DBREAKA0 DBREAKA1 sr146 sr147 sr148 sr149 sr150 sr151 sr152 sr153 sr154 sr155 sr156 sr157 sr158 sr159
+ DBREAKC0 DBREAKC1 sr162 sr163 sr164 sr165 sr166 sr167 sr168 sr169 sr170 sr171 sr172 sr173 sr174 sr175
+ sr176 EPC1 EPC2 EPC3 EPC4 EPC5 EPC6 EPC7 sr184 sr185 sr186 sr187 sr188 sr189 sr190 sr191
+ DEPC sr193 EPS2 EPS3 EPS4 EPS5 EPS6 EPS7 sr200 sr201 sr202 sr203 sr204 sr205 sr206 sr207
+ sr208 EXCSAVE1 EXCSAVE2 EXCSAVE3 EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 sr216 sr217 sr218 sr219 sr220 sr221 sr222 sr223
+#TODO: REVIEW NEEDED! - INTSET / INTERRUPT placement/address (also review related attach)
+ CPENABLE INTERRUPT INTSET INTCLEAR INTENABLE sr229 PS VECBASE EXCCAUSE DEBUGCAUSE CCOUNT PRID ICOUNT ICOUNTLEVEL EXCVADDR sr239
+ CCOMPARE0 CCOMPARE1 CCOMPARE2 sr243 MISC0 MISC1 MISC2 MISC3 sr248 sr249 sr250 sr251 sr252 sr253 sr254 sr255
+];
+
+define register offset=0x2040 size=8 [ ACC ];
+
+@define EPC_BASE "0x22c0" #address of EPCn = $(EPC_BASE) + (n * 4)
+@define EPS_BASE "0x2300" #address of EPSn = $(EPS_BASE) + (n * 4)
+
+@define PS_INTLEVEL "PS[0,4]"
+@define PS_EXCM "PS[4,1]"
+@define PS_UM "PS[5,1]"
+@define PS_RING "PS[6,2]"
+@define PS_OWB "PS[8,4]"
+@define PS_CALLINC "PS[12,2]"
+@define PS_WOE "PS[14,1]"
+
+
+define register offset=0xf000 size=4 contextreg;
+define context contextreg
+ loopMode=(0,0)
+ loopEnd=(1,1) noflow
+
+ #transient bits
+ phase=(31,31)
+;
+
+@if ENDIAN == "big"
+
+# little-endian -> big-endian 24-bit conversion chart
+#|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|
+#|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
+
+# Regular 24-bit instruction.
+define token insn(24)
+ # Named opcode/register fields.
+ op2 = (0,3)
+ op1 = (4,7)
+ ar = (8,11)
+ fr = (8,11)
+ br = (8,11)
+ as = (12,15)
+ fs = (12,15)
+ bs = (12,15)
+ sr = (8,15)
+ at = (16,19)
+ ft = (16,19)
+ bt = (16,19)
+ op0 = (20,23)
+
+ # Signed and unsigned immediates. Named [us]N_L.M, where u and s denote signedness, L and M the
+ # least and most significant bit of the immediate in the instruction word, and N the length
+ # (i.e. M-L+1).
+ u3_21_23 = (0,2)
+ u4_20_23 = (0,3)
+ s8_16_23 = (0,7) signed
+ u8_16_23 = (0,7)
+ u12_12_23 = (0,11)
+ s12_12_23 = (0,11) signed
+ u16_8_23 = (0,15)
+ s8_6_23 = (0,17) signed
+ u1_20 = (3,3)
+ u2_18_19 = (4,5)
+ u3_17_19 = (4,6)
+ u2_16_17 = (6,7)
+ u1_16 = (7,7)
+ u1_15_15 = (8,8)
+ u2_14_15 = (8,9)
+ u3_13_15 = (8,10)
+ u4_12_15 = (8,11)
+ m0m1_14_14 = (9,9)
+ u2_12_13 = (10,11)
+ mw_12_13 = (10,11)
+ u1_12 = (11,11)
+ u4_8_11 = (12,15)
+ u8_4_11 = (12,19)
+ s4_8_11 = (12,15) signed
+ u1_7_7 = (16,16)
+ u2_6_7 = (16,17)
+ u3_5_7 = (16,18)
+ u4_4_7 = (16,19)
+ s4_4_7 = (16,19)
+ m2m3_6_6 = (17,17)
+ u_4_23 = (0,19)
+ u2_4_5 = (18,19)
+ u1_4 = (19,19)
+;
+
+# little-endian -> big-endian 16-bit conversion chart
+#|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
+#|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
+
+# Narrow 16-bit instructions; fields are always prefixed with n_.
+define token narrowinsn(16)
+ n_ar = (0,3)
+ n_as = (4,7)
+ n_at = (8,11)
+ n_op0 = (12,15)
+
+ n_u4_12_15 = (0,3)
+ n_s4_12_15 = (0,3) signed
+ n_u4_8_11 = (4,7)
+ n_u1_7 = (8,8)
+ n_u2_6_7 = (8,9)
+ n_u4_4_7 = (8,11)
+ n_s3_4_6 = (9,11)
+ n_u2_4_5 = (10,11)
+;
+
+@else
+# Regular 24-bit instruction.
+define token insn(24)
+ # Named opcode/register fields.
+ op2 = (20,23)
+ ar = (12,15)
+ fr = (12,15)
+ br = (12,15)
+ as = (8,11)
+ fs = (8,11)
+ bs = (8,11)
+ sr = (8,15)
+ at = (4,7)
+ ft = (4,7)
+ bt = (4,7)
+ op1 = (16,19)
+ op0 = (0,3)
+
+ # Signed and unsigned immediates. Named [us]N_L_M, where u and s denote signedness, L and M the
+ # least and most significant bit of the immediate in the instruction word, and N the length
+ # (i.e. M-L+1).
+ u3_21_23 = (21,23)
+ u4_20_23 = (20,23)
+ s8_16_23 = (16,23) signed
+ u8_16_23 = (16,23)
+ u12_12_23 = (12,23)
+ s12_12_23 = (12,23) signed
+ u16_8_23 = (8,23)
+ s8_6_23 = (6,23) signed
+ u1_20 = (20,20)
+ u2_18_19 = (18,19)
+ u3_17_19 = (17,19)
+ u2_16_17 = (16,17)
+ u1_16 = (16,16)
+ u1_15_15 = (15,15)
+ u2_14_15 = (14,15)
+ u3_13_15 = (13,15)
+ u4_12_15 = (12,15)
+ m0m1_14_14 = (14,14)
+ u2_12_13 = (12,13)
+ mw_12_13 = (12,13)
+ u1_12 = (12,12)
+ u4_8_11 = (8,11)
+ u8_4_11 = (4,11)
+ s4_8_11 = (8,11) signed
+ u1_7_7 = (7,7)
+ u2_6_7 = (6,7)
+ u3_5_7 = (5,7)
+ u4_4_7 = (4,7)
+ s4_4_7 = (4,7)
+ m2m3_6_6 = (6,6)
+ u_4_23 = (4,23)
+ u2_4_5 = (4,5)
+ u1_4 = (4,4)
+;
+
+# Narrow 16-bit instructions; fields are always prefixed with n_.
+define token narrowinsn(16)
+ n_ar = (12,15)
+ n_as = (8,11)
+ n_at = (4,7)
+ n_op0 = (0, 3)
+
+ n_u4_12_15 = (12,15)
+ n_s4_12_15 = (12,15) signed
+ n_u4_8_11 = (8,11)
+ n_u1_7 = (7,7)
+ n_u2_6_7 = (6,7)
+ n_u4_4_7 = (4,7)
+ n_s3_4_6 = (4,6)
+ n_u2_4_5 = (4,5)
+;
+
+@endif
+
+attach variables [ sr ] [
+# 0x...0 0x...4 0x...8 0x...c
+ LBEG LEND LCOUNT SAR # 0x0_
+ BR LITBASE _ _ # 0x1_
+ _ _ _ _ # 0x2_
+ SCOMPARE1 _ _ _ # 0x3_
+ ACCLO ACCHI _ _ # 0x4_
+ _ _ _ _ # 0x5_
+ _ _ _ _ # 0x6_
+ _ _ _ _ # 0x7_
+ M0 M1 M2 M3 # 0x8_
+ _ _ _ _ # 0x9_
+ _ _ _ _ # 0xa_
+ _ _ _ _ # 0xb_
+ _ _ _ _ # 0xc_
+ _ _ _ _ # 0xd_
+ _ _ _ _ # 0xe_
+ _ _ _ _ # 0xf_
+# 0x...0 0x...4 0x...8 0x...c
+ _ _ _ _ # 0x10_
+ _ _ _ _ # 0x11_
+ WindowBase WindowStart _ _ # 0x12_
+ _ _ _ _ # 0x13_
+ _ _ _ PTEVADDR # 0x14_
+ _ _ _ _ # 0x15_
+ _ MMID RASID ITLBCFG # 0x16_
+ DTLBCFG _ _ _ # 0x17_
+ IBREAKENABLE MEMCTL CACHEATTR ATOMCTL # 0x18_
+ _ _ _ _ # 0x19_
+ DDR _ MEPC MEPS # 0x1a_
+ MESAVE MESR MECR MEVADDR # 0x1b_
+ _ _ _ _ # 0x1c_
+ _ _ _ _ # 0x1d_
+ _ _ _ _ # 0x1e_
+ _ _ _ _ # 0x1f_
+# 0x...0 0x...4 0x...8 0x...c
+ IBREAKA0 IBREAKA1 _ _ # 0x20_
+ _ _ _ _ # 0x21_
+ _ _ _ _ # 0x22_
+ _ _ _ _ # 0x23_
+ DBREAKA0 DBREAKA1 _ _ # 0x24_
+ _ _ _ _ # 0x25_
+ _ _ _ _ # 0x26_
+ _ _ _ _ # 0x27_
+ DBREAKC0 DBREAKC1 _ _ # 0x28_
+ _ _ _ _ # 0x29_
+ _ _ _ _ # 0x2a_
+ _ _ _ _ # 0x2b_
+ _ EPC1 EPC2 EPC3 # 0x2c_
+ EPC4 EPC5 EPC6 EPC7 # 0x2d_
+ _ _ _ _ # 0x2e_
+ _ _ _ _ # 0x2f_
+# 0x...0 0x...4 0x...8 0x...c
+ DEPC _ EPS2 EPS3 # 0x30_
+ EPS4 EPS5 EPS6 EPS7 # 0x31_
+ _ _ _ _ # 0x32_
+ _ _ _ _ # 0x33_
+ _ EXCSAVE1 EXCSAVE2 EXCSAVE3 # 0x34_
+ EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 # 0x35_
+ _ _ _ _ # 0x36_
+ _ _ _ _ # 0x37_
+ CPENABLE INTERRUPT INTSET INTCLEAR # 0x38_
+ INTENABLE _ PS VECBASE # 0x39_
+ EXCCAUSE DEBUGCAUSE CCOUNT PRID # 0x3a_
+ ICOUNT ICOUNTLEVEL EXCVADDR _ # 0x3b_
+ CCOMPARE0 CCOMPARE1 CCOMPARE2 _ # 0x3c_
+ MISC0 MISC1 MISC2 MISC3 # 0x3d_
+ _ _ _ _ # 0x3e_
+ _ _ _ _ # 0x3f_
+# 0x...0 0x...4 0x...8 0x...c
+];
+
+attach variables [ ar as at n_ar n_as n_at ] [
+ a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
+];
+
+attach variables [ fr fs ft ] [
+ f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
+];
+
+attach variables [ br bs bt ] [
+ b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
+];
+
+# Various 32-bit pointers relative to PC. Any operands that are split across non-consecutive
+# bits are named foo_LL.LM_ML.MM, where LL is the least significant bits of the least
+# singificant operand half, LM the most significant bits of the least significant operand half, etc.
+
+attach variables [ mw_12_13 ] [
+ M0 M1 M2 M3
+];
+
+attach variables [ m2m3_6_6 ] [
+ M2 M3
+];
+
+attach variables [ m0m1_14_14 ] [
+ M0 M1
+];
+
+
+#implemented pcodeops
+define pcodeop breakpoint;
+define pcodeop dhi;
+define pcodeop dhu;
+define pcodeop dhwb;
+define pcodeop dhwbi;
+define pcodeop dii;
+define pcodeop diu;
+define pcodeop diwb;
+define pcodeop diwbi;
+define pcodeop dpfl;
+define pcodeop dpfr;
+define pcodeop dpfro;
+define pcodeop dpfw;
+define pcodeop dpfwo;
+define pcodeop dsync;
+define pcodeop esync;
+define pcodeop excw;
+define pcodeop extw;
+define pcodeop idtlb;
+define pcodeop ihi;
+define pcodeop ihu;
+define pcodeop iii;
+define pcodeop iitlb;
+define pcodeop iiu;
+define pcodeop ill;
+define pcodeop ipf;
+define pcodeop ipfl;
+define pcodeop isync;
+define pcodeop acquire;
+define pcodeop ldct;
+define pcodeop lict;
+define pcodeop licw;
+define pcodeop memw;
+define pcodeop nsa;
+define pcodeop nsau;
+define pcodeop pdtlb;
+define pcodeop pitlb;
+define pcodeop rdtlb0;
+define pcodeop rdtlb1;
+define pcodeop rer;
+define pcodeop restore4;
+define pcodeop restore8;
+define pcodeop restore12;
+define pcodeop rfdd;
+define pcodeop rfde;
+define pcodeop rfdo;
+define pcodeop rfe;
+define pcodeop rfi;
+define pcodeop rfme;
+define pcodeop rfue;
+define pcodeop rfwo;
+define pcodeop rfwu;
+define pcodeop ritlb0;
+define pcodeop ritlb1;
+define pcodeop rsil;
+define pcodeop rsr;
+define pcodeop rsync;
+define pcodeop rur;
+define pcodeop s32c1i;
+define pcodeop release;
+define pcodeop restoreRegWindow;
+define pcodeop rotateRegWindow;
+define pcodeop sdct;
+define pcodeop sict;
+define pcodeop sicw;
+define pcodeop simcall;
+define pcodeop syscall;
+define pcodeop swap4;
+define pcodeop swap8;
+define pcodeop swap12;
+define pcodeop waiti;
+define pcodeop wdtlb;
+define pcodeop wer;
+define pcodeop witlb;
+define pcodeop wsr;
+define pcodeop wur;
+define pcodeop xsr;
+
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensaInstructions.sinc b/Ghidra/Processors/Xtensa/data/languages/xtensaInstructions.sinc
index 027733a3bc..8ef5613bcf 100644
--- a/Ghidra/Processors/Xtensa/data/languages/xtensaInstructions.sinc
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensaInstructions.sinc
@@ -1,162 +1,172 @@
+
+
# ABS - Absolute Value (RRR), pg. 246.
:abs ar, at is op2 = 0b0110 & op1 = 0 & ar & as = 0b0001 & at & op0 = 0 {
- ar = at;
- if (ar s> 0)
- goto inst_next;
- ar = -ar;
+ ar = at;
+ if (ar s> 0)
+ goto inst_next;
+ ar = -ar;
}
# ABS.S - Absolute Single Value (RRR), pg. 247.
:abs.s fr, fs is op2 = 0b1111 & op1 = 0b1010 & fr & fs & at = 0b0001 & op0 = 0b0000 {
- fr = abs(fs);
+ fr = abs(fs);
}
# ADD - Add (RRR), pg. 248.
:add ar, as, at is op2 = 0b1000 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = as + at;
+ ar = as + at;
}
# ADD.N - Narrow Add (RRRN), pg. 249.
:add.n n_ar, n_as, n_at is n_ar & n_as & n_at & n_op0 = 0b1010 {
- n_ar = n_as + n_at;
+ n_ar = n_as + n_at;
}
# ADD.S - Add Single (RRR), pg. 250.
:add.s fr, fs, ft is op2 = 0 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
- fr = fs f+ ft;
+ fr = fs f+ ft;
}
# ADDI - Add Immediate (RRI8), pg. 251.
:addi at, as, s8_16_23 is s8_16_23 & ar = 0b1100 & as & at & op0 = 0b0010 {
- at = as + s8_16_23;
+ at = as + s8_16_23;
}
# ADDI.N - Narrow Add Immediate (RRRN), pg. 252.
:addi.n n_ar, n_as, n_s4_4_7_nozero is n_ar & n_as & n_s4_4_7_nozero & n_op0 = 0b1011 {
- n_ar = n_as + n_s4_4_7_nozero;
+ n_ar = n_as + n_s4_4_7_nozero;
}
# ADDMI - Add Immediate with Shift by 8, pg. 253.
:addmi at, as, s16_16_23_sb8 is s16_16_23_sb8 & ar = 0b1101 & as & at & op0 = 0b0010 {
- at = as + sext(s16_16_23_sb8);
+ at = as + s16_16_23_sb8;
}
# ADDX2 - Add with Shift by 1, pg. 254.
:addx2 ar, as, at is op2 = 0b1001 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = (as << 1) + at;
+ ar = (as << 1) + at;
}
# ADDX4 - Add with Shift by 2, pg. 255.
:addx4 ar, as, at is op2 = 0b1010 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = (as << 2) + at;
+ ar = (as << 2) + at;
}
# ADDX8 - Add with Shift by 4, pg. 256.
:addx8 ar, as, at is op2 = 0b1011 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = (as << 3) + at;
+ ar = (as << 3) + at;
}
# ALL4 - All 4 Booleans True, pg. 257.
:all4 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1001 & bs & bt & op0 = 0 {
- local b = *[register]:1 &:4 bs+1;
- local c = *[register]:1 &:4 bs+2;
- local d = *[register]:1 &:4 bs+3;
- bt = bs && b && c && d;
+ local b = *[register]:1 &:4 bs+1;
+ local c = *[register]:1 &:4 bs+2;
+ local d = *[register]:1 &:4 bs+3;
+ bt = bs && b && c && d;
}
# ALL8 - All 8 Booleans True, pg. 258.
:all8 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1011 & bs & bt & op0 = 0 {
- local b = *[register]:1 &:4 bs+1;
- local c = *[register]:1 &:4 bs+2;
- local d = *[register]:1 &:4 bs+3;
- local e = *[register]:1 &:4 bs+4;
- local f = *[register]:1 &:4 bs+5;
- local g = *[register]:1 &:4 bs+6;
- local h = *[register]:1 &:4 bs+7;
- bt = bs && b && c && d && e && f && g && h;
+ local b = *[register]:1 &:4 bs+1;
+ local c = *[register]:1 &:4 bs+2;
+ local d = *[register]:1 &:4 bs+3;
+ local e = *[register]:1 &:4 bs+4;
+ local f = *[register]:1 &:4 bs+5;
+ local g = *[register]:1 &:4 bs+6;
+ local h = *[register]:1 &:4 bs+7;
+ bt = bs && b && c && d && e && f && g && h;
}
# AND - Bitwise Logical And, pg. 259.
:and ar, as, at is op2 = 0b0001 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = as & at;
+ ar = as & at;
}
# ANDB - Boolean And, pg. 260.
:andb br, bs, bt is op2 = 0 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
- br = bs && bt;
+ br = bs && bt;
}
# ANDBC - Boolean And with Complement, pg. 261.
:andbc br, bs, bt is op2 = 0b0001 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
- br = bs && !bt;
+ br = bs && !bt;
}
# ANY4 - Any 4 Booleans True, pg. 262.
:any4 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1000 & bs & bt & op0 = 0 {
- local b = *[register]:1 &:4 bs+1;
- local c = *[register]:1 &:4 bs+2;
- local d = *[register]:1 &:4 bs+3;
- bt = bs || b || c || d;
+ local b = *[register]:1 &:4 bs+1;
+ local c = *[register]:1 &:4 bs+2;
+ local d = *[register]:1 &:4 bs+3;
+ bt = bs || b || c || d;
}
# ANY8 - Any 8 Booleans True, pg. 263.
:any8 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1010 & bs & bt & op0 = 0 {
- local b = *[register]:1 &:4 bs+1;
- local c = *[register]:1 &:4 bs+2;
- local d = *[register]:1 &:4 bs+3;
- local e = *[register]:1 &:4 bs+4;
- local f = *[register]:1 &:4 bs+5;
- local g = *[register]:1 &:4 bs+6;
- local h = *[register]:1 &:4 bs+7;
- bt = bs || b || c || d || e || f || g || h;
+ local b = *[register]:1 &:4 bs+1;
+ local c = *[register]:1 &:4 bs+2;
+ local d = *[register]:1 &:4 bs+3;
+ local e = *[register]:1 &:4 bs+4;
+ local f = *[register]:1 &:4 bs+5;
+ local g = *[register]:1 &:4 bs+6;
+ local h = *[register]:1 &:4 bs+7;
+ bt = bs || b || c || d || e || f || g || h;
}
# BALL - Branch if All Bits Set, pg. 264.
:ball srel_16_23, as, at is srel_16_23 & ar = 0b0100 & as & at & op0 = 0b0111 {
- if ((~as & at) == 0)
- goto srel_16_23;
+ local test:4 = ~as & at;
+ if (test == 0) goto srel_16_23;
}
# BANY - Branch if Any Bit Set, pg. 265.
:bany srel_16_23, as, at, is srel_16_23 & ar = 0b1000 & as & at & op0 = 0b0111 {
- if ((as & at) != 0)
- goto srel_16_23;
+ local test:4 = as & at;
+ if (test == 0) goto srel_16_23;
}
-macro extract_bit(val, bit, result) {
- result = (val >> bit)&1;
+macro extract_bit(bit, result) {
+@if ENDIAN == "big"
+ result = 0x80000000 >> bit;
+@else
+ result = 0x1 << bit;
+@endif
}
# BBC - Branch if Bit Clear, pg. 266.
:bbc as, at, srel_16_23 is srel_16_23 & ar = 0b0101 & as & at & op0 = 0b0111 {
- local bval;
- extract_bit(as, at[0,5], bval);
- if (bval == 0)
- goto srel_16_23;
+ local bval:4 = 0;
+ extract_bit(at[0,5], bval);
+ bval = as & bval;
+ if (bval == 0)
+ goto srel_16_23;
}
# BBCI - Branch if Bit Clear immediate, pg. 267
:bbci as, u5_4_7_12, srel_16_23 is srel_16_23 & u3_13_15 = 0b011 & as & u5_4_7_12 & op0 = 0b0111 {
- local bval;
- extract_bit(as, u5_4_7_12, bval);
- if (bval == 0)
- goto srel_16_23;
+ local bval;
+ extract_bit(u5_4_7_12, bval);
+ bval = as & bval;
+ if (bval == 0)
+ goto srel_16_23;
}
# BBS - Branch if Bit Set, pg. 269.
:bbs as, at, srel_16_23 is srel_16_23 & ar = 0b1101 & as & at & op0 = 0b0111 {
- local bval;
- extract_bit(as, at[0,5], bval);
- if (bval != 0)
- goto srel_16_23;
+ local bval;
+ extract_bit(at[0,5], bval);
+ bval = as & bval;
+ if (bval != 0)
+ goto srel_16_23;
}
# BBSI - Branch if Bit Set immediate, pg. 270.
:bbsi as, u5_4_7_12, srel_16_23 is srel_16_23 & u3_13_15 = 0b111 & as & u5_4_7_12 & op0 = 0b0111 {
- local bval;
- extract_bit(as, u5_4_7_12, bval);
- if (bval != 0)
- goto srel_16_23;
+ local bval;
+ extract_bit(u5_4_7_12, bval);
+ bval = as & bval;
+ if (bval != 0)
+ goto srel_16_23;
}
# BEQ - Branch if Equal, pg. 272.
@@ -287,12 +297,14 @@ macro extract_bit(val, bit, result) {
# BREAK - Breakpoint, pg. 293.
:break u4_8_11, u4_4_7 is op2 = 0 & op1 = 0 & ar = 0b0100 & u4_8_11 & u4_4_7 & op0 = 0 {
- breakpoint(0x001000:4, u4_8_11:1, u4_4_7:1);
+ break_inst:4 = inst_start;
+ breakpoint(0x001000:4, break_inst, u4_8_11:1, u4_4_7:1);
}
# BREAK.N - Narrow Breakpoint, pg. 295.
:break.n n_u4_8_11 is n_ar = 0b1111 & n_u4_8_11 & n_at = 0b0010 & n_op0 = 0b1101 {
- breakpoint(0x010000:4, n_u4_8_11:1, 0:1);
+ break_inst:4 = inst_start;
+ breakpoint(0x010000:4, break_inst, n_u4_8_11:1, 0:1);
}
# BT - Branch if True, pg. 296.
@@ -303,224 +315,179 @@ macro extract_bit(val, bit, result) {
# CALL0 - Non-windowed Call, pg. 297.
:call0 srel_6_23_sb2 is srel_6_23_sb2 & u2_4_5 = 0 & op0 = 0b0101 {
- #local dst = srel_6_23_sb2;
- i2 = a2;
- i3 = a3;
- i4 = a4;
- i5 = a5;
- i6 = a6;
- i7 = a7;
- a0 = inst_start + 3;
- call srel_6_23_sb2;
+ $(PS_CALLINC) = 0;
+ a0 = inst_next;
+ call srel_6_23_sb2;
}
# CALL4 - Call PC-relative, Rotate Window by 4, pg. 298.
-:call4 srel_6_23_sb2 is srel_6_23_sb2 & u2_4_5 = 0b01 & op0 = 0b0101 {
- #local dst = srel_6_23_sb2;
- i2=a6;
- i3=a7;
- i4=a8;
- i5=a9;
- a0 = inst_start + 3;
- call srel_6_23_sb2;
- a6=o2;
+:call4 srel_6_23_sb2 is srel_6_23_sb2 & Ret4 & u2_4_5 = 0b01 & op0 = 0b0101 {
+ $(PS_CALLINC) = 1;
+ a4 = Ret4;
+ swap4();
+ call srel_6_23_sb2;
+ restore4();
}
# CALL8 - Call PC-relative, Rotate Window by 8, pg. 300.
-:call8 srel_6_23_sb2 is srel_6_23_sb2 & u2_4_5 = 0b10 & op0 = 0b0101 {
- #local dst:4 =
- i2=a10;
- i3=a11;
- i4=a12;
- i5=a13;
- i6=a14;
- i7=a15;
- a0 = inst_start + 3;
- call srel_6_23_sb2;
- a10=o2;
+:call8 srel_6_23_sb2 is srel_6_23_sb2 & Ret8 & u2_4_5 = 0b10 & op0 = 0b0101 {
+ $(PS_CALLINC) = 2;
+ a8 = Ret8;
+ swap8();
+ call srel_6_23_sb2;
+ restore8();
}
# CALL12 - Call PC-relative, Rotate Window by 12, pg. 302.
-:call12 srel_6_23_sb2 is srel_6_23_sb2 & u2_4_5 = 0b11 & op0 = 0b0101 {
- #local dst = srel_6_23_sb2;
- i2=a14;
- i3=a15;
- a0 = inst_start + 3;
- call srel_6_23_sb2;
- a14=o2;
+:call12 srel_6_23_sb2 is srel_6_23_sb2 & Ret12 & u2_4_5 = 0b11 & op0 = 0b0101 {
+ $(PS_CALLINC) = 3;
+ a12 = Ret12;
+ swap12();
+ call srel_6_23_sb2;
+ restore12();
}
# CALLX0 - Non-windowed Call Register, pg. 304.
:callx0 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6_7 = 0b11 & u2_4_5 = 0 & op0 = 0 {
- local dst = as;
- i2 = a2;
- i3 = a3;
- i4 = a4;
- i5 = a5;
- i6 = a6;
- i7 = a7;
- a0 = inst_start + 3;
- call [dst];
+ $(PS_CALLINC) = 0;
+ local dst = as;
+ a0 = inst_next;
+ call [dst];
}
# CALLX4 - Call Register, Rotate Window by 4, pg. 305.
-:callx4 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6_7 = 0b11 & u2_4_5 = 0b01 & op0 = 0 {
- local dst = as;
- i2=a6;
- i3=a7;
- i4=a8;
- i5=a9;
- i6=a10;
- i7=a11;
- a0 = inst_start + 3;
- call [dst];
- a6=o2;
+:callx4 as is op2 = 0 & op1 = 0 & ar = 0 & as & Ret4 & u2_6_7 = 0b11 & u2_4_5 = 0b01 & op0 = 0 {
+ $(PS_CALLINC) = 1;
+ dest:4 = as;
+ a4 = Ret4;
+ swap4();
+ call [dest];
+ restore4();
}
# CALLX8 - Call Register, Rotate Window by 8, pg. 307.
-:callx8 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6_7 = 0b11 & u2_4_5 = 0b10 & op0 = 0 {
- local dst = as;
- i2=a10;
- i3=a11;
- i4=a12;
- i5=a13;
- i6=a14;
- i7=a15;
- a0 = inst_start + 3;
- call [dst];
- a10=o2;
+:callx8 as is op2 = 0 & op1 = 0 & ar = 0 & as & Ret8 & u2_6_7 = 0b11 & u2_4_5 = 0b10 & op0 = 0 {
+ $(PS_CALLINC) = 2;
+ dest:4 = as;
+ a8 = Ret8;
+ swap8();
+ call [dest];
+ restore8();
}
# CALLX12 - Call Register, Rotate Window by 12, pg. 308.
-:callx12 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6_7 = 0b11 & u2_4_5 = 0b11 & op0 = 0 {
- local dst = as;
- i2=a14;
- i3=a15;
- a0 = inst_start + 3;
- call [dst];
- a14=o2;
+:callx12 as is op2 = 0 & op1 = 0 & ar = 0 & as & Ret12 & u2_6_7 = 0b11 & u2_4_5 = 0b11 & op0 = 0 {
+ $(PS_CALLINC) = 3;
+ dest:4 = as;
+ a12 = Ret12;
+ swap12();
+ call [dest];
+ restore12();
}
# CEIL.S - Ceiling Single to Fixed, pg. 311.
:ceil.s ar, fs, u4_4_7 is op2 = 0b1011 & op1 = 0b1010 & ar & fs & u4_4_7 & op0 = 0 {
- local scale:4 = int2float(1:1 << u4_4_7:1);
- ar = ceil(fs f* scale);
+ local scale:4 = 1 << u4_4_7;
+ ar = ceil(fs f* int2float(scale));
}
# CLAMPS - Signed Clamp, pg. 312.
:clamps ar, as, u5_4_7_plus7 is op2 = 0b0011 & op1 = 0b0011 & ar & as & u5_4_7_plus7 & op0 = 0 {
- # ar ← min(max(as, -2^{u5_4_7_plus7}), 2^{u5_4_7_plus7}-1)
- local maxval:4 = (1 << u5_4_7_plus7) - 1;
- local minval:4 = -(1 << u5_4_7_plus7);
- if (as s< minval)
- goto ;
- if (as s> maxval)
- goto ;
-
- ar = as;
- goto inst_next;
-
-
- ar = minval;
- goto inst_next;
-
-
- ar = maxval;
- # fallthrough inst_next
+ # ar min(max(as, -2^{u5_4_7_plus7}), 2^{u5_4_7_plus7}-1)
+ local x:4 = as;
+ local clamp:4 = 1 << u5_4_7_plus7;
+ local mt:1 = (x s> (-clamp));
+ local max:4 = (zext(mt) * x) + (zext(!mt) * (-clamp));
+ mt = (x s< (clamp-1));
+ local y = (zext(mt) * max) + (zext(!mt) * (clamp-1));
}
# DHI - Data Cache Hit Invalidate, pg. 313.
:dhi as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b0110 & op0 = 0b0010 {
- dhi(as + zext(u10_16_23_sb2));
+ dhi(as + u10_16_23_sb2);
}
# DHU - Data Cache Hit Unlock, pg. 315.
-:dhu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0010 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
- dhu(as + zext(u8_20.23_sb4));
+:dhu as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0b0010 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
+ dhu(as + u8_20_23_sb4);
}
# DHWB - Data Cache Hit Writeback, pg. 317.
:dhwb as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b0100 & op0 = 0b0010 {
- dhwb(as + zext(u10_16_23_sb2));
+ dhwb(as + u10_16_23_sb2);
}
# DHWBI - Data Cache Hit Writeback Invalidate, pg. 319.
:dhwbi as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b0101 & op0 = 0b0010 {
- dhwbi(as + zext(u10_16_23_sb2));
+ dhwbi(as + u10_16_23_sb2);
}
# DII - Data Cache Index Invalidate, pg. 321.
:dii as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b0111 & op0 = 0b0010 {
- dii(as + zext(u10_16_23_sb2));
+ dii(as + u10_16_23_sb2);
}
# DIU - Data Cache Index Unlock, pg. 323.
-:diu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0011 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
- diu(as + zext(u8_20.23_sb4));
+:diu as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0b0011 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
+ diu(as + u8_20_23_sb4);
}
# DIWB - Data Cache Index Write Back, pg. 325.
-:diwb as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0100 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
- diwb(as + zext(u8_20.23_sb4));
+:diwb as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0b0100 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
+ diwb(as + u8_20_23_sb4);
}
# DIWBI - Data Cache Index Write Back Invalidate, pg. 327.
-:diwbi as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0101 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
- diwbi(as + zext(u8_20.23_sb4));
+:diwbi as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0b0101 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
+ diwbi(as + u8_20_23_sb4);
}
# DPFL - Data Cache Prefetch and Lock, pg. 329.
-:dpfl as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
- dpfl(as + zext(u8_20.23_sb4));
+:dpfl as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
+ dpfl(as + u8_20_23_sb4);
}
# DPFR - Data Cache Prefetch for Read, pg. 331.
:dpfr as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0 & op0 = 0b0010 {
- dpfr(as + zext(u10_16_23_sb2));
+ dpfr(as + u10_16_23_sb2);
}
# DPFRO - Data Cache Prefetch for Read Once, pg. 333.
:dpfro as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b0010 & op0 = 0b0010 {
- dpfro(as + zext(u10_16_23_sb2));
+ dpfro(as + u10_16_23_sb2);
}
# DPFW - Data Cache Prefetch for Write, pg. 335.
:dpfw as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b0001 & op0 = 0b0010 {
- dpfw(as + zext(u10_16_23_sb2));
+ dpfw(as + u10_16_23_sb2);
}
# DPFWO - Data Cache Prefetch for Write Once, pg. 337.
:dpfwo as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b0011 & op0 = 0b0010 {
- dpfwo(as + zext(u10_16_23_sb2));
+ dpfwo(as + u10_16_23_sb2);
}
# DSYNC - Load/Store Synchronize, pg. 339.
:dsync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b0011 & op0 = 0 {
- dsync();
+ dsync();
}
# ENTRY - Subroutine Entry, pg. 340.
:entry as, u15_12_23_sb3 is u15_12_23_sb3 & as & u2_6_7 = 0b00 & u2_4_5 = 0b11 & op0 = 0b0110 {
- local amn = sext(u15_12_23_sb3);
- a2=i2;
- a3=i3;
- a4=i4;
- a5=i5;
- a6=i6;
- a7=i7;
- #as = as + amn;
- WindowBase = amn;
- a1 = a1 - amn;
+ local callSP = a1;
+ callinc:1 = $(PS_CALLINC);
+ rotateRegWindow(callinc);
+ as = callSP - zext(u15_12_23_sb3);
}
# ESYNC - Execute Synchronize, pg. 342.
:esync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b0010 & op0 = 0 {
- esync();
+ esync();
}
# EXCW - Exception Wait, pg. 343.
:excw is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b1000 & op0 = 0 {
- excw();
+ excw();
}
# EXTUI - Extract Unsigned Immediate, pg. 344.
@@ -532,75 +499,76 @@ macro extract_bit(val, bit, result) {
# EXTW - External Wait, pg. 345.
:extw is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b1101 & op0 = 0 {
- extw();
+ extw();
}
# FLOAT.S - Convert Fixed to Single, pg. 346.
:float.s fr, as, u4_4_7 is op2 = 0b1100 & op1 = 0b1010 & fr & as & u4_4_7 & op0 = 0 {
- local f = int2float(as);
- local d = int2float(1:2 << u4_4_7:2);
- fr = d f/ f;
+ local scale:4 = 1 << u4_4_7;
+ fr = int2float(as) f/ int2float(scale);
}
# FLOOR.S - Floor Single to Fixed, pg. 347.
:floor.s ar, fs, u4_4_7 is op2 = 0b1010 & op1 = 0b1010 & ar & fs & u4_4_7 & op0 = 0 {
- local scale:4 = int2float(1:2 << u4_4_7:2);
- ar = floor(fs f* scale);
+ local scale:4 = 1 << u4_4_7;
+ ar = floor(fs f* int2float(scale));
}
# IDTLB - Invalidate Data TLB Entry, pg. 348.
:idtlb as is op2 = 0b0101 & op1 = 0 & ar = 0b1100 & as & at = 0 & op0 = 0 {
- idtlb();
+ idtlb();
}
# IHI - Instruction Cache Hit Invalidate, pg. 349.
:ihi as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b1110 & op0 = 0b0010 {
- ihi(as + zext(u10_16_23_sb2));
+ ihi(as + u10_16_23_sb2);
}
# IHU - Instruction Cache Hit Unlock, pg. 351.
-:ihu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0010 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
- ihu(as + zext(u8_20.23_sb4));
+:ihu as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0b0010 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
+ ihu(as + u8_20_23_sb4);
}
# III - Instruction Cache Index Invalidate, pg. 353.
:iii as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b1111 & op0 = 0b0010 {
- iii(as + zext(u10_16_23_sb2));
+ iii(as + u10_16_23_sb2);
}
# IITLB - Invalidate Instruction TLB Entry, pg. 355.
:iitlb as is op2 = 0b0101 & op1 = 0 & ar = 0b0100 & as & at = 0 & op0 = 0 {
- iitlb(as);
+ iitlb(as);
}
# IIU - Instruction Cache Index Unlock, pg. 356.
-:iiu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0011 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
- iiu(as + zext(u8_20.23_sb4));
+:iiu as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0b0011 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
+ iiu(as + u8_20_23_sb4);
}
# ILL - Illegal Instruction, pg. 358.
:ill is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & at = 0 & op0 = 0 {
- ill();
+ ill();
+ goto inst_start;
}
# ILL.N - Narrow Illegal Instruction, pg. 359.
:ill.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0110 & n_op0 = 0b1101 {
- ill();
+ ill();
+ goto inst_start;
}
# IPF - Instruction Cache Prefetch, pg. 360.
:ipf as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0111 & as & at = 0b1100 & op0 = 0b0010 {
- ipf(as + zext(u10_16_23_sb2));
+ ipf(as + u10_16_23_sb2);
}
# IPFL - Instruction Cache Prefetch and Lock, pg. 362.
-:ipfl as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
- ipfl(as + zext(u8_20.23_sb4));
+:ipfl as, u8_20_23_sb4 is u8_20_23_sb4 & op1 = 0 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
+ ipfl(as + u8_20_23_sb4);
}
# ISYNC - Instruction Fetch Synchronize, pg. 364.
:isync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0 & op0 = 0 {
- isync();
+ isync();
}
# J - Unconditional Jump, pg. 366.
@@ -610,31 +578,12 @@ macro extract_bit(val, bit, result) {
# J.L is a macro.
+# The manual suggests that RET is equivalent to JX A0, yet RET has bit 5 unset, JX doesn’t.
# RET (JX A0) - Non-Windowed Return, pg. 478.
:ret is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & u2_6_7 = 0b10 & u2_4_5 = 0b10 & op0 = 0 {
return [a0];
}
-# RETW - Windowed Return, pg. 480.
-:retw is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & u2_6_7 = 0b10 & u2_4_5 = 0b01 & op0 = 0 {
-# Assume call8
- o2=a2;
- a1 = a1 + WindowBase;
- return [a0];
-}
-
-# RETW.N - Narrow Windowed Return, pg. 482.
-:retw.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0001 & n_op0 = 0b1101 {
- o2=a2;
- a1 = a1 + WindowBase;
- return [a0];
-}
-
-# The manual suggests that RET is equivalent to JX A0, yet RET has bit 5 unset, JX doesn’t.
-:ret is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & u2_6_7 = 0b10 & u2_4_5 = 0b00 & op0 = 0 {
- return [a0];
-}
-
# JX - Uncoditional Jump Register, pg. 368.
:jx as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6_7 = 0b10 & u2_4_5 = 0b10 & op0 = 0 {
goto [as];
@@ -648,32 +597,38 @@ macro extract_bit(val, bit, result) {
# L16SI - Load 16-bit Signed, pg. 370.
:l16si at, as, u9_16_23_sb1 is u9_16_23_sb1 & ar = 0b1001 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u9_16_23_sb1);
+ local addr:4 = as + u9_16_23_sb1;
at = sext(*:2 addr);
}
# L16UI - Load 16-bit Unsigned, pg. 372.
:l16ui at, as, u9_16_23_sb1 is u9_16_23_sb1 & ar = 0b001 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u9_16_23_sb1);
+ local addr:4 = as + u9_16_23_sb1;
at = zext(*:2 addr);
}
# L32AI - Load 32-bit Acquire, pg. 374.
:l32ai at, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b1011 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u10_16_23_sb2);
- at = *:4 addr;
- acquire(addr);
+ local addr:4 = as + u10_16_23_sb2;
+ at = *:4 addr;
+ acquire(addr);
+}
+
+# L32E - Load 32-bit for Window Exceptions, pg. 376.
+:l32e at, as, s5_12_15_oex is op2 = 0 & op1 = 0b1001 & s5_12_15_oex & as & at & op0 = 0 {
+ ptr:4 = as + sext(s5_12_15_oex);
+ at = *:4 ptr;
}
# L32I - Load 32-bit, pg. 378.
:l32i at, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0010 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u10_16_23_sb2);
+ local addr:4 = as + u10_16_23_sb2;
at = *:4 addr;
}
# L32I.N - Narrow Load 32-bit, pg. 380.
:l32i.n n_at, n_as, n_u6_12_15_sb2 is n_u6_12_15_sb2 & n_as & n_at & n_op0 = 0b1000 {
- local addr:4 = n_as + zext(n_u6_12_15_sb2);
+ local addr:4 = n_as + n_u6_12_15_sb2;
n_at = *:4 addr;
}
@@ -684,172 +639,129 @@ macro extract_bit(val, bit, result) {
# LDCT - Load Data Cache Tag, pg. 384.
:ldct at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b1000 & as & at & op0 = 0 {
- at = ldct(as);
+ at = ldct(as);
}
# LICT - Load Instruction Cache Tag, pg. 388.
:lict at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0 & as & at & op0 = 0 {
- at = lict(as);
+ at = lict(as);
}
# LICW - Load Instruction Cache Word, pg. 390.
:licw at, as is op2 = 0b1111 & op1 = 0b0010 & ar = 0 & as & at & op0 = 0 {
- at = licw(as);
-}
-
-macro loopSetup(as, end, doit) {
- LCOUNT = as - 1;
- LBEG = inst_next;
- #LEND = end;
- if (doit) goto ;
- goto end;
-
-}
-
-# LOOP - Loop, pg. 392.
-:loop as, urel_16_23 is urel_16_23 & ar=0b1000 & as & at=0b0111 & op0=0b0110
-[loopEnd=1; globalset(urel_16_23, loopEnd);] {
- loopSetup(as, urel_16_23, 1:1);
-}
-
-# LOOPGTZ - Loop if Greater Than Zero, pg. 394.
-:loopgtz as, urel_16_23 is urel_16_23 & ar=0b1010 & as & at=0b0111 & op0=0b0110
-[loopEnd=1; globalset(urel_16_23, loopEnd);] {
- loopSetup(as, urel_16_23, as s> 0);
-}
-
-# LOOPNEZ - Loop if Not Equal Zero, pg. 396.
-:loopnez as, urel_16_23 is urel_16_23 & ar=0b1001 & as & at=0b0111 & op0=0b0110
-[loopEnd=1; globalset(urel_16_23, loopEnd);] {
- loopSetup(as, urel_16_23, as != 0);
+ at = licw(as);
}
# LSI - Load Single Immediate, pg. 398.
:lsi ft, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0 & as & ft & op0 = 0b0011 {
- local addr:4 = as + zext(u10_16_23_sb2);
- ft = *:4 addr;
+ local addr:4 = as + u10_16_23_sb2;
+ ft = *:4 addr;
}
# LSIU - Load Single Immediate with Update, pg. 400.
:lsiu ft, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b1000 & as & ft & op0 = 0b0011 {
- local addr:4 = as + zext(u10_16_23_sb2);
- ft = *:4 addr;
- as = addr;
+ local addr:4 = as + u10_16_23_sb2;
+ ft = *:4 addr;
+ as = addr;
}
# LSX - Load Single Indexed, pg. 402.
:lsx fr, as, at is op2 = 0 & op1 = 0b1000 & fr & as & at & op0 = 0 {
- local addr:4 = as+at;
- fr = *:4 addr;
+ local addr:4 = as+at;
+ fr = *:4 addr;
}
# LSXU - Load Single Indexed with Update, pg. 404.
:lsxu fr, as, at is op2 = 0b0001 & op1 = 0b1000 & fr & as & at & op0 = 0 {
- local addr:4 = as+at;
- fr = *:4 addr;
- as = addr;
+ local addr:4 = as+at;
+ fr = *:4 addr;
+ as = addr;
}
# MADD.S - Multiply and Add Single, pg. 406.
:madd.s fr, fs, ft is op2 = 0b0100 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
- fr = fr f+ (fs f* ft);
+ fr = fr f+ (fs f* ft);
}
# MAX - Maximum Value, pg. 407.
:max ar, as, at is op2 = 0b0101 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (as s> at)
- goto ;
- ar = at;
- goto inst_next;
-
- ar = as;
+ test:1 = as s< at;
+ ar = (zext(test) * at) + (zext(!test) * as);
}
# MAXU - Maximum Value Unsigned, pg. 408.
:maxu ar, as, at is op2 = 0b0111 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (as > at)
- goto ;
- ar = at;
- goto inst_next;
-
- ar = as;
+ test:1 = as < at;
+ ar = (zext(test) * at) + (zext(!test) * as);
}
# MEMW - Memory Wait, pg. 409.
:memw is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b1100 & op0 = 0 {
- memw();
+ memw();
}
# MIN - Minimum Value, pg. 410.
:min ar, as, at is op2 = 0b0100 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (as s< at)
- goto ;
- ar = at;
- goto inst_next;
-
- ar = as;
+ test:1 = as s< at;
+ ar = (zext(test) * as) + (zext(!test) * at);
}
# MINU - Minimum Value Unsigned, pg. 411.
:minu ar, as, at is op2 = 0b0110 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (as < at)
- goto ;
- ar = at;
- goto inst_next;
-
- ar = as;
+ test:1 = as < at;
+ ar = (zext(test) * as) + (zext(!test) * at);
}
# MOV.N - Narrow Move, pg. 413.
:mov.n n_at, n_as is n_ar = 0 & n_as & n_at & n_op0 = 0b1101 {
- n_at = n_as;
+ n_at = n_as;
}
# MOV.S - Move Single, pg. 414.
:mov.s fr, fs is op2 = 0b1111 & op1 = 0b1010 & fr & fs & at = 0 & op0 = 0 {
- fr = fs;
+ fr = fs;
}
# MOVEQZ - Move if Equal to Zero, pg. 415.
:moveqz ar, as, at is op2 = 0b1000 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (at != 0)
- goto inst_next;
- ar = as;
+ if (at != 0) goto ;
+ ar = as;
+
}
# MOVEQZ.S - Move Single if Equal to Zero, pg. 416.
:moveqz.s fr, fs, at is op2 = 0b1000 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
- if (at != 0)
- goto inst_next;
- fr = fs;
+ if (at != 0) goto ;
+ fr = fs;
+
}
# MOVF - Move if False, pg. 417.
:movf ar, as, bt is op2 = 0b1100 & op1 = 0b0011 & ar & as & bt & op0 = 0 {
- if (bt)
- goto inst_next;
- ar = as;
+ if (bt) goto ;
+ ar = as;
+
}
# MOVF.S - Move Single if False, pg. 418.
:movf.s fr, fs, bt is op2 = 0b1100 & op1 = 0b1011 & fr & fs & bt & op0 = 0 {
- if (bt)
- goto inst_next;
- fr = fs;
+ if (bt)goto ;
+ fr = fs;
+
}
# MOVGEZ - Move if Greater Than or Equal to Zero, pg. 419.
:movgez ar, as, at is op2 = 0b1011 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (at s< 0)
- goto inst_next;
- ar = as;
+ if (at s< 0) goto ;
+ ar = as;
+
}
# MOVGEZ.S - Move Single if Greater Than or Equal to Zero, pg. 420.
:movgez.s fr, fs, at is op2 = 0b1011 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
- if (at s< 0)
- goto inst_next;
- fr = fs;
+ if (at s< 0) goto ;
+ fr = fs;
+
}
# MOVI - Move Immediate, pg. 421.
@@ -858,7 +770,6 @@ macro loopSetup(as, end, doit) {
at = val;
}
-
# MOVI.N - Narrow Move Immediate, pg. 422.
:movi.n n_as, n_s8_12_15_4_6_asymm is n_s8_12_15_4_6_asymm & n_as & n_u1_7 = 0 & n_op0 = 0b1100 {
local val:4 = sext(n_s8_12_15_4_6_asymm);
@@ -867,95 +778,100 @@ macro loopSetup(as, end, doit) {
# MOVLTZ - Move if Less Than Zero, pg. 423.
:movltz ar, as, at is op2 = 0b1010 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (at s>= 0)
- goto inst_next;
- ar = as;
+ if (at s>= 0) goto ;
+ ar = as;
+
}
# MOVLTZ.S - Move Single if Less Than Zero, pg. 424.
:movltz.s fr, fs, at is op2 = 0b1010 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
- if (at s>= 0)
- goto inst_next;
- fr = fs;
+ if (at s>= 0) goto ;
+ fr = fs;
+
}
# MOVNEZ - Move if Not Equal to Zero, pg. 425.
:movnez ar, as, at is op2 = 0b1001 & op1 = 0b0011 & ar & as & at & op0 = 0 {
- if (at == 0)
- goto inst_next;
- ar = as;
+ if (at == 0) goto ;
+ ar = as;
+
}
# MOVNEZ.S - Move Single if Not Equal to Zero, pg. 426.
:movnez.s fr, fs, at is op2 = 0b1001 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
- if (at == 0)
- goto inst_next;
- fr = fs;
+ if (at == 0) goto ;
+ fr = fs;
+
+}
+
+# MOVSP - Move to Stack Pointer, pg. 427.
+:movsp at, as is op2 = 0 & op1 = 0 & ar = 0b0001 & as & at & op0 = 0 {
+ at = (zext(WindowStart == 0) * at) + (zext(WindowStart != 0) * as);
}
# MOVT - Move if True, pg. 428.
:movt ar, as, bt is op2 = 0b1101 & op1 = 0b0011 & ar & as & bt & op0 = 0 {
- if (!bt)
- goto inst_next;
- ar = as;
+ if (!bt) goto ;
+ ar = as;
+
}
# MOVT.S - Move Single if True, pg. 429.
:movt.s fr, fs, bt is op2 = 0b1101 & op1 = 0b1011 & fr & fs & bt & op0 = 0 {
- if (!bt)
- goto inst_next;
- fr = fs;
+ if (!bt) goto ;
+ fr = fs;
+
}
# MSUB.S - Multiply and Subtract Single, pg. 430.
:msub.s fr, fs, ft is op2 = 0b0101 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
- fr = fr f- (fs f* ft);
+ fr = fr f- (fs f* ft);
}
# MUL.S - Multiply Single, pg. 435.
:mul.s fr, fs, ft is op2 = 0b0010 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
- fr = fs f* ft;
+ fr = fs f* ft;
}
# MUL16S - Multiply 16-bit Signed, pg. 436.
:mul16s ar, as, at is op2 = 0b1101 & op1 = 0b0001 & ar & as & at & op0 = 0 {
- ar = sext(as:2) * sext(at:2);
+ ar = sext(as:2) * sext(at:2);
}
# MUL16U - Multiply 16-bit Unsigned, pg. 437.
:mul16u ar, as, at is op2 = 0b1100 & op1 = 0b0001 & ar & as & at & op0 = 0 {
- ar = zext(as:2) * zext(at:2);
+ ar = zext(as:2) * zext(at:2);
}
# MULL - Multiply Low, pg. 450.
:mull ar, as, at is op2 = 0b1000 & op1 = 0b0010 & ar & as & at & op0 = 0 {
- ar = as * at;
+ ar = as * at;
}
# MULSH - Multiply Signed High, pg. 455.
:mulsh ar, as, at is op2 = 0b1011 & op1 = 0b0010 & ar & as & at & op0 = 0 {
- local s64:8 = sext(as);
- local t64:8 = sext(at);
- local p:8 = (s64 * t64);
- ar = p(4);
+ local s64:8 = sext(as);
+ local t64:8 = sext(at);
+ local p:8 = (s64 * t64);
+ ar = p(4);
}
# MULUH - Multiply Unsigned High, pg. 456.
:muluh ar, as, at is op2 = 0b1010 & op1 = 0b0010 & ar & as & at & op0 = 0 {
- local s64:8 = zext(as);
- local t64:8 = zext(at);
- local p:8 = (s64 * t64);
- ar = p(4);
+ local s64:8 = zext(as);
+ local t64:8 = zext(at);
+ local p:8 = (s64 * t64);
+ ar = p(4);
}
# NEG - Negate, pg. 457.
:neg ar, at is op2 = 0b0110 & op1 = 0 & ar & as = 0 & at & op0 = 0 {
- ar = -at;
+ ar = -at;
}
# NEG.S - Negate Single, pg. 458.
:neg.s fr, fs is op2 = 0b1111 & op1 = 0b1010 & fr & fs & at = 0b0110 & op0 = 0 {
- fr = f- fs;
+ fr = 0 f- fs;
}
# NOP - No Operation, pg. 459.
@@ -976,88 +892,103 @@ macro loopSetup(as, end, doit) {
# OEQ.S - Compare Single Equal, pg. 463.
:oeq.s br, fs, ft is op2 = 0b0010 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
- br = !nan(fs) && !nan(ft) && fs f== ft;
+ br = !nan(fs) && !nan(ft) && fs f== ft;
}
# OLE.S - Compare Single Ordered and Less Than or Equal, pg. 464
:ole.s br, fs, ft is op2 = 0b0110 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
- br = !nan(fs) && !nan(ft) && fs f<= ft;
+ br = !nan(fs) && !nan(ft) && fs f<= ft;
}
# OLT.S - Compare Single Ordered and Less Than, pg. 465.
:olt.s br, fs, ft is op2 = 0b0100 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
- br = !nan(fs) && !nan(ft) && fs f< ft;
+ br = !nan(fs) && !nan(ft) && fs f< ft;
}
# MOV - Move, pg. 412. Special case of OR as, at, at.
:mov ar, as is op2 = 0b0010 & op1 = 0 & ar & as & as = at & op0 = 0 {
- ar = as;
+ ar = as;
}
# OR - Bitwise Logical Or, pg. 466.
:or ar, as, at is op2 = 0b0010 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = as | at;
+ ar = as | at;
}
# ORB - Boolean Or, pg. 467.
:orb br, bs, bt is op2 = 0b0010 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
- br = bs || bt;
+ br = bs || bt;
}
# ORBC - Boolean Or with Complement, pg. 468.
:orbc br, bs, bt is op2 = 0b0011 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
- br = bs || !bt;
+ br = bs || !bt;
}
# PDTLB - Probe Data TLB, pg. 469.
:pdtlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1101 & as & at & op0 = 0 {
- at = pdtlb(as);
+ at = pdtlb(as);
}
# PITLB - Probe Instruction TLB, pg. 470.
:pitlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0101 & as & at & op0 = 0 {
- at = pitlb(as);
+ at = pitlb(as);
}
# QUOS - Quotient Signed, pg. 471.
:quos ar, as, at is op2 = 0b1101 & op1 = 0b0010 & ar & as & at & op0 = 0 {
- ar = as s/ at;
+ ar = as s/ at;
}
# QUOU - Quotient Unsigned, pg. 472.
:quou ar, as, at is op2 = 0b1100 & op1 = 0b0010 & ar & as & at & op0 = 0 {
- ar = as / at;
+ ar = as / at;
}
# RDTLB0 - Read Data TLB Virtual Entry, pg. 473.
:rdtlb0 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1011 & as & at & op0 = 0 {
- at = rdtlb0(as);
+ at = rdtlb0(as);
}
# RDTLB1 - Read Data TLB Entry Translation, pg. 474.
:rdtlb1 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1111 & as & at & op0 = 0 {
- at = rdtlb1(as);
+ at = rdtlb1(as);
}
# REMS - Remainder Signed, pg. 475.
:rems ar, as, at, is op2 = 0b1111 & op1 = 0b0010 & ar & as & at & op0 = 0 {
- ar = as s% at;
+ ar = as s% at;
}
# REMU - Remainder Unsigned, pg. 476.
:remu ar, as, at, is op2 = 0b1110 & op1 = 0b0010 & ar & as & at & op0 = 0 {
- ar = as % at;
+ ar = as % at;
}
# RER - Read External Register, pg. 477.
:rer as, at is op2 = 0b0100 & op1 = 0 & ar = 0b0110 & as & at & op0 = 0 {
- as = rer(at);
+ as = rer(at);
}
# RET.N - Narrow Non-Windowed Return, pg. 479.
:ret.n is n_ar = 0b1111 & n_as = 0 & n_at = 0 & n_op0 = 0b1101 {
+ o2=a2;
return [a0];
+}
+
+# RETW - Windowed Return, pg. 480.
+:retw is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & u2_6_7 = 0b10 & u2_4_5 = 0b01 & op0 = 0 {
+# Assume call8
o2=a2;
+ a1 = a1 + WindowBase;
+ return [a0];
+}
+
+# RETW.N - Narrow Windowed Return, pg. 482.
+:retw.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0001 & n_op0 = 0b1101 {
+ o2=a2;
+ a1 = a1 + WindowBase;
+ return [a0];
}
# RFDD - Return from Debug and Dispatch, pg. 484.
@@ -1084,21 +1015,25 @@ macro loopSetup(as, end, doit) {
return [tmp];
}
+rfi_epc: ptr is u4_8_11 [ ptr = $(EPC_BASE) + (4 * u4_8_11); ] { export *[register]:4 ptr; }
+rfi_eps: ptr is u4_8_11 [ ptr = $(EPS_BASE) + (4 * u4_8_11); ] { export *[register]:4 ptr; }
+
# RFI - Return from High-Priority Interrupt, pg. 488.
-:rfi u4_8_11 is op2 = 0 & op1 = 0 & ar = 0b0011 & u4_8_11 & at = 0b0001 & op0 = 0 {
- local tmp:4 = rfi(u4_8_11:1);
- return [tmp];
+:rfi u4_8_11 is op2 = 0 & op1 = 0 & ar = 0b0011 & u4_8_11 & at = 0b0001 & op0 = 0 & rfi_epc & rfi_eps {
+ PS = rfi_eps;
+ return [rfi_epc];
}
# RFME - Return from Memory Error, pg. 489.
:rfme is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0 & at = 0b0010 & op0 = 0 {
- local tmp:4 = rfme();
- return [tmp];
+ PS = MEPS;
+ MESR[0,1] = 0;
+ return [MEPC];
}
# RFR - Move FR to AR, pg. 490.
:rfr ar, fs is op2 = 0b1111 & op1 = 0b1010 & ar & fs & at = 0b0100 & op0 = 0 {
- ar = fs;
+ ar = fs;
}
# RFUE - Return from User-Mode Exception, pg. 491.
@@ -1109,24 +1044,26 @@ macro loopSetup(as, end, doit) {
# RFWO - Return from Window Overflow, pg. 492.
:rfwo is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0b0100 & at = 0 & op0 = 0 {
- local tmp:4 = rfwo();
- return [tmp];
+ $(PS_EXCM) = 0;
+ rfwo();
+ return [EPC1];
}
# RFWU - Return from Window Underflow, pg. 493.
:rfwu is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0b0101 & at = 0 & op0 = 0 {
- local tmp:4 = rfwu();
- return [tmp];
+ $(PS_EXCM) = 0;
+ rfwu();
+ return [EPC1];
}
# RITLB0 - Read Instruction TLB Virtual Entry, pg. 494.
:ritlb0 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0011 & as & at & op0 = 0 {
- at = ritlb0(as);
+ at = ritlb0(as);
}
# RITLB1 - Read Instruction TLB Entry Translation, pg. 495.
:ritlb1 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0111 & as & at & op0 = 0 {
- at = ritlb1(as);
+ at = ritlb1(as);
}
# ROTW - Rotate Window, pg. 496.
@@ -1136,8 +1073,17 @@ macro loopSetup(as, end, doit) {
# ROUND.S - Round Single to Fixed, pg. 497.
:round.s ar, fs, u4_4_7 is op2 = 0b1000 & op1 = 0b1010 & ar & fs & u4_4_7 & op0 = 0 {
- local scale:4 = int2float(1:2 << u4_4_7:2);
- ar = round(fs f* scale);
+ local scale:4 = 1 << u4_4_7;
+ local result = fs f* int2float(scale);
+ isNan:1 = nan(result);
+ if (isNan) goto ;
+ ar = round(fs f* scale);
+ goto ;
+
+ ar = 0x80000000;
+ if (fs f< 0) goto ;
+ ar = 0x7fffffff;
+
}
# RSIL - Read and Set Interrupt Level, pg. 498.
@@ -1147,20 +1093,19 @@ macro loopSetup(as, end, doit) {
# RSR - Read Special Register, pg. 500.
:rsr at, sr is op0 = 0 & op1 = 0b0011 & sr & at & op0 = 0 {
- local src:4 = zext(sr);
- at = *[register]:4 src;
+ at = rsr(sr:1);
}
# RSYNC - Register Read Synchronize, pg. 502.
:rsync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b0001 & op0 = 0 {
- rsync();
+ rsync();
}
+
# RUR - Read User Register, pg. 503.
:rur ar, u8_4_11 is op2 = 0b1110 & op1 = 0b0011 & ar & u8_4_11 & op0 = 0 {
ar = rur(u8_4_11:1);
}
-
# S8I - Store 8-bit, pg. 504.
:s8i at, as, u8_16_23 is u8_16_23 & ar = 0b0100 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u8_16_23:1);
@@ -1169,77 +1114,81 @@ macro loopSetup(as, end, doit) {
# S16I - Store 16-bit, pg. 505.
:s16i at, as, u9_16_23_sb1 is u9_16_23_sb1 & ar = 0b0101 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u9_16_23_sb1);
+ local addr:4 = as + u9_16_23_sb1;
*:2 addr = at:2;
}
# S32C1I - Store 32-bit Compare Conditional, pg. 506
:s32c1i at, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b1110 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u10_16_23_sb2);
- at = s32c1i(addr);
+ local addr:4 = as + u10_16_23_sb2;
+ old:4 = *:4 addr;
+ if (old != SCOMPARE1) goto ;
+ *:4 addr = at;
+
+ at = old;
}
# S32E - Store 32-bit for Window Exceptions, pg. 508.
:s32e at, as, s5_12_15_oex is op2 = 0b0100 & op1 = 0b1001 & s5_12_15_oex & as & at & op0 = 0 {
- #local vAddr:4 = as + s5_12_15_oex;
- #*:4 vAddr = at;
+ ptr:4 = as + sext(s5_12_15_oex);
+ *:4 ptr = at;
}
# S32I - Store 32-bit, pg. 510.
:s32i at, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0110 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u10_16_23_sb2);
+ local addr:4 = as + u10_16_23_sb2;
*:4 addr = at;
}
# S32I.N - Narrow Store 32-bit, pg. 512.
:s32i.n n_at, n_as, n_u6_12_15_sb2 is n_u6_12_15_sb2 & n_as & n_at & n_op0 = 0b1001 {
- local addr:4 = n_as + zext(n_u6_12_15_sb2);
+ local addr:4 = n_as + n_u6_12_15_sb2;
*:4 addr = n_at;
}
# S32RI - Store 32-bit Release, pg. 514.
:s32ri at, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b1111 & as & at & op0 = 0b0010 {
- local addr:4 = as + zext(u10_16_23_sb2);
- *:4 addr = at;
- release(addr);
+ local addr:4 = as + u10_16_23_sb2;
+ release(addr);
+ *:4 addr = at;
}
# SDCT - Store Data Cache Tag, pg. 516.
:sdct at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b1001 & as & at & op0 = 0 {
- sdct(as, at);
+ sdct(as, at);
}
# SEXT - Sign Extend, pg. 518.
:sext ar, as, u5_4_7_plus7 is op2 = 0b0010 & op1 = 0b0011 & ar & as & u5_4_7_plus7 & op0 = 0 {
- local shift:1 = 31:1 - u5_4_7_plus7;
- local tmp:4 = as << shift;
- ar = tmp s>> shift;
+ local shift:4 = 31 - u5_4_7_plus7;
+ local tmp:4 = as << shift;
+ ar = tmp s>> shift;
}
# SICT - Store Instruction Cache Tag, pg. 519.
:sict at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b0001 & as & at & op0 = 0 {
- sict(as, at);
+ sict(as, at);
}
# SICW - Store Instruction Cache word, pg. 521.
:sicw at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b0011 & as & at & op0 = 0 {
- sicw(as, at);
+ sicw(as, at);
}
# SIMCALL - Simulator Call, pg. 523.
:simcall is op2 = 0 & op1 = 0 & ar = 0b0101 & as = 0b0001 & at = 0 & op0 = 0 {
- simcall();
+ simcall();
}
# SLL - Shift Left Logical, pg. 524.
:sll ar, as is op2 = 0b1010 & op1 = 0b0001 & ar & as & at = 0 & op0 = 0 {
- local sa = 32 - SAR;
- ar = as << sa;
+ local sa:4 = 32 - SAR;
+ ar = as << sa;
}
# SLLI - Shift Left Logical Immediate, pg. 525.
-:slli ar, as, u5_4_7_20_slli is u3_21_23 = 0 & u5_4_7_20_slli & op1 = 0b0001 & ar & as & op0 = 0 {
- ar = as << u5_4_7_20_slli;
+:slli ar, as, u5_4_7_20 is u3_21_23 = 0 & u5_4_7_20 & op1 = 0b0001 & ar & as & op0 = 0 {
+ ar = as << u5_4_7_20;
}
# SRA - Shift Right Arithmetic, pg. 526.
@@ -1279,25 +1228,26 @@ macro loopSetup(as, end, doit) {
# SSA8L - Set Shift Amount for LE Byte Shift, pg. 532.
:ssa8l as is op2 = 0b0100 & op1 = 0 & ar = 0b0010 & as & at = 0 & op0 = 0 {
- SAR = (as&3)*8;
+ local rsa:4 = (as & 3)*8;
+ SAR = rsa;
}
# SSAI - Set Shift Amount Immediate, pg. 533.
:ssai u5_8_11_4 is op2 = 0b0100 & op1 = 0 & ar = 0b0100 & u5_8_11_4 & u3_5_7 = 0 & op0 = 0 {
- SAR = zext(u5_8_11_4);
+ SAR = u5_8_11_4;
}
# SSI - Store Single Immediate, pg. 534.
:ssi ft, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b0100 & as & ft & op0 = 0b0011 {
- local addr:4 = as + zext(u10_16_23_sb2);
- *:4 addr = ft;
+ local addr:4 = as + u10_16_23_sb2;
+ *:4 addr = ft;
}
# SSIU - Store Single Immediate with Update, pg. 536.
:ssiu ft, as, u10_16_23_sb2 is u10_16_23_sb2 & ar = 0b1100 & as & ft & op0 = 0b0011 {
- local addr:4 = as + zext(u10_16_23_sb2);
- *:4 addr = ft;
- as = addr;
+ local addr:4 = as + u10_16_23_sb2;
+ *:4 addr = ft;
+ as = addr;
}
# SSL - Set Shift Amount for Left Shift, pg. 538.
@@ -1312,81 +1262,87 @@ macro loopSetup(as, end, doit) {
# SSX - Store Single Indexed, pg. 540.
:ssx fr, as, at is op2 = 0b0100 & op1 = 0b1000 & fr & as & at & op0 = 0 {
- local addr:4 = as+at;
- *:4 addr = fr;
+ local addr:4 = as+at;
+ *:4 addr = fr;
}
# SSXU - Store Single Indexed with Update, pg. 541.
:ssxu fr, as, at is op2 = 0b0101 & op1 = 0b1000 & fr & as & at & op0 = 0 {
- local addr:4 = as+at;
- *:4 addr = fr;
- as = addr;
+ local addr:4 = as+at;
+ *:4 addr = fr;
+ as = addr;
}
# SUB - Subtract, pg. 542.
:sub ar, as, at is op2 = 0b1100 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = as - at;
+ ar = as - at;
}
# SUB.S - Subtract Single, pg. 543.
:sub.s fr, fs, ft is op2 = 0b0001 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
- fr = fs f- ft;
+ fr = fs f- ft;
}
# SUBX2 - Subtract with Shift by 1, pg. 544.
:subx2 ar, as, at is op2 = 0b1101 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = (as << 1) - at;
+ ar = (as << 1) - at;
}
# SUBX4 - Subtract with Shift by 2, pg. 545.
:subx4 ar, as, at is op2 = 0b1110 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = (as << 2) - at;
+ ar = (as << 2) - at;
}
# SUBX8 - Subtract with Shift by 3, pg. 546.
:subx8 ar, as, at is op2 = 0b1111 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = (as << 3) - at;
+ ar = (as << 3) - at;
}
# SYSCALL - System Call, pg. 547.
:syscall is op2 = 0 & op1 = 0 & ar = 0b0101 & as = 0 & at = 0 & op0 = 0 {
- syscall();
+ syscall();
}
# TRUNC.S - Truncate Single to Fixed, pg. 548
:trunc.s ar, fs, u4_4_7 is op2 = 0b1001 & op1 = 0b1010 & ar & fs & u4_4_7 & op0 = 0 {
- local scale:4 = int2float(1:2 << u4_4_7:2);
- ar = trunc(fs f* scale);
+ local scale:4 = 1 << u4_4_7;
+ local result = fs f* int2float(scale);
+ isNan:1 = nan(result);
+ if (isNan) goto ;
+ ar = trunc(fs f* scale);
+ goto ;
+
+ ar = 0x80000000;
+ if (fs f< 0) goto ;
+ ar = 0x7fffffff;
+
}
# UEQ.S - Compare Single Unordered or Equal, pg. 549.
:ueq.s br, fs, ft is op2 = 0b0011 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
- br = nan(fs) || nan(ft) || fs f== ft;
+ br = nan(fs) || nan(ft) || fs f== ft;
}
# UFLOAT.S - Convert Unsigned Fixed to Single, pg. 550.
:ufloat.s fr, as, u4_4_7 is op2 = 0b1101 & op1 = 0b1010 & fr & as & u4_4_7 & op0 = 0 {
- local tmp:8 = zext(as);
- local f = int2float(tmp);
- local d = int2float(1:2 << u4_4_7:2);
- fr = d f/ f;
+ local tmp:8 = zext(as);
+ local scale:4 = 1 << u4_4_7;
+ fr = int2float(tmp) f/ int2float(scale);
}
# ULE.S - Compare Single Unordered or Less Than or Equal, pg. 551.
:ule.s br, fs, ft is op2 = 0b0111 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
- br = nan(fs) || nan(ft) || fs f<= ft;
+ br = nan(fs) || nan(ft) || fs f<= ft;
}
# ULT.S - Compare Single Unordered or Less Than, pg. 552.
:ult.s br, fs, ft is op2 = 0b0101 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
- br = nan(fs) || nan(ft) || fs f< ft;
+ br = nan(fs) || nan(ft) || fs f< ft;
}
-# FIXME: UMUL.AA*
-
# UN.S - Compare Single Unordered, pg. 554.
:un.s br, fs, ft is op2 = 0b0001 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
- br = nan(fs) || nan(ft);
+ br = nan(fs) || nan(ft);
}
# UTRUNC.S - Truncate Single to Fixed Unsigned, pg. 555.
@@ -1406,96 +1362,558 @@ macro loopSetup(as, end, doit) {
# WDTLB - Write Data TLB Entry, pg. 557.
:wdtlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1110 & as & at & op0 = 0 {
- wdtlb(as, at);
+ wdtlb(as, at);
}
# WER - Write External Register, pg. 558.
:wer as, at is op2 = 0b0100 & op1 = 0 & ar = 0b0111 & as & at & op0 = 0 {
- wer(as, at);
+ wer(as, at);
}
# WFR - Move AR to FR, pg. 559.
:wfr fr, as is op2 = 0b1111 & op1 = 0b1010 & fr & as & at = 0b0101 & op0 = 0 {
- fr = as;
+ fr = as;
}
# WITLB - Write Instruction TLB Entry, pg. 560.
:witlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0110 & as & at & op0 = 0 {
- witlb(as, at);
+ witlb(as, at);
}
# WSR - Write Special Register, pg. 561.
:wsr at, sr is op2 = 0b0001 & op1 = 0b0011 & sr & at & op0 = 0 {
- local dst:4 = zext(sr);
- *[register]:4 dst = at;
+ wsr(sr:1, at);
}
# WUR - Write User Register, pg. 563.
-:wur at, u8_8_15 is op2 = 0b1111 & op1 = 0b0011 & u8_8_15 & at & op0 = 0 {
- wur(u8_8_15:1, at);
+:wur at, sr is op2 = 0b1111 & op1 = 0b0011 & sr & at & op0 = 0 {
+ wur(sr:1, at);
}
# XOR - Bitwise Exclusive Or, pg. 564.
:xor ar, as, at is op2 = 0b0011 & op1 = 0 & ar & as & at & op0 = 0 {
- ar = as ^ at;
+ ar = as ^ at;
}
# XORB - Boolean Exclusive Or, pg. 565.
:xorb br, bs, bt is op2 = 0b0100 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
- br = bs ^^ bt;
+ br = bs ^^ bt;
}
# XSR - Exchange Special Register, pg. 566.
-:xsr at, u8_8_15 is op2 = 0b0110 & op1 = 0b0001 & u8_8_15 & at & op0 = 0 {
- at = xsr(u8_8_15:1, at);
-}
-
-# PAD, dummy
-:pad is op0_16=0x0 {
-}
-
-# PAD, dummy
-:pad is op0_8=0x0 {
+:xsr at, sr is op2 = 0b0110 & op1 = 0b0001 & sr & at & op0 = 0 {
+ at = xsr(sr:1, at);
}
## MAC16 option ##
-# This produces correct pcode, tho it would be nicer to display the float in disasm as well
-# +0.0 +1.0 +2.0 +0.5
-const.s_imm: tmp is as=0 [ tmp = 0x00000000; ] { export *[const]:4 tmp; }
-const.s_imm: tmp is as=1 [ tmp = 0x3F800000; ] { export *[const]:4 tmp; }
-const.s_imm: tmp is as=2 [ tmp = 0x40000000; ] { export *[const]:4 tmp; }
-const.s_imm: tmp is as=3 [ tmp = 0x3F000000; ] { export *[const]:4 tmp; }
-
-:const.s fr, const.s_imm is op2=0b1111 & op1=0b1010 & fr & const.s_imm & at=0b0011 & op0=0 {
- fr = float2float(const.s_imm);
+# LDDEC - Load with Autodecrement, pg. 386.
+:lddec "MAC16_REGS[" mw_12_13 "]", as is op2 = 0b1001 & op1 = 0 & u2_14_15 = 0 & mw_12_13 & as & at = 0 & op0 = 0b0100 {
+ local ptr:4 = as - 4;
+ mw_12_13 = *:4 ptr;
+ as = ptr;
}
-# Stub out some insns which mainly appear in boilerplate library functions...
-:div0.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b0111 & op0=0 unimpl
-:sqrt0.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1001 & op0=0 unimpl
-:nexp01.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1011 & op0=0 unimpl
-:mksadj.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1100 & op0=0 unimpl
-:mkdadj.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1101 & op0=0 unimpl
-:addexp.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1110 & op0=0 unimpl
-:addexpm.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1111 & op0=0 unimpl
-:maddn.s fr, fs, ft is op2=0b0110 & op1=0b1010 & fr & fs & ft & op0=0 unimpl
-:divn.s fr, fs, ft is op2=0b0111 & op1=0b1010 & fr & fs & ft & op0=0 unimpl
-
-# UNIMPLEMENTED
-# - Windowed Register Option
-
-# L32E - Load 32-bit for Window Exceptions, pg. 376.
-:l32e at, as, s5_12_15_oex is op2 = 0 & op1 = 0b1001 & s5_12_15_oex & as & at & op0 = 0 unimpl
-
-# MOVSP - Move to Stack Pointer, pg. 427.
-:movsp at, as is op2 = 0 & op1 = 0 & ar = 0b0001 & as & at & op0 = 0 unimpl
-
-# LDDEC - Load with Autodecrement, pg. 386.
-:lddec "MAC16_REGS[" u2_12_13 "]", as is op2 = 0b1001 & op1 = 0 & u2_14_15 = 0 & u2_12_13 & as & at = 0 & op0 = 0b0100 unimpl
-
# LDINC - Load with Autoincrement, pg. 387.
-:ldinc "MAC16_REGS[" u2_12_13 "]", as is op2 = 0b1000 & op1 = 0 & u2_14_15 = 0 & u2_12_13 & as & at = 0 & op0 = 0b0100 unimpl
+:ldinc "MAC16_REGS[" mw_12_13 "]", as is op2 = 0b1000 & op1 = 0 & u2_14_15 = 0 & mw_12_13 & as & at = 0 & op0 = 0b0100 {
+ local ptr:4 = as + 4;
+ mw_12_13 = *:4 ptr;
+ as = ptr;
+}
+
+# MUL.AA.* - Signed Multiply, pg. 431.
+:mul.aa.ll as, at is op2 = 0x7 & op1 = 0x4 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+:mul.aa.hl as, at is op2 = 0x7 & op1 = 0x5 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.aa.lh as, at is op2 = 0x7 & op1 = 0x6 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.aa.hh as, at is op2 = 0x7 & op1 = 0x7 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+# MUL.AD.* - Signed Multiply, pg. 432.
+:mul.ad.ll as, m2m3_6_6 is op2 = 0x3 & op1 = 0x4 & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.ad.hl as, m2m3_6_6 is op2 = 0x3 & op1 = 0x5 & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+:mul.ad.lh as, m2m3_6_6 is op2 = 0x3 & op1 = 0x6 & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+:mul.ad.hh as, m2m3_6_6 is op2 = 0x3 & op1 = 0x7 & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+# MUL.AD.* - Signed Multiply, pg. 433.
+:mul.da.ll m0m1_14_14, at is op2 = 0x6 & at & op1 = 0x4 & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.da.hl m0m1_14_14, at is op2 = 0x6 & op1 = 0x5 & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & at & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.da.lh m0m1_14_14, at is op2 = 0x6 & op1 = 0x6 & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & at & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.da.hh m0m1_14_14, at is op2 = 0x6 & op1 = 0x7 & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & at & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+# MUL.AD.* - Signed Multiply, pg. 434.
+:mul.dd.ll m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0x4 & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.dd.hl m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0x5 & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.dd.lh m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0x6 & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
+
+:mul.dd.hh m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0x7 & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = sext(M1:2) * sext(M2:2);
+}
# MULA.AA.* - Signed Multiply, pg. 431.
-:mula.aa.* as, at is op2 = 0b0001 & u2_18_19 = 0b01 & ar = 0 & as & at & op0 = 0b0100 unimpl
+:mula.aa.ll as, at is op2 = 0x7 & op1 = 0x8 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+:mula.aa.hl as, at is op2 = 0x7 & op1 = 0x9 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.aa.lh as, at is op2 = 0x7 & op1 = 0xa & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.aa.hh as, at is op2 = 0x7 & op1 = 0xb & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.ad.ll as, m2m3_6_6 is op2 = 0x3 & op1 = 0x8 & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.ad.hl as, m2m3_6_6 is op2 = 0x3 & op1 = 0x9 & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+:mula.ad.lh as, m2m3_6_6 is op2 = 0x3 & op1 = 0xa & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+:mula.ad.hh as, m2m3_6_6 is op2 = 0x3 & op1 = 0xb & ar = 0 & as & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.da.ll m0m1_14_14, at is op2 = 0x6 & at & op1 = 0x8 & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.da.hl m0m1_14_14, at is op2 = 0x6 & op1 = 0x9 & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & at & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.da.lh m0m1_14_14, at is op2 = 0x6 & op1 = 0xa & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & at & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.da.hh m0m1_14_14, at is op2 = 0x6 & op1 = 0xb & as = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & at & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.dd.ll m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0x8 & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.dd.hl m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0x9 & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.dd.lh m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0xa & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+:mula.dd.hh m0m1_14_14, m2m3_6_6 is op2 = 0x2 & op1 = 0xb & ar = 0 & u1_15_15 = 0 & u2_12_13 = 0 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+}
+
+# Signed Mult/Accum, Ld/Autodec MULA.DA.*.LDDEC, pg. 441.
+:mula.da.ll.lddec mw_12_13, as, m0m1_14_14, at is op2 = 0x5 & at & op1 = 0x8 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.hl.lddec mw_12_13, as, m0m1_14_14, at is op2 = 0x5 & op1 = 0x9 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & at & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.lh.lddec mw_12_13, as, m0m1_14_14, at is op2 = 0x5 & op1 = 0xa & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & at & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.hh.lddec mw_12_13, as, m0m1_14_14, at is op2 = 0x5 & op1 = 0xb & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & at & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+# Signed Mult/Accum, Ld/Autoinc MULA.DA.*.LDINC, pg. 443.
+:mula.da.ll.ldinc mw_12_13, as, m0m1_14_14, at is op2 = 0x4 & at & op1 = 0x8 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.hl.ldinc mw_12_13, as, m0m1_14_14, at is op2 = 0x4 & op1 = 0x9 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & at & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.lh.ldinc mw_12_13, as, m0m1_14_14, at is op2 = 0x4 & op1 = 0xa & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & at & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.hh.ldinc mw_12_13, as, m0m1_14_14, at is op2 = 0x4 & op1 = 0xb & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & at & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+# Signed Mult/Accum, Ld/Autodec MULA.DD.*.LDDEC, pg. 446.
+:mula.dd.ll.lddec mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x1 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op1 = 0x8 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.dd.hl.lddec mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x1 & op1 = 0x9 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.dd.lh.lddec mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x1 & op1 = 0xa & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.dd.hh.lddec mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x1 & op1 = 0xb & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ local vaddr:4 = as - 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+# Signed Mult/Accum, Ld/Autoinc MULA.DD.*.LDINC, pg. 448.
+:mula.da.ll.ldinc mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x0 & op1 = 0x8 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.hl.ldinc mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x0 & op1 = 0x9 & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14:2;
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.lh.ldinc mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x0 & op1 = 0xa & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+:mula.da.hh.ldinc mw_12_13, as, m0m1_14_14, m2m3_6_6 is op2 = 0x0 & op1 = 0xb & as & u1_15_15 = 0 & mw_12_13 & m0m1_14_14 & u1_7_7 = 0 & u2_4_5 = 0 & m2m3_6_6 & op0 = 0x4 {
+ local vaddr:4 = as + 4;
+ tm1:2 = m0m1_14_14(2);
+ tm2:2 = m2m3_6_6(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = ACC + (sext(M1:2) * sext(M2:2));
+ as = vaddr;
+ mw_12_13 = *:4 vaddr;
+}
+
+# UMUL.AA.* - Unsigned Multiply, pg. 553.
+:umul.aa.ll as, at is op2 = 0x7 & op1 = 0x0 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = zext(M1:2) * zext(M2:2);
+}
+:umul.aa.hl as, at is op2 = 0x7 & op1 = 0x1 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = at:2;
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = zext(M1:2) * zext(M2:2);
+}
+
+:umul.aa.lh as, at is op2 = 0x7 & op1 = 0x2 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as:2;
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = zext(M1:2) * zext(M2:2);
+}
+
+:umul.aa.hh as, at is op2 = 0x7 & op1 = 0x3 & ar = 0 & as & at & op0 = 0x4 {
+ tm1:2 = as(2);
+ tm2:2 = at(2);
+ M1 = zext(tm1);
+ M2 = zext(tm2);
+ ACC = zext(M1:2) * zext(M2:2);
+}
+
+## Loop Option ##
+
+LoopOffset8: loc is u8_16_23 [ loc = inst_start + u8_16_23 + 4; ] { export *:4 loc; }
+
+# LOOP - Loop, pg. 392.
+:loop as, LoopOffset8 is LoopOffset8 & ar = 8 & as & at = 0b0111 & op0 = 6
+ [ loopMode=1; loopEnd = 1; globalset(LoopOffset8, loopEnd); ] {
+ LCOUNT = as - 1;
+ LBEG = inst_next;
+ LEND = &LoopOffset8;
+}
+
+# LOOPGTZ - Loop if Greater Than Zero, pg. 394.
+:loopgtz as, LoopOffset8 is LoopOffset8 & ar = 0b1010 & as & at = 0b0111 & op0 = 0b0110
+ [ loopMode=1; loopEnd = 1; globalset(LoopOffset8, loopEnd); ] {
+ LCOUNT = as - 1;
+ LBEG = inst_next;
+ LEND = &LoopOffset8;
+ if (as s<= 0) goto LoopOffset8;
+}
+
+# LOOPNEZ - Loop if Not Equal Zero, pg. 396.
+:loopnez as, LoopOffset8 is LoopOffset8 & ar = 0b1001 & as & at = 0b0111 & op0 = 0b0110
+ [ loopMode=1; loopEnd = 1; globalset(LoopOffset8, loopEnd); ] {
+ LCOUNT = as - 1;
+ LBEG = inst_next;
+ LEND = &LoopOffset8;
+ if (as == 0) goto LoopOffset8;
+}
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensaMain.sinc b/Ghidra/Processors/Xtensa/data/languages/xtensaMain.sinc
new file mode 100644
index 0000000000..dd13ae72fb
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensaMain.sinc
@@ -0,0 +1,116 @@
+# Various 32-bit pointers relative to PC. Any operands that are split across non-consecutive
+# bits are named foo_LL_LM_ML_MM, where LL is the least significant bits of the least
+# singificant operand half, LM the most significant bits of the least significant operand half, etc.
+
+srel_16_23: rel is s8_16_23 [ rel = inst_start + s8_16_23 + 4; ] { export *:4 rel; }
+
+srel_12_23: rel is s12_12_23 [ rel = inst_start + s12_12_23 + 4; ] { export *:4 rel; }
+
+srel_6_23: rel is s8_6_23 [ rel = inst_start + s8_6_23 + 4; ] { export *:4 rel; }
+
+urel_12_15_4_5: rel is n_u2_4_5 & n_u4_12_15 [
+ rel = inst_start + ((n_u2_4_5 << 4) | n_u4_12_15) + 4;
+] { export *:4 rel; }
+
+srel_6_23_sb2: rel is s8_6_23 [
+ rel = (inst_start & ~3) + ( s8_6_23 << 2 ) + 4;
+] { export *:4 rel; }
+
+srel_8_23_oex_sb2: rel is u16_8_23 [
+ rel = ((inst_start + 3) & ~3) + ((u16_8_23 | 0xffff0000) << 2);
+] { export *:4 rel; }
+
+# Immediates split across the instruction.
+u5_8_11_20: tmp is u1_20 & u4_8_11 [ tmp = (u1_20 << 4) | u4_8_11; ] { export *[const]:4 tmp; }
+u5_4_7_20: tmp is u1_20 & u4_4_7 [ tmp = 32 - ((u1_20 << 4) | u4_4_7); ] { export *[const]:4 tmp; }
+u5_8_11_16: tmp is u1_16 & u4_8_11 [ tmp = (u1_16 << 4) | u4_8_11; ] { export *[const]:4 tmp; }
+u5_4_7_12: tmp is u1_12 & u4_4_7 [ tmp = (u1_12 << 4) | u4_4_7; ] { export *[const]:4 tmp; }
+u5_8_11_4: tmp is u1_4 & u4_8_11 [ tmp = (u1_4 << 4) | u4_8_11; ] { export *[const]:4 tmp; }
+
+# Signed 12-bit (extended to 16) immediate, used by MOVI.
+s16_16_23_8_11: tmp is s4_8_11 & u8_16_23 [
+ tmp = (s4_8_11 << 8) | u8_16_23;
+] { export *[const]:2 tmp; }
+
+# An “asymmetric” immediate from -32..95, used by MOVI.N.
+n_s8_12_15_4_6_asymm: tmp is n_s3_4_6 & n_s4_12_15 [
+ tmp = ((((n_s3_4_6 & 7) << 4) | (n_s4_12_15 & 15)) |
+ ((((n_s3_4_6 >> 2) & 1) & ((n_s3_4_6 >> 1) & 1)) << 7));
+] { export *[const]:1 tmp; }
+
+# Immediates shifted or with offset.
+s16_16_23_sb8: tmp is s8_16_23 [ tmp = s8_16_23 << 8; ] { export *[const]:4 tmp; }
+u15_12_23_sb3: tmp is u12_12_23 [ tmp = u12_12_23 << 3; ] { export *[const]:4 tmp; }
+u10_16_23_sb2: tmp is u8_16_23 [ tmp = u8_16_23 << 2; ] { export *[const]:4 tmp; }
+u9_16_23_sb1: tmp is u8_16_23 [ tmp = u8_16_23 << 1; ] { export *[const]:4 tmp; }
+u5_20_23_plus1: tmp is u4_20_23 [ tmp = u4_20_23 + 1; ] { export *[const]:4 tmp; }
+u8_20_23_sb4: tmp is u4_20_23 [ tmp = u4_20_23 << 4; ] { export *[const]:4 tmp; }
+u5_4_7_plus7: tmp is u4_4_7 [ tmp = u4_4_7 + 7; ] { export *[const]:4 tmp; }
+
+n_u6_12_15_sb2: tmp is n_u4_12_15 [ tmp = n_u4_12_15 << 2; ] { export *[const]:4 tmp; }
+
+# One-extended. FIXME: Verify this. Only used by [LS]32E (window extension), which aren’t yet
+# implemented.
+s5_12_15_oex: tmp is u4_12_15 [ tmp = (u4_12_15 << 2) - 64; ] { export *[const]:2 tmp; }
+
+# Some 4-bit immediates with mappings that can’t be (easily) expressed in a single disassembly action.
+
+# n_u4_4_7 with 0 being -1, used by ADDI.N.
+n_s4_4_7_nozero: tmp is n_u4_4_7 = 0 [ tmp = -1; ] { export *[const]:4 tmp; }
+n_s4_4_7_nozero: tmp is n_u4_4_7 [ tmp = n_u4_4_7+0; ] { export *[const]:4 tmp; }
+
+# B4CONST(ar) (Branch Immediate) encodings, pg. 41 f.
+r_b4const: tmp is ar = 0 [ tmp = 0xffffffff; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 1 [ tmp = 0x1; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
+r_b4const: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
+
+# B4CONSTU(ar) (Branch Unsigned Immediate) encodings, pg. 42.
+r_b4constu: tmp is ar = 0 [ tmp = 0x8000; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 1 [ tmp = 0x1000; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
+r_b4constu: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
+
+Ret4: loc is epsilon [loc = ((inst_start + 3) & 0x0fffffff) | 0x40000000; ] { ret:4 = loc; export ret; }
+Ret8: loc is epsilon [loc = ((inst_start + 3) & 0x0fffffff) | 0x80000000; ] { ret:4 = loc; export ret; }
+Ret12: loc is epsilon [loc = ((inst_start + 3) & 0x0fffffff) | 0xc0000000; ] { ret:4 = loc; export ret; }
+
+:^instruction is phase=0 & loopMode=1 & instruction [ phase=1; ] {
+ build instruction;
+ if (LCOUNT == 0 || $(PS_EXCM)) goto inst_next;
+ LCOUNT = LCOUNT - 1;
+ goto [LBEG];
+}
+:^instruction is phase=0 & loopMode=1 & loopEnd=1 & instruction
+ [ loopMode=0; phase=1; ] {
+ build instruction;
+}
+
+:^instruction is phase=0 & loopMode=0 & instruction
+ [ phase=1; ] {
+ build instruction;
+}
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensaTodo.sinc b/Ghidra/Processors/Xtensa/data/languages/xtensaTodo.sinc
deleted file mode 100644
index b89eea56e8..0000000000
--- a/Ghidra/Processors/Xtensa/data/languages/xtensaTodo.sinc
+++ /dev/null
@@ -1,66 +0,0 @@
-## Windowed Register Option ##
-
-# CALL4 - Call PC-relative, Rotate Window by 4, pg. 298.
-:call4 srel_6.23_sb2 is srel_6.23_sb2 & u2_4.5 = 0b01 & op0 = 0b0101 unimpl
-
-# CALL8 - Call PC-relative, Rotate Window by 8, pg. 300.
-:call8 srel_6.23_sb2 is srel_6.23_sb2 & u2_4.5 = 0b10 & op0 = 0b0101 unimpl
-
-# CALL12 - Call PC-relative, Rotate Window by 12, pg. 302.
-:call12 srel_6.23_sb2 is srel_6.23_sb2 & u2_4.5 = 0b11 & op0 = 0b0101 unimpl
-
-# CALLX4 - Call Register, Rotate Window by 4, pg. 305.
-:callx4 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b11 & u2_4.5 = 0b01 & op0 = 0 unimpl
-
-# CALLX8 - Call Register, Rotate Window by 8, pg. 307.
-:callx8 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b11 & u2_4.5 = 0b10 & op0 = 0 unimpl
-
-# CALLX12 - Call Register, Rotate Window by 12, pg. 308.
-:callx12 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b11 & u2_4.5 = 0b11 & op0 = 0 unimpl
-
-# ENTRY - Subroutine Entry, pg. 340.
-:entry as, u15_12.23_sb3 is u15_12.23_sb3 & as & u2_6.7 = 0b00 & u2_4.5 = 0b11 & op0 = 0b0110 unimpl
-
-# L32E - Load 32-bit for Window Exceptions, pg. 376.
-:l32e at, as, s5_12.15_oex is op2 = 0 & op1 = 0b1001 & s5_12.15_oex & as & at & op0 = 0 unimpl
-
-# MOVSP - Move to Stack Pointer, pg. 427.
-:movsp at, as is op2 = 0 & op1 = 0 & ar = 0b0001 & as & at & op0 = 0 unimpl
-
-# RETW - Windowed Return, pg. 480.
-:retw is op2 = 0 & ar = 0 & as = 0 & at = 0 & u2_18.19 = 0b10 & u2_16.17 = 0b01 & op0 = 0 unimpl
-
-# RETW.N - Narrow Windowed Return, pg. 482.
-:retw.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0001 & n_op0 = 0b1101 unimpl
-
-# ROTW - Rotate Window, pg. 496.
-:rotw s4_4.7 is op2 = 0b0100 & op1 = 0 & ar = 0b1000 & as = 0 & s4_4.7 & op0 = 0 unimpl
-
-# S32E - Store 32-bit for Window Exceptions, pg. 508.
-:s32e at, as, s5_12.15_oex is op2 = 0b0100 & op1 = 0b1001 & s5_12.15_oex & as & at & op0 = 0 unimpl
-
-
-## MAC16 option ##
-
-# LDDEC - Load with Autodecrement, pg. 386.
-:lddec "MAC16_REGS[" u2_12.13 "]", as is op2 = 0b1001 & op1 = 0 & u2_14.15 = 0 & u2_12.13 & as & at = 0 & op0 = 0b0100 unimpl
-
-# LDINC - Load with Autoincrement, pg. 387.
-:ldinc "MAC16_REGS[" u2_12.13 "]", as is op2 = 0b1000 & op1 = 0 & u2_14.15 = 0 & u2_12.13 & as & at = 0 & op0 = 0b0100 unimpl
-
-# MULA.AA.* - Signed Multiply, pg. 431.
-:mula.aa.* as, at is op2 = 0b0001 & u2_18.19 = 0b01 & ar = 0 & as & at & op0 = 0b0100 unimpl
-
-# FIXME: Add remaining MUL.* opcodes.
-
-
-## Loop Option ##
-
-# LOOP - Loop, pg. 392.
-:loop as, urel_16.23 is urel_16.23 & ar = 0b1000 & as & at = 0b0111 & op0 = 0b0110 unimpl
-
-# LOOPGTZ - Loop if Greater Than Zero, pg. 394.
-:loopgtz as, urel_16.23 is urel_16.23 & ar = 0b1010 & as & at = 0b0111 & op0 = 0b0110 unimpl
-
-# LOOPNEZ - Loop if Not Equal Zero, pg. 396.
-:loopnez as, urel_16.23 is urel_16.23 & ar = 0b1001 & as & at = 0b0111 & op0 = 0b0110 unimpl
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa_be.slaspec b/Ghidra/Processors/Xtensa/data/languages/xtensa_be.slaspec
new file mode 100644
index 0000000000..e3d7f63a38
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensa_be.slaspec
@@ -0,0 +1,12 @@
+@define ENDIAN "big"
+@include "xtensaArch.sinc"
+@include "xtensaMain.sinc"
+
+with : phase=1 {
+
+@include "xtensaInstructions.sinc"
+#@include "xtensa_depbits.sinc" #comment floating-point and uncomment this to use depbits
+@include "cust.sinc"
+@include "flix.sinc"
+
+}
\ No newline at end of file
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa_depbits.sinc b/Ghidra/Processors/Xtensa/data/languages/xtensa_depbits.sinc
new file mode 100644
index 0000000000..ccf799116e
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensa_depbits.sinc
@@ -0,0 +1,11 @@
+# Xtensa Deposit Bits instruction
+# This is broken out because it collides with the floating point instructions. It is not included by default
+
+# DEPBITS - Add (RRR), pg. 394.
+shiftimm: simm is u4_20_23 & u1_16 [ simm = u1_16 << 4 + u4_20_23; ] { export *[const]:4 simm; }
+:depbits as, at, shiftimm, u4_12_15 is u3_17_19=0x5 & u4_12_15 & as & at & op0 = 0 & shiftimm {
+ mask:4 = (1 << u4_12_15) - 1;
+ bits:4 = (as & mask) << shiftimm;
+ mask = mask << shiftimm;
+ at = (~mask & at) | bits;
+}
diff --git a/Ghidra/Processors/Xtensa/data/languages/xtensa_le.slaspec b/Ghidra/Processors/Xtensa/data/languages/xtensa_le.slaspec
new file mode 100644
index 0000000000..dab1dac032
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/data/languages/xtensa_le.slaspec
@@ -0,0 +1,12 @@
+@define ENDIAN "little"
+@include "xtensaArch.sinc"
+@include "xtensaMain.sinc"
+
+with : phase=1 {
+
+@include "xtensaInstructions.sinc"
+#@include "xtensa_depbits.sinc" #comment floating-point and uncomment this to use depbits
+@include "cust.sinc"
+@include "flix.sinc"
+
+}
diff --git a/Ghidra/Processors/Xtensa/data/manuals/xtensa.idx b/Ghidra/Processors/Xtensa/data/manuals/xtensa.idx
index e98296d090..d8025054d8 100644
--- a/Ghidra/Processors/Xtensa/data/manuals/xtensa.idx
+++ b/Ghidra/Processors/Xtensa/data/manuals/xtensa.idx
@@ -1,242 +1,354 @@
-@xtensa.pdf[Xtensa® Instruction Set Architecture (ISA) Reference Manual, April 2010]
+@isa_summary.pdf[Xtensa® Instruction Set Architecture Summary, For all Xtensa LX Processors April 2022]
-b4const(ar), 65
-b4constu(ar), 66
-call4, 322
-call8, 324
-call12, 326
-callx4, 329
-callx8, 331
-callx12, 332
-entry, 364
-l32e, 400
-movsp, 451
-retw, 504
-retw.n, 506
-rotw, 520
-s32e, 532
-lddec, 410
-ldinc, 411
-mula.aa.*, 455
-loop, 416
-loopgtz, 418
-loopnez, 420
-abs, 270
-abs.s, 271
-add, 272
-add.n, 273
-add.s, 274
-addi, 275
-addi.n, 276
-addmi, 277
-addx2, 278
-addx4, 279
-addx8, 280
-all4, 281
-all8, 282
-and, 283
-andb, 284
-andbc, 285
-any4, 286
-any8, 287
-ball, 288
-bany, 289
-bbc, 290
-bbci, 291
-bbs, 293
-bbsi, 294
-beq, 296
-beqi, 297
-beqz, 298
-beqz.n, 299
-bf, 300
-bge, 301
-bgei, 302
-bgeu, 303
-bgeui, 304
-bgez, 305
-blt, 306
-blti, 307
-bltu, 308
-bltui, 309
-bltz, 310
-bnall, 311
-bne, 312
-bnei, 313
-bnez, 314
-bnez.n, 315
-bnone, 316
-break, 317
-break.n, 319
-bt, 320
-call0, 321
-callx0, 328
-ceil.s, 335
-clamps, 336
-dhi, 337
-dhu, 339
-dhwb, 341
-dhwbi, 343
-dii, 345
-diu, 347
-diwb, 349
-diwbi, 351
-dpfl, 353
-dpfr, 355
-dpfro, 357
-dpfw, 359
-dpfwo, 361
-dsync, 363
-esync, 366
-excw, 367
-extui, 368
-extw, 369
-float.s, 370
-floor.s, 371
-idtlb, 372
-ihi, 373
-ihu, 375
-iii, 377
-iitlb, 379
-iiu, 380
-ill, 382
-ill.n, 383
-ipf, 384
-ipfl, 386
-isync, 388
-j, 390
-ret, 502
-jx, 392
-l8ui, 393
-l16si, 394
-l16ui, 396
-l32ai, 398
-l32i, 402
-l32i.n, 404
-l32r, 406
-ldct, 408
-lict, 412
-licw, 414
-lsi, 422
-lsiu, 424
-lsx, 426
-lsxu, 428
-madd.s, 430
-max, 431
-maxu, 432
-memw, 433
-min, 434
-minu, 435
-mov.n, 437
-mov.s, 438
-moveqz, 439
-moveqz.s, 440
-movf, 441
-movf.s, 442
-movgez, 443
-movgez.s, 444
-movi, 445
-movi.n, 446
-movltz, 447
-movltz.s, 448
-movnez, 449
-movnez.s, 450
-movt, 452
-movt.s, 453
-msub.s, 454
-mul.s, 459
-mul16s, 460
-mul16u, 461
-mull, 474
-mulsh, 479
-muluh, 480
-neg, 481
-neg.s, 482
-nop, 483
-nop.n, 484
-nsa, 485
-nsau, 486
-oeq.s, 487
-ole.s, 488
-olt.s, 489
-mov, 436
-or, 490
-orb, 491
-orbc, 492
-pdtlb, 493
-pitlb, 494
-quos, 495
-quou, 496
-rdtlb0, 497
-rdtlb1, 498
-rems, 499
-remu, 500
-rer, 501
-ret.n, 503
-rfdd, 508
-rfde, 509
-rfdo, 510
-rfe, 511
-rfi, 512
-rfme, 513
-rfr, 514
-rfue, 515
-rfwo, 516
-rfwu, 517
-ritlb0, 518
-ritlb1, 519
-round.s, 521
-rsil, 522
-rsr, 524
-rsync, 526
-rur, 527
-s8i, 528
-s16i, 529
-s32c1i, 530
-s32i, 534
-s32i.n, 536
-s32ri, 538
-sdct, 540
-sext, 542
-sict, 543
-sicw, 545
-simcall, 547
-sll, 548
-slli, 549
-sra, 550
-srai, 551
-src, 552
-srl, 553
-srli, 554
-ssa8b, 555
-ssa8l, 556
-ssai, 557
-ssi, 558
-ssiu, 560
-ssl, 562
-ssr, 563
-ssx, 564
-ssxu, 565
-sub, 566
-sub.s, 567
-subx2, 568
-subx4, 569
-subx8, 570
-syscall, 571
-trunc.s, 572
-ueq.s, 573
-ufloat.s, 574
-ule.s, 575
-ult.s, 576
-un.s, 578
-utrunc.s, 579
-waiti, 580
-wdtlb, 581
-wer, 582
-wfr, 583
-witlb, 584
-wsr, 585
-wur, 587
-xor, 588
-xorb, 589
-xsr, 590
+ABS, 324
+ABS.D, 324
+ABS.S, 325
+ADD, 326
+ADD.N, 326
+ADD.D, 327
+ADD.S, 328
+ADDEXP.D, 329
+ADDEXP.S, 329
+ADDEXPM.D, 330
+ADDEXPM.S, 331
+ADDI, 332
+ADDI.N, 333
+ADDMI, 334
+ADDX2, 335
+ADDX4, 336
+ADDX8, 336
+ALL4, 337
+ALL8, 338
+AND, 339
+ANDB, 339
+ANDBC, 340
+ANY4, 341
+ANY8, 341
+BALL, 342
+BANY, 343
+BBC, 344
+BBCI, 345
+BBCI.L, 346
+BBS, 347
+BBSI, 348
+BBSI.L, 349
+BEQ, 349
+BEQI, 350
+BEQZ, 351
+BEQZ.N, 352
+BF, 353
+BGE, 354
+BGEI, 355
+ixBGEU, 356
+BGEUI, 357
+BGEZ, 358
+BLT, 359
+BLTI, 360
+BLTU, 361
+BLTUI, 361
+BLTZ, 362
+BNALL, 363
+BNE, 364
+BNEI, 365
+BNEZ, 366
+BNEZ.N, 367
+BNONE, 368
+BREAK, 369
+BREAK.N, 370
+BT, 371
+CALL0, 372
+CALL4 373
+CALL8, 375
+CALL12, 376
+CALLX0, 377
+CALLX4, 378
+CALLX8, 379
+CALLX12, 380
+CEIL.D, 382
+CEIL.S, 383
+CLAMPS, 383
+CLREX, 384
+CONST.D, 385
+CONST.S, 386
+CONST16, 387
+CVTD.S, 388
+CVTS.D, 389
+DCI, 389
+DCWB, 391
+DCWBI, 392
+DEPBITS, 394
+DHI, 395
+DHI.B, 396
+DHU, 397
+DHWB, 398
+DHWB.B, 400
+DHWBI, 400
+DHWBI.B, 402
+xDII, 403
+DIU, 404
+DIV0.D, 406
+DIV0.S, 406
+DIVN.D, 407
+DIVN.S, 408
+DIWB, 409
+DIWBI, 410
+DIWBUI.P, 412
+DPFL, 413
+DPFM.B, 415
+DPFM.BF, 416
+DPFR, 416
+DPFR.B, 418
+DPFR.BF, 419
+DPFRO, 419
+DPFW, 421
+DPFW.B, 422
+DPFW.BF, 423
+DPFWO, 424
+DSYNC, 425
+ENTRY, 426
+ESYNC, 427
+EXCW, 428
+EXTUI, 429
+EXTW, 430
+FLOAT.D, 431
+FLOAT.S, 431
+FLOOR.D, 432
+FLOOR.S, 433
+FSYNC, 434
+GETEX, 434
+IDTLB, 435
+IHI, 436
+IHU, 438
+III, 439
+IITLB, 441
+IIU, 442
+ILL, 443
+ILL.N, 444
+IPF, 444
+IPFL, 446
+ISYNC, 447
+J, 449
+J.L, 449
+JX, 450
+L8UI, 450
+L16SI, 451
+L16UI, 453
+L32AI, 454
+L32E, 455
+L32EX, 457
+L32I, 458
+L32I.N, 459
+L32R, 461
+LDCT, 463
+LDCW, 464
+LDDEC, 465
+LDDR32.P, 467
+LDI, 467
+LDINC, 468
+LDIP, 469
+LDX, 471
+LDXP, 472
+LOOP, 473
+LOOPGTZ, 475
+LOOPNEZ, 476
+LSI, 478
+LSIP, 480
+LSIU, 481
+LSX, 482
+LSXP, 483
+LSXU, 484
+MADD.D, 486
+MADD.S, 486
+MADDN.D, 487
+MADDN.S, 488
+MAX, 489
+MAXU, 489
+MEMW, 490
+MIN, 491
+MINU, 491
+MKDADJ.D, 492
+MKDADJ.S, 493
+MKSADJ.D, 494
+MKSADJ.S, 494
+MOV, 495
+MOV.D, 496
+MOV.N, 497
+MOV.S, 498
+MOVEQZ, 499
+MOVEQZ.D, 499
+MOVEQZ.S, 500
+MOVF, 501
+MOVF.D, 502
+MOVF.S, 503
+MOVGEZ, 504
+MOVGEZ.D, 504
+MOVGEZ.S, 505
+MOVI, 506
+MOVI.N, 507
+MOVLTZ, 508
+MOVLTZ.D, 509
+MOVLTZ.S, 510
+MOVNEZ, 510
+MOVNEZ.D, 511
+MOVNEZ.S, 512
+MOVSP, 513
+MOVT, 514
+MOVT.D, 515
+MOVT.S, 516
+MSUB.D, 517
+MSUB.S, 517
+MUL.AA.*, 518
+MUL.AD.*, 519
+MUL.DA.*, 520
+MUL.DD.*, 521
+MUL.D, 522
+MUL.S, 522
+MUL16S, 523
+MUL16U, 524
+MULA.AA.*, 524
+MULA.AD.*, 525
+MULA.DA.*, 526
+MULA.DA.*.LDDEC, 527
+MULA.DA.*.LDINC, 528
+MULA.DD.*, 530
+MULA.DD.*.LDDEC 531
+MULA.DD.*.LDINC 532
+MULL, 534
+MULS.AA.*, 535
+MULS.AD.*, 535
+MULS.DA.*, 536
+MULS.DD.*, 537
+MULSH, 538
+MULUH, 539
+NEG, 540
+NEG.D, 540
+NEG.S, 541
+NEXP01.D, 541
+NEXP01.S, 542
+NOP, 543
+NOP.N, 544
+NSA, 545
+NSAU, 546
+OEQ.D, 547
+OEQ.S, 547
+OLE.D, 548
+OLE.S, 549
+OLT.D, 550
+OLT.S, 551
+OR, 551
+ORB, 552
+ORBC, 553
+TLB, 553
+PITLB, 554
+PPTLB, 555
+QUOS, 556
+QUOU, 557
+RDTLB0, 558
+RDTLB1, 559
+RECIP0.D, 560
+RECIP0.S, 560
+REMS, 561
+REMU, 562
+RER, 563
+RET, 564
+RET.N, 564
+RETW, 565
+RETW.N, 567
+RFDD, 568
+RFDE, 569
+RFDO, 570
+RFE, 570
+RFI, 571
+RFME, 572
+RFR, 573
+RFRD, 573
+RFUE, 574
+RFWO, 575
+RFWU, 576
+RITLB0, 576
+RITLB1, 577
+ROTW, 578
+ROUND.D, 579
+ROUND.S, 580
+RPTLB0, 580
+RPTLB1, 581
+RSIL, 582
+RSQRT0.D, 583
+RSQRT0.S, 584
+RSR.*, 585
+RSYNC, 586
+RUR.*, 586
+S8I, 587
+S16I, 588
+S32C1I, 589
+S32E, 591
+S32EX, 592
+S32I, 594
+S32I.N, 595
+S32NB, 596
+S32RI, 597
+SALT, 599
+SALTU, 600
+SDDR32.P, 600
+SDI, 601
+SDIP, 602
+SDX, 603
+SDXP, 604
+SEXT, 605
+SICT, 606
+SICW, 607
+SIMCALL, 609
+SLL, 609
+SLLI, 610
+SQRT0.D, 611
+SQRT0.S, 612
+SRA, 613
+SRAI, 613
+SRC, 614
+SRL, 615
+SRLI, 616
+SSA8B, 616
+SSA8L, 617
+SSAI, 618
+SSI, 619
+SSIP, 620
+SSIU, 621
+SSL, 622
+SSR, 623
+SSX, 624
+SSXP, 625
+SSXU, 626
+SUB, 627
+SUB.D, 627
+SUB.S, 628
+SUBX2, 629
+SUBX4, 629
+SUBX8, 630
+SYSCALL, 631
+TRUNC.D, 632
+TRUNC.S, 632
+UEQ.D, 633
+UEQ.S, 634
+UFLOAT.D, 635
+UFLOAT.S, 636
+ULE.D, 636
+ULE.S, 637
+ULT.D, 638
+ULT.S, 639
+UMUL.AA.*, 639
+UN.D, 640
+UN.S, 641
+UTRUNC.D, 642
+UTRUNC.S, 642
+WAITI, 643
+WDTLB, 644
+WER, 645
+WFR, 646
+WFRD, 647
+WITLB, 648
+WPTLB, 649
+WSR.*, 650
+WUR.*, 651
+XOR, 652
+XORB, 652
+XSR.*, 653
diff --git a/Ghidra/Processors/Xtensa/src/main/help/help/TOC_Source.xml b/Ghidra/Processors/Xtensa/src/main/help/help/TOC_Source.xml
deleted file mode 100644
index a34f62e8f1..0000000000
--- a/Ghidra/Processors/Xtensa/src/main/help/help/TOC_Source.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
diff --git a/Ghidra/Processors/Xtensa/src/main/help/help/topics/xtensa/help.html b/Ghidra/Processors/Xtensa/src/main/help/help/topics/xtensa/help.html
deleted file mode 100644
index 1f9d6a1fc7..0000000000
--- a/Ghidra/Processors/Xtensa/src/main/help/help/topics/xtensa/help.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Skeleton Help File for a Module
-
-
-
-
-
Skeleton Help File for a Module
-
-
This is a simple skeleton help topic. For a better description of what should and should not
- go in here, see the "sample" Ghidra extension in the Extensions/Ghidra directory, or see your
- favorite help topic. In general, language modules do not have their own help topics.
-
-
diff --git a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java
index f74eb6d7ff..e5b9598490 100644
--- a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java
+++ b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java
@@ -1,3 +1,18 @@
+/* ###
+ * 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 class Xtensa_ElfRelocationConstants {
diff --git a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java
index f0033e4bed..279ebe4e1c 100644
--- a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java
+++ b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java
@@ -1,9 +1,21 @@
+/* ###
+ * 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.ElfConstants;
-import ghidra.app.util.bin.format.elf.ElfHeader;
-import ghidra.app.util.bin.format.elf.ElfRelocation;
-import ghidra.app.util.bin.format.elf.ElfSymbol;
+import ghidra.app.util.bin.format.elf.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryAccessException;
@@ -15,24 +27,25 @@ public class Xtensa_ElfRelocationHandler extends ElfRelocationHandler {
@Override
public boolean canRelocate(ElfHeader elf) {
return elf.e_machine() == ElfConstants.EM_XTENSA ||
- elf.e_machine() == Xtensa_ElfRelocationConstants.EM_XTENSA_OLD;
+ elf.e_machine() == Xtensa_ElfRelocationConstants.EM_XTENSA_OLD;
}
@Override
- public RelocationResult relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress)
+ public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
+ ElfRelocation relocation, Address relocationAddress)
throws MemoryAccessException, NotFoundException {
ElfHeader elf = elfRelocationContext.getElfHeader();
if (!canRelocate(elf)) {
return RelocationResult.FAILURE;
}
- int type=relocation.getType();
+ int type = relocation.getType();
if (Xtensa_ElfRelocationConstants.R_XTENSA_NONE == type) {
- return RelocationResult.FAILURE;
+ return RelocationResult.SKIPPED;
}
Program program = elfRelocationContext.getProgram();
-
+
ElfSymbol sym = null;
String symbolName = null;
@@ -47,243 +60,150 @@ public class Xtensa_ElfRelocationHandler extends ElfRelocationHandler {
//int byteLength = 4; // most relocations affect 4-bytes (change if different)
- switch(type) {
- case Xtensa_ElfRelocationConstants.R_XTENSA_32:
- markAsWarning(program, relocationAddress, "R_XTENSA_32",
- symbolName, symbolIndex, "TODO, needs support ",
+ switch (type) {
+ case Xtensa_ElfRelocationConstants.R_XTENSA_32:
+ markAsWarning(program, relocationAddress, "R_XTENSA_32", symbolName, symbolIndex,
+ "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_RTLD:
+ markAsWarning(program, relocationAddress, "R_XTENSA_RTLD", symbolName, symbolIndex,
+ "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_GLOB_DAT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_GLOB_DAT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_JMP_SLOT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_JMP_SLOT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_RELATIVE:
+ markAsWarning(program, relocationAddress, "R_XTENSA_RELATIVE", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_PLT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_PLT", symbolName, symbolIndex,
+ "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_OP0:
+ markAsWarning(program, relocationAddress, "R_XTENSA_OP0", symbolName, symbolIndex,
+ "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_OP1:
+ markAsWarning(program, relocationAddress, "R_XTENSA_OP1", symbolName, symbolIndex,
+ "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_OP2:
+ markAsWarning(program, relocationAddress, "R_XTENSA_OP2", symbolName, symbolIndex,
+ "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_EXPAND:
+ markAsWarning(program, relocationAddress, "R_XTENSA_ASM_EXPAND", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_SIMPLIFY:
+ markAsWarning(program, relocationAddress, "R_XTENSA_ASM_SIMPLIFY", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTINHERIT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTINHERIT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTENTRY:
+ markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTENTRY", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF8:
+ markAsWarning(program, relocationAddress, "R_XTENSA_DIFF8", symbolName, symbolIndex,
+ "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF16:
+ markAsWarning(program, relocationAddress, "R_XTENSA_DIFF16", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF32:
+ markAsWarning(program, relocationAddress, "R_XTENSA_DIFF32", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_OP:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_OP", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_ALT:
+ markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_ALT", symbolName,
+ symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
+ default:
+ markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_RTLD:
- markAsWarning(program, relocationAddress, "R_XTENSA_RTLD",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_GLOB_DAT:
- markAsWarning(program, relocationAddress, "R_XTENSA_GLOB_DAT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_JMP_SLOT:
- markAsWarning(program, relocationAddress, "R_XTENSA_JMP_SLOT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_RELATIVE:
- markAsWarning(program, relocationAddress, "R_XTENSA_RELATIVE",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_PLT:
- markAsWarning(program, relocationAddress, "R_XTENSA_PLT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_OP0:
- markAsWarning(program, relocationAddress, "R_XTENSA_OP0",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_OP1:
- markAsWarning(program, relocationAddress, "R_XTENSA_OP1",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_OP2:
- markAsWarning(program, relocationAddress, "R_XTENSA_OP2",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_EXPAND:
- markAsWarning(program, relocationAddress, "R_XTENSA_ASM_EXPAND",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_SIMPLIFY:
- markAsWarning(program, relocationAddress, "R_XTENSA_ASM_SIMPLIFY",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTINHERIT:
- markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTINHERIT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTENTRY:
- markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTENTRY",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF8:
- markAsWarning(program, relocationAddress, "R_XTENSA_DIFF8",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF16:
- markAsWarning(program, relocationAddress, "R_XTENSA_DIFF16",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF32:
- markAsWarning(program, relocationAddress, "R_XTENSA_DIFF32",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_OP:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_OP",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_ALT:
- markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_ALT",
- symbolName, symbolIndex, "TODO, needs support ",
- elfRelocationContext.getLog());
- return RelocationResult.UNSUPPORTED;
- default:
- markAsUnhandled(program, relocationAddress, type, symbolIndex,
- symbolName, elfRelocationContext.getLog());
- return RelocationResult.SKIPPED;
}
-
+ return RelocationResult.UNSUPPORTED;
}
}
diff --git a/Ghidra/Processors/Xtensa/src/main/java/ghidra/program/emulation/XtensaEmulateInstructionStateModifier.java b/Ghidra/Processors/Xtensa/src/main/java/ghidra/program/emulation/XtensaEmulateInstructionStateModifier.java
new file mode 100644
index 0000000000..ecd6264872
--- /dev/null
+++ b/Ghidra/Processors/Xtensa/src/main/java/ghidra/program/emulation/XtensaEmulateInstructionStateModifier.java
@@ -0,0 +1,159 @@
+/* ###
+ * 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.Stack;
+
+import ghidra.pcode.emulate.Emulate;
+import ghidra.pcode.emulate.EmulateInstructionStateModifier;
+import ghidra.pcode.emulate.callother.OpBehaviorOther;
+import ghidra.pcode.emulate.callother.OpBehaviorOtherNOP;
+import ghidra.pcode.error.LowlevelError;
+import ghidra.pcode.memstate.MemoryState;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.lang.Register;
+import ghidra.program.model.pcode.Varnode;
+
+public class XtensaEmulateInstructionStateModifier extends EmulateInstructionStateModifier {
+
+ private Stack stashStack = new Stack();
+ public XtensaEmulateInstructionStateModifier(Emulate emu) {
+ super(emu);
+
+ registerPcodeOpBehavior("rotateRegWindow", new RotateRegWindow());
+ registerPcodeOpBehavior("restoreRegWindow", new RestoreRegWindow());
+
+ registerPcodeOpBehavior("swap4", new OpBehaviorOtherNOP());
+ registerPcodeOpBehavior("swap8", new OpBehaviorOtherNOP());
+ registerPcodeOpBehavior("swap12", new OpBehaviorOtherNOP());
+ registerPcodeOpBehavior("restore4", new OpBehaviorOtherNOP());
+ registerPcodeOpBehavior("restore8", new OpBehaviorOtherNOP());
+ registerPcodeOpBehavior("restore12", new OpBehaviorOtherNOP());
+ }
+
+ private class RotateRegWindow implements OpBehaviorOther {
+
+ @Override
+ public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
+ if (inputs.length != 2) {
+ throw new LowlevelError("rotateRegWindow: missing required CALLINC input");
+ }
+
+ MemoryState memoryState = emu.getMemoryState();
+ Varnode in = inputs[1];
+ long callinc = memoryState.getValue(in);
+ if (callinc == 0) {
+ return;
+ }
+ if (callinc < 0 || callinc > 3) {
+ throw new LowlevelError("rotateRegWindow: invalid value for CALLINC (0x" +
+ Long.toHexString(callinc) + ")");
+ }
+
+ // push window onto stack
+ stashStack.push(new RegisterStash((int) callinc));
+
+ //rotate registers
+ Address baseARegAddr = language.getRegister("a0").getAddress();
+ int count = (int) callinc << 2; // windowSize
+ long windowRegOffset = count * 4;
+ count = 16 - count;
+
+ for (int i = 0; i < count; i++) {
+ Varnode fromRegVarnode =
+ new Varnode(baseARegAddr.add(windowRegOffset + (i * 4)), 4);
+ Varnode toRegVarnode = new Varnode(baseARegAddr.add(i * 4), 4);
+ long value = memoryState.getValue(fromRegVarnode);
+ memoryState.setValue(toRegVarnode, value);
+ }
+ }
+ }
+
+ private class RestoreRegWindow implements OpBehaviorOther {
+
+ @Override
+ public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
+ if (inputs.length != 1) {
+ throw new LowlevelError("restoreRegWindow: unexpected input varnodes");
+ }
+
+ MemoryState memoryState = emu.getMemoryState();
+
+ Register a0Reg = language.getRegister("a0");
+ long callinc = (memoryState.getValue(a0Reg) >> 30) & 0x3;
+ if (callinc == 0) {
+ return;
+ }
+
+ if (stashStack.isEmpty()) {
+ throw new LowlevelError("restoreRegWindow: window register stash is empty");
+ }
+
+ RegisterStash stash = stashStack.peek();
+ if (callinc != stash.callinc) {
+ throw new LowlevelError("restoreRegWindow: return address CALLINC (" + callinc +
+ ") does not match last entry CALLINC value (" + stash.callinc + ")");
+ }
+
+ //rotate registers
+ Address baseARegAddr = language.getRegister("a0").getAddress();
+ int count = (int) callinc << 2; // windowSize
+ long windowRegOffset = count * 4;
+ count = 16 - count;
+
+ for (int i = 0; i < count; i++) {
+ Varnode fromRegVarnode = new Varnode(baseARegAddr.add(i * 4), 4);
+ Varnode toRegVarnode = new Varnode(baseARegAddr.add(windowRegOffset + (i * 4)), 4);
+ long value = memoryState.getValue(fromRegVarnode);
+ memoryState.setValue(toRegVarnode, value);
+ }
+
+ // remove from stack and restore
+ stashStack.pop();
+ stash.restore();
+ }
+ }
+
+ private class RegisterStash {
+ private int callinc;
+ private int[] values;
+
+ RegisterStash(int callinc) {
+ this.callinc = callinc;
+
+ MemoryState memoryState = emu.getMemoryState();
+ Address baseARegAddr = language.getRegister("a0").getAddress();
+
+ int count = callinc << 2;
+ values = new int[count];
+
+ for (int i = 0; i < count; i++) {
+ Varnode regVarnode = new Varnode(baseARegAddr.add(4 * i), 4);
+ values[i] = (int) memoryState.getValue(regVarnode);
+ }
+ }
+
+ public void restore() {
+ MemoryState memoryState = emu.getMemoryState();
+ Address baseARegAddr = language.getRegister("a0").getAddress();
+
+ for (int i = 0; i < values.length; i++) {
+ Varnode regVarnode = new Varnode(baseARegAddr.add(4 * i), 4);
+ memoryState.setValue(regVarnode, values[i]);
+ }
+ }
+ }
+}
diff --git a/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O0_EmulatorTest.java b/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O0_EmulatorTest.java
index 65f528001f..628919694d 100644
--- a/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O0_EmulatorTest.java
+++ b/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O0_EmulatorTest.java
@@ -1,3 +1,18 @@
+/* ###
+ * 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.test.processors.support.ProcessorEmulatorTestAdapter;
diff --git a/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O3_EmulatorTest.java b/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O3_EmulatorTest.java
index 7e48b55816..b0b7962368 100644
--- a/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O3_EmulatorTest.java
+++ b/Ghidra/Processors/Xtensa/src/test.processors/java/ghidra/test/processors/Xtensa_O3_EmulatorTest.java
@@ -1,3 +1,18 @@
+/* ###
+ * 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.test.processors.support.ProcessorEmulatorTestAdapter;