From 977d0ca66763cd63e202ea63241a5670b8259135 Mon Sep 17 00:00:00 2001 From: b Date: Mon, 19 Aug 2024 10:22:07 +0100 Subject: [PATCH] Fix LQ instruction to support signed offsets Based on the Power ISA manual sign extended DQ<<4 is added to RA to get source EA. --- Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc | 1 + Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc index aaa76cc4acd..5947bdf859e 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc @@ -1983,6 +1983,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 ce9a52cc896..92cacf400c6 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc @@ -1609,8 +1609,10 @@ 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,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, BITS_0_3 is $(NOTVLE) & OP=56 & RT & Dp & RA & DQs & dqPlusRaOrZeroAddress & BITS_0_3 & regp [regpset = Dp+1;] { + ea:$(REGISTER_SIZE) = RA + sext(DQs:2 << 4); @if ENDIAN == "big" RT = *:$(REGISTER_SIZE) ea; regp = *:$(REGISTER_SIZE) (ea + $(REGISTER_SIZE));