Commit | Line | Data |
---|---|---|
8c1020c4 | 1 | /* Copyright (c) 1980 Regents of the University of California */ |
31cef89c | 2 | /* "@(#)as.h 4.8 11/5/80" */ |
8c1020c4 BJ |
3 | #ifdef VMS |
4 | # define vax 1 | |
5 | # define VAX 1 | |
6 | #endif VMS | |
7 | ||
451260e7 RH |
8 | #include <sys/types.h> |
9 | #ifdef UNIX | |
10 | ||
11 | #ifdef FLEXNAMES | |
12 | # include <a.out.h> | |
13 | # include <stab.h> | |
14 | #else not FLEXNAMES | |
0c940099 RH |
15 | # define ONLIST |
16 | # include "a.out.h" | |
451260e7 RH |
17 | # include <stab.h> |
18 | #endif FLEXNAMES | |
19 | ||
20 | #endif UNIX | |
21 | #ifdef VMS | |
22 | ||
23 | #ifdef UNIXDEVEL | |
24 | # include <a.out.h> | |
25 | #else not UNIXDEVEL | |
26 | # include <aout.h> | |
27 | #endif not UNIXDEVEL | |
28 | ||
29 | #endif VMS | |
8c1020c4 | 30 | |
451260e7 | 31 | #define readonly |
8c1020c4 BJ |
32 | #define NINST 300 |
33 | ||
34 | #define NEXP 20 /* max number of expr. terms per instruction */ | |
35 | #define NARG 6 /* max number of args per instruction */ | |
36 | #define NHASH 1103 /* hash table is dynamically extended */ | |
6cca131f | 37 | #define TNAMESIZE 32 /* maximum length of temporary file names */ |
8c1020c4 BJ |
38 | #define NLOC 4 /* number of location ctrs */ |
39 | ||
40 | #ifdef UNIX | |
41 | # ifndef FLEXNAMES | |
42 | # ifndef NCPS | |
43 | # define NCPS 8 /* number of characters per symbol*/ | |
44 | # endif | |
45 | # else | |
46 | # ifdef NCPS | |
47 | # undef NCPS | |
48 | # endif | |
49 | # define NCPS BUFSIZ /* needed to allocate yytext */ | |
50 | # endif | |
51 | # endif UNIX | |
52 | ||
53 | # ifdef VMS | |
54 | # ifdef NCPS | |
55 | # undef NCPS | |
56 | # endif NCPS | |
57 | # define NCPS 15 | |
58 | # endif VMS | |
59 | ||
60 | /* | |
61 | * Symbol types | |
62 | */ | |
63 | #define XUNDEF 0x0 | |
64 | #define XABS 0x2 | |
65 | #define XTEXT 0x4 | |
66 | #define XDATA 0x6 | |
67 | #define XBSS 0x8 | |
68 | ||
69 | #define XXTRN 0x1 | |
70 | #define XTYPE 0x1E | |
71 | ||
72 | #define XFORW 0x20 /* Was forward-referenced when undefined */ | |
73 | ||
74 | #define ERR (-1) | |
75 | #define NBPW 32 /* Bits per word */ | |
76 | ||
77 | #define AMASK 017 | |
78 | ||
79 | /* | |
80 | * Actual argument syntax types | |
81 | */ | |
6cca131f RH |
82 | #define AREG 1 /* %r */ |
83 | #define ABASE 2 /* (%r) */ | |
84 | #define ADECR 3 /* -(%r) */ | |
85 | #define AINCR 4 /* (%r)+ */ | |
86 | #define ADISP 5 /* expr(%r) */ | |
87 | #define AEXP 6 /* expr */ | |
88 | #define AIMM 7 /* $ expr */ | |
89 | #define ASTAR 8 /* * */ | |
90 | #define AINDX 16 /* [%r] */ | |
8c1020c4 BJ |
91 | |
92 | /* | |
93 | * Argument access types used to test validity of operands to operators | |
94 | */ | |
301986ee RH |
95 | #define ACCR (1<<3) /* read */ |
96 | #define ACCW (2<<3) /* write */ | |
97 | #define ACCB (4<<3) /* branch displacement */ | |
98 | #define ACCA (8<<3) /* address only */ | |
99 | #define ACCM (ACCR | ACCW) /* modify */ | |
100 | #define ACCI (ACCB | ACCR) /* XFC code */ | |
101 | ||
5b3c350a | 102 | #define ACCESSMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */ |
8c1020c4 BJ |
103 | |
104 | /* | |
5b3c350a RH |
105 | * Argument data types |
106 | * Also used to tell outrel what it is relocating | |
107 | * (possibly in combination with RELOC_PCREL and TYPNONE) | |
8c1020c4 | 108 | */ |
5b3c350a RH |
109 | #define TYPB 0 /* byte */ |
110 | #define TYPW 1 /* word */ | |
111 | #define TYPL 2 /* long */ | |
112 | #define TYPQ 3 /* quad */ | |
113 | #define TYPF 4 /* floating */ | |
114 | #define TYPD 5 /* double floating */ | |
115 | #define TYPNONE 6 /* when nothing */ | |
116 | #define RELOC_PCREL 8 /* implicit argument to outrel; ==> PCREL */ | |
8c1020c4 | 117 | |
6cca131f | 118 | #define TYPMASK 7 |
8c1020c4 | 119 | |
5b3c350a RH |
120 | /* |
121 | * reference types for loader | |
122 | */ | |
6cca131f RH |
123 | #define PCREL 1 |
124 | #define LEN1 2 | |
125 | #define LEN2 4 | |
126 | #define LEN4 6 | |
127 | #define LEN8 8 | |
5b3c350a RH |
128 | |
129 | extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */ | |
130 | extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */ | |
131 | extern int len124[]; /* {1,2,4,8} ==> {LEN1, LEN2, LEN4, LEN8} */ | |
132 | extern char mod124[]; /* {1,2,4,8} ==> {bits to construct operands */ | |
133 | extern int type_124[]; /* {1,2,4,8} ==> {TYPB, TYPW, TYPL, TYPQ} */ | |
134 | extern int ty_NORELOC[]; /* {TYPB..TYPD} ==> {1 if relocation not OK */ | |
135 | extern int ty_LEN[]; /* {TYPB..TYPD} ==> {LEN1..LEN8} */ | |
136 | extern int ty_nbyte[]; /* {TYPB..TYPD} ==> {1,2,4,8} */ | |
137 | extern int ty_nlg[]; /* {TYPB..TYPD} ==> lg{1,2,4,8} */ | |
8c1020c4 BJ |
138 | |
139 | #define TMPC 7 | |
140 | #define HW 01 | |
141 | #define FW 03 | |
142 | #define DW 07 | |
143 | ||
144 | #ifdef UNIX | |
145 | # include <pagsiz.h> | |
146 | #endif UNIX | |
147 | ||
148 | #ifdef VMS | |
149 | # define PAGRND 0x1FFL | |
150 | #endif VMS | |
151 | ||
152 | #define round(x,y) (((x)+(y)) & ~(y)) | |
153 | ||
154 | #define STABTYPS 0340 | |
6cca131f | 155 | #define STABFLAG 0200 |
8c1020c4 BJ |
156 | |
157 | /* | |
158 | * Follows are the definitions for the symbol table tags, which are | |
159 | * all unsigned characters.. | |
160 | * High value tags are generated by the asembler for internal | |
161 | * use. | |
162 | * Low valued tags are the parser coded tokens the scanner returns. | |
163 | * There are several pertinant bounds in this ordering: | |
164 | * a) Symbols greater than JXQUESTIONABLE | |
165 | * are used by the jxxx bumper, indicating that | |
166 | * the symbol table entry is a jxxx entry | |
167 | * that has yet to be bumped. | |
168 | * b) Symbols greater than IGNOREBOUND are not | |
169 | * bequeathed to the loader; they are truly | |
170 | * for assembler internal use only. | |
171 | * c) Symbols greater than OKTOBUMP represent | |
172 | * indices into the program text that should | |
173 | * be changed in preceeding jumps or aligns | |
174 | * must get turned into their long form. | |
175 | */ | |
176 | ||
6cca131f | 177 | #define TAGMASK 0xFF |
8c1020c4 BJ |
178 | |
179 | # define JXACTIVE 0xFF /*jxxx size unknown*/ | |
180 | # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ | |
181 | # define JXALIGN 0xFD /*align jxxx entry*/ | |
182 | # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ | |
183 | ||
6cca131f | 184 | #define JXQUESTIONABLE 0xFB |
8c1020c4 BJ |
185 | |
186 | # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ | |
187 | # define OBSOLETE 0xF9 /*erroneously entered symbol*/ | |
188 | ||
189 | #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ | |
190 | # define STABFLOATING 0xF7 | |
191 | # define LABELID 0xF6 | |
192 | ||
193 | #define OKTOBUMP 0xF5 | |
194 | # define STABFIXED 0xF4 | |
195 | ||
196 | /* | |
197 | * astoks.h contains reserved word codings the parser should | |
198 | * know about | |
199 | */ | |
200 | #include "astoks.h" | |
201 | ||
202 | /* | |
203 | * The structure for one symbol table entry. | |
204 | * Symbol table entries are used for both user defined symbols, | |
205 | * and symbol slots generated to create the jxxx jump from | |
206 | * slots. | |
451260e7 RH |
207 | * Caution: the instructions are stored in a shorter version |
208 | * of the struct symtab, using all fields in sym_nm and | |
209 | * tag. The fields used in sym_nm are carefully redeclared | |
210 | * in struct Instab and struct instab (see below). | |
211 | * If struct nlist gets changed, then Instab and instab may | |
212 | * have to be changed. | |
8c1020c4 BJ |
213 | */ |
214 | ||
8c1020c4 | 215 | struct symtab{ |
451260e7 RH |
216 | struct nlist s_nm; |
217 | u_char s_tag; /* assembler tag */ | |
218 | u_char s_ptype; /* if tag == NAME */ | |
219 | u_char s_jxoveralign; /* if a JXXX, jumped over align */ | |
220 | short s_index; /* which segment */ | |
221 | struct symtab *s_dest; /* if JXXX, where going to */ | |
8c1020c4 | 222 | #ifdef DJXXX |
451260e7 | 223 | short s_jxline; /* source line of the jump from */ |
8c1020c4 BJ |
224 | #endif |
225 | }; | |
451260e7 RH |
226 | /* |
227 | * Redefinitions of the fields in symtab for | |
228 | * use when the symbol table entry marks a jxxx instruction. | |
229 | */ | |
230 | #define s_jxbump s_ptype /* tag == JX..., how far to expand */ | |
231 | #define s_jxfear s_desc /* how far needs to be bumped */ | |
232 | /* | |
233 | * Redefinitions of fields in the struct nlist for symbols so that | |
234 | * one saves typing, and so that they conform | |
235 | * with the old naming conventions. | |
236 | */ | |
237 | #ifdef FLEXNAMES | |
238 | #define s_name s_nm.n_un.n_name /* name pointer */ | |
239 | #define s_nmx s_nm.n_un.n_strx /* string table index */ | |
240 | #else not FLEXNAMES | |
241 | #define s_name s_nm.n_name | |
242 | #endif | |
243 | #define s_type s_nm.n_type /* type of the symbol */ | |
244 | #define s_other s_nm.n_other /* other information for sdb */ | |
245 | #define s_desc s_nm.n_desc /* type descriptor */ | |
246 | #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ | |
247 | ||
248 | struct instab{ | |
249 | struct nlist s_nm; /* instruction name, type (opcode) */ | |
250 | u_char s_tag; | |
0c940099 | 251 | char s_pad[3]; /* round to 20 bytes */ |
8c1020c4 | 252 | }; |
451260e7 RH |
253 | /* |
254 | * The fields nm.n_desc and nm.n_value total 6 bytes; this is | |
255 | * just enough for the 6 bytes describing the argument types. | |
256 | * We use a macro to define access to these 6 bytes, assuming that | |
257 | * they are allocated adjacently. | |
258 | * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. | |
259 | * | |
0c940099 | 260 | * Instab is cleverly declared to look very much like the combination of |
451260e7 RH |
261 | * a struct symtab and a struct nlist. |
262 | */ | |
263 | struct Instab{ | |
264 | #ifdef FLEXNAMES | |
265 | char *I_name; | |
266 | #else not FLEXNAMES | |
267 | char I_name[NCPS]; | |
268 | #endif | |
269 | u_char I_opcode; | |
270 | char I_nargs; | |
271 | char I_args[6]; | |
272 | u_char I_s_tag; | |
0c940099 | 273 | char I_pad[3]; /* round to 20 bytes */ |
451260e7 RH |
274 | }; |
275 | /* | |
276 | * Redefinitions of fields in the struct nlist for instructions so that | |
277 | * one saves typing, and conforms to the old naming conventions | |
278 | */ | |
279 | #define i_opcode s_nm.n_type /* use the same field as symtab.type */ | |
280 | #define i_nargs s_nm.n_other /* number of arguments */ | |
281 | #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] | |
8c1020c4 BJ |
282 | |
283 | struct arg { /*one argument to an instruction*/ | |
451260e7 RH |
284 | char a_atype; |
285 | char a_areg1; | |
286 | char a_areg2; | |
287 | char a_dispsize; /*usually d124, unless have B^, etc*/ | |
288 | struct exp *a_xp; | |
8c1020c4 BJ |
289 | }; |
290 | ||
291 | struct exp { | |
451260e7 RH |
292 | long e_xvalue; /* MUST be the first field (look at union Double) */ |
293 | long e_yvalue; /* MUST be second field; least sig word of a double */ | |
294 | char e_xtype; | |
295 | char e_xloc; | |
296 | struct symtab *e_xname; | |
8c1020c4 BJ |
297 | }; |
298 | ||
451260e7 RH |
299 | #define doub_MSW e_xvalue |
300 | #define doub_LSW e_yvalue | |
8c1020c4 | 301 | |
451260e7 | 302 | union Double { |
8c1020c4 BJ |
303 | struct{ |
304 | long doub_MSW; | |
305 | long doub_LSW; | |
306 | } dis_dvalue; | |
307 | double dvalue; | |
308 | }; | |
309 | ||
451260e7 | 310 | struct Quad { |
8c1020c4 BJ |
311 | long quad_low_long; |
312 | long quad_high_long; | |
313 | }; | |
314 | ||
315 | /* | |
316 | * Magic layout macros | |
317 | */ | |
318 | #define MINBYTE -128 | |
319 | #define MAXBYTE 127 | |
320 | #define MINWORD -32768 | |
321 | #define MAXWORD 32767 | |
322 | ||
323 | #define LITFLTMASK 0x000043F0 /*really magic*/ | |
324 | /* | |
325 | * Is the floating point double word in xp a | |
326 | * short literal floating point number? | |
327 | */ | |
328 | #define slitflt(xp) \ | |
329 | ( (xp->doub_LSW == 0) \ | |
330 | && ( (xp->doub_MSW & LITFLTMASK) \ | |
331 | == xp->doub_MSW) ) | |
332 | /* | |
333 | * If it is a slitflt, then extract the 6 interesting bits | |
334 | */ | |
335 | #define extlitflt(xp) \ | |
336 | xp->doub_MSW >> 4 | |
337 | ||
338 | extern struct arg arglist[NARG]; /*building operands in instructions*/ | |
339 | extern struct exp explist[NEXP]; /*building up a list of expressions*/ | |
340 | extern struct exp *xp; /*current free expression*/ | |
341 | /* | |
342 | * Communication between the scanner and the jxxx handlers. | |
343 | * lastnam: the last name seen on the input | |
344 | * lastjxxx: pointer to the last symbol table entry for | |
345 | * a jump from | |
346 | */ | |
347 | extern struct symtab *lastnam; | |
348 | extern struct symtab *lastjxxx; | |
349 | ||
350 | #ifdef VMS | |
451260e7 RH |
351 | extern char *vms_obj_ptr; /* object buffer pointer */ |
352 | extern char sobuf[]; /* object buffer */ | |
8c1020c4 BJ |
353 | extern int objfil; /* VMS object file descriptor */ |
354 | #endif VMS | |
355 | ||
356 | /* | |
357 | * Lgensym is used to make up funny names for local labels. | |
358 | * lgensym[i] is the current funny number to put after | |
359 | * references to if, lgensym[i]-1 is for ib. | |
360 | * genref[i] is set when the label is referenced before | |
361 | * it is defined (i.e. 2f) so that we can be sure these | |
362 | * labels are always defined to avoid weird diagnostics | |
363 | * from the loader later. | |
364 | */ | |
365 | extern int lgensym[10]; | |
366 | extern char genref[10]; | |
367 | ||
368 | extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ | |
369 | extern struct exp *dotp; /* the current dot location */ | |
370 | extern int loctr; | |
371 | ||
372 | extern struct exec hdr; /* a.out header */ | |
373 | extern u_long tsize; /* total text size */ | |
374 | extern u_long dsize; /* total data size */ | |
375 | extern u_long trsize; /* total text relocation size */ | |
376 | extern u_long drsize; /* total data relocation size */ | |
377 | extern u_long datbase; /* base of the data segment */ | |
378 | /* | |
379 | * Bitoff and bitfield keep track of the packing into | |
380 | * bytes mandated by the expression syntax <expr> ':' <expr> | |
381 | */ | |
382 | extern int bitoff; | |
383 | extern long bitfield; | |
384 | ||
385 | /* | |
386 | * The lexical analyzer builds up symbols in yytext. Lookup | |
387 | * expects its argument in this buffer | |
388 | */ | |
389 | extern char yytext[NCPS+2]; /* text buffer for lexical */ | |
390 | /* | |
391 | * Variables to manage the input assembler source file | |
392 | */ | |
393 | extern int lineno; /*the line number*/ | |
394 | extern char *dotsname; /*the name of the as source*/ | |
395 | ||
396 | extern FILE *tmpfil; /* interpass communication*/ | |
397 | ||
398 | extern int passno; /* 1 or 2 */ | |
399 | ||
400 | extern int anyerrs; /*errors assembling arguments*/ | |
401 | extern int silent; /*don't mention the errors*/ | |
402 | extern int savelabels; /*save labels in a.out*/ | |
403 | extern int orgwarn; /* questionable origin ? */ | |
404 | extern int useVM; /*use virtual memory temp file*/ | |
e5b9ebfb | 405 | extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ |
030352e9 | 406 | extern int readonlydata; /*initialized data into text space*/ |
8c1020c4 BJ |
407 | #ifdef DEBUG |
408 | extern int debug; | |
409 | extern int toktrace; | |
410 | #endif | |
411 | /* | |
412 | * Information about the instructions | |
413 | */ | |
414 | extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ | |
451260e7 | 415 | extern readonly struct Instab instab[]; |
8c1020c4 BJ |
416 | |
417 | extern int curlen; /*current literal storage size*/ | |
418 | extern int d124; /*current pointer storage size*/ | |
419 | ||
420 | struct symtab **lookup(); /*argument in yytext*/ | |
421 | struct symtab *symalloc(); | |
422 | ||
451260e7 | 423 | #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} |
8c1020c4 | 424 | |
451260e7 | 425 | #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) |
8c1020c4 BJ |
426 | |
427 | /* | |
428 | * Most of the time, the argument to flushfield is a power of two constant, | |
429 | * the calculations involving it can be optimized to shifts. | |
430 | */ | |
431 | #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) | |
432 | ||
433 | /* | |
434 | * The biobuf structure and associated routines are used to write | |
435 | * into one file at several places concurrently. Calling bopen | |
436 | * with a biobuf structure sets it up to write ``biofd'' starting | |
437 | * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' | |
438 | * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. | |
439 | * Calling bflush drains all the buffers and MUST be done before exit. | |
440 | */ | |
441 | struct biobuf { | |
442 | short b_nleft; /* Number free spaces left in b_buf */ | |
443 | /* Initialize to be less than BUFSIZ initially, to boundary align in file */ | |
444 | char *b_ptr; /* Next place to stuff characters */ | |
445 | char b_buf[BUFSIZ]; /* The buffer itself */ | |
446 | off_t b_off; /* Current file offset */ | |
447 | struct biobuf *b_link; /* Link in chain for bflush() */ | |
448 | }; | |
449 | #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ | |
450 | : bflushc(b, c)) | |
451 | #define BFILE struct biobuf | |
452 | ||
453 | extern BFILE *biobufs; /* head of the block I/O buffer chain */ | |
454 | extern int biofd; /* file descriptor for block I/O file */ | |
455 | extern off_t boffset; /* physical position in logical file */ | |
456 | ||
457 | /* | |
458 | * For each of the named .text .data segments | |
459 | * (introduced by .text <expr>), we maintain | |
460 | * the current value of the dot, and the BFILE where | |
461 | * the information for each of the segments is placed | |
462 | * during the second pass. | |
463 | */ | |
464 | extern struct exp usedot[NLOC + NLOC]; | |
465 | extern BFILE *usefile[NLOC + NLOC]; | |
466 | extern BFILE *txtfil;/* file for text and data: into usefile */ | |
467 | /* | |
468 | * Relocation information for each segment is accumulated | |
469 | * seperately from the others. Writing the relocation | |
470 | * information is logically viewed as writing to one | |
471 | * relocation saving file for each segment; physically | |
472 | * we have a bunch of buffers allocated internally that | |
473 | * contain the relocation information. | |
474 | */ | |
475 | struct relbufdesc *rusefile[NLOC + NLOC]; | |
476 | struct relbufdesc *relfil; |