-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfastpass.c
204 lines (180 loc) · 6.49 KB
/
fastpass.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/****************************************************************************
*
* This code is Public Domain.
*
* ========================================================================
*
* Description: implements the "fastpass" handling.
* "fastpass" is an optimization which increases
* assembly time speed by storing preprocessed lines
* in memory during the first pass. In further passes,
* those lines are "read" instead of the original assembly
* source files.
* Speed increase is significant if there's a large include
* file at the top of an assembly source which contains
* just equates and type definitions, because there's no need
* to save such lines during pass one.
*
****************************************************************************/
#include <ctype.h>
#include "globals.h"
#include "memalloc.h"
#include "parser.h"
#include "input.h"
#include "segment.h"
#include "fastpass.h"
#if FASTPASS
struct mod_state modstate; /* struct to store assembly status */
static struct line_item *LineStoreHead;
static struct line_item *LineStoreTail;
struct line_item *LineStoreCurr; /* must be global! */
bool StoreState;
bool UseSavedState;
/*
* save the current status (happens in pass one only) and
* switch to "save precompiled lines" mode.
* the status is then restored in further passes,
* and the precompiled lines are used for assembly then.
*/
static void SaveState( void )
/***************************/
{
DebugMsg1(("SaveState enter\n" ));
StoreState = TRUE;
UseSavedState = TRUE;
modstate.init = TRUE;
modstate.EquHead = modstate.EquTail = NULL;
memcpy( &modstate.modinfo, &ModuleInfo, sizeof( struct module_info ) );
SegmentSaveState();
AssumeSaveState();
ContextSaveState(); /* save pushcontext/popcontext stack */
DebugMsg(( "SaveState exit\n" ));
}
void StoreLine( char *srcline, uint_32 list_pos, int flags )
/**********************************************************/
{
int i,j;
char *p;
#ifdef DEBUG_OUT
if ( Options.nofastpass )
return;
#endif
if ( GeneratedCode ) /* don't store generated lines! */
return;
if ( StoreState == FALSE ) /* line store already started? */
SaveState();
i = strlen( srcline );
j = ( ( ( flags & 1 ) && ModuleInfo.CurrComment ) ? strlen( ModuleInfo.CurrComment ) : 0 );
LineStoreCurr = LclAlloc( i + j + sizeof( struct line_item ) );
LineStoreCurr->next = NULL;
LineStoreCurr->lineno = LineNumber;
if ( MacroLevel ) {
LineStoreCurr->srcfile = 0xfff;
} else {
LineStoreCurr->srcfile = get_curr_srcfile();
}
LineStoreCurr->list_pos = list_pos;
if ( j ) {
memcpy( LineStoreCurr->line, srcline, i );
memcpy( LineStoreCurr->line + i, ModuleInfo.CurrComment, j + 1 );
} else
memcpy( LineStoreCurr->line, srcline, i + 1 );
DebugMsg1(("StoreLine(>%s<, listpos=%u): cur=%X\n", LineStoreCurr->line, list_pos, LineStoreCurr ));
/* v2.08: don't store % operator at pos 0 */
for ( p = LineStoreCurr->line; *p && isspace(*p); p++ );
if (*p == '%' && ( _memicmp( p+1, "OUT", 3 ) || is_valid_id_char( *(p+4) ) ) )
*p = ' ';
#ifdef DEBUG_OUT
if ( Options.print_linestore )
printf("%s\n", LineStoreCurr->line );
#endif
if ( LineStoreHead )
LineStoreTail->next = LineStoreCurr;
else
LineStoreHead = LineStoreCurr;
LineStoreTail = LineStoreCurr;
}
/* an error has been detected in pass one. it should be
reported in pass 2, so ensure that a full source scan is done then
*/
void SkipSavedState( void )
/*************************/
{
DebugMsg(("SkipSavedState enter\n"));
UseSavedState = FALSE;
}
/* for FASTPASS, just pass 1 is a full pass, the other passes
don't start from scratch and they just assemble the preprocessed
source. To be able to restart the assembly process from a certain
location within the source, it's necessary to save the value of
assembly time variables.
*/
void SaveVariableState( struct asym *sym )
/****************************************/
{
struct equ_item *p;
DebugMsg1(( "SaveVariableState(%s)=%d\n", sym->name, sym->value ));
sym->saved = TRUE; /* don't try to save this symbol (anymore) */
p = LclAlloc( sizeof( struct equ_item ) );
p->next = NULL;
p->sym = sym;
p->lvalue = sym->value;
p->hvalue = sym->value3264; /* v2.05: added */
p->mem_type = sym->mem_type; /* v2.07: added */
p->isdefined = sym->isdefined;
if ( modstate.EquTail ) {
modstate.EquTail->next = p;
modstate.EquTail = p;
} else {
modstate.EquHead = modstate.EquTail = p;
}
// printf("state of symbol >%s< saved, value=%u, defined=%u\n", sym->name, sym->value, sym->defined);
}
struct line_item *RestoreState( void )
/************************************/
{
DebugMsg1(("RestoreState enter\n"));
if ( modstate.init ) {
struct equ_item *curr;
/* restore values of assembly time variables */
for ( curr = modstate.EquHead; curr; curr = curr->next ) {
DebugMsg1(("RestoreState: sym >%s<, value=%Xh (hvalue=%Xh), defined=%u\n", curr->sym->name, curr->lvalue, curr->hvalue, curr->isdefined ));
/* v2.07: MT_ABS is obsolete */
//if ( curr->sym->mem_type == MT_ABS ) {
curr->sym->value = curr->lvalue;
curr->sym->value3264 = curr->hvalue;
curr->sym->mem_type = curr->mem_type; /* v2.07: added */
curr->sym->isdefined = curr->isdefined;
//}
}
/* fields in struct "g" are not to be restored. */
memcpy( &modstate.modinfo.g, &ModuleInfo.g, sizeof( ModuleInfo.g ) );
memcpy( &ModuleInfo, &modstate.modinfo, sizeof( struct module_info ) );
SetOfssize();
SymSetCmpFunc();
}
#if 0
/* v2.05: AFAICS this can't happen anymore. */
if ( LineStoreHead == NULL ) {
struct line_item *endl = LclAlloc( sizeof( struct line_item ) + 3 );
endl->next = NULL;
endl->srcfile = 0;
endl->lineno = LineNumber;
endl->list_pos = 0;
strcpy( endl->line, "END");
LineStoreHead = endl;
DebugMsg(("RestoreState: LineStoreHead was NULL !!!\n" ));
}
#endif
return( LineStoreHead );
}
void FastpassInit( void )
/***********************/
{
StoreState = FALSE;
modstate.init = FALSE;
LineStoreHead = NULL;
LineStoreTail = NULL;
UseSavedState = FALSE;
}
#endif