diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/JythonStubScriptProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/JythonStubScriptProvider.java new file mode 100644 index 0000000000..0c55f01e85 --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/JythonStubScriptProvider.java @@ -0,0 +1,64 @@ +/* ### + * 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.script; + +import java.io.PrintWriter; + +import generic.jar.ResourceFile; +import ghidra.util.classfinder.ExtensionPointProperties; + +/** + * A stub {@link GhidraScriptProvider} used to give feedback to a user trying to run a Jython + * script when the Jython Extension is not installed. + *

+ * Uses a sub-{@link ExtensionPointProperties#DEFAULT_PRIORITY default} priority so the Jython + * Extension can get prioritized over this if it's installed. + */ +@ExtensionPointProperties(priority = ExtensionPointProperties.DEFAULT_PRIORITY - 1) +public class JythonStubScriptProvider extends AbstractPythonScriptProvider { + + @Override + public String getDescription() { + return "Jython"; + } + + @Override + public String getRuntimeEnvironmentName() { + return "Jython"; + } + + @Override + public GhidraScript getScriptInstance(ResourceFile sourceFile, PrintWriter writer) + throws JythonStubException { + throw new JythonStubException(); + } + + /** + * A special type of {@link GhidraScriptLoadException} used to indicate that the Jython + * Extension is not installed. + */ + public static class JythonStubException extends GhidraScriptLoadException { + + /** + * Construct an new {@link JythonStubException} + */ + public JythonStubException() { + super("Jython script failed. " + + "In order to use Jython based scripts, you must install the Jython Ghidra " + + "Extension, or (recommended) port your script to PyGhidra or Java."); + } + } +} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/HeadlessAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/HeadlessAnalyzer.java index fbd30a53e1..9f49cb2801 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/HeadlessAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/HeadlessAnalyzer.java @@ -30,6 +30,7 @@ import ghidra.GhidraJarApplicationLayout; import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.app.plugin.core.osgi.BundleHost; import ghidra.app.script.*; +import ghidra.app.script.JythonStubScriptProvider.JythonStubException; import ghidra.app.util.headless.HeadlessScript.HeadlessContinuationOption; import ghidra.app.util.importer.ProgramLoader; import ghidra.app.util.opinion.*; @@ -960,7 +961,13 @@ public class HeadlessAnalyzer { } catch (Exception exc) { String logErrorMsg = "REPORT SCRIPT ERROR: " + scriptName + " : " + exc.getMessage(); - Msg.error(this, logErrorMsg, exc); + if (exc instanceof JythonStubException) { + Msg.error(this, logErrorMsg); + System.exit(1); + } + else { + Msg.error(this, logErrorMsg, exc); + } } return retOption; diff --git a/Ghidra/Processors/8051/certification.manifest b/Ghidra/Processors/8051/certification.manifest index ab3f5280a2..5dac87b24b 100644 --- a/Ghidra/Processors/8051/certification.manifest +++ b/Ghidra/Processors/8051/certification.manifest @@ -14,6 +14,8 @@ data/languages/8051.pspec||GHIDRA||||END| data/languages/8051.slaspec||GHIDRA||||END| data/languages/8051_archimedes.cspec||GHIDRA||||END| data/languages/8051_main.sinc||GHIDRA||||END| +data/languages/cip-51.slaspec||GHIDRA||||END| +data/languages/keil-cx51.cspec||GHIDRA||||END| data/languages/mx51.cspec||GHIDRA||||END| data/languages/mx51.pspec||GHIDRA||||END| data/languages/mx51.sinc||GHIDRA||||END| diff --git a/Ghidra/Processors/8051/data/languages/8051_main.sinc b/Ghidra/Processors/8051/data/languages/8051_main.sinc index 22700c13ac..2c3ad94af0 100644 --- a/Ghidra/Processors/8051/data/languages/8051_main.sinc +++ b/Ghidra/Processors/8051/data/languages/8051_main.sinc @@ -34,7 +34,7 @@ define space BITS type=ram_space size=2; # EXTERNAL - 0x010000-0x01ffff # INTERNAL - 0x000000-0x0000ff -@elif defined(MCS51) +@elif defined(MCS51) || defined(CIP51) @if defined(PTRSIZE) @else @@ -47,12 +47,64 @@ define space BITS type=ram_space size=2; # @define SP_SIZE 1 +define space RAM type=ram_space size=1; define space CODE type=ram_space size=$(PTRSIZE) default; define space INTMEM type=ram_space size=1; define space EXTMEM type=ram_space size=2; +@if defined(CIP51) +# +# CIP-51 allows up to 256 128-byte pages of these, or 32768 bytes, so two address bytes +# are needed for SFR space. +# +# At execution, SFR page selection uses the 8-bit SFRPAGE SFR to provide the page number, +# which effectively is the upper byte of SFR's full address. +# +# The devices covered in the F12x/13x datasheet only have 5 SFR pages and numbers them 0, +# 1, 2, 3, and F. The datasheet doesn't go into detail about SFRPAGE bits 2 to 6, but +# I suppose that for Ghidra instruction decoding it would suffice to just decode the full +# byte. A custom analyzer or script could check for the use of undefined SFRPAGEs. +# +define space SFR type=ram_space size=2; +@else +# +# Intel MCS-51 devices have a maximum of 128 SFRs and a byte-wide address suffices +# define space SFR type=ram_space size=1; +@endif define space BITS type=ram_space size=1; +@if defined(CIP51) +# Per the datasheet https://www.silabs.com/documents/public/data-sheets/C8051F12x-13x.pdf +# (rev 1.4) +# on-chip (internal) flash program/data memory addresses are +# 00000 - 1fbff F120/1/2/3/4/5/6/7, F130/1 +# 00000 - 0ffff F132/3 +# All of the 12x/13x chips covered by the datasheet have +# on-chip scratchpad (i.e. data only) flash: +# 20000 - 200FF +# So allowing 3 address bytes for CIP51 will cover the entire address range for the +# on-chip (internal) flash +define space IFLASH type=ram_space size=3; +# +# As with Intel's original MCS-51 architecture, CIP-51 "internal" ordinary RAM resides on +# the processor chip and uses single-byte addressing. +# +# The lower half of internal RAM can be accessed either directly (by encoding an 8 bit +# address in the opcode) or indirectly (via an address stored in R0 or R1). +# +# The upper half of internal RAM can be accessed only indirectly, again via R0 or R1. +# +# 00 - 7f directly and indirectly addressable +# 80 - ff indirectly addressable only (via R0 or R1) +# +# In CIP51 chips, addresses in the upper half of the range (that is, 80 - FF), when used +# directly, rather than accessing ordinary RAM get mapped to the chip's special function +# register RAM. +# + +define space XRAM type=ram_space size=2; +@endif + @elif defined(MCS80390) @define PTRSIZE 3 @@ -117,7 +169,7 @@ define register offset=0x38 size=1 [ R56 DPXL DPH DPL R60 R61 SPH ]; define register offset=0x3A size=2 [ DPTR ]; define register offset=0x38 size=4 [ DPX SPX ]; -@elif defined(MCS51) || defined(MCS80390) || defined(MX51) +@elif defined(MCS51) || defined(MCS80390) || defined(MX51) || defined(CIP51) define register offset=0x00 size=4 [ R0R1R2R3 ]; define register offset=0x01 size=3 [ R1R2R3 ]; # Used as R3R2R1 @@ -129,7 +181,7 @@ define register offset=0x05 size=3 [ R5R6R7 ]; define register offset=0x0A size=1 [ B ACC ]; # relocated to facilitate AB 16-bit access define register offset=0x0A size=2 [ AB ]; -@if defined(MCS51) || defined(MX51) +@if defined(MCS51) || defined(MX51) || defined(CIP51) define register offset=0x82 size=2 [ DPTR ]; define register offset=0x82 size=1 [ DPH DPL ]; # relocated to facilitate DPTR 16-bit access @elif defined(MCS80390) @@ -192,7 +244,7 @@ define context contextReg # GROUP3 - MCS251 instructions in 0x60-0xff range @define GROUP3 "((srcMode=0 & A5Prefix=1) | (srcMode=1 & A5Prefix=0))" -@elif defined(MCS51) || defined(MCS80390) || defined(MX51) +@elif defined(MCS51) || defined(MCS80390) || defined(MX51) || defined(CIP51) @define GROUP1 "epsilon" @define GROUP2 "epsilon" @@ -352,7 +404,7 @@ macro push8(val) { SPX = SPX + 1; ptr:3 = SPX:3; *[RAM]:1 ptr = val; -@elif defined(MCS51) || defined(MCS80390) +@elif defined(MCS51) || defined(MCS80390) || defined(CIP51) SP = SP + 1; *[INTMEM]:1 SP = val; @elif defined(MX51) @@ -384,16 +436,16 @@ macro push16(val) { *[RAM]:1 SPX:3 = al; SPX = SPX + 1; *[RAM]:1 SPX:3 = ah; - -@elif defined(MCS51) + +@elif defined(MCS51) || defined(CIP51) al:1 = val:1; ah:1 = val(1); - + SP = SP + 1; *[INTMEM]:1 SP = al; - SP = SP + 1; + SP = SP + 1; *[INTMEM]:1 SP = ah; - + @elif defined(MX51) # dptr push #ptr:1 = SP + 1; @@ -432,7 +484,7 @@ macro pop8(val) { ptr:3 = SPX:3; val = *[RAM]:1 ptr; SPX = SPX - 1; -@elif defined(MCS51) || defined(MCS80390) +@elif defined(MCS51) || defined(MCS80390) || defined(CIP51) val = *[INTMEM]:1 SP; SP = SP - 1; @elif defined(MX51) @@ -477,9 +529,9 @@ macro pop16(val) { SPX = SPX - 1; val = (zext(ah) << 8) | zext(al); - -@elif defined(MCS51) - + +@elif defined(MCS51) || defined(CIP51) + ah:1 = *[INTMEM]:1 SP; SP = SP - 1; al:1 = *[INTMEM]:1 SP; @@ -512,7 +564,7 @@ DPTRreg: DPTR is ophi & DPTR { export DPTR; } @if defined(MCS251) ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = 0xff0000 + zext(DPTR) + zext(ACC); export ptr; } -@elif defined(MCS51) +@elif defined(MCS51) || defined(CIP51) ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:$(PTRSIZE) = zext(DPTR) + zext(ACC); export ptr; } @elif defined(MCS80390) ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR) + zext(ACC); export ptr; } @@ -524,7 +576,7 @@ APC: "@A+PC" is epsilon { tmp:$(PTRSIZE) = inst_next + zext(ACC); expor @if defined(MCS251) ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = 0x010000 + zext(DPTR); export *:1 ptr; } # 8051 External data address mapped into RAM space -@elif defined(MCS51) +@elif defined(MCS51) || defined(CIP51) ATDPTR: "@"^DPTR is ophi & DPTR { ptr:2 = DPTR; export *[EXTMEM]:1 ptr; } @elif defined(MCS80390) ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[EXTMEM]:1 ptr; } @@ -536,13 +588,13 @@ ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[RAM]:1 ptr; } Ri: @ri is ri { ptr:3 = zext(ri); export *[RAM]:1 ptr; } @elif defined(MX51) Ri: @ri is ri { ptr:3 = zext(ri) + 0x7f0000; export *[RAM]:1 ptr; } -@elif defined(MCS51) || defined(MCS80390) +@elif defined(MCS51) || defined(MCS80390) || defined(CIP51) Ri: @ri is ri { export *[INTMEM]:1 ri; } @endif @if defined(MCS251) RiX: @ri is ri { ptr:3 = 0x010000 + zext(ri); export *:1 ptr; } # 8051 8-bit External data address mapped into RAM space -@elif defined(MCS51) +@elif defined(MCS51) || defined(CIP51) RiX: @ri is ri { ptr:2 = zext(ri); export *[EXTMEM]:1 ptr; } # limited to 8-bit external data address (I/O state can be used to produce 16-bit addr) @elif defined(MCS80390) RiX: @ri is ri { ptr:3 = zext(ri); export *[EXTMEM]:1 ptr; } # tocheck @@ -560,7 +612,7 @@ Data24: "#"data24 is data24 { export *[const]:3 data24; } Direct: mainreg is bank=0 & mainreg { export *[RAM]:1 mainreg; } @elif defined(MX51) Direct: mainreg is bank=0 & mainreg { tmp:3 = mainreg + 0x7f0000; export *[RAM]:1 tmp; } -@elif defined(MCS51) || defined(MCS80390) +@elif defined(MCS51) || defined(MCS80390) || defined(CIP51) Direct: mainreg is bank=0 & mainreg { export *[INTMEM]:1 mainreg; } @endif Direct: direct is bank=1 & direct { export *[SFR]:1 direct; } @@ -580,7 +632,7 @@ Direct: DPXL is bank=1 & direct=0x84 & DPXL { export DPXL; } Direct2: mainreg2 is bank2=0 & mainreg2 { export *[RAM]:1 mainreg2; } @elif defined(MX51) Direct2: mainreg2 is bank2=0 & mainreg2 { tmp:3 = mainreg2 + 0x7f0000; export *[RAM]:1 tmp; } -@elif defined(MCS51) || defined(MCS80390) +@elif defined(MCS51) || defined(MCS80390) || defined(CIP51) Direct2: mainreg2 is bank2=0 & mainreg2 { export *[INTMEM]:1 mainreg2; } @endif Direct2: direct2 is bank2=1 & direct2 { export *[SFR]:1 direct2; } @@ -601,7 +653,7 @@ BitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrb BitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; } BitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrbit; ] { export *[BITS]:1 bitaddr; } BitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; } -@elif defined(MCS51) || defined(MCS80390) || defined(MX51) +@elif defined(MCS51) || defined(MCS80390) || defined(MX51) || defined(CIP51) ## ##TODO !!! 8051 SFRBITS bit overlay block is probably incorrect since there is not a 1:1 mapping to the SFR space ## While the BitAddr is only used for disassembly markup, and labels come from pspec, the underlying data will @@ -622,7 +674,7 @@ BitByteAddr: PSW is bitbank=1 & sfrbyte=0x1A & sfrbit & PSW { export PSW; } BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[RAM]:1 byteaddr; } @elif defined(MX51) BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { tmp:3 = byteaddr + 0x7f0000; export *[RAM]:1 tmp; } -@elif defined(MCS51) || defined(MCS80390) +@elif defined(MCS51) || defined(MCS80390) || defined(CIP51) BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[INTMEM]:1 byteaddr; } @endif @@ -856,21 +908,21 @@ Rel16: relAddr is rel16 [ relAddr=inst_next+rel16; ] { export *:1 relAdd :PUSH Direct is $(GROUP1) & ophi=12 & oplo=0; Direct { push8(Direct); } -:RET is $(GROUP1) & ophi=2 & oplo=2 { +:RET is $(GROUP1) & ophi=2 & oplo=2 { @if defined(MCS251) || defined(MX51) -pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3]; -@elif defined(MCS51) -pc:2 = 0; pop16(pc); return[pc]; +pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3]; +@elif defined(MCS51) || defined(CIP51) +pc:2 = 0; pop16(pc); return[pc]; @elif defined(MCS80390) pc:3 = 0; pop24(pc); return[pc]; @endif } -:RETI is $(GROUP1) & ophi=3 & oplo=2 { +:RETI is $(GROUP1) & ophi=3 & oplo=2 { @if defined(MCS251) || defined(MX51) -pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3]; -@elif defined(MCS51) -pc:2 = 0; pop16(pc); return[pc]; +pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3]; +@elif defined(MCS51) || defined(CIP51) +pc:2 = 0; pop16(pc); return[pc]; @elif defined(MCS80390) pc:3 = 0; pop24(pc); return[pc]; @endif diff --git a/Ghidra/Processors/8051/data/languages/cip-51.slaspec b/Ghidra/Processors/8051/data/languages/cip-51.slaspec new file mode 100644 index 0000000000..737aaf743e --- /dev/null +++ b/Ghidra/Processors/8051/data/languages/cip-51.slaspec @@ -0,0 +1,4 @@ +@define CIP51 "" + +@include "8051_main.sinc" + diff --git a/Ghidra/Processors/8051/data/languages/keil-cx51.cspec b/Ghidra/Processors/8051/data/languages/keil-cx51.cspec new file mode 100644 index 0000000000..14efe89087 --- /dev/null +++ b/Ghidra/Processors/8051/data/languages/keil-cx51.cspec @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ghidra/Processors/ARM/data/languages/ARM.sinc b/Ghidra/Processors/ARM/data/languages/ARM.sinc index 9e4cdb8950..0f3b5806f1 100644 --- a/Ghidra/Processors/ARM/data/languages/ARM.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARM.sinc @@ -235,11 +235,12 @@ macro LoadWritePC(addr) { } # Branch depends on version +# ONLY USED IN ARMinstructions.sinc for thumb use BranchWritePC macro ALUWritePC(addr) { @if defined(VERSION_7) BXWritePC(addr); @else - BranchWritePC(addr); + BranchWritePC(addr & 0xfffffffc); @endif } diff --git a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc index c2269e5c78..1f6b9f8c49 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc @@ -1202,10 +1202,11 @@ with : ARMcondCk=1 { Hrd0002 = Hrd0002 + Hrm0305; } +# Destination is PC :add^ItCond Hrd0002,Hrm0305 is TMode=1 & ItCond & op8=0x44 & Hrd0002 & Hrm0305 & hrd0002=7 & h1=1 { build ItCond; - dest:4 = Hrd0002 + Hrm0305; + dest:4 = (Hrd0002 + Hrm0305) & 0xfffffffe; # Simple branch, mask off the last bit BranchWritePC(dest); goto [pc]; } @@ -2653,18 +2654,20 @@ macro th_set_carry_for_lsr(op1,shift_count) { Hrd0002 = Hrm0305; } +# Destination is PC :mov^ItCond Hrd0002,Hrm0305 is TMode=1 & ItCond & op8=0x46 & Hrm0305 & Hrd0002 & hrd0002=7 & h1=1 { build ItCond; - dest:4 = Hrm0305; + dest:4 = Hrm0305 & 0xfffffffe; # Simple branch, mask off the last bit BranchWritePC(dest); goto [pc]; } +# Destination is PC :mov^ItCond Hrd0002,Hrm0305 is TMode=1 & ItCond & op8=0x46 & Hrm0305 & rm0306=14 & Hrd0002 & hrd0002=7 & h1=1 { build ItCond; - dest:4 = Hrm0305; + dest:4 = Hrm0305 & 0xfffffffe; # Simple branch, mask off the last bit BranchWritePC(dest); return [pc]; } @@ -3664,7 +3667,7 @@ macro BitReverse(val) { cpsr = *ptr; ptr = ptr - 4; dest:4 = *ptr; - BranchWritePC(dest); + BranchWritePC(dest & 0xfffffffe); # Simple branch, mask off the last bit return [pc]; } @@ -3676,7 +3679,7 @@ macro BitReverse(val) { ptr = ptr - 4; dest:4 = *ptr; part2Rd0003 = ptr; - BranchWritePC(dest); + BranchWritePC(dest & 0xfffffffe); # Simple branch, mask off the last bit return [pc]; } @@ -3687,7 +3690,7 @@ macro BitReverse(val) { cpsr = *ptr; ptr = ptr + 4; dest:4 = *ptr; - BranchWritePC(dest); + BranchWritePC(dest & 0xfffffffe); # Simple branch, mask off the last bit return [pc]; } @@ -3699,7 +3702,7 @@ macro BitReverse(val) { ptr = ptr + 4; dest:4 = *ptr; part2Rd0003 = ptr + 4; - BranchWritePC(dest); + BranchWritePC(dest & 0xfffffffe); # Simple branch, mask off the last bit return [pc]; } diff --git a/Ghidra/Processors/ARM/data/languages/ARMneon.sinc b/Ghidra/Processors/ARM/data/languages/ARMneon.sinc index 7862e72bdc..0ef7ad2754 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMneon.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMneon.sinc @@ -548,7 +548,8 @@ simdExpImm_8: "#"^imm is TMode=1 & thv_c2828 & thv_c1818 & thv_c1717 & thv_c161 # see note d simdExpImm_16: "#"^imm is (TMode=0 & c2424=0 & c1618=0 & c0003=0) | (TMode=1 & thv_c2828=0 & thv_c1618=0 & thv_c0003=0) [ imm = 0; ] { - export *[const]:16 imm; + tmp:16 = 0; + export *[const]:16 tmp; } # cmode 0xxx I32 diff --git a/Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc b/Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc index da4b929978..5c28d52785 100644 --- a/Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc +++ b/Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc @@ -348,6 +348,11 @@ srcREG: "PC" is a=0 & f8=0xf9 { export PCL; } +dfLoc: f8 is a=1 & f8 { # (Banked mode) + addr:2 = (zext(BSR) << 8) + f8; + export *[DATA]:1 addr; +} + dfLoc: f8 is a=0 & f8_57=0x0 & f8 { export *[DATA]:1 f8; } # 0x00-0x1f (Access mode) dfLoc: f8 is a=0 & f8_57=0x1 & f8 { export *[DATA]:1 f8; } # 0x20-0x3f (Access mode) dfLoc: f8 is a=0 & f8_57=0x2 & f8 { export *[DATA]:1 f8; } # 0x40-0x5f (Access mode) @@ -468,8 +473,8 @@ dfLoc: freg is a=0 & f8=0xdb & freg { # Destination operand representation (w: W register is destination; f: specified fREG is destination) # Destination register (either srcREG or WREG) -destREG: "0" is d=0 { export WREG; } -destREG: "1" is d=1 & dfLoc { export dfLoc; } +destREG: "w" is d=0 { export WREG; } +destREG: "f" is d=1 & dfLoc { export dfLoc; } # Source File Registers specified by a 12-bit absolute offsets within 32-bit instriction srcREG32: fs is fs { export *[DATA]:1 fs; } # 0x000-0xeff diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc index 828f4c267f..e7f9580713 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc @@ -1988,6 +1988,7 @@ dUI16PlusRAOrZeroAddress: val^"("^RA_OR_ZERO^")" is RA_OR_ZERO & UI_16_s8 [ val @ifdef BIT_64 dsPlusRaAddress: simm_ds(A) is SIMM_DS & A [simm_ds = SIMM_DS << 2;] {tmp:8 = simm_ds + A;export tmp;} dsPlusRaOrZeroAddress: simm_ds(RA_OR_ZERO) is SIMM_DS & RA_OR_ZERO [simm_ds = SIMM_DS << 2;] {tmp:8 = simm_ds + RA_OR_ZERO;export tmp;} +dqPlusRaOrZeroAddress: simm_ds(RA_OR_ZERO) is DQs & RA_OR_ZERO [simm_ds = DQs << 4;] {tmp:8 = simm_ds + RA_OR_ZERO;export tmp;} @endif diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc index 17d5ed1080..fe36db64b7 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc @@ -1609,8 +1609,8 @@ define pcodeop stdcixOp; # ISA-info: lq - Form "DQ" Page 751 Category "LSQ" # binutils: power4.d: +0: e0 83 00 00 lq r4,0\(r3\) # binutils: power4.d: +4: e0 83 00 00 lq r4,0\(r3\) -:lq RT,A,DQ is $(NOTVLE) & OP=56 & RT & Dp & A & DQ & BITS_0_3=0 & regp [regpset = Dp+1;] { - ea:$(REGISTER_SIZE) = A + sext(DQ:2 << 4); +:lq RT,dqPlusRaOrZeroAddress is $(NOTVLE) & OP=56 & RT & Dp & dqPlusRaOrZeroAddress & regp [regpset = Dp+1;] { + ea:$(REGISTER_SIZE) = dqPlusRaOrZeroAddress; @if ENDIAN == "big" RT = *:$(REGISTER_SIZE) ea; regp = *:$(REGISTER_SIZE) (ea + $(REGISTER_SIZE)); @@ -1925,8 +1925,8 @@ define pcodeop stfdpOp; # binutils: power4.d: +58: f8 c7 ff f2 stq r6,-16\(r7\) # binutils: power4.d: +5c: f8 c7 80 02 stq r6,-32768\(r7\) # binutils: power4.d: +60: f8 c7 7f f2 stq r6,32752\(r7\) -:stq RS,RA_OR_ZERO,DS is $(NOTVLE) & OP=62 & RS & Dp & RA_OR_ZERO & DS & BITS_0_1=2 & regp [regpset = Dp+1;] { - ea:$(REGISTER_SIZE) = RA_OR_ZERO + sext(DS:2 << 2); +:stq RS,dsPlusRaOrZeroAddress is $(NOTVLE) & OP=62 & RS & Dp & dsPlusRaOrZeroAddress & BITS_0_1=2 & regp [regpset = Dp+1;] { + ea:$(REGISTER_SIZE) = dsPlusRaOrZeroAddress; @if ENDIAN == "big" *:$(REGISTER_SIZE) ea = RS; *:$(REGISTER_SIZE) (ea + $(REGISTER_SIZE)) = regp;