-
Notifications
You must be signed in to change notification settings - Fork 1
/
emt.h
182 lines (151 loc) · 5.38 KB
/
emt.h
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
/*
$Header: d:/cvsroot/tads/TADS2/EMT.H,v 1.2 1999/05/17 02:52:11 MJRoberts Exp $
*/
/*
* Copyright (c) 1991, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
emt.h - emitter definitions
Function
Defines interface to the code emitter
Notes
None
Modified
09/23/91 MJRoberts - creation
*/
#ifndef EMT_INCLUDED
#define EMT_INCLUDED
#ifndef STD_INCLUDED
# include "std.h"
#endif
#ifndef ERR_INCLUDED
# include "err.h"
#endif
#ifndef MCM_INCLUDED
# include "mcm.h"
#endif
#ifndef OBJ_INCLUDED
# include "obj.h"
#endif
#ifndef TOK_INCLUDED
#include "tok.h"
#endif
/* temporary labels/forward reference fixups */
struct emtldef
{
ushort emtllnk; /* link: first/next forward reference */
ushort emtlofs; /* offset of label/forward reference to fix up */
uchar emtlflg; /* flags */
# define EMTLFSET 1 /* label has been set - no longer forward */
};
typedef struct emtldef emtldef;
/* end of link list */
#define EMTLLNKEND ((ushort)~0)
/* emitter context */
struct emtcxdef
{
errcxdef *emtcxerr; /* error handling context */
mcmcxdef *emtcxmem; /* cache manager context */
mcmon emtcxobj; /* object code is being written to */
ushort emtcxofs; /* offset of next byte of code to be written */
uchar *emtcxptr; /* pointer to object's memory */
int emtcxlcnt; /* size of emtcxlbl array */
ushort emtcxlfre; /* first free label/forward reference */
emtldef emtcxlbl[1]; /* array of labels/forward reference fixups */
objnum emtcxfrob; /* debug frame object, if any */
};
typedef struct emtcxdef emtcxdef;
/* pre-emit list element structure */
struct emtledef
{
uchar emtletyp;
long emtleval;
};
typedef struct emtledef emtledef;
/* pre-emit list definition structure */
struct emtlidef
{
int emtlicnt; /* number of elements in the list */
emtledef emtliele[1]; /* array of list elements */
};
typedef struct emtlidef emtlidef;
/* emit a value, given as a token */
void emtval(emtcxdef *ctx, struct tokdef *tok, uchar *base);
/* emit an operand-less opcode */
/* void emtop(emtcxdef *ctx, uchar op); */
#define emtop(ctx,op) \
(emtres(ctx, (ushort)1), \
(void)(*((ctx)->emtcxptr + (ctx)->emtcxofs++) = (op)))
/* emit a single byte */
/* void emtbyte(emtcxdef *ctx, uchar b); */
#define emtbyte(ctx,b) emtop(ctx,b)
/* emit bytes from memory */
/* void emtmem(emtcxdef *ctx, void *ptr, size_t siz); */
#define emtmem(ctx,ptr,siz) \
(emtres(ctx, (ushort)(siz)),\
memcpy((ctx)->emtcxptr + (ctx)->emtcxofs,ptr,(size_t)(siz)),\
(void)((ctx)->emtcxofs += (siz)))
/* emit an 2-byte unsigned integer value */
/* void emtint2(emtcxdef *ctx, int i); */
#define emtint2(ctx,i) \
(emtres(ctx, (ushort)2), oswp2((ctx)->emtcxptr + (ctx)->emtcxofs, i), \
(ctx)->emtcxofs+=2)
/* emit a 2-byte signed integer value */
/* void emtint2s(emtcxdef *ctx, int i); */
#define emtint2s(ctx,i) \
(emtres(ctx, (ushort)2), oswp2s((ctx)->emtcxptr + (ctx)->emtcxofs, i), \
(ctx)->emtcxofs+=2)
/* emit a 2-byte integer at a particular offset in the code */
#define emtint2at(ctx,i,ofs) \
(oswp2((ctx)->emtcxptr + (ofs), i))
/* emit a signed 2-byte integer at a particular offset in the code */
#define emtint2sat(ctx,i,ofs) \
(oswp2s((ctx)->emtcxptr + (ofs), i))
/* read a 2-byte integer previously emitted */
#define emtint2from(ctx, ofs) \
(osrp2((ctx)->emtcxptr + (ofs)))
/* emit a 4-byte integer value */
/* void emtint4(emtcxdef *ctx, long l); */
#define emtint4(ctx,l) \
(emtres(ctx, (ushort)4), oswp4s((ctx)->emtcxptr + (ctx)->emtcxofs, l), \
(ctx)->emtcxofs+=4)
/* set up temporary labels in code generation context */
void emtlini(emtcxdef *ctx);
/* get a temporary code label */
uint emtglbl(emtcxdef *ctx);
/* get a temporary code label set to the current code location */
uint emtgslbl(emtcxdef *ctx);
/*
* Set a temporary label to the current position, releasing it if
* desired. If the label is released, *lab is set to an invalid label
* value (EMTLLNKEND) so that the caller can detect (for error-handling
* purposes) whether the label has been freed.
*/
void emtslbl(emtcxdef *ctx, noreg uint *lab, int release);
/*
* Release a temporary label for re-use. *lab is set to EMTLLNKEND so
* that the caller can detect (for error-handling purposes) whether the
* label has been freed.
*/
void emtdlbl(emtcxdef *ctx, noreg uint *lab);
/*
* Clear label, ignoring errors (used for error cleanup). *lab is set
* to EMTLLNKEND to flag that it's been freed.
*/
void emtclbl(emtcxdef *ctx, noreg uint *lab);
/* return TRUE if a label has been set, FALSE if not set */
/* int emtqset(emtcxdef *ctx, uint lab); */
#define emtqset(ctx,lab) (((ctx)->emtcxlbl[lab].emtlflg & EMTLFSET) != 0)
/* emit a jump to a temporary label */
void emtjmp(emtcxdef *ctx, uchar op, uint lab);
/* reserve space for code */
void emtres(emtcxdef *ctx, ushort bytes);
/* emit a list value */
void emtlst(emtcxdef *ctx, uint ofs, uchar *base);
/* incremental addition to object size when we run out of space */
#define EMTINC 256
#endif /* EMT_INCLUDED */