+2007-12-29 Borut Razem <borut.razem AT siol.net>
+
+ * src/SDCCasm.[ch]: renamed from asm[ch], use dbuf_getline(), ...
+ * src/src.dsp, src/Makefile.bcc, src/Makefile.in, src/common.h,
+ src/SDCCglue.c, src/xa51/main.c: asm.[ch] renamed to SDCCasm.[ch]
+ * support/Util/dbuf_string.[ch]: added function dbuf_getline()
+ * src/ds390/gen.c, src/hc08/gen.c, src/mcs51/gen.c, src/pic16/gen.c,
+ src/pic/gen.c, src/z80/gen.c, src/xa51/gen.c, src/pic16/ralloc.c,
+ src/pic16/pcode.[ch]: added const qualifier
+
+M src/SDCCglue.c
+M
+M
+M
+M
+
2007-12-28 Borut Razem <borut.razem AT siol.net>
* as/asxxsrc/aslex.c: moved from as/mcs51/aslex.c;
SDCCicode.obj SDCCbitv.obj SDCCset.obj SDCClabel.obj \
SDCCBBlock.obj SDCCloop.obj SDCCcse.obj SDCCcflow.obj SDCCdflow.obj \
SDCClrange.obj SDCCptropt.obj SDCCpeeph.obj SDCCglue.obj \
- asm.obj SDCCutil.obj SDCCmacro.obj SDCCdebug.obj cdbFile.obj SDCCerr.obj
+ SDCCasm.obj SDCCutil.obj SDCCmacro.obj SDCCdebug.obj cdbFile.obj SDCCerr.obj
SLIBOBJS = $(SLIB)/NewAlloc.obj $(SLIB)/MySystem.obj $(SLIB)/BuildCmd.obj $(SLIB)/dbuf.obj
SDCCicode.o SDCCbitv.o SDCCset.o SDCClabel.o \
SDCCBBlock.o SDCCloop.o SDCCcse.o SDCCcflow.o SDCCdflow.o \
SDCClrange.o SDCCptropt.o SDCCpeeph.o SDCCglue.o \
- asm.o SDCCmacro.o SDCCutil.o SDCCdebug.o cdbFile.o SDCCdwarf2.o\
+ SDCCasm.o SDCCmacro.o SDCCutil.o SDCCdebug.o cdbFile.o SDCCdwarf2.o\
SDCCerr.o
SPECIAL = SDCCy.h
--- /dev/null
+/*-------------------------------------------------------------------------
+ SDCCasm.c - header file for all types of stuff to support different assemblers.
+
+
+ Written By - Michael Hope <michaelh@juju.net.nz> 2000
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+/* Provides output functions that modify the output string
+ based on the input tokens and the assembler token mapping
+ specification loaded.
+
+ Note that the functions below only handle digit format modifiers.
+ eg %02X is ok, but %lu and %.4u will fail.
+*/
+
+#include <errno.h>
+
+#include "common.h"
+#include "dbuf_string.h"
+
+/* A 'token' is like !blah or %24f and is under the programmers
+ control. */
+
+static hTab *_h;
+
+char *
+FileBaseName (char *fileFullName)
+{
+ char *p = fileFullName;
+
+ if (!fileFullName) {
+ return "unknown";
+ }
+
+ while (*fileFullName)
+ {
+ if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
+ {
+ p = fileFullName;
+ p++;
+ }
+ fileFullName++;
+ }
+ return p;
+}
+
+void
+dbuf_tvprintf (struct dbuf_s *dbuf, const char *format, va_list ap)
+{
+ // Under Linux PPC va_list is a structure instead of a primitive type,
+ // and doesnt like being passed around. This version turns everything
+ // into one function.
+
+ // Supports:
+ // !tokens
+ // %[CIFN] - special formats with no argument (ie list isnt touched)
+ // All of the system formats
+
+ // This is acheived by expanding the tokens and zero arg formats into
+ // one big format string, which is passed to the native printf.
+ static int count;
+ struct dbuf_s tmpDBuf;
+ const char *noTokens;
+ const char *sz = format;
+
+ dbuf_init(&tmpDBuf, INITIAL_INLINEASM);
+
+ /* First pass: expand all of the macros */
+ while (*sz)
+ {
+ if (*sz == '!')
+ {
+ /* Start of a token. Search until the first
+ [non alpha, *] and call it a token. */
+ const char *t;
+ struct dbuf_s token;
+
+ dbuf_init (&token, 64);
+ sz++;
+ while (isalpha ((unsigned char)*sz) || *sz == '*')
+ {
+ dbuf_append (&token, sz++, 1);
+ }
+ /* Now find the token in the token list */
+ if ((t = shash_find (_h, dbuf_c_str(&token))))
+ {
+ dbuf_append_str (&tmpDBuf, t);
+ }
+ else
+ {
+ fprintf (stderr, "Cant find token \"%s\"\n", dbuf_c_str(&token));
+ wassert (0);
+ }
+ dbuf_destroy (&token);
+ }
+ else
+ {
+ dbuf_append_char (&tmpDBuf, *sz++);
+ }
+ }
+
+ /* Second pass: Expand any macros that we own */
+ dbuf_c_str (&tmpDBuf);
+ sz = noTokens = dbuf_detach (&tmpDBuf);
+
+ /* recycle tmpDBuf */
+ dbuf_init (&tmpDBuf, INITIAL_INLINEASM);
+
+ while (*sz)
+ {
+ if (*sz == '%')
+ {
+ // See if its one that we handle.
+ sz++;
+ switch (*sz)
+ {
+ case 'C':
+ // Code segment name.
+ dbuf_append_str (&tmpDBuf, CODE_NAME);
+ sz++;
+ break;
+
+ case 'F':
+ // Source file name.
+ dbuf_append_str (&tmpDBuf, fullSrcFileName);
+ sz++;
+ break;
+
+ case 'N':
+ // Current function name.
+ dbuf_append_str (&tmpDBuf, currFunc->rname);
+ sz++;
+ break;
+
+ case 'I':
+ // Unique ID.
+ dbuf_printf (&tmpDBuf, "%u", ++count);
+ sz++;
+ break;
+
+ default:
+ // Not one of ours. Copy until the end.
+ dbuf_append_char (&tmpDBuf, '%');
+ while (!isalpha ((unsigned char)*sz))
+ dbuf_append_char (&tmpDBuf, *sz++);
+
+ dbuf_append_char (&tmpDBuf, *sz++);
+ }
+ }
+ else
+ {
+ dbuf_append_char (&tmpDBuf, *sz++);
+ }
+ }
+
+ dbuf_free (noTokens);
+
+ dbuf_vprintf (dbuf, dbuf_c_str (&tmpDBuf), ap);
+
+ dbuf_destroy (&tmpDBuf);
+}
+
+void
+dbuf_tprintf (struct dbuf_s *dbuf, const char *szFormat,...)
+{
+ va_list ap;
+ va_start (ap, szFormat);
+ dbuf_tvprintf (dbuf, szFormat, ap);
+ va_end (ap);
+}
+
+void
+tsprintf (char *buffer, size_t len, const char *szFormat,...)
+{
+ va_list ap;
+ struct dbuf_s dbuf;
+ size_t copyLen;
+
+ dbuf_init (&dbuf, INITIAL_INLINEASM);
+
+ va_start (ap, szFormat);
+ dbuf_tvprintf (&dbuf, szFormat, ap);
+ va_end (ap);
+
+ copyLen = min (len - 1, dbuf_get_length (&dbuf));
+ memcpy (buffer, dbuf_get_buf (&dbuf), copyLen);
+ buffer[copyLen] = '\0';
+ dbuf_destroy (&dbuf);
+}
+
+void
+tfprintf (FILE *fp, const char *szFormat,...)
+{
+ va_list ap;
+ struct dbuf_s dbuf;
+ size_t len;
+
+ dbuf_init (&dbuf, INITIAL_INLINEASM);
+
+ va_start (ap, szFormat);
+ dbuf_tvprintf (&dbuf, szFormat, ap);
+ va_end (ap);
+
+ len = dbuf_get_length (&dbuf);
+ fwrite(dbuf_get_buf (&dbuf), 1, len, fp);
+ dbuf_destroy (&dbuf);
+}
+
+void
+asm_addTree (const ASM_MAPPINGS *pMappings)
+{
+ const ASM_MAPPING *pMap;
+
+ /* Traverse down first */
+ if (pMappings->pParent)
+ asm_addTree (pMappings->pParent);
+ pMap = pMappings->pMappings;
+ while (pMap->szKey && pMap->szValue) {
+ shash_add (&_h, pMap->szKey, pMap->szValue);
+ pMap++;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* printILine - return the readable i-code for this ic */
+/*-----------------------------------------------------------------*/
+const char *
+printILine (iCode *ic)
+{
+ char *verbalICode;
+ struct dbuf_s tmpBuf;
+ iCodeTable *icTab = getTableEntry (ic->op);
+
+ dbuf_init (&tmpBuf, 1024);
+
+ if (INLINEASM == ic->op)
+ dbuf_append (&tmpBuf, "inline", (sizeof "inline") - 1);
+ else
+ {
+ /* stuff the temporary file with the readable icode */
+ icTab->iCodePrint (&tmpBuf, ic, icTab->printName);
+ }
+
+ /* null terminate the buffer */
+ dbuf_c_str (&tmpBuf);
+ verbalICode = dbuf_detach (&tmpBuf);
+
+ /* kill the trailing NL */
+ if ('\n' == verbalICode[strlen(verbalICode) - 1])
+ verbalICode[strlen(verbalICode) - 1] = '\0';
+
+ /* and throw it up */
+ return verbalICode;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* skipLine - skip the line from file infp */
+/*-----------------------------------------------------------------*/
+static int
+skipLine (FILE *infp)
+{
+ int c;
+
+ while ((c = getc(infp)) != '\n' && EOF != c)
+ ;
+
+ return EOF != c;
+}
+
+/*-----------------------------------------------------------------*/
+/* printCLine - return the c-code for this lineno */
+/*-----------------------------------------------------------------*/
+/* int rewinds=0; */
+const char *
+printCLine (const char *srcFile, int lineno)
+{
+ static FILE *inFile = NULL;
+ static struct dbuf_s line;
+ static struct dbuf_s lastSrcFile;
+ static char dbufInitialized = 0;
+ static int inLineNo = 0;
+
+ if (!dbufInitialized)
+ {
+ dbuf_init (&line, 1024);
+ dbuf_init (&lastSrcFile, 1024);
+ dbufInitialized = 1;
+ }
+ else
+ {
+ /* empty the dynamic buffer */
+ dbuf_set_length (&line, 0);
+ }
+
+ if (inFile)
+ {
+ if (strcmp (dbuf_c_str (&lastSrcFile), srcFile) != 0)
+ {
+ fclose (inFile);
+ inFile = NULL;
+ inLineNo = 0;
+ dbuf_set_length (&lastSrcFile, 0);
+ dbuf_append_str (&lastSrcFile, srcFile);
+ }
+ }
+
+ if (!inFile && !(inFile = fopen(srcFile, "r")))
+ {
+ /* can't open the file:
+ don't panic, just return the error message */
+ dbuf_printf(&line, "ERROR: %s", strerror(errno));
+
+ return dbuf_c_str (&line);
+ }
+ else
+ {
+ if (lineno < inLineNo)
+ {
+ /* past the lineno: rewind the file pointer */
+ fseek (inFile, 0, SEEK_SET);
+ inLineNo = 0;
+ /* rewinds++; */
+ }
+
+ /* skip lines until lineno */
+ while (inLineNo + 1 < lineno)
+ {
+ if (!skipLine (inFile))
+ goto err_no_line;
+ }
+
+ /* get the line */
+ if (dbuf_getline (&line, inFile))
+ {
+ inLineNo++;
+ if (inLineNo == lineno)
+ {
+ const char *inLineString = dbuf_c_str (&line);
+ size_t len = strlen (inLineString);
+
+ /* remove the trailing NL */
+ if ('\n' == inLineString[len - 1])
+ {
+ dbuf_set_length (&line, len - 1);
+ inLineString = dbuf_c_str (&line);
+ }
+
+ /* skip leading spaces */
+ while (isspace (*inLineString))
+ inLineString++;
+
+ return inLineString;
+ }
+ }
+
+err_no_line:
+ dbuf_printf(&line, "ERROR: no line number %d in file %s", lineno, srcFile);
+
+ return dbuf_c_str (&line);
+ }
+}
+
+static const ASM_MAPPING _asxxxx_mapping[] =
+{
+ {"labeldef", "%s::"},
+ {"slabeldef", "%s:"},
+ {"tlabeldef", "%05d$:"},
+ {"tlabel", "%05d$"},
+ {"immed", "#"},
+ {"zero", "#0x00"},
+ {"one", "#0x01"},
+ {"area", ".area %s"},
+ {"areacode", ".area %s"},
+ {"areadata", ".area %s"},
+ {"areahome", ".area %s"},
+ {"ascii", ".ascii \"%s\""},
+ {"ds", ".ds %d"},
+ {"db", ".db"},
+ {"dbs", ".db %s"},
+ {"dw", ".dw"},
+ {"dws", ".dw %s"},
+ {"constbyte", "0x%02X"},
+ {"constword", "0x%04X"},
+ {"immedword", "#0x%04X"},
+ {"immedbyte", "#0x%02X"},
+ {"hashedstr", "#%s"},
+ {"lsbimmeds", "#<%s"},
+ {"msbimmeds", "#>%s"},
+ {"module", ".module %s"},
+ {"global", ".globl %s"},
+ {"fileprelude", ""},
+ {"functionheader",
+ "; ---------------------------------\n"
+ "; Function %s\n"
+ "; ---------------------------------"
+ },
+ {"functionlabeldef", "%s:"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {"los","(%s & 0xFF)"},
+ {"his","(%s >> 8)"},
+ {"hihis","(%s >> 16)"},
+ {"hihihis","(%s >> 24)"},
+ {"lod","(%d & 0xFF)"},
+ {"hid","(%d >> 8)"},
+ {"hihid","(%d >> 16)"},
+ {"hihihid","(%d >> 24)"},
+ {"lol","(%05d$ & 0xFF)"},
+ {"hil","(%05d$ >> 8)"},
+ {"hihil","(%05d$ >> 16)"},
+ {"hihihil","(%05d$ >> 24)"},
+ {"equ","="},
+ {"org", ".org 0x%04X"},
+ {NULL, NULL}
+};
+
+static const ASM_MAPPING _gas_mapping[] =
+{
+ {"labeldef", "%s::"},
+ {"slabeldef", "%s:"},
+ {"tlabeldef", "%05d$:"},
+ {"tlabel", "%05d$"},
+ {"immed", "#"},
+ {"zero", "#0x00"},
+ {"one", "#0x01"},
+ {"area", ".section %s"},
+ {"areacode", ".section %s"},
+ {"areadata", ".section %s"},
+ {"areahome", ".section %s"},
+ {"ascii", ".ascii \"%s\""},
+ {"ds", ".ds %d"},
+ {"db", ".db"},
+ {"dbs", ".db %s"},
+ {"dw", ".dw"},
+ {"dws", ".dw %s"},
+ {"constbyte", "0x%02X"},
+ {"constword", "0x%04X"},
+ {"immedword", "#0x%04X"},
+ {"immedbyte", "#0x%02X"},
+ {"hashedstr", "#%s"},
+ {"lsbimmeds", "#<%s"},
+ {"msbimmeds", "#>%s"},
+ {"module", ".file \"%s.c\""},
+ {"global", ".globl %s"},
+ {"extern", ".globl %s"},
+ {"fileprelude", ""},
+ {"functionheader",
+ "; ---------------------------------\n"
+ "; Function %s\n"
+ "; ---------------------------------"
+ },
+ {"functionlabeldef", "%s:"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {NULL, NULL}
+};
+
+static const ASM_MAPPING _a390_mapping[] =
+{
+ {"labeldef", "%s:"},
+ {"slabeldef", "%s:"},
+ {"tlabeldef", "L%05d:"},
+ {"tlabel", "L%05d"},
+ {"immed", "#"},
+ {"zero", "#0"},
+ {"one", "#1"},
+ {"area", "; SECTION NOT SUPPORTED"},
+ {"areacode", "; SECTION NOT SUPPORTED"},
+ {"areadata", "; SECTION NOT SUPPORTED"},
+ {"areahome", "; SECTION NOT SUPPORTED"},
+ {"ascii", "db \"%s\""},
+ {"ds", "; STORAGE NOT SUPPORTED"},
+ {"db", "db"},
+ {"dbs", "db \"%s\""},
+ {"dw", "dw"},
+ {"dws", "dw %s"},
+ {"constbyte", "0%02xh"},
+ {"constword", "0%04xh"},
+ {"immedword", "#0%04Xh"},
+ {"immedbyte", "#0%02Xh"},
+ {"hashedstr", "#%s"},
+ {"lsbimmeds", "#<%s"},
+ {"msbimmeds", "#>%s"},
+ {"module", "; .file \"%s.c\""},
+ {"global", "; .globl %s"},
+ {"fileprelude", ""},
+ {"functionheader",
+ "; ---------------------------------\n"
+ "; Function %s\n"
+ "; ---------------------------------"
+ },
+ {"functionlabeldef", "%s:"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {"los","(%s & 0FFh)"},
+ {"his","((%s / 256) & 0FFh)"},
+ {"hihis","((%s / 65536) & 0FFh)"},
+ {"hihihis","((%s / 16777216) & 0FFh)"},
+ {"lod","(%d & 0FFh)"},
+ {"hid","((%d / 256) & 0FFh)"},
+ {"hihid","((%d / 65536) & 0FFh)"},
+ {"hihihid","((%d / 16777216) & 0FFh)"},
+ {"lol","(L%05d & 0FFh)"},
+ {"hil","((L%05d / 256) & 0FFh)"},
+ {"hihil","((L%05d / 65536) & 0FFh)"},
+ {"hihihil","((L%09d / 16777216) & 0FFh)"},
+ {"equ"," equ"},
+ {"org", ".org 0x%04X"},
+ {NULL, NULL}
+};
+
+static const ASM_MAPPING _xa_asm_mapping[] =
+{
+ {"labeldef", "%s:"},
+ {"slabeldef", "%s:"},
+ {"tlabeldef", "L%05d:"},
+ {"tlabel", "L%05d"},
+ {"immed", "#"},
+ {"zero", "#0"},
+ {"one", "#1"},
+ {"area", ".area %s"},
+ {"areacode", ".area %s"},
+ {"areadata", ".area %s"},
+ {"areahome", ".area %s"},
+ {"ascii", ".db \"%s\""},
+ {"ds", ".ds %d"},
+ {"db", ".db"},
+ {"dbs", ".db \"%s\""},
+ {"dw", ".dw"},
+ {"dws", ".dw %s"},
+ {"constbyte", "0x%02x"},
+ {"constword", "0x%04x"},
+ {"immedword", "0x%04x"},
+ {"immedbyte", "0x%02x"},
+ {"hashedstr", "#%s"},
+ {"lsbimmeds", "#<%s"},
+ {"msbimmeds", "#>%s"},
+ {"module", "; .module %s"},
+ {"global", ".globl %s"},
+ {"fileprelude", ""},
+ {"functionheader",
+ "; ---------------------------------\n"
+ "; Function %s\n"
+ "; ---------------------------------"
+ },
+ {"functionlabeldef", "%s:"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {"los","(%s & 0FFh)"},
+ {"his","((%s / 256) & 0FFh)"},
+ {"hihis","((%s / 65536) & 0FFh)"},
+ {"hihihis","((%s / 16777216) & 0FFh)"},
+ {"lod","(%d & 0FFh)"},
+ {"hid","((%d / 256) & 0FFh)"},
+ {"hihid","((%d / 65536) & 0FFh)"},
+ {"hihihid","((%d / 16777216) & 0FFh)"},
+ {"lol","(L%05d & 0FFh)"},
+ {"hil","((L%05d / 256) & 0FFh)"},
+ {"hihil","((L%05d / 65536) & 0FFh)"},
+ {"hihihil","((L%09d / 16777216) & 0FFh)"},
+ {"equ"," equ"},
+ {NULL, NULL}
+};
+
+const ASM_MAPPINGS asm_asxxxx_mapping =
+{
+ NULL,
+ _asxxxx_mapping
+};
+
+const ASM_MAPPINGS asm_gas_mapping =
+{
+ NULL,
+ _gas_mapping
+};
+
+const ASM_MAPPINGS asm_a390_mapping =
+{
+ NULL,
+ _a390_mapping
+};
+
+const ASM_MAPPINGS asm_xa_asm_mapping =
+{
+ NULL,
+ _xa_asm_mapping
+};
--- /dev/null
+/*-------------------------------------------------------------------------
+ SDCCasm.h - header file for all types of stuff to support different assemblers.
+
+ Written By - Michael Hope <michaelh@juju.net.nz> 2000
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+#ifndef ASM_PORT_INCLUDE
+#define ASM_PORT_INCLUDE
+
+#include "dbuf.h"
+
+void tfprintf (FILE * fp, const char *szFormat, ...);
+void tsprintf (char *buffer, size_t len, const char *szFormat, ...);
+void dbuf_tprintf (struct dbuf_s *dbuf, const char *szFormat, ...);
+void dbuf_tvprintf (struct dbuf_s *dbuf, const char *szFormat, va_list ap);
+
+typedef struct
+ {
+ const char *szKey;
+ const char *szValue;
+ }
+ASM_MAPPING;
+
+typedef struct _ASM_MAPPINGS ASM_MAPPINGS;
+
+/* PENDING: could include the peephole rules here as well.
+ */
+struct _ASM_MAPPINGS
+ {
+ const ASM_MAPPINGS *pParent;
+ const ASM_MAPPING *pMappings;
+ };
+
+/* The default asxxxx token mapping.
+ */
+extern const ASM_MAPPINGS asm_asxxxx_mapping;
+extern const ASM_MAPPINGS asm_gas_mapping;
+extern const ASM_MAPPINGS asm_a390_mapping;
+extern const ASM_MAPPINGS asm_xa_asm_mapping;
+
+/** Last entry has szKey = NULL.
+ */
+void asm_addTree (const ASM_MAPPINGS *pMappings);
+
+char *FileBaseName (char *fileFullName);
+
+const char *printILine (iCode *ic);
+const char *printCLine (const char *srcFile, int lineno);
+#endif
-------------------------------------------------------------------------*/
#include "common.h"
-#include "asm.h"
#include <time.h>
#include "newalloc.h"
#include <fcntl.h>
+++ /dev/null
-/** @file asm.c
- Provides output functions that modify the output string
- based on the input tokens and the assembler token mapping
- specification loaded.
-
- Note that the functions below only handle digit format modifiers.
- eg %02X is ok, but %lu and %.4u will fail.
-*/
-#include <errno.h>
-
-#include "common.h"
-#include "asm.h"
-#include "dbuf_string.h"
-
-/* A 'token' is like !blah or %24f and is under the programmers
- control. */
-#define MAX_TOKEN_LEN 64
-
-static hTab *_h;
-
-char *
-FileBaseName (char *fileFullName)
-{
- char *p = fileFullName;
-
- if (!fileFullName) {
- return "unknown";
- }
-
- while (*fileFullName)
- {
- if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
- {
- p = fileFullName;
- p++;
- }
- fileFullName++;
- }
- return p;
-}
-
-void
-dbuf_tvprintf (struct dbuf_s *dbuf, const char *format, va_list ap)
-{
- // Under Linux PPC va_list is a structure instead of a primitive type,
- // and doesnt like being passed around. This version turns everything
- // into one function.
-
- // Supports:
- // !tokens
- // %[CIFN] - special formats with no argument (ie list isnt touched)
- // All of the system formats
-
- // This is acheived by expanding the tokens and zero arg formats into
- // one big format string, which is passed to the native printf.
- static int count;
- struct dbuf_s tmpDBuf;
- const char *noTokens;
- char *p;
- char token[MAX_TOKEN_LEN];
- const char *sz = format;
-
- dbuf_init(&tmpDBuf, INITIAL_INLINEASM);
-
- /* First pass: expand all of the macros */
- while (*sz)
- {
- if (*sz == '!')
- {
- /* Start of a token. Search until the first
- [non alpha, *] and call it a token. */
- const char *t;
- p = token;
- sz++;
- while (isalpha ((unsigned char)*sz) || *sz == '*')
- {
- *p++ = *sz++;
- }
- *p = '\0';
- /* Now find the token in the token list */
- if ((t = shash_find (_h, token)))
- {
- dbuf_append_str(&tmpDBuf, t);
- }
- else
- {
- fprintf (stderr, "Cant find token \"%s\"\n", token);
- wassert (0);
- }
- }
- else
- {
- dbuf_append_char(&tmpDBuf, *sz++);
- }
- }
-
- /* Second pass: Expand any macros that we own */
- noTokens = dbuf_c_str(&tmpDBuf);
- sz = noTokens;
-
- /* recycle tmpDBuf */
- dbuf_init(&tmpDBuf, INITIAL_INLINEASM);
-
- while (*sz)
- {
- if (*sz == '%')
- {
- // See if its one that we handle.
- sz++;
- switch (*sz)
- {
- case 'C':
- // Code segment name.
- dbuf_append_str(&tmpDBuf, CODE_NAME);
- sz++;
- break;
-
- case 'F':
- // Source file name.
- dbuf_append_str(&tmpDBuf, fullSrcFileName);
- sz++;
- break;
-
- case 'N':
- // Current function name.
- dbuf_append_str(&tmpDBuf, currFunc->rname);
- sz++;
- break;
-
- case 'I':
- // Unique ID.
- dbuf_printf(&tmpDBuf, "%u", ++count);
- sz++;
- break;
-
- default:
- // Not one of ours. Copy until the end.
- dbuf_append_char(&tmpDBuf, '%');
- while (!isalpha ((unsigned char)*sz))
- dbuf_append_char(&tmpDBuf, *sz++);
-
- dbuf_append_char(&tmpDBuf, *sz++);
- }
- }
- else
- {
- dbuf_append_char(&tmpDBuf, *sz++);
- }
- }
-
- dbuf_free(noTokens);
-
- sz = dbuf_c_str(&tmpDBuf);
-
- dbuf_vprintf(dbuf, sz, ap);
-
- dbuf_destroy(&tmpDBuf);
-}
-
-void
-dbuf_tprintf (struct dbuf_s *dbuf, const char *szFormat,...)
-{
- va_list ap;
- va_start (ap, szFormat);
- dbuf_tvprintf (dbuf, szFormat, ap);
- va_end(ap);
-}
-
-void
-tsprintf (char *buffer, size_t len, const char *szFormat,...)
-{
- va_list ap;
- struct dbuf_s dbuf;
- size_t copyLen;
-
- dbuf_init(&dbuf, INITIAL_INLINEASM);
-
- va_start (ap, szFormat);
- dbuf_tvprintf (&dbuf, szFormat, ap);
- va_end(ap);
-
- copyLen = min(len - 1, dbuf_get_length(&dbuf));
- memcpy(buffer, dbuf_get_buf(&dbuf), copyLen);
- buffer[copyLen] = '\0';
- dbuf_destroy(&dbuf);
-}
-
-void
-tfprintf (FILE *fp, const char *szFormat,...)
-{
- va_list ap;
- struct dbuf_s dbuf;
- size_t len;
-
- dbuf_init(&dbuf, INITIAL_INLINEASM);
-
- va_start (ap, szFormat);
- dbuf_tvprintf (&dbuf, szFormat, ap);
- va_end(ap);
-
- len = dbuf_get_length(&dbuf);
- fwrite(dbuf_get_buf(&dbuf), 1, len, fp);
- dbuf_destroy(&dbuf);
-}
-
-void
-asm_addTree (const ASM_MAPPINGS * pMappings)
-{
- const ASM_MAPPING *pMap;
-
- /* Traverse down first */
- if (pMappings->pParent)
- asm_addTree (pMappings->pParent);
- pMap = pMappings->pMappings;
- while (pMap->szKey && pMap->szValue) {
- shash_add (&_h, pMap->szKey, pMap->szValue);
- pMap++;
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* printILine - return the readable i-code for this ic */
-/*-----------------------------------------------------------------*/
-char *
-printILine (iCode *ic)
-{
- char *verbalICode;
- struct dbuf_s tmpBuf;
- iCodeTable *icTab=getTableEntry(ic->op);
-
- dbuf_init(&tmpBuf, 1024);
-
- if (INLINEASM == ic->op)
- dbuf_append (&tmpBuf, "inline", (sizeof "inline") - 1);
- else {
- /* stuff the temporary file with the readable icode */
- icTab->iCodePrint(&tmpBuf, ic, icTab->printName);
- }
-
- /* null terminate the buffer */
- dbuf_c_str(&tmpBuf);
- verbalICode = dbuf_detach(&tmpBuf);
-
- /* kill the trailing NL */
- if ('\n' == verbalICode[strlen(verbalICode) - 1])
- verbalICode[strlen(verbalICode) - 1] = '\0';
-
- /* and throw it up */
- return verbalICode;
-}
-
-/*-----------------------------------------------------------------*/
-/* printCLine - return the c-code for this lineno */
-/*-----------------------------------------------------------------*/
-/* int rewinds=0; */
-char *
-printCLine (char *srcFile, int lineno)
-{
- static FILE *inFile=NULL;
- static char inLineString[1024];
- static int inLineNo=0;
- static char lastSrcFile[PATH_MAX];
- char *ilsP=inLineString;
-
- if (inFile) {
- if (strcmp (lastSrcFile, srcFile) != 0) {
- fclose (inFile);
- inFile = NULL;
- inLineNo = 0;
- strncpyz (lastSrcFile, srcFile, PATH_MAX);
- }
- }
- if (!inFile && !(inFile = fopen(srcFile, "r"))) {
- /* can't open the file:
- don't panic, just return the error message */
- SDCCsnprintf(inLineString, sizeof(inLineString), "ERROR: %s", strerror(errno));
- }
- else {
- if (lineno<inLineNo) {
- fseek (inFile, 0, SEEK_SET);
- inLineNo=0;
- /* rewinds++; */
- }
- while (fgets (inLineString, 1024, inFile)) {
- inLineNo++;
- if (inLineNo==lineno) {
- // remove the trailing NL
- inLineString[strlen(inLineString)-1]='\0';
- break;
- }
- }
- }
-
- while (isspace ((unsigned char)*ilsP))
- ilsP++;
-
- return ilsP;
-}
-
-static const ASM_MAPPING _asxxxx_mapping[] =
-{
- {"labeldef", "%s::"},
- {"slabeldef", "%s:"},
- {"tlabeldef", "%05d$:"},
- {"tlabel", "%05d$"},
- {"immed", "#"},
- {"zero", "#0x00"},
- {"one", "#0x01"},
- {"area", ".area %s"},
- {"areacode", ".area %s"},
- {"areadata", ".area %s"},
- {"areahome", ".area %s"},
- {"ascii", ".ascii \"%s\""},
- {"ds", ".ds %d"},
- {"db", ".db"},
- {"dbs", ".db %s"},
- {"dw", ".dw"},
- {"dws", ".dw %s"},
- {"constbyte", "0x%02X"},
- {"constword", "0x%04X"},
- {"immedword", "#0x%04X"},
- {"immedbyte", "#0x%02X"},
- {"hashedstr", "#%s"},
- {"lsbimmeds", "#<%s"},
- {"msbimmeds", "#>%s"},
- {"module", ".module %s"},
- {"global", ".globl %s"},
- {"fileprelude", ""},
- {"functionheader",
- "; ---------------------------------\n"
- "; Function %s\n"
- "; ---------------------------------"
- },
- {"functionlabeldef", "%s:"},
- {"bankimmeds", "0 ; PENDING: bank support"},
- {"los","(%s & 0xFF)"},
- {"his","(%s >> 8)"},
- {"hihis","(%s >> 16)"},
- {"hihihis","(%s >> 24)"},
- {"lod","(%d & 0xFF)"},
- {"hid","(%d >> 8)"},
- {"hihid","(%d >> 16)"},
- {"hihihid","(%d >> 24)"},
- {"lol","(%05d$ & 0xFF)"},
- {"hil","(%05d$ >> 8)"},
- {"hihil","(%05d$ >> 16)"},
- {"hihihil","(%05d$ >> 24)"},
- {"equ","="},
- {"org", ".org 0x%04X"},
- {NULL, NULL}
-};
-
-static const ASM_MAPPING _gas_mapping[] =
-{
- {"labeldef", "%s::"},
- {"slabeldef", "%s:"},
- {"tlabeldef", "%05d$:"},
- {"tlabel", "%05d$"},
- {"immed", "#"},
- {"zero", "#0x00"},
- {"one", "#0x01"},
- {"area", ".section %s"},
- {"areacode", ".section %s"},
- {"areadata", ".section %s"},
- {"areahome", ".section %s"},
- {"ascii", ".ascii \"%s\""},
- {"ds", ".ds %d"},
- {"db", ".db"},
- {"dbs", ".db %s"},
- {"dw", ".dw"},
- {"dws", ".dw %s"},
- {"constbyte", "0x%02X"},
- {"constword", "0x%04X"},
- {"immedword", "#0x%04X"},
- {"immedbyte", "#0x%02X"},
- {"hashedstr", "#%s"},
- {"lsbimmeds", "#<%s"},
- {"msbimmeds", "#>%s"},
- {"module", ".file \"%s.c\""},
- {"global", ".globl %s"},
- {"extern", ".globl %s"},
- {"fileprelude", ""},
- {"functionheader",
- "; ---------------------------------\n"
- "; Function %s\n"
- "; ---------------------------------"
- },
- {"functionlabeldef", "%s:"},
- {"bankimmeds", "0 ; PENDING: bank support"},
- {NULL, NULL}
-};
-
-static const ASM_MAPPING _a390_mapping[] =
-{
- {"labeldef", "%s:"},
- {"slabeldef", "%s:"},
- {"tlabeldef", "L%05d:"},
- {"tlabel", "L%05d"},
- {"immed", "#"},
- {"zero", "#0"},
- {"one", "#1"},
- {"area", "; SECTION NOT SUPPORTED"},
- {"areacode", "; SECTION NOT SUPPORTED"},
- {"areadata", "; SECTION NOT SUPPORTED"},
- {"areahome", "; SECTION NOT SUPPORTED"},
- {"ascii", "db \"%s\""},
- {"ds", "; STORAGE NOT SUPPORTED"},
- {"db", "db"},
- {"dbs", "db \"%s\""},
- {"dw", "dw"},
- {"dws", "dw %s"},
- {"constbyte", "0%02xh"},
- {"constword", "0%04xh"},
- {"immedword", "#0%04Xh"},
- {"immedbyte", "#0%02Xh"},
- {"hashedstr", "#%s"},
- {"lsbimmeds", "#<%s"},
- {"msbimmeds", "#>%s"},
- {"module", "; .file \"%s.c\""},
- {"global", "; .globl %s"},
- {"fileprelude", ""},
- {"functionheader",
- "; ---------------------------------\n"
- "; Function %s\n"
- "; ---------------------------------"
- },
- {"functionlabeldef", "%s:"},
- {"bankimmeds", "0 ; PENDING: bank support"},
- {"los","(%s & 0FFh)"},
- {"his","((%s / 256) & 0FFh)"},
- {"hihis","((%s / 65536) & 0FFh)"},
- {"hihihis","((%s / 16777216) & 0FFh)"},
- {"lod","(%d & 0FFh)"},
- {"hid","((%d / 256) & 0FFh)"},
- {"hihid","((%d / 65536) & 0FFh)"},
- {"hihihid","((%d / 16777216) & 0FFh)"},
- {"lol","(L%05d & 0FFh)"},
- {"hil","((L%05d / 256) & 0FFh)"},
- {"hihil","((L%05d / 65536) & 0FFh)"},
- {"hihihil","((L%09d / 16777216) & 0FFh)"},
- {"equ"," equ"},
- {"org", ".org 0x%04X"},
- {NULL, NULL}
-};
-
-static const ASM_MAPPING _xa_asm_mapping[] =
-{
- {"labeldef", "%s:"},
- {"slabeldef", "%s:"},
- {"tlabeldef", "L%05d:"},
- {"tlabel", "L%05d"},
- {"immed", "#"},
- {"zero", "#0"},
- {"one", "#1"},
- {"area", ".area %s"},
- {"areacode", ".area %s"},
- {"areadata", ".area %s"},
- {"areahome", ".area %s"},
- {"ascii", ".db \"%s\""},
- {"ds", ".ds %d"},
- {"db", ".db"},
- {"dbs", ".db \"%s\""},
- {"dw", ".dw"},
- {"dws", ".dw %s"},
- {"constbyte", "0x%02x"},
- {"constword", "0x%04x"},
- {"immedword", "0x%04x"},
- {"immedbyte", "0x%02x"},
- {"hashedstr", "#%s"},
- {"lsbimmeds", "#<%s"},
- {"msbimmeds", "#>%s"},
- {"module", "; .module %s"},
- {"global", ".globl %s"},
- {"fileprelude", ""},
- {"functionheader",
- "; ---------------------------------\n"
- "; Function %s\n"
- "; ---------------------------------"
- },
- {"functionlabeldef", "%s:"},
- {"bankimmeds", "0 ; PENDING: bank support"},
- {"los","(%s & 0FFh)"},
- {"his","((%s / 256) & 0FFh)"},
- {"hihis","((%s / 65536) & 0FFh)"},
- {"hihihis","((%s / 16777216) & 0FFh)"},
- {"lod","(%d & 0FFh)"},
- {"hid","((%d / 256) & 0FFh)"},
- {"hihid","((%d / 65536) & 0FFh)"},
- {"hihihid","((%d / 16777216) & 0FFh)"},
- {"lol","(L%05d & 0FFh)"},
- {"hil","((L%05d / 256) & 0FFh)"},
- {"hihil","((L%05d / 65536) & 0FFh)"},
- {"hihihil","((L%09d / 16777216) & 0FFh)"},
- {"equ"," equ"},
- {NULL, NULL}
-};
-
-const ASM_MAPPINGS asm_asxxxx_mapping =
-{
- NULL,
- _asxxxx_mapping
-};
-
-const ASM_MAPPINGS asm_gas_mapping =
-{
- NULL,
- _gas_mapping
-};
-
-const ASM_MAPPINGS asm_a390_mapping =
-{
- NULL,
- _a390_mapping
-};
-
-const ASM_MAPPINGS asm_xa_asm_mapping =
-{
- NULL,
- _xa_asm_mapping
-};
+++ /dev/null
-#ifndef ASM_PORT_INCLUDE
-#define ASM_PORT_INCLUDE
-
-#include "dbuf.h"
-
-void tfprintf (FILE * fp, const char *szFormat, ...);
-void tsprintf (char *buffer, size_t len, const char *szFormat, ...);
-void dbuf_tprintf (struct dbuf_s *dbuf, const char *szFormat, ...);
-void dbuf_tvprintf (struct dbuf_s *dbuf, const char *szFormat, va_list ap);
-
-typedef struct
- {
- const char *szKey;
- const char *szValue;
- }
-ASM_MAPPING;
-
-typedef struct _ASM_MAPPINGS ASM_MAPPINGS;
-
-/* PENDING: could include the peephole rules here as well.
- */
-struct _ASM_MAPPINGS
- {
- const ASM_MAPPINGS *pParent;
- const ASM_MAPPING *pMappings;
- };
-
-/* The default asxxxx token mapping.
- */
-extern const ASM_MAPPINGS asm_asxxxx_mapping;
-extern const ASM_MAPPINGS asm_gas_mapping;
-extern const ASM_MAPPINGS asm_a390_mapping;
-extern const ASM_MAPPINGS asm_xa_asm_mapping;
-
-/** Last entry has szKey = NULL.
- */
-void asm_addTree (const ASM_MAPPINGS * pMappings);
-
-char *FileBaseName (char *fileFullName);
-
-char *printILine (iCode *ic);
-char *printCLine (char *srcFile, int lineno);
-#endif
#include "SDCCpeeph.h"
#include "SDCCdebug.h"
#include "SDCCutil.h"
+#include "SDCCasm.h"
-#include "asm.h"
#include "port.h"
#include "newalloc.h"
cln = ic->lineno;
}
if (options.iCodeInAsm) {
- char *iLine = printILine(ic);
+ const char *iLine = printILine(ic);
emitcode(";", "ic:%d: %s", ic->key, iLine);
dbuf_free(iLine);
}
default:
/* This should never happen, right? */
- fprintf(stderr, "*** Probable error: unsupported op 0x%x (%c) in %s @ %d\n",
+ fprintf(stderr, "*** Probable error: unsupported op 0x%x (%c) in %s @ %d\n",
ic->op, ic->op, __FILE__, __LINE__);
ic = ic;
}
(((x)->type == AOP_REG) \
&& ((x)->aopu.aop_reg[0] == hc08_reg_h) \
&& ((x)->size == 1) )
-
+
#define CLRC emitcode("clc","")
static lineNode *lineHead = NULL;
srcidx = sreg->rIdx;
dstidx = dreg->rIdx;
-
+
if (srcidx==dstidx)
return;
-
+
switch (dstidx)
{
case A_IDX:
/* there is no frame unless there is a function */
if (!currFunc)
return;
-
+
debugFile->writeFrameAddress (NULL, hc08_reg_sp,
1 + _G.stackOfs + _G.stackPushes);
}
pushReg (regs *reg, bool freereg)
{
int regidx = reg->rIdx;
-
+
switch (regidx)
{
case A_IDX:
pullReg (regs *reg)
{
int regidx = reg->rIdx;
-
+
switch (regidx)
{
case A_IDX:
n = 0;
updateCFA();
}
- }
+ }
}
{
static char buffer[256];
char *buf = buffer;
-
+
if (!aop)
return "(asmop*)NULL";
DD(emitcode ("", "; loadRegFromAop (%s, %s, %d)",
reg->name, aopName (aop), loffset));
-
+
/* If operand is volatile, we cannot optimize. */
if (!aop->op || isOperandVolatile (aop->op, FALSE))
goto forceload;
-
+
/* If this register already has this offset of the operand
then we need only mark it as in use. */
if (reg->aop && reg->aop->op && aop->op
hc08_useReg (reg);
return;
}
-
+
if (hc08_reg_x->aop && hc08_reg_x->aop->op && aop->op
&& operandsEqu(hc08_reg_x->aop->op,aop->op)
hc08_useReg (reg);
return;
}
-
+
if (hc08_reg_a->aop && hc08_reg_a->aop->op && aop->op
&& operandsEqu(hc08_reg_a->aop->op,aop->op)
&& (hc08_reg_a->aopofs == loffset))
loadRegFromAop (hc08_reg_x, aop, loffset+1);
}
break;
- }
+ }
// ignore caching for now
#if 0
int loffset;
asmop *newaop = newAsmop (aop->type);
memcpy (newaop, aop, sizeof(*newaop));
-
+
DD(emitcode("", "; forcedStackAop %s", aopName(aop)));
if (copyOrig && hc08_reg_a->isFree)
reg = hc08_reg_x;
else
reg = NULL;
-
+
for (loffset=0; loffset < newaop->size; loffset++)
{
asmop *aopsof = newAsmop (AOP_SOF);
storeRegToAop (hc08_reg_x, aop, loffset+1);
}
break;
- }
+ }
/* Disable the register tracking for now */
#if 0
hc08_reg_xa->aop = NULL;
DD(emitcode("","; marking xa stale"));
}
-
+
reg->aop = aop;
reg->aopofs = loffset;
}
{
// int regidx = reg->rIdx;
int size = aop->size;
-
+
if (size<=loffset)
return;
-
+
if (!isSigned)
{
/* Unsigned case */
&& operandsEqu(srcaop->op, dstaop->op) && srcofs == dstofs
&& dstaop->type == srcaop->type)
return;
-
+
if (srcaop->stacked && srcaop->stk_aop[srcofs])
{
transferAopAop (srcaop->stk_aop[srcofs], 0, dstaop, dstofs);
// aopName (srcaop), srcofs, aopName (dstaop), dstofs));
// DD(emitcode ("", "; srcaop->type = %d", srcaop->type));
// DD(emitcode ("", "; dstaop->type = %d", dstaop->type));
-
+
if (dstofs >= dstaop->size)
return;
{
unsigned long lit;
unsigned long bytemask;
-
+
lit = ulFromVal (srcaop->aopu.aop_lit);
bytemask = (lit >> (srcofs*8)) & 0xff;
-
+
if (bytemask == 0)
{
emitcode ("clr", "%s", aopAdrStr(dstaop, dstofs, FALSE));
if (hc08_reg_a->isFree)
reg = hc08_reg_a;
else if (hc08_reg_x->isFree)
- reg = hc08_reg_x;
+ reg = hc08_reg_x;
else
{
pushReg (hc08_reg_a, TRUE);
reg = hc08_reg_a;
}
}
-
+
loadRegFromAop (reg, srcaop, srcofs);
storeRegToAop (reg, dstaop, dstofs);
-
+
if (!keepreg)
pullOrFreeReg (hc08_reg_a, needpula);
}
rmwWithAop (rmwop, aop->stk_aop[loffset], 0);
return;
}
-
+
switch (aop->type)
{
case AOP_REG:
default:
emitcode (rmwop, "%s", aopAdrStr (aop, loffset, FALSE));
}
-
+
}
aop->aopu.aop_stk = sym->stack;
return aop;
}
-
+
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"aopForSym should never reach here");
exit(1);
-
+
/* if it is in code space */
if (IN_CODESPACE (space))
aop->code = 1;
aop->size = getSize( operandType (op));
//printf ("reusing underlying symbol %s\n",OP_SYMBOL (op)->name);
//printf (" with size = %d\n", aop->size);
-
+
aop->op = op;
aop->isaddr = op->isaddr;
/* if (aop->isaddr & IS_ITEMP (op))
//printf (" with size = %d\n", aop->size);
return;
}
-
+
/* else must be a dummy iTemp */
sym->aop = op->aop = aop = newAsmop (AOP_DUMMY);
aop->size = getSize (sym->type);
}
pullNull (stackAdjust);
}
-
+
dealloc:
/* all other cases just dealloc */
if (op)
asmop *newaop = NULL;
sym_link *type, *etype;
int p_type;
-
+
DD(emitcode ("", "; aopDerefAop(%s)", aopName(aop)));
if (aop->op)
{
-
+
type = operandType (aop->op);
etype = getSpec (type);
/* if op is of type of pointer then it is simple */
}
else
p_type = UPOINTER;
-
+
switch (aop->type)
{
case AOP_IMMD:
return NULL;
}
-
+
return newaop;
}
char *s = buffer;
char *rs;
int offset = aop->size - 1 - loffset;
-
+
/* offset is greater than
size then zero */
case AOP_DUMMY:
return zero;
-
+
case AOP_IMMD:
if (aop->aopu.aop_immd.from_cast_remat && (loffset == (aop->size-1)))
{
if (resultInA)
hc08_freeReg(hc08_reg_a);
-
+
switch (aop->type)
{
case AOP_REG:
asmopToBool ( AOP (IC_LEFT (ic)), TRUE);
emitcode ("eor", one);
storeRegToFullAop (hc08_reg_a, AOP (IC_RESULT (ic)), FALSE);
-
+
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
}
int offset = 0;
int size;
regs* reg = hc08_reg_a;
-
+
D(emitcode ("; genCpl",""));
/* assign asmOps to operand & result */
loadRegFromAop (hc08_reg_a, AOP( IC_LEFT (ic)), 0);
emitcode ("nega", "");
hc08_freeReg (hc08_reg_a);
- storeRegToFullAop (hc08_reg_a, AOP( IC_RESULT (ic)),
+ storeRegToFullAop (hc08_reg_a, AOP( IC_RESULT (ic)),
SPEC_USIGN (operandType (IC_LEFT (ic))));
pullOrFreeReg (hc08_reg_a, needpula);
}
result = forceStackedAop (AOP (IC_RESULT (ic)), FALSE);
else
result = AOP (IC_RESULT (ic));
-
+
needpula = pushRegIfUsed (hc08_reg_a);
sub="sub";
while (size--)
storeRegToAop (hc08_reg_a, result, offset++);
sub = "sbc";
}
- storeRegSignToUpperAop (hc08_reg_a, result, offset,
+ storeRegSignToUpperAop (hc08_reg_a, result, offset,
SPEC_USIGN (operandType (IC_LEFT (ic))));
pullOrFreeReg (hc08_reg_a, needpula);
-
+
if (IS_AOP_XA (AOP (IC_RESULT (ic))))
freeAsmop (NULL, result, ic, TRUE);
}
(IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) ||
IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic)))))
return;
-
+
/* safe the registers in use at this time but skip the
ones for the result */
- rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
hc08_rUmaskForOp (IC_RESULT(ic)));
ic->regsSaved = 1;
/* restore the registers in use at this time but skip the
ones for the result */
- rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
hc08_rUmaskForOp (IC_RESULT(ic)));
for (i = hc08_nRegs; i >= 0; i--)
hc08_aop_pass[offset+(sic->argreg-1)], 0);
offset--;
}
- }
+ }
freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
}
}
/* if we need assign a result value */
if ((IS_ITEMP (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->nRegs ||
- OP_SYMBOL (IC_RESULT (ic))->accuse ||
+ OP_SYMBOL (IC_RESULT (ic))->accuse ||
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
emitcode ("", "%s:", sym->rname);
lineCurr->isLabel = 1;
ftype = operandType (IC_LEFT (ic));
-
+
_G.stackOfs = 0;
_G.stackPushes = 0;
debugFile->writeFrameAddress (NULL, hc08_reg_sp, 0);
}
_G.stackOfs = sym->stack;
_G.stackPushes = 0;
-
+
/* if critical function then turn interrupts off */
if (IFFUNC_ISCRITICAL (ftype))
{
{
int i;
regs *reg;
-
+
/* For the high level labels we cannot depend on any */
/* register's contents. Amnesia time. */
for (i=A_IDX;i<=XA_IDX;i++)
/* special case never generate */
if (IC_LABEL (ic) == entryLabel)
return;
-
+
debugFile->writeLabel(IC_LABEL (ic), ic);
emitLabel (IC_LABEL (ic));
count++;
/* If we have any pushes or pops, we cannot predict the distance.
- I don't like this at all, this should be dealt with in the
+ I don't like this at all, this should be dealt with in the
back-end */
if (ic->op == IPUSH || ic->op == IPOP) {
return 0;
unsigned int size = getDataSize (IC_RESULT (ic));
unsigned int offset;
symbol *tlbl = NULL;
-
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
DD(emitcode ("", "; IS_AOP_HX = %d", IS_AOP_HX (AOP (left))));
-
+
if ((IS_AOP_HX (AOP (left)) ||
( (AOP_TYPE (left) == AOP_DIR) && (AOP_TYPE (result) == AOP_DIR) )
)
return TRUE;
}
- DD(emitcode ("", "; icount = %d, sameRegs=%d", icount,
+ DD(emitcode ("", "; icount = %d, sameRegs=%d", icount,
sameRegs (AOP (left), AOP (result))));
-
+
if ((icount > 255) || (icount<0))
return FALSE;
if (size>1)
emitLabel (tlbl);
-
+
pullOrFreeReg (hc08_reg_a, needpula);
-
+
return TRUE;
}
DD(emitcode("","; left size = %d", getDataSize (IC_LEFT(ic))));
DD(emitcode("","; right size = %d", getDataSize (IC_RIGHT(ic))));
DD(emitcode("","; result size = %d", getDataSize (IC_RESULT(ic))));
-
+
size = getDataSize (IC_RESULT (ic));
leftOp = AOP(IC_LEFT(ic));
unsigned int size = getDataSize (IC_RESULT (ic));
// int offset;
// symbol *tlbl;
-
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
pullOrFreeReg (hc08_reg_x, needpulx);
return TRUE;
}
-
+
if ((icount > 1) || (icount<0))
return FALSE;
D(emitcode ("; genMinusDec",""));
rmwWithAop ("dec", AOP (result), 0);
-
+
return TRUE;
}
{
char *sub;
int size, offset = 0;
-
+
asmop *leftOp, *rightOp;
D(emitcode ("; genMinus",""));
storeRegToAop (hc08_reg_a, AOP (IC_RESULT (ic)), offset++);
sub = "sbc";
}
-
-
+
+
// adjustArithmeticResult (ic);
release:
if (size<1 || size>2) {
// this should never happen
- fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
+ fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
AOP_SIZE(result), __FILE__, lineno);
exit (1);
}
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
-
+
/* lUnsigned rUnsigned negLiteral negate case */
/* false false false odd 3 */
/* false false true even 3 */
hc08_dirtyReg (hc08_reg_xa, FALSE);
storeRegToFullAop (hc08_reg_xa, AOP (result), TRUE);
hc08_freeReg (hc08_reg_xa);
-
+
return;
}
if (AOP_TYPE(right)==AOP_LIT && lUnsigned && !rUnsigned)
{
signed char val=(signed char) ulFromVal (AOP (right)->aopu.aop_lit);
-
+
loadRegFromAop (hc08_reg_a, AOP (left), 0);
if (val < 0)
emitcode ("ldx", "#0x%02x", -val);
else
emitcode ("ldx", "#0x%02x", val);
-
+
emitcode ("mul", "");
-
+
if (val < 0)
{
rmwWithReg ("neg", hc08_reg_a);
emitLabel (tlbl4);
rmwWithReg ("neg", hc08_reg_x);
}
-
+
hc08_dirtyReg (hc08_reg_xa, FALSE);
storeRegToFullAop (hc08_reg_xa, AOP (result), TRUE);
hc08_freeReg (hc08_reg_xa);
return;
}
-
+
/* case 3 */
adjustStack (-1);
/* special cases first */
/* if both are of size == 1 */
-// if (getSize(operandType(left)) == 1 &&
+// if (getSize(operandType(left)) == 1 &&
// getSize(operandType(right)) == 1)
- if (AOP_SIZE (left) == 1 &&
+ if (AOP_SIZE (left) == 1 &&
AOP_SIZE (right) == 1)
{
genMultOneByte (left, right, result);
int offset = 0;
bool lUnsigned, rUnsigned;
bool runtimeSign, compiletimeSign;
-
+
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
emitLabel (tlbl2);
}
}
-
+
loadRegFromConst (hc08_reg_h, zero);
emitcode ("div", "");
hc08_dirtyReg (hc08_reg_x, FALSE);
hc08_dirtyReg (hc08_reg_a, FALSE);
hc08_dirtyReg (hc08_reg_h, FALSE);
-
+
if (runtimeSign || compiletimeSign)
{
tlbl3 = newiTempLabel (NULL);
rmwWithReg ("ror", hc08_reg_x);
emitBranch ("bpl", tlbl3);
}
-
+
rmwWithReg ("neg", hc08_reg_a);
if (runtimeSign)
emitLabel (tlbl3);
-
+
storeRegToAop (hc08_reg_a, AOP (result), 0);
-
+
if (size > 1)
{
/* msb is 0x00 or 0xff depending on the sign */
int offset = 0;
bool lUnsigned, rUnsigned;
bool runtimeSign, compiletimeSign;
-
+
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
D(emitcode ("; genModOneByte",""));
size = AOP_SIZE (result);
-
+
if (lUnsigned && rUnsigned)
{
/* unsigned is easy */
}
/* signed is a little bit more difficult */
-
+
if (AOP_TYPE(right) == AOP_LIT)
{
signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
emitLabel (tlbl1);
}
}
-
+
/* let's see what's needed: */
/* apply negative sign during runtime */
runtimeSign = FALSE;
runtimeSign = TRUE;
adjustStack (-1);
emitcode ("clr", "1,s");
-
+
loadRegFromAop (hc08_reg_a, AOP (left), 0);
tlbl2 = newiTempLabel (NULL);
emitcode ("tsta", "");
emitLabel (tlbl2);
}
}
-
+
loadRegFromConst (hc08_reg_h, zero);
emitcode ("div", "");
hc08_freeReg (hc08_reg_a);
rmwWithReg ("ror", hc08_reg_x);
emitBranch ("bpl", tlbl3);
}
-
+
rmwWithReg ("neg", hc08_reg_a);
if (runtimeSign)
emitLabel (tlbl3);
-
+
storeRegToAop (hc08_reg_a, AOP (result), 0);
-
+
if (size > 1)
{
/* msb is 0x00 or 0xff depending on the sign */
{
storeRegToFullAop (hc08_reg_h, AOP (result), FALSE);
}
-
+
hc08_freeReg (hc08_reg_a);
hc08_freeReg (hc08_reg_x);
hc08_freeReg (hc08_reg_h);
/*------------------------------------------------------------------*/
static void
genCmp (iCode * ic, iCode * ifx)
-{
+{
operand *left, *right, *result;
sym_link *letype, *retype;
int sign, opcode;
jlbl = IC_FALSE (ifx);
}
}
-
+
size = max (AOP_SIZE (left), AOP_SIZE (right));
-
+
if ((size == 2)
&& ((AOP_TYPE (left) == AOP_DIR) && (AOP_SIZE (left) == 2))
- && ((AOP_TYPE (right) == AOP_LIT) ||
+ && ((AOP_TYPE (right) == AOP_LIT) ||
((AOP_TYPE (right) == AOP_DIR) && (AOP_SIZE (right) == 2)) )
&& hc08_reg_hx->isFree)
{
else
{
sub = "sub";
-
+
/* These conditions depend on the Z flag bit, but Z is */
/* only valid for the last byte of the comparison, not */
/* the whole value. So exchange the operands to get a */
right = temp;
opcode = exchangedCmp (opcode);
}
-
+
if ((AOP_TYPE (right) == AOP_LIT) && !isOperandVolatile (left, FALSE))
{
lit = ulFromVal (AOP (right)->aopu.aop_lit);
symbol *tlbl = newiTempLabel (NULL);
char *inst;
- freeAsmop (result, NULL, ic, TRUE);
-
+ freeAsmop (result, NULL, ic, TRUE);
+
inst = branchInstCmp (opcode, sign);
emitBranch (inst, tlbl);
emitBranch ("jmp", jlbl);
{
symbol *tlbl1 = newiTempLabel (NULL);
symbol *tlbl2 = newiTempLabel (NULL);
-
+
emitBranch (branchInstCmp (opcode, sign), tlbl1);
loadRegFromConst (hc08_reg_a, zero);
emitBranch ("bra", tlbl2);
loadRegFromConst (hc08_reg_a, one);
emitLabel (tlbl2);
storeRegToFullAop (hc08_reg_a, AOP(result), FALSE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
-
+
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void
genCmpEQorNE (iCode * ic, iCode * ifx)
-{
+{
operand *left, *right, *result;
sym_link *letype, *retype;
int sign, opcode;
symbol *jlbl = NULL;
symbol *tlbl_NE = NULL;
symbol *tlbl_EQ = NULL;
-
+
opcode = ic->op;
D(emitcode ("; genCmpEQorNE", "(%s)",nameCmp (opcode)));
aopOp (left, ic, FALSE);
aopOp (right, ic, FALSE);
aopOp (result, ic, TRUE);
-
+
/* need register operand on left, prefer literal operand on right */
if ((AOP_TYPE (right) == AOP_REG) || AOP_TYPE (left) == AOP_LIT)
{
jlbl = IC_FALSE (ifx);
}
}
-
+
size = max (AOP_SIZE (left), AOP_SIZE (right));
-
+
if ((size == 2)
&& ((AOP_TYPE (left) == AOP_DIR) && (AOP_SIZE (left) == 2))
- && ((AOP_TYPE (right) == AOP_LIT) ||
+ && ((AOP_TYPE (right) == AOP_LIT) ||
((AOP_TYPE (right) == AOP_DIR) && (AOP_SIZE (right) == 2)) )
&& hc08_reg_hx->isFree)
{
if (ifx)
{
- freeAsmop (result, NULL, ic, TRUE);
-
+ freeAsmop (result, NULL, ic, TRUE);
+
if (opcode == EQ_OP)
{
if (!tlbl_EQ)
else
{
symbol *tlbl = newiTempLabel (NULL);
-
+
if (opcode == EQ_OP)
{
if (!tlbl_EQ)
emitLabel (tlbl_NE);
loadRegFromConst (hc08_reg_a, one);
}
-
+
emitLabel (tlbl);
storeRegToFullAop (hc08_reg_a, AOP(result), FALSE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
-
+
}
/* Make sure this is the only use of the pointer */
if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
return FALSE;
-
+
DD(emitcode("", "; checking pset operandsEqu"));
if (pset & !operandsEqu (IC_RESULT (ic), IC_RESULT (lic)))
return FALSE;
return FALSE;
sym = OP_SYMBOL (IC_LEFT (ic));
-
+
DD(emitcode("", "; checking remat"));
if (!sym->remat)
return FALSE;
-
-
+
+
if (pget)
{
D(emitcode ("; genPointerGetOfs",""));
aopOp (IC_LEFT(ic), ic, FALSE);
derefaop = aopDerefAop (AOP (IC_LEFT (ic)));
freeAsmop (IC_LEFT(ic), NULL, ic, TRUE);
-
+
aopOp (IC_RIGHT(ic), ic, FALSE);
aopOp (IC_RESULT(lic), lic, FALSE);
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RESULT(lic));
derefaop->size = size;
-
+
while (size--)
{
emitcode ("lda", "%s,x",
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (IC_RIGHT(ic), NULL, ic, TRUE);
freeAsmop (IC_RESULT(lic), NULL, lic, TRUE);
-
+
return TRUE;
}
aopOp (IC_RIGHT(ic), ic, FALSE);
aopOp (IC_RIGHT(lic), lic, FALSE);
-
+
if (AOP_SIZE (IC_RIGHT (ic)) == 1)
{
if (SPEC_USIGN (getSpec (operandType (IC_RIGHT (ic)))))
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RIGHT(lic));
derefaop->size = size;
-
+
while (size--)
{
loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (lic)), size);
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (IC_RIGHT(ic), NULL, ic, TRUE);
freeAsmop (IC_RIGHT(lic), NULL, lic, TRUE);
-
+
return TRUE;
}
-
+
return FALSE;
}
sym_link *retype = getSpec (type);
iCode *lic = ic->next;
int isize ;
-
+
/* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
if (!IS_SYMOP(op)) 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) &&
+ isOperandEqual(IC_RESULT(lic),op) &&
isOperandLiteral(IC_RIGHT(lic)) &&
operandLitValue(IC_RIGHT(lic)) == isize) {
return lic;
tlbl = newiTempLabel (NULL);
tlbl0 = newiTempLabel (NULL);
-
+
asmopToBool (AOP (left), FALSE);
emitBranch ("beq", tlbl0);
asmopToBool (AOP (right), FALSE);
hc08_useReg (hc08_reg_a);
hc08_freeReg (hc08_reg_a);
-
+
storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
tlbl = newiTempLabel (NULL);
tlbl0 = newiTempLabel (NULL);
-
+
asmopToBool (AOP (left), FALSE);
emitBranch ("bne", tlbl0);
asmopToBool (AOP (right), FALSE);
hc08_useReg (hc08_reg_a);
hc08_freeReg (hc08_reg_a);
-
+
storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
unsigned long litinv;
unsigned char bytemask;
-
+
// int bytelit = 0;
// char buffer[10];
if (AOP_TYPE (right) == AOP_LIT)
lit = ulFromVal (AOP (right)->aopu.aop_lit);
-
+
size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
-
+
if (AOP_TYPE (result) == AOP_CRY
&& size > 1
&& (isOperandVolatile (left, FALSE) || isOperandVolatile (right, FALSE)))
/* this generates ugly code, but meets volatility requirements */
loadRegFromConst (hc08_reg_a, zero);
pushReg (hc08_reg_a, TRUE);
-
+
offset = 0;
while (size--)
{
emitcode ("sta", "1,s");
offset++;
}
-
+
pullReg (hc08_reg_a);
emitcode ("tsta", "");
genIfxJump (ifx, "a");
goto release;
}
-
+
if (AOP_TYPE (result) == AOP_CRY)
{
symbol *tlbl = NULL;
wassertl (ifx, "AOP_CRY result without ifx");
-
+
offset = 0;
while (size--)
{
bytemask = (lit >> (offset*8)) & 0xff;
-
+
if (AOP_TYPE (right) == AOP_LIT && bytemask == 0)
{
/* do nothing */
genIfxJump (ifx, "a");
goto release;
}
-
+
size = AOP_SIZE (result);
if (AOP_TYPE (right) == AOP_LIT)
goto release;
}
}
-
+
offset = 0;
while (size--)
{
bytemask = (lit >> (offset*8)) & 0xff;
-
+
if (AOP_TYPE (right) == AOP_LIT && bytemask == 0)
{
if (isOperandVolatile (left, FALSE))
{
loadRegFromAop (hc08_reg_a, AOP (left), offset);
- hc08_freeReg( hc08_reg_a);
+ hc08_freeReg( hc08_reg_a);
}
storeConstToAop (zero, AOP (result), offset);
}
loadRegFromAop (hc08_reg_a, AOP (left), offset);
accopWithAop ("and", AOP (right), offset);
storeRegToAop (hc08_reg_a, AOP (result), offset);
- hc08_freeReg (hc08_reg_a);
+ hc08_freeReg (hc08_reg_a);
}
offset++;
}
if (AOP_TYPE (right) == AOP_LIT)
lit = ulFromVal (AOP (right)->aopu.aop_lit);
-
+
size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
-
+
if (AOP_TYPE (result) == AOP_CRY
&& size > 1
&& (isOperandVolatile (left, FALSE) || isOperandVolatile (right, FALSE)))
/* this generates ugly code, but meets volatility requirements */
loadRegFromConst (hc08_reg_a, zero);
pushReg (hc08_reg_a, TRUE);
-
+
offset = 0;
while (size--)
{
emitcode ("sta", "1,s");
offset++;
}
-
+
pullReg (hc08_reg_a);
emitcode ("tsta", "");
genIfxJump (ifx, "a");
goto release;
}
-
+
if (AOP_TYPE (result) == AOP_CRY)
{
symbol *tlbl = NULL;
wassertl (ifx, "AOP_CRY result without ifx");
-
+
offset = 0;
while (size--)
{
bytemask = (lit >> (offset*8)) & 0xff;
-
+
if (AOP_TYPE (right) == AOP_LIT && bytemask == 0x00)
{
rmwWithAop ("tst", AOP (left), offset);
emitLabel (tlbl);
genIfxJump (ifx, "a");
}
-
+
if (AOP_TYPE (right) == AOP_LIT)
lit = ulFromVal (AOP (right)->aopu.aop_lit);
aopAdrStr (AOP (left), bitpos >> 3, FALSE));
goto release;
}
-
+
offset = 0;
while (size--)
{
bytemask = (lit >> (offset*8)) & 0xff;
-
+
if (AOP_TYPE (right) == AOP_LIT && bytemask == 0xff)
{
if (isOperandVolatile (left, FALSE))
{
loadRegFromAop (hc08_reg_a, AOP (left), offset);
- hc08_freeReg( hc08_reg_a);
+ hc08_freeReg( hc08_reg_a);
}
transferAopAop (AOP (right), offset, AOP (result), offset);
}
loadRegFromAop (hc08_reg_a, AOP (left), offset);
accopWithAop ("ora", AOP (right), offset);
storeRegToAop (hc08_reg_a, AOP (result), offset);
- hc08_freeReg (hc08_reg_a);
+ hc08_freeReg (hc08_reg_a);
}
offset++;
}
{
symbol *tlbl;
wassertl (ifx, "AOP_CPY result without ifx");
-
+
tlbl = newiTempLabel (NULL);
size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
offset = 0;
emitcode ("tsta","");
else
accopWithAop ("eor", AOP (right), offset);
- hc08_freeReg( hc08_reg_a);
+ hc08_freeReg( hc08_reg_a);
if (size)
emitBranch ("bne", tlbl);
else
offset++;
}
}
-
+
if (AOP_TYPE (right) == AOP_LIT)
lit = ulFromVal (AOP (right)->aopu.aop_lit);
loadRegFromAop (hc08_reg_a, AOP (left), offset);
accopWithAop ("eor", AOP (right), offset);
storeRegToAop (hc08_reg_a, AOP (result), offset++);
- hc08_freeReg( hc08_reg_a);
+ hc08_freeReg( hc08_reg_a);
}
//release:
symbol *sym, *tempsym;
asmop *aop;
char *l;
-
+
while (*inlin)
{
if (*inlin == '_')
if ((2+bp-buffer)>sizeof(buffer))
fprintf(stderr, "Inline assembly buffer overflow\n");
-
+
//printf("%s\n",buffer);
emitcode (buffer,"");
}
hc08_dirtyReg (hc08_reg_a, FALSE);
storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
hc08_freeReg (hc08_reg_a);
-
+
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
result = IC_RESULT (ic);
aopOp (left, ic, FALSE);
aopOp (result, ic, FALSE);
-
+
switch (AOP_SIZE (left))
{
case 1: /* swap nibbles in byte */
default:
wassertl(FALSE, "unsupported SWAP operand size");
}
-
+
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
AccLsh (int shCount)
{
int i;
-
+
shCount &= 0x0007; // shCount : 0..7
/* Shift counts of 4 and 5 are currently optimized for code size. */
AccSRsh (int shCount)
{
int i;
-
+
shCount &= 0x0007; // shCount : 0..7
if (shCount == 7)
AccRsh (int shCount, bool sign)
{
int i;
-
+
if (sign)
{
AccSRsh (shCount);
return;
}
-
+
shCount &= 0x0007; // shCount : 0..7
/* Shift counts of 4 and 5 are currently optimized for code size. */
XAccLsh (int shCount)
{
int i;
-
+
shCount &= 0x000f; // shCount : 0..15
if (shCount>=8)
XAccSRsh (int shCount)
{
int i;
-
+
shCount &= 0x000f; // shCount : 0..7
/* if we can beat 2n cycles or bytes for some special case, do it here */
XAccRsh (int shCount, bool sign)
{
int i;
-
+
if (sign)
{
XAccSRsh (shCount);
return;
}
-
+
shCount &= 0x000f; // shCount : 0..f
/* if we can beat 2n cycles or bytes for some special case, do it here */
int i;
bool needpula = FALSE;
bool needpulx = FALSE;
-
+
needpula = pushRegIfUsed (hc08_reg_a);
needpulx = pushRegIfUsed (hc08_reg_x);
D(emitcode ("; genlshTwo",""));
-
+
size = getDataSize (result);
/* if shCount >= 8 */
genlshFour (result, left, shCount);
break;
default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"*** ack! mystery literal shift!\n");
break;
}
aopResult = AOP (result);
if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
- || isOperandVolatile (result, FALSE))
+ || isOperandVolatile (result, FALSE))
aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
/* now move the left to the result if they are not the
}
freeAsmop (left, NULL, ic, TRUE);
AOP (result) = aopResult;
-
+
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
offset = 0;
emitcode ("tstx", "");
emitBranch ("beq", tlbl1);
emitLabel (tlbl);
-
+
shift="lsl";
for (offset=0;offset<size;offset++)
{
- rmwWithAop (shift, AOP (result), offset);
+ rmwWithAop (shift, AOP (result), offset);
shift="rol";
}
rmwWithReg ("dec", hc08_reg_x);
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
hc08_freeReg (hc08_reg_x);
-
+
freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
int shCount, int sign)
{
/* TODO: handle cases where left == result */
-
+
D(emitcode ("; genrshFour",""));
/* if shifting more that 3 bytes */
char *shift;
bool sign;
asmop *aopResult;
-
+
D(emitcode ("; genRightShift",""));
/* if signed then we do it the hard way preserve the
aopResult = AOP (result);
if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
- || isOperandVolatile (result, FALSE))
+ || isOperandVolatile (result, FALSE))
aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
/* now move the left to the result if they are not the
}
freeAsmop (left, NULL, ic, TRUE);
AOP (result) = aopResult;
-
+
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
offset = 0;
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
hc08_freeReg (hc08_reg_x);
-
+
freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
emitcode ("rola", "");
emitcode ("clra", "");
emitcode ("sbc", zero);
-
+
while (rsize--)
storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
int blen; /* bitfield length */
int bstr; /* bitfield starting bit within byte */
asmop *derefaop;
-
+
D(emitcode ("; genUnpackBitsImmed",""));
aopOp (result, ic, TRUE);
derefaop = aopDerefAop (AOP (left));
freeAsmop (left, NULL, ic, TRUE);
derefaop->size = size;
-
+
etype = getSpec (operandType (result));
rsize = getSize (operandType (result));
blen = SPEC_BLEN (etype);
if (!ifx && bstr)
{
symbol *tlbl = newiTempLabel (NULL);
-
+
loadRegFromConst (hc08_reg_a, zero);
emitcode ("brclr", "#%d,%s,%05d$",
bstr, aopAdrStr (derefaop, 0, FALSE),
symbol *tlbl = newiTempLabel (NULL);
symbol *jlbl;
char * inst;
-
+
if (IC_TRUE (ifx))
{
jlbl = IC_TRUE (ifx);
storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
}
-
+
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
-
+
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a");
{
int size;
asmop *derefaop;
-
+
D(emitcode ("; genDataPointerGet",""));
aopOp (result, ic, TRUE);
derefaop = aopDerefAop (AOP (left));
freeAsmop (left, NULL, ic, TRUE);
derefaop->size = size;
-
+
while (size--)
{
if (!ifx)
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
-
+
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a");
if (getSize (operandType (result))>1)
ifx = NULL;
-
+
aopOp (left, ic, FALSE);
/* if left is rematerialisable and
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
-
+
if (pi) {
aopOp (IC_RESULT (pi), pi, FALSE);
storeRegToAop (hc08_reg_hx, AOP (IC_RESULT (pi)), 0);
freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
pi->generated = 1;
}
-
+
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a");
}
hc08_freeReg (hc08_reg_hx);
-
+
}
/*-----------------------------------------------------------------*/
emitcode ("ora","#0x%02x", litval);
hc08_dirtyReg (hc08_reg_a, FALSE);
emitcode ("sta", ",x");
-
+
hc08_freeReg (hc08_reg_a);
return;
}
-
+
/* Case with a bitfield length < 8 and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), 0);
emitcode ("ora", "1,s");
emitcode ("sta", ",x");
pullReg (hc08_reg_a);
-
+
hc08_freeReg (hc08_reg_a);
return;
}
if (rlen)
{
mask = (((unsigned char) -1 << rlen) & 0xff);
-
+
if (AOP_TYPE (right) == AOP_LIT)
{
/* Case with partial byte and literal source
hc08_freeReg (hc08_reg_a);
return;
}
-
+
/* Case with partial byte and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), offset);
if (AOP_TYPE (right) == AOP_LIT)
{
litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
-
- emitcode ((litval & 1) ? "bset" : "bclr",
+
+ emitcode ((litval & 1) ? "bset" : "bclr",
"#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
}
else
{
symbol *tlbl1 = newiTempLabel (NULL);
symbol *tlbl2 = newiTempLabel (NULL);
-
+
loadRegFromAop (hc08_reg_a, AOP (right), 0);
emitcode ("bit", "#1");
emitBranch ("bne", tlbl1);
}
goto release;
}
-
+
/* If the bitfield length is less than a byte */
if (blen < 8)
{
emitcode ("ora","#0x%02x", litval);
hc08_dirtyReg (hc08_reg_a, FALSE);
storeRegToAop (hc08_reg_a, derefaop, 0);
-
+
hc08_freeReg (hc08_reg_a);
goto release;
}
-
+
/* Case with a bitfield length < 8 and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), 0);
emitcode ("ora", "1,s");
storeRegToAop (hc08_reg_a, derefaop, 0);
pullReg (hc08_reg_a);
-
+
hc08_freeReg (hc08_reg_a);
goto release;
}
if (rlen)
{
mask = (((unsigned char) -1 << rlen) & 0xff);
-
+
if (AOP_TYPE (right) == AOP_LIT)
{
/* Case with partial byte and literal source
hc08_freeReg (hc08_reg_a);
goto release;
}
-
+
/* Case with partial byte and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), offset);
hc08_freeReg (hc08_reg_a);
-release:
+release:
freeAsmop (right, NULL, ic, TRUE);
freeAsmop (NULL, derefaop, ic, TRUE);
}
derefaop = aopDerefAop (AOP (result));
freeAsmop (result, NULL, ic, TRUE);
derefaop->size = size;
-
+
while (size--)
{
transferAopAop (AOP (right), size, derefaop, size);
type = operandType (result);
etype = getSpec (type);
-
+
aopOp (result, ic, FALSE);
/* if the result is rematerializable */
loadRegFromAop(hc08_reg_hx, AOP (right), 0);
goto release;
}
-
+
/* general case */
size = AOP_SIZE (result);
while (size--)
symbol *jtab;
symbol *jtablo = newiTempLabel (NULL);
symbol *jtabhi = newiTempLabel (NULL);
-
+
D(emitcode ("; genJumpTab",""));
aopOp (IC_JTCOND (ic), ic, FALSE);
-
+
if (hc08_reg_x->isFree && hc08_reg_x->isFree)
{
/* get the condition into x */
{
adjustStack(-2);
pushReg(hc08_reg_hx, TRUE);
-
+
/* get the condition into x */
loadRegFromAop (hc08_reg_x, AOP (IC_JTCOND (ic)), 0);
freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
emitcode ("sta", "3,s");
emitcode ("lda", "%05d$,x", jtablo->key + 100);
emitcode ("sta", "4,s");
-
+
pullReg(hc08_reg_hx);
emitcode ("rts", "");
_G.stackPushes += 2;
{
int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
char gpValStr[10];
-
+
if (gpVal == -1)
{
// pointerTypeToGPByte will have bitched.
exit(1);
}
-
+
sprintf(gpValStr, "#0x%x", gpVal);
aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
- }
+ }
#endif
goto release;
}
if (!IS_SPEC (rtype) || SPEC_USIGN (rtype) || AOP_TYPE(right)==AOP_CRY)
{
while (size--)
- storeConstToAop (zero, AOP (result), offset++);
+ storeConstToAop (zero, AOP (result), offset++);
}
else
{
emitcode ("dbnz", "%s,%05d$", aopAdrStr (AOP (IC_RESULT (ic)), 0, FALSE),
lbl->key + 100);
-
+
emitBranch ("bra", lbl1);
emitLabel (lbl);
emitBranch ("jmp", IC_TRUE (ifx));
aopOp (IC_RESULT (ic), ic, FALSE);
size = AOP_SIZE (IC_RESULT (ic));
offset = 0;
-
+
if (ic->argreg) {
while (size--) {
transferAopAop( hc08_aop_pass[offset+(ic->argreg-1)], 0,
hc08_freeReg (hc08_aop_pass[offset]->aopu.aop_reg[0]);
offset++;
}
- }
+ }
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
genCritical (iCode *ic)
{
D(emitcode("; genCritical",""));
-
+
if (IC_RESULT (ic))
aopOp (IC_RESULT (ic), ic, TRUE);
genEndCritical (iCode *ic)
{
D(emitcode("; genEndCritical",""));
-
+
if (IC_RIGHT (ic))
{
aopOp (IC_RIGHT (ic), ic, FALSE);
spname = "_spx";
else
spname = "sp";
-
+
debugFile->writeFrameAddress (NULL, NULL, 0); /* have no idea where frame is now */
hc08_aop_pass[0] = newAsmop (AOP_REG);
for (ic = lic; ic; ic = ic->next)
{
-
+
_G.current_iCode = ic;
-
+
if (ic->level != clevel || ic->block != cblock)
{
if (options.debug)
clevel = ic->level;
cblock = ic->block;
}
-
+
if (ic->lineno && cln != ic->lineno)
{
if (options.debug)
#endif
}
if (!options.noCcodeInAsm) {
- emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,
+ emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,
printCLine(ic->filename, ic->lineno));
}
cln = ic->lineno;
if (options.iCodeInAsm) {
char regsInUse[80];
int i;
- char *iLine;
+ const char *iLine;
for (i=0; i<6; i++) {
sprintf (®sInUse[i],
- "%c", ic->riu & (1<<i) ? i+'0' : '-');
+ "%c", ic->riu & (1<<i) ? i+'0' : '-');
}
regsInUse[i]=0;
iLine = printILine(ic);
int i;
regs *reg;
symbol *sym;
-
+
for (i=A_IDX;i<=XA_IDX;i++)
{
reg = hc08_regWithIdx(i);
}
}
}
-
+
/* depending on the operation */
switch (ic->op)
{
case ENDCRITICAL:
genEndCritical (ic);
break;
-
+
case SWAP:
genSwap (ic);
break;
}
debugFile->writeFrameAddress (NULL, NULL, 0); /* have no idea where frame is now */
-
+
/* now we are ready to call the
peep hole optimizer */
if (options.iCodeInAsm) {
char regsInUse[80];
int i;
- char *iLine;
+ const char *iLine;
#if 0
for (i=0; i<8; i++) {
}
if (options.iCodeInAsm) {
- char *iLine = printILine(ic);
+ const char *iLine = printILine(ic);
emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
dbuf_free(iLine);
}
}
if(options.iCodeInAsm) {
- char *iLine;
+ const char *iLine;
- /* insert here code to print iCode as comment */
- iLine = printILine(ic);
- pic16_emitpcomment("ic:%d: %s", ic->seq, iLine);
- dbuf_free(iLine);
+ /* insert here code to print iCode as comment */
+ iLine = printILine(ic);
+ pic16_emitpcomment("ic:%d: %s", ic->seq, iLine);
+ dbuf_free(iLine);
}
/* if the result is marked as
/* pic16_newpCodeCSource - create a new pCode Source Symbol */
/*-----------------------------------------------------------------*/
-pCode *pic16_newpCodeCSource(int ln, char *f, char *l)
+pCode *pic16_newpCodeCSource(int ln, const char *f, const char *l)
{
pCodeCSource *pccs;
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program 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 General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
-------------------------------------------------------------------------*/
//#include "ralloc.h"
The post code generation is an assembler optimizer. The assembly code
produced by all of the previous steps is fully functional. This step
- will attempt to analyze the flow of the assembly code and agressively
+ will attempt to analyze the flow of the assembly code and agressively
optimize it. The peep hole optimizer attempts to do the same thing.
As you may recall, the peep hole optimizer replaces blocks of assembly
with more optimal blocks (e.g. removing redundant register loads).
However, the peep hole optimizer has to be somewhat conservative since
- an assembly program has implicit state information that's unavailable
+ an assembly program has implicit state information that's unavailable
when only a few instructions are examined.
Consider this example:
example3:
movwf t1
movf t1,w ; This movf can be removed
- xorwf t2,w ; since xorwf will over write Z
+ xorwf t2,w ; since xorwf will over write Z
skpz
return
/***********************************************************************
* debug stuff
- *
+ *
* The DFPRINTF macro will call fprintf if PCODE_DEBUG is defined.
* The macro is used like:
*
* DPRINTF(("%s #%d\n","test", 1));
*
* The double parenthesis (()) are necessary
- *
+ *
***********************************************************************/
//#define PCODE_DEBUG
/***********************************************************************
- * Operand types
+ * Operand types
***********************************************************************/
#define POT_RESULT 0
#define POT_LEFT 1
-typedef enum
+typedef enum
{
PO_NONE=0, // No operand e.g. NOP
PO_W, // The working register (as a destination)
PO_WREG, // The working register (as a file register)
PO_STATUS, // The 'STATUS' register
PO_BSR, // The 'BSR' register
- PO_FSR0, // The "file select register" (in PIC18 family it's one
+ PO_FSR0, // The "file select register" (in PIC18 family it's one
// of three)
PO_INDF0, // The Indirect register
PO_INTCON, // Interrupt Control register
* PIC_OPCODE
*
* This is not a list of the PIC's opcodes per se, but instead
- * an enumeration of all of the different types of pic opcodes.
+ * an enumeration of all of the different types of pic opcodes.
*
***********************************************************************/
typedef enum
{
POC_WILD=-1, /* Wild card - used in the pCode peep hole optimizer
- * to represent ANY pic opcode */
+ * to represent ANY pic opcode */
POC_ADDLW=0,
POC_ADDWF,
POC_ADDFW,
PC_LABEL, /* assembly label */
PC_FLOW, /* flow analysis */
PC_FUNCTION, /* Function start or end */
- PC_WILD, /* wildcard - an opcode place holder used
- * in the pCode peep hole optimizer */
+ PC_WILD, /* wildcard - an opcode place holder used
+ * in the pCode peep hole optimizer */
PC_CSOURCE, /* C-Source Line */
- PC_ASMDIR, /* Assembler directive */
+ PC_ASMDIR, /* Assembler directive */
PC_BAD, /* Mark the pCode object as being bad */
PC_INFO /* pCode information node, used primarily in optimizing */
} PC_TYPE;
/************************************************/
/*************** Structures ********************/
/************************************************/
-/* These are here as forward references - the
+/* These are here as forward references - the
* full definition of these are below */
struct pCode;
struct pCodeWildBlock;
{
struct pCode *pc; // Next pCode in a branch
struct pBranch *next; /* If more than one branch
- * the next one is here */
+ * the next one is here */
} pBranch;
pCodeOp
pCode Operand structure.
- For those assembly instructions that have arguments,
+ For those assembly instructions that have arguments,
the pCode will have a pCodeOp in which the argument
can be stored. For example
{
PIC_OPTYPE type;
char *name;
-
+
} pCodeOp;
#if 0
pCodeOp pcop;
int bit;
unsigned int inBitSpace: 1; /* True if in bit space, else
- just a bit of a register */
+ just a bit of a register */
} pCodeOpBit;
#endif
{
pCodeOp pcop;
int lit;
- pCodeOp *arg2; /* needed as pCodeOpLit and pCodeOpLit2 are not separable via their type (PO_LITERAL) */
+ pCodeOp *arg2; /* needed as pCodeOpLit and pCodeOpLit2 are not separable via their type (PO_LITERAL) */
} pCodeOpLit;
typedef struct pCodeOpLit2
typedef struct pCodeOp2
{
- pCodeOp pcop; // describes this pCodeOp
- pCodeOp *pcopL; // reference to left pCodeOp (src)
- pCodeOp *pcopR; // reference to right pCodeOp (dest)
+ pCodeOp pcop; // describes this pCodeOp
+ pCodeOp *pcopL; // reference to left pCodeOp (src)
+ pCodeOp *pcopR; // reference to right pCodeOp (dest)
} pCodeOp2;
typedef struct pCodeOpRegBit
int bit; // 0-7 bit number.
PIC_OPTYPE subtype; // The type of this register.
unsigned int inBitSpace: 1; /* True if in bit space, else
- just a bit of a register */
+ just a bit of a register */
} pCodeOpRegBit;
struct pCodeWildBlock *pcwb;
int id; /* index into an array of char *'s that will match
- * the wild card. The array is in *pcp. */
+ * the wild card. The array is in *pcp. */
pCodeOp *subtype; /* Pointer to the Operand type into which this wild
- * card will be expanded */
+ * card will be expanded */
pCodeOp *matched; /* When a wild matches, we'll store a pointer to the
- * opcode we matched */
+ * opcode we matched */
- pCodeOp *pcop2; /* second operand if exists */
+ pCodeOp *pcop2; /* second operand if exists */
} pCodeOpWild;
typedef struct pCodeOpOpt
{
pCodeOp pcop;
-
+
OPT_TYPE type; /* optimization node type */
-
+
char *key; /* key by which a block is identified */
} pCodeOpOpt;
pCodeOp pcop;
LR_TYPE type;
-} pCodeOpLocalReg;
+} pCodeOpLocalReg;
/*************************************************
pCode
/*************************************************
pCodeFlow
- The Flow object is used as marker to separate
+ The Flow object is used as marker to separate
the assembly code into contiguous chunks. In other
words, everytime an instruction cause or potentially
causes a branch, a Flow object will be inserted into
pCode pc;
pCode *end; /* Last pCode in this flow. Note that
- the first pCode is pc.next */
+ the first pCode is pc.next */
- /* set **uses; * map the pCode instruction inCond and outCond conditions
- * in this array of set's. The reason we allocate an
- * array of pointers instead of declaring each type of
- * usage is because there are port dependent usage definitions */
+ /* set **uses; * map the pCode instruction inCond and outCond conditions
+ * in this array of set's. The reason we allocate an
+ * array of pointers instead of declaring each type of
+ * usage is because there are port dependent usage definitions */
//int nuses; /* number of uses sets */
set *from; /* flow blocks that can send control to this flow block */
set *to; /* flow blocks to which this one can send control */
struct pCodeFlow *ancestor; /* The most immediate "single" pCodeFlow object that
- * executes prior to this one. In many cases, this
- * will be just the previous */
+ * executes prior to this one. In many cases, this
+ * will be just the previous */
int inCond; /* Input conditions - stuff assumed defined at entry */
int outCond; /* Output conditions - stuff modified by flow block */
set *registers;/* Registers used in this flow */
- struct defmap_s *defmap; /* chronologically ordered list of definitions performed
- in this flow (most recent at the front) */
- struct defmap_s *in_vals; /* definitions of all symbols reaching this flow
- * symbols with multiple different definitions are stored
- * with an assigned value of 0. */
- struct defmap_s *out_vals; /* definitions valid AFTER thie flow */
+ struct defmap_s *defmap; /* chronologically ordered list of definitions performed
+ in this flow (most recent at the front) */
+ struct defmap_s *in_vals; /* definitions of all symbols reaching this flow
+ * symbols with multiple different definitions are stored
+ * with an assigned value of 0. */
+ struct defmap_s *out_vals; /* definitions valid AFTER thie flow */
} pCodeFlow;
unsigned int isLit: 1; /* True if this instruction has an literal operand */
unsigned int isAccess: 1; /* True if this instruction has an access RAM operand */
unsigned int isFastCall: 1; /* True if this instruction has a fast call/return mode select operand */
- unsigned int is2MemOp: 1; /* True is second operand is a memory operand VR - support for MOVFF */
- unsigned int is2LitOp: 1; /* True if instruction takes 2 literal operands VR - support for LFSR */
+ unsigned int is2MemOp: 1; /* True is second operand is a memory operand VR - support for MOVFF */
+ unsigned int is2LitOp: 1; /* True if instruction takes 2 literal operands VR - support for LFSR */
PIC_OPCODE inverted_op; /* Opcode of instruction that's the opposite of this one */
unsigned int inCond; // Input conditions for this instruction
unsigned int outCond; // Output conditions for this instruction
-#define PCI_MAGIC 0x6e12
- unsigned int pci_magic; // sanity check for pci initialization
+#define PCI_MAGIC 0x6e12
+ unsigned int pci_magic; // sanity check for pci initialization
} pCodeInstruction;
typedef struct pCodeAsmDir
{
pCodeInstruction pci;
-
+
char *directive;
char *arg;
} pCodeAsmDir;
char *label;
int key;
- int force; /* label cannot be optimized out */
+ int force; /* label cannot be optimized out */
} pCodeLabel;
char *modname;
char *fname; /* If NULL, then this is the end of
- a function. Otherwise, it's the
- start and the name is contained
- here */
+ a function. Otherwise, it's the
+ start and the name is contained
+ here */
pBranch *from; // pCodes that execute before this one
pBranch *to; // pCodes that execute after
int absblock; /* hack to emulate a block pCodes in absolute position
but not inside a function */
int stackusage; /* stack positions used in function */
-
+
} pCodeFunction;
pCodeInstruction pci;
- int id; /* Index into the wild card array of a peepBlock
- * - this wild card will get expanded into that pCode
- * that is stored at this index */
+ int id; /* Index into the wild card array of a peepBlock
+ * - this wild card will get expanded into that pCode
+ * that is stored at this index */
/* Conditions on wild pcode instruction */
int mustBeBitSkipInst:1;
/*************************************************
pInfo
-
+
Here are stored generic informaton
*************************************************/
typedef struct pCodeInfo
{
pCodeInstruction pci;
-
- INFO_TYPE type; /* info node type */
-
- pCodeOp *oper1; /* info node arguments */
+
+ INFO_TYPE type; /* info node type */
+
+ pCodeOp *oper1; /* info node arguments */
} pCodeInfo;
-
+
/*************************************************
pBlock
/* (Note: a wildcard register is a place holder. Any register
- * can be replaced by the wildcard when the pcode is being
+ * can be replaced by the wildcard when the pcode is being
* compared to the target. */
/* Post Conditions. A post condition is a condition that
* must be either true or false before the peep rule is
* accepted. For example, a certain rule may be accepted
- * if and only if the Z-bit is not used as an input to
+ * if and only if the Z-bit is not used as an input to
* the subsequent instructions in a pCode chain.
*/
- unsigned int postFalseCond;
+ unsigned int postFalseCond;
unsigned int postTrueCond;
} pCodePeep;
/*************************************************
- pCode peep command definitions
+ pCode peep command definitions
Here are some special commands that control the
way the peep hole optimizer behaves
#define PCFLINK(x)((pCodeFlowLink *)(x))
#define PCW(x) ((pCodeWild *)(x))
#define PCCS(x) ((pCodeCSource *)(x))
-#define PCAD(x) ((pCodeAsmDir *)(x))
+#define PCAD(x) ((pCodeAsmDir *)(x))
#define PCINF(x) ((pCodeInfo *)(x))
#define PCOP(x) ((pCodeOp *)(x))
#define isPCL(x) ((PCODE(x)->type == PC_LABEL))
#define isPCW(x) ((PCODE(x)->type == PC_WILD))
#define isPCCS(x) ((PCODE(x)->type == PC_CSOURCE))
-#define isPCAD(x) ((PCODE(x)->type == PC_ASMDIR))
+#define isPCAD(x) ((PCODE(x)->type == PC_ASMDIR))
#define isPCINFO(x) ((PCODE(x)->type == PC_INFO))
#define isCALL(x) ((isPCI(x)) && (PCI(x)->op == POC_CALL))
#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
#define isBSR_REG(r) ((r)->pc_type == PO_BSR)
-#define isACCESS_BANK(r) (r->accessBank)
+#define isACCESS_BANK(r) (r->accessBank)
pCode *pic16_newpCodeFunction(char *g, char *f); // Create a new function
pCode *pic16_newpCodeLabel(char *name,int key); // Create a new label given a key
pCode *pic16_newpCodeLabelFORCE(char *name, int key); // Same as newpCodeLabel but label cannot be optimized out
-pCode *pic16_newpCodeCSource(int ln, char *f, char *l); // Create a new symbol line
+pCode *pic16_newpCodeCSource(int ln, const char *f, const char *l); // Create a new symbol line
pBlock *pic16_newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
void pic16_printpBlock(FILE *of, pBlock *pb); // Write a pBlock to a file
void pic16_addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock
void pic16_pBlockConvert2ISR(pBlock *pb);
void pic16_pBlockConvert2Absolute(pBlock *pb);
void pic16_initDB(void);
-void pic16_emitDB(int c, char ptype, void *p); // Add DB directives to a pBlock
+void pic16_emitDB(int c, char ptype, void *p); // Add DB directives to a pBlock
void pic16_emitDS(char *s, char ptype, void *p);
-void pic16_flushDB(char ptype, void *p); // Add pending DB data to a pBlock
+void pic16_flushDB(char ptype, void *p); // Add pending DB data to a pBlock
-pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
+pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
pCodeOp *pic16_newpCodeOpLabel(char *name, int key);
pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space);
#ifndef debugf
//#define debugf(frm, rest...) _debugf(__FILE__, __LINE__, frm, rest)
-#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
-#define debugf2(frm, arg1, arg2) _debugf(__FILE__, __LINE__, frm, arg1, arg2)
-#define debugf3(frm, arg1, arg2, arg3) _debugf(__FILE__, __LINE__, frm, arg1, arg2, arg3)
+#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
+#define debugf2(frm, arg1, arg2) _debugf(__FILE__, __LINE__, frm, arg1, arg2)
+#define debugf3(frm, arg1, arg2, arg3) _debugf(__FILE__, __LINE__, frm, arg1, arg2, arg3)
#endif
ralloc.c - source file for register allocation. PIC16 specific
Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
- Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
- Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
+ Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
+ Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program 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 General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+ what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
#include "common.h"
#endif
void _debugf(char *f, int l, char *frm, ...);
-#define NEWREG_DEBUG 0
+#define NEWREG_DEBUG 0
//#define USE_ONSTACK
bitVect *regAssigned;
short blockSpil;
int slocNum;
- bitVect *funcrUsed; /* registers used in a function */
+ bitVect *funcrUsed; /* registers used in a function */
int stackExtend;
int dataExtend;
}
_G;
/* Shared with gen.c */
-int pic16_ptrRegReq; /* one byte pointer register required */
+int pic16_ptrRegReq; /* one byte pointer register required */
set *pic16_dynAllocRegs=NULL;
extern set *sectNames;
-set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
-set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
-set *pic16_equ_data=NULL; /* registers used by equates */
-set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
-set *pic16_acs_udata=NULL; /* access bank variables */
+set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
+set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
+set *pic16_equ_data=NULL; /* registers used by equates */
+set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
+set *pic16_acs_udata=NULL; /* access bank variables */
set *pic16_builtin_functions=NULL;
-static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
+static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
static int rDirectIdx=0;
int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
int pic16_Gstack_base_addr=0; /* The starting address of registers that
- * are used to pass and return parameters */
+ * are used to pass and return parameters */
-int _inRegAllocator=0; /* flag that marks whther allocReg happens while
+int _inRegAllocator=0; /* flag that marks whther allocReg happens while
* inside the register allocator function */
-
+
static void spillThis (symbol *);
int pic16_ralloc_debug = 0;
static void
debugLog (char *fmt,...)
{
- static int append = 0; // First time through, open the file without append.
+ static int append = 0; // First time through, open the file without append.
char buffer[256];
//char *bufferP=buffer;
strcat (buffer, ".d");
if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
- {
- werror (E_FILE_OPEN_ERR, buffer);
- exit (1);
- }
- append = 1; // Next time debubLog is called, we'll append the debug info
+ {
+ werror (E_FILE_OPEN_ERR, buffer);
+ exit (1);
+ }
+ append = 1; // Next time debubLog is called, we'll append the debug info
}
/*
while (isspace((unsigned char)*bufferP)) bufferP++;
- if (bufferP && *bufferP)
+ if (bufferP && *bufferP)
lineCurr = (lineCurr ?
connectLine(lineCurr,newLineNode(lb)) :
(lineHead = newLineNode(lb)));
static char *
debugAopGet (char *str, operand * op)
{
- if(!pic16_ralloc_debug)return NULL;
+ if(!pic16_ralloc_debug)return NULL;
- if (str)
- debugLog (str);
+ if (str)
+ debugLog (str);
- printOperand (op, debugF);
- debugNewLine ();
+ printOperand (op, debugF);
+ debugNewLine ();
return NULL;
}
char *
pic16_decodeOp (unsigned int op)
{
- if (op < 128 && op > ' ') {
- buffer[0] = (op & 0xff);
- buffer[1] = 0;
- return buffer;
- }
-
- switch (op) {
- case IDENTIFIER: return "IDENTIFIER";
- case TYPE_NAME: return "TYPE_NAME";
- case CONSTANT: return "CONSTANT";
- case STRING_LITERAL: return "STRING_LITERAL";
- case SIZEOF: return "SIZEOF";
- case PTR_OP: return "PTR_OP";
- case INC_OP: return "INC_OP";
- case DEC_OP: return "DEC_OP";
- case LEFT_OP: return "LEFT_OP";
- case RIGHT_OP: return "RIGHT_OP";
- case LE_OP: return "LE_OP";
- case GE_OP: return "GE_OP";
- case EQ_OP: return "EQ_OP";
- case NE_OP: return "NE_OP";
- case AND_OP: return "AND_OP";
- case OR_OP: return "OR_OP";
- case MUL_ASSIGN: return "MUL_ASSIGN";
- case DIV_ASSIGN: return "DIV_ASSIGN";
- case MOD_ASSIGN: return "MOD_ASSIGN";
- case ADD_ASSIGN: return "ADD_ASSIGN";
- case SUB_ASSIGN: return "SUB_ASSIGN";
- case LEFT_ASSIGN: return "LEFT_ASSIGN";
- case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
- case AND_ASSIGN: return "AND_ASSIGN";
- case XOR_ASSIGN: return "XOR_ASSIGN";
- case OR_ASSIGN: return "OR_ASSIGN";
- case TYPEDEF: return "TYPEDEF";
- case EXTERN: return "EXTERN";
- case STATIC: return "STATIC";
- case AUTO: return "AUTO";
- case REGISTER: return "REGISTER";
- case CODE: return "CODE";
- case EEPROM: return "EEPROM";
- case INTERRUPT: return "INTERRUPT";
- case SFR: return "SFR";
- case AT: return "AT";
- case SBIT: return "SBIT";
- case REENTRANT: return "REENTRANT";
- case USING: return "USING";
- case XDATA: return "XDATA";
- case DATA: return "DATA";
- case IDATA: return "IDATA";
- case PDATA: return "PDATA";
- case VAR_ARGS: return "VAR_ARGS";
- case CRITICAL: return "CRITICAL";
- case NONBANKED: return "NONBANKED";
- case BANKED: return "BANKED";
- case CHAR: return "CHAR";
- case SHORT: return "SHORT";
- case INT: return "INT";
- case LONG: return "LONG";
- case SIGNED: return "SIGNED";
- case UNSIGNED: return "UNSIGNED";
- case FLOAT: return "FLOAT";
- case DOUBLE: return "DOUBLE";
- case CONST: return "CONST";
- case VOLATILE: return "VOLATILE";
- case VOID: return "VOID";
- case BIT: return "BIT";
- case STRUCT: return "STRUCT";
- case UNION: return "UNION";
- case ENUM: return "ENUM";
- case RANGE: return "RANGE";
- case FAR: return "FAR";
- case CASE: return "CASE";
- case DEFAULT: return "DEFAULT";
- case IF: return "IF";
- case ELSE: return "ELSE";
- case SWITCH: return "SWITCH";
- case WHILE: return "WHILE";
- case DO: return "DO";
- case FOR: return "FOR";
- case GOTO: return "GOTO";
- case CONTINUE: return "CONTINUE";
- case BREAK: return "BREAK";
- case RETURN: return "RETURN";
- case INLINEASM: return "INLINEASM";
- case IFX: return "IFX";
- case ADDRESS_OF: return "ADDRESS_OF";
- case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
- case SPIL: return "SPIL";
- case UNSPIL: return "UNSPIL";
- case GETHBIT: return "GETHBIT";
- case BITWISEAND: return "BITWISEAND";
- case UNARYMINUS: return "UNARYMINUS";
- case IPUSH: return "IPUSH";
- case IPOP: return "IPOP";
- case PCALL: return "PCALL";
+ if (op < 128 && op > ' ') {
+ buffer[0] = (op & 0xff);
+ buffer[1] = 0;
+ return buffer;
+ }
+
+ switch (op) {
+ case IDENTIFIER: return "IDENTIFIER";
+ case TYPE_NAME: return "TYPE_NAME";
+ case CONSTANT: return "CONSTANT";
+ case STRING_LITERAL: return "STRING_LITERAL";
+ case SIZEOF: return "SIZEOF";
+ case PTR_OP: return "PTR_OP";
+ case INC_OP: return "INC_OP";
+ case DEC_OP: return "DEC_OP";
+ case LEFT_OP: return "LEFT_OP";
+ case RIGHT_OP: return "RIGHT_OP";
+ case LE_OP: return "LE_OP";
+ case GE_OP: return "GE_OP";
+ case EQ_OP: return "EQ_OP";
+ case NE_OP: return "NE_OP";
+ case AND_OP: return "AND_OP";
+ case OR_OP: return "OR_OP";
+ case MUL_ASSIGN: return "MUL_ASSIGN";
+ case DIV_ASSIGN: return "DIV_ASSIGN";
+ case MOD_ASSIGN: return "MOD_ASSIGN";
+ case ADD_ASSIGN: return "ADD_ASSIGN";
+ case SUB_ASSIGN: return "SUB_ASSIGN";
+ case LEFT_ASSIGN: return "LEFT_ASSIGN";
+ case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
+ case AND_ASSIGN: return "AND_ASSIGN";
+ case XOR_ASSIGN: return "XOR_ASSIGN";
+ case OR_ASSIGN: return "OR_ASSIGN";
+ case TYPEDEF: return "TYPEDEF";
+ case EXTERN: return "EXTERN";
+ case STATIC: return "STATIC";
+ case AUTO: return "AUTO";
+ case REGISTER: return "REGISTER";
+ case CODE: return "CODE";
+ case EEPROM: return "EEPROM";
+ case INTERRUPT: return "INTERRUPT";
+ case SFR: return "SFR";
+ case AT: return "AT";
+ case SBIT: return "SBIT";
+ case REENTRANT: return "REENTRANT";
+ case USING: return "USING";
+ case XDATA: return "XDATA";
+ case DATA: return "DATA";
+ case IDATA: return "IDATA";
+ case PDATA: return "PDATA";
+ case VAR_ARGS: return "VAR_ARGS";
+ case CRITICAL: return "CRITICAL";
+ case NONBANKED: return "NONBANKED";
+ case BANKED: return "BANKED";
+ case CHAR: return "CHAR";
+ case SHORT: return "SHORT";
+ case INT: return "INT";
+ case LONG: return "LONG";
+ case SIGNED: return "SIGNED";
+ case UNSIGNED: return "UNSIGNED";
+ case FLOAT: return "FLOAT";
+ case DOUBLE: return "DOUBLE";
+ case CONST: return "CONST";
+ case VOLATILE: return "VOLATILE";
+ case VOID: return "VOID";
+ case BIT: return "BIT";
+ case STRUCT: return "STRUCT";
+ case UNION: return "UNION";
+ case ENUM: return "ENUM";
+ case RANGE: return "RANGE";
+ case FAR: return "FAR";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case GOTO: return "GOTO";
+ case CONTINUE: return "CONTINUE";
+ case BREAK: return "BREAK";
+ case RETURN: return "RETURN";
+ case INLINEASM: return "INLINEASM";
+ case IFX: return "IFX";
+ case ADDRESS_OF: return "ADDRESS_OF";
+ case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
+ case SPIL: return "SPIL";
+ case UNSPIL: return "UNSPIL";
+ case GETHBIT: return "GETHBIT";
+ case BITWISEAND: return "BITWISEAND";
+ case UNARYMINUS: return "UNARYMINUS";
+ case IPUSH: return "IPUSH";
+ case IPOP: return "IPOP";
+ case PCALL: return "PCALL";
case FUNCTION: return "FUNCTION";
- case ENDFUNCTION: return "ENDFUNCTION";
- case JUMPTABLE: return "JUMPTABLE";
- case RRC: return "RRC";
- case RLC: return "RLC";
- case CAST: return "CAST";
- case CALL: return "CALL";
- case PARAM: return "PARAM ";
- case NULLOP: return "NULLOP";
- case BLOCK: return "BLOCK";
- case LABEL: return "LABEL";
- case RECEIVE: return "RECEIVE";
- case SEND: return "SEND";
- case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE";
- }
- sprintf (buffer, "unkown op %d %c", op, op & 0xff);
+ case ENDFUNCTION: return "ENDFUNCTION";
+ case JUMPTABLE: return "JUMPTABLE";
+ case RRC: return "RRC";
+ case RLC: return "RLC";
+ case CAST: return "CAST";
+ case CALL: return "CALL";
+ case PARAM: return "PARAM ";
+ case NULLOP: return "NULLOP";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case RECEIVE: return "RECEIVE";
+ case SEND: return "SEND";
+ case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE";
+ }
+ sprintf (buffer, "unkown op %d %c", op, op & 0xff);
return buffer;
}
#if 0
static char *decodeRegType(short type)
{
- switch(type) {
- case REG_GPR: return "REG_GPR";
- case REG_PTR: return "REG_PTR";
- case REG_CND: return "REG_CNT";
-
- default:
- return "<unknown>";
- }
+ switch(type) {
+ case REG_GPR: return "REG_GPR";
+ case REG_PTR: return "REG_PTR";
+ case REG_CND: return "REG_CNT";
+
+ default:
+ return "<unknown>";
+ }
}
#endif
static char *
debugLogRegType (short type)
{
- if(!pic16_ralloc_debug)return NULL;
- switch (type) {
- case REG_GPR: return "REG_GPR";
- case REG_PTR: return "REG_PTR";
- case REG_CND: return "REG_CND";
- }
- sprintf (buffer, "unknown reg type %d", type);
+ if(!pic16_ralloc_debug)return NULL;
+ switch (type) {
+ case REG_GPR: return "REG_GPR";
+ case REG_PTR: return "REG_PTR";
+ case REG_CND: return "REG_CND";
+ }
+ sprintf (buffer, "unknown reg type %d", type);
return buffer;
}
regs *dReg;
- dReg = Safe_calloc(1,sizeof(regs));
- dReg->type = type;
- dReg->pc_type = pc_type;
- dReg->rIdx = rIdx;
- if(name)
- dReg->name = Safe_strdup(name);
- else {
+ dReg = Safe_calloc(1,sizeof(regs));
+ dReg->type = type;
+ dReg->pc_type = pc_type;
+ dReg->rIdx = rIdx;
+ if(name)
+ dReg->name = Safe_strdup(name);
+ else {
if(xinst && pc_type == PO_GPR_TEMP) {
sprintf(buffer,"0x%02x", dReg->rIdx);
} else {
sprintf(buffer,"r0x%02x", dReg->rIdx);
}
-
+
if(type == REG_STK) {
*buffer = 's';
}
dReg->name = Safe_strdup(buffer);
- }
+ }
- dReg->isFree = 0;
- dReg->wasUsed = 1;
- dReg->isEmitted = 0;
+ dReg->isFree = 0;
+ dReg->wasUsed = 1;
+ dReg->isEmitted = 0;
- if(type == REG_SFR) {
- dReg->isFixed = 1;
- dReg->address = rIdx;
- dReg->accessBank = 1;
- } else {
- dReg->isFixed = 0;
- dReg->address = 0;
- dReg->accessBank = 0;
- }
+ if(type == REG_SFR) {
+ dReg->isFixed = 1;
+ dReg->address = rIdx;
+ dReg->accessBank = 1;
+ } else {
+ dReg->isFixed = 0;
+ dReg->address = 0;
+ dReg->accessBank = 0;
+ }
#if NEWREG_DEBUG
- fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
+ fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
#endif
- dReg->size = size;
- dReg->alias = alias;
- dReg->reg_alias = NULL;
- dReg->reglives.usedpFlows = newSet();
- dReg->reglives.assignedpFlows = newSet();
- dReg->regop = refop;
-
- if(!(type == REG_SFR && alias == 0x80))
- hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
+ dReg->size = size;
+ dReg->alias = alias;
+ dReg->reg_alias = NULL;
+ dReg->reglives.usedpFlows = newSet();
+ dReg->reglives.assignedpFlows = newSet();
+ dReg->regop = refop;
+
+ if(!(type == REG_SFR && alias == 0x80))
+ hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
return dReg;
}
{
regs *dReg;
-//#define D(text) text
+//#define D(text) text
#define D(text)
- for (dReg = setFirstItem(dRegs) ; dReg ;
+ for (dReg = setFirstItem(dRegs) ; dReg ;
dReg = setNextItem(dRegs)) {
- D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed));
+ D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed));
if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
- D(fprintf(stderr, "found!\n"));
+ D(fprintf(stderr, "found!\n"));
return dReg;
} else
- D(fprintf(stderr, "not found!\n"));
+ D(fprintf(stderr, "not found!\n"));
}
return NULL;
{
regs *dReg;
- for (dReg = setFirstItem(dRegs) ; dReg ;
+ for (dReg = setFirstItem(dRegs) ; dReg ;
dReg = setNextItem(dRegs)) {
-// fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
-// __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
+// fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
+// __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
if(dReg->isFree) {
-// fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx);
-
+// fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx);
+
return dReg;
}
}
/* position at current register */
for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
}
-
+
for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
if(dReg->isFree) {
return dReg;
}
}
-
+
return NULL;
}
{
regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
-// fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
+// fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
- reg->wasUsed = 0; // we do not know if they are going to be used at all
- reg->accessBank = 1; // implicit add access Bank
+ reg->wasUsed = 0; // we do not know if they are going to be used at all
+ reg->accessBank = 1; // implicit add access Bank
- hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
+ hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
return addSet(&pic16_dynProcessorRegs, reg);
}
{
regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
-// fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
+// fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
if(reg) {
reg->wasUsed = 0;
allocReg (short type)
{
regs * reg=NULL;
-
-#define MAX_P16_NREGS 16
+
+#define MAX_P16_NREGS 16
#if 0
if(dynrIdx > pic16_nRegs)
- werror(W_POSSBUG2, __FILE__, __LINE__);
- return NULL;
+ werror(W_POSSBUG2, __FILE__, __LINE__);
+ return NULL;
#endif
- /* try to reuse some unused registers */
- reg = regFindFree( pic16_dynAllocRegs );
+ /* try to reuse some unused registers */
+ reg = regFindFree( pic16_dynAllocRegs );
- if(reg) {
-// fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
- }
+ if(reg) {
+// fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
+ }
- if(!reg) {
- reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
-// fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
-// (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
+ if(!reg) {
+ reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
+// fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
+// (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
#if 1
- if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
- // debugf("allocating more registers than available\n", 0);
- // return (NULL);
- }
-
- addSet(&pic16_dynAllocRegs, reg);
- hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
-// fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
+ if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
+ // debugf("allocating more registers than available\n", 0);
+ // return (NULL);
+ }
+
+ addSet(&pic16_dynAllocRegs, reg);
+ hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
+// fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
#endif
- }
-
- debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
+ }
+
+ debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
#if 0
- fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
- __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
+ fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
+ __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
#endif
- if(reg) {
- reg->isFree=0;
- reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
- reg->isLocal = 1; /* this is a local frame register */
-// reg->wasUsed = 1;
- }
-
- if (currFunc) {
-// fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
- currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
- }
-
- return (reg); // addSet(&pic16_dynAllocRegs,reg);
+ if(reg) {
+ reg->isFree=0;
+ reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
+ reg->isLocal = 1; /* this is a local frame register */
+// reg->wasUsed = 1;
+ }
+
+ if (currFunc) {
+// fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
+ currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
+ }
+
+ return (reg); // addSet(&pic16_dynAllocRegs,reg);
}
hkey = regname2key(name);
-// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
reg = hTabFirstItemWK(dynDirectRegNames, hkey);
while(reg) {
if(STRCASECMP(reg->name, name) == 0) {
-// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
+// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
return(reg);
}
reg = hTabNextItemWK (dynDirectRegNames);
-
+
}
return NULL; // name wasn't found in the hash table
}
reg = hTabNextItemWK (dynAllocRegNames);
-
+
}
return NULL; // name wasn't found in the hash table
hkey = regname2key(name);
-// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
reg = hTabFirstItemWK(dynProcRegNames, hkey);
}
reg = hTabNextItemWK (dynProcRegNames);
-
+
}
return NULL; // name wasn't found in the hash table
hkey = regname2key(name);
-// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
reg = hTabFirstItemWK(dynAccessRegNames, hkey);
}
reg = hTabNextItemWK (dynAccessRegNames);
-
+
}
return NULL; // name wasn't found in the hash table
{
regs *reg;
- reg = pic16_dirregWithName( name );
- if(reg)return reg;
-
- reg = pic16_procregWithName( name );
- if(reg)return reg;
-
- reg = pic16_allocregWithName( name );
- if(reg)return reg;
-
- reg = pic16_accessregWithName( name );
- if(reg)return reg;
-
+ reg = pic16_dirregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_procregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_allocregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_accessregWithName( name );
+ if(reg)return reg;
+
return NULL;
}
regs *reg;
char *name;
- if(!IS_SYMOP(op)) {
- debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
-// fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
- return NULL;
- }
+ if(!IS_SYMOP(op)) {
+ debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
+// fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
+ return NULL;
+ }
- name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+ name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
- if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
+ if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
#if 0
- if(pic16_debug_verbose)
- {
- fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
- OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
- }
+ if(pic16_debug_verbose)
+ {
+ fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
+ OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
+ }
#endif
- return NULL;
- }
+ return NULL;
+ }
- if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
- || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
+ if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+ || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
#if 0
- if(pic16_debug_verbose) {
- fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
- IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_STACK( OP_SYM_ETYPE(op)),
- SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
- IS_REGPARM(OP_SYM_ETYPE(op)),
- IS_PARM(op));
-
- fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
- OP_SYMBOL(op)->name);
- }
+ if(pic16_debug_verbose) {
+ fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
+ IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_STACK( OP_SYM_ETYPE(op)),
+ SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
+ IS_REGPARM(OP_SYM_ETYPE(op)),
+ IS_PARM(op));
+
+ fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
+ OP_SYMBOL(op)->name);
+ }
#endif
- }
+ }
+
+
+
+ if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
+// fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
+ return NULL;
+ }
+
+ if(IS_ITEMP(op))return NULL;
+
+// if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
+ if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
+ debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
+// fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
- if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
-// fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
- return NULL;
- }
+ {
+ if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
+ debugLog(" %d const char\n",__LINE__);
+ debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+// fprintf(stderr, " %d const char\n",__LINE__);
+// fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+ }
- if(IS_ITEMP(op))return NULL;
-
-// if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
-
- if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
-
- debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
-// fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
- {
- if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
- debugLog(" %d const char\n",__LINE__);
- debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
-// fprintf(stderr, " %d const char\n",__LINE__);
-// fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
- }
+ debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
+ if (IS_CODE ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d code space\n",__LINE__);
-
- debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
- if (IS_CODE ( OP_SYM_ETYPE(op)) )
- debugLog(" %d code space\n",__LINE__);
+ if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d integral\n",__LINE__);
- if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
- debugLog(" %d integral\n",__LINE__);
+ if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d literal\n",__LINE__);
- if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
- debugLog(" %d literal\n",__LINE__);
+ if (IS_SPEC ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d specifier\n",__LINE__);
- if (IS_SPEC ( OP_SYM_ETYPE(op)) )
- debugLog(" %d specifier\n",__LINE__);
+ debugAopGet(NULL, op);
+ }
- debugAopGet(NULL, op);
- }
+ reg = pic16_dirregWithName(name);
- reg = pic16_dirregWithName(name);
+ if(!reg) {
+ int address = 0;
+ int regtype = REG_GPR;
- if(!reg) {
- int address = 0;
- int regtype = REG_GPR;
-
- /* if this is at an absolute address, then get the address. */
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
- address = SPEC_ADDR ( OP_SYM_ETYPE(op));
-// fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
- }
+ /* if this is at an absolute address, then get the address. */
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+ address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+// fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
+ }
- /* Register wasn't found in hash, so let's create
- * a new one and put it in the hash table AND in the
- * dynDirectRegNames set */
- if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
- debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
- return NULL;
- }
+ /* Register wasn't found in hash, so let's create
+ * a new one and put it in the hash table AND in the
+ * dynDirectRegNames set */
+ if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+ debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
+ return NULL;
+ }
#if 0
- if(OP_SYMBOL(op)->onStack) {
- fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
- OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
- }
+ if(OP_SYMBOL(op)->onStack) {
+ fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
+ OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
+ }
#endif
- if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
- || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
+ if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+ || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
#if 0
- if(pic16_debug_verbose)
- {
- fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
- IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
- IN_STACK( OP_SYM_ETYPE(op)),
- SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
-
- fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
- OP_SYMBOL(op)->name);
- }
+ if(pic16_debug_verbose)
+ {
+ fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
+ IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_STACK( OP_SYM_ETYPE(op)),
+ SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
+
+ fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
+ OP_SYMBOL(op)->name);
+ }
#endif
- }
-
- reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
- debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
-
- if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
- fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
- name);
-
- reg->accessBank = 1;
- checkAddReg(&pic16_dynAccessRegs, reg);
- hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
-
- return (reg);
- }
-
-
-// if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
-// fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
-// reg->type = REG_SFR;
-// }
-
- if (IS_BITVAR (OP_SYM_ETYPE(op))) {
-// fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
- addSet(&pic16_dynDirectBitRegs, reg);
- reg->isBitField = 1;
- } else {
-// fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
-// addSet(&pic16_dynDirectRegs, reg);
+ }
+
+ reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
+ debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
+
+ if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
+ fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
+ name);
+
+ reg->accessBank = 1;
+ checkAddReg(&pic16_dynAccessRegs, reg);
+ hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
+
+ return (reg);
+ }
+
+
+// if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+// fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
+// reg->type = REG_SFR;
+// }
+
+ if (IS_BITVAR (OP_SYM_ETYPE(op))) {
+// fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
+ addSet(&pic16_dynDirectBitRegs, reg);
+ reg->isBitField = 1;
+ } else {
+// fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
+// addSet(&pic16_dynDirectRegs, reg);
#if 1
if(!(IS_STATIC(OP_SYM_ETYPE(op))
))
#endif
checkAddReg(&pic16_dynDirectRegs, reg);
- }
-
- } else {
-// debugLog (" -- %s is declared at address 0x30000x\n",name);
- return (reg); /* This was NULL before, but since we found it
- * why not just return it?! */
- }
-
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
- reg->isFixed = 1;
- reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
-
- /* work around for user defined registers in access bank */
- if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
- || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
- reg->accessBank = 1;
-
- debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
- }
+ }
+
+ } else {
+// debugLog (" -- %s is declared at address 0x30000x\n",name);
+ return (reg); /* This was NULL before, but since we found it
+ * why not just return it?! */
+ }
+
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+ reg->isFixed = 1;
+ reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+
+ /* work around for user defined registers in access bank */
+ if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
+ || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
+ reg->accessBank = 1;
+
+ debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
+ }
return reg;
}
if(!reg) {
/* Register wasn't found in hash, so let's create
- * a new one and put it in the hash table AND in the
+ * a new one and put it in the hash table AND in the
* dynDirectRegNames set */
- //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
+ //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
- //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
+ //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
- //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
+ //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
addSet(&pic16_dynDirectRegs, reg);
}
return dReg;
}
- if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
+ if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
debugLog ("Found an Internal Register!\n");
return dReg;
}
-
+
break;
case REG_STK:
if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
} else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
debugLog ("Found an Internal Register!\n");
} else {
-
+
debugLog ("Dynamic Register not found\n");
#if 1
- dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL);
- addSet(&pic16_dynAllocRegs, dReg);
- hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg);
+ dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL);
+ addSet(&pic16_dynAllocRegs, dReg);
+ hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg);
#endif
- if(!dReg) {
-// return (NULL);
+ if(!dReg) {
+// return (NULL);
//fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "allocWithIdx not found");
- exit (1);
- }
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "allocWithIdx not found");
+ exit (1);
+ }
}
dReg->wasUsed = 1;
case REG_GPR:
if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
return dReg;
-// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
return allocReg( REG_GPR );
case REG_STK:
case REG_GPR:
if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
return dReg;
-// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
return (allocReg( REG_GPR ) );
case REG_STK:
static void
freeReg (regs * reg)
{
- debugLog ("%s\n", __FUNCTION__);
-// fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
- reg->isFree = 1;
+ debugLog ("%s\n", __FUNCTION__);
+// fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
+ reg->isFree = 1;
}
int nfr=0;
- /* although I fixed the register allocation/freeing scheme
- * the for loop below doesn't give valid results. I do not
- * know why yet. -- VR 10-Jan-2003 */
-
- return 100;
+ /* although I fixed the register allocation/freeing scheme
+ * the for loop below doesn't give valid results. I do not
+ * know why yet. -- VR 10-Jan-2003 */
+
+ return 100;
/* dynamically allocate as many as we need and worry about
debugLog ("%s\n", __FUNCTION__);
- for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
- if((reg->type == type) && reg->isFree)nfr++;
+ for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
+ if((reg->type == type) && reg->isFree)nfr++;
- fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
+ fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
return nfr;
}
if (type == REG_PTR)
{
if ((nfr = nFreeRegs (type)) == 0)
- return nFreeRegs (REG_GPR);
+ return nFreeRegs (REG_GPR);
}
return nFreeRegs (type);
regs *dReg;
- for (dReg = setFirstItem(dRegs) ; dReg ;
+ for (dReg = setFirstItem(dRegs) ; dReg ;
dReg = setNextItem(dRegs)) {
if(dReg->wasUsed)
breg->address >>= 3;
if(!bitfield) {
- sprintf (buffer, "fbitfield%02x", breg->address);
- //fprintf(stderr,"new bit field\n");
- bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
- bitfield->isBitField = 1;
- bitfield->isFixed = 1;
- bitfield->address = breg->address;
- addSet(&pic16_dynDirectRegs,bitfield);
- //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
+ sprintf (buffer, "fbitfield%02x", breg->address);
+ //fprintf(stderr,"new bit field\n");
+ bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
+ bitfield->isBitField = 1;
+ bitfield->isFixed = 1;
+ bitfield->address = breg->address;
+ addSet(&pic16_dynDirectRegs,bitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
} else {
- //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
- ;
+ //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
+ ;
}
breg->reg_alias = bitfield;
bitfield = NULL;
} else {
if(!relocbitfield || bit_no >7) {
- byte_no++;
- bit_no=0;
- sprintf (buffer, "bitfield%d", byte_no);
- //fprintf(stderr,"new relocatable bit field\n");
- relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
- relocbitfield->isBitField = 1;
- addSet(&pic16_dynDirectRegs,relocbitfield);
- //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+ byte_no++;
+ bit_no=0;
+ sprintf (buffer, "bitfield%d", byte_no);
+ //fprintf(stderr,"new relocatable bit field\n");
+ relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
+ relocbitfield->isBitField = 1;
+ addSet(&pic16_dynDirectRegs,relocbitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
}
breg->rIdx = bit_no++;
}
}
-
+
}
-void pic16_writeUsedRegs(FILE *of)
+void pic16_writeUsedRegs(FILE *of)
{
packBits(pic16_dynDirectBitRegs);
pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
pic16_groupRegistersInSection(pic16_dynProcessorRegs);
pic16_groupRegistersInSection(pic16_dynAccessRegs);
-
+
/* dump equates */
pic16_dump_equates(of, pic16_equ_data);
-// pic16_dump_esection(of, pic16_rel_eedata, 0);
-// pic16_dump_esection(of, pic16_fix_eedata, 0);
+// pic16_dump_esection(of, pic16_rel_eedata, 0);
+// pic16_dump_esection(of, pic16_fix_eedata, 0);
/* dump access bank symbols */
pic16_dump_access(of, pic16_acs_udata);
/* dump internal registers */
pic16_dump_int_registers(of, pic16_int_regs);
}
-
+
/* dump generic section variables */
pic16_dump_gsection(of, sectNames);
bitVect *spillable;
debugLog ("%s\n", __FUNCTION__);
- /* spillable live ranges are those that are live at this
+ /* spillable live ranges are those that are live at this
point . the following categories need to be subtracted
- from this set.
+ from this set.
a) - those that are already spilt
b) - if being used by this one
c) - defined by this one */
spillable = bitVectCopy (ic->rlive);
spillable =
- bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
+ bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
spillable =
- bitVectCplAnd (spillable, ic->uses); /* used in this one */
+ bitVectCplAnd (spillable, ic->uses); /* used in this one */
bitVectUnSetBit (spillable, ic->defKey);
spillable = bitVectIntersect (spillable, _G.regAssigned);
return spillable;
{
debugLog ("%s\n", __FUNCTION__);
return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
- allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
+ allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static set *
liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
- eBBlock * ebp, iCode * ic)
+ eBBlock * ebp, iCode * ic)
{
set *rset = NULL;
int i;
{
symbol *sym;
if (!bitVectBitValue (lrs, i))
- continue;
+ continue;
- /* if we don't find it in the live range
+ /* if we don't find it in the live range
hash table we are in serious trouble */
if (!(sym = hTabItemWithKey (liveRanges, i)))
- {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "liveRangesWith could not find liveRange");
- exit (1);
- }
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "liveRangesWith could not find liveRange");
+ exit (1);
+ }
if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
- addSetHead (&rset, sym);
+ addSetHead (&rset, sym);
}
return rset;
/* if usage is the same then prefer
the spill the smaller of the two */
if (lsym->used == sym->used)
- if (getSize (lsym->type) < getSize (sym->type))
- sym = lsym;
+ if (getSize (lsym->type) < getSize (sym->type))
+ sym = lsym;
/* if less usage */
if (lsym->used < sym->used)
- sym = lsym;
+ sym = lsym;
}
sym = setNextItem (itmpStack))
{
if (sym->liveTo > fsym->liveFrom)
- return 0;
+ return 0;
}
/* if no registers assigned to it or
spilt */
- /* if it does not overlap with this then
+ /* if it does not overlap with this then
not need to spill it */
if (lrsym->isspilt || !lrsym->nRegs ||
- (lrsym->liveTo < forSym->liveFrom))
- continue;
+ (lrsym->liveTo < forSym->liveFrom))
+ continue;
/* go thru the registers : if it is either
r0 or r1 then spil it */
for (j = 0; j < lrsym->nRegs; j++)
- if (lrsym->regs[j] == r0 ||
- lrsym->regs[j] == r1)
- {
- spillThis (lrsym);
- break;
- }
+ if (lrsym->regs[j] == r0 ||
+ lrsym->regs[j] == r1)
+ {
+ spillThis (lrsym);
+ break;
+ }
}
}
char slocBuffer[30];
debugLog ("%s\n", __FUNCTION__);
- /* first go try and find a free one that is already
+ /* first go try and find a free one that is already
existing on the stack */
if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
{
if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
{
fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
exit (1);
}
temporarily turn it off ; we also
turn off memory model to prevent
the spil from going to the external storage
- and turn off overlaying
+ and turn off overlaying
*/
useXstack = options.useXstack;
options.useXstack = useXstack;
options.model = model;
options.noOverlay = noOverlay;
- sloc->isref = 1; /* to prevent compiler warning */
+ sloc->isref = 1; /* to prevent compiler warning */
/* if it is on the stack then update the stack */
if (IN_STACK (sloc->etype))
sym->usl.spillLoc = sloc;
sym->stackSpil = 1;
- /* add it to the set of itempStack set
+ /* add it to the set of itempStack set
of the spill location */
addSetHead (&sloc->usl.itmpStack, sym);
return sym;
if (sym->regs[i])
{
- freeReg (sym->regs[i]);
- sym->regs[i] = NULL;
+ freeReg (sym->regs[i]);
+ sym->regs[i] = NULL;
}
- /* if spilt on stack then free up r0 & r1
+ /* if spilt on stack then free up r0 & r1
if they could have been assigned to some
LIVE ranges */
if (!pic16_ptrRegReq && isSpiltOnStack (sym))
{
sym = leastUsedLR (selectS);
strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
- sym->usl.spillLoc->rname :
- sym->usl.spillLoc->name));
+ sym->usl.spillLoc->rname :
+ sym->usl.spillLoc->name));
sym->spildir = 1;
/* mark it as allocation required */
sym->usl.spillLoc->allocreq = 1;
/* check if there are any live ranges allocated
to registers that are not used in this block */
if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
- {
- sym = leastUsedLR (selectS);
- /* if this is not rematerializable */
- if (!sym->remat)
- {
- _G.blockSpil++;
- sym->blockSpil = 1;
- }
- return sym;
- }
+ {
+ sym = leastUsedLR (selectS);
+ /* if this is not rematerializable */
+ if (!sym->remat)
+ {
+ _G.blockSpil++;
+ sym->blockSpil = 1;
+ }
+ return sym;
+ }
/* check if there are any live ranges that not
used in the remainder of the block */
if (!_G.blockSpil &&
- !isiCodeInFunctionCall (ic) &&
+ !isiCodeInFunctionCall (ic) &&
(selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
- {
- sym = leastUsedLR (selectS);
- if (!sym->remat)
- {
- sym->remainSpil = 1;
- _G.blockSpil++;
- }
- return sym;
- }
+ {
+ sym = leastUsedLR (selectS);
+ if (!sym->remat)
+ {
+ sym->remainSpil = 1;
+ _G.blockSpil++;
+ }
+ return sym;
+ }
}
/* find live ranges with spillocation && not used as pointers */
if (ssym->regs[i])
freeReg (ssym->regs[i]);
- /* if spilt on stack then free up r0 & r1
+ /* if spilt on stack then free up r0 & r1
if they could have been assigned to as gprs */
if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
{
spillLRWithPtrReg (ssym);
}
- /* if this was a block level spil then insert push & pop
+ /* if this was a block level spil then insert push & pop
at the start & end of block respectively */
if (ssym->blockSpil)
{
iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
/* add push to the start of the block */
addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
- ebp->sch->next : ebp->sch));
+ ebp->sch->next : ebp->sch));
nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
/* add pop to the end of the block */
addiCodeToeBBlock (ebp, nic, NULL);
for (j=0; j<=sym->nRegs; j++)
if (sym->regs[j])
sym->regs[j]->isFree = 0;
-
- /* this looks like an infinite loop but
+
+ /* this looks like an infinite loop but
in really selectSpil will abort */
goto tryAgain;
}
for (j=0; j<=sym->nRegs; j++)
if (sym->regs[j])
sym->regs[j]->isFree = 0;
-
- /* this looks like an infinite loop but
+
+ /* this looks like an infinite loop but
in really selectSpil will abort */
goto tryAgain;
}
symbol *psym = NULL;
/* if it does not end here */
if (sym->liveTo > ic->seq)
- continue;
+ continue;
- /* if it was spilt on stack then we can
+ /* if it was spilt on stack then we can
mark the stack spil location as free */
if (sym->isspilt)
- {
- if (sym->stackSpil)
- {
- sym->usl.spillLoc->isFree = 1;
- sym->stackSpil = 0;
- }
- continue;
- }
+ {
+ if (sym->stackSpil)
+ {
+ sym->usl.spillLoc->isFree = 1;
+ sym->stackSpil = 0;
+ }
+ continue;
+ }
if (!bitVectBitValue (_G.regAssigned, sym->key))
- continue;
+ continue;
/* special case for shifting: there is a case where shift count
* can be allocated in the same register as the result, so do not
continue;
/* special case check if this is an IFX &
- the privious one was a pop and the
+ the privious one was a pop and the
previous one was not spilt then keep track
of the symbol */
if (ic->op == IFX && ic->prev &&
- ic->prev->op == IPOP &&
- !ic->prev->parmPush &&
- !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
- psym = OP_SYMBOL (IC_LEFT (ic->prev));
+ ic->prev->op == IPOP &&
+ !ic->prev->parmPush &&
+ !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
+ psym = OP_SYMBOL (IC_LEFT (ic->prev));
if (sym->nRegs)
- {
- int i = 0;
-
- bitVectUnSetBit (_G.regAssigned, sym->key);
-
- /* if the result of this one needs registers
- and does not have it then assign it right
- away */
- if (IC_RESULT (ic) &&
- !(SKIP_IC2 (ic) || /* not a special icode */
- ic->op == JUMPTABLE ||
- ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- ic->op == RETURN ||
- POINTER_SET (ic)) &&
- (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
- result->liveTo > ic->seq && /* and will live beyond this */
- result->liveTo <= ebp->lSeq && /* does not go beyond this block */
- result->liveFrom == ic->seq && /* does not start before here */
- result->regType == sym->regType && /* same register types */
- result->nRegs && /* which needs registers */
- !result->isspilt && /* and does not already have them */
- !result->remat &&
- !bitVectBitValue (_G.regAssigned, result->key) &&
- /* the number of free regs + number of regs in this LR
- can accomodate the what result Needs */
- ((nfreeRegsType (result->regType) +
- sym->nRegs) >= result->nRegs)
- )
- {
-
-
-// for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
+ {
+ int i = 0;
+
+ bitVectUnSetBit (_G.regAssigned, sym->key);
+
+ /* if the result of this one needs registers
+ and does not have it then assign it right
+ away */
+ if (IC_RESULT (ic) &&
+ !(SKIP_IC2 (ic) || /* not a special icode */
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ ic->op == RETURN ||
+ POINTER_SET (ic)) &&
+ (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
+ result->liveTo > ic->seq && /* and will live beyond this */
+ result->liveTo <= ebp->lSeq && /* does not go beyond this block */
+ result->liveFrom == ic->seq && /* does not start before here */
+ result->regType == sym->regType && /* same register types */
+ result->nRegs && /* which needs registers */
+ !result->isspilt && /* and does not already have them */
+ !result->remat &&
+ !bitVectBitValue (_G.regAssigned, result->key) &&
+ /* the number of free regs + number of regs in this LR
+ can accomodate the what result Needs */
+ ((nfreeRegsType (result->regType) +
+ sym->nRegs) >= result->nRegs)
+ )
+ {
+
+
+// for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
/* the above does not free the unsued registers in sym,
* leaving them marked as used, and increasing register usage
* until the end of the function - VR 23/11/05 */
- for (i = 0; i < result->nRegs; i++)
- if (i < sym->nRegs)
- result->regs[i] = sym->regs[i];
- else
- result->regs[i] = getRegGpr (ic, ebp, result);
-
- _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
- }
-
- /* free the remaining */
- for (; i < sym->nRegs; i++)
- {
- if (psym)
- {
- if (!symHasReg (psym, sym->regs[i]))
- freeReg (sym->regs[i]);
- }
- else
- freeReg (sym->regs[i]);
- }
- }
+ for (i = 0; i < result->nRegs; i++)
+ if (i < sym->nRegs)
+ result->regs[i] = sym->regs[i];
+ else
+ result->regs[i] = getRegGpr (ic, ebp, result);
+
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
+ }
+
+ /* free the remaining */
+ for (; i < sym->nRegs; i++)
+ {
+ if (psym)
+ {
+ if (!symHasReg (psym, sym->regs[i]))
+ freeReg (sym->regs[i]);
+ }
+ else
+ freeReg (sym->regs[i]);
+ }
+ }
}
}
of te type required */
if (rt == REG_PTR)
{
- /* special case for pointer type
- if pointer type not avlb then
+ /* special case for pointer type
+ if pointer type not avlb then
check for type gpr */
if (nFreeRegs (rt) >= nr)
- return 0;
+ return 0;
if (nFreeRegs (REG_GPR) >= nr)
- return 0;
+ return 0;
}
else
{
if (pic16_ptrRegReq)
- {
- if (nFreeRegs (rt) >= nr)
- return 0;
- }
+ {
+ if (nFreeRegs (rt) >= nr)
+ return 0;
+ }
else
- {
- if (nFreeRegs (REG_PTR) +
- nFreeRegs (REG_GPR) >= nr)
- return 0;
- }
+ {
+ if (nFreeRegs (REG_PTR) +
+ nFreeRegs (REG_GPR) >= nr)
+ return 0;
+ }
}
debugLog (" ... yep it will (cause a spill)\n");
for (i = 0; i < count; i++)
{
for (j = 0; j < count; j++)
- {
- if (result->regs[i] == opsym->regs[j] && i != j)
- {
- shared = 1;
- goto xchgPositions;
- }
- }
+ {
+ if (result->regs[i] == opsym->regs[j] && i != j)
+ {
+ shared = 1;
+ goto xchgPositions;
+ }
+ }
}
xchgPositions:
if (shared)
verifyRegsAssigned (operand *op, iCode * ic)
{
symbol * sym;
-
+
if (!op) return;
if (!IS_ITEMP (op)) return;
-
+
sym = OP_SYMBOL (op);
if (sym->isspilt) return;
if (!sym->nRegs) return;
if (sym->regs[0]) return;
-
- werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
- sym->prereqv ? sym->prereqv->name : sym->name);
+
+ werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
+ sym->prereqv ? sym->prereqv->name : sym->name);
spillThis (sym);
}
{
int i;
iCode *ic;
-
+
debugLog ("%s\n", __FUNCTION__);
/* for all blocks */
for (i = 0; i < count; i++)
{
if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
/* of all instructions do */
for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
-
- debugLog (" op: %s\n", pic16_decodeOp (ic->op));
-
- if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
- pic16_allocDirReg(IC_RESULT(ic));
-
- if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
- pic16_allocDirReg(IC_LEFT(ic));
-
- if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
- pic16_allocDirReg(IC_RIGHT(ic));
-
- /* if this is an ipop that means some live
- range will have to be assigned again */
- if (ic->op == IPOP)
- reassignLR (IC_LEFT (ic));
-
- /* if result is present && is a true symbol */
- if (IC_RESULT (ic) && ic->op != IFX &&
- IS_TRUE_SYMOP (IC_RESULT (ic)))
- OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
-
- /* take away registers from live
- ranges that end at this instruction */
- deassignLRs (ic, ebbs[i]);
-
- /* some don't need registers */
- if (SKIP_IC2 (ic) ||
- ic->op == JUMPTABLE ||
- ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- (IC_RESULT (ic) && POINTER_SET (ic)))
- continue;
-
- /* now we need to allocate registers
- only for the result */
- if (IC_RESULT (ic))
- {
- symbol *sym = OP_SYMBOL (IC_RESULT (ic));
- bitVect *spillable;
- int willCS;
- int j;
- int ptrRegSet = 0;
-
- /* Make sure any spill location is definately allocated */
- if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
- !sym->usl.spillLoc->allocreq)
- {
- sym->usl.spillLoc->allocreq++;
- }
-
- /* if it does not need or is spilt
- or is already assigned to registers
- or will not live beyond this instructions */
- if (!sym->nRegs ||
- sym->isspilt ||
- bitVectBitValue (_G.regAssigned, sym->key) ||
- sym->liveTo <= ic->seq)
- continue;
-
- /* if some liverange has been spilt at the block level
- and this one live beyond this block then spil this
- to be safe */
- if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
- {
- spillThis (sym);
- continue;
- }
- /* if trying to allocate this will cause
- a spill and there is nothing to spill
- or this one is rematerializable then
- spill this one */
- willCS = willCauseSpill (sym->nRegs, sym->regType);
-
- /* explicit turn off register spilling */
- willCS = 0;
-
- spillable = computeSpillable (ic);
- if (sym->remat ||
- (willCS && bitVectIsZero (spillable)))
- {
-
- spillThis (sym);
- continue;
-
- }
-
- /* If the live range preceeds the point of definition
- then ideally we must take into account registers that
- have been allocated after sym->liveFrom but freed
- before ic->seq. This is complicated, so spill this
- symbol instead and let fillGaps handle the allocation. */
+ {
+
+ debugLog (" op: %s\n", pic16_decodeOp (ic->op));
+
+ if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
+ pic16_allocDirReg(IC_RESULT(ic));
+
+ if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
+ pic16_allocDirReg(IC_LEFT(ic));
+
+ if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
+ pic16_allocDirReg(IC_RIGHT(ic));
+
+ /* if this is an ipop that means some live
+ range will have to be assigned again */
+ if (ic->op == IPOP)
+ reassignLR (IC_LEFT (ic));
+
+ /* if result is present && is a true symbol */
+ if (IC_RESULT (ic) && ic->op != IFX &&
+ IS_TRUE_SYMOP (IC_RESULT (ic)))
+ OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
+
+ /* take away registers from live
+ ranges that end at this instruction */
+ deassignLRs (ic, ebbs[i]);
+
+ /* some don't need registers */
+ if (SKIP_IC2 (ic) ||
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ (IC_RESULT (ic) && POINTER_SET (ic)))
+ continue;
+
+ /* now we need to allocate registers
+ only for the result */
+ if (IC_RESULT (ic))
+ {
+ symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+ bitVect *spillable;
+ int willCS;
+ int j;
+ int ptrRegSet = 0;
+
+ /* Make sure any spill location is definately allocated */
+ if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+ !sym->usl.spillLoc->allocreq)
+ {
+ sym->usl.spillLoc->allocreq++;
+ }
+
+ /* if it does not need or is spilt
+ or is already assigned to registers
+ or will not live beyond this instructions */
+ if (!sym->nRegs ||
+ sym->isspilt ||
+ bitVectBitValue (_G.regAssigned, sym->key) ||
+ sym->liveTo <= ic->seq)
+ continue;
+
+ /* if some liverange has been spilt at the block level
+ and this one live beyond this block then spil this
+ to be safe */
+ if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
+ {
+ spillThis (sym);
+ continue;
+ }
+ /* if trying to allocate this will cause
+ a spill and there is nothing to spill
+ or this one is rematerializable then
+ spill this one */
+ willCS = willCauseSpill (sym->nRegs, sym->regType);
+
+ /* explicit turn off register spilling */
+ willCS = 0;
+
+ spillable = computeSpillable (ic);
+ if (sym->remat ||
+ (willCS && bitVectIsZero (spillable)))
+ {
+
+ spillThis (sym);
+ continue;
+
+ }
+
+ /* If the live range preceeds the point of definition
+ then ideally we must take into account registers that
+ have been allocated after sym->liveFrom but freed
+ before ic->seq. This is complicated, so spill this
+ symbol instead and let fillGaps handle the allocation. */
#if 0
- if (sym->liveFrom < ic->seq)
- {
- spillThis (sym);
- continue;
- }
+ if (sym->liveFrom < ic->seq)
+ {
+ spillThis (sym);
+ continue;
+ }
#endif
- /* if it has a spillocation & is used less than
- all other live ranges then spill this */
- if (willCS) {
- if (sym->usl.spillLoc) {
- symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
- allLRs, ebbs[i], ic));
- if (leastUsed && leastUsed->used > sym->used) {
- spillThis (sym);
- continue;
- }
- } else {
- /* if none of the liveRanges have a spillLocation then better
- to spill this one than anything else already assigned to registers */
- if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
- /* if this is local to this block then we might find a block spil */
- if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
- spillThis (sym);
- continue;
- }
- }
- }
- }
-
- if (ic->op == RECEIVE)
- debugLog ("When I get clever, I'll optimize the receive logic\n");
+ /* if it has a spillocation & is used less than
+ all other live ranges then spill this */
+ if (willCS) {
+ if (sym->usl.spillLoc) {
+ symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
+ allLRs, ebbs[i], ic));
+ if (leastUsed && leastUsed->used > sym->used) {
+ spillThis (sym);
+ continue;
+ }
+ } else {
+ /* if none of the liveRanges have a spillLocation then better
+ to spill this one than anything else already assigned to registers */
+ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
+ /* if this is local to this block then we might find a block spil */
+ if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
+ spillThis (sym);
+ continue;
+ }
+ }
+ }
+ }
+
+ if (ic->op == RECEIVE)
+ debugLog ("When I get clever, I'll optimize the receive logic\n");
if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
&& (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
for(j=0;j<sym->nRegs;j++)
sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
// OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
-
+
continue;
}
- /* if we need ptr regs for the right side
- then mark it */
- if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
- <= (unsigned) PTRSIZE)
- {
- pic16_ptrRegReq++;
- ptrRegSet = 1;
- }
- /* else we assign registers to it */
- _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
-
- if(debugF)
- bitVectDebugOn(_G.regAssigned, debugF);
-
- for (j = 0; j < sym->nRegs; j++)
- {
- if (sym->regType == REG_PTR)
- sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
- else
- sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
-
- /* if the allocation falied which means
- this was spilt then break */
- if (!sym->regs[j])
- break;
- }
- debugLog (" %d - \n", __LINE__);
-
- /* if it shares registers with operands make sure
- that they are in the same position */
- if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
- /* do the same for the right operand */
- if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
-
- debugLog (" %d - \n", __LINE__);
- if (ptrRegSet)
- {
- debugLog (" %d - \n", __LINE__);
- pic16_ptrRegReq--;
- ptrRegSet = 0;
- }
-
- }
- }
+ /* if we need ptr regs for the right side
+ then mark it */
+ if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
+ <= (unsigned) PTRSIZE)
+ {
+ pic16_ptrRegReq++;
+ ptrRegSet = 1;
+ }
+ /* else we assign registers to it */
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+
+ if(debugF)
+ bitVectDebugOn(_G.regAssigned, debugF);
+
+ for (j = 0; j < sym->nRegs; j++)
+ {
+ if (sym->regType == REG_PTR)
+ sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
+ else
+ sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+
+ /* if the allocation falied which means
+ this was spilt then break */
+ if (!sym->regs[j])
+ break;
+ }
+ debugLog (" %d - \n", __LINE__);
+
+ /* if it shares registers with operands make sure
+ that they are in the same position */
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
+ /* do the same for the right operand */
+ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
+
+ debugLog (" %d - \n", __LINE__);
+ if (ptrRegSet)
+ {
+ debugLog (" %d - \n", __LINE__);
+ pic16_ptrRegReq--;
+ ptrRegSet = 0;
+ }
+
+ }
+ }
}
/* Check for and fix any problems with uninitialized operands */
for (i = 0; i < count; i++)
{
- iCode *ic;
-
- if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
-
- for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
- if (SKIP_IC2 (ic))
- continue;
-
- if (ic->op == IFX)
- {
- verifyRegsAssigned (IC_COND (ic), ic);
- continue;
- }
-
- if (ic->op == JUMPTABLE)
- {
- verifyRegsAssigned (IC_JTCOND (ic), ic);
- continue;
- }
-
- verifyRegsAssigned (IC_RESULT (ic), ic);
- verifyRegsAssigned (IC_LEFT (ic), ic);
- verifyRegsAssigned (IC_RIGHT (ic), ic);
+ iCode *ic;
+
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
+
+ for (ic = ebbs[i]->sch; ic; ic = ic->next)
+ {
+ if (SKIP_IC2 (ic))
+ continue;
+
+ if (ic->op == IFX)
+ {
+ verifyRegsAssigned (IC_COND (ic), ic);
+ continue;
+ }
+
+ if (ic->op == JUMPTABLE)
+ {
+ verifyRegsAssigned (IC_JTCOND (ic), ic);
+ continue;
+ }
+
+ verifyRegsAssigned (IC_RESULT (ic), ic);
+ verifyRegsAssigned (IC_LEFT (ic), ic);
+ verifyRegsAssigned (IC_RIGHT (ic), ic);
}
- }
-
+ }
+
}
/*-----------------------------------------------------------------*/
for (j = 0; j < sym->nRegs; j++)
{
rumask = bitVectSetBit (rumask,
- sym->regs[j]->rIdx);
+ sym->regs[j]->rIdx);
}
return rumask;
if (ic->op == IFX)
{
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_COND (ic)));
+ rUmaskForOp (IC_COND (ic)));
goto ret;
}
if (ic->op == JUMPTABLE)
{
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_JTCOND (ic)));
+ rUmaskForOp (IC_JTCOND (ic)));
goto ret;
}
/* of all other cases */
if (IC_LEFT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_LEFT (ic)));
+ rUmaskForOp (IC_LEFT (ic)));
if (IC_RIGHT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RIGHT (ic)));
+ rUmaskForOp (IC_RIGHT (ic)));
if (IC_RESULT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RESULT (ic)));
+ rUmaskForOp (IC_RESULT (ic)));
ret:
return rmask;
iCode *ic;
if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
/* for all instructions */
for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
-
- int j;
-
- if (SKIP_IC2 (ic) || !ic->rlive)
- continue;
-
- /* first mark the registers used in this
- instruction */
- ic->rUsed = regsUsedIniCode (ic);
- _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
-
- /* now create the register mask for those
- registers that are in use : this is a
- super set of ic->rUsed */
- ic->rMask = newBitVect (pic16_nRegs + 1);
-
- /* for all live Ranges alive at this point */
- for (j = 1; j < ic->rlive->size; j++)
- {
- symbol *sym;
- int k;
-
- /* if not alive then continue */
- if (!bitVectBitValue (ic->rlive, j))
- continue;
-
- /* find the live range we are interested in */
- if (!(sym = hTabItemWithKey (liveRanges, j)))
- {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "createRegMask cannot find live range");
- exit (0);
- }
-
- /* if no register assigned to it */
- if (!sym->nRegs || sym->isspilt)
- continue;
-
- /* for all the registers allocated to it */
- for (k = 0; k < sym->nRegs; k++)
- if (sym->regs[k])
- ic->rMask =
- bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
- }
- }
+ {
+
+ int j;
+
+ if (SKIP_IC2 (ic) || !ic->rlive)
+ continue;
+
+ /* first mark the registers used in this
+ instruction */
+ ic->rUsed = regsUsedIniCode (ic);
+ _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
+
+ /* now create the register mask for those
+ registers that are in use : this is a
+ super set of ic->rUsed */
+ ic->rMask = newBitVect (pic16_nRegs + 1);
+
+ /* for all live Ranges alive at this point */
+ for (j = 1; j < ic->rlive->size; j++)
+ {
+ symbol *sym;
+ int k;
+
+ /* if not alive then continue */
+ if (!bitVectBitValue (ic->rlive, j))
+ continue;
+
+ /* find the live range we are interested in */
+ if (!(sym = hTabItemWithKey (liveRanges, j)))
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "createRegMask cannot find live range");
+ exit (0);
+ }
+
+ /* if no register assigned to it */
+ if (!sym->nRegs || sym->isspilt)
+ continue;
+
+ /* for all the registers allocated to it */
+ for (k = 0; k < sym->nRegs; k++)
+ if (sym->regs[k])
+ ic->rMask =
+ bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
+ }
+ }
}
}
/* if plus or minus print the right hand side */
if (ic->op == '+' || ic->op == '-') {
-
+
iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
sprintf (s, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ric))->rname,
- ic->op,
- (int) operandLitValue (IC_RIGHT (ic)));
+ OP_SYMBOL (IC_LEFT (ric))->rname,
+ ic->op,
+ (int) operandLitValue (IC_RIGHT (ic)));
//fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
}
*/
if (ic->op == '+' || ic->op == '-')
- {
- iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
- sprintf (s, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ric))->rname,
- ic->op,
- (int) operandLitValue (IC_RIGHT (ic)));
-
- //s += strlen(s);
- //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
- //continue ;
- //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
- return buffer;
- }
+ {
+ iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+ sprintf (s, "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ric))->rname,
+ ic->op,
+ (int) operandLitValue (IC_RIGHT (ic)));
+
+ //s += strlen(s);
+ //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+ //continue ;
+ //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+ return buffer;
+ }
/* we reached the end */
sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
/* if the type is marked as a conditional */
if (sym->regType == REG_CND)
- continue;
+ continue;
- /* if used in return only then we don't
- need registers */
+ /* if used in return only then we don't
+ need registers */
if (sym->ruonly || sym->accuse) {
- if (IS_AGGREGATE (sym->type) || sym->isptr)
- sym->type = aggrToPtr (sym->type, FALSE);
- debugLog (" %d - no reg needed - used as a return\n", __LINE__);
- continue;
+ if (IS_AGGREGATE (sym->type) || sym->isptr)
+ sym->type = aggrToPtr (sym->type, FALSE);
+ debugLog (" %d - no reg needed - used as a return\n", __LINE__);
+ continue;
}
/* if the symbol has only one definition &
- that definition is a get_pointer and the
- pointer we are getting is rematerializable and
- in "data" space */
+ that definition is a get_pointer and the
+ pointer we are getting is rematerializable and
+ in "data" space */
if (bitVectnBitsOn (sym->defs) == 1 &&
- (ic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (sym->defs))) &&
- POINTER_GET (ic) &&
- !IS_BITVAR (sym->etype) &&
- (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
+ (ic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (sym->defs))) &&
+ POINTER_GET (ic) &&
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
// continue; /* FIXME -- VR */
- if (ptrPseudoSymSafe (sym, ic)) {
-
- symbol *psym;
-
- debugLog (" %d - \n", __LINE__);
-
- /* create a psuedo symbol & force a spil */
- //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
- psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
- psym->type = sym->type;
- psym->etype = sym->etype;
- psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
- strcpy (psym->rname, psym->name);
- sym->isspilt = 1;
- sym->usl.spillLoc = psym;
- continue;
- }
-
- /* if in data space or idata space then try to
- allocate pointer register */
+ if (ptrPseudoSymSafe (sym, ic)) {
+
+ symbol *psym;
+
+ debugLog (" %d - \n", __LINE__);
+
+ /* create a psuedo symbol & force a spil */
+ //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+ psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
+ psym->type = sym->type;
+ psym->etype = sym->etype;
+ psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
+ strcpy (psym->rname, psym->name);
+ sym->isspilt = 1;
+ sym->usl.spillLoc = psym;
+ continue;
+ }
+
+ /* if in data space or idata space then try to
+ allocate pointer register */
}
/* if not then we require registers */
sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
- getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
- getSize (sym->type));
+ getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
+ getSize (sym->type));
#if 0
}
if (sym->nRegs > 4) {
- fprintf (stderr, "allocated more than 4 or 0 registers for type ");
- printTypeChain (sym->type, stderr);
- fprintf (stderr, "\n");
+ fprintf (stderr, "allocated more than 4 or 0 registers for type ");
+ printTypeChain (sym->type, stderr);
+ fprintf (stderr, "\n");
}
/* determine the type of register required */
if (sym->nRegs == 1 &&
- IS_PTR (sym->type) &&
- sym->uptr)
- sym->regType = REG_PTR;
+ IS_PTR (sym->type) &&
+ sym->uptr)
+ sym->regType = REG_PTR;
else
- sym->regType = REG_GPR;
+ sym->regType = REG_GPR;
debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
/* registers for true symbols we will */
/* see how things go */
sym->nRegs = 0;
-
+
}
}
/* if the definition is a call then no */
if ((dic->op == CALL || dic->op == PCALL) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- {
- return NULL;
- }
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ {
+ return NULL;
+ }
/* if shift by unknown amount then not */
if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- return NULL;
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ return NULL;
/* if pointer get and size > 1 */
if (POINTER_GET (dic) &&
- getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
- return NULL;
+ getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
+ return NULL;
if (POINTER_SET (dic) &&
- getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
- return NULL;
+ getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
+ return NULL;
/* if any three is a true symbol in far space */
if (IC_RESULT (dic) &&
- IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- isOperandInFarSpace (IC_RESULT (dic)))
- return NULL;
+ IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ isOperandInFarSpace (IC_RESULT (dic)))
+ return NULL;
if (IC_RIGHT (dic) &&
- IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
- isOperandInFarSpace (IC_RIGHT (dic)) &&
- !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
- return NULL;
+ IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+ isOperandInFarSpace (IC_RIGHT (dic)) &&
+ !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+ return NULL;
if (IC_LEFT (dic) &&
- IS_TRUE_SYMOP (IC_LEFT (dic)) &&
- isOperandInFarSpace (IC_LEFT (dic)) &&
- !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
- return NULL;
+ IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+ isOperandInFarSpace (IC_LEFT (dic)) &&
+ !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+ return NULL;
if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
- {
- if ((dic->op == LEFT_OP ||
- dic->op == RIGHT_OP ||
- dic->op == '-') &&
- IS_OP_LITERAL (IC_RIGHT (dic)))
- return NULL;
- else
- return dic;
- }
+ {
+ if ((dic->op == LEFT_OP ||
+ dic->op == RIGHT_OP ||
+ dic->op == '-') &&
+ IS_OP_LITERAL (IC_RIGHT (dic)))
+ return NULL;
+ else
+ return dic;
+ }
}
return NULL;
debugAopGet (" left:", IC_LEFT (ic));
debugAopGet (" right:", IC_RIGHT (ic));
-// fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
+// fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
- debugLog(" %d - actuall processing\n", __LINE__ );
+ debugLog(" %d - actuall processing\n", __LINE__ );
if (!IS_ITEMP (IC_RESULT (ic))) {
pic16_allocDirReg(IC_RESULT (ic));
if (isOperandInFarSpace (IC_RESULT (ic)))
{
if ((dic = farSpacePackable (ic)))
- goto pack;
+ goto pack;
else
- return 0;
+ return 0;
}
- /* find the definition of iTempNN scanning backwards if we find a
- a use of the true symbol before we find the definition then
+ /* find the definition of iTempNN scanning backwards if we find a
+ a use of the true symbol before we find the definition then
we cannot pack */
for (dic = ic->prev; dic; dic = dic->prev)
{
/* if there is a function call and this is
a parameter & not my parameter then don't pack it */
if ((dic->op == CALL || dic->op == PCALL) &&
- (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
- !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
- {
- debugLog (" %d - \n", __LINE__);
- dic = NULL;
- break;
- }
+ (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
+ !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
+ {
+ debugLog (" %d - \n", __LINE__);
+ dic = NULL;
+ break;
+ }
if (SKIP_IC2 (dic))
- continue;
+ continue;
- debugLog("%d\tSearching for iTempNN\n", __LINE__);
+ debugLog("%d\tSearching for iTempNN\n", __LINE__);
if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- IS_OP_VOLATILE (IC_RESULT (dic)))
- {
- debugLog (" %d - dic is VOLATILE \n", __LINE__);
- dic = NULL;
- break;
- }
+ IS_OP_VOLATILE (IC_RESULT (dic)))
+ {
+ debugLog (" %d - dic is VOLATILE \n", __LINE__);
+ dic = NULL;
+ break;
+ }
#if 1
if( IS_SYMOP( IC_RESULT(dic)) &&
- IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
+ IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
- debugLog (" %d - result is bitfield\n", __LINE__);
- dic = NULL;
- break;
- }
+ debugLog (" %d - result is bitfield\n", __LINE__);
+ dic = NULL;
+ break;
+ }
#endif
if (IS_SYMOP (IC_RESULT (dic)) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- {
- /* A previous result was assigned to the same register - we'll our definition */
- debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
- __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
- if (POINTER_SET (dic))
- dic = NULL;
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ {
+ /* A previous result was assigned to the same register - we'll our definition */
+ debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
+ __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
+ if (POINTER_SET (dic))
+ dic = NULL;
- break;
- }
+ break;
+ }
if (IS_SYMOP (IC_RIGHT (dic)) &&
- (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
- IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
- {
- debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
- dic = NULL;
- break;
- }
+ (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+ IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
+ dic = NULL;
+ break;
+ }
if (IS_SYMOP (IC_LEFT (dic)) &&
- (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
- IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
- {
- debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
- dic = NULL;
- break;
- }
+ (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+ IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
+ dic = NULL;
+ break;
+ }
if (POINTER_SET (dic) &&
- IC_RESULT (dic)->key == IC_RESULT (ic)->key)
- {
- debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
- __LINE__);
- dic = NULL;
- break;
- }
+ IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+ {
+ debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
+ __LINE__);
+ dic = NULL;
+ break;
+ }
}
if (!dic)
- return 0; /* did not find */
+ return 0; /* did not find */
#if 1
- /* This code is taken from the hc08 port. Do not know
- * if it fits for pic16, but I leave it here just in case */
-
- /* if assignment then check that right is not a bit */
- if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
- sym_link *etype = operandType (IC_RESULT (dic));
-
- if (IS_BITFIELD (etype)) {
- /* if result is a bit too then it's ok */
- etype = operandType (IC_RESULT (ic));
- if (!IS_BITFIELD (etype)) {
- debugLog(" %d bitfields\n");
- return 0;
- }
- }
- }
+ /* This code is taken from the hc08 port. Do not know
+ * if it fits for pic16, but I leave it here just in case */
+
+ /* if assignment then check that right is not a bit */
+ if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
+ sym_link *etype = operandType (IC_RESULT (dic));
+
+ if (IS_BITFIELD (etype)) {
+ /* if result is a bit too then it's ok */
+ etype = operandType (IC_RESULT (ic));
+ if (!IS_BITFIELD (etype)) {
+ debugLog(" %d bitfields\n");
+ return 0;
+ }
+ }
+ }
#endif
/* if the result is on stack or iaccess then it must be
/* the operation has only one symbol
operator then we can pack */
if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
- (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
- goto pack;
+ (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
+ goto pack;
if (!((IC_LEFT (dic) &&
- IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
- (IC_RIGHT (dic) &&
- IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
- return 0;
+ IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
+ (IC_RIGHT (dic) &&
+ IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
+ return 0;
}
pack:
debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
/* replace the result with the result of */
/* this assignment and remove this assignment */
-
+
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
IC_RESULT (dic) = IC_RESULT (ic);
{
OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
}
- /* delete from liverange table also
+ /* delete from liverange table also
delete from all the points inbetween and the new
one */
for (sic = dic; sic != ic; sic = sic->next)
/* if definition by assignment */
if (dic->op == '=' &&
- !POINTER_SET (dic) &&
- IC_RESULT (dic)->key == op->key
+ !POINTER_SET (dic) &&
+ IC_RESULT (dic)->key == op->key
/* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
- )
- {
-
- /* we are interested only if defined in far space */
- /* or in stack space in case of + & - */
-
- /* if assigned to a non-symbol then return
- true */
- if (!IS_SYMOP (IC_RIGHT (dic)))
- break;
-
- /* if the symbol is in far space then
- we should not */
- if (isOperandInFarSpace (IC_RIGHT (dic)))
- return NULL;
-
- /* for + & - operations make sure that
- if it is on the stack it is the same
- as one of the three operands */
- if ((ic->op == '+' || ic->op == '-') &&
- OP_SYMBOL (IC_RIGHT (dic))->onStack)
- {
- if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
- IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
- IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
- return NULL;
- }
-
- break;
-
- }
+ )
+ {
+
+ /* we are interested only if defined in far space */
+ /* or in stack space in case of + & - */
+
+ /* if assigned to a non-symbol then return
+ true */
+ if (!IS_SYMOP (IC_RIGHT (dic)))
+ break;
+
+ /* if the symbol is in far space then
+ we should not */
+ if (isOperandInFarSpace (IC_RIGHT (dic)))
+ return NULL;
+
+ /* for + & - operations make sure that
+ if it is on the stack it is the same
+ as one of the three operands */
+ if ((ic->op == '+' || ic->op == '-') &&
+ OP_SYMBOL (IC_RIGHT (dic))->onStack)
+ {
+ if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
+ IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
+ IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
+ return NULL;
+ }
+
+ break;
+
+ }
/* if we find an usage then we cannot delete it */
if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
- return NULL;
+ return NULL;
if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
- return NULL;
+ return NULL;
if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
- return NULL;
+ return NULL;
}
/* now make sure that the right side of dic
iCode *sic = dic->next;
for (; sic != ic; sic = sic->next)
- if (IC_RESULT (sic) &&
- IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
- return NULL;
+ if (IC_RESULT (sic) &&
+ IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
+ return NULL;
}
return dic;
iCode *sic;
if (!dic)
- goto right;
+ goto right;
debugAopGet ("removing left:", IC_LEFT (ic));
/* found it we need to remove it from the
block */
for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
+ bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
IC_LEFT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
+ IC_RIGHT (dic)->operand.symOperand;
IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
remiCodeFromeBBlock (ebp, dic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
iCode *sic;
if (!dic)
- return change;
+ return change;
/* if this is a subtraction & the result
is a true symbol in far space then don't pack */
if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
- {
- sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
- if (IN_FARSPACE (SPEC_OCLS (etype)))
- return change;
- }
+ {
+ sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
+ if (IN_FARSPACE (SPEC_OCLS (etype)))
+ return change;
+ }
debugAopGet ("removing right:", IC_RIGHT (ic));
/* found it we need to remove it from the
block */
for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
+ bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
IC_RIGHT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
+ IC_RIGHT (dic)->operand.symOperand;
IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
remiCodeFromeBBlock (ebp, dic);
)
return NULL;
- /* this routine will mark the a symbol as used in one
- instruction use only && if the definition is local
+ /* this routine will mark the a symbol as used in one
+ instruction use only && if the definition is local
(ie. within the basic block) && has only one definition &&
- that definition is either a return value from a
+ that definition is either a return value from a
function or does not contain any variables in
far space */
#if 0
uses = bitVectCopy (OP_USES (op));
- bitVectUnSetBit (uses, ic->key); /* take away this iCode */
- if (!bitVectIsZero (uses)) /* has other uses */
+ bitVectUnSetBit (uses, ic->key); /* take away this iCode */
+ if (!bitVectIsZero (uses)) /* has other uses */
return NULL;
#endif
/* if it has only one defintion */
if (bitVectnBitsOn (OP_DEFS (op)) > 1)
- return NULL; /* has more than one definition */
+ return NULL; /* has more than one definition */
/* get that definition */
if (!(dic =
- hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_DEFS (op)))))
+ hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (OP_DEFS (op)))))
return NULL;
/* found the definition now check if it is local */
if (dic->seq < ebp->fSeq ||
dic->seq > ebp->lSeq)
- return NULL; /* non-local */
+ return NULL; /* non-local */
/* now check if it is the return from
a function call */
if (dic->op == CALL || dic->op == PCALL)
{
if (ic->op != SEND && ic->op != RETURN &&
- !POINTER_SET(ic) && !POINTER_GET(ic))
- {
- OP_SYMBOL (op)->ruonly = 1;
- return dic;
- }
+ !POINTER_SET(ic) && !POINTER_GET(ic))
+ {
+ OP_SYMBOL (op)->ruonly = 1;
+ return dic;
+ }
dic = dic->next;
}
else
/* if there is an intervening function call then no */
if (dic->op == CALL || dic->op == PCALL)
- return NULL;
+ return NULL;
/* if pointer set then make sure the pointer
is one byte */
if (POINTER_SET (dic) &&
- !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
- return NULL;
+ !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
+ return NULL;
if (POINTER_GET (dic) &&
- !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
- return NULL;
+ !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
+ return NULL;
/* if address of & the result is remat then okay */
if (dic->op == ADDRESS_OF &&
- OP_SYMBOL (IC_RESULT (dic))->remat)
- continue;
+ OP_SYMBOL (IC_RESULT (dic))->remat)
+ continue;
/* if operand has size of three or more & this
operation is a '*','/' or '%' then 'b' may
cause a problem */
if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
- getSize (operandType (op)) >= 2)
- return NULL;
+ getSize (operandType (op)) >= 2)
+ return NULL;
/* if left or right or result is in far space */
if (isOperandInFarSpace (IC_LEFT (dic)) ||
- isOperandInFarSpace (IC_RIGHT (dic)) ||
- isOperandInFarSpace (IC_RESULT (dic)) ||
- IS_OP_RUONLY (IC_LEFT (dic)) ||
- IS_OP_RUONLY (IC_RIGHT (dic)) ||
- IS_OP_RUONLY (IC_RESULT (dic)))
- {
- return NULL;
- }
+ isOperandInFarSpace (IC_RIGHT (dic)) ||
+ isOperandInFarSpace (IC_RESULT (dic)) ||
+ IS_OP_RUONLY (IC_LEFT (dic)) ||
+ IS_OP_RUONLY (IC_RIGHT (dic)) ||
+ IS_OP_RUONLY (IC_RESULT (dic)))
+ {
+ return NULL;
+ }
}
OP_SYMBOL (op)->ruonly = 1;
debugLog ("%s\n", __FUNCTION__);
/* bitwise operations are considered optimizable
- under the following conditions (Jean-Louis VERN)
+ under the following conditions (Jean-Louis VERN)
x & lit
bit & bit
debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* and the usage immediately follows this iCode */
if (!(uic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+ bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
return;
debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
return;
debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- /* if used in ^ operation then make sure right is not a
+ /* if used in ^ operation then make sure right is not a
literl */
if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
return;
debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* if one of them is a literal then we can */
if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
- (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
+ (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
(getSize (operandType (IC_RESULT (uic))) <= 1))
{
OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
(IS_ITEMP (IC_RIGHT (uic)) ||
(IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
- !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
+ !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
goto accuse;
if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
(IS_ITEMP (IC_LEFT (uic)) ||
(IS_TRUE_SYMOP (IC_LEFT (uic)) &&
- !OP_SYMBOL (IC_LEFT (uic))->onStack)))
+ !OP_SYMBOL (IC_LEFT (uic))->onStack)))
goto accuse;
return;
if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
(IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
- return;
+ return;
}
debugLog (" hey we can remove this unnecessary assign\n");
packForPush (iCode * ic, eBBlock * ebp)
{
iCode *dic;
- char *iLine;
-
+ const char *iLine;
+
debugLog ("%s\n", __FUNCTION__);
if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
return;
#if 0
{
int n1, n2;
- char *iLine;
-
- n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
- n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
- iLine = printILine(ic);
- debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
- dbuf_free(iLine);
- debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
+
+ n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
+ n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
+ iLine = printILine(ic);
+ debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
+ dbuf_free(iLine);
+ debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
}
#endif
/* find the definition */
if (!(dic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
+ bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
return;
/* if definition is not assignment,
if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
return;
// debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
-
+
/* we now we know that it has one & only one def & use
and the that the definition is an assignment */
IC_LEFT (ic) = IC_RIGHT (dic);
-
+
iLine = printILine(dic);
debugf("remiCodeFromeBBlock: %s\n", iLine);
dbuf_free(iLine);
static void printSymType(char * str, sym_link *sl)
{
- if(!pic16_ralloc_debug)return;
-
- debugLog (" %s Symbol type: ",str);
- printTypeChain (sl, debugF);
- debugLog ("\n");
+ if(!pic16_ralloc_debug)return;
+
+ debugLog (" %s Symbol type: ",str);
+ printTypeChain (sl, debugF);
+ debugLog ("\n");
}
/*-----------------------------------------------------------------*/
FILE *of = stderr;
if(!pic16_ralloc_debug)return;
-
+
if(!sl)return;
-
+
if(debugF)
of = debugF;
/* TrueSym := iTempNN:1 */
for (ic = ebp->sch; ic; ic = ic->next)
{
-// debugLog("%d\n", __LINE__);
- /* find assignment of the form TrueSym := iTempNN:1 */
- if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
- change += packRegsForAssign (ic, ebp);
- /* debug stuff */
- if (ic->op == '=')
- {
- if (POINTER_SET (ic))
- debugLog ("pointer is set\n");
- debugAopGet (" result:", IC_RESULT (ic));
- debugAopGet (" left:", IC_LEFT (ic));
- debugAopGet (" right:", IC_RIGHT (ic));
- }
+// debugLog("%d\n", __LINE__);
+ /* find assignment of the form TrueSym := iTempNN:1 */
+ if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
+ change += packRegsForAssign (ic, ebp);
+ /* debug stuff */
+ if (ic->op == '=')
+ {
+ if (POINTER_SET (ic))
+ debugLog ("pointer is set\n");
+ debugAopGet (" result:", IC_RESULT (ic));
+ debugAopGet (" left:", IC_LEFT (ic));
+ debugAopGet (" right:", IC_RIGHT (ic));
+ }
}
#else
if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
#endif
- debugLog (" is a pointer\n");
+ debugLog (" is a pointer\n");
if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
debugLog (" is a ptr\n");
if(IS_OP_VOLATILE(IC_LEFT(ic)))
- debugLog (" is volatile\n");
+ debugLog (" is volatile\n");
isData(etype);
- if(IS_OP_VOLATILE(IC_LEFT(ic))) {
- debugLog (" %d - left is not temp, allocating\n", __LINE__);
- pic16_allocDirReg(IC_LEFT (ic));
- }
+ if(IS_OP_VOLATILE(IC_LEFT(ic))) {
+ debugLog (" %d - left is not temp, allocating\n", __LINE__);
+ pic16_allocDirReg(IC_LEFT (ic));
+ }
printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
}
if (POINTER_SET (ic))
debugLog (" %d - Pointer set\n", __LINE__);
-
+
/* Look for two subsequent iCodes with */
/* iTemp := _c; */
/* _c = iTemp & op; */
{
iCode* ic_prev = ic->prev;
symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
-
+
ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
}
}
bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
-
+
bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
}
}
-
- /* if this is an itemp & result of a address of a true sym
+
+ /* if this is an itemp & result of a address of a true sym
then mark this as rematerialisable */
if (ic->op == ADDRESS_OF &&
- IS_ITEMP (IC_RESULT (ic)) &&
- IS_TRUE_SYMOP (IC_LEFT (ic)) &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- !OP_SYMBOL (IC_LEFT (ic))->onStack)
+ IS_ITEMP (IC_RESULT (ic)) &&
+ IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ !OP_SYMBOL (IC_LEFT (ic))->onStack)
{
- debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
+ debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
}
/* if straight assignment then carry remat flag if
this is the only definition */
if (ic->op == '=' &&
- !POINTER_SET (ic) &&
- IS_SYMOP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->remat &&
- bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+ !POINTER_SET (ic) &&
+ IS_SYMOP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->remat &&
+ bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
{
- debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
+ debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
- OP_SYMBOL (IC_RESULT (ic))->remat =
- OP_SYMBOL (IC_RIGHT (ic))->remat;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode =
- OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ OP_SYMBOL (IC_RESULT (ic))->remat =
+ OP_SYMBOL (IC_RIGHT (ic))->remat;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+ OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
}
- /* if this is a +/- operation with a rematerizable
+ /* if this is a +/- operation with a rematerizable
then mark this as rematerializable as well */
if ((ic->op == '+' || ic->op == '-') &&
- (IS_SYMOP (IC_LEFT (ic)) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->remat &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- IS_OP_LITERAL (IC_RIGHT (ic))))
+ (IS_SYMOP (IC_LEFT (ic)) &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->remat &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ IS_OP_LITERAL (IC_RIGHT (ic))))
{
- debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
- //int i =
- operandLitValue (IC_RIGHT (ic));
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
+ //int i =
+ operandLitValue (IC_RIGHT (ic));
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
}
#if 0
/* try to optimize FSR0 usage when reading data memory pointers */
-
+
if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
- static int fsr0usage=0;
- static iCode *usic;
-
- if(POINTER_GET(ic) /* this is a memory read */
- && ic->loop /* this is in a loop */
- ) {
- fprintf(stderr, "might optimize FSR0 usage\n");
- }
+ static int fsr0usage=0;
+ static iCode *usic;
+
+ if(POINTER_GET(ic) /* this is a memory read */
+ && ic->loop /* this is in a loop */
+ ) {
+ fprintf(stderr, "might optimize FSR0 usage\n");
+ }
}
#endif
-
+
/* mark the pointer usages */
if (POINTER_SET (ic))
{
- OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
- debugLog (" marking as a pointer (set) =>");
- debugAopGet (" result:", IC_RESULT (ic));
+ OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
+ debugLog (" marking as a pointer (set) =>");
+ debugAopGet (" result:", IC_RESULT (ic));
}
debugLog (" marking as a pointer (get) =>");
debugAopGet (" left:", IC_LEFT (ic));
}
-
+
if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
iCode *dic = ic->prev;
fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
-
+
if(dic && dic->op == '='
&& isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
-
+
fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
/* replace prev->left with ic->left */
IC_LEFT(ic) = IC_RIGHT(dic);
IC_RIGHT(ic->prev) = NULL;
-
+
/* remove ic->prev iCode (assignment) */
remiCodeFromeBBlock (ebp, dic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
}
}
- //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
+ //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
if (!SKIP_IC2 (ic))
{
- //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
- /* if we are using a symbol on the stack
- then we should say pic16_ptrRegReq */
- if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
- pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
- OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
- else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
- pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
- OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
- else
- {
-
- //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
- if (IS_SYMOP (IC_LEFT (ic)))
- pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
- OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
- if (IS_SYMOP (IC_RIGHT (ic)))
- pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
- OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
- if (IS_SYMOP (IC_RESULT (ic)))
- pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
- OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
- }
-
- debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
+ //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
+ /* if we are using a symbol on the stack
+ then we should say pic16_ptrRegReq */
+ if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
+ pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
+ OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
+ else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
+ pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
+ OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
+ else
+ {
+
+ //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
+ if (IS_SYMOP (IC_LEFT (ic)))
+ pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
+ OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP (IC_RIGHT (ic)))
+ pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
+ OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP (IC_RESULT (ic)))
+ pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
+ OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
+ }
+
+ debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
}
is defined in the previous instruction then
mark the itemp as a conditional */
if ((IS_CONDITIONAL (ic) ||
- ((ic->op == BITWISEAND ||
- ic->op == '|' ||
- ic->op == '^') &&
- isBitwiseOptimizable (ic))) &&
- ic->next && ic->next->op == IFX &&
- isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
- OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+ ((ic->op == BITWISEAND ||
+ ic->op == '|' ||
+ ic->op == '^') &&
+ isBitwiseOptimizable (ic))) &&
+ ic->next && ic->next->op == IFX &&
+ isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+ OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
{
- debugLog (" %d\n", __LINE__);
- OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
- continue;
+ debugLog (" %d\n", __LINE__);
+ OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+ continue;
}
- debugLog(" %d\n", __LINE__);
+ debugLog(" %d\n", __LINE__);
#ifndef NO_packRegsForSupport
/* reduce for support function calls */
/* some cases the redundant moves can
can be eliminated for return statements */
if ((ic->op == RETURN || ic->op == SEND) &&
- !isOperandInFarSpace (IC_LEFT (ic)) &&
- !options.model)
+ !isOperandInFarSpace (IC_LEFT (ic)) &&
+ !options.model)
packRegsForOneuse (ic, IC_LEFT (ic), ebp);
#endif
/* if pointer set & left has a size more than
one and right is not in far space */
if (POINTER_SET (ic) &&
- !isOperandInFarSpace (IC_RIGHT (ic)) &&
- !OP_SYMBOL (IC_RESULT (ic))->remat &&
- !IS_OP_RUONLY (IC_RIGHT (ic)) &&
- getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
+ !isOperandInFarSpace (IC_RIGHT (ic)) &&
+ !OP_SYMBOL (IC_RESULT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
packRegsForOneuse (ic, IC_RESULT (ic), ebp);
#endif
#ifndef NO_packRegsForOneuse
/* if pointer get */
if (POINTER_GET (ic) &&
- !isOperandInFarSpace (IC_RESULT (ic)) &&
- !OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_OP_RUONLY (IC_RESULT (ic)) &&
- getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
+ !isOperandInFarSpace (IC_RESULT (ic)) &&
+ !OP_SYMBOL (IC_LEFT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RESULT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
packRegsForOneuse (ic, IC_LEFT (ic), ebp);
debugLog("%d - return from packRegsForOneuse\n", __LINE__);
#ifndef NO_cast_peep
/* if this is cast for intergral promotion then
- check if only use of the definition of the
+ check if only use of the definition of the
operand being casted/ if yes then replace
- the result of that arithmetic operation with
+ the result of that arithmetic operation with
this result and get rid of the cast */
if (ic->op == CAST) {
-
+
sym_link *fromType = operandType (IC_RIGHT (ic));
sym_link *toType = operandType (IC_LEFT (ic));
debugLog (" %d - casting\n", __LINE__);
if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
- getSize (fromType) != getSize (toType)) {
-
-
- iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
- if (dic) {
-
- if (IS_ARITHMETIC_OP (dic)) {
- debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
-
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- IC_RESULT (dic) = IC_RESULT (ic);
- remiCodeFromeBBlock (ebp, ic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
- ic = ic->prev;
- } else
-
- OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
- }
+ getSize (fromType) != getSize (toType)) {
+
+
+ iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+ if (dic) {
+
+ if (IS_ARITHMETIC_OP (dic)) {
+ debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
+
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ IC_RESULT (dic) = IC_RESULT (ic);
+ remiCodeFromeBBlock (ebp, ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+ OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+ ic = ic->prev;
+ } else
+
+ OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
+ }
} else {
- /* if the type from and type to are the same
- then if this is the only use then packit */
- if (compareType (operandType (IC_RIGHT (ic)),
- operandType (IC_LEFT (ic))) == 1) {
-
- iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
- if (dic) {
-
- debugLog(" %d\n", __LINE__);
-
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- IC_RESULT (dic) = IC_RESULT (ic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
- remiCodeFromeBBlock (ebp, ic);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
- ic = ic->prev;
- }
- }
+ /* if the type from and type to are the same
+ then if this is the only use then packit */
+ if (compareType (operandType (IC_RIGHT (ic)),
+ operandType (IC_LEFT (ic))) == 1) {
+
+ iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+ if (dic) {
+
+ debugLog(" %d\n", __LINE__);
+
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ IC_RESULT (dic) = IC_RESULT (ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ remiCodeFromeBBlock (ebp, ic);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+ OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+ ic = ic->prev;
+ }
+ }
}
}
#endif
/* there are some problems with packing variables
* it seems that the live range estimator doesn't
* estimate correctly the liveranges of some symbols */
-
- /* pack for PUSH
+
+ /* pack for PUSH
iTempNN := (some variable in farspace) V1
push iTempNN ;
-------------
*/
if (ic->op == IPUSH)
{
- packForPush (ic, ebp);
+ packForPush (ic, ebp);
}
#endif
combination */
if ((IS_ARITHMETIC_OP (ic)
- || IS_BITWISE_OP (ic)
+ || IS_BITWISE_OP (ic)
- || ic->op == LEFT_OP || ic->op == RIGHT_OP
+ || ic->op == LEFT_OP || ic->op == RIGHT_OP
- ) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- getSize (operandType (IC_RESULT (ic))) <= 1)
+ ) &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ getSize (operandType (IC_RESULT (ic))) <= 1)
packRegsForAccUse (ic);
#endif
{
fprintf (debugF, "\n----------------------------------------------------------------\n");
fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
- ebbs[i]->entryLabel->name,
- ebbs[i]->depth,
- ebbs[i]->noPath,
- ebbs[i]->isLastInLoop);
+ ebbs[i]->entryLabel->name,
+ ebbs[i]->depth,
+ ebbs[i]->noPath,
+ ebbs[i]->isLastInLoop);
fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
- ebbs[i]->dfnum,
- ebbs[i]->bbnum,
- ebbs[i]->fSeq,
- ebbs[i]->lSeq);
+ ebbs[i]->dfnum,
+ ebbs[i]->bbnum,
+ ebbs[i]->fSeq,
+ ebbs[i]->lSeq);
fprintf (debugF, "visited %d : hasFcall = %d\n",
- ebbs[i]->visited,
- ebbs[i]->hasFcall);
+ ebbs[i]->visited,
+ ebbs[i]->hasFcall);
fprintf (debugF, "\ndefines bitVector :");
bitVectDebugOn (ebbs[i]->defSet, debugF);
pic16_freeAllRegs();
#if 0
- dbg_dumpregusage();
- /* clear whats left over from peephole parser */
- pic16_dynAllocRegs= newSet(); //NULL;
-// pic16_dynStackRegs= newSet(); //NULL;
-// pic16_dynProcessorRegs=newSet(); //NULL;
-// pic16_dynDirectRegs=newSet(); //NULL;
-// pic16_dynDirectBitRegs=newSet(); //NULL;
-// pic16_dynInternalRegs=newSet(); //NULL;
-// pic16_dynAccessRegs=newSet(); //NULL;
-
-// dynDirectRegNames=NULL;
- dynAllocRegNames=NULL;
-// dynProcRegNames=NULL;
-// dynAccessRegNames=NULL;
+ dbg_dumpregusage();
+ /* clear whats left over from peephole parser */
+ pic16_dynAllocRegs= newSet(); //NULL;
+// pic16_dynStackRegs= newSet(); //NULL;
+// pic16_dynProcessorRegs=newSet(); //NULL;
+// pic16_dynDirectRegs=newSet(); //NULL;
+// pic16_dynDirectBitRegs=newSet(); //NULL;
+// pic16_dynInternalRegs=newSet(); //NULL;
+// pic16_dynAccessRegs=newSet(); //NULL;
+
+// dynDirectRegNames=NULL;
+ dynAllocRegNames=NULL;
+// dynProcRegNames=NULL;
+// dynAccessRegNames=NULL;
#endif
setToNull ((void *) &_G.funcrUsed);
if (options.dump_pack)
dumpEbbsToFileExt (DUMP_PACK, ebbi);
- /* first determine for each live range the number of
+ /* first determine for each live range the number of
registers & the type of registers required for each */
regTypeNum ();
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
# Begin Source File\r
\r
-SOURCE=.\asm.c\r
-# End Source File\r
-# Begin Source File\r
-\r
SOURCE=..\support\Util\BuildCmd.c\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
+SOURCE=.\SDCCasm.c\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\SDCCast.c\r
# End Source File\r
# Begin Source File\r
# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
# Begin Source File\r
\r
-SOURCE=.\asm.h\r
-# End Source File\r
-# Begin Source File\r
-\r
SOURCE=.\common.h\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
+SOURCE=.\SDCCasm.h\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\SDCCast.h\r
# End Source File\r
# Begin Source File\r
if (inst && *inst)
{
if (fmt && *fmt)
- sprintf (lb, "%s\t", inst);
+ sprintf (lb, "%s\t", inst);
else
- sprintf (lb, "%s", inst);
+ sprintf (lb, "%s", inst);
vsprintf (lb + (strlen (lb)), fmt, ap);
}
else
if (lbp && *lbp)
lineCurr = (lineCurr ?
- connectLine (lineCurr, newLineNode (lb)) :
- (lineHead = newLineNode (lb)));
+ connectLine (lineCurr, newLineNode (lb)) :
+ (lineHead = newLineNode (lb)));
lineCurr->isInline = _G.inLine;
lineCurr->isDebug = _G.debugLine;
va_end (ap);
char *getStackOffset(int stack) {
static char gsoBuf[1024];
sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
- currFunc->stack, _G.nRegsSaved);
+ currFunc->stack, _G.nRegsSaved);
return gsoBuf;
}
/*-----------------------------------------------------------------*/
/* aopForSym - for a true symbol */
/*-----------------------------------------------------------------*/
-static asmop *aopForSym(symbol *sym,
- bool canUsePointer, bool canUseOffset) {
+static asmop *aopForSym(symbol *sym,
+ bool canUsePointer, bool canUseOffset) {
int size;
asmop *aop;
if (sym->onStack) {
if (!canUsePointer || !canUseOffset) {
aop->type=AOP_REG;
- switch (size)
- {
- case 1:
- emitcode ("mov.b", "r0l,[%s] ;aopForSym:stack:1", getStackOffset(sym->stack));
- sprintf (aop->name[0], "r0l");
- return aop;
- case 2:
- emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:2", getStackOffset(sym->stack));
- sprintf (aop->name[0], "r0");
- return aop;
- case 3:
- emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:3.w", getStackOffset(sym->stack));
- sprintf (aop->name[0], "r0");
- emitcode ("mov.b", "r1l,[%s] ;aopForSym:stack:3.b", getStackOffset(sym->stack+2));
- sprintf (aop->name[1], "r1l");
- return aop;
- case 4:
- emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:4", getStackOffset(sym->stack));
- sprintf (aop->name[0], "r0");
- emitcode ("mov.w", "r1,[%s] ;aopForSym:stack:4", getStackOffset(sym->stack+2));
- sprintf (aop->name[1], "r1");
- return aop;
- }
+ switch (size)
+ {
+ case 1:
+ emitcode ("mov.b", "r0l,[%s] ;aopForSym:stack:1", getStackOffset(sym->stack));
+ sprintf (aop->name[0], "r0l");
+ return aop;
+ case 2:
+ emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:2", getStackOffset(sym->stack));
+ sprintf (aop->name[0], "r0");
+ return aop;
+ case 3:
+ emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:3.w", getStackOffset(sym->stack));
+ sprintf (aop->name[0], "r0");
+ emitcode ("mov.b", "r1l,[%s] ;aopForSym:stack:3.b", getStackOffset(sym->stack+2));
+ sprintf (aop->name[1], "r1l");
+ return aop;
+ case 4:
+ emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:4", getStackOffset(sym->stack));
+ sprintf (aop->name[0], "r0");
+ emitcode ("mov.w", "r1,[%s] ;aopForSym:stack:4", getStackOffset(sym->stack+2));
+ sprintf (aop->name[1], "r1");
+ return aop;
+ }
}
aop->type=AOP_STK;
sprintf (aop->name[0], "[%s]", getStackOffset(sym->stack));
if (IN_CODESPACE(SPEC_OCLS(sym->etype))) {
if (!canUsePointer) {
aop->type=AOP_REG;
- switch (size)
- {
- case 1:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOVC, "r0l,[r0+]");
- sprintf (aop->name[0], "r0l");
- return aop;
- case 2:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOVC, "r0,[r0+]");
- sprintf (aop->name[0], "r0");
- return aop;
- case 3:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOVC, "r0,[r0+]");
- sprintf (aop->name[1], "r0");
- emitcode (MOV, "r1l,[r0+]");
- sprintf (aop->name[0], "r1l");
- return aop;
- case 4:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOVC, "r1,[r0+]");
- emitcode (MOVC, "r0,[r0+]");
- emitcode ("xch", "r0,r1");
- sprintf (aop->name[0], "r0");
- sprintf (aop->name[1], "r1");
- return aop;
- }
-
+ switch (size)
+ {
+ case 1:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOVC, "r0l,[r0+]");
+ sprintf (aop->name[0], "r0l");
+ return aop;
+ case 2:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOVC, "r0,[r0+]");
+ sprintf (aop->name[0], "r0");
+ return aop;
+ case 3:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOVC, "r0,[r0+]");
+ sprintf (aop->name[1], "r0");
+ emitcode (MOV, "r1l,[r0+]");
+ sprintf (aop->name[0], "r1l");
+ return aop;
+ case 4:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOVC, "r1,[r0+]");
+ emitcode (MOVC, "r0,[r0+]");
+ emitcode ("xch", "r0,r1");
+ sprintf (aop->name[0], "r0");
+ sprintf (aop->name[1], "r1");
+ return aop;
+ }
+
} else {
aop->type=AOP_CODE;
emitcode ("mov", "r0,#%s ; aopForSym:code", sym->rname);
sprintf (aop->name[0], "[r0]");
if (size>2) {
- sprintf (aop->name[1], "[r0+2]");
+ sprintf (aop->name[1], "[r0+2]");
}
}
return aop;
if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
if (!canUsePointer) {
aop->type=AOP_REG;
- switch (size)
- {
- case 1:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOV, "r0l,[r0]");
- sprintf (aop->name[0], "r0l");
- return aop;
- case 2:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOV, "r0,[r0]");
- sprintf (aop->name[0], "r0");
- return aop;
- case 3:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOV, "r1l,[r0+2]");
- sprintf (aop->name[1], "r1l");
- emitcode (MOV, "r0,[r0]");
- sprintf (aop->name[0], "r0");
- return aop;
- case 4:
- emitcode (MOV, "r0,#%s", sym->rname);
- emitcode (MOV, "r1,[r0+2]");
- sprintf (aop->name[1], "r1");
- emitcode (MOV, "r0,[r0]");
- sprintf (aop->name[0], "r0");
- return aop;
- }
+ switch (size)
+ {
+ case 1:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOV, "r0l,[r0]");
+ sprintf (aop->name[0], "r0l");
+ return aop;
+ case 2:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOV, "r0,[r0]");
+ sprintf (aop->name[0], "r0");
+ return aop;
+ case 3:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOV, "r1l,[r0+2]");
+ sprintf (aop->name[1], "r1l");
+ emitcode (MOV, "r0,[r0]");
+ sprintf (aop->name[0], "r0");
+ return aop;
+ case 4:
+ emitcode (MOV, "r0,#%s", sym->rname);
+ emitcode (MOV, "r1,[r0+2]");
+ sprintf (aop->name[1], "r1");
+ emitcode (MOV, "r0,[r0]");
+ sprintf (aop->name[0], "r0");
+ return aop;
+ }
} else {
aop->type=AOP_FAR;
emitcode ("mov.w", "r0,#%s ; aopForSym:far", sym->rname);
sprintf (aop->name[0], "[r0]");
if (size>2) {
- sprintf (aop->name[1], "[r0+2]");
+ sprintf (aop->name[1], "[r0+2]");
}
return aop;
}
}
-
+
bailOut("aopForSym");
return NULL;
}
switch ((aop->size=getSize(operandType(op))))
{
case 1:
- sprintf (aop->name[0], "#0x%02x",
- SPEC_CVAL(operandType(op)).v_int & 0xff);
- sprintf (aop->name[1], "#0");
- break;
+ sprintf (aop->name[0], "#0x%02x",
+ SPEC_CVAL(operandType(op)).v_int & 0xff);
+ sprintf (aop->name[1], "#0");
+ break;
case 2:
- sprintf (aop->name[0], "#0x%04x",
- SPEC_CVAL(operandType(op)).v_int & 0xffff);
- sprintf (aop->name[1], "#0");
- break;
+ sprintf (aop->name[0], "#0x%04x",
+ SPEC_CVAL(operandType(op)).v_int & 0xffff);
+ sprintf (aop->name[1], "#0");
+ break;
case 3:
- // must be a generic pointer, can only be zero
- // ?? if (v!=0) fprintf (stderr, "invalid val op for gptr\n"); exit(1);
- sprintf (aop->name[0], "#0x%04x",
- SPEC_CVAL(operandType(op)).v_uint & 0xffff);
- sprintf (aop->name[1], "#0");
- break;
+ // must be a generic pointer, can only be zero
+ // ?? if (v!=0) fprintf (stderr, "invalid val op for gptr\n"); exit(1);
+ sprintf (aop->name[0], "#0x%04x",
+ SPEC_CVAL(operandType(op)).v_uint & 0xffff);
+ sprintf (aop->name[1], "#0");
+ break;
case 4:
- sprintf (aop->name[0], "#0x%04x",
- SPEC_CVAL(operandType(op)).v_ulong & 0xffff);
- sprintf (aop->name[1], "#0x%04x",
- SPEC_CVAL(operandType(op)).v_ulong >> 16);
- break;
+ sprintf (aop->name[0], "#0x%04x",
+ SPEC_CVAL(operandType(op)).v_ulong & 0xffff);
+ sprintf (aop->name[1], "#0x%04x",
+ SPEC_CVAL(operandType(op)).v_ulong >> 16);
+ break;
default:
- bailOut("aopForVal");
+ bailOut("aopForVal");
}
return aop;
}
// must be immediate
if (IS_SYMOP(op)) {
op->aop = aop = newAsmop (AOP_IMMD);
- switch ((aop->size=getSize(OP_SYMBOL(op)->type)))
+ switch ((aop->size=getSize(OP_SYMBOL(op)->type)))
{
case 1:
case 2:
- sprintf (aop->name[0], "#%s", OP_SYMBOL(op)->rname);
- return aop;
+ sprintf (aop->name[0], "#%s", OP_SYMBOL(op)->rname);
+ return aop;
case 3: // generic pointer
- sprintf (aop->name[0], "#0x%02x", DCL_TYPE(operandType(op)));
- sprintf (aop->name[1], "#%s", OP_SYMBOL(op)->rname);
- return aop;
+ sprintf (aop->name[0], "#0x%02x", DCL_TYPE(operandType(op)));
+ sprintf (aop->name[1], "#%s", OP_SYMBOL(op)->rname);
+ return aop;
}
}
return NULL;
}
-static int aopOp(operand *op,
- bool canUsePointer, bool canUseOffset) {
+static int aopOp(operand *op,
+ bool canUsePointer, bool canUseOffset) {
if (IS_SYMOP(op)) {
op->aop=aopForSym (OP_SYMBOL(op), canUsePointer, canUseOffset);
return FALSE;
}
}
-
+
char *opRegName(operand *op, int offset, char *opName, bool decorate) {
if (IS_SYMOP(op)) {
case V_SBIT:
case V_BIT:
if (SPEC_CVAL(OP_VALUE(op)->type).v_int &&
- SPEC_CVAL(OP_VALUE(op)->type).v_int != 1) {
- bailOut("opRegName: invalid bit value");
+ SPEC_CVAL(OP_VALUE(op)->type).v_int != 1) {
+ bailOut("opRegName: invalid bit value");
}
// fall through
case V_CHAR:
- sprintf (opName, "#%s0x%02x", decorate?"(char)":"",
- SPEC_CVAL(OP_VALUE(op)->type).v_int);
+ sprintf (opName, "#%s0x%02x", decorate?"(char)":"",
+ SPEC_CVAL(OP_VALUE(op)->type).v_int);
break;
case V_INT:
if (SPEC_LONG(OP_VALUE(op)->type)) {
- sprintf (opName, "#%s0x%02x", decorate?"(long)":"",
- SPEC_CVAL(OP_VALUE(op)->type).v_long);
+ sprintf (opName, "#%s0x%02x", decorate?"(long)":"",
+ SPEC_CVAL(OP_VALUE(op)->type).v_long);
} else {
- sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
- SPEC_CVAL(OP_VALUE(op)->type).v_int);
+ sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
+ SPEC_CVAL(OP_VALUE(op)->type).v_int);
}
break;
case V_FLOAT:
sprintf (opName, "#%s%f", decorate?"(float)":"",
- SPEC_CVAL(OP_VALUE(op)->type).v_float);
+ SPEC_CVAL(OP_VALUE(op)->type).v_float);
break;
- default:
+ default:
bailOut("opRegName: unexpected noun");
}
return opName;
if (isPtr) {
sprintf (line, "[");
if (DCL_TYPE(optype)==FPOINTER)
- strcat (line, "far * ");
+ strcat (line, "far * ");
else if (DCL_TYPE(optype)==CPOINTER)
- strcat (line, "code * ");
+ strcat (line, "code * ");
else if (DCL_TYPE(optype)==GPOINTER)
- strcat (line, "gen * ");
+ strcat (line, "gen * ");
else if (DCL_TYPE(optype)==POINTER)
- strcat (line, "near * ");
+ strcat (line, "near * ");
else
- strcat (line, "unknown * ");
+ strcat (line, "unknown * ");
strcat (line, "(");
strcat (line, nounName(sym->etype));
strcat (line, ")");
if (sym->regs[0]) {
strcat (line, sym->regs[0]->name);
if (sym->regs[1]) {
- strcat (line, ",");
- strcat (line, sym->regs[1]->name);
+ strcat (line, ",");
+ strcat (line, sym->regs[1]->name);
}
return line;
}
sprintf (line, "(");
if (isPtr) {
if (DCL_TYPE(optype)==FPOINTER)
- strcat (line, "far * ");
+ strcat (line, "far * ");
else if (DCL_TYPE(optype)==CPOINTER)
- strcat (line, "code * ");
+ strcat (line, "code * ");
else if (DCL_TYPE(optype)==GPOINTER)
- strcat (line, "gen * ");
+ strcat (line, "gen * ");
else if (DCL_TYPE(optype)==POINTER)
- strcat (line, "near * ");
+ strcat (line, "near * ");
else
- strcat (line, "unknown * ");
+ strcat (line, "unknown * ");
}
// forget about static, volatile, ... for now
if (SPEC_USIGN(operandType(op))) strcat (line, "unsigned ");
return line;
}
-void printIc (bool printToStderr,
- char *op, iCode * ic, bool result, bool left, bool right) {
+void printIc (bool printToStderr,
+ char *op, iCode * ic, bool result, bool left, bool right) {
char line[132];
sprintf (line, "%s(%d)", op, ic->lineno);
static char *toBoolean (operand * op) {
symbol *tlbl=newiTempLabel(NULL);
- switch (AOP_SIZE(op))
+ switch (AOP_SIZE(op))
{
case 1:
case 2:
emitcode ("cjne", "%s,#1,%05d$; %s", AOP_NAME(op), tlbl->key+100,
- "This needs a second thought");
-
+ "This needs a second thought");
+
emitcode ("", "%05d$:", tlbl->key+100);
return "c";
}
{
int j;
if (!sym1->regs[i])
- continue;
+ continue;
for (j = 0; j < sym2->nRegs; j++)
- {
- if (!sym2->regs[j])
- continue;
+ {
+ if (!sym2->regs[j])
+ continue;
- if (sym2->regs[j] == sym1->regs[i])
- return TRUE;
- }
+ if (sym2->regs[j] == sym1->regs[i])
+ return TRUE;
+ }
}
return FALSE;
static int resultRemat (iCode * ic) {
if (SKIP_IC (ic) || ic->op == IFX)
return 0;
-
+
if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
{
symbol *sym = OP_SYMBOL (IC_RESULT (ic));
if (sym->remat && !POINTER_SET (ic))
- return 1;
+ return 1;
}
-
+
return 0;
}
if (AOP_TYPE(left)==AOP_LIT) {
- switch (AOP_SIZE(left))
+ switch (AOP_SIZE(left))
{
case 1:
- emitcode ("mov", "r1l,%s", AOP_NAME(left)[0]);
- emitcode ("push", "r1l");
- _G.parmsPushed++;
- return;
+ emitcode ("mov", "r1l,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1l");
+ _G.parmsPushed++;
+ return;
case 2:
- emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
- emitcode ("push", "r1");
- _G.parmsPushed++;
- return;
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1");
+ _G.parmsPushed++;
+ return;
case 3:
- emitcode ("mov", "r1l,%s", AOP_NAME(left)[1]);
- emitcode ("push", "r1l");
- emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
- emitcode ("push", "r1");
- _G.parmsPushed += 2;
- return;
+ emitcode ("mov", "r1l,%s", AOP_NAME(left)[1]);
+ emitcode ("push", "r1l");
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1");
+ _G.parmsPushed += 2;
+ return;
case 4:
- emitcode ("mov", "r1,%s", AOP_NAME(left)[1]);
- emitcode ("push", "r1");
- emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
- emitcode ("push", "r1");
- _G.parmsPushed += 2;
- return;
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[1]);
+ emitcode ("push", "r1");
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1");
+ _G.parmsPushed += 2;
+ return;
}
} else {
if (AOP_SIZE(left)>2) {
operand *result=IC_RESULT(ic);
emitcode (";", "genCall(%d) %s result=%s", ic->lineno,
- OP_SYMBOL(IC_LEFT(ic))->name,
- printOp (IC_RESULT(ic)));
+ OP_SYMBOL(IC_LEFT(ic))->name,
+ printOp (IC_RESULT(ic)));
emitcode ("call", "%s", OP_SYMBOL(IC_LEFT(ic))->rname);
/* readjust the stack if we have pushed some parms */
switch (AOP_SIZE(result))
{
case 1:
- emitcode ("mov", "%s,r0l", AOP_NAME(result)[0]);
- return;
+ emitcode ("mov", "%s,r0l", AOP_NAME(result)[0]);
+ return;
case 2:
- emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
- return;
+ emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+ return;
case 3:
- // generic pointer
- emitcode ("mov", "%s,r1l", AOP_NAME(result)[1]);
- emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
- return;
+ // generic pointer
+ emitcode ("mov", "%s,r1l", AOP_NAME(result)[1]);
+ emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+ return;
case 4:
- emitcode ("mov", "%s,r1", AOP_NAME(result)[1]);
- emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
- return;
+ emitcode ("mov", "%s,r1", AOP_NAME(result)[1]);
+ emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+ return;
}
bailOut("genCall");
}
if (IFFUNC_ISNAKED(sym->type)) {
emitcode(";", "naked function: no epilogue.");
if (options.debug && currFunc)
- debugFile->writeEndFunction (currFunc, ic, 0);
+ debugFile->writeEndFunction (currFunc, ic, 0);
return;
}
switch (AOP_SIZE(IC_LEFT(ic)))
{
case 4:
- emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
- emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
- break;
+ emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
+ emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
+ break;
case 3:
- emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
- // fall through
+ emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
+ // fall through
case 2:
- emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
- break;
+ emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
+ break;
case 1:
- emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
- break;
+ emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
+ break;
default:
- bailOut("genRet");
+ bailOut("genRet");
}
}
right = left;
left = tmp;
}
-
+
if (aopIsBit(result)) {
if (IS_LITERAL(operandType(right))) {
if (operandLitValue(right)) {
- emitcode ("setb", AOP_NAME(result)[0]);
- return;
+ emitcode ("setb", AOP_NAME(result)[0]);
+ return;
}
aopOp(left, TRUE, TRUE);
emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
}
bailOut("genPlus: unfinished genPlus bit");
}
-
+
aopOp(left, !aopIsPtr(result), !aopIsDir(result));
aopOp(right, !aopIsPtr(result), !aopIsDir(result));
right = left;
left = tmp;
}
-
+
if (aopIsBit(result)) {
if (IS_LITERAL(operandType(right))) {
if (operandLitValue(right)) {
- emitcode ("clr", AOP_NAME(result)[0]);
- return;
+ emitcode ("clr", AOP_NAME(result)[0]);
+ return;
}
aopOp(left, TRUE, TRUE);
emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
}
bailOut("genPlus: unfinished genPlus bit");
}
-
+
if (isOperandEqual(result,left)) {
left->aop=result->aop;
} else {
/* if true symbol then needs to be assigned */
if (IS_TRUE_SYMOP (op))
return NULL;
-
+
/* if this has register type condition and
the next instruction is ifx with the same operand
and live to of the operand is upto the ifx only then */
IC_COND (ic->next)->key == op->key &&
OP_SYMBOL (op)->liveTo <= ic->next->seq)
return ic->next;
-
+
return NULL;
}
isTrue=FALSE;
jlbl=IC_FALSE(ifx)->key+100;
}
-
+
if (!ifx) {
aopOp(IC_RESULT(ic), !aopIsPtr(left), TRUE);
jlbl=newiTempLabel(NULL)->key+100;
sym_link *retype = getSpec (type);
iCode *lic = ic->next;
int isize ;
-
+
/* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
if (!IS_SYMOP(op)) return NULL;
/* if operand of the form op = op + <sizeof *op> */
if (lic->op == '+') {
if (isOperandEqual(IC_LEFT(lic),op) &&
- //isOperandEqual(IC_RESULT(lic),op) &&
- isOperandLiteral(IC_RIGHT(lic)) &&
- operandLitValue(IC_RIGHT(lic)) == isize) {
- emitcode (";", "Found hasInc");
- return lic;
+ //isOperandEqual(IC_RESULT(lic),op) &&
+ isOperandLiteral(IC_RIGHT(lic)) &&
+ operandLitValue(IC_RIGHT(lic)) == isize) {
+ emitcode (";", "Found hasInc");
+ return lic;
}
}
/* if the operand used or deffed */
right = left;
left = tmp;
}
-
+
if (aopIsBit(result)) {
if (IS_LITERAL(operandType(right))) {
if (operandLitValue(right)) {
- emitcode ("setb", AOP_NAME(result)[0]);
- return;
+ emitcode ("setb", AOP_NAME(result)[0]);
+ return;
}
aopOp(left, TRUE, TRUE);
emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
return;
}
}
-
+
aopOp(left, !aopIsPtr(result), !aopIsDir(result));
aopOp(right, !aopIsPtr(result), !aopIsDir(result));
static void genInline (iCode * ic) {
printIc (0, "genInline", ic, 0,0,0);
-
+
emitcode ("", IC_INLINE(ic));
}
}
if (size>2) {
if (pi) {
- emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+ emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
} else {
- emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+ emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
}
}
emitcode ("br", "%05d$", tlbl2->key+100);
}
if (size>2) {
if (pi) {
- emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+ emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
} else {
- emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1]);
+ emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1]);
}
}
emitcode ("", "%05d$:", tlbl2->key+100);
return;
}
- switch (AOP_TYPE(left))
+ switch (AOP_TYPE(left))
{
case AOP_LIT:
emitcode("mov","r1,%s", AOP_NAME(left)[0]);
// fall through
case AOP_REG:
if (size>1) {
- if (codePointer) {
- instr=MOVCW;
- } else {
- instr=MOVW;
- }
- scratchReg=R1;
+ if (codePointer) {
+ instr=MOVCW;
+ } else {
+ instr=MOVW;
+ }
+ scratchReg=R1;
} else {
- if (codePointer) {
- instr=MOVCB;
- } else {
- instr=MOVB;
- }
- scratchReg=R1L;
+ if (codePointer) {
+ instr=MOVCB;
+ } else {
+ instr=MOVB;
+ }
+ scratchReg=R1L;
}
if (AOP_TYPE(result)==AOP_STK) {
- emitcode (MOV, "%s,[%s]", scratchReg, AOP_NAME(left)[0]);
- emitcode (MOV, "%s,%s", AOP_NAME(result)[0], scratchReg);
+ emitcode (MOV, "%s,[%s]", scratchReg, AOP_NAME(left)[0]);
+ emitcode (MOV, "%s,%s", AOP_NAME(result)[0], scratchReg);
} else {
- if (pi) {
- emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0],
- AOP_NAME(left)[0]);
- pi->generated=1;
- } else {
- if (codePointer) {
- emitcode (MOV, "r1,%s", AOP_NAME(left)[0]);
- emitcode (instr, "%s,[r1+]", AOP_NAME(result)[0]);
- } else {
- emitcode (instr, "%s,[%s]", AOP_NAME(result)[0],
- AOP_NAME(left)[0]);
- }
- }
+ if (pi) {
+ emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0],
+ AOP_NAME(left)[0]);
+ pi->generated=1;
+ } else {
+ if (codePointer) {
+ emitcode (MOV, "r1,%s", AOP_NAME(left)[0]);
+ emitcode (instr, "%s,[r1+]", AOP_NAME(result)[0]);
+ } else {
+ emitcode (instr, "%s,[%s]", AOP_NAME(result)[0],
+ AOP_NAME(left)[0]);
+ }
+ }
}
if (size > 2) {
- if (size==3) {
- if (codePointer) {
- instr=MOVCB;
- } else {
- instr=MOVB;
- }
- scratchReg=R1L;
- }
- if (AOP_TYPE(result)==AOP_STK) {
- emitcode (MOV, "%s,[%s+2]", scratchReg, AOP_NAME(left)[0]);
- emitcode (MOV, "%s,%s", AOP_NAME(result)[1], scratchReg);
- } else {
- if (pi) {
- emitcode (instr, "%s,[%s+]", AOP_NAME(result)[1],
- AOP_NAME(left)[0]);
- } else {
- if (codePointer) {
- emitcode (instr, "%s,[r1]", AOP_NAME(result)[1]);
- } else {
- emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1],
- AOP_NAME(left)[0]);
- }
- }
- }
+ if (size==3) {
+ if (codePointer) {
+ instr=MOVCB;
+ } else {
+ instr=MOVB;
+ }
+ scratchReg=R1L;
+ }
+ if (AOP_TYPE(result)==AOP_STK) {
+ emitcode (MOV, "%s,[%s+2]", scratchReg, AOP_NAME(left)[0]);
+ emitcode (MOV, "%s,%s", AOP_NAME(result)[1], scratchReg);
+ } else {
+ if (pi) {
+ emitcode (instr, "%s,[%s+]", AOP_NAME(result)[1],
+ AOP_NAME(left)[0]);
+ } else {
+ if (codePointer) {
+ emitcode (instr, "%s,[r1]", AOP_NAME(result)[1]);
+ } else {
+ emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1],
+ AOP_NAME(left)[0]);
+ }
+ }
+ }
}
return;
}
size=aopOp(right,FALSE, FALSE);
if (IS_GENPTR(operandType(result))) {
- emitcode (";", "INLINE\t_gptrset ; [%s %s] = %s %s",
- AOP_NAME(result)[0], AOP_NAME(result)[1],
- AOP_NAME(right)[0], AOP_NAME(right)[1]);
+ emitcode (";", "INLINE\t_gptrset ; [%s %s] = %s %s",
+ AOP_NAME(result)[0], AOP_NAME(result)[1],
+ AOP_NAME(right)[0], AOP_NAME(right)[1]);
return;
}
- switch (AOP_TYPE(right))
+ switch (AOP_TYPE(right))
{
case AOP_LIT:
case AOP_REG:
if (size>1) {
- instr=MOVW;
+ instr=MOVW;
} else {
- instr=MOVB;
+ instr=MOVB;
}
if (pi) {
- emitcode (instr, "[%s+],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
- pi->generated=1;
+ emitcode (instr, "[%s+],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ pi->generated=1;
} else {
- emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
}
if (size > 2) {
- if (size==3) {
- instr=MOVB;
- }
- if (pi) {
- emitcode (instr, "[%s+],%s", AOP_NAME(result)[0],
- AOP_NAME(right)[1]);
- } else {
- emitcode (instr, "[%s+2],%s", AOP_NAME(result)[0],
- AOP_NAME(right)[1]);
- }
+ if (size==3) {
+ instr=MOVB;
+ }
+ if (pi) {
+ emitcode (instr, "[%s+],%s", AOP_NAME(result)[0],
+ AOP_NAME(right)[1]);
+ } else {
+ emitcode (instr, "[%s+2],%s", AOP_NAME(result)[0],
+ AOP_NAME(right)[1]);
+ }
}
return;
}
symbol *jlbl, *tlbl=newiTempLabel(NULL);
operand *cond=IC_COND(ic);
- emitcode (";", "genIfx(%d) cond=%s trueLabel:%s falseLabel:%s",
- ic->lineno, printOp(cond),
- IC_TRUE(ic) ? IC_TRUE(ic)->name : "NULL",
- IC_FALSE(ic) ? IC_FALSE(ic)->name : "NULL");
+ emitcode (";", "genIfx(%d) cond=%s trueLabel:%s falseLabel:%s",
+ ic->lineno, printOp(cond),
+ IC_TRUE(ic) ? IC_TRUE(ic)->name : "NULL",
+ IC_FALSE(ic) ? IC_FALSE(ic)->name : "NULL");
size=aopOp(cond,TRUE,TRUE);
switch (AOP_TYPE(cond) )
{
case AOP_BIT:
- emitcode (trueOrFalse ? "jnb" : "jb", "%s,%05d$",
- AOP_NAME(cond)[0], tlbl->key+100);
+ emitcode (trueOrFalse ? "jnb" : "jb", "%s,%05d$",
+ AOP_NAME(cond)[0], tlbl->key+100);
emitcode ("jmp", "%05d$", jlbl->key+100);
emitcode ("", "%05d$:", tlbl->key+100);
return;
case AOP_FAR:
case AOP_STK:
if (size>1) {
- instr="cmp.w";
+ instr="cmp.w";
} else {
- instr="cmp.b";
+ instr="cmp.b";
}
emitcode (instr, "%s,#0", AOP_NAME(cond)[0]);
emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
if (size > 2) {
- if (size==3) {
- // generic pointer, forget the generic part
- } else {
- emitcode (instr, "%s,#0", AOP_NAME(cond)[1]);
- emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
- }
+ if (size==3) {
+ // generic pointer, forget the generic part
+ } else {
+ emitcode (instr, "%s,#0", AOP_NAME(cond)[1]);
+ emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
+ }
}
emitcode ("jmp", "%05d$", jlbl->key+100);
emitcode ("", "%05d$:", tlbl->key+100);
if (isOperandOnStack(left)) {
emitcode ("lea", "%s,%s", AOP_NAME(IC_RESULT(ic))[0],
- getStackOffset(OP_SYMBOL(left)->stack));
+ getStackOffset(OP_SYMBOL(left)->stack));
if (size > 2) {
// this must be a generic pointer
emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
isOperandInFarSpace(left) ||
isOperandInCodeSpace(left)) {
emitcode ("mov.w", "%s,#%s", AOP_NAME(IC_RESULT(ic))[0],
- OP_SYMBOL(left)->rname);
+ OP_SYMBOL(left)->rname);
if (size > 2) {
// this must be a generic pointer
int space=0; // dir space
if (isOperandInFarSpace(left)) {
- space=1;
+ space=1;
} else if (isOperandInCodeSpace(left)) {
- space=2;
+ space=2;
}
emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], space);
}
char *instr;
printIc (0, "genAssign", ic, 1,0,1);
-
+
if (!IS_SYMOP(result)) {
bailOut("genAssign: result is not a symbol");
}
-
+
aopOp(result, TRUE, TRUE);
aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
size=AOP_SIZE(result);
/* if right is literal, we know what the value is */
if (AOP_TYPE(right) == AOP_LIT) {
if (operandLitValue(right)) {
- emitcode ("setb", AOP_NAME(result)[0]);
+ emitcode ("setb", AOP_NAME(result)[0]);
} else {
- emitcode ("clr", AOP_NAME(result)[0]);
+ emitcode ("clr", AOP_NAME(result)[0]);
}
return;
}
aopOp(result, TRUE, TRUE);
aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
size=AOP_SIZE(result);
-
+
/* if result is a bit */
if (AOP_TYPE(result) == AOP_BIT) {
/* if right is literal, we know what the value is */
if (AOP_TYPE(right) == AOP_LIT) {
if (operandLitValue(right)) {
- emitcode ("setb", AOP_NAME(result)[0]);
+ emitcode ("setb", AOP_NAME(result)[0]);
} else {
- emitcode ("clr", AOP_NAME(result)[0]);
+ emitcode ("clr", AOP_NAME(result)[0]);
}
return;
}
emitcode ("sext", "r1h");
emitcode ("mov", "%s,r1", AOP_NAME(result)[0]);
}
-
+
/* if pointer to generic pointer */
if (IS_GENPTR (ctype)) {
-
+
if (IS_GENPTR (rtype)) {
- bailOut("genCast: gptr -> gptr");
+ bailOut("genCast: gptr -> gptr");
}
if (IS_PTR (rtype)) {
- ptrType = DCL_TYPE (rtype);
+ ptrType = DCL_TYPE (rtype);
} else {
- /* we have to go by the storage class */
- if (!SPEC_OCLS(etype)) {
- ptrType=0; // hush the compiler
- bailOut("genCast: unknown storage class");
- } else {
- ptrType = PTR_TYPE (SPEC_OCLS (etype));
- }
+ /* we have to go by the storage class */
+ if (!SPEC_OCLS(etype)) {
+ ptrType=0; // hush the compiler
+ bailOut("genCast: unknown storage class");
+ } else {
+ ptrType = PTR_TYPE (SPEC_OCLS (etype));
+ }
}
-
+
/* the generic part depends on the type */
switch (ptrType)
- {
- case POINTER:
- emitcode ("mov.b", "%s,#0x00", AOP_NAME(result)[1]);
- break;
- case FPOINTER:
- emitcode ("mov.b", "%s,#0x01", AOP_NAME(result)[1]);
- break;
- case CPOINTER:
- emitcode ("mov.b", "%s,#0x02", AOP_NAME(result)[1]);
- break;
- default:
- bailOut("genCast: got unknown storage class");
- }
+ {
+ case POINTER:
+ emitcode ("mov.b", "%s,#0x00", AOP_NAME(result)[1]);
+ break;
+ case FPOINTER:
+ emitcode ("mov.b", "%s,#0x01", AOP_NAME(result)[1]);
+ break;
+ case CPOINTER:
+ emitcode ("mov.b", "%s,#0x02", AOP_NAME(result)[1]);
+ break;
+ default:
+ bailOut("genCast: got unknown storage class");
+ }
}
return;
}
case 0x42:
emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
if (signedness) {
- emitcode("sext", "%s", AOP_NAME(result)[1]);
+ emitcode("sext", "%s", AOP_NAME(result)[1]);
} else {
- emitcode("mov", "%s,#0", AOP_NAME(result)[1]);
+ emitcode("mov", "%s,#0", AOP_NAME(result)[1]);
}
return;
case 0x41:
case 0x21:
emitcode("mov", "r1l,%s", AOP_NAME(right)[0]);
if (signedness) {
- emitcode("sext", "r1h");
+ emitcode("sext", "r1h");
} else {
- emitcode("mov", "r1h,#0");
+ emitcode("mov", "r1h,#0");
}
emitcode("mov", "%s,r1", AOP_NAME(result)[0]);
if (size==2)
- return;
+ return;
// fall through: case 0x41
if (signedness) {
- emitcode("sext", "r1");
+ emitcode("sext", "r1");
} else {
- emitcode("mov", "r1,#0");
+ emitcode("mov", "r1,#0");
}
emitcode("mov", "%s,r1", AOP_NAME(result)[1]);
return;
return;
}
fprintf(stderr, "genCast: unknown size: %d:%d\n",
- AOP_SIZE(result), AOP_SIZE(right));
+ AOP_SIZE(result), AOP_SIZE(right));
bailOut("genCast: unknown size");
}
for (ic = lic; ic; ic = ic->next) {
if (ic->lineno && cln != ic->lineno) {
if (options.debug) {
- debugFile->writeCLine (ic);
+ debugFile->writeCLine (ic);
}
if (!options.noCcodeInAsm) {
- emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
- printCLine(ic->filename, ic->lineno));
+ emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
+ printCLine(ic->filename, ic->lineno));
}
cln = ic->lineno;
}
if (options.iCodeInAsm) {
- char *iLine = printILine(ic);
+ const char *iLine = printILine(ic);
emitcode("", ";ic:%d: %s", ic->key, iLine);
dbuf_free(iLine);
}
switch (ic->op)
{
case '!':
- genNot (ic);
- break;
+ genNot (ic);
+ break;
case '~':
- genCpl (ic);
- break;
+ genCpl (ic);
+ break;
case UNARYMINUS:
- genUminus (ic);
- break;
-
+ genUminus (ic);
+ break;
+
case IPUSH:
- genIpush (ic);
- break;
-
+ genIpush (ic);
+ 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);
- break;
-
+ /* 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);
+ break;
+
case CALL:
- genCall (ic);
- break;
-
+ genCall (ic);
+ break;
+
case PCALL:
- genPcall (ic);
- break;
-
+ genPcall (ic);
+ break;
+
case FUNCTION:
- genFunction (ic);
- break;
-
+ genFunction (ic);
+ break;
+
case ENDFUNCTION:
- genEndFunction (ic);
- break;
-
+ genEndFunction (ic);
+ break;
+
case RETURN:
- genRet (ic);
- break;
-
+ genRet (ic);
+ break;
+
case LABEL:
- genLabel (ic);
- break;
-
+ genLabel (ic);
+ break;
+
case GOTO:
- genGoto (ic);
- break;
-
+ genGoto (ic);
+ break;
+
case '+':
- genPlus (ic);
- break;
-
+ genPlus (ic);
+ break;
+
case '-':
- if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
- genMinus (ic);
- break;
-
+ if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
+ genMinus (ic);
+ break;
+
case '*':
- genMult (ic);
- break;
-
+ genMult (ic);
+ break;
+
case '/':
- genDiv (ic);
- break;
-
+ genDiv (ic);
+ break;
+
case '%':
- genMod (ic);
- break;
-
+ genMod (ic);
+ break;
+
case '>':
- genCmpGt (ic);
- break;
-
+ genCmpGt (ic);
+ break;
+
case '<':
- genCmpLt (ic);
- break;
-
+ genCmpLt (ic);
+ break;
+
case LE_OP:
case GE_OP:
case NE_OP:
- /* note these two are xlated by algebraic equivalence
- during parsing SDCC.y */
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "got '>=' or '<=' shouldn't have come here");
- break;
+ /* note these two are xlated by algebraic equivalence
+ during parsing SDCC.y */
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "got '>=' or '<=' shouldn't have come here");
+ break;
case EQ_OP:
- genCmpEq (ic);
- break;
-
+ genCmpEq (ic);
+ break;
+
case AND_OP:
- genAndOp (ic);
- break;
-
+ genAndOp (ic);
+ break;
+
case OR_OP:
- genOrOp (ic);
- break;
-
+ genOrOp (ic);
+ break;
+
case '^':
- genXor (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
+ genXor (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
case '|':
- genOr (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
+ genOr (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
case BITWISEAND:
- genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
+ genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
case INLINEASM:
- genInline (ic);
- break;
-
+ genInline (ic);
+ break;
+
case RRC:
- genRRC (ic);
- break;
-
+ genRRC (ic);
+ break;
+
case RLC:
- genRLC (ic);
- break;
+ genRLC (ic);
+ break;
case GETHBIT:
- genGetHbit (ic);
- break;
-
+ genGetHbit (ic);
+ break;
+
case LEFT_OP:
- genLeftShift (ic);
- break;
-
+ genLeftShift (ic);
+ break;
+
case RIGHT_OP:
- genRightShift (ic);
- break;
-
+ genRightShift (ic);
+ break;
+
case GET_VALUE_AT_ADDRESS:
- genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_RESULT(ic)))));
- break;
-
+ genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_RESULT(ic)))));
+ break;
+
case '=':
- if (POINTER_SET (ic))
- genPointerSet (ic, hasInc(IC_RESULT(ic), ic, getSize(operandType(IC_RIGHT(ic)))));
- else
- genAssign (ic);
- break;
-
+ if (POINTER_SET (ic))
+ genPointerSet (ic, hasInc(IC_RESULT(ic), ic, getSize(operandType(IC_RIGHT(ic)))));
+ else
+ genAssign (ic);
+ break;
+
case IFX:
- genIfx (ic, NULL);
- break;
-
+ genIfx (ic, NULL);
+ break;
+
case ADDRESS_OF:
- genAddrOf (ic);
- break;
-
+ genAddrOf (ic);
+ break;
+
case JUMPTABLE:
- genJumpTab (ic);
- break;
-
+ genJumpTab (ic);
+ break;
+
case CAST:
- genCast (ic);
- break;
-
+ genCast (ic);
+ break;
+
case RECEIVE:
- genReceive (ic);
- break;
+ genReceive (ic);
+ break;
case SEND:
- addSet (&_G.sendSet, ic);
- break;
+ addSet (&_G.sendSet, ic);
+ break;
case DUMMY_READ_VOLATILE:
- genDummyRead (ic);
- break;
+ genDummyRead (ic);
+ break;
default:
- ic = ic;
+ ic = ic;
}
}
NULL
};
-/* rewinds declared in asm.c, function printCLine().
+/* rewinds declared in SDCCasm.c, function printCLine().
* Currently commented out.
*
* extern int rewinds;
void xa51_assignRegisters (ebbIndex *);
-static int regParmFlg = 0; /* determine if we can register a parameter */
+static int regParmFlg = 0; /* determine if we can register a parameter */
static void
_xa51_init (void)
/* Generate code to copy XINIT to XISEG */
static void _xa51_genXINIT (FILE * of) {
- fprintf (of, "; _xa51_genXINIT() start\n");
- fprintf (of, " mov r0,#l_XINIT\n");
- fprintf (of, " beq 00002$\n");
- fprintf (of, " mov r1,#s_XINIT\n");
+ fprintf (of, "; _xa51_genXINIT() start\n");
+ fprintf (of, " mov r0,#l_XINIT\n");
+ fprintf (of, " beq 00002$\n");
+ fprintf (of, " mov r1,#s_XINIT\n");
fprintf (of, " mov r2,#s_XISEG\n");
fprintf (of, "00001$: movc r3l,[r1+]\n");
fprintf (of, " mov [r2+],r3l\n");
fprintf (of, " djnz r0,00001$\n");
fprintf (of, "00002$:\n");
- fprintf (of, "; _xa51_genXINIT() end\n");
+ fprintf (of, "; _xa51_genXINIT() end\n");
}
static void
/* if it is a pointer then return ok for now */
if (IC_RESULT(ic) && IS_PTR(result_type)) return 1;
-
- /* if bitwise | add & subtract then no since xa51 is pretty good at it
+
+ /* if bitwise | add & subtract then no since xa51 is pretty good at it
so we will cse only if they are local (i.e. both ic & pdic belong to
the same basic block */
if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') {
- /* then if they are the same Basic block then ok */
- if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
- else return 0;
+ /* then if they are the same Basic block then ok */
+ if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
+ else return 0;
}
-
+
/* for others it is cheaper to do the cse */
return 1;
}
{
if (IN_FARSPACE(oclass))
return 1;
-
+
return 0;
}
{
TARGET_ID_XA51,
"xa51",
- "MCU 80C51XA", /* Target name */
- NULL, /* Processor name */
+ "MCU 80C51XA", /* Target name */
+ NULL, /* Processor name */
{
glue,
- FALSE, /* Emit glue around main */
+ FALSE, /* Emit glue around main */
MODEL_PAGE0,
MODEL_PAGE0
},
{
_asmCmd,
NULL,
- "", /* Options with debug */
- "", /* Options without debug */
+ "", /* Options with debug */
+ "", /* Options without debug */
0,
".asm",
- NULL /* no do_assemble function */
+ NULL /* no do_assemble function */
},
{
_linkCmd,
_defaultRules
},
{
- /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
+ /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
1, 2, 2, 4, 2, 2, 3, 1, 4, 4
},
/* tags for generic pointers */
- { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
+ { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
{
"XSEG (XDATA)",
"STACK (XDATA)",
"HOME (CODE)",
"XISEG (XDATA)", // initialized xdata
"XINIT (CODE)", // a code copy of xiseg
- "CONST (CODE)", // const_name - const data (code or not)
- "CABS (ABS,CODE)", // cabs_name - const absolute data (code or not)
- "XABS (ABS,XDATA)", // xabs_name - absolute xdata
- "IABS (ABS,DATA)", // iabs_name - absolute data
+ "CONST (CODE)", // const_name - const data (code or not)
+ "CABS (ABS,CODE)", // cabs_name - const absolute data (code or not)
+ "XABS (ABS,XDATA)", // xabs_name - absolute xdata
+ "IABS (ABS,DATA)", // iabs_name - absolute data
NULL, // default local map
NULL, // default global map
1
_xa51_genAssemblerEnd,
_xa51_genIVT,
_xa51_genXINIT,
- NULL, /* genInitStartup */
+ NULL, /* genInitStartup */
_xa51_reset_regparm,
_xa51_regparm,
NULL, // process_pragma()
NULL, // getMangledFunctionName()
NULL, // hasNativeMulFor()
- hasExtBitOp, /* hasExtBitOp */
- oclsExpense, /* oclsExpense */
+ hasExtBitOp, /* hasExtBitOp */
+ oclsExpense, /* oclsExpense */
TRUE, // use_dw_for_init
- TRUE, /* little endian */
- 0, /* leave lt */
- 0, /* leave gt */
- 1, /* transform <= to ! > */
- 1, /* transform >= to ! < */
- 1, /* transform != to !(a == b) */
- 0, /* leave == */
+ TRUE, /* little endian */
+ 0, /* leave lt */
+ 0, /* leave gt */
+ 1, /* transform <= to ! > */
+ 1, /* transform >= to ! < */
+ 1, /* transform != to !(a == b) */
+ 0, /* leave == */
FALSE, /* No array initializer support. */
cseCostEstimation,
- NULL, /* no builtin functions */
- GPOINTER, /* treat unqualified pointers as "generic" pointers */
- 1, /* reset labelKey to 1 */
- 1, /* globals & local static allowed */
+ NULL, /* no builtin functions */
+ GPOINTER, /* treat unqualified pointers as "generic" pointers */
+ 1, /* reset labelKey to 1 */
+ 1, /* globals & local static allowed */
PORT_MAGIC
};
}
if (options.iCodeInAsm)
{
- char *iLine = printILine(ic);
+ const char *iLine = printILine(ic);
emit2 (";ic:%d: %s", ic->key, iLine);
dbuf_free(iLine);
}
/*
dbuf_string.c - Append formatted string to the dynamic buffer
- version 1.0.0, January 6th, 2007
+ version 1.1.0, December 29th, 2007
Copyright (c) 2002-2007 Borut Razem
*/
int
-dbuf_append_str(struct dbuf_s *dbuf, const char *str)
+dbuf_append_str (struct dbuf_s *dbuf, const char *str)
{
- assert(str != NULL);
+ assert (str != NULL);
- return dbuf_append(dbuf, str, strlen(str));
+ return dbuf_append (dbuf, str, strlen(str));
}
*/
int
-dbuf_append_char(struct dbuf_s *dbuf, char chr)
+dbuf_append_char (struct dbuf_s *dbuf, char chr)
{
- return dbuf_append(dbuf, &chr, 1);
+ return dbuf_append (dbuf, &chr, 1);
}
/*
while (*p != '\0')
{
if (*p++ == '%')
- {
- while (strchr ("-+ #0", *p))
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- if (*p == '.')
- {
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- }
- while (strchr ("hlL", *p))
- ++p;
- /* Should be big enough for any format specifier except %s and floats. */
- total_width += 30;
- switch (*p)
- {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'c':
- (void) va_arg (ap, int);
- break;
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- (void) va_arg (ap, double);
- /* Since an ieee double can have an exponent of 307, we'll
- make the buffer wide enough to cover the gross case. */
- total_width += 307;
- break;
- case 's':
- total_width += strlen (va_arg (ap, char *));
- break;
- case 'p':
- case 'n':
- (void) va_arg (ap, char *);
- break;
- }
- p++;
- }
+ {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, (char **) &p, 10);
+ if (*p == '.')
+ {
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, (char **) &p, 10);
+ }
+ while (strchr ("hlL", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s and floats. */
+ total_width += 30;
+ switch (*p)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ (void) va_arg (ap, int);
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ (void) va_arg (ap, double);
+ /* Since an ieee double can have an exponent of 307, we'll
+ make the buffer wide enough to cover the gross case. */
+ total_width += 307;
+ break;
+ case 's':
+ total_width += strlen (va_arg (ap, char *));
+ break;
+ case 'p':
+ case 'n':
+ (void) va_arg (ap, char *);
+ break;
+ }
+ p++;
+ }
}
#ifdef va_copy
va_end (ap);
{
int size = calc_result_length (format, args);
- assert(dbuf != NULL);
- assert(dbuf->alloc != 0);
- assert(dbuf->buf != NULL);
+ assert (dbuf != NULL);
+ assert (dbuf->alloc != 0);
+ assert (dbuf->buf != NULL);
- if (_dbuf_expand(dbuf, size) != 0) {
- int len = vsprintf(&(((char *)dbuf->buf)[dbuf->len]), format, args);
-
- if (len >= 0) {
- /* if written length is greater then the calculated one,
- we have a buffer overrun! */
- assert(len <= size);
- dbuf->len += len;
+ if (0 != _dbuf_expand (dbuf, size))
+ {
+ int len = vsprintf (&(((char *)dbuf->buf)[dbuf->len]), format, args);
+
+ if (len >= 0)
+ {
+ /* if written length is greater then the calculated one,
+ we have a buffer overrun! */
+ assert (len <= size);
+ dbuf->len += len;
+ }
+ return len;
}
- return len;
- }
return 0;
}
int len;
va_start (arg, format);
- len = dbuf_vprintf(dbuf, format, arg);
+ len = dbuf_vprintf (dbuf, format, arg);
va_end (arg);
return len;
}
+/*
+ * Append line from file to the dynamic buffer
+ */
+
+size_t
+dbuf_getline (struct dbuf_s *dbuf, FILE *infp)
+{
+ int c;
+ char chr;
+
+ while ((c = getc (infp)) != '\n' && c != EOF)
+ {
+ chr = c;
+
+ dbuf_append (dbuf, &chr, 1);
+ }
+
+ /* add trailing NL */
+ if (c == '\n')
+ {
+ chr = c;
+
+ dbuf_append (dbuf, &chr, 1);
+ }
+
+ /* terminate the line without increasing the length */
+ if (0 != _dbuf_expand (dbuf, 1))
+ ((char *)dbuf->buf)[dbuf->len] = '\0';
+
+ return dbuf_get_length (dbuf);
+}
+
+
/*
* Write dynamic buffer to the file.
*/
void
dbuf_write (struct dbuf_s *dbuf, FILE *dest)
{
- fwrite(dbuf_get_buf(dbuf), 1, dbuf_get_length(dbuf), dest);
+ fwrite (dbuf_get_buf (dbuf), 1, dbuf_get_length (dbuf), dest);
}
{
dbuf_write (dbuf, dest);
- dbuf_destroy(dbuf);
+ dbuf_destroy (dbuf);
}
/*
dbuf_string.h - Append formatted string to the dynamic buffer
- version 1.0.0, January 6th, 2007
+ version 1.1.0, December 29th, 2007
Copyright (c) 2002-2007 Borut Razem
int dbuf_append_char(struct dbuf_s *dbuf, char chr);
int dbuf_vprintf(struct dbuf_s *dbuf, const char *format, va_list args);
int dbuf_printf (struct dbuf_s *dbuf, const char *format, ...) ATTRIBUTE_PRINTF(2, 3);
+size_t dbuf_getline(struct dbuf_s *dbuf, FILE *infp);
void dbuf_write (struct dbuf_s *dbuf, FILE *dest);
void dbuf_write_and_destroy (struct dbuf_s *dbuf, FILE *dest);