- register struct arg *ap2;
- register struct instab *ip;
- int i,nexp;
- ip = itab[op];
- nexp = ip->nargs;
- if (nact < nexp)
- yyerror("Too few arguments");
- if (nact > nexp) {
- yyerror("Too many arguments");
- nact = nexp;
- }
- /*
- * Check argument compatability with instruction template
- */
- for (ap2 = ap+nact, i = nact; --i >= 0;)
- argcompat(--ap2, ip->argtype[i], i+1);
- }
+ ip = itab[op];
+ if (nact < ip->i_nargs)
+ yyerror("Too few arguments");
+ if (nact > ip->i_nargs) {
+ yyerror("Too many arguments");
+ nact = ip->i_nargs;
+ }
+ /*
+ * Check argument compatability with instruction template
+ */
+ for (ap_walk = ap, i = 1; i <= nact; ap_walk++, i++){
+ ap_type = ap_walk->a_type;
+ ap_type_mask = ap_type & AMASK;
+ switch( (fetcharg(ip, i-1)) & AMASK){ /* type of fp */
+ case ACCB:
+ if ( !((ap_type_mask == AEXP) || (ap_type_mask == AIMM)) ){
+ yyerror("arg %d, branch displacement must be an expression",i);
+ return;
+ }
+ break;
+ case ACCA:
+ switch(ap_type_mask){
+ case AREG: yyerror("arg %d, addressing a register",i);
+ return;
+ case AIMM: if ( !(ap_type & ASTAR) ){
+ yyerror("arg %d, addressing an immediate operand",i);
+ return;
+ }
+ }
+ break;
+ case ACCM:
+ case ACCW:
+ switch(ap_type_mask){
+ case AIMM: if (!(ap_type&ASTAR)) {
+ yyerror("arg %d, modifying a constant",i);
+ return;
+ }
+ }
+ break;
+ } /* end of the switch on fp_type */
+ if (ap_type & AINDX) {
+ if (ap_walk->a_areg2==0xF) {
+ yyerror("arg %d, PC used as index",i);
+ return;
+ }
+ switch(ap_type_mask){
+ case AREG: yyerror("arg %d, indexing the register file",i);
+ return;
+ case AIMM: yyerror("arg %d, indexing a constant",i);
+ return;
+ case DECR:
+ case INCR: if (ap_walk->a_areg1==ap_walk->a_areg2) {
+ yyerror("arg %d, indexing with modified register",i);
+ return;
+ }
+ break;
+ } /* end of switch on ap_type_mask */
+ } /* end of AINDX */
+ }
+ } /* both passes here */