From 472c21d7ff28eae15e1ab4f378ae0286f49e8712 Mon Sep 17 00:00:00 2001 From: uz Date: Sun, 7 Aug 2011 20:01:40 +0000 Subject: [PATCH] Some improvements for spans. git-svn-id: svn://svn.cc65.org/cc65/trunk@5134 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/segment.c | 88 +++++++++++++++++++-------------------- src/ca65/span.c | 101 ++++++++++++++++++++++++++++----------------- src/ca65/span.h | 13 +++--- src/ca65/symtab.c | 2 +- 4 files changed, 112 insertions(+), 92 deletions(-) diff --git a/src/ca65/segment.c b/src/ca65/segment.c index a089a5d88..004bf45ab 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -457,6 +457,50 @@ void SegDump (void) +void InitSegments (void) +/* Initialize segments */ +{ + /* Create the predefined segments. Code segment is active */ + ActiveSeg = NewSegFromDef (&CodeSegDef); + NewSegFromDef (&RODataSegDef); + NewSegFromDef (&BssSegDef); + NewSegFromDef (&DataSegDef); + NewSegFromDef (&ZeropageSegDef); + NewSegFromDef (&NullSegDef); +} + + + +void SetSegmentSizes (void) +/* Set the default segment sizes according to the memory model */ +{ + /* Initialize segment sizes. The segment definitions do already contain + * the correct values for the default case (near), so we must only change + * things that should be different. + */ + switch (MemoryModel) { + + case MMODEL_NEAR: + break; + + case MMODEL_FAR: + CodeSegDef.AddrSize = ADDR_SIZE_FAR; + break; + + case MMODEL_HUGE: + CodeSegDef.AddrSize = ADDR_SIZE_FAR; + DataSegDef.AddrSize = ADDR_SIZE_FAR; + BssSegDef.AddrSize = ADDR_SIZE_FAR; + RODataSegDef.AddrSize = ADDR_SIZE_FAR; + break; + + default: + Internal ("Invalid memory model: %d", MemoryModel); + } +} + + + static void WriteOneSeg (Segment* Seg) /* Write one segment to the object file */ { @@ -541,50 +585,6 @@ static void WriteOneSeg (Segment* Seg) -void InitSegments (void) -/* Initialize segments */ -{ - /* Create the predefined segments. Code segment is active */ - ActiveSeg = NewSegFromDef (&CodeSegDef); - NewSegFromDef (&RODataSegDef); - NewSegFromDef (&BssSegDef); - NewSegFromDef (&DataSegDef); - NewSegFromDef (&ZeropageSegDef); - NewSegFromDef (&NullSegDef); -} - - - -void SetSegmentSizes (void) -/* Set the default segment sizes according to the memory model */ -{ - /* Initialize segment sizes. The segment definitions do already contain - * the correct values for the default case (near), so we must only change - * things that should be different. - */ - switch (MemoryModel) { - - case MMODEL_NEAR: - break; - - case MMODEL_FAR: - CodeSegDef.AddrSize = ADDR_SIZE_FAR; - break; - - case MMODEL_HUGE: - CodeSegDef.AddrSize = ADDR_SIZE_FAR; - DataSegDef.AddrSize = ADDR_SIZE_FAR; - BssSegDef.AddrSize = ADDR_SIZE_FAR; - RODataSegDef.AddrSize = ADDR_SIZE_FAR; - break; - - default: - Internal ("Invalid memory model: %d", MemoryModel); - } -} - - - void WriteSegments (void) /* Write the segment data to the object file */ { diff --git a/src/ca65/span.c b/src/ca65/span.c index 70bc85167..47db633b0 100644 --- a/src/ca65/span.c +++ b/src/ca65/span.c @@ -44,12 +44,18 @@ /*****************************************************************************/ -/* Code */ +/* Data */ /*****************************************************************************/ -Span* NewSpan (struct Segment* Seg) +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static Span* NewSpan (Segment* Seg, unsigned long Start, unsigned long End) /* Create a new span. The segment is set to Seg, Start and End are set to the * current PC of the segment. */ @@ -59,8 +65,8 @@ Span* NewSpan (struct Segment* Seg) /* Initialize the struct */ S->Seg = Seg; - S->Start = Seg->PC; - S->End = Seg->PC; + S->Start = Start; + S->End = End; /* Return the new struct */ return S; @@ -68,15 +74,24 @@ Span* NewSpan (struct Segment* Seg) -void AddSpans (Collection* Spans) -/* Add a span for all existing segments to the given collection of spans. The - * currently active segment will be inserted first with all others following. +static void FreeSpan (Span* S) +/* Free a span */ +{ + xfree (S); +} + + + +void OpenSpans (Collection* Spans) +/* Open a list of spans for all existing segments to the given collection of + * spans. The currently active segment will be inserted first with all others + * following. */ { unsigned I; /* Add the currently active segment */ - CollAppend (Spans, NewSpan (ActiveSeg)); + CollAppend (Spans, NewSpan (ActiveSeg, ActiveSeg->PC, ActiveSeg->PC)); /* Walk through the segment list and add all other segments */ for (I = 0; I < CollCount (&SegmentList); ++I) { @@ -84,7 +99,7 @@ void AddSpans (Collection* Spans) /* Be sure to skip the active segment, since it was already added */ if (Seg != ActiveSeg) { - CollAppend (Spans, NewSpan (Seg)); + CollAppend (Spans, NewSpan (Seg, Seg->PC, Seg->PC)); } } } @@ -92,19 +107,43 @@ void AddSpans (Collection* Spans) void CloseSpans (Collection* Spans) -/* Close all open spans by setting PC to the current PC for the segment. */ +/* Close a list of spans. This will add new segments to the list, mark the end + * of existing ones, and remove empty spans from the list. + */ { - unsigned I; + unsigned I, J; - /* Walk over the segment list */ - for (I = 0; I < CollCount (Spans); ++I) { + /* Have new segments been added while the span list was open? */ + for (I = CollCount (Spans); I < CollCount (&SegmentList); ++I) { + + /* Add new spans if not empty */ + Segment* S = CollAtUnchecked (&SegmentList, I); + if (S->PC == 0) { + /* Segment is empty */ + continue; + } + CollAppend (Spans, NewSpan (S, 0, S->PC)); + } - /* Get the next segment range */ + /* Walk over the spans, close open, remove empty ones */ + for (I = 0, J = 0; I < CollCount (Spans); ++I) { + + /* Get the next span */ Span* S = CollAtUnchecked (Spans, I); /* Set the end offset */ - S->End = S->Seg->PC; + if (S->Start == S->Seg->PC) { + /* Span is empty */ + FreeSpan (S); + } else { + /* Span is not empty */ + S->End = S->Seg->PC; + CollReplace (Spans, S, J++); + } } + + /* New Count is now in J */ + Spans->Count = J; } @@ -113,23 +152,9 @@ void WriteSpans (const Collection* Spans) /* Write a list of spans to the output file */ { unsigned I; - unsigned Count; - - /* Determine how many of the segments contain actual data */ - Count = 0; - for (I = 0; I < CollCount (Spans); ++I) { - /* Get next range */ - const Span* S = CollConstAt (Spans, I); - - /* Is this segment range empty? */ - if (S->Start != S->End) { - ++Count; - } - } - - /* Write the number of spans with data */ - ObjWriteVar (Count); + /* Write the number of spans */ + ObjWriteVar (CollCount (Spans)); /* Write the spans */ for (I = 0; I < CollCount (Spans); ++I) { @@ -137,15 +162,13 @@ void WriteSpans (const Collection* Spans) /* Get next range */ const Span* S = CollConstAt (Spans, I); - /* Write data for non empty spans. We will write the size instead of - * the end offset to save some bytes, since most spans are expected - * to be rather small. + /* Write data for th span We will write the size instead of the end + * offset to save some bytes, since most spans are expected to be + * rather small. */ - if (S->Start != S->End) { - ObjWriteVar (S->Seg->Num); - ObjWriteVar (S->Start); - ObjWriteVar (S->End - S->Start); - } + ObjWriteVar (S->Seg->Num); + ObjWriteVar (S->Start); + ObjWriteVar (S->End - S->Start); } } diff --git a/src/ca65/span.h b/src/ca65/span.h index 8bbc7c1f3..407c753d9 100644 --- a/src/ca65/span.h +++ b/src/ca65/span.h @@ -53,6 +53,7 @@ /* Span definition */ typedef struct Span Span; struct Span{ + unsigned Id; /* Span id */ struct Segment* Seg; /* Pointer to segment */ unsigned long Start; /* Start of range */ unsigned long End; /* End of range */ @@ -66,11 +67,6 @@ struct Span{ -Span* NewSpan (struct Segment* Seg); -/* Create a new span. The segment is set to Seg, Start and End are set to the - * current PC of the segment. - */ - #if defined(HAVE_INLINE) INLINE unsigned long GetSpanSize (const Span* R) /* Return the span size in bytes */ @@ -81,9 +77,10 @@ INLINE unsigned long GetSpanSize (const Span* R) # define GetSpanSize(R) ((R)->End - (R)->Start) #endif -void AddSpans (Collection* Spans); -/* Add a span for all existing segments to the given collection of spans. The - * currently active segment will be inserted first with all others following. +void OpenSpans (Collection* Spans); +/* Open a list of spans for all existing segments to the given collection of + * spans. The currently active segment will be inserted first with all others + * following. */ void CloseSpans (Collection* Spans); diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 3b83b8167..409a49669 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -223,7 +223,7 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, * space in any segment). */ if (CurrentScope->Type <= SCOPE_HAS_DATA) { - AddSpans (&CurrentScope->Spans); + OpenSpans (&CurrentScope->Spans); } } -- 2.39.5