From fa7c3b1fec5e133f5147b6c541d023c646c0b170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20COCAULT?= Date: Thu, 16 Apr 2020 18:58:10 +0200 Subject: [PATCH 1/7] [NDS32] Add support for the NDS32 Processor --- Ghidra/Processors/NDS32/Module.manifest | 0 Ghidra/Processors/NDS32/build.gradle | 15 + .../Processors/NDS32/data/buildLanguage.xml | 50 + .../Processors/NDS32/data/languages/lsmw.sinc | 576 +++++++++ .../NDS32/data/languages/nds32.cspec | 105 ++ .../NDS32/data/languages/nds32.dwarf | 14 + .../NDS32/data/languages/nds32.ldefs | 31 + .../NDS32/data/languages/nds32.opinion | 5 + .../NDS32/data/languages/nds32.pspec | 6 + .../NDS32/data/languages/nds32.sinc | 1081 +++++++++++++++++ .../NDS32/data/languages/nds32be.slaspec | 7 + .../NDS32/data/languages/nds32le.slaspec | 7 + .../NDS32/data/patterns/nds32_patterns.xml | 13 + .../data/patterns/patternconstraints.xml | 5 + Ghidra/Processors/NDS32/data/sleighArgs.txt | 6 + .../plugin/core/analysis/NDS32Analyzer.java | 187 +++ .../NDS32_ElfRelocationConstants.java | 74 ++ .../NDS32_ElfRelocationHandler.java | 111 ++ .../processors/NDS32_LE_O0_EmulatorTest.java | 41 + .../processors/NDS32_LE_O3_EmulatorTest.java | 41 + 20 files changed, 2375 insertions(+) create mode 100644 Ghidra/Processors/NDS32/Module.manifest create mode 100644 Ghidra/Processors/NDS32/build.gradle create mode 100644 Ghidra/Processors/NDS32/data/buildLanguage.xml create mode 100644 Ghidra/Processors/NDS32/data/languages/lsmw.sinc create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32.cspec create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32.dwarf create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32.ldefs create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32.opinion create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32.pspec create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32.sinc create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32be.slaspec create mode 100644 Ghidra/Processors/NDS32/data/languages/nds32le.slaspec create mode 100644 Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml create mode 100644 Ghidra/Processors/NDS32/data/patterns/patternconstraints.xml create mode 100644 Ghidra/Processors/NDS32/data/sleighArgs.txt create mode 100644 Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.java create mode 100644 Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java create mode 100644 Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java create mode 100644 Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java create mode 100644 Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java diff --git a/Ghidra/Processors/NDS32/Module.manifest b/Ghidra/Processors/NDS32/Module.manifest new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Ghidra/Processors/NDS32/build.gradle b/Ghidra/Processors/NDS32/build.gradle new file mode 100644 index 0000000000..6d9b72ae40 --- /dev/null +++ b/Ghidra/Processors/NDS32/build.gradle @@ -0,0 +1,15 @@ +apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle" +apply from: "$rootProject.projectDir/gradle/javaProject.gradle" +apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle" +apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle" +apply from: "$rootProject.projectDir/gradle/processorProject.gradle" +apply plugin: 'eclipse' +eclipse.project.name = 'Processors NDS32' + + +dependencies { + compile project(':Base') + // Temporary dependency so that pcodeTests can use the Decompiler switch recovery + compile project(':Decompiler') +} + diff --git a/Ghidra/Processors/NDS32/data/buildLanguage.xml b/Ghidra/Processors/NDS32/data/buildLanguage.xml new file mode 100644 index 0000000000..1e2a6276bc --- /dev/null +++ b/Ghidra/Processors/NDS32/data/buildLanguage.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/NDS32/data/languages/lsmw.sinc b/Ghidra/Processors/NDS32/data/languages/lsmw.sinc new file mode 100644 index 0000000000..2953e445d1 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/lsmw.sinc @@ -0,0 +1,576 @@ +macro Lmwbi(reg) { + reg = *mult_addr; + mult_addr = mult_addr + 4; +} + +macro Lmwbd(reg) { + reg = *mult_addr; + mult_addr = mult_addr - 4; +} + +macro Lmwai(reg) { + mult_addr = mult_addr + 4; + reg = *mult_addr; +} + +macro Lmwad(reg) { + mult_addr = mult_addr - 4; + reg = *mult_addr; +} + +macro Smwbi(reg) { + *mult_addr = reg; + mult_addr = mult_addr + 4; +} + +macro Smwbd(reg) { + *mult_addr = reg; + mult_addr = mult_addr - 4; +} + +macro Smwai(reg) { + mult_addr = mult_addr + 4; + *mult_addr = reg; +} + +macro Smwad(reg) { + mult_addr = mult_addr - 4; + *mult_addr = reg; +} + +Lmwbi.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwbi(a0); } +Lmwbi.a0: is LsmwRb_ & LsmwRe_ { } +Lmwbi.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwbi(a1); } +Lmwbi.a1: is LsmwRb_ & LsmwRe_ { } +Lmwbi.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwbi(a2); } +Lmwbi.a2: is LsmwRb_ & LsmwRe_ { } +Lmwbi.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwbi(a3); } +Lmwbi.a3: is LsmwRb_ & LsmwRe_ { } +Lmwbi.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwbi(a4); } +Lmwbi.a4: is LsmwRb_ & LsmwRe_ { } +Lmwbi.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwbi(a5); } +Lmwbi.a5: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwbi(s0); } +Lmwbi.s0: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwbi(s1); } +Lmwbi.s1: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwbi(s2); } +Lmwbi.s2: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwbi(s3); } +Lmwbi.s3: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwbi(s4); } +Lmwbi.s4: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwbi(s5); } +Lmwbi.s5: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwbi(s6); } +Lmwbi.s6: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwbi(s7); } +Lmwbi.s7: is LsmwRb_ & LsmwRe_ { } +Lmwbi.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwbi(s8); } +Lmwbi.s8: is LsmwRb_ & LsmwRe_ { } +Lmwbi.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwbi(ta); } +Lmwbi.ta: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwbi(t0); } +Lmwbi.t0: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwbi(t1); } +Lmwbi.t1: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwbi(t2); } +Lmwbi.t2: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwbi(t3); } +Lmwbi.t3: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwbi(t4); } +Lmwbi.t4: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwbi(t5); } +Lmwbi.t5: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwbi(t6); } +Lmwbi.t6: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwbi(t7); } +Lmwbi.t7: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwbi(t8); } +Lmwbi.t8: is LsmwRb_ & LsmwRe_ { } +Lmwbi.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwbi(t9); } +Lmwbi.t9: is LsmwRb_ & LsmwRe_ { } +Lmwbi.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwbi(p0); } +Lmwbi.p0: is LsmwRb_ & LsmwRe_ { } +Lmwbi.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwbi(p1); } +Lmwbi.p1: is LsmwRb_ & LsmwRe_ { } +Lmwbi.fp: fp is Enable4_fp=1 & fp { Lmwbi(fp); } +Lmwbi.fp: is Enable4_fp=0 { } +Lmwbi.gp: gp is Enable4_gp=1 & gp { Lmwbi(gp); } +Lmwbi.gp: is Enable4_gp=0 { } +Lmwbi.lp: lp is Enable4_lp=1 & lp { Lmwbi(lp); } +Lmwbi.lp: is Enable4_lp=0 { } +Lmwbi.sp: sp is Enable4_sp=1 & sp { Lmwbi(sp); } +Lmwbi.sp: is Enable4_sp=0 { } + +Lmwbd.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwbd(a0); } +Lmwbd.a0: is LsmwRb_ & LsmwRe_ { } +Lmwbd.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwbd(a1); } +Lmwbd.a1: is LsmwRb_ & LsmwRe_ { } +Lmwbd.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwbd(a2); } +Lmwbd.a2: is LsmwRb_ & LsmwRe_ { } +Lmwbd.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwbd(a3); } +Lmwbd.a3: is LsmwRb_ & LsmwRe_ { } +Lmwbd.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwbd(a4); } +Lmwbd.a4: is LsmwRb_ & LsmwRe_ { } +Lmwbd.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwbd(a5); } +Lmwbd.a5: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwbd(s0); } +Lmwbd.s0: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwbd(s1); } +Lmwbd.s1: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwbd(s2); } +Lmwbd.s2: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwbd(s3); } +Lmwbd.s3: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwbd(s4); } +Lmwbd.s4: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwbd(s5); } +Lmwbd.s5: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwbd(s6); } +Lmwbd.s6: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwbd(s7); } +Lmwbd.s7: is LsmwRb_ & LsmwRe_ { } +Lmwbd.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwbd(s8); } +Lmwbd.s8: is LsmwRb_ & LsmwRe_ { } +Lmwbd.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwbd(ta); } +Lmwbd.ta: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwbd(t0); } +Lmwbd.t0: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwbd(t1); } +Lmwbd.t1: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwbd(t2); } +Lmwbd.t2: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwbd(t3); } +Lmwbd.t3: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwbd(t4); } +Lmwbd.t4: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwbd(t5); } +Lmwbd.t5: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwbd(t6); } +Lmwbd.t6: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwbd(t7); } +Lmwbd.t7: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwbd(t8); } +Lmwbd.t8: is LsmwRb_ & LsmwRe_ { } +Lmwbd.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwbd(t9); } +Lmwbd.t9: is LsmwRb_ & LsmwRe_ { } +Lmwbd.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwbd(p0); } +Lmwbd.p0: is LsmwRb_ & LsmwRe_ { } +Lmwbd.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwbd(p1); } +Lmwbd.p1: is LsmwRb_ & LsmwRe_ { } +Lmwbd.fp: fp is Enable4_fp=1 & fp { Lmwbd(fp); } +Lmwbd.fp: is Enable4_fp=0 { } +Lmwbd.gp: gp is Enable4_gp=1 & gp { Lmwbd(gp); } +Lmwbd.gp: is Enable4_gp=0 { } +Lmwbd.lp: lp is Enable4_lp=1 & lp { Lmwbd(lp); } +Lmwbd.lp: is Enable4_lp=0 { } +Lmwbd.sp: sp is Enable4_sp=1 & sp { Lmwbd(sp); } +Lmwbd.sp: is Enable4_sp=0 { } + +Lmwai.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwai(a0); } +Lmwai.a0: is LsmwRb_ & LsmwRe_ { } +Lmwai.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwai(a1); } +Lmwai.a1: is LsmwRb_ & LsmwRe_ { } +Lmwai.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwai(a2); } +Lmwai.a2: is LsmwRb_ & LsmwRe_ { } +Lmwai.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwai(a3); } +Lmwai.a3: is LsmwRb_ & LsmwRe_ { } +Lmwai.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwai(a4); } +Lmwai.a4: is LsmwRb_ & LsmwRe_ { } +Lmwai.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwai(a5); } +Lmwai.a5: is LsmwRb_ & LsmwRe_ { } +Lmwai.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwai(s0); } +Lmwai.s0: is LsmwRb_ & LsmwRe_ { } +Lmwai.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwai(s1); } +Lmwai.s1: is LsmwRb_ & LsmwRe_ { } +Lmwai.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwai(s2); } +Lmwai.s2: is LsmwRb_ & LsmwRe_ { } +Lmwai.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwai(s3); } +Lmwai.s3: is LsmwRb_ & LsmwRe_ { } +Lmwai.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwai(s4); } +Lmwai.s4: is LsmwRb_ & LsmwRe_ { } +Lmwai.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwai(s5); } +Lmwai.s5: is LsmwRb_ & LsmwRe_ { } +Lmwai.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwai(s6); } +Lmwai.s6: is LsmwRb_ & LsmwRe_ { } +Lmwai.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwai(s7); } +Lmwai.s7: is LsmwRb_ & LsmwRe_ { } +Lmwai.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwai(s8); } +Lmwai.s8: is LsmwRb_ & LsmwRe_ { } +Lmwai.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwai(ta); } +Lmwai.ta: is LsmwRb_ & LsmwRe_ { } +Lmwai.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwai(t0); } +Lmwai.t0: is LsmwRb_ & LsmwRe_ { } +Lmwai.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwai(t1); } +Lmwai.t1: is LsmwRb_ & LsmwRe_ { } +Lmwai.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwai(t2); } +Lmwai.t2: is LsmwRb_ & LsmwRe_ { } +Lmwai.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwai(t3); } +Lmwai.t3: is LsmwRb_ & LsmwRe_ { } +Lmwai.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwai(t4); } +Lmwai.t4: is LsmwRb_ & LsmwRe_ { } +Lmwai.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwai(t5); } +Lmwai.t5: is LsmwRb_ & LsmwRe_ { } +Lmwai.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwai(t6); } +Lmwai.t6: is LsmwRb_ & LsmwRe_ { } +Lmwai.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwai(t7); } +Lmwai.t7: is LsmwRb_ & LsmwRe_ { } +Lmwai.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwai(t8); } +Lmwai.t8: is LsmwRb_ & LsmwRe_ { } +Lmwai.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwai(t9); } +Lmwai.t9: is LsmwRb_ & LsmwRe_ { } +Lmwai.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwai(p0); } +Lmwai.p0: is LsmwRb_ & LsmwRe_ { } +Lmwai.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwai(p1); } +Lmwai.p1: is LsmwRb_ & LsmwRe_ { } +Lmwai.fp: fp is Enable4_fp=1 & fp { Lmwai(fp); } +Lmwai.fp: is Enable4_fp=0 { } +Lmwai.gp: gp is Enable4_gp=1 & gp { Lmwai(gp); } +Lmwai.gp: is Enable4_gp=0 { } +Lmwai.lp: lp is Enable4_lp=1 & lp { Lmwai(lp); } +Lmwai.lp: is Enable4_lp=0 { } +Lmwai.sp: sp is Enable4_sp=1 & sp { Lmwai(sp); } +Lmwai.sp: is Enable4_sp=0 { } + +Lmwad.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwad(a0); } +Lmwad.a0: is LsmwRb_ & LsmwRe_ { } +Lmwad.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwad(a1); } +Lmwad.a1: is LsmwRb_ & LsmwRe_ { } +Lmwad.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwad(a2); } +Lmwad.a2: is LsmwRb_ & LsmwRe_ { } +Lmwad.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwad(a3); } +Lmwad.a3: is LsmwRb_ & LsmwRe_ { } +Lmwad.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwad(a4); } +Lmwad.a4: is LsmwRb_ & LsmwRe_ { } +Lmwad.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwad(a5); } +Lmwad.a5: is LsmwRb_ & LsmwRe_ { } +Lmwad.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwad(s0); } +Lmwad.s0: is LsmwRb_ & LsmwRe_ { } +Lmwad.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwad(s1); } +Lmwad.s1: is LsmwRb_ & LsmwRe_ { } +Lmwad.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwad(s2); } +Lmwad.s2: is LsmwRb_ & LsmwRe_ { } +Lmwad.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwad(s3); } +Lmwad.s3: is LsmwRb_ & LsmwRe_ { } +Lmwad.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwad(s4); } +Lmwad.s4: is LsmwRb_ & LsmwRe_ { } +Lmwad.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwad(s5); } +Lmwad.s5: is LsmwRb_ & LsmwRe_ { } +Lmwad.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwad(s6); } +Lmwad.s6: is LsmwRb_ & LsmwRe_ { } +Lmwad.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwad(s7); } +Lmwad.s7: is LsmwRb_ & LsmwRe_ { } +Lmwad.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwad(s8); } +Lmwad.s8: is LsmwRb_ & LsmwRe_ { } +Lmwad.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwad(ta); } +Lmwad.ta: is LsmwRb_ & LsmwRe_ { } +Lmwad.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwad(t0); } +Lmwad.t0: is LsmwRb_ & LsmwRe_ { } +Lmwad.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwad(t1); } +Lmwad.t1: is LsmwRb_ & LsmwRe_ { } +Lmwad.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwad(t2); } +Lmwad.t2: is LsmwRb_ & LsmwRe_ { } +Lmwad.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwad(t3); } +Lmwad.t3: is LsmwRb_ & LsmwRe_ { } +Lmwad.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwad(t4); } +Lmwad.t4: is LsmwRb_ & LsmwRe_ { } +Lmwad.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwad(t5); } +Lmwad.t5: is LsmwRb_ & LsmwRe_ { } +Lmwad.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwad(t6); } +Lmwad.t6: is LsmwRb_ & LsmwRe_ { } +Lmwad.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwad(t7); } +Lmwad.t7: is LsmwRb_ & LsmwRe_ { } +Lmwad.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwad(t8); } +Lmwad.t8: is LsmwRb_ & LsmwRe_ { } +Lmwad.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwad(t9); } +Lmwad.t9: is LsmwRb_ & LsmwRe_ { } +Lmwad.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwad(p0); } +Lmwad.p0: is LsmwRb_ & LsmwRe_ { } +Lmwad.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwad(p1); } +Lmwad.p1: is LsmwRb_ & LsmwRe_ { } +Lmwad.fp: fp is Enable4_fp=1 & fp { Lmwad(fp); } +Lmwad.fp: is Enable4_fp=0 { } +Lmwad.gp: gp is Enable4_gp=1 & gp { Lmwad(gp); } +Lmwad.gp: is Enable4_gp=0 { } +Lmwad.lp: lp is Enable4_lp=1 & lp { Lmwad(lp); } +Lmwad.lp: is Enable4_lp=0 { } +Lmwad.sp: sp is Enable4_sp=1 & sp { Lmwad(sp); } +Lmwad.sp: is Enable4_sp=0 { } + +Smwbi.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwbi(a0); } +Smwbi.a0: is LsmwRb_ & LsmwRe_ { } +Smwbi.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwbi(a1); } +Smwbi.a1: is LsmwRb_ & LsmwRe_ { } +Smwbi.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwbi(a2); } +Smwbi.a2: is LsmwRb_ & LsmwRe_ { } +Smwbi.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwbi(a3); } +Smwbi.a3: is LsmwRb_ & LsmwRe_ { } +Smwbi.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwbi(a4); } +Smwbi.a4: is LsmwRb_ & LsmwRe_ { } +Smwbi.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwbi(a5); } +Smwbi.a5: is LsmwRb_ & LsmwRe_ { } +Smwbi.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwbi(s0); } +Smwbi.s0: is LsmwRb_ & LsmwRe_ { } +Smwbi.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwbi(s1); } +Smwbi.s1: is LsmwRb_ & LsmwRe_ { } +Smwbi.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwbi(s2); } +Smwbi.s2: is LsmwRb_ & LsmwRe_ { } +Smwbi.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwbi(s3); } +Smwbi.s3: is LsmwRb_ & LsmwRe_ { } +Smwbi.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwbi(s4); } +Smwbi.s4: is LsmwRb_ & LsmwRe_ { } +Smwbi.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwbi(s5); } +Smwbi.s5: is LsmwRb_ & LsmwRe_ { } +Smwbi.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwbi(s6); } +Smwbi.s6: is LsmwRb_ & LsmwRe_ { } +Smwbi.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwbi(s7); } +Smwbi.s7: is LsmwRb_ & LsmwRe_ { } +Smwbi.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwbi(s8); } +Smwbi.s8: is LsmwRb_ & LsmwRe_ { } +Smwbi.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwbi(ta); } +Smwbi.ta: is LsmwRb_ & LsmwRe_ { } +Smwbi.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwbi(t0); } +Smwbi.t0: is LsmwRb_ & LsmwRe_ { } +Smwbi.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwbi(t1); } +Smwbi.t1: is LsmwRb_ & LsmwRe_ { } +Smwbi.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwbi(t2); } +Smwbi.t2: is LsmwRb_ & LsmwRe_ { } +Smwbi.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwbi(t3); } +Smwbi.t3: is LsmwRb_ & LsmwRe_ { } +Smwbi.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwbi(t4); } +Smwbi.t4: is LsmwRb_ & LsmwRe_ { } +Smwbi.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwbi(t5); } +Smwbi.t5: is LsmwRb_ & LsmwRe_ { } +Smwbi.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwbi(t6); } +Smwbi.t6: is LsmwRb_ & LsmwRe_ { } +Smwbi.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwbi(t7); } +Smwbi.t7: is LsmwRb_ & LsmwRe_ { } +Smwbi.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwbi(t8); } +Smwbi.t8: is LsmwRb_ & LsmwRe_ { } +Smwbi.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwbi(t9); } +Smwbi.t9: is LsmwRb_ & LsmwRe_ { } +Smwbi.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwbi(p0); } +Smwbi.p0: is LsmwRb_ & LsmwRe_ { } +Smwbi.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwbi(p1); } +Smwbi.p1: is LsmwRb_ & LsmwRe_ { } +Smwbi.fp: fp is Enable4_fp=1 & fp { Smwbi(fp); } +Smwbi.fp: is Enable4_fp=0 { } +Smwbi.gp: gp is Enable4_gp=1 & gp { Smwbi(gp); } +Smwbi.gp: is Enable4_gp=0 { } +Smwbi.lp: lp is Enable4_lp=1 & lp { Smwbi(lp); } +Smwbi.lp: is Enable4_lp=0 { } +Smwbi.sp: sp is Enable4_sp=1 & sp { Smwbi(sp); } +Smwbi.sp: is Enable4_sp=0 { } + +Smwbd.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwbd(a0); } +Smwbd.a0: is LsmwRb_ & LsmwRe_ { } +Smwbd.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwbd(a1); } +Smwbd.a1: is LsmwRb_ & LsmwRe_ { } +Smwbd.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwbd(a2); } +Smwbd.a2: is LsmwRb_ & LsmwRe_ { } +Smwbd.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwbd(a3); } +Smwbd.a3: is LsmwRb_ & LsmwRe_ { } +Smwbd.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwbd(a4); } +Smwbd.a4: is LsmwRb_ & LsmwRe_ { } +Smwbd.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwbd(a5); } +Smwbd.a5: is LsmwRb_ & LsmwRe_ { } +Smwbd.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwbd(s0); } +Smwbd.s0: is LsmwRb_ & LsmwRe_ { } +Smwbd.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwbd(s1); } +Smwbd.s1: is LsmwRb_ & LsmwRe_ { } +Smwbd.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwbd(s2); } +Smwbd.s2: is LsmwRb_ & LsmwRe_ { } +Smwbd.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwbd(s3); } +Smwbd.s3: is LsmwRb_ & LsmwRe_ { } +Smwbd.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwbd(s4); } +Smwbd.s4: is LsmwRb_ & LsmwRe_ { } +Smwbd.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwbd(s5); } +Smwbd.s5: is LsmwRb_ & LsmwRe_ { } +Smwbd.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwbd(s6); } +Smwbd.s6: is LsmwRb_ & LsmwRe_ { } +Smwbd.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwbd(s7); } +Smwbd.s7: is LsmwRb_ & LsmwRe_ { } +Smwbd.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwbd(s8); } +Smwbd.s8: is LsmwRb_ & LsmwRe_ { } +Smwbd.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwbd(ta); } +Smwbd.ta: is LsmwRb_ & LsmwRe_ { } +Smwbd.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwbd(t0); } +Smwbd.t0: is LsmwRb_ & LsmwRe_ { } +Smwbd.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwbd(t1); } +Smwbd.t1: is LsmwRb_ & LsmwRe_ { } +Smwbd.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwbd(t2); } +Smwbd.t2: is LsmwRb_ & LsmwRe_ { } +Smwbd.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwbd(t3); } +Smwbd.t3: is LsmwRb_ & LsmwRe_ { } +Smwbd.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwbd(t4); } +Smwbd.t4: is LsmwRb_ & LsmwRe_ { } +Smwbd.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwbd(t5); } +Smwbd.t5: is LsmwRb_ & LsmwRe_ { } +Smwbd.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwbd(t6); } +Smwbd.t6: is LsmwRb_ & LsmwRe_ { } +Smwbd.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwbd(t7); } +Smwbd.t7: is LsmwRb_ & LsmwRe_ { } +Smwbd.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwbd(t8); } +Smwbd.t8: is LsmwRb_ & LsmwRe_ { } +Smwbd.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwbd(t9); } +Smwbd.t9: is LsmwRb_ & LsmwRe_ { } +Smwbd.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwbd(p0); } +Smwbd.p0: is LsmwRb_ & LsmwRe_ { } +Smwbd.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwbd(p1); } +Smwbd.p1: is LsmwRb_ & LsmwRe_ { } +Smwbd.fp: fp is Enable4_fp=1 & fp { Smwbd(fp); } +Smwbd.fp: is Enable4_fp=0 { } +Smwbd.gp: gp is Enable4_gp=1 & gp { Smwbd(gp); } +Smwbd.gp: is Enable4_gp=0 { } +Smwbd.lp: lp is Enable4_lp=1 & lp { Smwbd(lp); } +Smwbd.lp: is Enable4_lp=0 { } +Smwbd.sp: sp is Enable4_sp=1 & sp { Smwbd(sp); } +Smwbd.sp: is Enable4_sp=0 { } + +Smwai.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwai(a0); } +Smwai.a0: is LsmwRb_ & LsmwRe_ { } +Smwai.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwai(a1); } +Smwai.a1: is LsmwRb_ & LsmwRe_ { } +Smwai.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwai(a2); } +Smwai.a2: is LsmwRb_ & LsmwRe_ { } +Smwai.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwai(a3); } +Smwai.a3: is LsmwRb_ & LsmwRe_ { } +Smwai.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwai(a4); } +Smwai.a4: is LsmwRb_ & LsmwRe_ { } +Smwai.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwai(a5); } +Smwai.a5: is LsmwRb_ & LsmwRe_ { } +Smwai.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwai(s0); } +Smwai.s0: is LsmwRb_ & LsmwRe_ { } +Smwai.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwai(s1); } +Smwai.s1: is LsmwRb_ & LsmwRe_ { } +Smwai.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwai(s2); } +Smwai.s2: is LsmwRb_ & LsmwRe_ { } +Smwai.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwai(s3); } +Smwai.s3: is LsmwRb_ & LsmwRe_ { } +Smwai.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwai(s4); } +Smwai.s4: is LsmwRb_ & LsmwRe_ { } +Smwai.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwai(s5); } +Smwai.s5: is LsmwRb_ & LsmwRe_ { } +Smwai.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwai(s6); } +Smwai.s6: is LsmwRb_ & LsmwRe_ { } +Smwai.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwai(s7); } +Smwai.s7: is LsmwRb_ & LsmwRe_ { } +Smwai.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwai(s8); } +Smwai.s8: is LsmwRb_ & LsmwRe_ { } +Smwai.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwai(ta); } +Smwai.ta: is LsmwRb_ & LsmwRe_ { } +Smwai.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwai(t0); } +Smwai.t0: is LsmwRb_ & LsmwRe_ { } +Smwai.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwai(t1); } +Smwai.t1: is LsmwRb_ & LsmwRe_ { } +Smwai.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwai(t2); } +Smwai.t2: is LsmwRb_ & LsmwRe_ { } +Smwai.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwai(t3); } +Smwai.t3: is LsmwRb_ & LsmwRe_ { } +Smwai.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwai(t4); } +Smwai.t4: is LsmwRb_ & LsmwRe_ { } +Smwai.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwai(t5); } +Smwai.t5: is LsmwRb_ & LsmwRe_ { } +Smwai.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwai(t6); } +Smwai.t6: is LsmwRb_ & LsmwRe_ { } +Smwai.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwai(t7); } +Smwai.t7: is LsmwRb_ & LsmwRe_ { } +Smwai.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwai(t8); } +Smwai.t8: is LsmwRb_ & LsmwRe_ { } +Smwai.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwai(t9); } +Smwai.t9: is LsmwRb_ & LsmwRe_ { } +Smwai.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwai(p0); } +Smwai.p0: is LsmwRb_ & LsmwRe_ { } +Smwai.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwai(p1); } +Smwai.p1: is LsmwRb_ & LsmwRe_ { } +Smwai.fp: fp is Enable4_fp=1 & fp { Smwai(fp); } +Smwai.fp: is Enable4_fp=0 { } +Smwai.gp: gp is Enable4_gp=1 & gp { Smwai(gp); } +Smwai.gp: is Enable4_gp=0 { } +Smwai.lp: lp is Enable4_lp=1 & lp { Smwai(lp); } +Smwai.lp: is Enable4_lp=0 { } +Smwai.sp: sp is Enable4_sp=1 & sp { Smwai(sp); } +Smwai.sp: is Enable4_sp=0 { } + +Smwad.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwad(a0); } +Smwad.a0: is LsmwRb_ & LsmwRe_ { } +Smwad.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwad(a1); } +Smwad.a1: is LsmwRb_ & LsmwRe_ { } +Smwad.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwad(a2); } +Smwad.a2: is LsmwRb_ & LsmwRe_ { } +Smwad.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwad(a3); } +Smwad.a3: is LsmwRb_ & LsmwRe_ { } +Smwad.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwad(a4); } +Smwad.a4: is LsmwRb_ & LsmwRe_ { } +Smwad.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwad(a5); } +Smwad.a5: is LsmwRb_ & LsmwRe_ { } +Smwad.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwad(s0); } +Smwad.s0: is LsmwRb_ & LsmwRe_ { } +Smwad.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwad(s1); } +Smwad.s1: is LsmwRb_ & LsmwRe_ { } +Smwad.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwad(s2); } +Smwad.s2: is LsmwRb_ & LsmwRe_ { } +Smwad.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwad(s3); } +Smwad.s3: is LsmwRb_ & LsmwRe_ { } +Smwad.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwad(s4); } +Smwad.s4: is LsmwRb_ & LsmwRe_ { } +Smwad.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwad(s5); } +Smwad.s5: is LsmwRb_ & LsmwRe_ { } +Smwad.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwad(s6); } +Smwad.s6: is LsmwRb_ & LsmwRe_ { } +Smwad.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwad(s7); } +Smwad.s7: is LsmwRb_ & LsmwRe_ { } +Smwad.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwad(s8); } +Smwad.s8: is LsmwRb_ & LsmwRe_ { } +Smwad.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwad(ta); } +Smwad.ta: is LsmwRb_ & LsmwRe_ { } +Smwad.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwad(t0); } +Smwad.t0: is LsmwRb_ & LsmwRe_ { } +Smwad.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwad(t1); } +Smwad.t1: is LsmwRb_ & LsmwRe_ { } +Smwad.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwad(t2); } +Smwad.t2: is LsmwRb_ & LsmwRe_ { } +Smwad.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwad(t3); } +Smwad.t3: is LsmwRb_ & LsmwRe_ { } +Smwad.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwad(t4); } +Smwad.t4: is LsmwRb_ & LsmwRe_ { } +Smwad.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwad(t5); } +Smwad.t5: is LsmwRb_ & LsmwRe_ { } +Smwad.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwad(t6); } +Smwad.t6: is LsmwRb_ & LsmwRe_ { } +Smwad.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwad(t7); } +Smwad.t7: is LsmwRb_ & LsmwRe_ { } +Smwad.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwad(t8); } +Smwad.t8: is LsmwRb_ & LsmwRe_ { } +Smwad.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwad(t9); } +Smwad.t9: is LsmwRb_ & LsmwRe_ { } +Smwad.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwad(p0); } +Smwad.p0: is LsmwRb_ & LsmwRe_ { } +Smwad.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwad(p1); } +Smwad.p1: is LsmwRb_ & LsmwRe_ { } +Smwad.fp: fp is Enable4_fp=1 & fp { Smwad(fp); } +Smwad.fp: is Enable4_fp=0 { } +Smwad.gp: gp is Enable4_gp=1 & gp { Smwad(gp); } +Smwad.gp: is Enable4_gp=0 { } +Smwad.lp: lp is Enable4_lp=1 & lp { Smwad(lp); } +Smwad.lp: is Enable4_lp=0 { } +Smwad.sp: sp is Enable4_sp=1 & sp { Smwad(sp); } +Smwad.sp: is Enable4_sp=0 { } + +Lmw.regs: is LsmwBa=0 & LsmwId=0 & Lmwbi.sp & Lmwbi.lp & Lmwbi.gp & Lmwbi.fp & Lmwbi.p1 & Lmwbi.p0 & Lmwbi.t9 & Lmwbi.t8 & Lmwbi.t7 & Lmwbi.t6 & Lmwbi.t5 & Lmwbi.t4 & Lmwbi.t3 & Lmwbi.t2 & Lmwbi.t1 & Lmwbi.t0 & Lmwbi.ta & Lmwbi.s8 & Lmwbi.s7 & Lmwbi.s6 & Lmwbi.s5 & Lmwbi.s4 & Lmwbi.s3 & Lmwbi.s2 & Lmwbi.s1 & Lmwbi.s0 & Lmwbi.a5 & Lmwbi.a4 & Lmwbi.a3 & Lmwbi.a2 & Lmwbi.a1 & Lmwbi.a0 { } +Lmw.regs: is LsmwBa=0 & LsmwId=1 & Lmwbd.a0 & Lmwbd.a1 & Lmwbd.a2 & Lmwbd.a3 & Lmwbd.a4 & Lmwbd.a5 & Lmwbd.s0 & Lmwbd.s1 & Lmwbd.s2 & Lmwbd.s3 & Lmwbd.s4 & Lmwbd.s5 & Lmwbd.s6 & Lmwbd.s7 & Lmwbd.s8 & Lmwbd.ta & Lmwbd.t0 & Lmwbd.t1 & Lmwbd.t2 & Lmwbd.t3 & Lmwbd.t4 & Lmwbd.t5 & Lmwbd.t6 & Lmwbd.t7 & Lmwbd.t8 & Lmwbd.t9 & Lmwbd.p0 & Lmwbd.p1 & Lmwbd.fp & Lmwbd.gp & Lmwbd.lp & Lmwbd.sp { } +Lmw.regs: is LsmwBa=1 & LsmwId=0 & Lmwai.sp & Lmwai.lp & Lmwai.gp & Lmwai.fp & Lmwai.p1 & Lmwai.p0 & Lmwai.t9 & Lmwai.t8 & Lmwai.t7 & Lmwai.t6 & Lmwai.t5 & Lmwai.t4 & Lmwai.t3 & Lmwai.t2 & Lmwai.t1 & Lmwai.t0 & Lmwai.ta & Lmwai.s8 & Lmwai.s7 & Lmwai.s6 & Lmwai.s5 & Lmwai.s4 & Lmwai.s3 & Lmwai.s2 & Lmwai.s1 & Lmwai.s0 & Lmwai.a5 & Lmwai.a4 & Lmwai.a3 & Lmwai.a2 & Lmwai.a1 & Lmwai.a0 { } +Lmw.regs: is LsmwBa=1 & LsmwId=1 & Lmwad.a0 & Lmwad.a1 & Lmwad.a2 & Lmwad.a3 & Lmwad.a4 & Lmwad.a5 & Lmwad.s0 & Lmwad.s1 & Lmwad.s2 & Lmwad.s3 & Lmwad.s4 & Lmwad.s5 & Lmwad.s6 & Lmwad.s7 & Lmwad.s8 & Lmwad.ta & Lmwad.t0 & Lmwad.t1 & Lmwad.t2 & Lmwad.t3 & Lmwad.t4 & Lmwad.t5 & Lmwad.t6 & Lmwad.t7 & Lmwad.t8 & Lmwad.t9 & Lmwad.p0 & Lmwad.p1 & Lmwad.fp & Lmwad.gp & Lmwad.lp & Lmwad.sp { } +Smw.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } +Smw.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } +Smw.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } +Smw.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } +Lmwa.regs: is LsmwBa=0 & LsmwId=0 & Lmwbi.sp & Lmwbi.lp & Lmwbi.gp & Lmwbi.fp & Lmwbi.p1 & Lmwbi.p0 & Lmwbi.t9 & Lmwbi.t8 & Lmwbi.t7 & Lmwbi.t6 & Lmwbi.t5 & Lmwbi.t4 & Lmwbi.t3 & Lmwbi.t2 & Lmwbi.t1 & Lmwbi.t0 & Lmwbi.ta & Lmwbi.s8 & Lmwbi.s7 & Lmwbi.s6 & Lmwbi.s5 & Lmwbi.s4 & Lmwbi.s3 & Lmwbi.s2 & Lmwbi.s1 & Lmwbi.s0 & Lmwbi.a5 & Lmwbi.a4 & Lmwbi.a3 & Lmwbi.a2 & Lmwbi.a1 & Lmwbi.a0 { } +Lmwa.regs: is LsmwBa=0 & LsmwId=1 & Lmwbd.a0 & Lmwbd.a1 & Lmwbd.a2 & Lmwbd.a3 & Lmwbd.a4 & Lmwbd.a5 & Lmwbd.s0 & Lmwbd.s1 & Lmwbd.s2 & Lmwbd.s3 & Lmwbd.s4 & Lmwbd.s5 & Lmwbd.s6 & Lmwbd.s7 & Lmwbd.s8 & Lmwbd.ta & Lmwbd.t0 & Lmwbd.t1 & Lmwbd.t2 & Lmwbd.t3 & Lmwbd.t4 & Lmwbd.t5 & Lmwbd.t6 & Lmwbd.t7 & Lmwbd.t8 & Lmwbd.t9 & Lmwbd.p0 & Lmwbd.p1 & Lmwbd.fp & Lmwbd.gp & Lmwbd.lp & Lmwbd.sp { } +Lmwa.regs: is LsmwBa=1 & LsmwId=0 & Lmwai.sp & Lmwai.lp & Lmwai.gp & Lmwai.fp & Lmwai.p1 & Lmwai.p0 & Lmwai.t9 & Lmwai.t8 & Lmwai.t7 & Lmwai.t6 & Lmwai.t5 & Lmwai.t4 & Lmwai.t3 & Lmwai.t2 & Lmwai.t1 & Lmwai.t0 & Lmwai.ta & Lmwai.s8 & Lmwai.s7 & Lmwai.s6 & Lmwai.s5 & Lmwai.s4 & Lmwai.s3 & Lmwai.s2 & Lmwai.s1 & Lmwai.s0 & Lmwai.a5 & Lmwai.a4 & Lmwai.a3 & Lmwai.a2 & Lmwai.a1 & Lmwai.a0 { } +Lmwa.regs: is LsmwBa=1 & LsmwId=1 & Lmwad.a0 & Lmwad.a1 & Lmwad.a2 & Lmwad.a3 & Lmwad.a4 & Lmwad.a5 & Lmwad.s0 & Lmwad.s1 & Lmwad.s2 & Lmwad.s3 & Lmwad.s4 & Lmwad.s5 & Lmwad.s6 & Lmwad.s7 & Lmwad.s8 & Lmwad.ta & Lmwad.t0 & Lmwad.t1 & Lmwad.t2 & Lmwad.t3 & Lmwad.t4 & Lmwad.t5 & Lmwad.t6 & Lmwad.t7 & Lmwad.t8 & Lmwad.t9 & Lmwad.p0 & Lmwad.p1 & Lmwad.fp & Lmwad.gp & Lmwad.lp & Lmwad.sp { } +Smwa.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } +Smwa.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } +Smwa.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } +Smwa.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.cspec b/Ghidra/Processors/NDS32/data/languages/nds32.cspec new file mode 100644 index 0000000000..8dc06318b2 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32.cspec @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.dwarf b/Ghidra/Processors/NDS32/data/languages/nds32.dwarf new file mode 100644 index 0000000000..b254e363fd --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32.dwarf @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.ldefs b/Ghidra/Processors/NDS32/data/languages/nds32.ldefs new file mode 100644 index 0000000000..80619e45b1 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32.ldefs @@ -0,0 +1,31 @@ + + + + + NDS32 default processor 32-bit big-endian + + + + + NDS32 default processor 32-bit little-endian + + + + + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.opinion b/Ghidra/Processors/NDS32/data/languages/nds32.opinion new file mode 100644 index 0000000000..bf744db132 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32.opinion @@ -0,0 +1,5 @@ + + + + + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.pspec b/Ghidra/Processors/NDS32/data/languages/nds32.pspec new file mode 100644 index 0000000000..dbce6f2f99 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32.pspec @@ -0,0 +1,6 @@ + + + + + + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.sinc b/Ghidra/Processors/NDS32/data/languages/nds32.sinc new file mode 100644 index 0000000000..06083dd57c --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32.sinc @@ -0,0 +1,1081 @@ +### General ### + +define endian=big; +define alignment=2; +define space ram type=ram_space size=4 wordsize=1 default; +define space register type=register_space size=4; + +define register offset=0 size=4 +[a0 a1 a2 a3 a4 a5 s0 s1 s2 s3 s4 s5 s6 s7 s8 ta t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 p0 p1 fp gp lp sp]; + +define register offset=0x90 size=4 +[pc ipc mult_addr mult_inc]; + +define register offset=0x100 size=8 +[d0 d1]; + +define register offset=0x100 size=4 +[d0.hi d0.lo d1.hi d1.lo]; + + + +define token instr32(32) + OpSz = (31, 31) + Opc = (25, 30) + Rt = (20, 24) + Rth = (21, 24) + Rtl = (21, 24) + Ra = (15, 19) + Rb = (10, 14) + Rd = (5, 9) + Rs = (5, 9) + Sub5 = (0, 4) + Sub6 = (0, 5) + Sub8 = (0, 7) + Imm5u = (10, 14) + Imm5s = (10, 14) signed + Br1t = (14, 14) + Br2t = (16, 19) + Alu2Mod = (6, 9) + Dtl = (22, 24) + Dt = (21, 21) + Dtlow = (21, 21) + Dthigh = (21, 21) + Dtr = (20, 20) + JIt = (24, 24) + Imm19s = (0, 18) signed + Imm18s = (0, 17) signed + Imm17s = (0, 16) signed + Imm16s = (0, 15) signed + Imm14s = (0, 13) signed + Imm15u = (0, 14) + Imm15s = (0, 14) signed + Imm20u = (0, 19) + Imm20s = (0, 19) signed + Imm24s = (0, 23) signed + Imm11s = (8, 18) signed + Imm8s = (0, 7) signed + sv = (8, 9) + SrIdx = (10, 19) + Swid = (5, 19) + + CctlZ = (11, 14) + CctlLevel = (10, 10) + CctlSub = (5, 9) + + MsyncZ = (8, 19) + MsyncSub = (5, 7) + + DtIt = (8, 9) + Jz = (6, 7) + JrHint = (5, 5) + + ToggleL = (21, 24) + Toggle = (20, 20) + + Usr = (15, 19) + Group = (10, 14) + + DprefD = (24, 24) + DprefSub = (20, 23) + + TlbopSub = (5, 9) + + StandbyZ = (7, 9) + StandbySub = (5, 6) + + GpSub1 = (19, 19) + GpSub2 = (18, 19) + GpSub3 = (17, 19) + + sh = (5, 9) + + Bxxc = (19, 19) + + LsmwRa = (15, 19) + LsmwRb = (20, 24) + LsmwRb_ = (20, 24) + LsmwRe = (10, 14) + LsmwRe_ = (10, 14) + Enable4 = (6, 9) + Enable4_fp = (9, 9) + Enable4_gp = (8, 8) + Enable4_lp = (7, 7) + Enable4_sp = (6, 6) + LsmwLs = (5, 5) + LsmwBa = (4, 4) + LsmwId = (3, 3) + LsmwM = (2, 2) + LsmwSub = (0, 1) +; + +attach variables [Rt Rs Ra Rb Rd LsmwRa LsmwRb LsmwRe] [ + a0 a1 a2 a3 a4 a5 s0 s1 s2 s3 s4 s5 s6 s7 s8 ta t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 p0 p1 fp gp lp sp +]; + +attach variables [Rtl] [ + a0 a2 a4 s0 s2 s4 s6 s8 t0 t2 t4 t6 t8 p0 fp lp +]; + +attach variables [Rth] [ + a1 a3 a5 s1 s3 s5 s7 ta t1 t3 t5 t7 t9 p1 gp sp +]; + +attach variables [Dt] [ + d0 d1 +]; + +attach variables [Dtlow] [ + d0.lo d1.lo +]; + +attach variables [Dthigh] [ + d0.hi d1.hi +]; + + +@define I32 "(OpSz=0)" +@define ALU_1 "(Opc=0b100000)" +@define ALU_2 "(Opc=0b100001)" +@define ALU2Z "(Alu2Mod=0b0000)" +@define GPR "(Alu2Mod=0b0001)" +@define BR1 "(Opc=0b100110)" +@define BR2 "(Opc=0b100111)" +@define BR3 "(Opc=0b101101)" +@define LSMW "(Opc=0b011101)" +@define JI "(Opc=0b100100)" +@define MEM "(Opc=0b011100)" +@define MISC "(Opc=0b110010)" +@define JREG "(Opc=0b100101)" +@define SBGP "(Opc=0b011111)" +@define LBGP "(Opc=0b010111)" +@define HWGP "(Opc=0b011110)" +@define SIMD "(Opc=0b111000)" + + + +### ALU Instruction with Immediate ### + +:addi Rt, Ra, Imm15s is $(I32) & Opc=0b101000 & Rt & Ra & Imm15s { Rt = Ra + Imm15s; } +:subri Rt, Ra, Imm15s is $(I32) & Opc=0b101001 & Rt & Ra & Imm15s { Rt = Imm15s - Ra; } +:andi Rt, Ra, Imm15u is $(I32) & Opc=0b101010 & Rt & Ra & Imm15u { Rt = Ra & Imm15u; } +:ori Rt, Ra, Imm15u is $(I32) & Opc=0b101100 & Rt & Ra & Imm15u { Rt = Ra | Imm15u; } +:xori Rt, Ra, Imm15u is $(I32) & Opc=0b101011 & Rt & Ra & Imm15u { Rt = Ra ^ Imm15u; } +:slti Rt, Ra, Imm15s is $(I32) & Opc=0b101110 & Rt & Ra & Imm15s { Rt = zext(Ra < Imm15s); } +:sltsi Rt, Ra, Imm15s is $(I32) & Opc=0b101111 & Rt & Ra & Imm15s { Rt = zext(Ra s< Imm15s); } +:movi Rt, Imm20s is $(I32) & Opc=0b100010 & Rt & Imm20s { Rt = Imm20s; } +:sethi Rt, Imm20u is $(I32) & Opc=0b100011 & Rt & Imm20u { Rt = Imm20u << 12;} + + +### ALU Instruction ### + +:add Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00000 { Rt = Ra + Rb; } +:sub Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00001 { Rt = Ra - Rb; } +:and Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00010 { Rt = Ra & Rb; } +:xor Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00011 { Rt = Ra ^ Rb; } +:or Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00100 { Rt = Ra | Rb; } +:nor Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00101 { Rt = ~(Ra | Rb); } +:slt Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00110 { Rt = zext(Ra < Rb); } +:slts Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b00111 { Rt = zext(Ra s< Rb); } +:sva Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b11000 { Rt = zext(scarry(Ra, Rb)); } +:svs Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b11001 { Rt = zext(sborrow(Ra, Rb)); } +:seb Rt, Ra is $(I32) & $(ALU_1) & Rt & Ra & Rb=0b00000 & Rd=0 & Sub5=0b10000 { local tmp = Ra; Rt = sext(tmp:1); } +:seh Rt, Ra is $(I32) & $(ALU_1) & Rt & Ra & Rb=0b00000 & Rd=0 & Sub5=0b10001 { local tmp = Ra; Rt = sext(tmp:2); } +:zeb Rt, Ra is $(I32) & Opc=0b101010 & Rt & Ra & Imm15u=0xff { local tmp = Ra; Rt = zext(tmp:1); } +:zeh Rt, Ra is $(I32) & $(ALU_1) & Rt & Ra & Rb=0b00000 & Rd=0 & Sub5=0b10011 { local tmp = Ra; Rt = zext(tmp:2); } +:wsbh Rt, Ra is $(I32) & $(ALU_1) & Rt & Ra & Rb=0b00000 & Rd=0 & Sub5=0b10100 +{ + Rt = ((Ra & 0x000000ff) << 8) + | ((Ra & 0x0000ff00) >> 8) + | ((Ra & 0x00ff0000) << 8) + | ((Ra & 0xff000000) >> 8); +} + + +### Shifter Instruction ### + +:slli Rt, Ra, Imm5u is $(I32) & $(ALU_1) & Rt & Ra & Imm5u & Rd=0 & Sub5=0b01000 { Rt = Ra << Imm5u; } +:srli Rt, Ra, Imm5u is $(I32) & $(ALU_1) & Rt & Ra & Imm5u & Rd=0 & Sub5=0b01001 { Rt = Ra >> Imm5u; } +:srai Rt, Ra, Imm5u is $(I32) & $(ALU_1) & Rt & Ra & Imm5u & Rd=0 & Sub5=0b01010 { Rt = Ra s>> Imm5u; } +:rotri Rt, Ra, Imm5u is $(I32) & $(ALU_1) & Rt & Ra & Imm5u & Rd=0 & Sub5=0b01011 { Rt = (Ra >> Imm5u) | (Ra << (32 - Imm5u)); } +:sll Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b01100 { tmp:4 = Rb & 0b11111; Rt = Ra << tmp; } +:srl Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b01101 { tmp:4 = Rb & 0b11111; Rt = Ra >> tmp; } +:sra Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b01110 { tmp:4 = Rb & 0b11111; Rt = Ra s>> tmp; } +:rotr Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b01111 { tmp:4 = Rb & 0b11111; Rt = (Ra >> tmp) | (Ra << (32 - tmp)); } + + +### Multiply Instruction ### + +:mul Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(ALU2Z) & Sub6=0b100100 { Rt = Ra * Rb; } +:mults64 Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101000 { Dt = sext(Ra) * sext(Rb); } +:mult64 Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101001 { Dt = zext(Ra) * zext(Rb); } +:madds64 Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101010 { Dt = Dt + (sext(Ra) * sext(Rb)); } +:madd64 Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101011 { Dt = Dt + (zext(Ra) * zext(Rb)); } +:msubs64 Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101100 { Dt = Dt - (sext(Ra) * sext(Rb)); } +:msub64 Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101101 { Dt = Dt - (zext(Ra) * zext(Rb)); } +:mult32 Dtlow, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dtlow & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b110001 { Dtlow = Ra * Rb; } +:madd32 Dtlow, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dtlow & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b110011 { Dtlow = Dtlow + (Ra * Rb); } +:msub32 Dtlow, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dtlow & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b110101 { Dtlow = Dtlow - (Ra * Rb); } + + +# TODO : special instruction, but used get the division results +# There are more special registers +UsrName: d0.lo is Group=0 & Usr=0 & d0.lo { export d0.lo; } +UsrName: d0.hi is Group=0 & Usr=1 & d0.hi { export d0.hi; } +UsrName: d1.lo is Group=0 & Usr=2 & d1.lo { export d1.lo; } +UsrName: d1.hi is Group=0 & Usr=3 & d1.hi { export d1.hi; } + +:mfusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100000 { UsrName = Rt; } +:mtusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100001 { Rt = UsrName; } + + +### Divide Instructions ### + +:div Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtlow & Dthigh & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101111 { Dtlow = Ra / Rb; Dthigh = Ra % Rb; } +:divs Dt, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dt & Dtlow & Dthigh & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b101110 { Dtlow = Ra s/ Rb; Dthigh = Ra s% Rb; } + + +### Load / Store Instruction (immediate) ### + +ByteOffset: off is Imm15s [ off = Imm15s << 0; ] { export *[const]:4 off; } +HalfOffset: off is Imm15s [ off = Imm15s << 1; ] { export *[const]:4 off; } +WordOffset: off is Imm15s [ off = Imm15s << 2; ] { export *[const]:4 off; } + +AddrByteRaImm15s: [Ra + ByteOffset] is Ra & ByteOffset { addr:4 = Ra + ByteOffset; export addr; } +AddrHalfRaImm15s: [Ra + HalfOffset] is Ra & HalfOffset { addr:4 = Ra + HalfOffset; export addr; } +AddrWordRaImm15s: [Ra + WordOffset] is Ra & WordOffset { addr:4 = Ra + WordOffset; export addr; } + +:lwi Rt, AddrWordRaImm15s is $(I32) & Opc=0b000010 & Rt & AddrWordRaImm15s { Rt = *AddrWordRaImm15s; } +:lhi Rt, AddrHalfRaImm15s is $(I32) & Opc=0b000001 & Rt & AddrHalfRaImm15s { local tmp:2 = *AddrHalfRaImm15s; Rt = zext(tmp); } +:lhsi Rt, AddrHalfRaImm15s is $(I32) & Opc=0b010001 & Rt & AddrHalfRaImm15s { local tmp:2 = *AddrHalfRaImm15s; Rt = sext(tmp); } +:lbi Rt, AddrByteRaImm15s is $(I32) & Opc=0b000000 & Rt & AddrByteRaImm15s { local tmp:1 = *AddrByteRaImm15s; Rt = zext(tmp); } +:lbsi Rt, AddrByteRaImm15s is $(I32) & Opc=0b010000 & Rt & AddrByteRaImm15s { local tmp:1 = *AddrByteRaImm15s; Rt = sext(tmp); } +:swi Rt, AddrWordRaImm15s is $(I32) & Opc=0b001010 & Rt & AddrWordRaImm15s { *AddrWordRaImm15s = Rt; } +:shi Rt, AddrHalfRaImm15s is $(I32) & Opc=0b001001 & Rt & AddrHalfRaImm15s { local tmp = Rt; *AddrHalfRaImm15s = tmp:2; } +:sbi Rt, AddrByteRaImm15s is $(I32) & Opc=0b001000 & Rt & AddrByteRaImm15s { local tmp = Rt; *AddrByteRaImm15s = tmp:1; } + +### Load / Store Instruction (immediate, postincr) ### + +:lwi.bi Rt, [Ra], WordOffset is $(I32) & Opc=0b000110 & Rt & Ra & WordOffset { Rt = *Ra; Ra = Ra + WordOffset; } +:lhi.bi Rt, [Ra], HalfOffset is $(I32) & Opc=0b000101 & Rt & Ra & HalfOffset { local tmp:2 = *Ra; Rt = zext(tmp); Ra = Ra + HalfOffset; } +:lhsi.bi Rt, [Ra], HalfOffset is $(I32) & Opc=0b010101 & Rt & Ra & HalfOffset { local tmp:2 = *Ra; Rt = sext(tmp); Ra = Ra + HalfOffset; } +:lbi.bi Rt, [Ra], ByteOffset is $(I32) & Opc=0b000100 & Rt & Ra & ByteOffset { local tmp:1 = *Ra; Rt = zext(tmp); Ra = Ra + ByteOffset; } +:lbsi.bi Rt, [Ra], ByteOffset is $(I32) & Opc=0b010100 & Rt & Ra & ByteOffset { local tmp:1 = *Ra; Rt = sext(tmp); Ra = Ra + ByteOffset; } +:swi.bi Rt, [Ra], WordOffset is $(I32) & Opc=0b001110 & Rt & Ra & WordOffset { *Ra = Rt; Ra = Ra + WordOffset; } +:shi.bi Rt, [Ra], HalfOffset is $(I32) & Opc=0b001101 & Rt & Ra & HalfOffset { local tmp = Rt; *Ra = tmp:2; Ra = Ra + HalfOffset; } +:sbi.bi Rt, [Ra], ByteOffset is $(I32) & Opc=0b001100 & Rt & Ra & ByteOffset { local tmp = Rt; *Ra = tmp:1; Ra = Ra + ByteOffset; } + + +### Load / Store Instruction (register) ### + +OffsetRbsv: (Rb "<<" sv) is Rb & sv { off:4 = Rb << sv; export off; } +AddrRaRbsv: [Ra + OffsetRbsv] is Ra & OffsetRbsv { addr:4 = Ra + OffsetRbsv; export addr; } + +:lw Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00000010 { Rt = *AddrRaRbsv; } +:lh Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00000001 { local tmp:2 = *AddrRaRbsv; Rt = zext(tmp); } +:lhs Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00010001 { local tmp:2 = *AddrRaRbsv; Rt = sext(tmp); } +:lb Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00000000 { local tmp:1 = *AddrRaRbsv; Rt = zext(tmp); } +:lbs Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00010000 { local tmp:1 = *AddrRaRbsv; Rt = sext(tmp); } +:sw Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00001010 { *AddrRaRbsv = Rt; } +:sh Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00001001 { local tmp = Rt; *AddrRaRbsv = tmp:2; } +:sb Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00001000 { local tmp = Rt; *AddrRaRbsv = tmp:1; } + + +### Load / Store Instruction (register, postincr) ### + +:lw.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00000110 { Rt = *Ra; Ra = Ra + OffsetRbsv; } +:lh.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00000101 { local tmp:2 = *Ra; Rt = zext(tmp); Ra = Ra + OffsetRbsv; } +:lhs.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00010101 { local tmp:2 = *Ra; Rt = sext(tmp); Ra = Ra + OffsetRbsv; } +:lb.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00000100 { local tmp:1 = *Ra; Rt = zext(tmp); Ra = Ra + OffsetRbsv; } +:lbs.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00010100 { local tmp:1 = *Ra; Rt = sext(tmp); Ra = Ra + OffsetRbsv; } +:sw.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00001110 { *Ra = Rt; Ra = Ra + OffsetRbsv; } +:sh.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00001101 { local tmp = Rt; *Ra = tmp:2; Ra = Ra + OffsetRbsv; } +:sb.bi Rt, [Ra], OffsetRbsv is $(I32) & $(MEM) & Rt & Ra & OffsetRbsv & Sub8=0b00001100 { local tmp = Rt; *Ra = tmp:1; Ra = Ra + OffsetRbsv; } + + +### Load / Store Multiple Word Instruction ### + +# TODO : this is ugly +@include "lsmw.sinc" + +LsmwBa_: "b" is LsmwBa=0 { } +LsmwBa_: "a" is LsmwBa=1 { } + +LsmwId_: "i" is LsmwId=0 { } +LsmwId_: "d" is LsmwId=1 { } + +LsmwM_: "" is LsmwRa & LsmwM=0 { } +LsmwM_: "m" is LsmwRa & LsmwM=1 { LsmwRa = mult_addr; } + + +:lmw.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=0 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b00 & Lmw.regs +{ + mult_addr = LsmwRa; + build Lmw.regs; + build LsmwM_; +} + +:smw.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=1 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b00 & Smw.regs +{ + mult_addr = LsmwRa; + build Smw.regs; + build LsmwM_; +} + + +### Load / Store Instruction for Atomic Updates ### + +:llw Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00011000 { Rt = *AddrRaRbsv; } +:scw Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00011001 { *AddrRaRbsv = Rt; } + + +### Load / Store Instructions with User-mode Privilege ### + +# TODO : special constraint (user-mode address translation) + +:lwup Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00100010 { Rt = *AddrRaRbsv; } +:swup Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00101010 { *AddrRaRbsv = Rt; } + + +### Jump Instruction ### + +Rel24: addr is Imm24s [ addr = inst_start + (Imm24s << 1); ] { export *:4 addr; } + +:j Rel24 is $(I32) & $(JI) & JIt=0 & Rel24 { goto Rel24; } +:jal Rel24 is $(I32) & $(JI) & JIt=1 & Rel24 { lp = inst_next; call Rel24; } +:jr Rb is $(I32) & $(JREG) & Rt=0 & Ra=0 & Rb & DtIt=0b00 & Jz=0 & JrHint=0 & Sub5=0b00000 { goto [Rb]; } +:ret Rb is $(I32) & $(JREG) & Rt=0 & Ra=0 & Rb & DtIt=0b00 & Jz=0 & JrHint=1 & Sub5=0b00000 { return [Rb]; } +:jral Rt,Rb is $(I32) & $(JREG) & Rt & Ra=0 & Rb & DtIt=0b00 & Jz=0 & JrHint=0 & Sub5=0b00001 { Rt = inst_next; call [Rb]; } + + +### Branch Instruction ### +Rel14: addr is Imm14s [ addr = inst_start + (Imm14s << 1); ] { export *:4 addr; } +Rel16: addr is Imm16s [ addr = inst_start + (Imm16s << 1); ] { export *:4 addr; } + +:beq Rt, Ra, Rel14 is $(I32) & $(BR1) & Rt & Ra & Br1t=0 & Rel14 { if(Rt == Ra) goto Rel14; } +:bne Rt, Ra, Rel14 is $(I32) & $(BR1) & Rt & Ra & Br1t=1 & Rel14 { if(Rt != Ra) goto Rel14; } +:beqz Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b0010 & Rel16 { if(Rt == 0) goto Rel16; } +:bnez Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b0011 & Rel16 { if(Rt != 0) goto Rel16; } +:bgez Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b0100 & Rel16 { if(Rt s>= 0) goto Rel16; } +:bltz Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b0101 & Rel16 { if(Rt s< 0) goto Rel16; } +:bgtz Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b0110 & Rel16 { if(Rt s> 0) goto Rel16; } +:blez Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b0111 & Rel16 { if(Rt s<= 0) goto Rel16; } + + +### Branch with link Instruction ### + +:bgezal Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b1100 & Rel16 +{ + lp = inst_next; + if(Rt s>= 0) goto ; + call Rel16; + +} + +:bltzal Rt, Rel16 is $(I32) & $(BR2) & Rt & Br2t=0b1101 & Rel16 +{ + lp = inst_next; + if(Rt s< 0) goto ; + call Rel16; + +} + + +### Read / Write System Registers ### + +# TODO : special instruction, do we create the system registers ? +define pcodeop mfsr; +define pcodeop mtsr; + +:mfsr Rt, SrIdx is $(I32) & $(MISC) & Rt & SrIdx & Rd=0 & Sub5=0b00010 { Rt = mfsr(SrIdx:4); } +:mtsr Rt, SrIdx is $(I32) & $(MISC) & Rt & SrIdx & Rd=0 & Sub5=0b00011 { mtsr(SrIdx:4, Rt:4); } + + +### Jump Register with System Register Update ### + +# TODO : special constraint (address translation off) + +:jr.itoff Rb is $(I32) & $(JREG) & Rt=0 & Ra=0 & Rb & DtIt=0b01 & Jz=0 & JrHint=0 & Sub5=0b00000 { goto [Rb]; } +:jr.toff Rb is $(I32) & $(JREG) & Rt=0 & Ra=0 & Rb & DtIt=0b11 & Jz=0 & JrHint=0 & Sub5=0b00000 { goto [Rb]; } +:jral.iton Rt,Rb is $(I32) & $(JREG) & Rt & Ra=0 & Rb & DtIt=0b01 & Jz=0 & JrHint=0 & Sub5=0b00001 { Rt = inst_next; call [Rb]; } +:jral.ton Rt,Rb is $(I32) & $(JREG) & Rt & Ra=0 & Rb & DtIt=0b11 & Jz=0 & JrHint=0 & Sub5=0b00001 { Rt = inst_next; call [Rb]; } + + +### MMU Instruction ### + +define pcodeop TLB_TargetRead; +define pcodeop TLB_TargetWrite; +define pcodeop TLB_RWrite; +define pcodeop TLB_RWriteLock; +define pcodeop TLB_Unlock; +define pcodeop TLB_Probe; +define pcodeop TLB_Invalidate; +define pcodeop TLB_FlushAll; + +:tlbop Ra,"TargetRead" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=0 & Sub5=0b01110 { TLB_TargetRead(Ra:4); } +:tlbop Ra,"TargetWrite" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=1 & Sub5=0b01110 { TLB_TargetWrite(Ra:4); } +:tlbop Ra,"RWrite" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=2 & Sub5=0b01110 { TLB_RWrite(Ra:4); } +:tlbop Ra,"RWriteLock" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=3 & Sub5=0b01110 { TLB_RWriteLock(Ra:4); } +:tlbop Ra,"Unlock" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=4 & Sub5=0b01110 { TLB_Unlock(Ra:4); } +:tlbop Rt,Ra,"Probe" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=5 & Sub5=0b01110 { TLB_Probe(Rt:4, Ra:4); } +:tlbop Ra,"Invalidate" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=6 & Sub5=0b01110 { TLB_Invalidate(Ra:4); } +:tlbop "FlushAll" is $(I32) & $(MISC) & Rt & Ra & Rb=0 & TlbopSub=7 & Sub5=0b01110 { TLB_FlushAll(); } + + +### Conditional Move ### + +:cmovz Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b11010 +{ + if(Rb != 0) goto ; + Rt = Ra; + +} + +:cmovn Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b11011 +{ + if(Rb == 0) goto ; + Rt = Ra; + +} + + +### Synchronization Instruction ### + +# TODO : special function, and subfunctions + +define pcodeop msync; +define pcodeop isync; + +:msync MsyncSub is $(I32) & $(MISC) & Rt=0 & MsyncZ=0 & MsyncSub & Sub5=0b01100 { msync(MsyncSub:1); } +:isync Rt is $(I32) & $(MISC) & Rt & Ra=0 & Rb=0 & Rd=0 & Sub5=0b01101 { isync(Rt:4); } + +### Prefetch Instruction ### + +define pcodeop dpref; + +OffsetRbsv2: (Rb "<<" sv) is Rb & sv { off:4 = Rb << (sv + 1); export off; } +AddrRaRbsv2: [Ra + OffsetRbsv2] is Ra & OffsetRbsv2 { addr:4 = Ra + OffsetRbsv2; export addr; } + +:dpref DprefSub, AddrRaRbsv2 is $(I32) & $(MEM) & DprefD=0 & DprefSub & AddrRaRbsv2 & Sub8=0b00010011 { + dpref(DprefSub:1, AddrRaRbsv2:4); +} + +DprefD_: "w" is DprefD=0 { } +DprefD_: "d" is DprefD=1 { } + +DprefiAddr: [Ra + Offset] is DprefD=0 & Ra & Imm15s [ Offset = Imm15s << 2; ] { export *[const]:4 Offset; } +DprefiAddr: [Ra + Offset] is DprefD=1 & Ra & Imm15s [ Offset = Imm15s << 3; ] { export *[const]:4 Offset; } + +:dprefi.^DprefD_ DprefSub, DprefiAddr is $(I32) & Opc=0b010011 & DprefD_ & DprefSub & DprefiAddr { + dpref(DprefSub:1, DprefiAddr:4); +} + + +### NOP Instruction ### + +:nop is $(I32) & $(ALU_1) & Rt=0 & Ra=0 & Imm5u=0 & Rd=0 & Sub5=0b01001 { } + + +### Serialization Instruction ### + +define pcodeop dsb; +define pcodeop isb; + +:dsb is $(I32) & $(MISC) & Rt=0 & Ra=0 & Rb=0 & Rd=0 & Sub5=0b01000 { dsb(); } +:isb is $(I32) & $(MISC) & Rt=0 & Ra=0 & Rb=0 & Rd=0 & Sub5=0b01001 { isb(); } + + +### Exception Generation Instruction ### + +define pcodeop break; +define pcodeop syscall; +define pcodeop trap; + +:break Swid is $(I32) & $(MISC) & Rt=0 & Swid & Sub5=0b01010 { break(Swid:4); } +:syscall Swid is $(I32) & $(MISC) & Rt=0 & Swid & Sub5=0b01011 { syscall(Swid:4); } +:trap Swid is $(I32) & $(MISC) & Rt=0 & Swid & Sub5=0b00101 { trap(Swid:4); } + +:teqz Rt, Swid is $(I32) & $(MISC) & Rt & Swid & Sub5=0b00110 +{ + if(Rt != 0) goto ; + trap(Swid:4); + +} + +:tnez Rt, Swid is $(I32) & $(MISC) & Rt & Swid & Sub5=0b00111 +{ + if(Rt == 0) goto ; + trap(Swid:4); + +} + + +### Special Return Instruction ### + +:iret is $(I32) & $(MISC) & Rt=0 & Ra=0 & Rb=0 & Rd=0 & Sub5=0b00100 { return [ipc]; } + +# TODO : special constraint (address translation off) +:ret.itoff Rb is $(I32) & $(JREG) & Rt=0 & Ra=0 & Rb & DtIt=0b01 & Jz=0 & JrHint=1 & Sub5=0b00000 { return [Rb]; } +:ret.toff Rb is $(I32) & $(JREG) & Rt=0 & Ra=0 & Rb & DtIt=0b11 & Jz=0 & JrHint=1 & Sub5=0b00000 { return [Rb]; } + + +### Cache Control Instruction ### + +# TODO : special function, with subfunctions +define pcodeop cctl; + +:cctl Rt, Ra, CctlLevel, CctlSub is $(I32) & $(MISC) & Rt & Ra & CctlZ=0 & CctlLevel & CctlSub & Sub5=0b00001 { cctl(Rt:4, Ra:4, CctlLevel:1, CctlSub:1); } + + +# Miscellaneous Instructions (Baseline) + +# TODO : special function. Not sure if we use context or registers for this. + +define pcodeop setgie; + +SetgieEN: "d" is Toggle=0 { setgie(0:1); } +SetgieEN: "e" is Toggle=1 { setgie(1:1); } + +:setgie.^SetgieEN is $(I32) & $(MISC) & ToggleL=0 & SetgieEN & SrIdx=0b0010000000 & Rd=0b00010 & Sub5=0b00011 { } + +define pcodeop setend; + +SetendBE: "l" is Toggle=0 { setend(0:1); } +SetendBE: "b" is Toggle=1 { setend(1:1); } + +:setend.^SetendBE is $(I32) & $(MISC) & ToggleL=0 & SetendBE & SrIdx=0b0010000000 & Rd=0b00001 & Sub5=0b00011 { } + +:standby StandbySub is $(I32) & $(MISC) & Rt=0 & Ra=0 & Rb=0 & StandbyZ=0 & StandbySub & Sub5=0b00000 { goto inst_start; } + + + +### 32-bit Baseline V2 instructions ### + +@if defined(BASELINE_V2) + +### ALU Instructions ### + +:addi.gp is $(I32) & $(SBGP) & Rt & GpSub1=0b1 & Imm19s { Rt = gp + Imm19s; } + + +### Multiply and Divide Instructions (V2) ### + +:mulr64 Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(GPR) & Sub6=0b101001 & Rtl & Rth +{ + res:8 = zext(Ra) * zext(Rb); +@if ENDIAN == "big" + Rtl = res(4); + Rth = res:4; +@else + Rtl = res:4; + Rth = res(4); +@endif +} + +:mulsr64 Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(GPR) & Sub6=0b101000 & Rtl & Rth +{ + res:8 = sext(Ra) * sext(Rb); +@if ENDIAN == "big" + Rtl = res(4); + Rth = res:4; +@else + Rtl = res:4; + Rth = res(4); +@endif +} + +:maddr32 Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(GPR) & Sub6=0b110011 { Rt = Rt + (Ra * Rb); } +:msubr32 Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(GPR) & Sub6=0b110101 { Rt = Rt - (Ra * Rb); } +:divr Rt, Rs, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rs & Sub5=0b10111 { local div = Ra / Rb; local mod = Ra % Rb; Rs = mod; Rt = div; } +:divsr Rt, Rs, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rs & Sub5=0b10110 { local div = Ra s/ Rb; local mod = Ra s% Rb; Rs = mod; Rt = div; } + + +### Load/Store Instructions ### + +GpByteAddress: [+ off] is Imm19s [ off = Imm19s << 0; ] { addr:4 = gp + off; export addr; } +GpHalfAddress: [+ off] is Imm18s [ off = Imm18s << 1; ] { addr:4 = gp + off; export addr; } +GpWordAddress: [+ off] is Imm17s [ off = Imm17s << 2; ] { addr:4 = gp + off; export addr; } + +:lbi.gp Rt, GpByteAddress is $(I32) & $(LBGP) & Rt & GpSub1=0b0 & GpByteAddress { local tmp:1 = *GpByteAddress; Rt = zext(tmp); } +:lbsi.gp Rt, GpByteAddress is $(I32) & $(LBGP) & Rt & GpSub1=0b1 & GpByteAddress { local tmp:1 = *GpByteAddress; Rt = sext(tmp); } +:lhi.gp Rt, GpHalfAddress is $(I32) & $(HWGP) & Rt & GpSub2=0b00 & GpHalfAddress { local tmp:2 = *GpHalfAddress; Rt = zext(tmp); } +:lhsi.gp Rt, GpHalfAddress is $(I32) & $(HWGP) & Rt & GpSub2=0b01 & GpHalfAddress { local tmp:2 = *GpHalfAddress; Rt = sext(tmp); } +:lwi.gp Rt, GpWordAddress is $(I32) & $(HWGP) & Rt & GpSub3=0b110 & GpWordAddress { Rt = *GpWordAddress; } +:sbi.gp Rt, GpByteAddress is $(I32) & $(SBGP) & Rt & GpSub1=0b0 & GpByteAddress { local tmp = Rt; *GpByteAddress = tmp:1; } +:shi.gp Rt, GpHalfAddress is $(I32) & $(HWGP) & Rt & GpSub2=0b10 & GpHalfAddress { local tmp = Rt; *GpHalfAddress = tmp:2; } +:swi.gp Rt, GpWordAddress is $(I32) & $(HWGP) & Rt & GpSub3=0b111 & GpWordAddress { *GpWordAddress = Rt; } + +# TODO : same as lmw/smw, this is horrible + +:lmwa.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=0 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b01 & Lmwa.regs +{ + mult_addr = LsmwRa; + build Lmwa.regs; + build LsmwM_; +} + +:smwa.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=1 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b01 & Smwa.regs +{ + mult_addr = LsmwRa; + build Smwa.regs; + build LsmwM_; +} + +:lbup Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00100000 { local tmp:1 = *AddrRaRbsv; Rt = zext(tmp); } +:sbup Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00101000 { local tmp = Rt; *AddrRaRbsv = tmp:1; } + +@endif + + + +### 32-bit Baseline V3 instructions ### + +@if defined(BASELINE_V3) + +### ALU Instructions with Shift Operation (v3) ### + +:add_slli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b00000 { Rt = Ra + (Rb << sh); } +:and_slli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b00010 { Rt = Ra & (Rb << sh); } +:or_slli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b00100 { Rt = Ra | (Rb << sh); } +:sub_slli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b00001 { Rt = Ra - (Rb << sh); } +:xor_slli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b00011 { Rt = Ra ^ (Rb << sh); } + +:add_srli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b11100 { Rt = Ra + (Rb << sh); } +:and_srli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b11110 { Rt = Ra & (Rb << sh); } +:or_srli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b10101 { Rt = Ra | (Rb << sh); } +:sub_srli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b11101 { Rt = Ra - (Rb << sh); } +:xor_srli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b11111 { Rt = Ra ^ (Rb << sh); } + +### Conditional Branch and Jump Instructions (V3) ### + +Rel8: addr is Imm8s [ addr = inst_start + (Imm8s << 1); ] { export *:4 addr; } +:beqc Rt, Imm11s, Rel8 is $(I32) & $(BR3) & Rt & Bxxc=0 & Imm11s & Rel8 { if(Rt == Imm11s) goto Rel8; } +:bnec Rt, Imm11s, Rel8 is $(I32) & $(BR3) & Rt & Bxxc=1 & Imm11s & Rel8 { if(Rt != Imm11s) goto Rel8; } + +:jralnez Rt,Rb is $(I32) & $(JREG) & Rt & Ra=0 & Rb & DtIt=0b00 & Jz=0 & JrHint=0 & Sub5=0b00011 { if(Rb == 0) goto ; Rt = inst_next; call [Rb]; } +:jrnez Rb is $(I32) & $(JREG) & Rt=0 & Ra=0 & Rb & DtIt=0b00 & Jz=0 & JrHint=0 & Sub5=0b00010 { if(Rb == 0) goto ; goto [Rb]; } + +### Bit Manipulation Instructions (V3) ### + +:bitc Rt, Ra, Rb is $(I32) & $(ALU_1) & Rt & Ra & Rb & Rd=0 & Sub5=0b10010 { Rt = Ra & (~Rb); } +:bitci Rt, Ra, Imm15u is $(I32) & Opc=0b110011 & Rt & Ra & Imm15u { Rt = Ra & (~Imm15u); } + +### Cache Control Instruction (V3) ### + +# TODO: Add CCTL L1D_WBALL, level + +@endif + + + +### 32-bit ISA extension ### + +### ALU Instruction (Performance) ### + +@if defined(PERFORMANCE_V1) + +:abs Rt, Ra is $(I32) & $(ALU_2) & Rt & Ra & Rb=0 & $(ALU2Z) & Sub6=0b000011 +{ + gez:4 = zext(Ra s>= 0); + ltz:4 = zext(Ra s< 0); + Rt = (Ra * gez) | ((-Ra) * ltz); +} + +:ave Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(ALU2Z) & Sub6=0b000010 +{ + Rt = (Ra + Rb + 1) s>> 2; +} + +:max Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(ALU2Z) & Sub6=0b000000 +{ + altb:4 = zext(Ra s< Rb); + ageb:4 = zext(Ra s>= Rb); + Rt = (Ra * ageb) | (Rb * altb); +} + +:min Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(ALU2Z) & Sub6=0b000001 +{ + altb:4 = zext(Ra s< Rb); + ageb:4 = zext(Ra s>= Rb); + Rt = (Ra * altb) | (Rb * ageb); +} + +:bset Rt, Ra, Imm5u is $(I32) & $(ALU_2) & Rt & Ra & Imm5u & $(ALU2Z) & Sub6=0b001000 { Rt = Ra | (1 << Imm5u); } +:bclr Rt, Ra, Imm5u is $(I32) & $(ALU_2) & Rt & Ra & Imm5u & $(ALU2Z) & Sub6=0b001001 { Rt = Ra & ~(1 << Imm5u); } +:btgl Rt, Ra, Imm5u is $(I32) & $(ALU_2) & Rt & Ra & Imm5u & $(ALU2Z) & Sub6=0b001010 { Rt = Ra ^ (1 << Imm5u); } +:btst Rt, Ra, Imm5u is $(I32) & $(ALU_2) & Rt & Ra & Imm5u & $(ALU2Z) & Sub6=0b001011 { Rt = (Ra >> Imm5u) & 1; } + +:clips Rt, Ra, Imm5u is $(I32) & $(ALU_2) & Rt & Ra & Imm5u & $(ALU2Z) & Sub6=0b000100 +{ + local upper:4 = (1 << Imm5u) - 1; + local lower:4 = -(1 << Imm5u); + if(Ra s<= upper) goto ; + Rt = upper; + goto ; + + if(Ra s>= lower) goto ; + Rt = lower; + goto ; + + Rt = Ra; + +} +:clip Rt, Ra, Imm5u is $(I32) & $(ALU_2) & Rt & Ra & Imm5u & $(ALU2Z) & Sub6=0b000101 +{ + local upper:4 = (1 << Imm5u) - 1; + if(Ra s<= upper) goto ; + Rt = upper; + goto ; + + if(Ra s>= 0) goto ; + Rt = 0; + goto ; + + Rt = Ra; + +} + +:clz Rt, Ra is $(I32) & $(ALU_2) & Rt & Ra & Imm5u=0 & $(ALU2Z) & Sub6=0b000111 +{ + countTmp:4 = 0; + inputTmp:4 = Ra; + + + if ((inputTmp & 0x80000000) != 0) goto ; + + countTmp = countTmp + 1; + inputTmp = (inputTmp << 1) | 1; + goto ; + + + Rt = countTmp; +} + +:clo Rt, Ra is $(I32) & $(ALU_2) & Rt & Ra & Imm5u=0 & $(ALU2Z) & Sub6=0b000110 +{ + countTmp:4 = 0; + inputTmp:4 = Ra; + + + if ((inputTmp & 0x80000000) == 0) goto ; + + countTmp = countTmp + 1; + inputTmp = (inputTmp << 1) | 1; + goto ; + + + Rt = countTmp; +} + +@endif + + +### Performance Extension V2 ### + +@if defined(PERFORMANCE_V2) + +# TODO : arithmetic functions: bs* +:bse is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(ALU2Z) & Sub6=0b001100 unimpl +:bsp is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(ALU2Z) & Sub6=0b001101 unimpl + +macro add_abs_diff(dst, src1, src2, shift) +{ + local src1_ = src1 >> shift; + local src2_ = src2 >> shift; + local src1__ = src1_:1; + local src2__ = src2_:1; + local a:1 = src1__ - src2__; + local agez:1 = zext(a s>= 0); + local altz:1 = zext(a s< 0); + local aabs:1 = (a * agez) | ((-a) * altz); + dst = dst + zext(aabs); +} +:pbsad Rt, Ra, Rb is $(I32) & $(SIMD) & Rt & Ra & Rb & Rd=0 & Sub5=0b0000 +{ + Rt = 0; + add_abs_diff(Rt, Ra, Rb, 0); + add_abs_diff(Rt, Ra, Rb, 8); + add_abs_diff(Rt, Ra, Rb, 16); + add_abs_diff(Rt, Ra, Rb, 24); +} +:pbsada Rt, Ra, Rb is $(I32) & $(SIMD) & Rt & Ra & Rb & Rd=0 & Sub5=0b0001 +{ + add_abs_diff(Rt, Ra, Rb, 0); + add_abs_diff(Rt, Ra, Rb, 8); + add_abs_diff(Rt, Ra, Rb, 16); + add_abs_diff(Rt, Ra, Rb, 24); +} + +@endif + + + + +########### 16b ############ + +define token instr16(16) + opsz = (15, 15) + opc4 = (11, 14) + opc5 = (10, 14) + opc6 = (9, 14) + opc7 = (8, 14) + opc8 = (7, 14) + opc10 = (5, 14) + re2 = (5, 6) + rt5 = (5, 9) + ra4 = (5, 8) + rt4 = (5, 8) + ra5 = (0, 4) + rb5 = (0, 4) + rt5b = (0, 4) + rt3 = (6, 8) + rt3b = (8, 10) + ra3 = (3, 5) + rb3 = (0, 2) + imm3u = (0, 2) + imm3ub = (3, 5) + imm5u = (0, 4) + imm5s = (0, 4) signed + imm6u = (0, 5) + imm7u = (0, 6) + imm8s = (0, 7) signed + imm10s = (0, 9) signed + xwi37_ls = (7, 7) + swid9 = (0, 8) + rt5e1 = (4, 7) + rt5e2 = (4, 7) + ra5e1 = (0, 3) + ra5e2 = (0, 3) +; + +attach variables [rt5 ra5 rb5 rt5b] [ + a0 a1 a2 a3 a4 a5 s0 s1 s2 s3 s4 s5 s6 s7 s8 ta t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 p0 p1 fp gp lp sp +]; + +attach variables [ra4 rt4] [ + a0 a1 a2 a3 a4 a5 s0 s1 s2 s3 s4 s5 t0 t1 t2 t3 +]; + +attach variables [rt3 ra3 rt3b rb3] [ + a0 a1 a2 a3 a4 a5 s0 s1 +]; + +attach variables [ra5e1 rt5e1] [ + a0 a2 a4 s0 s2 s4 s6 s8 t0 t2 t4 t6 t8 p0 fp lp +]; +attach variables [ra5e2 rt5e2] [ + a1 a3 a5 s1 s3 s5 s7 ta t1 t3 t5 t7 t9 p1 gp sp +]; + +attach variables [re2] [ + s0 s2 s4 s8 +]; + + +@define I16 "(opsz=1)" +@define BFMI333 "(opc6=0b001011)" +@define XWI37 "(opc4=0b0111)" +@define XWI37SP "(opc4=0b1110)" +@define MISC33 "(opc6=0b111111)" + + +### Move Instruction ### + +:movi55 rt5, imm5s is $(I16) & opc5=0b00001 & rt5 & imm5s { rt5 = imm5s; } +:mov55 rt5, ra5 is $(I16) & opc5=0b00000 & rt5 & ra5 { rt5 = ra5; } + + +### Add/Sub Instruction with Immediate ### + +:addi45 rt4, imm5u is $(I16) & opc6=0b000110 & rt4 & imm5u { rt4 = rt4 + imm5u; } +:addi333 rt3, ra3, imm3u is $(I16) & opc6=0b001110 & rt3 & ra3 & imm3u { rt3 = ra3 + imm3u; } +:subi45 rt4, imm5u is $(I16) & opc6=0b000111 & rt4 & imm5u { rt4 = rt4 - imm5u; } +:subi333 rt3, ra3, imm3u is $(I16) & opc6=0b001111 & rt3 & ra3 & imm3u { rt3 = ra3 - imm3u; } + + +### Add/Sub Instruction ### + +:add45 rt4, rb5 is $(I16) & opc6=0b000100 & rt4 & rb5 { rt4 = rt4 + rb5; } +:add333 rt3, ra3, rb3 is $(I16) & opc6=0b001100 & rt3 & ra3 & rb3 { rt3 = ra3 + rb3; } +:sub45 rt4, rb5 is $(I16) & opc6=0b000101 & rt4 & rb5 { rt4 = rt4 - rb5; } +:sub333 rt3, ra3, rb3 is $(I16) & opc6=0b001101 & rt3 & ra3 & rb3 { rt3 = ra3 - rb3; } + + +### Shift Instruction with Immediate ### + +:srai45 rt4, imm5u is $(I16) & opc6=0b001000 & rt4 & imm5u { rt4 = rt4 s>> imm5u; } +:srli45 rt4, imm5u is $(I16) & opc6=0b001001 & rt4 & imm5u { rt4 = rt4 >> imm5u; } +:slli333 rt3, ra3, imm3u is $(I16) & opc6=0b001010 & rt3 & ra3 & imm3u { rt3 = ra3 << imm3u; } + + +### Bit Field Mask Instruction with Immediate ### + +:zeb33 rt3, ra3 is $(I16) & $(BFMI333) & rt3 & ra3 & imm3u=0b000 { local tmp = ra3; rt3 = zext(tmp:1); } +:zeh33 rt3, ra3 is $(I16) & $(BFMI333) & rt3 & ra3 & imm3u=0b001 { local tmp = ra3; rt3 = zext(tmp:2); } +:seb33 rt3, ra3 is $(I16) & $(BFMI333) & rt3 & ra3 & imm3u=0b010 { local tmp = ra3; rt3 = sext(tmp:1); } +:seh33 rt3, ra3 is $(I16) & $(BFMI333) & rt3 & ra3 & imm3u=0b011 { local tmp = ra3; rt3 = sext(tmp:2); } +:xlsb33 rt3, ra3 is $(I16) & $(BFMI333) & rt3 & ra3 & imm3u=0b100 { rt3 = ra3 & 1; } +:x11b33 rt3, ra3 is $(I16) & $(BFMI333) & rt3 & ra3 & imm3u=0b101 { rt3 = ra3 & 0x7ff; } + + +### Load / Store Instruction ### + +:lwi450 rt4,[ra5] is $(I16) & opc6=0b011010 & rt4 & ra5 { rt4 = *ra5; } + +rel3w: off is imm3u [ off = imm3u << 2; ] { export *[const]:4 off; } +rel3h: off is imm3u [ off = imm3u << 1; ] { export *[const]:4 off; } +rel3b: off is imm3u [ off = imm3u << 0 ; ] { export *[const]:4 off; } +ra3_rel3w: [ra3 + rel3w] is ra3 & rel3w { addr:4 = ra3 + rel3w; export addr; } +ra3_rel3h: [ra3 + rel3h] is ra3 & rel3h { addr:4 = ra3 + rel3h; export addr; } +ra3_rel3b: [ra3 + rel3b] is ra3 & rel3b { addr:4 = ra3 + rel3b; export addr; } + +:lwi333 rt3, ra3_rel3w is $(I16) & opc6=0b010000 & rt3 & ra3_rel3w { rt3 = *ra3_rel3w; } +:lwi333.bi rt3, [ra3], rel3w is $(I16) & opc6=0b010001 & rt3 & ra3 & rel3w { rt3 = *ra3; ra3 = ra3 + rel3w; } +:lhi333 rt3, ra3_rel3h is $(I16) & opc6=0b010010 & rt3 & ra3_rel3h { local tmp:2 = *ra3_rel3h; rt3 = zext(tmp); } +:lbi333 rt3, ra3_rel3b is $(I16) & opc6=0b010011 & rt3 & ra3_rel3b { local tmp:1 = *ra3_rel3b; rt3 = zext(tmp); } +:swi450 rt4, [ra5] is $(I16) & opc6=0b011011 & rt4 & ra5 { *ra5 = rt4; } +:swi333 rt3, ra3_rel3w is $(I16) & opc6=0b010100 & rt3 & ra3_rel3w { *ra3_rel3w = rt3; } +:swi333.bi rt3, [ra3], rel3w is $(I16) & opc6=0b010101 & rt3 & ra3 & rel3w { *ra3 = rt3; ra3 = ra3 + rel3w; } +:shi333 rt3, ra3_rel3h is $(I16) & opc6=0b010110 & rt3 & ra3_rel3h { local tmp = rt3; *ra3_rel3h = tmp:2; } +:sbi333 rt3, ra3_rel3b is $(I16) & opc6=0b010111 & rt3 & ra3_rel3b { local tmp = rt3; *ra3_rel3b = tmp:1; } + + +### Load/Store Instruction with Implied FP ### + +rel7w: off is imm7u [ off = imm7u << 2; ] { export *[const]:4 off; } +fp_rel7w: [fp + rel7w] is fp & rel7w { addr:4 = fp + rel7w; export addr; } + +:lwi37 rt3b, fp_rel7w is $(I16) & rt3b & $(XWI37) & xwi37_ls=0 & fp_rel7w { rt3b = *fp_rel7w; } +:swi37 rt3b, fp_rel7w is $(I16) & rt3b & $(XWI37) & xwi37_ls=1 & fp_rel7w { *fp_rel7w = rt3b; } + + +### Branch and Jump Instruction ### + +rel8: addr is imm8s [ addr = inst_start + (imm8s << 1); ] { export *:4 addr; } + + +:beqs38 rt3b,rel8 is $(I16) & opc4=0b1010 & rt3b & rel8 { if(a5 == rt3b) goto rel8; } +:bnes38 rt3b,rel8 is $(I16) & opc4=0b1011 & rt3b & rel8 { if(a5 != rt3b) goto rel8; } +:beqz38 rt3b,rel8 is $(I16) & opc4=0b1000 & rt3b & rel8 { if(rt3b == 0) goto rel8; } +:bnez38 rt3b,rel8 is $(I16) & opc4=0b1001 & rt3b & rel8 { if(rt3b != 0) goto rel8; } + +:j8 rel8 is $(I16) & opc7=0b1010101 & rel8 { goto rel8; } +:jr5 rb5 is $(I16) & opc10=0b1011101000 & rb5 { goto [rb5]; } +:ret5 rb5 is $(I16) & opc10=0b1011101100 & rb5 { return [rb5]; } +:jral5 rb5 is $(I16) & opc10=0b1011101001 & rb5 { lp = inst_next; call [rb5]; } + + +### Compare and Branch Instruction ### + +:slti45 ra4, imm5u is $(I16) & opc6=0b110011 & ra4 & imm5u { ta = zext(ra4 < imm5u); } +:sltsi45 ra4, imm5u is $(I16) & opc6=0b110010 & ra4 & imm5u { ta = zext(ra4 s< imm5u); } +:slt45 ra4, rb5 is $(I16) & opc6=0b110001 & ra4 & rb5 { ta = zext(ra4 < rb5); } +:slts45 ra4, rb5 is $(I16) & opc6=0b110000 & ra4 & rb5 { ta = zext(ra4 s< rb5); } + +:beqzs8 rel8 is $(I16) & opc7=0b1101000 & rel8 { if(ta == 0) goto rel8; } +:bnezs8 rel8 is $(I16) & opc7=0b1101001 & rel8 { if(ta != 0) goto rel8; } + + +### Misc Instruction ### + +:break16 swid9 is $(I16) & opc6=0b110101 & swid9 { break(swid9:4); } +:nop16 is $(I16) & opc6=0b001001 & rt4=0b0000 & imm5u=0b00000 { } + + +### ALU Instructions (V2) ### + +@if defined(BASELINE_V2) + +:addi10.sp imm10s is $(I16) & opc5=0b11011 & imm10s { sp = sp + imm10s; } + + +### Load/Store Instruction (V2) ### + +sp_rel7w: [+ rel7w] is rel7w { addr:4 = sp + rel7w; export addr; } + +:lwi37.sp rt3b, sp_rel7w is $(I16) & rt3b & $(XWI37SP) & xwi37_ls=0 & sp_rel7w { rt3b = *sp_rel7w; } +:swi37.sp rt3b, sp_rel7w is $(I16) & rt3b & $(XWI37SP) & xwi37_ls=1 & sp_rel7w { *sp_rel7w = rt3b; } + +@endif + + + +### 16-bit Baseline V3 instructions ### + +@if defined(BASELINE_V3) + +### ALU Instructions (V3 16-bit) ### + +imm6u_: imm8 is imm6u [ imm8 = imm6u << 2; ] { export *[const]:4 imm8; } +:addri36.sp rt3, imm6u_ is $(I16) & opc6=0b011000 & rt3 & imm6u_ { rt3 = sp + imm6u_; } +:add5.pc rt5b is $(I16) & opc10=0b1011101101 & rt5b { rt5b = pc + rt5b; } +:and33 rt3, ra3 is $(I16) & $(MISC33) & rt3 & ra3 & imm3u=0b110 { rt3 = rt3 & ra3; } +:neg33 rt3, ra3 is $(I16) & $(MISC33) & rt3 & ra3 & imm3u=0b010 { rt3 = -ra3; } +:not33 rt3, ra3 is $(I16) & $(MISC33) & rt3 & ra3 & imm3u=0b011 { rt3 = ~ra3; } +:or33 rt3, ra3 is $(I16) & $(MISC33) & rt3 & ra3 & imm3u=0b111 { rt3 = rt3 | ra3; } +:xor33 rt3, ra3 is $(I16) & $(MISC33) & rt3 & ra3 & imm3u=0b101 { rt3 = rt3 ^ ra3; } + +### Bit Manipulation Instructions (V3 16-bit) ### + +:bmski33 rt3, imm3ub is $(I16) & opc6=0b001011 & rt3 & imm3ub & imm3u=0b110 { rt3 = (rt3 >> imm3ub) & 1; } +:fexti33 rt3, imm3ub is $(I16) & opc6=0b001011 & rt3 & imm3ub & imm3u=0b111 { rt3 = rt3 & ((1 << (imm3ub + 1)) - 1); } + +### Misc. Instructions (V3 16-bit) ### + +imm7n: off is imm5u [ off = -((32 - imm5u) << 2); ] { export *[const]:4 off; } +:lwi45.fe rt4, [imm7n] is $(I16) & opc6=0b011001 & rt4 & imm7n { addr:4 = s2 + imm7n; rt4 = *addr; } + +:movd44 rt5e1, ra5e1 is $(I16) & opc7=0b1111101 & rt5e1 & rt5e2 & ra5e1 & ra5e2 { rt5e1 = ra5e1; rt5e2 = ra5e2; } + +imm5u_: imm6 is imm5u [ imm6 = imm5u + 16; ] { export *[const]:4 imm6; } +:movpi45 rt4, imm5u_ is $(I16) & opc6=0b111101 & rt4 & imm5u_ { rt4 = imm5u_; } + +:mul33 rt3, ra3 is $(I16) & $(MISC33) & rt3 & ra3 & imm3u=0b100 { rt3 = rt3 * ra3; } + +# Note: POP25 and PUSH25 are highly untested ! And they just look messy :/ +imm5u__: imm8 is imm5u [ imm8 = imm5u << 3; ] { export *[const]:4 imm8; } + +macro push25_special() { Smwad(lp); Smwad(gp); Smwad(fp); } +macro push25_s0() { Smwad(s0); } +macro push25_s2() { Smwad(s2); Smwad(s1); push25_s0(); } +macro push25_s4() { Smwad(s4); Smwad(s3); push25_s2(); } +macro push25_s8() { Smwad(s8); Smwad(s7); Smwad(s6); Smwad(s5); push25_s4(); } + +push25_re: re2 is re2 & re2=0 { push25_s0(); } +push25_re: re2 is re2 & re2=1 { push25_s2(); } +push25_re: re2 is re2 & re2=2 { push25_s4(); } +push25_re: re2 is re2 & re2=3 { push25_s8(); } + +:push25 push25_re, imm5u__ is $(I16) & opc8=0b11111000 & re2 & push25_re & imm5u__ { + mult_addr = sp; + push25_special(); + build push25_re; + sp = mult_addr - imm5u__; + if(re2 < 1) goto ; + s2 = pc & 0xfffffffc; + +} + +macro pop25_special() { Lmwbi(fp); Lmwbi(gp); Lmwbi(lp); } +macro pop25_s0() { Lmwbi(s0); } +macro pop25_s2() { pop25_s0(); Lmwbi(s1); Lmwbi(s2); } +macro pop25_s4() { pop25_s2(); Lmwbi(s3); Lmwbi(s4); } +macro pop25_s8() { pop25_s4(); Lmwbi(s5); Lmwbi(s6); Lmwbi(s7); Lmwbi(s8); } + +pop25_re: re2 is re2 & re2=0 { pop25_s0(); } +pop25_re: re2 is re2 & re2=1 { pop25_s2(); } +pop25_re: re2 is re2 & re2=2 { pop25_s4(); } +pop25_re: re2 is re2 & re2=3 { pop25_s8(); } + +:pop25 pop25_re, imm5u__ is $(I16) & opc8=0b11111001 & re2 & pop25_re & imm5u__ { + mult_addr = sp; + build pop25_re; + pop25_special(); + sp = mult_addr + imm5u__; + return [lp]; +} + + +@endif + + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec b/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec new file mode 100644 index 0000000000..40714ad394 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec @@ -0,0 +1,7 @@ +@define BASELINE_V2 "yes" +@define BASELINE_V3 "yes" +@define PERFORMANCE_V1 "yes" +@define PERFORMANCE_V2 "yes" +@define ENDIAN "big" + +@include "nds32.sinc" diff --git a/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec b/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec new file mode 100644 index 0000000000..ee6a1b9c48 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec @@ -0,0 +1,7 @@ +@define BASELINE_V2 "yes" +@define BASELINE_V3 "yes" +@define PERFORMANCE_V1 "yes" +@define PERFORMANCE_V2 "yes" +@define ENDIAN "little" + +@include "nds32.sinc" diff --git a/Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml b/Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml new file mode 100644 index 0000000000..5cbde241f9 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml @@ -0,0 +1,13 @@ + + + + 0xd5 ........ + 0x48 ........ ........ ........ + 0x92 0x00 + + + 0011101. ....1111 1......0 .0111100 + + + + diff --git a/Ghidra/Processors/NDS32/data/patterns/patternconstraints.xml b/Ghidra/Processors/NDS32/data/patterns/patternconstraints.xml new file mode 100644 index 0000000000..735a59bec2 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/patterns/patternconstraints.xml @@ -0,0 +1,5 @@ + + + nds32_patterns.xml + + diff --git a/Ghidra/Processors/NDS32/data/sleighArgs.txt b/Ghidra/Processors/NDS32/data/sleighArgs.txt new file mode 100644 index 0000000000..ce06926358 --- /dev/null +++ b/Ghidra/Processors/NDS32/data/sleighArgs.txt @@ -0,0 +1,6 @@ +# Add sleigh compiler options to this file (one per line) which will +# be used when compiling each language within this module. +# All options should start with a '-' character. +# +# IMPORTANT: The -a option should NOT be specified +# \ No newline at end of file diff --git a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.java b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.java new file mode 100644 index 0000000000..b054561c04 --- /dev/null +++ b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.java @@ -0,0 +1,187 @@ +package ghidra.app.plugin.core.analysis; + +import java.math.BigInteger; + +import ghidra.app.util.importer.MessageLog; +import ghidra.framework.options.Options; +import ghidra.program.model.address.Address; +import ghidra.program.model.address.AddressSet; +import ghidra.program.model.address.AddressSetView; +import ghidra.program.model.lang.Processor; +import ghidra.program.model.lang.Register; +import ghidra.program.model.lang.RegisterValue; +import ghidra.program.model.listing.ContextChangeException; +import ghidra.program.model.listing.Function; +import ghidra.program.model.listing.Instruction; +import ghidra.program.model.listing.Program; +import ghidra.program.model.listing.ProgramContext; +import ghidra.program.model.symbol.FlowType; +import ghidra.program.model.symbol.Symbol; +import ghidra.program.model.symbol.SymbolUtilities; +import ghidra.program.util.ContextEvaluator; +import ghidra.program.util.SymbolicPropogator; +import ghidra.program.util.VarnodeContext; +import ghidra.util.Msg; +import ghidra.util.exception.AssertException; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.TaskMonitor; + +public class NDS32Analyzer extends ConstantPropagationAnalyzer { + private final static String PROCESSOR_NAME = "NDS32"; + + private static final String SWITCH_OPTION_NAME = "Switch Table Recovery"; + private static final String SWITCH_OPTION_DESCRIPTION = "Turn on to recover switch tables (not implemented yet !)"; + private static final boolean SWITCH_OPTION_DEFAULT_VALUE = false; + + private static final String RECOVER_GP_OPTION_NAME = "Recover global GP register writes"; + private static final String RECOVER_GP_OPTION_DESCRIPTION = "Reads the global GP value from the symbol _SDA_BASE_"; + private static final boolean RECOVER_GP_OPTION_DEFAULT_VALUE = true; + + + private boolean recoverSwitchTables = SWITCH_OPTION_DEFAULT_VALUE; + private boolean recoverGp = RECOVER_GP_OPTION_DEFAULT_VALUE; + + private Address gpAssumptionValue = null; + + private Register gp; + + public NDS32Analyzer() { + super(PROCESSOR_NAME); + } + + @Override + public boolean canAnalyze(Program program) { + boolean canAnalyze = program.getLanguage().getProcessor().equals( + Processor.findOrPossiblyCreateProcessor(PROCESSOR_NAME)); + + if (!canAnalyze) { + return false; + } + + gp = program.getRegister("gp"); + + return true; + } + + @Override + public void optionsChanged(Options options, Program program) { + super.optionsChanged(options, program); + + options.registerOption(SWITCH_OPTION_NAME, recoverSwitchTables, null, + SWITCH_OPTION_DESCRIPTION); + recoverSwitchTables = options.getBoolean(SWITCH_OPTION_NAME, recoverSwitchTables); + + options.registerOption(RECOVER_GP_OPTION_NAME, recoverGp, null, + RECOVER_GP_OPTION_DESCRIPTION); + recoverGp = options.getBoolean(RECOVER_GP_OPTION_NAME, recoverGp); + } + + @Override + public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log) + throws CancelledException { + gpAssumptionValue = null; + + checkForGlobalGP(program, set, monitor); + + return super.added(program, set, monitor, log); + } + + /** + * Check for a global GP register symbol or discovered symbol + * @param set + */ + private void checkForGlobalGP(Program program, AddressSetView set, TaskMonitor monitor) { + if (!recoverGp) { + return; + } + + Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(program, "_SDA_BASE_", + err -> Msg.error(this, err)); + if (symbol != null) { + gpAssumptionValue = symbol.getAddress(); + return; + } + + // TODO : if the symbol doesn't exist, check manually... somewhere else + + return; + } + + @Override + public AddressSetView flowConstants(final Program program, Address flowStart, + AddressSetView flowSet, final SymbolicPropogator symEval, final TaskMonitor monitor) + throws CancelledException { + + // get the function body + final Function func = program.getFunctionManager().getFunctionContaining(flowStart); + + final AddressSet coveredSet = new AddressSet(); + + Address currentGPAssumptionValue = gpAssumptionValue; + + // TODO : copypaste more code from MipsAddressAnalyzer to see if gp is written and act accordingly + if (func != null) { + flowStart = func.getEntryPoint(); + if (currentGPAssumptionValue != null) { + ProgramContext programContext = program.getProgramContext(); + RegisterValue gpVal = programContext.getRegisterValue(gp, flowStart); + if (gpVal == null || !gpVal.hasValue()) { + gpVal = new RegisterValue(gp, + BigInteger.valueOf(currentGPAssumptionValue.getOffset())); + try { + program.getProgramContext().setRegisterValue(func.getEntryPoint(), + func.getEntryPoint(), gpVal); + } + catch (ContextChangeException e) { + throw new AssertException("unexpected", e); // only happens for context register + } + } + } + } + + ContextEvaluator eval = new ConstantPropagationContextEvaluator(trustWriteMemOption) { + @Override + public boolean evaluateDestination(VarnodeContext context, Instruction instruction) { + FlowType flowtype = instruction.getFlowType(); + if (!flowtype.isJump()) { + return false; + } + + if (recoverSwitchTables) { + String mnemonic = instruction.getMnemonicString(); + if (mnemonic.equals("jr")) { + fixJumpTable(program, instruction, monitor); + } + } + + return false; + } + }; + + AddressSet resultSet = symEval.flowConstants(flowStart, null, eval, true, monitor); + + // Add in any addresses we should assume got covered + // These addresses are put on because we had to stop analysis due to an unknown register value + resultSet.add(coveredSet); + + return resultSet; + } + + /** + * @param program + * @param startInstr + * @param monitor + */ + private void fixJumpTable(Program program, Instruction startInstr, TaskMonitor monitor) { + /* TODO: implement switch recovery ? + * We are looking for tables like this : + * + * slti45 a0,0x4 <- table size + * beqzs8 LAB_005159ea <- default jump + * sethi ta, 0x515 + * ori ta, ta, 0x9a0 + * lw a0, [ta + (a0 << 0x2)] <- ref to table + * jr a0 <- table jump + */ + } +} diff --git a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java new file mode 100644 index 0000000000..5f5bea65d4 --- /dev/null +++ b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java @@ -0,0 +1,74 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public class NDS32_ElfRelocationConstants { + public static final int R_NDS32_NONE = 0; + public static final int R_NDS32_16_RELA = 19; + public static final int R_NDS32_32_RELA = 20; + public static final int R_NDS32_9_PCREL_RELA = 22; + public static final int R_NDS32_15_PCREL_RELA = 23; + public static final int R_NDS32_17_PCREL_RELA = 24; + public static final int R_NDS32_25_PCREL_RELA = 25; + public static final int R_NDS32_HI20_RELA = 26; + public static final int R_NDS32_LO12S3_RELA = 27; + public static final int R_NDS32_LO12S2_RELA = 28; + public static final int R_NDS32_LO12S1_RELA = 29; + public static final int R_NDS32_LO12S0_RELA = 30; + public static final int R_NDS32_SDA15S3_RELA = 31; + public static final int R_NDS32_SDA15S2_RELA = 32; + public static final int R_NDS32_SDA15S1_RELA = 33; + public static final int R_NDS32_SDA15S0_RELA = 34; + public static final int R_NDS32_GOT20 = 37; + public static final int R_NDS32_25_PLTREL = 38; + public static final int R_NDS32_COPY = 39; + public static final int R_NDS32_GLOB_DAT = 40; + public static final int R_NDS32_JMP_SLOT = 41; + public static final int R_NDS32_RELATIVE = 42; + public static final int R_NDS32_GOTOFF = 43; + public static final int R_NDS32_GOTPC20 = 44; + public static final int R_NDS32_GOT_HI20 = 45; + public static final int R_NDS32_GOT_LO12 = 46; + public static final int R_NDS32_GOTPC_HI20 = 47; + public static final int R_NDS32_GOTPC_LO12 = 48; + public static final int R_NDS32_GOTOFF_HI20 = 49; + public static final int R_NDS32_GOTOFF_LO12 = 50; + public static final int R_NDS32_INSN16 = 51; + public static final int R_NDS32_LABEL = 52; + public static final int R_NDS32_LONGCALL1 = 53; + public static final int R_NDS32_LONGCALL2 = 54; + public static final int R_NDS32_LONGCALL3 = 55; + public static final int R_NDS32_LONGJUMP1 = 56; + public static final int R_NDS32_LONGJUMP2 = 57; + public static final int R_NDS32_LONGJUMP3 = 58; + public static final int R_NDS32_LOADSTORE = 59; + public static final int R_NDS32_9_FIXED_RELA = 60; + public static final int R_NDS32_15_FIXED_RELA = 61; + public static final int R_NDS32_17_FIXED_RELA = 62; + public static final int R_NDS32_25_FIXED_RELA = 63; + public static final int R_NDS32_PLTREL_HI20 = 64; + public static final int R_NDS32_PLTREL_LO12 = 65; + public static final int R_NDS32_PLT_GOTREL_HI20 = 66; + public static final int R_NDS32_PLT_GOTREL_LO12 = 67; + public static final int R_NDS32_LO12S0_ORI_RELA = 72; + public static final int R_NDS32_DWARF2_OP1_RELA = 77; + public static final int R_NDS32_DWARF2_OP2_RELA = 78; + public static final int R_NDS32_DWARF2_LEB_RELA = 79; + public static final int R_NDS32_WORD_9_PCREL_RELA = 94; + public static final int R_NDS32_LONGCALL4 = 107; + public static final int R_NDS32_RELA_NOP_MIX = 192; + public static final int R_NDS32_RELA_NOP_MAX = 255; +} diff --git a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java new file mode 100644 index 0000000000..0d1f660454 --- /dev/null +++ b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java @@ -0,0 +1,111 @@ +/* ### + * 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 java.util.Map; +import ghidra.app.util.bin.format.elf.ElfConstants; +import ghidra.app.util.bin.format.elf.ElfHeader; +import ghidra.app.util.bin.format.elf.ElfLoadHelper; +import ghidra.app.util.bin.format.elf.ElfRelocation; +import ghidra.app.util.bin.format.elf.ElfRelocationTable; +import ghidra.app.util.bin.format.elf.ElfSymbol; +import ghidra.app.util.importer.MessageLog; +import ghidra.program.model.address.Address; +import ghidra.program.model.address.AddressOutOfBoundsException; +import ghidra.program.model.listing.Program; +import ghidra.program.model.mem.Memory; +import ghidra.program.model.mem.MemoryAccessException; +import ghidra.util.exception.NotFoundException; + +public class NDS32_ElfRelocationHandler extends ElfRelocationHandler { + + @Override + public boolean canRelocate(ElfHeader elf) { + return elf.e_machine() == ElfConstants.EM_NDS32; + } + + @Override + public NDS32_ElfRelocationContext createRelocationContext(ElfLoadHelper loadHelper, + ElfRelocationTable relocationTable, Map symbolMap) { + return new NDS32_ElfRelocationContext(this, loadHelper, relocationTable, symbolMap); + } + + @Override + public void relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress) + throws MemoryAccessException, NotFoundException { + ElfHeader elf = elfRelocationContext.getElfHeader(); + + if (elf.e_machine() != ElfConstants.EM_NDS32) { + return; + } + + if (!elf.is32Bit()) { + return; + } + + NDS32_ElfRelocationContext nds32RelocationContext = + (NDS32_ElfRelocationContext) elfRelocationContext; + + int type = relocation.getType(); + int symbolIndex = relocation.getSymbolIndex(); + doRelocate(nds32RelocationContext, type, symbolIndex, relocation, relocationAddress); + } + + private void doRelocate(NDS32_ElfRelocationContext nds32RelocationContext, int relocType, + int symbolIndex, ElfRelocation relocation, Address relocationAddress) + throws MemoryAccessException, NotFoundException, AddressOutOfBoundsException { + Program program = nds32RelocationContext.getProgram(); + Memory memory = program.getMemory(); + MessageLog log = nds32RelocationContext.getLog(); + ElfSymbol elfSymbol = nds32RelocationContext.getSymbol(symbolIndex); + long symbolValue = nds32RelocationContext.getSymbolValue(elfSymbol); + String symbolName = elfSymbol.getNameAsString(); + + // Read instruction as big endian + int oldValue = memory.getInt(relocationAddress, true); + + long addend = 0; + if(relocation.hasAddend()) { + addend = relocation.getAddend(); + } + + int value = 0; + int newValue = 0; + + switch(relocType) { + case NDS32_ElfRelocationConstants.R_NDS32_HI20_RELA: + value = (int)(symbolValue + addend); + newValue = (oldValue & 0xfff00000) | (value >> 12); + memory.setInt(relocationAddress, newValue, true); + break; + case NDS32_ElfRelocationConstants.R_NDS32_LO12S0_RELA: + value = (int)(symbolValue + addend); + newValue = (oldValue & 0xfffff000) | (value & 0xfff); + memory.setInt(relocationAddress, newValue, true); + break; + default: + markAsUnhandled(program, relocationAddress, relocType, symbolIndex, symbolName, log); + } + } + + private static class NDS32_ElfRelocationContext extends ElfRelocationContext { + + protected NDS32_ElfRelocationContext(ElfRelocationHandler handler, ElfLoadHelper loadHelper, + ElfRelocationTable relocationTable, Map symbolMap) { + super(handler, loadHelper, relocationTable, symbolMap); + } + } +} diff --git a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java new file mode 100644 index 0000000000..34e2b8ecde --- /dev/null +++ b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java @@ -0,0 +1,41 @@ +/* ### + * 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; + +import junit.framework.Test; + +public class NDS32_LE_O0_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "NDS32:LE:32:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public NDS32_LE_O0_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "NDS32LE_GCC_O0"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_LE_O0_EmulatorTest.class); + } +} diff --git a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java new file mode 100644 index 0000000000..d90c855ed4 --- /dev/null +++ b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java @@ -0,0 +1,41 @@ +/* ### + * 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; + +import junit.framework.Test; + +public class NDS32_LE_O3_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "NDS32:LE:32:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public NDS32_LE_O3_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "NDS32LE_GCC_O3"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_LE_O3_EmulatorTest.class); + } +} From 71cd33572c873b1eebd322032506c259632d0d52 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Mon, 22 Sep 2025 14:37:16 +0000 Subject: [PATCH 2/7] GP-6007: Updated NDS32 analyzer and elf relocation handler and test fixups --- .../pcodetest/c_src/misc_BODY.c | 8 + .../SleighDevTools/pcodetest/defaults.py | 12 +- .../SleighDevTools/pcodetest/pcode_defs.py | 15 +- .../SleighDevTools/pcodetest/pcodetest.py | 9 +- Ghidra/Processors/NDS32/build.gradle | 15 + .../Processors/NDS32/certification.manifest | 13 + .../Processors/NDS32/data/buildLanguage.xml | 50 -- .../Processors/NDS32/data/languages/lsmw.sinc | 687 ++++-------------- .../NDS32/data/languages/nds32.cspec | 11 +- .../NDS32/data/languages/nds32.sinc | 190 +++-- .../NDS32/data/languages/nds32be.slaspec | 4 - .../NDS32/data/languages/nds32le.slaspec | 4 - Ghidra/Processors/NDS32/data/sleighArgs.txt | 6 - .../plugin/core/analysis/NDS32Analyzer.java | 53 +- .../NDS32_ElfRelocationConstants.java | 74 -- .../NDS32_ElfRelocationHandler.java | 77 +- .../relocation/NDS32_ElfRelocationType.java | 195 +++++ .../processors/NDS32_BE_O0_EmulatorTest.java | 41 ++ .../processors/NDS32_BE_O3_EmulatorTest.java | 41 ++ .../processors/NDS32_LE_O0_EmulatorTest.java | 4 +- .../processors/NDS32_LE_O3_EmulatorTest.java | 4 +- 21 files changed, 671 insertions(+), 842 deletions(-) create mode 100644 Ghidra/Processors/NDS32/certification.manifest delete mode 100644 Ghidra/Processors/NDS32/data/buildLanguage.xml delete mode 100644 Ghidra/Processors/NDS32/data/sleighArgs.txt delete mode 100644 Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java create mode 100644 Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationType.java create mode 100644 Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O0_EmulatorTest.java create mode 100644 Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O3_EmulatorTest.java diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc_BODY.c b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc_BODY.c index 131404c87f..4120b125e2 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc_BODY.c +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc_BODY.c @@ -16,6 +16,14 @@ #include "pcode_test.h" #include "big_struct.h" +#ifdef HAS_LIBC +#include +#else +void *memset(void *b, int c, size_t len); +void *memcpy(void *dst, const void *src, size_t n); +int memcmp(const void *s1, const void *s2, size_t n); +#endif + static i4 int_expectedValue; static i4 int_actualValue; diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py b/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py index 91cd62de33..94f4982b7d 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py @@ -47,12 +47,14 @@ pcodeTestDefaults.has_vector = 0 pcodeTestDefaults.small_build = 0 pcodeTestDefaults.ld_library_path = '' pcodeTestDefaults.toolchain_type = 'gcc' -pcodeTestDefaults.compile_exe = 'bin/gcc' -pcodeTestDefaults.objdump_exe = 'bin/objdump' +pcodeTestDefaults.compile_exe = 'gcc' +pcodeTestDefaults.objdump_exe = 'objdump' pcodeTestDefaults.objdump_option = '' -pcodeTestDefaults.readelf_exe = 'bin/readelf' -pcodeTestDefaults.nm_exe = 'bin/nm' -pcodeTestDefaults.strip_exe = 'bin/strip' +pcodeTestDefaults.readelf_exe = 'readelf' +pcodeTestDefaults.exec_dir = 'bin/' +pcodeTestDefaults.exec_prefix = '' +pcodeTestDefaults.nm_exe = 'nm' +pcodeTestDefaults.strip_exe = 'strip' pcodeTestDefaults.variants = {'O0': '-O0', 'O3': '-O3'} pcodeTestDefaults.proc_test = '' pcodeTestDefaults.force = False diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py index 6c9ddaa373..0e70268d34 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py @@ -436,7 +436,7 @@ PCodeTest({ 'name': 'NDS32BE', 'build_all': 1, 'toolchain': 'NDS32/nds32be-elf', - 'ccflags': '', + 'ccflags': '-mbig-endian', 'cclibs': '-lgcc', 'language_id': 'NDS32:BE:32:default', }) @@ -444,9 +444,20 @@ PCodeTest({ PCodeTest({ 'name': 'NDS32LE', 'build_all': 1, - 'toolchain': 'NDS32/nds32le-elf', + 'toolchain': 'NDS32/nds32le-elf',#'NDS32/nds32le-linux-glibc-v5d', + 'ccflags': '-mlittle-endian -EL', + 'cclibs': '-lgcc', + 'language_id': 'NDS32:LE:32:default', +}) + +PCodeTest({ + 'name': 'NDS32AS', + 'build_all': 1, + 'toolchain': 'NDS32/nds32le-elf-mculib-v3s', + 'exec_prefix': 'nds32le-elf-', 'ccflags': '', 'cclibs': '-lgcc', + 'gcc_version': '12.2.0', 'language_id': 'NDS32:LE:32:default', }) diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py b/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py index 76a48ef3ba..1bdde635d8 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py @@ -88,7 +88,13 @@ class PCodeTestBuild(BuildUtil): def main(self): # make sure compiler exists and runnable - + self.config.compile_exe = self.config.exec_dir + self.config.exec_prefix + self.config.compile_exe + self.config.build_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.build_exe) + self.config.strip_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.strip_exe) + self.config.objdump_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.objdump_exe) + self.config.readelf_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.readelf_exe) + self.config.nm_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.nm_exe) + if not self.is_executable_file(self.which('compile_exe')): self.log_err(self.config.format('build the Toolchain before compilation')) return @@ -427,6 +433,7 @@ class PCodeBuildGCC(PCodeTestBuild): self.set_library_path(self.config.ld_library_path) # Construct the compile/link command line and execute it + cmp = self.which('compile_exe') cmd = [cmp] + input_files + self.cflags(output_file) + [opt_cflag, '-B', self.dirname(cmp), '-o', output_file] out, err = self.run(cmd) diff --git a/Ghidra/Processors/NDS32/build.gradle b/Ghidra/Processors/NDS32/build.gradle index 6d9b72ae40..360bb9e8ba 100644 --- a/Ghidra/Processors/NDS32/build.gradle +++ b/Ghidra/Processors/NDS32/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/jacocoProject.gradle" diff --git a/Ghidra/Processors/NDS32/certification.manifest b/Ghidra/Processors/NDS32/certification.manifest new file mode 100644 index 0000000000..cec7eed86b --- /dev/null +++ b/Ghidra/Processors/NDS32/certification.manifest @@ -0,0 +1,13 @@ +##VERSION: 2.0 +Module.manifest||GHIDRA||||END| +data/languages/lsmw.sinc||GHIDRA||||END| +data/languages/nds32.cspec||GHIDRA||||END| +data/languages/nds32.dwarf||GHIDRA||||END| +data/languages/nds32.ldefs||GHIDRA||||END| +data/languages/nds32.opinion||GHIDRA||||END| +data/languages/nds32.pspec||GHIDRA||||END| +data/languages/nds32.sinc||GHIDRA||||END| +data/languages/nds32be.slaspec||GHIDRA||||END| +data/languages/nds32le.slaspec||GHIDRA||||END| +data/patterns/nds32_patterns.xml||GHIDRA||||END| +data/patterns/patternconstraints.xml||GHIDRA||||END| diff --git a/Ghidra/Processors/NDS32/data/buildLanguage.xml b/Ghidra/Processors/NDS32/data/buildLanguage.xml deleted file mode 100644 index 1e2a6276bc..0000000000 --- a/Ghidra/Processors/NDS32/data/buildLanguage.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Ghidra/Processors/NDS32/data/languages/lsmw.sinc b/Ghidra/Processors/NDS32/data/languages/lsmw.sinc index 2953e445d1..3ac5595315 100644 --- a/Ghidra/Processors/NDS32/data/languages/lsmw.sinc +++ b/Ghidra/Processors/NDS32/data/languages/lsmw.sinc @@ -1,576 +1,139 @@ -macro Lmwbi(reg) { - reg = *mult_addr; - mult_addr = mult_addr + 4; -} - -macro Lmwbd(reg) { - reg = *mult_addr; - mult_addr = mult_addr - 4; -} - -macro Lmwai(reg) { - mult_addr = mult_addr + 4; - reg = *mult_addr; -} - -macro Lmwad(reg) { - mult_addr = mult_addr - 4; - reg = *mult_addr; -} - -macro Smwbi(reg) { - *mult_addr = reg; - mult_addr = mult_addr + 4; -} - -macro Smwbd(reg) { - *mult_addr = reg; - mult_addr = mult_addr - 4; -} - -macro Smwai(reg) { - mult_addr = mult_addr + 4; - *mult_addr = reg; -} +Dreg: a0 is a0 & regNum=0 { export a0; } +Dreg: a1 is a1 & regNum=1 { export a1; } +Dreg: a2 is a2 & regNum=2 { export a2; } +Dreg: a3 is a3 & regNum=3 { export a3; } +Dreg: a4 is a4 & regNum=4 { export a4; } +Dreg: a5 is a5 & regNum=5 { export a5; } +Dreg: s0 is s0 & regNum=6 { export s0; } +Dreg: s1 is s1 & regNum=7 { export s1; } +Dreg: s2 is s2 & regNum=8 { export s2; } +Dreg: s3 is s3 & regNum=9 { export s3; } +Dreg: s4 is s4 & regNum=10 { export s4; } +Dreg: s5 is s5 & regNum=11 { export s5; } +Dreg: s6 is s6 & regNum=12 { export s6; } +Dreg: s7 is s7 & regNum=13 { export s7; } +Dreg: s8 is s8 & regNum=14 { export s8; } +Dreg: ta is ta & regNum=15 { export ta; } +Dreg: t0 is t0 & regNum=16 { export t0; } +Dreg: t1 is t1 & regNum=17 { export t1; } +Dreg: t2 is t2 & regNum=18 { export t2; } +Dreg: t3 is t3 & regNum=19 { export t3; } +Dreg: t4 is t4 & regNum=20 { export t4; } +Dreg: t5 is t5 & regNum=21 { export t5; } +Dreg: t6 is t6 & regNum=22 { export t6; } +Dreg: t7 is t7 & regNum=23 { export t7; } +Dreg: t8 is t8 & regNum=24 { export t8; } +Dreg: t9 is t9 & regNum=25 { export t9; } +Dreg: p0 is p0 & regNum=26 { export p0; } +Dreg: p1 is p1 & regNum=27 { export p1; } +Dreg: fp is fp & regNum=28 { export fp; } +Dreg: gp is gp & regNum=29 { export gp; } +Dreg: lp is lp & regNum=30 { export lp; } +Dreg: sp is sp & regNum=31 { export sp; } macro Smwad(reg) { mult_addr = mult_addr - 4; *mult_addr = reg; } -Lmwbi.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwbi(a0); } -Lmwbi.a0: is LsmwRb_ & LsmwRe_ { } -Lmwbi.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwbi(a1); } -Lmwbi.a1: is LsmwRb_ & LsmwRe_ { } -Lmwbi.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwbi(a2); } -Lmwbi.a2: is LsmwRb_ & LsmwRe_ { } -Lmwbi.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwbi(a3); } -Lmwbi.a3: is LsmwRb_ & LsmwRe_ { } -Lmwbi.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwbi(a4); } -Lmwbi.a4: is LsmwRb_ & LsmwRe_ { } -Lmwbi.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwbi(a5); } -Lmwbi.a5: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwbi(s0); } -Lmwbi.s0: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwbi(s1); } -Lmwbi.s1: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwbi(s2); } -Lmwbi.s2: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwbi(s3); } -Lmwbi.s3: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwbi(s4); } -Lmwbi.s4: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwbi(s5); } -Lmwbi.s5: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwbi(s6); } -Lmwbi.s6: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwbi(s7); } -Lmwbi.s7: is LsmwRb_ & LsmwRe_ { } -Lmwbi.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwbi(s8); } -Lmwbi.s8: is LsmwRb_ & LsmwRe_ { } -Lmwbi.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwbi(ta); } -Lmwbi.ta: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwbi(t0); } -Lmwbi.t0: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwbi(t1); } -Lmwbi.t1: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwbi(t2); } -Lmwbi.t2: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwbi(t3); } -Lmwbi.t3: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwbi(t4); } -Lmwbi.t4: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwbi(t5); } -Lmwbi.t5: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwbi(t6); } -Lmwbi.t6: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwbi(t7); } -Lmwbi.t7: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwbi(t8); } -Lmwbi.t8: is LsmwRb_ & LsmwRe_ { } -Lmwbi.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwbi(t9); } -Lmwbi.t9: is LsmwRb_ & LsmwRe_ { } -Lmwbi.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwbi(p0); } -Lmwbi.p0: is LsmwRb_ & LsmwRe_ { } -Lmwbi.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwbi(p1); } -Lmwbi.p1: is LsmwRb_ & LsmwRe_ { } -Lmwbi.fp: fp is Enable4_fp=1 & fp { Lmwbi(fp); } -Lmwbi.fp: is Enable4_fp=0 { } -Lmwbi.gp: gp is Enable4_gp=1 & gp { Lmwbi(gp); } -Lmwbi.gp: is Enable4_gp=0 { } -Lmwbi.lp: lp is Enable4_lp=1 & lp { Lmwbi(lp); } -Lmwbi.lp: is Enable4_lp=0 { } -Lmwbi.sp: sp is Enable4_sp=1 & sp { Lmwbi(sp); } -Lmwbi.sp: is Enable4_sp=0 { } +macro LmwOp(reg) { + reg = *mult_addr; +} -Lmwbd.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwbd(a0); } -Lmwbd.a0: is LsmwRb_ & LsmwRe_ { } -Lmwbd.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwbd(a1); } -Lmwbd.a1: is LsmwRb_ & LsmwRe_ { } -Lmwbd.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwbd(a2); } -Lmwbd.a2: is LsmwRb_ & LsmwRe_ { } -Lmwbd.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwbd(a3); } -Lmwbd.a3: is LsmwRb_ & LsmwRe_ { } -Lmwbd.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwbd(a4); } -Lmwbd.a4: is LsmwRb_ & LsmwRe_ { } -Lmwbd.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwbd(a5); } -Lmwbd.a5: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwbd(s0); } -Lmwbd.s0: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwbd(s1); } -Lmwbd.s1: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwbd(s2); } -Lmwbd.s2: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwbd(s3); } -Lmwbd.s3: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwbd(s4); } -Lmwbd.s4: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwbd(s5); } -Lmwbd.s5: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwbd(s6); } -Lmwbd.s6: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwbd(s7); } -Lmwbd.s7: is LsmwRb_ & LsmwRe_ { } -Lmwbd.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwbd(s8); } -Lmwbd.s8: is LsmwRb_ & LsmwRe_ { } -Lmwbd.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwbd(ta); } -Lmwbd.ta: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwbd(t0); } -Lmwbd.t0: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwbd(t1); } -Lmwbd.t1: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwbd(t2); } -Lmwbd.t2: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwbd(t3); } -Lmwbd.t3: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwbd(t4); } -Lmwbd.t4: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwbd(t5); } -Lmwbd.t5: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwbd(t6); } -Lmwbd.t6: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwbd(t7); } -Lmwbd.t7: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwbd(t8); } -Lmwbd.t8: is LsmwRb_ & LsmwRe_ { } -Lmwbd.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwbd(t9); } -Lmwbd.t9: is LsmwRb_ & LsmwRe_ { } -Lmwbd.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwbd(p0); } -Lmwbd.p0: is LsmwRb_ & LsmwRe_ { } -Lmwbd.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwbd(p1); } -Lmwbd.p1: is LsmwRb_ & LsmwRe_ { } -Lmwbd.fp: fp is Enable4_fp=1 & fp { Lmwbd(fp); } -Lmwbd.fp: is Enable4_fp=0 { } -Lmwbd.gp: gp is Enable4_gp=1 & gp { Lmwbd(gp); } -Lmwbd.gp: is Enable4_gp=0 { } -Lmwbd.lp: lp is Enable4_lp=1 & lp { Lmwbd(lp); } -Lmwbd.lp: is Enable4_lp=0 { } -Lmwbd.sp: sp is Enable4_sp=1 & sp { Lmwbd(sp); } -Lmwbd.sp: is Enable4_sp=0 { } +macro SmwOp(reg) { + *mult_addr = reg; +} -Lmwai.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwai(a0); } -Lmwai.a0: is LsmwRb_ & LsmwRe_ { } -Lmwai.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwai(a1); } -Lmwai.a1: is LsmwRb_ & LsmwRe_ { } -Lmwai.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwai(a2); } -Lmwai.a2: is LsmwRb_ & LsmwRe_ { } -Lmwai.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwai(a3); } -Lmwai.a3: is LsmwRb_ & LsmwRe_ { } -Lmwai.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwai(a4); } -Lmwai.a4: is LsmwRb_ & LsmwRe_ { } -Lmwai.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwai(a5); } -Lmwai.a5: is LsmwRb_ & LsmwRe_ { } -Lmwai.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwai(s0); } -Lmwai.s0: is LsmwRb_ & LsmwRe_ { } -Lmwai.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwai(s1); } -Lmwai.s1: is LsmwRb_ & LsmwRe_ { } -Lmwai.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwai(s2); } -Lmwai.s2: is LsmwRb_ & LsmwRe_ { } -Lmwai.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwai(s3); } -Lmwai.s3: is LsmwRb_ & LsmwRe_ { } -Lmwai.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwai(s4); } -Lmwai.s4: is LsmwRb_ & LsmwRe_ { } -Lmwai.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwai(s5); } -Lmwai.s5: is LsmwRb_ & LsmwRe_ { } -Lmwai.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwai(s6); } -Lmwai.s6: is LsmwRb_ & LsmwRe_ { } -Lmwai.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwai(s7); } -Lmwai.s7: is LsmwRb_ & LsmwRe_ { } -Lmwai.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwai(s8); } -Lmwai.s8: is LsmwRb_ & LsmwRe_ { } -Lmwai.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwai(ta); } -Lmwai.ta: is LsmwRb_ & LsmwRe_ { } -Lmwai.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwai(t0); } -Lmwai.t0: is LsmwRb_ & LsmwRe_ { } -Lmwai.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwai(t1); } -Lmwai.t1: is LsmwRb_ & LsmwRe_ { } -Lmwai.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwai(t2); } -Lmwai.t2: is LsmwRb_ & LsmwRe_ { } -Lmwai.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwai(t3); } -Lmwai.t3: is LsmwRb_ & LsmwRe_ { } -Lmwai.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwai(t4); } -Lmwai.t4: is LsmwRb_ & LsmwRe_ { } -Lmwai.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwai(t5); } -Lmwai.t5: is LsmwRb_ & LsmwRe_ { } -Lmwai.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwai(t6); } -Lmwai.t6: is LsmwRb_ & LsmwRe_ { } -Lmwai.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwai(t7); } -Lmwai.t7: is LsmwRb_ & LsmwRe_ { } -Lmwai.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwai(t8); } -Lmwai.t8: is LsmwRb_ & LsmwRe_ { } -Lmwai.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwai(t9); } -Lmwai.t9: is LsmwRb_ & LsmwRe_ { } -Lmwai.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwai(p0); } -Lmwai.p0: is LsmwRb_ & LsmwRe_ { } -Lmwai.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwai(p1); } -Lmwai.p1: is LsmwRb_ & LsmwRe_ { } -Lmwai.fp: fp is Enable4_fp=1 & fp { Lmwai(fp); } -Lmwai.fp: is Enable4_fp=0 { } -Lmwai.gp: gp is Enable4_gp=1 & gp { Lmwai(gp); } -Lmwai.gp: is Enable4_gp=0 { } -Lmwai.lp: lp is Enable4_lp=1 & lp { Lmwai(lp); } -Lmwai.lp: is Enable4_lp=0 { } -Lmwai.sp: sp is Enable4_sp=1 & sp { Lmwai(sp); } -Lmwai.sp: is Enable4_sp=0 { } +macro MwDec() { mult_addr = mult_addr - 4; } +macro MwInc() { mult_addr = mult_addr + 4; } -Lmwad.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Lmwad(a0); } -Lmwad.a0: is LsmwRb_ & LsmwRe_ { } -Lmwad.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Lmwad(a1); } -Lmwad.a1: is LsmwRb_ & LsmwRe_ { } -Lmwad.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Lmwad(a2); } -Lmwad.a2: is LsmwRb_ & LsmwRe_ { } -Lmwad.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Lmwad(a3); } -Lmwad.a3: is LsmwRb_ & LsmwRe_ { } -Lmwad.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Lmwad(a4); } -Lmwad.a4: is LsmwRb_ & LsmwRe_ { } -Lmwad.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Lmwad(a5); } -Lmwad.a5: is LsmwRb_ & LsmwRe_ { } -Lmwad.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Lmwad(s0); } -Lmwad.s0: is LsmwRb_ & LsmwRe_ { } -Lmwad.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Lmwad(s1); } -Lmwad.s1: is LsmwRb_ & LsmwRe_ { } -Lmwad.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Lmwad(s2); } -Lmwad.s2: is LsmwRb_ & LsmwRe_ { } -Lmwad.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Lmwad(s3); } -Lmwad.s3: is LsmwRb_ & LsmwRe_ { } -Lmwad.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Lmwad(s4); } -Lmwad.s4: is LsmwRb_ & LsmwRe_ { } -Lmwad.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Lmwad(s5); } -Lmwad.s5: is LsmwRb_ & LsmwRe_ { } -Lmwad.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Lmwad(s6); } -Lmwad.s6: is LsmwRb_ & LsmwRe_ { } -Lmwad.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Lmwad(s7); } -Lmwad.s7: is LsmwRb_ & LsmwRe_ { } -Lmwad.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Lmwad(s8); } -Lmwad.s8: is LsmwRb_ & LsmwRe_ { } -Lmwad.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Lmwad(ta); } -Lmwad.ta: is LsmwRb_ & LsmwRe_ { } -Lmwad.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Lmwad(t0); } -Lmwad.t0: is LsmwRb_ & LsmwRe_ { } -Lmwad.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Lmwad(t1); } -Lmwad.t1: is LsmwRb_ & LsmwRe_ { } -Lmwad.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Lmwad(t2); } -Lmwad.t2: is LsmwRb_ & LsmwRe_ { } -Lmwad.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Lmwad(t3); } -Lmwad.t3: is LsmwRb_ & LsmwRe_ { } -Lmwad.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Lmwad(t4); } -Lmwad.t4: is LsmwRb_ & LsmwRe_ { } -Lmwad.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Lmwad(t5); } -Lmwad.t5: is LsmwRb_ & LsmwRe_ { } -Lmwad.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Lmwad(t6); } -Lmwad.t6: is LsmwRb_ & LsmwRe_ { } -Lmwad.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Lmwad(t7); } -Lmwad.t7: is LsmwRb_ & LsmwRe_ { } -Lmwad.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Lmwad(t8); } -Lmwad.t8: is LsmwRb_ & LsmwRe_ { } -Lmwad.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Lmwad(t9); } -Lmwad.t9: is LsmwRb_ & LsmwRe_ { } -Lmwad.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Lmwad(p0); } -Lmwad.p0: is LsmwRb_ & LsmwRe_ { } -Lmwad.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Lmwad(p1); } -Lmwad.p1: is LsmwRb_ & LsmwRe_ { } -Lmwad.fp: fp is Enable4_fp=1 & fp { Lmwad(fp); } -Lmwad.fp: is Enable4_fp=0 { } -Lmwad.gp: gp is Enable4_gp=1 & gp { Lmwad(gp); } -Lmwad.gp: is Enable4_gp=0 { } -Lmwad.lp: lp is Enable4_lp=1 & lp { Lmwad(lp); } -Lmwad.lp: is Enable4_lp=0 { } -Lmwad.sp: sp is Enable4_sp=1 & sp { Lmwad(sp); } -Lmwad.sp: is Enable4_sp=0 { } +Lsmw_id: is LsmwId=0 { MwInc(); } +Lsmw_id: is LsmwId=1 { MwDec(); } -Smwbi.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwbi(a0); } -Smwbi.a0: is LsmwRb_ & LsmwRe_ { } -Smwbi.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwbi(a1); } -Smwbi.a1: is LsmwRb_ & LsmwRe_ { } -Smwbi.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwbi(a2); } -Smwbi.a2: is LsmwRb_ & LsmwRe_ { } -Smwbi.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwbi(a3); } -Smwbi.a3: is LsmwRb_ & LsmwRe_ { } -Smwbi.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwbi(a4); } -Smwbi.a4: is LsmwRb_ & LsmwRe_ { } -Smwbi.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwbi(a5); } -Smwbi.a5: is LsmwRb_ & LsmwRe_ { } -Smwbi.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwbi(s0); } -Smwbi.s0: is LsmwRb_ & LsmwRe_ { } -Smwbi.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwbi(s1); } -Smwbi.s1: is LsmwRb_ & LsmwRe_ { } -Smwbi.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwbi(s2); } -Smwbi.s2: is LsmwRb_ & LsmwRe_ { } -Smwbi.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwbi(s3); } -Smwbi.s3: is LsmwRb_ & LsmwRe_ { } -Smwbi.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwbi(s4); } -Smwbi.s4: is LsmwRb_ & LsmwRe_ { } -Smwbi.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwbi(s5); } -Smwbi.s5: is LsmwRb_ & LsmwRe_ { } -Smwbi.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwbi(s6); } -Smwbi.s6: is LsmwRb_ & LsmwRe_ { } -Smwbi.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwbi(s7); } -Smwbi.s7: is LsmwRb_ & LsmwRe_ { } -Smwbi.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwbi(s8); } -Smwbi.s8: is LsmwRb_ & LsmwRe_ { } -Smwbi.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwbi(ta); } -Smwbi.ta: is LsmwRb_ & LsmwRe_ { } -Smwbi.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwbi(t0); } -Smwbi.t0: is LsmwRb_ & LsmwRe_ { } -Smwbi.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwbi(t1); } -Smwbi.t1: is LsmwRb_ & LsmwRe_ { } -Smwbi.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwbi(t2); } -Smwbi.t2: is LsmwRb_ & LsmwRe_ { } -Smwbi.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwbi(t3); } -Smwbi.t3: is LsmwRb_ & LsmwRe_ { } -Smwbi.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwbi(t4); } -Smwbi.t4: is LsmwRb_ & LsmwRe_ { } -Smwbi.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwbi(t5); } -Smwbi.t5: is LsmwRb_ & LsmwRe_ { } -Smwbi.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwbi(t6); } -Smwbi.t6: is LsmwRb_ & LsmwRe_ { } -Smwbi.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwbi(t7); } -Smwbi.t7: is LsmwRb_ & LsmwRe_ { } -Smwbi.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwbi(t8); } -Smwbi.t8: is LsmwRb_ & LsmwRe_ { } -Smwbi.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwbi(t9); } -Smwbi.t9: is LsmwRb_ & LsmwRe_ { } -Smwbi.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwbi(p0); } -Smwbi.p0: is LsmwRb_ & LsmwRe_ { } -Smwbi.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwbi(p1); } -Smwbi.p1: is LsmwRb_ & LsmwRe_ { } -Smwbi.fp: fp is Enable4_fp=1 & fp { Smwbi(fp); } -Smwbi.fp: is Enable4_fp=0 { } -Smwbi.gp: gp is Enable4_gp=1 & gp { Smwbi(gp); } -Smwbi.gp: is Enable4_gp=0 { } -Smwbi.lp: lp is Enable4_lp=1 & lp { Smwbi(lp); } -Smwbi.lp: is Enable4_lp=0 { } -Smwbi.sp: sp is Enable4_sp=1 & sp { Smwbi(sp); } -Smwbi.sp: is Enable4_sp=0 { } +Lmw.fp: fp is Lsmw_id & LsmwBa=0 & Enable4_fp=1 & fp { LmwOp(fp); build Lsmw_id; } +Lmw.fp: fp is Lsmw_id & LsmwBa=1 & Enable4_fp=1 & fp { build Lsmw_id; LmwOp(fp); } +Lmw.fp: is Enable4_fp=0 { } +Lmw.gp: gp is Lsmw_id & LsmwBa=0 & Enable4_gp=1 & gp { LmwOp(gp); build Lsmw_id; } +Lmw.gp: gp is Lsmw_id & LsmwBa=1 & Enable4_gp=1 & gp { build Lsmw_id; LmwOp(gp); } +Lmw.gp: is Enable4_gp=0 { } +Lmw.lp: lp is Lsmw_id & LsmwBa=0 & Enable4_lp=1 & lp { LmwOp(lp); build Lsmw_id; } +Lmw.lp: lp is Lsmw_id & LsmwBa=1 & Enable4_lp=1 & lp { build Lsmw_id; LmwOp(lp); } +Lmw.lp: is Enable4_lp=0 { } +Lmw.sp: sp is Lsmw_id & LsmwBa=0 & Enable4_sp=1 & sp { LmwOp(sp); build Lsmw_id; } +Lmw.sp: sp is Lsmw_id & LsmwBa=1 & Enable4_sp=1 & sp { build Lsmw_id; LmwOp(sp); } +Lmw.sp: is Enable4_sp=0 { } -Smwbd.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwbd(a0); } -Smwbd.a0: is LsmwRb_ & LsmwRe_ { } -Smwbd.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwbd(a1); } -Smwbd.a1: is LsmwRb_ & LsmwRe_ { } -Smwbd.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwbd(a2); } -Smwbd.a2: is LsmwRb_ & LsmwRe_ { } -Smwbd.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwbd(a3); } -Smwbd.a3: is LsmwRb_ & LsmwRe_ { } -Smwbd.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwbd(a4); } -Smwbd.a4: is LsmwRb_ & LsmwRe_ { } -Smwbd.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwbd(a5); } -Smwbd.a5: is LsmwRb_ & LsmwRe_ { } -Smwbd.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwbd(s0); } -Smwbd.s0: is LsmwRb_ & LsmwRe_ { } -Smwbd.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwbd(s1); } -Smwbd.s1: is LsmwRb_ & LsmwRe_ { } -Smwbd.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwbd(s2); } -Smwbd.s2: is LsmwRb_ & LsmwRe_ { } -Smwbd.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwbd(s3); } -Smwbd.s3: is LsmwRb_ & LsmwRe_ { } -Smwbd.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwbd(s4); } -Smwbd.s4: is LsmwRb_ & LsmwRe_ { } -Smwbd.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwbd(s5); } -Smwbd.s5: is LsmwRb_ & LsmwRe_ { } -Smwbd.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwbd(s6); } -Smwbd.s6: is LsmwRb_ & LsmwRe_ { } -Smwbd.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwbd(s7); } -Smwbd.s7: is LsmwRb_ & LsmwRe_ { } -Smwbd.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwbd(s8); } -Smwbd.s8: is LsmwRb_ & LsmwRe_ { } -Smwbd.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwbd(ta); } -Smwbd.ta: is LsmwRb_ & LsmwRe_ { } -Smwbd.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwbd(t0); } -Smwbd.t0: is LsmwRb_ & LsmwRe_ { } -Smwbd.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwbd(t1); } -Smwbd.t1: is LsmwRb_ & LsmwRe_ { } -Smwbd.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwbd(t2); } -Smwbd.t2: is LsmwRb_ & LsmwRe_ { } -Smwbd.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwbd(t3); } -Smwbd.t3: is LsmwRb_ & LsmwRe_ { } -Smwbd.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwbd(t4); } -Smwbd.t4: is LsmwRb_ & LsmwRe_ { } -Smwbd.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwbd(t5); } -Smwbd.t5: is LsmwRb_ & LsmwRe_ { } -Smwbd.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwbd(t6); } -Smwbd.t6: is LsmwRb_ & LsmwRe_ { } -Smwbd.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwbd(t7); } -Smwbd.t7: is LsmwRb_ & LsmwRe_ { } -Smwbd.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwbd(t8); } -Smwbd.t8: is LsmwRb_ & LsmwRe_ { } -Smwbd.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwbd(t9); } -Smwbd.t9: is LsmwRb_ & LsmwRe_ { } -Smwbd.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwbd(p0); } -Smwbd.p0: is LsmwRb_ & LsmwRe_ { } -Smwbd.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwbd(p1); } -Smwbd.p1: is LsmwRb_ & LsmwRe_ { } -Smwbd.fp: fp is Enable4_fp=1 & fp { Smwbd(fp); } -Smwbd.fp: is Enable4_fp=0 { } -Smwbd.gp: gp is Enable4_gp=1 & gp { Smwbd(gp); } -Smwbd.gp: is Enable4_gp=0 { } -Smwbd.lp: lp is Enable4_lp=1 & lp { Smwbd(lp); } -Smwbd.lp: is Enable4_lp=0 { } -Smwbd.sp: sp is Enable4_sp=1 & sp { Smwbd(sp); } -Smwbd.sp: is Enable4_sp=0 { } +# Terminating condition +LmwReg: Dreg is LsmwId=0 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; LmwOp(Dreg); MwInc(); } +LmwReg: Dreg is LsmwId=1 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; LmwOp(Dreg); MwDec(); } -Smwai.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwai(a0); } -Smwai.a0: is LsmwRb_ & LsmwRe_ { } -Smwai.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwai(a1); } -Smwai.a1: is LsmwRb_ & LsmwRe_ { } -Smwai.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwai(a2); } -Smwai.a2: is LsmwRb_ & LsmwRe_ { } -Smwai.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwai(a3); } -Smwai.a3: is LsmwRb_ & LsmwRe_ { } -Smwai.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwai(a4); } -Smwai.a4: is LsmwRb_ & LsmwRe_ { } -Smwai.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwai(a5); } -Smwai.a5: is LsmwRb_ & LsmwRe_ { } -Smwai.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwai(s0); } -Smwai.s0: is LsmwRb_ & LsmwRe_ { } -Smwai.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwai(s1); } -Smwai.s1: is LsmwRb_ & LsmwRe_ { } -Smwai.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwai(s2); } -Smwai.s2: is LsmwRb_ & LsmwRe_ { } -Smwai.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwai(s3); } -Smwai.s3: is LsmwRb_ & LsmwRe_ { } -Smwai.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwai(s4); } -Smwai.s4: is LsmwRb_ & LsmwRe_ { } -Smwai.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwai(s5); } -Smwai.s5: is LsmwRb_ & LsmwRe_ { } -Smwai.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwai(s6); } -Smwai.s6: is LsmwRb_ & LsmwRe_ { } -Smwai.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwai(s7); } -Smwai.s7: is LsmwRb_ & LsmwRe_ { } -Smwai.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwai(s8); } -Smwai.s8: is LsmwRb_ & LsmwRe_ { } -Smwai.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwai(ta); } -Smwai.ta: is LsmwRb_ & LsmwRe_ { } -Smwai.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwai(t0); } -Smwai.t0: is LsmwRb_ & LsmwRe_ { } -Smwai.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwai(t1); } -Smwai.t1: is LsmwRb_ & LsmwRe_ { } -Smwai.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwai(t2); } -Smwai.t2: is LsmwRb_ & LsmwRe_ { } -Smwai.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwai(t3); } -Smwai.t3: is LsmwRb_ & LsmwRe_ { } -Smwai.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwai(t4); } -Smwai.t4: is LsmwRb_ & LsmwRe_ { } -Smwai.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwai(t5); } -Smwai.t5: is LsmwRb_ & LsmwRe_ { } -Smwai.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwai(t6); } -Smwai.t6: is LsmwRb_ & LsmwRe_ { } -Smwai.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwai(t7); } -Smwai.t7: is LsmwRb_ & LsmwRe_ { } -Smwai.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwai(t8); } -Smwai.t8: is LsmwRb_ & LsmwRe_ { } -Smwai.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwai(t9); } -Smwai.t9: is LsmwRb_ & LsmwRe_ { } -Smwai.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwai(p0); } -Smwai.p0: is LsmwRb_ & LsmwRe_ { } -Smwai.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwai(p1); } -Smwai.p1: is LsmwRb_ & LsmwRe_ { } -Smwai.fp: fp is Enable4_fp=1 & fp { Smwai(fp); } -Smwai.fp: is Enable4_fp=0 { } -Smwai.gp: gp is Enable4_gp=1 & gp { Smwai(gp); } -Smwai.gp: is Enable4_gp=0 { } -Smwai.lp: lp is Enable4_lp=1 & lp { Smwai(lp); } -Smwai.lp: is Enable4_lp=0 { } -Smwai.sp: sp is Enable4_sp=1 & sp { Smwai(sp); } -Smwai.sp: is Enable4_sp=0 { } +LmwReg: Dreg is LsmwId=0 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; MwInc(); LmwOp(Dreg); } +LmwReg: Dreg is LsmwId=1 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; MwDec(); LmwOp(Dreg); } -Smwad.a0: a0 is LsmwRb_<=0 & LsmwRe_>=0 & a0 { Smwad(a0); } -Smwad.a0: is LsmwRb_ & LsmwRe_ { } -Smwad.a1: a1 is LsmwRb_<=1 & LsmwRe_>=1 & a1 { Smwad(a1); } -Smwad.a1: is LsmwRb_ & LsmwRe_ { } -Smwad.a2: a2 is LsmwRb_<=2 & LsmwRe_>=2 & a2 { Smwad(a2); } -Smwad.a2: is LsmwRb_ & LsmwRe_ { } -Smwad.a3: a3 is LsmwRb_<=3 & LsmwRe_>=3 & a3 { Smwad(a3); } -Smwad.a3: is LsmwRb_ & LsmwRe_ { } -Smwad.a4: a4 is LsmwRb_<=4 & LsmwRe_>=4 & a4 { Smwad(a4); } -Smwad.a4: is LsmwRb_ & LsmwRe_ { } -Smwad.a5: a5 is LsmwRb_<=5 & LsmwRe_>=5 & a5 { Smwad(a5); } -Smwad.a5: is LsmwRb_ & LsmwRe_ { } -Smwad.s0: s0 is LsmwRb_<=6 & LsmwRe_>=6 & s0 { Smwad(s0); } -Smwad.s0: is LsmwRb_ & LsmwRe_ { } -Smwad.s1: s1 is LsmwRb_<=7 & LsmwRe_>=7 & s1 { Smwad(s1); } -Smwad.s1: is LsmwRb_ & LsmwRe_ { } -Smwad.s2: s2 is LsmwRb_<=8 & LsmwRe_>=8 & s2 { Smwad(s2); } -Smwad.s2: is LsmwRb_ & LsmwRe_ { } -Smwad.s3: s3 is LsmwRb_<=9 & LsmwRe_>=9 & s3 { Smwad(s3); } -Smwad.s3: is LsmwRb_ & LsmwRe_ { } -Smwad.s4: s4 is LsmwRb_<=10 & LsmwRe_>=10 & s4 { Smwad(s4); } -Smwad.s4: is LsmwRb_ & LsmwRe_ { } -Smwad.s5: s5 is LsmwRb_<=11 & LsmwRe_>=11 & s5 { Smwad(s5); } -Smwad.s5: is LsmwRb_ & LsmwRe_ { } -Smwad.s6: s6 is LsmwRb_<=12 & LsmwRe_>=12 & s6 { Smwad(s6); } -Smwad.s6: is LsmwRb_ & LsmwRe_ { } -Smwad.s7: s7 is LsmwRb_<=13 & LsmwRe_>=13 & s7 { Smwad(s7); } -Smwad.s7: is LsmwRb_ & LsmwRe_ { } -Smwad.s8: s8 is LsmwRb_<=14 & LsmwRe_>=14 & s8 { Smwad(s8); } -Smwad.s8: is LsmwRb_ & LsmwRe_ { } -Smwad.ta: ta is LsmwRb_<=15 & LsmwRe_>=15 & ta { Smwad(ta); } -Smwad.ta: is LsmwRb_ & LsmwRe_ { } -Smwad.t0: t0 is LsmwRb_<=16 & LsmwRe_>=16 & t0 { Smwad(t0); } -Smwad.t0: is LsmwRb_ & LsmwRe_ { } -Smwad.t1: t1 is LsmwRb_<=17 & LsmwRe_>=17 & t1 { Smwad(t1); } -Smwad.t1: is LsmwRb_ & LsmwRe_ { } -Smwad.t2: t2 is LsmwRb_<=18 & LsmwRe_>=18 & t2 { Smwad(t2); } -Smwad.t2: is LsmwRb_ & LsmwRe_ { } -Smwad.t3: t3 is LsmwRb_<=19 & LsmwRe_>=19 & t3 { Smwad(t3); } -Smwad.t3: is LsmwRb_ & LsmwRe_ { } -Smwad.t4: t4 is LsmwRb_<=20 & LsmwRe_>=20 & t4 { Smwad(t4); } -Smwad.t4: is LsmwRb_ & LsmwRe_ { } -Smwad.t5: t5 is LsmwRb_<=21 & LsmwRe_>=21 & t5 { Smwad(t5); } -Smwad.t5: is LsmwRb_ & LsmwRe_ { } -Smwad.t6: t6 is LsmwRb_<=22 & LsmwRe_>=22 & t6 { Smwad(t6); } -Smwad.t6: is LsmwRb_ & LsmwRe_ { } -Smwad.t7: t7 is LsmwRb_<=23 & LsmwRe_>=23 & t7 { Smwad(t7); } -Smwad.t7: is LsmwRb_ & LsmwRe_ { } -Smwad.t8: t8 is LsmwRb_<=24 & LsmwRe_>=24 & t8 { Smwad(t8); } -Smwad.t8: is LsmwRb_ & LsmwRe_ { } -Smwad.t9: t9 is LsmwRb_<=25 & LsmwRe_>=25 & t9 { Smwad(t9); } -Smwad.t9: is LsmwRb_ & LsmwRe_ { } -Smwad.p0: p0 is LsmwRb_<=26 & LsmwRe_>=26 & p0 { Smwad(p0); } -Smwad.p0: is LsmwRb_ & LsmwRe_ { } -Smwad.p1: p1 is LsmwRb_<=27 & LsmwRe_>=27 & p1 { Smwad(p1); } -Smwad.p1: is LsmwRb_ & LsmwRe_ { } -Smwad.fp: fp is Enable4_fp=1 & fp { Smwad(fp); } -Smwad.fp: is Enable4_fp=0 { } -Smwad.gp: gp is Enable4_gp=1 & gp { Smwad(gp); } -Smwad.gp: is Enable4_gp=0 { } -Smwad.lp: lp is Enable4_lp=1 & lp { Smwad(lp); } -Smwad.lp: is Enable4_lp=0 { } -Smwad.sp: sp is Enable4_sp=1 & sp { Smwad(sp); } -Smwad.sp: is Enable4_sp=0 { } +LmwReg: Dreg, LmwReg is LsmwId=0 & LsmwBa=0 & Dreg & LmwReg [ counter = counter-1; regNum=regNum+1;] { LmwOp(Dreg); MwInc(); build LmwReg; } +LmwReg: Dreg, LmwReg is LsmwId=1 & LsmwBa=0 & Dreg & LmwReg [ counter = counter-1; regNum=regNum-1;] { LmwOp(Dreg); MwDec(); build LmwReg; } -Lmw.regs: is LsmwBa=0 & LsmwId=0 & Lmwbi.sp & Lmwbi.lp & Lmwbi.gp & Lmwbi.fp & Lmwbi.p1 & Lmwbi.p0 & Lmwbi.t9 & Lmwbi.t8 & Lmwbi.t7 & Lmwbi.t6 & Lmwbi.t5 & Lmwbi.t4 & Lmwbi.t3 & Lmwbi.t2 & Lmwbi.t1 & Lmwbi.t0 & Lmwbi.ta & Lmwbi.s8 & Lmwbi.s7 & Lmwbi.s6 & Lmwbi.s5 & Lmwbi.s4 & Lmwbi.s3 & Lmwbi.s2 & Lmwbi.s1 & Lmwbi.s0 & Lmwbi.a5 & Lmwbi.a4 & Lmwbi.a3 & Lmwbi.a2 & Lmwbi.a1 & Lmwbi.a0 { } -Lmw.regs: is LsmwBa=0 & LsmwId=1 & Lmwbd.a0 & Lmwbd.a1 & Lmwbd.a2 & Lmwbd.a3 & Lmwbd.a4 & Lmwbd.a5 & Lmwbd.s0 & Lmwbd.s1 & Lmwbd.s2 & Lmwbd.s3 & Lmwbd.s4 & Lmwbd.s5 & Lmwbd.s6 & Lmwbd.s7 & Lmwbd.s8 & Lmwbd.ta & Lmwbd.t0 & Lmwbd.t1 & Lmwbd.t2 & Lmwbd.t3 & Lmwbd.t4 & Lmwbd.t5 & Lmwbd.t6 & Lmwbd.t7 & Lmwbd.t8 & Lmwbd.t9 & Lmwbd.p0 & Lmwbd.p1 & Lmwbd.fp & Lmwbd.gp & Lmwbd.lp & Lmwbd.sp { } -Lmw.regs: is LsmwBa=1 & LsmwId=0 & Lmwai.sp & Lmwai.lp & Lmwai.gp & Lmwai.fp & Lmwai.p1 & Lmwai.p0 & Lmwai.t9 & Lmwai.t8 & Lmwai.t7 & Lmwai.t6 & Lmwai.t5 & Lmwai.t4 & Lmwai.t3 & Lmwai.t2 & Lmwai.t1 & Lmwai.t0 & Lmwai.ta & Lmwai.s8 & Lmwai.s7 & Lmwai.s6 & Lmwai.s5 & Lmwai.s4 & Lmwai.s3 & Lmwai.s2 & Lmwai.s1 & Lmwai.s0 & Lmwai.a5 & Lmwai.a4 & Lmwai.a3 & Lmwai.a2 & Lmwai.a1 & Lmwai.a0 { } -Lmw.regs: is LsmwBa=1 & LsmwId=1 & Lmwad.a0 & Lmwad.a1 & Lmwad.a2 & Lmwad.a3 & Lmwad.a4 & Lmwad.a5 & Lmwad.s0 & Lmwad.s1 & Lmwad.s2 & Lmwad.s3 & Lmwad.s4 & Lmwad.s5 & Lmwad.s6 & Lmwad.s7 & Lmwad.s8 & Lmwad.ta & Lmwad.t0 & Lmwad.t1 & Lmwad.t2 & Lmwad.t3 & Lmwad.t4 & Lmwad.t5 & Lmwad.t6 & Lmwad.t7 & Lmwad.t8 & Lmwad.t9 & Lmwad.p0 & Lmwad.p1 & Lmwad.fp & Lmwad.gp & Lmwad.lp & Lmwad.sp { } -Smw.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } -Smw.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } -Smw.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } -Smw.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } -Lmwa.regs: is LsmwBa=0 & LsmwId=0 & Lmwbi.sp & Lmwbi.lp & Lmwbi.gp & Lmwbi.fp & Lmwbi.p1 & Lmwbi.p0 & Lmwbi.t9 & Lmwbi.t8 & Lmwbi.t7 & Lmwbi.t6 & Lmwbi.t5 & Lmwbi.t4 & Lmwbi.t3 & Lmwbi.t2 & Lmwbi.t1 & Lmwbi.t0 & Lmwbi.ta & Lmwbi.s8 & Lmwbi.s7 & Lmwbi.s6 & Lmwbi.s5 & Lmwbi.s4 & Lmwbi.s3 & Lmwbi.s2 & Lmwbi.s1 & Lmwbi.s0 & Lmwbi.a5 & Lmwbi.a4 & Lmwbi.a3 & Lmwbi.a2 & Lmwbi.a1 & Lmwbi.a0 { } -Lmwa.regs: is LsmwBa=0 & LsmwId=1 & Lmwbd.a0 & Lmwbd.a1 & Lmwbd.a2 & Lmwbd.a3 & Lmwbd.a4 & Lmwbd.a5 & Lmwbd.s0 & Lmwbd.s1 & Lmwbd.s2 & Lmwbd.s3 & Lmwbd.s4 & Lmwbd.s5 & Lmwbd.s6 & Lmwbd.s7 & Lmwbd.s8 & Lmwbd.ta & Lmwbd.t0 & Lmwbd.t1 & Lmwbd.t2 & Lmwbd.t3 & Lmwbd.t4 & Lmwbd.t5 & Lmwbd.t6 & Lmwbd.t7 & Lmwbd.t8 & Lmwbd.t9 & Lmwbd.p0 & Lmwbd.p1 & Lmwbd.fp & Lmwbd.gp & Lmwbd.lp & Lmwbd.sp { } -Lmwa.regs: is LsmwBa=1 & LsmwId=0 & Lmwai.sp & Lmwai.lp & Lmwai.gp & Lmwai.fp & Lmwai.p1 & Lmwai.p0 & Lmwai.t9 & Lmwai.t8 & Lmwai.t7 & Lmwai.t6 & Lmwai.t5 & Lmwai.t4 & Lmwai.t3 & Lmwai.t2 & Lmwai.t1 & Lmwai.t0 & Lmwai.ta & Lmwai.s8 & Lmwai.s7 & Lmwai.s6 & Lmwai.s5 & Lmwai.s4 & Lmwai.s3 & Lmwai.s2 & Lmwai.s1 & Lmwai.s0 & Lmwai.a5 & Lmwai.a4 & Lmwai.a3 & Lmwai.a2 & Lmwai.a1 & Lmwai.a0 { } -Lmwa.regs: is LsmwBa=1 & LsmwId=1 & Lmwad.a0 & Lmwad.a1 & Lmwad.a2 & Lmwad.a3 & Lmwad.a4 & Lmwad.a5 & Lmwad.s0 & Lmwad.s1 & Lmwad.s2 & Lmwad.s3 & Lmwad.s4 & Lmwad.s5 & Lmwad.s6 & Lmwad.s7 & Lmwad.s8 & Lmwad.ta & Lmwad.t0 & Lmwad.t1 & Lmwad.t2 & Lmwad.t3 & Lmwad.t4 & Lmwad.t5 & Lmwad.t6 & Lmwad.t7 & Lmwad.t8 & Lmwad.t9 & Lmwad.p0 & Lmwad.p1 & Lmwad.fp & Lmwad.gp & Lmwad.lp & Lmwad.sp { } -Smwa.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } -Smwa.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } -Smwa.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } -Smwa.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } +LmwReg: Dreg, LmwReg is LsmwId=0 & LsmwBa=1 & Dreg & LmwReg [ counter = counter-1; regNum=regNum+1;] { MwInc(); LmwOp(Dreg); build LmwReg; } +LmwReg: Dreg, LmwReg is LsmwId=1 & LsmwBa=1 & Dreg & LmwReg [ counter = counter-1; regNum=regNum-1;] { MwDec(); LmwOp(Dreg); build LmwReg; } + +# Initial conditions +Lmw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp) ... & LmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build LmwReg; build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; } +Lmw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp) ... & LmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; build LmwReg; } +Lmw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp { build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; } +Lmw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp { build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; } + +Lmwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp) ... & LmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build LmwReg; build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; } +Lmwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp) ... & LmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; build LmwReg; } +Lmwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp { build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; } +Lmwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp { build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; } + +Smw.fp: fp is Lsmw_id & LsmwBa=0 & Enable4_fp=1 & fp { SmwOp(fp); build Lsmw_id; } +Smw.fp: fp is Lsmw_id & LsmwBa=1 & Enable4_fp=1 & fp { build Lsmw_id; SmwOp(fp); } +Smw.fp: is Enable4_fp=0 { } +Smw.gp: gp is Lsmw_id & LsmwBa=0 & Enable4_gp=1 & gp { SmwOp(gp); build Lsmw_id; } +Smw.gp: gp is Lsmw_id & LsmwBa=1 & Enable4_gp=1 & gp { build Lsmw_id; SmwOp(gp); } +Smw.gp: is Enable4_gp=0 { } +Smw.lp: lp is Lsmw_id & LsmwBa=0 & Enable4_lp=1 & lp { SmwOp(lp); build Lsmw_id; } +Smw.lp: lp is Lsmw_id & LsmwBa=1 & Enable4_lp=1 & lp { build Lsmw_id; SmwOp(lp); } +Smw.lp: is Enable4_lp=0 { } +Smw.sp: sp is Lsmw_id & LsmwBa=0 & Enable4_sp=1 & sp { SmwOp(sp); build Lsmw_id; } +Smw.sp: sp is Lsmw_id & LsmwBa=1 & Enable4_sp=1 & sp { build Lsmw_id; SmwOp(sp); } +Smw.sp: is Enable4_sp=0 { } + +# Terminating condition +SmwReg: Dreg is LsmwId=0 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; SmwOp(Dreg); MwInc(); } +SmwReg: Dreg is LsmwId=1 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; SmwOp(Dreg); MwDec(); } + +SmwReg: Dreg is LsmwId=0 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; MwInc(); SmwOp(Dreg); } +SmwReg: Dreg is LsmwId=1 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; MwDec(); SmwOp(Dreg); } + +SmwReg: Dreg, SmwReg is LsmwId=0 & LsmwBa=0 & Dreg & SmwReg [ counter = counter-1; regNum=regNum+1;] { build Dreg; SmwOp(Dreg); MwInc(); build SmwReg; } +SmwReg: Dreg, SmwReg is LsmwId=1 & LsmwBa=0 & Dreg & SmwReg [ counter = counter-1; regNum=regNum-1;] { build Dreg; SmwOp(Dreg); MwDec(); build SmwReg; } + +SmwReg: Dreg, SmwReg is LsmwId=0 & LsmwBa=1 & Dreg & SmwReg [ counter = counter-1; regNum=regNum+1;] { build Dreg; MwInc(); SmwOp(Dreg); build SmwReg; } +SmwReg: Dreg, SmwReg is LsmwId=1 & LsmwBa=1 & Dreg & SmwReg [ counter = counter-1; regNum=regNum-1;] { build Dreg; MwDec(); SmwOp(Dreg); build SmwReg; } + +# Initial conditions +Smw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp) ... & SmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build SmwReg; build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; } +Smw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp) ... & SmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; build SmwReg; } +Smw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; } +Smw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp { build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; } + +Smwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp) ... & SmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build SmwReg; build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; } +Smwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp) ... & SmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; build SmwReg; } +Smwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp { build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; } +Smwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; } + + +#Smw.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } +#Smw.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } +#Smw.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } +#Smw.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } +#Lmwa.regs: is LsmwBa=0 & LsmwId & Lmwbi.sp & Lmwbi.lp & Lmwbi.gp & Lmwbi.fp & Lmwbi.p1 & Lmwbi.p0 & Lmwbi.t9 & Lmwbi.t8 & Lmwbi.t7 & Lmwbi.t6 & Lmwbi.t5 & Lmwbi.t4 & Lmwbi.t3 & Lmwbi.t2 & Lmwbi.t1 & Lmwbi.t0 & Lmwbi.ta & Lmwbi.s8 & Lmwbi.s7 & Lmwbi.s6 & Lmwbi.s5 & Lmwbi.s4 & Lmwbi.s3 & Lmwbi.s2 & Lmwbi.s1 & Lmwbi.s0 & Lmwbi.a5 & Lmwbi.a4 & Lmwbi.a3 & Lmwbi.a2 & Lmwbi.a1 & Lmwbi.a0 { } +#Lmwa.regs: is LsmwBa=0 & LsmwId=1 & Lmwbd.a0 & Lmwbd.a1 & Lmwbd.a2 & Lmwbd.a3 & Lmwbd.a4 & Lmwbd.a5 & Lmwbd.s0 & Lmwbd.s1 & Lmwbd.s2 & Lmwbd.s3 & Lmwbd.s4 & Lmwbd.s5 & Lmwbd.s6 & Lmwbd.s7 & Lmwbd.s8 & Lmwbd.ta & Lmwbd.t0 & Lmwbd.t1 & Lmwbd.t2 & Lmwbd.t3 & Lmwbd.t4 & Lmwbd.t5 & Lmwbd.t6 & Lmwbd.t7 & Lmwbd.t8 & Lmwbd.t9 & Lmwbd.p0 & Lmwbd.p1 & Lmwbd.fp & Lmwbd.gp & Lmwbd.lp & Lmwbd.sp { } +#Lmwa.regs: is LsmwBa=1 & LsmwId=0 & Lmwai.sp & Lmwai.lp & Lmwai.gp & Lmwai.fp & Lmwai.p1 & Lmwai.p0 & Lmwai.t9 & Lmwai.t8 & Lmwai.t7 & Lmwai.t6 & Lmwai.t5 & Lmwai.t4 & Lmwai.t3 & Lmwai.t2 & Lmwai.t1 & Lmwai.t0 & Lmwai.ta & Lmwai.s8 & Lmwai.s7 & Lmwai.s6 & Lmwai.s5 & Lmwai.s4 & Lmwai.s3 & Lmwai.s2 & Lmwai.s1 & Lmwai.s0 & Lmwai.a5 & Lmwai.a4 & Lmwai.a3 & Lmwai.a2 & Lmwai.a1 & Lmwai.a0 { } +#Lmwa.regs: is LsmwBa=1 & LsmwId=1 & Lmwad.a0 & Lmwad.a1 & Lmwad.a2 & Lmwad.a3 & Lmwad.a4 & Lmwad.a5 & Lmwad.s0 & Lmwad.s1 & Lmwad.s2 & Lmwad.s3 & Lmwad.s4 & Lmwad.s5 & Lmwad.s6 & Lmwad.s7 & Lmwad.s8 & Lmwad.ta & Lmwad.t0 & Lmwad.t1 & Lmwad.t2 & Lmwad.t3 & Lmwad.t4 & Lmwad.t5 & Lmwad.t6 & Lmwad.t7 & Lmwad.t8 & Lmwad.t9 & Lmwad.p0 & Lmwad.p1 & Lmwad.fp & Lmwad.gp & Lmwad.lp & Lmwad.sp { } +#Smwa.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } +#Smwa.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } +#Smwa.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } +#Smwa.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.cspec b/Ghidra/Processors/NDS32/data/languages/nds32.cspec index 8dc06318b2..9d0e2bb3af 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.cspec +++ b/Ghidra/Processors/NDS32/data/languages/nds32.cspec @@ -50,8 +50,17 @@ + + + + + + + + + - + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.sinc b/Ghidra/Processors/NDS32/data/languages/nds32.sinc index 06083dd57c..5f68680d11 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.sinc +++ b/Ghidra/Processors/NDS32/data/languages/nds32.sinc @@ -17,7 +17,14 @@ define register offset=0x100 size=8 define register offset=0x100 size=4 [d0.hi d0.lo d1.hi d1.lo]; +define register offset=0x1000 size=4 +[ itb ]; +define register offset=0x1000 size=8 contextreg; +define context contextreg + counter = (22,26) + regNum = (27,31) # register for load/store multiple instructions +; define token instr32(32) OpSz = (31, 31) @@ -31,7 +38,10 @@ define token instr32(32) Rs = (5, 9) Sub5 = (0, 4) Sub6 = (0, 5) + Sub7 = (0, 6) Sub8 = (0, 7) + Sub3 = (7, 9) + Imm8u = (7,14) Imm5u = (10, 14) Imm5s = (10, 14) signed Br1t = (14, 14) @@ -295,7 +305,7 @@ AddrRaRbsv: [Ra + OffsetRbsv] is Ra & OffsetRbsv { addr:4 = Ra + OffsetRbsv; exp ### Load / Store Multiple Word Instruction ### -# TODO : this is ugly + @include "lsmw.sinc" LsmwBa_: "b" is LsmwBa=0 { } @@ -308,14 +318,14 @@ LsmwM_: "" is LsmwRa & LsmwM=0 { } LsmwM_: "m" is LsmwRa & LsmwM=1 { LsmwRa = mult_addr; } -:lmw.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=0 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b00 & Lmw.regs +:lmw.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is ($(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=0 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b00) ... & Lmw.regs { mult_addr = LsmwRa; build Lmw.regs; build LsmwM_; } -:smw.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=1 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b00 & Smw.regs +:smw.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is ($(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=1 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b00) ... & Smw.regs { mult_addr = LsmwRa; build Smw.regs; @@ -551,8 +561,6 @@ SetendBE: "b" is Toggle=1 { setend(1:1); } ### 32-bit Baseline V2 instructions ### -@if defined(BASELINE_V2) - ### ALU Instructions ### :addi.gp is $(I32) & $(SBGP) & Rt & GpSub1=0b1 & Imm19s { Rt = gp + Imm19s; } @@ -563,25 +571,16 @@ SetendBE: "b" is Toggle=1 { setend(1:1); } :mulr64 Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(GPR) & Sub6=0b101001 & Rtl & Rth { res:8 = zext(Ra) * zext(Rb); -@if ENDIAN == "big" - Rtl = res(4); - Rth = res:4; -@else - Rtl = res:4; - Rth = res(4); -@endif + Rtl = res[32,32]; + Rth = res[0,32]; + } :mulsr64 Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(GPR) & Sub6=0b101000 & Rtl & Rth { res:8 = sext(Ra) * sext(Rb); -@if ENDIAN == "big" - Rtl = res(4); - Rth = res:4; -@else - Rtl = res:4; - Rth = res(4); -@endif + Rtl = res[32,32]; + Rth = res[0,32]; } :maddr32 Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(GPR) & Sub6=0b110011 { Rt = Rt + (Ra * Rb); } @@ -605,16 +604,15 @@ GpWordAddress: [+ off] is Imm17s [ off = Imm17s << 2; ] { addr:4 = gp + off; exp :shi.gp Rt, GpHalfAddress is $(I32) & $(HWGP) & Rt & GpSub2=0b10 & GpHalfAddress { local tmp = Rt; *GpHalfAddress = tmp:2; } :swi.gp Rt, GpWordAddress is $(I32) & $(HWGP) & Rt & GpSub3=0b111 & GpWordAddress { *GpWordAddress = Rt; } -# TODO : same as lmw/smw, this is horrible -:lmwa.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=0 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b01 & Lmwa.regs +:lmwa.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is ($(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=0 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b01) ... & Lmwa.regs { mult_addr = LsmwRa; build Lmwa.regs; build LsmwM_; } -:smwa.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is $(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=1 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b01 & Smwa.regs +:smwa.^LsmwBa_^LsmwId_^LsmwM_ LsmwRb, [LsmwRa], LsmwRe, Enable4 is ($(I32) & $(LSMW) & LsmwRb & LsmwRa & LsmwRe & Enable4 & LsmwLs=1 & LsmwBa_ & LsmwId_ & LsmwM_ & LsmwSub=0b01) ... & Smwa.regs { mult_addr = LsmwRa; build Smwa.regs; @@ -624,14 +622,10 @@ GpWordAddress: [+ off] is Imm17s [ off = Imm17s << 2; ] { addr:4 = gp + off; exp :lbup Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00100000 { local tmp:1 = *AddrRaRbsv; Rt = zext(tmp); } :sbup Rt, AddrRaRbsv is $(I32) & $(MEM) & Rt & AddrRaRbsv & Sub8=0b00101000 { local tmp = Rt; *AddrRaRbsv = tmp:1; } -@endif - ### 32-bit Baseline V3 instructions ### -@if defined(BASELINE_V3) - ### ALU Instructions with Shift Operation (v3) ### :add_slli Rt, Ra, Rb, sh is $(I32) & $(ALU_1) & Rt & Ra & Rb & sh & Sub5=0b00000 { Rt = Ra + (Rb << sh); } @@ -664,15 +658,11 @@ Rel8: addr is Imm8s [ addr = inst_start + (Imm8s << 1); ] { export *:4 addr; } # TODO: Add CCTL L1D_WBALL, level -@endif - - ### 32-bit ISA extension ### ### ALU Instruction (Performance) ### -@if defined(PERFORMANCE_V1) :abs Rt, Ra is $(I32) & $(ALU_2) & Rt & Ra & Rb=0 & $(ALU2Z) & Sub6=0b000011 { @@ -767,12 +757,9 @@ Rel8: addr is Imm8s [ addr = inst_start + (Imm8s << 1); ] { export *:4 addr; } Rt = countTmp; } -@endif - ### Performance Extension V2 ### -@if defined(PERFORMANCE_V2) # TODO : arithmetic functions: bs* :bse is $(I32) & $(ALU_2) & Rt & Ra & Rb & $(ALU2Z) & Sub6=0b001100 unimpl @@ -806,10 +793,105 @@ macro add_abs_diff(dst, src1, src2, shift) add_abs_diff(Rt, Ra, Rb, 24); } + +# 32-bit String Extension +:ffb Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & Sub3=0 & Sub7=0b0001110 { + match:1 = Rb[0,8]; + m1:1 = (Ra[0,8] == match); + m2:1 = (Ra[8,8] == match); + m3:1 = (Ra[16,8] == match); + m4:1 = (Ra[24,8] == match); + Rt = -4; + if (m1) goto inst_next; + Rt = -3; + if (m2) goto inst_next; + Rt = -2; + if (m3) goto inst_next; + Rt = -1; + if (m4) goto inst_next; + Rt = 0; + # choosery method + # rd = 0 + (zext(m1)*-4) + (zext(m2)*-3) + (zext(m3)*-2) + (zext(m4)*-1); +} + +:ffbi Rt, Ra, Imm8u is $(I32) & $(ALU_2) & Rt & Ra & Imm8u & Sub7=0b1001110 { + match:1 = Imm8u; + m1:1 = (Ra[0,8] == match); + m2:1 = (Ra[8,8] == match); + m3:1 = (Ra[16,8] == match); + m4:1 = (Ra[24,8] == match); + Rt = -4; + if (m1) goto inst_next; + Rt = -3; + if (m2) goto inst_next; + Rt = -2; + if (m3) goto inst_next; + Rt = -1; + if (m4) goto inst_next; + Rt = 0; +} + +:ffmism Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & Sub3=0 & Sub7=0b0001111 { + match:1 = Rb[0,8]; + m1:1 = (Ra[0,8] != Rb[0,8]); + m2:1 = (Ra[8,8] != Rb[8,8]); + m3:1 = (Ra[16,8] != Rb[16,8]); + m4:1 = (Ra[24,8] != Rb[24,8]); +@if ENDIAN == "little" + Rt = -4; + if (m1) goto inst_next; + Rt = -3; + if (m2) goto inst_next; + Rt = -2; + if (m3) goto inst_next; + Rt = -1; + if (m4) goto inst_next; + Rt = 0; + # choosery method + # rd = 0 + (zext(m1)*-4) + (zext(m2)*-3) + (zext(m3)*-2) + (zext(m4)*-1); +@else + Rt = -4; + if (m4) goto inst_next; + Rt = -3; + if (m3) goto inst_next; + Rt = -2; + if (m2) goto inst_next; + Rt = -1; + if (m1) goto inst_next; + Rt = 0; @endif +} - - +:flmism Rt, Ra, Rb is $(I32) & $(ALU_2) & Rt & Ra & Rb & Sub3=0 & Sub7=0b1001111 { + match:1 = Rb[0,8]; + m1:1 = (Ra[0,8] != Rb[0,8]); + m2:1 = (Ra[8,8] != Rb[8,8]); + m3:1 = (Ra[16,8] != Rb[16,8]); + m4:1 = (Ra[24,8] != Rb[24,8]); +@if ENDIAN == "little" + Rt = -1; + if (m4) goto inst_next; + Rt = -2; + if (m3) goto inst_next; + Rt = -3; + if (m2) goto inst_next; + Rt = -4; + if (m1) goto inst_next; + Rt = 0; + # choosery method + # rd = 0 + (zext(m1)*-4) + (zext(m2)*-3) + (zext(m3)*-2) + (zext(m4)*-1); +@else + Rt = -1; + if (m1) goto inst_next; + Rt = -2; + if (m2) goto inst_next; + Rt = -3; + if (m3) goto inst_next; + Rt = -4; + if (m4) goto inst_next; + Rt = 0; +@endif +} ########### 16b ############ @@ -832,8 +914,13 @@ define token instr16(16) rt3b = (8, 10) ra3 = (3, 5) rb3 = (0, 2) + bit5 = (5,5) + bit6 = (6,6) + bit7 = (7,7) + bit8 = (8,8) imm3u = (0, 2) imm3ub = (3, 5) + imm4u = (5, 8) imm5u = (0, 4) imm5s = (0, 4) signed imm6u = (0, 5) @@ -978,14 +1065,13 @@ rel8: addr is imm8s [ addr = inst_start + (imm8s << 1); ] { export *:4 addr; } ### Misc Instruction ### -:break16 swid9 is $(I16) & opc6=0b110101 & swid9 { break(swid9:4); } -:nop16 is $(I16) & opc6=0b001001 & rt4=0b0000 & imm5u=0b00000 { } +# V3 doesn't allow break16 with SWID greater than 31 +:break16 swid9 is $(I16) & opc6=0b110101 & imm4u=0 & swid9 { break(swid9:4); } +:nop16 is $(I16) & opc6=0b001001 & rt4=0 & imm5u=0 { } ### ALU Instructions (V2) ### -@if defined(BASELINE_V2) - :addi10.sp imm10s is $(I16) & opc5=0b11011 & imm10s { sp = sp + imm10s; } @@ -996,14 +1082,10 @@ sp_rel7w: [+ rel7w] is rel7w { addr:4 = sp + rel7w; export addr; } :lwi37.sp rt3b, sp_rel7w is $(I16) & rt3b & $(XWI37SP) & xwi37_ls=0 & sp_rel7w { rt3b = *sp_rel7w; } :swi37.sp rt3b, sp_rel7w is $(I16) & rt3b & $(XWI37SP) & xwi37_ls=1 & sp_rel7w { *sp_rel7w = rt3b; } -@endif - ### 16-bit Baseline V3 instructions ### -@if defined(BASELINE_V3) - ### ALU Instructions (V3 16-bit) ### imm6u_: imm8 is imm6u [ imm8 = imm6u << 2; ] { export *[const]:4 imm8; } @@ -1056,11 +1138,11 @@ push25_re: re2 is re2 & re2=3 { push25_s8(); } } -macro pop25_special() { Lmwbi(fp); Lmwbi(gp); Lmwbi(lp); } -macro pop25_s0() { Lmwbi(s0); } -macro pop25_s2() { pop25_s0(); Lmwbi(s1); Lmwbi(s2); } -macro pop25_s4() { pop25_s2(); Lmwbi(s3); Lmwbi(s4); } -macro pop25_s8() { pop25_s4(); Lmwbi(s5); Lmwbi(s6); Lmwbi(s7); Lmwbi(s8); } +macro pop25_special() { LmwOp(fp); LmwOp(gp); LmwOp(lp); } +macro pop25_s0() { LmwOp(s0); } +macro pop25_s2() { pop25_s0(); LmwOp(s1); LmwOp(s2); } +macro pop25_s4() { pop25_s2(); LmwOp(s3); LmwOp(s4); } +macro pop25_s8() { pop25_s4(); LmwOp(s5); LmwOp(s6); LmwOp(s7); LmwOp(s8); } pop25_re: re2 is re2 & re2=0 { pop25_s0(); } pop25_re: re2 is re2 & re2=1 { pop25_s2(); } @@ -1076,6 +1158,16 @@ pop25_re: re2 is re2 & re2=3 { pop25_s8(); } } -@endif +# EX9.IT +imm9u_: imm9 is imm5u & imm4u [ imm9 = (imm4u << 5) | imm5u; ] { export *[const]:4 imm9; } +define pcodeop ex9; +# TODO: Depending on the value of ITB.HW the address is either set by hardware or set by ITB.Addr +:ex9.it imm9u_ is $(I16) & opc6=0b110101 & (bit5=1 | bit6=1 | bit7=1 | bit8=1) & imm9u_ { + ex9(imm9u_); +} + +:ex9.it imm5u is $(I16) & opc10=0b1011101010 & imm5u { + ex9(imm5u:4); +} diff --git a/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec b/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec index 40714ad394..244364229b 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec +++ b/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec @@ -1,7 +1,3 @@ -@define BASELINE_V2 "yes" -@define BASELINE_V3 "yes" -@define PERFORMANCE_V1 "yes" -@define PERFORMANCE_V2 "yes" @define ENDIAN "big" @include "nds32.sinc" diff --git a/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec b/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec index ee6a1b9c48..d6d998cd97 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec +++ b/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec @@ -1,7 +1,3 @@ -@define BASELINE_V2 "yes" -@define BASELINE_V3 "yes" -@define PERFORMANCE_V1 "yes" -@define PERFORMANCE_V2 "yes" @define ENDIAN "little" @include "nds32.sinc" diff --git a/Ghidra/Processors/NDS32/data/sleighArgs.txt b/Ghidra/Processors/NDS32/data/sleighArgs.txt deleted file mode 100644 index ce06926358..0000000000 --- a/Ghidra/Processors/NDS32/data/sleighArgs.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Add sleigh compiler options to this file (one per line) which will -# be used when compiling each language within this module. -# All options should start with a '-' character. -# -# IMPORTANT: The -a option should NOT be specified -# \ No newline at end of file diff --git a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.java b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.java index b054561c04..fa50a11cd7 100644 --- a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.java +++ b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/plugin/core/analysis/NDS32Analyzer.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.plugin.core.analysis; import java.math.BigInteger; @@ -29,16 +44,12 @@ import ghidra.util.task.TaskMonitor; public class NDS32Analyzer extends ConstantPropagationAnalyzer { private final static String PROCESSOR_NAME = "NDS32"; - private static final String SWITCH_OPTION_NAME = "Switch Table Recovery"; - private static final String SWITCH_OPTION_DESCRIPTION = "Turn on to recover switch tables (not implemented yet !)"; - private static final boolean SWITCH_OPTION_DEFAULT_VALUE = false; - private static final String RECOVER_GP_OPTION_NAME = "Recover global GP register writes"; private static final String RECOVER_GP_OPTION_DESCRIPTION = "Reads the global GP value from the symbol _SDA_BASE_"; private static final boolean RECOVER_GP_OPTION_DEFAULT_VALUE = true; - private boolean recoverSwitchTables = SWITCH_OPTION_DEFAULT_VALUE; + //private boolean recoverSwitchTables = SWITCH_OPTION_DEFAULT_VALUE; private boolean recoverGp = RECOVER_GP_OPTION_DEFAULT_VALUE; private Address gpAssumptionValue = null; @@ -67,10 +78,6 @@ public class NDS32Analyzer extends ConstantPropagationAnalyzer { public void optionsChanged(Options options, Program program) { super.optionsChanged(options, program); - options.registerOption(SWITCH_OPTION_NAME, recoverSwitchTables, null, - SWITCH_OPTION_DESCRIPTION); - recoverSwitchTables = options.getBoolean(SWITCH_OPTION_NAME, recoverSwitchTables); - options.registerOption(RECOVER_GP_OPTION_NAME, recoverGp, null, RECOVER_GP_OPTION_DESCRIPTION); recoverGp = options.getBoolean(RECOVER_GP_OPTION_NAME, recoverGp); @@ -88,7 +95,9 @@ public class NDS32Analyzer extends ConstantPropagationAnalyzer { /** * Check for a global GP register symbol or discovered symbol + * @param program * @param set + * @param monitor */ private void checkForGlobalGP(Program program, AddressSetView set, TaskMonitor monitor) { if (!recoverGp) { @@ -139,7 +148,7 @@ public class NDS32Analyzer extends ConstantPropagationAnalyzer { } } - ContextEvaluator eval = new ConstantPropagationContextEvaluator(trustWriteMemOption) { + ContextEvaluator eval = new ConstantPropagationContextEvaluator(monitor, trustWriteMemOption) { @Override public boolean evaluateDestination(VarnodeContext context, Instruction instruction) { FlowType flowtype = instruction.getFlowType(); @@ -147,13 +156,6 @@ public class NDS32Analyzer extends ConstantPropagationAnalyzer { return false; } - if (recoverSwitchTables) { - String mnemonic = instruction.getMnemonicString(); - if (mnemonic.equals("jr")) { - fixJumpTable(program, instruction, monitor); - } - } - return false; } }; @@ -167,21 +169,4 @@ public class NDS32Analyzer extends ConstantPropagationAnalyzer { return resultSet; } - /** - * @param program - * @param startInstr - * @param monitor - */ - private void fixJumpTable(Program program, Instruction startInstr, TaskMonitor monitor) { - /* TODO: implement switch recovery ? - * We are looking for tables like this : - * - * slti45 a0,0x4 <- table size - * beqzs8 LAB_005159ea <- default jump - * sethi ta, 0x515 - * ori ta, ta, 0x9a0 - * lw a0, [ta + (a0 << 0x2)] <- ref to table - * jr a0 <- table jump - */ - } } diff --git a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java deleted file mode 100644 index 5f5bea65d4..0000000000 --- a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationConstants.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ### - * 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 NDS32_ElfRelocationConstants { - public static final int R_NDS32_NONE = 0; - public static final int R_NDS32_16_RELA = 19; - public static final int R_NDS32_32_RELA = 20; - public static final int R_NDS32_9_PCREL_RELA = 22; - public static final int R_NDS32_15_PCREL_RELA = 23; - public static final int R_NDS32_17_PCREL_RELA = 24; - public static final int R_NDS32_25_PCREL_RELA = 25; - public static final int R_NDS32_HI20_RELA = 26; - public static final int R_NDS32_LO12S3_RELA = 27; - public static final int R_NDS32_LO12S2_RELA = 28; - public static final int R_NDS32_LO12S1_RELA = 29; - public static final int R_NDS32_LO12S0_RELA = 30; - public static final int R_NDS32_SDA15S3_RELA = 31; - public static final int R_NDS32_SDA15S2_RELA = 32; - public static final int R_NDS32_SDA15S1_RELA = 33; - public static final int R_NDS32_SDA15S0_RELA = 34; - public static final int R_NDS32_GOT20 = 37; - public static final int R_NDS32_25_PLTREL = 38; - public static final int R_NDS32_COPY = 39; - public static final int R_NDS32_GLOB_DAT = 40; - public static final int R_NDS32_JMP_SLOT = 41; - public static final int R_NDS32_RELATIVE = 42; - public static final int R_NDS32_GOTOFF = 43; - public static final int R_NDS32_GOTPC20 = 44; - public static final int R_NDS32_GOT_HI20 = 45; - public static final int R_NDS32_GOT_LO12 = 46; - public static final int R_NDS32_GOTPC_HI20 = 47; - public static final int R_NDS32_GOTPC_LO12 = 48; - public static final int R_NDS32_GOTOFF_HI20 = 49; - public static final int R_NDS32_GOTOFF_LO12 = 50; - public static final int R_NDS32_INSN16 = 51; - public static final int R_NDS32_LABEL = 52; - public static final int R_NDS32_LONGCALL1 = 53; - public static final int R_NDS32_LONGCALL2 = 54; - public static final int R_NDS32_LONGCALL3 = 55; - public static final int R_NDS32_LONGJUMP1 = 56; - public static final int R_NDS32_LONGJUMP2 = 57; - public static final int R_NDS32_LONGJUMP3 = 58; - public static final int R_NDS32_LOADSTORE = 59; - public static final int R_NDS32_9_FIXED_RELA = 60; - public static final int R_NDS32_15_FIXED_RELA = 61; - public static final int R_NDS32_17_FIXED_RELA = 62; - public static final int R_NDS32_25_FIXED_RELA = 63; - public static final int R_NDS32_PLTREL_HI20 = 64; - public static final int R_NDS32_PLTREL_LO12 = 65; - public static final int R_NDS32_PLT_GOTREL_HI20 = 66; - public static final int R_NDS32_PLT_GOTREL_LO12 = 67; - public static final int R_NDS32_LO12S0_ORI_RELA = 72; - public static final int R_NDS32_DWARF2_OP1_RELA = 77; - public static final int R_NDS32_DWARF2_OP2_RELA = 78; - public static final int R_NDS32_DWARF2_LEB_RELA = 79; - public static final int R_NDS32_WORD_9_PCREL_RELA = 94; - public static final int R_NDS32_LONGCALL4 = 107; - public static final int R_NDS32_RELA_NOP_MIX = 192; - public static final int R_NDS32_RELA_NOP_MAX = 255; -} diff --git a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java index 0d1f660454..4bac0c4d4f 100644 --- a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java +++ b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationHandler.java @@ -4,9 +4,9 @@ * 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. @@ -16,21 +16,22 @@ package ghidra.app.util.bin.format.elf.relocation; import java.util.Map; -import ghidra.app.util.bin.format.elf.ElfConstants; -import ghidra.app.util.bin.format.elf.ElfHeader; -import ghidra.app.util.bin.format.elf.ElfLoadHelper; -import ghidra.app.util.bin.format.elf.ElfRelocation; -import ghidra.app.util.bin.format.elf.ElfRelocationTable; -import ghidra.app.util.bin.format.elf.ElfSymbol; + +import ghidra.app.util.bin.format.elf.*; import ghidra.app.util.importer.MessageLog; import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressOutOfBoundsException; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; -import ghidra.util.exception.NotFoundException; +import ghidra.program.model.reloc.RelocationResult; +import ghidra.program.model.reloc.Relocation.Status; + +public class NDS32_ElfRelocationHandler extends AbstractElfRelocationHandler> { + + public NDS32_ElfRelocationHandler() { + super(NDS32_ElfRelocationType.class); + } -public class NDS32_ElfRelocationHandler extends ElfRelocationHandler { @Override public boolean canRelocate(ElfHeader elf) { @@ -38,35 +39,26 @@ public class NDS32_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public NDS32_ElfRelocationContext createRelocationContext(ElfLoadHelper loadHelper, - ElfRelocationTable relocationTable, Map symbolMap) { - return new NDS32_ElfRelocationContext(this, loadHelper, relocationTable, symbolMap); + public int getRelrRelocationType() { + return NDS32_ElfRelocationType.R_NDS32_RELATIVE.typeId; } @Override - public void relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException { - ElfHeader elf = elfRelocationContext.getElfHeader(); - - if (elf.e_machine() != ElfConstants.EM_NDS32) { - return; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, NDS32_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { - if (!elf.is32Bit()) { - return; - } - - NDS32_ElfRelocationContext nds32RelocationContext = - (NDS32_ElfRelocationContext) elfRelocationContext; + ElfRelocationContext nds32RelocationContext = elfRelocationContext; - int type = relocation.getType(); int symbolIndex = relocation.getSymbolIndex(); - doRelocate(nds32RelocationContext, type, symbolIndex, relocation, relocationAddress); + return doRelocate(nds32RelocationContext, type, symbolIndex, relocation, relocationAddress); + } - private void doRelocate(NDS32_ElfRelocationContext nds32RelocationContext, int relocType, + private RelocationResult doRelocate(ElfRelocationContext nds32RelocationContext, NDS32_ElfRelocationType type, int symbolIndex, ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException, AddressOutOfBoundsException { + throws MemoryAccessException { Program program = nds32RelocationContext.getProgram(); Memory memory = program.getMemory(); MessageLog log = nds32RelocationContext.getLog(); @@ -84,28 +76,21 @@ public class NDS32_ElfRelocationHandler extends ElfRelocationHandler { int value = 0; int newValue = 0; - - switch(relocType) { - case NDS32_ElfRelocationConstants.R_NDS32_HI20_RELA: + int byteLength = 4; + + switch(type) { + case R_NDS32_HI20_RELA: value = (int)(symbolValue + addend); newValue = (oldValue & 0xfff00000) | (value >> 12); memory.setInt(relocationAddress, newValue, true); - break; - case NDS32_ElfRelocationConstants.R_NDS32_LO12S0_RELA: + return new RelocationResult(Status.APPLIED, byteLength); + case R_NDS32_LO12S0_RELA: value = (int)(symbolValue + addend); newValue = (oldValue & 0xfffff000) | (value & 0xfff); memory.setInt(relocationAddress, newValue, true); - break; + return new RelocationResult(Status.APPLIED, byteLength); default: - markAsUnhandled(program, relocationAddress, relocType, symbolIndex, symbolName, log); - } - } - - private static class NDS32_ElfRelocationContext extends ElfRelocationContext { - - protected NDS32_ElfRelocationContext(ElfRelocationHandler handler, ElfLoadHelper loadHelper, - ElfRelocationTable relocationTable, Map symbolMap) { - super(handler, loadHelper, relocationTable, symbolMap); + return RelocationResult.UNSUPPORTED; } } } diff --git a/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationType.java b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationType.java new file mode 100644 index 0000000000..e255cad300 --- /dev/null +++ b/Ghidra/Processors/NDS32/src/main/java/ghidra/app/util/bin/format/elf/relocation/NDS32_ElfRelocationType.java @@ -0,0 +1,195 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum NDS32_ElfRelocationType implements ElfRelocationType { + /* REL relocations. */ + R_NDS32_16(1), + R_NDS32_32(2), + R_NDS32_20(3), + R_NDS32_9_PCREL(4), + R_NDS32_15_PCREL(5), + R_NDS32_17_PCREL(6), + R_NDS32_25_PCREL(7), + R_NDS32_HI20(8), + R_NDS32_LO12S3(9), + R_NDS32_LO12S2(10), + R_NDS32_LO12S1(11), + R_NDS32_LO12S0(12), + R_NDS32_SDA15S3(13), + R_NDS32_SDA15S2(14), + R_NDS32_SDA15S1(15), + R_NDS32_SDA15S0(16), + R_NDS32_GNU_VTINHERIT(17), + R_NDS32_GNU_VTENTRY(18), + /* RELA relocations. */ + R_NDS32_16_RELA(19), + R_NDS32_32_RELA(20), + R_NDS32_20_RELA(21), + R_NDS32_9_PCREL_RELA(22), + R_NDS32_15_PCREL_RELA(23), + R_NDS32_17_PCREL_RELA(24), + R_NDS32_25_PCREL_RELA(25), + R_NDS32_HI20_RELA(26), + R_NDS32_LO12S3_RELA(27), + R_NDS32_LO12S2_RELA(28), + R_NDS32_LO12S1_RELA(29), + R_NDS32_LO12S0_RELA(30), + R_NDS32_SDA15S3_RELA(31), + R_NDS32_SDA15S2_RELA(32), + R_NDS32_SDA15S1_RELA(33), + R_NDS32_SDA15S0_RELA(34), + R_NDS32_RELA_GNU_VTINHERIT(35), + R_NDS32_RELA_GNU_VTENTRY(36), + /* GOT and PLT. */ + R_NDS32_GOT20(37), + R_NDS32_25_PLTREL(38), + R_NDS32_COPY(39), + R_NDS32_GLOB_DAT(40), + R_NDS32_JMP_SLOT(41), + R_NDS32_RELATIVE(42), + R_NDS32_GOTOFF(43), + R_NDS32_GOTPC20(44), + R_NDS32_GOT_HI20(45), + R_NDS32_GOT_LO12(46), + R_NDS32_GOTPC_HI20(47), + R_NDS32_GOTPC_LO12(48), + R_NDS32_GOTOFF_HI20(49), + R_NDS32_GOTOFF_LO12(50), + /* 32_to_16 relaxations. */ + R_NDS32_INSN16(51), + /* Alignment tag. */ + R_NDS32_LABEL(52), + R_NDS32_LONGCALL1(53), /* This is obsoleted. */ + R_NDS32_LONGCALL2(54), /* This is obsoleted. */ + R_NDS32_LONGCALL3(55), /* This is obsoleted. */ + R_NDS32_LONGJUMP1(56), /* This is obsoleted. */ + R_NDS32_LONGJUMP2(57), /* This is obsoleted. */ + R_NDS32_LONGJUMP3(58), /* This is obsoleted. */ + R_NDS32_LOADSTORE(59), /* This is obsoleted. */ + R_NDS32_9_FIXED_RELA(60), + R_NDS32_15_FIXED_RELA(61), + R_NDS32_17_FIXED_RELA(62), + R_NDS32_25_FIXED_RELA(63), + R_NDS32_PLTREL_HI20(64), /* This is obsoleted. */ + R_NDS32_PLTREL_LO12(65), /* This is obsoleted. */ + R_NDS32_PLT_GOTREL_HI20(66), + R_NDS32_PLT_GOTREL_LO12(67), + R_NDS32_SDA12S2_DP_RELA(68), + R_NDS32_SDA12S2_SP_RELA(69), + R_NDS32_LO12S2_DP_RELA(70), + R_NDS32_LO12S2_SP_RELA(71), + R_NDS32_LO12S0_ORI_RELA(72), + R_NDS32_SDA16S3_RELA(73), + R_NDS32_SDA17S2_RELA(74), + R_NDS32_SDA18S1_RELA(75), + R_NDS32_SDA19S0_RELA(76), + R_NDS32_DWARF2_OP1_RELA(77), /* This is obsoleted. */ + R_NDS32_DWARF2_OP2_RELA(78), /* This is obsoleted. */ + R_NDS32_DWARF2_LEB_RELA(79), /* This is obsoleted. */ + R_NDS32_UPDATE_TA_RELA(80), /* This is obsoleted. */ + R_NDS32_9_PLTREL(81), + R_NDS32_PLT_GOTREL_LO20(82), + R_NDS32_PLT_GOTREL_LO15(83), + R_NDS32_PLT_GOTREL_LO19(84), + R_NDS32_GOT_LO15(85), + R_NDS32_GOT_LO19(86), + R_NDS32_GOTOFF_LO15(87), + R_NDS32_GOTOFF_LO19(88), + R_NDS32_GOT15S2_RELA(89), + R_NDS32_GOT17S2_RELA(90), + R_NDS32_5_RELA(91), + R_NDS32_10_UPCREL_RELA(92), /* This is obsoleted. */ + R_NDS32_SDA_FP7U2_RELA(93), + R_NDS32_WORD_9_PCREL_RELA(94), + R_NDS32_25_ABS_RELA(95), + R_NDS32_17IFC_PCREL_RELA(96), /* This is obsoleted. */ + R_NDS32_10IFCU_PCREL_RELA(97), /* This is obsoleted. */ + /* TLS support. */ + R_NDS32_TLS_LE_HI20(98), + R_NDS32_TLS_LE_LO12(99), + R_NDS32_TLS_IE_HI20(100), + R_NDS32_TLS_IE_LO12S2(101), + R_NDS32_TLS_TPOFF(102), + R_NDS32_TLS_LE_20(103), + R_NDS32_TLS_LE_15S0(104), + R_NDS32_TLS_LE_15S1(105), + R_NDS32_TLS_LE_15S2(106), + R_NDS32_LONGCALL4(107), + R_NDS32_LONGCALL5(108), + R_NDS32_LONGCALL6(109), + R_NDS32_LONGJUMP4(110), + R_NDS32_LONGJUMP5(111), + R_NDS32_LONGJUMP6(112), + R_NDS32_LONGJUMP7(113), + /* Reserved numbers: 114. */ + /* TLS support */ + R_NDS32_TLS_IE_LO12(115), + R_NDS32_TLS_IEGP_HI20(116), + R_NDS32_TLS_IEGP_LO12(117), + R_NDS32_TLS_IEGP_LO12S2(118), + R_NDS32_TLS_DESC(119), + R_NDS32_TLS_DESC_HI20(120), + R_NDS32_TLS_DESC_LO12(121), + R_NDS32_TLS_DESC_20(122), + R_NDS32_TLS_DESC_SDA17S2(123), + /* Reserved numbers: 124-191. */ + + /* These used only for relaxations */ + R_NDS32_RELAX_ENTRY(192), + R_NDS32_GOT_SUFF(193), + R_NDS32_GOTOFF_SUFF(194), + R_NDS32_PLT_GOT_SUFF(195), + R_NDS32_MULCALL_SUFF(196), /* This is obsoleted. */ + R_NDS32_PTR(197), + R_NDS32_PTR_COUNT(198), + R_NDS32_PTR_RESOLVED(199), + R_NDS32_PLTBLOCK(200), /* This is obsoleted. */ + R_NDS32_RELAX_REGION_BEGIN(201), + R_NDS32_RELAX_REGION_END(202), + R_NDS32_MINUEND(203), + R_NDS32_SUBTRAHEND(204), + R_NDS32_DIFF8(205), + R_NDS32_DIFF16(206), + R_NDS32_DIFF32(207), + R_NDS32_DIFF_ULEB128(208), + R_NDS32_DATA(209), + R_NDS32_TRAN(210), + /* TLS support */ + R_NDS32_TLS_LE_ADD(211), + R_NDS32_TLS_LE_LS(212), + R_NDS32_EMPTY(213), + R_NDS32_TLS_DESC_ADD(214), + R_NDS32_TLS_DESC_FUNC(215), + R_NDS32_TLS_DESC_CALL(216), + R_NDS32_TLS_DESC_MEM(217), + R_NDS32_RELAX_REMOVE(218), + R_NDS32_RELAX_GROUP(219), + R_NDS32_TLS_IEGP_LW(220), + R_NDS32_LSI(221), + R_NDS32_RELA_NOP_MAX(255); + + public final int typeId; + + private NDS32_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O0_EmulatorTest.java b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O0_EmulatorTest.java new file mode 100644 index 0000000000..b08df6306d --- /dev/null +++ b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O0_EmulatorTest.java @@ -0,0 +1,41 @@ +/* ### + * 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; + +import junit.framework.Test; + +public class NDS32_BE_O0_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "NDS32:BE:32:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public NDS32_BE_O0_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "NDS32BE_GCC_O0"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_BE_O0_EmulatorTest.class); + } +} diff --git a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O3_EmulatorTest.java b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O3_EmulatorTest.java new file mode 100644 index 0000000000..c8136ce919 --- /dev/null +++ b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_BE_O3_EmulatorTest.java @@ -0,0 +1,41 @@ +/* ### + * 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; + +import junit.framework.Test; + +public class NDS32_BE_O3_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "NDS32:BE:32:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public NDS32_BE_O3_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "NDS32BE_GCC_O3"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_BE_O3_EmulatorTest.class); + } +} diff --git a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java index 34e2b8ecde..3799bdeeeb 100644 --- a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java +++ b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O0_EmulatorTest.java @@ -4,9 +4,9 @@ * 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. diff --git a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java index d90c855ed4..5343e5a272 100644 --- a/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java +++ b/Ghidra/Processors/NDS32/src/test.processors/java/ghidra/test/processors/NDS32_LE_O3_EmulatorTest.java @@ -4,9 +4,9 @@ * 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. From ed4ae8bfa1f6b5db8c7356b2a4253c4c647e65f4 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Wed, 26 Nov 2025 20:19:40 +0000 Subject: [PATCH 3/7] GP-6007: Added stubs for nds32 FPU instructions --- Ghidra/Processors/NDS32/build.gradle | 4 +- .../NDS32/data/languages/nds32.ldefs | 2 + .../NDS32/data/languages/nds32.sinc | 433 +++++++++++++++++- .../NDS32/data/patterns/nds32_patterns.xml | 11 +- 4 files changed, 428 insertions(+), 22 deletions(-) diff --git a/Ghidra/Processors/NDS32/build.gradle b/Ghidra/Processors/NDS32/build.gradle index 360bb9e8ba..801e85ff93 100644 --- a/Ghidra/Processors/NDS32/build.gradle +++ b/Ghidra/Processors/NDS32/build.gradle @@ -23,8 +23,8 @@ eclipse.project.name = 'Processors NDS32' dependencies { - compile project(':Base') + api project(':Base') // Temporary dependency so that pcodeTests can use the Decompiler switch recovery - compile project(':Decompiler') + api project(':Decompiler') } diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.ldefs b/Ghidra/Processors/NDS32/data/languages/nds32.ldefs index 80619e45b1..8ee0ac46ac 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.ldefs +++ b/Ghidra/Processors/NDS32/data/languages/nds32.ldefs @@ -12,6 +12,7 @@ id="NDS32:BE:32:default"> NDS32 default processor 32-bit big-endian + NDS32 default processor 32-bit little-endian + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.sinc b/Ghidra/Processors/NDS32/data/languages/nds32.sinc index 5f68680d11..996a57d199 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.sinc +++ b/Ghidra/Processors/NDS32/data/languages/nds32.sinc @@ -17,10 +17,24 @@ define register offset=0x100 size=8 define register offset=0x100 size=4 [d0.hi d0.lo d1.hi d1.lo]; -define register offset=0x1000 size=4 -[ itb ]; +define register offset=0x200 size=4 +[ itb lb lc le ifc_lp]; -define register offset=0x1000 size=8 contextreg; +define register offset=0x1000 size=4 +[ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 + fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 + fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 + fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31 +]; + +define register offset=0x1000 size=8 +[ fd0 fd1 fd2 fd3 fd4 fd5 fd6 fd7 + fd8 fd9 fd10 fd11 fd12 fd13 fd14 fd15 + fd16 fd17 fd18 fd19 fd20 fd21 fd22 fd23 + fd24 fd25 fd26 fd27 fd28 fd29 fd30 fd31 +]; + +define register offset=0x300 size=8 contextreg; define context contextreg counter = (22,26) regNum = (27,31) # register for load/store multiple instructions @@ -30,10 +44,16 @@ define token instr32(32) OpSz = (31, 31) Opc = (25, 30) Rt = (20, 24) + Fst = (20, 24) + Fdt = (20, 24) Rth = (21, 24) Rtl = (21, 24) Ra = (15, 19) + Fsa = (15, 19) + Fda = (15, 19) Rb = (10, 14) + Fsb = (10, 14) + Fdb = (10, 14) Rd = (5, 9) Rs = (5, 9) Sub5 = (0, 4) @@ -41,6 +61,14 @@ define token instr32(32) Sub7 = (0, 6) Sub8 = (0, 7) Sub3 = (7, 9) + fop4 = (6, 9) + cop4 = (0, 3) + f2op = (10, 14) + fcnd = (7, 9) + cmpe = (6, 6) + fbi = (7, 7) + cpn = (13, 14) + fsbi = (12, 12) Imm8u = (7,14) Imm5u = (10, 14) Imm5s = (10, 14) signed @@ -63,8 +91,9 @@ define token instr32(32) Imm20u = (0, 19) Imm20s = (0, 19) signed Imm24s = (0, 23) signed - Imm11s = (8, 18) signed - Imm8s = (0, 7) signed + Imm12s = (0, 11) signed + Imm11s = (8, 18) signed + Imm8s = (0, 7) signed sv = (8, 9) SrIdx = (10, 19) Swid = (5, 19) @@ -143,25 +172,43 @@ attach variables [Dthigh] [ d0.hi d1.hi ]; +attach variables [ Fst Fsa Fsb ] +[ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 + fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 + fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 + fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31 +]; + +attach variables [ Fdt Fda Fdb ] +[ fd0 fd1 fd2 fd3 fd4 fd5 fd6 fd7 + fd8 fd9 fd10 fd11 fd12 fd13 fd14 fd15 + fd16 fd17 fd18 fd19 fd20 fd21 fd22 fd23 + fd24 fd25 fd26 fd27 fd28 fd29 fd30 fd31 +]; @define I32 "(OpSz=0)" +@define LBGP "(Opc=0b010111)" +@define LWC "(Opc=0b011000)" +@define SWC "(Opc=0b011001)" +@define LDC "(Opc=0b011010)" +@define SDC "(Opc=0b011011)" +@define LSMW "(Opc=0b011101)" +@define MEM "(Opc=0b011100)" +@define HWGP "(Opc=0b011110)" +@define SBGP "(Opc=0b011111)" @define ALU_1 "(Opc=0b100000)" @define ALU_2 "(Opc=0b100001)" -@define ALU2Z "(Alu2Mod=0b0000)" -@define GPR "(Alu2Mod=0b0001)" +@define JI "(Opc=0b100100)" +@define JREG "(Opc=0b100101)" @define BR1 "(Opc=0b100110)" @define BR2 "(Opc=0b100111)" @define BR3 "(Opc=0b101101)" -@define LSMW "(Opc=0b011101)" -@define JI "(Opc=0b100100)" -@define MEM "(Opc=0b011100)" @define MISC "(Opc=0b110010)" -@define JREG "(Opc=0b100101)" -@define SBGP "(Opc=0b011111)" -@define LBGP "(Opc=0b010111)" -@define HWGP "(Opc=0b011110)" +@define COP "(Opc=0b110101)" @define SIMD "(Opc=0b111000)" +@define ALU2Z "(Alu2Mod=0b0000)" +@define GPR "(Alu2Mod=0b0001)" ### ALU Instruction with Immediate ### @@ -234,9 +281,18 @@ UsrName: d0.lo is Group=0 & Usr=0 & d0.lo { export d0.lo; } UsrName: d0.hi is Group=0 & Usr=1 & d0.hi { export d0.hi; } UsrName: d1.lo is Group=0 & Usr=2 & d1.lo { export d1.lo; } UsrName: d1.hi is Group=0 & Usr=3 & d1.hi { export d1.hi; } +UsrName: le is Group=0 & Usr=0b11010 & le { export le; } +UsrName: itb is Group=0 & Usr=0b11100 & itb { export itb; } +UsrName: lb is Group=0 & Usr=0b11001 & lb { export lb; } +UsrName: lc is Group=0 & Usr=0b11011 & lc { export lc; } +UsrName: ifc_lp is Group=0 & Usr=0b11101 & ifc_lp { export ifc_lp; } +#UsrName: pc is Group=0 & Usr=0b11111 & pc { export pc; } + :mfusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100000 { UsrName = Rt; } +:mfusr Rt, pc is $(I32) & $(ALU_2) & Rt & Group=0 & Usr=0b11111 & $(ALU2Z) & Sub6=0b100000 & pc { pc = Rt; goto[pc]; } # Not sure this works correctly :mtusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100001 { Rt = UsrName; } +:mtusr Rt, pc is $(I32) & $(ALU_2) & Rt & Group=0 & Usr=0b11111 & $(ALU2Z) & Sub6=0b100001 & pc { Rt = inst_next; } ### Divide Instructions ### @@ -1171,3 +1227,352 @@ define pcodeop ex9; :ex9.it imm5u is $(I16) & opc10=0b1011101010 & imm5u { ex9(imm5u:4); } + +# Floating Point + +# FPU_FS1 +define pcodeop fadds; +:fadds Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x0 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fadds(Fsa, Fsb); +} + +define pcodeop fsubs; +:fsubs Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x1 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fsubs(Fsa, Fsb); +} + +define pcodeop fcpynss; +:fcpynss Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x2 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fcpynss(Fsa, Fsb); +} + +define pcodeop fcpyss; +:fcpyss Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x3 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fcpyss(Fsa, Fsb); +} + +define pcodeop fmadds; +:fmadds Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x4 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fmadds(Fsa, Fsb); +} + +define pcodeop fmsubs; +:fmsubs Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x5 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fmsubs(Fsa, Fsb); +} + +define pcodeop fcmovns; +:fcmovns Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x6 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fcmovns(Fsa, Fsb); +} + +define pcodeop fcmovzs; +:fcmovzs Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x7 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fcmovzs(Fsa, Fsb); +} + +define pcodeop fnmadds; +:fnmadds Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x8 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fnmadds(Fsa, Fsb); +} + +define pcodeop fnmsubs; +:fnmsubs Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0x9 & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fnmsubs(Fsa, Fsb); +} + +define pcodeop fmuls; +:fmuls Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0xa & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fmuls(Fsa, Fsb); +} + +define pcodeop fdivs; +:fdivs Fst, Fsa, Fsb is $(I32) & $(COP) & fop4=0xb & Fst & Fsa & Fsb & cop4=0x0 { + Fst = fdivs(Fsa, Fsb); +} + +# FPU_FS1_F2OP + +define pcodeop fs2d; +:fs2d Fdt, Fsa is $(I32) & $(COP) & fop4=0xf & Fdt & Fsa & f2op=0 & cop4=0x0 { + Fdt = fs2d(Fsa); +} + +define pcodeop fsqrts; +:fsqrts Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=1 & cop4=0x0 { + Fst = fsqrts(Fsa); +} + +define pcodeop fabss; +:fabss Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=0x5 & cop4=0x0 { + Fst = fabss(Fsa); +} + +define pcodeop fui2s; +:fui2s Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=0x8 & cop4=0x0 { + Fst = fui2s(Fsa); +} + +define pcodeop fsi2s; +:fsi2s Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=0xc & cop4=0x0 { + Fst = fsi2s(Fsa); +} + +define pcodeop fs2ui; +:fs2ui Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=0x10 & cop4=0x0 { + Fst = fs2ui(Fsa); +} + +define pcodeop fs2ui.z; +:fs2ui.z Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=0x14 & cop4=0x0 { + Fst = fs2ui.z(Fsa); +} + +define pcodeop fs2si; +:fs2si Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=0x18 & cop4=0x0 { + Fst = fs2si(Fsa); +} + +define pcodeop fs2si.z; +:fs2si.z Fst, Fsa is $(I32) & $(COP) & fop4=0xf & Fst & Fsa & f2op=0x1c & cop4=0x0 { + Fst = fs2si.z(Fsa); +} + +# FPU_FS2 +fcond: "eq" is fcnd=0 { local tmp:1 = 0; export *[const]:1 tmp; } +fcond: "lt" is fcnd=1 { local tmp:1 = 1; export *[const]:1 tmp; } +fcond: "le" is fcnd=2 { local tmp:1 = 2; export *[const]:1 tmp; } +fcond: "un" is fcnd=3 { local tmp:1 = 3; export *[const]:1 tmp; } + +fcmpe: "" is cmpe=0 { local tmp:1 = 0; export *[const]:1 tmp; } +fcmpe: ".e" is cmpe=1 { local tmp:1 = 1; export *[const]:1 tmp; } +define pcodeop fcmps; +:fcmp^fcond^"s"^fcmpe Fst, Fsa, Fsb is $(I32) & $(COP) & Fst & Fsa & Fsb & cop4=0x4 & fcond & fcmpe { + Fst = fcmps(Fsa, Fsb, fcond, fcmpe); +} + +# FPU_FD1 + +define pcodeop faddd; +:faddd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x0 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = faddd(Fda, Fdb); +} + +define pcodeop fsubd; +:fsubd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x1 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fsubd(Fda, Fdb); +} + +define pcodeop fcpynsd; +:fcpynsd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x2 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fcpynsd(Fda, Fdb); +} + +define pcodeop fcpysd; +:fcpysd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x3 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fcpysd(Fda, Fdb); +} + +define pcodeop fmaddd; +:fmaddd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x4 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fmaddd(Fda, Fdb); +} + +define pcodeop fmsubd; +:fmsubd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x5 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fmsubd(Fda, Fdb); +} + +define pcodeop fcmovnd; +:fcmovnd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x6 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fcmovnd(Fda, Fdb); +} + +define pcodeop fcmovzd; +:fcmovzd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x7 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fcmovzd(Fda, Fdb); +} + +define pcodeop fnmaddd; +:fnmaddd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x8 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fnmaddd(Fda, Fdb); +} + +define pcodeop fnmsubd; +:fnmsubd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0x9 & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fnmsubd(Fda, Fdb); +} + +define pcodeop fmuld; +:fmuld Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0xa & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fmuld(Fda, Fdb); +} + +define pcodeop fdivd; +:fdivd Fdt, Fda, Fdb is $(I32) & $(COP) & fop4=0xb & Fdt & Fda & Fdb & cop4=0x8 { + Fdt = fdivd(Fda, Fdb); +} + +# FPU_FD1_F2OP +define pcodeop fd2s; +:fd2s Fst, Fda is $(I32) & $(COP) & fop4=0xf & Fst & Fda & f2op=0 & cop4=0x8 { + Fst = fd2s(Fda); +} + +define pcodeop fsqrtd; +:fsqrtd Fdt, Fda is $(I32) & $(COP) & fop4=0xf & Fdt & Fda & f2op=1 & cop4=0x8 { + Fdt = fsqrtd(Fda); +} + +define pcodeop fabsd; +:fabsd Fdt, Fda is $(I32) & $(COP) & fop4=0xf & Fdt & Fda & f2op=0x5 & cop4=0x8 { + Fdt = fabsd(Fda); +} + +define pcodeop fui2d; +:fui2d Fdt, Fsa is $(I32) & $(COP) & fop4=0xf & Fdt & Fsa & f2op=0x8 & cop4=0x8 { + Fdt = fui2d(Fsa); +} + +define pcodeop fsi2d; +:fsi2d Fdt, Fsa is $(I32) & $(COP) & fop4=0xf & Fdt & Fsa & f2op=0xc & cop4=0x8 { + Fdt = fsi2d(Fsa); +} + +define pcodeop fd2ui; +:fd2ui Fst, Fda is $(I32) & $(COP) & fop4=0xf & Fst & Fda & f2op=0x10 & cop4=0x8 { + Fst = fd2ui(Fda); +} + +define pcodeop fd2ui.z; +:fd2ui.z Fst, Fda is $(I32) & $(COP) & fop4=0xf & Fst & Fda & f2op=0x14 & cop4=0x8 { + Fst = fs2ui.z(Fda); +} + +define pcodeop fd2si; +:fd2si Fst, Fda is $(I32) & $(COP) & fop4=0xf & Fst & Fda & f2op=0x18 & cop4=0x8 { + Fst = fd2si(Fda); +} + +define pcodeop fd2si.z; +:fd2si.z Fst, Fda is $(I32) & $(COP) & fop4=0xf & Fst & Fda & f2op=0x1c & cop4=0x8 { + Fst = fs2si.z(Fda); +} + +# FPU_FS2 +define pcodeop fcmpd; +:fcmp^fcond^"d"^fcmpe Fst, Fda, Fdb is $(I32) & $(COP) & Fst & Fda & Fdb & cop4=0xc & fcond & fcmpe { + Fst = fcmpd(Fda, Fdb, fcond, fcmpe); +} + +# FPU_MFCP +define pcodeop fmfsr; +:fmfsr Rt, Fsa is $(I32) & $(COP) & fop4=0x0 & Rt & Fsa & f2op=0x0 & cop4=0x1 { + Rt = fmfsr(Fsa); +} + +define pcodeop fmfdr; +:fmfdr Rt, Fda is $(I32) & $(COP) & fop4=0x1 & Rt & Fda & f2op=0x0 & cop4=0x1 { + Rt = fmfdr(Fda); +} + +# FPU_MTCP +define pcodeop ftmsr; +:ftmsr Rt, Fsa is $(I32) & $(COP) & fop4=0x0 & Rt & Fsa & f2op=0x0 & cop4=0x9 { + Fsa = ftmsr(Rt); +} + +define pcodeop ftmdr; +:ftmdr Rt, Fda is $(I32) & $(COP) & fop4=0x1 & Rt & Fda & f2op=0x0 & cop4=0x9 { + Fda = ftmdr(Rt); +} + +# FPU_FLS + +:fls Fst, AddrRaRbsv is $(I32) & $(COP) & Fst & AddrRaRbsv & fbi=0 & cop4=0x2 { + Fst = *AddrRaRbsv; +} + +:fls.bi Fst [Ra], OffsetRbsv is $(I32) & $(COP) & Fst & Ra & OffsetRbsv & fbi=1 & cop4=2 { + Fst = *Ra; + Ra = Ra + OffsetRbsv; +} + +# FPU_FLD + +:fld Fdt, AddrRaRbsv is $(I32) & $(COP) & Fdt & AddrRaRbsv & fbi=0 & cop4=0x3 { + Fdt = *AddrRaRbsv; +} + +:fld.bi Fdt [Ra], OffsetRbsv is $(I32) & $(COP) & Fdt & Ra & OffsetRbsv & fbi=1 & cop4=3 { + Fdt = *Ra; + Ra = Ra + OffsetRbsv; +} + +# FPU_FSS + +:fss Fst, AddrRaRbsv is $(I32) & $(COP) & Fst & AddrRaRbsv & fbi=0 & cop4=0xa { + *AddrRaRbsv = Fst; +} + +:fss.bi Fst [Ra], OffsetRbsv is $(I32) & $(COP) & Fst & Ra & OffsetRbsv & fbi=1 & cop4=0xa { + *Ra = Fst; + Ra = Ra + OffsetRbsv; +} + +# FPU_FSD +:fsd Fdt, AddrRaRbsv is $(I32) & $(COP) & Fdt & AddrRaRbsv & fbi=0 & cop4=0xb { + *AddrRaRbsv = Fdt; +} + +:fsd.bi Fdt [Ra], OffsetRbsv is $(I32) & $(COP) & Fdt & Ra & OffsetRbsv & fbi=1 & cop4=0xb { + *Ra = Fdt; + Ra = Ra + OffsetRbsv; +} + + +# LWC0 +AddrRaImm12s: [Ra + offs] is Ra & Imm12s [ offs = Imm12s << 2; ] { addr:4 = Ra + offs; export addr; } +OffImm12s: (offs) is Imm12s [ offs = Imm12s << 2; ] { export *[const]:4 offs; } + +:flsi Fst, AddrRaImm12s is $(I32) & $(LWC) & Fst & cpn=0 & fsbi=0 & AddrRaImm12s { + Fst = *AddrRaImm12s; +} + +:flsi.bi Fst [Ra], OffImm12s is $(I32) & $(LWC) & Fst & Ra & cpn=0 & fsbi=1 & OffImm12s { + Fst = *Ra; + Ra = Ra + OffImm12s; +} + +# LDC0 + +:fldi Fdt, AddrRaImm12s is $(I32) & $(LDC) & Fdt & cpn=0 & fsbi=0 & AddrRaImm12s { + Fdt = *AddrRaImm12s; +} + +:fldi.bi Fdt [Ra], OffImm12s is $(I32) & $(LDC) & Fdt & Ra & cpn=0 & fsbi=1 & OffImm12s { + Fdt = *Ra; + Ra = Ra + OffImm12s; +} + +# SWC0 + +:fssi Fst, AddrRaImm12s is $(I32) & $(SWC) & Fst & cpn=0 & fsbi=0 & AddrRaImm12s { + *AddrRaImm12s = Fst; +} + +:fssi.bi Fst [Ra], OffImm12s is $(I32) & $(SWC) & Fst & Ra & cpn=0 & fsbi=1 & OffImm12s { + *Ra = Fst; + Ra = Ra + OffImm12s; +} + +# SDC0 +:fsdi Fdt, AddrRaImm12s is $(I32) & $(SDC) & Fdt & cpn=0 & fsbi=0 & AddrRaImm12s { + *AddrRaImm12s = Fdt; +} + +:fsdi.bi Fdt [Ra], OffImm12s is $(I32) & $(SDC) & Fdt & Ra & cpn=0 & fsbi=1 & OffImm12s { + *Ra = Fdt; + Ra = Ra + OffImm12s; +} + diff --git a/Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml b/Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml index 5cbde241f9..802d6307b7 100644 --- a/Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml +++ b/Ghidra/Processors/NDS32/data/patterns/nds32_patterns.xml @@ -1,13 +1,12 @@ - + - 0xd5 ........ - 0x48 ........ ........ ........ - 0x92 0x00 + 0xfc 1....... + 0xdd 0x9e - 0011101. ....1111 1......0 .0111100 + 0xfc 0....... - + \ No newline at end of file From 9bdd19cc087f889a16421b7cda082e2a08653449 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 2 Dec 2025 15:30:45 +0000 Subject: [PATCH 4/7] GP-6007: Added CSR space and CSRs --- .../Processors/NDS32/data/languages/lsmw.sinc | 14 -- .../NDS32/data/languages/nds32.pspec | 151 +++++++++++++++- .../NDS32/data/languages/nds32.sinc | 164 ++++++++++++++++-- 3 files changed, 298 insertions(+), 31 deletions(-) diff --git a/Ghidra/Processors/NDS32/data/languages/lsmw.sinc b/Ghidra/Processors/NDS32/data/languages/lsmw.sinc index 3ac5595315..bff5e75888 100644 --- a/Ghidra/Processors/NDS32/data/languages/lsmw.sinc +++ b/Ghidra/Processors/NDS32/data/languages/lsmw.sinc @@ -123,17 +123,3 @@ Smwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp) Smwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp) ... & SmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; build SmwReg; } Smwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp { build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; } Smwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; } - - -#Smw.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } -#Smw.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } -#Smw.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } -#Smw.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } -#Lmwa.regs: is LsmwBa=0 & LsmwId & Lmwbi.sp & Lmwbi.lp & Lmwbi.gp & Lmwbi.fp & Lmwbi.p1 & Lmwbi.p0 & Lmwbi.t9 & Lmwbi.t8 & Lmwbi.t7 & Lmwbi.t6 & Lmwbi.t5 & Lmwbi.t4 & Lmwbi.t3 & Lmwbi.t2 & Lmwbi.t1 & Lmwbi.t0 & Lmwbi.ta & Lmwbi.s8 & Lmwbi.s7 & Lmwbi.s6 & Lmwbi.s5 & Lmwbi.s4 & Lmwbi.s3 & Lmwbi.s2 & Lmwbi.s1 & Lmwbi.s0 & Lmwbi.a5 & Lmwbi.a4 & Lmwbi.a3 & Lmwbi.a2 & Lmwbi.a1 & Lmwbi.a0 { } -#Lmwa.regs: is LsmwBa=0 & LsmwId=1 & Lmwbd.a0 & Lmwbd.a1 & Lmwbd.a2 & Lmwbd.a3 & Lmwbd.a4 & Lmwbd.a5 & Lmwbd.s0 & Lmwbd.s1 & Lmwbd.s2 & Lmwbd.s3 & Lmwbd.s4 & Lmwbd.s5 & Lmwbd.s6 & Lmwbd.s7 & Lmwbd.s8 & Lmwbd.ta & Lmwbd.t0 & Lmwbd.t1 & Lmwbd.t2 & Lmwbd.t3 & Lmwbd.t4 & Lmwbd.t5 & Lmwbd.t6 & Lmwbd.t7 & Lmwbd.t8 & Lmwbd.t9 & Lmwbd.p0 & Lmwbd.p1 & Lmwbd.fp & Lmwbd.gp & Lmwbd.lp & Lmwbd.sp { } -#Lmwa.regs: is LsmwBa=1 & LsmwId=0 & Lmwai.sp & Lmwai.lp & Lmwai.gp & Lmwai.fp & Lmwai.p1 & Lmwai.p0 & Lmwai.t9 & Lmwai.t8 & Lmwai.t7 & Lmwai.t6 & Lmwai.t5 & Lmwai.t4 & Lmwai.t3 & Lmwai.t2 & Lmwai.t1 & Lmwai.t0 & Lmwai.ta & Lmwai.s8 & Lmwai.s7 & Lmwai.s6 & Lmwai.s5 & Lmwai.s4 & Lmwai.s3 & Lmwai.s2 & Lmwai.s1 & Lmwai.s0 & Lmwai.a5 & Lmwai.a4 & Lmwai.a3 & Lmwai.a2 & Lmwai.a1 & Lmwai.a0 { } -#Lmwa.regs: is LsmwBa=1 & LsmwId=1 & Lmwad.a0 & Lmwad.a1 & Lmwad.a2 & Lmwad.a3 & Lmwad.a4 & Lmwad.a5 & Lmwad.s0 & Lmwad.s1 & Lmwad.s2 & Lmwad.s3 & Lmwad.s4 & Lmwad.s5 & Lmwad.s6 & Lmwad.s7 & Lmwad.s8 & Lmwad.ta & Lmwad.t0 & Lmwad.t1 & Lmwad.t2 & Lmwad.t3 & Lmwad.t4 & Lmwad.t5 & Lmwad.t6 & Lmwad.t7 & Lmwad.t8 & Lmwad.t9 & Lmwad.p0 & Lmwad.p1 & Lmwad.fp & Lmwad.gp & Lmwad.lp & Lmwad.sp { } -#Smwa.regs: is LsmwBa=0 & LsmwId=0 & Smwbi.sp & Smwbi.lp & Smwbi.gp & Smwbi.fp & Smwbi.p1 & Smwbi.p0 & Smwbi.t9 & Smwbi.t8 & Smwbi.t7 & Smwbi.t6 & Smwbi.t5 & Smwbi.t4 & Smwbi.t3 & Smwbi.t2 & Smwbi.t1 & Smwbi.t0 & Smwbi.ta & Smwbi.s8 & Smwbi.s7 & Smwbi.s6 & Smwbi.s5 & Smwbi.s4 & Smwbi.s3 & Smwbi.s2 & Smwbi.s1 & Smwbi.s0 & Smwbi.a5 & Smwbi.a4 & Smwbi.a3 & Smwbi.a2 & Smwbi.a1 & Smwbi.a0 { } -#Smwa.regs: is LsmwBa=0 & LsmwId=1 & Smwbd.a0 & Smwbd.a1 & Smwbd.a2 & Smwbd.a3 & Smwbd.a4 & Smwbd.a5 & Smwbd.s0 & Smwbd.s1 & Smwbd.s2 & Smwbd.s3 & Smwbd.s4 & Smwbd.s5 & Smwbd.s6 & Smwbd.s7 & Smwbd.s8 & Smwbd.ta & Smwbd.t0 & Smwbd.t1 & Smwbd.t2 & Smwbd.t3 & Smwbd.t4 & Smwbd.t5 & Smwbd.t6 & Smwbd.t7 & Smwbd.t8 & Smwbd.t9 & Smwbd.p0 & Smwbd.p1 & Smwbd.fp & Smwbd.gp & Smwbd.lp & Smwbd.sp { } -#Smwa.regs: is LsmwBa=1 & LsmwId=0 & Smwai.sp & Smwai.lp & Smwai.gp & Smwai.fp & Smwai.p1 & Smwai.p0 & Smwai.t9 & Smwai.t8 & Smwai.t7 & Smwai.t6 & Smwai.t5 & Smwai.t4 & Smwai.t3 & Smwai.t2 & Smwai.t1 & Smwai.t0 & Smwai.ta & Smwai.s8 & Smwai.s7 & Smwai.s6 & Smwai.s5 & Smwai.s4 & Smwai.s3 & Smwai.s2 & Smwai.s1 & Smwai.s0 & Smwai.a5 & Smwai.a4 & Smwai.a3 & Smwai.a2 & Smwai.a1 & Smwai.a0 { } -#Smwa.regs: is LsmwBa=1 & LsmwId=1 & Smwad.a0 & Smwad.a1 & Smwad.a2 & Smwad.a3 & Smwad.a4 & Smwad.a5 & Smwad.s0 & Smwad.s1 & Smwad.s2 & Smwad.s3 & Smwad.s4 & Smwad.s5 & Smwad.s6 & Smwad.s7 & Smwad.s8 & Smwad.ta & Smwad.t0 & Smwad.t1 & Smwad.t2 & Smwad.t3 & Smwad.t4 & Smwad.t5 & Smwad.t6 & Smwad.t7 & Smwad.t8 & Smwad.t9 & Smwad.p0 & Smwad.p1 & Smwad.fp & Smwad.gp & Smwad.lp & Smwad.sp { } diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.pspec b/Ghidra/Processors/NDS32/data/languages/nds32.pspec index dbce6f2f99..d70bdf4abd 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.pspec +++ b/Ghidra/Processors/NDS32/data/languages/nds32.pspec @@ -2,5 +2,154 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.sinc b/Ghidra/Processors/NDS32/data/languages/nds32.sinc index 996a57d199..324963a8e8 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.sinc +++ b/Ghidra/Processors/NDS32/data/languages/nds32.sinc @@ -5,11 +5,14 @@ define alignment=2; define space ram type=ram_space size=4 wordsize=1 default; define space register type=register_space size=4; +define space csreg type=ram_space size=2 wordsize=4; +@define CSR_REG_START "0x0000" + define register offset=0 size=4 [a0 a1 a2 a3 a4 a5 s0 s1 s2 s3 s4 s5 s6 s7 s8 ta t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 p0 p1 fp gp lp sp]; define register offset=0x90 size=4 -[pc ipc mult_addr mult_inc]; +[pc mult_addr mult_inc]; define register offset=0x100 size=8 [d0 d1]; @@ -34,6 +37,111 @@ define register offset=0x1000 size=8 fd24 fd25 fd26 fd27 fd28 fd29 fd30 fd31 ]; +#define SRIDX(major, minor, ext) \ +# (((major) << 7) | ((minor) << 3) | (ext)) + +define csreg offset=$(CSR_REG_START) size=4 +[ + cpu_ver core_id _ _ _ _ _ _ # SRIDX(0,0,n) + icm_cfg _ _ _ _ _ _ _ # SRIDX(0,1,n) + dcm_cfg _ _ _ _ _ _ _ + mmu_cfg _ _ _ _ _ _ _ + msc_cfg msc_cfg2 _ _ _ _ _ _ + fucop_exist _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ # SRIDX(0,7,n) + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ # SRIDX(0,15,n) + psw ipsw p_ipsw _ _ _ _ _ # SRIDX(1,0,n) + _ ivb int_ctrl int_gpr_push_dis _ _ _ _ + _ eva p_eva _ _ _ _ _ + _ itype p_itype _ _ _ _ _ + _ merr _ _ _ _ _ _ + _ ipc p_ipc oipc _ _ _ _ + _ _ p_p0 _ _ _ _ _ + _ _ p_p1 _ _ _ _ _ # SRIDX(1,7,n) + int_mask int_mask2 int_mask3 _ _ _ _ _ + int_pend int_pend2 int_pend3 _ int_trigger int_trigger2 _ _ + sp_usr sp_priv sp_usr1 sp_priv1 sp_usr2 sp_priv2 sp_usr3 sp_priv3 + int_pri int_pri2 int_pri3 int_pri4 _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ # SRIDX(1,15,n) + mmu_ctl bg_region _ _ _ _ _ _ # SRIDX(2,0,n) + l1_pptb _ _ _ _ _ _ _ + tlb_vpn _ _ _ _ _ _ _ + tlb_data _ _ _ _ _ _ _ + tlb_misc _ _ _ _ _ _ _ + vlpt_idx _ _ _ _ _ _ _ + ilmb _ _ _ _ _ _ _ + dlmb _ _ _ _ _ _ _ # SRIDX(2,7,n) + cache_ctl _ _ _ _ _ _ _ + hsmp_saddr hsmp_eaddr _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + sdz_ctl misc_ctl ecc_misc _ _ _ _ _ # SRIDX(2,15,n) + bpc0 bpc1 bpc2 bpc3 bpc4 bpc5 bpc6 bpc7 # SRIDX(3,0,n) + bpa0 bpa1 bpa2 bpa3 bpa4 bpa5 bpa6 bpa7 + bpam0 bpam1 bpam2 bpam3 bpam4 bpam5 bpam6 bpam7 + bpv0 bpv1 bpv2 bpv3 bpv4 bpv5 bpv6 bpv7 + bpcid0 bpcid1 bpcid2 bpcid3 bpcid4 bpcid5 bpcid6 bpcid7 + edm_cfg _ _ _ _ _ _ _ + edmsw _ _ _ _ _ _ _ + edm_ctl _ _ _ _ _ _ _ # SRIDX(3,7,n) + edm_dtr _ _ _ _ _ _ _ + bpmtc _ _ _ _ _ _ _ + dimbr _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + tecr0 tecr1 _ _ _ _ _ _ + _ _ _ _ _ _ _ _ # SRIDX(3,15,n) + pfmc0 pfmc1 pfmc2 _ _ _ _ _ # SRIDX(4,0,n) + pfm_ctl _ _ _ _ _ _ _ + pft_ctl _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + prusr_acc_ctl _ _ _ _ _ _ _ + fucpr _ _ _ _ _ _ _ + hsp_ctl sp_bound sp_bound_priv sp_base sp_base_priv _ _ _ + _ _ _ _ _ _ _ _ # SRIDX(4,7,n) + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ # SRIDX(4,15,n) + dma_cfg _ _ _ _ _ _ _ # SRIDX(5,0,n) + dma_gcsw _ _ _ _ _ _ _ + dma_chnsel _ _ _ _ _ _ _ + dma_act _ _ _ _ _ _ _ + dma_setup _ _ _ _ _ _ _ + dma_isaddr _ _ _ _ _ _ _ + dma_esaddr _ _ _ _ _ _ _ + dma_tcnt dma_rcnt _ _ _ _ _ _ # SRIDX(5,7,n) + dma_status dma_hstatus _ _ _ _ _ _ + dma_2dset dma_2dsctl _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ # SRIDX(5,15,n) + secur0 _ _ _ _ _ _ _ # SRIDX(6,0,n) + secur1 secur2 secur3 _ _ _ _ _ +]; + define register offset=0x300 size=8 contextreg; define context contextreg counter = (22,26) @@ -275,18 +383,38 @@ attach variables [ Fdt Fda Fdb ] :msub32 Dtlow, Ra, Rb is $(I32) & $(ALU_2) & Dtl=0 & Dtlow & Dtr=0 & Ra & Rb & $(ALU2Z) & Sub6=0b110101 { Dtlow = Dtlow - (Ra * Rb); } -# TODO : special instruction, but used get the division results -# There are more special registers -UsrName: d0.lo is Group=0 & Usr=0 & d0.lo { export d0.lo; } -UsrName: d0.hi is Group=0 & Usr=1 & d0.hi { export d0.hi; } -UsrName: d1.lo is Group=0 & Usr=2 & d1.lo { export d1.lo; } -UsrName: d1.hi is Group=0 & Usr=3 & d1.hi { export d1.hi; } -UsrName: le is Group=0 & Usr=0b11010 & le { export le; } -UsrName: itb is Group=0 & Usr=0b11100 & itb { export itb; } -UsrName: lb is Group=0 & Usr=0b11001 & lb { export lb; } -UsrName: lc is Group=0 & Usr=0b11011 & lc { export lc; } -UsrName: ifc_lp is Group=0 & Usr=0b11101 & ifc_lp { export ifc_lp; } -#UsrName: pc is Group=0 & Usr=0b11111 & pc { export pc; } +# Group 0 +UsrName: d0.lo is Group=0 & Usr=0 & d0.lo { export d0.lo; } +UsrName: d0.hi is Group=0 & Usr=1 & d0.hi { export d0.hi; } +UsrName: d1.lo is Group=0 & Usr=2 & d1.lo { export d1.lo; } +UsrName: d1.hi is Group=0 & Usr=3 & d1.hi { export d1.hi; } +UsrName: lb is Group=0 & Usr=25 & lb { export lb; } +UsrName: le is Group=0 & Usr=26 & le { export le; } +UsrName: lc is Group=0 & Usr=27 & lc { export lc; } +UsrName: itb is Group=0 & Usr=28 & itb { export itb; } +UsrName: ifc_lp is Group=0 & Usr=29 & ifc_lp { export ifc_lp; } +#UsrName: pc is Group=0 & Usr=31 & pc { export pc; } # handled separately + +# Group 1 +UsrName: dma_cfg is Group=1 & Usr=0 & dma_cfg { export dma_cfg; } +UsrName: dma_gcsw is Group=1 & Usr=1 & dma_gcsw { export dma_gcsw; } +UsrName: dma_chnsel is Group=1 & Usr=2 & dma_chnsel { export dma_chnsel; } +UsrName: dma_act is Group=1 & Usr=3 & dma_act { export dma_act; } +UsrName: dma_setup is Group=1 & Usr=4 & dma_setup { export dma_setup; } +UsrName: dma_isaddr is Group=1 & Usr=5 & dma_isaddr { export dma_isaddr; } +UsrName: dma_esaddr is Group=1 & Usr=6 & dma_esaddr { export dma_esaddr; } +UsrName: dma_tcnt is Group=1 & Usr=7 & dma_tcnt { export dma_tcnt; } +UsrName: dma_status is Group=1 & Usr=8 & dma_status { export dma_status; } +UsrName: dma_2dset is Group=1 & Usr=9 & dma_2dset { export dma_2dset; } +UsrName: dma_rcnt is Group=1 & Usr=23 & dma_rcnt { export dma_rcnt; } +UsrName: dma_hstatus is Group=1 & Usr=24 & dma_hstatus { export dma_hstatus; } +UsrName: dma_2dsctl is Group=1 & Usr=25 & dma_2dsctl { export dma_2dsctl; } + +# Group 2 +UsrName: pfmc0 is Group=2 & Usr=0 & pfmc0 { export pfmc0; } +UsrName: pfmc1 is Group=2 & Usr=1 & pfmc1 { export pfmc1; } +UsrName: pfmc2 is Group=2 & Usr=2 & pfmc2 { export pfmc2; } +UsrName: pfm_ctl is Group=2 & Usr=4 & pfm_ctl { export pfm_ctl; } :mfusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100000 { UsrName = Rt; } @@ -453,8 +581,10 @@ Rel16: addr is Imm16s [ addr = inst_start + (Imm16s << 1); ] { export *:4 addr; define pcodeop mfsr; define pcodeop mtsr; -:mfsr Rt, SrIdx is $(I32) & $(MISC) & Rt & SrIdx & Rd=0 & Sub5=0b00010 { Rt = mfsr(SrIdx:4); } -:mtsr Rt, SrIdx is $(I32) & $(MISC) & Rt & SrIdx & Rd=0 & Sub5=0b00011 { mtsr(SrIdx:4, Rt:4); } +csr: csr_reg is SrIdx [ csr_reg = $(CSR_REG_START) + SrIdx; ] { export *[csreg]:4 csr_reg; } + +:mfsr Rt, csr is $(I32) & $(MISC) & Rt & csr & Rd=0 & Sub5=0b00010 { Rt = csr; } +:mtsr Rt, csr is $(I32) & $(MISC) & Rt & csr & Rd=0 & Sub5=0b00011 { csr = Rt; } ### Jump Register with System Register Update ### @@ -1228,7 +1358,9 @@ define pcodeop ex9; ex9(imm5u:4); } -# Floating Point + +########################## +# Floating Point Extension # FPU_FS1 define pcodeop fadds; From df6e4049d4f91f8cb9c9ff3888bb5f2a15a411d8 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 2 Dec 2025 20:21:14 +0000 Subject: [PATCH 5/7] GP-6007: Added additional floating point config instructions --- .../NDS32/data/languages/nds32.sinc | 167 +++++------------- 1 file changed, 41 insertions(+), 126 deletions(-) diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.sinc b/Ghidra/Processors/NDS32/data/languages/nds32.sinc index 324963a8e8..02e2dd9929 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.sinc +++ b/Ghidra/Processors/NDS32/data/languages/nds32.sinc @@ -6,6 +6,7 @@ define space ram type=ram_space size=4 wordsize=1 default; define space register type=register_space size=4; define space csreg type=ram_space size=2 wordsize=4; + @define CSR_REG_START "0x0000" define register offset=0 size=4 @@ -21,7 +22,9 @@ define register offset=0x100 size=4 [d0.hi d0.lo d1.hi d1.lo]; define register offset=0x200 size=4 -[ itb lb lc le ifc_lp]; +[ itb lb lc le ifc_lp + fpcsr fpcfg +]; define register offset=0x1000 size=4 [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 @@ -37,109 +40,9 @@ define register offset=0x1000 size=8 fd24 fd25 fd26 fd27 fd28 fd29 fd30 fd31 ]; -#define SRIDX(major, minor, ext) \ -# (((major) << 7) | ((minor) << 3) | (ext)) - -define csreg offset=$(CSR_REG_START) size=4 +define csreg offset=0x0a9 size=4 [ - cpu_ver core_id _ _ _ _ _ _ # SRIDX(0,0,n) - icm_cfg _ _ _ _ _ _ _ # SRIDX(0,1,n) - dcm_cfg _ _ _ _ _ _ _ - mmu_cfg _ _ _ _ _ _ _ - msc_cfg msc_cfg2 _ _ _ _ _ _ - fucop_exist _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ # SRIDX(0,7,n) - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ # SRIDX(0,15,n) - psw ipsw p_ipsw _ _ _ _ _ # SRIDX(1,0,n) - _ ivb int_ctrl int_gpr_push_dis _ _ _ _ - _ eva p_eva _ _ _ _ _ - _ itype p_itype _ _ _ _ _ - _ merr _ _ _ _ _ _ - _ ipc p_ipc oipc _ _ _ _ - _ _ p_p0 _ _ _ _ _ - _ _ p_p1 _ _ _ _ _ # SRIDX(1,7,n) - int_mask int_mask2 int_mask3 _ _ _ _ _ - int_pend int_pend2 int_pend3 _ int_trigger int_trigger2 _ _ - sp_usr sp_priv sp_usr1 sp_priv1 sp_usr2 sp_priv2 sp_usr3 sp_priv3 - int_pri int_pri2 int_pri3 int_pri4 _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ # SRIDX(1,15,n) - mmu_ctl bg_region _ _ _ _ _ _ # SRIDX(2,0,n) - l1_pptb _ _ _ _ _ _ _ - tlb_vpn _ _ _ _ _ _ _ - tlb_data _ _ _ _ _ _ _ - tlb_misc _ _ _ _ _ _ _ - vlpt_idx _ _ _ _ _ _ _ - ilmb _ _ _ _ _ _ _ - dlmb _ _ _ _ _ _ _ # SRIDX(2,7,n) - cache_ctl _ _ _ _ _ _ _ - hsmp_saddr hsmp_eaddr _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - sdz_ctl misc_ctl ecc_misc _ _ _ _ _ # SRIDX(2,15,n) - bpc0 bpc1 bpc2 bpc3 bpc4 bpc5 bpc6 bpc7 # SRIDX(3,0,n) - bpa0 bpa1 bpa2 bpa3 bpa4 bpa5 bpa6 bpa7 - bpam0 bpam1 bpam2 bpam3 bpam4 bpam5 bpam6 bpam7 - bpv0 bpv1 bpv2 bpv3 bpv4 bpv5 bpv6 bpv7 - bpcid0 bpcid1 bpcid2 bpcid3 bpcid4 bpcid5 bpcid6 bpcid7 - edm_cfg _ _ _ _ _ _ _ - edmsw _ _ _ _ _ _ _ - edm_ctl _ _ _ _ _ _ _ # SRIDX(3,7,n) - edm_dtr _ _ _ _ _ _ _ - bpmtc _ _ _ _ _ _ _ - dimbr _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - tecr0 tecr1 _ _ _ _ _ _ - _ _ _ _ _ _ _ _ # SRIDX(3,15,n) - pfmc0 pfmc1 pfmc2 _ _ _ _ _ # SRIDX(4,0,n) - pfm_ctl _ _ _ _ _ _ _ - pft_ctl _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - prusr_acc_ctl _ _ _ _ _ _ _ - fucpr _ _ _ _ _ _ _ - hsp_ctl sp_bound sp_bound_priv sp_base sp_base_priv _ _ _ - _ _ _ _ _ _ _ _ # SRIDX(4,7,n) - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ # SRIDX(4,15,n) - dma_cfg _ _ _ _ _ _ _ # SRIDX(5,0,n) - dma_gcsw _ _ _ _ _ _ _ - dma_chnsel _ _ _ _ _ _ _ - dma_act _ _ _ _ _ _ _ - dma_setup _ _ _ _ _ _ _ - dma_isaddr _ _ _ _ _ _ _ - dma_esaddr _ _ _ _ _ _ _ - dma_tcnt dma_rcnt _ _ _ _ _ _ # SRIDX(5,7,n) - dma_status dma_hstatus _ _ _ _ _ _ - dma_2dset dma_2dsctl _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ # SRIDX(5,15,n) - secur0 _ _ _ _ _ _ _ # SRIDX(6,0,n) - secur1 secur2 secur3 _ _ _ _ _ + ipc ]; define register offset=0x300 size=8 contextreg; @@ -396,25 +299,25 @@ UsrName: ifc_lp is Group=0 & Usr=29 & ifc_lp { export ifc_lp; } #UsrName: pc is Group=0 & Usr=31 & pc { export pc; } # handled separately # Group 1 -UsrName: dma_cfg is Group=1 & Usr=0 & dma_cfg { export dma_cfg; } -UsrName: dma_gcsw is Group=1 & Usr=1 & dma_gcsw { export dma_gcsw; } -UsrName: dma_chnsel is Group=1 & Usr=2 & dma_chnsel { export dma_chnsel; } -UsrName: dma_act is Group=1 & Usr=3 & dma_act { export dma_act; } -UsrName: dma_setup is Group=1 & Usr=4 & dma_setup { export dma_setup; } -UsrName: dma_isaddr is Group=1 & Usr=5 & dma_isaddr { export dma_isaddr; } -UsrName: dma_esaddr is Group=1 & Usr=6 & dma_esaddr { export dma_esaddr; } -UsrName: dma_tcnt is Group=1 & Usr=7 & dma_tcnt { export dma_tcnt; } -UsrName: dma_status is Group=1 & Usr=8 & dma_status { export dma_status; } -UsrName: dma_2dset is Group=1 & Usr=9 & dma_2dset { export dma_2dset; } -UsrName: dma_rcnt is Group=1 & Usr=23 & dma_rcnt { export dma_rcnt; } -UsrName: dma_hstatus is Group=1 & Usr=24 & dma_hstatus { export dma_hstatus; } -UsrName: dma_2dsctl is Group=1 & Usr=25 & dma_2dsctl { export dma_2dsctl; } +UsrName: "dma_cfg" is Group=1 & Usr=0 { tmp:2 = 0x280; export *[csreg]:4 tmp; } +UsrName: "dma_gcsw" is Group=1 & Usr=1 { tmp:2 = 0x288; export *[csreg]:4 tmp; } +UsrName: "dma_chnsel" is Group=1 & Usr=2 { tmp:2 = 0x290; export *[csreg]:4 tmp; } +UsrName: "dma_act" is Group=1 & Usr=3 { tmp:2 = 0x298; export *[csreg]:4 tmp; } +UsrName: "dma_setup" is Group=1 & Usr=4 { tmp:2 = 0x2a0; export *[csreg]:4 tmp; } +UsrName: "dma_isaddr" is Group=1 & Usr=5 { tmp:2 = 0x2a8; export *[csreg]:4 tmp; } +UsrName: "dma_esaddr" is Group=1 & Usr=6 { tmp:2 = 0x2b0; export *[csreg]:4 tmp; } +UsrName: "dma_tcnt" is Group=1 & Usr=7 { tmp:2 = 0x2b8; export *[csreg]:4 tmp; } +UsrName: "dma_status" is Group=1 & Usr=8 { tmp:2 = 0x2c0; export *[csreg]:4 tmp; } +UsrName: "dma_2dset" is Group=1 & Usr=9 { tmp:2 = 0x2c8; export *[csreg]:4 tmp; } +UsrName: "dma_rcnt" is Group=1 & Usr=23 { tmp:2 = 0x2b9; export *[csreg]:4 tmp; } +UsrName: "dma_hstatus" is Group=1 & Usr=24 { tmp:2 = 0x2c1; export *[csreg]:4 tmp; } +UsrName: "dma_2dsctl" is Group=1 & Usr=25 { tmp:2 = 0x2c9; export *[csreg]:4 tmp; } # Group 2 -UsrName: pfmc0 is Group=2 & Usr=0 & pfmc0 { export pfmc0; } -UsrName: pfmc1 is Group=2 & Usr=1 & pfmc1 { export pfmc1; } -UsrName: pfmc2 is Group=2 & Usr=2 & pfmc2 { export pfmc2; } -UsrName: pfm_ctl is Group=2 & Usr=4 & pfm_ctl { export pfm_ctl; } +UsrName: "pfmc0" is Group=2 & Usr=0 { tmp:2 = 0x200; export *[csreg]:4 tmp; } +UsrName: "pfmc1" is Group=2 & Usr=1 { tmp:2 = 0x201; export *[csreg]:4 tmp; } +UsrName: "pfmc2" is Group=2 & Usr=2 { tmp:2 = 0x202; export *[csreg]:4 tmp; } +UsrName: "pfm_ctl" is Group=2 & Usr=4 { tmp:2 = 0x208; export *[csreg]:4 tmp; } :mfusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100000 { UsrName = Rt; } @@ -1609,14 +1512,14 @@ define pcodeop fmfdr; } # FPU_MTCP -define pcodeop ftmsr; -:ftmsr Rt, Fsa is $(I32) & $(COP) & fop4=0x0 & Rt & Fsa & f2op=0x0 & cop4=0x9 { - Fsa = ftmsr(Rt); +define pcodeop fmtsr; +:fmtsr Rt, Fsa is $(I32) & $(COP) & fop4=0x0 & Rt & Fsa & f2op=0x0 & cop4=0x9 { + Fsa = fmtsr(Rt); } -define pcodeop ftmdr; -:ftmdr Rt, Fda is $(I32) & $(COP) & fop4=0x1 & Rt & Fda & f2op=0x0 & cop4=0x9 { - Fda = ftmdr(Rt); +define pcodeop fmtdr; +:fmtdr Rt, Fda is $(I32) & $(COP) & fop4=0x1 & Rt & Fda & f2op=0x0 & cop4=0x9 { + Fda = fmtdr(Rt); } # FPU_FLS @@ -1708,3 +1611,15 @@ OffImm12s: (offs) is Imm12s [ offs = Imm12s << 2; ] { export *[const]:4 offs; } Ra = Ra + OffImm12s; } +:fmfcfg Rt is $(I32) & $(COP) & fop4=0xc & Rt & f2op=0x0 & cop4=0x1 { + Rt = fpcfg; +} + +:fmfcsr Rt is $(I32) & $(COP) & fop4=0xc & Rt & f2op=0x1 & cop4=0x1 { + Rt = fpcsr; +} + +:fmtcsr Rt is $(I32) & $(COP) & fop4=0xc & Rt & Fsa & f2op=0x1 & cop4=0x9 { + fpcsr = Rt; +} + From 2efa886f5ca0996d3ea9f1865d952aa2708389b6 Mon Sep 17 00:00:00 2001 From: emteere <47253321+emteere@users.noreply.github.com> Date: Wed, 3 Dec 2025 21:36:18 +0000 Subject: [PATCH 6/7] GP-6007 minor fixes for mfusr, mtusr and csreg space as global in cspec --- Ghidra/Processors/NDS32/data/languages/nds32.cspec | 1 + Ghidra/Processors/NDS32/data/languages/nds32.sinc | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.cspec b/Ghidra/Processors/NDS32/data/languages/nds32.cspec index 9d0e2bb3af..ed3a93b095 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.cspec +++ b/Ghidra/Processors/NDS32/data/languages/nds32.cspec @@ -24,6 +24,7 @@ + diff --git a/Ghidra/Processors/NDS32/data/languages/nds32.sinc b/Ghidra/Processors/NDS32/data/languages/nds32.sinc index 02e2dd9929..141183a38d 100644 --- a/Ghidra/Processors/NDS32/data/languages/nds32.sinc +++ b/Ghidra/Processors/NDS32/data/languages/nds32.sinc @@ -320,10 +320,10 @@ UsrName: "pfmc2" is Group=2 & Usr=2 { tmp:2 = 0x202; export *[csreg]:4 tmp UsrName: "pfm_ctl" is Group=2 & Usr=4 { tmp:2 = 0x208; export *[csreg]:4 tmp; } -:mfusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100000 { UsrName = Rt; } -:mfusr Rt, pc is $(I32) & $(ALU_2) & Rt & Group=0 & Usr=0b11111 & $(ALU2Z) & Sub6=0b100000 & pc { pc = Rt; goto[pc]; } # Not sure this works correctly -:mtusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100001 { Rt = UsrName; } -:mtusr Rt, pc is $(I32) & $(ALU_2) & Rt & Group=0 & Usr=0b11111 & $(ALU2Z) & Sub6=0b100001 & pc { Rt = inst_next; } +:mfusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100000 { Rt = UsrName; } +:mfusr Rt, pc is $(I32) & $(ALU_2) & Rt & Group=0 & Usr=0b11111 & $(ALU2Z) & Sub6=0b100000 & pc { Rt = inst_next; } +:mtusr Rt, UsrName is $(I32) & $(ALU_2) & Rt & UsrName & $(ALU2Z) & Sub6=0b100001 { UsrName = Rt; } +:mtusr Rt, pc is $(I32) & $(ALU_2) & Rt & Group=0 & Usr=0b11111 & $(ALU2Z) & Sub6=0b100001 & pc { pc = Rt; goto[pc]; } # Not sure this works correctly ### Divide Instructions ### From ddf4ad1182577f759b1c0e7c40d8825abd65b357 Mon Sep 17 00:00:00 2001 From: emteere <47253321+emteere@users.noreply.github.com> Date: Wed, 3 Dec 2025 22:06:38 +0000 Subject: [PATCH 7/7] GP-6007 minor fixes for Andestar v5 --- Ghidra/Processors/RISCV/data/languages/andestar_v5.instr.sinc | 3 ++- Ghidra/Processors/RISCV/data/languages/riscv.reg.sinc | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Ghidra/Processors/RISCV/data/languages/andestar_v5.instr.sinc b/Ghidra/Processors/RISCV/data/languages/andestar_v5.instr.sinc index bb30a6333a..c629881233 100644 --- a/Ghidra/Processors/RISCV/data/languages/andestar_v5.instr.sinc +++ b/Ghidra/Processors/RISCV/data/languages/andestar_v5.instr.sinc @@ -20,7 +20,8 @@ simm18_lh: val is sop3131 & op1516 & op1719 & op2020 & op2130 [ val = (sop3131<< export *[const]:$(XLEN) val; } -simm18_lw: val is sop3131 & op1516 & op1719 & op2020 & op2130 [ val = (sop3131<<18) | (op1516<<16) | (op1719<<13) | (op2020<<12) | (op2130<<2); ] { +#simm18_lw: val is sop3131 & op1516 & op1719 & op2020 & op2130 [ val = (sop3131<<18) | (op1516<<16) | (op1719<<13) | (op2020<<12) | (op2130<<2); ] { +simm18_lw: val is sop3131 & op2121 & op1516 & op1719 & op2020 & op2230 [ val = (sop3131<<18) | (op2121 << 17) | (op1516<<15) | (op1719<<12) | (op2020<<11) | (op2230<<2); ] { export *[const]:$(XLEN) val; } diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.reg.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.reg.sinc index 91ede6e4ae..ecd02ef3cc 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.reg.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.reg.sinc @@ -1231,6 +1231,7 @@ define token instr (32) op2122=(21,22) op2130=(21,30) op2222=(22,22) + op2230=(22,30) op2323=(23,23) op2324=(23,24) op2330=(23,30)