Fix gas 68HC12 indexed addressing code generation
authorStephane Carrez <stcarrez@nerim.fr>
Thu, 11 Jan 2001 20:19:17 +0000 (20:19 +0000)
committerStephane Carrez <stcarrez@nerim.fr>
Thu, 11 Jan 2001 20:19:17 +0000 (20:19 +0000)
gas/ChangeLog
gas/config/tc-m68hc11.c
gas/testsuite/ChangeLog
gas/testsuite/gas/m68hc11/opers12.d
gas/testsuite/gas/m68hc11/opers12.s

index d9a5dd911641bc737ca380609a2c0d2e4c87cd1d..96df47a8ea679c53219cc6ec394126ddbde94747 100644 (file)
@@ -1,3 +1,13 @@
+2001-01-11  Stephane Carrez  <Stephane.Carrez@worldnet.fr>
+
+       * config/tc-m68hc11.c (md_estimate_size_before_relax): Fix
+       STATE_INDEXED_OFFSET when the symbol is undefined (16-bit offset).
+       (build_indexed_byte): Don't relax indexed byte, use 16-bit offset
+       and fix_new_exp() instead.
+       (md_convert_frag): For indexed post byte use the symbol value
+       rather than the displacement.
+       (md_relax_table): Fix indexed offset relax.
+
 2001-01-11  Stephane Carrez  <Stephane.Carrez@worldnet.fr>
 
        * config/tc-m68hc11.c (md_estimate_size_before_relax):Don't
index 4bbaaac9c71f0817fa86c632398773b1e3601c30..9dcaa14926047074be17ab8b570acf4327026311 100644 (file)
@@ -85,7 +85,7 @@ relax_typeS md_relax_table[] =
   /* Relax for indexed offset: 5-bits, 9-bits, 16-bits.  */
   {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
   {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
-  {0, 0, 1, 0},
+  {0, 0, 2, 0},
   {1, 1, 0, 0},
 
   /* Relax for dbeq/ibeq/tbeq r,<L>:
@@ -1754,15 +1754,26 @@ build_indexed_byte (op, format, move_insn)
              return 3;
            }
        }
-      f = frag_more (1);
-      number_to_chars_bigendian (f, byte, 1);
-#if 0
-      fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
-                  &op->exp, false, BFD_RELOC_16);
-#endif
-      frag_var (rs_machine_dependent, 2, 2,
-               ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
-               op->exp.X_add_symbol, val, f);
+      if (op->reg1 != REG_PC)
+        {
+          byte = (byte << 3) | 0xe2;
+          f = frag_more (1);
+          number_to_chars_bigendian (f, byte, 1);
+
+          f = frag_more (2);
+          fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
+                       &op->exp, false, BFD_RELOC_16);
+          number_to_chars_bigendian (f, 0, 2);
+        }
+      else
+        {
+          f = frag_more (1);
+          number_to_chars_bigendian (f, byte, 1);
+          frag_var (rs_machine_dependent, 2, 2,
+                    ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
+                    op->exp.X_add_symbol,
+                    op->exp.X_add_number, f);
+        }
       return 3;
     }
 
@@ -2425,6 +2436,7 @@ md_convert_frag (abfd, sec, fragP)
      fragS *fragP;
 {
   fixS *fixp;
+  long value;
   long disp;
   char *buffer_address = fragP->fr_literal;
 
@@ -2434,8 +2446,8 @@ md_convert_frag (abfd, sec, fragP)
   buffer_address += fragP->fr_fix;
 
   /* The displacement of the address, from current location.  */
-  disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
-  disp = (disp + fragP->fr_offset) - object_address;
+  value = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
+  disp = (value + fragP->fr_offset) - object_address;
   disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
 
   switch (fragP->fr_subtype)
@@ -2485,24 +2497,37 @@ md_convert_frag (abfd, sec, fragP)
       break;
 
     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
-      fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5;
-      fragP->fr_opcode[0] |= disp & 0x1f;
+      fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
+      if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0)
+        fragP->fr_opcode[0] |= disp & 0x1f;
+      else
+        fragP->fr_opcode[0] |= value & 0x1f;
       break;
 
     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
       fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
       fragP->fr_opcode[0] |= 0xE0;
-      fix_new (fragP, fragP->fr_fix + 1, 1,
+      fix_new (fragP, fragP->fr_fix, 1,
               fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
       fragP->fr_fix += 1;
       break;
 
     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
       fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
-      fragP->fr_opcode[0] |= 0xE2;
-      fix_new (fragP, fragP->fr_fix, 2,
-              fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
-      fragP->fr_fix += 1;
+      fragP->fr_opcode[0] |= 0xe2;
+      if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)
+        {
+          fixp = fix_new (fragP, fragP->fr_fix, 2,
+                          fragP->fr_symbol, fragP->fr_offset,
+                          1, BFD_RELOC_16_PCREL);
+          fixp->fx_pcrel_adjust = 2;
+        }
+      else
+        {
+          fix_new (fragP, fragP->fr_fix, 2,
+                   fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
+        }
+      fragP->fr_fix += 2;
       break;
 
     case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
@@ -2621,13 +2646,12 @@ md_estimate_size_before_relax (fragP, segment)
       else
        {
          /* Switch the indexed operation to 16-bit mode.  */
-         if ((fragP->fr_opcode[1] & 0x21) == 0x20)
-           fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02;
-
+          fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
+          fragP->fr_opcode[0] |= 0xe2;
          fragP->fr_fix++;
          fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
                   fragP->fr_offset, 0, BFD_RELOC_16);
-         fragP->fr_fix += 2;
+         fragP->fr_fix++;
          frag_wane (fragP);
        }
       break;
index ba4c11cefd3415d6d30c7e1c6450672b57fe4bbe..1c6cd51590a38e4fe7209a1049bb36b414955ff9 100644 (file)
@@ -1,3 +1,8 @@
+2001-01-11  Stephane Carrez  <Stephane.Carrez@worldnet.fr>
+
+       * gas/m68hc11/opers12.s: Add more tests for index post byte.
+       * gas/m68hc11/opers12.d: Likewise.
+
 2001-01-11  Stephane Carrez  <Stephane.Carrez@worldnet.fr>
 
        * gas/m68hc11/all.exp: Add new tests for dwarf2.
index 2fbd3ddf0706347c660204d8f5b56003903152d9..e6cdce0297d40d7bbd39759954e8baba6ef2c811 100644 (file)
@@ -25,7 +25,7 @@ Disassembly of section .text:
 0+031 <L1\+0x28> ldaa  \[257,Y\]
 0+035 <L1\+0x2c> ldab  \[32767,SP\]
 0+039 <L1\+0x30> ldd   \[32768,PC\]
-0+03d <L1\+0x34> ldd   0,PC
+0+03d <L1\+0x34> ldd   9,PC
 0+040 <L1\+0x37> std   A,X
 0+042 <L1\+0x39> ldx   B,X
 0+044 <L1\+0x3b> stx   D,Y
@@ -68,9 +68,9 @@ Disassembly of section .text:
 0+0b8 <L1\+0xaf> trap  #128
 0+0ba <L1\+0xb1> trap  #255
 0+0bc <L2> movw        1,X, 2,X
-0+0c0 <L2\+0x4> movw   0+0ffff <L2\+0xff43>, 0000ffff <L2\+0xff43>
-0+0c6 <L2\+0xa> movw   0+0ffff <L2\+0xff43>, 1,X
-0+0cb <L2\+0xf> movw   #0+0ffff <L2\+0xff43>, 1,X
+0+0c0 <L2\+0x4> movw   0+0ffff <bb\+0xd7ff>, 0000ffff <bb\+0xd7ff>
+0+0c6 <L2\+0xa> movw   0+0ffff <bb\+0xd7ff>, 1,X
+0+0cb <L2\+0xf> movw   #0+0ffff <bb\+0xd7ff>, 1,X
 0+0d0 <L2\+0x14> movw  0+03 <start\+0x3>, 0+08 <start\+0x8>
 0+0d6 <L2\+0x1a> movw  #0+03 <start\+0x3>, 0+03 <start\+0x3>
 0+0dc <L2\+0x20> movw  #0+03 <start\+0x3>, 1,X
@@ -78,4 +78,13 @@ Disassembly of section .text:
 0+0e6 <L2\+0x2a> movw  0+03 <start\+0x3>, 2,X
 0+0eb <L2\+0x2f> movw  0+04 <start\+0x4>, -2,X
 0+0f0 <L2\+0x34> rts
-
+0+0f1 <post_indexed_pb> leas   0,X
+0+0f5 <t2> leax        4,Y
+0+0f7 <t2\+0x2> leax   100,X
+0+0fb <t2\+0x6> leas   110,SP
+0+0ff <t2\+0xa> leay   10,X
+0+103 <t2\+0xe> leas   10240,Y
+0+107 <t2\+0x12> leas  255,PC
+0+10b <t2\+0x16> leas  0,PC
+0+10f <t2\+0x1a> leas  255,PC
+0+113 <t2\+0x1e> leas  0,PC
index b4a9c242823694e709b23bb8bbd18eae3cb354d2..94f8912211ab23e4b513e7f5f70d985cac393568 100644 (file)
@@ -6,11 +6,11 @@
        globl start
 
 start:
-       anda    [12,x]
+       anda    [12,x]          ; Indexed indirect
        ldaa    #10
        ldx     L1
 L1:    ldy     ,x
-       addd    1,y
+       addd    1,y             ; Offset from register
        subd    -1,y
        eora    15,y
        eora    -16,y
@@ -22,33 +22,36 @@ L1: ldy     ,x
        orab    -256,x
        anda    256,x
        andb    -257,x
-       anda    [12,x]
+       anda    [12,x]          ; Indexed indirect (16-bit offset)
        ldaa    [257,y]
        ldab    [32767,sp]
        ldd     [32768,pc]
        ldd     L1,pc
-       std     a,x
+       std     a,x             ; Two-reg index
        ldx     b,x
        stx     d,y
-       addd    1,+x
+       addd    1,+x            ; Pre-Auto inc
        addd    2,+x
        addd    8,+x
-       addd    1,sp+
+       addd    1,sp+           ; Post-Auto inc
        addd    2,sp+
        addd    8,sp+
-       subd    1,-y
+       subd    1,-y            ; Pre-Auto dec
        subd    2,-y
        subd    8,-y
-       addd    1,y-
+       addd    1,y-            ; Post-Auto dec
        addd    2,y-
        addd    8,y-
-       std     [d,x]
+       std     [d,x]           ; Indexed indirect with two reg index
        std     [d,y]
        std     [d,sp]
        std     [d,pc]
        beq     L1
        lbeq    start
        lbcc    L2
+;;
+;; Move insn with various operands
+;; 
        movb    start, 1,x
        movw    1,x, start
        movb    start, 1,+x
@@ -80,3 +83,27 @@ L2:
        movw 3,+2,x
        movw 4,-2,x
        rts
+;;
+;; Post-index byte with relocation
+;; 
+post_indexed_pb:
+t1:
+       leas    abort,x
+t2:
+       leax    t2-t1,y
+       leax    toto,x
+       leas    toto+titi,sp
+       leay    titi,x
+       leas    bb,y
+       leas    min5b,pc
+       leas    max5b,pc
+       leas    min9b,pc
+       leas    max9b,pc
+
+titi = 10
+toto = 100
+min5b= -15
+max5b= 15
+min9b= -255
+max9b= 255
+bb = 10240