1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 00:29:31 +00:00

Rename SegRange to span. Write out the size instead of the end offset so we

can save some bytes in the object file.


git-svn-id: svn://svn.cc65.org/cc65/trunk@5113 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-08-04 12:49:59 +00:00
parent f04d65a662
commit 31d2fff060
6 changed files with 84 additions and 88 deletions

View File

@ -56,8 +56,8 @@ OBJS = anonname.o \
repeat.o \
scanner.o \
segment.o \
segrange.o \
sizeof.o \
span.o \
spool.o \
struct.o \
studyexpr.o \

View File

@ -89,8 +89,8 @@ OBJS = anonname.obj \
repeat.obj \
scanner.obj \
segment.obj \
segrange.obj \
sizeof.obj \
span.obj \
spool.obj \
struct.obj \
studyexpr.obj \

View File

@ -1,8 +1,8 @@
/*****************************************************************************/
/* */
/* segrange.c */
/* span.c */
/* */
/* A segment range */
/* A span of data within a segment */
/* */
/* */
/* */
@ -39,7 +39,7 @@
/* ca65 */
#include "objfile.h"
#include "segment.h"
#include "segrange.h"
#include "span.h"
@ -49,42 +49,41 @@
SegRange* NewSegRange (struct Segment* Seg)
/* Create a new segment range. The segment is set to Seg, Start and End are
* set to the current PC of the segment.
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.
*/
{
/* Allocate memory */
SegRange* R = xmalloc (sizeof (SegRange));
Span* S = xmalloc (sizeof (Span));
/* Initialize the struct */
R->Seg = Seg;
R->Start = Seg->PC;
R->End = Seg->PC;
S->Seg = Seg;
S->Start = Seg->PC;
S->End = Seg->PC;
/* Return the new struct */
return R;
return S;
}
void AddSegRanges (Collection* Ranges)
/* Add a segment range for all existing segments to the given collection of
* ranges. The currently active segment will be inserted first with all others
* following.
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.
*/
{
Segment* Seg;
/* Add the currently active segment */
CollAppend (Ranges, NewSegRange (ActiveSeg));
CollAppend (Spans, NewSpan (ActiveSeg));
/* Walk through the segment list and add all other segments */
Seg = SegmentList;
while (Seg) {
/* Be sure to skip the active segment, since it was already added */
if (Seg != ActiveSeg) {
CollAppend (Ranges, NewSegRange (Seg));
CollAppend (Spans, NewSpan (Seg));
}
Seg = Seg->List;
}
@ -92,59 +91,60 @@ void AddSegRanges (Collection* Ranges)
void CloseSegRanges (Collection* Ranges)
/* Close all open segment ranges by setting PC to the current PC for the
* segment.
*/
void CloseSpans (Collection* Spans)
/* Close all open spans by setting PC to the current PC for the segment. */
{
unsigned I;
/* Walk over the segment list */
for (I = 0; I < CollCount (Ranges); ++I) {
for (I = 0; I < CollCount (Spans); ++I) {
/* Get the next segment range */
SegRange* R = CollAtUnchecked (Ranges, I);
Span* S = CollAtUnchecked (Spans, I);
/* Set the end offset */
R->End = R->Seg->PC;
S->End = S->Seg->PC;
}
}
void WriteSegRanges (const Collection* Ranges)
/* Write a list of segment ranges to the output file */
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 (Ranges); ++I) {
for (I = 0; I < CollCount (Spans); ++I) {
/* Get next range */
const SegRange* R = CollConstAt (Ranges, I);
const Span* S = CollConstAt (Spans, I);
/* Is this segment range empty? */
if (R->Start != R->End) {
if (S->Start != S->End) {
++Count;
}
}
/* Write the number of ranges with data */
/* Write the number of spans with data */
ObjWriteVar (Count);
/* Write the ranges */
for (I = 0; I < CollCount (Ranges); ++I) {
/* Write the spans */
for (I = 0; I < CollCount (Spans); ++I) {
/* Get next range */
const SegRange* R = CollConstAt (Ranges, I);
const Span* S = CollConstAt (Spans, I);
/* Write data for non empty ranges */
if (R->Start != R->End) {
ObjWriteVar (R->Seg->Num);
ObjWriteVar (R->Start);
ObjWriteVar (R->End);
/* 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.
*/
if (S->Start != S->End) {
ObjWriteVar (S->Seg->Num);
ObjWriteVar (S->Start);
ObjWriteVar (S->End - S->Start);
}
}
}

View File

@ -1,8 +1,8 @@
/*****************************************************************************/
/* */
/* segrange.h */
/* span.h */
/* */
/* A segment range */
/* A span of data within a segment */
/* */
/* */
/* */
@ -33,8 +33,8 @@
#ifndef SEGRANGE_H
#define SEGRANGE_H
#ifndef SPAN_H
#define SPAN_H
@ -50,9 +50,9 @@
/* Segment range definition */
typedef struct SegRange SegRange;
struct SegRange{
/* Span definition */
typedef struct Span Span;
struct Span{
struct Segment* Seg; /* Pointer to segment */
unsigned long Start; /* Start of range */
unsigned long End; /* End of range */
@ -66,41 +66,37 @@ struct SegRange{
SegRange* NewSegRange (struct Segment* Seg);
/* Create a new segment range. The segment is set to Seg, Start and End are
* set to the current PC of the segment.
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 GetSegRangeSize (const SegRange* R)
/* Return the segment range size in bytes */
INLINE unsigned long GetSpanSize (const Span* R)
/* Return the span size in bytes */
{
return (R->End - R->Start);
}
#else
# define GetSegRangeSize(R) ((R)->End - (R)->Start)
# define GetSpanSize(R) ((R)->End - (R)->Start)
#endif
void AddSegRanges (Collection* Ranges);
/* Add a segment range for all existing segments to the given collection of
* ranges. The currently active segment will be inserted first with all others
* following.
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 CloseSegRanges (Collection* Ranges);
/* Close all open segment ranges by setting PC to the current PC for the
* segment.
*/
void CloseSpans (Collection* Spans);
/* Close all open spans by setting PC to the current PC for the segment. */
void WriteSegRanges (const Collection* Ranges);
/* Write a list of segment ranges to the output file */
void WriteSpans (const Collection* Spans);
/* Write a list of spans to the output file */
/* End of segrange.h */
/* End of span.h */
#endif

View File

@ -52,6 +52,7 @@
#include "scanner.h"
#include "segment.h"
#include "sizeof.h"
#include "span.h"
#include "spool.h"
#include "studyexpr.h"
#include "symtab.h"
@ -116,7 +117,7 @@ static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name)
S->Right = 0;
S->Childs = 0;
S->OwnerSym = 0;
S->SegRanges = AUTO_COLLECTION_INITIALIZER;
S->Spans = AUTO_COLLECTION_INITIALIZER;
S->Id = ScopeCount++;
S->Flags = ST_NONE;
S->AddrSize = ADDR_SIZE_DEFAULT;
@ -215,14 +216,14 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
CurrentScope->Type = Type;
CurrentScope->OwnerSym = OwnerSym;
/* If this is a scope that allows to emit data into segments, add segment
* ranges for all currently existing segments. Doing this for just a few
* scope types is not really necessary but an optimization, because it
* does not allocate memory for useless data (unhandled types here don't
* occupy space in any segment).
/* If this is a scope that allows to emit data into segments, add spans
* for all currently existing segments. Doing this for just a few scope
* types is not really necessary but an optimization, because it does not
* allocate memory for useless data (unhandled types here don't occupy
* space in any segment).
*/
if (CurrentScope->Type <= SCOPE_HAS_DATA) {
AddSegRanges (&CurrentScope->SegRanges);
AddSpans (&CurrentScope->Spans);
}
}
@ -231,19 +232,19 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
void SymLeaveLevel (void)
/* Leave the current lexical level */
{
/* Close the segment ranges. We don't care about the scope type here,
* since types without segment ranges will just have an empty list.
/* Close the spans. We don't care about the scope type here, since types
* without spans will just have an empty list.
*/
CloseSegRanges (&CurrentScope->SegRanges);
CloseSpans (&CurrentScope->Spans);
/* If we have segment ranges, the first one is the segment that was
* active, when the scope was opened. Set the size of the scope to the
* number of data bytes emitted into this segment. If we have an owner
* symbol set the size of this symbol, too.
/* If we have spans, the first one is the segment that was active, when the
* scope was opened. Set the size of the scope to the number of data bytes
* emitted into this segment. If we have an owner symbol set the size of
* this symbol, too.
*/
if (CollCount (&CurrentScope->SegRanges) > 0) {
const SegRange* R = CollAtUnchecked (&CurrentScope->SegRanges, 0);
unsigned long Size = GetSegRangeSize (R);
if (CollCount (&CurrentScope->Spans) > 0) {
const Span* S = CollAtUnchecked (&CurrentScope->Spans, 0);
unsigned long Size = GetSpanSize (S);
DefSizeOfScope (CurrentScope, Size);
if (CurrentScope->OwnerSym) {
DefSizeOfSymbol (CurrentScope->OwnerSym, Size);
@ -940,8 +941,8 @@ void WriteScopes (void)
ObjWriteVar (Size);
}
/* Segment ranges for this scope */
WriteSegRanges (&S->SegRanges);
/* Spans for this scope */
WriteSpans (&S->Spans);
/* Next scope */
S = S->Next;

View File

@ -45,7 +45,6 @@
#include "inline.h"
/* ca65 */
#include "segrange.h"
#include "symentry.h"
@ -69,7 +68,7 @@ struct SymTable {
SymTable* Parent; /* Link to enclosing scope if any */
SymTable* Childs; /* Pointer to child scopes */
SymEntry* OwnerSym; /* Symbol that "owns" the scope */
Collection SegRanges; /* Segment ranges for this scope */
Collection Spans; /* Spans for this scope */
unsigned Id; /* Scope id */
unsigned short Flags; /* Symbol table flags */
unsigned char AddrSize; /* Address size */