Adds assembly and dis-assembly support for the HPPA wide
authorAlan Modra <amodra@gmail.com>
Sun, 14 Jan 2001 05:14:45 +0000 (05:14 +0000)
committerAlan Modra <amodra@gmail.com>
Sun, 14 Jan 2001 05:14:45 +0000 (05:14 +0000)
mode, 16 bit forms of ldi, ldo, ldw and stw instructions.

gas/ChangeLog
gas/config/tc-hppa.c
include/opcode/ChangeLog
include/opcode/hppa.h
opcodes/ChangeLog
opcodes/hppa-dis.c

index 607300890406a64a0af87935c8282428303772a7..11bc523c66cbceaf4f9d34fa14207ce28eb41e34 100644 (file)
@@ -1,3 +1,9 @@
+2001-01-14  Alan Modra  <alan@linuxcare.com.au>
+
+       * config/tc-hppa.c (pa_ip): Store `a' flag in bit zero of operand
+       and don't bother storing `m' for "ce" completer.  Tidy handling of
+       'J' and 'K' operands to suit.  Handle '<' and '>' operands.
+
 Sun Jan 14 00:36:42 MET 2001  Jan Hubicka  <jh@suse.cz>
 
        * tc-i386.h (TARGET_MACH): New macro.
index 159aa67be06d4f7fa9f1bd213642080ddc823c97..69c1e044a2d7fd62a59ed188c0595b155e55ee1c 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-hppa.c -- Assemble for the PA
-   Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000
+   Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -1855,10 +1855,10 @@ pa_ip (str)
                      }
                    else if (*args == 'e')
                      {
-                       /* Gross!  Hide these values in the immediate field
-                          of the instruction, then pull them out later.  */
-                       opcode |= m << 8;
-                       opcode |= a << 9;
+                       /* Stash the ma/mb flag temporarily in the
+                          instruction.  We will use (and remove it)
+                          later when handling 'J', 'K', '<' & '>'.  */
+                       opcode |= a;
                        continue;
                      }
                  }
@@ -2922,26 +2922,22 @@ pa_ip (str)
              s = expr_end;
              if (the_insn.exp.X_op == O_constant)
                {
-                 int a, m;
+                 int mb;
 
-                 /* XXX the completer stored away tibits of information
+                 /* XXX the completer stored away tidbits of information
                     for us to extract.  We need a cleaner way to do this.
                     Now that we have lots of letters again, it would be
                     good to rethink this.  */
-                 m = (opcode & (1 << 8)) != 0;
-                 a = (opcode & (1 << 9)) != 0;
-                 opcode &= ~ (3 << 8);
+                 mb = opcode & 1;
+                 opcode -= mb;
                  num = evaluate_absolute (&the_insn);
-                 if ((a == 1 && num >= 0) || (a == 0 && num < 0))
+                 if (mb != (num < 0))
                    break;
                  CHECK_FIELD (num, 8191, -8192, 0);
                  num = low_sign_unext (num, 14);
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
                }
-             else
-               {
-                 break;
-               }
+             break;
 
            /* Handle a 14 bit immediate at 31.  */
            case 'K':
@@ -2950,31 +2946,62 @@ pa_ip (str)
              s = expr_end;
              if (the_insn.exp.X_op == O_constant)
                {
-                 int a, m;
+                 int mb;
 
-                 /* XXX the completer stored away tibits of information
-                    for us to extract.  We need a cleaner way to do this.
-                    Now that we have lots of letters again, it would be
-                    good to rethink this.  */
-                 m = (opcode & (1 << 8)) != 0;
-                 a = (opcode & (1 << 9)) != 0;
-                 opcode &= ~ (3 << 8);
+                 mb = opcode & 1;
+                 opcode -= mb;
                  num = evaluate_absolute (&the_insn);
-                 if ((a == 1 && num < 0) || (a == 0 && num > 0))
+                 if (mb == (num < 0))
                    break;
                  if (num % 4)
                    break;
                  CHECK_FIELD (num, 8191, -8192, 0);
-                 if (num < 0)
-                   opcode |= 1;
-                  num &= 0x1fff;
-                  num >>= 2;
-                  INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
+                 num = low_sign_unext (num, 14);
+                 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
                }
-             else
+             break;
+
+           /* Handle a 16 bit immediate at 31.  */
+           case '<':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
                {
-                 break;
+                 int mb;
+
+                 mb = opcode & 1;
+                 opcode -= mb;
+                 num = evaluate_absolute (&the_insn);
+                 if (mb != (num < 0))
+                   break;
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 num = re_assemble_16 (num);
+                 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+               }
+             break;
+
+           /* Handle a 16 bit immediate at 31.  */
+           case '>':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 int mb;
+
+                 mb = opcode & 1;
+                 opcode -= mb;
+                 num = evaluate_absolute (&the_insn);
+                 if (mb == (num < 0))
+                   break;
+                 if (num % 4)
+                   break;
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 num = re_assemble_16 (num);
+                 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
                }
+             break;
 
            /* Handle 14 bit immediate, shifted left three times.  */
            case '#':
index 4632f752085f3062a9ce1caf43b789b8acc77da2..9878734d73564bc5ba13ffd53b0b74ea1f89da17 100644 (file)
@@ -1,3 +1,10 @@
+2001-01-14  Alan Modra  <alan@linuxcare.com.au>
+
+       * hppa.h: Describe new '<' and '>' operand types, and tidy
+       existing comments.
+       (pa_opcodes): Add entries for missing wide mode ldi,ldo,ldw,stw.
+       Remove duplicate "ldw j(s,b),x".  Sort some entries.
+
 Sat Jan 13 09:56:32 MET 2001  Jan Hubicka  <jh@suse.cz>
 
        * i386.h (i386_optab): Fix pusha and ret templates.
index f04403d2eed8f607239b7f9c23f05ddaf4252d9a..2ac11e4277108ac6085ab5023553fa41ca3996f9 100644 (file)
@@ -1,5 +1,5 @@
 /* Table of opcodes for the PA-RISC.
-   Copyright (C) 1990, 1991, 1993, 1995, 1999, 2000
+   Copyright (C) 1990, 1991, 1993, 1995, 1999, 2000, 2001
    Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
@@ -71,15 +71,15 @@ struct pa_opcode
 
    In the args field, the following characters are unused:
 
-       '  "         -  /   34 6789:;< > @'
-       '  C         M             [\]  '
-       '    e g                     } '
+       '  "         -  /   34 6789:;    '
+       '@  C         M             [\]  '
+       '`    e g                     }  '
 
    Here are all the characters:
 
-       ' !"#$%&'()*+-,./0123456789:;<=>?@'
-       'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_'
-       'abcdefghijklmnopqrstuvwxyz{|}~'
+       ' !"#$%&'()*+-,./0123456789:;<=>?'
+       '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_'
+       '`abcdefghijklmnopqrstuvwxyz{|}~ '
 
 Kinds of operands:
    x    integer register field at 15.
@@ -147,7 +147,7 @@ Also these:
        the bb instruction. It's the same as r above, except the
         value is in a different location)
    B   5 bit immediate value at 10 (a bit position specified in
-       the bb instruction. Similar to Q, but 64bit handling is
+       the bb instruction. Similar to Q, but 64 bit handling is
        different.
    Z    %r1 -- implicit target of addil instruction.
    L    ,%r2 completer for new syntax branch
@@ -155,12 +155,14 @@ Also these:
    _    Destination format completer for fcnv
    h    cbit for fcmp
    =    gfx tests for ftest
-   d    14bit offset for single precision FP long load/store.
-   #    14bit offset for double precision FP load long/store.
-   J    Yet another 14bit offset with an unusual encoding.
-   K    Yet another 14bit offset with an unusual encoding.
-   y    16bit offset for single precision FP long load/store (PA2.0 wide).
-   &    16bit offset for double precision FP long load/store (PA2.0 wide).
+   d    14 bit offset for single precision FP long load/store.
+   #    14 bit offset for double precision FP load long/store.
+   J    Yet another 14 bit offset for load/store with ma,mb completers.
+   K    Yet another 14 bit offset for load/store with ma,mb completers.
+   y    16 bit offset for word aligned load/store (PA2.0 wide).
+   &    16 bit offset for dword aligned load/store (PA2.0 wide).
+   <    16 bit offset for load/store with ma,mb completers (PA2.0 wide).
+   >    16 bit offset for load/store with ma,mb completers (PA2.0 wide).
    Y    %sr0,%r31 -- implicit target of be,l instruction.
    @   implicit immediate value of 0
 
@@ -279,6 +281,7 @@ static const struct pa_opcode pa_opcodes[] =
 
 /* Pseudo-instructions.  */
 
+{ "ldi",       0x34000000, 0xffe00000, "l,x", pa20w, 0},/* ldo val(r0),r */
 { "ldi",       0x34000000, 0xffe0c000, "j,x", pa10, 0},/* ldo val(r0),r */
 
 { "call",      0xe800f000, 0xfc1ffffd, "n(b)", pa20, FLAG_STRICT},
@@ -321,36 +324,37 @@ static const struct pa_opcode pa_opcodes[] =
 { "ldd",       0x0c0010c0, 0xfc0013c0, "cmcc5(b),t", pa20, FLAG_STRICT},
 { "ldd",        0x50000000, 0xfc000002, "cq&(b),x", pa20w, FLAG_STRICT},
 { "ldd",        0x50000000, 0xfc000002, "cq#(b),x", pa20, FLAG_STRICT},
-{ "ldw",        0x48000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
 { "ldw",        0x0c000080, 0xfc0013c0, "cxccx(s,b),t", pa10, FLAG_STRICT},
 { "ldw",        0x0c000080, 0xfc0013c0, "cxccx(b),t", pa10, FLAG_STRICT},
 { "ldw",       0x0c0010a0, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT},
 { "ldw",       0x0c0010a0, 0xfc1f33e0, "cocc@(b),t", pa20, FLAG_STRICT},
 { "ldw",       0x0c001080, 0xfc0013c0, "cmcc5(s,b),t", pa10, FLAG_STRICT},
 { "ldw",       0x0c001080, 0xfc0013c0, "cmcc5(b),t", pa10, FLAG_STRICT},
+{ "ldw",        0x4c000000, 0xfc000000, "ce<(b),x", pa20w, FLAG_STRICT},
 { "ldw",        0x4c000000, 0xfc000000, "ceJ(s,b),x", pa10, FLAG_STRICT},
 { "ldw",        0x4c000000, 0xfc000000, "ceJ(b),x", pa10, FLAG_STRICT},
+{ "ldw",        0x5c000004, 0xfc000006, "ce>(b),x", pa20w, FLAG_STRICT},
 { "ldw",        0x5c000004, 0xfc000006, "ceK(s,b),x", pa20, FLAG_STRICT},
 { "ldw",        0x5c000004, 0xfc000006, "ceK(b),x", pa20, FLAG_STRICT},
-{ "ldw",        0x48000000, 0xfc000000, "j(s,b),x", pa10, 0},
+{ "ldw",        0x48000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
 { "ldw",        0x48000000, 0xfc000000, "j(s,b),x", pa10, 0},
 { "ldw",        0x48000000, 0xfc000000, "j(b),x", pa10, 0},
-{ "ldh",        0x44000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
 { "ldh",        0x0c000040, 0xfc0013c0, "cxccx(s,b),t", pa10, FLAG_STRICT},
 { "ldh",        0x0c000040, 0xfc0013c0, "cxccx(b),t", pa10, FLAG_STRICT},
 { "ldh",       0x0c001060, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT},
 { "ldh",       0x0c001060, 0xfc1f33e0, "cocc@(b),t", pa20, FLAG_STRICT},
 { "ldh",       0x0c001040, 0xfc0013c0, "cmcc5(s,b),t", pa10, FLAG_STRICT},
 { "ldh",       0x0c001040, 0xfc0013c0, "cmcc5(b),t", pa10, FLAG_STRICT},
+{ "ldh",        0x44000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
 { "ldh",        0x44000000, 0xfc000000, "j(s,b),x", pa10, 0},
 { "ldh",        0x44000000, 0xfc000000, "j(b),x", pa10, 0},
-{ "ldb",        0x40000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
 { "ldb",        0x0c000000, 0xfc0013c0, "cxccx(s,b),t", pa10, FLAG_STRICT},
 { "ldb",        0x0c000000, 0xfc0013c0, "cxccx(b),t", pa10, FLAG_STRICT},
 { "ldb",       0x0c001020, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT},
 { "ldb",       0x0c001020, 0xfc1f33e0, "cocc@(b),t", pa20, FLAG_STRICT},
 { "ldb",       0x0c001000, 0xfc0013c0, "cmcc5(s,b),t", pa10, FLAG_STRICT},
 { "ldb",       0x0c001000, 0xfc0013c0, "cmcc5(b),t", pa10, FLAG_STRICT},
+{ "ldb",        0x40000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
 { "ldb",        0x40000000, 0xfc000000, "j(s,b),x", pa10, 0},
 { "ldb",        0x40000000, 0xfc000000, "j(b),x", pa10, 0},
 { "std",       0x0c0012e0, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
@@ -359,29 +363,31 @@ static const struct pa_opcode pa_opcodes[] =
 { "std",       0x0c0012c0, 0xfc0013c0, "cmcCx,V(b)", pa20, FLAG_STRICT},
 { "std",        0x70000000, 0xfc000002, "cqx,&(b)", pa20w, FLAG_STRICT},
 { "std",        0x70000000, 0xfc000002, "cqx,#(b)", pa20, FLAG_STRICT},
-{ "stw",        0x68000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
 { "stw",       0x0c0012a0, 0xfc0013ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
 { "stw",       0x0c0012a0, 0xfc0013ff, "cocCx,@(b)", pa20, FLAG_STRICT},
 { "stw",       0x0c001280, 0xfc0013c0, "cmcCx,V(s,b)", pa10, FLAG_STRICT},
 { "stw",       0x0c001280, 0xfc0013c0, "cmcCx,V(b)", pa10, FLAG_STRICT},
+{ "stw",        0x6c000000, 0xfc000000, "cex,<(b)", pa20w, FLAG_STRICT},
 { "stw",        0x6c000000, 0xfc000000, "cex,J(s,b)", pa10, FLAG_STRICT},
 { "stw",        0x6c000000, 0xfc000000, "cex,J(b)", pa10, FLAG_STRICT},
+{ "stw",        0x7c000004, 0xfc000006, "cex,>(b)", pa20w, FLAG_STRICT},
 { "stw",        0x7c000004, 0xfc000006, "cex,K(s,b)", pa20, FLAG_STRICT},
 { "stw",        0x7c000004, 0xfc000006, "cex,K(b)", pa20, FLAG_STRICT},
+{ "stw",        0x68000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
 { "stw",        0x68000000, 0xfc000000, "x,j(s,b)", pa10, 0},
 { "stw",        0x68000000, 0xfc000000, "x,j(b)", pa10, 0},
-{ "sth",        0x64000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
 { "sth",       0x0c001260, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
 { "sth",       0x0c001260, 0xfc0033ff, "cocCx,@(b)", pa20, FLAG_STRICT},
 { "sth",       0x0c001240, 0xfc0013c0, "cmcCx,V(s,b)", pa10, FLAG_STRICT},
 { "sth",       0x0c001240, 0xfc0013c0, "cmcCx,V(b)", pa10, FLAG_STRICT},
+{ "sth",        0x64000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
 { "sth",        0x64000000, 0xfc000000, "x,j(s,b)", pa10, 0},
 { "sth",        0x64000000, 0xfc000000, "x,j(b)", pa10, 0},
-{ "stb",        0x60000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
 { "stb",       0x0c001220, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
 { "stb",       0x0c001220, 0xfc0033ff, "cocCx,@(b)", pa20, FLAG_STRICT},
 { "stb",       0x0c001200, 0xfc0013c0, "cmcCx,V(s,b)", pa10, FLAG_STRICT},
 { "stb",       0x0c001200, 0xfc0013c0, "cmcCx,V(b)", pa10, FLAG_STRICT},
+{ "stb",        0x60000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
 { "stb",        0x60000000, 0xfc000000, "x,j(s,b)", pa10, 0},
 { "stb",        0x60000000, 0xfc000000, "x,j(b)", pa10, 0},
 { "ldwm",       0x4c000000, 0xfc000000, "j(s,b),x", pa10, 0},
@@ -439,6 +445,7 @@ static const struct pa_opcode pa_opcodes[] =
 { "stbys",     0x0c001300, 0xfc001fc0, "csx,V(b)", pa10, 0},
 
 /* Immediate instructions.  */
+{ "ldo",       0x34000000, 0xfc000000, "l(b),x", pa20w, 0},
 { "ldo",       0x34000000, 0xfc00c000, "j(b),x", pa10, 0},
 { "ldil",      0x20000000, 0xfc000000, "k,b", pa10, 0},
 { "addil",     0x28000000, 0xfc000000, "k,b,Z", pa10, 0},
index e118c0effaf0cc7cfd1fbde34060eadbea446431..56091612889b6412bbe09857b0dd9a4db501b81a 100644 (file)
@@ -1,3 +1,7 @@
+2001-01-14  Alan Modra  <alan@linuxcare.com.au>
+
+       * hppa-dis.c (print_insn_hppa): Handle '>' and '<' arg types.
+
 2001-01-13  Nick Clifton  <nickc@redhat.com>
 
        * disassemble.c: Remove spurious white space.
index 1312bc5342576812c5efed0a6920426ffce68310..7fda0f2db062ae8196c00c2071940289cca47376 100644 (file)
@@ -1,5 +1,5 @@
 /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
-   Copyright 1989, 90, 92, 93, 94, 95, 98, 99, 2000
+   Copyright 1989, 90, 92, 93, 94, 95, 98, 99, 2000, 2001
    Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
@@ -889,6 +889,7 @@ print_insn_hppa (memaddr, info)
                case 'k':
                  fput_const (extract_21 (insn), info);
                  break;
+               case '<':
                case 'l':
                  /* 16-bit long disp., PA2.0 wide only.  */
                  fput_const (extract_16 (insn), info);
@@ -1099,6 +1100,7 @@ print_insn_hppa (memaddr, info)
                    break;
                  }
 
+               case '>':
                case 'y':
                  {
                    /* 16-bit long disp., PA2.0 wide only.  */