]> granicus.if.org Git - php/commitdiff
Better support for 64-bit .aword constants
authorDmitry Stogov <dmitry@zend.com>
Tue, 14 Jul 2020 12:14:21 +0000 (15:14 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 14 Jul 2020 12:14:21 +0000 (15:14 +0300)
ext/opcache/jit/dynasm/dasm_x86.h
ext/opcache/jit/dynasm/dasm_x86.lua

index 39449c15afdb3ca5ad77c2a6b45b98b40e13e3aa..89e99fec512413c11bacf47fe6b42221b94e34a5 100644 (file)
 
 /* Action definitions. DASM_STOP must be 255. */
 enum {
-  DASM_DISP = 232,
+  DASM_DISP = 231,
   DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
   DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
-  DASM_IMM_LG, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
+  DASM_IMM_LG, DASM_IMM_LG64, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
   DASM_ALIGN, DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
 };
 
@@ -220,6 +220,7 @@ void dasm_put(Dst_DECL, int start, ...)
     } else {
       int *pl, n;
       switch (action) {
+      case DASM_IMM_LG64: ofs += 4;
       case DASM_REL_LG:
       case DASM_IMM_LG:
        n = *p++; pl = D->lglabels + n;
@@ -333,7 +334,7 @@ int dasm_link(Dst_DECL, size_t *szp)
          pos += 2;
          break;
        }
-       case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
+       case DASM_SPACE: case DASM_IMM_LG: case DASM_IMM_LG64: case DASM_VREG: p++;
        case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
        case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
        case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: case DASM_IMM_PC64:
@@ -447,6 +448,11 @@ int dasm_encode(Dst_DECL, void *buffer)
          n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
          goto wd;
        }
+       case DASM_IMM_LG64: {
+         p++;
+         if (n < 0)
+           dasmq((ptrdiff_t)D->globals[-n]);
+       }
        case DASM_IMM_PC64: {
          int *pb = DASM_POS2PTR(D, n);
          dasmq(*pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base));
index f7d81d838f96232b5941d84295df749ec58943c6..0c94a7b5f7aaa5a779748d58c32a35e12beafcfc 100644 (file)
@@ -46,8 +46,8 @@ local action_names = {
   "SETLABEL", "REL_A",
   -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
   "REL_LG", "REL_PC",
-  -- action arg (1 byte) or int arg, 1 buffer pos (link):
-  "IMM_LG", "IMM_PC", "IMM_PC64",
+  -- action arg (1 byte) or ptrdiff_t arg, 1 buffer pos (link):
+  "IMM_LG", "IMM_LG64", "IMM_PC", "IMM_PC64",
   -- action arg (1 byte) or int arg, 1 buffer pos (offset):
   "LABEL_LG", "LABEL_PC",
   -- action arg (1 byte), 1 buffer pos (offset):
@@ -434,11 +434,17 @@ local function wputlabel(aprefix, imm, num)
     end
     wputxb(imm)
   else
-    if aprefix == "IMM_" and x64 then
-      waction("IMM_PC64", imm, num)
-    else
-      waction(aprefix.."PC", imm, num)
-    end
+    waction(aprefix.."PC", imm, num)
+  end
+end
+
+-- Put action for label arg (IMM_LG64, IMM_PC64, REL_LG, REL_PC).
+local function wputlabel64(aprefix, imm, num)
+  if type(imm) == "number" then
+    waction("IMM_LG64", nil, num);
+    wputxb(imm)
+  else
+    waction("IMM_PC64", imm, num)
   end
 end
 
@@ -473,6 +479,26 @@ local function wputwarg(n)
   else waction("IMM_W", n) end
 end
 
+-- Put signed or unsigned qword or arg.
+local function wputqarg(n)
+  local tn = type(n)
+  if tn == "number" then
+    wputb(band(n, 255))
+    wputb(band(shr(n, 8), 255))
+    wputb(band(shr(n, 16), 255))
+    wputb(band(shr(n, 24), 255))
+    wputb(band(shr(n, 32), 255))
+    wputb(band(shr(n, 40), 255))
+    wputb(band(shr(n, 48), 255))
+    wputb(shr(n, 56))
+  elseif tn == "table" then
+    wputlabel64("IMM_", n[1], 1)
+  else
+    waction("IMM_D", format("(unsigned int)(%s)", n))
+    waction("IMM_D", format("(unsigned int)((%s)>>32)", n))
+  end
+end
+
 -- Put signed or unsigned dword or arg.
 local function wputdarg(n)
   local tn = type(n)
@@ -2069,9 +2095,17 @@ local function op_data(params)
       werror("bad mode or size in `"..p.."'")
     end
     if a.mode == "iJ" then
-      wputlabel("IMM_", a.imm, 1)
+      if sz == 'q' then
+        wputlabel64("IMM_", a.imm, 1)
+      else
+        wputlabel("IMM_", a.imm, 1)
+      end
     else
-      wputszarg(sz, a.imm)
+      if sz == 'q' then
+        wputqarg(a.imm)
+      else
+        wputszarg(sz, a.imm)
+      end
     end
     if secpos+2 > maxsecpos then wflush() end
   end