case V_VOID: return "void";
case V_STRUCT: return "struct";
case V_LABEL: return "label";
+ case V_BITFIELD: return "bitfield";
case V_BIT: return "bit";
case V_SBIT: return "sbit";
case V_DOUBLE: return "double";
strncpyz (sym->name, name, sizeof(sym->name)); /* copy the name */
sym->level = scope; /* set the level */
sym->block = currBlockno;
- sym->lineDef = yylineno; /* set the line number */
+ sym->lineDef = mylineno; /* set the line number */
return sym;
}
case V_LABEL:
return 0;
case V_SBIT:
- return BITSIZE;
case V_BIT:
+ return BITSIZE;
+ case V_BITFIELD:
return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
default:
return 0;
case V_LABEL:
return 0;
case V_SBIT:
- return 1;
case V_BIT:
+ return 1;
+ case V_BITFIELD:
return SPEC_BLEN (p);
default:
return 0;
/* create the internal name for this variable */
SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
- loop->offset = (su == UNION ? sum = 0 : sum);
+ if (su == UNION) {
+ sum = 0;
+ bitOffset = 0;
+ }
SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
/* if this is a bit field */
if (loop->bitVar) {
/* change it to a unsigned bit */
- SPEC_NOUN (loop->etype) = V_BIT;
+ SPEC_NOUN (loop->etype) = V_BITFIELD;
SPEC_USIGN (loop->etype) = 1;
- /* check if this fit into the remaining */
- /* bits of this byte else align it to the */
- /* next byte boundary */
- if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
- SPEC_BSTR (loop->etype) = bitOffset;
- if ((bitOffset += (loop->bitVar % 8)) == 8)
- sum++;
+ 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;
+ loop->offset = sum;
}
- else /* does not fit */ {
- bitOffset = 0;
- SPEC_BSTR (loop->etype) = bitOffset;
- sum += (loop->bitVar / 8);
- bitOffset += (loop->bitVar % 8);
- }
- /* if this is the last field then pad */
- if (!loop->next && bitOffset && bitOffset != 8) {
- bitOffset = 0;
- sum++;
+ else {
+ if (bitOffset == 8) {
+ bitOffset = 0;
+ sum++;
+ }
+ /* check if this fit into the remaining */
+ /* bits of this byte else align it to the */
+ /* next byte boundary */
+ if (loop->bitVar <= (8 - bitOffset)) {
+ /* fits into current byte */
+ loop->offset = sum;
+ SPEC_BSTR (loop->etype) = bitOffset;
+ bitOffset += loop->bitVar;
+ }
+ else if (!bitOffset) {
+ /* does not fit, but is already byte aligned */
+ loop->offset = sum;
+ SPEC_BSTR (loop->etype) = bitOffset;
+ bitOffset += loop->bitVar;
+ }
+ else {
+ /* does not fit; need to realign first */
+ sum++;
+ loop->offset = (su == UNION ? sum = 0 : sum);
+ bitOffset = 0;
+ SPEC_BSTR (loop->etype) = bitOffset;
+ bitOffset += loop->bitVar;
+ }
+ while (bitOffset>8) {
+ bitOffset -= 8;
+ sum++;
+ }
}
}
else {
+ /* This is a non-bit field. Make sure we are */
+ /* byte aligned first */
+ if (bitOffset) {
+ sum++;
+ loop->offset = (su == UNION ? sum = 0 : sum);
+ bitOffset = 0;
+ }
+ loop->offset = sum;
checkDecl (loop, 1);
sum += getSize (loop->type);
}
loop = loop->next;
- /* if this is not a bitfield but the */
- /* previous one was and did not take */
- /* the whole byte then pad the rest */
- if ((loop && !loop->bitVar) && bitOffset) {
- bitOffset = 0;
- sum++;
- }
-
/* if union then size = sizeof larget field */
- if (su == UNION)
+ if (su == UNION) {
+ /* For UNION, round up after each field */
+ sum += ((bitOffset+7)/8);
usum = max (usum, sum);
+ }
}
+
+ /* For STRUCT, round up after all fields processed */
+ if (su != UNION)
+ sum += ((bitOffset+7)/8);
return (su == UNION ? usum : sum);
}
if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
(SPEC_NOUN (sym->etype) == V_BIT ||
SPEC_NOUN (sym->etype) == V_SBIT ||
+ SPEC_NOUN (sym->etype) == V_BITFIELD ||
SPEC_SCLS (sym->etype) == S_SFR))
werror (E_BIT_ARRAY, sym->name);
reType = getSpec (rType);
/* if either of them unsigned but not val then make this unsigned */
- if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) ||
- (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) &&
+ if (((/*!IS_LITERAL(type1) &&*/ SPEC_USIGN (etype1)) ||
+ (/*!IS_LITERAL(type2) &&*/ SPEC_USIGN (etype2))) &&
!IS_FLOAT (reType))
SPEC_USIGN (reType) = 1;
else
SPEC_USIGN (reType) = 0;
-
+
/* if result is a literal then make not so */
if (IS_LITERAL (reType))
SPEC_SCLS (reType) = S_REGISTER;
/*--------------------------------------------------------------------*/
/* compareType - will do type check return 1 if match, -1 if castable */
/*--------------------------------------------------------------------*/
-int
+int
compareType (sym_link * dest, sym_link * src)
{
if (!dest && !src)
/*------------------------------------------------------------------*/
/* inCalleeSaveList - return 1 if found in callee save list */
/*------------------------------------------------------------------*/
-bool
-inCalleeSaveList (char *s)
+static int
+calleeCmp(void *p1, void *p2)
{
- int i;
-
- if (options.all_callee_saves) return 1;
- for (i = 0; options.calleeSaves[i]; i++)
- if (strcmp (options.calleeSaves[i], s) == 0)
- return 1;
+ return (strcmp((char *)p1, (char *)(p2)) == 0);
+}
- return 0;
+bool
+inCalleeSaveList(char *s)
+{
+ if (options.all_callee_saves)
+ return 1;
+ return isinSetWith(options.calleeSavesSet, s, calleeCmp);
}
/*-----------------------------------------------------------------*/
printTypeChain (sym_link * start, FILE * of)
{
int nlr = 0;
+ value *args;
sym_link * type, * search;
STORAGE_CLASS scls;
fprintf (of, "function %s %s",
(IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
(IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
+ fprintf (of, "( ");
+ for (args = FUNC_ARGS(type);
+ args;
+ args=args->next) {
+ printTypeChain(args->type, of);
+ if (args->next)
+ fprintf(of, ", ");
+ }
+ fprintf (of, ") ");
break;
case GPOINTER:
fprintf (of, "generic* ");
break;
case V_BIT:
- fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
+ fprintf (of, "bit");
+ break;
+
+ case V_BITFIELD:
+ fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
break;
case V_DOUBLE:
}
}
+/*
for (muldivmod = 0; muldivmod < 3; muldivmod++)
{
for (bwd = 0; bwd < 3; bwd++)
{
for (su = 0; su < 2; su++)
{
- SNPRINTF (buffer, sizeof(buffer),
+ SNPRINTF (buffer, sizeof(buffer),
"_%s%s%s",
smuldivmod[muldivmod],
ssu[su],
}
}
+ muluint() and mulsint() resp. mululong() and mulslong() return the same result.
+ Therefore they've been merged into mulint() and mullong().
+*/
+
+ for (bwd = 0; bwd < 3; bwd++)
+ {
+ for (su = 0; su < 2; su++)
+ {
+ for (muldivmod = 1; muldivmod < 3; muldivmod++)
+ {
+ /* div and mod */
+ 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;
+ }
+ }
+ }
+ /* 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 */
+ for (bwd = 1; bwd < 3; bwd++)
+ {
+ /* mul, int/long */
+ SNPRINTF (buffer, sizeof(buffer),
+ "_%s%s",
+ smuldivmod[muldivmod],
+ sbwd[bwd]);
+ __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+ FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
+ /* signed = unsigned */
+ __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
+ }
+
for (rlrr = 0; rlrr < 2; rlrr++)
{
for (bwd = 0; bwd < 3; bwd++)
{
for (su = 0; su < 2; su++)
{
- SNPRINTF (buffer, sizeof(buffer),
+ SNPRINTF (buffer, sizeof(buffer),
"_%s%s%s",
srlrr[rlrr],
ssu[su],