|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #include <stdio.h>
3: #include "as.h"
4: #include "assyms.h"
5:
6: insout(op, ap, nact)
7: struct arg *ap;
8: {
9: int jxxflg;
10:
11: op &= 0xFF;
12: jxxflg = nact;
13: if (nact < 0)
14: nact = -nact;
15: if (passno!=2) {
16: register struct arg *ap2;
17: register struct instab *ip;
18: int i,nexp;
19: ip = itab[op];
20: nexp = ip->nargs;
21: if (nact < nexp)
22: yyerror("Too few arguments");
23: if (nact > nexp) {
24: yyerror("Too many arguments");
25: nact = nexp;
26: }
27: /*
28: * Check argument compatability with instruction template
29: */
30: for (ap2 = ap+nact, i = nact; --i >= 0;)
31: argcompat(--ap2, ip->argtype[i], i);
32: }
33: if (jxxflg < 0)
34: ijxout(op, ap, nact);
35: else putins(op, ap, nact);
36: }
37:
38: argcompat(act, exp, i)
39: struct arg *act;
40: int exp,i;
41: {
42: register at,atm;
43:
44: at = act->atype;
45: atm = at & AMASK;
46:
47: if ((exp & ACCA) && (atm == AREG)) {
48: yyerror("arg %d, addressing a register",i);
49: return;
50: }
51: if ((exp&ACCW) && (atm==AIMM) && !(at&ASTAR)) {
52: yyerror("arg %d, modifying a constant",i);
53: return;
54: }
55: if (at & AINDX) {
56: if (act->areg2==017) {
57: yyerror("arg %d, PC used as index",i);
58: return;
59: }
60: if (atm==AREG) {
61: yyerror("arg %d, indexing the register file",i);
62: return;
63: }
64: if (atm==AIMM) {
65: yyerror("arg %d, indexing a constant",i);
66: return;
67: }
68: if (((atm==ADECR) || (atm==AINCR)) && (act->areg1==act->areg2)) {
69: yyerror("arg %d, indexing with modified register",i);
70: return;
71: }
72: }
73: }
74:
75: int d124 = {4};
76: int len124[] = {0,LEN1,LEN2,0,LEN4};
77: char mod124[] = {0,0x00,0x20,0,0x40};
78:
79: putins(op, ap, n)
80: /*
81: * n had better be positive
82: */
83: register struct arg *ap;
84: {
85: register struct exp *xp;
86: register int a;
87: int i,xtrab;
88:
89: if (passno!=2) {
90: dotp->xvalue += n+1; /* 1 for the opcode, at least 1 per arg */
91: for (i=0; i<n; i++,ap++) {/* some args take more than 1 byte */
92: a=ap->atype;
93: if (a & AINDX)
94: dotp->xvalue++;
95: switch (a&~(AINDX|ASTAR)) {
96: case AEXP: {
97: a = itab[op]->argtype[i];
98: if (a == ACCB+TYPB)
99: break;
100: if (a==ACCB+TYPW){
101: dotp->xvalue++;
102: break;
103: }
104: dotp->xvalue += ap->dispsize;
105: break;
106: }
107: case ADISP: {
108: xp=ap->xp;
109: if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW){
110: dotp->xvalue += ap->dispsize;
111: break;
112: }
113: if (xp->xvalue==0 && !(a&ASTAR))
114: break;
115: dotp->xvalue++;
116: if ((xp->xvalue<MINBYTE) || (xp->xvalue>MAXBYTE))
117: dotp->xvalue++;
118: if ((xp->xvalue<MINWORD) || (xp->xvalue>MAXWORD))
119: dotp->xvalue += 2;
120: break;
121: }
122: case AIMM: {
123: if (ap->atype&ASTAR) a=TYPL;
124: else {
125: xp = ap->xp;
126: if ((xp->xtype&XTYPE)==XABS && !(xp->xtype&XFORW)
127: && xp->xvalue>=0 && xp->xvalue<=63)
128: break;
129: a = itab[op]->argtype[i];
130: if (a&ACCA)
131: a = TYPL;
132: else
133: a &= TYPMASK;
134: }
135: switch (a) {
136: case TYPD:
137: case TYPF:
138: if (slitflt(xp))
139: break;
140: if (a==TYPF)
141: dotp->xvalue -= 4;
142: case TYPQ:
143: dotp->xvalue += 4;
144: case TYPL:
145: dotp->xvalue += 2;
146: case TYPW:
147: dotp->xvalue++;
148: case TYPB:
149: dotp->xvalue++;
150: } /*end of the switch on a*/
151: } /*end of case AIMM*/
152: } /*end of the switch on the type*/
153: } /*end of looping for all arguments*/
154: return;
155: } /*end of it being time for pass 1*/
156: /*
157: * PASS2 HERE
158: */
159:
160: outb(op); /* the opcode */
161: for (i=0; i<n; i++,ap++) {/* now for the arguments */
162: a=ap->atype;
163: xp=ap->xp;
164: xtrab=0;
165: if (a&AINDX) {
166: { outb(0x40 | ap->areg2); }
167: a &= ~AINDX;
168: }
169: if (a&ASTAR) {
170: ap->areg1 |= 0x10;
171: a &= ~ASTAR;
172: }
173: switch (a) {
174: case AREG: /* %r */
175: ap->areg1 |= 0x50;
176: break;
177: case ABASE: /* (%r) */
178: ap->areg1 |= 0x60;
179: break;
180: case ADECR: /* -(%r) */
181: ap->areg1 |= 0x70;
182: break;
183: case AINCR: /* (%r) */
184: ap->areg1 |= 0x80;
185: break;
186: case AEXP: {/* expr */
187: a = itab[op]->argtype[i];
188: if (a == ACCB+TYPB) {
189: ap->areg1 = a =
190: xp->xvalue - (dotp->xvalue + 1);
191: if (a<MINBYTE || a>MAXBYTE)
192: yyerror("Branch too far"); break;
193: }
194: if (a == ACCB+TYPW) {
195: ap->areg1 = a = xp->xvalue
196: -= dotp->xvalue + 2;
197: xp->xtype = XABS;
198: if (a<MINWORD || a>MAXWORD)
199: yyerror("Branch too far");
200: xp->xvalue = a>>8;
201: xtrab = LEN1;
202: break;
203: }
204: /* reduces to expr(pc) mode */
205: ap->areg1 |= (0xAF + mod124[ap->dispsize]);
206: xtrab = len124[ap->dispsize]+PCREL;
207: break;
208: }
209: case ADISP: {/* expr(%r) */
210: ap->areg1 |= 0xA0;
211: if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW){
212: ap->areg1 += mod124[ap->dispsize];
213: xtrab=len124[ap->dispsize];
214: break;
215: }
216: if (xp->xvalue==0 && !(ap->areg1&0x10)) {
217: ap->areg1 ^= 0xC0;
218: break;
219: }
220: xtrab=LEN1;
221: if ((xp->xvalue<MINBYTE) || (xp->xvalue>MAXBYTE)){
222: ap->areg1 += 0x20;
223: xtrab=LEN2;
224: }
225: if ((xp->xvalue<MINWORD) || (xp->xvalue>MAXWORD)){
226: ap->areg1 += 0x20;
227: xtrab=LEN4;
228: }
229: break;
230: }
231: case AIMM: { /* $expr */
232: if (ap->atype&ASTAR)
233: a=TYPL;
234: else {
235: if ( ( (xp->xtype&XTYPE) == XABS)
236: && !(xp->xtype&XFORW)
237: && (xp->xvalue >= 0)
238: && (xp->xvalue <= 63) ) {
239: ap->areg1 = xp->xvalue;
240: break;
241: }
242: a = itab[op]->argtype[i];
243: if (a&ACCA)
244: a=TYPL;
245: else
246: a &= TYPMASK;
247: }
248: ap->areg1 |= 0x8F;
249: switch (a) {
250: case TYPD:
251: case TYPF:
252: if (slitflt(xp)){
253: ap->areg1=extlitflt(xp);
254: break;
255: }
256: if (a==TYPF) {
257: xtrab = LEN4;
258: break;
259: }
260: case TYPQ: xtrab = LEN8; break;
261: case TYPL: xtrab = LEN4; break;
262: case TYPW: xtrab = LEN2; break;
263: case TYPB: xtrab = LEN1; break;
264: }
265: } /*end of the switch on AIMM*/
266: } /*end of the switch on a*/
267: /*
268: * use the first byte to describe the argument
269: */
270: outb(ap->areg1);
271: if (xtrab)
272: outrel(&xp->xvalue, xtrab, xp->xtype, xp->xname);
273: } /*end of the for to pick up all arguments*/
274: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.