From 05d9679a3d8c3d9c3c5a1670624d47cdbff0d9bc Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Thu, 18 Jul 2019 11:23:04 -0400 Subject: [PATCH] Added instructions that correctly emulate/model/decompile division for the PIC-24 and PIC-30. --- .../Processors/PIC/data/languages/PIC24.ldefs | 12 +- .../Processors/PIC/data/languages/PIC24.sinc | 155 ++++++++++++++++-- 2 files changed, 143 insertions(+), 24 deletions(-) diff --git a/Ghidra/Processors/PIC/data/languages/PIC24.ldefs b/Ghidra/Processors/PIC/data/languages/PIC24.ldefs index 4b29d7b334..ddfc2f9bfe 100644 --- a/Ghidra/Processors/PIC/data/languages/PIC24.ldefs +++ b/Ghidra/Processors/PIC/data/languages/PIC24.ldefs @@ -5,7 +5,7 @@ endian="little" size="24" variant="24E" - version="1.3" + version="1.4" slafile="PIC24E.sla" processorspec="PIC24.pspec" manualindexfile="../manuals/PIC24.idx" @@ -17,7 +17,7 @@ endian="little" size="24" variant="24F" - version="1.3" + version="1.4" slafile="PIC24F.sla" processorspec="PIC24.pspec" manualindexfile="../manuals/PIC24.idx" @@ -29,7 +29,7 @@ endian="little" size="24" variant="24H" - version="1.3" + version="1.4" slafile="PIC24H.sla" processorspec="PIC24.pspec" manualindexfile="../manuals/PIC24.idx" @@ -41,7 +41,7 @@ endian="little" size="24" variant="default" - version="1.3" + version="1.4" slafile="dsPIC30F.sla" processorspec="PIC24.pspec" manualindexfile="../manuals/PIC24.idx" @@ -53,7 +53,7 @@ endian="little" size="24" variant="default" - version="1.3" + version="1.4" slafile="dsPIC33F.sla" processorspec="PIC24.pspec" manualindexfile="../manuals/PIC24.idx" @@ -65,7 +65,7 @@ endian="little" size="24" variant="default" - version="1.3" + version="1.4" slafile="dsPIC33E.sla" processorspec="PIC24.pspec" manualindexfile="../manuals/PIC24.idx" diff --git a/Ghidra/Processors/PIC/data/languages/PIC24.sinc b/Ghidra/Processors/PIC/data/languages/PIC24.sinc index f3b2de4943..27f4be1d81 100644 --- a/Ghidra/Processors/PIC/data/languages/PIC24.sinc +++ b/Ghidra/Processors/PIC/data/languages/PIC24.sinc @@ -250,6 +250,7 @@ define token instr(32) OP_11_7 =(7,11) OP_10_7 =(7,10) OP_31_4 =(4,31) + OP_31_0 =(0,31) OP_23_11=(11,23) OP_23_19=(19,23) @@ -3561,15 +3562,18 @@ cond1: "z" is TOK_CCCC=0x2 { tmpBool:1 = (SRL_Z); export tmpBool; } @endif @if defined(PIC24F) || defined(PIC24H) || defined(PIC24E) || defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) - -:div.sw TOK_10_7_Wreg,TOK_3_0_Wreg is +:repeat" 0x12 div.sw" TOK_10_7_Wreg,TOK_3_0_Wreg is + OP_31_0=0x090011; OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 & TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg { # Note: this implementation is not iterative, like the actual op. # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. - W0 = TOK_10_7_Wreg s/ TOK_3_0_Wreg; - W1 = TOK_10_7_Wreg s% TOK_3_0_Wreg; + local div:2 = sext(TOK_10_7_Wreg) s/ sext(TOK_3_0_Wreg); + local rem:2 = sext(TOK_10_7_Wreg) s% sext(TOK_3_0_Wreg); + W0 = div:1; + W1 = rem:1; + testSRL_N ( W1 ); # overflow as defined in note 2 @@ -3581,8 +3585,52 @@ cond1: "z" is TOK_CCCC=0x2 { tmpBool:1 = (SRL_Z); export tmpBool; } SRL_C = 0; } +:div.sw TOK_10_7_Wreg,TOK_3_0_Wreg is + OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 & TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg { + + # Note: this implementation is not iterative, like the actual op. + # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. + local div:2 = sext(TOK_10_7_Wreg) s/ sext(TOK_3_0_Wreg); + local rem:2 = sext(TOK_10_7_Wreg) s% sext(TOK_3_0_Wreg); + + W0 = div:1; + W1 = rem:1; + + testSRL_N ( W1 ); + + # overflow as defined in note 2 + SRL_OV = (TOK_10_7_Wreg == 0x8000) && (TOK_3_0_Wreg == 0xFFFF); + + testSRL_Z ( W1 ); + + # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis + SRL_C = 0; +} + define pcodeop isDivideOverflow; +:repeat" 0x12 div.sd" TOK_10_8_Dregn,TOK_3_0_Wreg is + OP_31_0=0x090011; + OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 & + TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x0 & TOK_3_0_Wreg { + + # overflow as defined in note 2 + SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg); + + # Note: this implementation is not iterative, like the actual op. + # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. + local div:4 = TOK_10_8_Dreg s/ sext(TOK_3_0_Wreg); + local rem:4 = TOK_10_8_Dreg s% sext(TOK_3_0_Wreg); + W0 = div:2; + W1 = rem:2; + + testSRL_N ( W1 ); + testSRL_Z ( W1 ); + + # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis + SRL_C = 0; +} + :div.sd TOK_10_8_Dregn,TOK_3_0_Wreg is OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 & TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x0 & TOK_3_0_Wreg { @@ -3592,29 +3640,33 @@ define pcodeop isDivideOverflow; # Note: this implementation is not iterative, like the actual op. # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. - local tmp:4 = TOK_10_8_Dreg s/ sext(TOK_3_0_Wreg); - W0 = tmp:2; - tmp = TOK_10_8_Dreg s% sext(TOK_3_0_Wreg); - W1 = tmp:2; + local div:4 = TOK_10_8_Dreg s/ sext(TOK_3_0_Wreg); + local rem:4 = TOK_10_8_Dreg s% sext(TOK_3_0_Wreg); + W0 = div:2; + W1 = rem:2; testSRL_N ( W1 ); testSRL_Z ( W1 ); # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis SRL_C = 0; -} +} @endif @if defined(PIC24F) || defined(PIC24H) || defined(PIC24E) || defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) -:div.uw TOK_10_7_Wreg,TOK_3_0_Wreg is +:repeat" 0x12 div.uw" TOK_10_7_Wreg,TOK_3_0_Wreg is + OP_31_0=0x090011; OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 & TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg { # Note: this implementation is not iterative, like the actual op. # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. - W0 = TOK_10_7_Wreg / TOK_3_0_Wreg; - W1 = TOK_10_7_Wreg % TOK_3_0_Wreg; + local div:2 = sext(TOK_10_7_Wreg) / sext(TOK_3_0_Wreg); + local rem:2 = sext(TOK_10_7_Wreg) % sext(TOK_3_0_Wreg); + + W0 = div:1; + W1 = rem:1; testSRL_N ( W1 ); @@ -3627,6 +3679,50 @@ define pcodeop isDivideOverflow; SRL_C = 0; } +:div.uw TOK_10_7_Wreg,TOK_3_0_Wreg is + OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 & + TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg { + + # Note: this implementation is not iterative, like the actual op. + # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. + local div:2 = sext(TOK_10_7_Wreg) / sext(TOK_3_0_Wreg); + local rem:2 = sext(TOK_10_7_Wreg) % sext(TOK_3_0_Wreg); + + W0 = div:1; + W1 = rem:1; + + testSRL_N ( W1 ); + + # overflow as defined in note 2 + SRL_OV = 0; + + testSRL_Z ( W1 ); + + # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis + SRL_C = 0; +} + +:repeat" 0x12 div.ud" TOK_10_8_Dregn,TOK_3_0_Wreg is + OP_31_0=0x090011; + OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 & + TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x0 & TOK_3_0_Wreg { + + # overflow as defined in note 2 + SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg); + + # Note: this implementation is not iterative, like the actual op. + # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. + local div:4 = TOK_10_8_Dreg / sext(TOK_3_0_Wreg); + local rem:4 = TOK_10_8_Dreg % sext(TOK_3_0_Wreg); + W0 = div:2; + W1 = rem:2; + + testSRL_N ( W1 ); + testSRL_Z ( W1 ); + + # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis + SRL_C = 0; +} :div.ud TOK_10_8_Dregn,TOK_3_0_Wreg is OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 & @@ -3637,17 +3733,17 @@ define pcodeop isDivideOverflow; # Note: this implementation is not iterative, like the actual op. # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. - local tmp:4 = TOK_10_8_Dreg / sext(TOK_3_0_Wreg); - W0 = tmp:2; - tmp = TOK_10_8_Dreg % sext(TOK_3_0_Wreg); - W1 = tmp:2; + local div:4 = TOK_10_8_Dreg / sext(TOK_3_0_Wreg); + local rem:4 = TOK_10_8_Dreg % sext(TOK_3_0_Wreg); + W0 = div:2; + W1 = rem:2; testSRL_N ( W1 ); testSRL_Z ( W1 ); # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis SRL_C = 0; -} +} @endif @if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) @@ -3673,7 +3769,30 @@ define pcodeop isDivideOverflow; # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis SRL_C = 0; -} +} + +:divf TOK_14_11_Wreg,TOK_3_0_Wreg is + OP_23_20=0xD & OP_19_16=0x9 & OP_15=0x0 & + TOK_14_11_Wreg & OP_10_8=0x0 & OP_7_4=0x0 & TOK_3_0_Wreg { + + # Note: this implementation is not iterative, like the actual op. + # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. + dividend:4 = (sext(TOK_14_11_Wreg) << 16); + local tmp0:4 = dividend s/ sext(TOK_3_0_Wreg); + W0 = tmp0:2; + local tmp1 = dividend s% sext(TOK_3_0_Wreg); + W1 = tmp1:2; + + testSRL_N ( W1 ); + + # overflow as defined in note 1 + SRL_OV = (TOK_14_11_Wreg s>= TOK_3_0_Wreg); + + testSRL_Z ( W1 ); + + # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis + SRL_C = 0; +} @endif @if defined(dsPIC30F) || defined(dsPIC33F)