|
|
1.1 root 1: static char ID[] = "@(#) expr1.c: 1.3 3/13/83";
2: #include "system.h"
3:
4: #include <stdio.h>
5: #include "structs.h"
6: #include "extrns.h"
7: #include "sgsmacros.h"
8: #include "y.tab.h"
9: #include "ldmacros.h"
10:
11: static int expsect;
12: /*eject*/
13: long
14: eval(p)
15: ENODE *p;
16: {
17:
18: /*
19: * Evaluate an expression node, returning the (long) value of the
20: * expression.
21: *
22: * The extern variable "cur_dot" is used when processing exprs
23: * inside of an output section specification, and is set to
24: * -1L after allocation, when all sections have been relocated.
25: */
26:
27: long val1, val2;
28: SYMTAB *symp;
29: OUTSECT *s;
30:
31: switch (p->gnode.exop) {
32: case INT:
33: return( p->vnode.exvalue );
34: case DOT:
35: /*
36: * Assign to DOT, if not a misuse of the assignment
37: */
38: if( p->nnode.exsymptr == 0L ) {
39: if( cur_dot == -1L ) {
40: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
41: "misuse of DOT symbol in assignment instruction");
42: return (0L);
43: }
44: return(cur_dot);
45: }
46: else {
47: /*
48: * Use of dot in assign to symbol
49: */
50: symp = getsym(p->nnode.exsymptr);
51: s = (OUTSECT *) symp->smscnptr;
52: val1 = symp->sment.n_value + s->oshdr.s_paddr;
53: if ( expsect == 0 )
54: expsect = s->ossecnum;
55: PUTSYM(symp, 0);
56: return (val1);
57: }
58: case NAME:
59: symp = getsym(p->nnode.exsymptr);
60: val1 = symp->smnewval;
61: if (symp->sment.n_scnum > 0) {
62: if(expsect == 0)
63: expsect = symp->sment.n_scnum;
64: else
65: expsect = -1;
66: }
67: else if( symp->sment.n_scnum == 0 )
68: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
69: "undefined symbol in expression");
70: PUTSYM(symp, 0);
71: return (val1);
72: case ALIGN:
73: if( cur_dot == -1L ) {
74: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
75: "ALIGN illegal in this context");
76: return(0L);
77: }
78: val2 = eval(p->gnode.exleft);
79: val1 = (cur_dot + val2 - 1) & (~(val2-1));
80: return(val1);
81:
82: case PHY:
83: /*
84: * If (cur_dot != -1L) here, then eval() was
85: * called from pboslist(), which is processing
86: * the output section list. Moreover, we have
87: * an assignment to DOT, because eval() is not
88: * called otherwise. The statement is
89: * . = ... PHY(...) ...
90: * which is invalid.
91: */
92: if( cur_dot != -1L ) {
93: lderror(1, curexp->evexpr.aiinlnno,
94: curexp->evexpr.aiinflnm,
95: "illegal assignment of physical address to DOT");
96: return (0L);
97: }
98: expsect = -1;
99: switch( p->gnode.exleft->gnode.exop ) {
100: case NAME:
101: symp = getsym(p->gnode.exleft->nnode.exsymptr);
102: val1 = symp->smnewval;
103: if ( symp->smscnptr == NULL ) {
104: switch ( symp->sment.n_scnum ) {
105: case -1 : /* absolute */
106: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
107: "phy of absolute symbol %s is illegal",
108: SYMNAME(symp->sment));
109: break;
110: case 0 : /* undefined */
111: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
112: "symbol %s is undefined",
113: SYMNAME(symp->sment));
114: break;
115: }
116: }
117: PUTSYM(symp, 0);
118: return ( val1 );
119: case DOT:
120: if( p->gnode.exleft->nnode.exsymptr == 0L ) {
121: lderror(1,curexp->evexpr.aiinlnno,
122: curexp->evexpr.aiinflnm,
123: "internal error: no symtab entry for DOT");
124: return (0L);
125: }
126: symp = getsym(p->gnode.exleft->nnode.exsymptr);
127: val1 = symp->sment.n_value;
128: val1 += ((OUTSECT *) symp->smscnptr)->oshdr.s_paddr;
129:
130: PUTSYM(symp, 0);
131: return ( val1 );
132: default:
133: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
134: "operand of PHY must be a name");
135: return(0L);
136: }
137:
138:
139: case UMINUS: val1 = eval(p->gnode.exleft);
140: return(-val1);
141: case NOT: val1 = eval(p->gnode.exleft);
142: return(!val1);
143: case BNOT: val1 = eval(p->gnode.exleft);
144: return(~val1);
145: case AND: val1 = eval(p->gnode.exleft);
146: val2 = eval(p->gnode.exright);
147: return(val1 & val2);
148: case ANDAND: val1 = eval(p->gnode.exleft);
149: val2 = eval(p->gnode.exright);
150: return(val1 && val2);
151: case DIV: val1 = eval(p->gnode.exleft);
152: val2 = eval(p->gnode.exright);
153: return(val1 / val2);
154: case EQEQ: val1 = eval(p->gnode.exleft);
155: val2 = eval(p->gnode.exright);
156: return(val1 == val2);
157: case GE: val1 = eval(p->gnode.exleft);
158: val2 = eval(p->gnode.exright);
159: return(val1 >= val2);
160: case GT: val1 = eval(p->gnode.exleft);
161: val2 = eval(p->gnode.exright);
162: return(val1 > val2);
163: case LE: val1 = eval(p->gnode.exleft);
164: val2 = eval(p->gnode.exright);
165: return(val1 <= val2);
166: case LSHIFT: val1 = eval(p->gnode.exleft);
167: val2 = eval(p->gnode.exright);
168: return(val1 << val2);
169: case LT: val1 = eval(p->gnode.exleft);
170: val2 = eval(p->gnode.exright);
171: return(val1 < val2);
172: case MINUS: val1 = eval(p->gnode.exleft);
173: val2 = eval(p->gnode.exright);
174: return(val1 - val2);
175: case MULT: val1 = eval(p->gnode.exleft);
176: val2 = eval(p->gnode.exright);
177: return(val1 * val2);
178: case NE: val1 = eval(p->gnode.exleft);
179: val2 = eval(p->gnode.exright);
180: return(val1 != val2);
181: case OR: val1 = eval(p->gnode.exleft);
182: val2 = eval(p->gnode.exright);
183: return(val1 | val2);
184: case OROR: val1 = eval(p->gnode.exleft);
185: val2 = eval(p->gnode.exright);
186: return(val1 || val2);
187: case PC: val1 = eval(p->gnode.exleft);
188: val2 = eval(p->gnode.exright);
189: return(val1 % val2);
190: case PLUS: val1 = eval(p->gnode.exleft);
191: val2 = eval(p->gnode.exright);
192: return(val1 + val2);
193: case RSHIFT: val1 = eval(p->gnode.exleft);
194: val2 = eval(p->gnode.exright);
195: return(val1 >> val2);
196:
197: default:
198: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
199: "illegal operator in expression");
200: return(0L);
201: }
202: }
203: /*eject*/
204: pexlist()
205: {
206:
207: /*
208: * After allocation, process the "expression list"
209: * to define any user-specified symbols.
210: */
211:
212: #if !ONEPROC
213: ACTITEM a;
214: #endif
215:
216: cur_dot = -1L;
217: curexp = (ACTITEM *) explist.head;
218:
219: while( curexp ) {
220:
221: pexitem();
222:
223: clrexp( curexp );
224:
225: curexp = curexp->evexpr.ainext;
226:
227: }
228:
229: #if DEBUG
230: if( dflag > 2 )
231: fprintf( stderr, "\nEXPLIST data structures:" );
232: #endif
233: #if !ONEPROC
234: while( expcnt-- ) {
235:
236: fread( &a, 1, sizeof(ACTITEM), trnfdes );
237: a.evexpr.aiinflnm = (char *) ((int) a.evexpr.aiinflnm + (int) strbase);
238:
239: #if DEBUG
240: if( dflag > 2 )
241: fprintf( stderr, "\n\t%04x AIEVEXPR (%s) %d %04x\n\t\tROOT:",
242: a.evexpr.ainext, a.evexpr.aiinflnm,
243: a.evexpr.aiinlnno, a.evexpr.aiexptr );
244: #endif
245:
246: curexp = ldexp( &a );
247:
248: pexitem();
249:
250: clrexp( curexp );
251:
252: }
253: #endif
254: }
255: /*eject*/
256: pexitem()
257: {
258:
259: /*
260: * Process one assignment instruction
261: */
262:
263: long val;
264: register SYMTAB *sp;
265: register OUTSECT *oscn;
266:
267: expsect = 0;
268: val = eval(curexp->evexpr.aiexptr->gnode.exright);
269: sp = getsym(curexp->evexpr.aiexptr->gnode.exleft->nnode.exsymptr);
270:
271: /*
272: * If the section number of the symbol we
273: * are assigning a value is not zero ( = undefined),
274: * the user is redefining the value of the symbol.
275: */
276:
277: if( sp->sment.n_scnum )
278: if( sp->smscnptr )
279: lderror(0, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
280: "symbol %s from file %s being redefined",
281: SYMNAME(sp->sment), sp->smscnptr->isfilptr->flname);
282: else
283: lderror(0, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm,
284: "absolute symbol %s being redefined",
285: SYMNAME(sp->sment));
286:
287: if( expsect == 0 )
288: sp->sment.n_scnum = -1; /* absolute symbol */
289: else
290: sp->sment.n_scnum = expsect;
291:
292: if( (oscn = findoscn(sp->sment.n_scnum)) != NULL )
293: sp->smnewvirt = val - oscn->oshdr.s_paddr + oscn->oshdr.s_vaddr;
294: else
295: sp->smnewvirt = val;
296: sp->smnewval = val;
297: sp->sment.n_sclass = C_EXT;
298: PUTSYM(sp, 1);
299:
300: }
301: /*eject*/
302: #if !ONEPROC
303: ACTITEM *
304: ldexp(a)
305: ACTITEM *a;
306: {
307:
308: /*
309: * Load an assignment instruction from the "transfer file" generated
310: * by PASS 1, into memory
311: *
312: * "a" is the action item which heads the expression tree
313: *
314: * Return a pointer to a separate copy of this action item
315: */
316:
317: register ACTITEM *aptr;
318: register ENODE *eptr;
319: ENODE *ldlimb();
320:
321: aptr = (ACTITEM *) myalloc(sizeof(ACTITEM));
322: *aptr = *a;
323:
324: eptr = (ENODE *) myalloc(sizeof(ENODE));
325: fread( eptr, 1, sizeof(ENODE), trnfdes );
326:
327: #if DEBUG
328: if( dflag > 2 )
329: fprintf( stderr, "\t%d %04x %04x", (unsigned) eptr->gnode.exop,
330: eptr->gnode.exleft, eptr->gnode.exright );
331: #endif
332:
333: if( eptr->gnode.exleft )
334: eptr->gnode.exleft = ldlimb();
335: if( eptr->gnode.exright )
336: eptr->gnode.exright = ldlimb();
337:
338: aptr->evexpr.ainext = NULL;
339: aptr->evexpr.aiexptr = eptr;
340:
341: return( aptr );
342: }
343: /*eject*/
344: ENODE *
345: ldlimb()
346: {
347:
348: /*
349: * Load a non-root node of an expression tree into memory
350: */
351:
352: register ENODE *eptr;
353: SYMENT sym;
354:
355: eptr = (ENODE *) myalloc(sizeof(ENODE));
356: fread( eptr, 1, sizeof(ENODE), trnfdes );
357:
358: switch( (unsigned) eptr->gnode.exop ) {
359: case INT:
360: #if DEBUG
361: if( dflag > 2 )
362: fprintf( stderr, "\n\t\t\tINT %08lx", eptr->vnode.exvalue );
363: #endif
364: break;
365: case DOT:
366: #if DEBUG
367: if( dflag > 2 )
368: fprintf( stderr, "\n\t\t\tDOT ()" );
369: #endif
370: break;
371: case NAME:
372: #if DEBUG
373: if( dflag > 2 )
374: fprintf( stderr, "\n\t\t\tNAME (%s)",
375: eptr->pnnode.symbol );
376: #endif
377: zero( (char *) &sym, SYMESZ );
378: #if FLEXNAMES
379: if (strlen(eptr->pnnode.symbol) > 8) {
380: sym.n_zeroes = 0L;
381: sym.n_nptr = eptr->pnnode.symbol;
382: }
383: else
384: #endif
385: copy( sym.n_name, eptr->pnnode.symbol, 8);
386: sym.n_type = T_INT;
387: sym.n_sclass = C_EXT;
388: eptr->nnode.exsymptr = putsym( makesym(&sym), 1 );
389: break;
390: default:
391: #if DEBUG
392: if( dflag > 2 )
393: fprintf( stderr, "\n\t\t\t%d %04x %04x", (unsigned) eptr->gnode.exop,
394: eptr->gnode.exleft, eptr->gnode.exright );
395: #endif
396: if( eptr->gnode.exleft )
397: eptr->gnode.exleft = ldlimb();
398: if( eptr->gnode.exright )
399: eptr->gnode.exright = ldlimb();
400: break;
401: }
402:
403: return( eptr );
404: }
405: /*eject*/
406: #endif
407: clrexp(a)
408: ACTITEM *a;
409: {
410:
411: /*
412: * Free up all memory assigned to the assignment instruction pointed
413: * to by "a"
414: */
415: ENODE *eptr;
416:
417: eptr = a->evexpr.aiexptr;
418:
419: switch( (unsigned) eptr->gnode.exop ) {
420: case INT:
421: case DOT:
422: case NAME:
423: break;
424: default:
425: if( eptr->gnode.exleft )
426: clrlimb(eptr->gnode.exleft);
427: if( eptr->gnode.exright )
428: clrlimb(eptr->gnode.exright);
429: break;
430: }
431:
432: free( eptr );
433: free( a );
434: }
435:
436:
437:
438:
439: clrlimb(eptr)
440: ENODE *eptr;
441: {
442:
443: /*
444: * Free up a non-root node of an expression tree
445: */
446:
447: switch( (unsigned) eptr->gnode.exop ) {
448: case INT:
449: case DOT:
450: case NAME:
451: break;
452: default:
453: if( eptr->gnode.exleft )
454: clrlimb(eptr->gnode.exleft);
455: if( eptr->gnode.exright )
456: clrlimb(eptr->gnode.exright);
457: break;
458: }
459:
460: free( eptr );
461: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.