/* Copyright (c) 1980 Regents of the University of California */
static char sccsid
[] = "@(#)ascode.c 4.1 %G%";
register struct arg
*ap2
;
register struct instab
*ip
;
yyerror("Too few arguments");
yyerror("Too many arguments");
* Check argument compatability with instruction template
for (ap2
= ap
+nact
, i
= nact
; --i
>= 0;)
argcompat(--ap2
, ip
->argtype
[i
], i
+1);
else putins(op
, ap
, nact
);
if ( (exp
& ACCB
) && (!((atm
== AEXP
) || (atm
== AIMM
))) ){
yyerror("arg %d, branch displacement must be an expression",i
);
if ((exp
& ACCA
) && (atm
== AREG
)) {
yyerror("arg %d, addressing a register",i
);
if ((exp
&ACCW
) && (atm
==AIMM
) && !(at
&ASTAR
)) {
yyerror("arg %d, modifying a constant",i
);
yyerror("arg %d, PC used as index",i
);
yyerror("arg %d, indexing the register file",i
);
yyerror("arg %d, indexing a constant",i
);
if (((atm
==ADECR
) || (atm
==AINCR
)) && (act
->areg1
==act
->areg2
)) {
yyerror("arg %d, indexing with modified register",i
);
int len124
[] = {0,LEN1
,LEN2
,0,LEN4
};
char mod124
[] = {0,0x00,0x20,0,0x40};
* n had better be positive
dotp
->xvalue
+= n
+1; /* 1 for the opcode, at least 1 per arg */
for (i
=0; i
<n
; i
++,ap
++) {/* some args take more than 1 byte */
switch (a
&~(AINDX
|ASTAR
)) {
a
= itab
[op
]->argtype
[i
];
dotp
->xvalue
+= ap
->dispsize
;
if ((xp
->xtype
&XTYPE
)!=XABS
|| xp
->xtype
&XFORW
){
dotp
->xvalue
+= ap
->dispsize
;
if (xp
->xvalue
==0 && !(a
&ASTAR
))
if ((xp
->xvalue
<MINBYTE
) || (xp
->xvalue
>MAXBYTE
))
if ((xp
->xvalue
<MINWORD
) || (xp
->xvalue
>MAXWORD
))
if (ap
->atype
&ASTAR
) a
=TYPL
;
a
= itab
[op
]->argtype
[i
];
if ( ((xp
->xtype
&XTYPE
)==XABS
)
if ( !(((xp
->xtype
&XTYPE
)==XABS
)
dotp
->xvalue
+= ((a
==TYPF
)?
} /*end of the switch on a*/
} /*end of the switch on the type*/
} /*end of looping for all arguments*/
outb(op
); /* the opcode */
*vms_obj_ptr
++ = -1; *vms_obj_ptr
++ = (char)op
;
for (i
=0; i
<n
; i
++,ap
++) {/* now for the arguments */
{ outb(0x40 | ap
->areg2
); }
*vms_obj_ptr
++ = (0x40 | ap
->areg2
);
a
= itab
[op
]->argtype
[i
];
xp
->xvalue
- (dotp
->xvalue
+ 1);
if (a
<MINBYTE
|| a
>MAXBYTE
)
yyerror("Branch too far"); break;
ap
->areg1
= a
= xp
->xvalue
if (a
<MINWORD
|| a
>MAXWORD
)
yyerror("Branch too far");
/* reduces to expr(pc) mode */
ap
->areg1
|= (0xAF + mod124
[ap
->dispsize
]);
xtrab
= len124
[ap
->dispsize
]+PCREL
;
case ADISP
: /* expr(%r) */
if ((xp
->xtype
&XTYPE
)!=XABS
|| xp
->xtype
&XFORW
){
ap
->areg1
+= mod124
[ap
->dispsize
];
xtrab
=len124
[ap
->dispsize
];
if (xp
->xvalue
==0 && !(ap
->areg1
&0x10)) {
if ((xp
->xvalue
<MINBYTE
) || (xp
->xvalue
>MAXBYTE
)){
if ((xp
->xvalue
<MINWORD
) || (xp
->xvalue
>MAXWORD
)){
a
= itab
[op
]->argtype
[i
];
if ( ( (xp
->xtype
&XTYPE
) == XABS
)
if ( ((xp
->xtype
&XTYPE
)==XABS
)
xtrab
= (a
==TYPF
) ? LEN4
: LEN8
;
case TYPQ
: xtrab
= LEN8
; break;
case TYPL
: xtrab
= LEN4
; break;
case TYPW
: xtrab
= LEN2
; break;
case TYPB
: xtrab
= LEN1
; break;
} /*end of the switch on a*/
* use the first byte to describe the argument
*vms_obj_ptr
++ = -1; *vms_obj_ptr
++ = (char)(ap
->areg1
);
if ((vms_obj_ptr
-sobuf
) > 400) {
write(objfil
,sobuf
,vms_obj_ptr
-sobuf
);
* Floating point numbers are written to a.out
* by outrel; they require that the least significant
* 4 bytes of an 8 byte double precision number
* immediately follow the field xvalue, which
outrel(&xp
->xvalue
, xtrab
, xp
->xtype
, xp
->xname
);
} /*end of the for to pick up all arguments*/