{
case V_INT: {
if (SPEC_LONG(sl)) return "long";
- if (sl->select.s._short) return "short";
+ if (SPEC_SHORT(sl)) return "short";
return "int";
}
case V_FLOAT: return "float";
+ case V_FIXED16X16: return "fixed16x16";
case V_CHAR: return "char";
case V_VOID: return "void";
case V_STRUCT: return "struct";
if ((SPEC_NOUN(etype)==V_CHAR ||
SPEC_NOUN(etype)==V_FLOAT ||
+ SPEC_NOUN(etype)==V_FIXED16X16 ||
SPEC_NOUN(etype)==V_DOUBLE ||
SPEC_NOUN(etype)==V_VOID) &&
- (etype->select.s._short || SPEC_LONG(etype))) {
+ (SPEC_SHORT(etype) || SPEC_LONG(etype))) {
// long or short for char float double or void
werror (E_LONG_OR_SHORT_INVALID, noun, name);
}
if ((SPEC_NOUN(etype)==V_FLOAT ||
+ SPEC_NOUN(etype)==V_FIXED16X16 ||
SPEC_NOUN(etype)==V_DOUBLE ||
SPEC_NOUN(etype)==V_VOID) &&
- (etype->select.s._signed || SPEC_USIGN(etype))) {
+ (etype->select.s.b_signed || SPEC_USIGN(etype))) {
// signed or unsigned for float double or void
werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
}
// special case for "short"
- if (etype->select.s._short) {
+ if (SPEC_SHORT(etype)) {
SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
- etype->select.s._short = 0;
+ SPEC_SHORT(etype) = 0;
}
/* if no noun e.g.
/* a "plain" int bitfield is unsigned */
if (SPEC_NOUN(etype)==V_BIT ||
SPEC_NOUN(etype)==V_SBIT) {
- if (!etype->select.s._signed)
+ if (!etype->select.s.b_signed)
SPEC_USIGN(etype) = 1;
}
- if (etype->select.s._signed && SPEC_USIGN(etype)) {
+ if (etype->select.s.b_signed && SPEC_USIGN(etype)) {
// signed AND unsigned
werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
}
- if (etype->select.s._short && SPEC_LONG(etype)) {
+ if (SPEC_SHORT(etype) && SPEC_LONG(etype)) {
// short AND long
werror (E_LONG_AND_SHORT_INVALID, noun, name);
}
// but there are more important thing right now
SPEC_LONG (dest) |= SPEC_LONG (src);
- dest->select.s._short|=src->select.s._short;
+ SPEC_SHORT(dest) |= SPEC_SHORT(src);
SPEC_USIGN (dest) |= SPEC_USIGN (src);
- dest->select.s._signed|=src->select.s._signed;
+ dest->select.s.b_signed|=src->select.s.b_signed;
SPEC_STAT (dest) |= SPEC_STAT (src);
SPEC_EXTR (dest) |= SPEC_EXTR (src);
SPEC_CONST(dest) |= SPEC_CONST (src);
return p;
}
+/*------------------------------------------------------------------*/
+/* newFixed16x16Link - a new Float type */
+/*------------------------------------------------------------------*/
+sym_link *
+newFixed16x16Link ()
+{
+ sym_link *p;
+
+ p = newLink (SPECIFIER);
+ SPEC_NOUN (p) = V_FIXED16X16;
+
+ return p;
+}
+
/*------------------------------------------------------------------*/
/* newLongLink() - new long type */
/*------------------------------------------------------------------*/
return p;
}
+/*------------------------------------------------------------------*/
+/* newBoolLink() - creates an bool type */
+/*------------------------------------------------------------------*/
+sym_link *
+newBoolLink ()
+{
+ sym_link *p;
+
+ p = newLink (SPECIFIER);
+ SPEC_NOUN (p) = V_BIT;
+
+ return p;
+}
+
/*------------------------------------------------------------------*/
/* getSize - returns size of a type chain in bits */
/*------------------------------------------------------------------*/
return (IS_LONG (p) ? LONGSIZE : INTSIZE);
case V_FLOAT:
return FLOATSIZE;
+ case V_FIXED16X16:
+ return (4);
case V_CHAR:
return CHARSIZE;
case V_VOID:
case FPOINTER:
case CPOINTER:
case FUNCTION:
- return (FPTRSIZE);
+ return (IFFUNC_BANKED (p) ? GPTRSIZE : FPTRSIZE);
case GPOINTER:
return (GPTRSIZE);
return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
case V_FLOAT:
return FLOATSIZE * 8;
+ case V_FIXED16X16:
+ return (32);
case V_CHAR:
return CHARSIZE * 8;
case V_VOID:
/* addSymChain - adds a symbol chain to the symboltable */
/*------------------------------------------------------------------*/
void
-addSymChain (symbol * symHead)
+addSymChain (symbol ** symHead)
{
- symbol *sym = symHead;
+ symbol *sym = *symHead;
symbol *csym = NULL;
+ symbol **symPtrPtr;
int error = 0;
for (; sym != NULL; sym = sym->next)
/* delete current entry */
deleteSym (SymbolTab, csym, csym->name);
deleteFromSeg(csym);
+
+ symPtrPtr = symHead;
+ while (*symPtrPtr && *symPtrPtr != csym)
+ symPtrPtr = &(*symPtrPtr)->next;
+ if (*symPtrPtr == csym)
+ *symPtrPtr = csym->next;
+
}
/* add new entry */
/* change it to a unsigned bit */
SPEC_NOUN (loop->etype) = V_BITFIELD;
- SPEC_USIGN (loop->etype) = 1;
+ /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
+ /* a "plain" int bitfield is unsigned */
+ if (!loop->etype->select.s.b_signed)
+ SPEC_USIGN(loop->etype) = 1;
+
SPEC_BLEN (loop->etype) = loop->bitVar;
if (loop->bitVar == BITVAR_PAD) {
if (IS_ABSOLUTE (sym->etype))
SPEC_VOLATILE (sym->etype) = 1;
+ if (TARGET_IS_MCS51 &&
+ IS_ABSOLUTE (sym->etype) &&
+ SPEC_SCLS (sym->etype) == S_SFR)
+ {
+ int n, size;
+ unsigned addr;
+
+ if (SPEC_NOUN (sym->etype) == V_CHAR)
+ size = 8;
+ else if (SPEC_LONG (sym->etype) == 0)
+ size = 16;
+ else
+ size = 32;
+
+ addr = SPEC_ADDR (sym->etype);
+ for (n=0; n<size; n+=8)
+ if (((addr >> n) & 0xFF) < 0x80)
+ werror (W_SFR_ABSRANGE, sym->name);
+ }
+
/* If code memory is read only, then pointers to code memory */
/* implicitly point to constants -- make this explicit */
t = sym->type;
/* if this is an automatic symbol */
if (sym->level && (options.stackAuto || reentrant)) {
- if ((SPEC_SCLS (sym->etype) == S_AUTO ||
- SPEC_SCLS (sym->etype) == S_FIXED ||
- SPEC_SCLS (sym->etype) == S_REGISTER ||
- SPEC_SCLS (sym->etype) == S_STACK ||
- SPEC_SCLS (sym->etype) == S_XSTACK)) {
- SPEC_SCLS (sym->etype) = S_AUTO;
- } else {
- /* storage class may only be specified for statics */
- if (!IS_STATIC(sym->etype)) {
- werror (E_AUTO_ASSUMED, sym->name);
+ if (SPEC_SCLS (sym->etype) != S_BIT) {
+ if ((SPEC_SCLS (sym->etype) == S_AUTO ||
+ SPEC_SCLS (sym->etype) == S_FIXED ||
+ SPEC_SCLS (sym->etype) == S_REGISTER ||
+ SPEC_SCLS (sym->etype) == S_STACK ||
+ SPEC_SCLS (sym->etype) == S_XSTACK)) {
+ SPEC_SCLS (sym->etype) = S_AUTO;
+ } else {
+ /* storage class may only be specified for statics */
+ if (!IS_STATIC(sym->etype)) {
+ werror (E_AUTO_ASSUMED, sym->name);
+ }
}
}
}
/* arrays & pointers cannot be defined for bits */
/* SBITS or SFRs or BIT */
if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
+ !IS_FUNCPTR (sym->type) &&
(SPEC_NOUN (sym->etype) == V_BIT ||
SPEC_NOUN (sym->etype) == V_SBIT ||
SPEC_NOUN (sym->etype) == V_BITFIELD ||
/* if parameter or local variable then change */
/* the storage class to reflect where the var will go */
- if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
- !IS_STATIC(sym->etype))
+ if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED
+ && !IS_STATIC(sym->etype)
+ )
{
if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
{
/* go thru the chain of declarations */
/* if we find a pointer to a function */
- /* unconditionally change it to a ptr */
- /* to code area */
+ /* change it to a ptr to code area */
+ /* unless the function is banked. */
for (; p; p = p->next)
{
if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
DCL_TYPE (p) = port->unqualified_pointer;
if (IS_PTR (p) && IS_FUNC (p->next))
+ if (!IFFUNC_BANKED(p->next))
DCL_TYPE (p) = CPOINTER;
}
}
/* which ever is greater in size */
if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
rType = newFloatLink ();
+ else
+ /* if both are fixed16x16 then result is float */
+ if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
+ rType = newFixed16x16Link();
+ else
+ if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
+ rType = newFloatLink ();
+ if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
+ rType = newFloatLink ();
else
/* if both are bitvars choose the larger one */
if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
reType = getSpec (rType);
/* avoid conflicting types */
- reType->select.s._signed = 0;
+ reType->select.s.b_signed = 0;
/* if result is a literal then make not so */
if (IS_LITERAL (reType))
{
if (IS_DECL (src))
{
+ /* banked function pointer */
+ if (IS_GENPTR (dest) && IS_GENPTR (src))
+ {
+ if (IS_FUNC (src->next) && IS_VOID(dest->next))
+ return -1;
+ if (IS_FUNC (dest->next) && IS_VOID(src->next))
+ return -1;
+ return compareType (dest->next, src->next);
+ }
+
if (DCL_TYPE (src) == DCL_TYPE (dest)) {
if (IS_FUNC(src)) {
//checkFunction(src,dest);
if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
return -1;
}
- if (IS_PTR (src) && IS_GENPTR (dest))
+ if (IS_PTR (src) &&
+ (IS_GENPTR (dest) ||
+ ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
+ ))
return -1;
if (IS_PTR (dest) && IS_ARRAY (src)) {
value *val=aggregateToPointer (valFromType(src));
return 0;
}
- /* function cannot return bit */
- if (IS_BITVAR (sym->type->next))
- {
- werror (E_FUNC_BIT, sym->name);
- return 0;
- }
-
/* check if this function is defined as calleeSaves
then mark it as such */
FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
}
}
+ if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
+ {
+ werror (E_SHADOWREGS_NO_ISR, sym->name);
+ }
+
+
for (argCnt=1, acargs = FUNC_ARGS(sym->type);
acargs;
acargs=acargs->next, argCnt++) {
werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
}
- if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
+ /* I don't think this is necessary for interrupts. An isr is a */
+ /* root in the calling tree. */
+ if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
+ (!FUNC_ISISR (sym->type)))
{
werror (E_PREV_DEF_CONFLICT, csym->name, "using");
}
{
werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
}
-
+
/* Really, reentrant should match regardless of argCnt, but */
/* this breaks some existing code (the fp lib functions). If */
/* the first argument is always passed the same way, this */
werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
}
+ if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
+ {
+ werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
+ }
+
+ if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
+ {
+ werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
+ }
+
+
/* compare expected args with actual args */
exargs = FUNC_ARGS(csym->type);
acargs = FUNC_ARGS(sym->type);
the function does not have VA_ARG
and as port dictates */
if (!IFFUNC_HASVARARGS(funcType) &&
- (argreg = (*port->reg_parm) (val->type)))
+ (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
{
SPEC_REGPARM (val->etype) = 1;
SPEC_ARGREG(val->etype) = argreg;
SNPRINTF (val->name, sizeof(val->name),
"_%s_PARM_%d", func->name, pNum++);
val->sym = newSymbol (val->name, 1);
- SPEC_OCLS (val->etype) = port->mem.default_local_map;
+ if (SPEC_SCLS(val->etype) == S_BIT)
+ SPEC_OCLS (val->etype) = bit;
+ else
+ SPEC_OCLS (val->etype) = port->mem.default_local_map;
val->sym->type = copyLinkChain (val->type);
val->sym->etype = getSpec (val->sym->type);
val->sym->_isparm = 1;
SPEC_STAT (func->etype);
}
#endif
- addSymChain (val->sym);
+ addSymChain (&val->sym);
}
else /* symbol name given create synth name */
SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
val->sym->_isparm = 1;
- SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
- (options.model != MODEL_SMALL ? xdata : data);
+ if (SPEC_SCLS(val->etype) == S_BIT)
+ SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
+ else
+ SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
+ port->mem.default_local_map;
#if 0
/* ?? static functions shouldn't imply static parameters - EEP */
}
#endif
}
+ if (SPEC_OCLS (val->sym->etype) == pdata)
+ val->sym->iaccess = 1;
if (!isinSet(operKeyReset, val->sym)) {
addSet (&operKeyReset, val->sym);
applyToSet (operKeyReset, resetParmKey);
fprintf (of, "float");
break;
+ case V_FIXED16X16:
+ fprintf (of, "fixed16x16");
+ break;
+
case V_STRUCT:
fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
break;
fprintf (of, "float");
break;
+ case V_FIXED16X16:
+ fprintf (of, "fixed16x16");
+ break;
+
case V_STRUCT:
fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
break;
}
if (n1s > 1 || nshifts == 0)
- return 0;
+ return -1;
return nshifts - 1;
}
symbol *__fsgt;
symbol *__fsgteq;
+symbol *__fps16x16_add;
+symbol *__fps16x16_sub;
+symbol *__fps16x16_mul;
+symbol *__fps16x16_div;
+symbol *__fps16x16_eq;
+symbol *__fps16x16_neq;
+symbol *__fps16x16_lt;
+symbol *__fps16x16_lteq;
+symbol *__fps16x16_gt;
+symbol *__fps16x16_gteq;
+
/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
symbol *__muldiv[3][3][2];
/* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
sym_link *__multypes[3][2];
/* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
symbol *__conv[2][3][2];
+/* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */
+symbol *__fp16x16conv[2][4][2];
/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
symbol *__rlrr[2][3][2];
sym_link *floatType;
+sym_link *fixed16x16Type;
static char *
_mangleFunctionName(char *in)
/* 'i' - int */
/* 'l' - long */
/* 'f' - float */
+/* 'q' - fixed16x16 */
/* 'v' - void */
/* '*' - pointer - default (GPOINTER) */
/* modifiers - 'u' - unsigned */
r->class = SPECIFIER;
SPEC_NOUN(r) = V_FLOAT;
break;
+ case 'q':
+ r->class = SPECIFIER;
+ SPEC_NOUN(r) = V_FIXED16X16;
+ break;
case 'v':
r->class = SPECIFIER;
SPEC_NOUN(r) = V_VOID;
};
const char *sbwd[] =
{
- "char", "int", "long"
+ "char", "int", "long", "fixed16x16",
+ };
+ const char *fp16x16sbwd[] =
+ {
+ "char", "int", "long", "float",
};
const char *ssu[] =
{
}
floatType = newFloatLink ();
+ fixed16x16Type = newFixed16x16Link ();
for (bwd = 0; bwd < 3; bwd++)
{
__fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
__fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
+ __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
+ __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
+
+
for (tofrom = 0; tofrom < 2; tofrom++)
{
for (bwd = 0; bwd < 3; bwd++)
}
}
+ for (tofrom = 0; tofrom < 2; tofrom++)
+ {
+ for (bwd = 0; bwd < 4; bwd++)
+ {
+ for (su = 0; su < 2; su++)
+ {
+ if (tofrom)
+ {
+ SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
+ if(bwd == 3) {
+ __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
+ } else
+ __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
+ }
+ else
+ {
+ SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
+ if(bwd == 3) {
+ __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
+ } else
+ __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent);
+ }
+ }
+ }
+ }
+
/*
for (muldivmod = 0; muldivmod < 3; muldivmod++)
{