mirror of
https://github.com/cc65/cc65.git
synced 2024-12-26 08:32:00 +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:
parent
f04d65a662
commit
31d2fff060
@ -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 \
|
||||
|
@ -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 \
|
||||
@ -119,7 +119,7 @@ $(EXE): $(OBJS) $(LIBS)
|
||||
@echo "OPTION QUIET" >> $(LNKCFG)
|
||||
@echo "OPTION MAP" >> $(LNKCFG)
|
||||
@echo "OPTION STACK=65536" >> $(LNKCFG)
|
||||
@echo "NAME $@" >> $(LNKCFG)
|
||||
@echo "NAME $@" >> $(LNKCFG)
|
||||
@for i in $(OBJS); do echo "FILE $${i}"; done >> $(LNKCFG)
|
||||
@for i in $(LIBS); do echo "LIBRARY $${i}"; done >> $(LNKCFG)
|
||||
@$(LD) system $(SYSTEM) @$(LNKCFG)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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,23 +232,23 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Leave the scope */
|
||||
@ -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;
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user