gnupic@linuxhacker.org

gnupic@linuxhacker.org


Subject: Re: gpdasm problem
From: Gabor Kiss [Bitman]
Date: Mon, 9 Feb 2004 09:05:11 +0100 (CET)

> > Assemble then disassemble this file:
> > --------------------------
> >         processor p18f448
> >         org     0x800
> >         goto    label1
> >         bra     label1
> > label1
> >         end
> > -------------------------
> >
> > 'gpdasm-0.11.8 alpha' produces this:
> > -----------------------------
> > 000800:  ef03  goto     0x806
> > 000802:  f004
> > 000804:  d000  bra      0x6
> > -----------------------------
> >
> > I think "bra 0x806" would be more intuitive. ;-)

> --- gpdis.c.orig	2004-01-19 07:54:15.000000000 -0600
> +++ gpdis.c	2004-01-19 07:52:05.000000000 -0600
> @@ -124,10 +124,10 @@
>        DECODE_ARG1(opcode & 0x1fff);
>        break;
>      case INSN_CLASS_RBRA8:
> -      DECODE_ARG1((((opcode & 0xff) + (*org + 1)) * 2)  & 0xff);
> +      DECODE_ARG1((((opcode & 0xff) + (*org + 1)) * 2));
>        break;
>      case INSN_CLASS_RBRA11:
> -      DECODE_ARG1((((opcode & 0x7ff) + (*org + 1)) * 2) & 0x7ff);
> +      DECODE_ARG1((((opcode & 0x7ff) + (*org + 1)) * 2));
>        break;
>      case INSN_CLASS_LIT20:
>        {

Further problem: the 8/11 bit displacement is a 2's complement
value. The simple masking above turns it into unsigned.

This patch solves the problem.

Gabor


--- gpdis.c.orig	Fri Mar 14 07:44:51 2003
+++ gpdis.c	Sun Feb  8 14:14:46 2004
@@ -124,10 +124,13 @@
       DECODE_ARG1(opcode & 0x1fff);
       break;
     case INSN_CLASS_RBRA8:
-      DECODE_ARG1((((opcode & 0xff) + (*org + 1)) * 2) & 0xff);
+#define unwanted(bits) (sizeof(long)*8-(bits))
+#define displacement(opcode,bits) (((signed long)((opcode)<<unwanted(bits))) / \
+							(1<<unwanted(bits)))
+      DECODE_ARG1(((displacement(opcode,8) + (*org + 1)) * 2));
       break;
     case INSN_CLASS_RBRA11:
-      DECODE_ARG1((((opcode & 0x7ff) + (*org + 1)) * 2) & 0x7ff);
+      DECODE_ARG1(((displacement(opcode,11) + (*org + 1)) * 2));
       break;
     case INSN_CLASS_LIT20:
       {


gnupic@linuxhacker.org