This commit was manufactured by cvs2svn to create branch 'binutils-
[external/binutils.git] / opcodes / d30v-dis.c
index 9358b75..9cdad69 100644 (file)
@@ -1,5 +1,5 @@
 /* Disassemble D30V instructions.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
 
 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
@@ -305,38 +305,41 @@ print_insn ( info, memaddr, num, insn, is_long, show_ext )
                (info->stream, _("<unknown register %d>"), val & 0x3F);       
            }
        }
-      else if (insn->op->reloc_flag == RELOC_PCREL || 
-              (opind == 1 && (insn->form->form == SHORT_D2 || insn->form->form == LONG_D)))
+      /* repeati has a relocation, but its first argument is a plain
+        immediate.  OTOH instructions like djsri have a pc-relative
+        delay target, but a absolute jump target.  Therefore, a test
+        of insn->op->reloc_flag is not specific enough; we must test
+        if the actual operand we are handling now is pc-relative.  */
+      else if (oper->flags & OPERAND_PCREL)
        {
-         long max;
-         int neg=0;
-         max = (1 << (bits - 1));
-         if (val & max)
+         int neg = 0;
+         
+         /* IMM6S3 is unsigned.  */
+         if (oper->flags & OPERAND_SIGNED || bits == 32)
            {
-             if (bits == 32)
-               val = -val;
-             else
-               val = -val & ((1 << bits)-1);
-             neg = 1;
+             long max;
+             max = (1 << (bits - 1));
+             if (val & max)
+               {
+                 if (bits == 32)
+                   val = -val;
+                 else
+                   val = -val & ((1 << bits)-1);
+                 neg = 1;
+               }
+           }
+         if (neg)
+           {
+             (*info->fprintf_func) (info->stream, "-%x\t(",val);
+             (*info->print_address_func) ((memaddr - val) & PC_MASK, info);
+             (*info->fprintf_func) (info->stream, ")");
            }
-         if (opind == 1 && (insn->form->form == SHORT_D2 || insn->form->form == LONG_D))
+         else
            {
-             (*info->fprintf_func) (info->stream, "%x",val);
+             (*info->fprintf_func) (info->stream, "%x\t(",val);
+             (*info->print_address_func) ((memaddr + val) & PC_MASK, info);
+             (*info->fprintf_func) (info->stream, ")");
            }
-         else {
-           if (neg)
-             {
-               (*info->fprintf_func) (info->stream, "-%x\t(",val);
-               (*info->print_address_func) ((memaddr - val) & PC_MASK, info);
-               (*info->fprintf_func) (info->stream, ")");
-             }
-           else
-             {
-               (*info->fprintf_func) (info->stream, "%x\t(",val);
-               (*info->print_address_func) ((memaddr + val) & PC_MASK, info);
-               (*info->fprintf_func) (info->stream, ")");
-             }
-         }
        }
       else if (insn->op->reloc_flag == RELOC_ABS)
        {