+2008-04-17 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * device/lib/libsdcc.lib,
+ * device/lib/Makefile.in,
+ * support/regression/ports/mcs51-xstack-auto/spec.mk,
+ * device/lib/calloc.c: renamed to _calloc.c
+ * device/lib/free.c: renamed to _free.c
+ * device/lib/malloc.c: renamed to _malloc.c
+ * device/lib/realloc.c: renamed to _realloc.c
+ * src/ds390/gen.c (aopGet, aopPut, genPlusBits, genDataPointerSet,
+ genNearPointerSet, genPagedPointerSet): synchronized with mcs51/gen.c
+ * src/ds390/gen.c (popForBranch, genIfxJump, genCmp, genCmpEq, ifxForOp,
+ genAnd, genOr, genXor, genIfx, gen390Code): fixed bug 1509084
+ * src/mcs51/gen.c (popForBranch, genIfxJump, genCmp, genCmpEq,
+ ifxForOp, genAnd, genOr, genXor, genNearPointerGet,
+ genPagedPointerGet, genFarPointerGet, genCodePointerGet,
+ genGenPointerGet, genIfx, gen51Code): fixed bug 1509084
+ * src/ds390/gen.c,
+ * src/mcs51/gen.c: throughout cosmetic changes for syncing both
+ * src/SDCCsymt.h: updated IS_OP_RUONLY, IS_OP_ACCUSE
+ * support/regression/tests/bug1509084.c: new, added
+
2008-04-14 Maarten Brock <sourceforge.brock AT dse.nl>
* device/include/mcs51/cc2510fx.h: added _XPAGE
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_memcmp.c _memcpy.c _memmove.c _memset.c \
- _heap.c calloc.c malloc.c realloc.c free.c \
+ _heap.c _calloc.c _malloc.c _realloc.c _free.c \
printf_large.c sprintf.c vprintf.c puts.c gets.c \
printf_fast.c printf_fast_f.c printf_tiny.c printfl.c \
assert.c time.c bpx.c \
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_memcmp.c _memcpy.c _memmove.c _memset.c \
- calloc.c malloc.c realloc.c free.c \
+ _calloc.c _malloc.c _realloc.c _free.c \
printf_large.c sprintf.c vprintf.c puts.c gets.c \
assert.c time.c \
fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_uchar2fs.c _uint2fs.c _ulong2fs.c \
- _heap.c calloc.c malloc.c realloc.c free.c \
+ _heap.c _calloc.c _malloc.c _realloc.c _free.c \
puts.c gets.c \
printf_large.c puts.c gets.c \
assert.c time.c \
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_memcmp.c _memcpy.c _memmove.c _memset.c \
- _heap.c calloc.c malloc.c realloc.c free.c \
+ _heap.c _calloc.c _malloc.c _realloc.c _free.c \
printf_large.c sprintf.c vprintf.c puts.c gets.c \
assert.c time.c \
fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
--- /dev/null
+/*-------------------------------------------------------------------------
+ calloc.c - allocate cleared memory.
+
+ Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-------------------------------------------------------------------------*/
+
+#include <sdcc-lib.h>
+#include <malloc.h>
+#include <string.h>
+
+//--------------------------------------------------------------------
+//calloc function implementation for embedded system
+//Non-ANSI keywords are C51 specific.
+// __xdata - variable in external memory (just RAM)
+//--------------------------------------------------------------------
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+#define __xdata
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+ MEMHEADER * next;
+ MEMHEADER * prev;
+ unsigned int len;
+ unsigned char mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+
+#else
+
+#define MEMHEADER struct MAH// Memory Allocation Header
+
+MEMHEADER
+{
+ MEMHEADER __xdata * next;
+ unsigned int len;
+ unsigned char mem[];
+};
+
+#define HEADER_SIZE sizeof(MEMHEADER)
+
+#endif
+
+void __xdata * calloc (size_t nmemb, size_t size)
+{
+ register void __xdata * ptr;
+
+ ptr = malloc(nmemb * size);
+ if (ptr)
+ {
+ memset(ptr, 0, nmemb * size);
+ }
+ return ptr;
+}
+//END OF MODULE
--- /dev/null
+/*-------------------------------------------------------------------------
+ free.c - release allocated memory.
+
+ Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-------------------------------------------------------------------------*/
+
+#include <sdcc-lib.h>
+#include <malloc.h>
+
+#if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) || defined(SDCC_gbz80)
+ #define CRITICAL __critical
+#else
+ #define CRITICAL
+#endif
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+ MEMHEADER * next;
+ MEMHEADER * prev;
+ unsigned int len;
+ unsigned char mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+
+/* These variables are defined through the crt0 functions. */
+/* Base of this variable is the first byte of the heap. */
+extern MEMHEADER _sdcc_heap_start;
+/* Address of this variable is the last byte of the heap. */
+extern char _sdcc_heap_end;
+
+MEMHEADER * _sdcc_prev_memheader;
+// apart from finding the header
+// this function also finds it's predecessor
+MEMHEADER *
+_sdcc_find_memheader(void * p)
+{
+ register MEMHEADER * pthis;
+ if (!p)
+ return NULL;
+ pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header
+ _sdcc_prev_memheader = pthis->prev;
+
+ return (pthis);
+}
+
+void
+free (void *p)
+{
+ MEMHEADER *prev_header, *pthis;
+
+ if ( p ) //For allocated pointers only!
+ CRITICAL
+ {
+ pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header
+ if ( pthis->prev ) // For the regular header
+ {
+ prev_header = pthis->prev;
+ prev_header->next = pthis->next;
+ if (pthis->next)
+ {
+ pthis->next->prev = prev_header;
+ }
+ }
+ else
+ {
+ pthis->len = 0; //For the first header
+ }
+ }
+}
+
+#else
+
+ //--------------------------------------------------------------------
+ //Written by Dmitry S. Obukhov, 1997
+ //dso@usa.net
+ //--------------------------------------------------------------------
+ //Modified for SDCC by Sandeep Dutta, 1999
+ //sandeep.dutta@usa.net
+ //--------------------------------------------------------------------
+ //malloc and free functions implementation for embedded system
+ //Non-ANSI keywords are C51 specific.
+ // __xdata - variable in external memory (just RAM)
+ //--------------------------------------------------------------------
+
+ #define MEMHEADER struct MAH// Memory Allocation Header
+
+ MEMHEADER
+ {
+ MEMHEADER __xdata * next;
+ unsigned int len;
+ unsigned char mem[];
+ };
+
+ #define HEADER_SIZE sizeof(MEMHEADER)
+
+ //Static here means: can be accessed from this module only
+ extern MEMHEADER __xdata * _sdcc_first_memheader;
+
+ MEMHEADER __xdata * _sdcc_prev_memheader;
+ // apart from finding the header
+ // this function also finds it's predecessor
+ MEMHEADER __xdata * _sdcc_find_memheader(void __xdata * p)
+ {
+ register MEMHEADER __xdata * pthis;
+ register MEMHEADER __xdata * cur_header;
+
+ if (!p)
+ return NULL;
+ pthis = (MEMHEADER __xdata *) p;
+ pthis -= 1; //to start of header
+ cur_header = _sdcc_first_memheader;
+ _sdcc_prev_memheader = NULL;
+ while (cur_header && pthis != cur_header)
+ {
+ _sdcc_prev_memheader = cur_header;
+ cur_header = cur_header->next;
+ }
+ return (cur_header);
+ }
+
+ void free (void * p)
+ {
+ register MEMHEADER __xdata * pthis;
+
+ CRITICAL
+ {
+ pthis = _sdcc_find_memheader(p);
+ if (pthis) //For allocated pointers only!
+ {
+ if (!_sdcc_prev_memheader)
+ {
+ pthis->len = 0;
+ }
+ else
+ {
+ _sdcc_prev_memheader->next = pthis->next;
+ }
+ }
+ }
+ }
+ //END OF MODULE
+#endif
--- /dev/null
+/*-------------------------------------------------------------------------
+ malloc.c - allocate memory.
+
+ Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-------------------------------------------------------------------------*/
+
+#include <sdcc-lib.h>
+#include <malloc.h>
+
+#if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) || defined(SDCC_gbz80)
+ #define CRITICAL __critical
+#else
+ #define CRITICAL
+#endif
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+ MEMHEADER * next;
+ MEMHEADER * prev;
+ unsigned int len;
+ unsigned char mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+
+/* These variables are defined through the crt0 functions. */
+/* Base of this variable is the first byte of the heap. */
+extern MEMHEADER _sdcc_heap_start;
+/* Address of this variable is the last byte of the heap. */
+extern char _sdcc_heap_end;
+
+void
+_sdcc_heap_init(void)
+{
+ MEMHEADER *pbase = &_sdcc_heap_start;
+ unsigned int size = &_sdcc_heap_end - (char *)pbase;
+
+ pbase->next = (MEMHEADER *)((char *)pbase + size - HEADER_SIZE);
+ pbase->next->next = NULL; //And mark it as last
+ pbase->prev = NULL; //and mark first as first
+ pbase->len = 0; //Empty and ready.
+}
+
+void *
+malloc (unsigned int size)
+{
+ register MEMHEADER * current_header;
+ register MEMHEADER * new_header;
+ register void * ret;
+
+ if (size>(0xFFFF-HEADER_SIZE))
+ {
+ return NULL; //To prevent overflow in next line
+ }
+
+ size += HEADER_SIZE; //We need a memory for header too
+ current_header = &_sdcc_heap_start;
+
+ CRITICAL
+ {
+ while (1)
+ {
+ // current
+ // | len next
+ // v v v
+ //....*****.........******....
+ // ^^^^^^^^^
+ // spare
+
+ if ((((unsigned int)current_header->next) -
+ ((unsigned int)current_header) -
+ current_header->len) >= size)
+ { //if spare is more than needed
+ ret = ¤t_header->mem;
+ break;
+ }
+ current_header = current_header->next; //else try next
+ if (!current_header->next)
+ { //if end_of_list reached
+ ret = NULL;
+ break;
+ }
+ }
+
+ if (ret)
+ {
+ if (!current_header->len)
+ { //This code works only for first_header in the list and only
+ current_header->len = size; //for first allocation
+ }
+ else
+ {
+ //else create new header at the begin of spare
+ new_header = (MEMHEADER * )((char *)current_header + current_header->len);
+ new_header->next = current_header->next; //and plug it into the chain
+ new_header->prev = current_header;
+ current_header->next = new_header;
+ if (new_header->next)
+ {
+ new_header->next->prev = new_header;
+ }
+ new_header->len = size; //mark as used
+ ret = &new_header->mem;
+ }
+ }
+ }
+ return ret;
+}
+
+#else
+
+ //--------------------------------------------------------------------
+ //Written by Dmitry S. Obukhov, 1997
+ //dso@usa.net
+ //--------------------------------------------------------------------
+ //Modified for SDCC by Sandeep Dutta, 1999
+ //sandeep.dutta@usa.net
+ //--------------------------------------------------------------------
+ //malloc and free functions implementation for embedded system
+ //Non-ANSI keywords are C51 specific.
+ // __xdata - variable in external memory (just RAM)
+ //--------------------------------------------------------------------
+
+ #define MEMHEADER struct MAH// Memory Allocation Header
+
+ MEMHEADER
+ {
+ MEMHEADER __xdata * next;
+ unsigned int len;
+ unsigned char mem[];
+ };
+
+ #define HEADER_SIZE sizeof(MEMHEADER)
+
+ MEMHEADER __xdata * _sdcc_first_memheader = NULL;
+
+ extern __xdata char _sdcc_heap[];
+ extern const unsigned int _sdcc_heap_size;
+
+ static void init_dynamic_memory(void)
+ {
+ char __xdata * heap = (char __xdata *)_sdcc_heap;
+ unsigned int size = _sdcc_heap_size;
+
+ if ( !heap ) //Reserved memory starts at 0x0000 but that's NULL...
+ { //So, we lost one byte!
+ heap++;
+ size--;
+ }
+ _sdcc_first_memheader = (MEMHEADER __xdata * ) heap;
+ //Reserve a mem for last header
+ _sdcc_first_memheader->next = (MEMHEADER __xdata * )(heap + size - sizeof(MEMHEADER __xdata *));
+ _sdcc_first_memheader->next->next = (MEMHEADER __xdata * ) NULL; //And mark it as last
+ _sdcc_first_memheader->len = 0; //Empty and ready.
+ }
+
+ void __xdata * malloc (unsigned int size)
+ {
+ register MEMHEADER __xdata * current_header;
+ register MEMHEADER __xdata * new_header;
+ register void __xdata * ret;
+
+ if (size>(0xFFFF-HEADER_SIZE))
+ return (void __xdata *) NULL; //To prevent overflow in next line
+ size += HEADER_SIZE; //We need a memory for header too
+
+ if (!_sdcc_first_memheader)
+ init_dynamic_memory();
+
+ current_header = _sdcc_first_memheader;
+ CRITICAL
+ {
+ while (1)
+ {
+
+ // current
+ // | len next
+ // v v v
+ //....*****.........******....
+ // ^^^^^^^^^
+ // spare
+
+ if ((((unsigned int)current_header->next) -
+ ((unsigned int)current_header) -
+ current_header->len) >= size)
+ { //if spare is more than needed
+ ret = current_header->mem;
+ break;
+ }
+ current_header = current_header->next; //else try next
+ if (!current_header->next)
+ { //if end_of_list reached
+ ret = (void __xdata *) NULL;
+ break;
+ }
+ }
+ if (ret)
+ {
+ if (!current_header->len)
+ { //This code works only for first_header in the list and only
+ current_header->len = size; //for first allocation
+ }
+ else
+ { //else create new header at the begin of spare
+ new_header = (MEMHEADER __xdata * )((char __xdata *)current_header + current_header->len);
+ new_header->next = current_header->next; //and plug it into the chain
+ current_header->next = new_header;
+ new_header->len = size; //mark as used
+ ret = new_header->mem;
+ }
+ }
+ }
+ return ret;
+ }
+
+ //END OF MODULE
+#endif
--- /dev/null
+/*-------------------------------------------------------------------------
+ realloc.c - reallocate allocated memory.
+
+ Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-------------------------------------------------------------------------*/
+
+#include <sdcc-lib.h>
+#include <malloc.h>
+#include <string.h>
+
+#if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) || defined(SDCC_gbz80)
+ #define CRITICAL __critical
+#else
+ #define CRITICAL
+#endif
+
+//--------------------------------------------------------------------
+//realloc function implementation for embedded system
+//Non-ANSI keywords are C51 specific.
+// __xdata - variable in external memory (just RAM)
+//--------------------------------------------------------------------
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+#define __xdata
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+ MEMHEADER * next;
+ MEMHEADER * prev;
+ unsigned int len;
+ unsigned char mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+#define MEM(x) (&x->mem)
+
+#else
+
+#define MEMHEADER struct MAH// Memory Allocation Header
+
+MEMHEADER
+{
+ MEMHEADER __xdata * next;
+ unsigned int len;
+ unsigned char mem[];
+};
+
+#define HEADER_SIZE sizeof(MEMHEADER)
+#define MEM(x) (x->mem)
+
+#endif
+
+extern MEMHEADER __xdata * _sdcc_prev_memheader;
+
+// apart from finding the header
+// this function also finds it's predecessor
+extern MEMHEADER __xdata * _sdcc_find_memheader(void __xdata * p);
+
+void __xdata * realloc (void * p, size_t size)
+{
+ register MEMHEADER __xdata * pthis;
+ register MEMHEADER __xdata * pnew;
+ register void __xdata * ret;
+
+ CRITICAL
+ {
+ pthis = _sdcc_find_memheader(p);
+ if (pthis)
+ {
+ if (size > (0xFFFF-HEADER_SIZE))
+ {
+ ret = (void __xdata *) NULL; //To prevent overflow in next line
+ }
+ else
+ {
+ size += HEADER_SIZE; //We need a memory for header too
+
+ if ((((unsigned int)pthis->next) - ((unsigned int)pthis)) >= size)
+ {//if spare is more than needed
+ pthis->len = size;
+ ret = p;
+ }
+ else
+ {
+ if ((_sdcc_prev_memheader) &&
+ ((((unsigned int)pthis->next) -
+ ((unsigned int)_sdcc_prev_memheader) -
+ _sdcc_prev_memheader->len) >= size))
+ {
+ pnew = (MEMHEADER __xdata * )((char __xdata *)_sdcc_prev_memheader + _sdcc_prev_memheader->len);
+ _sdcc_prev_memheader->next = pnew;
+
+#if _SDCC_MALLOC_TYPE_MLH
+ pthis->next->prev = pnew;
+#endif
+
+ memmove(pnew, pthis, pthis->len);
+ pnew->len = size;
+ ret = MEM(pnew);
+ }
+ else
+ {
+ ret = malloc(size - HEADER_SIZE);
+ if (ret)
+ {
+ memcpy(ret, MEM(pthis), pthis->len - HEADER_SIZE);
+ free(p);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ret = malloc(size);
+ }
+ }
+ return ret;
+}
+//END OF MODULE
+++ /dev/null
-/*-------------------------------------------------------------------------
- calloc.c - allocate cleared memory.
-
- Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
-
-#include <sdcc-lib.h>
-#include <malloc.h>
-#include <string.h>
-
-//--------------------------------------------------------------------
-//calloc function implementation for embedded system
-//Non-ANSI keywords are C51 specific.
-// __xdata - variable in external memory (just RAM)
-//--------------------------------------------------------------------
-
-#if _SDCC_MALLOC_TYPE_MLH
-
-#define __xdata
-
-typedef struct _MEMHEADER MEMHEADER;
-
-struct _MEMHEADER
-{
- MEMHEADER * next;
- MEMHEADER * prev;
- unsigned int len;
- unsigned char mem;
-};
-
-#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
-
-#else
-
-#define MEMHEADER struct MAH// Memory Allocation Header
-
-MEMHEADER
-{
- MEMHEADER __xdata * next;
- unsigned int len;
- unsigned char mem[];
-};
-
-#define HEADER_SIZE sizeof(MEMHEADER)
-
-#endif
-
-void __xdata * calloc (size_t nmemb, size_t size)
-{
- register void __xdata * ptr;
-
- ptr = malloc(nmemb * size);
- if (ptr)
- {
- memset(ptr, 0, nmemb * size);
- }
- return ptr;
-}
-//END OF MODULE
+++ /dev/null
-/*-------------------------------------------------------------------------
- free.c - release allocated memory.
-
- Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
-
-#include <sdcc-lib.h>
-#include <malloc.h>
-
-#if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) || defined(SDCC_gbz80)
- #define CRITICAL __critical
-#else
- #define CRITICAL
-#endif
-
-#if _SDCC_MALLOC_TYPE_MLH
-
-typedef struct _MEMHEADER MEMHEADER;
-
-struct _MEMHEADER
-{
- MEMHEADER * next;
- MEMHEADER * prev;
- unsigned int len;
- unsigned char mem;
-};
-
-#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
-
-/* These variables are defined through the crt0 functions. */
-/* Base of this variable is the first byte of the heap. */
-extern MEMHEADER _sdcc_heap_start;
-/* Address of this variable is the last byte of the heap. */
-extern char _sdcc_heap_end;
-
-MEMHEADER * _sdcc_prev_memheader;
-// apart from finding the header
-// this function also finds it's predecessor
-MEMHEADER *
-_sdcc_find_memheader(void * p)
-{
- register MEMHEADER * pthis;
- if (!p)
- return NULL;
- pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header
- _sdcc_prev_memheader = pthis->prev;
-
- return (pthis);
-}
-
-void
-free (void *p)
-{
- MEMHEADER *prev_header, *pthis;
-
- if ( p ) //For allocated pointers only!
- CRITICAL
- {
- pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header
- if ( pthis->prev ) // For the regular header
- {
- prev_header = pthis->prev;
- prev_header->next = pthis->next;
- if (pthis->next)
- {
- pthis->next->prev = prev_header;
- }
- }
- else
- {
- pthis->len = 0; //For the first header
- }
- }
-}
-
-#else
-
- //--------------------------------------------------------------------
- //Written by Dmitry S. Obukhov, 1997
- //dso@usa.net
- //--------------------------------------------------------------------
- //Modified for SDCC by Sandeep Dutta, 1999
- //sandeep.dutta@usa.net
- //--------------------------------------------------------------------
- //malloc and free functions implementation for embedded system
- //Non-ANSI keywords are C51 specific.
- // __xdata - variable in external memory (just RAM)
- //--------------------------------------------------------------------
-
- #define MEMHEADER struct MAH// Memory Allocation Header
-
- MEMHEADER
- {
- MEMHEADER __xdata * next;
- unsigned int len;
- unsigned char mem[];
- };
-
- #define HEADER_SIZE sizeof(MEMHEADER)
-
- //Static here means: can be accessed from this module only
- extern MEMHEADER __xdata * _sdcc_first_memheader;
-
- MEMHEADER __xdata * _sdcc_prev_memheader;
- // apart from finding the header
- // this function also finds it's predecessor
- MEMHEADER __xdata * _sdcc_find_memheader(void __xdata * p)
- {
- register MEMHEADER __xdata * pthis;
- register MEMHEADER __xdata * cur_header;
-
- if (!p)
- return NULL;
- pthis = (MEMHEADER __xdata *) p;
- pthis -= 1; //to start of header
- cur_header = _sdcc_first_memheader;
- _sdcc_prev_memheader = NULL;
- while (cur_header && pthis != cur_header)
- {
- _sdcc_prev_memheader = cur_header;
- cur_header = cur_header->next;
- }
- return (cur_header);
- }
-
- void free (void * p)
- {
- register MEMHEADER __xdata * pthis;
-
- CRITICAL
- {
- pthis = _sdcc_find_memheader(p);
- if (pthis) //For allocated pointers only!
- {
- if (!_sdcc_prev_memheader)
- {
- pthis->len = 0;
- }
- else
- {
- _sdcc_prev_memheader->next = pthis->next;
- }
- }
- }
- }
- //END OF MODULE
-#endif
_atoi
_atol
_heap
-calloc
-malloc
-realloc
-free
+_calloc
+_malloc
+_realloc
+_free
serial
_autobaud
_startup
+++ /dev/null
-/*-------------------------------------------------------------------------
- malloc.c - allocate memory.
-
- Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
-
-#include <sdcc-lib.h>
-#include <malloc.h>
-
-#if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) || defined(SDCC_gbz80)
- #define CRITICAL __critical
-#else
- #define CRITICAL
-#endif
-
-#if _SDCC_MALLOC_TYPE_MLH
-
-typedef struct _MEMHEADER MEMHEADER;
-
-struct _MEMHEADER
-{
- MEMHEADER * next;
- MEMHEADER * prev;
- unsigned int len;
- unsigned char mem;
-};
-
-#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
-
-/* These variables are defined through the crt0 functions. */
-/* Base of this variable is the first byte of the heap. */
-extern MEMHEADER _sdcc_heap_start;
-/* Address of this variable is the last byte of the heap. */
-extern char _sdcc_heap_end;
-
-void
-_sdcc_heap_init(void)
-{
- MEMHEADER *pbase = &_sdcc_heap_start;
- unsigned int size = &_sdcc_heap_end - (char *)pbase;
-
- pbase->next = (MEMHEADER *)((char *)pbase + size - HEADER_SIZE);
- pbase->next->next = NULL; //And mark it as last
- pbase->prev = NULL; //and mark first as first
- pbase->len = 0; //Empty and ready.
-}
-
-void *
-malloc (unsigned int size)
-{
- register MEMHEADER * current_header;
- register MEMHEADER * new_header;
- register void * ret;
-
- if (size>(0xFFFF-HEADER_SIZE))
- {
- return NULL; //To prevent overflow in next line
- }
-
- size += HEADER_SIZE; //We need a memory for header too
- current_header = &_sdcc_heap_start;
-
- CRITICAL
- {
- while (1)
- {
- // current
- // | len next
- // v v v
- //....*****.........******....
- // ^^^^^^^^^
- // spare
-
- if ((((unsigned int)current_header->next) -
- ((unsigned int)current_header) -
- current_header->len) >= size)
- { //if spare is more than needed
- ret = ¤t_header->mem;
- break;
- }
- current_header = current_header->next; //else try next
- if (!current_header->next)
- { //if end_of_list reached
- ret = NULL;
- break;
- }
- }
-
- if (ret)
- {
- if (!current_header->len)
- { //This code works only for first_header in the list and only
- current_header->len = size; //for first allocation
- }
- else
- {
- //else create new header at the begin of spare
- new_header = (MEMHEADER * )((char *)current_header + current_header->len);
- new_header->next = current_header->next; //and plug it into the chain
- new_header->prev = current_header;
- current_header->next = new_header;
- if (new_header->next)
- {
- new_header->next->prev = new_header;
- }
- new_header->len = size; //mark as used
- ret = &new_header->mem;
- }
- }
- }
- return ret;
-}
-
-#else
-
- //--------------------------------------------------------------------
- //Written by Dmitry S. Obukhov, 1997
- //dso@usa.net
- //--------------------------------------------------------------------
- //Modified for SDCC by Sandeep Dutta, 1999
- //sandeep.dutta@usa.net
- //--------------------------------------------------------------------
- //malloc and free functions implementation for embedded system
- //Non-ANSI keywords are C51 specific.
- // __xdata - variable in external memory (just RAM)
- //--------------------------------------------------------------------
-
- #define MEMHEADER struct MAH// Memory Allocation Header
-
- MEMHEADER
- {
- MEMHEADER __xdata * next;
- unsigned int len;
- unsigned char mem[];
- };
-
- #define HEADER_SIZE sizeof(MEMHEADER)
-
- MEMHEADER __xdata * _sdcc_first_memheader = NULL;
-
- extern __xdata char _sdcc_heap[];
- extern const unsigned int _sdcc_heap_size;
-
- static void init_dynamic_memory(void)
- {
- char __xdata * heap = (char __xdata *)_sdcc_heap;
- unsigned int size = _sdcc_heap_size;
-
- if ( !heap ) //Reserved memory starts at 0x0000 but that's NULL...
- { //So, we lost one byte!
- heap++;
- size--;
- }
- _sdcc_first_memheader = (MEMHEADER __xdata * ) heap;
- //Reserve a mem for last header
- _sdcc_first_memheader->next = (MEMHEADER __xdata * )(heap + size - sizeof(MEMHEADER __xdata *));
- _sdcc_first_memheader->next->next = (MEMHEADER __xdata * ) NULL; //And mark it as last
- _sdcc_first_memheader->len = 0; //Empty and ready.
- }
-
- void __xdata * malloc (unsigned int size)
- {
- register MEMHEADER __xdata * current_header;
- register MEMHEADER __xdata * new_header;
- register void __xdata * ret;
-
- if (size>(0xFFFF-HEADER_SIZE))
- return (void __xdata *) NULL; //To prevent overflow in next line
- size += HEADER_SIZE; //We need a memory for header too
-
- if (!_sdcc_first_memheader)
- init_dynamic_memory();
-
- current_header = _sdcc_first_memheader;
- CRITICAL
- {
- while (1)
- {
-
- // current
- // | len next
- // v v v
- //....*****.........******....
- // ^^^^^^^^^
- // spare
-
- if ((((unsigned int)current_header->next) -
- ((unsigned int)current_header) -
- current_header->len) >= size)
- { //if spare is more than needed
- ret = current_header->mem;
- break;
- }
- current_header = current_header->next; //else try next
- if (!current_header->next)
- { //if end_of_list reached
- ret = (void __xdata *) NULL;
- break;
- }
- }
- if (ret)
- {
- if (!current_header->len)
- { //This code works only for first_header in the list and only
- current_header->len = size; //for first allocation
- }
- else
- { //else create new header at the begin of spare
- new_header = (MEMHEADER __xdata * )((char __xdata *)current_header + current_header->len);
- new_header->next = current_header->next; //and plug it into the chain
- current_header->next = new_header;
- new_header->len = size; //mark as used
- ret = new_header->mem;
- }
- }
- }
- return ret;
- }
-
- //END OF MODULE
-#endif
+++ /dev/null
-/*-------------------------------------------------------------------------
- realloc.c - reallocate allocated memory.
-
- Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
-
-#include <sdcc-lib.h>
-#include <malloc.h>
-#include <string.h>
-
-#if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) || defined(SDCC_gbz80)
- #define CRITICAL __critical
-#else
- #define CRITICAL
-#endif
-
-//--------------------------------------------------------------------
-//realloc function implementation for embedded system
-//Non-ANSI keywords are C51 specific.
-// __xdata - variable in external memory (just RAM)
-//--------------------------------------------------------------------
-
-#if _SDCC_MALLOC_TYPE_MLH
-
-#define __xdata
-
-typedef struct _MEMHEADER MEMHEADER;
-
-struct _MEMHEADER
-{
- MEMHEADER * next;
- MEMHEADER * prev;
- unsigned int len;
- unsigned char mem;
-};
-
-#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
-#define MEM(x) (&x->mem)
-
-#else
-
-#define MEMHEADER struct MAH// Memory Allocation Header
-
-MEMHEADER
-{
- MEMHEADER __xdata * next;
- unsigned int len;
- unsigned char mem[];
-};
-
-#define HEADER_SIZE sizeof(MEMHEADER)
-#define MEM(x) (x->mem)
-
-#endif
-
-extern MEMHEADER __xdata * _sdcc_prev_memheader;
-
-// apart from finding the header
-// this function also finds it's predecessor
-extern MEMHEADER __xdata * _sdcc_find_memheader(void __xdata * p);
-
-void __xdata * realloc (void * p, size_t size)
-{
- register MEMHEADER __xdata * pthis;
- register MEMHEADER __xdata * pnew;
- register void __xdata * ret;
-
- CRITICAL
- {
- pthis = _sdcc_find_memheader(p);
- if (pthis)
- {
- if (size > (0xFFFF-HEADER_SIZE))
- {
- ret = (void __xdata *) NULL; //To prevent overflow in next line
- }
- else
- {
- size += HEADER_SIZE; //We need a memory for header too
-
- if ((((unsigned int)pthis->next) - ((unsigned int)pthis)) >= size)
- {//if spare is more than needed
- pthis->len = size;
- ret = p;
- }
- else
- {
- if ((_sdcc_prev_memheader) &&
- ((((unsigned int)pthis->next) -
- ((unsigned int)_sdcc_prev_memheader) -
- _sdcc_prev_memheader->len) >= size))
- {
- pnew = (MEMHEADER __xdata * )((char __xdata *)_sdcc_prev_memheader + _sdcc_prev_memheader->len);
- _sdcc_prev_memheader->next = pnew;
-
-#if _SDCC_MALLOC_TYPE_MLH
- pthis->next->prev = pnew;
-#endif
-
- memmove(pnew, pthis, pthis->len);
- pnew->len = size;
- ret = MEM(pnew);
- }
- else
- {
- ret = malloc(size - HEADER_SIZE);
- if (ret)
- {
- memcpy(ret, MEM(pthis), pthis->len - HEADER_SIZE);
- free(p);
- }
- }
- }
- }
- }
- else
- {
- ret = malloc(size);
- }
- }
- return ret;
-}
-//END OF MODULE
const char *file,
unsigned line);
/* Easy Access Macros */
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-#define IS_OP_ACCUSE(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->accuse)
+#define IS_OP_RUONLY(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->ruonly)
+#define IS_OP_ACCUSE(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->accuse)
#define DCL_TYPE(l) validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type
#define DCL_ELEM(l) validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem
#define AOP_TYPE(op) AOP(op)->type
#define AOP_SIZE(op) AOP(op)->size
#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \
- AOP_TYPE(x) == AOP_R0))
+ AOP_TYPE(x) == AOP_R0))
#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
#define MOVA(x) mova(x) /* use function to avoid multiple eval */
#define MOVB(x) movb(x)
-#define CLRC emitcode("clr","c")
-#define SETC emitcode("setb","c")
+#define CLRC emitcode("clr","c")
+#define SETC emitcode("setb","c")
// A scratch register which will be used to hold
// result bytes from operands in far space via DPTR2.
{
dbuf_append_char (&dbuf, '\t');
dbuf_tvprintf (&dbuf, fmt, ap);
- }
+ }
}
else
{
if (ic->op == IFX)
{
op = IC_COND (ic);
- if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ if (IS_OP_ACCUSE (op))
{
accuse = 1;
size = getSize (OP_SYMBOL (op)->type);
else if (ic->op == JUMPTABLE)
{
op = IC_JTCOND (ic);
- if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ if (IS_OP_ACCUSE (op))
{
accuse = 1;
size = getSize (OP_SYMBOL (op)->type);
else
{
op = IC_LEFT (ic);
- if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ if (IS_OP_ACCUSE (op))
{
accuse = 1;
size = getSize (OP_SYMBOL (op)->type);
accuseSize = size;
}
op = IC_RIGHT (ic);
- if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ if (IS_OP_ACCUSE (op))
{
accuse = 1;
size = getSize (OP_SYMBOL (op)->type);
}
/*-----------------------------------------------------------------*/
-/* aopForRemat - rematerialzes an object */
+/* aopForRemat - rematerializes an object */
/*-----------------------------------------------------------------*/
static asmop *
aopForRemat (symbol * sym)
val += (int) operandLitValue (IC_RIGHT (ic));
else if (ic->op == '-')
val -= (int) operandLitValue (IC_RIGHT (ic));
- else if (IS_CAST_ICODE(ic)) {
- sym_link *from_type = operandType(IC_RIGHT(ic));
- aop->aopu.aop_immd.from_cast_remat = 1;
- ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
- ptr_type = pointerTypeToGPByte (DCL_TYPE(from_type), NULL, NULL);
- continue;
- } else break;
+ else if (IS_CAST_ICODE(ic))
+ {
+ sym_link *from_type = operandType(IC_RIGHT(ic));
+ aop->aopu.aop_immd.from_cast_remat = 1;
+ ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ ptr_type = pointerTypeToGPByte (DCL_TYPE(from_type), NULL, NULL);
+ continue;
+ }
+ else break;
ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
}
if (val)
- {
+ {
SNPRINTF (buffer, sizeof(buffer),
"(%s %c 0x%06x)",
OP_SYMBOL (IC_LEFT (ic))->rname,
val >= 0 ? '+' : '-',
abs (val) & 0xffffff);
- }
+ }
else
- {
+ {
if (IS_ASSIGN_ICODE(ic) && isOperandLiteral(IC_RIGHT(ic)))
- {
+ {
SNPRINTF(buffer, sizeof(buffer),
"0x%x",(int) operandLitValue (IC_RIGHT (ic)));
- }
+ }
else
- {
+ {
strncpyz (buffer, OP_SYMBOL (IC_LEFT (ic))->rname, sizeof(buffer));
- }
- }
+ }
+ }
aop->aopu.aop_immd.aop_immd1 = Safe_strdup(buffer);
/* set immd2 field if required */
if (aop->aopu.aop_immd.from_cast_remat)
- {
+ {
tsprintf(buffer, sizeof(buffer), "#!constbyte",ptr_type);
aop->aopu.aop_immd.aop_immd2 = Safe_strdup(buffer);
- }
+ }
return aop;
}
/* rematerialize it NOW */
if (sym->remat)
{
- sym->aop = op->aop = aop =
- aopForRemat (sym);
+ sym->aop = op->aop = aop = aopForRemat (sym);
aop->size = getSize (sym->type);
return;
}
/*-----------------------------------------------------------------*/
/* freeAsmop - free up the asmop given to an operand */
-/*----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
static void
freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
{
{
SNPRINTF (buffer, sizeof(buffer),
"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
+ aop->aopu.aop_dir,
+ offset);
}
else
{
return aop->aopu.aop_reg[offset]->name;
case AOP_CRY:
- emitcode ("clr", "a");
emitcode ("mov", "c,%s", aop->aopu.aop_dir);
+ emitcode ("clr", "a");
emitcode ("rlc", "a");
return (dname ? "acc" : "a");
bool bvolatile = isOperandVolatile (result, FALSE);
bool accuse = FALSE;
asmop * aop = AOP (result);
+ const char *d = NULL;
if (aop->size && offset > (aop->size - 1))
{
emitcode ("mov", "%s,%s",
aop->aopu.aop_reg[offset]->dname, s);
}
- else
+ else
{
emitcode ("mov", "%s,%s",
aop->aopu.aop_reg[offset]->name, s);
emitcode ("mov", "@%s,%s",
aop->aopu.aop_ptr->name, buffer);
}
- else
+ else
{
- emitcode ("mov", "@%s,%s", aop->aopu.aop_ptr->name, s);
+ emitcode ("mov", "@%s,%s", aop->aopu.aop_ptr->name, s);
}
break;
case AOP_STK:
if (strcmp (s, "a") == 0)
- emitcode ("push", "acc");
- else
- if (*s=='@') {
+ {
+ emitcode ("push", "acc");
+ }
+ else if (*s=='@')
+ {
MOVA(s);
emitcode ("push", "acc");
- } else {
+ }
+ else if (strcmp (s, "r0") == 0 ||
+ strcmp (s, "r1") == 0 ||
+ strcmp (s, "r2") == 0 ||
+ strcmp (s, "r3") == 0 ||
+ strcmp (s, "r4") == 0 ||
+ strcmp (s, "r5") == 0 ||
+ strcmp (s, "r6") == 0 ||
+ strcmp (s, "r7") == 0)
+ {
+ char buffer[10];
+ SNPRINTF (buffer, sizeof(buffer), "a%s", s);
+ emitcode ("push", buffer);
+ }
+ else
+ {
emitcode ("push", s);
}
break;
case AOP_CRY:
- /* if not bit variable */
- if (!aop->aopu.aop_dir)
+ // destination is carry for return-use-only
+ d = (IS_OP_RUONLY (result)) ? "c" : aop->aopu.aop_dir;
+
+ // source is no literal and not in carry
+ if ((s != zero) && (s != one) && strcmp (s, "c"))
{
- /* inefficient: move carry into A and use jz/jnz */
- emitcode ("clr", "a");
- emitcode ("rlc", "a");
- accuse = TRUE;
+ MOVA (s);
+ /* set C, if a >= 1 */
+ emitcode ("add", "a,#!constbyte",0xff);
+ s = "c";
}
- else
+ // now source is zero, one or carry
+
+ /* if result no bit variable */
+ if (!d)
{
- if (s == zero)
- emitcode ("clr", "%s", aop->aopu.aop_dir);
- else if (s == one)
- emitcode ("setb", "%s", aop->aopu.aop_dir);
- else if (!strcmp (s, "c"))
- emitcode ("mov", "%s,c", aop->aopu.aop_dir);
- else if (strcmp (s, aop->aopu.aop_dir))
+ if (!strcmp (s, "c"))
+ {
+ /* inefficient: move carry into A and use jz/jnz */
+ emitcode ("clr", "a");
+ emitcode ("rlc", "a");
+ accuse = TRUE;
+ }
+ else
{
MOVA (s);
- /* set C, if a >= 1 */
- emitcode ("add", "a,#!constbyte",0xff);
- emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+ accuse = TRUE;
}
}
+ else if (s == zero)
+ emitcode ("clr", "%s", d);
+ else if (s == one)
+ emitcode ("setb", "%s", d);
+ else if (strcmp (s, d))
+ emitcode ("mov", "%s,c", d);
break;
case AOP_STR:
}
/*-----------------------------------------------------------------*/
-/* opIsGptr: returns non-zero if the passed operand is */
-/* a generic pointer type. */
+/* opIsGptr: returns non-zero if the passed operand is */
+/* a generic pointer type. */
/*-----------------------------------------------------------------*/
static int
opIsGptr (operand * op)
/* set C, if a == 0 */
tlbl = newiTempLabel (NULL);
- emitcode ("cjne", "a,#1,!tlabel", tlbl->key + 100);
+ emitcode ("cjne", "a,#0x01,!tlabel", tlbl->key + 100);
emitLabel (tlbl);
outBitC (IC_RESULT (ic));
if (offset == 0)
SETC;
emitcode ("cpl", "a");
- emitcode ("addc", "a,#0");
+ emitcode ("addc", "a,#0x00");
}
else
{
}
/*-----------------------------------------------------------------*/
-/* genIpush - generate code for pushing this gets a little complex */
+/* genIpush - generate code for pushing this gets a little complex */
/*-----------------------------------------------------------------*/
static void
genIpush (iCode * ic)
}
else
{
- emitcode ("push", "%s", l);
+ emitcode ("push", "%s", l);
}
prev = l;
}
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* popForBranch - recover the spilt registers for a branch */
+/*-----------------------------------------------------------------*/
+static void
+popForBranch (iCode * ic, bool markGenerated)
+{
+ while (ic && ic->op == IPOP)
+ {
+ genIpop (ic);
+ if (markGenerated)
+ ic->generated = 1; /* mark the icode as generated */
+ ic = ic->next;
+ }
+}
+
/*-----------------------------------------------------------------*/
/* saveRBank - saves an entire register bank on the stack */
/*-----------------------------------------------------------------*/
if (!ic)
{
/* Assume r0 is available for use. */
- r = REG_WITH_INDEX (R0_IDX);;
+ r = REG_WITH_INDEX (R0_IDX);
}
else
{
}
if (ic)
- {
- ic->bankSaved = 1;
- }
+ {
+ ic->bankSaved = 1;
+ }
}
/*-----------------------------------------------------------------*/
sic = setNextItem (sendSet))
{
if (sic->argreg <= 12)
- {
- int size, offset = 0;
+ {
+ int size, offset = 0;
- size = getSize (operandType (IC_LEFT (sic)));
- D (emitcode (";", "genSend argreg = %d, size = %d ",sic->argreg,size));
- if (sendCount == 0) { /* first parameter */
- // we know that dpl(hxb) is the result, so
- rb1_count = 0 ;
- _startLazyDPSEvaluation ();
- if (size>1) {
- aopOp (IC_LEFT (sic), sic, FALSE,
- (AOP_IS_STR(IC_LEFT(sic)) ? FALSE : TRUE));
- } else {
- aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+ size = getSize (operandType (IC_LEFT (sic)));
+ D (emitcode (";", "genSend argreg = %d, size = %d ",sic->argreg,size));
+ if (sendCount == 0)
+ { /* first parameter */
+ // we know that dpl(hxb) is the result, so
+ rb1_count = 0 ;
+ _startLazyDPSEvaluation ();
+ if (size>1)
+ {
+ aopOp (IC_LEFT (sic), sic, FALSE,
+ (AOP_IS_STR(IC_LEFT(sic)) ? FALSE : TRUE));
+ }
+ else
+ {
+ aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+ }
+ while (size--)
+ {
+ char *l = aopGet (IC_LEFT (sic), offset, FALSE, FALSE, NULL);
+ if (strcmp (l, fReturn[offset]))
+ {
+ emitcode ("mov", "%s,%s", fReturn[offset], l);
+ }
+ offset++;
+ }
+ _endLazyDPSEvaluation ();
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ rb1_count =0;
}
- while (size--)
- {
- char *l = aopGet (IC_LEFT (sic), offset, FALSE, FALSE, NULL);
- if (strcmp (l, fReturn[offset]))
- {
- emitcode ("mov", "%s,%s", fReturn[offset], l);
- }
- offset++;
- }
- _endLazyDPSEvaluation ();
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
- rb1_count =0;
- } else { /* if more parameter in registers */
- aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
- while (size--) {
- emitcode ("mov","b1_%d,%s",rb1_count++,aopGet (IC_LEFT (sic), offset++,
- FALSE, FALSE, NULL));
+ else
+ { /* if more parameter in registers */
+ aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+ while (size--)
+ {
+ emitcode ("mov","b1_%d,%s",rb1_count++,
+ aopGet (IC_LEFT (sic), offset, FALSE, FALSE, NULL));
+ offset++;
+ }
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
}
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ sendCount++;
}
- sendCount++;
- }
}
}
/* if this is an interrupt service routine then
save acc, b, dpl, dph */
if (IFFUNC_ISISR (sym->type))
- { /* is ISR */
+ { /* is ISR */
if (!inExcludeList ("acc"))
emitcode ("push", "acc");
if (!inExcludeList ("b"))
registers :-) */
if (!FUNC_REGBANK (sym->type))
{
- int i;
+ int i;
/* if this function does not call any other
function then we can be economical and
determine register usage so we will have to push the
entire bank */
saveRBank (0, ic, FALSE);
- if (options.parms_in_bank1) {
- for (i=0; i < 8 ; i++ ) {
+ if (options.parms_in_bank1)
+ {
+ for (i=0; i < 8 ; i++ )
+ {
emitcode ("push","%s",rb1regs[i]);
- }
- }
+ }
+ }
}
}
- else
+ else
{
/* This ISR uses a non-zero bank.
*
static void
genEndFunction (iCode * ic)
{
- symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+ symbol *sym = OP_SYMBOL (IC_LEFT (ic));
lineNode *lnp = lineCurr;
- bitVect *regsUsed;
- bitVect *regsUsedPrologue;
- bitVect *regsUnneeded;
- int idx;
+ bitVect *regsUsed;
+ bitVect *regsUsedPrologue;
+ bitVect *regsUnneeded;
+ int idx;
D (emitcode (";", "genEndFunction"));
/* this function has a function call. We cannot
determine register usage so we will have to pop the
entire bank */
- if (options.parms_in_bank1) {
- for (i = 7 ; i >= 0 ; i-- ) {
+ if (options.parms_in_bank1)
+ {
+ for (i = 7 ; i >= 0 ; i-- )
+ {
emitcode ("pop","%s",rb1regs[i]);
- }
- }
+ }
+ }
unsaveRBank (0, ic, FALSE);
}
}
{
if (!strcmp(l, "acc"))
{
- emitcode("jnz", "!tlabel", tlbl->key + 100);
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
}
else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
IS_AOP_PREG (IC_RESULT (ic)))
{
- emitcode ("cjne", "%s,%s,!tlabel", l, zero, tlbl->key + 100);
+ emitcode ("cjne", "%s,%s,!tlabel", l, zero, tlbl->key + 100);
}
else
{
- emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+ emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
}
l = aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE, NULL);
{
if (!strcmp(l, "acc"))
{
- emitcode("jnz", "!tlabel", tlbl->key + 100);
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
}
else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
IS_AOP_PREG (IC_RESULT (ic)))
{
- emitcode ("cjne", "%s,%s,!tlabel", l, zero, tlbl->key + 100);
+ emitcode ("cjne", "%s,%s,!tlabel", l, zero, tlbl->key + 100);
}
else
{
- emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+ emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
}
l = aopGet (IC_RESULT (ic), MSB32, FALSE, FALSE, NULL);
while (icount--)
emitcode ("inc", "dptr");
return TRUE;
- }
+ }
if (AOP_INDPTRn(IC_LEFT(ic)) && AOP_INDPTRn(IC_RESULT(ic)) &&
AOP(IC_LEFT(ic))->aopu.dptr == AOP(IC_RESULT(ic))->aopu.dptr &&
- icount <= 5 ) {
+ icount <= 5 )
+ {
emitcode ("mov","dps,#!constbyte",AOP(IC_LEFT(ic))->aopu.dptr);
while (icount--)
emitcode ("inc", "dptr");
emitcode ("mov", "dps,#0");
return TRUE;
- }
+ }
/* if the sizes are greater than 1 then we cannot */
if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
{
D (emitcode (";", "genPlusBits"));
+ emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
{
symbol *lbl = newiTempLabel (NULL);
- emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
emitcode ("jnb", "%s,!tlabel", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
emitcode ("cpl", "c");
emitLabel (lbl);
else
{
emitcode ("clr", "a");
- emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
emitcode ("rlc", "a");
emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
emitcode ("addc", "a,%s", zero);
if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
IS_AOP_PREG (IC_RESULT (ic)))
- {
+ {
emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
- }
+ }
else
- {
+ {
emitcode ("mov", "a,#!constbyte",0xff);
emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
- }
+ }
l = aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE, NULL);
emitcode ("dec", "%s", l);
if (size > 2)
{
- if (!strcmp(l, "acc"))
+ if (!strcmp(l, "acc"))
{
- emitcode("jnz", "!tlabel", tlbl->key + 100);
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
}
- else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
- AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
- IS_AOP_PREG (IC_RESULT (ic)))
+ else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+ IS_AOP_PREG (IC_RESULT (ic)))
{
- emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
+ emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
}
- else
+ else
{
- emitcode ("mov", "a,#!constbyte",0xff);
- emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+ emitcode ("mov", "a,#!constbyte",0xff);
+ emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
}
- l = aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE, NULL);
- emitcode ("dec", "%s", l);
+ l = aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE, NULL);
+ emitcode ("dec", "%s", l);
}
if (size > 3)
{
- if (!strcmp(l, "acc"))
+ if (!strcmp(l, "acc"))
{
- emitcode("jnz", "!tlabel", tlbl->key + 100);
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
}
- else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
- AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
- IS_AOP_PREG (IC_RESULT (ic)))
+ else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+ IS_AOP_PREG (IC_RESULT (ic)))
{
- emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
+ emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
}
- else
+ else
{
- emitcode ("mov", "a,#!constbyte",0xff);
- emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+ emitcode ("mov", "a,#!constbyte",0xff);
+ emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
}
- l = aopGet (IC_RESULT (ic), MSB32, FALSE, FALSE, NULL);
- emitcode ("dec", "%s", l);
+ l = aopGet (IC_RESULT (ic), MSB32, FALSE, FALSE, NULL);
+ emitcode ("dec", "%s", l);
}
if (emitTlbl)
{
}
}
else
- {
- while (size--)
{
- aopPut (result, zero, offset++);
+ while (size--)
+ {
+ aopPut (result, zero, offset++);
+ }
}
- }
_endLazyDPSEvaluation();
}
}
emitcode ("inc", "a"); /* inc doesn't set carry flag */
else
{
- emitcode ("add", "a,#1"); /* this sets carry flag */
+ emitcode ("add", "a,#0x01"); /* this sets carry flag */
emitcode ("xch", "a,b");
emitcode ("cpl", "a"); /* msb 2's complement */
- emitcode ("addc", "a,#0");
+ emitcode ("addc", "a,#0x00");
emitcode ("xch", "a,b");
}
emitLabel (lbl);
/* genIfxJump :- will create a jump depending on the ifx */
/*-----------------------------------------------------------------*/
static void
-genIfxJump (iCode * ic, char *jval)
+genIfxJump (iCode * ic, char *jval, iCode *popIc)
{
symbol *jlbl;
symbol *tlbl = newiTempLabel (NULL);
char *inst;
+ /* if there is something to be popped then do it first */
+ popForBranch (popIc, TRUE);
+
D (emitcode (";", "genIfxJump"));
/* if true label then we jump if condition
if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
{
freeAsmop (result, NULL, ic, TRUE);
- genIfxJump (ifx, "acc.7");
+ genIfxJump (ifx, "acc.7", ic->next);
return;
}
else
code a little differently */
if (ifx)
{
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", ic->next);
}
else
{
/* if the left side is a literal or
if the right is in a pointer register and left
is not */
- if ((AOP_TYPE (left) == AOP_LIT) ||
+ if ((AOP_TYPE (left) == AOP_LIT) ||
(AOP_TYPE (left) == AOP_IMMD) ||
(IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
{
genCmpEq (iCode * ic, iCode * ifx)
{
operand *left, *right, *result;
+ iCode * popIc = ic->next;
D (emitcode (";", "genCmpEq"));
if (IC_TRUE (ifx))
{
emitcode ("jnc", "!tlabel", tlbl->key + 100);
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100);
}
else
{
emitcode ("jc", "!tlabel", tlbl->key + 100);
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "!tlabel", IC_FALSE (ifx)->key + 100);
}
emitLabel (tlbl);
gencjneshort (left, right, tlbl);
if (IC_TRUE (ifx))
{
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100);
emitLabel (tlbl);
}
symbol *lbl = newiTempLabel (NULL);
emitcode ("sjmp", "!tlabel", lbl->key + 100);
emitLabel (tlbl);
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "!tlabel", IC_FALSE (ifx)->key + 100);
emitLabel (lbl);
}
}
if (ifx)
{
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", popIc);
goto release;
}
/* if the result is used in an arithmetic operation
}
if (ifx)
{
- genIfxJump (ifx, "a");
+ genIfxJump (ifx, "a", popIc);
goto release;
}
/* if the result is used in an arithmetic operation
static iCode *
ifxForOp (operand * op, iCode * ic)
{
+ iCode *ifxIc;
+
/* if true symbol then needs to be assigned */
if (IS_TRUE_SYMOP (op))
return NULL;
/* if this has register type condition and
+ while skipping ipop's (see bug 1509084),
the next instruction is ifx with the same operand
and live to of the operand is upto the ifx only then */
- if (ic->next &&
- ic->next->op == IFX &&
- IC_COND (ic->next)->key == op->key &&
- OP_SYMBOL (op)->liveTo <= ic->next->seq)
- return ic->next;
+ for (ifxIc = ic->next; ifxIc && ifxIc->op == IPOP; ifxIc = ifxIc->next);
+ if (ifxIc && ifxIc->op == IFX &&
+ IC_COND (ifxIc)->key == op->key &&
+ OP_SYMBOL (op)->liveTo <= ifxIc->seq)
+ return ifxIc;
return NULL;
}
if (IS_AGGREGATE(type->next)) return NULL;
if (osize != (isize = getSize(type->next))) return NULL;
- while (lic) {
+ while (lic)
+ {
/* if operand of the form op = op + <sizeof *op> */
if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
isOperandEqual(IC_RESULT(lic),op) &&
isOperandLiteral(IC_RIGHT(lic)) &&
- operandLitValue(IC_RIGHT(lic)) == isize) {
+ operandLitValue(IC_RIGHT(lic)) == isize)
+ {
return lic;
- }
+ }
/* if the operand used or deffed */
- if (bitVectBitValue(OP_USES(op),lic->key) || lic->defKey == op->key) {
+ if (bitVectBitValue(OP_USES(op),lic->key) || lic->defKey == op->key)
+ {
return NULL;
- }
+ }
/* if GOTO or IFX */
if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
lic = lic->next;
- }
+ }
return NULL;
}
outBitAcc (result);
}
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
outBitC (result);
// if(bit & ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", ic->next);
goto release;
}
{
SNPRINTF (buffer, sizeof(buffer),
"acc.%d", posbit & 0x07);
- genIfxJump (ifx, buffer);
+ genIfxJump (ifx, buffer, ic->next);
}
else
{
outBitC (result);
// if(bit | ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", ic->next);
goto release;
}
}
else
{
- genIfxJump (ifx, "a");
+ genIfxJump (ifx, "a", ic->next);
goto release;
}
}
right = left;
left = tmp;
}
+
if (AOP_TYPE (right) == AOP_LIT)
lit = ulFromVal (AOP (right)->aopu.aop_lit);
// val = c
if (size)
outBitC (result);
- // if(bit | ...)
+ // if(bit ^ ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", ic->next);
goto release;
}
}
else
{
- for (; (size--); offset++)
- {
- // normal case
- // result = left ^ right
- if (AOP_TYPE (right) == AOP_LIT)
- {
- bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL);
- if (bytelit == 0)
- {
- aopPut (result,
- aopGet (left, offset, FALSE, FALSE, NULL),
- offset);
- continue;
- }
- D (emitcode (";", "better literal XOR."));
- MOVA (aopGet (left, offset, FALSE, FALSE, NULL));
- emitcode ("xrl", "a, %s",
- aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG));
- }
- else
- {
- // faster than result <- left, anl result,right
- // and better if result is SFR
- if (AOP_TYPE (left) == AOP_ACC)
- {
- emitcode ("xrl", "a,%s",
- aopGet (right, offset,
- FALSE, FALSE, DP2_RESULT_REG));
- }
- else
- {
+ for (; (size--); offset++)
+ {
+ // normal case
+ // result = left ^ right
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL);
+ if (bytelit == 0)
+ {
+ aopPut (result,
+ aopGet (left, offset, FALSE, FALSE, NULL),
+ offset);
+ continue;
+ }
+ D (emitcode (";", "better literal XOR."));
+ MOVA (aopGet (left, offset, FALSE, FALSE, NULL));
+ emitcode ("xrl", "a, %s",
+ aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG));
+ }
+ else
+ {
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE (left) == AOP_ACC)
+ {
+ emitcode ("xrl", "a,%s",
+ aopGet (right, offset,
+ FALSE, FALSE, DP2_RESULT_REG));
+ }
+ else
+ {
char *rOp = aopGet (right, offset, FALSE, FALSE, NULL);
if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
- {
+ {
emitcode("mov", "b,a");
rOp = "b";
- }
+ }
MOVA (aopGet (left, offset, FALSE, FALSE, NULL));
emitcode ("xrl", "a,%s", rOp);
- }
- }
- aopPut (result, "a", offset);
- }
+ }
+ }
+ aopPut (result, "a", offset);
+ }
}
}
_G.inLine += (!options.asmpeep);
- buffer = bp = bp1 = Safe_strdup (IC_INLINE(ic));
+ buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
/* emit each line as a code */
while (*bp)
{
operand *left, *result;
int size, offset;
- char *l;
+ char *l;
D (emitcode (";", "genRRC"));
else
{
emitcode ("rl", "a");
- emitcode ("anl", "a,#1");
+ emitcode ("anl", "a,#0x01");
outAcc (result);
}
l = aopGet (left, offl, FALSE, FALSE, NULL);
if (*l == '@' && (IS_AOP_PREG (result)))
- {
+ {
emitcode ("mov", "a,%s", l);
aopPut (result, "a", offr);
- }
+ }
else
- {
+ {
if (!sign)
{
aopPut (result, l, offr);
aopPut (result, "a", offr);
}
}
- }
- }
+ }
+ }
}
#endif
/* if shCount >= 8 */
if (shCount >= 8)
- {
+ {
shCount -= 8;
_startLazyDPSEvaluation();
if (size > 1)
{
if (shCount)
- {
- _endLazyDPSEvaluation();
- shiftL1Left2Result (left, LSB, result, MSB16, shCount);
- aopPut (result, zero, LSB);
- }
+ {
+ _endLazyDPSEvaluation();
+ shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ aopPut (result, zero, LSB);
+ }
else
- {
- movLeft2Result (left, LSB, result, MSB16, 0);
- aopPut (result, zero, LSB);
- _endLazyDPSEvaluation();
- }
+ {
+ movLeft2Result (left, LSB, result, MSB16, 0);
+ aopPut (result, zero, LSB);
+ _endLazyDPSEvaluation();
+ }
}
- else
+ else
{
aopPut (result, zero, LSB);
_endLazyDPSEvaluation();
/* I suppose that the left size >= result size */
if (shCount == 0)
- {
- _startLazyDPSEvaluation();
- while (size--)
+ {
+ _startLazyDPSEvaluation();
+ while (size--)
{
movLeft2Result (left, size, result, size, 0);
}
- _endLazyDPSEvaluation();
- }
+ _endLazyDPSEvaluation();
+ }
else if (shCount >= (size * 8))
- {
- _startLazyDPSEvaluation();
- while (size--)
{
- aopPut (result, zero, size);
+ _startLazyDPSEvaluation();
+ while (size--)
+ {
+ aopPut (result, zero, size);
+ }
+ _endLazyDPSEvaluation();
}
- _endLazyDPSEvaluation();
- }
else
- {
+ {
switch (size)
{
case 1:
/* I suppose that the left size >= result size */
if (shCount == 0)
- {
+ {
size = getDataSize (result);
_startLazyDPSEvaluation();
while (size--)
movLeft2Result (left, size, result, size, 0);
_endLazyDPSEvaluation();
- }
+ }
else if (shCount >= (size * 8))
{
if (sign)
_startLazyDPSEvaluation ();
while (size--)
{
- if (offset)
+ if (offset)
{
- SNPRINTF (buffer, sizeof(buffer),
- "(%s + %d)", l + 1, offset);
+ SNPRINTF (buffer, sizeof(buffer), "(%s + %d)", l + 1, offset);
}
- else
+ else
{
- SNPRINTF (buffer, sizeof(buffer),
- "%s", l + 1);
+ SNPRINTF (buffer, sizeof(buffer), "%s", l + 1);
}
aopPut (result, buffer, offset++);
}
/* if bit then unpack */
if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
- {
- genUnpackBits (result, "dptr", GPOINTER);
- }
+ {
+ genUnpackBits (result, "dptr", GPOINTER);
+ }
else
{
- size = AOP_SIZE (result);
- offset = 0;
+ size = AOP_SIZE (result);
+ offset = 0;
- while (size--)
+ while (size--)
{
- if (size)
+ if (size)
{
// Get two bytes at a time, results in _AP & A.
// dptr will be incremented ONCE by __gptrgetWord.
aopPut (result, DP2_RESULT_REG, offset++);
size--;
}
- else
+ else
{
// Only one byte to get.
emitcode ("lcall", "__gptrget");
aopPut (result, "a", offset++);
}
- if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
+ if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
{
emitcode ("inc", "dptr");
}
etype = getSpec (type);
/* if left is of type of pointer then it is simple */
if (IS_PTR (type) && !IS_FUNC (type->next))
- p_type = DCL_TYPE (type);
+ {
+ p_type = DCL_TYPE (type);
+ }
else
{
/* we have to go by the storage class */
while (size--)
{
if (offset)
- SNPRINTF (buffer, sizeof(buffer), "(%s + %d)", l + 1, offset);
+ SNPRINTF (buffer, sizeof(buffer), "(%s + %d)", l + 1, offset);
else
- SNPRINTF (buffer, sizeof(buffer), "%s", l + 1);
+ SNPRINTF (buffer, sizeof(buffer), "%s", l + 1);
emitcode ("mov", "%s,%s", buffer,
aopGet (right, offset++, FALSE, FALSE, NULL));
}
- freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
-/* genNearPointerSet - emitcode for near pointer put */
+/* genNearPointerSet - emitcode for near pointer put */
/*-----------------------------------------------------------------*/
static void
genNearPointerSet (operand * right,
}
/* done */
- if (pi) pi->generated = 1;
- freeAsmop (result, NULL, ic, TRUE);
+ if (pi)
+ pi->generated = 1;
freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
genPagedPointerSet (operand * right,
operand * result,
iCode * ic,
- iCode *pi)
+ iCode * pi)
{
asmop *aop = NULL;
char *rname, *l;
rname = preg->name;
}
else
- rname = aopGet (result, 0, FALSE, FALSE, NULL);
+ {
+ rname = aopGet (result, 0, FALSE, FALSE, NULL);
+ }
aopOp (right, ic, FALSE, FALSE);
genPackBits ((IS_BITFIELD (retype) ? retype : letype), right, rname, PPOINTER);
else
{
- /* we have can just get the values */
+ /* we can just get the values */
int size = AOP_SIZE (right);
int offset = 0;
l = aopGet (right, offset, FALSE, TRUE, NULL);
MOVA (l);
emitcode ("movx", "@%s,a", rname);
-
if (size || pi)
emitcode ("inc", "%s", rname);
-
offset++;
}
}
belongs */
if (AOP_SIZE (right) > 1 &&
!OP_SYMBOL (result)->remat &&
- (OP_SYMBOL (result)->liveTo > ic->seq ||
- ic->depth) &&
+ (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth) &&
!pi)
{
int size = AOP_SIZE (right) - 1;
}
/* done */
- if (pi) pi->generated = 1;
- freeAsmop (result, NULL, ic, TRUE);
+ if (pi)
+ pi->generated = 1;
freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void
genGenPointerSet (operand * right,
- operand * result, iCode * ic, iCode *pi)
+ operand * result, iCode * ic, iCode * pi)
{
int size, offset;
bool pushedB;
/* if bit then unpack */
if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
{
- genPackBits ((IS_BITFIELD (retype) ? retype : letype), right, "dptr", GPOINTER);
+ genPackBits ((IS_BITFIELD (retype) ? retype : letype), right, "dptr", GPOINTER);
}
else
{
- size = AOP_SIZE (right);
- offset = 0;
+ size = AOP_SIZE (right);
+ offset = 0;
- _startLazyDPSEvaluation ();
- while (size--)
+ _startLazyDPSEvaluation ();
+ while (size--)
{
- if (size)
+ if (size)
{
- // Set two bytes at a time, passed in _AP & A.
- // dptr will be incremented ONCE by __gptrputWord.
- //
- // Note: any change here must be coordinated
- // with the implementation of __gptrputWord
- // in device/lib/_gptrput.c
- emitcode("mov", "_ap, %s",
- aopGet (right, offset++, FALSE, FALSE, NULL));
- MOVA (aopGet (right, offset++, FALSE, FALSE, NULL));
-
- genSetDPTR (0);
- _flushLazyDPS ();
- emitcode ("lcall", "__gptrputWord");
- size--;
+ // Set two bytes at a time, passed in _AP & A.
+ // dptr will be incremented ONCE by __gptrputWord.
+ //
+ // Note: any change here must be coordinated
+ // with the implementation of __gptrputWord
+ // in device/lib/_gptrput.c
+ emitcode("mov", "_ap, %s",
+ aopGet (right, offset++, FALSE, FALSE, NULL));
+ MOVA (aopGet (right, offset++, FALSE, FALSE, NULL));
+
+ genSetDPTR (0);
+ _flushLazyDPS ();
+ emitcode ("lcall", "__gptrputWord");
+ size--;
}
- else
+ else
{
- // Only one byte to put.
- MOVA (aopGet (right, offset++, FALSE, FALSE, NULL));
+ // Only one byte to put.
+ MOVA (aopGet (right, offset++, FALSE, FALSE, NULL));
- genSetDPTR (0);
- _flushLazyDPS ();
- emitcode ("lcall", "__gptrput");
+ genSetDPTR (0);
+ _flushLazyDPS ();
+ emitcode ("lcall", "__gptrput");
}
- if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
+ if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
{
- emitcode ("inc", "dptr");
+ emitcode ("inc", "dptr");
}
}
- _endLazyDPSEvaluation ();
+ _endLazyDPSEvaluation ();
}
if (pi && AOP_TYPE (result) != AOP_IMMD) {
/* the result is now in the accumulator or a directly addressable bit */
freeAsmop (cond, NULL, ic, TRUE);
- /* if there was something to be popped then do it */
- if (popIc)
- genIpop (popIc);
-
/* if the condition is a bit variable */
if (isbit && dup)
- genIfxJump (ic, dup);
+ genIfxJump (ic, dup, popIc);
else if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond))
- genIfxJump (ic, SPIL_LOC (cond)->rname);
+ genIfxJump (ic, SPIL_LOC (cond)->rname, popIc);
else if (isbit && !IS_ITEMP (cond))
- genIfxJump (ic, OP_SYMBOL (cond)->rname);
+ genIfxJump (ic, OP_SYMBOL (cond)->rname, popIc);
else
- genIfxJump (ic, "a");
+ genIfxJump (ic, "a", popIc);
ic->generated = 1;
}
need to get the stack offset of this
variable */
if (sym->onStack)
- {
-
+ {
/* if 10 bit stack */
if (options.stack10bit) {
char buff[10];
}
}
goto release;
- }
+ }
/* object not on stack then we need the name */
size = getDataSize (IC_RESULT (ic));
default: /* should not need this (just in case) */
SNPRINTF (s, sizeof(s), "#(%s >> %d)", sym->rname, offset * 8);
}
- }
+ }
else
- {
+ {
SNPRINTF (s, sizeof(s), "#%s", sym->rname);
- }
-
+ }
aopPut (IC_RESULT (ic), s, offset++);
}
if (opIsGptr (IC_RESULT (ic)))
#if 0 // obsolete, and buggy for != xdata
/*-----------------------------------------------------------------*/
-/* genArrayInit - generates code for address of */
+/* genArrayInit - generates code for address of */
/*-----------------------------------------------------------------*/
static void
genArrayInit (iCode * ic)
static void
genReceive (iCode * ic)
{
- int size = getSize (operandType (IC_RESULT (ic)));
- int offset = 0;
- int rb1off ;
+ int size = getSize (operandType (IC_RESULT (ic)));
+ int offset = 0;
+ int rb1off ;
- D (emitcode (";", "genReceive"));
+ D (emitcode (";", "genReceive"));
- if (ic->argreg == 1)
+ if (ic->argreg == 1)
{
- /* first parameter */
- if (AOP_IS_STR(IC_RESULT(ic)))
+ /* first parameter */
+ if (AOP_IS_STR(IC_RESULT(ic)))
{
- /* Nothing to do: it's already in the proper place. */
- return;
+ /* Nothing to do: it's already in the proper place. */
+ return;
}
- else
+ else
{
- bool useDp2;
+ bool useDp2;
- useDp2 = isOperandInFarSpace (IC_RESULT (ic)) &&
+ useDp2 = isOperandInFarSpace (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->isspilt ||
IS_TRUE_SYMOP (IC_RESULT (ic)));
- _G.accInUse++;
- aopOp (IC_RESULT (ic), ic, FALSE, useDp2);
- _G.accInUse--;
+ _G.accInUse++;
+ aopOp (IC_RESULT (ic), ic, FALSE, useDp2);
+ _G.accInUse--;
- /* Sanity checking... */
- if (AOP_USESDPTR(IC_RESULT(ic)))
+ /* Sanity checking... */
+ if (AOP_USESDPTR(IC_RESULT(ic)))
{
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "genReceive got unexpected DPTR.");
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "genReceive got unexpected DPTR.");
}
- assignResultValue (IC_RESULT (ic), NULL);
+ assignResultValue (IC_RESULT (ic), NULL);
}
}
- else if (ic->argreg > 12)
+ else if (ic->argreg > 12)
{ /* bit parameters */
if (OP_SYMBOL (IC_RESULT (ic))->regs[0]->rIdx != ic->argreg-5)
{
outBitC(IC_RESULT (ic));
}
}
- else
+ else
{
- /* second receive onwards */
- /* this gets a little tricky since unused receives will be
- eliminated, we have saved the reg in the type field . and
- we use that to figure out which register to use */
- aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
- rb1off = ic->argreg;
- while (size--)
+ /* second receive onwards */
+ /* this gets a little tricky since unused receives will be
+ eliminated, we have saved the reg in the type field . and
+ we use that to figure out which register to use */
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+ rb1off = ic->argreg;
+ while (size--)
{
- aopPut (IC_RESULT (ic), rb1regs[rb1off++ -5], offset++);
+ aopPut (IC_RESULT (ic), rb1regs[rb1off++ -5], offset++);
}
}
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
break;
case IPOP:
- /* IPOP happens only when trying to restore a
- spilt live range, if there is an ifx statement
- following this pop then the if statement might
- be using some of the registers being popped which
- would destory the contents of the register so
- we need to check for this condition and handle it */
- if (ic->next &&
- ic->next->op == IFX &&
- regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
- genIfx (ic->next, ic);
- else
- genIpop (ic);
+ {
+ iCode *ifxIc, *popIc;
+ bool CommonRegs = FALSE;
+
+ /* IPOP happens only when trying to restore a
+ spilt live range, if there is an ifx statement
+ following this pop (or several) then the if statement might
+ be using some of the registers being popped which
+ would destory the contents of the register so
+ we need to check for this condition and handle it */
+ for (ifxIc = ic->next; ifxIc && ifxIc->op == IPOP; ifxIc = ifxIc->next);
+ for (popIc = ic; popIc && popIc->op == IPOP; popIc = popIc->next)
+ CommonRegs |= (ifxIc && ifxIc->op == IFX && !ifxIc->generated &&
+ regsInCommon (IC_LEFT (popIc), IC_COND (ifxIc)));
+ if (CommonRegs)
+ genIfx (ifxIc, ic);
+ else
+ genIpop (ic);
+ }
break;
case CALL:
case AOP_CRY:
// destination is carry for return-use-only
d = (IS_OP_RUONLY (result)) ? "c" : aop->aopu.aop_dir;
+
// source is no literal and not in carry
if ((s != zero) && (s != one) && strcmp (s, "c"))
{
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* popForBranch - recover the spilt registers for a branch */
+/*-----------------------------------------------------------------*/
+static void
+popForBranch (iCode * ic, bool markGenerated)
+{
+ while (ic && ic->op == IPOP)
+ {
+ genIpop (ic);
+ if (markGenerated)
+ ic->generated = 1; /* mark the icode as generated */
+ ic = ic->next;
+ }
+}
+
/*-----------------------------------------------------------------*/
/* saveRBank - saves an entire register bank on the stack */
/*-----------------------------------------------------------------*/
if (swapBanks)
{
- emitcode ("mov", "psw,#0x%02x",
- ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+ emitcode ("mov", "psw,#0x%02x", ((FUNC_REGBANK(dtype)) << 3) & 0xff);
}
/* make the call */
/* this function has a function call. We cannot
determine register usage so we will have to push the
entire bank */
- saveRBank (0, ic, FALSE);
- if (options.parms_in_bank1) {
- for (i=0; i < 8 ; i++ ) {
- emitcode ("push","%s",rb1regs[i]);
+ saveRBank (0, ic, FALSE);
+ if (options.parms_in_bank1)
+ {
+ for (i=0; i < 8 ; i++ )
+ {
+ emitcode ("push","%s",rb1regs[i]);
}
}
}
}
else
{
- if (options.parms_in_bank1) {
- for (i = 7 ; i >= 0 ; i-- ) {
+ if (options.parms_in_bank1)
+ {
+ for (i = 7 ; i >= 0 ; i-- )
+ {
emitcode ("pop","%s",rb1regs[i]);
- }
- }
+ }
+ }
/* this function has a function call. We cannot
determine register usage so we will have to pop the
entire bank */
unsaveRBank (0, ic, FALSE);
}
}
- else
+ else
{
/* This ISR uses a non-zero bank.
*
symbol *tlbl;
int emitTlbl;
int labelRange;
+ char *l;
/* If the next instruction is a goto and the goto target
* is < 10 instructions previous to this, we can generate
tlbl = newiTempLabel (NULL);
emitTlbl = 1;
}
- emitcode ("inc", "%s", aopGet (IC_RESULT (ic), LSB, FALSE, FALSE));
+ l = aopGet (IC_RESULT (ic), LSB, FALSE, FALSE);
+ emitcode ("inc", "%s", l);
if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
IS_AOP_PREG (IC_RESULT (ic)))
- emitcode ("cjne", "%s,#0x00,%05d$",
- aopGet (IC_RESULT (ic), LSB, FALSE, FALSE),
- tlbl->key + 100);
+ {
+ emitcode ("cjne", "%s,#0x00,%05d$", l, tlbl->key + 100);
+ }
else
{
emitcode ("clr", "a");
- emitcode ("cjne", "a,%s,%05d$",
- aopGet (IC_RESULT (ic), LSB, FALSE, FALSE),
- tlbl->key + 100);
+ emitcode ("cjne", "a,%s,%05d$", l, tlbl->key + 100);
}
- emitcode ("inc", "%s", aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE));
+ l = aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE);
+ emitcode ("inc", "%s", l);
if (size > 2)
{
- if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
- IS_AOP_PREG (IC_RESULT (ic)))
- emitcode ("cjne", "%s,#0x00,%05d$",
- aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE),
- tlbl->key + 100);
+ if (!strcmp(l, "acc"))
+ {
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
+ }
+ else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ IS_AOP_PREG (IC_RESULT (ic)))
+ {
+ emitcode ("cjne", "%s,#0x00,%05d$", l, tlbl->key + 100);
+ }
else
- emitcode ("cjne", "a,%s,%05d$",
- aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE),
- tlbl->key + 100);
+ {
+ emitcode ("cjne", "a,%s,%05d$", l, tlbl->key + 100);
+ }
- emitcode ("inc", "%s", aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE));
+ l = aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE);
+ emitcode ("inc", "%s", l);
}
if (size > 3)
{
- if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
- IS_AOP_PREG (IC_RESULT (ic)))
- emitcode ("cjne", "%s,#0x00,%05d$",
- aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE),
- tlbl->key + 100);
+ if (!strcmp(l, "acc"))
+ {
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
+ }
+ else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ IS_AOP_PREG (IC_RESULT (ic)))
+ {
+ emitcode ("cjne", "%s,#0x00,%05d$", l, tlbl->key + 100);
+ }
else
{
- emitcode ("cjne", "a,%s,%05d$",
- aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE),
- tlbl->key + 100);
+ emitcode ("cjne", "a,%s,%05d$", l, tlbl->key + 100);
}
- emitcode ("inc", "%s", aopGet (IC_RESULT (ic), MSB32, FALSE, FALSE));
+
+ l = aopGet (IC_RESULT (ic), MSB32, FALSE, FALSE);
+ emitcode ("inc", "%s", l);
}
if (emitTlbl)
(icount == 1))
{
symbol *tlbl;
- int emitTlbl;
- int labelRange;
+ int emitTlbl;
+ int labelRange;
+ char *l;
/* If the next instruction is a goto and the goto target
* is <= 10 instructions previous to this, we can generate
emitTlbl = 1;
}
- emitcode ("dec", "%s", aopGet (IC_RESULT (ic), LSB, FALSE, FALSE));
+ l = aopGet (IC_RESULT (ic), LSB, FALSE, FALSE);
+ emitcode ("dec", "%s", l);
+
if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
IS_AOP_PREG (IC_RESULT (ic)))
- emitcode ("cjne", "%s,#0xff,%05d$"
- ,aopGet (IC_RESULT (ic), LSB, FALSE, FALSE)
- ,tlbl->key + 100);
+ {
+ emitcode ("cjne", "%s,#0xff,%05d$", l, tlbl->key + 100);
+ }
else
{
emitcode ("mov", "a,#0xff");
- emitcode ("cjne", "a,%s,%05d$"
- ,aopGet (IC_RESULT (ic), LSB, FALSE, FALSE)
- ,tlbl->key + 100);
+ emitcode ("cjne", "a,%s,%05d$", l, tlbl->key + 100);
}
- emitcode ("dec", "%s", aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE));
+ l = aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE);
+ emitcode ("dec", "%s", l);
if (size > 2)
{
- if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
- IS_AOP_PREG (IC_RESULT (ic)))
- emitcode ("cjne", "%s,#0xff,%05d$"
- ,aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE)
- ,tlbl->key + 100);
+ if (!strcmp(l, "acc"))
+ {
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
+ }
+ else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ IS_AOP_PREG (IC_RESULT (ic)))
+ {
+ emitcode ("cjne", "%s,#0xff,%05d$", l, tlbl->key + 100);
+ }
else
{
- emitcode ("cjne", "a,%s,%05d$"
- ,aopGet (IC_RESULT (ic), MSB16, FALSE, FALSE)
- ,tlbl->key + 100);
+ emitcode ("cjne", "a,%s,%05d$", l, tlbl->key + 100);
}
- emitcode ("dec", "%s", aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE));
+ l = aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE);
+ emitcode ("dec", "%s", l);
}
if (size > 3)
{
- if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
- IS_AOP_PREG (IC_RESULT (ic)))
- emitcode ("cjne", "%s,#0xff,%05d$"
- ,aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE)
- ,tlbl->key + 100);
+ if (!strcmp(l, "acc"))
+ {
+ emitcode("jnz", "!tlabel", tlbl->key + 100);
+ }
+ else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ IS_AOP_PREG (IC_RESULT (ic)))
+ {
+ emitcode ("cjne", "%s,#0xff,%05d$", l, tlbl->key + 100);
+ }
else
{
- emitcode ("cjne", "a,%s,%05d$"
- ,aopGet (IC_RESULT (ic), MSB24, FALSE, FALSE)
- ,tlbl->key + 100);
+ emitcode ("cjne", "a,%s,%05d$", l, tlbl->key + 100);
}
- emitcode ("dec", "%s", aopGet (IC_RESULT (ic), MSB32, FALSE, FALSE));
+ l = aopGet (IC_RESULT (ic), MSB32, FALSE, FALSE);
+ emitcode ("dec", "%s", l);
}
if (emitTlbl)
{
lbl = newiTempLabel (NULL);
emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
emitcode ("cpl", "F0"); /* complement sign flag */
- emitcode ("cpl", "a"); /* 2's complement */
+ emitcode ("cpl", "a"); /* 2's complement */
emitcode ("inc", "a");
emitLabel (lbl);
}
/* msb is 0x00 or 0xff depending on the sign */
if (runtimeSign)
{
- emitcode ("mov", "c,F0");
+ emitcode ("mov", "c,F0");
emitcode ("subb", "a,acc");
while (size--)
aopPut (result, "a", offset++);
/* genIfxJump :- will create a jump depending on the ifx */
/*-----------------------------------------------------------------*/
static void
-genIfxJump (iCode * ic, char *jval, operand *left, operand *right, operand *result)
+genIfxJump (iCode * ic, char *jval, operand *left, operand *right, operand *result, iCode *popIc)
{
symbol *jlbl;
symbol *tlbl = newiTempLabel (NULL);
char *inst;
+ /* if there is something to be popped then do it first */
+ popForBranch (popIc, TRUE);
+
D (emitcode (";", "genIfxJump"));
/* if true label then we jump if condition
MOVA (aopGet (left, AOP_SIZE (left) - 1, FALSE, FALSE));
if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
{
- genIfxJump (ifx, "acc.7", left, right, result);
+ genIfxJump (ifx, "acc.7", left, right, result, ic->next);
freeAsmop (right, NULL, ic, TRUE);
freeAsmop (left, NULL, ic, TRUE);
code a little differently */
if (ifx)
{
- genIfxJump (ifx, "c", NULL, NULL, result);
+ genIfxJump (ifx, "c", NULL, NULL, result, ic->next);
}
else
{
{
bool swappedLR = FALSE;
operand *left, *right, *result;
+ iCode * popIc = ic->next;
D (emitcode (";", "genCmpEq"));
freeForBranchAsmop (result);
freeForBranchAsmop (right);
freeForBranchAsmop (left);
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
}
else
freeForBranchAsmop (result);
freeForBranchAsmop (right);
freeForBranchAsmop (left);
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
}
emitLabel (tlbl);
freeForBranchAsmop (result);
freeForBranchAsmop (right);
freeForBranchAsmop (left);
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
emitLabel (tlbl);
}
freeForBranchAsmop (result);
freeForBranchAsmop (right);
freeForBranchAsmop (left);
+ popForBranch (popIc, FALSE);
emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
emitLabel (lbl);
}
}
if (ifx)
{
- genIfxJump (ifx, "c", left, right, result);
+ genIfxJump (ifx, "c", left, right, result, popIc);
goto release;
}
/* if the result is used in an arithmetic operation
gencjne (left, right, newiTempLabel (NULL), FALSE);
if (ifx)
{
- genIfxJump (ifx, "a", left, right, result);
+ genIfxJump (ifx, "a", left, right, result, popIc);
goto release;
}
/* if the result is used in an arithmetic operation
static iCode *
ifxForOp (operand * op, iCode * ic)
{
+ iCode *ifxIc;
+
/* if true symbol then needs to be assigned */
if (IS_TRUE_SYMOP (op))
return NULL;
/* if this has register type condition and
+ while skipping ipop's (see bug 1509084),
the next instruction is ifx with the same operand
and live to of the operand is upto the ifx only then */
- if (ic->next &&
- ic->next->op == IFX &&
- IC_COND (ic->next)->key == op->key &&
- OP_SYMBOL (op)->liveTo <= ic->next->seq)
- return ic->next;
+ for (ifxIc = ic->next; ifxIc && ifxIc->op == IPOP; ifxIc = ifxIc->next);
+ if (ifxIc && ifxIc->op == IFX &&
+ IC_COND (ifxIc)->key == op->key &&
+ OP_SYMBOL (op)->liveTo <= ifxIc->seq)
+ return ifxIc;
return NULL;
}
if (IS_AGGREGATE(type->next)) return NULL;
if (osize != (isize = getSize(type->next))) return NULL;
- while (lic) {
- /* if operand of the form op = op + <sizeof *op> */
- if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
- isOperandEqual(IC_RESULT(lic),op) &&
- isOperandLiteral(IC_RIGHT(lic)) &&
- operandLitValue(IC_RIGHT(lic)) == isize) {
- return lic;
- }
- /* if the operand used or deffed */
- if (bitVectBitValue(OP_USES(op),lic->key) || lic->defKey == op->key) {
- return NULL;
+ while (lic)
+ {
+ /* if operand of the form op = op + <sizeof *op> */
+ if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
+ isOperandEqual(IC_RESULT(lic),op) &&
+ isOperandLiteral(IC_RIGHT(lic)) &&
+ operandLitValue(IC_RIGHT(lic)) == isize)
+ {
+ return lic;
+ }
+ /* if the operand used or deffed */
+ if (bitVectBitValue(OP_USES(op),lic->key) || lic->defKey == op->key)
+ {
+ return NULL;
+ }
+ /* if GOTO or IFX */
+ if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
+ lic = lic->next;
}
- /* if GOTO or IFX */
- if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
- lic = lic->next;
- }
return NULL;
}
outBitC (result);
// if(bit & ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c", left, right, result);
+ genIfxJump (ifx, "c", left, right, result, ic->next);
goto release;
}
{
SNPRINTF (buffer, sizeof(buffer),
"acc.%d", posbit & 0x07);
- genIfxJump (ifx, buffer, left, right, result);
+ genIfxJump (ifx, buffer, left, right, result, ic->next);
}
else
{// what is this case? just found it in ds390/gen.c
{
MOVA (aopGet (left, offset, FALSE, FALSE));
emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE));
- }
+ }
else
{
MOVA (aopGet (right, offset, FALSE, FALSE));
outBitC (result);
// if(bit | ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c", left, right, result);
+ genIfxJump (ifx, "c", left, right, result, ic->next);
goto release;
}
}
else
{
- genIfxJump (ifx, "a", left, right, result);
+ genIfxJump (ifx, "a", left, right, result, ic->next);
goto release;
}
}
outBitC (result);
// if(bit ^ ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c", left, right, result);
+ genIfxJump (ifx, "c", left, right, result, ic->next);
goto release;
}
genRRC (iCode * ic)
{
operand *left, *result;
- int size, offset;
- char *l;
+ int size, offset;
+ char *l;
D (emitcode (";", "genRRC"));
break;
case 3:
case 4:
- case 5: // AAAAABBB:CCCCCDDD
+ case 5: // AAAAABBB:CCCCCDDD
- AccRol (shCount); // BBBAAAAA:CCCCCDDD
+ AccRol (shCount); // BBBAAAAA:CCCCCDDD
emitcode ("anl", "a,#0x%02x",
SLMask[shCount]); // BBB00000:CCCCCDDD
emitcode ("xch", "a,%s", x); // CCCCCDDD:BBB00000
- AccRol (shCount); // DDDCCCCC:BBB00000
+ AccRol (shCount); // DDDCCCCC:BBB00000
emitcode ("xch", "a,%s", x); // BBB00000:DDDCCCCC
emitcode ("xrl", "a,%s", x); // BBBCCCCC:DDD00000
break;
- case 6: // AAAAAABB:CCCCCCDD
+ case 6: // AAAAAABB:CCCCCCDD
emitcode ("anl", "a,#0x%02x",
SRMask[shCount]); // 000000BB:CCCCCCDD
emitcode ("mov", "c,acc.0"); // c = B
emitcode ("xch", "a,%s", x); // CCCCCCDD:000000BB
#if 0 // REMOVE ME
- AccAXRrl1 (x); // BCCCCCCD:D000000B
- AccAXRrl1 (x); // BBCCCCCC:DD000000
+ AccAXRrl1 (x); // BCCCCCCD:D000000B
+ AccAXRrl1 (x); // BBCCCCCC:DD000000
#else
emitcode("rrc","a");
emitcode("xch","a,%s", x);
emitcode("xch","a,%s", x);
#endif
break;
- case 7: // a:x <<= 7
+ case 7: // a:x <<= 7
emitcode ("anl", "a,#0x%02x",
SRMask[shCount]); // 0000000B:CCCCCCCD
emitcode ("xch", "a,%s", x); // CCCCCCCD:0000000B
- AccAXRrl1 (x); // BCCCCCCC:D0000000
+ AccAXRrl1 (x); // BCCCCCCC:D0000000
break;
default:
break;
case 1:
CLRC;
- AccAXRrl1 (x); // 0->a:x
+ AccAXRrl1 (x); // 0->a:x
break;
case 2:
CLRC;
- AccAXRrl1 (x); // 0->a:x
+ AccAXRrl1 (x); // 0->a:x
CLRC;
- AccAXRrl1 (x); // 0->a:x
+ AccAXRrl1 (x); // 0->a:x
break;
case 3:
case 4:
- case 5: // AAAAABBB:CCCCCDDD = a:x
+ case 5: // AAAAABBB:CCCCCDDD = a:x
- AccRol (8 - shCount); // BBBAAAAA:DDDCCCCC
+ AccRol (8 - shCount); // BBBAAAAA:DDDCCCCC
emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
- AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
+ AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
emitcode ("anl", "a,#0x%02x",
SRMask[shCount]); // 000CCCCC:BBBAAAAA
emitcode ("xch", "a,%s", x); // 000AAAAA:BBBCCCCC
break;
- case 6: // AABBBBBB:CCDDDDDD
+ case 6: // AABBBBBB:CCDDDDDD
emitcode ("mov", "c,acc.7");
- AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
+ AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
emitcode ("mov", "c,acc.7");
- AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
+ AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
SRMask[shCount]); // 000000AA:BBBBBBCC
break;
- case 7: // ABBBBBBB:CDDDDDDD
+ case 7: // ABBBBBBB:CDDDDDDD
emitcode ("mov", "c,acc.7"); // c = A
- AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
+ AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
break;
case 1:
emitcode ("mov", "c,acc.7");
- AccAXRrl1 (x); // s->a:x
+ AccAXRrl1 (x); // s->a:x
break;
case 2:
emitcode ("mov", "c,acc.7");
- AccAXRrl1 (x); // s->a:x
+ AccAXRrl1 (x); // s->a:x
emitcode ("mov", "c,acc.7");
- AccAXRrl1 (x); // s->a:x
+ AccAXRrl1 (x); // s->a:x
break;
case 3:
case 4:
- case 5: // AAAAABBB:CCCCCDDD = a:x
+ case 5: // AAAAABBB:CCCCCDDD = a:x
tlbl = newiTempLabel (NULL);
- AccRol (8 - shCount); // BBBAAAAA:CCCCCDDD
+ AccRol (8 - shCount); // BBBAAAAA:CCCCCDDD
emitcode ("xch", "a,%s", x); // CCCCCDDD:BBBAAAAA
- AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
+ AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA
emitcode ("anl", "a,#0x%02x",
SRMask[shCount]); // 000CCCCC:BBBAAAAA
(unsigned char) ~SRMask[shCount]); // 111AAAAA:BBBCCCCC
emitLabel (tlbl);
- break; // SSSSAAAA:BBBCCCCC
+ break; // SSSSAAAA:BBBCCCCC
- case 6: // AABBBBBB:CCDDDDDD
+ case 6: // AABBBBBB:CCDDDDDD
tlbl = newiTempLabel (NULL);
emitcode ("mov", "c,acc.7");
- AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
+ AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA
emitcode ("mov", "c,acc.7");
- AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
+ AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA
emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC
emitLabel (tlbl);
break;
- case 7: // ABBBBBBB:CDDDDDDD
+ case 7: // ABBBBBBB:CDDDDDDD
tlbl = newiTempLabel (NULL);
emitcode ("mov", "c,acc.7"); // c = A
- AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
+ AccAXLrl1 (x); // BBBBBBBC:DDDDDDDA
emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC
if (size > 1)
{
if (shCount)
- shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ {
+ shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ }
else
- movLeft2Result (left, LSB, result, MSB16, 0);
+ {
+ movLeft2Result (left, LSB, result, MSB16, 0);
+ }
}
aopPut (result, zero, LSB);
}
while (size--)
movLeft2Result (left, size, result, size, 0);
}
-
else if (shCount >= (size * 8))
{
if (sign)
rname = aopGet (left, 0, FALSE, FALSE);
if (*rname != '@')
{
- fprintf(stderr, "probable internal error: unexpected rname @ %s:%d\n",
- __FILE__, __LINE__);
+ fprintf(stderr, "probable internal error: unexpected rname '%s' @ %s:%d\n",
+ rname, __FILE__, __LINE__);
}
else
{
}
/* now some housekeeping stuff */
- if (aop) /* we had to allocate for this iCode */
+ if (aop) /* we had to allocate for this iCode */
{
if (pi) { /* post increment present */
aopPut (left, rname, 0);
if (ifx && !ifx->generated)
{
- genIfxJump (ifx, ifxCond, left, NULL, result);
+ genIfxJump (ifx, ifxCond, left, NULL, result, ic->next);
}
/* done */
}
/* now some housekeeping stuff */
- if (aop) /* we had to allocate for this iCode */
+ if (aop) /* we had to allocate for this iCode */
{
if (pi)
aopPut (left, rname, 0);
if (ifx && !ifx->generated)
{
- genIfxJump (ifx, ifxCond, left, NULL, result);
+ genIfxJump (ifx, ifxCond, left, NULL, result, ic->next);
}
/* done */
if (ifx && !ifx->generated)
{
- genIfxJump (ifx, ifxCond, left, NULL, result);
+ genIfxJump (ifx, ifxCond, left, NULL, result, ic->next);
}
freeAsmop (result, NULL, ic, TRUE);
if (ifx && !ifx->generated)
{
- genIfxJump (ifx, ifxCond, left, NULL, result);
+ genIfxJump (ifx, ifxCond, left, NULL, result, ic->next);
}
freeAsmop (result, NULL, ic, TRUE);
if (ifx && !ifx->generated)
{
- genIfxJump (ifx, ifxCond, left, NULL, result);
+ genIfxJump (ifx, ifxCond, left, NULL, result, ic->next);
}
freeAsmop (result, NULL, ic, TRUE);
}
/* now some housekeeping stuff */
- if (aop) /* we had to allocate for this iCode */
+ if (aop) /* we had to allocate for this iCode */
{
if (pi)
aopPut (result, rname, 0);
/* the result is now in the accumulator or a directly addressable bit */
freeAsmop (cond, NULL, ic, TRUE);
- /* if there was something to be popped then do it */
- if (popIc)
- genIpop (popIc);
-
/* if the condition is a bit variable */
if (isbit && dup)
- genIfxJump(ic, dup, NULL, NULL, NULL);
+ genIfxJump(ic, dup, NULL, NULL, NULL, popIc);
else if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond))
- genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL);
+ genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL, popIc);
else if (isbit && !IS_ITEMP (cond))
- genIfxJump (ic, OP_SYMBOL (cond)->rname, NULL, NULL, NULL);
+ genIfxJump (ic, OP_SYMBOL (cond)->rname, NULL, NULL, NULL, popIc);
else
- genIfxJump (ic, "a", NULL, NULL, NULL);
+ genIfxJump (ic, "a", NULL, NULL, NULL, popIc);
ic->generated = 1;
}
{
char s[SDCC_NAME_MAX];
if (offset)
- sprintf (s, "#(%s >> %d)",
- sym->rname,
- offset * 8);
+ {
+ sprintf (s, "#(%s >> %d)",
+ sym->rname,
+ offset * 8);
+ }
else
- SNPRINTF (s, sizeof(s), "#%s", sym->rname);
+ {
+ SNPRINTF (s, sizeof(s), "#%s", sym->rname);
+ }
aopPut (IC_RESULT (ic), s, offset++);
}
if (opIsGptr (IC_RESULT (ic)))
break;
case IPOP:
+ {
+ iCode *ifxIc, *popIc;
+ bool CommonRegs = FALSE;
+
/* IPOP happens only when trying to restore a
spilt live range, if there is an ifx statement
- following this pop then the if statement might
+ following this pop (or several) then the if statement might
be using some of the registers being popped which
would destory the contents of the register so
we need to check for this condition and handle it */
- if (ic->next &&
- ic->next->op == IFX &&
- regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
- genIfx (ic->next, ic);
+ for (ifxIc = ic->next; ifxIc && ifxIc->op == IPOP; ifxIc = ifxIc->next);
+ for (popIc = ic; popIc && popIc->op == IPOP; popIc = popIc->next)
+ CommonRegs |= (ifxIc && ifxIc->op == IFX && !ifxIc->generated &&
+ regsInCommon (IC_LEFT (popIc), IC_COND (ifxIc)));
+ if (CommonRegs)
+ genIfx (ifxIc, ic);
else
genIpop (ic);
+ }
break;
case CALL:
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_uchar2fs.c _uint2fs.c _ulong2fs.c \
- _heap.c calloc.c malloc.c realloc.c free.c \
+ _heap.c _calloc.c _malloc.c _realloc.c _free.c \
serial.c ser_ir.c printfl.c \
printf_large.c sprintf.c vprintf.c puts.c gets.c \
assert.c time.c bpx.c
--- /dev/null
+/*
+ bug 1509084
+*/
+
+#include <testfwk.h>
+#include <stdbool.h>
+
+#if !defined(__bool_true_false_are_defined)
+#define bool unsigned char
+#endif
+
+unsigned char aa, bb, cc, dd, ee;
+
+void leds_name_repaint(void)
+{
+ unsigned char an;
+ unsigned char dg = aa;
+ bool s = 0;
+
+ for( an = 0; an < 5; an ++ )
+ {
+ s = ( (long) aa >> 1 ) > 0;
+ if( s )
+ {
+ aa += dg + 1;
+ bb += dg + 2;
+ cc += dg + 3;
+ dd += dg + 4;
+ ee += dg + 5;
+ }
+ }
+}
+
+void
+testBug(void)
+{
+ aa = 2;
+ leds_name_repaint();
+ ASSERT(aa == 17);
+}