Merge remote-tracking branch 'upstream/master' into pcenginetarget
This commit is contained in:
116
src/ca65/expr.c
116
src/ca65/expr.c
@@ -62,6 +62,7 @@
|
||||
#include "symtab.h"
|
||||
#include "toklist.h"
|
||||
#include "ulabel.h"
|
||||
#include "macro.h"
|
||||
|
||||
|
||||
|
||||
@@ -417,6 +418,34 @@ static ExprNode* FuncDefined (void)
|
||||
|
||||
|
||||
|
||||
static ExprNode* FuncIsMnemonic (void)
|
||||
/* Handle the .ISMNEMONIC, .ISMNEM builtin function */
|
||||
{
|
||||
int Instr = -1;
|
||||
|
||||
/* Check for a macro or an instruction depending on UbiquitousIdents */
|
||||
|
||||
if (CurTok.Tok == TOK_IDENT) {
|
||||
if (UbiquitousIdents) {
|
||||
/* Macros CAN be instructions, so check for them first */
|
||||
if (FindMacro (&CurTok.SVal) == 0) {
|
||||
Instr = FindInstruction (&CurTok.SVal);
|
||||
}
|
||||
} else {
|
||||
/* Macros and symbols may NOT use the names of instructions, so just check for the instruction */
|
||||
Instr = FindInstruction (&CurTok.SVal);
|
||||
}
|
||||
} else {
|
||||
Error ("Identifier expected.");
|
||||
}
|
||||
/* Skip the name */
|
||||
NextTok ();
|
||||
|
||||
return GenLiteralExpr (Instr > 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ExprNode* FuncHiByte (void)
|
||||
/* Handle the .HIBYTE builtin function */
|
||||
{
|
||||
@@ -629,6 +658,85 @@ static ExprNode* FuncReferenced (void)
|
||||
|
||||
|
||||
|
||||
static ExprNode* FuncAddrSize (void)
|
||||
/* Handle the .ADDRSIZE function */
|
||||
{
|
||||
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
|
||||
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||
SymEntry* Sym;
|
||||
int AddrSize;
|
||||
int NoScope;
|
||||
|
||||
|
||||
/* Assume we don't know the size */
|
||||
AddrSize = 0;
|
||||
|
||||
/* Check for a cheap local which needs special handling */
|
||||
if (CurTok.Tok == TOK_LOCAL_IDENT) {
|
||||
|
||||
/* Cheap local symbol */
|
||||
Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
|
||||
if (Sym == 0) {
|
||||
Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
|
||||
} else {
|
||||
AddrSize = Sym->AddrSize;
|
||||
}
|
||||
|
||||
/* Remember and skip SVal, terminate ScopeName so it is empty */
|
||||
SB_Copy (&Name, &CurTok.SVal);
|
||||
NextTok ();
|
||||
SB_Terminate (&ScopeName);
|
||||
|
||||
} else {
|
||||
|
||||
/* Parse the scope and the name */
|
||||
SymTable* ParentScope = ParseScopedIdent (&Name, &ScopeName);
|
||||
|
||||
/* Check if the parent scope is valid */
|
||||
if (ParentScope == 0) {
|
||||
/* No such scope */
|
||||
SB_Done (&ScopeName);
|
||||
SB_Done (&Name);
|
||||
return GenLiteral0 ();
|
||||
}
|
||||
|
||||
/* If ScopeName is empty, no explicit scope was specified. We have to
|
||||
** search upper scope levels in this case.
|
||||
*/
|
||||
NoScope = SB_IsEmpty (&ScopeName);
|
||||
|
||||
/* If we did find a scope with the name, read the symbol defining the
|
||||
** size, otherwise search for a symbol entry with the name and scope.
|
||||
*/
|
||||
if (NoScope) {
|
||||
Sym = SymFindAny (ParentScope, &Name);
|
||||
} else {
|
||||
Sym = SymFind (ParentScope, &Name, SYM_FIND_EXISTING);
|
||||
}
|
||||
/* If we found the symbol retrieve the size, otherwise complain */
|
||||
if (Sym) {
|
||||
AddrSize = Sym->AddrSize;
|
||||
} else {
|
||||
Error ("Unknown symbol or scope: `%m%p%m%p'", &ScopeName, &Name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (AddrSize == 0) {
|
||||
Warning (1, "Unknown address size: `%m%p%m%p'", &ScopeName, &Name);
|
||||
}
|
||||
|
||||
/* Free the string buffers */
|
||||
SB_Done (&ScopeName);
|
||||
SB_Done (&Name);
|
||||
|
||||
/* Return the size. */
|
||||
|
||||
return GenLiteralExpr (AddrSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ExprNode* FuncSizeOf (void)
|
||||
/* Handle the .SIZEOF function */
|
||||
{
|
||||
@@ -965,6 +1073,10 @@ static ExprNode* Factor (void)
|
||||
N = Function (FuncBankByte);
|
||||
break;
|
||||
|
||||
case TOK_ADDRSIZE:
|
||||
N = Function (FuncAddrSize);
|
||||
break;
|
||||
|
||||
case TOK_BLANK:
|
||||
N = Function (FuncBlank);
|
||||
break;
|
||||
@@ -982,6 +1094,10 @@ static ExprNode* Factor (void)
|
||||
N = Function (FuncDefined);
|
||||
break;
|
||||
|
||||
case TOK_ISMNEMONIC:
|
||||
N = Function (FuncIsMnemonic);
|
||||
break;
|
||||
|
||||
case TOK_HIBYTE:
|
||||
N = Function (FuncHiByte);
|
||||
break;
|
||||
|
||||
@@ -63,6 +63,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
|
||||
"c_comments",
|
||||
"force_range",
|
||||
"underline_in_numbers",
|
||||
"addrsize",
|
||||
};
|
||||
|
||||
|
||||
@@ -119,6 +120,7 @@ feature_t SetFeature (const StrBuf* Key)
|
||||
case FEAT_C_COMMENTS: CComments = 1; break;
|
||||
case FEAT_FORCE_RANGE: ForceRange = 1; break;
|
||||
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break;
|
||||
case FEAT_ADDRSIZE: AddrSize = 1; break;
|
||||
default: /* Keep gcc silent */ break;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef enum {
|
||||
FEAT_C_COMMENTS,
|
||||
FEAT_FORCE_RANGE,
|
||||
FEAT_UNDERLINE_IN_NUMBERS,
|
||||
FEAT_ADDRSIZE,
|
||||
|
||||
/* Special value: Number of features available */
|
||||
FEAT_COUNT
|
||||
|
||||
@@ -82,3 +82,4 @@ unsigned char OrgPerSeg = 0; /* Make .org local to current seg */
|
||||
unsigned char CComments = 0; /* Allow C like comments */
|
||||
unsigned char ForceRange = 0; /* Force values into expected range */
|
||||
unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */
|
||||
unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */
|
||||
|
||||
@@ -84,6 +84,8 @@ extern unsigned char OrgPerSeg; /* Make .org local to current seg */
|
||||
extern unsigned char CComments; /* Allow C like comments */
|
||||
extern unsigned char ForceRange; /* Force values into expected range */
|
||||
extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */
|
||||
extern unsigned char AddrSize; /* Allow .ADDRSIZE function */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -713,9 +713,9 @@ static const struct {
|
||||
{ "ROR", 0x000006F, 0x62, 1, PutAll },
|
||||
{ "RTI", 0x0000001, 0x40, 0, PutAll },
|
||||
{ "RTS", 0x0000001, 0x60, 0, PutAll },
|
||||
{ "SBC", 0x080A66C, 0xe0, 0, PutAll },
|
||||
{ "SAX", 0x0000001, 0x22, 0, PutAll },
|
||||
{ "SAY", 0x0000001, 0x42, 0, PutAll },
|
||||
{ "SBC", 0x080A66C, 0xe0, 0, PutAll },
|
||||
{ "SEC", 0x0000001, 0x38, 0, PutAll },
|
||||
{ "SED", 0x0000001, 0xf8, 0, PutAll },
|
||||
{ "SEI", 0x0000001, 0x78, 0, PutAll },
|
||||
|
||||
@@ -303,6 +303,10 @@ static void SetSys (const char* Sys)
|
||||
NewSymbol ("__SIM65C02__", 1);
|
||||
break;
|
||||
|
||||
case TGT_OSIC1P:
|
||||
NewSymbol ("__OSIC1P__", 1);
|
||||
break;
|
||||
|
||||
case TGT_PCENGINE:
|
||||
NewSymbol ("__PCE__", 1);
|
||||
break;
|
||||
|
||||
@@ -1964,6 +1964,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoA16 },
|
||||
{ ccNone, DoA8 },
|
||||
{ ccNone, DoAddr }, /* .ADDR */
|
||||
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
|
||||
{ ccNone, DoAlign },
|
||||
{ ccNone, DoASCIIZ },
|
||||
{ ccNone, DoAssert },
|
||||
@@ -2039,6 +2040,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoIncBin },
|
||||
{ ccNone, DoInclude },
|
||||
{ ccNone, DoInterruptor },
|
||||
{ ccNone, DoUnexpected }, /* .ISMNEMONIC */
|
||||
{ ccNone, DoInvalid }, /* .LEFT */
|
||||
{ ccNone, DoLineCont },
|
||||
{ ccNone, DoList },
|
||||
|
||||
@@ -135,6 +135,7 @@ struct DotKeyword {
|
||||
{ ".A16", TOK_A16 },
|
||||
{ ".A8", TOK_A8 },
|
||||
{ ".ADDR", TOK_ADDR },
|
||||
{ ".ADDRSIZE", TOK_ADDRSIZE },
|
||||
{ ".ALIGN", TOK_ALIGN },
|
||||
{ ".AND", TOK_BOOLAND },
|
||||
{ ".ASCIIZ", TOK_ASCIIZ },
|
||||
@@ -222,6 +223,8 @@ struct DotKeyword {
|
||||
{ ".INCBIN", TOK_INCBIN },
|
||||
{ ".INCLUDE", TOK_INCLUDE },
|
||||
{ ".INTERRUPTOR", TOK_INTERRUPTOR },
|
||||
{ ".ISMNEM", TOK_ISMNEMONIC },
|
||||
{ ".ISMNEMONIC", TOK_ISMNEMONIC },
|
||||
{ ".LEFT", TOK_LEFT },
|
||||
{ ".LINECONT", TOK_LINECONT },
|
||||
{ ".LIST", TOK_LIST },
|
||||
@@ -723,7 +726,24 @@ static token_t FindDotKeyword (void)
|
||||
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
|
||||
sizeof (DotKeywords [0]), CmpDotKeyword);
|
||||
if (R != 0) {
|
||||
|
||||
/* By default, disable any somewhat experiemental DotKeyword. */
|
||||
|
||||
switch (R->Tok) {
|
||||
|
||||
case TOK_ADDRSIZE:
|
||||
/* Disallow .ADDRSIZE function by default */
|
||||
if (AddrSize == 0) {
|
||||
return TOK_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return R->Tok;
|
||||
|
||||
} else {
|
||||
return TOK_NONE;
|
||||
}
|
||||
|
||||
@@ -696,10 +696,10 @@ void SymDump (FILE* F)
|
||||
|
||||
while (S) {
|
||||
/* Ignore unused symbols */
|
||||
if ((S->Flags & SF_UNUSED) != 0) {
|
||||
if ((S->Flags & SF_UNUSED) == 0) {
|
||||
fprintf (F,
|
||||
"%m%-24p %s %s %s %s %s\n",
|
||||
GetSymName (S),
|
||||
"%-24s %s %s %s %s %s\n",
|
||||
SB_GetConstBuf (GetSymName (S)),
|
||||
(S->Flags & SF_DEFINED)? "DEF" : "---",
|
||||
(S->Flags & SF_REFERENCED)? "REF" : "---",
|
||||
(S->Flags & SF_IMPORT)? "IMP" : "---",
|
||||
|
||||
@@ -123,6 +123,7 @@ typedef enum token_t {
|
||||
TOK_A16 = TOK_FIRSTPSEUDO,
|
||||
TOK_A8,
|
||||
TOK_ADDR,
|
||||
TOK_ADDRSIZE,
|
||||
TOK_ALIGN,
|
||||
TOK_ASCIIZ,
|
||||
TOK_ASSERT,
|
||||
@@ -198,6 +199,7 @@ typedef enum token_t {
|
||||
TOK_INCBIN,
|
||||
TOK_INCLUDE,
|
||||
TOK_INTERRUPTOR,
|
||||
TOK_ISMNEMONIC,
|
||||
TOK_LEFT,
|
||||
TOK_LINECONT,
|
||||
TOK_LIST,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001-2012, Ullrich von Bassewitz */
|
||||
/* (C) 2001-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "codeseg.h"
|
||||
#include "datatype.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "reginfo.h"
|
||||
#include "symtab.h"
|
||||
#include "codeinfo.h"
|
||||
@@ -386,33 +387,35 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
|
||||
** Search for it in the list of builtin functions.
|
||||
*/
|
||||
if (Name[0] == '_') {
|
||||
|
||||
/* Search in the symbol table, skip the leading underscore */
|
||||
SymEntry* E = FindGlobalSym (Name+1);
|
||||
|
||||
/* Did we find it in the top level table? */
|
||||
/* Did we find it in the top-level table? */
|
||||
if (E && IsTypeFunc (E->Type)) {
|
||||
|
||||
FuncDesc* D = E->V.F.Func;
|
||||
|
||||
/* A function may use the A or A/X registers if it is a fastcall
|
||||
** function. If it is not a fastcall function but a variadic one,
|
||||
** it will use the Y register (the parameter size is passed here).
|
||||
** In all other cases, no registers are used. However, we assume
|
||||
** that any function will destroy all registers.
|
||||
/* A variadic function will use the Y register (the parameter list
|
||||
** size is passed there). A fastcall function will use the A or A/X
|
||||
** registers. In all other cases, no registers are used. However,
|
||||
** we assume that any function will destroy all registers.
|
||||
*/
|
||||
if (IsQualFastcall (E->Type) && D->ParamCount > 0) {
|
||||
/* Will use registers depending on the last param */
|
||||
unsigned LastParamSize = CheckedSizeOf (D->LastParam->Type);
|
||||
if (LastParamSize == 1) {
|
||||
*Use = REG_A;
|
||||
} else if (LastParamSize == 2) {
|
||||
*Use = REG_AX;
|
||||
} else {
|
||||
*Use = REG_EAX;
|
||||
}
|
||||
} else if ((D->Flags & FD_VARIADIC) != 0) {
|
||||
if ((D->Flags & FD_VARIADIC) != 0) {
|
||||
*Use = REG_Y;
|
||||
} else if (D->ParamCount > 0 &&
|
||||
(AutoCDecl ?
|
||||
IsQualFastcall (E->Type) :
|
||||
!IsQualCDecl (E->Type))) {
|
||||
/* Will use registers depending on the last param. */
|
||||
switch (CheckedSizeOf (D->LastParam->Type)) {
|
||||
case 1u:
|
||||
*Use = REG_A;
|
||||
break;
|
||||
case 2u:
|
||||
*Use = REG_AX;
|
||||
break;
|
||||
default:
|
||||
*Use = REG_EAX;
|
||||
}
|
||||
} else {
|
||||
/* Will not use any registers */
|
||||
*Use = REG_NONE;
|
||||
|
||||
@@ -766,12 +766,8 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer
|
||||
InsertEntry (D, X, D->IP++);
|
||||
|
||||
/* Lhs load entries can be removed */
|
||||
if (LoadX->AM != AM65_IMM) {
|
||||
D->Lhs.X.Flags |= LI_REMOVE;
|
||||
}
|
||||
if (LoadA->AM != AM65_IMM) {
|
||||
D->Lhs.A.Flags |= LI_REMOVE;
|
||||
}
|
||||
D->Lhs.X.Flags |= LI_REMOVE;
|
||||
D->Lhs.A.Flags |= LI_REMOVE;
|
||||
|
||||
} else if ((D->Rhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT &&
|
||||
(D->Rhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT) {
|
||||
@@ -794,12 +790,8 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer
|
||||
InsertEntry (D, X, D->IP++);
|
||||
|
||||
/* Rhs load entries can be removed */
|
||||
if (LoadX->AM != AM65_IMM) {
|
||||
D->Rhs.X.Flags |= LI_REMOVE;
|
||||
}
|
||||
if (LoadA->AM != AM65_IMM) {
|
||||
D->Rhs.A.Flags |= LI_REMOVE;
|
||||
}
|
||||
D->Rhs.X.Flags |= LI_REMOVE;
|
||||
D->Rhs.A.Flags |= LI_REMOVE;
|
||||
|
||||
} else if ((D->Rhs.A.Flags & LI_DIRECT) != 0 &&
|
||||
(D->Rhs.X.Flags & LI_DIRECT) != 0) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -293,15 +293,15 @@ void PrintType (FILE* F, const Type* T)
|
||||
/* Recursive call */
|
||||
PrintType (F, T + 1);
|
||||
if (T->A.L == UNSPECIFIED) {
|
||||
fprintf (F, "[]");
|
||||
fprintf (F, " []");
|
||||
} else {
|
||||
fprintf (F, "[%ld]", T->A.L);
|
||||
fprintf (F, " [%ld]", T->A.L);
|
||||
}
|
||||
return;
|
||||
case T_TYPE_PTR:
|
||||
/* Recursive call */
|
||||
PrintType (F, T + 1);
|
||||
fprintf (F, "*");
|
||||
fprintf (F, " *");
|
||||
return;
|
||||
case T_TYPE_FUNC:
|
||||
fprintf (F, "function returning ");
|
||||
@@ -659,7 +659,7 @@ Type* GetBaseElementType (Type* T)
|
||||
** will return. Otherwise it will return the base element type, which means
|
||||
** the element type that is not an array.
|
||||
*/
|
||||
{
|
||||
{
|
||||
while (IsTypeArray (T)) {
|
||||
++T;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -603,6 +603,16 @@ INLINE int IsQualCDecl (const Type* T)
|
||||
# define IsQualCDecl(T) (((T)->C & T_QUAL_CDECL) != 0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int IsQualCConv (const Type* T)
|
||||
/* Return true if the given type has a calling convention qualifier */
|
||||
{
|
||||
return (T->C & T_QUAL_CCONV) != 0;
|
||||
}
|
||||
#else
|
||||
# define IsQualCConv(T) (((T)->C & T_QUAL_CCONV) != 0)
|
||||
#endif
|
||||
|
||||
int IsVariadicFunc (const Type* T) attribute ((const));
|
||||
/* Return true if this is a function type or pointer to function type with
|
||||
** variable parameter list
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2013, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -85,7 +85,7 @@ struct StructInitData {
|
||||
|
||||
|
||||
static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers);
|
||||
/* Parse a type specificier */
|
||||
/* Parse a type specifier */
|
||||
|
||||
static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers);
|
||||
/* Parse initialization of variables. Return the number of data bytes. */
|
||||
@@ -335,18 +335,30 @@ static void FixQualifiers (Type* DataType)
|
||||
T = DataType;
|
||||
while (T->C != T_END) {
|
||||
if (IsTypePtr (T)) {
|
||||
/* Calling convention qualifier on the pointer? */
|
||||
if (IsQualCConv (T)) {
|
||||
/* Pull the convention off of the pointer */
|
||||
Q = T[0].C & T_QUAL_CCONV;
|
||||
T[0].C &= ~T_QUAL_CCONV;
|
||||
|
||||
/* Fastcall qualifier on the pointer? */
|
||||
if (IsQualFastcall (T)) {
|
||||
/* Pointer to function which is not fastcall? */
|
||||
if (IsTypeFunc (T+1) && !IsQualFastcall (T+1)) {
|
||||
/* Move the fastcall qualifier from the pointer to
|
||||
** the function.
|
||||
*/
|
||||
T[0].C &= ~T_QUAL_FASTCALL;
|
||||
T[1].C |= T_QUAL_FASTCALL;
|
||||
/* Pointer to a function which doesn't have an explicit convention? */
|
||||
if (IsTypeFunc (T + 1)) {
|
||||
if (IsQualCConv (T + 1)) {
|
||||
if ((T[1].C & T_QUAL_CCONV) == Q) {
|
||||
Warning ("Pointer duplicates function's calling convention");
|
||||
} else {
|
||||
Error ("Function's and pointer's calling conventions are different");
|
||||
}
|
||||
} else {
|
||||
if (Q == T_QUAL_FASTCALL && IsVariadicFunc (T + 1)) {
|
||||
Error ("Variadic-function pointers cannot be __fastcall__");
|
||||
} else {
|
||||
/* Move the qualifier from the pointer to the function. */
|
||||
T[1].C |= Q;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Error ("Invalid `_fastcall__' qualifier for pointer");
|
||||
Error ("Not pointer to a function; can't use a calling convention");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,8 +367,8 @@ static void FixQualifiers (Type* DataType)
|
||||
if (Q == T_QUAL_NONE) {
|
||||
/* No address size qualifiers specified */
|
||||
if (IsTypeFunc (T+1)) {
|
||||
/* Pointer to function. Use the qualifier from the function
|
||||
** or the default if the function don't has one.
|
||||
/* Pointer to function. Use the qualifier from the function,
|
||||
** or the default if the function doesn't have one.
|
||||
*/
|
||||
Q = (T[1].C & T_QUAL_ADDRSIZE);
|
||||
if (Q == T_QUAL_NONE) {
|
||||
@@ -368,7 +380,7 @@ static void FixQualifiers (Type* DataType)
|
||||
T[0].C |= Q;
|
||||
} else {
|
||||
/* We have address size qualifiers. If followed by a function,
|
||||
** apply these also to the function.
|
||||
** apply them to the function also.
|
||||
*/
|
||||
if (IsTypeFunc (T+1)) {
|
||||
TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE);
|
||||
@@ -489,7 +501,7 @@ static void ParseEnumDecl (void)
|
||||
|
||||
|
||||
static int ParseFieldWidth (Declaration* Decl)
|
||||
/* Parse an optional field width. Returns -1 if no field width is speficied,
|
||||
/* Parse an optional field width. Returns -1 if no field width is specified,
|
||||
** otherwise the width of the field.
|
||||
*/
|
||||
{
|
||||
@@ -862,7 +874,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
|
||||
|
||||
|
||||
static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
|
||||
/* Parse a type specificier */
|
||||
/* Parse a type specifier */
|
||||
{
|
||||
ident Ident;
|
||||
SymEntry* Entry;
|
||||
@@ -1376,13 +1388,13 @@ static FuncDesc* ParseFuncDecl (void)
|
||||
static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
||||
/* Recursively process declarators. Build a type array in reverse order. */
|
||||
{
|
||||
/* Read optional function or pointer qualifiers. These modify the
|
||||
** identifier or token to the right. For convenience, we allow the fastcall
|
||||
** qualifier also for pointers here. If it is a pointer-to-function, the
|
||||
** qualifier will later be transfered to the function itself. If it's a
|
||||
/* Read optional function or pointer qualifiers. They modify the
|
||||
** identifier or token to the right. For convenience, we allow a calling
|
||||
** convention also for pointers here. If it's a pointer-to-function, the
|
||||
** qualifier later will be transfered to the function itself. If it's a
|
||||
** pointer to something else, it will be flagged as an error.
|
||||
*/
|
||||
TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_FASTCALL);
|
||||
TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_CCONV);
|
||||
|
||||
/* Pointer to something */
|
||||
if (CurTok.Tok == TOK_STAR) {
|
||||
@@ -1390,10 +1402,10 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
||||
/* Skip the star */
|
||||
NextToken ();
|
||||
|
||||
/* Allow const, restrict and volatile qualifiers */
|
||||
/* Allow const, restrict, and volatile qualifiers */
|
||||
Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT);
|
||||
|
||||
/* Parse the type, the pointer points to */
|
||||
/* Parse the type that the pointer points to */
|
||||
Declarator (Spec, D, Mode);
|
||||
|
||||
/* Add the type */
|
||||
@@ -1443,7 +1455,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
||||
|
||||
/* We cannot specify fastcall for variadic functions */
|
||||
if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) {
|
||||
Error ("Variadic functions cannot be `__fastcall__'");
|
||||
Error ("Variadic functions cannot be __fastcall__");
|
||||
Qualifiers &= ~T_QUAL_FASTCALL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* expr.c
|
||||
**
|
||||
** Ullrich von Bassewitz, 21.06.1998
|
||||
** 1998-06-21, Ullrich von Bassewitz
|
||||
** 2015-06-26, Greg King
|
||||
*/
|
||||
|
||||
|
||||
@@ -470,9 +471,11 @@ static void FunctionCall (ExprDesc* Expr)
|
||||
/* Handle function pointers transparently */
|
||||
IsFuncPtr = IsTypeFuncPtr (Expr->Type);
|
||||
if (IsFuncPtr) {
|
||||
|
||||
/* Check wether it's a fastcall function that has parameters */
|
||||
IsFastcall = IsQualFastcall (Expr->Type + 1) && (Func->ParamCount > 0);
|
||||
/* Check whether it's a fastcall function that has parameters */
|
||||
IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && Func->ParamCount > 0 &&
|
||||
(AutoCDecl ?
|
||||
IsQualFastcall (Expr->Type + 1) :
|
||||
!IsQualCDecl (Expr->Type + 1));
|
||||
|
||||
/* Things may be difficult, depending on where the function pointer
|
||||
** resides. If the function pointer is an expression of some sort
|
||||
@@ -517,7 +520,10 @@ static void FunctionCall (ExprDesc* Expr)
|
||||
}
|
||||
|
||||
/* If we didn't inline the function, get fastcall info */
|
||||
IsFastcall = IsQualFastcall (Expr->Type);
|
||||
IsFastcall = (Func->Flags & FD_VARIADIC) == 0 &&
|
||||
(AutoCDecl ?
|
||||
IsQualFastcall (Expr->Type) :
|
||||
!IsQualCDecl (Expr->Type));
|
||||
}
|
||||
|
||||
/* Parse the parameter list */
|
||||
@@ -1707,8 +1713,13 @@ void hie10 (ExprDesc* Expr)
|
||||
} else {
|
||||
Error ("Illegal indirection");
|
||||
}
|
||||
/* The * operator yields an lvalue */
|
||||
ED_MakeLVal (Expr);
|
||||
/* If the expression points to an array, then don't convert the
|
||||
** address -- it already is the location of the first element.
|
||||
*/
|
||||
if (!IsTypeArray (Expr->Type)) {
|
||||
/* The * operator yields an lvalue */
|
||||
ED_MakeLVal (Expr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2012, Ullrich von Bassewitz */
|
||||
/* (C) 2000-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -460,6 +460,9 @@ void NewFunc (SymEntry* Func)
|
||||
*/
|
||||
if (D->ParamCount > 0 || (D->Flags & FD_VARIADIC) != 0) {
|
||||
g_importmainargs ();
|
||||
|
||||
/* The start-up code doesn't fast-call main(). */
|
||||
Func->Type->C |= T_QUAL_CDECL;
|
||||
}
|
||||
|
||||
/* Determine if this is a main function in a C99 environment that
|
||||
@@ -478,13 +481,12 @@ void NewFunc (SymEntry* Func)
|
||||
PushLiteralPool (Func);
|
||||
|
||||
/* If this is a fastcall function, push the last parameter onto the stack */
|
||||
if (IsQualFastcall (Func->Type) && D->ParamCount > 0) {
|
||||
|
||||
if ((D->Flags & FD_VARIADIC) == 0 && D->ParamCount > 0 &&
|
||||
(AutoCDecl ?
|
||||
IsQualFastcall (Func->Type) :
|
||||
!IsQualCDecl (Func->Type))) {
|
||||
unsigned Flags;
|
||||
|
||||
/* Fastcall functions may never have an ellipsis or the compiler is buggy */
|
||||
CHECK ((D->Flags & FD_VARIADIC) == 0);
|
||||
|
||||
/* Generate the push */
|
||||
if (IsTypeFunc (D->LastParam->Type)) {
|
||||
/* Pointer to function */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
|
||||
unsigned char AddSource = 0; /* Add source lines as comments */
|
||||
unsigned char AutoCDecl = 0; /* Make functions default to __cdecl__ */
|
||||
unsigned char DebugInfo = 0; /* Add debug info to the obj */
|
||||
unsigned char PreprocessOnly = 0; /* Just preprocess the input */
|
||||
unsigned char DebugOptOutput = 0; /* Output debug stuff */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
/* Options */
|
||||
extern unsigned char AddSource; /* Add source lines as comments */
|
||||
extern unsigned char AutoCDecl; /* Make functions default to __cdecl__ */
|
||||
extern unsigned char DebugInfo; /* Add debug info to the obj */
|
||||
extern unsigned char PreprocessOnly; /* Just preprocess the input */
|
||||
extern unsigned char DebugOptOutput; /* Output debug stuff */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2013, Ullrich von Bassewitz */
|
||||
/* (C) 2000-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -104,6 +104,7 @@ static void Usage (void)
|
||||
"\n"
|
||||
"Long options:\n"
|
||||
" --add-source\t\t\tInclude source as comment\n"
|
||||
" --all-cdecl\t\t\tMake functions default to __cdecl__\n"
|
||||
" --bss-name seg\t\tSet the name of the BSS segment\n"
|
||||
" --check-stack\t\t\tGenerate stack overflow checks\n"
|
||||
" --code-name seg\t\tSet the name of the CODE segment\n"
|
||||
@@ -258,6 +259,10 @@ static void SetSys (const char* Sys)
|
||||
DefineNumericMacro ("__SIM65C02__", 1);
|
||||
break;
|
||||
|
||||
case TGT_OSIC1P:
|
||||
DefineNumericMacro ("__OSIC1P__", 1);
|
||||
break;
|
||||
|
||||
case TGT_PCENGINE:
|
||||
DefineNumericMacro ("__PCE__", 1);
|
||||
break;
|
||||
@@ -350,6 +355,15 @@ static void OptAddSource (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
|
||||
static void OptAllCDecl (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Make functions default to cdecl instead of fastcall. */
|
||||
{
|
||||
AutoCDecl = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptBssName (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Handle the --bss-name option */
|
||||
{
|
||||
@@ -790,6 +804,7 @@ int main (int argc, char* argv[])
|
||||
/* Program long options */
|
||||
static const LongOpt OptTab[] = {
|
||||
{ "--add-source", 0, OptAddSource },
|
||||
{ "--all-cdecl", 0, OptAllCDecl },
|
||||
{ "--bss-name", 1, OptBssName },
|
||||
{ "--check-stack", 0, OptCheckStack },
|
||||
{ "--code-name", 1, OptCodeName },
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
/* cc65 */
|
||||
#include "funcdesc.h"
|
||||
#include "global.h"
|
||||
#include "symtab.h"
|
||||
#include "typecmp.h"
|
||||
|
||||
@@ -245,23 +246,36 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (LeftType == T_TYPE_FUNC) {
|
||||
/* If a calling convention wasn't set explicitly,
|
||||
** then assume the default one.
|
||||
*/
|
||||
if ((LeftQual & T_QUAL_CCONV) == T_QUAL_NONE) {
|
||||
LeftQual |= (AutoCDecl || IsVariadicFunc (lhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL;
|
||||
}
|
||||
if ((RightQual & T_QUAL_CCONV) == T_QUAL_NONE) {
|
||||
RightQual |= (AutoCDecl || IsVariadicFunc (rhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL;
|
||||
}
|
||||
}
|
||||
|
||||
if (LeftQual != RightQual) {
|
||||
/* On the first indirection level, different qualifiers mean
|
||||
** that the types are still compatible. On the second level,
|
||||
** this is a (maybe minor) error, so we create a special
|
||||
** return code, since a qualifier is dropped from a pointer.
|
||||
** Starting from the next level, the types are incompatible
|
||||
** if the qualifiers differ.
|
||||
** that the types still are compatible. On the second level,
|
||||
** that is a (maybe minor) error. We create a special return-code
|
||||
** if a qualifier is dropped from a pointer. But, different calling
|
||||
** conventions are incompatible. Starting from the next level,
|
||||
** the types are incompatible if the qualifiers differ.
|
||||
*/
|
||||
/* (Debugging statement) */
|
||||
/* printf ("Ind = %d %06X != %06X\n", Indirections, LeftQual, RightQual); */
|
||||
switch (Indirections) {
|
||||
|
||||
case 0:
|
||||
SetResult (Result, TC_STRICT_COMPATIBLE);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* A non const value on the right is compatible to a
|
||||
/* A non-const value on the right is compatible to a
|
||||
** const one to the left, same for volatile.
|
||||
*/
|
||||
if ((LeftQual & T_QUAL_CONST) < (RightQual & T_QUAL_CONST) ||
|
||||
@@ -270,7 +284,11 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
||||
} else {
|
||||
SetResult (Result, TC_STRICT_COMPATIBLE);
|
||||
}
|
||||
break;
|
||||
|
||||
if (LeftType != T_TYPE_FUNC || (LeftQual & T_QUAL_CCONV) == (RightQual & T_QUAL_CCONV)) {
|
||||
break;
|
||||
}
|
||||
/* else fall through */
|
||||
|
||||
default:
|
||||
SetResult (Result, TC_INCOMPATIBLE);
|
||||
@@ -280,7 +298,6 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
||||
|
||||
/* Check for special type elements */
|
||||
switch (LeftType) {
|
||||
|
||||
case T_TYPE_PTR:
|
||||
++Indirections;
|
||||
break;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2011, Ullrich von Bassewitz */
|
||||
/* (C) 2000-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/* Translation table with direct (no) translation */
|
||||
static unsigned char CTNone[256] = {
|
||||
static const unsigned char CTNone[256] = {
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||
@@ -69,8 +69,8 @@ static unsigned char CTNone[256] = {
|
||||
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
|
||||
};
|
||||
|
||||
/* Translation table ISO-8859-1 -> ATASCII */
|
||||
static const unsigned char CTAtari [256] = {
|
||||
/* Translation table ISO-8859-1 -> AtASCII */
|
||||
static const unsigned char CTAtari[256] = {
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0xFD,0x08,0x7F,0x9B,0x0B,0x7D,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||
@@ -89,8 +89,28 @@ static const unsigned char CTAtari [256] = {
|
||||
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
|
||||
};
|
||||
|
||||
/* Translation table ISO-8859-1 -> PETSCII */
|
||||
static const unsigned char CTPET [256] = {
|
||||
/* Translation table ISO-8859-1 -> OSASCII */
|
||||
static const unsigned char CTOSI[256] = {
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
|
||||
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
|
||||
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
|
||||
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
|
||||
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7D,0x7C,0x7F,0x7E,
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
|
||||
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
|
||||
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
|
||||
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
|
||||
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
|
||||
};
|
||||
|
||||
/* Translation table ISO-8859-1 -> PetSCII */
|
||||
static const unsigned char CTPET[256] = {
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x14,0x09,0x0D,0x11,0x93,0x0A,0x0E,0x0F,
|
||||
0x10,0x0B,0x12,0x13,0x08,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||
@@ -142,6 +162,7 @@ static const TargetEntry TargetMap[] = {
|
||||
{ "module", TGT_MODULE },
|
||||
{ "nes", TGT_NES },
|
||||
{ "none", TGT_NONE },
|
||||
{ "osic1p", TGT_OSIC1P },
|
||||
{ "pce", TGT_PCENGINE },
|
||||
{ "pet", TGT_PET },
|
||||
{ "plus4", TGT_PLUS4 },
|
||||
@@ -168,6 +189,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = {
|
||||
{ "plus4", CPU_6502, BINFMT_BINARY, CTPET },
|
||||
{ "cbm510", CPU_6502, BINFMT_BINARY, CTPET },
|
||||
{ "cbm610", CPU_6502, BINFMT_BINARY, CTPET },
|
||||
{ "osic1p", CPU_6502, BINFMT_BINARY, CTOSI },
|
||||
{ "pet", CPU_6502, BINFMT_BINARY, CTPET },
|
||||
{ "bbc", CPU_6502, BINFMT_BINARY, CTNone },
|
||||
{ "apple2", CPU_6502, BINFMT_BINARY, CTNone },
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef enum {
|
||||
TGT_PLUS4,
|
||||
TGT_CBM510,
|
||||
TGT_CBM610,
|
||||
TGT_OSIC1P,
|
||||
TGT_PET,
|
||||
TGT_BBC,
|
||||
TGT_APPLE2,
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
#define VER_MAJOR 2U
|
||||
#define VER_MINOR 14U
|
||||
#define VER_MINOR 15U
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||
/* R<EFBFBD>merstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@@ -66,6 +66,18 @@ void AddrCheck (unsigned Addr)
|
||||
|
||||
|
||||
|
||||
attr_t GetAttr (unsigned Addr)
|
||||
/* Return the attribute for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return AttrTab[Addr];
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SegmentDefined (unsigned Start, unsigned End)
|
||||
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||
{
|
||||
@@ -79,14 +91,18 @@ int SegmentDefined (unsigned Start, unsigned End)
|
||||
|
||||
|
||||
|
||||
int HaveSegmentChange (unsigned Addr)
|
||||
/* Return true if the segment change attribute is set for the given address */
|
||||
int IsSegmentEnd (unsigned Addr)
|
||||
/* Return true if a segment ends at the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
return (GetAttr (Addr) & atSegmentEnd) != 0x0000;
|
||||
}
|
||||
|
||||
/* Return the attribute */
|
||||
return (AttrTab[Addr] & atSegmentChange) != 0;
|
||||
|
||||
|
||||
int IsSegmentStart (unsigned Addr)
|
||||
/* Return true if a segment starts at the given address */
|
||||
{
|
||||
return (GetAttr (Addr) & atSegmentStart) != 0x0000;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,18 +161,6 @@ void MarkAddr (unsigned Addr, attr_t Attr)
|
||||
|
||||
|
||||
|
||||
attr_t GetAttr (unsigned Addr)
|
||||
/* Return the attribute for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return AttrTab[Addr];
|
||||
}
|
||||
|
||||
|
||||
|
||||
attr_t GetStyleAttr (unsigned Addr)
|
||||
/* Return the style attribute for the given address */
|
||||
{
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||
/* R<EFBFBD>merstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@@ -47,33 +47,34 @@
|
||||
typedef enum attr_t {
|
||||
|
||||
/* Styles */
|
||||
atDefault = 0x0000, /* Default style */
|
||||
atCode = 0x0001,
|
||||
atIllegal = 0x0002,
|
||||
atByteTab = 0x0003, /* Same as illegal */
|
||||
atDByteTab = 0x0004,
|
||||
atWordTab = 0x0005,
|
||||
atDWordTab = 0x0006,
|
||||
atAddrTab = 0x0007,
|
||||
atRtsTab = 0x0008,
|
||||
atTextTab = 0x0009,
|
||||
atSkip = 0x000A, /* Skip code completely */
|
||||
atDefault = 0x0000, /* Default style */
|
||||
atCode = 0x0001,
|
||||
atIllegal = 0x0002,
|
||||
atByteTab = 0x0003, /* Same as illegal */
|
||||
atDByteTab = 0x0004,
|
||||
atWordTab = 0x0005,
|
||||
atDWordTab = 0x0006,
|
||||
atAddrTab = 0x0007,
|
||||
atRtsTab = 0x0008,
|
||||
atTextTab = 0x0009,
|
||||
atSkip = 0x000A, /* Skip code completely */
|
||||
|
||||
/* Label flags */
|
||||
atNoLabel = 0x0000, /* No label for this address */
|
||||
atExtLabel = 0x0010, /* External label */
|
||||
atIntLabel = 0x0020, /* Internally generated label */
|
||||
atDepLabel = 0x0040, /* Dependent label */
|
||||
atUnnamedLabel = 0x0080, /* Unnamed label */
|
||||
atNoLabel = 0x0000, /* No label for this address */
|
||||
atExtLabel = 0x0010, /* External label */
|
||||
atIntLabel = 0x0020, /* Internally generated label */
|
||||
atDepLabel = 0x0040, /* Dependent label */
|
||||
atUnnamedLabel = 0x0080, /* Unnamed label */
|
||||
|
||||
atLabelDefined = 0x0100, /* True if we defined the label */
|
||||
atLabelDefined = 0x0100, /* True if we defined the label */
|
||||
|
||||
atStyleMask = 0x000F, /* Output style */
|
||||
atLabelMask = 0x00F0, /* Label information */
|
||||
atStyleMask = 0x000F, /* Output style */
|
||||
atLabelMask = 0x00F0, /* Label information */
|
||||
|
||||
/* Segment */
|
||||
atSegment = 0x0100, /* Code is in a segment */
|
||||
atSegmentChange = 0x0200, /* Either segment start or segment end */
|
||||
atSegment = 0x0100, /* Code is in a segment */
|
||||
atSegmentEnd = 0x0200, /* Segment end */
|
||||
atSegmentStart = 0x0400, /* Segment start */
|
||||
} attr_t;
|
||||
|
||||
|
||||
@@ -87,11 +88,17 @@ typedef enum attr_t {
|
||||
void AddrCheck (unsigned Addr);
|
||||
/* Check if the given address has a valid range */
|
||||
|
||||
attr_t GetAttr (unsigned Addr);
|
||||
/* Return the attribute for the given address */
|
||||
|
||||
int SegmentDefined (unsigned Start, unsigned End);
|
||||
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||
|
||||
int HaveSegmentChange (unsigned Addr);
|
||||
/* Return true if the segment change attribute is set for the given address */
|
||||
int IsSegmentEnd (unsigned Addr);
|
||||
/* Return true if a segment ends at the given address */
|
||||
|
||||
int IsSegmentStart (unsigned Addr);
|
||||
/* Return true if a segment starts at the given address */
|
||||
|
||||
unsigned GetGranularity (attr_t Style);
|
||||
/* Get the granularity for the given style */
|
||||
@@ -102,9 +109,6 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr);
|
||||
void MarkAddr (unsigned Addr, attr_t Attr);
|
||||
/* Mark an address with an attribute */
|
||||
|
||||
attr_t GetAttr (unsigned Addr);
|
||||
/* Return the attribute for the given address */
|
||||
|
||||
attr_t GetStyleAttr (unsigned Addr);
|
||||
/* Return the style attribute for the given address */
|
||||
|
||||
@@ -114,5 +118,4 @@ attr_t GetLabelAttr (unsigned Addr);
|
||||
|
||||
|
||||
/* End of attrtab.h */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@@ -65,12 +65,12 @@ static unsigned GetSpan (attr_t Style)
|
||||
attr_t Attr;
|
||||
if (MustDefLabel(PC+Count)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Attr = GetAttr (PC+Count);
|
||||
if ((Attr & atStyleMask) != Style) {
|
||||
break;
|
||||
}
|
||||
if ((Attr & atSegmentChange)) {
|
||||
if ((Attr & (atSegmentStart | atSegmentEnd))) {
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2011, Ullrich von Bassewitz */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -748,16 +748,13 @@ static void SegmentSection (void)
|
||||
if (Start < 0) {
|
||||
InfoError ("Start address is missing");
|
||||
}
|
||||
if (Start == End) {
|
||||
InfoError ("Segment is empty");
|
||||
}
|
||||
if (Start > End) {
|
||||
InfoError ("Start address of segment is greater than end address");
|
||||
}
|
||||
|
||||
/* Check that segments do not overlap */
|
||||
if (SegmentDefined ((unsigned) Start, (unsigned) End)) {
|
||||
InfoError ("Segments cannot overlap");
|
||||
InfoError ("Segments must not overlap");
|
||||
}
|
||||
|
||||
/* Remember the segment data */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "opctable.h"
|
||||
#include "output.h"
|
||||
#include "scanner.h"
|
||||
#include "segment.h"
|
||||
|
||||
|
||||
|
||||
@@ -347,6 +348,8 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
||||
static void OneOpcode (unsigned RemainingBytes)
|
||||
/* Disassemble one opcode */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
/* Get the opcode from the current address */
|
||||
unsigned char OPC = GetCodeByte (PC);
|
||||
|
||||
@@ -356,6 +359,14 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
/* Get the output style for the current PC */
|
||||
attr_t Style = GetStyleAttr (PC);
|
||||
|
||||
/* If a segment begins here, then name that segment.
|
||||
** Note that the segment is named even if its code is being skipped,
|
||||
** because some of its later code might not be skipped.
|
||||
*/
|
||||
if (IsSegmentStart (PC)) {
|
||||
StartSegment (GetSegmentStartName (PC), GetSegmentAddrSize (PC));
|
||||
}
|
||||
|
||||
/* If we have a label at this address, output the label and an attached
|
||||
** comment, provided that we aren't in a skip area.
|
||||
*/
|
||||
@@ -371,7 +382,8 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
** - ...if we have enough bytes remaining for the code at this address.
|
||||
** - ...if the current instruction is valid for the given CPU.
|
||||
** - ...if there is no label somewhere between the instruction bytes.
|
||||
** If any of these conditions is false, switch to data mode.
|
||||
** - ...if there is no segment change between the instruction bytes.
|
||||
** If any one of those conditions is false, switch to data mode.
|
||||
*/
|
||||
if (Style == atDefault) {
|
||||
if (D->Size > RemainingBytes) {
|
||||
@@ -381,9 +393,15 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
} else {
|
||||
unsigned I;
|
||||
for (I = 1; I < D->Size; ++I) {
|
||||
if (HaveLabel (PC+I) || HaveSegmentChange (PC+I)) {
|
||||
for (I = PC + D->Size; --I > PC; ) {
|
||||
if (HaveLabel (I) || IsSegmentStart (I)) {
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (I = 0; I < D->Size - 1u; ++I) {
|
||||
if (IsSegmentEnd (PC + I)) {
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
break;
|
||||
@@ -406,7 +424,6 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
*/
|
||||
if (D->Size <= RemainingBytes) {
|
||||
/* Output labels within the next insn */
|
||||
unsigned I;
|
||||
for (I = 1; I < D->Size; ++I) {
|
||||
ForwardLabel (I);
|
||||
}
|
||||
@@ -453,7 +470,16 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
DataByteLine (1);
|
||||
++PC;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change back to the default CODE segment if
|
||||
** a named segment stops at the current address.
|
||||
*/
|
||||
for (I = D->Size; I >= 1; --I) {
|
||||
if (IsSegmentEnd (PC - I)) {
|
||||
EndSegment ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2009, Ullrich von Bassewitz */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@@ -63,6 +63,8 @@ static unsigned Col = 1; /* Current column */
|
||||
static unsigned Line = 0; /* Current line on page */
|
||||
static unsigned Page = 1; /* Current output page */
|
||||
|
||||
static const char* SegmentName = 0; /* Name of current segment */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -223,23 +225,6 @@ void DefConst (const char* Name, const char* Comment, unsigned Addr)
|
||||
|
||||
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize)
|
||||
/* Start a segment */
|
||||
{
|
||||
if (Pass == PassCount) {
|
||||
Output (".segment");
|
||||
Indent (ACol);
|
||||
if (AddrSize == ADDR_SIZE_DEFAULT) {
|
||||
Output ("\"%s\"", Name);
|
||||
} else {
|
||||
Output ("\"%s\": %s", Name, AddrSizeToStr (AddrSize));
|
||||
}
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataByteLine (unsigned ByteCount)
|
||||
/* Output a line with bytes */
|
||||
{
|
||||
@@ -335,6 +320,39 @@ void SeparatorLine (void)
|
||||
|
||||
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize)
|
||||
/* Start a segment */
|
||||
{
|
||||
if (Pass == PassCount) {
|
||||
LineFeed ();
|
||||
Output (".segment");
|
||||
Indent (ACol);
|
||||
SegmentName = Name;
|
||||
Output ("\"%s\"", Name);
|
||||
if (AddrSize != ADDR_SIZE_DEFAULT) {
|
||||
Output (": %s", AddrSizeToStr (AddrSize));
|
||||
}
|
||||
LineFeed ();
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EndSegment (void)
|
||||
/* End a segment */
|
||||
{
|
||||
LineFeed ();
|
||||
Output ("; End of \"%s\" segment", SegmentName);
|
||||
LineFeed ();
|
||||
SeparatorLine ();
|
||||
Output (".code");
|
||||
LineFeed ();
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void UserComment (const char* Comment)
|
||||
/* Output a comment line */
|
||||
{
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@@ -74,12 +74,6 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs);
|
||||
|
||||
void DefConst (const char* Name, const char* Comment, unsigned Addr);
|
||||
/* Define an address constant */
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize);
|
||||
/* Start a segment */
|
||||
|
||||
void EndSegment (void);
|
||||
/* End a segment */
|
||||
|
||||
void OneDataByte (void);
|
||||
/* Output a .byte line with the current code byte */
|
||||
@@ -99,6 +93,12 @@ void DataDWordLine (unsigned ByteCount);
|
||||
void SeparatorLine (void);
|
||||
/* Print a separator line */
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize);
|
||||
/* Start a segment */
|
||||
|
||||
void EndSegment (void);
|
||||
/* End a segment */
|
||||
|
||||
void UserComment (const char* Comment);
|
||||
/* Output a comment line */
|
||||
|
||||
@@ -111,5 +111,4 @@ void OutputSettings (void);
|
||||
|
||||
|
||||
/* End of output.h */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2007-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@@ -58,18 +58,15 @@
|
||||
typedef struct Segment Segment;
|
||||
struct Segment {
|
||||
Segment* NextStart; /* Pointer to next segment */
|
||||
Segment* NextEnd; /* Pointer to next segment */
|
||||
unsigned long Start;
|
||||
unsigned long End;
|
||||
unsigned AddrSize;
|
||||
char Name[1]; /* Name, dynamically allocated */
|
||||
};
|
||||
|
||||
/* Tables containing the segments. A segment is inserted using it's hash
|
||||
** value. Collision is done by single linked lists.
|
||||
/* Table containing the segments. A segment is inserted using its hash
|
||||
** value. Collisions are handled by single-linked lists.
|
||||
*/
|
||||
static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */
|
||||
static Segment* EndTab[HASH_SIZE]; /* Table containing segment ends */
|
||||
|
||||
|
||||
|
||||
@@ -90,20 +87,53 @@ void AddAbsSegment (unsigned Start, unsigned End, const char* Name)
|
||||
|
||||
/* Fill in the data */
|
||||
S->Start = Start;
|
||||
S->End = End;
|
||||
S->AddrSize = ADDR_SIZE_ABS;
|
||||
memcpy (S->Name, Name, Len + 1);
|
||||
|
||||
/* Insert the segment into the hash tables */
|
||||
/* Insert the segment into the hash table */
|
||||
S->NextStart = StartTab[Start % HASH_SIZE];
|
||||
StartTab[Start % HASH_SIZE] = S;
|
||||
S->NextEnd = EndTab[End % HASH_SIZE];
|
||||
EndTab[End % HASH_SIZE] = S;
|
||||
|
||||
/* Mark start and end of the segment */
|
||||
MarkAddr (Start, atSegmentChange);
|
||||
MarkAddr (End, atSegmentChange);
|
||||
MarkAddr (Start, atSegmentStart);
|
||||
MarkAddr (End, atSegmentEnd);
|
||||
|
||||
/* Mark the addresses within the segment */
|
||||
MarkRange (Start, End, atSegment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char* GetSegmentStartName (unsigned Addr)
|
||||
/* Return the name of the segment which starts at the given address */
|
||||
{
|
||||
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||
|
||||
/* Search the collision list for the exact address */
|
||||
while (S != 0) {
|
||||
if (S->Start == Addr) {
|
||||
return S->Name;
|
||||
}
|
||||
S = S->NextStart;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned GetSegmentAddrSize (unsigned Addr)
|
||||
/* Return the address size of the segment which starts at the given address */
|
||||
{
|
||||
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||
|
||||
/* Search the collision list for the exact address */
|
||||
while (S != 0) {
|
||||
if (S->Start == Addr) {
|
||||
return S->AddrSize;
|
||||
}
|
||||
S = S->NextStart;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2007-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@@ -47,8 +47,13 @@
|
||||
void AddAbsSegment (unsigned Start, unsigned End, const char* Name);
|
||||
/* Add an absolute segment to the segment table */
|
||||
|
||||
char* GetSegmentStartName (unsigned Addr);
|
||||
/* Return the name of the segment which starts at the given address */
|
||||
|
||||
unsigned GetSegmentAddrSize (unsigned Addr);
|
||||
/* Return the address size of the segment which starts at the given address */
|
||||
|
||||
|
||||
|
||||
/* End of segment.h */
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user