|
|
1.1 root 1: /*
2: * Copyright (c) 1982 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)ascode.c 5.1 (Berkeley) 4/24/85";
9: #endif not lint
10:
11: #include <stdio.h>
12: #include "as.h"
13: #include "assyms.h"
14:
15: insout(opcode, ap, nact)
16: struct Opcode opcode;
17: struct arg *ap;
18: int nact;
19: {
20: int jxxflg;
21: reg struct instab *ip; /* the instruction */
22: reg struct arg *ap_walk; /* actual param walk */
23: reg int i;
24: reg int ap_type; /* actual param type */
25: reg int ap_type_mask; /* masked actual param */
26:
27: jxxflg = nact;
28: if (nact < 0)
29: nact = -nact;
30: if (passno == 1) {
31: if (!(ITABCHECK(opcode)))
32: panic("Botched reference into itab");
33: ip = ITABFETCH(opcode);
34: if (nact < ip->i_nargs)
35: yyerror("Too few arguments");
36: if (nact > ip->i_nargs) {
37: yyerror("Too many arguments");
38: nact = ip->i_nargs;
39: }
40: /*
41: * Check argument compatability with instruction template
42: */
43: for (ap_walk = ap, i = 1; i <= nact; ap_walk++, i++){
44: ap_type = ap_walk->a_atype;
45: ap_type_mask = ap_type & AMASK;
46: /*
47: * The switch value is >> by TYPLG so that the switch
48: * code is dense, not implemented as a sequence
49: * of branches but implemented as a casel.
50: * In addition, cases ACCI and ACCR are added to force
51: * dense switch code.
52: * switch on the type of fp
53: */
54: switch( ((fetcharg(ip, i-1)) & ACCESSMASK) >> TYPLG){
55: case ACCI >> TYPLG:
56: case ACCR >> TYPLG:
57: break;
58: case ACCB >> TYPLG:
59: if ( !((ap_type_mask == AEXP) || (ap_type_mask == AIMM)) ){
60: yyerror("arg %d, branch displacement must be an expression",i);
61: return;
62: }
63: break;
64: case ACCA >> TYPLG:
65: switch(ap_type_mask){
66: case AREG: yyerror("arg %d, addressing a register",i);
67: return;
68: case AIMM: if ( !(ap_type & ASTAR) ){
69: yyerror("arg %d, addressing an immediate operand",i);
70: return;
71: }
72: }
73: break;
74: case ACCM >> TYPLG:
75: case ACCW >> TYPLG:
76: switch(ap_type_mask){
77: case AIMM: if (!(ap_type&ASTAR)) {
78: yyerror("arg %d, modifying a constant",i);
79: return;
80: }
81: }
82: break;
83: } /* end of the switch on fp_type */
84: if (ap_type & AINDX) {
85: if (ap_walk->a_areg2==0xF) {
86: yyerror("arg %d, PC used as index",i);
87: return;
88: }
89: switch(ap_type_mask){
90: case AREG: yyerror("arg %d, indexing the register file",i);
91: return;
92: case AIMM: yyerror("arg %d, indexing a constant",i);
93: return;
94: case ADECR:
95: case AINCR: if (ap_walk->a_areg1==ap_walk->a_areg2) {
96: yyerror("arg %d, indexing with modified register",i);
97: return;
98: }
99: break;
100: } /* end of switch on ap_type_mask */
101: } /* end of AINDX */
102: }
103: } /* both passes here */
104: if (jxxflg < 0)
105: ijxout(opcode, ap, nact);
106: else
107: putins(opcode, ap, nact);
108: }
109:
110: extern int d124;
111:
112: putins(opcode, ap, n)
113: struct Opcode opcode;
114: register struct arg *ap;
115: int n; /* Must be positive */
116: {
117: reg struct exp *xp;
118: reg int argtype;
119: int i;
120: int reloc_how;
121: int value;
122:
123: #ifdef DEBUG
124: fflush(stdout);
125: #endif
126: if (passno == 2)
127: goto PASS2;
128:
129: dotp->e_xvalue += n; /* at least one byte per arg */
130: switch(opcode.Op_eopcode){
131: case NEW:
132: case CORE:
133: dotp->e_xvalue += 1; /* 1 byte opcode */
134: break;
135: case ESCD:
136: case ESCF:
137: dotp->e_xvalue += 2; /* 2 byte opcode */
138: break;
139: default:
140: panic("Bad escape opcode");
141: }
142:
143: for (i=0; i<n; i++,ap++) { /* some args take more than 1 byte */
144: argtype = ap->a_atype;
145: if (argtype & AINDX)
146: dotp->e_xvalue++;
147: /*
148: * This switch has been fixed by enumerating the no action
149: * alternatives (those that have 1 one byte of code)
150: * so that a casel instruction is emitted.
151: */
152: switch (argtype&~(AINDX|ASTAR)) {
153: case AREG:
154: case ABASE:
155: case ADECR:
156: case AINCR:
157: break;
158: case AEXP:
159: argtype = fetcharg(ITABFETCH(opcode), i);
160: if (argtype == A_BB)
161: break;
162: if (argtype == A_BW){
163: dotp->e_xvalue++;
164: break;
165: }
166: /*
167: * Reduces to PC relative
168: */
169: dotp->e_xvalue += ap->a_dispsize;
170: break;
171:
172: case ADISP:
173: xp=ap->a_xp;
174: if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){
175: dotp->e_xvalue += ap->a_dispsize;
176: break;
177: }
178: if (xp->e_xvalue==0 && !(argtype&ASTAR))
179: break;
180: dotp->e_xvalue += 1;
181: if (ISBYTE(xp->e_xvalue))
182: break;
183: dotp->e_xvalue += 1;
184: if (ISWORD(xp->e_xvalue))
185: break;
186: dotp->e_xvalue += 2;
187: break;
188:
189: case AIMM:
190: if (ap->a_atype&ASTAR) {
191: argtype=TYPL;
192: } else {
193: argtype = fetcharg(ITABFETCH(opcode), i);
194: if (argtype&ACCA)
195: argtype = TYPL;
196: else
197: argtype &= TYPMASK;
198: xp = ap->a_xp;
199: if (immconstant(ap->a_xp, argtype, &value))
200: break;
201: }
202: dotp->e_xvalue += ty_nbyte[argtype];
203: } /*end of the switch on the type*/
204: } /*end of looping for all arguments*/
205: return;
206:
207: PASS2:
208: /*
209: * Output the opcode
210: */
211: switch(opcode.Op_eopcode){
212: case NEW:
213: nnewopcodes++;
214: break;
215: case ESCD:
216: case ESCF:
217: nGHopcodes++;
218: Outb(opcode.Op_eopcode);
219: break;
220: case CORE:
221: break;
222: default:
223: panic("Bad escape opcode");
224: }
225: Outb(opcode.Op_popcode);
226:
227: for (i=0; i<n; i++,ap++) {/* now for the arguments */
228: argtype=ap->a_atype;
229: xp=ap->a_xp;
230: reloc_how = TYPNONE;
231: if (argtype&AINDX) {
232: { Outb(0x40 | ap->a_areg2); }
233: argtype &= ~AINDX;
234: }
235: if (argtype&ASTAR) {
236: ap->a_areg1 |= 0x10;
237: argtype &= ~ASTAR;
238: }
239: switch (argtype) {
240: case AREG: /* %r */
241: ap->a_areg1 |= 0x50;
242: break;
243: case ABASE: /* (%r) */
244: ap->a_areg1 |= 0x60;
245: break;
246: case ADECR: /* -(%r) */
247: ap->a_areg1 |= 0x70;
248: break;
249: case AINCR: /* (%r)+ */
250: ap->a_areg1 |= 0x80;
251: break;
252: case AEXP: /* expr */
253: argtype = fetcharg(ITABFETCH(opcode), i);
254: if (argtype == A_BB) {
255: ap->a_areg1 = argtype =
256: xp->e_xvalue - (dotp->e_xvalue + 1);
257: if ((xp->e_xtype & XTYPE) == XUNDEF)
258: yywarning("%s: destination label is external",
259: FETCHNAME(ITABFETCH(opcode)));
260: if (!ISBYTE(argtype))
261: yyerror("%s: Branch too far(%db): try -J flag",
262: FETCHNAME(ITABFETCH(opcode)),
263: argtype);
264: break;
265: }
266: if (argtype == A_BW) {
267: ap->a_areg1 = argtype = xp->e_xvalue
268: -= dotp->e_xvalue + 2;
269: if ((xp->e_xtype & XTYPE) == XUNDEF)
270: yywarning("%s: destination label is external",
271: FETCHNAME(ITABFETCH(opcode)));
272: xp->e_xtype = XABS;
273: if (!ISWORD(argtype))
274: yyerror("%s: Branch too far(%db): try -J flag",
275: FETCHNAME(ITABFETCH(opcode)),
276: argtype);
277: xp->e_xvalue = argtype>>8;
278: reloc_how = TYPB;
279: break;
280: }
281: /* reduces to expr(pc) mode */
282: ap->a_areg1 |= (0xAF + mod124[ap->a_dispsize]);
283: reloc_how = type_124[ap->a_dispsize] + RELOC_PCREL;
284: break;
285:
286: case ADISP: /* expr(%r) */
287: ap->a_areg1 |= 0xA0;
288: if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){
289: ap->a_areg1 += mod124[ap->a_dispsize];
290: reloc_how = type_124[ap->a_dispsize];
291: break;
292: }
293: if (xp->e_xvalue==0 && !(ap->a_areg1&0x10)) {
294: ap->a_areg1 ^= 0xC0;
295: break;
296: }
297: reloc_how = TYPB;
298: if (ISBYTE(xp->e_xvalue))
299: break;
300: ap->a_areg1 += 0x20;
301: reloc_how = TYPW;
302: if (ISWORD(xp->e_xvalue))
303: break;
304: ap->a_areg1 += 0x20;
305: reloc_how = TYPL;
306: break;
307:
308: case AIMM: /* $expr */
309: if (ap->a_atype&ASTAR) {
310: argtype=TYPL;
311: } else {
312: argtype = fetcharg(ITABFETCH(opcode), i);
313: if (argtype&ACCA)
314: argtype = TYPL;
315: else
316: argtype &= TYPMASK;
317: if (immconstant(xp, argtype, &value)){
318: reloc_how = TYPNONE;
319: ap->a_areg1 = value;
320: break;
321: }
322: }
323: ap->a_areg1 |= 0x8F;
324: reloc_how = argtype;
325: break;
326:
327: } /*end of the switch on argtype*/
328: /*
329: * use the first byte to describe the argument
330: */
331: Outb(ap->a_areg1);
332: if (reloc_how != TYPNONE)
333: outrel(xp, reloc_how);
334: } /*end of the for to pick up all arguments*/
335: }
336: /*
337: * Is xp an immediate constant?
338: * argtype: how the instruction will interpret the bytes
339: * xp->e_number.num_tag ("numtype"): the kind of number given
340: *
341: * Use the following table:
342: * float: TYPF, TYPD, TYPG, TYPH
343: * quad: TYPQ, TYPO
344: * int: TYPG, TYPW, TYPL
345: *
346: * numtype
347: * argtype float quad int
348: *
349: * float slitflt slitflt slitflt
350: * quad 0 0 0
351: * int 0..63 0 0..63
352: *
353: * Where the table entry implies the predicate to return.
354: */
355: #define IMMFLT 1 /* these flags are not used by anybody (yet) */
356: #define IMMINT 2
357:
358: int immconstant(xp, argtype, valuep)
359: reg struct exp *xp;
360: int argtype;
361: int *valuep;
362: {
363: reg int back = 0;
364: int numtype;
365: reg int fits;
366:
367: if ((xp->e_xtype & XTYPE) != XABS)
368: return(0);
369: if ((xp->e_xtype & XFORW) != 0)
370: return(0);
371: numtype = xp->e_number.num_tag;
372:
373: fits = 1;
374: if (passno == 2) switch(argtype){
375: case TYPB:
376: switch(numtype){
377: default: fits = 0; break;
378: case TYPB: fits = 1; break;
379: case TYPW:
380: case TYPL:
381: fits = ISBYTE(xp->e_xvalue) || ISUBYTE(xp->e_xvalue);
382: break;
383: }
384: break;
385: case TYPW:
386: switch(numtype){
387: default: fits = 0; break;
388: case TYPB:
389: case TYPW: fits = 1; break;
390: case TYPL:
391: fits = ISWORD(xp->e_xvalue) || ISUWORD(xp->e_xvalue);
392: break;
393: }
394: break;
395: case TYPF:
396: if (numtype == TYPD){ /* same format for first 32 bits */
397: fits = 1;
398: break;
399: }
400: /*FALLTHROUGH*/
401: default:
402: fits = ty_nbyte[argtype] >= ty_nbyte[numtype];
403: }
404: if (!fits){
405: yywarning("Immediate constant type %s mismatches instruction type %s",
406: ty_string[numtype],
407: ty_string[argtype]);
408: }
409:
410: switch(argtype){
411: case TYPF:
412: case TYPG:
413: case TYPD:
414: case TYPH:
415: back = slitflt(xp->e_number, argtype, valuep);
416: break;
417: case TYPO:
418: case TYPQ:
419: back = 0;
420: break;
421: case TYPB:
422: case TYPW:
423: case TYPL:
424: switch(numtype){
425: case TYPO:
426: case TYPQ:
427: back = 0;
428: break;
429: default:
430: *valuep = xp->e_xvalue;
431: back = ISLIT(xp->e_xvalue);
432: break;
433: }
434: break;
435: }
436: return(back);
437: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.