Menu

#2830 z80instructionSize() failed to parse '.dw 0x1243'

closed-fixed
PATCH (2)
Z80
5
2018-10-25
2018-10-23
Tom Li
No

Version

SDCC : z80 3.8.1 #10616 (Linux)
published under GNU General Public License (GPL)

Attempting to compile the following sample code, by calling sdcc -mz80 -o dw.ihx dw.c triggers a bug. The compiler will be confused by the dw 0x1234 instruction, and report the following error message...

dw.c:13: info 218: z80instructionSize() failed to parse line node, assuming 999 bytes
'.dw    0x1234'

A quick code review finds z80instructionSize() in peep.c doesn't have any code to recongize the .dw pseudoinstruction, although it has included the code to handle .db:

int z80instructionSize(lineNode *pl)
{
    /* omitted code */

      if(ISINST(pl->line, ".db"))
    {
      int i, j;
      for(i = 1, j = 0; pl->line[j]; i += pl->line[j] == ',', j++);
      return(i);
    }

  /* If the instruction is unrecognized, we shouldn't try to optimize.  */
  /* For all we know it might be some .ds or similar possibly long line */
  /* Return a large value to discourage optimization.                   */
  if (pl->ic)
    werrorfl(pl->ic->filename, pl->ic->lineno, W_UNRECOGNIZED_ASM, __func__, 999, pl->line);
  else
    werrorfl("unknown", 0, W_UNRECOGNIZED_ASM, __func__, 999, pl->line);
  return(999);

Solution

Using the .db code as a template, it is easy to include additional handler for .dw, since these two instructions are nearly identical, as shown by the following code.

diff -upr sdcc-src-20181016-10616/src/z80/peep.c sdcc-src-20181016-10616.patch/src/z80/peep.c
--- sdcc-src-20181016-10616/src/z80/peep.c      2018-10-24 01:23:35.987648614 +0800
+++ sdcc-src-20181016-10616.patch/src/z80/peep.c        2018-10-24 01:24:37.519830586 +0800
@@ -1086,6 +1086,13 @@ int z80instructionSize(lineNode *pl)
       return(i);
     }

+  if(ISINST(pl->line, ".dw"))
+    {
+      int i, j;
+      for(i = 1, j = 0; pl->line[j]; i += pl->line[j] == ',', j++);
+      return(i * 2);
+    }
+
   /* If the instruction is unrecognized, we shouldn't try to optimize.  */
   /* For all we know it might be some .ds or similar possibly long line */
   /* Return a large value to discourage optimization.                   */

The patch needed for the change above has been submitted as an attachment.

Sample Code

#include <string.h>

void inline_dw_instruction(unsigned char *ptr)
{
    unsigned char buf[10];

    if (strlen(ptr) == NULL) {
        goto fail;
    }

__asm
    .dw 0x1234
__endasm;

fail:
    return;

}
1 Attachments

Discussion

  • Tom Li

    Tom Li - 2018-10-23

    It's the bloody SourceForge editor again, destroying every single bug report.

     
  • Tom Li

    Tom Li - 2018-10-23

    Version

    SDCC : z80 3.8.1 #10616 (Linux)
    published under GNU General Public License (GPL)

    Issue

    Attempting to compile the following sample code, by calling sdcc -mz80 -o dw.ihx dw.c triggers a bug. The compiler will be confused by the dw 0x1234 instruction, and report the following error message...

    dw.c:13: info 218: z80instructionSize() failed to parse line node, assuming 999 bytes
    '.dw 0x1234'

    Analysis

    A quick code review finds z80instructionSize() in peep.c doesn't have any code to recongize the .dw pseudoinstruction, although it has included the code to handle .db:

    int z80instructionSize(lineNode *pl)
    {
        /* omitted code */
    
          if(ISINST(pl->line, ".db"))
        {
          int i, j;
          for(i = 1, j = 0; pl->line[j]; i += pl->line[j] == ',', j++);
          return(i);
        }
    
      /* If the instruction is unrecognized, we shouldn't try to optimize.  */
      /* For all we know it might be some .ds or similar possibly long line */
      /* Return a large value to discourage optimization.                   */
      if (pl->ic)
        werrorfl(pl->ic->filename, pl->ic->lineno, W_UNRECOGNIZED_ASM, __func__, 999, pl->line);
      else
        werrorfl("unknown", 0, W_UNRECOGNIZED_ASM, __func__, 999, pl->line);
      return(999);
    

    Solution

    Using the .db code as a template, it is easy to include additional handler for .dw, since these two instructions are nearly identical, as shown by the following code.

    diff -upr sdcc-src-20181016-10616/src/z80/peep.c sdcc-src-20181016-10616.patch/src/z80/peep.c
    --- sdcc-src-20181016-10616/src/z80/peep.c 2018-10-24 01:23:35.987648614 +0800
    +++ sdcc-src-20181016-10616.patch/src/z80/peep.c 2018-10-24 01:24:37.519830586 +0800
    @@ -1086,6 +1086,13 @@ int z80instructionSize(lineNode *pl)
    return(i);
    }
    
        if(ISINST(pl->line, ".dw"))
        {
        int i, j;
        for(i = 1, j = 0; pl->line[j]; i += pl->line[j] == ',', j++);
        return(i * 2);
        }
        +
        / If the instruction is unrecognized, we shouldn't try to optimize. /
        / For all we know it might be some .ds or similar possibly long line /
        / Return a large value to discourage optimization. /
    

    The patch needed for the change above has been submitted as an attachment.

    Sample Code

    #include <string.h>
    
    void inline_dw_instruction(unsigned char *ptr)
    {
        unsigned char buf[10];
    
        if (strlen(ptr) == NULL) {
            goto fail;
        }
    
    __asm
        .dw 0x1234
    __endasm;
    
    fail:
        return;
    }
    
     

    Last edit: Maarten Brock 2018-10-24
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
     
  • Philipp Klaus Krause

    Fixed in [r10629]. Thanks for the patch.

    Philipp

     
  • Maarten Brock

    Maarten Brock - 2018-10-24
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -34,7 +34,7 @@
       else
         werrorfl("unknown", 0, W_UNRECOGNIZED_ASM, __func__, 999, pl->line);
       return(999);
    -  ~~~
    +~~~
    
     ### Solution
    
     
  • Maarten Brock

    Maarten Brock - 2018-10-24

    If you do not swear, we won't have to moderate.
    Further, if you place spaces before the tildes they will not be recognized.
    You can press the 'eye' icon to preview your post before you commit it to catch problems like this.

     
  • Tom Li

    Tom Li - 2018-10-25

    Won't do again, thanks for the editor tip.

     

Log in to post a comment.