/* newValue - allocates and returns a new value */
/*-----------------------------------------------------------------*/
value *
-newValue ()
+newValue (void)
{
value *val;
/* constFloatVal - converts a FLOAT constant to value */
/*-----------------------------------------------------------------*/
value *
-constFloatVal (char *s)
+constFloatVal (const char *s)
{
value *val = newValue ();
double sval;
if (p == s)
{
werror (E_INVALID_FLOAT_CONST, s);
- return constVal ("0");
+ return constCharVal (0);
}
val->type = val->etype = newLink (SPECIFIER);
/* constFixed16x16Val - converts a FIXED16X16 constant to value */
/*-----------------------------------------------------------------*/
value *
-constFixed16x16Val (char *s)
+constFixed16x16Val (const char *s)
{
value *val = newValue ();
double sval;
if (p == s)
{
werror (E_INVALID_FLOAT_CONST, s);
- return constVal ("0");
+ return constCharVal (0);
}
val->type = val->etype = newLink (SPECIFIER);
value *constVal (const char *s)
{
value *val;
- short hex = 0, octal = 0;
+ bool hex = FALSE, octal = FALSE;
+ char *p;
double dval;
val = newValue (); /* alloc space for value */
SPEC_NOUN (val->type) = V_CHAR;
SPEC_USIGN (val->type) = 0;
- hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
-
- /* set the octal flag */
- if (!hex && *s == '0' && *(s + 1))
- octal = 1;
+ if (s[0] == '0')
+ {
+ if (s[1] == 'x' || s[1] == 'X')
+ hex = TRUE;
+ else if (isdigit(s[1]))
+ octal = TRUE;
+ }
errno = 0;
- if (hex || octal) {
- unsigned long sval;
- sval = strtoul (s, NULL, 0);
- dval = sval;
- if (errno) {
- dval = 4294967295.0;
- werror (W_INVALID_INT_CONST, s, dval);
+ if (hex || octal)
+ {
+ dval = strtoul (s, &p, 0);
+ if (errno)
+ {
+ dval = 4294967295.0;
+ werror (W_INVALID_INT_CONST, s, dval);
+ }
+ }
+ else
+ {
+ dval = strtod(s, &p);
}
- } else {
- dval = strtod(s, NULL);
- }
/* Setup the flags first */
/* set the unsigned flag if 'uU' is found */
- if (strchr (s, 'u') || strchr (s, 'U')) {
- SPEC_USIGN (val->type) = 1;
- }
+ if (strchr (p, 'u') || strchr (p, 'U'))
+ {
+ SPEC_USIGN (val->type) = 1;
+ }
/* set the b_long flag if 'lL' is found */
- if (strchr (s, 'l') || strchr (s, 'L')) {
- SPEC_NOUN (val->type) = V_INT;
- SPEC_LONG (val->type) = 1;
- } else {
- if (dval<0) { /* "-28u" will still be signed and negative */
- if (dval<-128) { /* check if we have to promote to int */
- SPEC_NOUN (val->type) = V_INT;
- }
- if (dval<-32768) { /* check if we have to promote to long int */
- SPEC_LONG (val->type) = 1;
- }
- } else { /* >=0 */
- if (dval>0xff || /* check if we have to promote to int */
- SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
- char. After an integral promotion it will
- be a signed int; this certainly isn't what
- the programer wants */
- SPEC_NOUN (val->type) = V_INT;
- }
- else { /* store char's always as unsigned; this helps other optimizations */
- SPEC_USIGN (val->type) = 1;
- }
- if (dval>0xffff && SPEC_USIGN (val->type)) { /* check if we have to promote to long */
- SPEC_LONG (val->type) = 1;
- }
- else if (dval>0x7fff && !SPEC_USIGN (val->type)) { /* check if we have to promote to long int */
- if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
- dval<=0xffff) {
- SPEC_USIGN (val->type) = 1;
- } else {
- SPEC_LONG (val->type) = 1;
- if (dval>0x7fffffff) {
- SPEC_USIGN (val->type) = 1;
- }
+ if (strchr (p, 'l') || strchr (p, 'L'))
+ {
+ SPEC_NOUN (val->type) = V_INT;
+ SPEC_LONG (val->type) = 1;
+ }
+ else
+ {
+ if (dval < 0)
+ { /* "-28u" will still be signed and negative */
+ if (dval < -128)
+ { /* check if we have to promote to int */
+ SPEC_NOUN (val->type) = V_INT;
+ }
+ if (dval < -32768)
+ { /* check if we have to promote to long int */
+ SPEC_LONG (val->type) = 1;
+ }
+ }
+ else
+ { /* >=0 */
+ if (dval > 0xff || /* check if we have to promote to int */
+ SPEC_USIGN (val->type))
+ { /* if it's unsigned, we can't use unsigned
+ char. After an integral promotion it will
+ be a signed int; this certainly isn't what
+ the programer wants */
+ SPEC_NOUN (val->type) = V_INT;
+ }
+ else
+ { /* store char's always as unsigned; this helps other optimizations */
+ SPEC_USIGN (val->type) = 1;
+ }
+ if (dval > 0xffff && SPEC_USIGN (val->type))
+ { /* check if we have to promote to long */
+ SPEC_LONG (val->type) = 1;
+ }
+ else if (dval > 0x7fff && !SPEC_USIGN (val->type))
+ { /* check if we have to promote to long int */
+ if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
+ dval <= 0xffff)
+ {
+ SPEC_USIGN (val->type) = 1;
+ }
+ else
+ {
+ SPEC_LONG (val->type) = 1;
+ if (dval > 0x7fffffff)
+ {
+ SPEC_USIGN (val->type) = 1;
+ }
+ }
+ }
}
- }
}
- }
/* check for out of range */
- if (dval<-2147483648.0) {
- dval = -2147483648.0;
- werror (W_INVALID_INT_CONST, s, dval);
- }
- if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
- dval = 2147483647.0;
- werror (W_INVALID_INT_CONST, s, dval);
- }
- if (dval>4294967295.0) {
- dval = 4294967295.0;
- werror (W_INVALID_INT_CONST, s, dval);
- }
+ if (dval < -2147483648.0)
+ {
+ dval = -2147483648.0;
+ werror (W_INVALID_INT_CONST, s, dval);
+ }
+ if (dval > 2147483647.0 && !SPEC_USIGN (val->type))
+ {
+ dval = 2147483647.0;
+ werror (W_INVALID_INT_CONST, s, dval);
+ }
+ if (dval > 4294967295.0)
+ {
+ dval = 4294967295.0;
+ werror (W_INVALID_INT_CONST, s, dval);
+ }
if (SPEC_LONG (val->type))
{
return val;
}
+value *constCharVal (unsigned char v)
+{
+ value *val = newValue (); /* alloc space for value */
+
+ val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
+ SPEC_SCLS (val->type) = S_LITERAL;
+ /* let's start with a signed char */
+ SPEC_NOUN (val->type) = V_CHAR;
+ SPEC_USIGN (val->type) = 1;
+ SPEC_CVAL (val->type).v_uint = v;
+
+ return val;
+}
+
/*------------------------------------------------------------------*/
/* strVal - converts a string constant to a value */
/*------------------------------------------------------------------*/
value *
charVal (const char *s)
{
- value *val;
-
- val = newValue ();
-
- val->type = val->etype = newLink (SPECIFIER);
- SPEC_NOUN (val->type) = V_CHAR;
- SPEC_USIGN(val->type) = 1;
- SPEC_SCLS (val->type) = S_LITERAL;
-
- s++; /* get rid of quotation */
+ /* get rid of quotation */
/* if \ then special processing */
- if (*s == '\\')
+ if (*++s == '\\')
{
- s++; /* go beyond the backslash */
- switch (*s)
+ switch (*++s) /* go beyond the backslash */
{
case 'n':
- SPEC_CVAL (val->type).v_uint = '\n';
- break;
+ return constCharVal ('\n');
case 't':
- SPEC_CVAL (val->type).v_uint = '\t';
- break;
+ return constCharVal ('\t');
case 'v':
- SPEC_CVAL (val->type).v_uint = '\v';
- break;
+ return constCharVal ('\v');
case 'b':
- SPEC_CVAL (val->type).v_uint = '\b';
- break;
+ return constCharVal ('\b');
case 'r':
- SPEC_CVAL (val->type).v_uint = '\r';
- break;
+ return constCharVal ('\r');
case 'f':
- SPEC_CVAL (val->type).v_uint = '\f';
- break;
+ return constCharVal ('\f');
case 'a':
- SPEC_CVAL (val->type).v_uint = '\a';
- break;
+ return constCharVal ('\a');
case '\\':
- SPEC_CVAL (val->type).v_uint = '\\';
- break;
+ return constCharVal ('\\');
case '\?':
- SPEC_CVAL (val->type).v_uint = '\?';
- break;
+ return constCharVal ('\?');
case '\'':
- SPEC_CVAL (val->type).v_uint = '\'';
- break;
+ return constCharVal ('\'');
case '\"':
- SPEC_CVAL (val->type).v_uint = '\"';
- break;
+ return constCharVal ('\"');
case '0' :
case '1' :
case '5' :
case '6' :
case '7' :
- SPEC_CVAL (val->type).v_uint = octalEscape(&s);
- break;
+ return constCharVal (octalEscape (&s));
case 'x':
- SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
- break;
+ return constCharVal (hexEscape (&s));
default:
- SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
- break;
+ return constCharVal (*s);
}
}
else /* not a backslash */
- SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
-
- return val;
+ return constCharVal (*s);
}
/*------------------------------------------------------------------*/
double tmp=0, exp=2;
tmp = (value & 0xffff0000) >> 16;
-
+
while(value) {
value &= 0xffff;
if(value & 0x8000)tmp += 1/exp;
exp *= 2;
value <<= 1;
}
-
+
return (tmp);
#else
return ((double)(value * 1.0) / (double)(1UL << 16));
tmp = floor( value );
res = tmp << 16;
value -= tmp;
-
+
tmp = 0;
while(pos--) {
value *= 2;
if(value >= 1.0)tmp |= (1 << pos);
value -= floor( value );
}
-
+
res |= tmp;
return (res);
float f;
unsigned char c[4];
} fl;
-
+
/* if it is a float then it gets tricky */
/* otherwise it is fairly simple */
if (!IS_FLOAT(val->type)) {
unsigned long v = ulFromVal (val);
-
+
return ( (v >> (offset * 8)) & 0xff);
}
-
+
/* it is type float */
fl.f = (float) floatFromVal(val);
#ifdef WORDS_BIGENDIAN
#else
return fl.c[offset];
#endif
-
+
}
#if 0
char a;
if (!name) return 0;
a = *name;
-
+
/* only accept [a-zA-Z_][a-zA-Z0-9_] */
if (!((a >= 'a' && a <= 'z')
|| (a >= 'A' && a <= 'z')
}
continue;
}
-
+
if (max == -1 || addr > max) max = addr;
if (min == -1 || addr < min) min = addr;
//fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
if (sym->ival) break;
} // for
if (sym) continue;
-
+
dbuf_printf (oBuf, "UD_abs_%s_%x\tudata_ovr\t0x%04x\n",
moduleName, addr, addr);
for (sym = setFirstItem (aliases); sym;
if (getSize(sym->type) > size) {
size = getSize(sym->type);
}
-
+
/* initialized values are handled somewhere else */
if (sym->ival) continue;
-
+
/* emit STATUS as well as _STATUS, required for SFRs only */
//dbuf_printf (oBuf, "%s\tres\t0\n", sym->name);
dbuf_printf (oBuf, "%s\n", sym->rname);
{
symbol *sym;
int bitvars = 0;;
-
+
/* print the area name */
if (addPublics)
dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
-
+
for (sym = setFirstItem (map->syms); sym;
sym = setNextItem (map->syms)) {
-
+
//printf("%s\n",sym->name);
/* ignore if config word */
if (SPEC_ABSA(sym->etype)
&& IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
continue;
-
+
/* if extern then add it into the extern list */
if (IS_EXTERN (sym->etype)) {
addSetHead (&externs, sym);
continue;
}
-
+
/* if allocation required check is needed
then check if the symbol really requires
allocation only for local variables */
!(sym->_isparm && !IS_REGPARM (sym->etype)) &&
!sym->allocreq && sym->level)
continue;
-
+
/* if global variable & not static or extern
and addPublics allowed then add it to the public set */
if ((sym->level == 0 ||
//fprintf( stderr, "%s: made public %s\n", __FUNCTION__, sym->name );
addSetHead (&publics, sym);
}
-
+
// PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs()
if (sym->_isparm)
continue;
/* absolute symbols are handled in pic14_constructAbsMap */
if (SPEC_ABSA(sym->etype) && IS_DEFINED_HERE(sym))
continue;
-
+
/* if it has an absolute address then generate
an equate for this no need to allocate space */
if (0 && SPEC_ABSA (sym->etype))
{
//if (options.debug || sym->level == 0)
//dbuf_printf (&map->oBuf,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
-
+
dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
sym->rname,
SPEC_ADDR (sym->etype));
else
{
/* allocate space */
-
+
/* If this is a bit variable, then allocate storage after 8 bits have been declared */
/* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
/* by grouping the bits together into groups of 8 and storing them in the normal ram. */
{
if (!sym->ival) {
emitSymbol (&map->oBuf,
- sym->rname,
+ sym->rname,
NULL,
getSize (sym->type) & 0xffff,
SPEC_ABSA(sym->etype)
/*
{
int i, size;
-
+
if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
{
for (i = 1; i < size; i++)
pic14_stringInSet(sym->name, &emitted, 1);
pic14_stringInSet(sym->rname, &emitted, 1);
}
-#if 0
+#if 0
/* if it has a initial value then do it only if
it is a global variable */
if (sym->ival && sym->level == 0) {
ast *ival = NULL;
-
+
if (IS_AGGREGATE (sym->type))
ival = initAggregates (sym, sym->ival, NULL);
else
/*-----------------------------------------------------------------*/
/* printIvalType - generates ival for int/char */
/*-----------------------------------------------------------------*/
-static void
+static void
printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
{
value *val;
unsigned long ulval;
-
+
//fprintf(stderr, "%s\n",__FUNCTION__);
-
+
/* if initList is deep */
if (ilist->type == INIT_DEEP)
ilist = ilist->init.deep;
-
+
if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
}
-
+
if (!(val = list2val (ilist))) {
// assuming a warning has been thrown
- val=constVal("0");
+ val = constCharVal (0);
}
-
+
if (val->type != type) {
val = valCastLiteral(type, floatFromVal(val));
}
-
- if(val)
+
+ if(val)
ulval = ulFromVal (val);
else
ulval =0;
-
+
switch (getSize (type)) {
case 1:
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
break;
-
+
case 2:
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
break;
-
+
case 4:
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
/*-----------------------------------------------------------------*/
/* printIvalBitFields - generate initializer for bitfields */
/*-----------------------------------------------------------------*/
-static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb )
+static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb )
{
value *val ;
symbol *lsym = *sym;
initList *lilist = *ilist ;
unsigned long ival = 0;
int size =0;
-
-
+
+
do {
unsigned long i;
val = list2val(lilist);
if (size) {
if (SPEC_BLEN(lsym->etype) > 8) {
- size += ((SPEC_BLEN (lsym->etype) / 8) +
+ size += ((SPEC_BLEN (lsym->etype) / 8) +
(SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
}
} else {
- size = ((SPEC_BLEN (lsym->etype) / 8) +
+ size = ((SPEC_BLEN (lsym->etype) / 8) +
(SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
}
i = ulFromVal (val);
//tfprintf (oFile, "\t!db !constbyte\n",ival);
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
break;
-
+
case 2:
//tfprintf (oFile, "\t!dw !constword\n",ival);
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
{
symbol *sflds;
initList *iloop = NULL;
-
+
sflds = SPEC_STRUCT (type)->fields;
-
+
if (ilist) {
if (ilist->type != INIT_DEEP) {
werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
return;
}
-
+
iloop = ilist->init.deep;
}
-
+
for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
if (IS_BITFIELD(sflds->type)) {
printIvalBitFields(&sflds,&iloop,pb);
/*-----------------------------------------------------------------*/
/* printIvalChar - generates initital value for character array */
/*-----------------------------------------------------------------*/
-static int
+static int
printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
{
value *val;
int remain, ilen;
-
+
if(!pb)
return 0;
-
+
//fprintf(stderr, "%s\n",__FUNCTION__);
if (!s)
{
-
+
val = list2val (ilist);
/* if the value is a character string */
if (!DCL_ELEM (type))
DCL_ELEM (type) = ilen;
-
+
/* emit string constant */
for (remain = 0; remain < ilen; remain++) {
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(SPEC_CVAL(val->etype).v_char[remain])));
}
-
+
/* fill array up to desired size */
if ((remain = (DCL_ELEM (type) - ilen)) > 0)
while (remain--)
}
else {
//printChar (oFile, s, strlen (s) + 1);
-
+
for(remain=0; remain<(int)strlen(s); remain++) {
addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
//fprintf(stderr,"0x%02x ",s[remain]);
/*-----------------------------------------------------------------*/
/* printIvalArray - generates code for array initialization */
/*-----------------------------------------------------------------*/
-static void
+static void
printIvalArray (symbol * sym, sym_link * type, initList * ilist,
pBlock *pb)
{
/*-----------------------------------------------------------------*/
extern value *initPointer (initList *, sym_link *toType);
-static void
+static void
printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
{
value *val;
-
+
if (!ilist || !pb)
return;
-
+
fprintf (stderr, "FIXME: initializers for pointers...\n");
printTypeChain (type, stderr);
-
+
fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
if (ilist && (ilist->type == INIT_DEEP))
ilist = ilist->init.deep;
-
+
/* function pointers */
if (IS_FUNC (type->next))
{
if (!(val = initPointer (ilist, type)))
return;
-
+
if (IS_CHAR (type->next))
{
if (printIvalChar (type, ilist, pb, NULL)) return;
/*-----------------------------------------------------------------*/
/* printIval - generates code for initial value */
/*-----------------------------------------------------------------*/
-static void
+static void
printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
{
if (!ilist || !pb)
return;
-
+
/* if structure then */
if (IS_STRUCT (type))
{
printIvalStruct (sym, type, ilist, pb);
return;
}
-
+
/* if this is an array */
if (IS_ARRAY (type))
{
printIvalArray (sym, type, ilist, pb);
return;
}
-
+
/* if this is a pointer */
if (IS_PTR (type))
{
printIvalPtr (sym, type, ilist, pb);
return;
}
-
+
/* if type is SPECIFIER */
if (IS_SPEC (type))
{
pic14emitStaticSeg (memmap * map)
{
symbol *sym;
-
+
dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
-
+
//fprintf(stderr, "%s\n",__FUNCTION__);
-
+
/* for all variables in this segment do */
for (sym = setFirstItem (map->syms); sym;
sym = setNextItem (map->syms))
addSetHead (&externs, sym);
continue;
}
-
+
/* if it is not static add it to the public
table */
if (!IS_STATIC (sym->etype))
addSetHead (&publics, sym);
-
+
/* print extra debug info if required */
if (options.debug || sym->level == 0)
{
dbuf_printf (&code->oBuf, "L%s_",
(sym->localof ? sym->localof->name : "-null-"));
dbuf_printf (&code->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
-
+
}
-
+
/* if it has an absolute address */
if (SPEC_ABSA (sym->etype))
{
if (options.debug || sym->level == 0)
dbuf_printf (&code->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
+
dbuf_printf (&code->oBuf, "%s\t=\t0x%04x\n",
sym->rname,
SPEC_ADDR (sym->etype));
{
if (options.debug || sym->level == 0)
dbuf_printf (&code->oBuf, " == .\n");
-
+
/* if it has an initial value */
if (sym->ival)
{
#if 0
pBlock *pb;
-
+
dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
noAlloc++;
resolveIvalSym (sym->ival, sym->type);
pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
addpBlock(pb);
addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
-
+
printIval (sym, sym->type, sym->ival, pb);
noAlloc--;
#endif
}
else
{
-
+
/* allocate space */
dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
/* special case for character strings */
}
}
}
-
+
}
#endif
{
mainf = newSymbol ("main", 0);
mainf->block = 0;
-
+
/* only if the main function exists */
if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
{
fprintf(stderr,"WARNING: function 'main' undefined\n");
return;
}
-
+
/* if the main is only a prototype ie. no body then do nothing */
if (!IFFUNC_HASBODY(mainf->type))
{
fprintf(stderr,"WARNING: function 'main' undefined\n");
return;
}
-
+
dbuf_printf (vBuf, "%s", iComments2);
dbuf_printf (vBuf, "; reset vector \n");
dbuf_printf (vBuf, "%s", iComments2);
initialComments (afile);
fprintf (afile, "; PIC port for the 14-bit core\n");
fprintf (afile, iComments2);
-
+
}
int
pic14printExterns (FILE * afile)
{
symbol *sym;
-
+
fprintf (afile, "%s", iComments2);
fprintf (afile, "; extern variables in this module\n");
fprintf (afile, "%s", iComments2);
-
+
for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
pic14_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
}
int
pic14_operandsAllocatedInSameBank(const char *str1, const char *str2) {
// see pic14printLocals
-
+
if (getenv("SDCC_PIC14_SPLIT_LOCALS")) {
// no clustering applied, each register resides in its own bank
} else {
pic14emitOverlay (struct dbuf_s * aBuf)
{
set *ovrset;
-
+
/* if (!elementsInSet (ovrSetSets))*/
-
+
/* the hack below, fixes translates for devices which
* only have udata_shr memory */
dbuf_printf (aBuf, "%s\t%s\n",
(elementsInSet(ovrSetSets)?"":";"),
port->mem.overlay_name);
-
+
/* for each of the sets in the overlay segment do */
for (ovrset = setFirstItem (ovrSetSets); ovrset;
ovrset = setNextItem (ovrSetSets))
{
-
+
symbol *sym;
-
+
if (elementsInSet (ovrset))
{
/* this dummy area is used to fool the assembler
otherwise the assembler will append each of these
declarations into one chunk and will not overlay
sad but true */
-
+
/* I don't think this applies to us. We are using gpasm. CRF */
-
+
dbuf_printf (aBuf, ";\t.area _DUMMY\n");
/* output the area informtion */
dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
}
-
+
for (sym = setFirstItem (ovrset); sym;
sym = setNextItem (ovrset))
{
-
+
/* if extern then do nothing */
if (IS_EXTERN (sym->etype))
continue;
-
+
/* if allocation required check is needed
then check if the symbol really requires
allocation only for local variables */
!(sym->_isparm && !IS_REGPARM (sym->etype))
&& !sym->allocreq && sym->level)
continue;
-
+
/* if global variable & not static or extern
and addPublics allowed then add it to the public set */
if ((sym->_isparm && !IS_REGPARM (sym->etype))
&& !IS_STATIC (sym->etype))
addSetHead (&publics, sym);
-
+
/* if extern then do nothing or is a function
then do nothing */
if (IS_FUNC (sym->type))
continue;
-
+
/* print extra debug info if required */
if (options.debug || sym->level == 0)
{
(sym->localof ? sym->localof->name : "-null-"));
dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
}
-
+
/* if is has an absolute address then generate
an equate for this no need to allocate space */
if (SPEC_ABSA (sym->etype))
{
-
+
if (options.debug || sym->level == 0)
dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
+
dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
sym->rname,
SPEC_ADDR (sym->etype));
{
if (options.debug || sym->level == 0)
dbuf_printf (aBuf, "==.\n");
-
+
/* allocate space */
dbuf_printf (aBuf, "%s:\n", sym->rname);
dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
}
-
+
}
}
}
// Note: Do NOT name this code_interrupt to avoid nameclashes with
// source files's code segment (interrupt.c -> code_interrupt)
fprintf (asmFile, "c_interrupt\t%s\t0x4\n", CODE_NAME);
-
+
/* interrupt service routine */
fprintf (asmFile, "__sdcc_interrupt\n");
copypCode(asmFile, 'I');
- }
+ }
}
/*-----------------------------------------------------------------*/
#if 0
if (mainf && IFFUNC_HASBODY(mainf->type)) {
-
+
pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
addpBlock(pb);
-
+
/* entry point @ start of CSEG */
addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
/* put in the call to main */
addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
-
+
if (options.mainreturn) {
-
+
addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
-
+
} else {
-
+
addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
-
+
}
}
-#endif
-
+#endif
+
/* At this point we've got all the code in the form of pCode structures */
/* Now it needs to be rearranged into the order it should be placed in the */
/* code space */
-
+
movepBlock2Head('P'); // Last
movepBlock2Head(code->dbName);
movepBlock2Head('X');
movepBlock2Head(statsg->dbName); // First
-
-
+
+
/* print the global struct definitions */
if (options.debug)
cdbStructBlock (0);
//pic14emitMaps ();
/* do the overlay segments */
pic14emitOverlay(&ovrBuf);
-
+
/* PENDING: this isnt the best place but it will do */
if (port->general.glue_up_main) {
/* create the interrupt vector table */
pic14createInterruptVect (&vBuf);
}
-
+
AnalyzepCode('*');
-
+
ReuseReg(); // ReuseReg where call tree permits
-
+
InlinepCode();
-
+
AnalyzepCode('*');
-
+
if (options.debug) pcode_test();
-
-
+
+
/* now put it all together into the assembler file */
/* create the assembler file name */
-
+
if ((noAssemble || options.c1mode) && fullDstFileName)
{
sprintf (buffer, fullDstFileName);
sprintf (buffer, dstFileName);
strcat (buffer, ".asm");
}
-
+
if (!(asmFile = fopen (buffer, "w"))) {
werror (E_FILE_OPEN_ERR, buffer);
exit (1);
/* prepare statistics */
resetpCodeStatistics ();
-
+
/* initial comments */
pic14initialComments (asmFile);
-
+
/* print module name */
fprintf (asmFile, "%s\t.file\t\"%s\"\n",
- options.debug ? "" : ";", fullSrcFileName);
-
+ options.debug ? "" : ";", fullSrcFileName);
+
/* Let the port generate any global directives, etc. */
if (port->genAssemblerPreamble)
{
/* print the global variables in this module */
//pic14printPublics (asmFile);
-
+
/* print the extern variables in this module */
//pic14printExterns (asmFile);
-
+
/* copy the sfr segment */
#if 0
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; special function registers\n");
fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&sfr->oBuf, asmFile);
-
-
+
+
if (udata_section_name) {
sprintf(udata_name,"%s",udata_section_name);
} else {
/* print the locally defined variables in this module */
writeUsedRegs(asmFile);
-
+
/* create the overlay segments */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; overlayable items in internal ram \n");
- fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&ovrBuf, asmFile);
-
+
#if 0
-
+
/* create the stack segment MOF */
if (mainf && IFFUNC_HASBODY(mainf->type)) {
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; Stack segment in internal ram \n");
- fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
";__start__stack:\n;\t.ds\t1\n\n");
}
-
+
/* create the idata segment */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; indirectly addressable internal ram data\n");
fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
fprintf (asmFile,";\t.ds 256\n");
}
-
+
/* copy xtern ram data */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; external ram data\n");
dbuf_write_and_destroy (&xdata->oBuf, asmFile);
#endif
-
+
/* copy the bit segment */
#if 0
fprintf (asmFile, "%s", iComments2);
/* create interupt ventor handler */
pic14_emitInterruptHandler (asmFile);
-
+
/* copy over code */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; code\n");
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
-
+
/* unknown */
copypCode(asmFile, 'X');
-
+
/* _main function */
copypCode(asmFile, 'M');
-
+
/* other functions */
copypCode(asmFile, code->dbName);
-
+
/* unknown */
copypCode(asmFile, 'P');
dumppCodeStatistics (asmFile);
-
+
fprintf (asmFile,"\tend\n");
-
+
fclose (asmFile);
pic14_debugLogClose();
}
#define LEN 4096
char *buffer = NULL;
char *left, *right;
-
+
if (IS_AST_VALUE(node)) {
value *val = AST_VALUE(node);
symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
{
*inCodeSpace = 1;
}
-
+
DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
if (IS_AST_LIT_VALUE(node)) {
buffer = Safe_alloc(LEN);
} else {
assert ( !"Invalid construct in initializer." );
}
-
+
return (buffer);
}
/*
- * Emit the section preamble, absolute location (if any) and
+ * Emit the section preamble, absolute location (if any) and
* symbol name(s) for intialized data.
*/
static int
char *segname;
static int in_code = 0;
static int sectionNr = 0;
-
+
if (sym) {
// code or data space?
if (IS_CODE(getSpec(sym->type))) {
int inCodeSpace = 0;
char *str = NULL;
int in_code;
-
+
assert (size <= sizeof(long));
assert (!list || (list->type == INIT_NODE));
node = list ? list->init.node : NULL;
-
+
in_code = emitIvalLabel(oBuf, sym);
if (!in_code) dbuf_printf (oBuf, "\tdb\t");
dbuf_printf (oBuf, "\n");
return;
} // if
-
+
op = NULL;
if (constExprTree(node) && (val = constExprValue(node, 0))) {
op = operandFromValue(val);
assert ( !"Unhandled construct in intializer." );
}
- if (op) {
+ if (op) {
aopOp(op, NULL, 1);
assert(AOP(op));
//printOperand(op, of);
}
-
+
for (i=0; i < size; i++) {
char *text = op ? aopGet(AOP(op), i, 0, 0)
: get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0);
matchIvalToUnion (initList *list, sym_link *type, int size)
{
symbol *sym;
-
+
assert (type);
if (IS_PTR(type) || IS_CHAR(type) || IS_INT(type) || IS_LONG(type)
- || IS_FLOAT(type))
+ || IS_FLOAT(type))
{
if (!list || (list->type == INIT_NODE)) {
DEBUGprintf ("OK, simple type\n");
if (list) list = list->next;
sym = sym->next;
} // while
-
+
// excess initializers?
if (list) {
DEBUGprintf ("ERROR, excess initializers\n");
return (NULL);
}
-
+
DEBUGprintf ("OK, struct\n");
return (type);
}
} // for i
return;
}
-
+
if (IS_FLOAT(my_type)) {
// float, 32 bit
DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
emitIvals(oBuf, topsym, list, 0, size);
return;
}
-
+
if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
// integral type, 8, 16, or 32 bit
DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
emitIvals(oBuf, topsym, list, 0, size);
return;
-
+
} else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
// struct
DEBUGprintf ("(struct, %d byte) handled below\n", size);
int len = 0;
if (IS_BITFIELD(sym->type)) {
while (sym && IS_BITFIELD(sym->type)) {
- assert (!list || ((list->type == INIT_NODE)
+ assert (!list || ((list->type == INIT_NODE)
&& IS_AST_LIT_VALUE(list->init.node)));
lit = (long) (list ? list2int(list) : 0);
DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
emitIvals(oBuf, topsym, NULL, bitfield, len / 8);
topsym = NULL;
} // if
-
+
if (sym) {
emitInitVal(oBuf, topsym, sym->type, list);
topsym = NULL;
assert ( !"Excess initializers." );
} // if
return;
-
+
} else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
// union
DEBUGprintf ("(union, %d byte) handled below\n", size);
}
return;
} // if
-
+
assert ( !"No UNION member matches the initializer structure.");
} else if (IS_BITFIELD(my_type)) {
assert ( !"bitfields should only occur in structs..." );
-
+
} else {
printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
assert( !"Unhandled initialized type.");
//DEBUGprintf ("memmap %i: %p\n", i, map);
if (map) {
#if 0
- fprintf (stdout, "; pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
+ fprintf (stdout, "; pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
map->pageno, map->sname, map->dbName, map->ptrType, map->slbl,
map->sloc, map->fmap, map->paged, map->direct, map->bitsp,
map->codesp, map->regsp, map->syms);