From 282ac6dc581f9490727d70a1a25b94d18a14010d Mon Sep 17 00:00:00 2001 From: vrokas Date: Fri, 20 Feb 2004 00:48:07 +0000 Subject: [PATCH] * doc/sdccman.lyx: removed PIC16 from PIC16 Port Specific Options, removed -penable-stack, added comment for stack pragma, added warning for not initializing the stack/frame registers, removed comment at interrupts section Stack is made permanent, there is no ability to disable stack usage. * src/pic16/device.h, * src/pic16/device.c: removed all references to USE_STACK macro, * src/pic16/device.c (pic16_dump_section): when no elements in rlist, free rlist before return, * (pic16_dump_int_registers): NEW, internal registers are a new set of general purpose registers reused by each function, * (checkAddReg): returns 1 if registers is added to set, * (pic16_groupRegistersInSection): when a registers is of type PO_GPR_TEMP add it in pic16_int_regs and not in pic16_rel_udata, * src/pic16/device.h: memRange and Assigned Memory are deleted, SRCASECMP macro is moved here from device.c * src/pic16/genarith.c (pic16_pCodeOpType): added cases for PO_PCLATU, PO_PRODL, PO_PRODH, * (pic16_pCodeOpType, genMinus, changed compares to "a" register, with AOP_ACC, * (pic16_genPlus): fixed some bugs and indented properly, * (pic16_addSign): changed size to size+offset in the MOVWF instruction, * (pic16_genUMult8XLit_8): NEW, uses processor MULLW instruction to multiply 8-bit operand by literal, result is 8-bit, * (pic16_genUMult8X8_8): NEW, uses processor MULWF instruction to multiply 2 8-bit operand, result is 8-bit, * (pic16_genMult8X8_8): modified to call genUMult8X*_8 functions and not genUMult8X*_16, * src/pic16/gen.c: changed accUse to contain WREG only, * (pic16_emitcomment): renamed to pic16_emitpcomment, * (aopForSym): allocated dir register when IN_DIRSPACE(space) is, true, do not use immediate addressing any more unless sym is a pointer in codespace, * (aopForRemat): do not use immediate addressing when symbol not in codespace and when symbol's address is requested, * (aopOp): for-loop in if(sym->accUse) is modified for the new accUse size (= 1), * (aopGet): added case for AOP_ACC and don't return "accumulator bug" but WREG instead, * (popGetTempReg): pushes contents of temporary register in stack, * (popReleaseTempReg): pops contents of temporary register from stack. Use popGetTempReg/popReleaseTempReg in aligned pairs, * (pic16_popGet): separated case AOP_ACC to return register WREG from processor registers, AOP_PCODE not checks if pcop is PO_DIR or PO_IMMEDIATE and initializes their instance/offset appropriately, * The whole issue with aopForSym,aopForRemat,popGet) is to minimize the use of immediate pointers to certain cases only. * (pic16_pushpCodeOpReg, pic16_poppCodeOpReg): use pic16_popGet2p, * (pic16_loadFromReturn, pic16_storeForReturn: NEW, * (assignResultValue, genCall, genRet): modified to use the new function return value scheme with WREG,PRODL,PRODH,FSR0L and FSR0, genPcall is still broken, * (genFunction): added code to create 'A' type pBlocks when interrupt functions are generated, code not extensively tested yet, ISRs push WREG,STATUS,BSR,PRODL,PRODH,FSR0L,FSR0H registers on stack, * (genEndFunction): modified so ISRs pop stored registers from stack, * (genMultOneByte): cleanup, * (AccRsh): added flag andmask, to and result with appropriate mask, * (genUnpackBits,genPackBits): fixed and can handle bit fields, * (genDataPointerGet): fixed and reenabled its use, * (genNearDataPointerGet): bugs fixed, * (genDataPointerSet): bugs fixed, * src/pic16/genutils.c: added functions pic16_DumpValue,pic16_DumpAop, pic16_DumpSymbol, pic16_DumpOp, * src/pic16/genutils.h: function prototypes for the above functions, * src/pic16/glue.c: new flags initsfpnt, to initialize stack/frame pointers, * (pic16emitRegularMap): many many many improvements, but needs a major cleanup, * src/pic16/main.c: enable_stack in pic16_options is removed, * (_pic16_parseOptions): removed command line options -penable-stack, * (_process_pragma): emit stack symbol only when stack pragma is processed, * src/pic16/pcode.c: pic16_pc_fsr0 is removed, all operations are redirected to FSR0L/FSR0H pair, * (pic16_get_op, pic16_get_op2): modifications and improvements, * (pic16_getRegFromInstruction, pic16_getRegFromInstruction2): added cases PO_PRODL,PO_PRODH, pic16_getRegFromInstruction2 returns sane for immediates, * (insertBankSwitch): modified to handle cases like: (alfa + 1) * (dumpPicOptype): NEW, * src/pic16/pcode.h: added PO_PCLATU,PO_PRODL,PO_PRODH in enum, * src/pic16/pcoderegs.c (pCodeRegMapLiveRangesInFlow): fixed bug with movff instruction, * src/pic16/ralloc.c: renamed typeRegWithIdx to pic16_typeRegWithIdx, added pic16_int_regs, some packRegsFor* functions are commented out, because produce errors, * src/pic16/NOTES: minor modifications git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3210 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 95 +++ doc/sdccman.lyx | 138 +--- src/pic16/NOTES | 26 +- src/pic16/device.c | 100 ++- src/pic16/device.h | 61 +- src/pic16/gen.c | 1758 +++++++++++++++++++++++------------------ src/pic16/gen.h | 16 +- src/pic16/genarith.c | 718 ++++++++++------- src/pic16/genutils.c | 243 ++++++ src/pic16/genutils.h | 10 +- src/pic16/glue.c | 84 +- src/pic16/main.c | 30 +- src/pic16/pcode.c | 457 +++++------ src/pic16/pcode.h | 8 +- src/pic16/pcodepeep.c | 5 +- src/pic16/pcoderegs.c | 17 +- src/pic16/ralloc.c | 141 ++-- src/pic16/ralloc.h | 11 +- 18 files changed, 2323 insertions(+), 1595 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a65af7b..9e197ce3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,98 @@ +2004-02-20 Vangelis Rokas + Hans-Juergen Dorn + + * doc/sdccman.lyx: removed PIC16 from PIC16 Port Specific Options, + removed -penable-stack, added comment for stack pragma, added + warning for not initializing the stack/frame registers, removed + comment at interrupts section + + Stack is made permanent, there is no ability to disable stack usage. + * src/pic16/device.h, + * src/pic16/device.c: removed all references to USE_STACK macro, + * src/pic16/device.c (pic16_dump_section): when no elements in + rlist, free rlist before return, + * (pic16_dump_int_registers): NEW, internal registers are a new set + of general purpose registers reused by each function, + * (checkAddReg): returns 1 if registers is added to set, + * (pic16_groupRegistersInSection): when a registers is of type + PO_GPR_TEMP add it in pic16_int_regs and not in pic16_rel_udata, + * src/pic16/device.h: memRange and Assigned Memory are deleted, + SRCASECMP macro is moved here from device.c + * src/pic16/genarith.c (pic16_pCodeOpType): added cases for + PO_PCLATU, PO_PRODL, PO_PRODH, + * (pic16_pCodeOpType, genMinus, + changed compares to "a" register, with AOP_ACC, + * (pic16_genPlus): fixed some bugs and indented properly, + * (pic16_addSign): changed size to size+offset in the MOVWF + instruction, + * (pic16_genUMult8XLit_8): NEW, uses processor MULLW instruction to + multiply 8-bit operand by literal, result is 8-bit, + * (pic16_genUMult8X8_8): NEW, uses processor MULWF instruction to + multiply 2 8-bit operand, result is 8-bit, + * (pic16_genMult8X8_8): modified to call genUMult8X*_8 functions and not + genUMult8X*_16, + * src/pic16/gen.c: changed accUse to contain WREG only, + * (pic16_emitcomment): renamed to pic16_emitpcomment, + * (aopForSym): allocated dir register when IN_DIRSPACE(space) is, + true, do not use immediate addressing any more unless sym is a + pointer in codespace, + * (aopForRemat): do not use immediate addressing when symbol not in + codespace and when symbol's address is requested, + * (aopOp): for-loop in if(sym->accUse) is modified for the new + accUse size (= 1), + * (aopGet): added case for AOP_ACC and don't return "accumulator + bug" but WREG instead, + * (popGetTempReg): pushes contents of temporary register in stack, + * (popReleaseTempReg): pops contents of temporary register from + stack. Use popGetTempReg/popReleaseTempReg in aligned pairs, + * (pic16_popGet): separated case AOP_ACC to return register WREG + from processor registers, AOP_PCODE not checks if pcop is PO_DIR + or PO_IMMEDIATE and initializes their instance/offset appropriately, + * The whole issue with aopForSym,aopForRemat,popGet) is to minimize + the use of immediate pointers to certain cases only. + + * (pic16_pushpCodeOpReg, pic16_poppCodeOpReg): use pic16_popGet2p, + * (pic16_loadFromReturn, pic16_storeForReturn: NEW, + * (assignResultValue, genCall, genRet): modified to use the new + function return value scheme with WREG,PRODL,PRODH,FSR0L and FSR0, + genPcall is still broken, + * (genFunction): added code to create 'A' type pBlocks when + interrupt functions are generated, code not extensively tested yet, + ISRs push WREG,STATUS,BSR,PRODL,PRODH,FSR0L,FSR0H registers on stack, + * (genEndFunction): modified so ISRs pop stored registers from stack, + * (genMultOneByte): cleanup, + * (AccRsh): added flag andmask, to and result with appropriate mask, + * (genUnpackBits,genPackBits): fixed and can handle bit fields, + * (genDataPointerGet): fixed and reenabled its use, + * (genNearDataPointerGet): bugs fixed, + * (genDataPointerSet): bugs fixed, + * src/pic16/genutils.c: added functions pic16_DumpValue,pic16_DumpAop, + pic16_DumpSymbol, pic16_DumpOp, + * src/pic16/genutils.h: function prototypes for the above functions, + * src/pic16/glue.c: new flags initsfpnt, to initialize stack/frame + pointers, + * (pic16emitRegularMap): many many many improvements, but needs a + major cleanup, + * src/pic16/main.c: enable_stack in pic16_options is removed, + * (_pic16_parseOptions): removed command line options -penable-stack, + * (_process_pragma): emit stack symbol only when stack pragma is + processed, + * src/pic16/pcode.c: pic16_pc_fsr0 is removed, all operations are + redirected to FSR0L/FSR0H pair, + * (pic16_get_op, pic16_get_op2): modifications and improvements, + * (pic16_getRegFromInstruction, pic16_getRegFromInstruction2): added + cases PO_PRODL,PO_PRODH, pic16_getRegFromInstruction2 returns sane + for immediates, + * (insertBankSwitch): modified to handle cases like: (alfa + 1) + * (dumpPicOptype): NEW, + * src/pic16/pcode.h: added PO_PCLATU,PO_PRODL,PO_PRODH in enum, + * src/pic16/pcoderegs.c (pCodeRegMapLiveRangesInFlow): fixed bug + with movff instruction, + * src/pic16/ralloc.c: renamed typeRegWithIdx to pic16_typeRegWithIdx, + added pic16_int_regs, some packRegsFor* functions are commented out, + because produce errors, + * src/pic16/NOTES: minor modifications + 2004-02-18 Jesus Calvino-Fraga * as/mcs51/aslink.h, as/mcs51/lkarea.c, as/mcs51/lkdata.c, as/mcs51/lkmain.c, diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index b6bfc028..36fecf54 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -1718,10 +1718,10 @@ Install paths \begin_inset Tabular - - - - + + + + \begin_inset Text @@ -3469,7 +3469,7 @@ It tries to document SDCC for several processor architectures in one document currently matches SDCC for mcs51 and DS390 best and does give too few informati on about f.e. - Z80, PIC and HC08. + Z80, PIC14, PIC16 and HC08. \layout Itemize There are many references pointing away from this documentation. @@ -6178,47 +6178,6 @@ status Collapsed \layout Subsection -PIC Options -\begin_inset LatexCommand \index{Options PIC} - -\end_inset - - -\begin_inset LatexCommand \index{PIC options} - -\end_inset - - -\layout List -\labelwidthstring 00.00.0000 - - -\series bold -- -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - --gen-banksel -\begin_inset LatexCommand \index{-\/-gen-banksel} - -\end_inset - - -\series default - enable the generation of banksel assembler directives in the PIC16 -\begin_inset LatexCommand \index{PIC16} - -\end_inset - - port. -\layout Subsection - Z80 Options \begin_inset LatexCommand \index{Options Z80} @@ -12301,8 +12260,8 @@ For signed & unsigned int (16 bit) and long (32 bit) variables, division, \begin_inset Tabular - - + + \begin_inset Text @@ -12595,8 +12554,8 @@ SDCC supports IEEE (single precision 4 bytes) floating point numbers.The \begin_inset Tabular - - + + \begin_inset Text @@ -13918,8 +13877,8 @@ The compiler creates the following #defines \begin_inset Tabular - - + + \begin_inset Text @@ -14712,7 +14671,7 @@ status Collapsed no local variables. \layout Subsection -PIC16 Port Specific Options +Port Specific Options \layout Standard The port specific options appear after the global options in the sdcc --help @@ -14795,31 +14754,6 @@ status Collapsed / \end_inset --penable-stack Enables stack usage. - All new development is done with stack enabled. - This command line soon will be deprecated and stack will be enabled by - default. - For the time being it must be entered if one wants to have stack. -\newline - -\series bold -This option is deprecated. - Stack is enabled by default in the port and there is no way to disable - it. - It is left here only for reference. -\layout List -\labelwidthstring 00.00.0000 - -- -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - -stack-model=[model] Used in conjuction with the command above. Defines the stack model to be used, valid stack models are : \begin_deeper @@ -14923,8 +14857,8 @@ PIC16 port defines the following preprocessor macros while translating a \begin_inset Tabular - - + + \begin_inset Text @@ -14985,10 +14919,10 @@ PIC16 port uses the following directories for searching header files and \begin_inset Tabular - - - - + + + + \begin_inset Text @@ -15023,7 +14957,7 @@ Command prefix \end_inset - + \begin_inset Text @@ -15124,6 +15058,9 @@ It is important to initialize the stack, otherwise strange things can happen. . \newline +The stack pragma should be used only once in a project. + Multiple pragmas may result in indeterminate behaviour of the program. +\newline If you omit setting the pragma the port emits a warning message before linking. If not initializing the stack is desired ignore the message. \layout LyX-Code @@ -15207,9 +15144,9 @@ Memory model affects the default size of pointers within the source. \begin_inset Tabular - - - + + + \begin_inset Text @@ -15359,9 +15296,9 @@ large \begin_inset Tabular - - - + + + \begin_inset Text @@ -15445,6 +15382,14 @@ Frame pointer FSR2 \end_inset +\layout Standard + + +\series bold +Currently stack and frame pointers should be initialized explicit by the + user at the desired Data RAM position (see 4.5.5 Pragma Stack). + Uninitialized stack and frame pointers can result in unexpected behavior + of the resulting binary. \layout Subsection Function return values @@ -15459,8 +15404,8 @@ Return values from functions are placed to the appropriate registers following \begin_inset Tabular - - + + \begin_inset Text @@ -15609,11 +15554,6 @@ NOTE that when the _naked attribute is specified for an interrupt routine, \end_inset . -\layout Standard - -Currently interrupt enable flags are left unaffected when entering an interrupt - routine. - This may change in the future. \layout Chapter Debugging with SDCDB @@ -17371,7 +17311,7 @@ Documentation \begin_inset Tabular - + diff --git a/src/pic16/NOTES b/src/pic16/NOTES index d49eb7e5..c2ce6ca3 100644 --- a/src/pic16/NOTES +++ b/src/pic16/NOTES @@ -11,10 +11,32 @@ For any questions please ask the current port developers. Current developer: -Vangelis Rokas +Vangelis Rokas Other people to contact: -Scott Dattalo +Scott Dattalo + +====================================================================== +====================================================================== +2004-Feb-20 Vangelis Rokas +Major update with many bugfixes. + +1. The most of the pic16 regression tests (former pic regression tests) pass +successfully. Many thanks to Hans Dorn who did a great job with the +arithmetic, shift and pointer functions. + +2. Bit fields now work properly. + +3. Stack is permanently enabled. Command argument -pstack-enable is deleted +and no more recognized by the port. + + +2004-Feb-07 Vangelis Rokas + +1. Fixed a bug so that compiler allocated internal registered, will +be shared along multiple sources via '.registers' section placed +in absolute data memory address 0x0000. Registers 0x00 to 0x7f are +considered as internal since they can be used for fast access. diff --git a/src/pic16/device.c b/src/pic16/device.c index d7e500db..6a5c7006 100644 --- a/src/pic16/device.c +++ b/src/pic16/device.c @@ -39,17 +39,10 @@ #include "ralloc.h" #include "device.h" -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif static PIC16_device Pics16[] = { { {"p18f242", "18f242", "pic18f242", "f242"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x300, // bank mask 0x300, // RAMsize @@ -58,8 +51,6 @@ static PIC16_device Pics16[] = { { {"p18f252", "18f252", "pic18f252", "f252"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x600, // bank mask 0x600, // RAMsize @@ -68,8 +59,6 @@ static PIC16_device Pics16[] = { { {"p18f442", "18f442", "pic18f442", "f442"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x300, // bank mask 0x300, // RAMsize @@ -78,8 +67,6 @@ static PIC16_device Pics16[] = { { {"p18f452", "18f452", "pic18f452", "f452"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x600, // bank mask 0x600, // RAMsize @@ -88,8 +75,6 @@ static PIC16_device Pics16[] = { { {"p18f248", "18f248", "pic18f248", "f248"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x300, // bank mask 0x300, // RAMsize @@ -98,8 +83,6 @@ static PIC16_device Pics16[] = { { {"p18f258", "18f258", "pic18f258", "f258"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x600, // bank mask 0x600, // RAMsize @@ -108,8 +91,6 @@ static PIC16_device Pics16[] = { { {"p18f448", "18f448", "pic18f448", "f448"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x300, // bank mask 0x300, // RAMsize @@ -118,8 +99,6 @@ static PIC16_device Pics16[] = { { {"p18f458", "18f458", "pic18f458", "f458"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x600, // bank mask 0x600, // RAMsize @@ -128,8 +107,6 @@ static PIC16_device Pics16[] = { { {"p18f6520", "18f6520", "pic18f6520", "f6520"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x800, // bank mask 0x800, // RAMsize @@ -138,8 +115,6 @@ static PIC16_device Pics16[] = { { {"p18f6620", "18f6620", "pic18f6620", "f6620"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0xf00, // bank mask 0xf00, // RAMsize @@ -147,8 +122,6 @@ static PIC16_device Pics16[] = { }, { {"p18f6680", "18f6680", "pic18f6680", "f6680"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0xc00, // bank mask 0xc00, // RAMsize @@ -156,8 +129,6 @@ static PIC16_device Pics16[] = { }, { {"p18f6720", "18f6720", "pic18f6720", "f6720"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0xf00, // bank mask 0xf00, // RAMsize @@ -165,8 +136,6 @@ static PIC16_device Pics16[] = { }, { {"p18f8520", "18f8520", "pic18f8520", "f8520"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0x800, // bank mask 0x800, // RAMsize @@ -174,8 +143,6 @@ static PIC16_device Pics16[] = { }, { {"p18f8620", "18f8620", "pic18f8620", "f8620"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0xf00, // bank mask 0xf00, // RAMsize @@ -183,8 +150,6 @@ static PIC16_device Pics16[] = { }, { {"p18f8680", "18f8680", "pic18f8680", "f8680"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0xc00, // bank mask 0x800, // RAMsize @@ -192,8 +157,6 @@ static PIC16_device Pics16[] = { }, { {"p18f8720", "18f8720", "pic18f8720", "f8720"}, // aliases - (memRange *)NULL, // ram memory map - (memRange *)NULL, // sfr memory map 0, 0xf00, // bank mask 0xf00, // RAMsize @@ -261,15 +224,8 @@ extern regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i void pic16_setMaxRAM(int size) { - regs * reg; - pic16->maxRAMaddress = size; - stackPos = pic16->RAMsize-1; - - - if(USE_STACK) { - reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "stack", 1, 0, NULL); - addSet(&pic16_fix_udata, reg); - } + pic16->maxRAMaddress = size; + stackPos = pic16->RAMsize-1; if (pic16->maxRAMaddress < 0) { fprintf(stderr, "invalid \"#pragma maxram 0x%x\" setting\n", @@ -331,7 +287,10 @@ void pic16_dump_section(FILE *of, set *section, int fix) /* sort symbols according to their address */ qsort(rlist, elementsInSet(section), sizeof(regs *), regCompare); - if(!i)return; + if(!i) { + if(rlist)free(rlist); + return; + } if(!fix) { fprintf(of, "\n\n\tudata\n"); @@ -359,6 +318,35 @@ void pic16_dump_section(FILE *of, set *section, int fix) free(rlist); } +void pic16_dump_int_registers(FILE *of, set *section) +{ + regs *r, *rprev; + int i; + regs **rlist; + + /* put all symbols in an array */ + rlist = Safe_calloc(elementsInSet(section), sizeof(regs *)); + r = rlist[0]; i = 0; + for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) { + rlist[i] = rprev; i++; + } + + /* sort symbols according to their address */ + qsort(rlist, elementsInSet(section), sizeof(regs *), regCompare); + + if(!i) { + if(rlist)free(rlist); + return; + } + + fprintf(of, "\n\n; Internal registers\n"); + + fprintf(of, "%s\tudata_ovr\t0x0000\n", ".registers"); + for(r = setFirstItem(section); r; r = setNextItem(section)) + fprintf(of, "%s\tres\t%d\n", r->name, r->size); + + free(rlist); +} @@ -489,7 +477,10 @@ char *pic16_processor_base_name(void) } -void checkAddReg(set **set, regs *reg) +/* + * return 1 if register wasn't found and added, 0 otherwise + */ +int checkAddReg(set **set, regs *reg) { regs *tmp; @@ -498,8 +489,12 @@ void checkAddReg(set **set, regs *reg) if(!strcmp(tmp->name, reg->name))break; } - if(!tmp) + if(!tmp) { addSet(set, reg); + return 1; + } + + return 0; } /*-----------------------------------------------------------------* @@ -523,9 +518,10 @@ void pic16_groupRegistersInSection(set *regset) checkAddReg(&pic16_fix_udata, reg); } else if(!reg->isFixed) { -// fprintf(stderr, "%s:%d adding symbol %s in relocatable udata section\n", -// __FILE__, __LINE__, reg->name); - checkAddReg(&pic16_rel_udata, reg); + if(reg->pc_type == PO_GPR_TEMP) + checkAddReg(&pic16_int_regs, reg); + else + checkAddReg(&pic16_rel_udata, reg); } } } diff --git a/src/pic16/device.h b/src/pic16/device.h index 5ec77986..d2bef36f 100644 --- a/src/pic16/device.h +++ b/src/pic16/device.h @@ -30,54 +30,11 @@ #ifndef __DEVICE_H__ #define __DEVICE_H__ -/* memRange - a structure to define a range of valid memory addresses - * - * The Memory of most PICs (and other micros) is a collection of - * disjoint chunks. The memRange structure will define the start - * and end address of one of these chunks. The memory map of a - * particular device is a collection of memRange struct's. - */ - -typedef struct memRange { - int start_address; /* first address in range */ - int end_address; /* last */ - int alias; /* bit mask defining how/if memory range is aliased - * e.g. alias = 0x80 means start_address is identical - * to the memory location at (0x80 | start_address) */ - int bank; /* PIC memory bank this range occupies */ - -} memRange; - -/* AssignedMemory - A structure to keep track of the memory that has been used. - * - * When a register gets assigned an address this struct is used to - * keep track of a few details about the register. There is one of - * these structures for each memory location in the device. - */ - -typedef struct AssignedMemory { - regs *reg; /* Pointer to the register (NULL if this is an invalid address) */ - int instance; /* the i'th byte of a multibyte register */ - int alias; /* Bit mapping of aliased addresses (see memRange) */ - int bank; /* Memory bank of this register */ - int isValid:1; /* True if the address is legal */ - int isSFR:1; /* True if the address is that of a Special Function reg */ - int isEmitted:1; /* True if the register has been written to a cBlock */ - -} AssignedMemory; - - -/* - * pic16_finalMapping - Dynamically allocated array that records the register assignments - */ - -//extern AssignedMemory *pic16_finalMapping; - -/* - * pic16_finalMappingSize - Size of register assignments that pic16_finalMapping can hold - */ - -//extern int pic16_finalMappingSize; +#if defined(__BORLANDC__) || defined(_MSC_VER) +#define STRCASECMP stricmp +#else +#define STRCASECMP strcasecmp +#endif #define PROCESSOR_NAMES 4 @@ -85,9 +42,6 @@ typedef struct AssignedMemory { typedef struct PIC16_device { char *name[PROCESSOR_NAMES];/* aliases for the processor name */ - memRange *ram; /* RAM memory map */ - memRange *sfr; /* SFR memory map */ - int maxRAMaddress; /* maximum value for a data address */ int bankMask; /* Bitmask that is ANDed with address to extract banking bits */ int RAMsize; /* size of Data RAM - VR 031120 */ @@ -107,11 +61,9 @@ typedef struct { int omit_configw; int omit_ivt; int leave_reset; - int enable_stack; int stack_model; } pic16_options_t; -#define USE_STACK (pic16_options.enable_stack) #define STACK_MODEL_SMALL (pic16_options.stack_model == 0) #define STACK_MODEL_LARGE (pic16_options.stack_model == 1) @@ -124,10 +76,9 @@ void pic16_assignConfigWordValue(int address, int value); int pic16_getConfigWord(int address); int pic16_isREGinBank(regs *reg, int bank); int pic16_REGallBanks(regs *reg); -void pic16_addMemRange(memRange *r, int type); void pic16_setMaxRAM(int size); -void checkAddReg(set **set, regs *reg); +int checkAddReg(set **set, regs *reg); #endif /* __DEVICE_H__ */ diff --git a/src/pic16/gen.c b/src/pic16/gen.c index e0cde477..7bf945e7 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -77,6 +77,11 @@ unsigned int pic16aopLiteral (value *val, int offset); const char *pic16_AopType(short type); static iCode *ifxForOp ( operand *op, iCode *ic ); +void pic16_pushpCodeOp(pCodeOp *pcop); +void pic16_poppCodeOp(pCodeOp *pcop); + + + #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) /* this is the down and dirty file with all kinds of @@ -88,12 +93,24 @@ static char *zero = "#0x00"; static char *one = "#0x01"; static char *spname = "sp"; + +/* + * Function return value policy (MSB-->LSB): + * 8 bits -> WREG + * 16 bits -> PRODL:WREG + * 24 bits -> PRODH:PRODL:WREG + * 32 bits -> FSR0L:PRODH:PRODL:WREG + * >32 bits -> on stack, and FSR0 points to the beginning + * + */ + + char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" }; //char *fReturn390[] = {"dpl","dph","dpx", "b","a" }; unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic16; -static char *accUse[] = {"a","b"}; +static char *accUse[] = {"WREG"}; //static short rbank = -1; @@ -186,15 +203,12 @@ void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, op } -void pic16_emitcomment (char *fmt, ...) +void pic16_emitpcomment (char *fmt, ...) { va_list ap; char lb[INITIAL_INLINEASM]; char *lbp = lb; - if(!pic16_debug_verbose) - return; - va_start(ap,fmt); lb[0] = ';'; @@ -495,6 +509,9 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) /* if it is on the stack or indirectly addressable */ /* space we need to assign either r0 or r1 to it */ if ((sym->onStack && !options.stack10bit) || sym->iaccess) { + + DEBUGpic16_emitcode("; ***", "sum->onStack || sym->iaccess"); + sym->aop = aop = newAsmop(0); aop->aopu.aop_ptr = getFreePtr(ic,&aop,result); aop->size = getSize(sym->type); @@ -564,7 +581,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) sym->aop = aop = newAsmop (AOP_CRY); aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); - //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); return aop; } /* if it is in direct space */ @@ -573,6 +590,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); return aop; } @@ -592,24 +610,29 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) /* in which case DPTR gets the address */ sym->aop = aop = newAsmop(AOP_PCODE); - aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0); - PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); - PCOI(aop->aopu.pcop)->index = 0; +/* change the next if to 1 to revert to good old immediate code */ + if(IN_CODESPACE(space)) { + aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0); + PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); + PCOI(aop->aopu.pcop)->index = 0; + } else { + /* try to allocate via direct register */ + aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), 0); +// aop->size = getSize( sym->type ); + } - DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", - __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const); + DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", + __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const); - pic16_allocDirReg (IC_LEFT(ic)); + pic16_allocDirReg (IC_LEFT(ic)); - aop->size = FPTRSIZE; -/* - DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); - sym->aop = aop = newAsmop(AOP_DPTR); - pic16_emitcode ("mov","dptr,#%s", sym->rname); - aop->size = getSize(sym->type); + if(IN_DIRSPACE( space )) + aop->size = PTRSIZE; + else if(IN_CODESPACE( space )) + aop->size = FPTRSIZE; + else aop->size = AOP_SIZE( IC_LEFT(ic) ); DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size); -*/ /* if it is in code space */ if (IN_CODESPACE(space)) @@ -624,48 +647,77 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) static asmop *aopForRemat (operand *op) // x symbol *sym) { symbol *sym = OP_SYMBOL(op); - iCode *ic = NULL; + iCode *ic = NULL, *oldic; asmop *aop = newAsmop(AOP_PCODE); int val = 0; int offset = 0; + int viaimmd=0; - ic = sym->rematiCode; - DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__); - if(IS_OP_POINTER(op)) { - DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); - } - for (;;) { - if (ic->op == '+') { - val += (int) operandLitValue(IC_RIGHT(ic)); - } else if (ic->op == '-') { - val -= (int) operandLitValue(IC_RIGHT(ic)); - } else - break; + ic = sym->rematiCode; + + DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__); - ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; - } + if(IS_OP_POINTER(op)) { + DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); + } + + for (;;) { + oldic = ic; + +// pic16_emitpcomment("ic: %s\n", printILine(ic)); + + if (ic->op == '+') { + val += (int) operandLitValue(IC_RIGHT(ic)); + } else if (ic->op == '-') { + val -= (int) operandLitValue(IC_RIGHT(ic)); + } else + break; + + ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; + } + + offset = OP_SYMBOL(IC_LEFT(ic))->offset; + + if(!op->isaddr)viaimmd++; else viaimmd=0; + +/* set the following if to 1 to revert to good old immediate code */ + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))) + || viaimmd) { + + pic16_emitpcomment("%s:%d immediate", __FILE__, __LINE__); + + aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val); - offset = OP_SYMBOL(IC_LEFT(ic))->offset; - aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val); #if 0 - PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); + PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); #else - PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op)); + PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op)); #endif - PCOI(aop->aopu.pcop)->index = val; - DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", - __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname, + PCOI(aop->aopu.pcop)->index = val; + } else { + pic16_emitpcomment("%s:%d dir", __FILE__, __LINE__); + + aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val); +// aop->size = AOP_SIZE( IC_LEFT(ic) ); + } + + + DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", + __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname, #if 0 - val, IS_PTR_CONST(operandType(op))); + val, IS_PTR_CONST(operandType(op))); #else - val, IS_CODEPTR(operandType(op))); + val, IS_CODEPTR(operandType(op))); #endif - // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic)))); +// DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic)))); - pic16_allocDirReg (IC_LEFT(ic)); + pic16_allocDirReg (IC_LEFT(ic)); + + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) )) + aop->code = 1; return aop; } @@ -798,7 +850,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) if (!op) return ; -// DEBUGpic16_emitcode(";","%d",__LINE__); +// DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__); /* if this a literal */ if (IS_OP_LITERAL(op)) { @@ -870,16 +922,22 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) return; } +#if 1 if (sym->accuse) { int i; aop = op->aop = sym->aop = newAsmop(AOP_ACC); aop->size = getSize(sym->type); - for ( i = 0 ; i < 2 ; i++ ) - aop->aopu.aop_str[i] = accUse[i]; + for ( i = 0 ; i < 1 ; i++ ) { + aop->aopu.aop_str[i] = accUse[i]; +// aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset); + } + fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name); DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size); return; } +#endif +#if 1 if (sym->ruonly ) { /* sym->aop = op->aop = aop = newAsmop(AOP_PCODE); @@ -898,7 +956,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) DEBUGpic16_emitcode(";","%d",__LINE__); return; } - +#endif /* else spill location */ if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) { /* force a new aop if sizes differ */ @@ -1158,7 +1216,9 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) case AOP_ACC: DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__); - return "AOP_accumulator_bug"; +// fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__); +// assert( 0 ); + return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug"; case AOP_LIT: sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset)); @@ -1204,14 +1264,16 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGetTempReg(void) { - pCodeOp *pcop; - pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { - PCOR(pcop)->r->wasUsed=1; - PCOR(pcop)->r->isFree=0; - } + pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + + /* push value on stack */ + pic16_pushpCodeOp( pcop ); + } return pcop; } @@ -1221,10 +1283,11 @@ pCodeOp *pic16_popGetTempReg(void) /*-----------------------------------------------------------------*/ void pic16_popReleaseTempReg(pCodeOp *pcop) { - - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) - PCOR(pcop)->r->isFree = 1; - + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + PCOR(pcop)->r->isFree = 1; + + pic16_poppCodeOp( pcop ); + } } /*-----------------------------------------------------------------*/ /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */ @@ -1259,7 +1322,7 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc) pcor->rIdx = pc->rIdx; pcor->r->wasUsed=1; - //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); +// DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); return PCOP(pcor); } @@ -1337,9 +1400,9 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset) //fprintf(stderr, "allocating new register -> %s\n", str); - DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset); +// DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset); } else { - DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset); +// DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset); } PCOR(pcop)->instance = offset; @@ -1391,9 +1454,9 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset) /*--------------------------------------------------------------------------------.-*/ pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst) { - pCodeOpReg2 *pcop2; + pCodeOpReg2 *pcop2; - pcop2 = (pCodeOpReg2 *) src; + pcop2 = (pCodeOpReg2 *)src; pcop2->pcop2 = dst; return PCOP(pcop2); @@ -1428,17 +1491,16 @@ pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc) pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) { //char *s = buffer ; - //char *rs; - - pCodeOp *pcop; + char *rs; + pCodeOp *pcop; //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* offset is greater than size then zero */ - if (offset > (aop->size - 1) && - aop->type != AOP_LIT) - return NULL; //zero; +// if (offset > (aop->size - 1) && +// aop->type != AOP_LIT) +// return NULL; //zero; /* depending on type */ switch (aop->type) { @@ -1447,15 +1509,42 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) case AOP_R1: case AOP_DPTR: case AOP_DPTR2: - case AOP_ACC: DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type)); fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type)); + assert( 0 ); return NULL; - + + + case AOP_IMMD: DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__); return pic16_popGetImmd(aop->aopu.aop_immd,offset,0); + case AOP_ACC: + fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]); + + int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx; + + DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__); + + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx); + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; +// rs = aop->aopu.aop_reg[offset]->name; +// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs); + return pcop; + + + return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset); +// return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); + +// assert( 0 ); + case AOP_DIR: DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__); return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset); @@ -1465,6 +1554,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) int rIdx = aop->aopu.aop_reg[offset]->rIdx; DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__); + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcop)->rIdx = rIdx; PCOR(pcop)->r = pic16_regWithIdx(rIdx); @@ -1473,8 +1563,8 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) PCOR(pcop)->instance = offset; pcop->type = PCOR(pcop)->r->pc_type; - //rs = aop->aopu.aop_reg[offset]->name; - //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs); + rs = aop->aopu.aop_reg[offset]->name; + DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs); return pcop; } @@ -1506,11 +1596,20 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) */ case AOP_PCODE: - DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop), + DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop), __LINE__, - ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name")); + ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset); pcop = pic16_pCodeOpCopy(aop->aopu.pcop); +#if 1 + switch( aop->aopu.pcop->type ) { + case PO_DIR: PCOR(pcop)->instance = offset; break; + case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break; + default: + assert( 0 ); /* should never reach here */; + } +#else PCOI(pcop)->offset = offset; +#endif return pcop; } @@ -1769,14 +1868,16 @@ static void mov2w (asmop *aop, int offset) } -void pic16_pushpCodeOpReg(pCodeOpReg *pcop) +/* push pcop into stack */ +void pic16_pushpCodeOp(pCodeOp *pcop) { - pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pcop, &pic16_pc_postdec1, 0)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1))); } -void pic16_poppCodeOpReg(pCodeOpReg *pcop) +/* pop pcop from stack */ +void pic16_poppCodeOp(pCodeOp *pcop) { - pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, pcop, 0)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop)); } @@ -2279,46 +2380,109 @@ static void pushSide(operand * oper, int size) #endif } +void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src) +{ +// (AOP(left)->aopu.pcop->type == PO_DIR)? + + if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) { + pic16_emitpcode(POC_MOVFW, src); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + src, pic16_popGet(AOP(op), offset))); + } +} + + /*-----------------------------------------------------------------*/ -/* assignResultValue - */ +/* assignResultValue - assign results to oper, rescall==1 is */ +/* called from genCall() or genPCall() */ /*-----------------------------------------------------------------*/ -static void assignResultValue(operand * oper) +static void assignResultValue(operand * oper, int rescall) { int size = AOP_SIZE(oper); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL); - if(!GpsuedoStkPtr) { -// DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr); - /* The last byte in the assignment is in W */ - size--; - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); - GpsuedoStkPtr++; - } - - while (size--) { -// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); -// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + if(rescall) { + /* assign result from a call/pcall function() */ -#if STACK_SUPPORT - if(USE_STACK) { - popaopidx(AOP(oper), size, GpsuedoStkPtr); + /* function results are stored in a special order, + * see top of file with Function return policy, or manual */ + + if(size <= 4) { + /* 8-bits, result in WREG */ + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0)); + + if(size>1) { + /* 16-bits, result in PRODL:WREG */ + pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(oper), 1))); + } + + if(size>2) { + /* 24-bits, result in PRODH:PRODL:WREG */ + pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodl)); + +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(oper), 2))); + } + + if(size>3) { + /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */ + pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_prodl)); + +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popGet(AOP(oper), 3))); + } } else { - pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr)); + /* >32-bits, result on stack, and FSR0 points to beginning. + * Fix stack when done */ + + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + popaopidx(AOP(oper), size, GpsuedoStkPtr); + GpsuedoStkPtr++; + } + + /* fix stack */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) )); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + if(STACK_MODEL_LARGE) { + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + } + } + } else { + if(!GpsuedoStkPtr) { +// DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr); + /* The last byte in the assignment is in W */ + size--; + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); + GpsuedoStkPtr++; } -#else - pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr)); -#endif /* STACK_SUPPORT */ - GpsuedoStkPtr++; + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + popaopidx(AOP(oper), size, GpsuedoStkPtr); + GpsuedoStkPtr++; + +#if 0 #if STACK_SUPPORT if(!USE_STACK) pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); #else pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); +#endif #endif + } } } @@ -2573,16 +2737,8 @@ static void genCall (iCode *ic) * register. The last byte of the last parameter is * passed in W. */ -#if STACK_SUPPORT - if(USE_STACK) { - pushw(); - --psuedoStkPtr; // sanity check - } else { - pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr)); - } -#else - pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr)); -#endif /* STACK_SUPPORT */ + pushw(); + --psuedoStkPtr; // sanity check } firstTimeThruLoop=0; @@ -2611,7 +2767,7 @@ static void genCall (iCode *ic) pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + assignResultValue(IC_RESULT(ic), 1); DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, pic16_AopType(AOP_TYPE(IC_RESULT(ic)))); @@ -2619,8 +2775,7 @@ static void genCall (iCode *ic) pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); } -#if STACK_SUPPORT - if(USE_STACK && stackParms>0) { + if(stackParms>0) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms)); pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); if(STACK_MODEL_LARGE) { @@ -2628,7 +2783,6 @@ static void genCall (iCode *ic) pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); } } -#endif /* adjust the stack for parameters if required */ // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes); @@ -2734,7 +2888,7 @@ static void genPcall (iCode *ic) pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + assignResultValue(IC_RESULT(ic), 1); pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } @@ -2826,6 +2980,42 @@ static void genFunction (iCode *ic) max_key=0; GpsuedoStkPtr=0; _G.nRegsSaved = 0; + + ftype = operandType(IC_LEFT(ic)); + + if(/*!IFFUNC_ISNAKED(ftype) &&*/ IFFUNC_ISISR(ftype)) { + /* create an absolute section at the interrupt vector: + * that is 0x0008 for interrupt 1, 0x0018 interrupt 2 */ + int ivec; + symbol *asym; + char asymname[128]; + + { + int i; + + sym = OP_SYMBOL( IC_LEFT(ic)); + for(i=1;i<=2;i++) + if(STRCASECMP(interrupts[i]->name, sym->name))break; + + if(i>2) { + fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n", + __FILE__, __LINE__, sym->name); + exit(-1); + } + ivec = i; + } + sprintf(asymname, "ivec_%s", sym->name); + asym = newSymbol(asymname, 0); + pic16_emitcode(";","-----------------------------------------"); + pic16_emitcode(";"," interrupt vector %d for function %s", ivec, sym->name); + pic16_emitcode(";","-----------------------------------------"); + pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(moduleName, asym->name)); + pic16_emitpcode(POC_GOTO, pic16_popGetWithString( sym->rname )); + + pic16_pBlockConvert2Absolute(pb); + } + + /* create the function header */ pic16_emitcode(";","-----------------------------------------"); pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); @@ -2845,49 +3035,42 @@ static void genFunction (iCode *ic) } - ftype = operandType(IC_LEFT(ic)); if(IFFUNC_ISNAKED(ftype)) { DEBUGpic16_emitcode("; ***", "_naked function, no prologue"); return; } - /* if critical function then turn interrupts off */ if (IFFUNC_ISCRITICAL(ftype)) pic16_emitcode("clr","ea"); - /* here we need to generate the equates for the - * register bank if required */ -#if 0 - if (FUNC_REGBANK(ftype) != rbank) { - int i ; - - rbank = FUNC_REGBANK(ftype); - for ( i = 0 ; i < pic16_nRegs ; i++ ) { - if (strcmp(regspic16[i].base,"0") == 0) - pic16_emitcode("","%s = 0x%02x", - regspic16[i].dname, - 8*rbank+regspic16[i].offset); - else - pic16_emitcode ("","%s = %s + 0x%02x", - regspic16[i].dname, - regspic16[i].base, - *rbank+regspic16[i].offset); - } - } -#endif - /* if this is an interrupt service routine then * save acc, b, dpl, dph */ if (IFFUNC_ISISR(sym->type)) { + int i; + /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH */ + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h )); + + +#if 0 + /* VR -- this is the old code which clears STATUS register for + * the ISR routine. Why? */ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave)); pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status)); pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status)); pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave)); +#endif pic16_pBlockConvert2ISR(pb); -#if 0 + +#if 0 if (!inExcludeList("acc")) pic16_emitcode ("push","acc"); if (!inExcludeList("b")) @@ -2896,57 +3079,29 @@ static void genFunction (iCode *ic) pic16_emitcode ("push","dpl"); if (!inExcludeList("dph")) pic16_emitcode ("push","dph"); - - if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) { - pic16_emitcode ("push", "dpx"); - - /* Make sure we're using standard DPTR */ - pic16_emitcode ("push", "dps"); - pic16_emitcode ("mov", "dps, #0x00"); - if (options.stack10bit) { - /* This ISR could conceivably use DPTR2. Better save it. */ - pic16_emitcode ("push", "dpl1"); - pic16_emitcode ("push", "dph1"); - pic16_emitcode ("push", "dpx1"); - } - } +#endif - /* if this isr has no bank i.e. is going to - * run with bank 0 , then we need to save more - * registers :-) */ - if (!FUNC_REGBANK(sym->type)) { - - /* if this function does not call any other - * function then we can be economical and - * save only those registers that are used */ - if (! IFFUNC_HASFCALL(sym->type)) { - int i; - - /* if any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname); - } + /* if any registers used */ + if (sym->regsUsed) { + /* save the registers used */ + DEBUGpic16_emitcode("; **", "Saving used registers in stack"); + for ( i = 0 ; i < sym->regsUsed->size ; i++) { + if (bitVectBitValue(sym->regsUsed,i)) { +// fprintf(stderr, "%s:%d function %s uses register %s\n", +// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, +// pic16_regWithIdx(i)->name); + + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); + _G.nRegsSaved++; } - - } else { - /* this function has a function call cannot - * determines register usage so we will have the - * entire bank */ - saverbank(0,ic,FALSE); - } + } } -#endif } else { -#if STACK_SUPPORT /* emit code to setup stack frame if user enabled, * and function is not main() */ // fprintf(stderr, "function name: %s\n", sym->name); - if(USE_STACK && strcmp(sym->name, "main")) { + if(strcmp(sym->name, "main")) { if(!options.ommitFramePtr || sym->regsUsed) { /* setup the stack frame */ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0)); @@ -2955,7 +3110,6 @@ static void genFunction (iCode *ic) pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0)); } } -#endif /* if callee-save to be used for this function * then save the registers being used in this function */ @@ -2965,11 +3119,7 @@ static void genFunction (iCode *ic) // fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed); /* if any registers used */ - if (sym->regsUsed -#if STACK_SUPPORT - && USE_STACK -#endif - ) { + if (sym->regsUsed) { /* save the registers used */ DEBUGpic16_emitcode("; **", "Saving used registers in stack"); for ( i = 0 ; i < sym->regsUsed->size ; i++) { @@ -2978,7 +3128,7 @@ static void genFunction (iCode *ic) // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, // pic16_regWithIdx(i)->name); - pic16_pushpCodeOpReg( PCOR(pic16_popRegFromIdx(i) )); + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), // &pic16_pc_postdec1, 0)); @@ -3084,101 +3234,68 @@ static void genEndFunction (iCode *ic) if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) pic16_emitcode ("pop","psw"); - if (IFFUNC_ISISR(sym->type)) { + if (IFFUNC_ISISR(sym->type)) { - /* now we need to restore the registers */ - /* if this isr has no bank i.e. is going to - run with bank 0 , then we need to save more - registers :-) */ - if (!FUNC_REGBANK(sym->type)) { - - /* if this function does not call any other - function then we can be economical and - save only those registers that are used */ - if (! IFFUNC_HASFCALL(sym->type)) { - int i; + /* now we need to restore the registers */ /* if any registers used */ if (sym->regsUsed) { - /* save the registers used */ - for ( i = sym->regsUsed->size ; i >= 0 ; i--) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname); - } - } - - } else { - /* this function has a function call cannot - determines register usage so we will have the - entire bank */ - unsaverbank(0,ic,FALSE); - } - } -#if 0 - if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) - { - if (options.stack10bit) - { - pic16_emitcode ("pop", "dpx1"); - pic16_emitcode ("pop", "dph1"); - pic16_emitcode ("pop", "dpl1"); - } - pic16_emitcode ("pop", "dps"); - pic16_emitcode ("pop", "dpx"); - } - if (!inExcludeList("dph")) - pic16_emitcode ("pop","dph"); - if (!inExcludeList("dpl")) - pic16_emitcode ("pop","dpl"); - if (!inExcludeList("b")) - pic16_emitcode ("pop","b"); - if (!inExcludeList("acc")) - pic16_emitcode ("pop","acc"); - - if (IFFUNC_ISCRITICAL(sym->type)) - pic16_emitcode("setb","ea"); -#endif + int i; - /* if debug then send end of function */ -/* if (options.debug && currFunc) { */ - if (currFunc) { - _G.debugLine = 1; - pic16_emitcode(";","C$%s$%d$%d$%d ==.", - FileBaseName(ic->filename),currFunc->lastLine, - ic->level,ic->block); - if (IS_STATIC(currFunc->etype)) - pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); - else - pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name); - _G.debugLine = 0; - } + /* restore registers used */ + DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); + for ( i = sym->regsUsed->size; i >= 0; i--) { + if (bitVectBitValue(sym->regsUsed,i)) { +// fprintf(stderr, "%s:%d function %s uses register %s\n", +// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, +// pic16_regWithIdx(i)->name); + + pic16_emitpcode(POC_MOVFF, pic16_popCombine2( + &pic16_pc_preinc1, + PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0)); + } + } + } + + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l)); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg )); -// pic16_emitcode ("reti",""); - - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave)); + /* if debug then send end of function */ +/* if (options.debug && currFunc) */ + if (currFunc) { + _G.debugLine = 1; + pic16_emitcode(";","C$%s$%d$%d$%d ==.", + FileBaseName(ic->filename),currFunc->lastLine, + ic->level,ic->block); + if (IS_STATIC(currFunc->etype)) + pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); + else + pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name); + _G.debugLine = 0; + } + #if 0 - pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1)); + pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status)); + pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status)); + pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave)); + pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave)); #endif - pic16_emitpcodeNULLop(POC_RETFIE); - - } - else { - if (IFFUNC_ISCRITICAL(sym->type)) - pic16_emitcode("setb","ea"); + pic16_emitpcodeNULLop(POC_RETFIE); + } + else { + if (IFFUNC_ISCRITICAL(sym->type)) + pic16_emitcode("setb","ea"); /* if any registers used */ - if (sym->regsUsed -#if STACK_SUPPORT - && USE_STACK -#endif - ) { + if (sym->regsUsed) { int i; /* save the registers used */ DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); @@ -3209,21 +3326,19 @@ static void genEndFunction (iCode *ic) _G.debugLine = 0; } -#if STACK_SUPPORT /* insert code to restore stack frame, if user enabled it * and function is not main() */ - if(USE_STACK && strcmp(sym->name, "main")) { + if(strcmp(sym->name, "main")) { if(!options.ommitFramePtr || sym->regsUsed) { /* restore stack frame */ if(STACK_MODEL_LARGE) pic16_emitpcode(POC_MOVFF, - pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h, 0)); + pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0)); pic16_emitpcode(POC_MOVFF, - pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l, 0)); + pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0)); } } -#endif pic16_emitcode ("return",""); pic16_emitpcodeNULLop(POC_RETURN); @@ -3234,83 +3349,151 @@ static void genEndFunction (iCode *ic) } + +void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest) +{ +// (AOP(left)->aopu.pcop->type == PO_DIR)? + + if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); + pic16_emitpcode(POC_MOVWF, dest); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popGet(AOP(op), offset), dest)); + } +} + /*-----------------------------------------------------------------*/ /* genRet - generate code for return statement */ /*-----------------------------------------------------------------*/ static void genRet (iCode *ic) { - int size,offset = 0 , pushed = 0; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if we have no return value then - just generate the "ret" */ - if (!IC_LEFT(ic)) - goto jumpret; - - /* we have something to return then - move the return value into place */ - pic16_aopOp(IC_LEFT(ic),ic,FALSE); - size = AOP_SIZE(IC_LEFT(ic)); - - while (size--) { - char *l ; - if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { - /* #NOCHANGE */ - l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, - FALSE,TRUE); - pic16_emitcode("push","%s",l); - pushed++; - } else { - DEBUGpic16_emitcode(";", "%d", __LINE__); - l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, - FALSE,FALSE); - DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l); - if (strcmp(fReturn[offset],l)) { - if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) || - ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - }else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - } - if(size) { - pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr)); - } - offset++; - } - } - } + int size; + operand *left; - if (pushed) { - while(pushed) { - pushed--; - if (strcmp(fReturn[pushed],"a")) - pic16_emitcode("pop",fReturn[pushed]); - else - pic16_emitcode("pop","acc"); - } - } - pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); - - jumpret: - /* generate a jump to the return label - if the next is not the return statement */ - if (!(ic->next && ic->next->op == LABEL && - IC_LABEL(ic->next) == returnLabel)) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if we have no return value then + * just generate the "ret" */ - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key)); - pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); - } + if (!IC_LEFT(ic)) + goto jumpret; -} + /* we have something to return then + * move the return value into place */ + pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); + size = AOP_SIZE(IC_LEFT(ic)); + + if(size <= 4) { + if(size>3) { + pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l))); + } + if(size>2) { + pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh))); + } + if(size>1) { + pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl))); + } -/*-----------------------------------------------------------------*/ -/* genLabel - generates a label */ -/*-----------------------------------------------------------------*/ -static void genLabel (iCode *ic) -{ - /* special case never generate */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (IC_LABEL(ic) == entryLabel) + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); + +// pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg))); + + } else { + /* >32-bits, setup stack and FSR0 */ + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) ); + +// popaopidx(AOP(oper), size, GpseudoStkPtr); + GpsuedoStkPtr++; + } + + /* setup FSR0 */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l))); + + if(STACK_MODEL_LARGE) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h))); + } else { + pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) ); + } + } + +#if 0 + /* old code, left here for reference -- VR */ + while (size--) { + char *l ; + + if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { + /* #NOCHANGE */ + l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE); + pic16_emitpcomment("push %s",l); + pushed++; + } else { + DEBUGpic16_emitcode(";", "%d", __LINE__); + l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE); + DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l); + + if (strcmp(fReturn[offset],l)) { + if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) + || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + } else { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + } + + if(size) { + pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr)); + } + offset++; + } + } + } + + if (pushed) { + while(pushed) { + pushed--; + if (strcmp(fReturn[pushed],"a")) + pic16_emitcode("pop",fReturn[pushed]); + else + pic16_emitcode("pop","acc"); + } + } +#endif + + + pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); + +jumpret: + /* generate a jump to the return label + * if the next is not the return statement */ + if (!(ic->next && ic->next->op == LABEL + && IC_LABEL(ic->next) == returnLabel)) { + + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key)); + pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); + } +} + +/*-----------------------------------------------------------------*/ +/* genLabel - generates a label */ +/*-----------------------------------------------------------------*/ +static void genLabel (iCode *ic) +{ + /* special case never generate */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (IC_LABEL(ic) == entryLabel) return ; pic16_emitpLabel(IC_LABEL(ic)->key); @@ -3375,30 +3558,17 @@ static void genMultOneByte (operand *left, if(size == 1) { if (AOP_TYPE(right) == AOP_LIT){ - pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s", + pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", pic16_aopGet(AOP(right),0,FALSE,FALSE), pic16_aopGet(AOP(left),0,FALSE,FALSE), pic16_aopGet(AOP(result),0,FALSE,FALSE)); - pic16_emitcode("call","genMultLit"); } else { - pic16_emitcode("multiply ","variable :%s by variable %s and store in %s", + pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", pic16_aopGet(AOP(right),0,FALSE,FALSE), pic16_aopGet(AOP(left),0,FALSE,FALSE), pic16_aopGet(AOP(result),0,FALSE,FALSE)); - pic16_emitcode("call","pic16_genMult8X8_8"); - } pic16_genMult8X8_8 (left, right,result); - - - /* signed or unsigned */ - //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE)); - //l = pic16_aopGet(AOP(left),0,FALSE,FALSE); - //MOVA(l); - //pic16_emitcode("mul","ab"); - /* if result size = 1, mul signed = mul unsigned */ - //pic16_aopPut(AOP(result),"a",0); - } else { // (size > 1) pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", @@ -3488,7 +3658,7 @@ static void genMult (iCode *ic) pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor."); /* should have been converted to function call */ - //assert(0) ; + assert(0) ; release : pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); @@ -6338,19 +6508,22 @@ static void genInline (iCode *ic) char *buffer, *bp, *bp1; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + _G.inLine += (!options.asmpeep); buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); strcpy(buffer,IC_INLINE(ic)); +// fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer); + /* emit each line as a code */ while (*bp) { if (*bp == '\n') { *bp++ = '\0'; - + if(*bp1) #if 0 - pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process #else pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1)); #endif @@ -6369,13 +6542,15 @@ static void genInline (iCode *ic) if ((bp1 != bp) && *bp1) #if 0 - pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process #else pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1)); #endif - Safe_free(buffer); - _G.inLine -= (!options.asmpeep); + + Safe_free(buffer); + + _G.inLine -= (!options.asmpeep); } /*-----------------------------------------------------------------*/ @@ -6468,6 +6643,10 @@ static void genRLC (iCode *ic) pic16_freeAsmop(result,NULL,ic,TRUE); } + +/* gpasm can get the highest order bit with HIGH/UPPER + * so the following probably is not needed -- VR */ + /*-----------------------------------------------------------------*/ /* genGetHbit - generates code get highest order bit */ /*-----------------------------------------------------------------*/ @@ -6542,78 +6721,83 @@ static void AccRol (int shCount) /*-----------------------------------------------------------------*/ static void AccLsh (int shCount) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - switch(shCount){ - case 0 : + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + switch(shCount){ + case 0 : return; - break; - case 1 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 2 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 3 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 4 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 5 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 6 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 7 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - } - pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount])); + break; + case 1 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 2 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 3 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 4 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 5 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 6 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 7 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + } + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount])); } /*-----------------------------------------------------------------*/ /* AccRsh - right shift accumulator by known count */ /*-----------------------------------------------------------------*/ -static void AccRsh (int shCount) +static void AccRsh (int shCount, int andmask) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - switch(shCount){ - case 0 : - return; - break; - case 1 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 2 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 3 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 4 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 5 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 6 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 7 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - } - pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount])); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + switch(shCount){ + case 0 : + return; break; + case 1 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); +// andmask = 0; /* no need */ + break; + case 2 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); +// andmask = 0; /* no need */ + break; + case 3 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 4 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 5 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 6 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 7 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + } + + if(andmask) + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount])); + else + DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__); } #if 0 @@ -7254,7 +7438,7 @@ static void shiftRLeftOrResult (operand *left, int offl, pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl)); /* shift right accumulator */ - AccRsh(shCount); + AccRsh(shCount, 1); /* or with result */ /* back to result */ pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr)); @@ -8208,49 +8392,53 @@ static void genUnpackBits (operand *result, char *rname, int ptype) sym_link *etype; int offset = 0 ; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - etype = getSpec(operandType(result)); - - /* read the first byte */ - switch (ptype) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + etype = getSpec(operandType(result)); - case POINTER: - case IPOINTER: - pic16_emitcode("mov","a,@%s",rname); - break; - - case PPOINTER: - pic16_emitcode("movx","a,@%s",rname); - break; + /* read the first byte */ + switch (ptype) { + case POINTER: + case IPOINTER: + case PPOINTER: + case FPOINTER: + case GPOINTER: + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + break; + case CPOINTER: + pic16_emitcode("clr","a"); + pic16_emitcode("movc","a","@a+dptr"); + break; + } - case FPOINTER: - pic16_emitcode("movx","a,@dptr"); - break; - case CPOINTER: - pic16_emitcode("clr","a"); - pic16_emitcode("movc","a","@a+dptr"); - break; + /* if we have bitdisplacement then it fits */ + /* into this byte completely or if length is */ + /* less than a byte */ + if ((shCnt = SPEC_BSTR(etype)) || + (SPEC_BLEN(etype) <= 8)) { - case GPOINTER: - pic16_emitcode("lcall","__gptrget"); - break; - } + /* shift right acc */ + AccRsh(shCnt, 0); - /* if we have bitdisplacement then it fits */ - /* into this byte completely or if length is */ - /* less than a byte */ - if ((shCnt = SPEC_BSTR(etype)) || - (SPEC_BLEN(etype) <= 8)) { + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ])); - /* shift right acc */ - AccRsh(shCnt); +/* VR -- normally I would use the following, but since we use the hack, + * to avoid the masking from AccRsh, why not mask it right now? */ - pic16_emitcode("anl","a,#0x%02x", - ((unsigned char) -1)>>(8 - SPEC_BLEN(etype))); - pic16_aopPut(AOP(result),"a",offset); - return ; - } +/* + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype)))); +*/ + + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + return ; + } + + + + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); /* bit field did not fit in a byte */ rlen = SPEC_BLEN(etype) - 8; @@ -8304,42 +8492,79 @@ static void genUnpackBits (operand *result, char *rname, int ptype) return ; } -#if 0 -/*-----------------------------------------------------------------*/ -/* genDataPointerGet - generates code when ptr offset is known */ -/*-----------------------------------------------------------------*/ -static void genDataPointerGet (operand *left, - operand *result, - iCode *ic) + +static void genDataPointerGet(operand *left, + operand *result, + iCode *ic) { - int size , offset = 0; + int size, offset = 0, leoffset=0 ; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(result, ic, FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + size = AOP_SIZE(result); +// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); - /* optimization - most of the time, left and result are the same - * address, but different types. for the pic code, we could omit - * the following - */ +#if 0 + /* The following tests may save a redudant movff instruction when + * accessing unions */ + + /* if they are the same */ + if (operandsEqu (left, result)) { + DEBUGpic16_emitcode("; ***", "left and result operands are equ/same"); + goto release; + } - pic16_aopOp(result,ic,TRUE); + /* if they are the same registers */ + if (pic16_sameRegs(AOP(left),AOP(result))) { + DEBUGpic16_emitcode("; ***", "left and result registers are same"); + goto release; + } +#endif - DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); +#if 0 + if ( AOP_TYPE(left) == AOP_PCODE) { + fprintf(stderr,"genDataPointerGet %s, %d\n", + AOP(left)->aopu.pcop->name, + (AOP(left)->aopu.pcop->type == PO_DIR)? + PCOR(AOP(left)->aopu.pcop)->instance: + PCOI(AOP(left)->aopu.pcop)->offset); + } +#endif - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); + if(AOP(left)->aopu.pcop->type == PO_DIR) + leoffset=PCOR(AOP(left)->aopu.pcop)->instance; - size = AOP_SIZE(result); + DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); - while (size--) { - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - offset++; - } + while (size--) { + DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset); + + if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE + || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) { + mov2w(AOP(left), leoffset); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popGet(AOP(left), leoffset), + pic16_popGet(AOP(result), offset))); + } - pic16_freeAsmop(left,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); + offset++; + leoffset++; + } + +//release: + pic16_freeAsmop(result,NULL,ic,TRUE); } -#endif + +void pic16_loadFSR0(operand *op) +{ + pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); +} + + /*-----------------------------------------------------------------*/ /* genNearPointerGet - pic16_emitcode for near pointer fetch */ /*-----------------------------------------------------------------*/ @@ -8349,68 +8574,79 @@ static void genNearPointerGet (operand *left, { asmop *aop = NULL; //regs *preg = NULL ; - char *rname ; sym_link *rtype, *retype; sym_link *ltype = operandType(left); - //char buffer[80]; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - rtype = operandType(result); - retype= getSpec(rtype); - - pic16_aopOp(left,ic,FALSE); + rtype = operandType(result); + retype= getSpec(rtype); - /* if left is rematerialisable and - result is not bit variable type and - the left is pointer to data space i.e - lower 128 bytes of space */ - if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD && - !IS_BITVAR(retype) && - DCL_TYPE(ltype) == POINTER) { - //genDataPointerGet (left,result,ic); - return ; - } + pic16_aopOp(left,ic,FALSE); + + /* if left is rematerialisable and + * result is not bit variable type and + * the left is pointer to data space i.e + * lower 128 bytes of space */ + if (AOP_TYPE(left) == AOP_PCODE + && !IS_BITFIELD(retype) + && DCL_TYPE(ltype) == POINTER) { + + genDataPointerGet (left,result,ic); + pic16_freeAsmop(left, NULL, ic, TRUE); + return ; + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(left))) { - /* otherwise get a free pointer register */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -/* - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - pic16_emitcode("mov","%s,%s", - preg->name, - pic16_aopGet(AOP(left),0,FALSE,TRUE)); - rname = preg->name ; -*/ - rname ="BAD"; - } else - rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); + * then don't need anything more */ + if (!AOP_INPREG(AOP(left))) { + /* otherwise get a free pointer register */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* VR -- the whole concept is to load FSR0 with the address of the symbol */ + pic16_loadFSR0( left ); + } +// else +// rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); pic16_aopOp (result,ic,FALSE); /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genUnpackBits (result,rname,POINTER); + genUnpackBits (result, NULL, POINTER); else { /* we have can just get the values */ int size = AOP_SIZE(result); - int offset = 0 ; + int offset = 0; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); + + /* fsr0 is loaded already -- VR */ +// pic16_loadFSR0( left ); + +// pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); +// pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); while(size--) { - pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); + + if(size) { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), + pic16_popGet(AOP(result), offset++))); + } else { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), + pic16_popGet(AOP(result), offset++))); + } + } +#if 0 +// pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0)); +// pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); if(size) pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0)); - } +#endif /* while (size--) { if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { @@ -8444,9 +8680,9 @@ static void genNearPointerGet (operand *left, !OP_SYMBOL(left)->remat && ( OP_SYMBOL(left)->liveTo > ic->seq || ic->depth )) { - int size = AOP_SIZE(result) - 1; - while (size--) - pic16_emitcode("dec","%s",rname); +// int size = AOP_SIZE(result) - 1; +// while (size--) +// pic16_emitcode("dec","%s",rname); } } @@ -8644,8 +8880,8 @@ static void genCodePointerGet (operand *left, static void genGenPointerGet (operand *left, operand *result, iCode *ic) { - int size, offset, lit; - sym_link *retype = getSpec(operandType(result)); + int size, offset, lit; + sym_link *retype = getSpec(operandType(result)); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(left,ic,FALSE); @@ -8659,6 +8895,9 @@ static void genGenPointerGet (operand *left, lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit); // load FSR0 from immediate pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit))); + +// pic16_loadFSR0( left ); + offset = 0; while(size--) { if(size) { @@ -8837,71 +9076,83 @@ static void genPackBits (sym_link *etype , operand *right , char *rname, int p_type) { - int shCount = 0 ; - int offset = 0 ; - int rLen = 0 ; - int blen, bstr ; - char *l ; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); - - l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - - /* if the bit lenth is less than or */ - /* it exactly fits a byte then */ - if (SPEC_BLEN(etype) <= 8 ) { - shCount = SPEC_BSTR(etype) ; + int shCnt = 0 ; + int offset = 0 ; + int rLen = 0 ; + int blen, bstr ; + char *l ; - /* shift left acc */ - AccLsh(shCount); - - if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + blen = SPEC_BLEN(etype); + bstr = SPEC_BSTR(etype); + if(AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0)); + offset++; + } else + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); - switch (p_type) { - case POINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("mov","a,@%s",rname); - break; +/* l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE); + MOVA(l); +*/ + /* if the bit lenth is less than or */ + /* it exactly fits a byte then */ + if((shCnt=SPEC_BSTR(etype)) + || SPEC_BLEN(etype) <= 8 ) { + + /* shift left acc */ + AccLsh(shCnt); + + /* using PRODL as a temporary register here */ + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); + + switch (p_type) { + case FPOINTER: + case POINTER: + case GPOINTER: + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); +// pic16_emitcode ("mov","b,a"); +// pic16_emitcode("mov","a,@%s",rname); + break; + } +#if 1 + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (unsigned char)((unsigned char)(0xff << (blen+bstr)) | + (unsigned char)(0xff >> (8-bstr))) )); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); +#endif - case FPOINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("movx","a,@dptr"); - break; +#if 0 + pic16_emitcode ("anl","a,#0x%02x",(unsigned char) + ((unsigned char)(0xFF << (blen+bstr)) | + (unsigned char)(0xFF >> (8-bstr)) ) ); + pic16_emitcode ("orl","a,b"); + if (p_type == GPOINTER) + pic16_emitcode("pop","b"); - case GPOINTER: - pic16_emitcode ("push","b"); - pic16_emitcode ("push","acc"); - pic16_emitcode ("lcall","__gptrget"); - pic16_emitcode ("pop","b"); - break; - } + + switch (p_type) { + case POINTER: + pic16_emitcode("mov","@%s,a",rname); + break; + case FPOINTER: + pic16_emitcode("movx","@dptr,a"); + break; + case GPOINTER: + DEBUGpic16_emitcode(";lcall","__gptrput"); + break; + } +#endif - pic16_emitcode ("anl","a,#0x%02x",(unsigned char) - ((unsigned char)(0xFF << (blen+bstr)) | - (unsigned char)(0xFF >> (8-bstr)) ) ); - pic16_emitcode ("orl","a,b"); - if (p_type == GPOINTER) - pic16_emitcode("pop","b"); - } - } + return; + } - switch (p_type) { - case POINTER: - pic16_emitcode("mov","@%s,a",rname); - break; - case FPOINTER: - pic16_emitcode("movx","@dptr,a"); - break; + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); - case GPOINTER: - DEBUGpic16_emitcode(";lcall","__gptrput"); - break; - } /* if we r done */ if ( SPEC_BLEN(etype) <= 8 ) @@ -8910,6 +9161,8 @@ static void genPackBits (sym_link *etype , pic16_emitcode("inc","%s",rname); rLen = SPEC_BLEN(etype) ; + + /* now generate for lengths greater than one byte */ while (1) { @@ -8994,65 +9247,53 @@ static void genDataPointerSet(operand *right, operand *result, iCode *ic) { - int size, offset = 0 ; - char *l, buffer[256]; + int size, offset = 0, resoffset=0 ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(right,ic,FALSE); - - l = pic16_aopGet(AOP(result),0,FALSE,TRUE); + size = AOP_SIZE(right); -/* + fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); + +#if 1 if ( AOP_TYPE(result) == AOP_PCODE) { fprintf(stderr,"genDataPointerSet %s, %d\n", AOP(result)->aopu.pcop->name, + (AOP(result)->aopu.pcop->type == PO_DIR)? + PCOR(AOP(result)->aopu.pcop)->instance: PCOI(AOP(result)->aopu.pcop)->offset); } -*/ - - // tsd, was l+1 - the underline `_' prefix was being stripped - while (size--) { - if (offset) { - sprintf(buffer,"(%s + %d)",l,offset); - fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer); - } else - sprintf(buffer,"%s",l); - - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = lit >> (8*offset); - if(lit&0xff) { - pic16_emitcode("movlw","%d",lit); - pic16_emitcode("movwf","%s",buffer); - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); - //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); +#endif - } else { - pic16_emitcode("clrf","%s",buffer); - //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer)); - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - } - }else { - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s",buffer); + if(AOP(result)->aopu.pcop->type == PO_DIR) + resoffset=PCOR(AOP(result)->aopu.pcop)->instance; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + while (size--) { + if (AOP_TYPE(right) == AOP_LIT) { + unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); + lit = lit >> (8*offset); + if(lit&0xff) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset)); + } else { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),resoffset)); + } + } else { + mov2w(AOP(right), offset); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset)); + } + offset++; + resoffset++; } - offset++; - } - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); } + + /*-----------------------------------------------------------------*/ -/* genNearPointerSet - pic16_emitcode for near pointer put */ +/* genNearPointerSet - pic16_emitcode for near pointer put */ /*-----------------------------------------------------------------*/ static void genNearPointerSet (operand *right, operand *result, @@ -9062,121 +9303,114 @@ static void genNearPointerSet (operand *right, char *l; sym_link *retype; sym_link *ptype = operandType(result); - + sym_link *resetype; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - retype= getSpec(operandType(right)); - - pic16_aopOp(result,ic,FALSE); - + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + retype= getSpec(operandType(right)); + resetype = getSpec(operandType(result)); + + pic16_aopOp(result,ic,FALSE); - /* if the result is rematerializable & - in data space & not a bit variable */ - //if (AOP_TYPE(result) == AOP_IMMD && - if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD && - DCL_TYPE(ptype) == POINTER && - !IS_BITVAR(retype)) { - genDataPointerSet (right,result,ic); - pic16_freeAsmop(result,NULL,ic,TRUE); - return; - } + /* if the result is rematerializable & + * in data space & not a bit variable */ + + /* and result is not a bit variable */ + if (AOP_TYPE(result) == AOP_PCODE +// && AOP_TYPE(result) == AOP_IMMD + && DCL_TYPE(ptype) == POINTER + && !IS_BITFIELD(retype) + && !IS_BITFIELD(resetype)) { + + genDataPointerSet (right,result,ic); + pic16_freeAsmop(result,NULL,ic,TRUE); + return; + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp(right,ic,FALSE); - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(right,ic,FALSE); + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { - /* otherwise get a free pointer register */ - //aop = newAsmop(0); - //preg = getFreePtr(ic,&aop,FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - //pic16_emitcode("mov","%s,%s", - // preg->name, - // pic16_aopGet(AOP(result),0,FALSE,TRUE)); - //rname = preg->name ; - //pic16_emitcode("movwf","fsr0"); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0)); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); - goto release; + /* if the value is already in a pointer register + * then don't need anything more */ + if (!AOP_INPREG(AOP(result))) { + /* otherwise get a free pointer register */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - }// else + pic16_loadFSR0( result ); + } +// else // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if bitfield then unpack the bits */ - if (IS_BITFIELD(retype)) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "The programmer is obviously confused"); -// genPackBits (retype,right,"BAD",POINTER); - exit(1); - } - else { - /* we have can just get the values */ - int size = AOP_SIZE(right); - int offset = 0 ; + /* if bitfield then unpack the bits */ + if (IS_BITFIELD(resetype)) { + genPackBits (resetype, right, NULL, POINTER); + } else { + /* we have can just get the values */ + int size = AOP_SIZE(right); + int offset = 0 ; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - while (size--) { - l = pic16_aopGet(AOP(right),offset,FALSE,TRUE); - if (*l == '@' ) { - //MOVA(l); - //pic16_emitcode("mov","@%s,a",rname); - pic16_emitcode("movf","indf0,w ;1"); - } else { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + while (size--) { + l = pic16_aopGet(AOP(right),offset,FALSE,TRUE); + if (*l == '@' ) { + //MOVA(l); + //pic16_emitcode("mov","@%s,a",rname); + pic16_emitcode("movf","indf0,w ;1"); + } else { - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - if(lit) { - pic16_emitcode("movlw","%s",l); - pic16_emitcode("movwf","indf0 ;2"); - } else - pic16_emitcode("clrf","indf0"); - }else { - pic16_emitcode("movf","%s,w",l); - pic16_emitcode("movwf","indf0 ;2"); - } - //pic16_emitcode("mov","@%s,%s",rname,l); - } - if (size) - pic16_emitcode("incf","fsr0,f ;3"); - //pic16_emitcode("inc","%s",rname); - offset++; - } - } + if (AOP_TYPE(right) == AOP_LIT) { + unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - pic16_freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_SIZE(right) > 1 && - !OP_SYMBOL(result)->remat && - ( OP_SYMBOL(result)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(right) - 1; - while (size--) - pic16_emitcode("decf","fsr0,f"); - //pic16_emitcode("dec","%s",rname); - } - } + if(lit) { + pic16_emitcode("movlw","%s",l); + pic16_emitcode("movwf","indf0 ;2"); + } else + pic16_emitcode("clrf","indf0"); + } else { + pic16_emitcode("movf","%s,w",l); + pic16_emitcode("movwf","indf0 ;2"); + } + //pic16_emitcode("mov","@%s,%s",rname,l); + } + if (size) + pic16_emitcode("incf","fsr0,f ;3"); + //pic16_emitcode("inc","%s",rname); + offset++; + } + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* done */ - release: - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* now some housekeeping stuff */ + if (aop) { + /* we had to allocate for this iCode */ + pic16_freeAsmop(NULL,aop,ic,TRUE); + } else { + /* we did not allocate which means left + * already in a pointer register, then + * if size > 0 && this could be used again + * we have to point it back to where it + * belongs */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (AOP_SIZE(right) > 1 + && !OP_SYMBOL(result)->remat + && ( OP_SYMBOL(result)->liveTo > ic->seq + || ic->depth )) { + + int size = AOP_SIZE(right) - 1; + + while (size--) + pic16_emitcode("decf","fsr0,f"); + //pic16_emitcode("dec","%s",rname); + } + } + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* done */ +//release: + pic16_freeAsmop(right,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -9328,7 +9562,6 @@ static void genGenPointerSet (operand *right, DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - /* if the operand is already in dptr then we do nothing else we move the value to dptr */ if (AOP_TYPE(result) != AOP_STR) { @@ -9376,7 +9609,6 @@ static void genGenPointerSet (operand *right, } // right = ACC DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); goto release; } // if (AOP_TYPE(result) != AOP_IMMD) @@ -9534,41 +9766,6 @@ static void genIfx (iCode *ic, iCode *popIc) /*-----------------------------------------------------------------*/ /* genAddrOf - generates code for address of */ /*-----------------------------------------------------------------*/ -#if 0 -static void genAddrOf (iCode *ic) -{ - operand *right, *result, *left; - int size, offset ; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - - //pic16_aopOp(IC_RESULT(ic),ic,FALSE); - - pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); - pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); - - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); - - size = AOP_SIZE(IC_RESULT(ic)); - offset = 0; - - - while (size--) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - offset++; - } - - - pic16_freeAsmop(left,NULL,ic,FALSE); - pic16_freeAsmop(result,NULL,ic,TRUE); - -} - -#else /* new genAddrOf */ - static void genAddrOf (iCode *ic) { operand *result, *left; @@ -9624,7 +9821,6 @@ static void genAddrOf (iCode *ic) pic16_freeAsmop(left, NULL, ic, FALSE); } -#endif /* new genAddrOf */ #if 0 /*-----------------------------------------------------------------*/ @@ -10350,7 +10546,7 @@ static void genReceive (iCode *ic) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (isOperandInFarSpace(IC_RESULT(ic)) && + if (isOperandInFarSpace(IC_RESULT(ic)) && ( OP_SYMBOL(IC_RESULT(ic))->isspilt || IS_TRUE_SYMOP(IC_RESULT(ic))) ) { @@ -10378,7 +10574,7 @@ static void genReceive (iCode *ic) _G.accInUse++; pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + assignResultValue(IC_RESULT(ic), 0); } pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); @@ -10436,12 +10632,8 @@ void genpic16Code (iCode *lic) } #endif -// dumpiCode(lic); - for (ic = lic ; ic ; ic = ic->next ) { -// fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op); -// DEBUGpic16_emitcode("; VR", ""); DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op); if ( cln != ic->lineno ) { if ( options.debug ) { @@ -10463,7 +10655,7 @@ void genpic16Code (iCode *lic) if(options.iCodeInAsm) { /* insert here code to print iCode as comment */ - pic16_emitcomment("; ic:%d: %s", ic->seq, printILine(ic)); + pic16_emitpcomment("ic:%d: %s", ic->seq, printILine(ic)); } /* if the result is marked as diff --git a/src/pic16/gen.h b/src/pic16/gen.h index 54ed8d20..e942384d 100644 --- a/src/pic16/gen.h +++ b/src/pic16/gen.h @@ -32,12 +32,18 @@ struct pCodeOp; enum { AOP_LIT = 1, - AOP_REG, AOP_DIR, - AOP_DPTR, AOP_DPTR2, AOP_R0, AOP_R1, - AOP_STK, AOP_IMMD, AOP_STR, - AOP_CRY, AOP_ACC, + AOP_REG, + AOP_DIR, + AOP_DPTR, + AOP_DPTR2, + AOP_R0, + AOP_R1, + AOP_STK, + AOP_IMMD, + AOP_STR, + AOP_CRY, + AOP_ACC, AOP_PCODE - }; /* type asmop : a homogenised type for diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index ea7f5725..2015eb59 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -54,7 +54,8 @@ #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result); - +void pic16_emitpcomment(char *, ...); +pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst); const char *pic16_AopType(short type) { switch(type) { @@ -137,6 +138,12 @@ const char *pic16_pCodeOpType( pCodeOp *pcop) return "PO_PCL"; case PO_PCLATH: return "PO_PCLATH"; + case PO_PCLATU: + return "PO_PCLATU"; + case PO_PRODL: + return "PO_PRODL"; + case PO_PRODH: + return "PO_PRODH"; case PO_LITERAL: return "PO_LITERAL"; case PO_REL_ADDR: @@ -207,7 +214,7 @@ bool pic16_genPlusIncr (iCode *ic) DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__); /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?! - if( strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") && + if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) && (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) { pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); @@ -785,294 +792,348 @@ static void genAddLit (iCode *ic, int lit) /*-----------------------------------------------------------------*/ void pic16_genPlus (iCode *ic) { - int size, offset = 0; - operand *result, *left, *right; - - /* special cases :- */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + int i, size, offset = 0; + operand *result, *left, *right; + + /* special cases :- */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -#if 1 result = IC_RESULT(ic); left = IC_LEFT(ic); right = IC_RIGHT(ic); - pic16_aopOp (left,ic,FALSE); - pic16_aopOp (right,ic,FALSE); - pic16_aopOp (result,ic,TRUE); - DEBUGpic16_pic16_AopType(__LINE__,left, right, result); - -#else - pic16_aopOp (IC_LEFT(ic),ic,FALSE); - pic16_aopOp (IC_RIGHT(ic),ic,FALSE); - pic16_aopOp (IC_RESULT(ic),ic,TRUE); - DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic)); -#endif - - - /* if literal, literal on the right or - if left requires ACC or right is already - in ACC */ - - if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) { - operand *t = IC_RIGHT(ic); - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = t; - } - - /* if both left & right are in bit space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - pic16_genPlusBits (ic); - goto release ; - } - - /* if left in bit space & right literal */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) { - /* if result in bit space */ - if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){ - if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0)); - if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0)); - } - } else { - size = pic16_getDataSize(IC_RESULT(ic)); - while (size--) { - MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - pic16_emitcode("addc","a,#00 ;%d",__LINE__); - pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - } - goto release ; - } - - /* if I can do an increment instead - of add then GOOD for ME */ - if (pic16_genPlusIncr (ic) == TRUE) - goto release; - - size = pic16_getDataSize(IC_RESULT(ic)); - - if(AOP(IC_RIGHT(ic))->type == AOP_LIT) { - /* Add a literal to something else */ - //bool know_W=0; - unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - // unsigned l1=0; - - // offset = 0; - DEBUGpic16_emitcode(";","adding lit to something. size %d",size); - - genAddLit (ic, lit); - goto release; - - } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - - pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - - /* here we are adding a bit to a char or int */ - if(size == 1) { - if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0)); - - pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - } else { - - if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_XORLW , pic16_popGetLit(1)); - - pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" xorlw","1"); - } else { - pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_aopOp (left,ic,FALSE); + pic16_aopOp (right,ic,FALSE); + pic16_aopOp (result,ic,TRUE); + DEBUGpic16_pic16_AopType(__LINE__,left, right, result); + // pic16_DumpOp("(left)",left); + + /* if literal, literal on the right or + if left requires ACC or right is already + in ACC */ + + if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) { + operand *t = right; + right = left; + left = t; + } - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + /* if both left & right are in bit space */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right) == AOP_CRY) { + pic16_genPlusBits (ic); + goto release ; } + + /* if left in bit space & right literal */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right) == AOP_LIT) { + /* if result in bit space */ + if(AOP_TYPE(result) == AOP_CRY){ + if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0)); + if (!pic16_sameRegs(AOP(left), AOP(result)) ) + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0)); + } + } else { + size = pic16_getDataSize(result); + while (size--) { + MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE)); + pic16_emitcode("addc","a,#00 ;%d",__LINE__); + pic16_aopPut(AOP(result),"a",offset++); + } + } + goto release ; + } // left == CRY + + /* if I can do an increment instead + of add then GOOD for ME */ + if (pic16_genPlusIncr (ic) == TRUE) + goto release; + + size = pic16_getDataSize(IC_RESULT(ic)); + + if(AOP(IC_RIGHT(ic))->type == AOP_LIT) { + /* Add a literal to something else */ + //bool know_W=0; + unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + //unsigned l1=0; + + //offset = 0; + DEBUGpic16_emitcode(";","adding lit to something. size %d",size); + + genAddLit (ic, lit); + goto release; + + } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { + + pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + + /* here we are adding a bit to a char or int */ + if(size == 1) { + if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { + + pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); + pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0)); + + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_RIGHT(ic))->aopu.aop_dir, + AOP(IC_RIGHT(ic))->aopu.aop_dir); + pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + } else { // not same + + if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { + pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); + pic16_emitpcode(POC_XORLW , pic16_popGetLit(1)); + + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_RIGHT(ic))->aopu.aop_dir, + AOP(IC_RIGHT(ic))->aopu.aop_dir); + pic16_emitcode(" xorlw","1"); + } else { + pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); + pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0)); + + pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_RIGHT(ic))->aopu.aop_dir, + AOP(IC_RIGHT(ic))->aopu.aop_dir); + pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + } - if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) { + if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) { - if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { - pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1)); - pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0)); - emitSKPZ; - pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0)); - } else { - pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0)); - pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - } - } - } - - } else { - int offset = 1; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitCLRZ; - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); - - pic16_emitcode("clrz",""); - - pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - - } else { - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); - //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitMOVWF(IC_RIGHT(ic),0); - - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - - } - - while(--size){ - emitSKPZ; - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++)); - //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE)); - } - - } + if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { + pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1)); + pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0)); + emitSKPZ; + pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0)); + } else { + pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + } + } + } + + } else { + int offset = 1; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { + emitCLRZ; + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + + pic16_emitcode("clrz",""); + + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_RIGHT(ic))->aopu.aop_dir, + AOP(IC_RIGHT(ic))->aopu.aop_dir); + pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + + } else { + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0)); + pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitMOVWF(IC_RIGHT(ic),0); + + pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_RIGHT(ic))->aopu.aop_dir, + AOP(IC_RIGHT(ic))->aopu.aop_dir); + pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + + } + + while(--size){ + emitSKPZ; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++)); + //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE)); + } + + } - } else { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - /* Add the first bytes */ - - if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) { - pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - } else { - - if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - } else { - - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0)); + } else { + // add bytes + + // Note: the following is an example of WISC code, eg. + // it's supposed to run on a Weird Instruction Set Computer :o) + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if ( AOP_TYPE(left) == AOP_ACC) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0)); + if ( AOP_TYPE(result) != AOP_ACC) + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0)); + goto release; // we're done, since WREG is 1 byte + } + + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + size = min( AOP_SIZE(result), AOP_SIZE(right) ); + offset = 0; + + if ((AOP_TYPE(left) == AOP_PCODE) && ( + (AOP(left)->aopu.pcop->type == PO_LITERAL) || + (AOP(left)->aopu.pcop->type == PO_DIR) || + (AOP(left)->aopu.pcop->type == PO_IMMEDIATE))) + { + // add to literal operand + + // add first bytes + for(i=0; iaopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) - poc = POC_ADDLW; - pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0)); - if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); } - } - } - - size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1; - offset = 1; - - - while(size--){ - if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - } - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset)); - emitSKPNC; - pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset)); - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - - /* - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitSKPNC; - pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - */ - - offset++; - } - } + // TODO: anything from here to before "release:" is probably obsolete and should be removed + // when the regression tests are stable - if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { - int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) | - SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) ); + if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { + int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) | + SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) ); - /* Need to extend result to higher bytes */ - size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1; + /* Need to extend result to higher bytes */ + size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1; - /* First grab the carry from the lower bytes */ - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + /* First grab the carry from the lower bytes */ + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - if(sign) { - /* Now this is really horrid. Gotta check the sign of the addends and propogate - * to the result */ + if(sign) { + /* Now this is really horrid. Gotta check the sign of the addends and propogate + * to the result */ - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - /* if chars or ints or being signed extended to longs: */ - if(size) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0)); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); - } - } + /* if chars or ints or being signed extended to longs: */ + if(size) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); + } + } - offset++; - while(size--) { + offset++; + while(size--) { - if(sign) - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - else - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + if(sign) + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + else + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - offset++; - } - } + offset++; + } + } - //adjustArithmeticResult(ic); + //adjustArithmeticResult(ic); - release: - pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + release: + pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -1201,7 +1262,7 @@ void pic16_addSign(operand *result, int offset, int sign) pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0)); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); while(size--) - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size)); } } else @@ -1489,7 +1550,7 @@ void pic16_genMinus (iCode *ic) pic16_AopType(AOP_TYPE(IC_LEFT(ic))), pic16_AopType(AOP_TYPE(IC_RIGHT(ic)))); - if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) { + if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0)); pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0)); @@ -1564,6 +1625,7 @@ void pic16_genMinus (iCode *ic) pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } + /*-----------------------------------------------------------------* * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers. * @@ -1778,6 +1840,67 @@ void pic16_genUMult8XLit_16 (operand *left, } + +/*-----------------------------------------------------------------* + * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers. + * + * + *-----------------------------------------------------------------*/ +void pic16_genUMult8XLit_8 (operand *left, + operand *right, + operand *result) +{ + unsigned int lit; + int same; + + if (AOP_TYPE(right) != AOP_LIT){ + fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__); + exit(1); + } + + lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit); + lit &= 0xff; + pic16_emitpcomment("Unrolled 8 X 8 multiplication"); + pic16_emitpcomment("FIXME: the function does not support result==WREG"); + + same = pic16_sameRegs(AOP(left), AOP(result)); + if(same) { + switch(lit) { + case 0: + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); + return; + case 2: + // its faster to left shift + pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(left),0)); + return; + + default: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), + pic16_popGet(AOP(result), 0))); + return; + } + } else { + // operands different + switch(lit) { + case 0: + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0)); + return; + case 2: + pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + return; + default: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), + pic16_popGet(AOP(result), 0))); + return; + } + } +} + /*-----------------------------------------------------------------* * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers. * @@ -1842,9 +1965,7 @@ void pic16_genUMult8X8_16 (operand *left, symbol *tlbl = newiTempLabel(NULL); pCodeOp *temp; - - pic16_emitcode(";","Looped 8 X 8 multiplication"); - + pic16_emitpcomment("; Looped 8 X 8 multiplication"); pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi)); @@ -1870,10 +1991,61 @@ void pic16_genUMult8X8_16 (operand *left, pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key)); pic16_popReleaseTempReg(temp); - } } +/*-----------------------------------------------------------------* + * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers. + * + * + *-----------------------------------------------------------------*/ +void pic16_genUMult8X8_8 (operand *left, + operand *right, + operand *result) + +{ + if (AOP_TYPE(right) == AOP_LIT) { + pic16_genUMult8XLit_8(left,right,result); + return; + } + + pic16_emitpcomment("; Looped 8 X 8 multiplication"); + /* cases: + A = A x B B = A x B + A = B x C + W = A x B + W = W x B W = B x W + */ + /* if result == right then exchange left and right */ + if(pic16_sameRegs(AOP(result), AOP(right))) { + operand *tmp; + tmp = left; + left = right; + right = tmp; + } + + if(AOP_TYPE(left) != AOP_ACC) { + // left is not WREG + if(AOP_TYPE(right) != AOP_ACC) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); + } else { + pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0)); + } + } else { + // left is WREG, right cannot be WREG (or can?!) + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0)); + } + + /* result is in PRODL:PRODH */ + if(AOP_TYPE(result) != AOP_ACC) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), + pic16_popGet(AOP(result), 0))); + } else { + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl)); + } +} + /*-----------------------------------------------------------------* * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers * @@ -1911,14 +2083,10 @@ void pic16_genMult8X8_8 (operand *left, operand *right, operand *result) { - pCodeOp *result_hi = pic16_popGetTempReg(); - if (AOP_TYPE(right) == AOP_LIT) - pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi)); + pic16_genUMult8XLit_8(left,right,result); else - pic16_genUMult8X8_16(left,right,result,PCOR(result_hi)); - - pic16_popReleaseTempReg(result_hi); + pic16_genUMult8X8_8(left,right,result); } #if 0 /*-----------------------------------------------------------------*/ diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c index c79db385..25d645cf 100644 --- a/src/pic16/genutils.c +++ b/src/pic16/genutils.c @@ -162,3 +162,246 @@ release: } #endif /* defined(GEN_Cpl) */ + + +/*-----------------------------------------------------------------*/ +/* Helper function to dump operand into comment lines */ +/*-----------------------------------------------------------------*/ + +void pic16_DumpValue(char *prefix, value *val) +{ +// char s[INITIAL_INLINEASM]; + if(!val) return; + + DEBUGpic16_emitcode (";", " %s Dump value",prefix); + DEBUGpic16_emitcode (";", " %s name:%s",prefix,val->name); +} + +void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop) +{ +// char s[INITIAL_INLINEASM]; + if(!pcop) return; + + DEBUGpic16_emitcode (";", " %s Dump pCodeOp",prefix); + DEBUGpic16_emitcode (";", " %s name:%s",prefix,pcop->name); + if(pcop->type == PO_NONE) { + DEBUGpic16_emitcode (";", " %s type:PO_NONE",prefix); + } + if(pcop->type == PO_W) { + DEBUGpic16_emitcode (";", " %s type:PO_W",prefix); + } + if(pcop->type == PO_WREG) { + DEBUGpic16_emitcode (";", " %s type:PO_WREG",prefix); + } + if(pcop->type == PO_STATUS) { + DEBUGpic16_emitcode (";", " %s type:PO_STATUS",prefix); + } + if(pcop->type == PO_BSR) { + DEBUGpic16_emitcode (";", " %s type:PO_BSR",prefix); + } + if(pcop->type == PO_FSR0) { + DEBUGpic16_emitcode (";", " %s type:PO_FSR0",prefix); + } + if(pcop->type == PO_INDF0) { + DEBUGpic16_emitcode (";", " %s type:PO_INDF0",prefix); + } + if(pcop->type == PO_INTCON) { + DEBUGpic16_emitcode (";", " %s type:PO_INTCON",prefix); + } + if(pcop->type == PO_GPR_REGISTER) { + DEBUGpic16_emitcode (";", " %s type:PO_GPR_REGISTER",prefix); + } + if(pcop->type == PO_GPR_BIT) { + DEBUGpic16_emitcode (";", " %s type:PO_GPR_BIT",prefix); + } + if(pcop->type == PO_GPR_TEMP) { + DEBUGpic16_emitcode (";", " %s type:PO_GPR_TEMP",prefix); + } + if(pcop->type == PO_SFR_REGISTER) { + DEBUGpic16_emitcode (";", " %s type:PO_SFR_REGISTER",prefix); + } + if(pcop->type == PO_PCL) { + DEBUGpic16_emitcode (";", " %s type:PO_PCL",prefix); + } + if(pcop->type == PO_PCLATH) { + DEBUGpic16_emitcode (";", " %s type:PO_PCLATH",prefix); + } + if(pcop->type == PO_LITERAL) { + DEBUGpic16_emitcode (";", " %s type:PO_LITERAL",prefix); + DEBUGpic16_emitcode (";", " %s lit:%s",prefix,PCOL(pcop)->lit); + } + if(pcop->type == PO_REL_ADDR) { + DEBUGpic16_emitcode (";", " %s type:PO_REL_ADDR",prefix); + } + if(pcop->type == PO_IMMEDIATE) { + DEBUGpic16_emitcode (";", " %s type:PO_IMMEDIATE",prefix); + } + if(pcop->type == PO_DIR) { + DEBUGpic16_emitcode (";", " %s type:PO_DIR",prefix); + } + if(pcop->type == PO_CRY) { + DEBUGpic16_emitcode (";", " %s type:PO_CRY",prefix); + } + if(pcop->type == PO_BIT) { + DEBUGpic16_emitcode (";", " %s type:PO_BIT",prefix); + } + if(pcop->type == PO_STR) { + DEBUGpic16_emitcode (";", " %s type:PO_STR",prefix); + } + if(pcop->type == PO_LABEL) { + DEBUGpic16_emitcode (";", " %s type:PO_LABEL",prefix); + } + if(pcop->type == PO_WILD) { + DEBUGpic16_emitcode (";", " %s type:PO_WILD",prefix); + } +} + + + +void pic16_DumpAop(char *prefix, asmop *aop) +{ + char s[INITIAL_INLINEASM]; + if(!aop) return; + + DEBUGpic16_emitcode (";", " %s Dump asmop",prefix); + if (aop->type == AOP_LIT) + { + DEBUGpic16_emitcode (";", " %s type:AOP_LIT",prefix); + sprintf(s,"%s (aopu.aop_lit)",prefix); + pic16_DumpValue(s,aop->aopu.aop_lit); + } + if (aop->type == AOP_REG) + DEBUGpic16_emitcode (";", " %s type:AOP_REG",prefix); + if (aop->type == AOP_DIR) + { + DEBUGpic16_emitcode (";", " %s type:AOP_DIR",prefix); + DEBUGpic16_emitcode (";", " %s aopu.aop_dir:%s",prefix,aop->aopu.aop_dir); + } + if (aop->type == AOP_DPTR) + DEBUGpic16_emitcode (";", " %s type:AOP_DPTR",prefix); + if (aop->type == AOP_DPTR2) + DEBUGpic16_emitcode (";", " %s type:AOP_DPTR2",prefix); + if (aop->type == AOP_R0) + DEBUGpic16_emitcode (";", " %s type:AOP_R0",prefix); + if (aop->type == AOP_R1) + DEBUGpic16_emitcode (";", " %s type:AOP_R1",prefix); + if (aop->type == AOP_STK) + DEBUGpic16_emitcode (";", " %s type:AOP_STK",prefix); + if (aop->type == AOP_IMMD) + { + DEBUGpic16_emitcode (";", " %s type:AOP_IMMD",prefix); + DEBUGpic16_emitcode (";", " %s aopu.aop_immd:%s",prefix,aop->aopu.aop_immd); + } + if (aop->type == AOP_STR) + { + DEBUGpic16_emitcode (";", " %s type:AOP_STR",prefix); + DEBUGpic16_emitcode (";", " %s aopu.aop_str:%s/%s/%s/%s",prefix,aop->aopu.aop_str[0], + aop->aopu.aop_str[1],aop->aopu.aop_str[2],aop->aopu.aop_str[3]); + } + if (aop->type == AOP_CRY) + DEBUGpic16_emitcode (";", " %s type:AOP_CRY",prefix); + if (aop->type == AOP_ACC) + DEBUGpic16_emitcode (";", " %s type:AOP_ACC",prefix); + if (aop->type == AOP_PCODE) + { + DEBUGpic16_emitcode (";", " %s type:AOP_PCODE",prefix); + sprintf(s,"%s (aopu.pcop)",prefix); + pic16_DumpPcodeOp(s,aop->aopu.pcop); + } + + + DEBUGpic16_emitcode (";", " %s coff:%d",prefix,aop->coff); + DEBUGpic16_emitcode (";", " %s size:%d",prefix,aop->size); + DEBUGpic16_emitcode (";", " %s code:%d",prefix,aop->code); + DEBUGpic16_emitcode (";", " %s paged:%d",prefix,aop->paged); + DEBUGpic16_emitcode (";", " %s freed:%d",prefix,aop->freed); + +} + +void pic16_DumpSymbol(char *prefix, symbol *sym) +{ + char s[INITIAL_INLINEASM]; + if(!sym) return; + + DEBUGpic16_emitcode (";", " %s Dump symbol",prefix); + DEBUGpic16_emitcode (";", " %s name:%s",prefix,sym->name); + DEBUGpic16_emitcode (";", " %s rname:%s",prefix,sym->rname); + DEBUGpic16_emitcode (";", " %s level:%d",prefix,sym->level); + DEBUGpic16_emitcode (";", " %s block:%d",prefix,sym->block); + DEBUGpic16_emitcode (";", " %s key:%d",prefix,sym->key); + DEBUGpic16_emitcode (";", " %s implicit:%d",prefix,sym->implicit); + DEBUGpic16_emitcode (";", " %s undefined:%d",prefix,sym->undefined); + DEBUGpic16_emitcode (";", " %s _isparm:%d",prefix,sym->_isparm); + DEBUGpic16_emitcode (";", " %s ismyparm:%d",prefix,sym->ismyparm); + DEBUGpic16_emitcode (";", " %s isitmp:%d",prefix,sym->isitmp); + DEBUGpic16_emitcode (";", " %s islbl:%d",prefix,sym->islbl); + DEBUGpic16_emitcode (";", " %s isref:%d",prefix,sym->isref); + DEBUGpic16_emitcode (";", " %s isind:%d",prefix,sym->isind); + DEBUGpic16_emitcode (";", " %s isinvariant:%d",prefix,sym->isinvariant); + DEBUGpic16_emitcode (";", " %s cdef:%d",prefix,sym->cdef); + DEBUGpic16_emitcode (";", " %s addrtaken:%d",prefix,sym->addrtaken); + DEBUGpic16_emitcode (";", " %s isreqv:%d",prefix,sym->isreqv); + DEBUGpic16_emitcode (";", " %s udChked:%d",prefix,sym->udChked); + DEBUGpic16_emitcode (";", " %s isLiveFcall:%d",prefix,sym->isLiveFcall); + DEBUGpic16_emitcode (";", " %s isspilt:%d",prefix,sym->isspilt); + DEBUGpic16_emitcode (";", " %s spillA:%d",prefix,sym->spillA); + DEBUGpic16_emitcode (";", " %s remat:%d",prefix,sym->remat); + DEBUGpic16_emitcode (";", " %s isptr:%d",prefix,sym->isptr); + DEBUGpic16_emitcode (";", " %s uptr:%d",prefix,sym->uptr); + DEBUGpic16_emitcode (";", " %s isFree:%d",prefix,sym->isFree); + DEBUGpic16_emitcode (";", " %s islocal:%d",prefix,sym->islocal); + DEBUGpic16_emitcode (";", " %s blockSpil:%d",prefix,sym->blockSpil); + DEBUGpic16_emitcode (";", " %s remainSpil:%d",prefix,sym->remainSpil); + DEBUGpic16_emitcode (";", " %s stackSpil:%d",prefix,sym->stackSpil); + DEBUGpic16_emitcode (";", " %s onStack:%d",prefix,sym->onStack); + DEBUGpic16_emitcode (";", " %s iaccess:%d",prefix,sym->iaccess); + DEBUGpic16_emitcode (";", " %s ruonly:%d",prefix,sym->ruonly); + DEBUGpic16_emitcode (";", " %s spildir:%d",prefix,sym->spildir); + DEBUGpic16_emitcode (";", " %s ptrreg:%d",prefix,sym->ptrreg); + DEBUGpic16_emitcode (";", " %s noSpilLoc:%d",prefix,sym->noSpilLoc); + DEBUGpic16_emitcode (";", " %s isstrlit:%d",prefix,sym->isstrlit); + DEBUGpic16_emitcode (";", " %s accuse:%d",prefix,sym->accuse); + DEBUGpic16_emitcode (";", " %s dptr:%d",prefix,sym->dptr); + DEBUGpic16_emitcode (";", " %s allocreq:%d",prefix,sym->allocreq); + DEBUGpic16_emitcode (";", " %s stack:%d",prefix,sym->stack); + DEBUGpic16_emitcode (";", " %s xstack:%d",prefix,sym->xstack); + DEBUGpic16_emitcode (";", " %s nRegs:%d",prefix,sym->nRegs); + DEBUGpic16_emitcode (";", " %s regType:%d",prefix,sym->regType); + + // struct regs !!! + + if(sym->aop) + { + sprintf(s,"%s (aop)",prefix); + pic16_DumpAop(s,sym->aop); + } else { + DEBUGpic16_emitcode (";", " %s aop:NULL",prefix); + } +} + +void pic16_DumpOp(char *prefix, operand *op) +{ + char s[INITIAL_INLINEASM]; + if(!op) return; + + DEBUGpic16_emitcode (";", " %s Dump operand",prefix); + if(IS_SYMOP(op)) + DEBUGpic16_emitcode (";", " %s type: SYMBOL",prefix); + if(IS_VALOP(op)) + DEBUGpic16_emitcode (";", " %s type: VALUE",prefix); + if(IS_TYPOP(op)) + DEBUGpic16_emitcode (";", " %s type: TYPE",prefix); + DEBUGpic16_emitcode (";", " %s isaddr:%d",prefix,op->isaddr); + DEBUGpic16_emitcode (";", " %s isvolatile:%d",prefix,op->isvolatile); + DEBUGpic16_emitcode (";" ," %s isGlobal:%d",prefix,op->isGlobal); + DEBUGpic16_emitcode (";", " %s isPtr:%d",prefix,op->isPtr); + DEBUGpic16_emitcode (";", " %s isGptr:%d",prefix,op->isGptr); + DEBUGpic16_emitcode (";", " %s isParm:%d",prefix,op->isParm); + DEBUGpic16_emitcode (";", " %s isLiteral:%d",prefix,op->isLiteral); + DEBUGpic16_emitcode (";", " %s key:%d",prefix,op->key); + if(IS_SYMOP(op)) { + sprintf(s,"%s (symOperand)",prefix); + pic16_DumpSymbol(s,op->operand.symOperand); + } + +} diff --git a/src/pic16/genutils.h b/src/pic16/genutils.h index f6dc45ce..358c4ed2 100644 --- a/src/pic16/genutils.h +++ b/src/pic16/genutils.h @@ -13,7 +13,7 @@ /* * The various GEN_xxxxx macros handle which functions * should be included in the gen.c source. We are going to use - * our own functions here so, they must be commentted out from + * our own functions here so, they must be commented out from * gen.c */ @@ -30,4 +30,12 @@ void pic16_genCpl(iCode *ic); void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result); +void pic16_DumpValue(char *prefix, value *val); +void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop); +void pic16_DumpAop(char *prefix, asmop *aop); +void pic16_DumpSymbol(char *prefix, symbol *sym); +void pic16_DumpOp(char *prefix, operand *op); + + + #endif /* __GENUTILS_H__ */ diff --git a/src/pic16/glue.c b/src/pic16/glue.c index 8e071761..c1a71805 100644 --- a/src/pic16/glue.c +++ b/src/pic16/glue.c @@ -27,6 +27,7 @@ #include "ralloc.h" #include "pcode.h" #include "newalloc.h" +#include "gen.h" #include "device.h" #include "main.h" @@ -55,6 +56,8 @@ extern char *iComments1; extern char *iComments2; //extern void emitStaticSeg (memmap * map); +extern int initsfpnt; + extern DEFSETFUNC (closeTmpFiles); extern DEFSETFUNC (rmTmpFiles); @@ -71,7 +74,6 @@ void pic16_pCodeInitRegisters(void); pCodeOp *pic16_popGetLit(unsigned int lit); pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2); pCodeOp *pic16_popCopyReg(pCodeOpReg *pc); -pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst); /*-----------------------------------------------------------------*/ /* aopLiteral - string from a literal value */ @@ -118,7 +120,8 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag) /* print the area name */ for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { #if 0 - fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used); + fprintf(stderr, "\t%s: sym: %s\tused: %d\textern: %d\n", + map->sname, sym->name, sym->used, IS_EXTERN(sym->etype)); printTypeChain( sym->type, stderr ); printf("\n"); #endif @@ -128,24 +131,45 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag) addSetHead(&externs, sym); continue; } + /* if allocation required check is needed * then check if the symbol really requires * allocation only for local variables */ if (arFlag && !IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && - !sym->allocreq && sym->level) - + !sym->allocreq && sym->level) { + + fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__); + continue; + } /* if global variable & not static or extern * and addPublics allowed then add it to the public set */ if ((sym->used) && (sym->level == 0 || (sym->_isparm && !IS_REGPARM (sym->etype))) && addPublics && - !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) - + !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) { +// regs *reg; + addSetHead (&publics, sym); +// reg = pic16_allocRegByName(sym->name, sym->size); //( operandFromSymbol( sym )); +// checkAddReg(&pic16_rel_udata, reg); + + } else + if(IS_STATIC(sym->etype)) { + regs *reg; + /* add it to udata list */ + + fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__, + sym->name, sym->rname, sym->remat); + + //, OP_SYMBOL(operandFromSymbol(sym))->name); + reg = pic16_allocDirReg( operandFromSymbol( sym )); + checkAddReg(&pic16_rel_udata, reg); + } + /* if extern then do nothing or is a function * then do nothing */ if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) { @@ -187,23 +211,42 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag) fprintf (map->oFile, "%s\tEQU\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype)); -#if 1 + /* emit only if it is global */ if(sym->level == 0) { regs *reg; operand *op; -// fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name); - op = operandFromSymbol( sym ); - reg = pic16_allocDirReg( op ); - if(reg) { - //continue; - checkAddReg(&pic16_fix_udata, reg); - /* and add to globals list */ - addSetHead(&publics, sym); + + reg = pic16_dirregWithName( sym->name ); + if(!reg) { + fprintf(stderr, "%s:%d: implicit add of symbol = %s\n", + __FUNCTION__, __LINE__, sym->name); + + op = operandFromSymbol( sym ); + reg = pic16_allocDirReg( op ); + if(reg) { + if(checkAddReg(&pic16_fix_udata, reg)) { + /* and add to globals list if not exist */ + addSetHead(&publics, sym); + } + } } } -#endif } else { + if(!sym->used && (sym->level == 0)) { + regs *reg; + + /* symbol not used, just declared probably, but its in + * level 0, so we must declare it fine as global */ + +// fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name); + reg = pic16_allocDirReg( operandFromSymbol( sym ) ); + if(checkAddReg(&pic16_rel_udata, reg)) { + addSetHead(&publics, sym); +// addSetHead(&externs, sym); + } + } + /* allocate space */ /* If this is a bit variable, then allocate storage after 8 bits have been declared */ /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */ @@ -811,18 +854,11 @@ pic16glue () /* entry point @ start of CSEG */ pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup\t;VR1",-1)); - if(USE_STACK) { -#if 0 - pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, - pic16_popGetLit2(1, pic16_popGetLit(stackPos)))); - pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, - pic16_popGetLit2(2, pic16_popGetLit(stackPos)))); -#else + if(initsfpnt) { pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("stack")))); pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("stack")))); -#endif } /* put in the call to main */ diff --git a/src/pic16/main.c b/src/pic16/main.c index f8d50c9b..86036f2d 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -30,6 +30,7 @@ #include "device.h" #include "SDCCutil.h" #include "glue.h" +#include "pcode.h" //#include "gen.h" @@ -87,7 +88,6 @@ _pic16_init (void) asm_addTree (&asm_asxxxx_mapping); pic16_pCodeInitRegisters(); maxInterrupts = 2; - /* set pic16 port options to defaults */ pic16_options.gen_banksel = 0; @@ -95,7 +95,6 @@ _pic16_init (void) pic16_options.omit_configw = 0; pic16_options.omit_ivt = 0; pic16_options.leave_reset = 0; - pic16_options.enable_stack = 0; pic16_options.stack_model = 0; /* 0 for 'small', 1 for 'large' */ } @@ -118,6 +117,8 @@ _pic16_regparm (sym_link * l) } +int initsfpnt=0; /* set to 1 if source provides a pragma for stack + * so glue() later emits code to initialize stack/frame pointers */ set *absSymSet; static int @@ -143,11 +144,17 @@ _process_pragma(const char *sz) if(startsWith(ptr, "stack")) { char *stackPosS = strtok((char *)NULL, WHITE); value *stackPosVal; + regs *reg; // fprintf(stderr, "Initializing stack pointer to 0x%x\n", (int)floatFromVal(constVal(stackPos))); stackPosVal = constVal( stackPosS ); stackPos = (unsigned int)floatFromVal( stackPosVal ); + reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "stack", 1, 0, NULL); + addSet(&pic16_fix_udata, reg); + + initsfpnt = 1; // force glue() to initialize stack/frame pointers */ + return 0; } @@ -205,7 +212,6 @@ OPTION pic16_optionsTable[]= { { 0, "--pomit-config-words", &pic16_options.omit_configw, "omit the generation of configuration words"}, { 0, "--pomit-ivt", &pic16_options.omit_ivt, "omit the generation of the Interrupt Vector Table"}, { 0, "--pleave-reset-vector",&pic16_options.leave_reset, "when omitting IVT leave RESET vector"}, - { 0, "--penable-stack", &pic16_options.enable_stack, "enable the use of stack"}, { 0, STACK_MODEL, NULL, "use stack model 'small' (default) or 'large'"}, { 0, "--debug-xtra", &pic16_debug_verbose, "show more debug info in assembly output"}, @@ -252,7 +258,8 @@ _pic16_parseOptions (int *pargc, char **argv, int *i) { int j=0; // set *tset; - + char *stkmodel; + /* TODO: allow port-specific command line options to specify * segment names here. */ @@ -267,13 +274,12 @@ _pic16_parseOptions (int *pargc, char **argv, int *i) if(ISOPT(STACK_MODEL)) { - switch(*getStringArg(STACK_MODEL, argv, i, *pargc)) { - case 's': pic16_options.stack_model = 0; break; - case 'l': pic16_options.stack_model = 1; break; - - default: - fprintf(stderr, "Unknown stack model"); - exit(-1); + stkmodel = getStringArg(STACK_MODEL, argv, i, *pargc); + if(STRCASECMP(stkmodel, "small"))pic16_options.stack_model = 0; + else if(STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1; + else { + fprintf(stderr, "Unknown stack model: %s", stkmodel); + exit(-1); } return TRUE; } @@ -614,7 +620,7 @@ _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) // sym_link *test = NULL; // value *val; - fprintf(stderr,"checking for native mult\n"); +// fprintf(stderr,"checking for native mult\n"); if ( ic->op != '*') { diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 7f54dbbd..9c4de584 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -60,7 +60,7 @@ pCodeOpReg pic16_pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_wreg = {{PO_WREG, "WREG"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_bsr = {{PO_BSR, "BSR"}, -1, NULL,0,NULL}; -pCodeOpReg pic16_pc_fsr0 = {{PO_FSR0, "FSR0"}, -1, NULL,0,NULL}; //deprecated ! +//pCodeOpReg pic16_pc_fsr0 = {{PO_FSR0, "FSR0"}, -1, NULL,0,NULL}; //deprecated ! pCodeOpReg pic16_pc_fsr0l = {{PO_FSR0, "FSR0L"}, -1, NULL, 0, NULL}; pCodeOpReg pic16_pc_fsr0h = {{PO_FSR0, "FSR0H"}, -1, NULL, 0, NULL}; @@ -87,7 +87,8 @@ pCodeOpReg pic16_pc_postdec2 = {{PO_INDF0, "POSTDEC2"}, -1, NULL, 0, NULL}; pCodeOpReg pic16_pc_preinc2 = {{PO_INDF0, "PREINC2"}, -1, NULL, 0, NULL}; pCodeOpReg pic16_pc_plusw2 = {{PO_INDF0, "PLUSW2"}, -1, NULL, 0, NULL}; - +pCodeOpReg pic16_pc_prodl = {{PO_PRODL, "PRODL"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_prodh = {{PO_PRODH, "PRODH"}, -1, NULL, 0, NULL}; pCodeOpReg pic16_pc_kzero = {{PO_GPR_REGISTER, "KZ"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_wsave = {{PO_GPR_REGISTER, "WSAVE"}, -1, NULL,0,NULL}; @@ -149,6 +150,7 @@ extern pCodeOp *pic16_popCopyReg(pCodeOpReg *pc); pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval); void pic16_pCodeRegMapLiveRanges(pBlock *pb); +char *dumpPicOptype(PIC_OPTYPE type); /****************************************************************/ /* PIC Instructions */ @@ -2558,7 +2560,7 @@ void pic16_pCodeInitRegisters(void) pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80); pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80); - pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80); // deprecated ! +// pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80); // deprecated ! pic16_pc_fsr0l.r = pic16_allocProcessorRegister(IDX_FSR0L, "FSR0L", PO_FSR0, 0x80); pic16_pc_fsr0h.r = pic16_allocProcessorRegister(IDX_FSR0H, "FSR0H", PO_FSR0, 0x80); @@ -2585,12 +2587,15 @@ void pic16_pCodeInitRegisters(void) pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "PREINC2", PO_INDF0, 0x80); pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "PLUSW2", PO_INDF0, 0x80); + pic16_pc_prodl.r = pic16_allocProcessorRegister(IDX_PRODL, "PRODL", PO_PRODL, 0x80); + pic16_pc_prodh.r = pic16_allocProcessorRegister(IDX_PRODH, "PRODH", PO_PRODH, 0x80); + pic16_pc_status.rIdx = IDX_STATUS; pic16_pc_intcon.rIdx = IDX_INTCON; pic16_pc_pcl.rIdx = IDX_PCL; pic16_pc_pclath.rIdx = IDX_PCLATH; pic16_pc_wreg.rIdx = IDX_WREG; - pic16_pc_fsr0.rIdx = IDX_FSR0; +// pic16_pc_fsr0.rIdx = IDX_FSR0; pic16_pc_fsr0l.rIdx = IDX_FSR0L; pic16_pc_fsr0h.rIdx = IDX_FSR0H; pic16_pc_fsr1l.rIdx = IDX_FSR1L; @@ -2612,6 +2617,8 @@ void pic16_pCodeInitRegisters(void) pic16_pc_postdec2.rIdx = IDX_POSTDEC2; pic16_pc_preinc2.rIdx = IDX_PREINC2; pic16_pc_plusw2.rIdx = IDX_PLUSW2; + pic16_pc_prodl.rIdx = IDX_PRODL; + pic16_pc_prodh.rIdx = IDX_PRODH; pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0); pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80); @@ -3535,7 +3542,7 @@ pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space) PCOI(pcop)->r = r; if(r) { - fprintf(stderr, "%s:%d %s reg %s exists\n",__FILE__, __LINE__, __FUNCTION__, name); +// fprintf(stderr, "%s:%d %s reg %s exists\n",__FILE__, __LINE__, __FUNCTION__, name); PCOI(pcop)->rIdx = r->rIdx; } else { // fprintf(stderr, "%s:%d %s reg %s doesn't exist\n", @@ -3649,10 +3656,10 @@ pCodeOp *pic16_newpCodeOpRegFromStr(char *name) pcop->type = PCOR(pcop)->r->pc_type; pcop->name = PCOR(pcop)->r->name; - if(pic16_pcode_verbose) { - fprintf(stderr, "%s:%d %s allocates register %s rIdx:0x%02x\n", - __FILE__, __LINE__, __FUNCTION__, r->name, r->rIdx); - } +// if(pic16_pcode_verbose) { +// fprintf(stderr, "%s:%d %s allocates register %s rIdx:0x%02x\n", +// __FILE__, __LINE__, __FUNCTION__, r->name, r->rIdx); +// } return pcop; } @@ -3969,123 +3976,84 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) char *s; int use_buffer = 1; // copy the string to the passed buffer pointer - if(!buffer) { - buffer = b; - size = sizeof(b); - use_buffer = 0; // Don't bother copying the string to the buffer. - } - - if(pcop) { - switch(pcop->type) { - case PO_INDF0: - case PO_FSR0: - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name); - return buffer; - } - return PCOR(pcop)->r->name; - break; - case PO_GPR_TEMP: - r = pic16_regWithIdx(PCOR(pcop)->r->rIdx); - - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",r->name); - return buffer; - } - - return r->name; - - - case PO_IMMEDIATE: - s = buffer; + if(!buffer) { + buffer = b; + size = sizeof(b); + use_buffer = 0; // Don't bother copying the string to the buffer. + } + + if(pcop) { + switch(pcop->type) { + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: + case PO_FSR0: + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name); + return buffer; + } + return PCOR(pcop)->r->name; + break; + case PO_GPR_TEMP: + r = pic16_regWithIdx(PCOR(pcop)->r->rIdx); + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",r->name); + return buffer; + } + return r->name; + + case PO_IMMEDIATE: + s = buffer; + if(PCOI(pcop)->offset && PCOI(pcop)->offset<4) { + if(PCOI(pcop)->index) { + SAFE_snprintf(&s,&size, "%s(%s + %d)", + immdmod[ PCOI(pcop)->offset ], + pcop->name, + PCOI(pcop)->index); + } else { + SAFE_snprintf(&s,&size,"%s(%s)", + immdmod[ PCOI(pcop)->offset ], + pcop->name); + } + } else { + if(PCOI(pcop)->index) { + SAFE_snprintf(&s,&size, "%s(%s + %d)", + immdmod[ 0 ], + pcop->name, + PCOI(pcop)->index); + } else { + SAFE_snprintf(&s,&size, "%s(%s)", + immdmod[ 0 ], + pcop->name); + } + } + return buffer; + + case PO_DIR: + s = buffer; +// size = sizeof(buffer); + if( PCOR(pcop)->instance) { + SAFE_snprintf(&s,&size,"(%s + %d)", + pcop->name, + PCOR(pcop)->instance ); + } else { + SAFE_snprintf(&s,&size,"%s",pcop->name); + } + return buffer; + + default: + if(pcop->name) { + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",pcop->name); + return buffer; + } + return pcop->name; + } - if(PCOI(pcop)->offset && PCOI(pcop)->offset<4) { - if(PCOI(pcop)->index) { - SAFE_snprintf(&s,&size, "%s(%s + %d)", - immdmod[ PCOI(pcop)->offset ], - pcop->name, - PCOI(pcop)->index); - } else { - SAFE_snprintf(&s,&size,"%s(%s)", - immdmod[ PCOI(pcop)->offset ], - pcop->name); - } - } else { - if(PCOI(pcop)->index) { - SAFE_snprintf(&s,&size, "%s(%s + %d)", - immdmod[ 0 ], - pcop->name, - PCOI(pcop)->index); - } else { - SAFE_snprintf(&s,&size, "%s(%s)", - immdmod[ 0 ], - pcop->name); } } - -#if 0 - if(PCOI(pcop)->_const) { - if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) { - if(PCOI(pcop)->index) { - SAFE_snprintf(&s,&size,"%s(%s + %d)", - immdmod[ PCOI(pcop)->offset ], - pcop->name, - PCOI(pcop)->index); - } else { - SAFE_snprintf(&s,&size,"%s(%s)", - immdmod[ PCOI(pcop)->offset ], - pcop->name); - } - - } else { - if(PCOI(pcop)->index) - SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); - else - SAFE_snprintf(&s,&size,"LOW(%s)",pcop->name); - } - } else { - if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) - SAFE_snprintf(&s,&size,"(%s + %d)", - pcop->name, - PCOI(pcop)->index ); - } else { - if(PCOI(pcop)->offset) - SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); - else - SAFE_snprintf(&s,&size,"(%s)",pcop->name); - } - } -#endif - - return buffer; - - case PO_DIR: - s = buffer; - //size = sizeof(buffer); - if( PCOR(pcop)->instance) { - SAFE_snprintf(&s,&size,"(%s + %d)", - pcop->name, - PCOR(pcop)->instance ); - } - //fprintf(stderr,"PO_DIR %s\n",buffer); - else - SAFE_snprintf(&s,&size,"%s",pcop->name); - return buffer; - - default: - if (pcop->name) { - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",pcop->name); - return buffer; - } - return pcop->name; - } - - } - } - - return "NO operand"; + return "NO operand1"; } /*-----------------------------------------------------------------*/ @@ -4098,11 +4066,11 @@ char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size) char *s; int use_buffer = 1; // copy the string to the passed buffer pointer - if(!buffer) { - buffer = b; - size = sizeof(b); - use_buffer = 0; // Don't bother copying the string to the buffer. - } + if(!buffer) { + buffer = b; + size = sizeof(b); + use_buffer = 0; // Don't bother copying the string to the buffer. + } #if 0 fprintf(stderr, "%s:%d second operand %s is %d\tPO_DIR(%d) PO_GPR_TEMP(%d) PO_IMMEDIATE(%d) PO_INDF0(%d) PO_FSR0(%d)\n", @@ -4110,88 +4078,78 @@ char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size) PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0); #endif - if(pcop) { - switch(PCOR2(pcop)->pcop2->type) { - case PO_INDF0: - case PO_FSR0: - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); - return buffer; - } - return PCOR(PCOR2(pcop)->pcop2)->r->name; - break; - case PO_GPR_TEMP: - r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx); - - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",r->name); - return buffer; - } - - return r->name; - - - case PO_IMMEDIATE: - break; + if(pcop) { + switch(PCOR2(pcop)->pcop2->type) { + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: + case PO_FSR0: + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); + return buffer; + } + return PCOR(PCOR2(pcop)->pcop2)->r->name; + break; + case PO_GPR_TEMP: + r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx); + + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",r->name); + return buffer; + } + return r->name; + + case PO_IMMEDIATE: + assert( 0 ); + break; #if 0 - s = buffer; - - if(PCOI(pcop)->_const) { - - if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) { - SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)", - pcop->name, - PCOI(pcop)->index, - 8 * PCOI(pcop)->offset ); - } else - SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); - } else { - - if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) { - SAFE_snprintf(&s,&size,"(%s + %d)", - pcop->name, - PCOI(pcop)->index ); - } else { - if(PCOI(pcop)->offset) - SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); - else - SAFE_snprintf(&s,&size,"%s",pcop->name); - } - } - - return buffer; + s = buffer; + + if(PCOI(pcop)->_const) { + if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) { + SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)", + pcop->name, + PCOI(pcop)->index, + 8 * PCOI(pcop)->offset ); + } else + SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); + } else { + if( PCOI(pcop)->index) { + SAFE_snprintf(&s,&size,"(%s + %d)", + pcop->name, + PCOI(pcop)->index ); + } else { + if(PCOI(pcop)->offset) + SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); + else + SAFE_snprintf(&s,&size,"%s",pcop->name); + } + } + return buffer; #endif - - case PO_DIR: - s = buffer; - //size = sizeof(buffer); - if( PCOR(PCOR2(pcop)->pcop2)->instance) { - SAFE_snprintf(&s,&size,"(%s + %d)", - PCOR(PCOR2(pcop)->pcop2)->r->name, - PCOR(PCOR2(pcop)->pcop2)->instance ); - } - //fprintf(stderr,"PO_DIR %s\n",buffer); - else - SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); - return buffer; - - default: -#if 0 - if (PCOR2(pcop)->r1->name) { - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR2(pcop)->r1->name); - return buffer; + case PO_DIR: + s = buffer; + if( PCOR(PCOR2(pcop)->pcop2)->instance) { + SAFE_snprintf(&s,&size,"(%s + %d)", + PCOR(PCOR2(pcop)->pcop2)->r->name, + PCOR(PCOR2(pcop)->pcop2)->instance ); + } else { + SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); + } + return buffer; + + default: + if(PCOR(PCOR2(pcop)->pcop2)->r->name) { + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); + return buffer; + } + return PCOR(PCOR2(pcop)->pcop2)->r->name; + } + } } - return PCOR2(pcop)->r1->name; - } -#else - break; -#endif - } - } - - return "NO operand"; + return "NO operand2"; } /*-----------------------------------------------------------------*/ @@ -4275,7 +4233,7 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *pc) SAFE_snprintf(&s,&size,"(1 << (%s & 7))",pic16_get_op_from_instruction(PCI(pc))); }else { - SAFE_snprintf(&s,&size,"%s",pic16_get_op_from_instruction(PCI(pc))); + SAFE_snprintf(&s,&size,"%s", pic16_get_op_from_instruction(PCI(pc))); if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) { if(PCI(pc)->num_ops == 3) @@ -4368,7 +4326,6 @@ static void genericPrint(FILE *of, pCode *pc) pic16_pCode2str(str, 256, pc); fprintf(of,"%s",str); - /* Debug */ if(pic16_debug_verbose) { fprintf(of, "\t;key=%03x",pc->seq); @@ -4897,7 +4854,15 @@ regs * pic16_getRegFromInstruction(pCode *pc) (PCI(pc)->num_ops == 1 && PCI(pc)->isFastCall)) return NULL; +#if 0 + fprintf(stderr, "pic16_getRegFromInstruction - reg type %s (%d)\n", + dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type); +#endif + switch(PCI(pc)->pcop->type) { + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: case PO_FSR0: return PCOR(PCI(pc)->pcop)->r; @@ -4928,13 +4893,13 @@ regs * pic16_getRegFromInstruction(pCode *pc) break; default: - //fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type); - //genericPrint(stderr, pc); +// fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type); +// genericPrint(stderr, pc); +// assert( 0 ); break; } return NULL; - } /*-------------------------------------------------------------------------------*/ @@ -4951,6 +4916,11 @@ regs * pic16_getRegFromInstruction2(pCode *pc) return NULL; +#if 0 + fprintf(stderr, "pic16_getRegFromInstruction2 - reg type %s (%d)\n", + dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type); +#endif + /* * operands supported in MOVFF: * PO_INF0/PO_FSR0 @@ -4960,6 +4930,9 @@ regs * pic16_getRegFromInstruction2(pCode *pc) * */ switch(PCI(pc)->pcop->type) { + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: case PO_FSR0: return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r; @@ -4968,17 +4941,17 @@ regs * pic16_getRegFromInstruction2(pCode *pc) // case PO_BIT: case PO_GPR_TEMP: - //fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n"); + //fprintf(stderr, "pic16_getRegFromInstruction2 - bit or temp\n"); return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r; case PO_IMMEDIATE: - break; -#if 0 - if(PCOI(PCI(pc)->pcop)->r) - return (PCOI(PCI(pc)->pcop)->r); +// break; +#if 1 +// if(PCOI(PCI(pc)->pcop)->r) +// return (PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r); - //fprintf(stderr, "pic16_getRegFromInstruction - immediate\n"); - return pic16_dirregWithName(PCI(pc)->pcop->name); + //fprintf(stderr, "pic16_getRegFromInstruction2 - immediate\n"); + return pic16_dirregWithName(PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r->name); //return NULL; // PCOR(PCI(pc)->pcop)->r; #endif @@ -4987,15 +4960,15 @@ regs * pic16_getRegFromInstruction2(pCode *pc) // return PCOR2(PCI(pc)->pcop)->r; case PO_DIR: - //fprintf(stderr, "pic16_getRegFromInstruction - dir\n"); + //fprintf(stderr, "pic16_getRegFromInstruction2 - dir\n"); return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r; case PO_LITERAL: break; - //fprintf(stderr, "pic16_getRegFromInstruction - literal\n"); + //fprintf(stderr, "pic16_getRegFromInstruction2 - literal\n"); default: - //fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type); + //fprintf(stderr, "pic16_getRegFromInstruction2 - unknown reg type %d\n",PCI(pc)->pcop->type); //genericPrint(stderr, pc); break; } @@ -5512,7 +5485,7 @@ static void insertBankSwitch(int position, pCode *pc, int bsr) reg = pic16_getRegFromInstruction(pc); if(!reg)return; - new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", reg->name); + new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", pic16_get_op_from_instruction(PCI(pc))); position = 0; // position is always before (sanity check!) } @@ -5702,7 +5675,7 @@ static pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs) for(pc = pcs; pc; pc = pc->next) { - if((pc->type == PC_OPCODE) && + if(((pc->type == PC_OPCODE) || (pc->type == PC_INLINE)) && (PCI(pc)->pcop) && (PCI(pc)->pcop->type == PO_LABEL) && (PCOLAB(PCI(pc)->pcop)->key == pcl->key)) @@ -5726,7 +5699,7 @@ static void exchangeLabels(pCodeLabel *pcl, pCode *pc) pCodeOpLabel *pcol = PCOLAB(PCI(pc)->pcop); - //fprintf(stderr,"changing label key from %d to %d\n",pcol->key, pcl->key); +// fprintf(stderr,"changing label key from %d to %d\n",pcol->key, pcl->key); if(pcol->pcop.name) free(pcol->pcop.name); @@ -5795,7 +5768,7 @@ static void pBlockRemoveUnusedLabels(pBlock *pb) pcl = PCL(PCI(pc)->label->pc); else continue; - //fprintf(stderr," found A LABEL !!! key = %d, %s\n", pcl->key,pcl->label); + //fprintf(stderr," found A LABEL !!! key = %d, %s\n", pcl->key,pcl->label); /* This pCode is a label, so search the pBlock to see if anyone * refers to it */ @@ -6932,3 +6905,39 @@ void pic16_InlinepCode(void) unBuildFlow(pb); } + +char *pic_optype_names[]={ + "PO_NONE", // No operand e.g. NOP + "PO_W", // The working register (as a destination) + "PO_WREG", // The working register (as a file register) + "PO_STATUS", // The 'STATUS' register + "PO_BSR", // The 'BSR' register + "PO_FSR0", // The "file select register" (in PIC18 family it's one + // of three) + "PO_INDF0", // The Indirect register + "PO_INTCON", // Interrupt Control register + "PO_GPR_REGISTER", // A general purpose register + "PO_GPR_BIT", // A bit of a general purpose register + "PO_GPR_TEMP", // A general purpose temporary register + "PO_SFR_REGISTER", // A special function register (e.g. PORTA) + "PO_PCL", // Program counter Low register + "PO_PCLATH", // Program counter Latch high register + "PO_PCLATU", // Program counter Latch upper register + "PO_PRODL", // Product Register Low + "PO_PRODH", // Product Register High + "PO_LITERAL", // A constant + "PO_REL_ADDR", // A relative address + "PO_IMMEDIATE", // (8051 legacy) + "PO_DIR", // Direct memory (8051 legacy) + "PO_CRY", // bit memory (8051 legacy) + "PO_BIT", // bit operand. + "PO_STR", // (8051 legacy) + "PO_LABEL", + "PO_WILD" // Wild card operand in peep optimizer +}; + + +char *dumpPicOptype(PIC_OPTYPE type) +{ + return (pic_optype_names[ type ]); +} diff --git a/src/pic16/pcode.h b/src/pic16/pcode.h index ecb554f9..4d2ce533 100644 --- a/src/pic16/pcode.h +++ b/src/pic16/pcode.h @@ -157,6 +157,9 @@ typedef enum PO_SFR_REGISTER, // A special function register (e.g. PORTA) PO_PCL, // Program counter Low register PO_PCLATH, // Program counter Latch high register + PO_PCLATU, // Program counter Latch upper register + PO_PRODL, // Product Register Low + PO_PRODH, // Product Register High PO_LITERAL, // A constant PO_REL_ADDR, // A relative address PO_IMMEDIATE, // (8051 legacy) @@ -371,7 +374,7 @@ typedef struct pCodeOpLit2 typedef struct pCodeOpImmd { pCodeOp pcop; - int offset; /* low,med, or high byte of immediat value */ + int offset; /* low,high or upper byte of immediate value */ int index; /* add this to the immediate value */ unsigned _const:1; /* is in code space */ @@ -921,6 +924,7 @@ extern pCodeOpReg pic16_pc_intcon; extern pCodeOpReg pic16_pc_pcl; extern pCodeOpReg pic16_pc_pclath; extern pCodeOpReg pic16_pc_wreg; +extern pCodeOpReg pic16_pc_bsr; extern pCodeOpReg pic16_pc_fsr0; extern pCodeOpReg pic16_pc_fsr0l; extern pCodeOpReg pic16_pc_fsr0h; @@ -943,6 +947,8 @@ extern pCodeOpReg pic16_pc_postinc2; extern pCodeOpReg pic16_pc_postdec2; extern pCodeOpReg pic16_pc_preinc2; extern pCodeOpReg pic16_pc_plusw2; +extern pCodeOpReg pic16_pc_prodl; +extern pCodeOpReg pic16_pc_prodh; extern pCodeOpReg pic16_pc_kzero; extern pCodeOpReg pic16_pc_wsave; /* wsave and ssave are used to save W and the Status */ diff --git a/src/pic16/pcodepeep.c b/src/pic16/pcodepeep.c index 4b6c1a96..69aac418 100644 --- a/src/pic16/pcodepeep.c +++ b/src/pic16/pcodepeep.c @@ -939,9 +939,9 @@ static void tokenizeLineNode(char *ln) if(!ln || !*ln) return; +// fprintf(stderr, "%s:%d: processing %s\n", __FILE__, __LINE__, ln); while(*ln) { - if(isspace(*ln)) { // add a SPACE token and eat the extra spaces. tokArr[tokIdx++].tt = PCT_SPACE; @@ -2196,6 +2196,9 @@ pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop) case PO_INTCON: case PO_PCL: case PO_PCLATH: + case PO_PCLATU: + case PO_PRODL: + case PO_PRODH: case PO_REL_ADDR: //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type)); pcopnew = Safe_calloc(1,sizeof(pCodeOp) ); diff --git a/src/pic16/pcoderegs.c b/src/pic16/pcoderegs.c index 0a772a8d..a4b5b259 100644 --- a/src/pic16/pcoderegs.c +++ b/src/pic16/pcoderegs.c @@ -170,6 +170,7 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) if(reg) { #if 0 + fprintf(stderr, "reg= %p\n", reg); fprintf(stderr, "flow seq %d, inst seq %d %s ",PCODE(pcfl)->seq,pc->seq,reg->name); fprintf(stderr, "addr = 0x%03x, type = %d rIdx=0x%03x", reg->address,reg->type,reg->rIdx); @@ -184,7 +185,7 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) if(PCC_REGISTER & PCI(pc)->outCond) addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl); - + addSetIfnotP(& (reg->reglives.usedpCodes), pc); #if 1 @@ -195,6 +196,13 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) // fprintf(stderr, "trying to get second operand from pCode reg= %s\n", reg->name); addSetIfnotP(& (PCFL(pcfl)->registers), reg); + + if((PCC_REGISTER | PCC_LITERAL) & PCI(pc)->inCond) + addSetIfnotP(& (reg->reglives.usedpFlows), pcfl); + + if(PCC_REGISTER & PCI(pc)->outCond) + addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl); + addSetIfnotP(& (reg->reglives.usedpCodes), pc); } @@ -677,12 +685,13 @@ static void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_l * instructions are examined. If possible, they're optimized out. */ -/* +#if 0 fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n", reg->name, reg->address, reg->rIdx, reg->type, used); -*/ +#endif + pc1 = setFirstItem(reg->reglives.usedpCodes); pc2 = setNextItem(reg->reglives.usedpCodes); @@ -712,7 +721,7 @@ static void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_l //fprintf(stderr,"WARNING %s: reg %s used without being assigned\n",__FUNCTION__,reg->name); } else { - //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name); +// fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name); Remove2pcodes(pcfl_assigned, pc1, pc2, reg, 1); total_registers_saved++; // debugging stats. } diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 58b8906b..0a7a9413 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -46,7 +46,7 @@ /* since the pack the registers depending strictly on the MCU */ /*-----------------------------------------------------------------*/ -static regs *typeRegWithIdx (int idx, int type, int fixed); +regs *pic16_typeRegWithIdx (int idx, int type, int fixed); extern void genpic16Code (iCode *); extern void pic16_assignConfigWordValue(int address, int value); @@ -78,9 +78,10 @@ set *pic16_dynInternalRegs=NULL; static hTab *dynDirectRegNames= NULL; //static hTab *regHash = NULL; /* a hash table containing ALL registers */ -set *pic16_rel_udata=NULL; -set *pic16_fix_udata=NULL; -set *pic16_equ_data=NULL; +set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */ +set *pic16_fix_udata=NULL; /* absolute uninitialized registers */ +set *pic16_equ_data=NULL; /* registers used by equates */ +set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */ set *pic16_builtin_functions=NULL; @@ -488,12 +489,8 @@ allocReg (short type) return NULL; #endif -#if STACK_SUPPORT - if(USE_STACK) { - /* try to reuse some unused registers */ - reg = regFindFree( pic16_dynAllocRegs ); - } -#endif + /* try to reuse some unused registers */ + reg = regFindFree( pic16_dynAllocRegs ); if(!reg) { reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL); @@ -501,7 +498,7 @@ allocReg (short type) } reg->isFree=0; - debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); +// debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n", // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree); @@ -511,10 +508,8 @@ allocReg (short type) reg->isLocal = 1; /* this is a local frame register */ } -#if STACK_SUPPORT if (currFunc) currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx); -#endif return (reg); // addSet(&pic16_dynAllocRegs,reg); @@ -661,11 +656,14 @@ pic16_allocDirReg (operand *op ) // reg->type = REG_SFR; // } - if (IS_BITVAR (OP_SYM_ETYPE(op))) { - addSet(&pic16_dynDirectBitRegs, reg); - reg->isBitField = 1; - } else - addSet(&pic16_dynDirectRegs, reg); + if (IS_BITVAR (OP_SYM_ETYPE(op))) { +// fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name); + addSet(&pic16_dynDirectBitRegs, reg); + reg->isBitField = 1; + } else { +// fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name); + checkAddReg(&pic16_dynDirectRegs, reg); + } } else { debugLog (" -- %s is declared at address 0x30000x\n",name); @@ -722,8 +720,7 @@ pic16_allocRegByName (char *name, int size) /*-----------------------------------------------------------------*/ /* RegWithIdx - returns pointer to register with index number */ /*-----------------------------------------------------------------*/ -static regs * -typeRegWithIdx (int idx, int type, int fixed) +regs *pic16_typeRegWithIdx (int idx, int type, int fixed) { regs *dReg; @@ -774,13 +771,13 @@ pic16_regWithIdx (int idx) { regs *dReg; - if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL) + if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL) return dReg; - if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL) + if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL) return dReg; - if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL) + if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL) return dReg; return NULL; @@ -930,7 +927,7 @@ extern void pic16_groupRegistersInSection(set *regset); extern void pic16_dump_equates(FILE *of, set *equs); //extern void pic16_dump_map(void); extern void pic16_dump_section(FILE *of, set *section, int fix); - +extern void pic16_dump_int_registers(FILE *of, set *section); static void packBits(set *bregs) { @@ -953,7 +950,7 @@ static void packBits(set *bregs) if(breg->isFixed) { //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address); - bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1); + bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1); breg->rIdx = breg->address & 7; breg->address >>= 3; @@ -1082,18 +1079,15 @@ void pic16_writeUsedRegs(FILE *of) // pic16_dump_map(); // pic16_dump_cblock(of); + /* dump equates */ pic16_dump_equates(of, pic16_equ_data); + /* dump internal registers */ + pic16_dump_int_registers(of, pic16_int_regs); + + /* dump other variables */ pic16_dump_section(of, pic16_rel_udata, 0); pic16_dump_section(of, pic16_fix_udata, 1); - -#if 0 - bitEQUs(of,pic16_dynDirectBitRegs); - aliasEQUs(of,pic16_dynAllocRegs,0); - aliasEQUs(of,pic16_dynDirectRegs,0); - aliasEQUs(of,pic16_dynStackRegs,0); - aliasEQUs(of,pic16_dynProcessorRegs,1); -#endif } @@ -2800,14 +2794,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } -#if 0 - if(ic->op == CALL || ic->op == PCALL) { - addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic))); - debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name); - return 0; - } -#endif - /* find the definition of iTempNN scanning backwards if we find a a use of the true symbol before we find the definition then we cannot pack */ @@ -2874,6 +2860,17 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } #endif + +#if 1 + if( IS_SYMOP( IC_RESULT(dic)) && + IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) { + + debugLog (" %d - result is bitfield\n", __LINE__); + dic = NULL; + break; + } +#endif + if (IS_SYMOP (IC_RESULT (dic)) && IC_RESULT (dic)->key == IC_RIGHT (ic)->key) { @@ -2917,6 +2914,25 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (!dic) return 0; /* did not find */ +#if 1 + /* This code is taken from the hc08 port. Do not know + * if it fits for pic16, but I leave it here just in case */ + + /* if assignment then check that right is not a bit */ + if (ASSIGNMENT (dic) && !POINTER_SET (dic)) { + sym_link *etype = operandType (IC_RIGHT (dic)); + + if (IS_BITFIELD (etype)) { + /* if result is a bit too then it's ok */ + etype = operandType (IC_RESULT (dic)); + if (!IS_BITFIELD (etype)) { + debugLog(" %d bitfields\n"); + return 0; + } + } + } +#endif + /* if the result is on stack or iaccess then it must be the same atleast one of the operands */ if (OP_SYMBOL (IC_RESULT (ic))->onStack || @@ -3144,7 +3160,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* only upto 2 bytes since we cannot predict the usage of b, & acc */ - if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) && + if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */ ic->op != RETURN && ic->op != SEND) return NULL; @@ -3410,6 +3426,7 @@ packRegsForAccUse (iCode * ic) IC_LEFT (uic)->key != IC_RESULT (ic)->key) return; +#if 1 debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* if one of them is a literal then we can */ if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) || @@ -3419,6 +3436,7 @@ packRegsForAccUse (iCode * ic) OP_SYMBOL (IC_RESULT (ic))->accuse = 1; return; } +#endif debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* if the other one is not on stack then we can */ @@ -3560,11 +3578,15 @@ static void isData(sym_link *sl) } } -#define NO_packRegsForSupport 1 -#define NO_packRegsForAccUse 1 -#define NO_packRegsForOneuse 1 -#define NO_cast_peep 1 +/* set if conditional to 1 to disable optimizations */ + +#define NO_packRegsForAccUse +#if 0 +#define NO_packRegsForSupport +#define NO_packRegsForOneuse +//#define NO_cast_peep +#endif /*--------------------------------------------------------------------*/ /* pic16_packRegisters - does some transformations to reduce */ /* register pressure */ @@ -3648,6 +3670,19 @@ pic16_packRegisters (eBBlock * ebp) printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type); } + if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) { + debugAopGet (" right:", IC_RIGHT (ic)); + printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type); +// pic16_allocDirReg(IC_RIGHT(ic)); + } + + if(IS_TRUE_SYMOP ( IC_RESULT(ic))) { + debugAopGet (" result:", IC_RESULT (ic)); + printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type); +// pic16_allocDirReg(IC_RESULT(ic)); + } + + if (POINTER_SET (ic)) debugLog (" %d - Pointer set\n", __LINE__); @@ -3768,7 +3803,7 @@ pic16_packRegisters (eBBlock * ebp) debugLog(" %d\n", __LINE__); -#if NO_packRegsForSupport +#ifndef NO_packRegsForSupport /* reduce for support function calls */ if (ic->supportRtn || ic->op == '+' || ic->op == '-') packRegsForSupport (ic, ebp); @@ -3779,7 +3814,7 @@ pic16_packRegisters (eBBlock * ebp) if (ic->op == RECEIVE) packForReceive (ic, ebp); -#if NO_packRegsForOneuse +#ifndef NO_packRegsForOneuse /* some cases the redundant moves can can be eliminated for return statements */ if ((ic->op == RETURN || ic->op == SEND) && @@ -3788,7 +3823,7 @@ pic16_packRegisters (eBBlock * ebp) packRegsForOneuse (ic, IC_LEFT (ic), ebp); #endif -#if NO_packRegsForOneuse +#ifndef NO_packRegsForOneuse /* if pointer set & left has a size more than one and right is not in far space */ if (POINTER_SET (ic) && @@ -3800,7 +3835,7 @@ pic16_packRegisters (eBBlock * ebp) packRegsForOneuse (ic, IC_RESULT (ic), ebp); #endif -#if NO_packRegsForOneuse +#ifndef NO_packRegsForOneuse /* if pointer get */ if (POINTER_GET (ic) && !isOperandInFarSpace (IC_RESULT (ic)) && @@ -3812,7 +3847,7 @@ pic16_packRegisters (eBBlock * ebp) debugLog("%d - return from packRegsForOneuse\n", __LINE__); #endif -#if NO_cast_peep +#ifndef NO_cast_peep /* if this is cast for intergral promotion then check if only use of the definition of the operand being casted/ if yes then replace @@ -3882,7 +3917,7 @@ pic16_packRegisters (eBBlock * ebp) } -#if NO_packRegsForAccUse +#ifndef NO_packRegsForAccUse /* pack registers for accumulator use, when the result of an arithmetic or bit wise operation has only one use, that use is immediately following @@ -3899,7 +3934,7 @@ pic16_packRegisters (eBBlock * ebp) ) && IS_ITEMP (IC_RESULT (ic)) && - getSize (operandType (IC_RESULT (ic))) <= 2) + getSize (operandType (IC_RESULT (ic))) <= 1) packRegsForAccUse (ic); #endif diff --git a/src/pic16/ralloc.h b/src/pic16/ralloc.h index e500dcd3..b337893f 100644 --- a/src/pic16/ralloc.h +++ b/src/pic16/ralloc.h @@ -31,8 +31,6 @@ #include "pcoderegs.h" -/* set STACK_SUPPORT to 1 to compile code for stack */ -#define STACK_SUPPORT 1 extern unsigned int stackPos; enum @@ -108,8 +106,10 @@ extern set *pic16_builtin_functions; extern set *pic16_rel_udata; extern set *pic16_fix_udata; extern set *pic16_equ_data; +extern set *pic16_int_regs; regs *pic16_regWithIdx (int); +regs *pic16_typeRegWithIdx(int, int, int); regs *pic16_dirregWithName (char *name ); void pic16_freeAllRegs (); void pic16_deallocateAllRegs (); @@ -119,12 +119,12 @@ regs *pic16_allocWithIdx (int idx); regs *pic16_allocDirReg (operand *op ); regs *pic16_allocRegByName (char *name, int size ); +regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop); + /* Define register address that are constant across PIC16 family */ #define IDX_TMR0 0xfd6 #define IDX_PCL 0xff9 #define IDX_STATUS 0xfd8 -#define IDX_PORTA 0xf80 -#define IDX_PORTB 0xf81 #define IDX_PCLATH 0xffa #define IDX_INTCON 0xff2 #define IDX_WREG 0xfe8 @@ -155,6 +155,9 @@ regs *pic16_allocRegByName (char *name, int size ); #define IDX_PREINC2 0xfdc #define IDX_PLUSW2 0xfdb +#define IDX_PRODL 0xff3 +#define IDX_PRODH 0xff4 + #define IDX_KZ 0x7fff /* Known zero - actually just a general purpose reg. */ #define IDX_WSAVE 0x7ffe #define IDX_SSAVE 0x7ffd -- 2.30.2