/* Copyright (c) 1980 Regents of the University of California */
static char sccsid
[] = "@(#)ascode.c 4.3 %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
, fetcharg(ip
, 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
);
yyerror("arg %d, addressing a register",i
);
if ( (atm
== AIMM
) && !(at
& ASTAR
) ){
yyerror("arg %d, addressing an immediate operand",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
->a_areg1
==act
->a_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
->e_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
= fetcharg(itab
[op
], i
);
dotp
->e_xvalue
+= ap
->a_dispsize
;
if ((xp
->e_xtype
&XTYPE
)!=XABS
|| xp
->e_xtype
&XFORW
){
dotp
->e_xvalue
+= ap
->a_dispsize
;
if (xp
->e_xvalue
==0 && !(a
&ASTAR
))
if ((xp
->e_xvalue
<MINBYTE
) || (xp
->e_xvalue
>MAXBYTE
))
if ((xp
->e_xvalue
<MINWORD
) || (xp
->e_xvalue
>MAXWORD
))
if (ap
->a_atype
&ASTAR
) a
=TYPL
;
a
= fetcharg(itab
[op
], i
);
if ( ((xp
->e_xtype
&XTYPE
)==XABS
)
&& (!(xp
->e_xtype
&XFORW
))
if ( !(((xp
->e_xtype
&XTYPE
)==XABS
)
&& (!(xp
->e_xtype
&XFORW
))
dotp
->e_xvalue
+= ((a
==TYPF
)?
dotp
->e_xvalue
+= 8;break;
dotp
->e_xvalue
+= 4;break;
dotp
->e_xvalue
+= 2;break;
dotp
->e_xvalue
+= 1;break;
} /*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
->a_areg2
); }
*vms_obj_ptr
++ = (0x40 | ap
->a_areg2
);
a
= fetcharg(itab
[op
], i
);
xp
->e_xvalue
- (dotp
->e_xvalue
+ 1);
if (a
<MINBYTE
|| a
>MAXBYTE
)
yyerror("Branch too far"); break;
ap
->a_areg1
= a
= xp
->e_xvalue
if (a
<MINWORD
|| a
>MAXWORD
)
yyerror("Branch too far");
/* reduces to expr(pc) mode */
ap
->a_areg1
|= (0xAF + mod124
[ap
->a_dispsize
]);
xtrab
= len124
[ap
->a_dispsize
]+PCREL
;
case ADISP
: /* expr(%r) */
if ((xp
->e_xtype
&XTYPE
)!=XABS
|| xp
->e_xtype
&XFORW
){
ap
->a_areg1
+= mod124
[ap
->a_dispsize
];
xtrab
=len124
[ap
->a_dispsize
];
if (xp
->e_xvalue
==0 && !(ap
->a_areg1
&0x10)) {
if ((xp
->e_xvalue
<MINBYTE
) || (xp
->e_xvalue
>MAXBYTE
)){
if ((xp
->e_xvalue
<MINWORD
) || (xp
->e_xvalue
>MAXWORD
)){
a
= fetcharg(itab
[op
], i
);
if ( ( (xp
->e_xtype
&XTYPE
) == XABS
)
ap
->a_areg1
= xp
->e_xvalue
;
if ( ((xp
->e_xtype
&XTYPE
)==XABS
)
&& (!(xp
->e_xtype
&XFORW
))
ap
->a_areg1
=extlitflt(xp
);
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
->a_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
->e_xvalue
, xtrab
, xp
->e_xtype
, xp
->e_xname
);
} /*end of the for to pick up all arguments*/