* Copyright (c) 1982 Regents of the University of California
static char sccsid
[] = "@(#)ascode.c 4.11 6/30/83";
reg
struct instab
*ip
; /* the instruction */
reg
struct arg
*ap_walk
; /* actual param walk */
reg
int ap_type
; /* actual param type */
reg
int ap_type_mask
; /* masked actual param */
ip
= ITABFETCH(opcode
& 0xFF);
yyerror("Too few arguments");
if (nact
> ip
->i_nargs
) {
yyerror("Too many arguments");
* Check argument compatability with instruction template
for (ap_walk
= ap
, i
= 1; i
<= nact
; ap_walk
++, i
++){
ap_type
= ap_walk
->a_atype
;
ap_type_mask
= ap_type
& AMASK
;
* The switch value is >> by TYPLG so that the switch
* code is dense, not implemented as a sequence
* of branches but implemented as a casel.
* In addition, cases ACCI and ACCR are added to force
* switch on the type of fp
argtype
= fetcharg(ip
, i
-1);
switch( (argtype
& ACCESSMASK
) >> TYPLG
){
(ap_type_mask
== AREG
) &&
(ap_walk
->a_areg1
& 0x01)) {
yyerror("arg %d, register must be even",i
);
if (ap_type_mask
== ADECR
)
yyerror("arg %d, a source arg cant be auto decrement",i
);
if (ap_type_mask
== AIMM
)
yyerror("arg %d, cant be immediate data",i
);
((ap_type_mask
== AINCR
) ||
(ap_type_mask
== ADECR
)))
yyerror("arg %d, cant be auto increment/decrement",i
);
(ap_type_mask
== AREG
) &&
(ap_walk
->a_areg1
& 0x01)) {
yyerror("arg %d, register must be even",i
);
if ( ap_type_mask
!= AEXP
)
yyerror("arg %d, branch displacement must be an expression",i
);
case AREG
: yyerror("arg %d, addressing a register",i
);
case AIMM
: if ( !(ap_type
& ASTAR
) ){
yyerror("arg %d, addressing an immediate operand",i
);
(ap_type_mask
== AREG
) &&
(ap_walk
->a_areg1
& 0x01)) {
yyerror("arg %d, register must be even",i
);
case AIMM
: if (!(ap_type
&ASTAR
)) {
yyerror("arg %d, modifying a constant",i
);
yyerror("arg %d, a destination arg cant be auto increment",i
);
} /* end of the switch on fp_type */
if (ap_walk
->a_areg2
==0xF) {
yyerror("arg %d, PC used as index",i
);
if (ap_walk
->a_areg2
==0xE) {
yyerror("arg %d, SP used as index",i
);
case AREG
: yyerror("arg %d, indexing the register file",i
);
case AIMM
: yyerror("arg %d, indexing a constant",i
);
case AINCR
: if (ap_walk
->a_areg1
==ap_walk
->a_areg2
) {
yyerror("arg %d, indexing with modified register",i
);
} /* end of switch on ap_type_mask */
ijxout(opcode
, ap
, nact
);
putins(opcode
, ap
, nact
);
int n
; /* Must be positive */
dotp
->e_xvalue
+= n
+1; /* at least one byte per arg */
for (i
=0; i
<n
; i
++,ap
++) { /* some args take more than 1 byte */
* This switch has been fixed by enumerating the no action
* alternatives (those that have 1 one byte of code)
* so that a casel instruction is emitted.
switch (argtype
&~(AINDX
|ASTAR
)) {
argtype
= fetcharg(ITABFETCH(opcode
), 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 && !(argtype
&ASTAR
))
if (ISBYTE(xp
->e_xvalue
))
if (ISWORD(xp
->e_xvalue
))
argtype
= fetcharg(ITABFETCH(opcode
), i
);
if ( ((xp
->e_xtype
&XTYPE
)==XABS
)
&& (!(xp
->e_xtype
&XFORW
))
if (ISBYTE(xp
->e_xvalue
))
if (ISWORD(xp
->e_xvalue
))
dotp
->e_xvalue
+= ty_nbyte
[argtype
];
} /*end of the switch on argtype*/
} /*end of the switch on the type*/
} /*end of looping for all arguments*/
if ((passno
== 2) && liston
)
for (i
=0; i
<n
; i
++,ap
++) {/* now for the arguments */
{ Outb(0x40 | ap
->a_areg2
);
if ((passno
== 2) && liston
)
byte_out (0x40 | ap
->a_areg2
); }
argtype
= fetcharg(ITABFETCH(opcode
), i
);
xp
->e_xvalue
- (dotp
->e_xvalue
+ 1);
yywarning("%s: destination label is external",
FETCHNAME(ITABFETCH(opcode
)));
if (!ISBYTE(argtype
) && !jxxxJUMP
)
yyerror("%s: Branch too far(%db): try -J flag",
FETCHNAME(ITABFETCH(opcode
)),
ap
->a_areg1
= argtype
= xp
->e_xvalue
yywarning("%s: destination label is external",
FETCHNAME(ITABFETCH(opcode
)));
if (!ISWORD(argtype
) && !jxxxJUMP
)
yyerror("%s: Branch too far(%db): try -J flag",
FETCHNAME(ITABFETCH(opcode
)),
ap
->a_areg1
= argtype
>>8;
/* reduces to expr(pc) mode */
ap
->a_areg1
|= (0xAF + mod124
[ap
->a_dispsize
]);
reloc_how
= type_124
[ap
->a_dispsize
] + RELOC_PCREL
;
case ADISP
: /* expr(%r) */
if ((xp
->e_xtype
&XTYPE
)!=XABS
|| xp
->e_xtype
&XFORW
){
ap
->a_areg1
+= mod124
[ap
->a_dispsize
];
reloc_how
= type_124
[ap
->a_dispsize
];
if (xp
->e_xvalue
==0 && !(ap
->a_areg1
&0x10)) {
if (ISBYTE(xp
->e_xvalue
))
if (ISWORD(xp
->e_xvalue
))
argtype
= fetcharg(ITABFETCH(opcode
), i
);
if ( ( (xp
->e_xtype
&XTYPE
) == XABS
)
ap
->a_areg1
= xp
->e_xvalue
;
if (ISBYTE (xp
->e_xvalue
))
if (ISWORD (xp
->e_xvalue
))
if (reloc_how
== TYPD
|| reloc_how
== TYPF
){
if ( ((xp
->e_xtype
&XTYPE
)==XABS
)
&& (!(xp
->e_xtype
&XFORW
))
ap
->a_areg1
=extlitflt(xp
);
} /*end of the switch on argtype*/
* use the first byte to describe the argument
if ((passno
== 2) && liston
)
if (reloc_how
!= TYPNONE
)
if ((passno
== 2) && liston
)
} /*end of the for to pick up all arguments*/