PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/opcache/jit/dynasm - dasm_x86.h (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 258 268 96.3 %
Date: 2019-05-06 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             : ** DynASM x86 encoding engine.
       3             : ** Copyright (C) 2005-2016 Mike Pall. All rights reserved.
       4             : ** Released under the MIT license. See dynasm.lua for full copyright notice.
       5             : */
       6             : 
       7             : #include <stddef.h>
       8             : #include <stdarg.h>
       9             : #include <string.h>
      10             : #include <stdlib.h>
      11             : 
      12             : #define DASM_ARCH               "x86"
      13             : 
      14             : #ifndef DASM_EXTERN
      15             : #define DASM_EXTERN(a,b,c,d)    0
      16             : #endif
      17             : 
      18             : /* Action definitions. DASM_STOP must be 255. */
      19             : enum {
      20             :   DASM_DISP = 233,
      21             :   DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
      22             :   DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
      23             :   DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,
      24             :   DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
      25             : };
      26             : 
      27             : /* Maximum number of section buffer positions for a single dasm_put() call. */
      28             : #define DASM_MAXSECPOS          25
      29             : 
      30             : /* DynASM encoder status codes. Action list offset or number are or'ed in. */
      31             : #define DASM_S_OK               0x00000000
      32             : #define DASM_S_NOMEM            0x01000000
      33             : #define DASM_S_PHASE            0x02000000
      34             : #define DASM_S_MATCH_SEC        0x03000000
      35             : #define DASM_S_RANGE_I          0x11000000
      36             : #define DASM_S_RANGE_SEC        0x12000000
      37             : #define DASM_S_RANGE_LG         0x13000000
      38             : #define DASM_S_RANGE_PC         0x14000000
      39             : #define DASM_S_RANGE_VREG       0x15000000
      40             : #define DASM_S_UNDEF_L          0x21000000
      41             : #define DASM_S_UNDEF_PC         0x22000000
      42             : 
      43             : /* Macros to convert positions (8 bit section + 24 bit index). */
      44             : #define DASM_POS2IDX(pos)       ((pos)&0x00ffffff)
      45             : #define DASM_POS2BIAS(pos)      ((pos)&0xff000000)
      46             : #define DASM_SEC2POS(sec)       ((sec)<<24)
      47             : #define DASM_POS2SEC(pos)       ((pos)>>24)
      48             : #define DASM_POS2PTR(D, pos)    (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
      49             : 
      50             : /* Action list type. */
      51             : typedef const unsigned char *dasm_ActList;
      52             : 
      53             : /* Per-section structure. */
      54             : typedef struct dasm_Section {
      55             :   int *rbuf;            /* Biased buffer pointer (negative section bias). */
      56             :   int *buf;             /* True buffer pointer. */
      57             :   size_t bsize;         /* Buffer size in bytes. */
      58             :   int pos;              /* Biased buffer position. */
      59             :   int epos;             /* End of biased buffer position - max single put. */
      60             :   int ofs;              /* Byte offset into section. */
      61             : } dasm_Section;
      62             : 
      63             : /* Core structure holding the DynASM encoding state. */
      64             : struct dasm_State {
      65             :   size_t psize;                 /* Allocated size of this structure. */
      66             :   dasm_ActList actionlist;      /* Current actionlist pointer. */
      67             :   int *lglabels;                /* Local/global chain/pos ptrs. */
      68             :   size_t lgsize;
      69             :   int *pclabels;                /* PC label chains/pos ptrs. */
      70             :   size_t pcsize;
      71             :   void **globals;               /* Array of globals (bias -10). */
      72             :   dasm_Section *section;        /* Pointer to active section. */
      73             :   size_t codesize;              /* Total size of all code sections. */
      74             :   int maxsection;               /* 0 <= sectionidx < maxsection. */
      75             :   int status;                   /* Status code. */
      76             :   dasm_Section sections[1];     /* All sections. Alloc-extended. */
      77             : };
      78             : 
      79             : /* The size of the core structure depends on the max. number of sections. */
      80             : #define DASM_PSZ(ms)    (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
      81             : 
      82             : 
      83             : /* Initialize DynASM state. */
      84         462 : void dasm_init(Dst_DECL, int maxsection)
      85             : {
      86             :   dasm_State *D;
      87         462 :   size_t psz = 0;
      88             :   int i;
      89         462 :   Dst_REF = NULL;
      90         462 :   DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
      91         462 :   D = Dst_REF;
      92         462 :   D->psize = psz;
      93         462 :   D->lglabels = NULL;
      94         462 :   D->lgsize = 0;
      95         462 :   D->pclabels = NULL;
      96         462 :   D->pcsize = 0;
      97         462 :   D->globals = NULL;
      98         462 :   D->maxsection = maxsection;
      99        1386 :   for (i = 0; i < maxsection; i++) {
     100         924 :     D->sections[i].buf = NULL;  /* Need this for pass3. */
     101         924 :     D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
     102         924 :     D->sections[i].bsize = 0;
     103         924 :     D->sections[i].epos = 0;  /* Wrong, but is recalculated after resize. */
     104             :   }
     105         462 : }
     106             : 
     107             : /* Free DynASM state. */
     108         462 : void dasm_free(Dst_DECL)
     109             : {
     110         462 :   dasm_State *D = Dst_REF;
     111             :   int i;
     112        1386 :   for (i = 0; i < D->maxsection; i++)
     113         924 :     if (D->sections[i].buf)
     114         632 :       DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
     115         462 :   if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
     116         462 :   if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
     117         462 :   DASM_M_FREE(Dst, D, D->psize);
     118         462 : }
     119             : 
     120             : /* Setup global label array. Must be called before dasm_setup(). */
     121         462 : void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
     122             : {
     123         462 :   dasm_State *D = Dst_REF;
     124         462 :   D->globals = gl - 10;  /* Negative bias to compensate for locals. */
     125         462 :   DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
     126         462 : }
     127             : 
     128             : /* Grow PC label array. Can be called after dasm_setup(), too. */
     129         287 : void dasm_growpc(Dst_DECL, unsigned int maxpc)
     130             : {
     131         287 :   dasm_State *D = Dst_REF;
     132         287 :   size_t osz = D->pcsize;
     133         287 :   DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
     134         287 :   memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
     135         287 : }
     136             : 
     137             : /* Setup encoder. */
     138        4137 : void dasm_setup(Dst_DECL, const void *actionlist)
     139             : {
     140        4137 :   dasm_State *D = Dst_REF;
     141             :   int i;
     142        4137 :   D->actionlist = (dasm_ActList)actionlist;
     143        4137 :   D->status = DASM_S_OK;
     144        4137 :   D->section = &D->sections[0];
     145        4137 :   memset((void *)D->lglabels, 0, D->lgsize);
     146        4137 :   if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
     147       12411 :   for (i = 0; i < D->maxsection; i++) {
     148        8274 :     D->sections[i].pos = DASM_SEC2POS(i);
     149        8274 :     D->sections[i].ofs = 0;
     150             :   }
     151        4137 : }
     152             : 
     153             : 
     154             : #ifdef DASM_CHECKS
     155             : #define CK(x, st) \
     156             :   do { if (!(x)) { \
     157             :     D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
     158             : #define CKPL(kind, st) \
     159             :   do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
     160             :     D->status=DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
     161             : #else
     162             : #define CK(x, st)       ((void)0)
     163             : #define CKPL(kind, st)  ((void)0)
     164             : #endif
     165             : 
     166             : /* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
     167       58399 : void dasm_put(Dst_DECL, int start, ...)
     168             : {
     169             :   va_list ap;
     170       58399 :   dasm_State *D = Dst_REF;
     171       58399 :   dasm_ActList p = D->actionlist + start;
     172       58399 :   dasm_Section *sec = D->section;
     173       58399 :   int pos = sec->pos, ofs = sec->ofs, mrm = -1;
     174             :   int *b;
     175             : 
     176       58399 :   if (pos >= sec->epos) {
     177        1325 :     DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
     178             :       sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
     179        1325 :     sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
     180        1325 :     sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
     181             :   }
     182             : 
     183       58399 :   b = sec->rbuf;
     184       58399 :   b[pos++] = start;
     185             : 
     186       58399 :   va_start(ap, start);
     187      299606 :   while (1) {
     188      358005 :     int action = *p++;
     189      358005 :     if (action < DASM_DISP) {
     190      190180 :       ofs++;
     191      167825 :     } else if (action <= DASM_REL_A) {
     192       57516 :       int n = va_arg(ap, int);
     193       57516 :       b[pos++] = n;
     194       57516 :       switch (action) {
     195       21251 :       case DASM_DISP:
     196       21251 :         if (n == 0) { if (mrm < 0) mrm = p[-2]; if ((mrm&7) != 5) break; }
     197       20213 :       case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;
     198             :       case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
     199       24403 :       case DASM_IMM_D: ofs += 4; break;
     200           0 :       case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
     201       21265 :       case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
     202         350 :       case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob;
     203         350 :       case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
     204           0 :       case DASM_SPACE: p++; ofs += n; break;
     205           0 :       case DASM_SETLABEL: b[pos-2] = -0x40000000; break;  /* Neg. label ofs. */
     206        7868 :       case DASM_VREG: CK((n&-16) == 0 && (n != 4 || (*p>>5) != 2), RANGE_VREG);
     207        7868 :         if (*p < 0x40 && p[1] == DASM_DISP) mrm = n;
     208        7868 :         if (*p < 0x20 && (n&7) == 4) ofs++;
     209        7868 :         switch ((*p++ >> 3) & 3) {
     210           0 :         case 3: n |= b[pos-3];
     211         860 :         case 2: n |= b[pos-2];
     212        3191 :         case 1: if (n <= 7) { b[pos-1] |= 0x10; ofs--; }
     213             :         }
     214        7868 :         continue;
     215             :       }
     216       49648 :       mrm = -1;
     217             :     } else {
     218             :       int *pl, n;
     219      110309 :       switch (action) {
     220       11887 :       case DASM_REL_LG:
     221             :       case DASM_IMM_LG:
     222       11887 :         n = *p++; pl = D->lglabels + n;
     223             :         /* Bkwd rel or global. */
     224       11887 :         if (n <= 246) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
     225        8724 :         pl -= 246; n = *pl;
     226        8724 :         if (n < 0) n = 0;  /* Start new chain for fwd rel if label exists. */
     227        8724 :         goto linkrel;
     228         508 :       case DASM_REL_PC:
     229         508 :       case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
     230        3671 :       putrel:
     231        3671 :         n = *pl;
     232        3671 :         if (n < 0) {  /* Label exists. Get label pos and store it. */
     233          59 :           b[pos] = -n;
     234             :         } else {
     235        3612 :       linkrel:
     236       12336 :           b[pos] = n;  /* Else link to rel chain, anchored at label. */
     237       12336 :           *pl = pos;
     238             :         }
     239       12395 :         pos++;
     240       12395 :         ofs += 4;  /* Maximum offset needed. */
     241       12395 :         if (action == DASM_REL_LG || action == DASM_REL_PC)
     242       12393 :           b[pos++] = ofs;  /* Store pass1 offset estimate. */
     243       12395 :         break;
     244       12269 :       case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
     245        1580 :       case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
     246       13849 :       putlabel:
     247       13849 :         n = *pl;  /* n > 0: Collapse rel chain and replace with label pos. */
     248       13849 :         while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }
     249       13849 :         *pl = -pos;  /* Label exists now. */
     250       13849 :         b[pos++] = ofs;  /* Store pass1 offset estimate. */
     251       13849 :         break;
     252         287 :       case DASM_ALIGN:
     253         287 :         ofs += *p++;  /* Maximum alignment needed (arg is 2**n-1). */
     254         287 :         b[pos++] = ofs;  /* Store pass1 offset estimate. */
     255         287 :         break;
     256           0 :       case DASM_EXTERN: p += 2; ofs += 4; break;
     257       17771 :       case DASM_ESC: p++; ofs++; break;
     258        7608 :       case DASM_MARK: mrm = p[-2]; break;
     259        4452 :       case DASM_SECTION:
     260        4452 :         n = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n];
     261       58399 :       case DASM_STOP: goto stop;
     262             :       }
     263             :     }
     264             :   }
     265       58399 : stop:
     266       58399 :   va_end(ap);
     267       58399 :   sec->pos = pos;
     268       58399 :   sec->ofs = ofs;
     269       58399 : }
     270             : #undef CK
     271             : 
     272             : /* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */
     273        4137 : int dasm_link(Dst_DECL, size_t *szp)
     274             : {
     275        4137 :   dasm_State *D = Dst_REF;
     276             :   int secnum;
     277        4137 :   int ofs = 0;
     278             : 
     279             : #ifdef DASM_CHECKS
     280             :   *szp = 0;
     281             :   if (D->status != DASM_S_OK) return D->status;
     282             :   {
     283             :     int pc;
     284             :     for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
     285             :       if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
     286             :   }
     287             : #endif
     288             : 
     289             :   { /* Handle globals not defined in this translation unit. */
     290             :     int idx;
     291      227535 :     for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
     292      223398 :       int n = D->lglabels[idx];
     293             :       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
     294      223398 :       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
     295             :     }
     296             :   }
     297             : 
     298             :   /* Combine all code sections. No support for data sections (yet). */
     299       12411 :   for (secnum = 0; secnum < D->maxsection; secnum++) {
     300        8274 :     dasm_Section *sec = D->sections + secnum;
     301        8274 :     int *b = sec->rbuf;
     302        8274 :     int pos = DASM_SEC2POS(secnum);
     303        8274 :     int lastpos = sec->pos;
     304             : 
     305       74947 :     while (pos != lastpos) {
     306       58399 :       dasm_ActList p = D->actionlist + b[pos++];
     307      299606 :       while (1) {
     308      358005 :         int op, action = *p++;
     309      358005 :         switch (action) {
     310       11886 :         case DASM_REL_LG: p++; op = p[-3]; goto rel_pc;
     311         507 :         case DASM_REL_PC: op = p[-2]; rel_pc: {
     312       12393 :           int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
     313       12393 :           if (shrink) {  /* Shrinkable branch opcode? */
     314       12387 :             int lofs, lpos = b[pos];
     315       12387 :             if (lpos < 0) goto noshrink;  /* Ext global? */
     316        9269 :             lofs = *DASM_POS2PTR(D, lpos);
     317        9269 :             if (lpos > pos) {  /* Fwd label: add cumulative section offsets. */
     318             :               int i;
     319        8639 :               for (i = secnum; i < DASM_POS2SEC(lpos); i++)
     320        2202 :                 lofs += D->sections[i].ofs;
     321             :             } else {
     322        2832 :               lofs -= ofs;  /* Bkwd label: unfix offset. */
     323             :             }
     324        9269 :             lofs -= b[pos+1];  /* Short branch ok? */
     325       13468 :             if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink;  /* Yes. */
     326        5070 :             else { noshrink: shrink = 0; }  /* No, cannot shrink op. */
     327             :           }
     328       12393 :           b[pos+1] = shrink;
     329       12393 :           pos += 2;
     330       12393 :           break;
     331             :         }
     332        7869 :         case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
     333       57518 :         case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
     334             :         case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
     335       57518 :         case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
     336       12269 :         case DASM_LABEL_LG: p++;
     337       13849 :         case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
     338         287 :         case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
     339           0 :         case DASM_EXTERN: p += 2; break;
     340       17771 :         case DASM_ESC: p++; break;
     341        7608 :         case DASM_MARK: break;
     342       58399 :         case DASM_SECTION: case DASM_STOP: goto stop;
     343             :         }
     344             :       }
     345       66673 :       stop: (void)0;
     346             :     }
     347        8274 :     ofs += sec->ofs;  /* Next section starts right after current section. */
     348             :   }
     349             : 
     350        4137 :   D->codesize = ofs;  /* Total size of all code sections */
     351        4137 :   *szp = ofs;
     352        4137 :   return DASM_S_OK;
     353             : }
     354             : 
     355             : #define dasmb(x)        *cp++ = (unsigned char)(x)
     356             : #ifndef DASM_ALIGNED_WRITES
     357             : #define dasmw(x) \
     358             :   do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
     359             : #define dasmd(x) \
     360             :   do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
     361             : #else
     362             : #define dasmw(x)        do { dasmb(x); dasmb((x)>>8); } while (0)
     363             : #define dasmd(x)        do { dasmw(x); dasmw((x)>>16); } while (0)
     364             : #endif
     365             : 
     366             : /* Pass 3: Encode sections. */
     367        4137 : int dasm_encode(Dst_DECL, void *buffer)
     368             : {
     369        4137 :   dasm_State *D = Dst_REF;
     370        4137 :   unsigned char *base = (unsigned char *)buffer;
     371        4137 :   unsigned char *cp = base;
     372             :   int secnum;
     373             : 
     374             :   /* Encode all code sections. No support for data sections (yet). */
     375       12411 :   for (secnum = 0; secnum < D->maxsection; secnum++) {
     376        8274 :     dasm_Section *sec = D->sections + secnum;
     377        8274 :     int *b = sec->buf;
     378        8274 :     int *endb = sec->rbuf + sec->pos;
     379             : 
     380       74947 :     while (b != endb) {
     381       58399 :       dasm_ActList p = D->actionlist + *b++;
     382       58399 :       unsigned char *mark = NULL;
     383      299606 :       while (1) {
     384      358005 :         int action = *p++;
     385      358005 :         int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;
     386      358005 :         switch (action) {
     387       21251 :         case DASM_DISP: if (!mark) mark = cp; {
     388       21251 :           unsigned char *mm = mark;
     389       21251 :           if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;
     390       21251 :           if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7;
     391        3630 :             if (mrm != 5) { mm[-1] -= 0x80; break; } }
     392       17621 :           if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;
     393             :         }
     394       25464 :         case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
     395        2592 :         case DASM_IMM_DB: if (((n+128)&-256) == 0) {
     396        2352 :             db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
     397         240 :           } else mark = NULL;
     398       32599 :         case DASM_IMM_D: wd: dasmd(n); break;
     399         350 :         case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
     400         350 :         case DASM_IMM_W: dasmw(n); break;
     401        7868 :         case DASM_VREG: {
     402        7868 :           int t = *p++;
     403        7868 :           unsigned char *ex = cp - (t&7);
     404        7868 :           if ((n & 8) && t < 0xa0) {
     405        4556 :             if (*ex & 0x80) ex[1] ^= 0x20 << (t>>6); else *ex ^= 1 << (t>>6);
     406        4556 :             n &= 7;
     407        3312 :           } else if (n & 0x10) {
     408         640 :             if (*ex & 0x80) {
     409           0 :               *ex = 0xc5; ex[1] = (ex[1] & 0x80) | ex[2]; ex += 2;
     410             :             }
     411         640 :             while (++ex < cp) ex[-1] = *ex;
     412         640 :             if (mark) mark--;
     413         640 :             cp--;
     414         640 :             n &= 7;
     415             :           }
     416        7868 :           if (t >= 0xc0) n <<= 4;
     417        7868 :           else if (t >= 0x40) n <<= 3;
     418        6079 :           else if (n == 4 && t < 0x20) { cp[-1] ^= n; *cp++ = 0x20; }
     419        7868 :           cp[-1] ^= n;
     420        7868 :           break;
     421             :         }
     422       11886 :         case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
     423        3124 :           b++; n = (int)(ptrdiff_t)D->globals[-n];
     424        7135 :         case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
     425        9269 :         case DASM_REL_PC: rel_pc: {
     426        9269 :           int shrink = *b++;
     427        9269 :           int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }
     428        9269 :           n = *pb - ((int)(cp-base) + 4-shrink);
     429        9269 :           if (shrink == 0) goto wd;
     430        4199 :           if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;
     431        4199 :           goto wb;
     432             :         }
     433           1 :         case DASM_IMM_LG:
     434           1 :           p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
     435             :         case DASM_IMM_PC: {
     436           2 :           int *pb = DASM_POS2PTR(D, n);
     437           2 :           n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
     438           2 :           goto wd;
     439             :         }
     440       12269 :         case DASM_LABEL_LG: {
     441       12269 :           int idx = *p++;
     442       12269 :           if (idx >= 10)
     443        3850 :             D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
     444       12269 :           break;
     445             :         }
     446        1580 :         case DASM_LABEL_PC: case DASM_SETLABEL: break;
     447           0 :         case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }
     448         287 :         case DASM_ALIGN:
     449         287 :           n = *p++;
     450         287 :           while (((cp-base) & n)) *cp++ = 0x90; /* nop */
     451         287 :           break;
     452           0 :         case DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;
     453        7608 :         case DASM_MARK: mark = cp; break;
     454       17771 :         case DASM_ESC: action = *p++;
     455      207951 :         default: *cp++ = action; break;
     456       58399 :         case DASM_SECTION: case DASM_STOP: goto stop;
     457             :         }
     458             :       }
     459       66673 :       stop: (void)0;
     460             :     }
     461             :   }
     462             : 
     463        4137 :   if (base + D->codesize != cp)  /* Check for phase errors. */
     464           0 :     return DASM_S_PHASE;
     465        4137 :   return DASM_S_OK;
     466             : }
     467             : 
     468             : /* Get PC label offset. */
     469         633 : int dasm_getpclabel(Dst_DECL, unsigned int pc)
     470             : {
     471         633 :   dasm_State *D = Dst_REF;
     472         633 :   if (pc*sizeof(int) < D->pcsize) {
     473         633 :     int pos = D->pclabels[pc];
     474         633 :     if (pos < 0) return *DASM_POS2PTR(D, -pos);
     475          15 :     if (pos > 0) return -1;  /* Undefined. */
     476             :   }
     477          15 :   return -2;  /* Unused or out of range. */
     478             : }
     479             : 
     480             : #ifdef DASM_CHECKS
     481             : /* Optional sanity checker to call between isolated encoding steps. */
     482             : int dasm_checkstep(Dst_DECL, int secmatch)
     483             : {
     484             :   dasm_State *D = Dst_REF;
     485             :   if (D->status == DASM_S_OK) {
     486             :     int i;
     487             :     for (i = 1; i <= 9; i++) {
     488             :       if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }
     489             :       D->lglabels[i] = 0;
     490             :     }
     491             :   }
     492             :   if (D->status == DASM_S_OK && secmatch >= 0 &&
     493             :       D->section != &D->sections[secmatch])
     494             :     D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
     495             :   return D->status;
     496             : }
     497             : #endif
     498             : 

Generated by: LCOV version 1.10

Generated at Mon, 06 May 2019 17:58:22 +0000 (992 days ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.