%{ /* xa_rasm.l - This file is part of Paul's XA51 Assembler Copyright 1997,2002 Paul Stoffregen (paul at pjrc dot com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Author contact: paul@pjrc.com */ #include #include #include "xa_main.h" #include "xa_rasm.tab.h" extern int inst_size, yylval; char line_text[MAX_LINE]={'\0'}, last_line_text[MAX_LINE]; char lex_sym_name[MAX_SYMBOL]; extern char base_symbol_name[]; #define LIST if (p3) strcat(line_text, yytext) %} %% add\.w {LIST; inst_size=SIZE16; return ADD;} add\.b {LIST; inst_size=SIZE8; return ADD;} add {LIST; inst_size=UNKNOWN; return ADD;} addc\.w {LIST; inst_size=SIZE16; return ADDC;} addc\.b {LIST; inst_size=SIZE8; return ADDC;} addc {LIST; inst_size=UNKNOWN; return ADDC;} adds\.w {LIST; inst_size=SIZE16; return ADDS;} adds\.b {LIST; inst_size=SIZE8; return ADDS;} adds {LIST; inst_size=UNKNOWN; return ADDS;} and\.w {LIST; inst_size=SIZE16; return AND;} and\.b {LIST; inst_size=SIZE8; return AND;} and {LIST; inst_size=UNKNOWN; return AND;} anl {LIST; inst_size=UNKNOWN; return ANL;} asl\.d {LIST; inst_size=SIZE32; return ASL;} asl\.w {LIST; inst_size=SIZE16; return ASL;} asl\.b {LIST; inst_size=SIZE8; return ASL;} asl {LIST; inst_size=UNKNOWN; return ASL;} asr\.d {LIST; inst_size=SIZE32; return ASR;} asr\.w {LIST; inst_size=SIZE16; return ASR;} asr\.b {LIST; inst_size=SIZE8; return ASR;} asr {LIST; inst_size=UNKNOWN; return ASR;} bcc {LIST; inst_size=UNKNOWN; return BCC;} bcs {LIST; inst_size=UNKNOWN; return BCS;} beq {LIST; inst_size=UNKNOWN; return BEQ;} bg {LIST; inst_size=UNKNOWN; return BG;} bge {LIST; inst_size=UNKNOWN; return BGE;} bgt {LIST; inst_size=UNKNOWN; return BGT;} bkpt {LIST; inst_size=UNKNOWN; return BKPT;} bl {LIST; inst_size=UNKNOWN; return BL;} ble {LIST; inst_size=UNKNOWN; return BLE;} blt {LIST; inst_size=UNKNOWN; return BLT;} bmi {LIST; inst_size=UNKNOWN; return BMI;} bne {LIST; inst_size=UNKNOWN; return BNE;} bnv {LIST; inst_size=UNKNOWN; return BNV;} bov {LIST; inst_size=UNKNOWN; return BOV;} bpl {LIST; inst_size=UNKNOWN; return BPL;} br {LIST; inst_size=UNKNOWN; return BR;} call {LIST; inst_size=UNKNOWN; return CALL;} cjne\.w {LIST; inst_size=SIZE16; return CJNE;} cjne\.b {LIST; inst_size=SIZE8; return CJNE;} cjne {LIST; inst_size=UNKNOWN; return CJNE;} clr {LIST; inst_size=UNKNOWN; return CLR;} cmp\.w {LIST; inst_size=SIZE16; return CMP;} cmp\.b {LIST; inst_size=SIZE8; return CMP;} cmp {LIST; inst_size=UNKNOWN; return CMP;} cpl\.w {LIST; inst_size=SIZE16; return CPL;} cpl\.b {LIST; inst_size=SIZE8; return CPL;} cpl {LIST; inst_size=UNKNOWN; return CPL;} da\.b {LIST; inst_size=SIZE8; return DA;} da {LIST; inst_size=UNKNOWN; return DA;} div\.d {LIST; inst_size=SIZE32; return DIV;} div\.w {LIST; inst_size=SIZE16; return DIV;} div\.b {LIST; inst_size=SIZE8; return DIV;} div {LIST; inst_size=UNKNOWN; return DIV;} divu\.d {LIST; inst_size=SIZE32; return DIVU;} divu\.w {LIST; inst_size=SIZE16; return DIVU;} divu\.b {LIST; inst_size=SIZE8; return DIVU;} divu {LIST; inst_size=UNKNOWN; return DIVU;} djnz\.w {LIST; inst_size=SIZE16; return DJNZ;} djnz\.b {LIST; inst_size=SIZE8; return DJNZ;} djnz {LIST; inst_size=UNKNOWN; return DJNZ;} fcall {LIST; inst_size=UNKNOWN; return FCALL;} fjmp {LIST; inst_size=UNKNOWN; return FJMP;} jb {LIST; inst_size=UNKNOWN; return JB;} jbc {LIST; inst_size=UNKNOWN; return JBC;} jmp {LIST; inst_size=UNKNOWN; return JMP;} jnb {LIST; inst_size=UNKNOWN; return JNB;} jnz {LIST; inst_size=UNKNOWN; return JNZ;} jz {LIST; inst_size=UNKNOWN; return JZ;} lea\.w {LIST; inst_size=SIZE16; return LEA;} lea {LIST; inst_size=UNKNOWN; return LEA;} lsr\.d {LIST; inst_size=SIZE32; return LSR;} lsr\.w {LIST; inst_size=SIZE16; return LSR;} lsr\.b {LIST; inst_size=SIZE8; return LSR;} lsr {LIST; inst_size=UNKNOWN; return LSR;} mov\.w {LIST; inst_size=SIZE16; return MOV;} mov\.b {LIST; inst_size=SIZE8; return MOV;} mov {LIST; inst_size=UNKNOWN; return MOV;} movc\.w {LIST; inst_size=SIZE16; return MOVC;} movc\.b {LIST; inst_size=SIZE8; return MOVC;} movc {LIST; inst_size=UNKNOWN; return MOVC;} movs\.w {LIST; inst_size=SIZE16; return MOVS;} movs\.b {LIST; inst_size=SIZE8; return MOVS;} movs {LIST; inst_size=UNKNOWN; return MOVS;} movx\.w {LIST; inst_size=SIZE16; return MOVX;} movx\.b {LIST; inst_size=SIZE8; return MOVX;} movx {LIST; inst_size=UNKNOWN; return MOVX;} mul\.d {LIST; inst_size=SIZE32; return MUL;} mul\.w {LIST; inst_size=SIZE16; return MUL;} mul\.b {LIST; inst_size=SIZE8; return MUL;} mul {LIST; inst_size=UNKNOWN; return MUL;} mulu\.d {LIST; inst_size=SIZE32; return MULU;} mulu\.w {LIST; inst_size=SIZE16; return MULU;} mulu\.b {LIST; inst_size=SIZE8; return MULU;} mulu {LIST; inst_size=UNKNOWN; return MULU;} neg\.w {LIST; inst_size=SIZE16; return NEG;} neg\.b {LIST; inst_size=SIZE8; return NEG;} neg {LIST; inst_size=UNKNOWN; return NEG;} nop {LIST; inst_size=UNKNOWN; return NOP;} norm\.d {LIST; inst_size=SIZE32; return NORM;} norm\.w {LIST; inst_size=SIZE16; return NORM;} norm\.b {LIST; inst_size=SIZE8; return NORM;} norm {LIST; inst_size=UNKNOWN; return NORM;} or\.w {LIST; inst_size=SIZE16; return OR;} or\.b {LIST; inst_size=SIZE8; return OR;} or {LIST; inst_size=UNKNOWN; return OR;} orl {LIST; inst_size=UNKNOWN; return ORL;} pop\.w {LIST; inst_size=SIZE16; return POP;} pop\.b {LIST; inst_size=SIZE8; return POP;} pop {LIST; inst_size=UNKNOWN; return POP;} popu\.w {LIST; inst_size=SIZE16; return POPU;} popu\.b {LIST; inst_size=SIZE8; return POPU;} popu {LIST; inst_size=UNKNOWN; return POPU;} push\.w {LIST; inst_size=SIZE16; return PUSH;} push\.b {LIST; inst_size=SIZE8; return PUSH;} push {LIST; inst_size=UNKNOWN; return PUSH;} pushu\.w {LIST; inst_size=SIZE16; return PUSHU;} pushu\.b {LIST; inst_size=SIZE8; return PUSHU;} pushu {LIST; inst_size=UNKNOWN; return PUSHU;} reset {LIST; inst_size=UNKNOWN; return RESET;} ret {LIST; inst_size=UNKNOWN; return RET;} reti {LIST; inst_size=UNKNOWN; return RETI;} rl\.w {LIST; inst_size=SIZE16; return RL;} rl\.b {LIST; inst_size=SIZE8; return RL;} rl {LIST; inst_size=UNKNOWN; return RL;} rlc\.w {LIST; inst_size=SIZE16; return RLC;} rlc\.b {LIST; inst_size=SIZE8; return RLC;} rlc {LIST; inst_size=UNKNOWN; return RLC;} rr\.w {LIST; inst_size=SIZE16; return RR;} rr\.b {LIST; inst_size=SIZE8; return RR;} rr {LIST; inst_size=UNKNOWN; return RR;} rrc\.w {LIST; inst_size=SIZE16; return RRC;} rrc\.b {LIST; inst_size=SIZE8; return RRC;} rrc {LIST; inst_size=UNKNOWN; return RRC;} setb {LIST; inst_size=UNKNOWN; return SETB;} sext\.w {LIST; inst_size=SIZE16; return SEXT;} sext\.b {LIST; inst_size=SIZE8; return SEXT;} sext {LIST; inst_size=UNKNOWN; return SEXT;} sub\.w {LIST; inst_size=SIZE16; return SUB;} sub\.b {LIST; inst_size=SIZE8; return SUB;} sub {LIST; inst_size=UNKNOWN; return SUB;} subb\.w {LIST; inst_size=SIZE16; return SUBB;} subb\.b {LIST; inst_size=SIZE8; return SUBB;} subb {LIST; inst_size=UNKNOWN; return SUBB;} trap {LIST; inst_size=UNKNOWN; return TRAP;} xch\.w {LIST; inst_size=SIZE16; return XCH;} xch\.b {LIST; inst_size=SIZE8; return XCH;} xch {LIST; inst_size=UNKNOWN; return XCH;} xor\.w {LIST; inst_size=SIZE16; return XOR;} xor\.b {LIST; inst_size=SIZE8; return XOR;} xor {LIST; inst_size=UNKNOWN; return XOR;} dptr {LIST; return DPTR;} pc {LIST; return PC;} a {LIST; return A;} c {LIST; return C;} usp {LIST; return USP;} org {LIST; return ORG;} equ {LIST; return EQU;} sfr {LIST; return SFR;} db {LIST; return DB;} dw {LIST; return DW;} byte {LIST; return DB;} bit {LIST; return BITDEF;} reg {LIST; return REGDEF;} area {LIST; return AREA;} ds {LIST; return DS;} DSEG {LIST; yylval = AREA_DSEG; return AREA_NAME;} BSEG {LIST; yylval = AREA_BSEG; return AREA_NAME;} XSEG {LIST; yylval = AREA_XSEG; return AREA_NAME;} XISEG {LIST; yylval = AREA_XISEG; return AREA_NAME;} XINIT {LIST; yylval = AREA_XINIT; return AREA_NAME;} GSINIT {LIST; yylval = AREA_GSINIT; return AREA_NAME;} GSFINAL {LIST; yylval = AREA_GSFINAL; return AREA_NAME;} HOME {LIST; yylval = AREA_HOME; return AREA_NAME;} SSEG {LIST; yylval = AREA_SSEG; return AREA_NAME;} CSEG {LIST; yylval = AREA_CSEG; return AREA_NAME;} module {LIST; return MODULE;} globl {LIST; return GLOBL;} \(DATA\) {LIST; return AREA_DESC;} \(OVR,XDATA\) {LIST; return AREA_DESC;} \(BIT\) {LIST; return AREA_DESC;} \(XDATA\) {LIST; return AREA_DESC;} \(CODE\) {LIST; return AREA_DESC;} low {LIST; return LOW;} high {LIST; return HIGH;} >> {LIST; return RSHIFT;} \<\< {LIST; return LSHIFT;} R[0-9] {LIST; yylval = yytext[1] - '0' + WORD_REG; return REG;} R1[0-5] {LIST; yylval = yytext[2] - '0' + 10 + WORD_REG; return REG;} R[0-7]L {LIST; yylval = (yytext[1] - '0') * 2 + BYTE_REG; return REG;} R[0-7]H {LIST; yylval = (yytext[1] - '0') * 2 + 1 + BYTE_REG; return REG;} [a-z_][a-z0-9_]* { LIST; if (is_def(yytext)) { yylval = get_value(yytext); } else { if (p1) build_sym_list(yytext); yylval = 0; //if (p3) error("Symbol undefined"); } /* keep name in lex_sym_name since yytext */ /* could be overwritten if the parser does */ /* a lookahead operation */ strcpy(lex_sym_name, yytext); if (is_def(lex_sym_name)) { yylval = get_value(lex_sym_name); /* return correct type if special */ if (is_bit(lex_sym_name)) return BIT; if (is_reg(lex_sym_name)) return REG; } if (p3) { if (*operand[0]) { // first one in use strcpy (operand[1], yytext); } else { strcpy (operand[0], yytext); } } return WORD; } [0-9]+\$ { LIST; /* should print error if base_symbol_name */ /* is not defined */ sprintf(lex_sym_name, "%s:%s", base_symbol_name, yytext); if (is_def(lex_sym_name)) { yylval = get_value(lex_sym_name); } else { yylval = 0; if (p3) error("Symbol undefined"); } return WORD; } [01]+[bq] { LIST; yylval = binary2int(yytext); return NUMBER; } 0x[0-9a-f]+ { LIST; sscanf(yytext, "%*c%*c%x", &yylval); return NUMBER; } [0-9a-f]+[h] { LIST; sscanf(yytext, "%x%*[hH]", &yylval); return NUMBER; } \$[0-9a-f]+ { LIST; sscanf(yytext, "$%x", &yylval); return NUMBER; } -?[0-9]+ { LIST; sscanf(yytext, "%d", &yylval); return NUMBER; } \'.\' { LIST; yylval = (int)yytext[1]; return CHAR; } \'\\.\' { LIST; switch (yytext[1]) { case 'n': case 'N': yylval = 10; break; case 'r': case 'R': yylval = 13; break; case '0': yylval = 0; break; default: yylval = (int)yytext[1]; /* print a warning here */ } return CHAR; } \"[^"\n]*["\n] { LIST; return STRING; } ;[^\n]* {LIST; /* comments */} [ \t\r] {LIST; /* whitespace */} \n { strcpy(last_line_text, line_text); line_text[0] = '\0'; ++lineno; return EOL; } . {LIST; return yytext[0];} %%