}
/*-----------------------------------------------------------------*/
-/* newBucket - allocates & returns a new bucket */
+/* newBucket - allocates & returns a new bucket */
/*-----------------------------------------------------------------*/
bucket *
newBucket ()
int checkType)
{
int i; /* index into the hash Table */
- bucket *bp; /* temp bucket * */
+ bucket *bp; /* temp bucket * */
if (checkType) {
symbol *csym = (symbol *)sym;
/* get a free entry */
bp = Safe_alloc ( sizeof (bucket));
- bp->sym = sym; /* update the symbol pointer */
- bp->level = level; /* update the nest level */
+ bp->sym = sym; /* update the symbol pointer */
+ bp->level = level; /* update the nest level */
bp->block = block;
strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
}
/*-----------------------------------------------------------------*/
-/* deleteSym - deletes a symbol from the hash Table entry */
+/* deleteSym - deletes a symbol from the hash Table entry */
/*-----------------------------------------------------------------*/
void
deleteSym (bucket ** stab, void *sym, char *sname)
if (!bp) /* did not find it */
return;
+
/* if this is the first one in the chain */
if (!bp->prev)
{
bp->prev->next = bp->next;
}
-
}
/*-----------------------------------------------------------------*/
-/* findSym - finds a symbol in a table */
+/* findSym - finds a symbol in a table */
/*-----------------------------------------------------------------*/
void *
findSym (bucket ** stab, void *sym, const char *sname)
// short AND long
werror (E_LONG_AND_SHORT_INVALID, noun, name);
}
-
}
/*------------------------------------------------------------------*/
return dest;
}
-/*------------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
/* genSymName - generates and returns a name used for anonymous vars */
-/*------------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
char *
genSymName (int level)
{
}
/*------------------------------------------------------------------*/
-/* newFixed16x16Link - a new Float type */
+/* newFixed16x16Link - a new Float type */
/*------------------------------------------------------------------*/
sym_link *
newFixed16x16Link ()
}
/*------------------------------------------------------------------*/
-/* reverseSyms - reverses the links for a symbol chain */
+/* reverseSyms - reverses the links for a symbol chain */
/*------------------------------------------------------------------*/
symbol *
reverseSyms (symbol * sym)
}
/*------------------------------------------------------------------*/
-/* reverseLink - reverses the links for a type chain */
+/* reverseLink - reverses the links for a type chain */
/*------------------------------------------------------------------*/
sym_link *
reverseLink (sym_link * type)
DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
}
- /* if already exists in the symbol table
- then check if the type match;
- if yes then if at least one is not extern
- set the new symbol to non extern */
+ /* if already exists in the symbol table on the same level */
if ((csym = findSymWithLevel (SymbolTab, sym)) &&
csym->level == sym->level)
{
/* if not formal parameter and not in file scope
then show symbol redefined error
- else check if symbols have conpatible types */
+ else check if symbols have compatible types */
if (!sym->_isparm && sym->level > 0)
error = 1;
else
{
- /* If the previous definition was for an array with incomplete */
- /* type, and the new definition has completed the type, update */
- /* the original type to match */
+ /* If the previous definition was for an array with incomplete
+ type, and the new definition has completed the type, update
+ the original type to match */
if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
&& IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
{
if (csym->ival && !sym->ival)
sym->ival = csym->ival;
- if (!sym->cdef && IS_EXTERN (sym->etype))
+ if (!csym->cdef && !sym->cdef && IS_EXTERN (sym->etype))
{
- /* set the new symbol to not extern if not a compiler defined function
- and at least one is non extern */
+ /* if none of symbols is a compiler defined function
+ and at least one is not extern
+ then set the new symbol to non extern */
SPEC_EXTR(sym->etype) = SPEC_EXTR(csym->etype);
- sym->cdef = csym->cdef;
}
/* delete current entry */
etype = getSpec (type);
SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
SPEC_SCLS (etype) : SPEC_SCLS (petype));
+ SPEC_OCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
+ SPEC_OCLS (etype) : SPEC_OCLS (petype));
if (IS_SPEC (type))
SPEC_CONST (type) |= SPEC_CONST (stype);
else
/* if this is a bit field */
if (loop->bitVar) {
+ SPEC_BUNNAMED (loop->etype) = loop->bitUnnamed;
+
/* change it to a unsigned bit */
SPEC_NOUN (loop->etype) = V_BITFIELD;
/* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
if (!loop->etype->select.s.b_signed)
SPEC_USIGN(loop->etype) = 1;
- SPEC_BLEN (loop->etype) = loop->bitVar;
-
if (loop->bitVar == BITVAR_PAD) {
/* A zero length bitfield forces padding */
- SPEC_BSTR (loop->etype) = bitOffset;
SPEC_BLEN (loop->etype) = 0;
- bitOffset = 8;
+ SPEC_BSTR (loop->etype) = bitOffset;
+ if (bitOffset > 0)
+ bitOffset = 8; /* padding is not needed when at bit 0 */
loop->offset = sum;
}
else {
+ SPEC_BLEN (loop->etype) = loop->bitVar;
+
if (bitOffset == 8) {
bitOffset = 0;
sum++;
}
/*------------------------------------------------------------------*/
-/* checkDecl - does semantic validation of a declaration */
+/* checkDecl - does semantic validation of a declaration */
/*------------------------------------------------------------------*/
int
checkDecl (symbol * sym, int isProto)
{
- checkSClass (sym, isProto); /* check the storage class */
- changePointer (sym->type); /* change pointers if required */
+ checkSClass (sym, isProto); /* check the storage class */
+ changePointer (sym->type); /* change pointers if required */
/* if this is an array without any dimension
then update the dimension from the initial value */
/* if both are bitvars choose the larger one */
else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
- copyLinkChain (type1) : copyLinkChain (type1);
+ copyLinkChain (type1) : copyLinkChain (type2);
/* if only one of them is a bit variable then the other one prevails */
else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
return rType;
}
+int
+comparePtrType (sym_link * dest, sym_link * src, bool bMustCast)
+{
+ int res;
+
+ if (IS_VOID (src->next) && IS_VOID (dest->next))
+ return bMustCast ? -1 : 1;
+ if ((IS_VOID (src->next) && !IS_VOID (dest->next)) ||
+ (!IS_VOID (src->next) && IS_VOID (dest->next)) )
+ return -1;
+ res = compareType (dest->next, src->next);
+ if (res == 1)
+ return bMustCast ? -1 : 1;
+ else if (res == -2)
+ return -2;
+ else
+ return 0;
+}
+
/*--------------------------------------------------------------------*/
-/* compareType - will do type check return 1 if match, -1 if castable */
+/* compareType - will do type check return 1 if match, 0 if no match, */
+/* -1 if castable, -2 if only signedness differs */
/*--------------------------------------------------------------------*/
int
compareType (sym_link * dest, sym_link * src)
return -1;
if (IS_FUNC (dest->next) && IS_VOID(src->next))
return -1;
- return compareType (dest->next, src->next);
+ return comparePtrType(dest, src, FALSE);
}
if (DCL_TYPE (src) == DCL_TYPE (dest))
{
//checkFunction(src,dest);
}
- return compareType (dest->next, src->next);
+ return comparePtrType(dest, src, FALSE);
}
if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next))
{
(IS_GENPTR (dest) ||
((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
))
- return -1;
+ {
+ return comparePtrType(dest, src, TRUE);
+ }
if (IS_PTR (dest) && IS_ARRAY (src))
{
value *val=aggregateToPointer (valFromType(src));
return 0;
}
+ if (IS_PTR (src) && IS_VOID (dest))
+ return -1;
+
/* if one is a specifier and the other is not */
if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
(IS_SPEC (dest) && !IS_SPEC (src)))
return -1;
if (SPEC_USIGN (dest) != SPEC_USIGN (src))
- return -1;
+ return -2;
return 1;
}
}
/*------------------------------------------------------------------*/
-/* inCalleeSaveList - return 1 if found in callee save list */
+/* inCalleeSaveList - return 1 if found in callee save list */
/*------------------------------------------------------------------*/
static int
calleeCmp(void *p1, void *p2)
}
break;
case S_AUTO:
+ DCL_TYPE (val->type) = PTR_TYPE(SPEC_OCLS(val->etype));
+ break;
case S_DATA:
case S_REGISTER:
DCL_TYPE (val->type) = POINTER;
symbol *__fps16x16_gt;
symbol *__fps16x16_gteq;
-/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
-symbol *__muldiv[3][3][2];
+/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */
+symbol *__muldiv[3][3][4];
/* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
sym_link *__multypes[3][2];
/* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
};
const char *ssu[] =
{
- "s", "u"
+ "s", "su", "us", "u"
};
const char *srlrr[] =
{
{
if (tofrom)
{
- SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
+ SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su*3], sbwd[bwd]);
__conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
}
else
{
- SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
+ SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su*3], sbwd[bwd]);
__conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
}
}
{
if (tofrom)
{
- SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
+ SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su*3], fp16x16sbwd[bwd]);
if(bwd == 3) {
__fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
} else
}
else
{
- SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
+ SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su*3], fp16x16sbwd[bwd]);
if(bwd == 3) {
__fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
} else
SNPRINTF (buffer, sizeof(buffer),
"_%s%s%s",
smuldivmod[muldivmod],
- ssu[su],
+ ssu[su*3],
sbwd[bwd]);
__muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
Therefore they've been merged into mulint() and mullong().
*/
- for (bwd = 0; bwd < 3; bwd++)
+ /* byte */
+ bwd = 0;
+ for (su = 0; su < 4; su++)
+ {
+ for (muldivmod = 0; muldivmod < 3; muldivmod++)
+ {
+ /* muluchar, mulschar, mulsuchar and muluschar are separate functions, because e.g. the z80
+ port is sign/zero-extending to int before calling mulint() */
+ /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
+ if (!TARGET_IS_PIC16 || muldivmod != 1 || su != 0)
+ {
+ SNPRINTF (buffer, sizeof(buffer),
+ "_%s%s%s",
+ smuldivmod[muldivmod],
+ ssu[su],
+ sbwd[bwd]);
+ __muldiv[muldivmod][bwd][su] = funcOfType (
+ _mangleFunctionName(buffer),
+ __multypes[bwd][su%2],
+ __multypes[bwd][su/2],
+ 2,
+ options.intlong_rent);
+ FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
+ }
+ }
+ }
+
+ for (bwd = 1; bwd < 3; bwd++)
{
for (su = 0; su < 2; su++)
{
SNPRINTF (buffer, sizeof(buffer),
"_%s%s%s",
smuldivmod[muldivmod],
- ssu[su],
+ ssu[su*3],
sbwd[bwd]);
__muldiv[muldivmod][bwd][su] = funcOfType (
_mangleFunctionName(buffer),
/* mul only */
muldivmod = 0;
- /* byte */
- bwd = 0;
- for (su = 0; su < 2; su++)
- {
- /* muluchar and mulschar are still separate functions, because e.g. the z80
- port is sign/zero-extending to int before calling mulint() */
- SNPRINTF (buffer, sizeof(buffer),
- "_%s%s%s",
- smuldivmod[muldivmod],
- ssu[su],
- sbwd[bwd]);
- __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
- FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
- }
/* signed only */
su = 0;
/* word and doubleword */
SNPRINTF (buffer, sizeof(buffer),
"_%s%s%s",
srlrr[rlrr],
- ssu[su],
+ ssu[su*3],
sbwd[bwd]);
__rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;