mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 15:29:46 +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 \
|
repeat.o \
|
||||||
scanner.o \
|
scanner.o \
|
||||||
segment.o \
|
segment.o \
|
||||||
segrange.o \
|
|
||||||
sizeof.o \
|
sizeof.o \
|
||||||
|
span.o \
|
||||||
spool.o \
|
spool.o \
|
||||||
struct.o \
|
struct.o \
|
||||||
studyexpr.o \
|
studyexpr.o \
|
||||||
|
@ -89,8 +89,8 @@ OBJS = anonname.obj \
|
|||||||
repeat.obj \
|
repeat.obj \
|
||||||
scanner.obj \
|
scanner.obj \
|
||||||
segment.obj \
|
segment.obj \
|
||||||
segrange.obj \
|
|
||||||
sizeof.obj \
|
sizeof.obj \
|
||||||
|
span.obj \
|
||||||
spool.obj \
|
spool.obj \
|
||||||
struct.obj \
|
struct.obj \
|
||||||
studyexpr.obj \
|
studyexpr.obj \
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* segrange.c */
|
/* span.c */
|
||||||
/* */
|
/* */
|
||||||
/* A segment range */
|
/* A span of data within a segment */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -39,7 +39,7 @@
|
|||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "objfile.h"
|
#include "objfile.h"
|
||||||
#include "segment.h"
|
#include "segment.h"
|
||||||
#include "segrange.h"
|
#include "span.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -49,42 +49,41 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SegRange* NewSegRange (struct Segment* Seg)
|
Span* NewSpan (struct Segment* Seg)
|
||||||
/* Create a new segment range. The segment is set to Seg, Start and End are
|
/* Create a new span. The segment is set to Seg, Start and End are set to the
|
||||||
* set to the current PC of the segment.
|
* current PC of the segment.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
SegRange* R = xmalloc (sizeof (SegRange));
|
Span* S = xmalloc (sizeof (Span));
|
||||||
|
|
||||||
/* Initialize the struct */
|
/* Initialize the struct */
|
||||||
R->Seg = Seg;
|
S->Seg = Seg;
|
||||||
R->Start = Seg->PC;
|
S->Start = Seg->PC;
|
||||||
R->End = Seg->PC;
|
S->End = Seg->PC;
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return R;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddSegRanges (Collection* Ranges)
|
void AddSpans (Collection* Spans)
|
||||||
/* Add a segment range for all existing segments to the given collection of
|
/* Add a span for all existing segments to the given collection of spans. The
|
||||||
* ranges. The currently active segment will be inserted first with all others
|
* currently active segment will be inserted first with all others following.
|
||||||
* following.
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Segment* Seg;
|
Segment* Seg;
|
||||||
|
|
||||||
/* Add the currently active segment */
|
/* Add the currently active segment */
|
||||||
CollAppend (Ranges, NewSegRange (ActiveSeg));
|
CollAppend (Spans, NewSpan (ActiveSeg));
|
||||||
|
|
||||||
/* Walk through the segment list and add all other segments */
|
/* Walk through the segment list and add all other segments */
|
||||||
Seg = SegmentList;
|
Seg = SegmentList;
|
||||||
while (Seg) {
|
while (Seg) {
|
||||||
/* Be sure to skip the active segment, since it was already added */
|
/* Be sure to skip the active segment, since it was already added */
|
||||||
if (Seg != ActiveSeg) {
|
if (Seg != ActiveSeg) {
|
||||||
CollAppend (Ranges, NewSegRange (Seg));
|
CollAppend (Spans, NewSpan (Seg));
|
||||||
}
|
}
|
||||||
Seg = Seg->List;
|
Seg = Seg->List;
|
||||||
}
|
}
|
||||||
@ -92,59 +91,60 @@ void AddSegRanges (Collection* Ranges)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CloseSegRanges (Collection* Ranges)
|
void CloseSpans (Collection* Spans)
|
||||||
/* Close all open segment ranges by setting PC to the current PC for the
|
/* Close all open spans by setting PC to the current PC for the segment. */
|
||||||
* segment.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
/* Walk over the segment list */
|
/* Walk over the segment list */
|
||||||
for (I = 0; I < CollCount (Ranges); ++I) {
|
for (I = 0; I < CollCount (Spans); ++I) {
|
||||||
|
|
||||||
/* Get the next segment range */
|
/* Get the next segment range */
|
||||||
SegRange* R = CollAtUnchecked (Ranges, I);
|
Span* S = CollAtUnchecked (Spans, I);
|
||||||
|
|
||||||
/* Set the end offset */
|
/* Set the end offset */
|
||||||
R->End = R->Seg->PC;
|
S->End = S->Seg->PC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void WriteSegRanges (const Collection* Ranges)
|
void WriteSpans (const Collection* Spans)
|
||||||
/* Write a list of segment ranges to the output file */
|
/* Write a list of spans to the output file */
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
unsigned Count;
|
unsigned Count;
|
||||||
|
|
||||||
/* Determine how many of the segments contain actual data */
|
/* Determine how many of the segments contain actual data */
|
||||||
Count = 0;
|
Count = 0;
|
||||||
for (I = 0; I < CollCount (Ranges); ++I) {
|
for (I = 0; I < CollCount (Spans); ++I) {
|
||||||
|
|
||||||
/* Get next range */
|
/* Get next range */
|
||||||
const SegRange* R = CollConstAt (Ranges, I);
|
const Span* S = CollConstAt (Spans, I);
|
||||||
|
|
||||||
/* Is this segment range empty? */
|
/* Is this segment range empty? */
|
||||||
if (R->Start != R->End) {
|
if (S->Start != S->End) {
|
||||||
++Count;
|
++Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the number of ranges with data */
|
/* Write the number of spans with data */
|
||||||
ObjWriteVar (Count);
|
ObjWriteVar (Count);
|
||||||
|
|
||||||
/* Write the ranges */
|
/* Write the spans */
|
||||||
for (I = 0; I < CollCount (Ranges); ++I) {
|
for (I = 0; I < CollCount (Spans); ++I) {
|
||||||
|
|
||||||
/* Get next range */
|
/* Get next range */
|
||||||
const SegRange* R = CollConstAt (Ranges, I);
|
const Span* S = CollConstAt (Spans, I);
|
||||||
|
|
||||||
/* Write data for non empty ranges */
|
/* Write data for non empty spans. We will write the size instead of
|
||||||
if (R->Start != R->End) {
|
* the end offset to save some bytes, since most spans are expected
|
||||||
ObjWriteVar (R->Seg->Num);
|
* to be rather small.
|
||||||
ObjWriteVar (R->Start);
|
*/
|
||||||
ObjWriteVar (R->End);
|
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
|
#ifndef SPAN_H
|
||||||
#define SEGRANGE_H
|
#define SPAN_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -50,9 +50,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Segment range definition */
|
/* Span definition */
|
||||||
typedef struct SegRange SegRange;
|
typedef struct Span Span;
|
||||||
struct SegRange{
|
struct Span{
|
||||||
struct Segment* Seg; /* Pointer to segment */
|
struct Segment* Seg; /* Pointer to segment */
|
||||||
unsigned long Start; /* Start of range */
|
unsigned long Start; /* Start of range */
|
||||||
unsigned long End; /* End of range */
|
unsigned long End; /* End of range */
|
||||||
@ -66,41 +66,37 @@ struct SegRange{
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SegRange* NewSegRange (struct Segment* Seg);
|
Span* NewSpan (struct Segment* Seg);
|
||||||
/* Create a new segment range. The segment is set to Seg, Start and End are
|
/* Create a new span. The segment is set to Seg, Start and End are set to the
|
||||||
* set to the current PC of the segment.
|
* current PC of the segment.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE unsigned long GetSegRangeSize (const SegRange* R)
|
INLINE unsigned long GetSpanSize (const Span* R)
|
||||||
/* Return the segment range size in bytes */
|
/* Return the span size in bytes */
|
||||||
{
|
{
|
||||||
return (R->End - R->Start);
|
return (R->End - R->Start);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetSegRangeSize(R) ((R)->End - (R)->Start)
|
# define GetSpanSize(R) ((R)->End - (R)->Start)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void AddSegRanges (Collection* Ranges);
|
void AddSpans (Collection* Spans);
|
||||||
/* Add a segment range for all existing segments to the given collection of
|
/* Add a span for all existing segments to the given collection of spans. The
|
||||||
* ranges. The currently active segment will be inserted first with all others
|
* currently active segment will be inserted first with all others following.
|
||||||
* following.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void CloseSegRanges (Collection* Ranges);
|
void CloseSpans (Collection* Spans);
|
||||||
/* Close all open segment ranges by setting PC to the current PC for the
|
/* Close all open spans by setting PC to the current PC for the segment. */
|
||||||
* segment.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void WriteSegRanges (const Collection* Ranges);
|
void WriteSpans (const Collection* Spans);
|
||||||
/* Write a list of segment ranges to the output file */
|
/* Write a list of spans to the output file */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of segrange.h */
|
/* End of span.h */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
|||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "segment.h"
|
#include "segment.h"
|
||||||
#include "sizeof.h"
|
#include "sizeof.h"
|
||||||
|
#include "span.h"
|
||||||
#include "spool.h"
|
#include "spool.h"
|
||||||
#include "studyexpr.h"
|
#include "studyexpr.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
@ -116,7 +117,7 @@ static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name)
|
|||||||
S->Right = 0;
|
S->Right = 0;
|
||||||
S->Childs = 0;
|
S->Childs = 0;
|
||||||
S->OwnerSym = 0;
|
S->OwnerSym = 0;
|
||||||
S->SegRanges = AUTO_COLLECTION_INITIALIZER;
|
S->Spans = AUTO_COLLECTION_INITIALIZER;
|
||||||
S->Id = ScopeCount++;
|
S->Id = ScopeCount++;
|
||||||
S->Flags = ST_NONE;
|
S->Flags = ST_NONE;
|
||||||
S->AddrSize = ADDR_SIZE_DEFAULT;
|
S->AddrSize = ADDR_SIZE_DEFAULT;
|
||||||
@ -215,14 +216,14 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
|
|||||||
CurrentScope->Type = Type;
|
CurrentScope->Type = Type;
|
||||||
CurrentScope->OwnerSym = OwnerSym;
|
CurrentScope->OwnerSym = OwnerSym;
|
||||||
|
|
||||||
/* If this is a scope that allows to emit data into segments, add segment
|
/* If this is a scope that allows to emit data into segments, add spans
|
||||||
* ranges for all currently existing segments. Doing this for just a few
|
* for all currently existing segments. Doing this for just a few scope
|
||||||
* scope types is not really necessary but an optimization, because it
|
* types is not really necessary but an optimization, because it does not
|
||||||
* does not allocate memory for useless data (unhandled types here don't
|
* allocate memory for useless data (unhandled types here don't occupy
|
||||||
* occupy space in any segment).
|
* space in any segment).
|
||||||
*/
|
*/
|
||||||
if (CurrentScope->Type <= SCOPE_HAS_DATA) {
|
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)
|
void SymLeaveLevel (void)
|
||||||
/* Leave the current lexical level */
|
/* Leave the current lexical level */
|
||||||
{
|
{
|
||||||
/* Close the segment ranges. We don't care about the scope type here,
|
/* Close the spans. We don't care about the scope type here, since types
|
||||||
* since types without segment ranges will just have an empty list.
|
* 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
|
/* If we have spans, the first one is the segment that was active, when the
|
||||||
* active, when the scope was opened. Set the size of the scope to the
|
* scope was opened. Set the size of the scope to the number of data bytes
|
||||||
* number of data bytes emitted into this segment. If we have an owner
|
* emitted into this segment. If we have an owner symbol set the size of
|
||||||
* symbol set the size of this symbol, too.
|
* this symbol, too.
|
||||||
*/
|
*/
|
||||||
if (CollCount (&CurrentScope->SegRanges) > 0) {
|
if (CollCount (&CurrentScope->Spans) > 0) {
|
||||||
const SegRange* R = CollAtUnchecked (&CurrentScope->SegRanges, 0);
|
const Span* S = CollAtUnchecked (&CurrentScope->Spans, 0);
|
||||||
unsigned long Size = GetSegRangeSize (R);
|
unsigned long Size = GetSpanSize (S);
|
||||||
DefSizeOfScope (CurrentScope, Size);
|
DefSizeOfScope (CurrentScope, Size);
|
||||||
if (CurrentScope->OwnerSym) {
|
if (CurrentScope->OwnerSym) {
|
||||||
DefSizeOfSymbol (CurrentScope->OwnerSym, Size);
|
DefSizeOfSymbol (CurrentScope->OwnerSym, Size);
|
||||||
@ -940,8 +941,8 @@ void WriteScopes (void)
|
|||||||
ObjWriteVar (Size);
|
ObjWriteVar (Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Segment ranges for this scope */
|
/* Spans for this scope */
|
||||||
WriteSegRanges (&S->SegRanges);
|
WriteSpans (&S->Spans);
|
||||||
|
|
||||||
/* Next scope */
|
/* Next scope */
|
||||||
S = S->Next;
|
S = S->Next;
|
||||||
|
@ -45,7 +45,6 @@
|
|||||||
#include "inline.h"
|
#include "inline.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "segrange.h"
|
|
||||||
#include "symentry.h"
|
#include "symentry.h"
|
||||||
|
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ struct SymTable {
|
|||||||
SymTable* Parent; /* Link to enclosing scope if any */
|
SymTable* Parent; /* Link to enclosing scope if any */
|
||||||
SymTable* Childs; /* Pointer to child scopes */
|
SymTable* Childs; /* Pointer to child scopes */
|
||||||
SymEntry* OwnerSym; /* Symbol that "owns" the scope */
|
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 Id; /* Scope id */
|
||||||
unsigned short Flags; /* Symbol table flags */
|
unsigned short Flags; /* Symbol table flags */
|
||||||
unsigned char AddrSize; /* Address size */
|
unsigned char AddrSize; /* Address size */
|
||||||
|
Loading…
Reference in New Issue
Block a user