Fixing vgrind formatting glitches
[unix-history] / usr / src / old / as.vax / ascode.c
CommitLineData
cb3898cb
BJ
1/* Copyright (c) 1980 Regents of the University of California */
2static char sccsid[] = "@(#)ascode.c 4.1 %G%";
3#include <stdio.h>
4#include <sys/types.h>
5#include <a.out.h>
6#include "as.h"
7#include "assyms.h"
8
9insout(op, ap, nact)
10 struct arg *ap;
11{
12 int jxxflg;
13
14 op &= 0xFF;
15 jxxflg = nact;
16 if (nact < 0)
17 nact = -nact;
18 if (passno == 1) {
19 register struct arg *ap2;
20 register struct instab *ip;
21 int i,nexp;
22 ip = itab[op];
23 nexp = ip->nargs;
24 if (nact < nexp)
25 yyerror("Too few arguments");
26 if (nact > nexp) {
27 yyerror("Too many arguments");
28 nact = nexp;
29 }
30 /*
31 * Check argument compatability with instruction template
32 */
33 for (ap2 = ap+nact, i = nact; --i >= 0;)
34 argcompat(--ap2, ip->argtype[i], i+1);
35 }
36 if (jxxflg < 0)
37 ijxout(op, ap, nact);
38 else putins(op, ap, nact);
39}
40
41argcompat(act, exp, i)
42 struct arg *act;
43 int exp,i;
44{
45 register at,atm;
46
47 at = act->atype;
48 atm = at & AMASK;
49
50 if ( (exp & ACCB) && (!((atm == AEXP) || (atm == AIMM))) ){
51 yyerror("arg %d, branch displacement must be an expression",i);
52 return;
53 }
54 if ((exp & ACCA) && (atm == AREG)) {
55 yyerror("arg %d, addressing a register",i);
56 return;
57 }
58 if ((exp&ACCW) && (atm==AIMM) && !(at&ASTAR)) {
59 yyerror("arg %d, modifying a constant",i);
60 return;
61 }
62 if (at & AINDX) {
63 if (act->areg2==017) {
64 yyerror("arg %d, PC used as index",i);
65 return;
66 }
67 if (atm==AREG) {
68 yyerror("arg %d, indexing the register file",i);
69 return;
70 }
71 if (atm==AIMM) {
72 yyerror("arg %d, indexing a constant",i);
73 return;
74 }
75 if (((atm==ADECR) || (atm==AINCR)) && (act->areg1==act->areg2)) {
76 yyerror("arg %d, indexing with modified register",i);
77 return;
78 }
79 }
80}
81
82extern int d124;
83 int len124[] = {0,LEN1,LEN2,0,LEN4};
84 char mod124[] = {0,0x00,0x20,0,0x40};
85
86putins(op, ap, n)
87 /*
88 * n had better be positive
89 */
90 register struct arg *ap;
91{
92 register struct exp *xp;
93 register int a;
94 int i,xtrab;
95
96#ifdef DEBUG
97 fflush(stdout);
98#endif
99 if (passno == 2)
100 goto PASS2;
101
102 dotp->xvalue += n+1; /* 1 for the opcode, at least 1 per arg */
103 for (i=0; i<n; i++,ap++) {/* some args take more than 1 byte */
104 xtrab = 0;
105 a=ap->atype;
106 if (a & AINDX)
107 dotp->xvalue++;
108 switch (a&~(AINDX|ASTAR)) {
109 case AEXP:
110 a = itab[op]->argtype[i];
111 if (a == ACCB+TYPB)
112 break;
113 if (a==ACCB+TYPW){
114 dotp->xvalue++;
115 break;
116 }
117 /*
118 * Reduces to PC relative
119 */
120 xtrab++;
121 dotp->xvalue += ap->dispsize;
122 break;
123
124 case ADISP:
125 xp=ap->xp;
126 if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW){
127 dotp->xvalue += ap->dispsize;
128 break;
129 }
130 if (xp->xvalue==0 && !(a&ASTAR))
131 break;
132 dotp->xvalue++;
133 if ((xp->xvalue<MINBYTE) || (xp->xvalue>MAXBYTE))
134 dotp->xvalue++;
135 if ((xp->xvalue<MINWORD) || (xp->xvalue>MAXWORD))
136 dotp->xvalue += 2;
137 break;
138
139 case AIMM:
140 if (ap->atype&ASTAR) a=TYPL;
141 else {
142 a = itab[op]->argtype[i];
143 if (a&ACCA)
144 a = TYPL;
145 else
146 a &= TYPMASK;
147 xp = ap->xp;
148 if ( ((xp->xtype&XTYPE)==XABS)
149 && (!(xp->xtype&XFORW))
150 && (xp->xvalue>=0)
151 && (xp->xvalue<=63)
152 && (xp->yvalue == 0)
153 && (a != TYPD)
154 && (a != TYPF)
155 )
156 break;
157 }
158 switch (a) {
159 case TYPD:
160 case TYPF:
161 if ( !(((xp->xtype&XTYPE)==XABS)
162 && (!(xp->xtype&XFORW))
163 && (slitflt(xp)))
164 ){
165 /* it is NOT short */
166 dotp->xvalue += ((a==TYPF)?
167 4 : 8);
168 }
169 break;
170 case TYPQ:
171 dotp->xvalue += 8;break;
172 case TYPL:
173 dotp->xvalue += 4;break;
174 case TYPW:
175 dotp->xvalue += 2;break;
176 case TYPB:
177 dotp->xvalue += 1;break;
178 } /*end of the switch on a*/
179 } /*end of the switch on the type*/
180 } /*end of looping for all arguments*/
181 return;
182
183PASS2:
184
185#ifdef UNIX
186 outb(op); /* the opcode */
187#endif UNIX
188#ifdef VMS
189 *vms_obj_ptr++ = -1; *vms_obj_ptr++ = (char)op;
190 dotp->xvalue += 1;
191#endif VMS
192
193 for (i=0; i<n; i++,ap++) {/* now for the arguments */
194 a=ap->atype;
195 xp=ap->xp;
196 xtrab=0;
197 if (a&AINDX) {
198#ifdef UNIX
199 { outb(0x40 | ap->areg2); }
200#endif UNIX
201#ifdef VMS
202 { *vms_obj_ptr++ = -1;
203 *vms_obj_ptr++ = (0x40 | ap->areg2);
204 dotp->xvalue += 1; }
205#endif VMS
206 a &= ~AINDX;
207 }
208 if (a&ASTAR) {
209 ap->areg1 |= 0x10;
210 a &= ~ASTAR;
211 }
212 switch (a) {
213 case AREG: /* %r */
214 ap->areg1 |= 0x50;
215 break;
216 case ABASE: /* (%r) */
217 ap->areg1 |= 0x60;
218 break;
219 case ADECR: /* -(%r) */
220 ap->areg1 |= 0x70;
221 break;
222 case AINCR: /* (%r) */
223 ap->areg1 |= 0x80;
224 break;
225 case AEXP: /* expr */
226 a = itab[op]->argtype[i];
227 if (a == ACCB+TYPB) {
228 ap->areg1 = a =
229 xp->xvalue - (dotp->xvalue + 1);
230 if (a<MINBYTE || a>MAXBYTE)
231 yyerror("Branch too far"); break;
232 }
233 if (a == ACCB+TYPW) {
234 ap->areg1 = a = xp->xvalue
235 -= dotp->xvalue + 2;
236 xp->xtype = XABS;
237 if (a<MINWORD || a>MAXWORD)
238 yyerror("Branch too far");
239 xp->xvalue = a>>8;
240 xtrab = LEN1;
241 break;
242 }
243 /* reduces to expr(pc) mode */
244 ap->areg1 |= (0xAF + mod124[ap->dispsize]);
245 xtrab = len124[ap->dispsize]+PCREL;
246 break;
247
248 case ADISP: /* expr(%r) */
249 ap->areg1 |= 0xA0;
250 if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW){
251 ap->areg1 += mod124[ap->dispsize];
252 xtrab=len124[ap->dispsize];
253 break;
254 }
255 if (xp->xvalue==0 && !(ap->areg1&0x10)) {
256 ap->areg1 ^= 0xC0;
257 break;
258 }
259 xtrab=LEN1;
260 if ((xp->xvalue<MINBYTE) || (xp->xvalue>MAXBYTE)){
261 ap->areg1 += 0x20;
262 xtrab=LEN2;
263 }
264 if ((xp->xvalue<MINWORD) || (xp->xvalue>MAXWORD)){
265 ap->areg1 += 0x20;
266 xtrab=LEN4;
267 }
268 break;
269
270 case AIMM: /* $expr */
271 if (ap->atype&ASTAR)
272 a=TYPL;
273 else {
274 a = itab[op]->argtype[i];
275 if (a&ACCA)
276 a=TYPL;
277 else
278 a &= TYPMASK;
279 if ( ( (xp->xtype&XTYPE) == XABS)
280 && !(xp->xtype&XFORW)
281 && (xp->xvalue >= 0)
282 && (xp->xvalue <= 63)
283 && (xp->yvalue == 0)
284 && (a != TYPF)
285 && (a != TYPD) ) {
286 ap->areg1 = xp->xvalue;
287 break;
288 }
289 }
290 ap->areg1 |= 0x8F;
291 switch (a) {
292 case TYPD:
293 case TYPF:
294 if ( ((xp->xtype&XTYPE)==XABS)
295 && (!(xp->xtype&XFORW))
296 && (slitflt(xp))
297 ){
298 ap->areg1=extlitflt(xp);
299 } else {
300 xtrab = (a==TYPF) ? LEN4: LEN8;
301 }
302 break;
303 case TYPQ: xtrab = LEN8; break;
304 case TYPL: xtrab = LEN4; break;
305 case TYPW: xtrab = LEN2; break;
306 case TYPB: xtrab = LEN1; break;
307 }
308 break;
309
310 } /*end of the switch on a*/
311 /*
312 * use the first byte to describe the argument
313 */
314#ifdef UNIX
315 outb(ap->areg1);
316#endif UNIX
317#ifdef VMS
318 *vms_obj_ptr++ = -1; *vms_obj_ptr++ = (char)(ap->areg1);
319 dotp->xvalue += 1;
320 if ((vms_obj_ptr-sobuf) > 400) {
321 write(objfil,sobuf,vms_obj_ptr-sobuf);
322 vms_obj_ptr=sobuf+1;
323 }
324#endif VMS
325 if (xtrab)
326 /*
327 * Floating point numbers are written to a.out
328 * by outrel; they require that the least significant
329 * 4 bytes of an 8 byte double precision number
330 * immediately follow the field xvalue, which
331 * they do.
332 */
333 outrel(&xp->xvalue, xtrab, xp->xtype, xp->xname);
334 } /*end of the for to pick up all arguments*/
335}