diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/PowerPCVLEAssemblyTest.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/PowerPCVLEAssemblyTest.java new file mode 100644 index 0000000000..eda12ee397 --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/PowerPCVLEAssemblyTest.java @@ -0,0 +1,39 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.assembler.sleigh; + +import org.junit.Test; + +import ghidra.program.model.lang.LanguageID; + +public class PowerPCVLEAssemblyTest extends AbstractAssemblyTest { + public static final String VLE = "20:00:00:00:00:00:00:00"; + + @Override + protected LanguageID getLanguageID() { + return new LanguageID("PowerPC:BE:64:VLEALT-32addr"); + } + + @Test + public void testAssemble_e_nop() { + assertOneCompatRestExact("e_nop", "18:00:d0:00", VLE, 0x00400000, "e_nop"); + } + + @Test + public void testAssemble_e_ori_r0_r0_neg0x2() { + assertOneCompatRestExact("e_ori r0,r0,-0x2", "18:00:d4:fe", VLE, 0x00400000, "e_ori r0,r0,-0x2"); + } +} diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc index 510bf96343..7b08e4b5a0 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc @@ -34,14 +34,11 @@ sd4WPlusRxAddr: SD4_OFF(RX_VLE) is SD4_VLE & RX_VLE [SD4_OFF = SD4_VLE << 2;] { OIMM: val is UI5_VLE [ val = UI5_VLE+1; ] { export *[const]:$(REGISTER_SIZE) val; } @if REGISTER_SIZE == "4" -SCALE: val is BIT_10 & SCL_VLE & IMM8 [ val = (((0xFFFFFFFF << ((SCL_VLE*8) + 8)) | (0xFFFFFFFF >> (32 - (SCL_VLE*8)))) * BIT_10) | (IMM8 << (SCL_VLE*8)); ] { export *[const]:4 val;} +SCALE: val is BIT_10=1 & SCL_VLE & IMM8 [ val = (0xFFFFFFFF) & ~((0xFF-IMM8) << (SCL_VLE*8)); ] { export *[const]:4 val;} +SCALE: val is BIT_10=0 & SCL_VLE & IMM8 [ val = (IMM8 << (SCL_VLE*8)); ] { export *[const]:4 val;} @else -# Due to the way this big >> would work in java (arithmetic), we have to modify the orig way this was done. -# (0xFFFFFFFFFFFFFFFF >> (64 - (SCL_VLE*8)) <--- Original -# (0x7FFFFFFFFFFFFFFF >> (63 - (SCL_VLE*8)) <--- New -# We 'pre-shift' by 1 and take 1 off the total we'd shift by. SCL_VLE*8 is at most 24 so we don't have to -# worry about a negative shift value. -SCALE: val is BIT_10 & SCL_VLE & IMM8 [ val = (((0xFFFFFFFFFFFFFFFF << ((SCL_VLE*8) + 8)) | (0x7FFFFFFFFFFFFFFF >> (63 - (SCL_VLE*8)))) * BIT_10) | (IMM8 << (SCL_VLE*8)); ] { export *[const]:8 val;} +SCALE: val is BIT_10=1 & SCL_VLE & IMM8 [ val = (0xFFFFFFFFFFFFFFFF) & ~((0xFF-IMM8) << (SCL_VLE*8)); ] { export *[const]:8 val;} +SCALE: val is BIT_10=0 & SCL_VLE & IMM8 [ val = IMM8 << (SCL_VLE*8); ] { export *[const]:8 val;} @endif SIMM16: val is IMM_0_10_VLE & SIMM_21_25_VLE [ val = (SIMM_21_25_VLE << 11) | IMM_0_10_VLE ;] { export *[const]:2 val; } @@ -695,10 +692,15 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) | D = D | tmp; } +:e_nop is $(ISVLE) & OP=6 & XOP_12_VLE=13 & BITS_1_10=0 & BIT_0=0 & S=0 & A=0 { + +} + :e_ori A,S,SCALE is $(ISVLE) & OP=6 & XOP_12_VLE=13 & BIT_11=0 & S & A & SCALE { A = S | SCALE; } + :e_ori. A,S,SCALE is $(ISVLE) & OP=6 & XOP_12_VLE=13 & BIT_11=1 & S & A & SCALE { A = S | SCALE; cr0flags(A); @@ -726,6 +728,10 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) | RX_VLE = RX_VLE & ~RY_VLE; } +:se_nop is $(ISVLE) & OP6_VLE=17 & BITS_8_9=0 & RX_VLE=0 & RY_VLE=0 { + +} + :se_or RX_VLE,RY_VLE is $(ISVLE) & OP6_VLE=17 & BITS_8_9=0 & RX_VLE & RY_VLE { RX_VLE = RX_VLE | RY_VLE; }