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