* as/z80/z80mch.c: fixed bug #1704376: missing as-z80 errors
[fw/sdcc] / as / xa51 / xa_rasm.y
old mode 100755 (executable)
new mode 100644 (file)
index 03ade71..be78e10
@@ -1,19 +1,20 @@
 %{
-/* This file is part of Paul's XA51 Assembler, Copyright 1997,2002 Paul Stoffregen
- *
- * Paul's XA51 Assembler 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; version 2.
- *
- * Paul's XA51 Assembler 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 Foobar; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
+/* xa_rasm.y - 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 <http://www.gnu.org/licenses/>. */
 
 /* Author contact: paul@pjrc.com */
 
@@ -33,7 +34,7 @@ int stack_addr_opcode, stack_reg_opcode, branch_opcode;
 int rlist_reg_bank, rlist_bitmask, rlist_size;
 int db_count, dw_count, i;
 char symbol_name[MAX_SYMBOL], base_symbol_name[MAX_SYMBOL]={'\0'};
-char expr_var[2][MAX_SYMBOL]={{'\0'},{'\0'}};
+char operand[2][MAX_SYMBOL]={{'\0'},{'\0'}};
 
 extern char lex_sym_name[];
 extern int yylex();
@@ -43,101 +44,91 @@ extern char * disasm(int byte, int memory_location);
 void error(char *s);
 
 
-void RELOC_FF(unsigned pc, unsigned short offset, short rl) {
+void RELOC_FF(unsigned where, unsigned pc, short rl) {
+  // pc = PC of the next instruction
   struct symbol *sym;
-  if ((sym=findSymbol(yytext))) {
-    if (sym->mode=='X') {
-      sprintf (rel_line[rl], "R %d REL_FF 0x%04x %s", offset, pc,
-              sym->name);
+  if ((sym=findSymbol(operand[0]))) {
+    if (sym->mode=='X' || sym->area!=current_area) {
+      sprintf (rel_line[rl], "R %04x REL_FF %s %04x", 
+              where, sym->name, pc);
     }
   }
 }
  
-void RELOC_FFFF(unsigned pc, unsigned short offset, short rl) {
+void RELOC_FFFF(unsigned where, unsigned pc, short rl) {
   struct symbol *sym;
-  if ((sym=findSymbol(yytext))) {
-    if (sym->mode=='X') {
-      sprintf (rel_line[rl], "R %d REL_FFFF 0x%04x %s", offset, pc,
-              sym->name);
+  if ((sym=findSymbol(operand[0]))) {
+    if (sym->mode=='X' || sym->area!=current_area) {
+      sprintf (rel_line[rl], "R %04x REL_FFFF %s %04x", 
+              where, sym->name, pc);
     }
   }
 }
  
-void RELOC_ABS_0F(unsigned short offset, int expr) {
+void RELOC_ABS_0F(unsigned where, int seq) {
   struct symbol *sym;
-  if ((sym=findSymbol(expr_var[expr]))) {
-    if (sym->mode=='X') {
-      sprintf (rel_line[expr], "R %d ABS_0F %s", offset, sym->name);
-    }
+  if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
+    sprintf (rel_line[seq], "R %04x ABS_0F %s 0", where, sym->name);
   }
 }
 
-void RELOC_ABS_FF(unsigned short offset, int expr) {
+void RELOC_BIT_03FF(unsigned where, int seq) {
   struct symbol *sym;
-  if ((sym=findSymbol(expr_var[expr]))) {
-    if (sym->mode=='X') {
-      sprintf (rel_line[expr], "R %d ABS_FF %s", offset, sym->name);
-    }
+  if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
+    sprintf (rel_line[seq], "R %04x BIT_03FF %s 0", where, sym->name);
   }
 }
 
-void RELOC_ABS_03FF(unsigned short offset, int expr) {
+void RELOC_DIR_07FF(unsigned where, int seq) {
   struct symbol *sym;
-  if (expr_var[0]) {
-    if ((sym=findSymbol(expr_var[expr]))) {
-      if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_03FF %s", offset, sym->name);
-      }
-    }
+  if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
+    sprintf (rel_line[seq], "R %04x DIR_07FF %s 0", where, sym->name);
   }
 }
 
-void RELOC_ABS_07ff(unsigned short offset, int expr) {
+void RELOC_DIR_70FF(unsigned where, int seq) {
   struct symbol *sym;
-  if (expr_var[0]) {
-    if ((sym=findSymbol(expr_var[expr]))) {
-      if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_07ff %s", offset, sym->name);
-      }
-    }
+  if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
+    sprintf (rel_line[seq], "R %04x DIR_70FF %s 0", where, sym->name);
   }
 }
 
-void RELOC_ABS_F0FF(unsigned short offset, int expr) {
+void RELOC_ABS_FF(unsigned where, int seq) {
   struct symbol *sym;
-  if (expr_var[0]) {
-    if ((sym=findSymbol(expr_var[expr]))) {
-      if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_F0FF %s", offset, sym->name);
-      }
-    }
+  if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
+    sprintf (rel_line[seq], "R %04x DIR_FF %s 0", where, sym->name);
   }
 }
-void RELOC_ABS_FFFF(unsigned short offset, int expr) {
+
+void RELOC_ABS_FFFF(unsigned where, int seq) {
   struct symbol *sym;
-  if (expr_var[0]) {
-    if ((sym=findSymbol(expr_var[expr]))) {
-      if (sym->mode=='X') {
-#if 1
-       sprintf (rel_line[expr], "R %d ABS_FFFF %s", offset, sym->name);
-#else
-       sprintf (rel_line[expr], "R 0 0 00 %02x 02 %02x %02x", current_area, 
-                (sym->lk_index>>8)&0xff, sym->lk_index&&0xff);
-#endif
-      }
+  if ((sym=findSymbol(operand[seq]))) {
+    switch (sym->mode) {
+    case 'A':
+      // sfr or sbit, already in instruction
+    case '=':
+      // equat, already in instruction
+      break;
+    case 'X':
+      // external reference
+      sprintf (rel_line[seq], "R %04x ABS_FFFF %s %04x", where, sym->name,
+              sym->value);
+      break;
+    case 'R':
+      // absolute in current segment
+      sprintf (rel_line[seq], "R %04x ABS_PC PC %04x", where, sym->value);
+      break;
+    default:
+      fprintf (stderr, "unknown ABS_FFFF\n");
+      exit (1);
     }
   }
 }
  
-void RELOC_ABS_0F00FF(unsigned short offset, int expr) {
+void RELOC_DIR_0700FF(unsigned where, int seq) {
   struct symbol *sym;
-  if (expr_var[0]) {
-    if ((sym=findSymbol(expr_var[expr]))) {
-      if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_0F00FF %s", offset, sym->name);
-      }
-    }
+  if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
+    sprintf (rel_line[seq], "R %04x ABS_0700FF %s 0", where, sym->name);
   }
 }
  
@@ -163,7 +154,6 @@ void RELOC_ABS_0F00FF(unsigned short offset, int expr) {
 %nonassoc UNARY
 
 %%
-
 all:           line
              | line all;
 
@@ -178,7 +168,9 @@ line:          linesymbol ':' linenosym {
                        MEM_POS += $3;
                }
              | linenosym {
-                       MEM_POS += $1;
+                        if (!is_abs(symbol_name)) {
+                         MEM_POS += $1;
+                       }
                }
 
 linenosym:     directive EOL {
@@ -209,9 +201,9 @@ directive:     '.' ORG expr {
                        if (p1 || p2) assign_value(symbol_name, $5, '?');
                        $$ = 0;
                }
-             | normal_or_bit_symbol '=' expr {
+             | symbol '=' expr {
                        if (p1) build_sym_list(symbol_name);
-                       if (p1 || p2) assign_value(symbol_name, $3, '?');
+                       if (p1 || p2) assign_value(symbol_name, $3, '=');
                }
             | symbol SFR expr {
                        if (p1) build_sym_list(symbol_name);
@@ -279,12 +271,13 @@ directive:     '.' ORG expr {
                        $$ = 0;
                }
             | '.' GLOBL WORD {
+                       mk_global(lex_sym_name);
                        /* ignore global symbol declaration */
                        $$ = 0;
                }
             | '.' GLOBL bit {
                        /* ignore bit symbol declaration */
-                       $$ = 0;
+                       $$ = 0;
                }
             | '.' DS expr {
                        /* todo: if CSEG, emit some filler bytes */
@@ -411,15 +404,7 @@ expr:      value   {$$ = $1;}
 
 value:   NUMBER {$$ = $1;}
        | CHAR {$$ = $1;}
-       | WORD {
-         $$ = $1; 
-         if (expr_var[0][0]=='\0') {
-           strcpy(expr_var[0], yytext);
-         } else {
-           strcpy(expr_var[1], yytext);
-         }
-       }
-
+        | WORD { $$ = $1;}
 
 rlist: REG {
                rlist_bitmask = 1<<(reg($1) % 8);
@@ -465,14 +450,14 @@ instruction:
                op[0] = arith_opcode * 16 + size * 8 + 4;
                op[1] = reg($2) * 16 + reg_indirect($5);
                op[2] = ($7 >= 0) ? $7 : 256 + $7;
-               RELOC_ABS_FF(2,0);
+               RELOC_ABS_FF(MEM_POS+2,0);
        } else {
                $$ = 4;
                op[0] = arith_opcode * 16 + size * 8 + 5;
                op[1] = reg($2) * 16 + reg_indirect($5);
                op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
                op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
-               RELOC_ABS_FFFF(2,0);
+               RELOC_ABS_FFFF(MEM_POS+2,0);
        }
   }
 | arith_inst '[' REG '+' expr ']' ',' REG {
@@ -482,14 +467,14 @@ instruction:
                op[0] = arith_opcode * 16 + size * 8 + 4;
                op[1] = reg($8) * 16 + 8 + reg_indirect($3);
                op[2] = ($5 >= 0) ? $5 : 256 + $5;
-               RELOC_ABS_FF(2,0);
+               RELOC_ABS_FF(MEM_POS+2,0);
        } else {
                $$ = 4;
                op[0] = arith_opcode * 16 + size * 8 + 5;
                op[1] = reg($8) * 16 + 8 + reg_indirect($3);
                op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
                op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
-               RELOC_ABS_FFFF(2,0);
+               RELOC_ABS_FFFF(MEM_POS+2,0);
        }
   }
 | arith_inst REG ',' '[' REG '+' ']' {
@@ -510,7 +495,7 @@ instruction:
        op[0] = arith_opcode * 16 + size * 8 + 6;
        op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_DIR_07FF(MEM_POS+1, 0);
   }
 | arith_inst REG ',' WORD {
        $$ = 3;
@@ -518,7 +503,7 @@ instruction:
        op[0] = arith_opcode * 16 + size * 8 + 6;
        op[1] = reg($2) * 16 + msb(direct_addr($4));
        op[2] = lsb(direct_addr($4));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_DIR_07FF(MEM_POS+1, 0);
   }
 | arith_inst REG ',' '#' expr {
        size = find_size1(inst_size, $2);
@@ -527,14 +512,14 @@ instruction:
                op[0] = 0x91;
                op[1] = reg($2) * 16 + arith_opcode;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0x99;
                op[1] = reg($2) * 16 + arith_opcode;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF (2, 0);
+               RELOC_ABS_FFFF (MEM_POS+2, 0);
        }
   }
 | arith_inst '[' REG ']' ',' '#' expr {
@@ -544,14 +529,14 @@ instruction:
                op[0] = 0x92;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = imm_data8($7);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0x9A;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = msb(imm_data16($7));
                op[3] = lsb(imm_data16($7));
-               RELOC_ABS_FFFF (2, 0);
+               RELOC_ABS_FFFF (MEM_POS+2, 0);
        }
   }
 | arith_inst '[' REG '+' ']' ',' '#' expr {
@@ -561,14 +546,14 @@ instruction:
                op[0] = 0x93;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = imm_data8($8);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0x9B;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = msb(imm_data16($8));
                op[3] = lsb(imm_data16($8));
-               RELOC_ABS_FFFF (2, 0);
+               RELOC_ABS_FFFF (MEM_POS+2, 0);
        }
   }
 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
@@ -580,8 +565,8 @@ instruction:
                        op[1] = reg_indirect($3) * 16 + arith_opcode;
                        op[2] = ($5 >= 0) ? $5 : 256 + $5;
                        op[3] = imm_data8($9);
-                       RELOC_ABS_FF(2, 0);
-                       RELOC_ABS_FF(3, 1);
+                       RELOC_ABS_FF(MEM_POS+2, 0);
+                       RELOC_ABS_FF(MEM_POS+3, 1);
                } else {
                        $$ = 5;
                        op[0] = 0x9C;
@@ -589,8 +574,8 @@ instruction:
                        op[2] = ($5 >= 0) ? $5 : 256 + $5;
                        op[3] = msb(imm_data16($9));
                        op[4] = lsb(imm_data16($9));
-                       RELOC_ABS_FF(2, 0);
-                       RELOC_ABS_FFFF(3, 1);
+                       RELOC_ABS_FF(MEM_POS+2, 0);
+                       RELOC_ABS_FFFF(MEM_POS+3, 1);
                }
        } else {
                if (size == SIZE8) {
@@ -600,8 +585,8 @@ instruction:
                        op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
                        op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
                        op[4] = imm_data8($9);
-                       RELOC_ABS_FFFF(2,0);
-                       RELOC_ABS_FF(4,1);
+                       RELOC_ABS_FFFF(MEM_POS+2,0);
+                       RELOC_ABS_FF(MEM_POS+4,1);
                } else {
                        $$ = 6;
                        op[0] = 0x9D;
@@ -610,8 +595,8 @@ instruction:
                        op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
                        op[4] = msb(imm_data16($9));
                        op[5] = lsb(imm_data16($9));
-                       RELOC_ABS_FFFF(2, 0);
-                       RELOC_ABS_FFFF(4, 1);
+                       RELOC_ABS_FFFF(MEM_POS+2, 0);
+                       RELOC_ABS_FFFF(MEM_POS+4, 1);
                }
        }
   }
@@ -623,8 +608,8 @@ instruction:
                op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
                op[2] = lsb(direct_addr($2));
                op[3] = imm_data8($5);
-               RELOC_ABS_F0FF(1,0);
-               RELOC_ABS_FF(3,1);
+               RELOC_DIR_70FF(MEM_POS+1,0);
+               RELOC_ABS_FF(MEM_POS+3,1);
        } else {
                $$ = 5;
                op[0] = 0x9E;
@@ -632,8 +617,8 @@ instruction:
                op[2] = lsb(direct_addr($2));
                op[3] = msb(imm_data16($5));
                op[4] = lsb(imm_data16($5));
-               RELOC_ABS_F0FF(1,0);
-               RELOC_ABS_FFFF (3,1);
+               RELOC_DIR_70FF(MEM_POS+1,0);
+               RELOC_ABS_FFFF (MEM_POS+3,1);
        }
   }
 
@@ -658,7 +643,7 @@ instruction:
        op[0] = 0xA0 + size * 8;
        op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_DIR_07FF(MEM_POS+1, 0);
   }
 | arith_inst '[' REG ']' ',' WORD {
        /* this addr mode is only valid for MOV */
@@ -668,7 +653,7 @@ instruction:
        op[0] = 0xA0 + size * 8;
        op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
        op[2] = lsb(direct_addr($6));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_DIR_07FF(MEM_POS+1, 0);
   }
 | arith_inst WORD ',' WORD {
        /* this addr mode is only valid for MOV */
@@ -679,8 +664,8 @@ instruction:
        op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
        op[2] = lsb(direct_addr($2));
        op[3] = lsb(direct_addr($4));
-       RELOC_ABS_F0FF(1, 0);
-       RELOC_ABS_0F00FF(1, 1);
+       RELOC_DIR_70FF(MEM_POS+1, 0);
+       RELOC_DIR_0700FF(MEM_POS+1, 1);
   }
 | arith_inst REG ',' USP {
        /* this addr mode is only valid for MOV */
@@ -703,7 +688,7 @@ instruction:
        op[0] = 0x08;
        op[1] = 0x20 + msb(bit_addr($4));
        op[2] = lsb(bit_addr($4));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 | arith_inst bit ',' C {
        /* this addr mode is only valid for MOV */
@@ -712,7 +697,7 @@ instruction:
        op[0] = 0x08;
        op[1] = 0x30 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 
 | MOVC REG ',' '[' REG '+' ']' {
@@ -761,28 +746,28 @@ instruction:
        op[0] = 0xA0 + size * 8;
        op[1] = reg($2) * 16 + msb(direct_addr($4));
         op[2] = lsb(direct_addr($4));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_DIR_07FF(MEM_POS+1, 0);
   }
 | short_data_inst REG ',' '#' expr {
        $$ = 2;
        size = find_size1(inst_size, $2);
        op[0] = short_opcode + size * 8 + 1;
        op[1] = reg($2) * 16 + imm_data4_signed($5);
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | short_data_inst '[' REG ']' ',' '#' expr {
        $$ = 2;
        size = find_size0(inst_size);
        op[0] = short_opcode + size * 8 + 2;
        op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | short_data_inst '[' REG '+' ']' ',' '#' expr {
        $$ = 2;
        size = find_size0(inst_size);
        op[0] = short_opcode + size * 8 + 3;
        op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
        size = find_size0(inst_size);
@@ -791,16 +776,16 @@ instruction:
                op[0] = short_opcode + size * 8 + 4;
                op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
                op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
-               RELOC_ABS_0F(1, 1);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_0F(MEM_POS+1, 1);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = short_opcode + size * 8 + 5;
                op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
                op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
                op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
-               RELOC_ABS_0F(1, 1);
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_0F(MEM_POS+1, 1);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
        }
   }
 | short_data_inst expr ',' '#' expr {
@@ -809,21 +794,21 @@ instruction:
        op[0] = short_opcode + size * 8 + 6;
        op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | ANL C ',' bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x40 + msb(bit_addr($4));
        op[2] = lsb(bit_addr($4));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 | ANL C ',' '/' bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x50 + msb(bit_addr($5));
        op[2] = lsb(bit_addr($5));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 
 | ORL C ',' bit {
@@ -831,28 +816,28 @@ instruction:
        op[0] = 0x08;
        op[1] = 0x60 + msb(bit_addr($4));
        op[2] = lsb(bit_addr($4));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 | ORL C ',' '/' bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x70 + msb(bit_addr($5));
        op[2] = lsb(bit_addr($5));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 | CLR bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 | SETB bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x10 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
   }
 | logical_shift_inst REG ',' REG {
        size = find_size1(inst_size, $2);
@@ -937,13 +922,13 @@ instruction:
                op[0] = 0x40;
                op[1] = reg($2) * 16 + reg_indirect($4);
                op[2] = ($6 >= 0) ? $6 : 256 + $6;
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                op[0] = 0x48;
                op[1] = reg($2) * 16 + reg_indirect($4);
                op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
                op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
        }
   }
 | stack_inst WORD {
@@ -952,7 +937,7 @@ instruction:
        op[0] = msb(stack_addr_opcode) + size * 8;
        op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_DIR_07FF(MEM_POS+1, 0);
   }
 | stack_inst rlist {
        $$ = 2;
@@ -987,7 +972,7 @@ instruction:
        op[1] = reg($2) + 8;
        op[2] = msb(imm_data16($5));
        op[3] = lsb(imm_data16($5));
-       RELOC_ABS_FFFF(2, 0);
+       RELOC_ABS_FFFF(MEM_POS+2, 0);
   }
 | MULU REG ',' '#' expr {
        size = find_size2(inst_size, $2, $4);
@@ -996,14 +981,14 @@ instruction:
                op[0] = 0xE8;
                op[1] = reg($2) * 16;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0xE9;
                op[1] = reg($2) * 16;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
        }
   }
 | DIV REG ',' REG {
@@ -1011,7 +996,7 @@ instruction:
        size = find_size2(inst_size, $2, $4);
        switch (size) {
        case SIZE8:
-               error("Singed DIV can't be 8 bit size"); break;
+               error("Signed DIV can't be 8 bit size"); break;
        case SIZE16:
                op[0] = 0xE7;
                op[1] = reg($2) * 16 + reg($4);
@@ -1050,7 +1035,7 @@ instruction:
                op[0] = 0xE8;
                op[1] = reg($2) * 16 + 11;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
                break;
        case SIZE32:
                $$ = 4;
@@ -1058,7 +1043,7 @@ instruction:
                op[1] = (reg($2) / 2) * 32 + 9;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
                break;
        }
   }
@@ -1070,14 +1055,14 @@ instruction:
                op[0] = 0xE8;
                op[1] = reg($2) * 16 + 1;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
                break;
        case SIZE16:
                $$ = 3;
                op[0] = 0xE8;
                op[1] = reg($2) * 16 + 3;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
                break;
        case SIZE32:
                $$ = 4;
@@ -1085,7 +1070,7 @@ instruction:
                op[1] = (reg($2) / 2) * 32 + 1;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
                break;
        }
   }
@@ -1129,7 +1114,7 @@ instruction:
        op[0] = 0xD5;
        op[1] = msb(rel16(MEM_POS + $$, $2));
        op[2] = lsb(rel16(MEM_POS + $$, $2));
-       RELOC_FFFF(MEM_POS+$$,1,0);
+       RELOC_FFFF(MEM_POS+1,MEM_POS+$$,0);
   }
 
 | CALL jmpaddr {
@@ -1137,13 +1122,13 @@ instruction:
         op[0] = 0xC5;
         op[1] = msb(rel16(MEM_POS + $$, $2));
         op[2] = lsb(rel16(MEM_POS + $$, $2));
-       RELOC_FFFF(MEM_POS+$$,1,0);
+       RELOC_FFFF(MEM_POS+1, MEM_POS+$$, 0);
   }
 | branch_inst jmpaddr {
        $$ = 2;
        op[0] = branch_opcode;
        op[1] = rel8(MEM_POS + $$, $2);
-       RELOC_FF(MEM_POS + $$, 1,0);
+       RELOC_FF(MEM_POS+1,MEM_POS + $$, 0);
   }
 | CJNE REG ',' expr ',' jmpaddr {
         $$ = 4;
@@ -1152,8 +1137,8 @@ instruction:
        op[1] = reg($2) * 16 + msb(direct_addr($4));
        op[2] = lsb(direct_addr($4));
        op[3] = rel8(MEM_POS + $$, $6);
-       RELOC_ABS_07ff(1, 0);
-       RELOC_FF(MEM_POS + $$, 3,1);
+       RELOC_DIR_07FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }
 | CJNE REG ',' '#' expr ',' jmpaddr {
        size  = find_size1(inst_size, $2);
@@ -1163,7 +1148,7 @@ instruction:
                op[1] = reg($2) * 16;
                op[2] = rel8(MEM_POS + $$, $7);
                op[3] = imm_data8($5);
-               RELOC_ABS_FF(3, 0);
+               RELOC_ABS_FF(MEM_POS+3, 0);
        } else {
                $$ = 5;
                op[0] = 0xEB;
@@ -1171,7 +1156,7 @@ instruction:
                op[2] = rel8(MEM_POS + $$, $7);
                op[3] = msb(imm_data16($5));
                op[4] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(3, 0);
+               RELOC_ABS_FFFF(MEM_POS+3, 0);
        }
   }
 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
@@ -1182,7 +1167,7 @@ instruction:
                op[1] = reg_indirect($3) * 16 + 8;
                op[2] = rel8(MEM_POS + $$, $9);
                op[3] = imm_data8($7);
-               RELOC_ABS_FF(3, 0);
+               RELOC_ABS_FF(MEM_POS+3, 0);
        } else {
                $$ = 5;
                op[0] = 0xEB;
@@ -1190,7 +1175,7 @@ instruction:
                op[2] = rel8(MEM_POS + $$, $9);
                op[3] = msb(imm_data16($7));
                op[4] = lsb(imm_data16($7));
-               RELOC_ABS_FFFF(3, 0);
+               RELOC_ABS_FFFF(MEM_POS+3, 0);
        }
   }
 | DJNZ REG ',' jmpaddr {
@@ -1199,7 +1184,7 @@ instruction:
        op[0] = 0x87 + size * 8;
        op[1] = reg($2) * 16 + 8;
        op[2] = rel8(MEM_POS + $$, $4);
-       RELOC_FF(MEM_POS+$$, 2, 0);
+       RELOC_FF(MEM_POS+2, MEM_POS+$$, 0);
   }
 
 
@@ -1210,8 +1195,8 @@ instruction:
        op[1] = msb(direct_addr($2)) + 8;
        op[2] = lsb(direct_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_07ff(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1)
+       RELOC_DIR_07FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1)
   }
 
 | JB bit ',' jmpaddr {
@@ -1220,8 +1205,8 @@ instruction:
        op[1] = 0x80 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_03FF(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }
 
 | JBC bit ',' jmpaddr {
@@ -1230,8 +1215,8 @@ instruction:
        op[1] = 0xC0 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_03FF(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }
 
 | JNB bit ',' jmpaddr {
@@ -1240,8 +1225,8 @@ instruction:
        op[1] = 0xA0 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_03FF(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1);
+       RELOC_BIT_03FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }