diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS.test b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS.test index 0d481087fd..109e1ed505 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS.test +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS.test @@ -404,7 +404,7 @@ TEST biopLogicOri1i1_Main() TEST biopDividi1i1_Main() { extern i1 biopDividi1i1(i1 lhs, i1 rhs); - ASSERTI1(biopDividi1i1(0x01, 0x01), 1); + ASSERTI1(biopDividi1i1(0x1, 0x1), 1); ASSERTI1(biopDividi1i1(I1_MAX, I1_MAX), 1); ASSERTI1(biopDividi1i1(I1_MIN, I1_MIN), 1); ASSERTI1(biopDividi1i1(I1_MAX, 1), I1_MAX); @@ -465,7 +465,7 @@ TEST unopPlusi4_Main() TEST biopShtLfti2i2_Main() { extern i2 biopShtLfti2i2(i2 lhs, i2 rhs); - ASSERTI2(biopShtLfti2i2(0x0101, 16), 0x0); + ASSERTI2(biopShtLfti2i2(0x0101, 15), 0x8000); ASSERTI2(biopShtLfti2i2(0x0101, 8), 0x100); ASSERTI2(biopShtLfti2i2(0x0101, 0), 0x101); ASSERTI2(biopShtLfti2i2(2, 1), 4); @@ -506,7 +506,7 @@ TEST biopMultu4u4_Main() TEST biopShtRhti2i2_Main() { extern i2 biopShtRhti2i2(i2 lhs, i2 rhs); - ASSERTI2(biopShtRhti2i2(0x0101, 16), 0x0); + ASSERTI2(biopShtRhti2i2(0x7fff, 15), 0x0000); ASSERTI2(biopShtRhti2i2(0x0101, 8), 0x1); ASSERTI2(biopShtRhti2i2(0x0101, 0), 0x0101); ASSERTI2(biopShtRhti2i2(2, 1), 1); diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.c b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.c index fdfda1778d..e31d9fccdb 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.c +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.c @@ -231,7 +231,6 @@ void assertU4(const char *file, int line, const char *func, u4 val, u4 expected) MainInfo.lastErrorLine = line; MainInfo.lastErrorFile = (char *) file; breakOnError(); - MainInfo.numfail++; } MainInfo.lastTestPos = line; DO_PRINT_UINT(val == expected); diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.h b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.h index b7af4d774b..6787ee493b 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.h +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.h @@ -29,8 +29,6 @@ #define PACKED_STRUCTURE #endif -typedef i4 (*entryFunc)(i4 * val); -typedef i4 (*breakOn)(void); typedef i4 (*testFuncPtr)(void); typedef struct PACKED_STRUCTURE FunctionInfo @@ -45,9 +43,9 @@ typedef struct PACKED_STRUCTURE TestInfo char id[8]; /* id constains a "Magic Number" which will allow us to find this in a binary */ u4 ptrSz; /* how many bytes in a pointer? */ u4 byteOrder; /* value 0x01020304 used to detect endianess */ - breakOn onPass; /* address of breakOnPass function, (where it goes on test pass) */ - breakOn onError; /* address of breakOnError function, (where it goes on test failure) */ - breakOn onDone; /* address of breakOnDone function, (where it goes when all test done) */ + void *onPass; /* address of breakOnPass function, (where it goes on test pass) */ + void *onError; /* address of breakOnError function, (where it goes on test failure) */ + void *onDone; /* address of breakOnDone function, (where it goes when all test done) */ u4 numpass; /* How many test passed */ u4 numfail; /* How many test failed */ u4 lastTestPos; /* Last test index number */ diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/types.h b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/types.h index 052e945b95..6f918a5b60 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/types.h +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/types.h @@ -14,21 +14,29 @@ * limitations under the License. */ #if defined(__GNUC__) && !defined(__llvm__) -#define HAS_GNU_ATTRIBUTES 1 -#define FUNCNAME __FUNCTION__ -#define NO_OPTIMIZE __attribute__((optimize("O0"))) -#elif defined(__llvm__) #define HAS_GNU_ATTRIBUTES 1 #define FUNCNAME __FUNCTION__ #define NO_OPTIMIZE __attribute__((optimize("O0"))) + +#elif defined(__llvm__) + +#define HAS_GNU_ATTRIBUTES 1 +#define FUNCNAME __FUNCTION__ +#define NO_OPTIMIZE __attribute__((optimize("O0"))) + #elif defined(__SDCC) + #define FUNCNAME __func__ #define NO_OPTIMIZE +#define __VERSION__ "version" + #else -#if !defined(__MSP430__) -#define __VERSION__ "version" + +#ifndef __VERSION__ +#define __VERSION__ "version" #endif + #define FUNCNAME __FUNCTION__ #define NO_OPTIMIZE #endif @@ -344,12 +352,6 @@ typedef i1 size_t; #include #endif -#ifndef HAS_LIBC -void *memcpy(void *dest, const void *src, size_t n); -void *memset(void *s, int c, size_t n); -int memcmp(void *s1, void *s2, size_t n); -#endif - #ifdef BUILD_EXE #ifndef HAS_LIBC void write(int fd, char *buf, int count); diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py b/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py index 2eac695b09..16bd50ef87 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py @@ -8,7 +8,7 @@ PCodeTest.defaults.toolchain_root = '/local/ToolChains' PCodeTest.defaults.build_root = '/local/build-pcodetest' PCodeTest.defaults.gcc_version = '7.3.0' PCodeTest.defaults.skip_files = [] -PCodeTest.defaults.export_root = os.getcwd() + '/../../../../../../ghidra.bin/Ghidra/Test/TestResources/data/pcodetests/' +PCodeTest.defaults.export_root = os.getcwd() + '/../../../../../ghidra.bin/Ghidra/Test/TestResources/data/pcodetests/' PCodeTest.defaults.pcodetest_src = os.getcwd() + '/c_src' # PCodeTest.defaults that cannot be overridden on the command line diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py index 5914865545..6cf0021d4f 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py @@ -600,7 +600,7 @@ PCodeTest({ # Currently the 'omitted' option is only supported by the SDCC toolchain! # Causes a bit of funk with tpp.py still including references to these # tests in cunit_main.c but the compiler accepts it with a warning. - 'omitted': {'PointerManipulation', 'StructUnionManipulation'}, + 'skip_files': ['PointerManipulation.test', 'StructUnionManipulation.test'], # These tests are omitted because the SDCC compiler doesn't properly handle # structs in functions and requires a more strict format than ANSI C requires. }) diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py b/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py index 8640c4ab91..dfc796f48d 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py @@ -49,7 +49,7 @@ class PCodeTest(BuildUtil): ce = 'can-export:%-5s' % ('yes' if self.config.can_export else 'no') ct = 'compiler-type:%-5s' % self.config.toolchain_type tc = 'Toolchain:%s' % self.config.toolchain - return self.config.architecture.ljust(20) + cb + ce + ct + tc + return self.config.name.ljust(20) + cb + ce + ct + tc class PCodeTestBuild(BuildUtil): def __init__(self, pcode_test): @@ -182,7 +182,7 @@ class PCodeTestBuild(BuildUtil): if not self.isfile(companion_file) or not self.isfile(body_file): self.log_info('Skipping %s %s build' % (companion_file, body_file)) continue - input_files = ['pcode_test.c', 'pcode_main.c', companion_file, body_file] + input_files = ['pcode_test.c', 'pcode_main.c', 'builtin.c', companion_file, body_file] self.compile(input_files, opt_cflag, small_name) self.export_file(small_name+'.out', build_dir) 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..de56567ad9 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" 0x11 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,9 +3585,29 @@ cond1: "z" is TOK_CCCC=0x2 { tmpBool:1 = (SRL_Z); export tmpBool; } SRL_C = 0; } +define pcodeop pic30_div; +define pcodeop pic30_rem; +: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 { + local div:2 = pic30_div(sext(TOK_10_7_Wreg),sext(TOK_3_0_Wreg)); + local rem:2 = pic30_rem(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 = (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; -:div.sd TOK_10_8_Dregn,TOK_3_0_Wreg is +:repeat" 0x11 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 { @@ -3592,29 +3616,52 @@ 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; -} +} + +: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 { + + # overflow as defined in note 2 + SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg); + + local div:4 = pic30_div(sext(TOK_10_8_Dreg),sext(TOK_3_0_Wreg)); + local rem:4 = pic30_rem(sext(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(PIC24F) || defined(PIC24H) || defined(PIC24E) || defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) -:div.uw TOK_10_7_Wreg,TOK_3_0_Wreg is +:repeat" 0x11 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 = zext(TOK_10_7_Wreg) / zext(TOK_3_0_Wreg); + local rem:2 = zext(TOK_10_7_Wreg) % zext(TOK_3_0_Wreg); + + W0 = div:1; + W1 = rem:1; testSRL_N ( W1 ); @@ -3627,8 +3674,28 @@ 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 { + local div:2 = pic30_div(zext(TOK_10_7_Wreg),zext(TOK_3_0_Wreg)); + local rem:2 = pic30_rem(zext(TOK_10_7_Wreg),zext(TOK_3_0_Wreg)); -:div.ud TOK_10_8_Dregn,TOK_3_0_Wreg is + 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" 0x11 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 { @@ -3637,22 +3704,43 @@ 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; -} +} + +:div.ud TOK_10_8_Dregn,TOK_3_0_Wreg is + 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); + + local div:4 = pic30_div(zext(TOK_10_8_Dreg),zext(TOK_3_0_Wreg)); + local rem:4 = pic30_rem(zext(TOK_10_8_Dreg),zext(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) -:divf TOK_14_11_Wreg,TOK_3_0_Wreg is +:repeat" 0x11 divf" TOK_14_11_Wreg,TOK_3_0_Wreg is + OP_31_0=0x090011; 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 { @@ -3673,7 +3761,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 = pic30_div(dividend,zext(TOK_3_0_Wreg)); + W0 = tmp0:2; + local tmp1 = pic30_rem(dividend,zext(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)