opcodes:
authorZack Weinberg <zackw@panix.com>
Wed, 8 Jun 2005 17:27:41 +0000 (17:27 +0000)
committerZack Weinberg <zackw@panix.com>
Wed, 8 Jun 2005 17:27:41 +0000 (17:27 +0000)
* arm-opc.h: Delete; fold contents into ...
* arm-dis.c: ... here.  Move includes of internal COFF headers
next to includes of internal ELF headers.
(streq, WORD_ADDRESS, BDISP, BDISP23): Delete, unused.
(struct arm_opcode): Rename struct opcode32.  Make 'assembler' const.
(struct thumb_opcode): Rename struct opcode16.  Make 'assembler' const.
(arm_conditional, arm_fp_const, arm_shift, arm_regname, regnames)
(iwmmxt_wwnames, iwmmxt_wwssnames):
Make const.
(regnames): Remove iWMMXt coprocessor register sets.
(iwmmxt_regnames, iwmmxt_cregnames): New statics.
(get_arm_regnames): Adjust fourth argument to match above changes.
(set_iwmmxt_regnames): Delete.
(print_insn_arm): Constify 'c'.  Use ISO syntax for function
pointer calls.  Expand sole use of BDISP.  Use iwmmxt_regnames
and iwmmxt_cregnames, not set_iwmmxt_regnames.
(print_insn_thumb16, print_insn_thumb32): Constify 'c'.  Use
ISO syntax for function pointer calls.
include:
* dis-asm.h (get_arm_regnames): Update prototype.

include/ChangeLog
include/dis-asm.h
opcodes/ChangeLog
opcodes/Makefile.am
opcodes/Makefile.in
opcodes/arm-dis.c
opcodes/arm-opc.h [deleted file]

index 6ab5c12..54d7f07 100644 (file)
@@ -1,3 +1,7 @@
+2005-06-08  Zack Weinberg  <zack@codesourcery.com>
+
+       * dis-asm.h (get_arm_regnames): Update prototype.
+
 2005-06-07  Aldy Hernandez  <aldyh@redhat.com>
            Michael Snyder  <msnyder@redhat.com>
            Stan Cox  <scox@redhat.com>
index 906a5b8..fc1776c 100644 (file)
@@ -274,7 +274,7 @@ extern void print_arm_disassembler_options (FILE *);
 extern void parse_arm_disassembler_option (char *);
 extern int get_arm_regname_num_options (void);
 extern int set_arm_regname_option (int);
-extern int get_arm_regnames (int, const char **, const char **, const char ***);
+extern int get_arm_regnames (int, const char **, const char **, const char *const **);
 extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *);
 
 /* Fetch the disassembler for a given BFD, if that support is available.  */
index 55618ff..94452d8 100644 (file)
@@ -1,3 +1,24 @@
+2005-06-08  Zack Weinberg  <zack@codesourcery.com>
+
+       * arm-opc.h: Delete; fold contents into ...
+       * arm-dis.c: ... here.  Move includes of internal COFF headers
+       next to includes of internal ELF headers.
+       (streq, WORD_ADDRESS, BDISP, BDISP23): Delete, unused.
+       (struct arm_opcode): Rename struct opcode32.  Make 'assembler' const.
+       (struct thumb_opcode): Rename struct opcode16.  Make 'assembler' const.
+       (arm_conditional, arm_fp_const, arm_shift, arm_regname, regnames)
+       (iwmmxt_wwnames, iwmmxt_wwssnames):
+       Make const.
+       (regnames): Remove iWMMXt coprocessor register sets.
+       (iwmmxt_regnames, iwmmxt_cregnames): New statics.
+       (get_arm_regnames): Adjust fourth argument to match above changes.
+       (set_iwmmxt_regnames): Delete.
+       (print_insn_arm): Constify 'c'.  Use ISO syntax for function
+       pointer calls.  Expand sole use of BDISP.  Use iwmmxt_regnames
+       and iwmmxt_cregnames, not set_iwmmxt_regnames.
+       (print_insn_thumb16, print_insn_thumb32): Constify 'c'.  Use
+       ISO syntax for function pointer calls.
+
 2005-06-07  Zack Weinberg  <zack@codesourcery.com>
 
        * arm-dis.c: Split up the comments describing the format codes, so
index b7fea89..51f8df7 100644 (file)
@@ -25,7 +25,6 @@ LIBIBERTY = ../libiberty/libiberty.a
 
 # Header files.
 HFILES = \
-       arm-opc.h \
        fr30-desc.h fr30-opc.h \
        frv-desc.h frv-opc.h \
        h8500-opc.h \
@@ -533,10 +532,10 @@ arc-ext.lo: arc-ext.c sysdep.h config.h $(INCDIR)/ansidecl.h \
   $(BFD_H) $(INCDIR)/symcat.h arc-ext.h $(INCDIR)/libiberty.h
 arm-dis.lo: arm-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/arm.h \
-  arm-opc.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
-  $(INCDIR)/bfdlink.h opintl.h $(INCDIR)/safe-ctype.h \
-  $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
-  $(INCDIR)/elf/external.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
+  opintl.h $(INCDIR)/safe-ctype.h $(INCDIR)/coff/internal.h \
+  $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(BFDDIR)/elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
 avr-dis.lo: avr-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h opintl.h \
   $(INCDIR)/libiberty.h $(INCDIR)/opcode/avr.h
@@ -643,8 +642,8 @@ ia64-opc-i.lo: ia64-opc-i.c ia64-opc.h $(INCDIR)/opcode/ia64.h \
 ia64-opc-m.lo: ia64-opc-m.c ia64-opc.h $(INCDIR)/opcode/ia64.h \
   $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
 ia64-opc-d.lo: ia64-opc-d.c
-ia64-opc.lo: ia64-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
-  sysdep.h config.h ia64-asmtab.h $(INCDIR)/opcode/ia64.h \
+ia64-opc.lo: ia64-opc.c $(INCDIR)/ansidecl.h sysdep.h \
+  config.h $(INCDIR)/libiberty.h ia64-asmtab.h $(INCDIR)/opcode/ia64.h \
   $(BFD_H) $(INCDIR)/symcat.h ia64-asmtab.c
 ia64-gen.lo: ia64-gen.c $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
   $(INCDIR)/safe-ctype.h sysdep.h config.h $(INCDIR)/getopt.h \
index ec3cb6d..c32eca3 100644 (file)
@@ -246,7 +246,6 @@ LIBIBERTY = ../libiberty/libiberty.a
 
 # Header files.
 HFILES = \
-       arm-opc.h \
        fr30-desc.h fr30-opc.h \
        frv-desc.h frv-opc.h \
        h8500-opc.h \
@@ -1063,10 +1062,10 @@ arc-ext.lo: arc-ext.c sysdep.h config.h $(INCDIR)/ansidecl.h \
   $(BFD_H) $(INCDIR)/symcat.h arc-ext.h $(INCDIR)/libiberty.h
 arm-dis.lo: arm-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/arm.h \
-  arm-opc.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
-  $(INCDIR)/bfdlink.h opintl.h $(INCDIR)/safe-ctype.h \
-  $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
-  $(INCDIR)/elf/external.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
+  opintl.h $(INCDIR)/safe-ctype.h $(INCDIR)/coff/internal.h \
+  $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(BFDDIR)/elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
 avr-dis.lo: avr-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h opintl.h \
   $(INCDIR)/libiberty.h $(INCDIR)/opcode/avr.h
@@ -1173,8 +1172,8 @@ ia64-opc-i.lo: ia64-opc-i.c ia64-opc.h $(INCDIR)/opcode/ia64.h \
 ia64-opc-m.lo: ia64-opc-m.c ia64-opc.h $(INCDIR)/opcode/ia64.h \
   $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
 ia64-opc-d.lo: ia64-opc-d.c
-ia64-opc.lo: ia64-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
-  sysdep.h config.h ia64-asmtab.h $(INCDIR)/opcode/ia64.h \
+ia64-opc.lo: ia64-opc.c $(INCDIR)/ansidecl.h sysdep.h \
+  config.h $(INCDIR)/libiberty.h ia64-asmtab.h $(INCDIR)/opcode/ia64.h \
   $(BFD_H) $(INCDIR)/symcat.h ia64-asmtab.c
 ia64-gen.lo: ia64-gen.c $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
   $(INCDIR)/safe-ctype.h sysdep.h config.h $(INCDIR)/getopt.h \
index a1540b7..d136af1 100644 (file)
 
 #include "dis-asm.h"
 #include "opcode/arm.h"
-#include "arm-opc.h"
-#include "coff/internal.h"
-#include "libcoff.h"
 #include "opintl.h"
 #include "safe-ctype.h"
 
 /* FIXME: This shouldn't be done here.  */
+#include "coff/internal.h"
+#include "libcoff.h"
 #include "elf-bfd.h"
 #include "elf/internal.h"
 #include "elf/arm.h"
 
-#ifndef streq
-#define streq(a,b)     (strcmp ((a), (b)) == 0)
-#endif
-
+/* FIXME: Belongs in global header.  */
 #ifndef strneq
 #define strneq(a,b,n)  (strncmp ((a), (b), (n)) == 0)
 #endif
 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
 #endif
 
-#define WORD_ADDRESS(pc) ((pc) & ~0x3)
+struct opcode32
+{
+  unsigned long arch;          /* Architecture defining this insn.  */
+  unsigned long value, mask;   /* Recognise insn if (op&mask)==value.  */
+  const char *assembler;       /* How to disassemble this insn.  */
+};
+
+struct opcode16
+{
+  unsigned long arch;          /* Architecture defining this insn.  */
+  unsigned short value, mask;  /* Recognise insn if (op&mask)==value.  */
+  const char *assembler;       /* How to disassemble this insn.  */
+};
 
 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb.  All three are partially
    ordered: they must be searched linearly from the top to obtain a correct
    %E                  print the LSB and WIDTH fields of a BFI or BFC instruction.
    %V                   print the 16-bit immediate field of a MOVT or MOVW instruction.  */
 
-static const struct arm_opcode arm_opcodes[] =
+static const struct opcode32 arm_opcodes[] =
 {
   /* ARM instructions.  */
   {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
@@ -644,7 +652,7 @@ static const struct arm_opcode arm_opcodes[] =
    %<bitnum>'c         print specified char iff bit is one
    %<bitnum>?ab                print a if bit is one else print b.  */
 
-static const struct thumb_opcode thumb_opcodes[] =
+static const struct opcode16 thumb_opcodes[] =
 {
   /* Thumb instructions.  */
 
@@ -812,7 +820,7 @@ static const struct thumb_opcode thumb_opcodes[] =
    is guaranteed never to catch a special-case bit pattern with a more
    general mask, which is important, because this instruction encoding
    makes heavy use of special-case bit patterns.  */
-static const struct arm_opcode thumb32_opcodes[] =
+static const struct opcode32 thumb32_opcodes[] =
 {
   /* Instructions defined in the basic V6T2 set.  */
   {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
@@ -1018,20 +1026,25 @@ static const struct arm_opcode thumb32_opcodes[] =
   {0, 0, 0, 0}
 };
    
-
-static char * arm_conditional[] =
+static const char *const arm_conditional[] =
 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
  "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
 
+static const char *const arm_fp_const[] =
+{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
+
+static const char *const arm_shift[] =
+{"lsl", "lsr", "asr", "ror"};
+
 typedef struct
 {
-  const char * name;
-  const char * description;
-  const char * reg_names[16];
+  const char *name;
+  const char *description;
+  const char *reg_names[16];
 }
 arm_regname;
 
-static arm_regname regnames[] =
+static const arm_regname regnames[] =
 {
   { "raw" , "Select raw register names",
     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
@@ -1045,22 +1058,28 @@ static arm_regname regnames[] =
     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
   { "special-atpcs", "Select special register names used in the ATPCS",
     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
-  { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
-    { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
-  { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
-    {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
 };
 
-static char * iwmmxt_wwnames[] =
+static const char *const iwmmxt_wwnames[] =
 {"b", "h", "w", "d"};
 
-static char * iwmmxt_wwssnames[] =
+static const char *const iwmmxt_wwssnames[] =
 {"b", "bus", "b", "bss",
  "h", "hus", "h", "hss",
  "w", "wus", "w", "wss",
  "d", "dus", "d", "dss"
 };
 
+static const char *const iwmmxt_regnames[] =
+{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
+  "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
+};
+
+static const char *const iwmmxt_cregnames[] =
+{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
+  "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
+};
+
 /* Default to GCC register name set.  */
 static unsigned int regname_selected = 1;
 
@@ -1069,11 +1088,6 @@ static unsigned int regname_selected = 1;
 
 static bfd_boolean force_thumb = FALSE;
 
-static char * arm_fp_const[] =
-{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
-
-static char * arm_shift[] =
-{"lsl", "lsr", "asr", "ror"};
 \f
 /* Functions.  */
 int
@@ -1092,7 +1106,7 @@ set_arm_regname_option (int option)
 
 int
 get_arm_regnames (int option, const char **setname, const char **setdescription,
-                 const char ***register_names)
+                 const char *const **register_names)
 {
   *setname = regnames[option].name;
   *setdescription = regnames[option].description;
@@ -1131,33 +1145,14 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream)
     }
 }
 
-static int
-set_iwmmxt_regnames (void)
-{
-  const char * setname;
-  const char * setdesc;
-  const char ** regnames;
-  int iwmmxt_regnames = 0;
-  int num_regnames = get_arm_regname_num_options ();
-
-  get_arm_regnames (iwmmxt_regnames, &setname,
-                   &setdesc, &regnames);
-  while ((strcmp ("iwmmxt_regnames", setname))
-        && (iwmmxt_regnames < num_regnames))
-    get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
-
-  return iwmmxt_regnames;
-}
-
 /* Print one ARM instruction from PC on INFO->STREAM.  */
 
 static void
 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
 {
-  const struct arm_opcode *insn;
+  const struct opcode32 *insn;
   void *stream = info->stream;
-  fprintf_ftype func   = info->fprintf_func;
-  static int iwmmxt_regnames = 0;
+  fprintf_ftype func = info->fprintf_func;
 
   for (insn = arm_opcodes; insn->assembler; insn++)
     {
@@ -1174,7 +1169,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
              || (insn->mask & 0xF0000000) == 0xF0000000
              || (insn->mask == 0 && insn->value == 0)))
        {
-         char * c;
+         const char *c;
 
          for (c = insn->assembler; *c; c++)
            {
@@ -1281,9 +1276,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                            offset = -offset;
 
                          func (stream, "[pc, #%d]\t; ", offset);
-
-                         (*info->print_address_func)
-                           (offset + pc + 8, info);
+                         info->print_address_func (offset + pc + 8, info);
                        }
                      else
                        {
@@ -1340,8 +1333,10 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                      break;
 
                    case 'b':
-                     (*info->print_address_func)
-                       (BDISP (given) * 4 + pc + 8, info);
+                     {
+                       int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
+                       info->print_address_func (disp*4 + pc + 8, info);
+                     }
                      break;
 
                    case 'c':
@@ -1663,34 +1658,18 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                              case 'g':
                                {
                                  long reg;
-                                 int current_regnames;
-
-                                 if (! iwmmxt_regnames)
-                                   iwmmxt_regnames = set_iwmmxt_regnames ();
-                                 current_regnames = set_arm_regname_option
-                                   (iwmmxt_regnames);
-
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
-                                 func (stream, "%s", arm_regnames[reg]);
-                                 set_arm_regname_option (current_regnames);
+                                 func (stream, "%s", iwmmxt_regnames[reg]);
                                }
                                break;
 
                              case 'G':
                                {
                                  long reg;
-                                 int current_regnames;
-
-                                 if (! iwmmxt_regnames)
-                                   iwmmxt_regnames = set_iwmmxt_regnames ();
-                                 current_regnames = set_arm_regname_option
-                                   (iwmmxt_regnames + 1);
-
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
-                                 func (stream, "%s", arm_regnames[reg]);
-                                 set_arm_regname_option (current_regnames);
+                                 func (stream, "%s", iwmmxt_cregnames[reg]);
                                }
                                break;
 
@@ -1901,14 +1880,14 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
 static void
 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
 {
-  const struct thumb_opcode *insn;
+  const struct opcode16 *insn;
   void *stream = info->stream;
   fprintf_ftype func = info->fprintf_func;
 
   for (insn = thumb_opcodes; insn->assembler; insn++)
     if ((given & insn->mask) == insn->value)
       {
-       char * c = insn->assembler;
+       const char *c = insn->assembler;
        for (; *c; c++)
          {
            int domaskpc = 0;
@@ -2070,8 +2049,7 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
 
                          case 'B':
                            reg = ((reg ^ (1 << bitend)) - (1 << bitend));
-                           (*info->print_address_func)
-                             (reg * 2 + pc + 4, info);
+                           info->print_address_func (reg * 2 + pc + 4, info);
                            break;
 
                          case 'c':
@@ -2127,14 +2105,14 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
 static void
 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 {
-  const struct arm_opcode *insn;
+  const struct opcode32 *insn;
   void *stream = info->stream;
   fprintf_ftype func = info->fprintf_func;
 
   for (insn = thumb32_opcodes; insn->assembler; insn++)
     if ((given & insn->mask) == insn->value)
       {
-       char * c = insn->assembler;
+       const char *c = insn->assembler;
        for (; *c; c++)
          {
            if (*c != '%')
diff --git a/opcodes/arm-opc.h b/opcodes/arm-opc.h
deleted file mode 100644 (file)
index 51c1905..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Disassembler definitions for ARM.
-
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004 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
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-
-struct arm_opcode
-{
-  unsigned long arch;          /* Architecture defining this insn.  */
-  unsigned long value, mask;   /* Recognise insn if (op&mask)==value.  */
-  char *assembler;             /* How to disassemble this insn.  */
-};
-
-struct thumb_opcode
-{
-  unsigned long arch;          /* Architecture defining this insn.  */
-  unsigned short value, mask;  /* Recognise insn if (op&mask)==value.  */
-  char * assembler;            /* How to disassemble this insn.  */
-};
-
-
-#define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */
-
-#define BDISP23(x) ((((((x) & 0x07ff) << 11) | (((x) & 0x07ff0000) >> 16)) \
-                     ^ 0x200000) - 0x200000) /* 23bit */
-