LCOV - code coverage report
Current view: top level - js/src/jit/x86-shared - Disassembler-x86-shared.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 311 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 26 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "jit/Disassembler.h"
       8             : 
       9             : #include "jit/x86-shared/Encoding-x86-shared.h"
      10             : 
      11             : using namespace js;
      12             : using namespace js::jit;
      13             : using namespace js::jit::X86Encoding;
      14             : using namespace js::jit::Disassembler;
      15             : 
      16           0 : MOZ_COLD static bool REX_W(uint8_t rex) { return (rex >> 3) & 0x1; }
      17           0 : MOZ_COLD static bool REX_R(uint8_t rex) { return (rex >> 2) & 0x1; }
      18           0 : MOZ_COLD static bool REX_X(uint8_t rex) { return (rex >> 1) & 0x1; }
      19           0 : MOZ_COLD static bool REX_B(uint8_t rex) { return (rex >> 0) & 0x1; }
      20             : 
      21             : MOZ_COLD static uint8_t
      22           0 : MakeREXFlags(bool w, bool r, bool x, bool b)
      23             : {
      24           0 :     uint8_t rex = (w << 3) | (r << 2) | (x << 1) | (b << 0);
      25           0 :     MOZ_RELEASE_ASSERT(REX_W(rex) == w);
      26           0 :     MOZ_RELEASE_ASSERT(REX_R(rex) == r);
      27           0 :     MOZ_RELEASE_ASSERT(REX_X(rex) == x);
      28           0 :     MOZ_RELEASE_ASSERT(REX_B(rex) == b);
      29           0 :     return rex;
      30             : }
      31             : 
      32             : MOZ_COLD static ModRmMode
      33           0 : ModRM_Mode(uint8_t modrm)
      34             : {
      35           0 :     return ModRmMode((modrm >> 6) & 0x3);
      36             : }
      37             : 
      38             : MOZ_COLD static uint8_t
      39           0 : ModRM_Reg(uint8_t modrm)
      40             : {
      41           0 :     return (modrm >> 3) & 0x7;
      42             : }
      43             : 
      44             : MOZ_COLD static uint8_t
      45           0 : ModRM_RM(uint8_t modrm)
      46             : {
      47           0 :     return (modrm >> 0) & 0x7;
      48             : }
      49             : 
      50             : MOZ_COLD static bool
      51           0 : ModRM_hasSIB(uint8_t modrm)
      52             : {
      53           0 :     return ModRM_Mode(modrm) != ModRmRegister && ModRM_RM(modrm) == hasSib;
      54             : }
      55             : MOZ_COLD static bool
      56           0 : ModRM_hasDisp8(uint8_t modrm)
      57             : {
      58           0 :     return ModRM_Mode(modrm) == ModRmMemoryDisp8;
      59             : }
      60             : MOZ_COLD static bool
      61           0 : ModRM_hasRIP(uint8_t modrm)
      62             : {
      63             : #ifdef JS_CODEGEN_X64
      64           0 :     return ModRM_Mode(modrm) == ModRmMemoryNoDisp && ModRM_RM(modrm) == noBase;
      65             : #else
      66             :     return false;
      67             : #endif
      68             : }
      69             : MOZ_COLD static bool
      70           0 : ModRM_hasDisp32(uint8_t modrm)
      71             : {
      72           0 :     return ModRM_Mode(modrm) == ModRmMemoryDisp32 ||
      73           0 :            ModRM_hasRIP(modrm);
      74             : }
      75             : 
      76             : MOZ_COLD static uint8_t
      77           0 : SIB_SS(uint8_t sib)
      78             : {
      79           0 :     return (sib >> 6) & 0x3;
      80             : }
      81             : 
      82             : MOZ_COLD static uint8_t
      83           0 : SIB_Index(uint8_t sib)
      84             : {
      85           0 :     return (sib >> 3) & 0x7;
      86             : }
      87             : 
      88             : MOZ_COLD static uint8_t
      89           0 : SIB_Base(uint8_t sib)
      90             : {
      91           0 :     return (sib >> 0) & 0x7;
      92             : }
      93             : 
      94             : MOZ_COLD static bool
      95           0 : SIB_hasRIP(uint8_t sib)
      96             : {
      97           0 :     return SIB_Base(sib) == noBase && SIB_Index(sib) == noIndex;
      98             : }
      99             : 
     100             : MOZ_COLD static bool
     101           0 : HasRIP(uint8_t modrm, uint8_t sib, uint8_t rex)
     102             : {
     103           0 :     return ModRM_hasRIP(modrm) && SIB_hasRIP(sib);
     104             : }
     105             : 
     106             : MOZ_COLD static bool
     107           0 : HasDisp8(uint8_t modrm)
     108             : {
     109           0 :     return ModRM_hasDisp8(modrm);
     110             : }
     111             : 
     112             : MOZ_COLD static bool
     113           0 : HasDisp32(uint8_t modrm, uint8_t sib)
     114             : {
     115           0 :     return ModRM_hasDisp32(modrm) ||
     116           0 :            (SIB_Base(sib) == noBase &&
     117           0 :             SIB_Index(sib) == noIndex &&
     118           0 :             ModRM_Mode(modrm) == ModRmMemoryNoDisp);
     119             : }
     120             : 
     121             : MOZ_COLD static uint32_t
     122           0 : Reg(uint8_t modrm, uint8_t sib, uint8_t rex)
     123             : {
     124           0 :     return ModRM_Reg(modrm) | (REX_R(rex) << 3);
     125             : }
     126             : 
     127             : MOZ_COLD static bool
     128           0 : HasBase(uint8_t modrm, uint8_t sib)
     129             : {
     130           0 :     return !ModRM_hasSIB(modrm) ||
     131           0 :            SIB_Base(sib) != noBase ||
     132           0 :            SIB_Index(sib) != noIndex ||
     133           0 :            ModRM_Mode(modrm) != ModRmMemoryNoDisp;
     134             : }
     135             : 
     136             : MOZ_COLD static RegisterID
     137           0 : DecodeBase(uint8_t modrm, uint8_t sib, uint8_t rex)
     138             : {
     139           0 :     return HasBase(modrm, sib)
     140           0 :            ? RegisterID((ModRM_hasSIB(modrm) ? SIB_Base(sib) : ModRM_RM(modrm)) | (REX_B(rex) << 3))
     141           0 :            : invalid_reg;
     142             : }
     143             : 
     144             : MOZ_COLD static RegisterID
     145           0 : DecodeIndex(uint8_t modrm, uint8_t sib, uint8_t rex)
     146             : {
     147           0 :     RegisterID index = RegisterID(SIB_Index(sib) | (REX_X(rex) << 3));
     148           0 :     return ModRM_hasSIB(modrm) && index != noIndex ? index : invalid_reg;
     149             : }
     150             : 
     151             : MOZ_COLD static uint32_t
     152           0 : DecodeScale(uint8_t modrm, uint8_t sib, uint8_t rex)
     153             : {
     154           0 :     return ModRM_hasSIB(modrm) ? SIB_SS(sib) : 0;
     155             : }
     156             : 
     157             : #define PackOpcode(op0, op1, op2) ((op0) | ((op1) << 8) | ((op2) << 16))
     158             : #define Pack2ByteOpcode(op1) PackOpcode(OP_2BYTE_ESCAPE, op1, 0)
     159             : #define Pack3ByteOpcode(op1, op2) PackOpcode(OP_2BYTE_ESCAPE, op1, op2)
     160             : 
     161             : uint8_t*
     162           0 : js::jit::Disassembler::DisassembleHeapAccess(uint8_t* ptr, HeapAccess* access)
     163             : {
     164           0 :     VexOperandType type = VEX_PS;
     165           0 :     uint32_t opcode = OP_HLT;
     166           0 :     uint8_t modrm = 0;
     167           0 :     uint8_t sib = 0;
     168           0 :     uint8_t rex = 0;
     169           0 :     int32_t disp = 0;
     170           0 :     int32_t imm = 0;
     171           0 :     bool haveImm = false;
     172           0 :     int opsize = 4;
     173             : 
     174             :     // Legacy prefixes
     175           0 :     switch (*ptr) {
     176             :       case PRE_LOCK:
     177             :       case PRE_PREDICT_BRANCH_NOT_TAKEN: // (obsolete), aka %cs
     178             :       case 0x3E: // aka predict-branch-taken (obsolete)
     179             :       case 0x36: // %ss
     180             :       case 0x26: // %es
     181             :       case 0x64: // %fs
     182             :       case 0x65: // %gs
     183             :       case 0x67: // address-size override
     184           0 :         MOZ_CRASH("Unable to disassemble instruction");
     185             :       case PRE_SSE_F2: // aka REPNZ/REPNE
     186           0 :         type = VEX_SD;
     187           0 :         ptr++;
     188           0 :         break;
     189             :       case PRE_SSE_F3: // aka REP/REPE/REPZ
     190           0 :         type = VEX_SS;
     191           0 :         ptr++;
     192           0 :         break;
     193             :       case PRE_SSE_66: // aka PRE_OPERAND_SIZE
     194           0 :         type = VEX_PD;
     195           0 :         opsize = 2;
     196           0 :         ptr++;
     197           0 :         break;
     198             :       default:
     199           0 :         break;
     200             :     }
     201             : 
     202             :     // REX and VEX prefixes
     203             :     {
     204           0 :         int x = 0, b = 0, m = 1, w = 0;
     205             :         int r, l, p;
     206           0 :         switch (*ptr) {
     207             : #ifdef JS_CODEGEN_X64
     208             :           case PRE_REX | 0x0: case PRE_REX | 0x1: case PRE_REX | 0x2: case PRE_REX | 0x3:
     209             :           case PRE_REX | 0x4: case PRE_REX | 0x5: case PRE_REX | 0x6: case PRE_REX | 0x7:
     210             :           case PRE_REX | 0x8: case PRE_REX | 0x9: case PRE_REX | 0xa: case PRE_REX | 0xb:
     211             :           case PRE_REX | 0xc: case PRE_REX | 0xd: case PRE_REX | 0xe: case PRE_REX | 0xf:
     212           0 :             rex = *ptr++ & 0xf;
     213           0 :             goto rex_done;
     214             : #endif
     215             :           case PRE_VEX_C4: {
     216           0 :             if (type != VEX_PS)
     217           0 :                 MOZ_CRASH("Unable to disassemble instruction");
     218           0 :             ++ptr;
     219           0 :             uint8_t c4a = *ptr++ ^ 0xe0;
     220           0 :             uint8_t c4b = *ptr++ ^ 0x78;
     221           0 :             r = (c4a >> 7) & 0x1;
     222           0 :             x = (c4a >> 6) & 0x1;
     223           0 :             b = (c4a >> 5) & 0x1;
     224           0 :             m = (c4a >> 0) & 0x1f;
     225           0 :             w = (c4b >> 7) & 0x1;
     226           0 :             l = (c4b >> 2) & 0x1;
     227           0 :             p = (c4b >> 0) & 0x3;
     228           0 :             break;
     229             :           }
     230             :           case PRE_VEX_C5: {
     231           0 :             if (type != VEX_PS)
     232           0 :               MOZ_CRASH("Unable to disassemble instruction");
     233           0 :             ++ptr;
     234           0 :             uint8_t c5 = *ptr++ ^ 0xf8;
     235           0 :             r = (c5 >> 7) & 0x1;
     236           0 :             l = (c5 >> 2) & 0x1;
     237           0 :             p = (c5 >> 0) & 0x3;
     238           0 :             break;
     239             :           }
     240             :           default:
     241           0 :             goto rex_done;
     242             :         }
     243           0 :         if (l != 0) // 256-bit SIMD
     244           0 :             MOZ_CRASH("Unable to disassemble instruction");
     245           0 :         type = VexOperandType(p);
     246           0 :         rex = MakeREXFlags(w, r, x, b);
     247           0 :         switch (m) {
     248             :           case 0x1:
     249           0 :             opcode = Pack2ByteOpcode(*ptr++);
     250           0 :             goto opcode_done;
     251             :           case 0x2:
     252           0 :             opcode = Pack3ByteOpcode(ESCAPE_38, *ptr++);
     253           0 :             goto opcode_done;
     254             :           case 0x3:
     255           0 :             opcode = Pack3ByteOpcode(ESCAPE_3A, *ptr++);
     256           0 :             goto opcode_done;
     257             :           default:
     258           0 :             MOZ_CRASH("Unable to disassemble instruction");
     259             :         }
     260             :     }
     261             :   rex_done:;
     262           0 :     if (REX_W(rex))
     263           0 :         opsize = 8;
     264             : 
     265             :     // Opcode.
     266           0 :     opcode = *ptr++;
     267           0 :     switch (opcode) {
     268             : #ifdef JS_CODEGEN_X64
     269             :       case OP_PUSH_EAX + 0: case OP_PUSH_EAX + 1: case OP_PUSH_EAX + 2: case OP_PUSH_EAX + 3:
     270             :       case OP_PUSH_EAX + 4: case OP_PUSH_EAX + 5: case OP_PUSH_EAX + 6: case OP_PUSH_EAX + 7:
     271             :       case OP_POP_EAX + 0: case OP_POP_EAX + 1: case OP_POP_EAX + 2: case OP_POP_EAX + 3:
     272             :       case OP_POP_EAX + 4: case OP_POP_EAX + 5: case OP_POP_EAX + 6: case OP_POP_EAX + 7:
     273             :       case OP_PUSH_Iz:
     274             :       case OP_PUSH_Ib:
     275           0 :         opsize = 8;
     276           0 :         break;
     277             : #endif
     278             :       case OP_2BYTE_ESCAPE:
     279           0 :         opcode |= *ptr << 8;
     280           0 :         switch (*ptr++) {
     281             :           case ESCAPE_38:
     282             :           case ESCAPE_3A:
     283           0 :             opcode |= *ptr++ << 16;
     284           0 :             break;
     285             :           default:
     286           0 :             break;
     287             :         }
     288           0 :         break;
     289             :       default:
     290           0 :         break;
     291             :     }
     292             :   opcode_done:;
     293             : 
     294             :     // ModR/M
     295           0 :     modrm = *ptr++;
     296             : 
     297             :     // SIB
     298           0 :     if (ModRM_hasSIB(modrm))
     299           0 :         sib = *ptr++;
     300             : 
     301             :     // Address Displacement
     302           0 :     if (HasDisp8(modrm)) {
     303           0 :         disp = int8_t(*ptr++);
     304           0 :     } else if (HasDisp32(modrm, sib)) {
     305           0 :         memcpy(&disp, ptr, sizeof(int32_t));
     306           0 :         ptr += sizeof(int32_t);
     307             :     }
     308             : 
     309             :     // Immediate operand
     310           0 :     switch (opcode) {
     311             :       case OP_PUSH_Ib:
     312             :       case OP_IMUL_GvEvIb:
     313             :       case OP_GROUP1_EbIb:
     314             :       case OP_GROUP1_EvIb:
     315             :       case OP_TEST_EAXIb:
     316             :       case OP_GROUP2_EvIb:
     317             :       case OP_GROUP11_EvIb:
     318             :       case OP_GROUP3_EbIb:
     319             :       case Pack2ByteOpcode(OP2_PSHUFD_VdqWdqIb):
     320             :       case Pack2ByteOpcode(OP2_PSLLD_UdqIb): // aka OP2_PSRAD_UdqIb, aka OP2_PSRLD_UdqIb
     321             :       case Pack2ByteOpcode(OP2_PEXTRW_GdUdIb):
     322             :       case Pack2ByteOpcode(OP2_SHUFPS_VpsWpsIb):
     323             :       case Pack3ByteOpcode(ESCAPE_3A, OP3_PEXTRD_EdVdqIb):
     324             :       case Pack3ByteOpcode(ESCAPE_3A, OP3_BLENDPS_VpsWpsIb):
     325             :       case Pack3ByteOpcode(ESCAPE_3A, OP3_PINSRD_VdqEdIb):
     326             :         // 8-bit signed immediate
     327           0 :         imm = int8_t(*ptr++);
     328           0 :         haveImm = true;
     329           0 :         break;
     330             :       case OP_RET_Iz:
     331             :         // 16-bit unsigned immediate
     332           0 :         memcpy(&imm, ptr, sizeof(int16_t));
     333           0 :         ptr += sizeof(int16_t);
     334           0 :         haveImm = true;
     335           0 :         break;
     336             :       case OP_ADD_EAXIv:
     337             :       case OP_OR_EAXIv:
     338             :       case OP_AND_EAXIv:
     339             :       case OP_SUB_EAXIv:
     340             :       case OP_XOR_EAXIv:
     341             :       case OP_CMP_EAXIv:
     342             :       case OP_PUSH_Iz:
     343             :       case OP_IMUL_GvEvIz:
     344             :       case OP_GROUP1_EvIz:
     345             :       case OP_TEST_EAXIv:
     346             :       case OP_MOV_EAXIv:
     347             :       case OP_GROUP3_EvIz:
     348             :         // 32-bit signed immediate
     349           0 :         memcpy(&imm, ptr, sizeof(int32_t));
     350           0 :         ptr += sizeof(int32_t);
     351           0 :         haveImm = true;
     352           0 :         break;
     353             :       case OP_GROUP11_EvIz:
     354             :         // opsize-sized signed immediate
     355           0 :         memcpy(&imm, ptr, opsize);
     356           0 :         imm = (imm << (32 - opsize * 8)) >> (32 - opsize * 8);
     357           0 :         ptr += opsize;
     358           0 :         haveImm = true;
     359           0 :         break;
     360             :       default:
     361           0 :         break;
     362             :     }
     363             : 
     364             :     // Interpret the opcode.
     365           0 :     if (HasRIP(modrm, sib, rex))
     366           0 :         MOZ_CRASH("Unable to disassemble instruction");
     367             : 
     368           0 :     size_t memSize = 0;
     369           0 :     OtherOperand otherOperand(imm);
     370           0 :     HeapAccess::Kind kind = HeapAccess::Unknown;
     371           0 :     RegisterID gpr(RegisterID(Reg(modrm, sib, rex)));
     372           0 :     XMMRegisterID xmm(XMMRegisterID(Reg(modrm, sib, rex)));
     373             :     ComplexAddress addr(disp,
     374           0 :                         DecodeBase(modrm, sib, rex),
     375           0 :                         DecodeIndex(modrm, sib, rex),
     376           0 :                         DecodeScale(modrm, sib, rex));
     377           0 :     switch (opcode) {
     378             :       case OP_GROUP11_EvIb:
     379           0 :         if (gpr != RegisterID(GROUP11_MOV))
     380           0 :             MOZ_CRASH("Unable to disassemble instruction");
     381           0 :         MOZ_RELEASE_ASSERT(haveImm);
     382           0 :         memSize = 1;
     383           0 :         kind = HeapAccess::Store;
     384           0 :         break;
     385             :       case OP_GROUP11_EvIz:
     386           0 :         if (gpr != RegisterID(GROUP11_MOV))
     387           0 :             MOZ_CRASH("Unable to disassemble instruction");
     388           0 :         MOZ_RELEASE_ASSERT(haveImm);
     389           0 :         memSize = opsize;
     390           0 :         kind = HeapAccess::Store;
     391           0 :         break;
     392             :       case OP_MOV_GvEv:
     393           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     394           0 :         otherOperand = OtherOperand(gpr);
     395           0 :         memSize = opsize;
     396           0 :         kind = HeapAccess::Load;
     397           0 :         break;
     398             :       case OP_MOV_GvEb:
     399           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     400           0 :         otherOperand = OtherOperand(gpr);
     401           0 :         memSize = 1;
     402           0 :         kind = HeapAccess::Load;
     403           0 :         break;
     404             :       case OP_MOV_EvGv:
     405           0 :         if (!haveImm)
     406           0 :             otherOperand = OtherOperand(gpr);
     407           0 :         memSize = opsize;
     408           0 :         kind = HeapAccess::Store;
     409           0 :         break;
     410             :       case OP_MOV_EbGv:
     411           0 :         if (!haveImm)
     412           0 :             otherOperand = OtherOperand(gpr);
     413           0 :         memSize = 1;
     414           0 :         kind = HeapAccess::Store;
     415           0 :         break;
     416             :       case Pack2ByteOpcode(OP2_MOVZX_GvEb):
     417           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     418           0 :         otherOperand = OtherOperand(gpr);
     419           0 :         memSize = 1;
     420           0 :         kind = HeapAccess::Load;
     421           0 :         break;
     422             :       case Pack2ByteOpcode(OP2_MOVZX_GvEw):
     423           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     424           0 :         otherOperand = OtherOperand(gpr);
     425           0 :         memSize = 2;
     426           0 :         kind = HeapAccess::Load;
     427           0 :         break;
     428             :       case Pack2ByteOpcode(OP2_MOVSX_GvEb):
     429           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     430           0 :         otherOperand = OtherOperand(gpr);
     431           0 :         memSize = 1;
     432           0 :         kind = opsize == 8 ? HeapAccess::LoadSext64 : HeapAccess::LoadSext32;
     433           0 :         break;
     434             :       case Pack2ByteOpcode(OP2_MOVSX_GvEw):
     435           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     436           0 :         otherOperand = OtherOperand(gpr);
     437           0 :         memSize = 2;
     438           0 :         kind = opsize == 8 ? HeapAccess::LoadSext64 : HeapAccess::LoadSext32;
     439           0 :         break;
     440             : #ifdef JS_CODEGEN_X64
     441             :       case OP_MOVSXD_GvEv:
     442           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     443           0 :         otherOperand = OtherOperand(gpr);
     444           0 :         memSize = 4;
     445           0 :         kind = HeapAccess::LoadSext64;
     446           0 :         break;
     447             : #endif // JS_CODEGEN_X64
     448             :       case Pack2ByteOpcode(OP2_MOVDQ_VdqWdq): // aka OP2_MOVDQ_VsdWsd
     449             :       case Pack2ByteOpcode(OP2_MOVAPS_VsdWsd):
     450           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     451           0 :         otherOperand = OtherOperand(xmm);
     452           0 :         memSize = 16;
     453           0 :         kind = HeapAccess::Load;
     454           0 :         break;
     455             :       case Pack2ByteOpcode(OP2_MOVSD_VsdWsd): // aka OP2_MOVPS_VpsWps
     456           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     457           0 :         otherOperand = OtherOperand(xmm);
     458           0 :         switch (type) {
     459           0 :           case VEX_SS: memSize = 4; break;
     460           0 :           case VEX_SD: memSize = 8; break;
     461             :           case VEX_PS:
     462           0 :           case VEX_PD: memSize = 16; break;
     463           0 :           default: MOZ_CRASH("Unexpected VEX type");
     464             :         }
     465           0 :         kind = HeapAccess::Load;
     466           0 :         break;
     467             :       case Pack2ByteOpcode(OP2_MOVDQ_WdqVdq):
     468           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     469           0 :         otherOperand = OtherOperand(xmm);
     470           0 :         memSize = 16;
     471           0 :         kind = HeapAccess::Store;
     472           0 :         break;
     473             :       case Pack2ByteOpcode(OP2_MOVSD_WsdVsd): // aka OP2_MOVPS_WpsVps
     474           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     475           0 :         otherOperand = OtherOperand(xmm);
     476           0 :         switch (type) {
     477           0 :           case VEX_SS: memSize = 4; break;
     478           0 :           case VEX_SD: memSize = 8; break;
     479             :           case VEX_PS:
     480           0 :           case VEX_PD: memSize = 16; break;
     481           0 :           default: MOZ_CRASH("Unexpected VEX type");
     482             :         }
     483           0 :         kind = HeapAccess::Store;
     484           0 :         break;
     485             :       case Pack2ByteOpcode(OP2_MOVD_VdEd):
     486           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     487           0 :         otherOperand = OtherOperand(xmm);
     488           0 :         switch (type) {
     489           0 :           case VEX_PD: memSize = 4; break;
     490           0 :           default: MOZ_CRASH("Unexpected VEX type");
     491             :         }
     492           0 :         kind = HeapAccess::Load;
     493           0 :         break;
     494             :       case Pack2ByteOpcode(OP2_MOVQ_WdVd):
     495           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     496           0 :         otherOperand = OtherOperand(xmm);
     497           0 :         switch (type) {
     498           0 :           case VEX_PD: memSize = 8; break;
     499           0 :           default: MOZ_CRASH("Unexpected VEX type");
     500             :         }
     501           0 :         kind = HeapAccess::Store;
     502           0 :         break;
     503             :       case Pack2ByteOpcode(OP2_MOVD_EdVd): // aka OP2_MOVQ_VdWd
     504           0 :         MOZ_RELEASE_ASSERT(!haveImm);
     505           0 :         otherOperand = OtherOperand(xmm);
     506           0 :         switch (type) {
     507           0 :           case VEX_SS: memSize = 8; kind = HeapAccess::Load; break;
     508           0 :           case VEX_PD: memSize = 4; kind = HeapAccess::Store; break;
     509           0 :           default: MOZ_CRASH("Unexpected VEX type");
     510             :         }
     511           0 :         break;
     512             :       default:
     513           0 :         MOZ_CRASH("Unable to disassemble instruction");
     514             :     }
     515             : 
     516           0 :     *access = HeapAccess(kind, memSize, addr, otherOperand);
     517           0 :     return ptr;
     518             : }
     519             : 
     520             : #ifdef DEBUG
     521             : void
     522           0 : js::jit::Disassembler::DumpHeapAccess(const HeapAccess& access)
     523             : {
     524           0 :     switch (access.kind()) {
     525           0 :       case HeapAccess::Store:      fprintf(stderr, "store"); break;
     526           0 :       case HeapAccess::Load:       fprintf(stderr, "load"); break;
     527           0 :       case HeapAccess::LoadSext32: fprintf(stderr, "loadSext32"); break;
     528           0 :       case HeapAccess::LoadSext64: fprintf(stderr, "loadSext64"); break;
     529           0 :       default:                     fprintf(stderr, "unknown"); break;
     530             :     }
     531           0 :     fprintf(stderr, "%u ", unsigned(access.size()));
     532             : 
     533           0 :     switch (access.otherOperand().kind()) {
     534             :       case OtherOperand::Imm:
     535           0 :         fprintf(stderr, "imm %d", access.otherOperand().imm());
     536           0 :         break;
     537             :       case OtherOperand::GPR:
     538           0 :         fprintf(stderr, "gpr %s", X86Encoding::GPRegName(access.otherOperand().gpr()));
     539           0 :         break;
     540             :       case OtherOperand::FPR:
     541           0 :         fprintf(stderr, "fpr %s", X86Encoding::XMMRegName(access.otherOperand().fpr()));
     542           0 :         break;
     543           0 :       default: fprintf(stderr, "unknown");
     544             :     }
     545             : 
     546           0 :     fprintf(stderr, " @ ");
     547             : 
     548           0 :     if (access.address().isPCRelative()) {
     549           0 :         fprintf(stderr, MEM_o32r " ", ADDR_o32r(access.address().disp()));
     550           0 :     } else if (access.address().hasIndex()) {
     551           0 :         if (access.address().hasBase()) {
     552           0 :             fprintf(stderr, MEM_obs " ",
     553           0 :                     ADDR_obs(access.address().disp(), access.address().base(),
     554           0 :                              access.address().index(), access.address().scale()));
     555             :         } else {
     556           0 :             fprintf(stderr, MEM_os " ",
     557           0 :                     ADDR_os(access.address().disp(),
     558           0 :                             access.address().index(), access.address().scale()));
     559             :         }
     560           0 :     } else if (access.address().hasBase()) {
     561           0 :         fprintf(stderr, MEM_ob " ", ADDR_ob(access.address().disp(), access.address().base()));
     562             :     } else {
     563           0 :         fprintf(stderr, MEM_o " ", ADDR_o(access.address().disp()));
     564             :     }
     565             : 
     566           0 :     fprintf(stderr, "\n");
     567           0 : }
     568             : #endif

Generated by: LCOV version 1.13