* Added several type casts to increase C++ compatibility.
* __fixargs__ is now an actual function symbol and no longer handled in the scanner. * Additional symbol __argsize__ that is a constant in normal functions and a const local variable for variadic functions. Using this symbol, the va_arg macro gets a lot simpler and smaller. * Added special code to handle the fixed parameters of a variadic function. The code has some overhead, but the va_fix macro is no longer needed (and the compiler generated code is better than va_fix anyway). git-svn-id: svn://svn.cc65.org/cc65/trunk@652 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
59db8bdf1f
commit
544705e6f4
22 changed files with 227 additions and 109 deletions
|
@ -52,7 +52,7 @@
|
|||
|
||||
|
||||
/* Marker for an assembler code position */
|
||||
typedef struct Line_* CodeMark;
|
||||
typedef struct Line* CodeMark;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* common */
|
||||
#include "xmalloc.h"
|
||||
#include "xsprintf.h"
|
||||
|
||||
|
||||
/* cc65 */
|
||||
#include "error.h"
|
||||
#include "asmline.h"
|
||||
|
@ -82,7 +82,7 @@ static Line* NewLine (const char* Format, va_list ap)
|
|||
Len = strlen (Buf);
|
||||
|
||||
/* Allocate memory */
|
||||
L = xmalloc (sizeof (Line) + Len);
|
||||
L = (Line*) xmalloc (sizeof (Line) + Len);
|
||||
|
||||
/* Partially initialize the struct (the remaining fields are initialized
|
||||
* by the caller).
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
|
||||
|
||||
/* Structure that contains one line */
|
||||
typedef struct Line_ Line;
|
||||
struct Line_ {
|
||||
typedef struct Line Line;
|
||||
struct Line {
|
||||
Line* Next; /* Next line on double linked list */
|
||||
Line* Prev; /* Revious line in list */
|
||||
unsigned Flags; /* Flags for this line */
|
||||
|
|
|
@ -206,7 +206,7 @@ static void UseSeg (int NewSeg)
|
|||
/* Switch to a specific segment */
|
||||
{
|
||||
if (CurSeg != NewSeg) {
|
||||
CurSeg = NewSeg;
|
||||
CurSeg = (segment_t) NewSeg;
|
||||
AddCodeLine (".segment\t\"%s\"", SegmentNames [CurSeg]);
|
||||
AddCodeHint (SegmentHints [CurSeg]);
|
||||
}
|
||||
|
@ -846,7 +846,7 @@ void g_getlocal (unsigned flags, int offs)
|
|||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
typeerror (flags);
|
||||
}
|
||||
}
|
||||
|
@ -889,7 +889,7 @@ void g_getind (unsigned flags, unsigned offs)
|
|||
} else {
|
||||
AddCodeLine ("\tjsr\tldai");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CF_INT:
|
||||
|
@ -938,35 +938,111 @@ void g_leasp (int offs)
|
|||
|
||||
/* For value 0 we do direct code */
|
||||
if (offs == 0) {
|
||||
AddCodeLine ("\tlda\tsp");
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tlda\tsp");
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
} else {
|
||||
if (FavourSize) {
|
||||
ldaconst (offs); /* Load A with offset value */
|
||||
AddCodeLine ("\tjsr\tleaasp"); /* Load effective address */
|
||||
} else {
|
||||
if (CPU == CPU_65C02 && offs == 1) {
|
||||
AddCodeLine ("\tlda\tsp");
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tina");
|
||||
AddCodeLine ("\tbne\t*+3");
|
||||
AddCodeLine ("\tinx");
|
||||
AddCodeHint ("x:!"); /* Invalidate X */
|
||||
} else {
|
||||
ldaconst (offs);
|
||||
AddCodeLine ("\tclc");
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tadc\tsp");
|
||||
AddCodeLine ("\tbcc\t*+3");
|
||||
AddCodeLine ("\tinx");
|
||||
AddCodeHint ("x:!"); /* Invalidate X */
|
||||
}
|
||||
}
|
||||
if (FavourSize) {
|
||||
ldaconst (offs); /* Load A with offset value */
|
||||
AddCodeLine ("\tjsr\tleaasp"); /* Load effective address */
|
||||
} else {
|
||||
if (CPU == CPU_65C02 && offs == 1) {
|
||||
AddCodeLine ("\tlda\tsp");
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tina");
|
||||
AddCodeLine ("\tbne\t*+3");
|
||||
AddCodeLine ("\tinx");
|
||||
AddCodeHint ("x:!"); /* Invalidate X */
|
||||
} else {
|
||||
ldaconst (offs);
|
||||
AddCodeLine ("\tclc");
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tadc\tsp");
|
||||
AddCodeLine ("\tbcc\t*+3");
|
||||
AddCodeLine ("\tinx");
|
||||
AddCodeHint ("x:!"); /* Invalidate X */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void g_leavariadic (int Offs)
|
||||
/* Fetch the address of a parameter in a variadic function into the primary
|
||||
* register
|
||||
*/
|
||||
{
|
||||
unsigned ArgSizeOffs;
|
||||
|
||||
/* Calculate the offset relative to sp */
|
||||
Offs -= oursp;
|
||||
|
||||
/* Get the offset of the parameter which is stored at sp+0 on function
|
||||
* entry and check if this offset is reachable with a byte offset.
|
||||
*/
|
||||
CHECK (oursp <= 0);
|
||||
ArgSizeOffs = -oursp;
|
||||
CheckLocalOffs (ArgSizeOffs);
|
||||
|
||||
/* Get the stack pointer plus offset. Clear the carry as the result of
|
||||
* this sequence.
|
||||
*/
|
||||
if (Offs > 0) {
|
||||
AddCodeLine ("\tclc");
|
||||
AddCodeLine ("\tlda\tsp");
|
||||
AddCodeLine ("\tadc\t#$%02X", Offs & 0xFF);
|
||||
if (Offs >= 256) {
|
||||
AddCodeLine ("\tpha");
|
||||
AddCodeLine ("\tlda\tsp+1");
|
||||
AddCodeLine ("\tadc\t#$%02X", (Offs >> 8) & 0xFF);
|
||||
AddCodeLine ("\ttax");
|
||||
AddCodeLine ("\tpla");
|
||||
AddCodeLine ("\tclc");
|
||||
} else {
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tbcc\t*+4"); /* Jump over the clc */
|
||||
AddCodeLine ("\tinx");
|
||||
AddCodeHint ("x:!"); /* Invalidate X */
|
||||
AddCodeLine ("\tclc");
|
||||
}
|
||||
} else if (Offs < 0) {
|
||||
Offs = -Offs;
|
||||
AddCodeLine ("\tsec");
|
||||
AddCodeLine ("\tlda\tsp");
|
||||
AddCodeLine ("\tsbc\t#$%02X", Offs & 0xFF);
|
||||
if (Offs >= 256) {
|
||||
AddCodeLine ("\tpha");
|
||||
AddCodeLine ("\tlda\tsp+1");
|
||||
AddCodeLine ("\tsbc\t#$%02X", (Offs >> 8) & 0xFF);
|
||||
AddCodeLine ("\ttax");
|
||||
AddCodeLine ("\tpla");
|
||||
} else {
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tbcs\t*+3");
|
||||
AddCodeLine ("\tdex");
|
||||
AddCodeHint ("x:!"); /* Invalidate X */
|
||||
}
|
||||
AddCodeLine ("\tclc");
|
||||
} else {
|
||||
AddCodeLine ("\tlda\tsp");
|
||||
AddCodeLine ("\tldx\tsp+1");
|
||||
AddCodeLine ("\tclc");
|
||||
}
|
||||
|
||||
/* Add the size of all parameters. Carry is clear on entry. */
|
||||
if (ArgSizeOffs == 0 && CPU == CPU_65C02) {
|
||||
AddCodeLine ("\tadc\t(sp)");
|
||||
} else {
|
||||
ldyconst (ArgSizeOffs);
|
||||
AddCodeLine ("\tadc\t(sp),y");
|
||||
}
|
||||
AddCodeLine ("\tbcc\t*+3");
|
||||
AddCodeLine ("\tinx");
|
||||
AddCodeHint ("x:!"); /* Invalidate X */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Store into memory */
|
||||
/*****************************************************************************/
|
||||
|
@ -997,7 +1073,7 @@ void g_putstatic (unsigned flags, unsigned long label, unsigned offs)
|
|||
AddCodeLine ("\tldy\tsreg");
|
||||
AddCodeLine ("\tsty\t%s+2", lbuf);
|
||||
AddCodeLine ("\tldy\tsreg+1");
|
||||
AddCodeLine ("\tsty\t%s+3", lbuf);
|
||||
AddCodeLine ("\tsty\t%s+3", lbuf);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1083,7 +1159,7 @@ void g_putind (unsigned Flags, unsigned Offs)
|
|||
/* We can just add the high byte */
|
||||
AddCodeLine ("\tldy\t#$01");
|
||||
AddCodeLine ("\tclc");
|
||||
AddCodeLine ("\tpha");
|
||||
AddCodeLine ("\tpha");
|
||||
AddCodeLine ("\tlda\t#$%02X", (Offs >> 8) & 0xFF);
|
||||
AddCodeLine ("\tadc\t(sp),y");
|
||||
AddCodeLine ("\tsta\t(sp),y");
|
||||
|
@ -1642,7 +1718,7 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs,
|
|||
case CF_LONG:
|
||||
if (flags & CF_CONST) {
|
||||
if (val < 0x100) {
|
||||
AddCodeLine ("\tldy\t#<(%s)", lbuf);
|
||||
AddCodeLine ("\tldy\t#<(%s)", lbuf);
|
||||
AddCodeLine ("\tsty\tptr1");
|
||||
AddCodeLine ("\tldy\t#>(%s+1)", lbuf);
|
||||
if (val == 1) {
|
||||
|
@ -1771,7 +1847,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val)
|
|||
AddCodeLine ("\tadc\t(ptr1,x)");
|
||||
AddCodeLine ("\tsta\t(ptr1,x)");
|
||||
} else {
|
||||
AddCodeLine ("\tldy\t#$%02X", offs);
|
||||
AddCodeLine ("\tldy\t#$%02X", offs);
|
||||
AddCodeLine ("\tldx\t#$00");
|
||||
AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF));
|
||||
AddCodeLine ("\tclc");
|
||||
|
@ -1857,7 +1933,7 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
|
|||
|
||||
case CF_INT:
|
||||
AddCodeLine ("\tsec");
|
||||
if (flags & CF_CONST) {
|
||||
if (flags & CF_CONST) {
|
||||
AddCodeLine ("\tlda\t%s", lbuf);
|
||||
AddCodeLine ("\tsbc\t#$%02X", (unsigned char)val);
|
||||
AddCodeLine ("\tsta\t%s", lbuf);
|
||||
|
@ -1900,7 +1976,7 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
|
|||
AddCodeLine ("\tlda\t#$%02X", (unsigned char)val);
|
||||
AddCodeLine ("\tjsr\tlsubeqa");
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
g_getstatic (flags, label, offs);
|
||||
g_dec (flags, val);
|
||||
g_putstatic (flags, label, offs);
|
||||
|
@ -2029,7 +2105,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val)
|
|||
AddCodeLine ("\tiny");
|
||||
AddCodeLine ("\tlda\t(ptr1),y");
|
||||
AddCodeLine ("\tsbc\t#$%02X", (unsigned char)(val >> 8));
|
||||
AddCodeLine ("\tsta\t(ptr1),y");
|
||||
AddCodeLine ("\tsta\t(ptr1),y");
|
||||
AddCodeLine ("\ttax");
|
||||
AddCodeLine ("\tpla");
|
||||
break;
|
||||
|
@ -2115,7 +2191,7 @@ void g_save (unsigned flags)
|
|||
switch (flags & CF_TYPE) {
|
||||
|
||||
case CF_CHAR:
|
||||
if (flags & CF_FORCECHAR) {
|
||||
if (flags & CF_FORCECHAR) {
|
||||
AddCodeLine ("\tpha");
|
||||
break;
|
||||
}
|
||||
|
@ -2201,7 +2277,7 @@ void g_cmp (unsigned flags, unsigned long val)
|
|||
static void oper (unsigned flags, unsigned long val, char** subs)
|
||||
/* Encode a binary operation. subs is a pointer to four groups of three
|
||||
* strings:
|
||||
* 0-2 --> Operate on ints
|
||||
* 0-2 --> Operate on ints
|
||||
* 3-5 --> Operate on unsigneds
|
||||
* 6-8 --> Operate on longs
|
||||
* 9-11 --> Operate on unsigned longs
|
||||
|
@ -2244,7 +2320,7 @@ static void oper (unsigned flags, unsigned long val, char** subs)
|
|||
AddCodeLine ("\tjsr\t%s", subs [offs+2]);
|
||||
}
|
||||
} else {
|
||||
/* Value not constant (is already in (e)ax) */
|
||||
/* Value not constant (is already in (e)ax) */
|
||||
AddCodeLine ("\tjsr\t%s", subs [offs+2]);
|
||||
}
|
||||
|
||||
|
@ -3748,13 +3824,16 @@ void g_defdata (unsigned flags, unsigned long val, unsigned offs)
|
|||
|
||||
|
||||
|
||||
void g_defbytes (const unsigned char* Bytes, unsigned Count)
|
||||
void g_defbytes (const void* Bytes, unsigned Count)
|
||||
/* Output a row of bytes as a constant */
|
||||
{
|
||||
unsigned Chunk;
|
||||
char Buf [128];
|
||||
char* B;
|
||||
|
||||
/* Cast the buffer pointer */
|
||||
const unsigned char* Data = (const unsigned char*) Bytes;
|
||||
|
||||
/* Output the stuff */
|
||||
while (Count) {
|
||||
|
||||
|
@ -3768,7 +3847,7 @@ void g_defbytes (const unsigned char* Bytes, unsigned Count)
|
|||
strcpy (Buf, "\t.byte\t");
|
||||
B = Buf + 7;
|
||||
do {
|
||||
B += sprintf (B, "$%02X", *Bytes++ & 0xFF);
|
||||
B += sprintf (B, "$%02X", *Data++);
|
||||
if (--Chunk) {
|
||||
*B++ = ',';
|
||||
}
|
||||
|
|
|
@ -240,11 +240,27 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes);
|
|||
|
||||
|
||||
|
||||
void g_getimmed (unsigned flags, unsigned long val, unsigned offs);
|
||||
void g_getstatic (unsigned flags, unsigned long label, unsigned offs);
|
||||
void g_getlocal (unsigned flags, int offs);
|
||||
void g_getind (unsigned flags, unsigned offs);
|
||||
void g_leasp (int offs);
|
||||
void g_getimmed (unsigned Flags, unsigned long Val, unsigned Offs);
|
||||
/* Load a constant into the primary register */
|
||||
|
||||
void g_getstatic (unsigned Flags, unsigned long Label, unsigned Offs);
|
||||
/* Fetch an static memory cell into the primary register */
|
||||
|
||||
void g_getlocal (unsigned Flags, int Offs);
|
||||
/* Fetch specified local object (local var). */
|
||||
|
||||
void g_getind (unsigned Flags, unsigned Offs);
|
||||
/* Fetch the specified object type indirect through the primary register
|
||||
* into the primary register
|
||||
*/
|
||||
|
||||
void g_leasp (int Offs);
|
||||
/* Fetch the address of the specified symbol into the primary register */
|
||||
|
||||
void g_leavariadic (int Offs);
|
||||
/* Fetch the address of a parameter in a variadic function into the primary
|
||||
* register
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
@ -406,7 +422,7 @@ void g_res (unsigned n);
|
|||
void g_defdata (unsigned flags, unsigned long val, unsigned offs);
|
||||
/* Define data with the size given in flags */
|
||||
|
||||
void g_defbytes (const unsigned char *bytes, unsigned count);
|
||||
void g_defbytes (const void* bytes, unsigned count);
|
||||
/* Output a row of bytes as a constant */
|
||||
|
||||
void g_zerobytes (unsigned n);
|
||||
|
|
|
@ -112,7 +112,7 @@ type* TypeDup (const type* T)
|
|||
/* Create a copy of the given type on the heap */
|
||||
{
|
||||
unsigned Len = (TypeLen (T) + 1) * sizeof (type);
|
||||
return memcpy (xmalloc (Len), T, Len);
|
||||
return (type*) memcpy (xmalloc (Len), T, Len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,7 +122,7 @@ type* TypeAlloc (unsigned Len)
|
|||
* trailing T_END.
|
||||
*/
|
||||
{
|
||||
return xmalloc (Len * sizeof (type));
|
||||
return (type*) xmalloc (Len * sizeof (type));
|
||||
}
|
||||
|
||||
|
||||
|
@ -413,7 +413,7 @@ unsigned SizeOf (const type* T)
|
|||
|
||||
case T_STRUCT:
|
||||
case T_UNION:
|
||||
Entry = DecodePtr (T+1);
|
||||
Entry = (SymEntry*) DecodePtr (T+1);
|
||||
return Entry->V.S.Size;
|
||||
|
||||
case T_ARRAY:
|
||||
|
@ -475,7 +475,7 @@ unsigned TypeOf (const type* T)
|
|||
return CF_LONG | CF_UNSIGNED;
|
||||
|
||||
case T_FUNC:
|
||||
F = DecodePtr (T+1);
|
||||
F = (FuncDesc*) DecodePtr (T+1);
|
||||
return (F->Flags & FD_ELLIPSIS)? 0 : CF_FIXARGC;
|
||||
|
||||
case T_STRUCT:
|
||||
|
@ -642,18 +642,18 @@ int IsFastCallFunc (const type* T)
|
|||
{
|
||||
FuncDesc* F;
|
||||
CHECK (IsTypeFunc (T));
|
||||
F = DecodePtr (T+1);
|
||||
F = (FuncDesc*) DecodePtr (T+1);
|
||||
return (F->Flags & FD_FASTCALL) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int IsEllipsisFunc (const type* T)
|
||||
int IsVariadicFunc (const type* T)
|
||||
/* Return true if this is a function type with variable parameter list */
|
||||
{
|
||||
FuncDesc* F;
|
||||
CHECK (IsTypeFunc (T));
|
||||
F = DecodePtr (T+1);
|
||||
F = (FuncDesc*) DecodePtr (T+1);
|
||||
return (F->Flags & FD_ELLIPSIS) != 0;
|
||||
}
|
||||
|
||||
|
@ -668,7 +668,7 @@ int IsTypeFuncPtr (const type* T)
|
|||
|
||||
|
||||
type GetType (const type* T)
|
||||
/* Get the raw type */
|
||||
/* Get the raw type */
|
||||
{
|
||||
PRECONDITION (T[0] != T_END);
|
||||
return (T[0] & T_MASK_TYPE);
|
||||
|
@ -717,7 +717,7 @@ type GetQualifier (const type* T)
|
|||
|
||||
|
||||
|
||||
struct FuncDesc* GetFuncDesc (const type* T)
|
||||
FuncDesc* GetFuncDesc (const type* T)
|
||||
/* Get the FuncDesc pointer from a function or pointer-to-function type */
|
||||
{
|
||||
if (T[0] == T_PTR) {
|
||||
|
@ -729,7 +729,7 @@ struct FuncDesc* GetFuncDesc (const type* T)
|
|||
CHECK (T[0] == T_FUNC);
|
||||
|
||||
/* Decode the function descriptor and return it */
|
||||
return DecodePtr (T+1);
|
||||
return (FuncDesc*) DecodePtr (T+1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
/* common */
|
||||
#include "attrib.h"
|
||||
|
||||
/* cc65 */
|
||||
#include "funcdesc.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -283,7 +286,7 @@ int IsQualVolatile (const type* T) attribute ((const));
|
|||
int IsFastCallFunc (const type* T) attribute ((const));
|
||||
/* Return true if this is a function type with __fastcall__ calling conventions */
|
||||
|
||||
int IsEllipsisFunc (const type* T) attribute ((const));
|
||||
int IsVariadicFunc (const type* T) attribute ((const));
|
||||
/* Return true if this is a function type with variable parameter list */
|
||||
|
||||
int IsTypeFuncPtr (const type* T) attribute ((const));
|
||||
|
@ -304,7 +307,7 @@ type GetSizeModifier (const type* T) attribute ((const));
|
|||
type GetQualifier (const type* T) attribute ((const));
|
||||
/* Get the qualifier from the given type string */
|
||||
|
||||
struct FuncDesc* GetFuncDesc (const type* T) attribute ((const));
|
||||
FuncDesc* GetFuncDesc (const type* T) attribute ((const));
|
||||
/* Get the FuncDesc pointer from a function or pointer-to-function type */
|
||||
|
||||
|
||||
|
|
|
@ -775,10 +775,10 @@ static void Decl (Declaration* D, unsigned Mode)
|
|||
/* Set the fastcall flag */
|
||||
if (!IsTypeFunc (T)) {
|
||||
Error ("__fastcall__ modifier applied to non function");
|
||||
} else if (IsEllipsisFunc (T)) {
|
||||
} else if (IsVariadicFunc (T)) {
|
||||
Error ("Cannot apply __fastcall__ to functions with variable parameter list");
|
||||
} else {
|
||||
FuncDesc* F = DecodePtr (T+1);
|
||||
} else {
|
||||
FuncDesc* F = (FuncDesc*) DecodePtr (T+1);
|
||||
F->Flags |= FD_FASTCALL;
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -68,13 +68,13 @@ static attrib_t FindAttribute (const char* Attr)
|
|||
* Return atNone if the attribute name is not known.
|
||||
*/
|
||||
{
|
||||
attrib_t A;
|
||||
int A;
|
||||
|
||||
/* For now do a linear search */
|
||||
for (A = 0; A < atCount; ++A) {
|
||||
if (strcmp (Attr, AttrNames[A]) == 0) {
|
||||
/* Found */
|
||||
return A;
|
||||
return (attrib_t) A;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -783,9 +783,20 @@ static int primary (struct expent* lval)
|
|||
lval->e_name = (unsigned long) Sym->Name;
|
||||
lval->e_const = 0;
|
||||
} else if ((Sym->Flags & SC_AUTO) == SC_AUTO) {
|
||||
/* Local variable */
|
||||
lval->e_flags = E_MLOCAL | E_TLOFFS;
|
||||
lval->e_const = Sym->V.Offs;
|
||||
/* Local variable. If this is a parameter for a variadic
|
||||
* function, we have to add some address calculations, and the
|
||||
* address is not const.
|
||||
*/
|
||||
if ((Sym->Flags & SC_PARAM) == SC_PARAM && IsVariadic (CurrentFunc)) {
|
||||
/* Variadic parameter */
|
||||
g_leavariadic (Sym->V.Offs - GetParamSize (CurrentFunc));
|
||||
lval->e_flags = E_MEXPR;
|
||||
lval->e_const = 0;
|
||||
} else {
|
||||
/* Normal parameter */
|
||||
lval->e_flags = E_MLOCAL | E_TLOFFS;
|
||||
lval->e_const = Sym->V.Offs;
|
||||
}
|
||||
} else if ((Sym->Flags & SC_STATIC) == SC_STATIC) {
|
||||
/* Static variable */
|
||||
if (Sym->Flags & (SC_EXTERN | SC_STORAGE)) {
|
||||
|
@ -2915,7 +2926,7 @@ int evalexpr (unsigned flags, int (*f) (struct expent*), struct expent* lval)
|
|||
|
||||
|
||||
|
||||
int expr (int (*func) (), struct expent *lval)
|
||||
int expr (int (*func) (struct expent*), struct expent *lval)
|
||||
/* Expression parser; func is either hie0 or hie1. */
|
||||
{
|
||||
int k;
|
||||
|
|
|
@ -83,7 +83,7 @@ static ExprNodeBlock* NewExprNodeBlock (unsigned Count)
|
|||
unsigned Size = sizeof (ExprNodeBlock) + (Count-1) * sizeof (ExprNode);
|
||||
|
||||
/* Allocate memory */
|
||||
ExprNodeBlock* B = xmalloc (Size);
|
||||
ExprNodeBlock* B = (ExprNodeBlock*) xmalloc (Size);
|
||||
|
||||
/* Initialize the fields */
|
||||
B->Next = 0;
|
||||
|
@ -106,7 +106,7 @@ static ExprHeap* NewExprHeap (void)
|
|||
/* Create and return a new expression tree */
|
||||
{
|
||||
/* Allocate memory */
|
||||
ExprHeap* H = xmalloc (sizeof (ExprHeap));
|
||||
ExprHeap* H = (ExprHeap*) xmalloc (sizeof (ExprHeap));
|
||||
|
||||
/* Allocate the first node block */
|
||||
H->BlockRoot = NewExprNodeBlock (64);
|
||||
|
@ -214,7 +214,7 @@ void FreeExprTree (ExprNode* N)
|
|||
unsigned I;
|
||||
unsigned Count = CollCount (&N->List);
|
||||
for (I = 0; I < Count; ++I) {
|
||||
FreeExprNode (CollAt (&N->List, I));
|
||||
FreeExprNode ((ExprNode*) CollAt (&N->List, I));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ void SetRightNode (ExprNode* Root, ExprNode* Right)
|
|||
struct SymEntry* GetNodeSym (ExprNode* N)
|
||||
/* Get the symbol entry for a NT_SYM node */
|
||||
{
|
||||
return GetItem (N, IDX_SYM);
|
||||
return (struct SymEntry*) GetItem (N, IDX_SYM);
|
||||
}
|
||||
|
||||
|
||||
|
@ -247,7 +247,7 @@ void DumpExpr (FILE* F, const ExprNode* E)
|
|||
case NT_LIST_EXPR:
|
||||
Count = CollCount (&E->List);
|
||||
for (I = 0; I < Count; ++I) {
|
||||
DumpExpr (F, CollConstAt (&E->List, I));
|
||||
DumpExpr (F, (const ExprNode*) CollConstAt (&E->List, I));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ FuncDesc* NewFuncDesc (void)
|
|||
/* Create a new symbol table with the given name */
|
||||
{
|
||||
/* Create a new function descriptor */
|
||||
FuncDesc* F = xmalloc (sizeof (FuncDesc));
|
||||
FuncDesc* F = (FuncDesc*) xmalloc (sizeof (FuncDesc));
|
||||
|
||||
/* Nullify the fields */
|
||||
F->Flags = 0;
|
||||
|
|
|
@ -84,12 +84,12 @@ static Function* NewFunction (struct SymEntry* Sym)
|
|||
/* Create a new function activation structure and return it */
|
||||
{
|
||||
/* Allocate a new structure */
|
||||
Function* F = xmalloc (sizeof (Function));
|
||||
Function* F = (Function*) xmalloc (sizeof (Function));
|
||||
|
||||
/* Initialize the fields */
|
||||
F->FuncEntry = Sym;
|
||||
F->ReturnType = Sym->Type + 1 + DECODE_SIZE;
|
||||
F->Desc = DecodePtr (Sym->Type + 1);
|
||||
F->Desc = (FuncDesc*) DecodePtr (Sym->Type + 1);
|
||||
F->EntryCode = 0;
|
||||
F->Reserved = 0;
|
||||
F->RetLab = GetLabel ();
|
||||
|
@ -148,6 +148,14 @@ int HasVoidReturn (const Function* F)
|
|||
|
||||
|
||||
|
||||
int IsVariadic (const Function* F)
|
||||
/* Return true if this is a variadic function */
|
||||
{
|
||||
return (F->Desc->Flags & FD_ELLIPSIS) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RememberEntry (Function* F)
|
||||
/* Remember the current output position for local space creation later */
|
||||
{
|
||||
|
@ -211,7 +219,7 @@ void NewFunc (SymEntry* Func)
|
|||
unsigned Flags;
|
||||
|
||||
/* Get the function descriptor from the function entry */
|
||||
FuncDesc* D = DecodePtr (Func->Type+1);
|
||||
FuncDesc* D = (FuncDesc*) DecodePtr (Func->Type+1);
|
||||
|
||||
/* Allocate the function activation record for the function */
|
||||
CurrentFunc = NewFunction (Func);
|
||||
|
|
|
@ -46,6 +46,9 @@ type* GetReturnType (Function* F);
|
|||
int HasVoidReturn (const Function* F);
|
||||
/* Return true if the function does not have a return value */
|
||||
|
||||
int IsVariadic (const Function* F);
|
||||
/* Return true if this is a variadic function */
|
||||
|
||||
void RememberEntry (Function* F);
|
||||
/* Remember the current output position for local space creation later */
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
/* common */
|
||||
#include "xmalloc.h"
|
||||
|
||||
|
||||
/* cc65 */
|
||||
#include "incpath.h"
|
||||
|
||||
|
@ -86,7 +86,7 @@ static char* Add (char* Orig, const char* New)
|
|||
}
|
||||
|
||||
/* Allocate memory for the new string */
|
||||
NewPath = xmalloc (OrigLen + NewLen + 2);
|
||||
NewPath = (char*) xmalloc (OrigLen + NewLen + 2);
|
||||
|
||||
/* Copy the strings */
|
||||
memcpy (NewPath, Orig, OrigLen);
|
||||
|
|
|
@ -106,7 +106,7 @@ static IFile* NewIFile (const char* Name)
|
|||
unsigned Len = strlen (Name);
|
||||
|
||||
/* Allocate a IFile structure */
|
||||
IFile* IF = xmalloc (sizeof (IFile) + Len);
|
||||
IFile* IF = (IFile*) xmalloc (sizeof (IFile) + Len);
|
||||
|
||||
/* Initialize the fields */
|
||||
IF->Index = CollCount (&IFiles) + 1;
|
||||
|
@ -132,7 +132,7 @@ static AFile* NewAFile (IFile* IF, FILE* F)
|
|||
/* Create and return a new AFile */
|
||||
{
|
||||
/* Allocate a AFile structure */
|
||||
AFile* AF = xmalloc (sizeof (AFile));
|
||||
AFile* AF = (AFile*) xmalloc (sizeof (AFile));
|
||||
|
||||
/* Initialize the fields */
|
||||
AF->Line = 0;
|
||||
|
@ -174,7 +174,7 @@ static IFile* FindFile (const char* Name)
|
|||
unsigned I;
|
||||
for (I = 0; I < CollCount (&IFiles); ++I) {
|
||||
/* Get the file struct */
|
||||
IFile* IF = CollAt (&IFiles, I);
|
||||
IFile* IF = (IFile*) CollAt (&IFiles, I);
|
||||
/* Check the name */
|
||||
if (strcmp (Name, IF->Name) == 0) {
|
||||
/* Found, return the struct */
|
||||
|
@ -266,7 +266,7 @@ static void CloseIncludeFile (void)
|
|||
PRECONDITION (AFileCount > 0);
|
||||
|
||||
/* Get the current active input file */
|
||||
Input = CollLast (&AFiles);
|
||||
Input = (AFile*) CollLast (&AFiles);
|
||||
|
||||
/* Close the current input file (we're just reading so no error check) */
|
||||
fclose (Input->F);
|
||||
|
@ -342,7 +342,7 @@ int NextLine (void)
|
|||
if (CollCount (&AFiles) == 0) {
|
||||
return 0;
|
||||
}
|
||||
Input = CollLast (&AFiles);
|
||||
Input = (AFile*) CollLast (&AFiles);
|
||||
|
||||
/* Read lines until we get one with real contents */
|
||||
Len = 0;
|
||||
|
@ -363,7 +363,7 @@ int NextLine (void)
|
|||
if (CollCount (&AFiles) == 0) {
|
||||
return 0;
|
||||
}
|
||||
Input = CollLast (&AFiles);
|
||||
Input = (AFile*) CollLast (&AFiles);
|
||||
|
||||
}
|
||||
|
||||
|
@ -410,13 +410,13 @@ const char* GetCurrentFile (void)
|
|||
{
|
||||
unsigned AFileCount = CollCount (&AFiles);
|
||||
if (AFileCount > 0) {
|
||||
const AFile* AF = CollAt (&AFiles, AFileCount-1);
|
||||
const AFile* AF = (const AFile*) CollAt (&AFiles, AFileCount-1);
|
||||
return AF->Name;
|
||||
} else {
|
||||
/* No open file. Use the main file if we have one. */
|
||||
unsigned IFileCount = CollCount (&IFiles);
|
||||
if (IFileCount > 0) {
|
||||
const IFile* IF = CollAt (&IFiles, 0);
|
||||
const IFile* IF = (const IFile*) CollAt (&IFiles, 0);
|
||||
return IF->Name;
|
||||
} else {
|
||||
return "(outside file scope)";
|
||||
|
@ -431,7 +431,7 @@ unsigned GetCurrentLine (void)
|
|||
{
|
||||
unsigned AFileCount = CollCount (&AFiles);
|
||||
if (AFileCount > 0) {
|
||||
const AFile* AF = CollAt (&AFiles, AFileCount-1);
|
||||
const AFile* AF = (const AFile*) CollAt (&AFiles, AFileCount-1);
|
||||
return AF->Line;
|
||||
} else {
|
||||
/* No open file */
|
||||
|
@ -455,7 +455,7 @@ void WriteDependencies (FILE* F, const char* OutputFile)
|
|||
/* Loop over all files */
|
||||
for (I = 0; I < IFileCount; ++I) {
|
||||
/* Get the next input file */
|
||||
const IFile* IF = CollAt (&IFiles, I);
|
||||
const IFile* IF = (const IFile*) CollAt (&IFiles, I);
|
||||
/* If this is not the first file, add a space */
|
||||
const char* Format = (I == 0)? "%s" : " %s";
|
||||
/* Print the dependency */
|
||||
|
|
|
@ -84,7 +84,7 @@ void InitRegVars (void)
|
|||
* will usually waste some space but we don't need to dynamically
|
||||
* grow the array.
|
||||
*/
|
||||
RegSyms = xmalloc (MaxRegSpace * sizeof (RegSyms[0]));
|
||||
RegSyms = (const SymEntry**) xmalloc (MaxRegSpace * sizeof (RegSyms[0]));
|
||||
RegOffs = MaxRegSpace;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,10 +63,8 @@ LoopDesc* AddLoop (unsigned sp, unsigned loop, unsigned label,
|
|||
unsigned linc, unsigned lstat)
|
||||
/* Create and add a new loop descriptor */
|
||||
{
|
||||
LoopDesc* L;
|
||||
|
||||
/* Allocate a new struct */
|
||||
L = xmalloc (sizeof (LoopDesc));
|
||||
LoopDesc* L = (LoopDesc*) xmalloc (sizeof (LoopDesc));
|
||||
|
||||
/* Fill in the data */
|
||||
L->StackPtr = sp;
|
||||
|
|
|
@ -79,7 +79,7 @@ Macro* NewMacro (const char* Name)
|
|||
unsigned Len = strlen(Name);
|
||||
|
||||
/* Allocate the structure */
|
||||
Macro* M = xmalloc (sizeof(Macro) + Len);
|
||||
Macro* M = (Macro*) xmalloc (sizeof(Macro) + Len);
|
||||
|
||||
/* Initialize the data */
|
||||
M->Next = 0;
|
||||
|
@ -152,7 +152,7 @@ void InsertMacro (Macro* M)
|
|||
|
||||
/* Allocate the ActualArgs parameter array */
|
||||
if (M->ArgCount > 0) {
|
||||
M->ActualArgs = xmalloc (M->ArgCount * sizeof(char*));
|
||||
M->ActualArgs = (char const**) xmalloc (M->ArgCount * sizeof(char*));
|
||||
}
|
||||
|
||||
/* Get the hash value of the macro name */
|
||||
|
@ -291,11 +291,11 @@ void AddMacroArg (Macro* M, const char* Arg)
|
|||
/* Check if we have enough room available, otherwise expand the array
|
||||
* that holds the formal argument list.
|
||||
*/
|
||||
if (M->ArgCount >= M->MaxArgs) {
|
||||
if (M->ArgCount >= (int) M->MaxArgs) {
|
||||
/* We must expand the array */
|
||||
char** OldArgs = M->FormalArgs;
|
||||
M->MaxArgs += 10;
|
||||
M->FormalArgs = xmalloc (M->MaxArgs * sizeof(char*));
|
||||
M->FormalArgs = (char**) xmalloc (M->MaxArgs * sizeof(char*));
|
||||
memcpy (M->FormalArgs, OldArgs, M->ArgCount * sizeof (char*));
|
||||
xfree (OldArgs);
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ static void DefineSym (const char* Def)
|
|||
*/
|
||||
char* Q;
|
||||
unsigned Len = strlen (Def)+1;
|
||||
char* S = xmalloc (Len);
|
||||
char* S = (char*) xmalloc (Len);
|
||||
memcpy (S, Def, Len);
|
||||
Q = S + (P - Def);
|
||||
*Q++ = '\0';
|
||||
|
@ -473,7 +473,7 @@ int main (int argc, char* argv[])
|
|||
|
||||
/* Parse the command line */
|
||||
I = 1;
|
||||
while (I < ArgCount) {
|
||||
while (I < (int)ArgCount) {
|
||||
|
||||
const char* P;
|
||||
|
||||
|
|
|
@ -67,9 +67,9 @@ static void StdFunc_strlen (struct expent*);
|
|||
/* Table with all known functions and their handlers. Must be sorted
|
||||
* alphabetically!
|
||||
*/
|
||||
static struct FuncDesc {
|
||||
const char* Name;
|
||||
void (*Handler) (struct expent*);
|
||||
static struct StdFuncDesc {
|
||||
const char* Name;
|
||||
void (*Handler) (struct expent*);
|
||||
} StdFuncs [] = {
|
||||
{ "strlen", StdFunc_strlen },
|
||||
|
||||
|
@ -86,12 +86,12 @@ static struct FuncDesc {
|
|||
static int CmpFunc (const void* Key, const void* Elem)
|
||||
/* Compare function for bsearch */
|
||||
{
|
||||
return strcmp ((const char*) Key, ((const struct FuncDesc*) Elem)->Name);
|
||||
return strcmp ((const char*) Key, ((const struct StdFuncDesc*) Elem)->Name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct FuncDesc* FindFunc (const char* Name)
|
||||
static struct StdFuncDesc* FindFunc (const char* Name)
|
||||
/* Find a function with the given name. Return a pointer to the descriptor if
|
||||
* found, return NULL otherwise.
|
||||
*/
|
||||
|
@ -102,7 +102,7 @@ static struct FuncDesc* FindFunc (const char* Name)
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Handle known functions */
|
||||
/* Handle known functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -173,7 +173,7 @@ void HandleStdFunc (struct expent* lval)
|
|||
/* Generate code for a known standard function. */
|
||||
{
|
||||
/* Get a pointer to the table entry */
|
||||
struct FuncDesc* F = FindFunc ((const char*) lval->e_name);
|
||||
struct StdFuncDesc* F = FindFunc ((const char*) lval->e_name);
|
||||
CHECK (F != 0);
|
||||
|
||||
/* Call the handler function */
|
||||
|
|
Loading…
Add table
Reference in a new issue