Merge remote-tracking branch 'origin/GT-3008_ghidorahrex_PIC-30_division_instructions'

This commit is contained in:
Ryan Kurtz
2019-08-09 13:50:31 -04:00
9 changed files with 162 additions and 52 deletions
@@ -404,7 +404,7 @@ TEST biopLogicOri1i1_Main()
TEST biopDividi1i1_Main() TEST biopDividi1i1_Main()
{ {
extern i1 biopDividi1i1(i1 lhs, i1 rhs); 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_MAX, I1_MAX), 1);
ASSERTI1(biopDividi1i1(I1_MIN, I1_MIN), 1); ASSERTI1(biopDividi1i1(I1_MIN, I1_MIN), 1);
ASSERTI1(biopDividi1i1(I1_MAX, 1), I1_MAX); ASSERTI1(biopDividi1i1(I1_MAX, 1), I1_MAX);
@@ -465,7 +465,7 @@ TEST unopPlusi4_Main()
TEST biopShtLfti2i2_Main() TEST biopShtLfti2i2_Main()
{ {
extern i2 biopShtLfti2i2(i2 lhs, i2 rhs); 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, 8), 0x100);
ASSERTI2(biopShtLfti2i2(0x0101, 0), 0x101); ASSERTI2(biopShtLfti2i2(0x0101, 0), 0x101);
ASSERTI2(biopShtLfti2i2(2, 1), 4); ASSERTI2(biopShtLfti2i2(2, 1), 4);
@@ -506,7 +506,7 @@ TEST biopMultu4u4_Main()
TEST biopShtRhti2i2_Main() TEST biopShtRhti2i2_Main()
{ {
extern i2 biopShtRhti2i2(i2 lhs, i2 rhs); 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, 8), 0x1);
ASSERTI2(biopShtRhti2i2(0x0101, 0), 0x0101); ASSERTI2(biopShtRhti2i2(0x0101, 0), 0x0101);
ASSERTI2(biopShtRhti2i2(2, 1), 1); ASSERTI2(biopShtRhti2i2(2, 1), 1);
@@ -231,7 +231,6 @@ void assertU4(const char *file, int line, const char *func, u4 val, u4 expected)
MainInfo.lastErrorLine = line; MainInfo.lastErrorLine = line;
MainInfo.lastErrorFile = (char *) file; MainInfo.lastErrorFile = (char *) file;
breakOnError(); breakOnError();
MainInfo.numfail++;
} }
MainInfo.lastTestPos = line; MainInfo.lastTestPos = line;
DO_PRINT_UINT(val == expected); DO_PRINT_UINT(val == expected);
@@ -29,8 +29,6 @@
#define PACKED_STRUCTURE #define PACKED_STRUCTURE
#endif #endif
typedef i4 (*entryFunc)(i4 * val);
typedef i4 (*breakOn)(void);
typedef i4 (*testFuncPtr)(void); typedef i4 (*testFuncPtr)(void);
typedef struct PACKED_STRUCTURE FunctionInfo 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 */ 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 ptrSz; /* how many bytes in a pointer? */
u4 byteOrder; /* value 0x01020304 used to detect endianess */ u4 byteOrder; /* value 0x01020304 used to detect endianess */
breakOn onPass; /* address of breakOnPass function, (where it goes on test pass) */ void *onPass; /* address of breakOnPass function, (where it goes on test pass) */
breakOn onError; /* address of breakOnError function, (where it goes on test failure) */ void *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 *onDone; /* address of breakOnDone function, (where it goes when all test done) */
u4 numpass; /* How many test passed */ u4 numpass; /* How many test passed */
u4 numfail; /* How many test failed */ u4 numfail; /* How many test failed */
u4 lastTestPos; /* Last test index number */ u4 lastTestPos; /* Last test index number */
@@ -14,21 +14,29 @@
* limitations under the License. * limitations under the License.
*/ */
#if defined(__GNUC__) && !defined(__llvm__) #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 HAS_GNU_ATTRIBUTES 1
#define FUNCNAME __FUNCTION__ #define FUNCNAME __FUNCTION__
#define NO_OPTIMIZE __attribute__((optimize("O0"))) #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) #elif defined(__SDCC)
#define FUNCNAME __func__ #define FUNCNAME __func__
#define NO_OPTIMIZE #define NO_OPTIMIZE
#define __VERSION__ "version"
#else #else
#if !defined(__MSP430__)
#define __VERSION__ "version" #ifndef __VERSION__
#define __VERSION__ "version"
#endif #endif
#define FUNCNAME __FUNCTION__ #define FUNCNAME __FUNCTION__
#define NO_OPTIMIZE #define NO_OPTIMIZE
#endif #endif
@@ -344,12 +352,6 @@ typedef i1 size_t;
#include <stdio.h> #include <stdio.h>
#endif #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 #ifdef BUILD_EXE
#ifndef HAS_LIBC #ifndef HAS_LIBC
void write(int fd, char *buf, int count); void write(int fd, char *buf, int count);
@@ -8,7 +8,7 @@ PCodeTest.defaults.toolchain_root = '/local/ToolChains'
PCodeTest.defaults.build_root = '/local/build-pcodetest' PCodeTest.defaults.build_root = '/local/build-pcodetest'
PCodeTest.defaults.gcc_version = '7.3.0' PCodeTest.defaults.gcc_version = '7.3.0'
PCodeTest.defaults.skip_files = [] 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.pcodetest_src = os.getcwd() + '/c_src'
# PCodeTest.defaults that cannot be overridden on the command line # PCodeTest.defaults that cannot be overridden on the command line
@@ -600,7 +600,7 @@ PCodeTest({
# Currently the 'omitted' option is only supported by the SDCC toolchain! # Currently the 'omitted' option is only supported by the SDCC toolchain!
# Causes a bit of funk with tpp.py still including references to these # 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. # 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 # 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. # structs in functions and requires a more strict format than ANSI C requires.
}) })
@@ -49,7 +49,7 @@ class PCodeTest(BuildUtil):
ce = 'can-export:%-5s' % ('yes' if self.config.can_export else 'no') ce = 'can-export:%-5s' % ('yes' if self.config.can_export else 'no')
ct = 'compiler-type:%-5s' % self.config.toolchain_type ct = 'compiler-type:%-5s' % self.config.toolchain_type
tc = 'Toolchain:%s' % self.config.toolchain 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): class PCodeTestBuild(BuildUtil):
def __init__(self, pcode_test): def __init__(self, pcode_test):
@@ -182,7 +182,7 @@ class PCodeTestBuild(BuildUtil):
if not self.isfile(companion_file) or not self.isfile(body_file): if not self.isfile(companion_file) or not self.isfile(body_file):
self.log_info('Skipping %s %s build' % (companion_file, body_file)) self.log_info('Skipping %s %s build' % (companion_file, body_file))
continue 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.compile(input_files, opt_cflag, small_name)
self.export_file(small_name+'.out', build_dir) self.export_file(small_name+'.out', build_dir)
@@ -5,7 +5,7 @@
endian="little" endian="little"
size="24" size="24"
variant="24E" variant="24E"
version="1.3" version="1.4"
slafile="PIC24E.sla" slafile="PIC24E.sla"
processorspec="PIC24.pspec" processorspec="PIC24.pspec"
manualindexfile="../manuals/PIC24.idx" manualindexfile="../manuals/PIC24.idx"
@@ -17,7 +17,7 @@
endian="little" endian="little"
size="24" size="24"
variant="24F" variant="24F"
version="1.3" version="1.4"
slafile="PIC24F.sla" slafile="PIC24F.sla"
processorspec="PIC24.pspec" processorspec="PIC24.pspec"
manualindexfile="../manuals/PIC24.idx" manualindexfile="../manuals/PIC24.idx"
@@ -29,7 +29,7 @@
endian="little" endian="little"
size="24" size="24"
variant="24H" variant="24H"
version="1.3" version="1.4"
slafile="PIC24H.sla" slafile="PIC24H.sla"
processorspec="PIC24.pspec" processorspec="PIC24.pspec"
manualindexfile="../manuals/PIC24.idx" manualindexfile="../manuals/PIC24.idx"
@@ -41,7 +41,7 @@
endian="little" endian="little"
size="24" size="24"
variant="default" variant="default"
version="1.3" version="1.4"
slafile="dsPIC30F.sla" slafile="dsPIC30F.sla"
processorspec="PIC24.pspec" processorspec="PIC24.pspec"
manualindexfile="../manuals/PIC24.idx" manualindexfile="../manuals/PIC24.idx"
@@ -53,7 +53,7 @@
endian="little" endian="little"
size="24" size="24"
variant="default" variant="default"
version="1.3" version="1.4"
slafile="dsPIC33F.sla" slafile="dsPIC33F.sla"
processorspec="PIC24.pspec" processorspec="PIC24.pspec"
manualindexfile="../manuals/PIC24.idx" manualindexfile="../manuals/PIC24.idx"
@@ -65,7 +65,7 @@
endian="little" endian="little"
size="24" size="24"
variant="default" variant="default"
version="1.3" version="1.4"
slafile="dsPIC33E.sla" slafile="dsPIC33E.sla"
processorspec="PIC24.pspec" processorspec="PIC24.pspec"
manualindexfile="../manuals/PIC24.idx" manualindexfile="../manuals/PIC24.idx"
+132 -21
View File
@@ -250,6 +250,7 @@ define token instr(32)
OP_11_7 =(7,11) OP_11_7 =(7,11)
OP_10_7 =(7,10) OP_10_7 =(7,10)
OP_31_4 =(4,31) OP_31_4 =(4,31)
OP_31_0 =(0,31)
OP_23_11=(11,23) OP_23_11=(11,23)
OP_23_19=(19,23) OP_23_19=(19,23)
@@ -3561,15 +3562,18 @@ cond1: "z" is TOK_CCCC=0x2 { tmpBool:1 = (SRL_Z); export tmpBool; }
@endif @endif
@if defined(PIC24F) || defined(PIC24H) || defined(PIC24E) || defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) @if defined(PIC24F) || defined(PIC24H) || defined(PIC24E) || defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E)
:repeat" 0x11 div.sw" TOK_10_7_Wreg,TOK_3_0_Wreg is
: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 { 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. # Note: this implementation is not iterative, like the actual op.
# Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
W0 = TOK_10_7_Wreg s/ TOK_3_0_Wreg; local div:2 = sext(TOK_10_7_Wreg) s/ sext(TOK_3_0_Wreg);
W1 = TOK_10_7_Wreg s% 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 ); testSRL_N ( W1 );
# overflow as defined in note 2 # 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; 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; 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 & 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 { 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. # Note: this implementation is not iterative, like the actual op.
# Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. # 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); local div:4 = TOK_10_8_Dreg s/ sext(TOK_3_0_Wreg);
W0 = tmp:2; local rem:4 = TOK_10_8_Dreg s% sext(TOK_3_0_Wreg);
tmp = TOK_10_8_Dreg s% sext(TOK_3_0_Wreg); W0 = div:2;
W1 = tmp:2; W1 = rem:2;
testSRL_N ( W1 ); testSRL_N ( W1 );
testSRL_Z ( W1 ); testSRL_Z ( W1 );
# Carry is modified, but modification is not defined, just assign to 0 for data flow analysis # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
SRL_C = 0; 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 @endif
@if defined(PIC24F) || defined(PIC24H) || defined(PIC24E) || defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) @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 & 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 { 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. # Note: this implementation is not iterative, like the actual op.
# Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
W0 = TOK_10_7_Wreg / TOK_3_0_Wreg; local div:2 = zext(TOK_10_7_Wreg) / zext(TOK_3_0_Wreg);
W1 = TOK_10_7_Wreg % 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 ); testSRL_N ( W1 );
@@ -3627,8 +3674,28 @@ define pcodeop isDivideOverflow;
SRL_C = 0; 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 & 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 { 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. # Note: this implementation is not iterative, like the actual op.
# Rather, it will decompile accurately and emulate correctly using the Sleigh divide support. # 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); local div:4 = TOK_10_8_Dreg / sext(TOK_3_0_Wreg);
W0 = tmp:2; local rem:4 = TOK_10_8_Dreg % sext(TOK_3_0_Wreg);
tmp = TOK_10_8_Dreg % sext(TOK_3_0_Wreg); W0 = div:2;
W1 = tmp:2; W1 = rem:2;
testSRL_N ( W1 ); testSRL_N ( W1 );
testSRL_Z ( W1 ); testSRL_Z ( W1 );
# Carry is modified, but modification is not defined, just assign to 0 for data flow analysis # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
SRL_C = 0; 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 @endif
@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) @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 & 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 { 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 # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
SRL_C = 0; 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 @endif
@if defined(dsPIC30F) || defined(dsPIC33F) @if defined(dsPIC30F) || defined(dsPIC33F)