LCOV - code coverage report
Current view: top level - libcpu - i386_data.h (source / functions) Hit Total Coverage
Test: elfutils-0.191 Lines: 613 682 89.9 %
Date: 2024-10-18 16:35:36 Functions: 46 46 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 286 450 63.6 %

           Branch data     Line data    Source code
       1                 :            : /* Helper routines for disassembler for x86/x86-64.
       2                 :            :    Copyright (C) 2007, 2008 Red Hat, Inc.
       3                 :            :    This file is part of elfutils.
       4                 :            :    Written by Ulrich Drepper <drepper@redhat.com>, 2007.
       5                 :            : 
       6                 :            :    This file is free software; you can redistribute it and/or modify
       7                 :            :    it under the terms of either
       8                 :            : 
       9                 :            :      * the GNU Lesser General Public License as published by the Free
      10                 :            :        Software Foundation; either version 3 of the License, or (at
      11                 :            :        your option) any later version
      12                 :            : 
      13                 :            :    or
      14                 :            : 
      15                 :            :      * the GNU General Public License as published by the Free
      16                 :            :        Software Foundation; either version 2 of the License, or (at
      17                 :            :        your option) any later version
      18                 :            : 
      19                 :            :    or both in parallel, as here.
      20                 :            : 
      21                 :            :    elfutils is distributed in the hope that it will be useful, but
      22                 :            :    WITHOUT ANY WARRANTY; without even the implied warranty of
      23                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      24                 :            :    General Public License for more details.
      25                 :            : 
      26                 :            :    You should have received copies of the GNU General Public License and
      27                 :            :    the GNU Lesser General Public License along with this program.  If
      28                 :            :    not, see <http://www.gnu.org/licenses/>.  */
      29                 :            : 
      30                 :            : #include <inttypes.h>
      31                 :            : #include <stddef.h>
      32                 :            : #include <stdio.h>
      33                 :            : #include <stdint.h>
      34                 :            : #include <libasm.h>
      35                 :            : 
      36                 :            : struct instr_enc
      37                 :            : {
      38                 :            :   /* The mnemonic.  Especially encoded for the optimized table.  */
      39                 :            :   unsigned int mnemonic : MNEMONIC_BITS;
      40                 :            : 
      41                 :            :   /* The rep/repe prefixes.  */
      42                 :            :   unsigned int rep : 1;
      43                 :            :   unsigned int repe : 1;
      44                 :            : 
      45                 :            :   /* Mnemonic suffix.  */
      46                 :            :   unsigned int suffix : SUFFIX_BITS;
      47                 :            : 
      48                 :            :   /* Nonzero if the instruction uses modr/m.  */
      49                 :            :   unsigned int modrm : 1;
      50                 :            : 
      51                 :            :   /* 1st parameter.  */
      52                 :            :   unsigned int fct1 : FCT1_BITS;
      53                 :            : #ifdef STR1_BITS
      54                 :            :   unsigned int str1 : STR1_BITS;
      55                 :            : #endif
      56                 :            :   unsigned int off1_1 : OFF1_1_BITS;
      57                 :            :   unsigned int off1_2 : OFF1_2_BITS;
      58                 :            :   unsigned int off1_3 : OFF1_3_BITS;
      59                 :            : 
      60                 :            :   /* 2nd parameter.  */
      61                 :            :   unsigned int fct2 : FCT2_BITS;
      62                 :            : #ifdef STR2_BITS
      63                 :            :   unsigned int str2 : STR2_BITS;
      64                 :            : #endif
      65                 :            :   unsigned int off2_1 : OFF2_1_BITS;
      66                 :            :   unsigned int off2_2 : OFF2_2_BITS;
      67                 :            :   unsigned int off2_3 : OFF2_3_BITS;
      68                 :            : 
      69                 :            :   /* 3rd parameter.  */
      70                 :            :   unsigned int fct3 : FCT3_BITS;
      71                 :            : #ifdef STR3_BITS
      72                 :            :   unsigned int str3 : STR3_BITS;
      73                 :            : #endif
      74                 :            :   unsigned int off3_1 : OFF3_1_BITS;
      75                 :            : #ifdef OFF3_2_BITS
      76                 :            :   unsigned int off3_2 : OFF3_2_BITS;
      77                 :            : #endif
      78                 :            : #ifdef OFF3_3_BITS
      79                 :            :   unsigned int off3_3 : OFF3_3_BITS;
      80                 :            : #endif
      81                 :            : };
      82                 :            : 
      83                 :            : 
      84                 :            : typedef int (*opfct_t) (struct output_data *);
      85                 :            : 
      86                 :            : 
      87                 :            : static int
      88                 :      22802 : data_prefix (struct output_data *d)
      89                 :            : {
      90                 :      22802 :   char ch = '\0';
      91         [ +  + ]:      22802 :   if (*d->prefixes & has_cs)
      92                 :            :     {
      93                 :          2 :       ch = 'c';
      94                 :          2 :       *d->prefixes &= ~has_cs;
      95                 :            :     }
      96         [ +  + ]:      22800 :   else if (*d->prefixes & has_ds)
      97                 :            :     {
      98                 :         48 :       ch = 'd';
      99                 :         48 :       *d->prefixes &= ~has_ds;
     100                 :            :     }
     101         [ +  + ]:      22752 :   else if (*d->prefixes & has_es)
     102                 :            :     {
     103                 :          2 :       ch = 'e';
     104                 :          2 :       *d->prefixes &= ~has_es;
     105                 :            :     }
     106         [ +  + ]:      22750 :   else if (*d->prefixes & has_fs)
     107                 :            :     {
     108                 :         16 :       ch = 'f';
     109                 :         16 :       *d->prefixes &= ~has_fs;
     110                 :            :     }
     111         [ +  + ]:      22734 :   else if (*d->prefixes & has_gs)
     112                 :            :     {
     113                 :         20 :       ch = 'g';
     114                 :         20 :       *d->prefixes &= ~has_gs;
     115                 :            :     }
     116         [ +  + ]:      22714 :   else if (*d->prefixes & has_ss)
     117                 :            :     {
     118                 :          2 :       ch = 's';
     119                 :          2 :       *d->prefixes &= ~has_ss;
     120                 :            :     }
     121                 :            :   else
     122                 :            :     return 0;
     123                 :            : 
     124         [ -  + ]:         90 :   if (*d->bufcntp + 4 > d->bufsize)
     125                 :          0 :     return *d->bufcntp + 4 - d->bufsize;
     126                 :            : 
     127                 :         90 :   d->bufp[(*d->bufcntp)++] = '%';
     128                 :         90 :   d->bufp[(*d->bufcntp)++] = ch;
     129                 :         90 :   d->bufp[(*d->bufcntp)++] = 's';
     130                 :         90 :   d->bufp[(*d->bufcntp)++] = ':';
     131                 :            : 
     132                 :         90 :   return 0;
     133                 :            : }
     134                 :            : 
     135                 :            : #ifdef X86_64
     136                 :            : static const char hiregs[8][4] =
     137                 :            :   {
     138                 :            :     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
     139                 :            :   };
     140                 :            : static const char aregs[8][4] =
     141                 :            :   {
     142                 :            :     "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"
     143                 :            :   };
     144                 :            : static const char dregs[8][4] =
     145                 :            :   {
     146                 :            :     "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
     147                 :            :   };
     148                 :            : #else
     149                 :            : static const char aregs[8][4] =
     150                 :            :   {
     151                 :            :     "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
     152                 :            :   };
     153                 :            : # define dregs aregs
     154                 :            : #endif
     155                 :            : 
     156                 :            : static int
     157                 :      22696 : general_mod$r_m (struct output_data *d)
     158                 :            : {
     159                 :      22696 :   int r = data_prefix (d);
     160         [ +  - ]:      22696 :   if (r != 0)
     161                 :            :     return r;
     162                 :            : 
     163                 :      22696 :   int prefixes = *d->prefixes;
     164                 :      22696 :   const uint8_t *data = &d->data[d->opoff1 / 8];
     165                 :      22696 :   char *bufp = d->bufp;
     166                 :      22696 :   size_t *bufcntp = d->bufcntp;
     167                 :      22696 :   size_t bufsize = d->bufsize;
     168                 :            : 
     169                 :      22696 :   uint_fast8_t modrm = data[0];
     170                 :            : #ifndef X86_64
     171         [ +  + ]:       7504 :   if (unlikely ((prefixes & has_addr16) != 0))
     172                 :            :     {
     173                 :         80 :       int16_t disp = 0;
     174                 :         80 :       bool nodisp = false;
     175                 :            : 
     176   [ +  +  +  + ]:         80 :       if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80)
     177                 :            :         /* 16 bit displacement.  */
     178                 :         34 :         disp = read_2sbyte_unaligned (&data[1]);
     179         [ +  + ]:         46 :       else if ((modrm & 0xc0) == 0x40)
     180                 :            :         /* 8 bit displacement.  */
     181                 :         32 :         disp = *(const int8_t *) &data[1];
     182         [ +  - ]:         14 :       else if ((modrm & 0xc0) == 0)
     183                 :         14 :         nodisp = true;
     184                 :            : 
     185                 :         80 :       char tmpbuf[sizeof ("-0x1234(%rr,%rr)")];
     186                 :         80 :       int n;
     187         [ +  + ]:         80 :       if ((modrm & 0xc7) == 6)
     188                 :          2 :         n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx16, disp);
     189                 :            :       else
     190                 :            :         {
     191                 :         78 :           n = 0;
     192         [ +  + ]:         78 :           if (!nodisp)
     193                 :         64 :             n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx16,
     194         [ +  + ]:         64 :                           disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
     195                 :            : 
     196         [ +  + ]:         78 :           if ((modrm & 0x4) == 0)
     197                 :         40 :             n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%b%c,%%%ci)",
     198                 :         40 :                            "xp"[(modrm >> 1) & 1], "sd"[modrm & 1]);
     199                 :            :           else
     200                 :         38 :             n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%%s)",
     201                 :         38 :                            ((const char [4][3]) { "si", "di", "bp", "bx" })[modrm & 3]);
     202                 :            :         }
     203                 :            : 
     204         [ -  + ]:         80 :       if (*bufcntp + n + 1 > bufsize)
     205                 :          0 :         return *bufcntp + n + 1 - bufsize;
     206                 :            : 
     207                 :         80 :       memcpy (&bufp[*bufcntp], tmpbuf, n + 1);
     208                 :         80 :       *bufcntp += n;
     209                 :            :     }
     210                 :            :   else
     211                 :            : #endif
     212                 :            :     {
     213         [ +  + ]:      22616 :       if ((modrm & 7) != 4)
     214                 :            :         {
     215                 :      10344 :           int32_t disp = 0;
     216                 :      10344 :           bool nodisp = false;
     217                 :            : 
     218   [ +  +  +  + ]:      10344 :           if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80)
     219                 :            :             /* 32 bit displacement.  */
     220                 :       3752 :             disp = read_4sbyte_unaligned (&data[1]);
     221         [ +  + ]:       6592 :           else if ((modrm & 0xc0) == 0x40)
     222                 :            :             /* 8 bit displacement.  */
     223                 :       3498 :             disp = *(const int8_t *) &data[1];
     224         [ +  - ]:       3094 :           else if ((modrm & 0xc0) == 0)
     225                 :       3094 :             nodisp = true;
     226                 :            : 
     227                 :      10344 :           char tmpbuf[sizeof ("-0x12345678(%rrrr)")];
     228                 :      10344 :           int n;
     229                 :       7250 :           if (nodisp)
     230                 :            :             {
     231                 :       3094 :               n = snprintf (tmpbuf, sizeof (tmpbuf), "(%%%s)",
     232                 :            : #ifdef X86_64
     233         [ +  + ]:       1732 :                             (prefixes & has_rex_b) ? hiregs[modrm & 7] :
     234                 :            : #endif
     235                 :       1362 :                             aregs[modrm & 7]);
     236                 :            : #ifdef X86_64
     237         [ +  + ]:       1732 :               if (prefixes & has_addr16)
     238                 :            :                 {
     239         [ -  + ]:         12 :                   if (prefixes & has_rex_b)
     240                 :          0 :                     tmpbuf[n++] = 'd';
     241                 :            :                   else
     242                 :         12 :                     tmpbuf[2] = 'e';
     243                 :            :                 }
     244                 :            : #endif
     245                 :            :             }
     246         [ +  + ]:       7250 :           else if ((modrm & 0xc7) != 5)
     247                 :            :             {
     248                 :       6854 :               int p;
     249         [ +  + ]:       6854 :               n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%%n%s)",
     250                 :            :                             disp < 0 ? "-" : "", disp < 0 ? -disp : disp, &p,
     251                 :            : #ifdef X86_64
     252         [ +  + ]:       3788 :                             (prefixes & has_rex_b) ? hiregs[modrm & 7] :
     253                 :            : #endif
     254         [ +  + ]:       3066 :                             aregs[modrm & 7]);
     255                 :            : #ifdef X86_64
     256         [ +  + ]:       3788 :               if (prefixes & has_addr16)
     257                 :            :                 {
     258         [ -  + ]:         52 :                   if (prefixes & has_rex_b)
     259                 :          0 :                     tmpbuf[n++] = 'd';
     260                 :            :                   else
     261                 :         52 :                     tmpbuf[p] = 'e';
     262                 :            :                 }
     263                 :            : #endif
     264                 :            :             }
     265                 :            :           else
     266                 :            :             {
     267                 :            : #ifdef X86_64
     268         [ +  + ]:        222 :               n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%rip)",
     269                 :            :                             disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
     270                 :            : 
     271                 :        222 :               d->symaddr_use = addr_rel_always;
     272                 :        222 :               d->symaddr = disp;
     273                 :            : #else
     274                 :        174 :               n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx32, disp);
     275                 :            : #endif
     276                 :            :             }
     277                 :            : 
     278         [ -  + ]:      10344 :           if (*bufcntp + n + 1 > bufsize)
     279                 :          0 :             return *bufcntp + n + 1 - bufsize;
     280                 :            : 
     281                 :      10344 :           memcpy (&bufp[*bufcntp], tmpbuf, n + 1);
     282                 :      10344 :           *bufcntp += n;
     283                 :            :         }
     284                 :            :       else
     285                 :            :         {
     286                 :            :           /* SIB */
     287                 :      12272 :           uint_fast8_t sib = data[1];
     288                 :      12272 :           int32_t disp = 0;
     289                 :      12272 :           bool nodisp = false;
     290                 :            : 
     291   [ +  -  +  + ]:      12272 :           if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80
     292   [ +  +  +  + ]:       8576 :               || ((modrm & 0xc7) == 0x4 && (sib & 0x7) == 0x5))
     293                 :            :             /* 32 bit displacement.  */
     294                 :       4380 :             disp = read_4sbyte_unaligned (&data[2]);
     295         [ +  + ]:       7892 :           else if ((modrm & 0xc0) == 0x40)
     296                 :            :             /* 8 bit displacement.  */
     297                 :       3664 :             disp = *(const int8_t *) &data[2];
     298                 :            :           else
     299                 :            :             nodisp = true;
     300                 :            : 
     301                 :      12272 :           char tmpbuf[sizeof ("-0x12345678(%rrrr,%rrrr,N)")];
     302                 :      12272 :           char *cp = tmpbuf;
     303                 :      12272 :           int n;
     304   [ +  +  +  + ]:      12272 :           if ((modrm & 0xc0) != 0 || (sib & 0x3f) != 0x25
     305                 :            : #ifdef X86_64
     306         [ +  + ]:         42 :               || (prefixes & has_rex_x) != 0
     307                 :            : #endif
     308                 :            :               )
     309                 :            :             {
     310         [ +  + ]:      12228 :               if (!nodisp)
     311                 :            :                 {
     312         [ +  + ]:       8000 :                   n = snprintf (cp, sizeof (tmpbuf), "%s0x%" PRIx32,
     313                 :            :                                 disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
     314                 :       8000 :                   cp += n;
     315                 :            :                 }
     316                 :            : 
     317                 :      12228 :               *cp++ = '(';
     318                 :            : 
     319   [ +  +  +  + ]:      12228 :               if ((modrm & 0xc7) != 0x4 || (sib & 0x7) != 0x5)
     320                 :            :                 {
     321                 :      11588 :                   *cp++ = '%';
     322                 :      22220 :                   cp = stpcpy (cp,
     323                 :            : #ifdef X86_64
     324         [ +  + ]:       8948 :                                (prefixes & has_rex_b) ? hiregs[sib & 7] :
     325         [ +  + ]:       7264 :                                (prefixes & has_addr16) ? dregs[sib & 7] :
     326                 :            : #endif
     327                 :       9894 :                                aregs[sib & 7]);
     328                 :            : #ifdef X86_64
     329         [ -  + ]:       8948 :                   if ((prefixes & (has_rex_b | has_addr16))
     330                 :            :                       == (has_rex_b | has_addr16))
     331                 :          0 :                     *cp++ = 'd';
     332                 :            : #endif
     333                 :            :                 }
     334                 :            : 
     335         [ +  + ]:      12228 :               if ((sib & 0x38) != 0x20
     336                 :            : #ifdef X86_64
     337         [ +  + ]:       1054 :                   || (prefixes & has_rex_x) != 0
     338                 :            : #endif
     339                 :            :                   )
     340                 :            :                 {
     341                 :      11056 :                   *cp++ = ',';
     342                 :      11056 :                   *cp++ = '%';
     343                 :      21308 :                   cp = stpcpy (cp,
     344                 :            : #ifdef X86_64
     345         [ +  + ]:       8554 :                                (prefixes & has_rex_x)
     346                 :       1698 :                                ? hiregs[(sib >> 3) & 7] :
     347                 :       6856 :                                (prefixes & has_addr16)
     348         [ +  + ]:       6856 :                                ? dregs[(sib >> 3) & 7] :
     349                 :            : #endif
     350                 :       9348 :                                aregs[(sib >> 3) & 7]);
     351                 :            : #ifdef X86_64
     352         [ -  + ]:       8554 :                   if ((prefixes & (has_rex_b | has_addr16))
     353                 :            :                       == (has_rex_b | has_addr16))
     354                 :          0 :                     *cp++ = 'd';
     355                 :            : #endif
     356                 :            : 
     357                 :      11056 :                   *cp++ = ',';
     358                 :      11056 :                   *cp++ = '0' + (1 << (sib >> 6));
     359                 :            :                 }
     360                 :            : 
     361                 :      12228 :               *cp++ = ')';
     362                 :            :             }
     363                 :            :           else
     364                 :            :             {
     365         [ -  + ]:         44 :               assert (! nodisp);
     366                 :            : #ifdef X86_64
     367         [ +  - ]:         34 :               if ((prefixes & has_addr16) == 0)
     368                 :         34 :                 n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx64,
     369                 :            :                               (int64_t) disp);
     370                 :            :               else
     371                 :            : #endif
     372                 :         10 :                 n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx32, disp);
     373                 :         44 :               cp += n;
     374                 :            :             }
     375                 :            : 
     376         [ -  + ]:      12272 :           if (*bufcntp + (cp - tmpbuf) > bufsize)
     377                 :          0 :             return *bufcntp + (cp - tmpbuf) - bufsize;
     378                 :            : 
     379                 :      12272 :           memcpy (&bufp[*bufcntp], tmpbuf, cp - tmpbuf);
     380                 :      12272 :           *bufcntp += cp - tmpbuf;
     381                 :            :         }
     382                 :            :     }
     383                 :            :   return 0;
     384                 :            : }
     385                 :            : 
     386                 :            : 
     387                 :            : static int
     388                 :       3588 : FCT_MOD$R_M (struct output_data *d)
     389                 :            : {
     390         [ -  + ]:       3588 :   assert (d->opoff1 % 8 == 0);
     391                 :       3588 :   uint_fast8_t modrm = d->data[d->opoff1 / 8];
     392         [ +  + ]:       3588 :   if ((modrm & 0xc0) == 0xc0)
     393                 :            :     {
     394         [ -  + ]:       2496 :       assert (d->opoff1 / 8 == d->opoff2 / 8);
     395         [ -  + ]:       2496 :       assert (d->opoff2 % 8 == 5);
     396                 :            :       //uint_fast8_t byte = d->data[d->opoff2 / 8] & 7;
     397                 :       2496 :       uint_fast8_t byte = modrm & 7;
     398                 :            : 
     399                 :       2496 :       size_t *bufcntp = d->bufcntp;
     400                 :       2496 :       char *buf = d->bufp + *bufcntp;
     401                 :       2496 :       size_t avail = d->bufsize - *bufcntp;
     402                 :       2496 :       int needed;
     403         [ -  + ]:       2496 :       if (*d->prefixes & (has_rep | has_repne))
     404                 :          0 :         needed = snprintf (buf, avail, "%%%s", dregs[byte]);
     405                 :            :       else
     406                 :       2496 :         needed = snprintf (buf, avail, "%%mm%" PRIxFAST8, byte);
     407         [ -  + ]:       2496 :       if ((size_t) needed > avail)
     408                 :          0 :         return needed - avail;
     409                 :       2496 :       *bufcntp += needed;
     410                 :       2496 :       return 0;
     411                 :            :     }
     412                 :            : 
     413                 :       1092 :   return general_mod$r_m (d);
     414                 :            : }
     415                 :            : 
     416                 :            : 
     417                 :            : static int
     418                 :      10584 : FCT_Mod$R_m (struct output_data *d)
     419                 :            : {
     420         [ -  + ]:      10584 :   assert (d->opoff1 % 8 == 0);
     421                 :      10584 :   uint_fast8_t modrm = d->data[d->opoff1 / 8];
     422         [ +  + ]:      10584 :   if ((modrm & 0xc0) == 0xc0)
     423                 :            :     {
     424         [ -  + ]:       6152 :       assert (d->opoff1 / 8 == d->opoff2 / 8);
     425         [ -  + ]:       6152 :       assert (d->opoff2 % 8 == 5);
     426                 :            :       //uint_fast8_t byte = data[opoff2 / 8] & 7;
     427                 :       6152 :       uint_fast8_t byte = modrm & 7;
     428                 :            : 
     429                 :       6152 :       size_t *bufcntp = d->bufcntp;
     430                 :       6152 :       size_t avail = d->bufsize - *bufcntp;
     431         [ -  + ]:       6152 :       int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8,
     432                 :            :                              byte);
     433         [ -  + ]:       6152 :       if ((size_t) needed > avail)
     434                 :          0 :         return needed - avail;
     435                 :       6152 :       *d->bufcntp += needed;
     436                 :       6152 :       return 0;
     437                 :            :     }
     438                 :            : 
     439                 :       4432 :   return general_mod$r_m (d);
     440                 :            : }
     441                 :            : 
     442                 :            : static int
     443                 :         22 : generic_abs (struct output_data *d, const char *absstring
     444                 :            : #ifdef X86_64
     445                 :            :              , int abslen
     446                 :            : #else
     447                 :            : # define abslen 4
     448                 :            : #endif
     449                 :            :              )
     450                 :            : {
     451                 :         22 :   int r = data_prefix (d);
     452         [ +  - ]:         22 :   if (r != 0)
     453                 :            :     return r;
     454                 :            : 
     455         [ -  + ]:         22 :   assert (d->opoff1 % 8 == 0);
     456         [ -  + ]:         22 :   assert (d->opoff1 / 8 == 1);
     457         [ +  - ]:         22 :   if (*d->param_start + abslen > d->end)
     458                 :            :     return -1;
     459                 :         22 :   *d->param_start += abslen;
     460                 :            : #ifndef X86_64
     461                 :         14 :   uint32_t absval;
     462                 :            : # define ABSPRIFMT PRIx32
     463                 :            : #else
     464                 :          8 :   uint64_t absval;
     465                 :            : # define ABSPRIFMT PRIx64
     466         [ +  - ]:          8 :   if (abslen == 8)
     467                 :          8 :     absval = read_8ubyte_unaligned (&d->data[1]);
     468                 :            :   else
     469                 :            : #endif
     470                 :         14 :     absval = read_4ubyte_unaligned (&d->data[1]);
     471                 :         22 :   size_t *bufcntp = d->bufcntp;
     472                 :         22 :   size_t avail = d->bufsize - *bufcntp;
     473         [ -  + ]:         22 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "%s0x%" ABSPRIFMT,
     474                 :            :                          absstring, absval);
     475         [ -  + ]:         22 :   if ((size_t) needed > avail)
     476                 :          0 :     return needed - avail;
     477                 :         22 :   *bufcntp += needed;
     478                 :         22 :   return 0;
     479                 :            : }
     480                 :            : 
     481                 :            : 
     482                 :            : static int
     483                 :          6 : FCT_absval (struct output_data *d)
     484                 :            : {
     485                 :          6 :   return generic_abs (d, "$"
     486                 :            : #ifdef X86_64
     487                 :            :                       , 4
     488                 :            : #endif
     489                 :            :                       );
     490                 :            : }
     491                 :            : 
     492                 :            : static int
     493                 :         16 : FCT_abs (struct output_data *d)
     494                 :            : {
     495                 :         16 :   return generic_abs (d, ""
     496                 :            : #ifdef X86_64
     497                 :            :                       , 8
     498                 :            : #endif
     499                 :            :                       );
     500                 :            : }
     501                 :            : 
     502                 :            : static int
     503                 :        212 : FCT_ax (struct output_data *d)
     504                 :            : {
     505                 :        212 :   int is_16bit = (*d->prefixes & has_data16) != 0;
     506                 :            : 
     507                 :        212 :   size_t *bufcntp = d->bufcntp;
     508                 :        212 :   char *bufp = d->bufp;
     509                 :        212 :   size_t bufsize = d->bufsize;
     510                 :            : 
     511         [ -  + ]:        212 :   if (*bufcntp + 4 - is_16bit > bufsize)
     512                 :          0 :     return *bufcntp + 4 - is_16bit - bufsize;
     513                 :            : 
     514                 :        212 :   bufp[(*bufcntp)++] = '%';
     515         [ +  + ]:        212 :   if (! is_16bit)
     516                 :        164 :     bufp[(*bufcntp)++] = (
     517                 :            : #ifdef X86_64
     518         [ +  + ]:        102 :                           (*d->prefixes & has_rex_w) ? 'r' :
     519                 :            : #endif
     520                 :            :                           'e');
     521                 :        212 :   bufp[(*bufcntp)++] = 'a';
     522                 :        212 :   bufp[(*bufcntp)++] = 'x';
     523                 :            : 
     524                 :        212 :   return 0;
     525                 :            : }
     526                 :            : 
     527                 :            : 
     528                 :            : static int
     529                 :        276 : FCT_ax$w (struct output_data *d)
     530                 :            : {
     531         [ +  + ]:        276 :   if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0)
     532                 :        176 :     return FCT_ax (d);
     533                 :            : 
     534                 :        100 :   size_t *bufcntp = d->bufcntp;
     535                 :        100 :   char *bufp = d->bufp;
     536                 :        100 :   size_t bufsize = d->bufsize;
     537                 :            : 
     538         [ -  + ]:        100 :   if (*bufcntp + 3 > bufsize)
     539                 :          0 :     return *bufcntp + 3 - bufsize;
     540                 :            : 
     541                 :        100 :   bufp[(*bufcntp)++] = '%';
     542                 :        100 :   bufp[(*bufcntp)++] = 'a';
     543                 :        100 :   bufp[(*bufcntp)++] = 'l';
     544                 :            : 
     545                 :        100 :   return 0;
     546                 :            : }
     547                 :            : 
     548                 :            : 
     549                 :            : static int
     550                 :            : __attribute__ ((noinline))
     551                 :       1024 : FCT_crdb (struct output_data *d, const char *regstr)
     552                 :            : {
     553         [ +  - ]:       1024 :   if (*d->prefixes & has_data16)
     554                 :            :     return -1;
     555                 :            : 
     556                 :       1024 :   size_t *bufcntp = d->bufcntp;
     557                 :            : 
     558                 :            :   // XXX If this assert is true, use absolute offset below
     559         [ -  + ]:       1024 :   assert (d->opoff1 / 8 == 2);
     560         [ -  + ]:       1024 :   assert (d->opoff1 % 8 == 2);
     561                 :       1024 :   size_t avail = d->bufsize - *bufcntp;
     562                 :       1024 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "%%%s%" PRIx32,
     563         [ -  + ]:       1024 :                          regstr, (uint32_t) (d->data[d->opoff1 / 8] >> 3) & 7);
     564         [ -  + ]:       1024 :   if ((size_t) needed > avail)
     565                 :          0 :     return needed - avail;
     566                 :       1024 :   *bufcntp += needed;
     567                 :       1024 :   return 0;
     568                 :            : }
     569                 :            : 
     570                 :            : 
     571                 :            : static int
     572                 :        512 : FCT_ccc (struct output_data *d)
     573                 :            : {
     574                 :        512 :   return FCT_crdb (d, "cr");
     575                 :            : }
     576                 :            : 
     577                 :            : 
     578                 :            : static int
     579                 :        512 : FCT_ddd (struct output_data *d)
     580                 :            : {
     581                 :        512 :   return FCT_crdb (d, "db");
     582                 :            : }
     583                 :            : 
     584                 :            : 
     585                 :            : static int
     586                 :        176 : FCT_disp8 (struct output_data *d)
     587                 :            : {
     588         [ -  + ]:        176 :   assert (d->opoff1 % 8 == 0);
     589         [ +  - ]:        176 :   if (*d->param_start >= d->end)
     590                 :            :     return -1;
     591                 :        176 :   int32_t offset = *(const int8_t *) (*d->param_start)++;
     592                 :            : 
     593                 :        176 :   size_t *bufcntp = d->bufcntp;
     594                 :        176 :   size_t avail = d->bufsize - *bufcntp;
     595                 :        176 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32,
     596         [ -  + ]:        176 :                          (uint32_t) (d->addr + (*d->param_start - d->data)
     597                 :            :                                      + offset));
     598         [ -  + ]:        176 :   if ((size_t) needed > avail)
     599                 :          0 :     return needed - avail;
     600                 :        176 :   *bufcntp += needed;
     601                 :        176 :   return 0;
     602                 :            : }
     603                 :            : 
     604                 :            : 
     605                 :            : static int
     606                 :            : __attribute__ ((noinline))
     607                 :         84 : FCT_ds_xx (struct output_data *d, const char *reg)
     608                 :            : {
     609                 :         84 :   int prefix = *d->prefixes & SEGMENT_PREFIXES;
     610                 :            : 
     611         [ +  + ]:         84 :   if (prefix == 0)
     612                 :         48 :     *d->prefixes |= prefix = has_ds;
     613                 :            :   /* Make sure only one bit is set.  */
     614         [ +  - ]:         36 :   else if ((prefix - 1) & prefix)
     615                 :            :     return -1;
     616                 :            : 
     617                 :         84 :   int r = data_prefix (d);
     618                 :            : 
     619         [ -  + ]:         84 :   assert ((*d->prefixes & prefix) == 0);
     620                 :            : 
     621         [ +  - ]:         84 :   if (r != 0)
     622                 :            :     return r;
     623                 :            : 
     624                 :         84 :   size_t *bufcntp = d->bufcntp;
     625                 :         84 :   size_t avail = d->bufsize - *bufcntp;
     626         [ -  + ]:         84 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "(%%%s%s)",
     627                 :            : #ifdef X86_64
     628         [ +  - ]:         42 :                          *d->prefixes & idx_addr16 ? "e" : "r",
     629                 :            : #else
     630         [ +  - ]:         42 :                          *d->prefixes & idx_addr16 ? "" : "e",
     631                 :            : #endif
     632                 :            :                          reg);
     633         [ -  + ]:         84 :   if ((size_t) needed > avail)
     634                 :          0 :     return (size_t) needed - avail;
     635                 :         84 :   *bufcntp += needed;
     636                 :            : 
     637                 :         84 :   return 0;
     638                 :            : }
     639                 :            : 
     640                 :            : 
     641                 :            : static int
     642                 :          8 : FCT_ds_bx (struct output_data *d)
     643                 :            : {
     644                 :          8 :   return FCT_ds_xx (d, "bx");
     645                 :            : }
     646                 :            : 
     647                 :            : 
     648                 :            : static int
     649                 :         76 : FCT_ds_si (struct output_data *d)
     650                 :            : {
     651                 :         76 :   return FCT_ds_xx (d, "si");
     652                 :            : }
     653                 :            : 
     654                 :            : 
     655                 :            : static int
     656                 :         40 : FCT_dx (struct output_data *d)
     657                 :            : {
     658                 :         40 :   size_t *bufcntp = d->bufcntp;
     659                 :            : 
     660         [ -  + ]:         40 :   if (*bufcntp + 7 > d->bufsize)
     661                 :          0 :     return *bufcntp + 7 - d->bufsize;
     662                 :            : 
     663                 :         40 :   memcpy (&d->bufp[*bufcntp], "(%dx)", 5);
     664                 :         40 :   *bufcntp += 5;
     665                 :            : 
     666                 :         40 :   return 0;
     667                 :            : }
     668                 :            : 
     669                 :            : 
     670                 :            : static int
     671                 :         80 : FCT_es_di (struct output_data *d)
     672                 :            : {
     673                 :         80 :   size_t *bufcntp = d->bufcntp;
     674                 :         80 :   size_t avail = d->bufsize - *bufcntp;
     675         [ -  + ]:         80 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "%%es:(%%%sdi)",
     676                 :            : #ifdef X86_64
     677         [ +  - ]:         40 :                          *d->prefixes & idx_addr16 ? "e" : "r"
     678                 :            : #else
     679         [ +  - ]:         40 :                          *d->prefixes & idx_addr16 ? "" : "e"
     680                 :            : #endif
     681                 :            :                          );
     682         [ -  + ]:         80 :   if ((size_t) needed > avail)
     683                 :          0 :     return (size_t) needed - avail;
     684                 :         80 :   *bufcntp += needed;
     685                 :            : 
     686                 :         80 :   return 0;
     687                 :            : }
     688                 :            : 
     689                 :            : 
     690                 :            : static int
     691                 :        488 : FCT_imm (struct output_data *d)
     692                 :            : {
     693                 :        488 :   size_t *bufcntp = d->bufcntp;
     694                 :        488 :   size_t avail = d->bufsize - *bufcntp;
     695                 :        488 :   int needed;
     696         [ +  + ]:        488 :   if (*d->prefixes & has_data16)
     697                 :            :     {
     698         [ +  - ]:         88 :       if (*d->param_start + 2 > d->end)
     699                 :            :         return -1;
     700                 :         88 :       uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
     701                 :         88 :       needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
     702                 :            :     }
     703                 :            :   else
     704                 :            :     {
     705         [ +  - ]:        400 :       if (*d->param_start + 4 > d->end)
     706                 :            :         return -1;
     707                 :        400 :       int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
     708                 :            : #ifdef X86_64
     709         [ +  + ]:        200 :       if (*d->prefixes & has_rex_w)
     710                 :         16 :         needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
     711                 :            :                            (int64_t) word);
     712                 :            :       else
     713                 :            : #endif
     714                 :        384 :         needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
     715                 :            :     }
     716         [ -  + ]:        488 :   if ((size_t) needed > avail)
     717                 :          0 :     return (size_t) needed - avail;
     718                 :        488 :   *bufcntp += needed;
     719                 :        488 :   return 0;
     720                 :            : }
     721                 :            : 
     722                 :            : 
     723                 :            : static int
     724                 :        900 : FCT_imm$w (struct output_data *d)
     725                 :            : {
     726         [ +  + ]:        900 :   if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0)
     727                 :        488 :     return FCT_imm (d);
     728                 :            : 
     729                 :        412 :   size_t *bufcntp = d->bufcntp;
     730                 :        412 :   size_t avail = d->bufsize - *bufcntp;
     731         [ +  - ]:        412 :   if (*d->param_start>= d->end)
     732                 :            :     return -1;
     733                 :        412 :   uint_fast8_t word = *(*d->param_start)++;
     734         [ -  + ]:        412 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIxFAST8, word);
     735         [ -  + ]:        412 :   if ((size_t) needed > avail)
     736                 :          0 :     return (size_t) needed - avail;
     737                 :        412 :   *bufcntp += needed;
     738                 :        412 :   return 0;
     739                 :            : }
     740                 :            : 
     741                 :            : 
     742                 :            : #ifdef X86_64
     743                 :            : static int
     744                 :        108 : FCT_imm64$w (struct output_data *d)
     745                 :            : {
     746         [ +  + ]:        108 :   if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) == 0
     747         [ +  + ]:         72 :       || (*d->prefixes & has_data16) != 0)
     748                 :         68 :     return FCT_imm$w (d);
     749                 :            : 
     750                 :         40 :   size_t *bufcntp = d->bufcntp;
     751                 :         40 :   size_t avail = d->bufsize - *bufcntp;
     752                 :         40 :   int needed;
     753         [ +  + ]:         40 :   if (*d->prefixes & has_rex_w)
     754                 :            :     {
     755         [ +  - ]:          4 :       if (*d->param_start + 8 > d->end)
     756                 :            :         return -1;
     757                 :          4 :       uint64_t word = read_8ubyte_unaligned_inc (*d->param_start);
     758                 :          4 :       needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, word);
     759                 :            :     }
     760                 :            :   else
     761                 :            :     {
     762         [ +  - ]:         36 :       if (*d->param_start + 4 > d->end)
     763                 :            :         return -1;
     764                 :         36 :       int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
     765                 :         36 :       needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
     766                 :            :     }
     767         [ -  + ]:         40 :   if ((size_t) needed > avail)
     768                 :          0 :     return (size_t) needed - avail;
     769                 :         40 :   *bufcntp += needed;
     770                 :         40 :   return 0;
     771                 :            : }
     772                 :            : #endif
     773                 :            : 
     774                 :            : 
     775                 :            : static int
     776                 :         24 : FCT_imms (struct output_data *d)
     777                 :            : {
     778                 :         24 :   size_t *bufcntp = d->bufcntp;
     779                 :         24 :   size_t avail = d->bufsize - *bufcntp;
     780         [ +  - ]:         24 :   if (*d->param_start>= d->end)
     781                 :            :     return -1;
     782                 :         24 :   int8_t byte = *(*d->param_start)++;
     783                 :            : #ifdef X86_64
     784         [ -  + ]:         12 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
     785                 :            :                          (int64_t) byte);
     786                 :            : #else
     787         [ -  + ]:         12 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
     788                 :            :                          (int32_t) byte);
     789                 :            : #endif
     790         [ -  + ]:         24 :   if ((size_t) needed > avail)
     791                 :          0 :     return (size_t) needed - avail;
     792                 :         24 :   *bufcntp += needed;
     793                 :         24 :   return 0;
     794                 :            : }
     795                 :            : 
     796                 :            : 
     797                 :            : static int
     798                 :         44 : FCT_imm$s (struct output_data *d)
     799                 :            : {
     800                 :         44 :   uint_fast8_t opcode = d->data[d->opoff2 / 8];
     801                 :         44 :   size_t *bufcntp = d->bufcntp;
     802                 :         44 :   size_t avail = d->bufsize - *bufcntp;
     803         [ +  + ]:         44 :   if ((opcode & 2) != 0)
     804                 :         24 :     return FCT_imms (d);
     805                 :            : 
     806         [ +  - ]:         20 :   if ((*d->prefixes & has_data16) == 0)
     807                 :            :     {
     808         [ +  - ]:         20 :       if (*d->param_start + 4 > d->end)
     809                 :            :         return -1;
     810                 :         20 :       int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
     811                 :            : #ifdef X86_64
     812         [ -  + ]:         10 :       int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
     813                 :            :                              (int64_t) word);
     814                 :            : #else
     815         [ -  + ]:         10 :       int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
     816                 :            : #endif
     817         [ -  + ]:         20 :       if ((size_t) needed > avail)
     818                 :          0 :         return (size_t) needed - avail;
     819                 :         20 :       *bufcntp += needed;
     820                 :            :     }
     821                 :            :   else
     822                 :            :     {
     823         [ #  # ]:          0 :       if (*d->param_start + 2 > d->end)
     824                 :            :         return -1;
     825                 :          0 :       uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
     826         [ #  # ]:          0 :       int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
     827         [ #  # ]:          0 :       if ((size_t) needed > avail)
     828                 :          0 :         return (size_t) needed - avail;
     829                 :          0 :       *bufcntp += needed;
     830                 :            :     }
     831                 :            :   return 0;
     832                 :            : }
     833                 :            : 
     834                 :            : 
     835                 :            : static int
     836                 :         20 : FCT_imm16 (struct output_data *d)
     837                 :            : {
     838         [ +  - ]:         20 :   if (*d->param_start + 2 > d->end)
     839                 :            :     return -1;
     840                 :         20 :   uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
     841                 :         20 :   size_t *bufcntp = d->bufcntp;
     842                 :         20 :   size_t avail = d->bufsize - *bufcntp;
     843         [ -  + ]:         20 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
     844         [ -  + ]:         20 :   if ((size_t) needed > avail)
     845                 :          0 :     return (size_t) needed - avail;
     846                 :         20 :   *bufcntp += needed;
     847                 :         20 :   return 0;
     848                 :            : }
     849                 :            : 
     850                 :            : 
     851                 :            : static int
     852                 :        216 : FCT_imms8 (struct output_data *d)
     853                 :            : {
     854                 :        216 :   size_t *bufcntp = d->bufcntp;
     855                 :        216 :   size_t avail = d->bufsize - *bufcntp;
     856         [ +  - ]:        216 :   if (*d->param_start >= d->end)
     857                 :            :     return -1;
     858                 :        216 :   int_fast8_t byte = *(*d->param_start)++;
     859                 :        216 :   int needed;
     860                 :            : #ifdef X86_64
     861         [ +  + ]:        124 :   if (*d->prefixes & has_rex_w)
     862                 :         16 :     needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
     863                 :            :                        (int64_t) byte);
     864                 :            :   else
     865                 :            : #endif
     866         [ -  + ]:        200 :     needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
     867                 :            :                        (int32_t) byte);
     868         [ -  + ]:        216 :   if ((size_t) needed > avail)
     869                 :          0 :     return (size_t) needed - avail;
     870                 :        216 :   *bufcntp += needed;
     871                 :        216 :   return 0;
     872                 :            : }
     873                 :            : 
     874                 :            : 
     875                 :            : static int
     876                 :       1876 : FCT_imm8 (struct output_data *d)
     877                 :            : {
     878                 :       1876 :   size_t *bufcntp = d->bufcntp;
     879                 :       1876 :   size_t avail = d->bufsize - *bufcntp;
     880         [ +  - ]:       1876 :   if (*d->param_start >= d->end)
     881                 :            :     return -1;
     882                 :       1876 :   uint_fast8_t byte = *(*d->param_start)++;
     883         [ -  + ]:       1876 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
     884                 :            :                          (uint32_t) byte);
     885         [ -  + ]:       1876 :   if ((size_t) needed > avail)
     886                 :          0 :     return (size_t) needed - avail;
     887                 :       1876 :   *bufcntp += needed;
     888                 :       1876 :   return 0;
     889                 :            : }
     890                 :            : 
     891                 :            : 
     892                 :            : static int
     893                 :         80 : FCT_rel (struct output_data *d)
     894                 :            : {
     895                 :         80 :   size_t *bufcntp = d->bufcntp;
     896                 :         80 :   size_t avail = d->bufsize - *bufcntp;
     897         [ +  - ]:         80 :   if (*d->param_start + 4 > d->end)
     898                 :            :     return -1;
     899                 :         80 :   int32_t rel = read_4sbyte_unaligned_inc (*d->param_start);
     900                 :            : #ifdef X86_64
     901                 :         40 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx64,
     902                 :         40 :                          (uint64_t) (d->addr + rel
     903         [ -  + ]:         40 :                                      + (*d->param_start - d->data)));
     904                 :            : #else
     905                 :         40 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32,
     906                 :         40 :                          (uint32_t) (d->addr + rel
     907         [ -  + ]:         40 :                                      + (*d->param_start - d->data)));
     908                 :            : #endif
     909         [ -  + ]:         80 :   if ((size_t) needed > avail)
     910                 :          0 :     return (size_t) needed - avail;
     911                 :         80 :   *bufcntp += needed;
     912                 :         80 :   return 0;
     913                 :            : }
     914                 :            : 
     915                 :            : 
     916                 :            : static int
     917                 :       4064 : FCT_mmxreg (struct output_data *d)
     918                 :            : {
     919                 :       4064 :   uint_fast8_t byte = d->data[d->opoff1 / 8];
     920         [ -  + ]:       4064 :   assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5);
     921                 :       4064 :   byte = (byte >> (5 - d->opoff1 % 8)) & 7;
     922                 :       4064 :   size_t *bufcntp =  d->bufcntp;
     923                 :       4064 :   size_t avail = d->bufsize - *bufcntp;
     924         [ -  + ]:       4064 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte);
     925         [ -  + ]:       4064 :   if ((size_t) needed > avail)
     926                 :          0 :     return needed - avail;
     927                 :       4064 :   *bufcntp += needed;
     928                 :       4064 :   return 0;
     929                 :            : }
     930                 :            : 
     931                 :            : 
     932                 :            : static int
     933                 :       2706 : FCT_mod$r_m (struct output_data *d)
     934                 :            : {
     935         [ -  + ]:       2706 :   assert (d->opoff1 % 8 == 0);
     936                 :       2706 :   uint_fast8_t modrm = d->data[d->opoff1 / 8];
     937         [ +  + ]:       2706 :   if ((modrm & 0xc0) == 0xc0)
     938                 :            :     {
     939                 :        648 :       int prefixes = *d->prefixes;
     940         [ +  - ]:        648 :       if (prefixes & has_addr16)
     941                 :            :         return -1;
     942                 :            : 
     943                 :        648 :       int is_16bit = (prefixes & has_data16) != 0;
     944                 :            : 
     945                 :        648 :       size_t *bufcntp = d->bufcntp;
     946                 :        648 :       char *bufp = d->bufp;
     947         [ -  + ]:        648 :       if (*bufcntp + 5 - is_16bit > d->bufsize)
     948                 :          0 :         return *bufcntp + 5 - is_16bit - d->bufsize;
     949                 :        648 :       bufp[(*bufcntp)++] = '%';
     950                 :            : 
     951                 :        648 :       char *cp;
     952                 :            : #ifdef X86_64
     953   [ -  +  -  - ]:        304 :       if ((prefixes & has_rex_b) != 0 && !is_16bit)
     954                 :            :         {
     955         [ #  # ]:          0 :           cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]);
     956         [ #  # ]:          0 :           if ((prefixes & has_rex_w) == 0)
     957                 :          0 :             *cp++ = 'd';
     958                 :            :         }
     959                 :            :       else
     960                 :            : #endif
     961                 :            :         {
     962         [ +  - ]:        648 :           cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit);
     963                 :            : #ifdef X86_64
     964         [ +  - ]:        304 :           if ((prefixes & has_rex_w) != 0)
     965                 :          0 :             bufp[*bufcntp] = 'r';
     966                 :            : #endif
     967                 :            :         }
     968                 :        648 :       *bufcntp = cp - bufp;
     969                 :        648 :       return 0;
     970                 :            :     }
     971                 :            : 
     972                 :       2058 :   return general_mod$r_m (d);
     973                 :            : }
     974                 :            : 
     975                 :            : 
     976                 :            : #ifndef X86_64
     977                 :            : static int
     978                 :          4 : FCT_moda$r_m (struct output_data *d)
     979                 :            : {
     980         [ -  + ]:          4 :   assert (d->opoff1 % 8 == 0);
     981                 :          4 :   uint_fast8_t modrm = d->data[d->opoff1 / 8];
     982         [ -  + ]:          4 :   if ((modrm & 0xc0) == 0xc0)
     983                 :            :     {
     984         [ #  # ]:          0 :       if (*d->prefixes & has_addr16)
     985                 :            :         return -1;
     986                 :            : 
     987                 :          0 :       size_t *bufcntp = d->bufcntp;
     988         [ #  # ]:          0 :       if (*bufcntp + 3 > d->bufsize)
     989                 :          0 :         return *bufcntp + 3 - d->bufsize;
     990                 :            : 
     991                 :          0 :       memcpy (&d->bufp[*bufcntp], "???", 3);
     992                 :          0 :       *bufcntp += 3;
     993                 :            : 
     994                 :          0 :       return 0;
     995                 :            :     }
     996                 :            : 
     997                 :          4 :   return general_mod$r_m (d);
     998                 :            : }
     999                 :            : #endif
    1000                 :            : 
    1001                 :            : 
    1002                 :            : #ifdef X86_64
    1003                 :            : static const char rex_8bit[8][3] =
    1004                 :            :   {
    1005                 :            :     [0] = "a", [1] = "c", [2] = "d", [3] = "b",
    1006                 :            :     [4] = "sp", [5] = "bp", [6] = "si", [7] = "di"
    1007                 :            :   };
    1008                 :            : #endif
    1009                 :            : 
    1010                 :            : 
    1011                 :            : static int
    1012                 :      16098 : FCT_mod$r_m$w (struct output_data *d)
    1013                 :            : {
    1014         [ -  + ]:      16098 :   assert (d->opoff1 % 8 == 0);
    1015                 :      16098 :   const uint8_t *data = d->data;
    1016                 :      16098 :   uint_fast8_t modrm = data[d->opoff1 / 8];
    1017         [ +  + ]:      16098 :   if ((modrm & 0xc0) == 0xc0)
    1018                 :            :     {
    1019                 :       1372 :       int prefixes = *d->prefixes;
    1020                 :            : 
    1021         [ +  - ]:       1372 :       if (prefixes & has_addr16)
    1022                 :            :         return -1;
    1023                 :            : 
    1024                 :       1372 :       size_t *bufcntp = d->bufcntp;
    1025                 :       1372 :       char *bufp = d->bufp;
    1026         [ -  + ]:       1372 :       if (*bufcntp + 5 > d->bufsize)
    1027                 :          0 :         return *bufcntp + 5 - d->bufsize;
    1028                 :            : 
    1029         [ +  + ]:       1372 :       if ((data[d->opoff3 / 8] & (1 << (7 - (d->opoff3 & 7)))) == 0)
    1030                 :            :         {
    1031                 :        492 :           bufp[(*bufcntp)++] = '%';
    1032                 :            : 
    1033                 :            : #ifdef X86_64
    1034         [ -  + ]:        246 :           if (prefixes & has_rex)
    1035                 :            :             {
    1036         [ #  # ]:          0 :               if (prefixes & has_rex_r)
    1037                 :          0 :                 *bufcntp += snprintf (bufp + *bufcntp, d->bufsize - *bufcntp,
    1038                 :          0 :                                       "r%db", 8 + (modrm & 7));
    1039                 :            :               else
    1040                 :            :                 {
    1041                 :          0 :                   char *cp = stpcpy (bufp + *bufcntp, hiregs[modrm & 7]);
    1042                 :          0 :                   *cp++ = 'l';
    1043                 :          0 :                   *bufcntp = cp - bufp;
    1044                 :            :                 }
    1045                 :            :             }
    1046                 :            :           else
    1047                 :            : #endif
    1048                 :            :             {
    1049                 :        492 :               bufp[(*bufcntp)++] = "acdb"[modrm & 3];
    1050                 :        492 :               bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2];
    1051                 :            :             }
    1052                 :            :         }
    1053                 :            :       else
    1054                 :            :         {
    1055                 :        880 :           int is_16bit = (prefixes & has_data16) != 0;
    1056                 :            : 
    1057                 :        880 :           bufp[(*bufcntp)++] = '%';
    1058                 :            : 
    1059                 :        880 :           char *cp;
    1060                 :            : #ifdef X86_64
    1061   [ +  +  +  - ]:        504 :           if ((prefixes & has_rex_b) != 0 && !is_16bit)
    1062                 :            :             {
    1063         [ +  - ]:        128 :               cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]);
    1064         [ +  - ]:        128 :               if ((prefixes & has_rex_w) == 0)
    1065                 :        128 :                 *cp++ = 'd';
    1066                 :            :             }
    1067                 :            :           else
    1068                 :            : #endif
    1069                 :            :             {
    1070         [ +  - ]:        752 :               cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit);
    1071                 :            : #ifdef X86_64
    1072         [ +  - ]:        376 :               if ((prefixes & has_rex_w) != 0)
    1073                 :          0 :                 bufp[*bufcntp] = 'r';
    1074                 :            : #endif
    1075                 :            :             }
    1076                 :        880 :           *bufcntp = cp - bufp;
    1077                 :            :         }
    1078                 :       1372 :       return 0;
    1079                 :            :     }
    1080                 :            : 
    1081                 :      14726 :   return general_mod$r_m (d);
    1082                 :            : }
    1083                 :            : 
    1084                 :            : 
    1085                 :            : static int
    1086                 :        320 : FCT_mod$8r_m (struct output_data *d)
    1087                 :            : {
    1088         [ -  + ]:        320 :   assert (d->opoff1 % 8 == 0);
    1089                 :        320 :   uint_fast8_t modrm = d->data[d->opoff1 / 8];
    1090         [ +  + ]:        320 :   if ((modrm & 0xc0) == 0xc0)
    1091                 :            :     {
    1092                 :         80 :       size_t *bufcntp = d->bufcntp;
    1093                 :         80 :       char *bufp = d->bufp;
    1094         [ -  + ]:         80 :       if (*bufcntp + 3 > d->bufsize)
    1095                 :          0 :         return *bufcntp + 3 - d->bufsize;
    1096                 :         80 :       bufp[(*bufcntp)++] = '%';
    1097                 :         80 :       bufp[(*bufcntp)++] = "acdb"[modrm & 3];
    1098                 :         80 :       bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2];
    1099                 :         80 :       return 0;
    1100                 :            :     }
    1101                 :            : 
    1102                 :        240 :   return general_mod$r_m (d);
    1103                 :            : }
    1104                 :            : 
    1105                 :            : 
    1106                 :            : static int
    1107                 :        144 : FCT_mod$16r_m (struct output_data *d)
    1108                 :            : {
    1109         [ -  + ]:        144 :   assert (d->opoff1 % 8 == 0);
    1110                 :        144 :   uint_fast8_t modrm = d->data[d->opoff1 / 8];
    1111         [ +  + ]:        144 :   if ((modrm & 0xc0) == 0xc0)
    1112                 :            :     {
    1113         [ -  + ]:         36 :       assert (d->opoff1 / 8 == d->opoff2 / 8);
    1114                 :            :       //uint_fast8_t byte = data[opoff2 / 8] & 7;
    1115                 :         36 :       uint_fast8_t byte = modrm & 7;
    1116                 :            : 
    1117                 :         36 :       size_t *bufcntp = d->bufcntp;
    1118         [ -  + ]:         36 :       if (*bufcntp + 3 > d->bufsize)
    1119                 :          0 :         return *bufcntp + 3 - d->bufsize;
    1120                 :         36 :       d->bufp[(*bufcntp)++] = '%';
    1121                 :         36 :       memcpy (&d->bufp[*bufcntp], dregs[byte] + 1, sizeof (dregs[0]) - 1);
    1122                 :         36 :       *bufcntp += 2;
    1123                 :         36 :       return 0;
    1124                 :            :     }
    1125                 :            : 
    1126                 :        108 :   return general_mod$r_m (d);
    1127                 :            : }
    1128                 :            : 
    1129                 :            : 
    1130                 :            : #ifdef X86_64
    1131                 :            : static int
    1132                 :         72 : FCT_mod$64r_m (struct output_data *d)
    1133                 :            : {
    1134         [ -  + ]:         72 :   assert (d->opoff1 % 8 == 0);
    1135                 :         72 :   uint_fast8_t modrm = d->data[d->opoff1 / 8];
    1136         [ +  + ]:         72 :   if ((modrm & 0xc0) == 0xc0)
    1137                 :            :     {
    1138         [ -  + ]:         36 :       assert (d->opoff1 / 8 == d->opoff2 / 8);
    1139                 :            :       //uint_fast8_t byte = data[opoff2 / 8] & 7;
    1140                 :         36 :       uint_fast8_t byte = modrm & 7;
    1141                 :            : 
    1142                 :         36 :       size_t *bufcntp = d->bufcntp;
    1143         [ -  + ]:         36 :       if (*bufcntp + 4 > d->bufsize)
    1144                 :          0 :         return *bufcntp + 4 - d->bufsize;
    1145                 :         36 :       char *cp = &d->bufp[*bufcntp];
    1146                 :         36 :       *cp++ = '%';
    1147                 :        108 :       cp = stpcpy (cp,
    1148         [ -  + ]:         36 :                    (*d->prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]);
    1149                 :         36 :       *bufcntp = cp - d->bufp;
    1150                 :         36 :       return 0;
    1151                 :            :     }
    1152                 :            : 
    1153                 :         36 :   return general_mod$r_m (d);
    1154                 :            : }
    1155                 :            : #else
    1156                 :            : #define FCT_mod$64r_m FCT_mod$r_m
    1157                 :            : #endif
    1158                 :            : 
    1159                 :            : 
    1160                 :            : static int
    1161                 :      14292 : FCT_reg (struct output_data *d)
    1162                 :            : {
    1163                 :      14292 :   uint_fast8_t byte = d->data[d->opoff1 / 8];
    1164         [ -  + ]:      14292 :   assert (d->opoff1 % 8 + 3 <= 8);
    1165                 :      14292 :   byte >>= 8 - (d->opoff1 % 8 + 3);
    1166                 :      14292 :   byte &= 7;
    1167                 :      14292 :   int is_16bit = (*d->prefixes & has_data16) != 0;
    1168                 :      14292 :   size_t *bufcntp = d->bufcntp;
    1169         [ -  + ]:      14292 :   if (*bufcntp + 5 > d->bufsize)
    1170                 :          0 :     return *bufcntp + 5 - d->bufsize;
    1171                 :      14292 :   d->bufp[(*bufcntp)++] = '%';
    1172                 :            : #ifdef X86_64
    1173   [ +  +  +  - ]:      10978 :   if ((*d->prefixes & has_rex_r) != 0 && !is_16bit)
    1174                 :            :     {
    1175         [ +  + ]:       2120 :       *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
    1176                 :            :                             8 + byte);
    1177         [ +  + ]:       2120 :       if ((*d->prefixes & has_rex_w) == 0)
    1178                 :       2052 :         d->bufp[(*bufcntp)++] = 'd';
    1179                 :            :     }
    1180                 :            :   else
    1181                 :            : #endif
    1182                 :            :     {
    1183         [ +  + ]:      12172 :       memcpy (&d->bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit);
    1184                 :            : #ifdef X86_64
    1185   [ +  +  +  - ]:       8858 :       if ((*d->prefixes & has_rex_w) != 0 && !is_16bit)
    1186                 :       1986 :         d->bufp[*bufcntp] = 'r';
    1187                 :            : #endif
    1188                 :      12172 :       *bufcntp += 3 - is_16bit;
    1189                 :            :     }
    1190                 :       3314 :   return 0;
    1191                 :            : }
    1192                 :            : 
    1193                 :            : 
    1194                 :            : #ifdef X86_64
    1195                 :            : static int
    1196                 :         22 : FCT_oreg (struct output_data *d)
    1197                 :            : {
    1198                 :            :   /* Special form where register comes from opcode.  The rex.B bit is used,
    1199                 :            :      rex.R and rex.X are ignored.  */
    1200                 :         22 :   int save_prefixes = *d->prefixes;
    1201                 :            : 
    1202                 :         22 :   *d->prefixes = ((save_prefixes & ~has_rex_r)
    1203                 :         22 :                   | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b)));
    1204                 :            : 
    1205                 :         22 :   int r = FCT_reg (d);
    1206                 :            : 
    1207                 :         22 :   *d->prefixes = save_prefixes;
    1208                 :            : 
    1209                 :         22 :   return r;
    1210                 :            : }
    1211                 :            : #endif
    1212                 :            : 
    1213                 :            : 
    1214                 :            : static int
    1215                 :       1158 : FCT_reg64 (struct output_data *d)
    1216                 :            : {
    1217                 :       1158 :   uint_fast8_t byte = d->data[d->opoff1 / 8];
    1218         [ -  + ]:       1158 :   assert (d->opoff1 % 8 + 3 <= 8);
    1219                 :       1158 :   byte >>= 8 - (d->opoff1 % 8 + 3);
    1220                 :       1158 :   byte &= 7;
    1221         [ +  - ]:       1158 :   if ((*d->prefixes & has_data16) != 0)
    1222                 :            :     return -1;
    1223                 :       1158 :   size_t *bufcntp = d->bufcntp;
    1224         [ -  + ]:       1158 :   if (*bufcntp + 5 > d->bufsize)
    1225                 :          0 :     return *bufcntp + 5 - d->bufsize;
    1226                 :       1158 :   d->bufp[(*bufcntp)++] = '%';
    1227                 :            : #ifdef X86_64
    1228         [ -  + ]:        602 :   if ((*d->prefixes & has_rex_r) != 0)
    1229                 :            :     {
    1230         [ #  # ]:          0 :       *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
    1231                 :            :                             8 + byte);
    1232         [ #  # ]:          0 :       if ((*d->prefixes & has_rex_w) == 0)
    1233                 :          0 :         d->bufp[(*bufcntp)++] = 'd';
    1234                 :            :     }
    1235                 :            :   else
    1236                 :            : #endif
    1237                 :            :     {
    1238                 :       1158 :       memcpy (&d->bufp[*bufcntp], aregs[byte], 3);
    1239                 :       1158 :       *bufcntp += 3;
    1240                 :            :     }
    1241                 :        556 :   return 0;
    1242                 :            : }
    1243                 :            : 
    1244                 :            : 
    1245                 :            : static int
    1246                 :      14650 : FCT_reg$w (struct output_data *d)
    1247                 :            : {
    1248         [ +  + ]:      14650 :   if (d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7))))
    1249                 :      13176 :     return FCT_reg (d);
    1250                 :            : 
    1251                 :       1474 :   uint_fast8_t byte = d->data[d->opoff1 / 8];
    1252         [ -  + ]:       1474 :   assert (d->opoff1 % 8 + 3 <= 8);
    1253                 :       1474 :   byte >>= 8 - (d->opoff1 % 8 + 3);
    1254                 :       1474 :   byte &= 7;
    1255                 :            : 
    1256                 :       1474 :   size_t *bufcntp = d->bufcntp;
    1257         [ -  + ]:       1474 :   if (*bufcntp + 4 > d->bufsize)
    1258                 :          0 :     return *bufcntp + 4 - d->bufsize;
    1259                 :            : 
    1260                 :       1474 :   d->bufp[(*bufcntp)++] = '%';
    1261                 :            : 
    1262                 :            : #ifdef X86_64
    1263         [ +  + ]:        768 :   if (*d->prefixes & has_rex)
    1264                 :            :     {
    1265         [ +  + ]:         48 :       if (*d->prefixes & has_rex_r)
    1266                 :         28 :         *bufcntp += snprintf (d->bufp + *bufcntp, d->bufsize - *bufcntp,
    1267                 :            :                               "r%db", 8 + byte);
    1268                 :            :       else
    1269                 :            :         {
    1270                 :         20 :           char* cp = stpcpy (d->bufp + *bufcntp, rex_8bit[byte]);
    1271                 :         20 :           *cp++ = 'l';
    1272                 :         20 :           *bufcntp = cp - d->bufp;
    1273                 :            :         }
    1274                 :            :     }
    1275                 :            :   else
    1276                 :            : #endif
    1277                 :            :     {
    1278                 :       1426 :       d->bufp[(*bufcntp)++] = "acdb"[byte & 3];
    1279                 :       1426 :       d->bufp[(*bufcntp)++] = "lh"[byte >> 2];
    1280                 :            :     }
    1281                 :        706 :   return 0;
    1282                 :            : }
    1283                 :            : 
    1284                 :            : 
    1285                 :            : #ifdef X86_64
    1286                 :            : static int
    1287                 :        108 : FCT_oreg$w (struct output_data *d)
    1288                 :            : {
    1289                 :            :   /* Special form where register comes from opcode.  The rex.B bit is used,
    1290                 :            :      rex.R and rex.X are ignored.  */
    1291                 :        108 :   int save_prefixes = *d->prefixes;
    1292                 :            : 
    1293                 :        108 :   *d->prefixes = ((save_prefixes & ~has_rex_r)
    1294                 :        108 :                   | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b)));
    1295                 :            : 
    1296                 :        108 :   int r = FCT_reg$w (d);
    1297                 :            : 
    1298                 :        108 :   *d->prefixes = save_prefixes;
    1299                 :            : 
    1300                 :        108 :   return r;
    1301                 :            : }
    1302                 :            : #endif
    1303                 :            : 
    1304                 :            : 
    1305                 :            : static int
    1306                 :       1248 : FCT_freg (struct output_data *d)
    1307                 :            : {
    1308         [ -  + ]:       1248 :   assert (d->opoff1 / 8 == 1);
    1309         [ -  + ]:       1248 :   assert (d->opoff1 % 8 == 5);
    1310                 :       1248 :   size_t *bufcntp = d->bufcntp;
    1311                 :       1248 :   size_t avail = d->bufsize - *bufcntp;
    1312                 :       1248 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "%%st(%" PRIx32 ")",
    1313         [ -  + ]:       1248 :                          (uint32_t) (d->data[1] & 7));
    1314         [ -  + ]:       1248 :   if ((size_t) needed > avail)
    1315                 :          0 :     return (size_t) needed - avail;
    1316                 :       1248 :   *bufcntp += needed;
    1317                 :       1248 :   return 0;
    1318                 :            : }
    1319                 :            : 
    1320                 :            : 
    1321                 :            : #ifndef X86_64
    1322                 :            : static int
    1323                 :          8 : FCT_reg16 (struct output_data *d)
    1324                 :            : {
    1325         [ +  - ]:          8 :   if (*d->prefixes & has_data16)
    1326                 :            :     return -1;
    1327                 :            : 
    1328                 :          8 :   *d->prefixes |= has_data16;
    1329                 :          8 :   return FCT_reg (d);
    1330                 :            : }
    1331                 :            : #endif
    1332                 :            : 
    1333                 :            : 
    1334                 :            : static int
    1335                 :          6 : FCT_sel (struct output_data *d)
    1336                 :            : {
    1337         [ -  + ]:          6 :   assert (d->opoff1 % 8 == 0);
    1338         [ -  + ]:          6 :   assert (d->opoff1 / 8 == 5);
    1339         [ +  - ]:          6 :   if (*d->param_start + 2 >= d->end)
    1340                 :            :     return -1;
    1341                 :          6 :   *d->param_start += 2;
    1342                 :          6 :   uint16_t absval = read_2ubyte_unaligned (&d->data[5]);
    1343                 :            : 
    1344                 :          6 :   size_t *bufcntp = d->bufcntp;
    1345                 :          6 :   size_t avail = d->bufsize - *bufcntp;
    1346         [ -  + ]:          6 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, absval);
    1347         [ -  + ]:          6 :   if ((size_t) needed > avail)
    1348                 :          0 :     return needed - avail;
    1349                 :          6 :   *bufcntp += needed;
    1350                 :          6 :   return 0;
    1351                 :            : }
    1352                 :            : 
    1353                 :            : 
    1354                 :            : static int
    1355                 :         14 : FCT_sreg2 (struct output_data *d)
    1356                 :            : {
    1357                 :         14 :   uint_fast8_t byte = d->data[d->opoff1 / 8];
    1358         [ -  + ]:         14 :   assert (d->opoff1 % 8 + 3 <= 8);
    1359                 :         14 :   byte >>= 8 - (d->opoff1 % 8 + 2);
    1360                 :            : 
    1361                 :         14 :   size_t *bufcntp = d->bufcntp;
    1362                 :         14 :   char *bufp = d->bufp;
    1363         [ -  + ]:         14 :   if (*bufcntp + 3 > d->bufsize)
    1364                 :          0 :     return *bufcntp + 3 - d->bufsize;
    1365                 :            : 
    1366                 :         14 :   bufp[(*bufcntp)++] = '%';
    1367                 :         14 :   bufp[(*bufcntp)++] = "ecsd"[byte & 3];
    1368                 :         14 :   bufp[(*bufcntp)++] = 's';
    1369                 :            : 
    1370                 :         14 :   return 0;
    1371                 :            : }
    1372                 :            : 
    1373                 :            : 
    1374                 :            : static int
    1375                 :        260 : FCT_sreg3 (struct output_data *d)
    1376                 :            : {
    1377                 :        260 :   uint_fast8_t byte = d->data[d->opoff1 / 8];
    1378         [ -  + ]:        260 :   assert (d->opoff1 % 8 + 4 <= 8);
    1379                 :        260 :   byte >>= 8 - (d->opoff1 % 8 + 3);
    1380                 :            : 
    1381         [ +  - ]:        260 :   if ((byte & 7) >= 6)
    1382                 :            :     return -1;
    1383                 :            : 
    1384                 :        260 :   size_t *bufcntp = d->bufcntp;
    1385                 :        260 :   char *bufp = d->bufp;
    1386         [ -  + ]:        260 :   if (*bufcntp + 3 > d->bufsize)
    1387                 :          0 :     return *bufcntp + 3 - d->bufsize;
    1388                 :            : 
    1389                 :        260 :   bufp[(*bufcntp)++] = '%';
    1390                 :        260 :   bufp[(*bufcntp)++] = "ecsdfg"[byte & 7];
    1391                 :        260 :   bufp[(*bufcntp)++] = 's';
    1392                 :            : 
    1393                 :        260 :   return 0;
    1394                 :            : }
    1395                 :            : 
    1396                 :            : 
    1397                 :            : static int
    1398                 :       1424 : FCT_string (struct output_data *d __attribute__ ((unused)))
    1399                 :            : {
    1400                 :       1424 :   return 0;
    1401                 :            : }
    1402                 :            : 
    1403                 :            : 
    1404                 :            : static int
    1405                 :      11424 : FCT_xmmreg (struct output_data *d)
    1406                 :            : {
    1407                 :      11424 :   uint_fast8_t byte = d->data[d->opoff1 / 8];
    1408         [ -  + ]:      11424 :   assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5);
    1409                 :      11424 :   byte = (byte >> (5 - d->opoff1 % 8)) & 7;
    1410                 :            : 
    1411                 :      11424 :   size_t *bufcntp = d->bufcntp;
    1412                 :      11424 :   size_t avail = d->bufsize - *bufcntp;
    1413         [ -  + ]:      11424 :   int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, byte);
    1414         [ -  + ]:      11424 :   if ((size_t) needed > avail)
    1415                 :          0 :     return needed - avail;
    1416                 :      11424 :   *bufcntp += needed;
    1417                 :      11424 :   return 0;
    1418                 :            : }

Generated by: LCOV version 1.16