📄 parser.y
字号:
set_md($$.mode,0); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,$3.value); } | C ',' '/' bit { set_md($$.mode,1); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,$4.value); } | C ',' '!' bit { set_md($$.mode,1); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,$4.value); } ;two_op4 : bit ',' rel { set_md($$.mode,0); set_ov($$.mode,0); set_sz($$.mode,2); set_b1($$.mode,$1.value); set_b2($$.mode,$3.value); } ;two_op5 : reg ',' rel2 { set_md($$.mode,0); set_ov($$.mode,$1.value); set_sz($$.mode,1); set_b1($$.mode,$3.value); } | data8 ',' rel { set_md($$.mode,1); set_ov($$.mode,0); set_sz($$.mode,2); set_b1($$.mode,$1.value); set_b2($$.mode,$3.value); } ;two_op6 : reg ',' A { set_md($$.mode,0); set_ov($$.mode,$1.value); set_sz($$.mode,0); } | reg ',' data8 { set_md($$.mode,1); set_ov($$.mode,$1.value); set_sz($$.mode,1); set_b1($$.mode,$3.value); } | reg ',' '#' data8 { set_md($$.mode,2); set_ov($$.mode,$1.value); set_sz($$.mode,1); set_b1($$.mode,$4.value); } | data8 ',' reg { set_md($$.mode,3); set_ov($$.mode,$3.value); set_sz($$.mode,1); set_b1($$.mode,$1.value); } | data8 ',' data8 { set_md($$.mode,4); set_ov($$.mode,0); set_sz($$.mode,2); set_b1($$.mode,$3.value); set_b2($$.mode,$1.value); } | data8 ',' '@' regi { set_md($$.mode,5); set_ov($$.mode,$4.value); set_sz($$.mode,1); set_b1($$.mode,$1.value); } | '@' regi ',' A { set_md($$.mode,6); set_ov($$.mode,$2.value); set_sz($$.mode,0); } | '@' regi ',' data8 { set_md($$.mode,7); set_ov($$.mode,$2.value); set_sz($$.mode,1); set_b1($$.mode,$4.value); } | '@' regi ',' '#' data8 { set_md($$.mode,8); set_ov($$.mode,$2.value); set_sz($$.mode,1); set_b1($$.mode,$5.value); } | DPTR ',' '#' data16 { set_md($$.mode,9); set_ov($$.mode,0); set_sz($$.mode,2); set_b1($$.mode, ($4.value & 0xff00) >> 8 ); set_b2($$.mode, ($4.value & 0x00ff) ); } | C ',' bit { set_md($$.mode,10); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,$3.value); } /* * Following two productions cannot be represented by: * * bit ',' C * * Because yacc gives tons of reduce/reduce errors if * that is attempted. * */ | data8 ',' C { set_md($$.mode,11); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,$1.value); } | data8 BITPOS ',' C{ if( pass2 ) { if( !isbit8($1.value) ) warn("Bit address exceeds 8-bits"); if( isbmram($1.value) ) set_b1($$.mode, ($1.value-0x20)*8+ $2.value ); else if( isbmsfr($1.value) ) set_b1($$.mode, $1.value + $2.value ); else warn("Invalid bit addressable RAM location"); } set_md($$.mode,11); set_ov($$.mode,0); set_sz($$.mode,1);} ;single_op1 : A { set_md($$.mode,0); set_ov($$.mode,0); set_sz($$.mode,0); } | reg { set_md($$.mode,1); set_ov($$.mode,$1.value); set_sz($$.mode,0); } | data8 { set_md($$.mode,2); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,$1.value); } | '@' regi { set_md($$.mode,3); set_ov($$.mode,$2.value); set_sz($$.mode,0); } ;single_op2 : A { set_md($$.mode,0); set_ov($$.mode,0); set_sz($$.mode,0); } | C { set_md($$.mode,1); set_ov($$.mode,0); set_sz($$.mode,0); } | bit { set_md($$.mode,2); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,$1.value); } ;three_op1 : A ',' data8 ',' rel { set_md($$.mode,0); set_ov($$.mode,0); set_sz($$.mode,2); set_b1($$.mode,$3.value); set_b2($$.mode,$5.value); } | A ',' '#' data8 ',' rel { set_md($$.mode,1); set_ov($$.mode,0); set_sz($$.mode,2); set_b1($$.mode,$4.value); set_b2($$.mode,$6.value); } | reg ',' '#' data8 ',' rel { set_md($$.mode,2); set_ov($$.mode,$1.value); set_sz($$.mode,2); set_b1($$.mode,$4.value); set_b2($$.mode,$6.value); } | '@' regi ',' '#' data8 ',' rel { set_md($$.mode,3); set_ov($$.mode,$2.value); set_sz($$.mode,2); set_b1($$.mode,$5.value); set_b2($$.mode,$7.value); } ;rel : expr{ long offset; if( pass2 ) { offset = $1.val.v - (lc+3); if( offset > 127 || offset < -128 ) warn("Relative offset exceeds -128 / +127"); $$.value = offset; }} ;/* * This production differs from the above, by 1 number! * */rel2 : expr{ long offset; if( pass2 ) { offset = $1.val.v - (lc+2); /* different! */ if( offset > 127 || offset < -128 ) warn("Relative offset exceeds -128 / +127"); $$.value = offset; }} ;bit : bitv BITPOS{ if( pass2 ) { if( !isbit8($1.value) ) warn("Bit address exceeds 8-bits"); if( isbmram($1.value) ) $$.value = ($1.value-0x20)*8+$2.value; else if( isbmsfr($1.value) ) $$.value = $1.value + $2.value; else warn("Invalid bit addressable RAM location"); }} | bitv{ if( pass2 ) { if( !isbit8($1.value) ) warn("Bit address exceeds 8-bits"); $$.value = $1.value; }} ;bitv : SYMBOL{ if( $1.sym->type == UNDEF && pass2 ) warn("Symbol %s undefined",$1.sym->name); $$.value = $1.sym->value;} | VALUE { $$.value = $1.value; } ;reg : R0 { $$.value = 0; } | R1 { $$.value = 1; } | R2 { $$.value = 2; } | R3 { $$.value = 3; } | R4 { $$.value = 4; } | R5 { $$.value = 5; } | R6 { $$.value = 6; } | R7 { $$.value = 7; } ;regi : R0 { $$.value = 0; } | R1 { $$.value = 1; } | R2 { $$.value = 0; warn("Illegal indirect register: @r2"); } | R3 { $$.value = 0; warn("Illegal indirect register: @r3"); } | R4 { $$.value = 0; warn("Illegal indirect register: @r4"); } | R5 { $$.value = 0; warn("Illegal indirect register: @r5"); } | R6 { $$.value = 0; warn("Illegal indirect register: @r6"); } | R7 { $$.value = 0; warn("Illegal indirect register: @r7"); } ;data8 : expr{ if( pass2 ) { if( !isbit8($1.val.v) ) warn("Expression greater than 8-bits"); } $$.value = $1.val.v;} ;data16 : expr{ if( pass2 ) { if( !isbit16($1.val.v) ) warn("Expression greater than 16-bits"); } $$.value = $1.val.v;} ;addr11 : expr{ if( pass2 ) { if( !isbit16($1.val.v) ) warn("Address greater than 16-bits"); if( ($1.val.v & size11) != ((lc+2) & size11) ) warn("Address outside current 2K page"); } set_md($$.mode,0); set_ov($$.mode, ($1.val.v&0x0700)>>3 ); set_sz($$.mode,1); set_b1($$.mode,$1.val.v&0x00ff);} ;addr16 : expr{ if( pass2 ) { if( !isbit16($1.val.v) ) warn("Address greater than 16-bits"); } set_md($$.mode,0); set_ov($$.mode, 0 ); set_sz($$.mode,2); set_b1($$.mode, ($1.val.v & 0xff00 ) >> 8 ); set_b2($$.mode, ($1.val.v & 0x00ff ) );} ;relative : expr{ long offset=0; if( pass2 ) { offset = $1.val.v - (lc+2); if( offset>127 || offset<-128 ) warn("Relative offset exceeds -128 / +127"); } set_md($$.mode,0); set_ov($$.mode,0); set_sz($$.mode,1); set_b1($$.mode,offset);} ;%%/* ---------------------------------------------------------------------- */void yyerror(const char *s){ warn("%s near \"%s\"", s, get_last_token());}/* ---------------------------------------------------------------------- * makeop: * This function makes an opcode based on the instruction symbol table * entry, and an addressing mode structure. * This function is called from both passes, but * only generates code in pass 2. * * Resultant opcode bytes are passed to genbyte(). * * Returns the nuumber of bytes that the instruction * occupies. * */int makeop(struct opcode * op, struct mode *m, int add){ register unsigned int newop; if( m == NULL ) { if(pass2) genbyte(op->bytes[0+add]); return(1); } if( pass2 ) { newop = op->bytes[ get_md(*m)+add ] | get_ov(*m); genbyte(newop); if( get_sz(*m) > 0 ) genbyte( get_b1(*m) ); if( get_sz(*m) > 1 ) genbyte( get_b2(*m) ); } return( get_sz(*m)+1 );}/* ---------------------------------------------------------------------- * inclc: * Increments the Location Counter by 'i' amount. * Check to see if 'i' overflows 64K. * Checks to see if assembler is overlapping previous sections * of code. (using a large bit field). * */#define indx(a) ( (a)/(sizeof(long)*8) )#define bit(a) ( 1 << ((a)%(sizeof(long)*8)) )#define getloc(a) (regions[indx(a)] & bit(a))#define setloc(a) (regions[indx(a)] |= bit(a))static unsigned long regions[ 0x10000/(sizeof(long)*8) ];void inclc(int i){ while (i-- > 0) { if( pass2 && getloc(lc) ) error("Location counter overlaps"); if( pass2 ) setloc(lc); lc += 1; } if( lc > 0xffff ) error("Location counter has exceeded 16-bits");}void clear_location_counter(void){ memset(regions, 0, sizeof(regions));}/* ---------------------------------------------------------------------- * padline: * This routine returns a new string, which is equivilant to * 'line' except that all tabs have been expanded to spaces, and * the total length has been truncated to 60 chars. */char *padline(char *line){ static char newline[61]; char *p1; int pos=0,nxtpos; for(p1=line; pos<sizeof(newline)-1 && *p1; p1++ ) { if( *p1 == '\t' ) { nxtpos = pos+8-pos%8; while(pos<sizeof(newline)-1 && pos <= nxtpos) newline[pos++] = ' '; } else if( *p1 != '\n' ) newline[pos++]= *p1; } newline[pos] = '\0'; return(newline);}/* ---------------------------------------------------------------------- * dumplist: * Outputs the current location counter, bytebuf[] array, and * the string 'txt' to the listing file. * This routine is called for every source line encountered in the * source file. (Only in pass 2, and if listing is turned on). * */void dumplist(char *txt, int show){ int i,j; fprintf(listing,show?"%04X: ":" ",lc); j=0; for(i=0; i<bytecount; i++ ) { fprintf(listing,"%02X ",bytebuf[i]); if( ++j >= 4 ) { j = 0; fprintf(listing,"\n "); } } while(++j <= 4) fprintf(listing," "); fprintf(listing," %s\n",padline(txt));}/* ---------------------------------------------------------------------- * gen* routines: * Place information into the bytebuf[] array, and also * call emitbyte with the byte. * */void genbyte(int b){ if( bytecount < sizeof(bytebuf) ) bytebuf[bytecount++] = b; emitbyte(b);}void genstr(const char *s){ while( *s ) genbyte(*s++);}void genword(unsigned long w){ genbyte( (w & 0xff00) >> 8 ); genbyte( (w & 0x00ff) );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -