]> git.gag.com Git - fw/sdcc/commitdiff
* doc/sdccman.lyx: removed PIC16 from PIC16 Port Specific Options,
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 20 Feb 2004 00:48:07 +0000 (00:48 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 20 Feb 2004 00:48:07 +0000 (00:48 +0000)
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

18 files changed:
ChangeLog
doc/sdccman.lyx
src/pic16/NOTES
src/pic16/device.c
src/pic16/device.h
src/pic16/gen.c
src/pic16/gen.h
src/pic16/genarith.c
src/pic16/genutils.c
src/pic16/genutils.h
src/pic16/glue.c
src/pic16/main.c
src/pic16/pcode.c
src/pic16/pcode.h
src/pic16/pcodepeep.c
src/pic16/pcoderegs.c
src/pic16/ralloc.c
src/pic16/ralloc.h

index 5a65af7b561913c38c86987637aef63a37197a35..9e197ce334a4630f1421c5d2e0449ba5a5f27ad5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,98 @@
+2004-02-20 Vangelis Rokas <vrokas AT otenet.gr>
+          Hans-Juergen Dorn <hans.dorn AT apl-landau.de>
+
+       * 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 <jesusc AT ece.ubc.ca>
 
        * as/mcs51/aslink.h, as/mcs51/lkarea.c, as/mcs51/lkdata.c, as/mcs51/lkmain.c,
index b6bfc0289cd839e5adc96a29c4cd701a7343efa2..36fecf54ac542d5eb85f9fbc46728b920f7147c6 100644 (file)
@@ -1718,10 +1718,10 @@ Install paths
 \begin_inset  Tabular
 <lyxtabular version="3" rows="5" columns="4">
 <features>
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \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
 <lyxtabular version="3" rows="11" columns="2">
 <features>
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \begin_inset Text
@@ -12595,8 +12554,8 @@ SDCC supports IEEE (single precision 4 bytes) floating point numbers.The
 \begin_inset  Tabular
 <lyxtabular version="3" rows="17" columns="2">
 <features>
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \begin_inset Text
@@ -13918,8 +13877,8 @@ The compiler creates the following #defines
 \begin_inset  Tabular
 <lyxtabular version="3" rows="10" columns="2">
 <features>
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \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
 <lyxtabular version="3" rows="2" columns="2">
 <features>
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \begin_inset Text
@@ -14985,10 +14919,10 @@ PIC16 port uses the following directories for searching header files and
 \begin_inset  Tabular
 <lyxtabular version="3" rows="3" columns="4">
 <features>
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \begin_inset Text
@@ -15023,7 +14957,7 @@ Command prefix
 \end_inset 
 </cell>
 </row>
-<row topline="true" bottomline="true">
+<row topline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \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
 <lyxtabular version="3" rows="3" columns="3">
 <features>
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \begin_inset Text
@@ -15359,9 +15296,9 @@ large
 \begin_inset  Tabular
 <lyxtabular version="3" rows="3" columns="3">
 <features>
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \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
 <lyxtabular version="3" rows="6" columns="2">
 <features>
-<column alignment="center" valignment="top" leftline="true" width="0(null)">
-<column alignment="center" valignment="top" leftline="true" rightline="true" width="0(null)">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \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
 <lyxtabular version="3" rows="10" columns="2">
 <features>
-<column alignment="left" valignment="top" leftline="true" width="0(null)">
+<column alignment="left" valignment="top" leftline="true" width="0">
 <column alignment="left" valignment="top" leftline="true" rightline="true" width="0pt">
 <row topline="true" bottomline="true">
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
index d49eb7e5747606b1e7166359482f694008d30f03..c2ce6ca38cce167212b1c1b6295e77923a120711 100644 (file)
@@ -11,10 +11,32 @@ For any questions please ask the current port
 developers.
 
 Current developer:
-Vangelis Rokas <vrokas@otenet.gr>
+Vangelis Rokas <vrokas AT otenet.gr>
 
 Other people to contact:
-Scott Dattalo  <scott@dattalo.com>
+Scott Dattalo  <scott AT dattalo.com>
+
+======================================================================
+======================================================================
+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.
 
 
 
index d7e500db220cc206144d42f29596763b2882d2d6..6a5c7006b31fcae72178edab4214a0f8f0f1a0fc 100644 (file)
 #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);
                        }
                }
        }
index 5ec7798657330618ab4ed53670b774e9edf23e71..d2bef36f57d6eaa1e05701e374d1a961ae0a25a1 100644 (file)
 #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__ */
index e0cde477cbe746caf41159ebb9779806b7e5e2bf..7bf945e7936df44996af7bb80e174cf227c319c9 100644 (file)
@@ -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
index 54ed8d2061b62855ab491700c6a41642f602cafb..e942384ddc66886948a90ae04d880985df218255 100644 (file)
@@ -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 
index ea7f5725f867f62ca031efc0c34c97caf38e46dc..2015eb59ceccf527ff61af8d749146a7a3d2512e 100644 (file)
@@ -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; i<size; i++) {
+                               if (AOP_TYPE(right) == AOP_ACC) {
+                                       pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
+                               } else {
+                                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
+                                       if(i) { // add with carry
+                                               pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
+                                       } else { // add without
+                                               pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
+                                       }
+                               }
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+                       }
+
+                       // add leftover bytes
+                       if (SPEC_USIGN(getSpec(operandType(right)))) {
+                               // right is unsigned
+                               for(i=size; i< AOP_SIZE(result); i++) {
+                                       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+                                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
+                                       pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
+                               }
+
+                       } else {
+                               // right is signed, oh dear ...
+                               for(i=size; i< AOP_SIZE(result); i++) {
+                                       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+                                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0));
+                                       pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
+                                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
+                                       pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
+                               }
+
+                       }
+                       goto release;
+
+               } else {
+                       // add regs
+
+                       // add first bytes
+                       for(i=0; i<size; i++) {
+                               if (AOP_TYPE(right) != AOP_ACC)
+                                       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
+                               if (pic16_sameRegs(AOP(left), AOP(result)))
+                               {
+                                       if(i) { // add with carry
+                                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
+                                       } else { // add without
+                                               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
+                                       }
+                               } else { // not same
+                                       if(i) { // add with carry
+                                               pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
+                                       } else { // add without
+                                               pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
+                                       }
+                                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+                               }
+                       }
+
+                       // add leftover bytes
+                       if (SPEC_USIGN(getSpec(operandType(right)))) {
+                               // right is unsigned
+                               for(i=size; i< AOP_SIZE(result); i++) {
+                                       if (pic16_sameRegs(AOP(left), AOP(result)))
+                                       {
+                                               pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+                                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
+                                       } else { // not same
+                                               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
+                                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
+                                       }
+                               }
+                       } else {
+                               // right is signed
+                               for(i=size; i< AOP_SIZE(result); i++) {
+                                       pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+                                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0));
+                                       pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
+                                       if (pic16_sameRegs(AOP(left), AOP(result)))
+                                       {
+                                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
+                                       } else { // not same
+                                               pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
+                                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+                                       }
+                               }
+                       }
+                       goto release;
+               }
 
-       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
-         pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
-       else {
-         PIC_OPCODE poc = POC_ADDFW;
-
-         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-             (AOP(IC_LEFT(ic))->aopu.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
 /*-----------------------------------------------------------------*/
index c79db38540b7adb378ebaa66c4bb64d03fe42dc7..25d645cfe43cde2bc1bd6c972a1565013f1afa7e 100644 (file)
@@ -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);
+       }
+
+}
index f6dc45ce59dd1ac89f48b5bc21735386306c2d0e..358c4ed2727259297b0291011593628025222644 100644 (file)
@@ -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__ */
index 8e071761f6abada623d58065a346366780488d22..c1a71805e3aa8e0256508d503ac68482d17d0c65 100644 (file)
@@ -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 */
index f8d50c9bc388d9364634b939b90dec27c1ce8854..86036f2d0f462f1b7e5e729b08089655692eb623 100644 (file)
@@ -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 != '*')
     {
index 7f54dbbdeb7dc877cd5018e6930516f5c742475c..9c4de584cdfe6b7a4d226cc233d6c8f57241ba65 100644 (file)
@@ -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 ]);
+}
index ecb554f9583dcc8b8e081fb6eb5ecc803eda8557..4d2ce533aeeb97dd3fe3198d2d2b9d37c251e4a5 100644 (file)
@@ -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 */
index 4b6c1a96e7c509c45a4b07bdb1d47e63f21dc388..69aac418fd87b7ef0c7f4b904fb50c5481122211 100644 (file)
@@ -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) );
index 0a772a8d7287d887977e78cde6b2198e38ea48db..a4b5b25955b9116a83964370a5d9627516f65330 100644 (file)
@@ -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.
       }
index 58b8906b91164bd655c32f76c228b3381a069d95..0a7a9413de5ba58ad915d50d6fccabad96a14d9d 100644 (file)
@@ -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
index e500dcd3f788b0e0f9ecaad95665f6b9173c8210..b337893f0550fab25b2dea07eb83ad8e48ccb66b 100644 (file)
@@ -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