LCOV - code coverage report
Current view: top level - js/src/jit/x86-shared - BaseAssembler-x86-shared.h (source / functions) Hit Total Coverage
Test: output.info Lines: 666 2834 23.5 %
Date: 2017-07-14 16:53:18 Functions: 145 605 24.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             :  *
       4             :  * ***** BEGIN LICENSE BLOCK *****
       5             :  * Copyright (C) 2008 Apple Inc. All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions
       9             :  * are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
      17             :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      18             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      19             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
      20             :  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      21             :  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      22             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      23             :  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
      24             :  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             :  *
      28             :  * ***** END LICENSE BLOCK ***** */
      29             : 
      30             : #ifndef jit_x86_shared_BaseAssembler_x86_shared_h
      31             : #define jit_x86_shared_BaseAssembler_x86_shared_h
      32             : 
      33             : #include "mozilla/IntegerPrintfMacros.h"
      34             : 
      35             : #include "jit/x86-shared/AssemblerBuffer-x86-shared.h"
      36             : #include "jit/x86-shared/Encoding-x86-shared.h"
      37             : #include "jit/x86-shared/Patching-x86-shared.h"
      38             : 
      39             : extern volatile uintptr_t* blackbox;
      40             : 
      41             : namespace js {
      42             : namespace jit {
      43             : 
      44             : namespace X86Encoding {
      45             : 
      46             : class BaseAssembler;
      47             : 
      48        4503 : class BaseAssembler : public GenericAssembler {
      49             : public:
      50        4503 :     BaseAssembler()
      51        4503 :       : useVEX_(true)
      52        4503 :     { }
      53             : 
      54        4503 :     void disableVEX() { useVEX_ = false; }
      55             : 
      56      335901 :     size_t size() const { return m_formatter.size(); }
      57             :     const unsigned char* buffer() const { return m_formatter.buffer(); }
      58           0 :     unsigned char* data() { return m_formatter.data(); }
      59      256035 :     bool oom() const { return m_formatter.oom(); }
      60             : 
      61           0 :     void disableProtection() { m_formatter.disableProtection(); }
      62             :     void enableProtection() { m_formatter.enableProtection(); }
      63             :     void setLowerBoundForProtection(size_t size)
      64             :     {
      65             :         m_formatter.setLowerBoundForProtection(size);
      66             :     }
      67             :     void unprotectRegion(unsigned char* first, size_t size)
      68             :     {
      69             :         m_formatter.unprotectRegion(first, size);
      70             :     }
      71             :     void reprotectRegion(unsigned char* first, size_t size)
      72             :     {
      73             :         m_formatter.reprotectRegion(first, size);
      74             :     }
      75             : 
      76          64 :     void nop()
      77             :     {
      78          64 :         spew("nop");
      79          64 :         m_formatter.oneByteOp(OP_NOP);
      80          64 :     }
      81             : 
      82         288 :     void comment(const char* msg)
      83             :     {
      84         288 :         spew("; %s", msg);
      85         288 :     }
      86             : 
      87             :     MOZ_MUST_USE JmpSrc
      88           0 :     twoByteNop()
      89             :     {
      90           0 :         spew("nop (2 byte)");
      91           0 :         JmpSrc r(m_formatter.size());
      92           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
      93           0 :         m_formatter.oneByteOp(OP_NOP);
      94           0 :         return r;
      95             :     }
      96             : 
      97           0 :     static void patchTwoByteNopToJump(uint8_t* jump, uint8_t* target)
      98             :     {
      99             :         // Note: the offset is relative to the address of the instruction after
     100             :         // the jump which is two bytes.
     101           0 :         ptrdiff_t rel8 = target - jump - 2;
     102           0 :         MOZ_RELEASE_ASSERT(rel8 >= INT8_MIN && rel8 <= INT8_MAX);
     103           0 :         MOZ_RELEASE_ASSERT(jump[0] == PRE_OPERAND_SIZE);
     104           0 :         MOZ_RELEASE_ASSERT(jump[1] == OP_NOP);
     105           0 :         jump[0] = OP_JMP_rel8;
     106           0 :         jump[1] = rel8;
     107           0 :     }
     108             : 
     109           0 :     static void patchJumpToTwoByteNop(uint8_t* jump)
     110             :     {
     111             :         // See twoByteNop.
     112           0 :         MOZ_RELEASE_ASSERT(jump[0] == OP_JMP_rel8);
     113           0 :         jump[0] = PRE_OPERAND_SIZE;
     114           0 :         jump[1] = OP_NOP;
     115           0 :     }
     116             : 
     117           0 :     static void patchFiveByteNopToCall(uint8_t* callsite, uint8_t* target)
     118             :     {
     119             :         // Note: the offset is relative to the address of the instruction after
     120             :         // the call which is five bytes.
     121           0 :         uint8_t* inst = callsite - sizeof(int32_t) - 1;
     122             :         // The nop can be already patched as call, overriding the call.
     123             :         // See also nop_five.
     124           0 :         MOZ_ASSERT(inst[0] == OP_NOP_0F || inst[0] == OP_CALL_rel32);
     125           0 :         MOZ_ASSERT_IF(inst[0] == OP_NOP_0F, inst[1] == OP_NOP_1F ||
     126             :                                             inst[2] == OP_NOP_44 ||
     127             :                                             inst[3] == OP_NOP_00 ||
     128             :                                             inst[4] == OP_NOP_00);
     129           0 :         inst[0] = OP_CALL_rel32;
     130           0 :         SetRel32(callsite, target);
     131           0 :     }
     132             : 
     133           0 :     static void patchCallToFiveByteNop(uint8_t* callsite)
     134             :     {
     135             :         // See also patchFiveByteNopToCall and nop_five.
     136           0 :         uint8_t* inst = callsite - sizeof(int32_t) - 1;
     137             :         // The call can be already patched as nop.
     138           0 :         if (inst[0] == OP_NOP_0F) {
     139           0 :             MOZ_ASSERT(inst[1] == OP_NOP_1F || inst[2] == OP_NOP_44 ||
     140             :                        inst[3] == OP_NOP_00 || inst[4] == OP_NOP_00);
     141           0 :             return;
     142             :         }
     143           0 :         MOZ_ASSERT(inst[0] == OP_CALL_rel32);
     144           0 :         inst[0] = OP_NOP_0F;
     145           0 :         inst[1] = OP_NOP_1F;
     146           0 :         inst[2] = OP_NOP_44;
     147           0 :         inst[3] = OP_NOP_00;
     148           0 :         inst[4] = OP_NOP_00;
     149             :     }
     150             : 
     151             :     /*
     152             :      * The nop multibytes sequences are directly taken from the Intel's
     153             :      * architecture software developer manual.
     154             :      * They are defined for sequences of sizes from 1 to 9 included.
     155             :      */
     156           0 :     void nop_one()
     157             :     {
     158           0 :         m_formatter.oneByteOp(OP_NOP);
     159           0 :     }
     160             : 
     161           0 :     void nop_two()
     162             :     {
     163           0 :         m_formatter.oneByteOp(OP_NOP_66);
     164           0 :         m_formatter.oneByteOp(OP_NOP);
     165           0 :     }
     166             : 
     167           0 :     void nop_three()
     168             :     {
     169           0 :         m_formatter.oneByteOp(OP_NOP_0F);
     170           0 :         m_formatter.oneByteOp(OP_NOP_1F);
     171           0 :         m_formatter.oneByteOp(OP_NOP_00);
     172           0 :     }
     173             : 
     174           0 :     void nop_four()
     175             :     {
     176           0 :         m_formatter.oneByteOp(OP_NOP_0F);
     177           0 :         m_formatter.oneByteOp(OP_NOP_1F);
     178           0 :         m_formatter.oneByteOp(OP_NOP_40);
     179           0 :         m_formatter.oneByteOp(OP_NOP_00);
     180           0 :     }
     181             : 
     182           0 :     void nop_five()
     183             :     {
     184           0 :         m_formatter.oneByteOp(OP_NOP_0F);
     185           0 :         m_formatter.oneByteOp(OP_NOP_1F);
     186           0 :         m_formatter.oneByteOp(OP_NOP_44);
     187           0 :         m_formatter.oneByteOp(OP_NOP_00);
     188           0 :         m_formatter.oneByteOp(OP_NOP_00);
     189           0 :     }
     190             : 
     191           0 :     void nop_six()
     192             :     {
     193           0 :         m_formatter.oneByteOp(OP_NOP_66);
     194           0 :         nop_five();
     195           0 :     }
     196             : 
     197           0 :     void nop_seven()
     198             :     {
     199           0 :         m_formatter.oneByteOp(OP_NOP_0F);
     200           0 :         m_formatter.oneByteOp(OP_NOP_1F);
     201           0 :         m_formatter.oneByteOp(OP_NOP_80);
     202           0 :         for (int i = 0; i < 4; ++i)
     203           0 :             m_formatter.oneByteOp(OP_NOP_00);
     204           0 :     }
     205             : 
     206           0 :     void nop_eight()
     207             :     {
     208           0 :         m_formatter.oneByteOp(OP_NOP_0F);
     209           0 :         m_formatter.oneByteOp(OP_NOP_1F);
     210           0 :         m_formatter.oneByteOp(OP_NOP_84);
     211           0 :         for (int i = 0; i < 5; ++i)
     212           0 :             m_formatter.oneByteOp(OP_NOP_00);
     213           0 :     }
     214             : 
     215           0 :     void nop_nine()
     216             :     {
     217           0 :         m_formatter.oneByteOp(OP_NOP_66);
     218           0 :         nop_eight();
     219           0 :     }
     220             : 
     221           0 :     void insert_nop(int size)
     222             :     {
     223           0 :         switch (size) {
     224             :           case 1:
     225           0 :             nop_one();
     226           0 :             break;
     227             :           case 2:
     228           0 :             nop_two();
     229           0 :             break;
     230             :           case 3:
     231           0 :             nop_three();
     232           0 :             break;
     233             :           case 4:
     234           0 :             nop_four();
     235           0 :             break;
     236             :           case 5:
     237           0 :             nop_five();
     238           0 :             break;
     239             :           case 6:
     240           0 :             nop_six();
     241           0 :             break;
     242             :           case 7:
     243           0 :             nop_seven();
     244           0 :             break;
     245             :           case 8:
     246           0 :             nop_eight();
     247           0 :             break;
     248             :           case 9:
     249           0 :             nop_nine();
     250           0 :             break;
     251             :           case 10:
     252           0 :             nop_three();
     253           0 :             nop_seven();
     254           0 :             break;
     255             :           case 11:
     256           0 :             nop_four();
     257           0 :             nop_seven();
     258           0 :             break;
     259             :           case 12:
     260           0 :             nop_six();
     261           0 :             nop_six();
     262           0 :             break;
     263             :           case 13:
     264           0 :             nop_six();
     265           0 :             nop_seven();
     266           0 :             break;
     267             :           case 14:
     268           0 :             nop_seven();
     269           0 :             nop_seven();
     270           0 :             break;
     271             :           case 15:
     272           0 :             nop_one();
     273           0 :             nop_seven();
     274           0 :             nop_seven();
     275           0 :             break;
     276             :           default:
     277           0 :             MOZ_CRASH("Unhandled alignment");
     278             :         }
     279           0 :     }
     280             : 
     281             :     // Stack operations:
     282             : 
     283      143086 :     void push_r(RegisterID reg)
     284             :     {
     285      143086 :         spew("push       %s", GPRegName(reg));
     286      143087 :         m_formatter.oneByteOp(OP_PUSH_EAX, reg);
     287      143090 :     }
     288             : 
     289      117823 :     void pop_r(RegisterID reg)
     290             :     {
     291      117823 :         spew("pop        %s", GPRegName(reg));
     292      117823 :         m_formatter.oneByteOp(OP_POP_EAX, reg);
     293      117824 :     }
     294             : 
     295        6210 :     void push_i(int32_t imm)
     296             :     {
     297        6210 :         spew("push       $%s0x%x", PRETTYHEX(imm));
     298        6210 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     299        2265 :             m_formatter.oneByteOp(OP_PUSH_Ib);
     300        2265 :             m_formatter.immediate8s(imm);
     301             :         } else {
     302        3945 :             m_formatter.oneByteOp(OP_PUSH_Iz);
     303        3945 :             m_formatter.immediate32(imm);
     304             :         }
     305        6210 :     }
     306             : 
     307             :     void push_i32(int32_t imm)
     308             :     {
     309             :         spew("push       $%s0x%04x", PRETTYHEX(imm));
     310             :         m_formatter.oneByteOp(OP_PUSH_Iz);
     311             :         m_formatter.immediate32(imm);
     312             :     }
     313             : 
     314        4054 :     void push_m(int32_t offset, RegisterID base)
     315             :     {
     316        4054 :         spew("push       " MEM_ob, ADDR_ob(offset, base));
     317        4054 :         m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_PUSH);
     318        4054 :     }
     319             : 
     320         665 :     void pop_m(int32_t offset, RegisterID base)
     321             :     {
     322         665 :         spew("pop        " MEM_ob, ADDR_ob(offset, base));
     323         665 :         m_formatter.oneByteOp(OP_GROUP1A_Ev, offset, base, GROUP1A_OP_POP);
     324         665 :     }
     325             : 
     326           0 :     void push_flags()
     327             :     {
     328           0 :         spew("pushf");
     329           0 :         m_formatter.oneByteOp(OP_PUSHFLAGS);
     330           0 :     }
     331             : 
     332           0 :     void pop_flags()
     333             :     {
     334           0 :         spew("popf");
     335           0 :         m_formatter.oneByteOp(OP_POPFLAGS);
     336           0 :     }
     337             : 
     338             :     // Arithmetic operations:
     339             : 
     340          47 :     void addl_rr(RegisterID src, RegisterID dst)
     341             :     {
     342          47 :         spew("addl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
     343          47 :         m_formatter.oneByteOp(OP_ADD_GvEv, src, dst);
     344          47 :     }
     345             : 
     346           0 :     void addw_rr(RegisterID src, RegisterID dst)
     347             :     {
     348           0 :         spew("addw       %s, %s", GPReg16Name(src), GPReg16Name(dst));
     349           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     350           0 :         m_formatter.oneByteOp(OP_ADD_GvEv, src, dst);
     351           0 :     }
     352             : 
     353           0 :     void addl_mr(int32_t offset, RegisterID base, RegisterID dst)
     354             :     {
     355           0 :         spew("addl       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
     356           0 :         m_formatter.oneByteOp(OP_ADD_GvEv, offset, base, dst);
     357           0 :     }
     358             : 
     359           0 :     void addl_rm(RegisterID src, int32_t offset, RegisterID base)
     360             :     {
     361           0 :         spew("addl       %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
     362           0 :         m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, src);
     363           0 :     }
     364             : 
     365           0 :     void addl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     366             :     {
     367           0 :         spew("addl       %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
     368           0 :         m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, index, scale, src);
     369           0 :     }
     370             : 
     371        1163 :     void addl_ir(int32_t imm, RegisterID dst)
     372             :     {
     373        1163 :         spew("addl       $%d, %s", imm, GPReg32Name(dst));
     374        1163 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     375        1163 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_ADD);
     376        1163 :             m_formatter.immediate8s(imm);
     377             :         } else {
     378           0 :             if (dst == rax)
     379           0 :                 m_formatter.oneByteOp(OP_ADD_EAXIv);
     380             :             else
     381           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD);
     382           0 :             m_formatter.immediate32(imm);
     383             :         }
     384        1163 :     }
     385             : 
     386           0 :     void addw_ir(int32_t imm, RegisterID dst)
     387             :     {
     388           0 :         spew("addw       $%d, %s", int16_t(imm), GPReg16Name(dst));
     389           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     390           0 :         m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD);
     391           0 :         m_formatter.immediate16(imm);
     392           0 :     }
     393             : 
     394             :     void addl_i32r(int32_t imm, RegisterID dst)
     395             :     {
     396             :         // 32-bit immediate always, for patching.
     397             :         spew("addl       $0x%04x, %s", imm, GPReg32Name(dst));
     398             :         if (dst == rax)
     399             :             m_formatter.oneByteOp(OP_ADD_EAXIv);
     400             :         else
     401             :             m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD);
     402             :         m_formatter.immediate32(imm);
     403             :     }
     404             : 
     405           8 :     void addl_im(int32_t imm, int32_t offset, RegisterID base)
     406             :     {
     407           8 :         spew("addl       $%d, " MEM_ob, imm, ADDR_ob(offset, base));
     408           8 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     409           8 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_ADD);
     410           8 :             m_formatter.immediate8s(imm);
     411             :         } else {
     412           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_ADD);
     413           0 :             m_formatter.immediate32(imm);
     414             :         }
     415           8 :     }
     416             : 
     417           0 :     void addl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
     418             :     {
     419           0 :         spew("addl       $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
     420           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     421           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_ADD);
     422           0 :             m_formatter.immediate8s(imm);
     423             :         } else {
     424           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_ADD);
     425           0 :             m_formatter.immediate32(imm);
     426             :         }
     427           0 :     }
     428             : 
     429           0 :     void addl_im(int32_t imm, const void* addr)
     430             :     {
     431           0 :         spew("addl       $%d, %p", imm, addr);
     432           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     433           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADD);
     434           0 :             m_formatter.immediate8s(imm);
     435             :         } else {
     436           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADD);
     437           0 :             m_formatter.immediate32(imm);
     438             :         }
     439           0 :     }
     440           0 :     void addw_im(int32_t imm, const void* addr)
     441             :     {
     442           0 :         spew("addw       $%d, %p", int16_t(imm), addr);
     443           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     444           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     445           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADD);
     446           0 :             m_formatter.immediate8s(imm);
     447             :         } else {
     448           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADD);
     449           0 :             m_formatter.immediate16(imm);
     450             :         }
     451           0 :     }
     452             : 
     453           0 :     void addw_im(int32_t imm, int32_t offset, RegisterID base) {
     454           0 :         spew("addw       $%d, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
     455           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     456           0 :         m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_ADD);
     457           0 :         m_formatter.immediate16(imm);
     458           0 :     }
     459             : 
     460           0 :     void addw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
     461             :     {
     462           0 :         spew("addw       $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
     463           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     464           0 :         m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_ADD);
     465           0 :         m_formatter.immediate16(imm);
     466           0 :     }
     467             : 
     468           0 :     void addw_rm(RegisterID src, int32_t offset, RegisterID base) {
     469           0 :         spew("addw       %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
     470           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     471           0 :         m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, src);
     472           0 :     }
     473             : 
     474           0 :     void addw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     475             :     {
     476           0 :         spew("addw       %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
     477           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     478           0 :         m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, index, scale, src);
     479           0 :     }
     480             : 
     481           0 :     void addb_im(int32_t imm, int32_t offset, RegisterID base) {
     482           0 :         spew("addb       $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
     483           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_ADD);
     484           0 :         m_formatter.immediate8(imm);
     485           0 :     }
     486             : 
     487           0 :     void addb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
     488             :     {
     489           0 :         spew("addb       $%d, " MEM_obs, int8_t(imm), ADDR_obs(offset, base, index, scale));
     490           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale, GROUP1_OP_ADD);
     491           0 :         m_formatter.immediate8(imm);
     492           0 :     }
     493             : 
     494           0 :     void addb_rm(RegisterID src, int32_t offset, RegisterID base) {
     495           0 :         spew("addb       %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
     496           0 :         m_formatter.oneByteOp8(OP_ADD_EbGb, offset, base, src);
     497           0 :     }
     498             : 
     499           0 :     void addb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     500             :     {
     501           0 :         spew("addb       %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
     502           0 :         m_formatter.oneByteOp8(OP_ADD_EbGb, offset, base, index, scale, src);
     503           0 :     }
     504             : 
     505           0 :     void subb_im(int32_t imm, int32_t offset, RegisterID base) {
     506           0 :         spew("subb       $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
     507           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_SUB);
     508           0 :         m_formatter.immediate8(imm);
     509           0 :     }
     510             : 
     511           0 :     void subb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
     512             :     {
     513           0 :         spew("subb       $%d, " MEM_obs, int8_t(imm), ADDR_obs(offset, base, index, scale));
     514           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale, GROUP1_OP_SUB);
     515           0 :         m_formatter.immediate8(imm);
     516           0 :     }
     517             : 
     518           0 :     void subb_rm(RegisterID src, int32_t offset, RegisterID base) {
     519           0 :         spew("subb       %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
     520           0 :         m_formatter.oneByteOp8(OP_SUB_EbGb, offset, base, src);
     521           0 :     }
     522             : 
     523           0 :     void subb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     524             :     {
     525           0 :         spew("subb       %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
     526           0 :         m_formatter.oneByteOp8(OP_SUB_EbGb, offset, base, index, scale, src);
     527           0 :     }
     528             : 
     529           0 :     void andb_im(int32_t imm, int32_t offset, RegisterID base) {
     530           0 :         spew("andb       $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
     531           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_AND);
     532           0 :         m_formatter.immediate8(imm);
     533           0 :     }
     534             : 
     535           0 :     void andb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
     536             :     {
     537           0 :         spew("andb       $%d, " MEM_obs, int8_t(imm), ADDR_obs(offset, base, index, scale));
     538           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale, GROUP1_OP_AND);
     539           0 :         m_formatter.immediate8(imm);
     540           0 :     }
     541             : 
     542           0 :     void andb_rm(RegisterID src, int32_t offset, RegisterID base) {
     543           0 :         spew("andb       %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
     544           0 :         m_formatter.oneByteOp8(OP_AND_EbGb, offset, base, src);
     545           0 :     }
     546             : 
     547           0 :     void andb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     548             :     {
     549           0 :         spew("andb       %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
     550           0 :         m_formatter.oneByteOp8(OP_AND_EbGb, offset, base, index, scale, src);
     551           0 :     }
     552             : 
     553           0 :     void orb_im(int32_t imm, int32_t offset, RegisterID base) {
     554           0 :         spew("orb       $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
     555           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_OR);
     556           0 :         m_formatter.immediate8(imm);
     557           0 :     }
     558             : 
     559           0 :     void orb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
     560             :     {
     561           0 :         spew("orb        $%d, " MEM_obs, int8_t(imm), ADDR_obs(offset, base, index, scale));
     562           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale, GROUP1_OP_OR);
     563           0 :         m_formatter.immediate8(imm);
     564           0 :     }
     565             : 
     566           0 :     void orb_rm(RegisterID src, int32_t offset, RegisterID base) {
     567           0 :         spew("orb       %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
     568           0 :         m_formatter.oneByteOp8(OP_OR_EbGb, offset, base, src);
     569           0 :     }
     570             : 
     571           0 :     void orb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     572             :     {
     573           0 :         spew("orb        %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
     574           0 :         m_formatter.oneByteOp8(OP_OR_EbGb, offset, base, index, scale, src);
     575           0 :     }
     576             : 
     577           0 :     void xorb_im(int32_t imm, int32_t offset, RegisterID base) {
     578           0 :         spew("xorb       $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
     579           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_XOR);
     580           0 :         m_formatter.immediate8(imm);
     581           0 :     }
     582             : 
     583           0 :     void xorb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
     584             :     {
     585           0 :         spew("xorb       $%d, " MEM_obs, int8_t(imm), ADDR_obs(offset, base, index, scale));
     586           0 :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale, GROUP1_OP_XOR);
     587           0 :         m_formatter.immediate8(imm);
     588           0 :     }
     589             : 
     590           0 :     void xorb_rm(RegisterID src, int32_t offset, RegisterID base) {
     591           0 :         spew("xorb       %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
     592           0 :         m_formatter.oneByteOp8(OP_XOR_EbGb, offset, base, src);
     593           0 :     }
     594             : 
     595           0 :     void xorb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     596             :     {
     597           0 :         spew("xorb       %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
     598           0 :         m_formatter.oneByteOp8(OP_XOR_EbGb, offset, base, index, scale, src);
     599           0 :     }
     600             : 
     601           0 :     void lock_xaddb_rm(RegisterID srcdest, int32_t offset, RegisterID base)
     602             :     {
     603           0 :         spew("lock xaddb %s, " MEM_ob, GPReg8Name(srcdest), ADDR_ob(offset, base));
     604           0 :         m_formatter.oneByteOp(PRE_LOCK);
     605           0 :         m_formatter.twoByteOp8(OP2_XADD_EbGb, offset, base, srcdest);
     606           0 :     }
     607             : 
     608           0 :     void lock_xaddb_rm(RegisterID srcdest, int32_t offset, RegisterID base, RegisterID index, int scale)
     609             :     {
     610           0 :         spew("lock xaddb %s, " MEM_obs, GPReg8Name(srcdest), ADDR_obs(offset, base, index, scale));
     611           0 :         m_formatter.oneByteOp(PRE_LOCK);
     612           0 :         m_formatter.twoByteOp8(OP2_XADD_EbGb, offset, base, index, scale, srcdest);
     613           0 :     }
     614             : 
     615           0 :     void lock_xaddl_rm(RegisterID srcdest, int32_t offset, RegisterID base)
     616             :     {
     617           0 :         spew("lock xaddl %s, " MEM_ob, GPReg32Name(srcdest), ADDR_ob(offset, base));
     618           0 :         m_formatter.oneByteOp(PRE_LOCK);
     619           0 :         m_formatter.twoByteOp(OP2_XADD_EvGv, offset, base, srcdest);
     620           0 :     }
     621             : 
     622           0 :     void lock_xaddl_rm(RegisterID srcdest, int32_t offset, RegisterID base, RegisterID index, int scale)
     623             :     {
     624           0 :         spew("lock xaddl %s, " MEM_obs, GPReg32Name(srcdest), ADDR_obs(offset, base, index, scale));
     625           0 :         m_formatter.oneByteOp(PRE_LOCK);
     626           0 :         m_formatter.twoByteOp(OP2_XADD_EvGv, offset, base, index, scale, srcdest);
     627           0 :     }
     628             : 
     629           0 :     void vpaddb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     630             :     {
     631           0 :         twoByteOpSimd("vpaddb", VEX_PD, OP2_PADDB_VdqWdq, src1, src0, dst);
     632           0 :     }
     633           0 :     void vpaddb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     634             :     {
     635           0 :         twoByteOpSimd("vpaddb", VEX_PD, OP2_PADDB_VdqWdq, offset, base, src0, dst);
     636           0 :     }
     637           0 :     void vpaddb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     638             :     {
     639           0 :         twoByteOpSimd("vpaddb", VEX_PD, OP2_PADDB_VdqWdq, address, src0, dst);
     640           0 :     }
     641             : 
     642           0 :     void vpaddsb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     643             :     {
     644           0 :         twoByteOpSimd("vpaddsb", VEX_PD, OP2_PADDSB_VdqWdq, src1, src0, dst);
     645           0 :     }
     646           0 :     void vpaddsb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     647             :     {
     648           0 :         twoByteOpSimd("vpaddsb", VEX_PD, OP2_PADDSB_VdqWdq, offset, base, src0, dst);
     649           0 :     }
     650           0 :     void vpaddsb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     651             :     {
     652           0 :         twoByteOpSimd("vpaddsb", VEX_PD, OP2_PADDSB_VdqWdq, address, src0, dst);
     653           0 :     }
     654             : 
     655           0 :     void vpaddusb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     656             :     {
     657           0 :         twoByteOpSimd("vpaddusb", VEX_PD, OP2_PADDUSB_VdqWdq, src1, src0, dst);
     658           0 :     }
     659           0 :     void vpaddusb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     660             :     {
     661           0 :         twoByteOpSimd("vpaddusb", VEX_PD, OP2_PADDUSB_VdqWdq, offset, base, src0, dst);
     662           0 :     }
     663           0 :     void vpaddusb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     664             :     {
     665           0 :         twoByteOpSimd("vpaddusb", VEX_PD, OP2_PADDUSB_VdqWdq, address, src0, dst);
     666           0 :     }
     667             : 
     668           0 :     void vpaddw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     669             :     {
     670           0 :         twoByteOpSimd("vpaddw", VEX_PD, OP2_PADDW_VdqWdq, src1, src0, dst);
     671           0 :     }
     672           0 :     void vpaddw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     673             :     {
     674           0 :         twoByteOpSimd("vpaddw", VEX_PD, OP2_PADDW_VdqWdq, offset, base, src0, dst);
     675           0 :     }
     676           0 :     void vpaddw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     677             :     {
     678           0 :         twoByteOpSimd("vpaddw", VEX_PD, OP2_PADDW_VdqWdq, address, src0, dst);
     679           0 :     }
     680             : 
     681           0 :     void vpaddsw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     682             :     {
     683           0 :         twoByteOpSimd("vpaddsw", VEX_PD, OP2_PADDSW_VdqWdq, src1, src0, dst);
     684           0 :     }
     685           0 :     void vpaddsw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     686             :     {
     687           0 :         twoByteOpSimd("vpaddsw", VEX_PD, OP2_PADDSW_VdqWdq, offset, base, src0, dst);
     688           0 :     }
     689           0 :     void vpaddsw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     690             :     {
     691           0 :         twoByteOpSimd("vpaddsw", VEX_PD, OP2_PADDSW_VdqWdq, address, src0, dst);
     692           0 :     }
     693             : 
     694           0 :     void vpaddusw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     695             :     {
     696           0 :         twoByteOpSimd("vpaddusw", VEX_PD, OP2_PADDUSW_VdqWdq, src1, src0, dst);
     697           0 :     }
     698           0 :     void vpaddusw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     699             :     {
     700           0 :         twoByteOpSimd("vpaddusw", VEX_PD, OP2_PADDUSW_VdqWdq, offset, base, src0, dst);
     701           0 :     }
     702           0 :     void vpaddusw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     703             :     {
     704           0 :         twoByteOpSimd("vpaddusw", VEX_PD, OP2_PADDUSW_VdqWdq, address, src0, dst);
     705           0 :     }
     706             : 
     707           0 :     void vpaddd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     708             :     {
     709           0 :         twoByteOpSimd("vpaddd", VEX_PD, OP2_PADDD_VdqWdq, src1, src0, dst);
     710           0 :     }
     711           0 :     void vpaddd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     712             :     {
     713           0 :         twoByteOpSimd("vpaddd", VEX_PD, OP2_PADDD_VdqWdq, offset, base, src0, dst);
     714           0 :     }
     715           0 :     void vpaddd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     716             :     {
     717           0 :         twoByteOpSimd("vpaddd", VEX_PD, OP2_PADDD_VdqWdq, address, src0, dst);
     718           0 :     }
     719             : 
     720           0 :     void vpsubb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     721             :     {
     722           0 :         twoByteOpSimd("vpsubb", VEX_PD, OP2_PSUBB_VdqWdq, src1, src0, dst);
     723           0 :     }
     724           0 :     void vpsubb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     725             :     {
     726           0 :         twoByteOpSimd("vpsubb", VEX_PD, OP2_PSUBB_VdqWdq, offset, base, src0, dst);
     727           0 :     }
     728           0 :     void vpsubb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     729             :     {
     730           0 :         twoByteOpSimd("vpsubb", VEX_PD, OP2_PSUBB_VdqWdq, address, src0, dst);
     731           0 :     }
     732             : 
     733           0 :     void vpsubsb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     734             :     {
     735           0 :         twoByteOpSimd("vpsubsb", VEX_PD, OP2_PSUBSB_VdqWdq, src1, src0, dst);
     736           0 :     }
     737           0 :     void vpsubsb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     738             :     {
     739           0 :         twoByteOpSimd("vpsubsb", VEX_PD, OP2_PSUBSB_VdqWdq, offset, base, src0, dst);
     740           0 :     }
     741           0 :     void vpsubsb_mr(const void* subress, XMMRegisterID src0, XMMRegisterID dst)
     742             :     {
     743           0 :         twoByteOpSimd("vpsubsb", VEX_PD, OP2_PSUBSB_VdqWdq, subress, src0, dst);
     744           0 :     }
     745             : 
     746           0 :     void vpsubusb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     747             :     {
     748           0 :         twoByteOpSimd("vpsubusb", VEX_PD, OP2_PSUBUSB_VdqWdq, src1, src0, dst);
     749           0 :     }
     750           0 :     void vpsubusb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     751             :     {
     752           0 :         twoByteOpSimd("vpsubusb", VEX_PD, OP2_PSUBUSB_VdqWdq, offset, base, src0, dst);
     753           0 :     }
     754           0 :     void vpsubusb_mr(const void* subress, XMMRegisterID src0, XMMRegisterID dst)
     755             :     {
     756           0 :         twoByteOpSimd("vpsubusb", VEX_PD, OP2_PSUBUSB_VdqWdq, subress, src0, dst);
     757           0 :     }
     758             : 
     759           0 :     void vpsubw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     760             :     {
     761           0 :         twoByteOpSimd("vpsubw", VEX_PD, OP2_PSUBW_VdqWdq, src1, src0, dst);
     762           0 :     }
     763           0 :     void vpsubw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     764             :     {
     765           0 :         twoByteOpSimd("vpsubw", VEX_PD, OP2_PSUBW_VdqWdq, offset, base, src0, dst);
     766           0 :     }
     767           0 :     void vpsubw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     768             :     {
     769           0 :         twoByteOpSimd("vpsubw", VEX_PD, OP2_PSUBW_VdqWdq, address, src0, dst);
     770           0 :     }
     771             : 
     772           0 :     void vpsubsw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     773             :     {
     774           0 :         twoByteOpSimd("vpsubsw", VEX_PD, OP2_PSUBSW_VdqWdq, src1, src0, dst);
     775           0 :     }
     776           0 :     void vpsubsw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     777             :     {
     778           0 :         twoByteOpSimd("vpsubsw", VEX_PD, OP2_PSUBSW_VdqWdq, offset, base, src0, dst);
     779           0 :     }
     780           0 :     void vpsubsw_mr(const void* subress, XMMRegisterID src0, XMMRegisterID dst)
     781             :     {
     782           0 :         twoByteOpSimd("vpsubsw", VEX_PD, OP2_PSUBSW_VdqWdq, subress, src0, dst);
     783           0 :     }
     784             : 
     785           0 :     void vpsubusw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     786             :     {
     787           0 :         twoByteOpSimd("vpsubusw", VEX_PD, OP2_PSUBUSW_VdqWdq, src1, src0, dst);
     788           0 :     }
     789           0 :     void vpsubusw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     790             :     {
     791           0 :         twoByteOpSimd("vpsubusw", VEX_PD, OP2_PSUBUSW_VdqWdq, offset, base, src0, dst);
     792           0 :     }
     793           0 :     void vpsubusw_mr(const void* subress, XMMRegisterID src0, XMMRegisterID dst)
     794             :     {
     795           0 :         twoByteOpSimd("vpsubusw", VEX_PD, OP2_PSUBUSW_VdqWdq, subress, src0, dst);
     796           0 :     }
     797             : 
     798           0 :     void vpsubd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     799             :     {
     800           0 :         twoByteOpSimd("vpsubd", VEX_PD, OP2_PSUBD_VdqWdq, src1, src0, dst);
     801           0 :     }
     802           0 :     void vpsubd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     803             :     {
     804           0 :         twoByteOpSimd("vpsubd", VEX_PD, OP2_PSUBD_VdqWdq, offset, base, src0, dst);
     805           0 :     }
     806           0 :     void vpsubd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     807             :     {
     808           0 :         twoByteOpSimd("vpsubd", VEX_PD, OP2_PSUBD_VdqWdq, address, src0, dst);
     809           0 :     }
     810             : 
     811           0 :     void vpmuludq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     812             :     {
     813           0 :         twoByteOpSimd("vpmuludq", VEX_PD, OP2_PMULUDQ_VdqWdq, src1, src0, dst);
     814           0 :     }
     815             :     void vpmuludq_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     816             :     {
     817             :         twoByteOpSimd("vpmuludq", VEX_PD, OP2_PMULUDQ_VdqWdq, offset, base, src0, dst);
     818             :     }
     819             : 
     820           0 :     void vpmullw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     821             :     {
     822           0 :         twoByteOpSimd("vpmullw", VEX_PD, OP2_PMULLW_VdqWdq, src1, src0, dst);
     823           0 :     }
     824           0 :     void vpmullw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     825             :     {
     826           0 :         twoByteOpSimd("vpmullw", VEX_PD, OP2_PMULLW_VdqWdq, offset, base, src0, dst);
     827           0 :     }
     828             : 
     829           0 :     void vpmulld_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     830             :     {
     831           0 :         threeByteOpSimd("vpmulld", VEX_PD, OP3_PMULLD_VdqWdq, ESCAPE_38, src1, src0, dst);
     832           0 :     }
     833           0 :     void vpmulld_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     834             :     {
     835           0 :         threeByteOpSimd("vpmulld", VEX_PD, OP3_PMULLD_VdqWdq, ESCAPE_38, offset, base, src0, dst);
     836           0 :     }
     837           0 :     void vpmulld_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     838             :     {
     839           0 :         threeByteOpSimd("vpmulld", VEX_PD, OP3_PMULLD_VdqWdq, ESCAPE_38, address, src0, dst);
     840           0 :     }
     841             : 
     842           0 :     void vaddps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     843             :     {
     844           0 :         twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, src1, src0, dst);
     845           0 :     }
     846           0 :     void vaddps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     847             :     {
     848           0 :         twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, offset, base, src0, dst);
     849           0 :     }
     850           0 :     void vaddps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     851             :     {
     852           0 :         twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, address, src0, dst);
     853           0 :     }
     854             : 
     855           0 :     void vsubps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     856             :     {
     857           0 :         twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, src1, src0, dst);
     858           0 :     }
     859           0 :     void vsubps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     860             :     {
     861           0 :         twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, offset, base, src0, dst);
     862           0 :     }
     863           0 :     void vsubps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     864             :     {
     865           0 :         twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, address, src0, dst);
     866           0 :     }
     867             : 
     868           0 :     void vmulps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     869             :     {
     870           0 :         twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, src1, src0, dst);
     871           0 :     }
     872           0 :     void vmulps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     873             :     {
     874           0 :         twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, offset, base, src0, dst);
     875           0 :     }
     876           0 :     void vmulps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     877             :     {
     878           0 :         twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, address, src0, dst);
     879           0 :     }
     880             : 
     881           0 :     void vdivps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     882             :     {
     883           0 :         twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, src1, src0, dst);
     884           0 :     }
     885           0 :     void vdivps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     886             :     {
     887           0 :         twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, offset, base, src0, dst);
     888           0 :     }
     889           0 :     void vdivps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     890             :     {
     891           0 :         twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, address, src0, dst);
     892           0 :     }
     893             : 
     894           0 :     void vmaxps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     895             :     {
     896           0 :         twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, src1, src0, dst);
     897           0 :     }
     898           0 :     void vmaxps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     899             :     {
     900           0 :         twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, offset, base, src0, dst);
     901           0 :     }
     902           0 :     void vmaxps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     903             :     {
     904           0 :         twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, address, src0, dst);
     905           0 :     }
     906             : 
     907           0 :     void vminps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
     908             :     {
     909           0 :         twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, src1, src0, dst);
     910           0 :     }
     911           0 :     void vminps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     912             :     {
     913           0 :         twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, offset, base, src0, dst);
     914           0 :     }
     915           0 :     void vminps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
     916             :     {
     917           0 :         twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, address, src0, dst);
     918           0 :     }
     919             : 
     920         164 :     void andl_rr(RegisterID src, RegisterID dst)
     921             :     {
     922         164 :         spew("andl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
     923         164 :         m_formatter.oneByteOp(OP_AND_GvEv, src, dst);
     924         164 :     }
     925             : 
     926           0 :     void andw_rr(RegisterID src, RegisterID dst)
     927             :     {
     928           0 :         spew("andw       %s, %s", GPReg16Name(src), GPReg16Name(dst));
     929           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     930           0 :         m_formatter.oneByteOp(OP_AND_GvEv, src, dst);
     931           0 :     }
     932             : 
     933           4 :     void andl_mr(int32_t offset, RegisterID base, RegisterID dst)
     934             :     {
     935           4 :         spew("andl       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
     936           4 :         m_formatter.oneByteOp(OP_AND_GvEv, offset, base, dst);
     937           4 :     }
     938             : 
     939           0 :     void andl_rm(RegisterID src, int32_t offset, RegisterID base)
     940             :     {
     941           0 :         spew("andl       %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
     942           0 :         m_formatter.oneByteOp(OP_AND_EvGv, offset, base, src);
     943           0 :     }
     944             : 
     945           0 :     void andw_rm(RegisterID src, int32_t offset, RegisterID base)
     946             :     {
     947           0 :         spew("andw       %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
     948           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     949           0 :         m_formatter.oneByteOp(OP_AND_EvGv, offset, base, src);
     950           0 :     }
     951             : 
     952           0 :     void andl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     953             :     {
     954           0 :         spew("andl       %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
     955           0 :         m_formatter.oneByteOp(OP_AND_EvGv, offset, base, index, scale, src);
     956           0 :     }
     957             : 
     958           0 :     void andw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     959             :     {
     960           0 :         spew("andw       %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
     961           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     962           0 :         m_formatter.oneByteOp(OP_AND_EvGv, offset, base, index, scale, src);
     963           0 :     }
     964             : 
     965         204 :     void andl_ir(int32_t imm, RegisterID dst)
     966             :     {
     967         204 :         spew("andl       $0x%x, %s", imm, GPReg32Name(dst));
     968         204 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     969          28 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_AND);
     970          28 :             m_formatter.immediate8s(imm);
     971             :         } else {
     972         176 :             if (dst == rax)
     973         125 :                 m_formatter.oneByteOp(OP_AND_EAXIv);
     974             :             else
     975          51 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_AND);
     976         176 :             m_formatter.immediate32(imm);
     977             :         }
     978         204 :     }
     979             : 
     980           0 :     void andw_ir(int32_t imm, RegisterID dst)
     981             :     {
     982           0 :         spew("andw       $0x%x, %s", int16_t(imm), GPReg16Name(dst));
     983           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
     984           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
     985           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_AND);
     986           0 :             m_formatter.immediate8s(imm);
     987             :         } else {
     988           0 :             if (dst == rax)
     989           0 :                 m_formatter.oneByteOp(OP_AND_EAXIv);
     990             :             else
     991           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_AND);
     992           0 :             m_formatter.immediate16(imm);
     993             :         }
     994           0 :     }
     995             : 
     996           0 :     void andl_im(int32_t imm, int32_t offset, RegisterID base)
     997             :     {
     998           0 :         spew("andl       $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
     999           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1000           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_AND);
    1001           0 :             m_formatter.immediate8s(imm);
    1002             :         } else {
    1003           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_AND);
    1004           0 :             m_formatter.immediate32(imm);
    1005             :         }
    1006           0 :     }
    1007             : 
    1008           0 :     void andw_im(int32_t imm, int32_t offset, RegisterID base)
    1009             :     {
    1010           0 :         spew("andw       $0x%x, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
    1011           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1012           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1013           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_AND);
    1014           0 :             m_formatter.immediate8s(imm);
    1015             :         } else {
    1016           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_AND);
    1017           0 :             m_formatter.immediate16(imm);
    1018             :         }
    1019           0 :     }
    1020             : 
    1021           0 :     void andl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1022             :     {
    1023           0 :         spew("andl       $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    1024           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1025           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_AND);
    1026           0 :             m_formatter.immediate8s(imm);
    1027             :         } else {
    1028           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_AND);
    1029           0 :             m_formatter.immediate32(imm);
    1030             :         }
    1031           0 :     }
    1032             : 
    1033           0 :     void andw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1034             :     {
    1035           0 :         spew("andw       $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
    1036           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1037           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1038           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_AND);
    1039           0 :             m_formatter.immediate8s(imm);
    1040             :         } else {
    1041           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_AND);
    1042           0 :             m_formatter.immediate16(imm);
    1043             :         }
    1044           0 :     }
    1045             : 
    1046             :     void fld_m(int32_t offset, RegisterID base)
    1047             :     {
    1048             :         spew("fld        " MEM_ob, ADDR_ob(offset, base));
    1049             :         m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FLD);
    1050             :     }
    1051             :     void fld32_m(int32_t offset, RegisterID base)
    1052             :     {
    1053             :         spew("fld        " MEM_ob, ADDR_ob(offset, base));
    1054             :         m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FLD);
    1055             :     }
    1056             :     void faddp()
    1057             :     {
    1058             :         spew("addp       ");
    1059             :         m_formatter.oneByteOp(OP_FPU6_ADDP);
    1060             :         m_formatter.oneByteOp(OP_ADDP_ST0_ST1);
    1061             :     }
    1062             :     void fisttp_m(int32_t offset, RegisterID base)
    1063             :     {
    1064             :         spew("fisttp     " MEM_ob, ADDR_ob(offset, base));
    1065             :         m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FISTTP);
    1066             :     }
    1067             :     void fistp_m(int32_t offset, RegisterID base)
    1068             :     {
    1069             :         spew("fistp      " MEM_ob, ADDR_ob(offset, base));
    1070             :         m_formatter.oneByteOp(OP_FILD, offset, base, FPU6_OP_FISTP);
    1071             :     }
    1072             :     void fstp_m(int32_t offset, RegisterID base)
    1073             :     {
    1074             :         spew("fstp       " MEM_ob, ADDR_ob(offset, base));
    1075             :         m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FSTP);
    1076             :     }
    1077             :     void fstp32_m(int32_t offset, RegisterID base)
    1078             :     {
    1079             :         spew("fstp32     " MEM_ob, ADDR_ob(offset, base));
    1080             :         m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FSTP);
    1081             :     }
    1082             :     void fnstcw_m(int32_t offset, RegisterID base)
    1083             :     {
    1084             :         spew("fnstcw     " MEM_ob, ADDR_ob(offset, base));
    1085             :         m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FISTP);
    1086             :     }
    1087             :     void fldcw_m(int32_t offset, RegisterID base)
    1088             :     {
    1089             :         spew("fldcw      " MEM_ob, ADDR_ob(offset, base));
    1090             :         m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FLDCW);
    1091             :     }
    1092             :     void fnstsw_m(int32_t offset, RegisterID base)
    1093             :     {
    1094             :         spew("fnstsw     " MEM_ob, ADDR_ob(offset, base));
    1095             :         m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FISTP);
    1096             :     }
    1097             : 
    1098           0 :     void negl_r(RegisterID dst)
    1099             :     {
    1100           0 :         spew("negl       %s", GPReg32Name(dst));
    1101           0 :         m_formatter.oneByteOp(OP_GROUP3_Ev, dst, GROUP3_OP_NEG);
    1102           0 :     }
    1103             : 
    1104           0 :     void negl_m(int32_t offset, RegisterID base)
    1105             :     {
    1106           0 :         spew("negl       " MEM_ob, ADDR_ob(offset, base));
    1107           0 :         m_formatter.oneByteOp(OP_GROUP3_Ev, offset, base, GROUP3_OP_NEG);
    1108           0 :     }
    1109             : 
    1110           1 :     void notl_r(RegisterID dst)
    1111             :     {
    1112           1 :         spew("notl       %s", GPReg32Name(dst));
    1113           1 :         m_formatter.oneByteOp(OP_GROUP3_Ev, dst, GROUP3_OP_NOT);
    1114           1 :     }
    1115             : 
    1116           0 :     void notl_m(int32_t offset, RegisterID base)
    1117             :     {
    1118           0 :         spew("notl       " MEM_ob, ADDR_ob(offset, base));
    1119           0 :         m_formatter.oneByteOp(OP_GROUP3_Ev, offset, base, GROUP3_OP_NOT);
    1120           0 :     }
    1121             : 
    1122           0 :     void orl_rr(RegisterID src, RegisterID dst)
    1123             :     {
    1124           0 :         spew("orl        %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1125           0 :         m_formatter.oneByteOp(OP_OR_GvEv, src, dst);
    1126           0 :     }
    1127             : 
    1128           0 :     void orw_rr(RegisterID src, RegisterID dst)
    1129             :     {
    1130           0 :         spew("orw        %s, %s", GPReg16Name(src), GPReg16Name(dst));
    1131           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1132           0 :         m_formatter.oneByteOp(OP_OR_GvEv, src, dst);
    1133           0 :     }
    1134             : 
    1135           0 :     void orl_mr(int32_t offset, RegisterID base, RegisterID dst)
    1136             :     {
    1137           0 :         spew("orl        " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    1138           0 :         m_formatter.oneByteOp(OP_OR_GvEv, offset, base, dst);
    1139           0 :     }
    1140             : 
    1141           0 :     void orl_rm(RegisterID src, int32_t offset, RegisterID base)
    1142             :     {
    1143           0 :         spew("orl        %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    1144           0 :         m_formatter.oneByteOp(OP_OR_EvGv, offset, base, src);
    1145           0 :     }
    1146             : 
    1147           0 :     void orw_rm(RegisterID src, int32_t offset, RegisterID base)
    1148             :     {
    1149           0 :         spew("orw        %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    1150           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1151           0 :         m_formatter.oneByteOp(OP_OR_EvGv, offset, base, src);
    1152           0 :     }
    1153             : 
    1154           0 :     void orl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1155             :     {
    1156           0 :         spew("orl        %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
    1157           0 :         m_formatter.oneByteOp(OP_OR_EvGv, offset, base, index, scale, src);
    1158           0 :     }
    1159             : 
    1160           0 :     void orw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1161             :     {
    1162           0 :         spew("orw        %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
    1163           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1164           0 :         m_formatter.oneByteOp(OP_OR_EvGv, offset, base, index, scale, src);
    1165           0 :     }
    1166             : 
    1167           0 :     void orl_ir(int32_t imm, RegisterID dst)
    1168             :     {
    1169           0 :         spew("orl        $0x%x, %s", imm, GPReg32Name(dst));
    1170           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1171           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_OR);
    1172           0 :             m_formatter.immediate8s(imm);
    1173             :         } else {
    1174           0 :             if (dst == rax)
    1175           0 :                 m_formatter.oneByteOp(OP_OR_EAXIv);
    1176             :             else
    1177           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_OR);
    1178           0 :             m_formatter.immediate32(imm);
    1179             :         }
    1180           0 :     }
    1181             : 
    1182           0 :     void orw_ir(int32_t imm, RegisterID dst)
    1183             :     {
    1184           0 :         spew("orw        $0x%x, %s", int16_t(imm), GPReg16Name(dst));
    1185           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1186           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1187           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_OR);
    1188           0 :             m_formatter.immediate8s(imm);
    1189             :         } else {
    1190           0 :             if (dst == rax)
    1191           0 :                 m_formatter.oneByteOp(OP_OR_EAXIv);
    1192             :             else
    1193           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_OR);
    1194           0 :             m_formatter.immediate16(imm);
    1195             :         }
    1196           0 :     }
    1197             : 
    1198         185 :     void orl_im(int32_t imm, int32_t offset, RegisterID base)
    1199             :     {
    1200         185 :         spew("orl        $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
    1201         185 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1202         185 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_OR);
    1203         185 :             m_formatter.immediate8s(imm);
    1204             :         } else {
    1205           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_OR);
    1206           0 :             m_formatter.immediate32(imm);
    1207             :         }
    1208         185 :     }
    1209             : 
    1210           0 :     void orw_im(int32_t imm, int32_t offset, RegisterID base)
    1211             :     {
    1212           0 :         spew("orw        $0x%x, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
    1213           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1214           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1215           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_OR);
    1216           0 :             m_formatter.immediate8s(imm);
    1217             :         } else {
    1218           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_OR);
    1219           0 :             m_formatter.immediate16(imm);
    1220             :         }
    1221           0 :     }
    1222             : 
    1223           0 :     void orl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1224             :     {
    1225           0 :         spew("orl        $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    1226           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1227           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_OR);
    1228           0 :             m_formatter.immediate8s(imm);
    1229             :         } else {
    1230           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_OR);
    1231           0 :             m_formatter.immediate32(imm);
    1232             :         }
    1233           0 :     }
    1234             : 
    1235           0 :     void orw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1236             :     {
    1237           0 :         spew("orw        $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
    1238           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1239           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1240           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_OR);
    1241           0 :             m_formatter.immediate8s(imm);
    1242             :         } else {
    1243           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_OR);
    1244           0 :             m_formatter.immediate16(imm);
    1245             :         }
    1246           0 :     }
    1247             : 
    1248          15 :     void subl_rr(RegisterID src, RegisterID dst)
    1249             :     {
    1250          15 :         spew("subl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1251          15 :         m_formatter.oneByteOp(OP_SUB_GvEv, src, dst);
    1252          15 :     }
    1253             : 
    1254           0 :     void subw_rr(RegisterID src, RegisterID dst)
    1255             :     {
    1256           0 :         spew("subw       %s, %s", GPReg16Name(src), GPReg16Name(dst));
    1257           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1258           0 :         m_formatter.oneByteOp(OP_SUB_GvEv, src, dst);
    1259           0 :     }
    1260             : 
    1261           0 :     void subl_mr(int32_t offset, RegisterID base, RegisterID dst)
    1262             :     {
    1263           0 :         spew("subl       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    1264           0 :         m_formatter.oneByteOp(OP_SUB_GvEv, offset, base, dst);
    1265           0 :     }
    1266             : 
    1267           0 :     void subl_rm(RegisterID src, int32_t offset, RegisterID base)
    1268             :     {
    1269           0 :         spew("subl       %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    1270           0 :         m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, src);
    1271           0 :     }
    1272             : 
    1273           0 :     void subw_rm(RegisterID src, int32_t offset, RegisterID base)
    1274             :     {
    1275           0 :         spew("subw       %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    1276           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1277           0 :         m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, src);
    1278           0 :     }
    1279             : 
    1280           0 :     void subl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1281             :     {
    1282           0 :         spew("subl       %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
    1283           0 :         m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, index, scale, src);
    1284           0 :     }
    1285             : 
    1286           0 :     void subw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1287             :     {
    1288           0 :         spew("subw       %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
    1289           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1290           0 :         m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, index, scale, src);
    1291           0 :     }
    1292             : 
    1293         663 :     void subl_ir(int32_t imm, RegisterID dst)
    1294             :     {
    1295         663 :         spew("subl       $%d, %s", imm, GPReg32Name(dst));
    1296         663 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1297         663 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_SUB);
    1298         663 :             m_formatter.immediate8s(imm);
    1299             :         } else {
    1300           0 :             if (dst == rax)
    1301           0 :                 m_formatter.oneByteOp(OP_SUB_EAXIv);
    1302             :             else
    1303           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_SUB);
    1304           0 :             m_formatter.immediate32(imm);
    1305             :         }
    1306         663 :     }
    1307             : 
    1308           0 :     void subw_ir(int32_t imm, RegisterID dst)
    1309             :     {
    1310           0 :         spew("subw       $%d, %s", int16_t(imm), GPReg16Name(dst));
    1311           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1312           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1313           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_SUB);
    1314           0 :             m_formatter.immediate8s(imm);
    1315             :         } else {
    1316           0 :             if (dst == rax)
    1317           0 :                 m_formatter.oneByteOp(OP_SUB_EAXIv);
    1318             :             else
    1319           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_SUB);
    1320           0 :             m_formatter.immediate16(imm);
    1321             :         }
    1322           0 :     }
    1323             : 
    1324           0 :     void subl_im(int32_t imm, int32_t offset, RegisterID base)
    1325             :     {
    1326           0 :         spew("subl       $%d, " MEM_ob, imm, ADDR_ob(offset, base));
    1327           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1328           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_SUB);
    1329           0 :             m_formatter.immediate8s(imm);
    1330             :         } else {
    1331           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_SUB);
    1332           0 :             m_formatter.immediate32(imm);
    1333             :         }
    1334           0 :     }
    1335             : 
    1336           0 :     void subw_im(int32_t imm, int32_t offset, RegisterID base)
    1337             :     {
    1338           0 :         spew("subw       $%d, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
    1339           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1340           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1341           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_SUB);
    1342           0 :             m_formatter.immediate8s(imm);
    1343             :         } else {
    1344           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_SUB);
    1345           0 :             m_formatter.immediate16(imm);
    1346             :         }
    1347           0 :     }
    1348             : 
    1349           0 :     void subl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1350             :     {
    1351           0 :         spew("subl       $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    1352           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1353           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_SUB);
    1354           0 :             m_formatter.immediate8s(imm);
    1355             :         } else {
    1356           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_SUB);
    1357           0 :             m_formatter.immediate32(imm);
    1358             :         }
    1359           0 :     }
    1360             : 
    1361           0 :     void subw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1362             :     {
    1363           0 :         spew("subw       $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
    1364           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1365           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1366           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_SUB);
    1367           0 :             m_formatter.immediate8s(imm);
    1368             :         } else {
    1369           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_SUB);
    1370           0 :             m_formatter.immediate16(imm);
    1371             :         }
    1372           0 :     }
    1373             : 
    1374        1199 :     void xorl_rr(RegisterID src, RegisterID dst)
    1375             :     {
    1376        1199 :         spew("xorl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1377        1199 :         m_formatter.oneByteOp(OP_XOR_GvEv, src, dst);
    1378        1199 :     }
    1379             : 
    1380           0 :     void xorw_rr(RegisterID src, RegisterID dst)
    1381             :     {
    1382           0 :         spew("xorw       %s, %s", GPReg16Name(src), GPReg16Name(dst));
    1383           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1384           0 :         m_formatter.oneByteOp(OP_XOR_GvEv, src, dst);
    1385           0 :     }
    1386             : 
    1387           0 :     void xorl_mr(int32_t offset, RegisterID base, RegisterID dst)
    1388             :     {
    1389           0 :         spew("xorl       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    1390           0 :         m_formatter.oneByteOp(OP_XOR_GvEv, offset, base, dst);
    1391           0 :     }
    1392             : 
    1393           0 :     void xorl_rm(RegisterID src, int32_t offset, RegisterID base)
    1394             :     {
    1395           0 :         spew("xorl       %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    1396           0 :         m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, src);
    1397           0 :     }
    1398             : 
    1399           0 :     void xorw_rm(RegisterID src, int32_t offset, RegisterID base)
    1400             :     {
    1401           0 :         spew("xorw       %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    1402           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1403           0 :         m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, src);
    1404           0 :     }
    1405             : 
    1406           0 :     void xorl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1407             :     {
    1408           0 :         spew("xorl       %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
    1409           0 :         m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, index, scale, src);
    1410           0 :     }
    1411             : 
    1412           0 :     void xorw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1413             :     {
    1414           0 :         spew("xorw       %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
    1415           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1416           0 :         m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, index, scale, src);
    1417           0 :     }
    1418             : 
    1419           0 :     void xorl_im(int32_t imm, int32_t offset, RegisterID base)
    1420             :     {
    1421           0 :         spew("xorl       $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
    1422           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1423           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_XOR);
    1424           0 :             m_formatter.immediate8s(imm);
    1425             :         } else {
    1426           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_XOR);
    1427           0 :             m_formatter.immediate32(imm);
    1428             :         }
    1429           0 :     }
    1430             : 
    1431           0 :     void xorw_im(int32_t imm, int32_t offset, RegisterID base)
    1432             :     {
    1433           0 :         spew("xorw       $0x%x, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
    1434           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1435           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1436           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_XOR);
    1437           0 :             m_formatter.immediate8s(imm);
    1438             :         } else {
    1439           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_XOR);
    1440           0 :             m_formatter.immediate16(imm);
    1441             :         }
    1442           0 :     }
    1443             : 
    1444           0 :     void xorl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1445             :     {
    1446           0 :         spew("xorl       $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    1447           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1448           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_XOR);
    1449           0 :             m_formatter.immediate8s(imm);
    1450             :         } else {
    1451           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_XOR);
    1452           0 :             m_formatter.immediate32(imm);
    1453             :         }
    1454           0 :     }
    1455             : 
    1456           0 :     void xorw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1457             :     {
    1458           0 :         spew("xorw       $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
    1459           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1460           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1461           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_XOR);
    1462           0 :             m_formatter.immediate8s(imm);
    1463             :         } else {
    1464           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_XOR);
    1465           0 :             m_formatter.immediate16(imm);
    1466             :         }
    1467           0 :     }
    1468             : 
    1469          37 :     void xorl_ir(int32_t imm, RegisterID dst)
    1470             :     {
    1471          37 :         spew("xorl       $%d, %s", imm, GPReg32Name(dst));
    1472          37 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1473          37 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_XOR);
    1474          37 :             m_formatter.immediate8s(imm);
    1475             :         } else {
    1476           0 :             if (dst == rax)
    1477           0 :                 m_formatter.oneByteOp(OP_XOR_EAXIv);
    1478             :             else
    1479           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_XOR);
    1480           0 :             m_formatter.immediate32(imm);
    1481             :         }
    1482          37 :     }
    1483             : 
    1484           0 :     void xorw_ir(int32_t imm, RegisterID dst)
    1485             :     {
    1486           0 :         spew("xorw       $%d, %s", int16_t(imm), GPReg16Name(dst));
    1487           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1488           0 :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1489           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_XOR);
    1490           0 :             m_formatter.immediate8s(imm);
    1491             :         } else {
    1492           0 :             if (dst == rax)
    1493           0 :                 m_formatter.oneByteOp(OP_XOR_EAXIv);
    1494             :             else
    1495           0 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_XOR);
    1496           0 :             m_formatter.immediate16(imm);
    1497             :         }
    1498           0 :     }
    1499             : 
    1500           0 :     void sarl_ir(int32_t imm, RegisterID dst)
    1501             :     {
    1502           0 :         MOZ_ASSERT(imm < 32);
    1503           0 :         spew("sarl       $%d, %s", imm, GPReg32Name(dst));
    1504           0 :         if (imm == 1)
    1505           0 :             m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_SAR);
    1506             :         else {
    1507           0 :             m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_SAR);
    1508           0 :             m_formatter.immediate8u(imm);
    1509             :         }
    1510           0 :     }
    1511             : 
    1512           0 :     void sarl_CLr(RegisterID dst)
    1513             :     {
    1514           0 :         spew("sarl       %%cl, %s", GPReg32Name(dst));
    1515           0 :         m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_SAR);
    1516           0 :     }
    1517             : 
    1518           2 :     void shrl_ir(int32_t imm, RegisterID dst)
    1519             :     {
    1520           2 :         MOZ_ASSERT(imm < 32);
    1521           2 :         spew("shrl       $%d, %s", imm, GPReg32Name(dst));
    1522           2 :         if (imm == 1)
    1523           0 :             m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_SHR);
    1524             :         else {
    1525           2 :             m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_SHR);
    1526           2 :             m_formatter.immediate8u(imm);
    1527             :         }
    1528           2 :     }
    1529             : 
    1530           0 :     void shrl_CLr(RegisterID dst)
    1531             :     {
    1532           0 :         spew("shrl       %%cl, %s", GPReg32Name(dst));
    1533           0 :         m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_SHR);
    1534           0 :     }
    1535             : 
    1536             :     void shrdl_CLr(RegisterID src, RegisterID dst)
    1537             :     {
    1538             :         spew("shrdl      %%cl, %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1539             :         m_formatter.twoByteOp(OP2_SHRD_GvEv, dst, src);
    1540             :     }
    1541             : 
    1542             :     void shldl_CLr(RegisterID src, RegisterID dst)
    1543             :     {
    1544             :         spew("shldl      %%cl, %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1545             :         m_formatter.twoByteOp(OP2_SHLD_GvEv, dst, src);
    1546             :     }
    1547             : 
    1548          12 :     void shll_ir(int32_t imm, RegisterID dst)
    1549             :     {
    1550          12 :         MOZ_ASSERT(imm < 32);
    1551          12 :         spew("shll       $%d, %s", imm, GPReg32Name(dst));
    1552          12 :         if (imm == 1)
    1553           0 :             m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_SHL);
    1554             :         else {
    1555          12 :             m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_SHL);
    1556          12 :             m_formatter.immediate8u(imm);
    1557             :         }
    1558          12 :     }
    1559             : 
    1560           0 :     void shll_CLr(RegisterID dst)
    1561             :     {
    1562           0 :         spew("shll       %%cl, %s", GPReg32Name(dst));
    1563           0 :         m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_SHL);
    1564           0 :     }
    1565             : 
    1566           0 :     void roll_ir(int32_t imm, RegisterID dst)
    1567             :     {
    1568           0 :         MOZ_ASSERT(imm < 32);
    1569           0 :         spew("roll       $%d, %s", imm, GPReg32Name(dst));
    1570           0 :         if (imm == 1)
    1571           0 :             m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_ROL);
    1572             :         else {
    1573           0 :             m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_ROL);
    1574           0 :             m_formatter.immediate8u(imm);
    1575             :         }
    1576           0 :     }
    1577           0 :     void roll_CLr(RegisterID dst)
    1578             :     {
    1579           0 :         spew("roll       %%cl, %s", GPReg32Name(dst));
    1580           0 :         m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_ROL);
    1581           0 :     }
    1582             : 
    1583           0 :     void rorl_ir(int32_t imm, RegisterID dst)
    1584             :     {
    1585           0 :         MOZ_ASSERT(imm < 32);
    1586           0 :         spew("rorl       $%d, %s", imm, GPReg32Name(dst));
    1587           0 :         if (imm == 1)
    1588           0 :             m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_ROR);
    1589             :         else {
    1590           0 :             m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_ROR);
    1591           0 :             m_formatter.immediate8u(imm);
    1592             :         }
    1593           0 :     }
    1594           0 :     void rorl_CLr(RegisterID dst)
    1595             :     {
    1596           0 :         spew("rorl       %%cl, %s", GPReg32Name(dst));
    1597           0 :         m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_ROR);
    1598           0 :     }
    1599             : 
    1600           0 :     void bsrl_rr(RegisterID src, RegisterID dst)
    1601             :     {
    1602           0 :         spew("bsrl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1603           0 :         m_formatter.twoByteOp(OP2_BSR_GvEv, src, dst);
    1604           0 :     }
    1605             : 
    1606           0 :     void bsfl_rr(RegisterID src, RegisterID dst)
    1607             :     {
    1608           0 :         spew("bsfl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1609           0 :         m_formatter.twoByteOp(OP2_BSF_GvEv, src, dst);
    1610           0 :     }
    1611             : 
    1612           0 :     void popcntl_rr(RegisterID src, RegisterID dst)
    1613             :     {
    1614           0 :         spew("popcntl    %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1615           0 :         m_formatter.legacySSEPrefix(VEX_SS);
    1616           0 :         m_formatter.twoByteOp(OP2_POPCNT_GvEv, src, dst);
    1617           0 :     }
    1618             : 
    1619           0 :     void imull_rr(RegisterID src, RegisterID dst)
    1620             :     {
    1621           0 :         spew("imull      %s, %s", GPReg32Name(src), GPReg32Name(dst));
    1622           0 :         m_formatter.twoByteOp(OP2_IMUL_GvEv, src, dst);
    1623           0 :     }
    1624             : 
    1625           0 :     void imull_r(RegisterID multiplier)
    1626             :     {
    1627           0 :         spew("imull      %s", GPReg32Name(multiplier));
    1628           0 :         m_formatter.oneByteOp(OP_GROUP3_Ev, multiplier, GROUP3_OP_IMUL);
    1629           0 :     }
    1630             : 
    1631           0 :     void imull_mr(int32_t offset, RegisterID base, RegisterID dst)
    1632             :     {
    1633           0 :         spew("imull      " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    1634           0 :         m_formatter.twoByteOp(OP2_IMUL_GvEv, offset, base, dst);
    1635           0 :     }
    1636             : 
    1637           0 :     void imull_ir(int32_t value, RegisterID src, RegisterID dst)
    1638             :     {
    1639           0 :         spew("imull      $%d, %s, %s", value, GPReg32Name(src), GPReg32Name(dst));
    1640           0 :         if (CAN_SIGN_EXTEND_8_32(value)) {
    1641           0 :             m_formatter.oneByteOp(OP_IMUL_GvEvIb, src, dst);
    1642           0 :             m_formatter.immediate8s(value);
    1643             :         } else {
    1644           0 :             m_formatter.oneByteOp(OP_IMUL_GvEvIz, src, dst);
    1645           0 :             m_formatter.immediate32(value);
    1646             :         }
    1647           0 :     }
    1648             : 
    1649           0 :     void mull_r(RegisterID multiplier)
    1650             :     {
    1651           0 :         spew("mull       %s", GPReg32Name(multiplier));
    1652           0 :         m_formatter.oneByteOp(OP_GROUP3_Ev, multiplier, GROUP3_OP_MUL);
    1653           0 :     }
    1654             : 
    1655           0 :     void idivl_r(RegisterID divisor)
    1656             :     {
    1657           0 :         spew("idivl      %s", GPReg32Name(divisor));
    1658           0 :         m_formatter.oneByteOp(OP_GROUP3_Ev, divisor, GROUP3_OP_IDIV);
    1659           0 :     }
    1660             : 
    1661           0 :     void divl_r(RegisterID divisor)
    1662             :     {
    1663           0 :         spew("div        %s", GPReg32Name(divisor));
    1664           0 :         m_formatter.oneByteOp(OP_GROUP3_Ev, divisor, GROUP3_OP_DIV);
    1665           0 :     }
    1666             : 
    1667           0 :     void prefix_lock()
    1668             :     {
    1669           0 :         spew("lock");
    1670           0 :         m_formatter.oneByteOp(PRE_LOCK);
    1671           0 :     }
    1672             : 
    1673           0 :     void prefix_16_for_32()
    1674             :     {
    1675           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1676           0 :     }
    1677             : 
    1678             :     void incl_m32(int32_t offset, RegisterID base)
    1679             :     {
    1680             :         spew("incl       " MEM_ob, ADDR_ob(offset, base));
    1681             :         m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_INC);
    1682             :     }
    1683             : 
    1684             :     void decl_m32(int32_t offset, RegisterID base)
    1685             :     {
    1686             :         spew("decl       " MEM_ob, ADDR_ob(offset, base));
    1687             :         m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_DEC);
    1688             :     }
    1689             : 
    1690             :     // Note that CMPXCHG performs comparison against REG = %al/%ax/%eax/%rax.
    1691             :     // If %REG == [%base+offset], then %src -> [%base+offset].
    1692             :     // Otherwise, [%base+offset] -> %REG.
    1693             :     // For the 8-bit operations src must also be an 8-bit register.
    1694             : 
    1695           0 :     void cmpxchgb(RegisterID src, int32_t offset, RegisterID base)
    1696             :     {
    1697           0 :         spew("cmpxchgb   %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    1698           0 :         m_formatter.twoByteOp8(OP2_CMPXCHG_GvEb, offset, base, src);
    1699           0 :     }
    1700           0 :     void cmpxchgb(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1701             :     {
    1702           0 :         spew("cmpxchgb   %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
    1703           0 :         m_formatter.twoByteOp8(OP2_CMPXCHG_GvEb, offset, base, index, scale, src);
    1704           0 :     }
    1705           0 :     void cmpxchgw(RegisterID src, int32_t offset, RegisterID base)
    1706             :     {
    1707           0 :         spew("cmpxchgw   %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    1708           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1709           0 :         m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, offset, base, src);
    1710           0 :     }
    1711           0 :     void cmpxchgw(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1712             :     {
    1713           0 :         spew("cmpxchgw   %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
    1714           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1715           0 :         m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, offset, base, index, scale, src);
    1716           0 :     }
    1717           0 :     void cmpxchgl(RegisterID src, int32_t offset, RegisterID base)
    1718             :     {
    1719           0 :         spew("cmpxchgl   %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    1720           0 :         m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, offset, base, src);
    1721           0 :     }
    1722           0 :     void cmpxchgl(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    1723             :     {
    1724           0 :         spew("cmpxchgl   %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
    1725           0 :         m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, offset, base, index, scale, src);
    1726           0 :     }
    1727             : 
    1728             : 
    1729             :     // Comparisons:
    1730             : 
    1731         226 :     void cmpl_rr(RegisterID rhs, RegisterID lhs)
    1732             :     {
    1733         226 :         spew("cmpl       %s, %s", GPReg32Name(rhs), GPReg32Name(lhs));
    1734         226 :         m_formatter.oneByteOp(OP_CMP_GvEv, rhs, lhs);
    1735         226 :     }
    1736             : 
    1737         101 :     void cmpl_rm(RegisterID rhs, int32_t offset, RegisterID base)
    1738             :     {
    1739         101 :         spew("cmpl       %s, " MEM_ob, GPReg32Name(rhs), ADDR_ob(offset, base));
    1740         101 :         m_formatter.oneByteOp(OP_CMP_EvGv, offset, base, rhs);
    1741         101 :     }
    1742             : 
    1743           3 :     void cmpl_mr(int32_t offset, RegisterID base, RegisterID lhs)
    1744             :     {
    1745           3 :         spew("cmpl       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(lhs));
    1746           3 :         m_formatter.oneByteOp(OP_CMP_GvEv, offset, base, lhs);
    1747           3 :     }
    1748             : 
    1749           0 :     void cmpl_mr(const void* address, RegisterID lhs)
    1750             :     {
    1751           0 :         spew("cmpl       %p, %s", address, GPReg32Name(lhs));
    1752           0 :         m_formatter.oneByteOp(OP_CMP_GvEv, address, lhs);
    1753           0 :     }
    1754             : 
    1755        7659 :     void cmpl_ir(int32_t rhs, RegisterID lhs)
    1756             :     {
    1757        7659 :         if (rhs == 0) {
    1758         267 :             testl_rr(lhs, lhs);
    1759         267 :             return;
    1760             :         }
    1761             : 
    1762        7392 :         spew("cmpl       $0x%x, %s", rhs, GPReg32Name(lhs));
    1763        7392 :         if (CAN_SIGN_EXTEND_8_32(rhs)) {
    1764         711 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, lhs, GROUP1_OP_CMP);
    1765         711 :             m_formatter.immediate8s(rhs);
    1766             :         } else {
    1767        6681 :             if (lhs == rax)
    1768         264 :                 m_formatter.oneByteOp(OP_CMP_EAXIv);
    1769             :             else
    1770        6417 :                 m_formatter.oneByteOp(OP_GROUP1_EvIz, lhs, GROUP1_OP_CMP);
    1771        6681 :             m_formatter.immediate32(rhs);
    1772             :         }
    1773             :     }
    1774             : 
    1775             :     void cmpl_i32r(int32_t rhs, RegisterID lhs)
    1776             :     {
    1777             :         spew("cmpl       $0x%04x, %s", rhs, GPReg32Name(lhs));
    1778             :         if (lhs == rax)
    1779             :             m_formatter.oneByteOp(OP_CMP_EAXIv);
    1780             :         else
    1781             :             m_formatter.oneByteOp(OP_GROUP1_EvIz, lhs, GROUP1_OP_CMP);
    1782             :         m_formatter.immediate32(rhs);
    1783             :     }
    1784             : 
    1785        1658 :     void cmpl_im(int32_t rhs, int32_t offset, RegisterID base)
    1786             :     {
    1787        1658 :         spew("cmpl       $0x%x, " MEM_ob, rhs, ADDR_ob(offset, base));
    1788        1658 :         if (CAN_SIGN_EXTEND_8_32(rhs)) {
    1789        1616 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_CMP);
    1790        1616 :             m_formatter.immediate8s(rhs);
    1791             :         } else {
    1792          42 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_CMP);
    1793          42 :             m_formatter.immediate32(rhs);
    1794             :         }
    1795        1658 :     }
    1796             : 
    1797             :     void cmpb_im(int32_t rhs, int32_t offset, RegisterID base)
    1798             :     {
    1799             :         spew("cmpb       $0x%x, " MEM_ob, rhs, ADDR_ob(offset, base));
    1800             :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_CMP);
    1801             :         m_formatter.immediate8(rhs);
    1802             :     }
    1803             : 
    1804             :     void cmpb_im(int32_t rhs, int32_t offset, RegisterID base, RegisterID index, int scale)
    1805             :     {
    1806             :         spew("cmpb       $0x%x, " MEM_obs, rhs, ADDR_obs(offset, base, index, scale));
    1807             :         m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale, GROUP1_OP_CMP);
    1808             :         m_formatter.immediate8(rhs);
    1809             :     }
    1810             : 
    1811           0 :     void cmpl_im(int32_t rhs, int32_t offset, RegisterID base, RegisterID index, int scale)
    1812             :     {
    1813           0 :         spew("cmpl       $0x%x, " MEM_o32b, rhs, ADDR_o32b(offset, base));
    1814           0 :         if (CAN_SIGN_EXTEND_8_32(rhs)) {
    1815           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_CMP);
    1816           0 :             m_formatter.immediate8s(rhs);
    1817             :         } else {
    1818           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_CMP);
    1819           0 :             m_formatter.immediate32(rhs);
    1820             :         }
    1821           0 :     }
    1822             : 
    1823             :     MOZ_MUST_USE JmpSrc
    1824             :     cmpl_im_disp32(int32_t rhs, int32_t offset, RegisterID base)
    1825             :     {
    1826             :         spew("cmpl       $0x%x, " MEM_o32b, rhs, ADDR_o32b(offset, base));
    1827             :         JmpSrc r;
    1828             :         if (CAN_SIGN_EXTEND_8_32(rhs)) {
    1829             :             m_formatter.oneByteOp_disp32(OP_GROUP1_EvIb, offset, base, GROUP1_OP_CMP);
    1830             :             r = JmpSrc(m_formatter.size());
    1831             :             m_formatter.immediate8s(rhs);
    1832             :         } else {
    1833             :             m_formatter.oneByteOp_disp32(OP_GROUP1_EvIz, offset, base, GROUP1_OP_CMP);
    1834             :             r = JmpSrc(m_formatter.size());
    1835             :             m_formatter.immediate32(rhs);
    1836             :         }
    1837             :         return r;
    1838             :     }
    1839             : 
    1840             :     MOZ_MUST_USE JmpSrc
    1841             :     cmpl_im_disp32(int32_t rhs, const void* addr)
    1842             :     {
    1843             :         spew("cmpl       $0x%x, %p", rhs, addr);
    1844             :         JmpSrc r;
    1845             :         if (CAN_SIGN_EXTEND_8_32(rhs)) {
    1846             :             m_formatter.oneByteOp_disp32(OP_GROUP1_EvIb, addr, GROUP1_OP_CMP);
    1847             :             r = JmpSrc(m_formatter.size());
    1848             :             m_formatter.immediate8s(rhs);
    1849             :         } else {
    1850             :             m_formatter.oneByteOp_disp32(OP_GROUP1_EvIz, addr, GROUP1_OP_CMP);
    1851             :             r = JmpSrc(m_formatter.size());
    1852             :             m_formatter.immediate32(rhs);
    1853             :         }
    1854             :         return r;
    1855             :     }
    1856             : 
    1857             :     void cmpl_i32m(int32_t rhs, int32_t offset, RegisterID base)
    1858             :     {
    1859             :         spew("cmpl       $0x%04x, " MEM_ob, rhs, ADDR_ob(offset, base));
    1860             :         m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_CMP);
    1861             :         m_formatter.immediate32(rhs);
    1862             :     }
    1863             : 
    1864             :     void cmpl_i32m(int32_t rhs, const void* addr)
    1865             :     {
    1866             :         spew("cmpl       $0x%04x, %p", rhs, addr);
    1867             :         m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_CMP);
    1868             :         m_formatter.immediate32(rhs);
    1869             :     }
    1870             : 
    1871           0 :     void cmpl_rm(RegisterID rhs, const void* addr)
    1872             :     {
    1873           0 :         spew("cmpl       %s, %p", GPReg32Name(rhs), addr);
    1874           0 :         m_formatter.oneByteOp(OP_CMP_EvGv, addr, rhs);
    1875           0 :     }
    1876             : 
    1877             :     void cmpl_rm_disp32(RegisterID rhs, const void* addr)
    1878             :     {
    1879             :         spew("cmpl       %s, %p", GPReg32Name(rhs), addr);
    1880             :         m_formatter.oneByteOp_disp32(OP_CMP_EvGv, addr, rhs);
    1881             :     }
    1882             : 
    1883           0 :     void cmpl_im(int32_t rhs, const void* addr)
    1884             :     {
    1885           0 :         spew("cmpl       $0x%x, %p", rhs, addr);
    1886           0 :         if (CAN_SIGN_EXTEND_8_32(rhs)) {
    1887           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_CMP);
    1888           0 :             m_formatter.immediate8s(rhs);
    1889             :         } else {
    1890           0 :             m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_CMP);
    1891           0 :             m_formatter.immediate32(rhs);
    1892             :         }
    1893           0 :     }
    1894             : 
    1895             :     void cmpw_rr(RegisterID rhs, RegisterID lhs)
    1896             :     {
    1897             :         spew("cmpw       %s, %s", GPReg16Name(rhs), GPReg16Name(lhs));
    1898             :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1899             :         m_formatter.oneByteOp(OP_CMP_GvEv, rhs, lhs);
    1900             :     }
    1901             : 
    1902             :     void cmpw_rm(RegisterID rhs, int32_t offset, RegisterID base, RegisterID index, int scale)
    1903             :     {
    1904             :         spew("cmpw       %s, " MEM_obs, GPReg16Name(rhs), ADDR_obs(offset, base, index, scale));
    1905             :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1906             :         m_formatter.oneByteOp(OP_CMP_EvGv, offset, base, index, scale, rhs);
    1907             :     }
    1908             : 
    1909             :     void cmpw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    1910             :     {
    1911             :         spew("cmpw       $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    1912             :         if (CAN_SIGN_EXTEND_8_32(imm)) {
    1913             :             m_formatter.prefix(PRE_OPERAND_SIZE);
    1914             :             m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_CMP);
    1915             :             m_formatter.immediate8s(imm);
    1916             :         } else {
    1917             :             m_formatter.prefix(PRE_OPERAND_SIZE);
    1918             :             m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_CMP);
    1919             :             m_formatter.immediate16(imm);
    1920             :         }
    1921             :     }
    1922             : 
    1923        3515 :     void testl_rr(RegisterID rhs, RegisterID lhs)
    1924             :     {
    1925        3515 :         spew("testl      %s, %s", GPReg32Name(rhs), GPReg32Name(lhs));
    1926        3515 :         m_formatter.oneByteOp(OP_TEST_EvGv, lhs, rhs);
    1927        3515 :     }
    1928             : 
    1929         796 :     void testb_rr(RegisterID rhs, RegisterID lhs)
    1930             :     {
    1931         796 :         spew("testb      %s, %s", GPReg8Name(rhs), GPReg8Name(lhs));
    1932         796 :         m_formatter.oneByteOp(OP_TEST_EbGb, lhs, rhs);
    1933         796 :     }
    1934             : 
    1935       13589 :     void testl_ir(int32_t rhs, RegisterID lhs)
    1936             :     {
    1937             :         // If the mask fits in an 8-bit immediate, we can use testb with an
    1938             :         // 8-bit subreg.
    1939       13589 :         if (CAN_ZERO_EXTEND_8_32(rhs) && HasSubregL(lhs)) {
    1940       13577 :             testb_ir(rhs, lhs);
    1941       13577 :             return;
    1942             :         }
    1943             :         // If the mask is a subset of 0xff00, we can use testb with an h reg, if
    1944             :         // one happens to be available.
    1945          12 :         if (CAN_ZERO_EXTEND_8H_32(rhs) && HasSubregH(lhs)) {
    1946           0 :             testb_ir_norex(rhs >> 8, GetSubregH(lhs));
    1947           0 :             return;
    1948             :         }
    1949          12 :         spew("testl      $0x%x, %s", rhs, GPReg32Name(lhs));
    1950          12 :         if (lhs == rax)
    1951           0 :             m_formatter.oneByteOp(OP_TEST_EAXIv);
    1952             :         else
    1953          12 :             m_formatter.oneByteOp(OP_GROUP3_EvIz, lhs, GROUP3_OP_TEST);
    1954          12 :         m_formatter.immediate32(rhs);
    1955             :     }
    1956             : 
    1957        7960 :     void testl_i32m(int32_t rhs, int32_t offset, RegisterID base)
    1958             :     {
    1959        7960 :         spew("testl      $0x%x, " MEM_ob, rhs, ADDR_ob(offset, base));
    1960        7960 :         m_formatter.oneByteOp(OP_GROUP3_EvIz, offset, base, GROUP3_OP_TEST);
    1961        7960 :         m_formatter.immediate32(rhs);
    1962        7960 :     }
    1963             : 
    1964           0 :     void testl_i32m(int32_t rhs, const void* addr)
    1965             :     {
    1966           0 :         spew("testl      $0x%x, %p", rhs, addr);
    1967           0 :         m_formatter.oneByteOp(OP_GROUP3_EvIz, addr, GROUP3_OP_TEST);
    1968           0 :         m_formatter.immediate32(rhs);
    1969           0 :     }
    1970             : 
    1971             :     void testb_im(int32_t rhs, int32_t offset, RegisterID base)
    1972             :     {
    1973             :         spew("testb      $0x%x, " MEM_ob, rhs, ADDR_ob(offset, base));
    1974             :         m_formatter.oneByteOp(OP_GROUP3_EbIb, offset, base, GROUP3_OP_TEST);
    1975             :         m_formatter.immediate8(rhs);
    1976             :     }
    1977             : 
    1978             :     void testb_im(int32_t rhs, int32_t offset, RegisterID base, RegisterID index, int scale)
    1979             :     {
    1980             :         spew("testb      $0x%x, " MEM_obs, rhs, ADDR_obs(offset, base, index, scale));
    1981             :         m_formatter.oneByteOp(OP_GROUP3_EbIb, offset, base, index, scale, GROUP3_OP_TEST);
    1982             :         m_formatter.immediate8(rhs);
    1983             :     }
    1984             : 
    1985             :     void testl_i32m(int32_t rhs, int32_t offset, RegisterID base, RegisterID index, int scale)
    1986             :     {
    1987             :         spew("testl      $0x%4x, " MEM_obs, rhs, ADDR_obs(offset, base, index, scale));
    1988             :         m_formatter.oneByteOp(OP_GROUP3_EvIz, offset, base, index, scale, GROUP3_OP_TEST);
    1989             :         m_formatter.immediate32(rhs);
    1990             :     }
    1991             : 
    1992             :     void testw_rr(RegisterID rhs, RegisterID lhs)
    1993             :     {
    1994             :         spew("testw      %s, %s", GPReg16Name(rhs), GPReg16Name(lhs));
    1995             :         m_formatter.prefix(PRE_OPERAND_SIZE);
    1996             :         m_formatter.oneByteOp(OP_TEST_EvGv, lhs, rhs);
    1997             :     }
    1998             : 
    1999       13577 :     void testb_ir(int32_t rhs, RegisterID lhs)
    2000             :     {
    2001       13577 :         spew("testb      $0x%x, %s", rhs, GPReg8Name(lhs));
    2002       13577 :         if (lhs == rax)
    2003         135 :             m_formatter.oneByteOp8(OP_TEST_EAXIb);
    2004             :         else
    2005       13442 :             m_formatter.oneByteOp8(OP_GROUP3_EbIb, lhs, GROUP3_OP_TEST);
    2006       13577 :         m_formatter.immediate8(rhs);
    2007       13577 :     }
    2008             : 
    2009             :     // Like testb_ir, but never emits a REX prefix. This may be used to
    2010             :     // reference ah..bh.
    2011           0 :     void testb_ir_norex(int32_t rhs, HRegisterID lhs)
    2012             :     {
    2013           0 :         spew("testb      $0x%x, %s", rhs, HRegName8(lhs));
    2014           0 :         m_formatter.oneByteOp8_norex(OP_GROUP3_EbIb, lhs, GROUP3_OP_TEST);
    2015           0 :         m_formatter.immediate8(rhs);
    2016           0 :     }
    2017             : 
    2018         186 :     void setCC_r(Condition cond, RegisterID lhs)
    2019             :     {
    2020         186 :         spew("set%s      %s", CCName(cond), GPReg8Name(lhs));
    2021         186 :         m_formatter.twoByteOp8(setccOpcode(cond), lhs, (GroupOpcodeID)0);
    2022         186 :     }
    2023             : 
    2024             :     void sete_r(RegisterID dst)
    2025             :     {
    2026             :         setCC_r(ConditionE, dst);
    2027             :     }
    2028             : 
    2029             :     void setz_r(RegisterID dst)
    2030             :     {
    2031             :         sete_r(dst);
    2032             :     }
    2033             : 
    2034             :     void setne_r(RegisterID dst)
    2035             :     {
    2036             :         setCC_r(ConditionNE, dst);
    2037             :     }
    2038             : 
    2039             :     void setnz_r(RegisterID dst)
    2040             :     {
    2041             :         setne_r(dst);
    2042             :     }
    2043             : 
    2044             :     // Various move ops:
    2045             : 
    2046           0 :     void cdq()
    2047             :     {
    2048           0 :         spew("cdq        ");
    2049           0 :         m_formatter.oneByteOp(OP_CDQ);
    2050           0 :     }
    2051             : 
    2052           0 :     void xchgb_rm(RegisterID src, int32_t offset, RegisterID base)
    2053             :     {
    2054           0 :         spew("xchgb      %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    2055           0 :         m_formatter.oneByteOp8(OP_XCHG_GbEb, offset, base, src);
    2056           0 :     }
    2057           0 :     void xchgb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    2058             :     {
    2059           0 :         spew("xchgb      %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
    2060           0 :         m_formatter.oneByteOp8(OP_XCHG_GbEb, offset, base, index, scale, src);
    2061           0 :     }
    2062             : 
    2063           0 :     void xchgw_rm(RegisterID src, int32_t offset, RegisterID base)
    2064             :     {
    2065           0 :         spew("xchgw      %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    2066           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2067           0 :         m_formatter.oneByteOp(OP_XCHG_GvEv, offset, base, src);
    2068           0 :     }
    2069           0 :     void xchgw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    2070             :     {
    2071           0 :         spew("xchgw      %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
    2072           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2073           0 :         m_formatter.oneByteOp(OP_XCHG_GvEv, offset, base, index, scale, src);
    2074           0 :     }
    2075             : 
    2076             :     void xchgl_rr(RegisterID src, RegisterID dst)
    2077             :     {
    2078             :         spew("xchgl      %s, %s", GPReg32Name(src), GPReg32Name(dst));
    2079             :         m_formatter.oneByteOp(OP_XCHG_GvEv, src, dst);
    2080             :     }
    2081           0 :     void xchgl_rm(RegisterID src, int32_t offset, RegisterID base)
    2082             :     {
    2083           0 :         spew("xchgl      %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    2084           0 :         m_formatter.oneByteOp(OP_XCHG_GvEv, offset, base, src);
    2085           0 :     }
    2086           0 :     void xchgl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    2087             :     {
    2088           0 :         spew("xchgl      %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
    2089           0 :         m_formatter.oneByteOp(OP_XCHG_GvEv, offset, base, index, scale, src);
    2090           0 :     }
    2091             : 
    2092           0 :     void cmovz_rr(RegisterID src, RegisterID dst)
    2093             :     {
    2094           0 :         spew("cmovz     %s, %s", GPReg16Name(src), GPReg32Name(dst));
    2095           0 :         m_formatter.twoByteOp(OP2_CMOVZ_GvEv, src, dst);
    2096           0 :     }
    2097           0 :     void cmovz_mr(int32_t offset, RegisterID base, RegisterID dst)
    2098             :     {
    2099           0 :         spew("cmovz     " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    2100           0 :         m_formatter.twoByteOp(OP2_CMOVZ_GvEv, offset, base, dst);
    2101           0 :     }
    2102           0 :     void cmovz_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2103             :     {
    2104           0 :         spew("cmovz     " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
    2105           0 :         m_formatter.twoByteOp(OP2_CMOVZ_GvEv, offset, base, index, scale, dst);
    2106           0 :     }
    2107             : 
    2108         420 :     void movl_rr(RegisterID src, RegisterID dst)
    2109             :     {
    2110         420 :         spew("movl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
    2111         420 :         m_formatter.oneByteOp(OP_MOV_GvEv, src, dst);
    2112         420 :     }
    2113             : 
    2114          36 :     void movw_rm(RegisterID src, int32_t offset, RegisterID base)
    2115             :     {
    2116          36 :         spew("movw       %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    2117          36 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2118          36 :         m_formatter.oneByteOp(OP_MOV_EvGv, offset, base, src);
    2119          36 :     }
    2120             : 
    2121             :     void movw_rm_disp32(RegisterID src, int32_t offset, RegisterID base)
    2122             :     {
    2123             :         spew("movw       %s, " MEM_o32b, GPReg16Name(src), ADDR_o32b(offset, base));
    2124             :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2125             :         m_formatter.oneByteOp_disp32(OP_MOV_EvGv, offset, base, src);
    2126             :     }
    2127             : 
    2128           0 :     void movw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    2129             :     {
    2130           0 :         spew("movw       %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
    2131           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2132           0 :         m_formatter.oneByteOp(OP_MOV_EvGv, offset, base, index, scale, src);
    2133           0 :     }
    2134             : 
    2135             :     void movw_rm(RegisterID src, const void* addr)
    2136             :     {
    2137             :         spew("movw       %s, %p", GPReg16Name(src), addr);
    2138             :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2139             :         m_formatter.oneByteOp_disp32(OP_MOV_EvGv, addr, src);
    2140             :     }
    2141             : 
    2142        2598 :     void movl_rm(RegisterID src, int32_t offset, RegisterID base)
    2143             :     {
    2144        2598 :         spew("movl       %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    2145        2598 :         m_formatter.oneByteOp(OP_MOV_EvGv, offset, base, src);
    2146        2598 :     }
    2147             : 
    2148             :     void movl_rm_disp32(RegisterID src, int32_t offset, RegisterID base)
    2149             :     {
    2150             :         spew("movl       %s, " MEM_o32b, GPReg32Name(src), ADDR_o32b(offset, base));
    2151             :         m_formatter.oneByteOp_disp32(OP_MOV_EvGv, offset, base, src);
    2152             :     }
    2153             : 
    2154           0 :     void movl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    2155             :     {
    2156           0 :         spew("movl       %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
    2157           0 :         m_formatter.oneByteOp(OP_MOV_EvGv, offset, base, index, scale, src);
    2158           0 :     }
    2159             : 
    2160           0 :     void movl_mEAX(const void* addr)
    2161             :     {
    2162             : #ifdef JS_CODEGEN_X64
    2163           0 :         if (IsAddressImmediate(addr)) {
    2164           0 :             movl_mr(addr, rax);
    2165           0 :             return;
    2166             :         }
    2167             : #endif
    2168             : 
    2169             : #ifdef JS_CODEGEN_X64
    2170           0 :         spew("movabs     %p, %%eax", addr);
    2171             : #else
    2172             :         spew("movl       %p, %%eax", addr);
    2173             : #endif
    2174           0 :         m_formatter.oneByteOp(OP_MOV_EAXOv);
    2175             : #ifdef JS_CODEGEN_X64
    2176           0 :         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
    2177             : #else
    2178             :         m_formatter.immediate32(reinterpret_cast<int32_t>(addr));
    2179             : #endif
    2180             :     }
    2181             : 
    2182        1670 :     void movl_mr(int32_t offset, RegisterID base, RegisterID dst)
    2183             :     {
    2184        1670 :         spew("movl       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    2185        1670 :         m_formatter.oneByteOp(OP_MOV_GvEv, offset, base, dst);
    2186        1670 :     }
    2187             : 
    2188             :     void movl_mr_disp32(int32_t offset, RegisterID base, RegisterID dst)
    2189             :     {
    2190             :         spew("movl       " MEM_o32b ", %s", ADDR_o32b(offset, base), GPReg32Name(dst));
    2191             :         m_formatter.oneByteOp_disp32(OP_MOV_GvEv, offset, base, dst);
    2192             :     }
    2193             : 
    2194             :     void movl_mr(const void* base, RegisterID index, int scale, RegisterID dst)
    2195             :     {
    2196             :         int32_t disp = AddressImmediate(base);
    2197             : 
    2198             :         spew("movl       " MEM_os ", %s", ADDR_os(disp, index, scale), GPReg32Name(dst));
    2199             :         m_formatter.oneByteOp_disp32(OP_MOV_GvEv, disp, index, scale, dst);
    2200             :     }
    2201             : 
    2202          51 :     void movl_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2203             :     {
    2204          51 :         spew("movl       " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
    2205          51 :         m_formatter.oneByteOp(OP_MOV_GvEv, offset, base, index, scale, dst);
    2206          51 :     }
    2207             : 
    2208           0 :     void movl_mr(const void* addr, RegisterID dst)
    2209             :     {
    2210           0 :         if (dst == rax
    2211             : #ifdef JS_CODEGEN_X64
    2212           0 :             && !IsAddressImmediate(addr)
    2213             : #endif
    2214             :             )
    2215             :         {
    2216           0 :             movl_mEAX(addr);
    2217           0 :             return;
    2218             :         }
    2219             : 
    2220           0 :         spew("movl       %p, %s", addr, GPReg32Name(dst));
    2221           0 :         m_formatter.oneByteOp(OP_MOV_GvEv, addr, dst);
    2222             :     }
    2223             : 
    2224        5777 :     void movl_i32r(int32_t imm, RegisterID dst)
    2225             :     {
    2226        5777 :         spew("movl       $0x%x, %s", imm, GPReg32Name(dst));
    2227        5777 :         m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
    2228        5777 :         m_formatter.immediate32(imm);
    2229        5777 :     }
    2230             : 
    2231           0 :     void movb_ir(int32_t imm, RegisterID reg)
    2232             :     {
    2233           0 :         spew("movb       $0x%x, %s", imm, GPReg8Name(reg));
    2234           0 :         m_formatter.oneByteOp8(OP_MOV_EbIb, reg);
    2235           0 :         m_formatter.immediate8(imm);
    2236           0 :     }
    2237             : 
    2238           4 :     void movb_im(int32_t imm, int32_t offset, RegisterID base)
    2239             :     {
    2240           4 :         spew("movb       $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
    2241           4 :         m_formatter.oneByteOp(OP_GROUP11_EvIb, offset, base, GROUP11_MOV);
    2242           4 :         m_formatter.immediate8(imm);
    2243           4 :     }
    2244             : 
    2245           0 :     void movb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    2246             :     {
    2247           0 :         spew("movb       $0x%x, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    2248           0 :         m_formatter.oneByteOp(OP_GROUP11_EvIb, offset, base, index, scale, GROUP11_MOV);
    2249           0 :         m_formatter.immediate8(imm);
    2250           0 :     }
    2251             : 
    2252             :     void movb_im(int32_t imm, const void* addr)
    2253             :     {
    2254             :         spew("movb       $%d, %p", imm, addr);
    2255             :         m_formatter.oneByteOp_disp32(OP_GROUP11_EvIb, addr, GROUP11_MOV);
    2256             :         m_formatter.immediate8(imm);
    2257             :     }
    2258             : 
    2259           4 :     void movw_im(int32_t imm, int32_t offset, RegisterID base)
    2260             :     {
    2261           4 :         spew("movw       $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
    2262           4 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2263           4 :         m_formatter.oneByteOp(OP_GROUP11_EvIz, offset, base, GROUP11_MOV);
    2264           4 :         m_formatter.immediate16(imm);
    2265           4 :     }
    2266             : 
    2267             :     void movw_im(int32_t imm, const void* addr)
    2268             :     {
    2269             :         spew("movw       $%d, %p", imm, addr);
    2270             :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2271             :         m_formatter.oneByteOp_disp32(OP_GROUP11_EvIz, addr, GROUP11_MOV);
    2272             :         m_formatter.immediate16(imm);
    2273             :     }
    2274             : 
    2275        4123 :     void movl_i32m(int32_t imm, int32_t offset, RegisterID base)
    2276             :     {
    2277        4123 :         spew("movl       $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
    2278        4123 :         m_formatter.oneByteOp(OP_GROUP11_EvIz, offset, base, GROUP11_MOV);
    2279        4123 :         m_formatter.immediate32(imm);
    2280        4123 :     }
    2281             : 
    2282           0 :     void movw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    2283             :     {
    2284           0 :         spew("movw       $0x%x, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    2285           0 :         m_formatter.prefix(PRE_OPERAND_SIZE);
    2286           0 :         m_formatter.oneByteOp(OP_GROUP11_EvIz, offset, base, index, scale, GROUP11_MOV);
    2287           0 :         m_formatter.immediate16(imm);
    2288           0 :     }
    2289             : 
    2290           0 :     void movl_i32m(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
    2291             :     {
    2292           0 :         spew("movl       $0x%x, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    2293           0 :         m_formatter.oneByteOp(OP_GROUP11_EvIz, offset, base, index, scale, GROUP11_MOV);
    2294           0 :         m_formatter.immediate32(imm);
    2295           0 :     }
    2296             : 
    2297           0 :     void movl_EAXm(const void* addr)
    2298             :     {
    2299             : #ifdef JS_CODEGEN_X64
    2300           0 :         if (IsAddressImmediate(addr)) {
    2301           0 :             movl_rm(rax, addr);
    2302           0 :             return;
    2303             :         }
    2304             : #endif
    2305             : 
    2306           0 :         spew("movl       %%eax, %p", addr);
    2307           0 :         m_formatter.oneByteOp(OP_MOV_OvEAX);
    2308             : #ifdef JS_CODEGEN_X64
    2309           0 :         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
    2310             : #else
    2311             :         m_formatter.immediate32(reinterpret_cast<int32_t>(addr));
    2312             : #endif
    2313             :     }
    2314             : 
    2315           0 :     void vmovq_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    2316             :     {
    2317             :         // vmovq_rm can be encoded either as a true vmovq or as a vmovd with a
    2318             :         // REX prefix modifying it to be 64-bit. We choose the vmovq encoding
    2319             :         // because it's smaller (when it doesn't need a REX prefix for other
    2320             :         // reasons) and because it works on 32-bit x86 too.
    2321           0 :         twoByteOpSimd("vmovq", VEX_PD, OP2_MOVQ_WdVd, offset, base, invalid_xmm, src);
    2322           0 :     }
    2323             : 
    2324             :     void vmovq_rm_disp32(XMMRegisterID src, int32_t offset, RegisterID base)
    2325             :     {
    2326             :         twoByteOpSimd_disp32("vmovq", VEX_PD, OP2_MOVQ_WdVd, offset, base, invalid_xmm, src);
    2327             :     }
    2328             : 
    2329           0 :     void vmovq_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    2330             :     {
    2331           0 :         twoByteOpSimd("vmovq", VEX_PD, OP2_MOVQ_WdVd, offset, base, index, scale, invalid_xmm, src);
    2332           0 :     }
    2333             : 
    2334           0 :     void vmovq_rm(XMMRegisterID src, const void* addr)
    2335             :     {
    2336           0 :         twoByteOpSimd("vmovq", VEX_PD, OP2_MOVQ_WdVd, addr, invalid_xmm, src);
    2337           0 :     }
    2338             : 
    2339           0 :     void vmovq_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    2340             :     {
    2341             :         // vmovq_mr can be encoded either as a true vmovq or as a vmovd with a
    2342             :         // REX prefix modifying it to be 64-bit. We choose the vmovq encoding
    2343             :         // because it's smaller (when it doesn't need a REX prefix for other
    2344             :         // reasons) and because it works on 32-bit x86 too.
    2345           0 :         twoByteOpSimd("vmovq", VEX_SS, OP2_MOVQ_VdWd, offset, base, invalid_xmm, dst);
    2346           0 :     }
    2347             : 
    2348             :     void vmovq_mr_disp32(int32_t offset, RegisterID base, XMMRegisterID dst)
    2349             :     {
    2350             :         twoByteOpSimd_disp32("vmovq", VEX_SS, OP2_MOVQ_VdWd, offset, base, invalid_xmm, dst);
    2351             :     }
    2352             : 
    2353           0 :     void vmovq_mr(int32_t offset, RegisterID base, RegisterID index, int32_t scale, XMMRegisterID dst)
    2354             :     {
    2355           0 :         twoByteOpSimd("vmovq", VEX_SS, OP2_MOVQ_VdWd, offset, base, index, scale, invalid_xmm, dst);
    2356           0 :     }
    2357             : 
    2358           0 :     void vmovq_mr(const void* addr, XMMRegisterID dst)
    2359             :     {
    2360           0 :         twoByteOpSimd("vmovq", VEX_SS, OP2_MOVQ_VdWd, addr, invalid_xmm, dst);
    2361           0 :     }
    2362             : 
    2363           0 :     void movl_rm(RegisterID src, const void* addr)
    2364             :     {
    2365           0 :         if (src == rax
    2366             : #ifdef JS_CODEGEN_X64
    2367           0 :             && !IsAddressImmediate(addr)
    2368             : #endif
    2369             :             ) {
    2370           0 :             movl_EAXm(addr);
    2371           0 :             return;
    2372             :         }
    2373             : 
    2374           0 :         spew("movl       %s, %p", GPReg32Name(src), addr);
    2375           0 :         m_formatter.oneByteOp(OP_MOV_EvGv, addr, src);
    2376             :     }
    2377             : 
    2378           0 :     void movl_i32m(int32_t imm, const void* addr)
    2379             :     {
    2380           0 :         spew("movl       $%d, %p", imm, addr);
    2381           0 :         m_formatter.oneByteOp(OP_GROUP11_EvIz, addr, GROUP11_MOV);
    2382           0 :         m_formatter.immediate32(imm);
    2383           0 :     }
    2384             : 
    2385           8 :     void movb_rm(RegisterID src, int32_t offset, RegisterID base)
    2386             :     {
    2387           8 :         spew("movb       %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    2388           8 :         m_formatter.oneByteOp8(OP_MOV_EbGv, offset, base, src);
    2389           8 :     }
    2390             : 
    2391             :     void movb_rm_disp32(RegisterID src, int32_t offset, RegisterID base)
    2392             :     {
    2393             :         spew("movb       %s, " MEM_o32b, GPReg8Name(src), ADDR_o32b(offset, base));
    2394             :         m_formatter.oneByteOp8_disp32(OP_MOV_EbGv, offset, base, src);
    2395             :     }
    2396             : 
    2397           3 :     void movb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    2398             :     {
    2399           3 :         spew("movb       %s, " MEM_obs, GPReg8Name(src), ADDR_obs(offset, base, index, scale));
    2400           3 :         m_formatter.oneByteOp8(OP_MOV_EbGv, offset, base, index, scale, src);
    2401           3 :     }
    2402             : 
    2403             :     void movb_rm(RegisterID src, const void* addr)
    2404             :     {
    2405             :         spew("movb       %s, %p", GPReg8Name(src), addr);
    2406             :         m_formatter.oneByteOp8(OP_MOV_EbGv, addr, src);
    2407             :     }
    2408             : 
    2409           0 :     void movb_mr(int32_t offset, RegisterID base, RegisterID dst)
    2410             :     {
    2411           0 :         spew("movb       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg8Name(dst));
    2412           0 :         m_formatter.oneByteOp(OP_MOV_GvEb, offset, base, dst);
    2413           0 :     }
    2414             : 
    2415           0 :     void movb_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2416             :     {
    2417           0 :         spew("movb       " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg8Name(dst));
    2418           0 :         m_formatter.oneByteOp(OP_MOV_GvEb, offset, base, index, scale, dst);
    2419           0 :     }
    2420             : 
    2421         124 :     void movzbl_mr(int32_t offset, RegisterID base, RegisterID dst)
    2422             :     {
    2423         124 :         spew("movzbl     " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    2424         124 :         m_formatter.twoByteOp(OP2_MOVZX_GvEb, offset, base, dst);
    2425         124 :     }
    2426             : 
    2427             :     void movzbl_mr_disp32(int32_t offset, RegisterID base, RegisterID dst)
    2428             :     {
    2429             :         spew("movzbl     " MEM_o32b ", %s", ADDR_o32b(offset, base), GPReg32Name(dst));
    2430             :         m_formatter.twoByteOp_disp32(OP2_MOVZX_GvEb, offset, base, dst);
    2431             :     }
    2432             : 
    2433         532 :     void movzbl_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2434             :     {
    2435         532 :         spew("movzbl     " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
    2436         532 :         m_formatter.twoByteOp(OP2_MOVZX_GvEb, offset, base, index, scale, dst);
    2437         532 :     }
    2438             : 
    2439             :     void movzbl_mr(const void* addr, RegisterID dst)
    2440             :     {
    2441             :         spew("movzbl     %p, %s", addr, GPReg32Name(dst));
    2442             :         m_formatter.twoByteOp(OP2_MOVZX_GvEb, addr, dst);
    2443             :     }
    2444             : 
    2445           0 :     void movsbl_rr(RegisterID src, RegisterID dst)
    2446             :     {
    2447           0 :         spew("movsbl     %s, %s", GPReg8Name(src), GPReg32Name(dst));
    2448           0 :         m_formatter.twoByteOp8_movx(OP2_MOVSX_GvEb, src, dst);
    2449           0 :     }
    2450             : 
    2451           0 :     void movsbl_mr(int32_t offset, RegisterID base, RegisterID dst)
    2452             :     {
    2453           0 :         spew("movsbl     " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    2454           0 :         m_formatter.twoByteOp(OP2_MOVSX_GvEb, offset, base, dst);
    2455           0 :     }
    2456             : 
    2457             :     void movsbl_mr_disp32(int32_t offset, RegisterID base, RegisterID dst)
    2458             :     {
    2459             :         spew("movsbl     " MEM_o32b ", %s", ADDR_o32b(offset, base), GPReg32Name(dst));
    2460             :         m_formatter.twoByteOp_disp32(OP2_MOVSX_GvEb, offset, base, dst);
    2461             :     }
    2462             : 
    2463           0 :     void movsbl_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2464             :     {
    2465           0 :         spew("movsbl     " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
    2466           0 :         m_formatter.twoByteOp(OP2_MOVSX_GvEb, offset, base, index, scale, dst);
    2467           0 :     }
    2468             : 
    2469             :     void movsbl_mr(const void* addr, RegisterID dst)
    2470             :     {
    2471             :         spew("movsbl     %p, %s", addr, GPReg32Name(dst));
    2472             :         m_formatter.twoByteOp(OP2_MOVSX_GvEb, addr, dst);
    2473             :     }
    2474             : 
    2475           0 :     void movzwl_rr(RegisterID src, RegisterID dst)
    2476             :     {
    2477           0 :         spew("movzwl     %s, %s", GPReg16Name(src), GPReg32Name(dst));
    2478           0 :         m_formatter.twoByteOp(OP2_MOVZX_GvEw, src, dst);
    2479           0 :     }
    2480             : 
    2481         130 :     void movzwl_mr(int32_t offset, RegisterID base, RegisterID dst)
    2482             :     {
    2483         130 :         spew("movzwl     " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    2484         130 :         m_formatter.twoByteOp(OP2_MOVZX_GvEw, offset, base, dst);
    2485         130 :     }
    2486             : 
    2487             :     void movzwl_mr_disp32(int32_t offset, RegisterID base, RegisterID dst)
    2488             :     {
    2489             :         spew("movzwl     " MEM_o32b ", %s", ADDR_o32b(offset, base), GPReg32Name(dst));
    2490             :         m_formatter.twoByteOp_disp32(OP2_MOVZX_GvEw, offset, base, dst);
    2491             :     }
    2492             : 
    2493          73 :     void movzwl_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2494             :     {
    2495          73 :         spew("movzwl     " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
    2496          73 :         m_formatter.twoByteOp(OP2_MOVZX_GvEw, offset, base, index, scale, dst);
    2497          73 :     }
    2498             : 
    2499             :     void movzwl_mr(const void* addr, RegisterID dst)
    2500             :     {
    2501             :         spew("movzwl     %p, %s", addr, GPReg32Name(dst));
    2502             :         m_formatter.twoByteOp(OP2_MOVZX_GvEw, addr, dst);
    2503             :     }
    2504             : 
    2505           0 :     void movswl_rr(RegisterID src, RegisterID dst)
    2506             :     {
    2507           0 :         spew("movswl     %s, %s", GPReg16Name(src), GPReg32Name(dst));
    2508           0 :         m_formatter.twoByteOp(OP2_MOVSX_GvEw, src, dst);
    2509           0 :     }
    2510             : 
    2511           0 :     void movswl_mr(int32_t offset, RegisterID base, RegisterID dst)
    2512             :     {
    2513           0 :         spew("movswl     " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    2514           0 :         m_formatter.twoByteOp(OP2_MOVSX_GvEw, offset, base, dst);
    2515           0 :     }
    2516             : 
    2517             :     void movswl_mr_disp32(int32_t offset, RegisterID base, RegisterID dst)
    2518             :     {
    2519             :         spew("movswl     " MEM_o32b ", %s", ADDR_o32b(offset, base), GPReg32Name(dst));
    2520             :         m_formatter.twoByteOp_disp32(OP2_MOVSX_GvEw, offset, base, dst);
    2521             :     }
    2522             : 
    2523           0 :     void movswl_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2524             :     {
    2525           0 :         spew("movswl     " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
    2526           0 :         m_formatter.twoByteOp(OP2_MOVSX_GvEw, offset, base, index, scale, dst);
    2527           0 :     }
    2528             : 
    2529             :     void movswl_mr(const void* addr, RegisterID dst)
    2530             :     {
    2531             :         spew("movswl     %p, %s", addr, GPReg32Name(dst));
    2532             :         m_formatter.twoByteOp(OP2_MOVSX_GvEw, addr, dst);
    2533             :     }
    2534             : 
    2535          61 :     void movzbl_rr(RegisterID src, RegisterID dst)
    2536             :     {
    2537          61 :         spew("movzbl     %s, %s", GPReg8Name(src), GPReg32Name(dst));
    2538          61 :         m_formatter.twoByteOp8_movx(OP2_MOVZX_GvEb, src, dst);
    2539          61 :     }
    2540             : 
    2541           0 :     void leal_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    2542             :     {
    2543           0 :         spew("leal       " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
    2544           0 :         m_formatter.oneByteOp(OP_LEA, offset, base, index, scale, dst);
    2545           0 :     }
    2546             : 
    2547           0 :     void leal_mr(int32_t offset, RegisterID base, RegisterID dst)
    2548             :     {
    2549           0 :         spew("leal       " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    2550           0 :         m_formatter.oneByteOp(OP_LEA, offset, base, dst);
    2551           0 :     }
    2552             : 
    2553             :     // Flow control:
    2554             : 
    2555             :     MOZ_MUST_USE JmpSrc
    2556       17388 :     call()
    2557             :     {
    2558       17388 :         m_formatter.oneByteOp(OP_CALL_rel32);
    2559       17388 :         JmpSrc r = m_formatter.immediateRel32();
    2560       17387 :         spew("call       .Lfrom%d", r.offset());
    2561       17387 :         return r;
    2562             :     }
    2563             : 
    2564          94 :     void call_r(RegisterID dst)
    2565             :     {
    2566          94 :         m_formatter.oneByteOp(OP_GROUP5_Ev, dst, GROUP5_OP_CALLN);
    2567          94 :         spew("call       *%s", GPRegName(dst));
    2568          94 :     }
    2569             : 
    2570       19474 :     void call_m(int32_t offset, RegisterID base)
    2571             :     {
    2572       19474 :         spew("call       *" MEM_ob, ADDR_ob(offset, base));
    2573       19474 :         m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_CALLN);
    2574       19474 :     }
    2575             : 
    2576             :     // Comparison of EAX against a 32-bit immediate. The immediate is patched
    2577             :     // in as if it were a jump target. The intention is to toggle the first
    2578             :     // byte of the instruction between a CMP and a JMP to produce a pseudo-NOP.
    2579             :     MOZ_MUST_USE JmpSrc
    2580           0 :     cmp_eax()
    2581             :     {
    2582           0 :         m_formatter.oneByteOp(OP_CMP_EAXIv);
    2583           0 :         JmpSrc r = m_formatter.immediateRel32();
    2584           0 :         spew("cmpl       %%eax, .Lfrom%d", r.offset());
    2585           0 :         return r;
    2586             :     }
    2587             : 
    2588         695 :     void jmp_i(JmpDst dst)
    2589             :     {
    2590         695 :         int32_t diff = dst.offset() - m_formatter.size();
    2591         695 :         spew("jmp        .Llabel%d", dst.offset());
    2592             : 
    2593             :         // The jump immediate is an offset from the end of the jump instruction.
    2594             :         // A jump instruction is either 1 byte opcode and 1 byte offset, or 1
    2595             :         // byte opcode and 4 bytes offset.
    2596         695 :         if (CAN_SIGN_EXTEND_8_32(diff - 2)) {
    2597         365 :             m_formatter.oneByteOp(OP_JMP_rel8);
    2598         365 :             m_formatter.immediate8s(diff - 2);
    2599             :         } else {
    2600         330 :             m_formatter.oneByteOp(OP_JMP_rel32);
    2601         330 :             m_formatter.immediate32(diff - 5);
    2602             :         }
    2603         695 :     }
    2604             :     MOZ_MUST_USE JmpSrc
    2605        9220 :     jmp()
    2606             :     {
    2607        9220 :         m_formatter.oneByteOp(OP_JMP_rel32);
    2608        9220 :         JmpSrc r = m_formatter.immediateRel32();
    2609        9220 :         spew("jmp        .Lfrom%d", r.offset());
    2610        9220 :         return r;
    2611             :     }
    2612             : 
    2613         199 :     void jmp_r(RegisterID dst)
    2614             :     {
    2615         199 :         spew("jmp        *%s", GPRegName(dst));
    2616         199 :         m_formatter.oneByteOp(OP_GROUP5_Ev, dst, GROUP5_OP_JMPN);
    2617         199 :     }
    2618             : 
    2619        2384 :     void jmp_m(int32_t offset, RegisterID base)
    2620             :     {
    2621        2384 :         spew("jmp        *" MEM_ob, ADDR_ob(offset, base));
    2622        2384 :         m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_JMPN);
    2623        2384 :     }
    2624             : 
    2625           0 :     void jmp_m(int32_t offset, RegisterID base, RegisterID index, int scale) {
    2626           0 :         spew("jmp        *" MEM_obs, ADDR_obs(offset, base, index, scale));
    2627           0 :         m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, index, scale, GROUP5_OP_JMPN);
    2628           0 :     }
    2629             : 
    2630         535 :     void jCC_i(Condition cond, JmpDst dst)
    2631             :     {
    2632         535 :         int32_t diff = dst.offset() - m_formatter.size();
    2633         535 :         spew("j%s        .Llabel%d", CCName(cond), dst.offset());
    2634             : 
    2635             :         // The jump immediate is an offset from the end of the jump instruction.
    2636             :         // A conditional jump instruction is either 1 byte opcode and 1 byte
    2637             :         // offset, or 2 bytes opcode and 4 bytes offset.
    2638         535 :         if (CAN_SIGN_EXTEND_8_32(diff - 2)) {
    2639         245 :             m_formatter.oneByteOp(jccRel8(cond));
    2640         245 :             m_formatter.immediate8s(diff - 2);
    2641             :         } else {
    2642         290 :             m_formatter.twoByteOp(jccRel32(cond));
    2643         290 :             m_formatter.immediate32(diff - 6);
    2644             :         }
    2645         535 :     }
    2646             : 
    2647             :     MOZ_MUST_USE JmpSrc
    2648       40369 :     jCC(Condition cond)
    2649             :     {
    2650       40369 :         m_formatter.twoByteOp(jccRel32(cond));
    2651       40369 :         JmpSrc r = m_formatter.immediateRel32();
    2652       40368 :         spew("j%s        .Lfrom%d", CCName(cond), r.offset());
    2653       40368 :         return r;
    2654             :     }
    2655             : 
    2656             :     // SSE operations:
    2657             : 
    2658           0 :     void vpcmpeqb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2659             :     {
    2660           0 :         twoByteOpSimd("vpcmpeqb", VEX_PD, OP2_PCMPEQB_VdqWdq, src1, src0, dst);
    2661           0 :     }
    2662           0 :     void vpcmpeqb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2663             :     {
    2664           0 :         twoByteOpSimd("vpcmpeqb", VEX_PD, OP2_PCMPEQB_VdqWdq, offset, base, src0, dst);
    2665           0 :     }
    2666           0 :     void vpcmpeqb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2667             :     {
    2668           0 :         twoByteOpSimd("vpcmpeqb", VEX_PD, OP2_PCMPEQB_VdqWdq, address, src0, dst);
    2669           0 :     }
    2670             : 
    2671           0 :     void vpcmpgtb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2672             :     {
    2673           0 :         twoByteOpSimd("vpcmpgtb", VEX_PD, OP2_PCMPGTB_VdqWdq, src1, src0, dst);
    2674           0 :     }
    2675           0 :     void vpcmpgtb_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2676             :     {
    2677           0 :         twoByteOpSimd("vpcmpgtb", VEX_PD, OP2_PCMPGTB_VdqWdq, offset, base, src0, dst);
    2678           0 :     }
    2679           0 :     void vpcmpgtb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2680             :     {
    2681           0 :         twoByteOpSimd("vpcmpgtb", VEX_PD, OP2_PCMPGTB_VdqWdq, address, src0, dst);
    2682           0 :     }
    2683             : 
    2684           0 :     void vpcmpeqw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2685             :     {
    2686           0 :         twoByteOpSimd("vpcmpeqw", VEX_PD, OP2_PCMPEQW_VdqWdq, src1, src0, dst);
    2687           0 :     }
    2688           0 :     void vpcmpeqw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2689             :     {
    2690           0 :         twoByteOpSimd("vpcmpeqw", VEX_PD, OP2_PCMPEQW_VdqWdq, offset, base, src0, dst);
    2691           0 :     }
    2692           0 :     void vpcmpeqw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2693             :     {
    2694           0 :         twoByteOpSimd("vpcmpeqw", VEX_PD, OP2_PCMPEQW_VdqWdq, address, src0, dst);
    2695           0 :     }
    2696             : 
    2697           0 :     void vpcmpgtw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2698             :     {
    2699           0 :         twoByteOpSimd("vpcmpgtw", VEX_PD, OP2_PCMPGTW_VdqWdq, src1, src0, dst);
    2700           0 :     }
    2701           0 :     void vpcmpgtw_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2702             :     {
    2703           0 :         twoByteOpSimd("vpcmpgtw", VEX_PD, OP2_PCMPGTW_VdqWdq, offset, base, src0, dst);
    2704           0 :     }
    2705           0 :     void vpcmpgtw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2706             :     {
    2707           0 :         twoByteOpSimd("vpcmpgtw", VEX_PD, OP2_PCMPGTW_VdqWdq, address, src0, dst);
    2708           0 :     }
    2709             : 
    2710           0 :     void vpcmpeqd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2711             :     {
    2712           0 :         twoByteOpSimd("vpcmpeqd", VEX_PD, OP2_PCMPEQD_VdqWdq, src1, src0, dst);
    2713           0 :     }
    2714           0 :     void vpcmpeqd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2715             :     {
    2716           0 :         twoByteOpSimd("vpcmpeqd", VEX_PD, OP2_PCMPEQD_VdqWdq, offset, base, src0, dst);
    2717           0 :     }
    2718           0 :     void vpcmpeqd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2719             :     {
    2720           0 :         twoByteOpSimd("vpcmpeqd", VEX_PD, OP2_PCMPEQD_VdqWdq, address, src0, dst);
    2721           0 :     }
    2722             : 
    2723           0 :     void vpcmpgtd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2724             :     {
    2725           0 :         twoByteOpSimd("vpcmpgtd", VEX_PD, OP2_PCMPGTD_VdqWdq, src1, src0, dst);
    2726           0 :     }
    2727           0 :     void vpcmpgtd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2728             :     {
    2729           0 :         twoByteOpSimd("vpcmpgtd", VEX_PD, OP2_PCMPGTD_VdqWdq, offset, base, src0, dst);
    2730           0 :     }
    2731           0 :     void vpcmpgtd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2732             :     {
    2733           0 :         twoByteOpSimd("vpcmpgtd", VEX_PD, OP2_PCMPGTD_VdqWdq, address, src0, dst);
    2734           0 :     }
    2735             : 
    2736           0 :     void vcmpps_rr(uint8_t order, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2737             :     {
    2738           0 :         twoByteOpImmSimd("vcmpps", VEX_PS, OP2_CMPPS_VpsWps, order, src1, src0, dst);
    2739           0 :     }
    2740           0 :     void vcmpps_mr(uint8_t order, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2741             :     {
    2742           0 :         twoByteOpImmSimd("vcmpps", VEX_PS, OP2_CMPPS_VpsWps, order, offset, base, src0, dst);
    2743           0 :     }
    2744           0 :     void vcmpps_mr(uint8_t order, const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2745             :     {
    2746           0 :         twoByteOpImmSimd("vcmpps", VEX_PS, OP2_CMPPS_VpsWps, order, address, src0, dst);
    2747           0 :     }
    2748             : 
    2749           0 :     void vrcpps_rr(XMMRegisterID src, XMMRegisterID dst) {
    2750           0 :         twoByteOpSimd("vrcpps", VEX_PS, OP2_RCPPS_VpsWps, src, invalid_xmm, dst);
    2751           0 :     }
    2752           0 :     void vrcpps_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
    2753           0 :         twoByteOpSimd("vrcpps", VEX_PS, OP2_RCPPS_VpsWps, offset, base, invalid_xmm, dst);
    2754           0 :     }
    2755           0 :     void vrcpps_mr(const void* address, XMMRegisterID dst) {
    2756           0 :         twoByteOpSimd("vrcpps", VEX_PS, OP2_RCPPS_VpsWps, address, invalid_xmm, dst);
    2757           0 :     }
    2758             : 
    2759           0 :     void vrsqrtps_rr(XMMRegisterID src, XMMRegisterID dst) {
    2760           0 :         twoByteOpSimd("vrsqrtps", VEX_PS, OP2_RSQRTPS_VpsWps, src, invalid_xmm, dst);
    2761           0 :     }
    2762           0 :     void vrsqrtps_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
    2763           0 :         twoByteOpSimd("vrsqrtps", VEX_PS, OP2_RSQRTPS_VpsWps, offset, base, invalid_xmm, dst);
    2764           0 :     }
    2765           0 :     void vrsqrtps_mr(const void* address, XMMRegisterID dst) {
    2766           0 :         twoByteOpSimd("vrsqrtps", VEX_PS, OP2_RSQRTPS_VpsWps, address, invalid_xmm, dst);
    2767           0 :     }
    2768             : 
    2769           0 :     void vsqrtps_rr(XMMRegisterID src, XMMRegisterID dst) {
    2770           0 :         twoByteOpSimd("vsqrtps", VEX_PS, OP2_SQRTPS_VpsWps, src, invalid_xmm, dst);
    2771           0 :     }
    2772           0 :     void vsqrtps_mr(int32_t offset, RegisterID base, XMMRegisterID dst) {
    2773           0 :         twoByteOpSimd("vsqrtps", VEX_PS, OP2_SQRTPS_VpsWps, offset, base, invalid_xmm, dst);
    2774           0 :     }
    2775           0 :     void vsqrtps_mr(const void* address, XMMRegisterID dst) {
    2776           0 :         twoByteOpSimd("vsqrtps", VEX_PS, OP2_SQRTPS_VpsWps, address, invalid_xmm, dst);
    2777           0 :     }
    2778             : 
    2779           0 :     void vaddsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2780             :     {
    2781           0 :         twoByteOpSimd("vaddsd", VEX_SD, OP2_ADDSD_VsdWsd, src1, src0, dst);
    2782           0 :     }
    2783             : 
    2784           0 :     void vaddss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2785             :     {
    2786           0 :         twoByteOpSimd("vaddss", VEX_SS, OP2_ADDSD_VsdWsd, src1, src0, dst);
    2787           0 :     }
    2788             : 
    2789           0 :     void vaddsd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2790             :     {
    2791           0 :         twoByteOpSimd("vaddsd", VEX_SD, OP2_ADDSD_VsdWsd, offset, base, src0, dst);
    2792           0 :     }
    2793             : 
    2794           0 :     void vaddss_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2795             :     {
    2796           0 :         twoByteOpSimd("vaddss", VEX_SS, OP2_ADDSD_VsdWsd, offset, base, src0, dst);
    2797           0 :     }
    2798             : 
    2799           0 :     void vaddsd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2800             :     {
    2801           0 :         twoByteOpSimd("vaddsd", VEX_SD, OP2_ADDSD_VsdWsd, address, src0, dst);
    2802           0 :     }
    2803           0 :     void vaddss_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2804             :     {
    2805           0 :         twoByteOpSimd("vaddss", VEX_SS, OP2_ADDSD_VsdWsd, address, src0, dst);
    2806           0 :     }
    2807             : 
    2808           0 :     void vcvtss2sd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2809             :     {
    2810           0 :         twoByteOpSimd("vcvtss2sd", VEX_SS, OP2_CVTSS2SD_VsdEd, src1, src0, dst);
    2811           0 :     }
    2812             : 
    2813           0 :     void vcvtsd2ss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2814             :     {
    2815           0 :         twoByteOpSimd("vcvtsd2ss", VEX_SD, OP2_CVTSD2SS_VsdEd, src1, src0, dst);
    2816           0 :     }
    2817             : 
    2818           0 :     void vcvtsi2ss_rr(RegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2819             :     {
    2820           0 :         twoByteOpInt32Simd("vcvtsi2ss", VEX_SS, OP2_CVTSI2SD_VsdEd, src1, src0, dst);
    2821           0 :     }
    2822             : 
    2823          58 :     void vcvtsi2sd_rr(RegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2824             :     {
    2825          58 :         twoByteOpInt32Simd("vcvtsi2sd", VEX_SD, OP2_CVTSI2SD_VsdEd, src1, src0, dst);
    2826          58 :     }
    2827             : 
    2828           0 :     void vcvttps2dq_rr(XMMRegisterID src, XMMRegisterID dst)
    2829             :     {
    2830           0 :         twoByteOpSimd("vcvttps2dq", VEX_SS, OP2_CVTTPS2DQ_VdqWps, src, invalid_xmm, dst);
    2831           0 :     }
    2832             : 
    2833           0 :     void vcvtdq2ps_rr(XMMRegisterID src, XMMRegisterID dst)
    2834             :     {
    2835           0 :         twoByteOpSimd("vcvtdq2ps", VEX_PS, OP2_CVTDQ2PS_VpsWdq, src, invalid_xmm, dst);
    2836           0 :     }
    2837             : 
    2838           0 :     void vcvtsi2sd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2839             :     {
    2840           0 :         twoByteOpSimd("vcvtsi2sd", VEX_SD, OP2_CVTSI2SD_VsdEd, offset, base, src0, dst);
    2841           0 :     }
    2842             : 
    2843           0 :     void vcvtsi2sd_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID src0, XMMRegisterID dst)
    2844             :     {
    2845           0 :         twoByteOpSimd("vcvtsi2sd", VEX_SD, OP2_CVTSI2SD_VsdEd, offset, base, index, scale, src0, dst);
    2846           0 :     }
    2847             : 
    2848             :     void vcvtsi2ss_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2849             :     {
    2850             :         twoByteOpSimd("vcvtsi2ss", VEX_SS, OP2_CVTSI2SD_VsdEd, offset, base, src0, dst);
    2851             :     }
    2852             : 
    2853             :     void vcvtsi2ss_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID src0, XMMRegisterID dst)
    2854             :     {
    2855             :         twoByteOpSimd("vcvtsi2ss", VEX_SS, OP2_CVTSI2SD_VsdEd, offset, base, index, scale, src0, dst);
    2856             :     }
    2857             : 
    2858          26 :     void vcvttsd2si_rr(XMMRegisterID src, RegisterID dst)
    2859             :     {
    2860          26 :         twoByteOpSimdInt32("vcvttsd2si", VEX_SD, OP2_CVTTSD2SI_GdWsd, src, dst);
    2861          26 :     }
    2862             : 
    2863           0 :     void vcvttss2si_rr(XMMRegisterID src, RegisterID dst)
    2864             :     {
    2865           0 :         twoByteOpSimdInt32("vcvttss2si", VEX_SS, OP2_CVTTSD2SI_GdWsd, src, dst);
    2866           0 :     }
    2867             : 
    2868           0 :     void vunpcklps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2869             :     {
    2870           0 :         twoByteOpSimd("vunpcklps", VEX_PS, OP2_UNPCKLPS_VsdWsd, src1, src0, dst);
    2871           0 :     }
    2872           0 :     void vunpcklps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2873             :     {
    2874           0 :         twoByteOpSimd("vunpcklps", VEX_PS, OP2_UNPCKLPS_VsdWsd, offset, base, src0, dst);
    2875           0 :     }
    2876           0 :     void vunpcklps_mr(const void* addr, XMMRegisterID src0, XMMRegisterID dst)
    2877             :     {
    2878           0 :         twoByteOpSimd("vunpcklps", VEX_PS, OP2_UNPCKLPS_VsdWsd, addr, src0, dst);
    2879           0 :     }
    2880             : 
    2881           0 :     void vunpckhps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2882             :     {
    2883           0 :         twoByteOpSimd("vunpckhps", VEX_PS, OP2_UNPCKHPS_VsdWsd, src1, src0, dst);
    2884           0 :     }
    2885           0 :     void vunpckhps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2886             :     {
    2887           0 :         twoByteOpSimd("vunpckhps", VEX_PS, OP2_UNPCKHPS_VsdWsd, offset, base, src0, dst);
    2888           0 :     }
    2889           0 :     void vunpckhps_mr(const void* addr, XMMRegisterID src0, XMMRegisterID dst)
    2890             :     {
    2891           0 :         twoByteOpSimd("vunpckhps", VEX_PS, OP2_UNPCKHPS_VsdWsd, addr, src0, dst);
    2892           0 :     }
    2893             : 
    2894           0 :     void vpand_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2895             :     {
    2896           0 :         twoByteOpSimd("vpand", VEX_PD, OP2_PANDDQ_VdqWdq, src1, src0, dst);
    2897           0 :     }
    2898           0 :     void vpand_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2899             :     {
    2900           0 :         twoByteOpSimd("vpand", VEX_PD, OP2_PANDDQ_VdqWdq, offset, base, src0, dst);
    2901           0 :     }
    2902           0 :     void vpand_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2903             :     {
    2904           0 :         twoByteOpSimd("vpand", VEX_PD, OP2_PANDDQ_VdqWdq, address, src0, dst);
    2905           0 :     }
    2906           0 :     void vpor_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2907             :     {
    2908           0 :         twoByteOpSimd("vpor", VEX_PD, OP2_PORDQ_VdqWdq, src1, src0, dst);
    2909           0 :     }
    2910           0 :     void vpor_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2911             :     {
    2912           0 :         twoByteOpSimd("vpor", VEX_PD, OP2_PORDQ_VdqWdq, offset, base, src0, dst);
    2913           0 :     }
    2914           0 :     void vpor_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2915             :     {
    2916           0 :         twoByteOpSimd("vpor", VEX_PD, OP2_PORDQ_VdqWdq, address, src0, dst);
    2917           0 :     }
    2918           0 :     void vpxor_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2919             :     {
    2920           0 :         twoByteOpSimd("vpxor", VEX_PD, OP2_PXORDQ_VdqWdq, src1, src0, dst);
    2921           0 :     }
    2922           0 :     void vpxor_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2923             :     {
    2924           0 :         twoByteOpSimd("vpxor", VEX_PD, OP2_PXORDQ_VdqWdq, offset, base, src0, dst);
    2925           0 :     }
    2926           0 :     void vpxor_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2927             :     {
    2928           0 :         twoByteOpSimd("vpxor", VEX_PD, OP2_PXORDQ_VdqWdq, address, src0, dst);
    2929           0 :     }
    2930             :     void vpandn_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2931             :     {
    2932             :         twoByteOpSimd("vpandn", VEX_PD, OP2_PANDNDQ_VdqWdq, src1, src0, dst);
    2933             :     }
    2934             :     void vpandn_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2935             :     {
    2936             :         twoByteOpSimd("vpandn", VEX_PD, OP2_PANDNDQ_VdqWdq, offset, base, src0, dst);
    2937             :     }
    2938             :     void vpandn_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2939             :     {
    2940             :         twoByteOpSimd("vpandn", VEX_PD, OP2_PANDNDQ_VdqWdq, address, src0, dst);
    2941             :     }
    2942             : 
    2943           0 :     void vpshufd_irr(uint32_t mask, XMMRegisterID src, XMMRegisterID dst)
    2944             :     {
    2945           0 :         twoByteOpImmSimd("vpshufd", VEX_PD, OP2_PSHUFD_VdqWdqIb, mask, src, invalid_xmm, dst);
    2946           0 :     }
    2947           0 :     void vpshufd_imr(uint32_t mask, int32_t offset, RegisterID base, XMMRegisterID dst)
    2948             :     {
    2949           0 :         twoByteOpImmSimd("vpshufd", VEX_PD, OP2_PSHUFD_VdqWdqIb, mask, offset, base, invalid_xmm, dst);
    2950           0 :     }
    2951           0 :     void vpshufd_imr(uint32_t mask, const void* address, XMMRegisterID dst)
    2952             :     {
    2953           0 :         twoByteOpImmSimd("vpshufd", VEX_PD, OP2_PSHUFD_VdqWdqIb, mask, address, invalid_xmm, dst);
    2954           0 :     }
    2955             : 
    2956           0 :     void vpshuflw_irr(uint32_t mask, XMMRegisterID src, XMMRegisterID dst)
    2957             :     {
    2958           0 :         twoByteOpImmSimd("vpshuflw", VEX_SD, OP2_PSHUFLW_VdqWdqIb, mask, src, invalid_xmm, dst);
    2959           0 :     }
    2960             : 
    2961             :     void vpshufhw_irr(uint32_t mask, XMMRegisterID src, XMMRegisterID dst)
    2962             :     {
    2963             :         twoByteOpImmSimd("vpshufhw", VEX_SS, OP2_PSHUFHW_VdqWdqIb, mask, src, invalid_xmm, dst);
    2964             :     }
    2965             : 
    2966           0 :     void vpshufb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2967             :     {
    2968           0 :         threeByteOpSimd("vpshufb", VEX_PD, OP3_PSHUFB_VdqWdq, ESCAPE_38, src1, src0, dst);
    2969           0 :     }
    2970             : 
    2971           0 :     void vshufps_irr(uint32_t mask, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2972             :     {
    2973           0 :         twoByteOpImmSimd("vshufps", VEX_PS, OP2_SHUFPS_VpsWpsIb, mask, src1, src0, dst);
    2974           0 :     }
    2975           0 :     void vshufps_imr(uint32_t mask, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    2976             :     {
    2977           0 :         twoByteOpImmSimd("vshufps", VEX_PS, OP2_SHUFPS_VpsWpsIb, mask, offset, base, src0, dst);
    2978           0 :     }
    2979           0 :     void vshufps_imr(uint32_t mask, const void* address, XMMRegisterID src0, XMMRegisterID dst)
    2980             :     {
    2981           0 :         twoByteOpImmSimd("vshufps", VEX_PS, OP2_SHUFPS_VpsWpsIb, mask, address, src0, dst);
    2982           0 :     }
    2983             : 
    2984           0 :     void vmovddup_rr(XMMRegisterID src, XMMRegisterID dst)
    2985             :     {
    2986           0 :         twoByteOpSimd("vmovddup", VEX_SD, OP2_MOVDDUP_VqWq, src, invalid_xmm, dst);
    2987           0 :     }
    2988             : 
    2989           0 :     void vmovhlps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2990             :     {
    2991           0 :         twoByteOpSimd("vmovhlps", VEX_PS, OP2_MOVHLPS_VqUq, src1, src0, dst);
    2992           0 :     }
    2993             : 
    2994           0 :     void vmovlhps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    2995             :     {
    2996           0 :         twoByteOpSimd("vmovlhps", VEX_PS, OP2_MOVLHPS_VqUq, src1, src0, dst);
    2997           0 :     }
    2998             : 
    2999             :     void vpsrldq_ir(uint32_t count, XMMRegisterID src, XMMRegisterID dst)
    3000             :     {
    3001             :         MOZ_ASSERT(count < 16);
    3002             :         shiftOpImmSimd("vpsrldq", OP2_PSRLDQ_Vd, ShiftID::vpsrldq, count, src, dst);
    3003             :     }
    3004             : 
    3005           0 :     void vpsllq_ir(uint32_t count, XMMRegisterID src, XMMRegisterID dst)
    3006             :     {
    3007           0 :         MOZ_ASSERT(count < 64);
    3008           0 :         shiftOpImmSimd("vpsllq", OP2_PSRLDQ_Vd, ShiftID::vpsllx, count, src, dst);
    3009           0 :     }
    3010             : 
    3011             :     void vpsrlq_ir(uint32_t count, XMMRegisterID src, XMMRegisterID dst)
    3012             :     {
    3013             :         MOZ_ASSERT(count < 64);
    3014             :         shiftOpImmSimd("vpsrlq", OP2_PSRLDQ_Vd, ShiftID::vpsrlx, count, src, dst);
    3015             :     }
    3016             : 
    3017           0 :     void vpslld_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3018             :     {
    3019           0 :         twoByteOpSimd("vpslld", VEX_PD, OP2_PSLLD_VdqWdq, src1, src0, dst);
    3020           0 :     }
    3021             : 
    3022           0 :     void vpslld_ir(uint32_t count, XMMRegisterID src, XMMRegisterID dst)
    3023             :     {
    3024           0 :         MOZ_ASSERT(count < 32);
    3025           0 :         shiftOpImmSimd("vpslld", OP2_PSLLD_UdqIb, ShiftID::vpsllx, count, src, dst);
    3026           0 :     }
    3027             : 
    3028           0 :     void vpsrad_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3029             :     {
    3030           0 :         twoByteOpSimd("vpsrad", VEX_PD, OP2_PSRAD_VdqWdq, src1, src0, dst);
    3031           0 :     }
    3032             : 
    3033           0 :     void vpsrad_ir(int32_t count, XMMRegisterID src, XMMRegisterID dst)
    3034             :     {
    3035           0 :         MOZ_ASSERT(count < 32);
    3036           0 :         shiftOpImmSimd("vpsrad", OP2_PSRAD_UdqIb, ShiftID::vpsrad, count, src, dst);
    3037           0 :     }
    3038             : 
    3039           0 :     void vpsrld_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3040             :     {
    3041           0 :         twoByteOpSimd("vpsrld", VEX_PD, OP2_PSRLD_VdqWdq, src1, src0, dst);
    3042           0 :     }
    3043             : 
    3044           0 :     void vpsrld_ir(uint32_t count, XMMRegisterID src, XMMRegisterID dst)
    3045             :     {
    3046           0 :         MOZ_ASSERT(count < 32);
    3047           0 :         shiftOpImmSimd("vpsrld", OP2_PSRLD_UdqIb, ShiftID::vpsrlx, count, src, dst);
    3048           0 :     }
    3049             : 
    3050           0 :     void vpsllw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3051             :     {
    3052           0 :         twoByteOpSimd("vpsllw", VEX_PD, OP2_PSLLW_VdqWdq, src1, src0, dst);
    3053           0 :     }
    3054             : 
    3055           0 :     void vpsllw_ir(uint32_t count, XMMRegisterID src, XMMRegisterID dst)
    3056             :     {
    3057           0 :         MOZ_ASSERT(count < 16);
    3058           0 :         shiftOpImmSimd("vpsllw", OP2_PSLLW_UdqIb, ShiftID::vpsllx, count, src, dst);
    3059           0 :     }
    3060             : 
    3061           0 :     void vpsraw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3062             :     {
    3063           0 :         twoByteOpSimd("vpsraw", VEX_PD, OP2_PSRAW_VdqWdq, src1, src0, dst);
    3064           0 :     }
    3065             : 
    3066           0 :     void vpsraw_ir(int32_t count, XMMRegisterID src, XMMRegisterID dst)
    3067             :     {
    3068           0 :         MOZ_ASSERT(count < 16);
    3069           0 :         shiftOpImmSimd("vpsraw", OP2_PSRAW_UdqIb, ShiftID::vpsrad, count, src, dst);
    3070           0 :     }
    3071             : 
    3072           0 :     void vpsrlw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3073             :     {
    3074           0 :         twoByteOpSimd("vpsrlw", VEX_PD, OP2_PSRLW_VdqWdq, src1, src0, dst);
    3075           0 :     }
    3076             : 
    3077           0 :     void vpsrlw_ir(uint32_t count, XMMRegisterID src, XMMRegisterID dst)
    3078             :     {
    3079           0 :         MOZ_ASSERT(count < 16);
    3080           0 :         shiftOpImmSimd("vpsrlw", OP2_PSRLW_UdqIb, ShiftID::vpsrlx, count, src, dst);
    3081           0 :     }
    3082             : 
    3083           0 :     void vmovmskpd_rr(XMMRegisterID src, RegisterID dst)
    3084             :     {
    3085           0 :         twoByteOpSimdInt32("vmovmskpd", VEX_PD, OP2_MOVMSKPD_EdVd, src, dst);
    3086           0 :     }
    3087             : 
    3088           0 :     void vmovmskps_rr(XMMRegisterID src, RegisterID dst)
    3089             :     {
    3090           0 :         twoByteOpSimdInt32("vmovmskps", VEX_PS, OP2_MOVMSKPD_EdVd, src, dst);
    3091           0 :     }
    3092             : 
    3093           0 :     void vpmovmskb_rr(XMMRegisterID src, RegisterID dst)
    3094             :     {
    3095           0 :         twoByteOpSimdInt32("vpmovmskb", VEX_PD, OP2_PMOVMSKB_EdVd, src, dst);
    3096           0 :     }
    3097             : 
    3098             :     void vptest_rr(XMMRegisterID rhs, XMMRegisterID lhs) {
    3099             :         threeByteOpSimd("vptest", VEX_PD, OP3_PTEST_VdVd, ESCAPE_38, rhs, invalid_xmm, lhs);
    3100             :     }
    3101             : 
    3102           0 :     void vmovd_rr(XMMRegisterID src, RegisterID dst)
    3103             :     {
    3104           0 :         twoByteOpSimdInt32("vmovd", VEX_PD, OP2_MOVD_EdVd, (XMMRegisterID)dst, (RegisterID)src);
    3105           0 :     }
    3106             : 
    3107           0 :     void vmovd_rr(RegisterID src, XMMRegisterID dst)
    3108             :     {
    3109           0 :         twoByteOpInt32Simd("vmovd", VEX_PD, OP2_MOVD_VdEd, src, invalid_xmm, dst);
    3110           0 :     }
    3111             : 
    3112           0 :     void vmovd_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3113             :     {
    3114           0 :         twoByteOpSimd("vmovd", VEX_PD, OP2_MOVD_VdEd, offset, base, invalid_xmm, dst);
    3115           0 :     }
    3116             : 
    3117           0 :     void vmovd_mr(int32_t offset, RegisterID base, RegisterID index, int32_t scale, XMMRegisterID dst)
    3118             :     {
    3119           0 :         twoByteOpSimd("vmovd", VEX_PD, OP2_MOVD_VdEd, offset, base, index, scale, invalid_xmm, dst);
    3120           0 :     }
    3121             : 
    3122             :     void vmovd_mr_disp32(int32_t offset, RegisterID base, XMMRegisterID dst)
    3123             :     {
    3124             :         twoByteOpSimd_disp32("vmovd", VEX_PD, OP2_MOVD_VdEd, offset, base, invalid_xmm, dst);
    3125             :     }
    3126             : 
    3127             :     void vmovd_mr(const void* address, XMMRegisterID dst)
    3128             :     {
    3129             :         twoByteOpSimd("vmovd", VEX_PD, OP2_MOVD_VdEd, address, invalid_xmm, dst);
    3130             :     }
    3131             : 
    3132           0 :     void vmovd_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    3133             :     {
    3134           0 :         twoByteOpSimd("vmovd", VEX_PD, OP2_MOVD_EdVd, offset, base, invalid_xmm, src);
    3135           0 :     }
    3136             : 
    3137           0 :     void vmovd_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    3138             :     {
    3139           0 :         twoByteOpSimd("vmovd", VEX_PD, OP2_MOVD_EdVd, offset, base, index, scale, invalid_xmm, src);
    3140           0 :     }
    3141             : 
    3142             :     void vmovd_rm_disp32(XMMRegisterID src, int32_t offset, RegisterID base)
    3143             :     {
    3144             :         twoByteOpSimd_disp32("vmovd", VEX_PD, OP2_MOVD_EdVd, offset, base, invalid_xmm, src);
    3145             :     }
    3146             : 
    3147             :     void vmovd_rm(XMMRegisterID src, const void* address)
    3148             :     {
    3149             :         twoByteOpSimd("vmovd", VEX_PD, OP2_MOVD_EdVd, address, invalid_xmm, src);
    3150             :     }
    3151             : 
    3152           7 :     void vmovsd_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    3153             :     {
    3154           7 :         twoByteOpSimd("vmovsd", VEX_SD, OP2_MOVSD_WsdVsd, offset, base, invalid_xmm, src);
    3155           7 :     }
    3156             : 
    3157             :     void vmovsd_rm_disp32(XMMRegisterID src, int32_t offset, RegisterID base)
    3158             :     {
    3159             :         twoByteOpSimd_disp32("vmovsd", VEX_SD, OP2_MOVSD_WsdVsd, offset, base, invalid_xmm, src);
    3160             :     }
    3161             : 
    3162           0 :     void vmovss_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    3163             :     {
    3164           0 :         twoByteOpSimd("vmovss", VEX_SS, OP2_MOVSD_WsdVsd, offset, base, invalid_xmm, src);
    3165           0 :     }
    3166             : 
    3167             :     void vmovss_rm_disp32(XMMRegisterID src, int32_t offset, RegisterID base)
    3168             :     {
    3169             :         twoByteOpSimd_disp32("vmovss", VEX_SS, OP2_MOVSD_WsdVsd, offset, base, invalid_xmm, src);
    3170             :     }
    3171             : 
    3172           0 :     void vmovss_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3173             :     {
    3174           0 :         twoByteOpSimd("vmovss", VEX_SS, OP2_MOVSD_VsdWsd, offset, base, invalid_xmm, dst);
    3175           0 :     }
    3176             : 
    3177             :     void vmovss_mr_disp32(int32_t offset, RegisterID base, XMMRegisterID dst)
    3178             :     {
    3179             :         twoByteOpSimd_disp32("vmovss", VEX_SS, OP2_MOVSD_VsdWsd, offset, base, invalid_xmm, dst);
    3180             :     }
    3181             : 
    3182           0 :     void vmovsd_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    3183             :     {
    3184           0 :         twoByteOpSimd("vmovsd", VEX_SD, OP2_MOVSD_WsdVsd, offset, base, index, scale, invalid_xmm, src);
    3185           0 :     }
    3186             : 
    3187           0 :     void vmovss_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    3188             :     {
    3189           0 :         twoByteOpSimd("vmovss", VEX_SS, OP2_MOVSD_WsdVsd, offset, base, index, scale, invalid_xmm, src);
    3190           0 :     }
    3191             : 
    3192           0 :     void vmovss_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
    3193             :     {
    3194           0 :         twoByteOpSimd("vmovss", VEX_SS, OP2_MOVSD_VsdWsd, offset, base, index, scale, invalid_xmm, dst);
    3195           0 :     }
    3196             : 
    3197          16 :     void vmovsd_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3198             :     {
    3199          16 :         twoByteOpSimd("vmovsd", VEX_SD, OP2_MOVSD_VsdWsd, offset, base, invalid_xmm, dst);
    3200          16 :     }
    3201             : 
    3202             :     void vmovsd_mr_disp32(int32_t offset, RegisterID base, XMMRegisterID dst)
    3203             :     {
    3204             :         twoByteOpSimd_disp32("vmovsd", VEX_SD, OP2_MOVSD_VsdWsd, offset, base, invalid_xmm, dst);
    3205             :     }
    3206             : 
    3207           0 :     void vmovsd_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
    3208             :     {
    3209           0 :         twoByteOpSimd("vmovsd", VEX_SD, OP2_MOVSD_VsdWsd, offset, base, index, scale, invalid_xmm, dst);
    3210           0 :     }
    3211             : 
    3212             :     // Note that the register-to-register form of vmovsd does not write to the
    3213             :     // entire output register. For general-purpose register-to-register moves,
    3214             :     // use vmovapd instead.
    3215             :     void vmovsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3216             :     {
    3217             :         twoByteOpSimd("vmovsd", VEX_SD, OP2_MOVSD_VsdWsd, src1, src0, dst);
    3218             :     }
    3219             : 
    3220             :     // The register-to-register form of vmovss has the same problem as vmovsd
    3221             :     // above. Prefer vmovaps for register-to-register moves.
    3222           0 :     void vmovss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3223             :     {
    3224           0 :         twoByteOpSimd("vmovss", VEX_SS, OP2_MOVSD_VsdWsd, src1, src0, dst);
    3225           0 :     }
    3226             : 
    3227             :     void vmovsd_mr(const void* address, XMMRegisterID dst)
    3228             :     {
    3229             :         twoByteOpSimd("vmovsd", VEX_SD, OP2_MOVSD_VsdWsd, address, invalid_xmm, dst);
    3230             :     }
    3231             : 
    3232             :     void vmovss_mr(const void* address, XMMRegisterID dst)
    3233             :     {
    3234             :         twoByteOpSimd("vmovss", VEX_SS, OP2_MOVSD_VsdWsd, address, invalid_xmm, dst);
    3235             :     }
    3236             : 
    3237             :     void vmovups_mr(const void* address, XMMRegisterID dst)
    3238             :     {
    3239             :         twoByteOpSimd("vmovups", VEX_PS, OP2_MOVPS_VpsWps, address, invalid_xmm, dst);
    3240             :     }
    3241             : 
    3242             :     void vmovdqu_mr(const void* address, XMMRegisterID dst)
    3243             :     {
    3244             :         twoByteOpSimd("vmovdqu", VEX_SS, OP2_MOVDQ_VdqWdq, address, invalid_xmm, dst);
    3245             :     }
    3246             : 
    3247             :     void vmovsd_rm(XMMRegisterID src, const void* address)
    3248             :     {
    3249             :         twoByteOpSimd("vmovsd", VEX_SD, OP2_MOVSD_WsdVsd, address, invalid_xmm, src);
    3250             :     }
    3251             : 
    3252             :     void vmovss_rm(XMMRegisterID src, const void* address)
    3253             :     {
    3254             :         twoByteOpSimd("vmovss", VEX_SS, OP2_MOVSD_WsdVsd, address, invalid_xmm, src);
    3255             :     }
    3256             : 
    3257             :     void vmovdqa_rm(XMMRegisterID src, const void* address)
    3258             :     {
    3259             :         twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_WdqVdq, address, invalid_xmm, src);
    3260             :     }
    3261             : 
    3262             :     void vmovaps_rm(XMMRegisterID src, const void* address)
    3263             :     {
    3264             :         twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_WsdVsd, address, invalid_xmm, src);
    3265             :     }
    3266             : 
    3267             :     void vmovdqu_rm(XMMRegisterID src, const void* address)
    3268             :     {
    3269             :         twoByteOpSimd("vmovdqu", VEX_SS, OP2_MOVDQ_WdqVdq, address, invalid_xmm, src);
    3270             :     }
    3271             : 
    3272             :     void vmovups_rm(XMMRegisterID src, const void* address)
    3273             :     {
    3274             :         twoByteOpSimd("vmovups", VEX_PS, OP2_MOVPS_WpsVps, address, invalid_xmm, src);
    3275             :     }
    3276             : 
    3277           0 :     void vmovaps_rr(XMMRegisterID src, XMMRegisterID dst)
    3278             :     {
    3279             : #ifdef JS_CODEGEN_X64
    3280             :         // There are two opcodes that can encode this instruction. If we have
    3281             :         // one register in [xmm8,xmm15] and one in [xmm0,xmm7], use the
    3282             :         // opcode which swaps the operands, as that way we can get a two-byte
    3283             :         // VEX in that case.
    3284           0 :         if (src >= xmm8 && dst < xmm8) {
    3285           0 :             twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_WsdVsd, dst, invalid_xmm, src);
    3286           0 :             return;
    3287             :         }
    3288             : #endif
    3289           0 :         twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_VsdWsd, src, invalid_xmm, dst);
    3290             :     }
    3291           0 :     void vmovaps_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    3292             :     {
    3293           0 :         twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_WsdVsd, offset, base, invalid_xmm, src);
    3294           0 :     }
    3295           0 :     void vmovaps_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    3296             :     {
    3297           0 :         twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_WsdVsd, offset, base, index, scale, invalid_xmm, src);
    3298           0 :     }
    3299           0 :     void vmovaps_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3300             :     {
    3301           0 :         twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_VsdWsd, offset, base, invalid_xmm, dst);
    3302           0 :     }
    3303           0 :     void vmovaps_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
    3304             :     {
    3305           0 :         twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_VsdWsd, offset, base, index, scale, invalid_xmm, dst);
    3306           0 :     }
    3307             : 
    3308      165673 :     void vmovups_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    3309             :     {
    3310      165673 :         twoByteOpSimd("vmovups", VEX_PS, OP2_MOVPS_WpsVps, offset, base, invalid_xmm, src);
    3311      165663 :     }
    3312             :     void vmovups_rm_disp32(XMMRegisterID src, int32_t offset, RegisterID base)
    3313             :     {
    3314             :         twoByteOpSimd_disp32("vmovups", VEX_PS, OP2_MOVPS_WpsVps, offset, base, invalid_xmm, src);
    3315             :     }
    3316           0 :     void vmovups_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    3317             :     {
    3318           0 :         twoByteOpSimd("vmovups", VEX_PS, OP2_MOVPS_WpsVps, offset, base, index, scale, invalid_xmm, src);
    3319           0 :     }
    3320      165542 :     void vmovups_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3321             :     {
    3322      165542 :         twoByteOpSimd("vmovups", VEX_PS, OP2_MOVPS_VpsWps, offset, base, invalid_xmm, dst);
    3323      165522 :     }
    3324             :     void vmovups_mr_disp32(int32_t offset, RegisterID base, XMMRegisterID dst)
    3325             :     {
    3326             :         twoByteOpSimd_disp32("vmovups", VEX_PS, OP2_MOVPS_VpsWps, offset, base, invalid_xmm, dst);
    3327             :     }
    3328           0 :     void vmovups_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
    3329             :     {
    3330           0 :         twoByteOpSimd("vmovups", VEX_PS, OP2_MOVPS_VpsWps, offset, base, index, scale, invalid_xmm, dst);
    3331           0 :     }
    3332             : 
    3333           0 :     void vmovapd_rr(XMMRegisterID src, XMMRegisterID dst)
    3334             :     {
    3335             : #ifdef JS_CODEGEN_X64
    3336             :         // There are two opcodes that can encode this instruction. If we have
    3337             :         // one register in [xmm8,xmm15] and one in [xmm0,xmm7], use the
    3338             :         // opcode which swaps the operands, as that way we can get a two-byte
    3339             :         // VEX in that case.
    3340           0 :         if (src >= xmm8 && dst < xmm8) {
    3341           0 :             twoByteOpSimd("vmovapd", VEX_PD, OP2_MOVAPS_WsdVsd, dst, invalid_xmm, src);
    3342           0 :             return;
    3343             :         }
    3344             : #endif
    3345           0 :         twoByteOpSimd("vmovapd", VEX_PD, OP2_MOVAPD_VsdWsd, src, invalid_xmm, dst);
    3346             :     }
    3347             : 
    3348           0 :     void vmovdqu_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    3349             :     {
    3350           0 :         twoByteOpSimd("vmovdqu", VEX_SS, OP2_MOVDQ_WdqVdq, offset, base, invalid_xmm, src);
    3351           0 :     }
    3352             : 
    3353             :     void vmovdqu_rm_disp32(XMMRegisterID src, int32_t offset, RegisterID base)
    3354             :     {
    3355             :         twoByteOpSimd_disp32("vmovdqu", VEX_SS, OP2_MOVDQ_WdqVdq, offset, base, invalid_xmm, src);
    3356             :     }
    3357             : 
    3358           0 :     void vmovdqu_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    3359             :     {
    3360           0 :         twoByteOpSimd("vmovdqu", VEX_SS, OP2_MOVDQ_WdqVdq, offset, base, index, scale, invalid_xmm, src);
    3361           0 :     }
    3362             : 
    3363           0 :     void vmovdqu_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3364             :     {
    3365           0 :         twoByteOpSimd("vmovdqu", VEX_SS, OP2_MOVDQ_VdqWdq, offset, base, invalid_xmm, dst);
    3366           0 :     }
    3367             : 
    3368             :     void vmovdqu_mr_disp32(int32_t offset, RegisterID base, XMMRegisterID dst)
    3369             :     {
    3370             :         twoByteOpSimd_disp32("vmovdqu", VEX_SS, OP2_MOVDQ_VdqWdq, offset, base, invalid_xmm, dst);
    3371             :     }
    3372             : 
    3373           0 :     void vmovdqu_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
    3374             :     {
    3375           0 :         twoByteOpSimd("vmovdqu", VEX_SS, OP2_MOVDQ_VdqWdq, offset, base, index, scale, invalid_xmm, dst);
    3376           0 :     }
    3377             : 
    3378           0 :     void vmovdqa_rr(XMMRegisterID src, XMMRegisterID dst)
    3379             :     {
    3380             : #ifdef JS_CODEGEN_X64
    3381             :         // There are two opcodes that can encode this instruction. If we have
    3382             :         // one register in [xmm8,xmm15] and one in [xmm0,xmm7], use the
    3383             :         // opcode which swaps the operands, as that way we can get a two-byte
    3384             :         // VEX in that case.
    3385           0 :         if (src >= xmm8 && dst < xmm8) {
    3386           0 :             twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_WdqVdq, dst, invalid_xmm, src);
    3387           0 :             return;
    3388             :         }
    3389             : #endif
    3390           0 :         twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_VdqWdq, src, invalid_xmm, dst);
    3391             :     }
    3392             : 
    3393           0 :     void vmovdqa_rm(XMMRegisterID src, int32_t offset, RegisterID base)
    3394             :     {
    3395           0 :         twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_WdqVdq, offset, base, invalid_xmm, src);
    3396           0 :     }
    3397             : 
    3398           0 :     void vmovdqa_rm(XMMRegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
    3399             :     {
    3400           0 :         twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_WdqVdq, offset, base, index, scale, invalid_xmm, src);
    3401           0 :     }
    3402             : 
    3403           0 :     void vmovdqa_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3404             :     {
    3405             : 
    3406           0 :         twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_VdqWdq, offset, base, invalid_xmm, dst);
    3407           0 :     }
    3408             : 
    3409           0 :     void vmovdqa_mr(int32_t offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
    3410             :     {
    3411           0 :         twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_VdqWdq, offset, base, index, scale, invalid_xmm, dst);
    3412           0 :     }
    3413             : 
    3414           0 :     void vmulsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3415             :     {
    3416           0 :         twoByteOpSimd("vmulsd", VEX_SD, OP2_MULSD_VsdWsd, src1, src0, dst);
    3417           0 :     }
    3418             : 
    3419           0 :     void vmulss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3420             :     {
    3421           0 :         twoByteOpSimd("vmulss", VEX_SS, OP2_MULSD_VsdWsd, src1, src0, dst);
    3422           0 :     }
    3423             : 
    3424           0 :     void vmulsd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3425             :     {
    3426           0 :         twoByteOpSimd("vmulsd", VEX_SD, OP2_MULSD_VsdWsd, offset, base, src0, dst);
    3427           0 :     }
    3428             : 
    3429           0 :     void vmulss_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3430             :     {
    3431           0 :         twoByteOpSimd("vmulss", VEX_SS, OP2_MULSD_VsdWsd, offset, base, src0, dst);
    3432           0 :     }
    3433             : 
    3434           0 :     void vpinsrw_irr(uint32_t whichWord, RegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3435             :     {
    3436           0 :         MOZ_ASSERT(whichWord < 8);
    3437           0 :         twoByteOpImmInt32Simd("vpinsrw", VEX_PD, OP2_PINSRW, whichWord, src1, src0, dst);
    3438           0 :     }
    3439             : 
    3440           0 :     void vpextrw_irr(uint32_t whichWord, XMMRegisterID src, RegisterID dst)
    3441             :     {
    3442           0 :         MOZ_ASSERT(whichWord < 8);
    3443           0 :         twoByteOpImmSimdInt32("vpextrw", VEX_PD, OP2_PEXTRW_GdUdIb, whichWord, src, dst);
    3444           0 :     }
    3445             : 
    3446           0 :     void vsubsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3447             :     {
    3448           0 :         twoByteOpSimd("vsubsd", VEX_SD, OP2_SUBSD_VsdWsd, src1, src0, dst);
    3449           0 :     }
    3450             : 
    3451           0 :     void vsubss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3452             :     {
    3453           0 :         twoByteOpSimd("vsubss", VEX_SS, OP2_SUBSD_VsdWsd, src1, src0, dst);
    3454           0 :     }
    3455             : 
    3456           0 :     void vsubsd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3457             :     {
    3458           0 :         twoByteOpSimd("vsubsd", VEX_SD, OP2_SUBSD_VsdWsd, offset, base, src0, dst);
    3459           0 :     }
    3460             : 
    3461           0 :     void vsubss_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3462             :     {
    3463           0 :         twoByteOpSimd("vsubss", VEX_SS, OP2_SUBSD_VsdWsd, offset, base, src0, dst);
    3464           0 :     }
    3465             : 
    3466           0 :     void vucomiss_rr(XMMRegisterID rhs, XMMRegisterID lhs)
    3467             :     {
    3468           0 :         twoByteOpSimdFlags("vucomiss", VEX_PS, OP2_UCOMISD_VsdWsd, rhs, lhs);
    3469           0 :     }
    3470             : 
    3471          38 :     void vucomisd_rr(XMMRegisterID rhs, XMMRegisterID lhs)
    3472             :     {
    3473          38 :         twoByteOpSimdFlags("vucomisd", VEX_PD, OP2_UCOMISD_VsdWsd, rhs, lhs);
    3474          38 :     }
    3475             : 
    3476             :     void vucomisd_mr(int32_t offset, RegisterID base, XMMRegisterID lhs)
    3477             :     {
    3478             :         twoByteOpSimdFlags("vucomisd", VEX_PD, OP2_UCOMISD_VsdWsd, offset, base, lhs);
    3479             :     }
    3480             : 
    3481           1 :     void vdivsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3482             :     {
    3483           1 :         twoByteOpSimd("vdivsd", VEX_SD, OP2_DIVSD_VsdWsd, src1, src0, dst);
    3484           1 :     }
    3485             : 
    3486           0 :     void vdivss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3487             :     {
    3488           0 :         twoByteOpSimd("vdivss", VEX_SS, OP2_DIVSD_VsdWsd, src1, src0, dst);
    3489           0 :     }
    3490             : 
    3491           0 :     void vdivsd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3492             :     {
    3493           0 :         twoByteOpSimd("vdivsd", VEX_SD, OP2_DIVSD_VsdWsd, offset, base, src0, dst);
    3494           0 :     }
    3495             : 
    3496           0 :     void vdivss_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3497             :     {
    3498           0 :         twoByteOpSimd("vdivss", VEX_SS, OP2_DIVSD_VsdWsd, offset, base, src0, dst);
    3499           0 :     }
    3500             : 
    3501          59 :     void vxorpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3502             :     {
    3503          59 :         twoByteOpSimd("vxorpd", VEX_PD, OP2_XORPD_VpdWpd, src1, src0, dst);
    3504          59 :     }
    3505             : 
    3506           0 :     void vorpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3507             :     {
    3508           0 :         twoByteOpSimd("vorpd", VEX_PD, OP2_ORPD_VpdWpd, src1, src0, dst);
    3509           0 :     }
    3510             : 
    3511           0 :     void vandpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3512             :     {
    3513           0 :         twoByteOpSimd("vandpd", VEX_PD, OP2_ANDPD_VpdWpd, src1, src0, dst);
    3514           0 :     }
    3515             : 
    3516           0 :     void vandps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3517             :     {
    3518           0 :         twoByteOpSimd("vandps", VEX_PS, OP2_ANDPS_VpsWps, src1, src0, dst);
    3519           0 :     }
    3520             : 
    3521           0 :     void vandps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3522             :     {
    3523           0 :         twoByteOpSimd("vandps", VEX_PS, OP2_ANDPS_VpsWps, offset, base, src0, dst);
    3524           0 :     }
    3525             : 
    3526           0 :     void vandps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    3527             :     {
    3528           0 :         twoByteOpSimd("vandps", VEX_PS, OP2_ANDPS_VpsWps, address, src0, dst);
    3529           0 :     }
    3530             : 
    3531           0 :     void vandnps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3532             :     {
    3533           0 :         twoByteOpSimd("vandnps", VEX_PS, OP2_ANDNPS_VpsWps, src1, src0, dst);
    3534           0 :     }
    3535             : 
    3536           0 :     void vandnps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3537             :     {
    3538           0 :         twoByteOpSimd("vandnps", VEX_PS, OP2_ANDNPS_VpsWps, offset, base, src0, dst);
    3539           0 :     }
    3540             : 
    3541           0 :     void vandnps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    3542             :     {
    3543           0 :         twoByteOpSimd("vandnps", VEX_PS, OP2_ANDNPS_VpsWps, address, src0, dst);
    3544           0 :     }
    3545             : 
    3546           0 :     void vorps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3547             :     {
    3548           0 :         twoByteOpSimd("vorps", VEX_PS, OP2_ORPS_VpsWps, src1, src0, dst);
    3549           0 :     }
    3550             : 
    3551           0 :     void vorps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3552             :     {
    3553           0 :         twoByteOpSimd("vorps", VEX_PS, OP2_ORPS_VpsWps, offset, base, src0, dst);
    3554           0 :     }
    3555             : 
    3556           0 :     void vorps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    3557             :     {
    3558           0 :         twoByteOpSimd("vorps", VEX_PS, OP2_ORPS_VpsWps, address, src0, dst);
    3559           0 :     }
    3560             : 
    3561           0 :     void vxorps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3562             :     {
    3563           0 :         twoByteOpSimd("vxorps", VEX_PS, OP2_XORPS_VpsWps, src1, src0, dst);
    3564           0 :     }
    3565             : 
    3566           0 :     void vxorps_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3567             :     {
    3568           0 :         twoByteOpSimd("vxorps", VEX_PS, OP2_XORPS_VpsWps, offset, base, src0, dst);
    3569           0 :     }
    3570             : 
    3571           0 :     void vxorps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
    3572             :     {
    3573           0 :         twoByteOpSimd("vxorps", VEX_PS, OP2_XORPS_VpsWps, address, src0, dst);
    3574           0 :     }
    3575             : 
    3576           0 :     void vsqrtsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3577             :     {
    3578           0 :         twoByteOpSimd("vsqrtsd", VEX_SD, OP2_SQRTSD_VsdWsd, src1, src0, dst);
    3579           0 :     }
    3580             : 
    3581           0 :     void vsqrtss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3582             :     {
    3583           0 :         twoByteOpSimd("vsqrtss", VEX_SS, OP2_SQRTSS_VssWss, src1, src0, dst);
    3584           0 :     }
    3585             : 
    3586           0 :     void vroundsd_irr(RoundingMode mode, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3587             :     {
    3588           0 :         threeByteOpImmSimd("vroundsd", VEX_PD, OP3_ROUNDSD_VsdWsd, ESCAPE_3A, mode, src1, src0, dst);
    3589           0 :     }
    3590             : 
    3591           0 :     void vroundss_irr(RoundingMode mode, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3592             :     {
    3593           0 :         threeByteOpImmSimd("vroundss", VEX_PD, OP3_ROUNDSS_VsdWsd, ESCAPE_3A, mode, src1, src0, dst);
    3594           0 :     }
    3595             : 
    3596           0 :     void vinsertps_irr(uint32_t mask, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3597             :     {
    3598           0 :         threeByteOpImmSimd("vinsertps", VEX_PD, OP3_INSERTPS_VpsUps, ESCAPE_3A, mask, src1, src0, dst);
    3599           0 :     }
    3600           0 :     void vinsertps_imr(uint32_t mask, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3601             :     {
    3602           0 :         threeByteOpImmSimd("vinsertps", VEX_PD, OP3_INSERTPS_VpsUps, ESCAPE_3A, mask, offset, base, src0, dst);
    3603           0 :     }
    3604             : 
    3605           0 :     void vpinsrb_irr(unsigned lane, RegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3606             :     {
    3607           0 :         MOZ_ASSERT(lane < 16);
    3608           0 :         threeByteOpImmInt32Simd("vpinsrb", VEX_PD, OP3_PINSRB_VdqEdIb, ESCAPE_3A, lane, src1, src0, dst);
    3609           0 :     }
    3610             : 
    3611           0 :     void vpinsrd_irr(unsigned lane, RegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3612             :     {
    3613           0 :         MOZ_ASSERT(lane < 4);
    3614           0 :         threeByteOpImmInt32Simd("vpinsrd", VEX_PD, OP3_PINSRD_VdqEdIb, ESCAPE_3A, lane, src1, src0, dst);
    3615           0 :     }
    3616             : 
    3617           0 :     void vpextrb_irr(unsigned lane, XMMRegisterID src, RegisterID dst)
    3618             :     {
    3619           0 :         MOZ_ASSERT(lane < 16);
    3620           0 :         threeByteOpImmSimdInt32("vpextrb", VEX_PD, OP3_PEXTRB_EdVdqIb, ESCAPE_3A, lane, (XMMRegisterID)dst, (RegisterID)src);
    3621           0 :     }
    3622             : 
    3623           0 :     void vpextrd_irr(unsigned lane, XMMRegisterID src, RegisterID dst)
    3624             :     {
    3625           0 :         MOZ_ASSERT(lane < 4);
    3626           0 :         threeByteOpImmSimdInt32("vpextrd", VEX_PD, OP3_PEXTRD_EdVdqIb, ESCAPE_3A, lane, (XMMRegisterID)dst, (RegisterID)src);
    3627           0 :     }
    3628             : 
    3629           0 :     void vblendps_irr(unsigned imm, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3630             :     {
    3631           0 :         MOZ_ASSERT(imm < 16);
    3632             :         // Despite being a "ps" instruction, vblendps is encoded with the "pd" prefix.
    3633           0 :         threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, src1, src0, dst);
    3634           0 :     }
    3635             : 
    3636           0 :     void vblendps_imr(unsigned imm, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3637             :     {
    3638           0 :         MOZ_ASSERT(imm < 16);
    3639             :         // Despite being a "ps" instruction, vblendps is encoded with the "pd" prefix.
    3640           0 : threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, offset, base, src0, dst);
    3641           0 :     }
    3642             : 
    3643           0 :     void vblendvps_rr(XMMRegisterID mask, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    3644           0 :         vblendvOpSimd(mask, src1, src0, dst);
    3645           0 :     }
    3646             :     void vblendvps_mr(XMMRegisterID mask, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst) {
    3647             :         vblendvOpSimd(mask, offset, base, src0, dst);
    3648             :     }
    3649             : 
    3650           0 :     void vmovsldup_rr(XMMRegisterID src, XMMRegisterID dst)
    3651             :     {
    3652           0 :         twoByteOpSimd("vmovsldup", VEX_SS, OP2_MOVSLDUP_VpsWps, src, invalid_xmm, dst);
    3653           0 :     }
    3654             :     void vmovsldup_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3655             :     {
    3656             :         twoByteOpSimd("vmovsldup", VEX_SS, OP2_MOVSLDUP_VpsWps, offset, base, invalid_xmm, dst);
    3657             :     }
    3658             : 
    3659           0 :     void vmovshdup_rr(XMMRegisterID src, XMMRegisterID dst)
    3660             :     {
    3661           0 :         twoByteOpSimd("vmovshdup", VEX_SS, OP2_MOVSHDUP_VpsWps, src, invalid_xmm, dst);
    3662           0 :     }
    3663             :     void vmovshdup_mr(int32_t offset, RegisterID base, XMMRegisterID dst)
    3664             :     {
    3665             :         twoByteOpSimd("vmovshdup", VEX_SS, OP2_MOVSHDUP_VpsWps, offset, base, invalid_xmm, dst);
    3666             :     }
    3667             : 
    3668           0 :     void vminsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3669             :     {
    3670           0 :         twoByteOpSimd("vminsd", VEX_SD, OP2_MINSD_VsdWsd, src1, src0, dst);
    3671           0 :     }
    3672             :     void vminsd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3673             :     {
    3674             :         twoByteOpSimd("vminsd", VEX_SD, OP2_MINSD_VsdWsd, offset, base, src0, dst);
    3675             :     }
    3676             : 
    3677           0 :     void vminss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3678             :     {
    3679           0 :         twoByteOpSimd("vminss", VEX_SS, OP2_MINSS_VssWss, src1, src0, dst);
    3680           0 :     }
    3681             : 
    3682           0 :     void vmaxsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3683             :     {
    3684           0 :         twoByteOpSimd("vmaxsd", VEX_SD, OP2_MAXSD_VsdWsd, src1, src0, dst);
    3685           0 :     }
    3686             :     void vmaxsd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3687             :     {
    3688             :         twoByteOpSimd("vmaxsd", VEX_SD, OP2_MAXSD_VsdWsd, offset, base, src0, dst);
    3689             :     }
    3690             : 
    3691           0 :     void vmaxss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    3692             :     {
    3693           0 :         twoByteOpSimd("vmaxss", VEX_SS, OP2_MAXSS_VssWss, src1, src0, dst);
    3694           0 :     }
    3695             : 
    3696             :     // Misc instructions:
    3697             : 
    3698       21541 :     void int3()
    3699             :     {
    3700       21541 :         spew("int3");
    3701       21541 :         m_formatter.oneByteOp(OP_INT3);
    3702       21541 :     }
    3703             : 
    3704       19127 :     void ud2()
    3705             :     {
    3706       19127 :         spew("ud2");
    3707       19127 :         m_formatter.twoByteOp(OP2_UD2);
    3708       19127 :     }
    3709             : 
    3710        3552 :     void ret()
    3711             :     {
    3712        3552 :         spew("ret");
    3713        3552 :         m_formatter.oneByteOp(OP_RET);
    3714        3552 :     }
    3715             : 
    3716        1036 :     void ret_i(int32_t imm)
    3717             :     {
    3718        1036 :         spew("ret        $%d", imm);
    3719        1036 :         m_formatter.oneByteOp(OP_RET_Iz);
    3720        1036 :         m_formatter.immediate16u(imm);
    3721        1036 :     }
    3722             : 
    3723           0 :     void mfence() {
    3724           0 :         spew("mfence");
    3725           0 :         m_formatter.twoByteOp(OP_FENCE, (RegisterID)0, 6);
    3726           0 :     }
    3727             : 
    3728             :     // Assembler admin methods:
    3729             : 
    3730      200888 :     JmpDst label()
    3731             :     {
    3732      200888 :         JmpDst r = JmpDst(m_formatter.size());
    3733      200896 :         spew(".set .Llabel%d, .", r.offset());
    3734      200896 :         return r;
    3735             :     }
    3736             : 
    3737       31963 :     size_t currentOffset() const {
    3738       31963 :         return m_formatter.size();
    3739             :     }
    3740             : 
    3741             :     static JmpDst labelFor(JmpSrc jump, intptr_t offset = 0)
    3742             :     {
    3743             :         return JmpDst(jump.offset() + offset);
    3744             :     }
    3745             : 
    3746        3142 :     void haltingAlign(int alignment)
    3747             :     {
    3748        3142 :         spew(".balign %d, 0x%x   # hlt", alignment, OP_HLT);
    3749       48674 :         while (!m_formatter.isAligned(alignment))
    3750       22766 :             m_formatter.oneByteOp(OP_HLT);
    3751        3142 :     }
    3752             : 
    3753           0 :     void nopAlign(int alignment)
    3754             :     {
    3755           0 :         spew(".balign %d", alignment);
    3756             : 
    3757           0 :         int remainder = m_formatter.size() % alignment;
    3758           0 :         if (remainder > 0)
    3759           0 :             insert_nop(alignment - remainder);
    3760           0 :     }
    3761             : 
    3762           0 :     void jumpTablePointer(uintptr_t ptr)
    3763             :     {
    3764             : #ifdef JS_CODEGEN_X64
    3765           0 :         spew(".quad 0x%" PRIxPTR, ptr);
    3766             : #else
    3767             :         spew(".int 0x%" PRIxPTR, ptr);
    3768             : #endif
    3769           0 :         m_formatter.jumpTablePointer(ptr);
    3770           0 :     }
    3771             : 
    3772           0 :     void doubleConstant(double d)
    3773             :     {
    3774           0 :         spew(".double %.16g", d);
    3775           0 :         m_formatter.doubleConstant(d);
    3776           0 :     }
    3777           0 :     void floatConstant(float f)
    3778             :     {
    3779           0 :         spew(".float %.16g", f);
    3780           0 :         m_formatter.floatConstant(f);
    3781           0 :     }
    3782             : 
    3783           0 :     void simd128Constant(const void* data)
    3784             :     {
    3785           0 :         const uint32_t* dw = reinterpret_cast<const uint32_t*>(data);
    3786           0 :         spew(".int 0x%08x,0x%08x,0x%08x,0x%08x", dw[0], dw[1], dw[2], dw[3]);
    3787           0 :         MOZ_ASSERT(m_formatter.isAligned(16));
    3788           0 :         m_formatter.simd128Constant(data);
    3789           0 :     }
    3790             : 
    3791             :     void int32Constant(int32_t i)
    3792             :     {
    3793             :         spew(".int %d", i);
    3794             :         m_formatter.int32Constant(i);
    3795             :     }
    3796             :     void int64Constant(int64_t i)
    3797             :     {
    3798             :         spew(".quad %lld", (long long)i);
    3799             :         m_formatter.int64Constant(i);
    3800             :     }
    3801             : 
    3802             :     // Linking & patching:
    3803             : 
    3804      142599 :     void assertValidJmpSrc(JmpSrc src)
    3805             :     {
    3806             :         // The target offset is stored at offset - 4.
    3807      142599 :         MOZ_RELEASE_ASSERT(src.offset() > int32_t(sizeof(int32_t)));
    3808      142599 :         MOZ_RELEASE_ASSERT(size_t(src.offset()) <= size());
    3809      142597 :     }
    3810             : 
    3811       47628 :     bool nextJump(const JmpSrc& from, JmpSrc* next)
    3812             :     {
    3813             :         // Sanity check - if the assembler has OOM'd, it will start overwriting
    3814             :         // its internal buffer and thus our links could be garbage.
    3815       47628 :         if (oom())
    3816           0 :             return false;
    3817             : 
    3818       47628 :         assertValidJmpSrc(from);
    3819             : 
    3820       47628 :         const unsigned char* code = m_formatter.data();
    3821       47628 :         int32_t offset = GetInt32(code + from.offset());
    3822       47628 :         if (offset == -1)
    3823       40622 :             return false;
    3824             : 
    3825        7006 :         if (MOZ_UNLIKELY(size_t(offset) >= size())) {
    3826             : #ifdef NIGHTLY_BUILD
    3827             :             // Stash some data on the stack so we can retrieve it from minidumps,
    3828             :             // see bug 1124397.
    3829           0 :             int32_t startOffset = from.offset() - 1;
    3830           0 :             while (startOffset >= 0 && code[startOffset] == 0xe5)
    3831           0 :                 startOffset--;
    3832           0 :             int32_t endOffset = from.offset() - 1;
    3833           0 :             while (endOffset < int32_t(size()) && code[endOffset] == 0xe5)
    3834           0 :                 endOffset++;
    3835             :             volatile uintptr_t dump[10];
    3836           0 :             blackbox = dump;
    3837           0 :             blackbox[0] = uintptr_t(0xABCD1234);
    3838           0 :             blackbox[1] = uintptr_t(offset);
    3839           0 :             blackbox[2] = uintptr_t(size());
    3840           0 :             blackbox[3] = uintptr_t(from.offset());
    3841           0 :             blackbox[4] = uintptr_t(code[from.offset() - 5]);
    3842           0 :             blackbox[5] = uintptr_t(code[from.offset() - 4]);
    3843           0 :             blackbox[6] = uintptr_t(code[from.offset() - 3]);
    3844           0 :             blackbox[7] = uintptr_t(startOffset);
    3845           0 :             blackbox[8] = uintptr_t(endOffset);
    3846           0 :             blackbox[9] = uintptr_t(0xFFFF7777);
    3847             : #endif
    3848           0 :             MOZ_CRASH("nextJump bogus offset");
    3849             :         }
    3850             : 
    3851        7006 :         *next = JmpSrc(offset);
    3852        7006 :         return true;
    3853             :     }
    3854       47631 :     void setNextJump(const JmpSrc& from, const JmpSrc& to)
    3855             :     {
    3856             :         // Sanity check - if the assembler has OOM'd, it will start overwriting
    3857             :         // its internal buffer and thus our links could be garbage.
    3858       47631 :         if (oom())
    3859           0 :             return;
    3860             : 
    3861       47631 :         assertValidJmpSrc(from);
    3862       47631 :         MOZ_RELEASE_ASSERT(to.offset() == -1 || size_t(to.offset()) <= size());
    3863             : 
    3864       47630 :         unsigned char* code = m_formatter.data();
    3865       47630 :         SetInt32(code + from.offset(), to.offset());
    3866             :     }
    3867             : 
    3868       47344 :     void linkJump(JmpSrc from, JmpDst to)
    3869             :     {
    3870       47344 :         MOZ_ASSERT(from.offset() != -1);
    3871       47344 :         MOZ_ASSERT(to.offset() != -1);
    3872             : 
    3873             :         // Sanity check - if the assembler has OOM'd, it will start overwriting
    3874             :         // its internal buffer and thus our links could be garbage.
    3875       47344 :         if (oom())
    3876           0 :             return;
    3877             : 
    3878       47344 :         assertValidJmpSrc(from);
    3879       47344 :         MOZ_RELEASE_ASSERT(size_t(to.offset()) <= size());
    3880             : 
    3881       47344 :         spew(".set .Lfrom%d, .Llabel%d", from.offset(), to.offset());
    3882       47345 :         unsigned char* code = m_formatter.data();
    3883       47345 :         SetRel32(code + from.offset(), code + to.offset());
    3884             :     }
    3885             : 
    3886        4499 :     void executableCopy(void* dst)
    3887             :     {
    3888        4499 :         const unsigned char* src = m_formatter.buffer();
    3889        4499 :         memcpy(dst, src, size());
    3890        4499 :     }
    3891           0 :     MOZ_MUST_USE bool appendBuffer(const BaseAssembler& other)
    3892             :     {
    3893           0 :         const unsigned char* buf = other.m_formatter.buffer();
    3894           0 :         bool ret = m_formatter.append(buf, other.size());
    3895           0 :         return ret;
    3896             :     }
    3897             : 
    3898             :   protected:
    3899      556000 :     static bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(int8_t)value; }
    3900             :     static bool CAN_SIGN_EXTEND_16_32(int32_t value) { return value == (int32_t)(int16_t)value; }
    3901       21077 :     static bool CAN_ZERO_EXTEND_8_32(int32_t value) { return value == (int32_t)(uint8_t)value; }
    3902          12 :     static bool CAN_ZERO_EXTEND_8H_32(int32_t value) { return value == (value & 0xff00); }
    3903        1036 :     static bool CAN_ZERO_EXTEND_16_32(int32_t value) { return value == (int32_t)(uint16_t)value; }
    3904       13390 :     static bool CAN_ZERO_EXTEND_32_64(int32_t value) { return value >= 0; }
    3905             : 
    3906             :     // Methods for encoding SIMD instructions via either legacy SSE encoding or
    3907             :     // VEX encoding.
    3908             : 
    3909      331360 :     bool useLegacySSEEncoding(XMMRegisterID src0, XMMRegisterID dst)
    3910             :     {
    3911             :         // If we don't have AVX or it's disabled, use the legacy SSE encoding.
    3912      331360 :         if (!useVEX_) {
    3913      331360 :             MOZ_ASSERT(src0 == invalid_xmm || src0 == dst,
    3914             :                        "Legacy SSE (pre-AVX) encoding requires the output register to be "
    3915             :                        "the same as the src0 input register");
    3916      331360 :             return true;
    3917             :         }
    3918             : 
    3919             :         // If src0 is the same as the output register, we might as well use
    3920             :         // the legacy SSE encoding, since it is smaller. However, this is only
    3921             :         // beneficial as long as we're not using ymm registers anywhere.
    3922           0 :         return src0 == dst;
    3923             :     }
    3924             : 
    3925           0 :     bool useLegacySSEEncodingForVblendv(XMMRegisterID mask, XMMRegisterID src0, XMMRegisterID dst)
    3926             :     {
    3927             :         // Similar to useLegacySSEEncoding, but for vblendv the Legacy SSE
    3928             :         // encoding also requires the mask to be in xmm0.
    3929             : 
    3930           0 :         if (!useVEX_) {
    3931           0 :             MOZ_ASSERT(src0 == dst,
    3932             :                        "Legacy SSE (pre-AVX) encoding requires the output register to be "
    3933             :                        "the same as the src0 input register");
    3934           0 :             MOZ_ASSERT(mask == xmm0,
    3935             :                        "Legacy SSE (pre-AVX) encoding for blendv requires the mask to be "
    3936             :                        "in xmm0");
    3937           0 :             return true;
    3938             :         }
    3939             : 
    3940           0 :         return src0 == dst && mask == xmm0;
    3941             :     }
    3942             : 
    3943          73 :     bool useLegacySSEEncodingForOtherOutput()
    3944             :     {
    3945          73 :         return !useVEX_;
    3946             :     }
    3947             : 
    3948      331429 :     const char* legacySSEOpName(const char* name)
    3949             :     {
    3950      331429 :         MOZ_ASSERT(name[0] == 'v');
    3951      331429 :         return name + 1;
    3952             :     }
    3953             : 
    3954          60 :     void twoByteOpSimd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    3955             :                        XMMRegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
    3956             :     {
    3957          60 :         if (useLegacySSEEncoding(src0, dst)) {
    3958          60 :             if (IsXMMReversedOperands(opcode))
    3959           0 :                 spew("%-11s%s, %s", legacySSEOpName(name), XMMRegName(dst), XMMRegName(rm));
    3960             :             else
    3961          60 :                 spew("%-11s%s, %s", legacySSEOpName(name), XMMRegName(rm), XMMRegName(dst));
    3962          60 :             m_formatter.legacySSEPrefix(ty);
    3963          60 :             m_formatter.twoByteOp(opcode, (RegisterID)rm, dst);
    3964          60 :             return;
    3965             :         }
    3966             : 
    3967           0 :         if (src0 == invalid_xmm) {
    3968           0 :             if (IsXMMReversedOperands(opcode))
    3969           0 :                 spew("%-11s%s, %s", name, XMMRegName(dst), XMMRegName(rm));
    3970             :             else
    3971           0 :                 spew("%-11s%s, %s", name, XMMRegName(rm), XMMRegName(dst));
    3972             :         } else {
    3973           0 :             spew("%-11s%s, %s, %s", name, XMMRegName(rm), XMMRegName(src0), XMMRegName(dst));
    3974             :         }
    3975           0 :         m_formatter.twoByteOpVex(ty, opcode, (RegisterID)rm, src0, dst);
    3976             :     }
    3977             : 
    3978           0 :     void twoByteOpImmSimd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    3979             :                           uint32_t imm, XMMRegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
    3980             :     {
    3981           0 :         if (useLegacySSEEncoding(src0, dst)) {
    3982           0 :             spew("%-11s$0x%x, %s, %s", legacySSEOpName(name), imm, XMMRegName(rm), XMMRegName(dst));
    3983           0 :             m_formatter.legacySSEPrefix(ty);
    3984           0 :             m_formatter.twoByteOp(opcode, (RegisterID)rm, dst);
    3985           0 :             m_formatter.immediate8u(imm);
    3986           0 :             return;
    3987             :         }
    3988             : 
    3989           0 :         if (src0 == invalid_xmm)
    3990           0 :             spew("%-11s$0x%x, %s, %s", name, imm, XMMRegName(rm), XMMRegName(dst));
    3991             :         else
    3992           0 :             spew("%-11s$0x%x, %s, %s, %s", name, imm, XMMRegName(rm), XMMRegName(src0), XMMRegName(dst));
    3993           0 :         m_formatter.twoByteOpVex(ty, opcode, (RegisterID)rm, src0, dst);
    3994           0 :         m_formatter.immediate8u(imm);
    3995             :     }
    3996             : 
    3997      331189 :     void twoByteOpSimd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    3998             :                        int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    3999             :     {
    4000      331189 :         if (useLegacySSEEncoding(src0, dst)) {
    4001      331190 :             if (IsXMMReversedOperands(opcode)) {
    4002      165680 :                 spew("%-11s%s, " MEM_ob, legacySSEOpName(name),
    4003      165680 :                      XMMRegName(dst), ADDR_ob(offset, base));
    4004             :             } else {
    4005      165558 :                 spew("%-11s" MEM_ob ", %s", legacySSEOpName(name),
    4006      165558 :                      ADDR_ob(offset, base), XMMRegName(dst));
    4007             :             }
    4008      331238 :             m_formatter.legacySSEPrefix(ty);
    4009      331186 :             m_formatter.twoByteOp(opcode, offset, base, dst);
    4010      331174 :             return;
    4011             :         }
    4012             : 
    4013           0 :         if (src0 == invalid_xmm) {
    4014           0 :             if (IsXMMReversedOperands(opcode))
    4015           0 :                 spew("%-11s%s, " MEM_ob, name, XMMRegName(dst), ADDR_ob(offset, base));
    4016             :             else
    4017           0 :                 spew("%-11s" MEM_ob ", %s", name, ADDR_ob(offset, base), XMMRegName(dst));
    4018             :         } else {
    4019           0 :             spew("%-11s" MEM_ob ", %s, %s", name,
    4020           0 :                  ADDR_ob(offset, base), XMMRegName(src0), XMMRegName(dst));
    4021             :         }
    4022           0 :         m_formatter.twoByteOpVex(ty, opcode, offset, base, src0, dst);
    4023             :     }
    4024             : 
    4025             :     void twoByteOpSimd_disp32(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4026             :                               int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    4027             :     {
    4028             :         if (useLegacySSEEncoding(src0, dst)) {
    4029             :             if (IsXMMReversedOperands(opcode))
    4030             :                 spew("%-11s%s, " MEM_o32b, legacySSEOpName(name), XMMRegName(dst), ADDR_o32b(offset, base));
    4031             :             else
    4032             :                 spew("%-11s" MEM_o32b ", %s", legacySSEOpName(name), ADDR_o32b(offset, base), XMMRegName(dst));
    4033             :             m_formatter.legacySSEPrefix(ty);
    4034             :             m_formatter.twoByteOp_disp32(opcode, offset, base, dst);
    4035             :             return;
    4036             :         }
    4037             : 
    4038             :         if (src0 == invalid_xmm) {
    4039             :             if (IsXMMReversedOperands(opcode))
    4040             :                 spew("%-11s%s, " MEM_o32b, name, XMMRegName(dst), ADDR_o32b(offset, base));
    4041             :             else
    4042             :                 spew("%-11s" MEM_o32b ", %s", name, ADDR_o32b(offset, base), XMMRegName(dst));
    4043             :         } else {
    4044             :             spew("%-11s" MEM_o32b ", %s, %s", name,
    4045             :                  ADDR_o32b(offset, base), XMMRegName(src0), XMMRegName(dst));
    4046             :         }
    4047             :         m_formatter.twoByteOpVex_disp32(ty, opcode, offset, base, src0, dst);
    4048             :     }
    4049             : 
    4050           0 :     void twoByteOpImmSimd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4051             :                           uint32_t imm, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    4052             :     {
    4053           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4054           0 :             spew("%-11s$0x%x, " MEM_ob ", %s", legacySSEOpName(name), imm,
    4055           0 :                  ADDR_ob(offset, base), XMMRegName(dst));
    4056           0 :             m_formatter.legacySSEPrefix(ty);
    4057           0 :             m_formatter.twoByteOp(opcode, offset, base, dst);
    4058           0 :             m_formatter.immediate8u(imm);
    4059           0 :             return;
    4060             :         }
    4061             : 
    4062           0 :         spew("%-11s$0x%x, " MEM_ob ", %s, %s", name, imm, ADDR_ob(offset, base),
    4063           0 :              XMMRegName(src0), XMMRegName(dst));
    4064           0 :         m_formatter.twoByteOpVex(ty, opcode, offset, base, src0, dst);
    4065           0 :         m_formatter.immediate8u(imm);
    4066             :     }
    4067             : 
    4068           0 :     void twoByteOpSimd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4069             :                        int32_t offset, RegisterID base, RegisterID index, int scale,
    4070             :                        XMMRegisterID src0, XMMRegisterID dst)
    4071             :     {
    4072           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4073           0 :             if (IsXMMReversedOperands(opcode)) {
    4074           0 :                 spew("%-11s%s, " MEM_obs, legacySSEOpName(name),
    4075           0 :                      XMMRegName(dst), ADDR_obs(offset, base, index, scale));
    4076             :             } else {
    4077           0 :                 spew("%-11s" MEM_obs ", %s", legacySSEOpName(name),
    4078           0 :                      ADDR_obs(offset, base, index, scale), XMMRegName(dst));
    4079             :             }
    4080           0 :             m_formatter.legacySSEPrefix(ty);
    4081           0 :             m_formatter.twoByteOp(opcode, offset, base, index, scale, dst);
    4082           0 :             return;
    4083             :         }
    4084             : 
    4085           0 :         if (src0 == invalid_xmm) {
    4086           0 :             if (IsXMMReversedOperands(opcode)) {
    4087           0 :                 spew("%-11s%s, " MEM_obs, name, XMMRegName(dst),
    4088           0 :                      ADDR_obs(offset, base, index, scale));
    4089             :             } else {
    4090           0 :                 spew("%-11s" MEM_obs ", %s", name, ADDR_obs(offset, base, index, scale),
    4091           0 :                      XMMRegName(dst));
    4092             :             }
    4093             :         } else {
    4094           0 :             spew("%-11s" MEM_obs ", %s, %s", name, ADDR_obs(offset, base, index, scale),
    4095           0 :                  XMMRegName(src0), XMMRegName(dst));
    4096             :         }
    4097           0 :         m_formatter.twoByteOpVex(ty, opcode, offset, base, index, scale, src0, dst);
    4098             :     }
    4099             : 
    4100           0 :     void twoByteOpSimd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4101             :                        const void* address, XMMRegisterID src0, XMMRegisterID dst)
    4102             :     {
    4103           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4104           0 :             if (IsXMMReversedOperands(opcode))
    4105           0 :                 spew("%-11s%s, %p", legacySSEOpName(name), XMMRegName(dst), address);
    4106             :             else
    4107           0 :                 spew("%-11s%p, %s", legacySSEOpName(name), address, XMMRegName(dst));
    4108           0 :             m_formatter.legacySSEPrefix(ty);
    4109           0 :             m_formatter.twoByteOp(opcode, address, dst);
    4110           0 :             return;
    4111             :         }
    4112             : 
    4113           0 :         if (src0 == invalid_xmm) {
    4114           0 :             if (IsXMMReversedOperands(opcode))
    4115           0 :                 spew("%-11s%s, %p", name, XMMRegName(dst), address);
    4116             :             else
    4117           0 :                 spew("%-11s%p, %s", name, address, XMMRegName(dst));
    4118             :         } else {
    4119           0 :             spew("%-11s%p, %s, %s", name, address, XMMRegName(src0), XMMRegName(dst));
    4120             :         }
    4121           0 :         m_formatter.twoByteOpVex(ty, opcode, address, src0, dst);
    4122             :     }
    4123             : 
    4124           0 :     void twoByteOpImmSimd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4125             :                           uint32_t imm, const void* address, XMMRegisterID src0, XMMRegisterID dst)
    4126             :     {
    4127           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4128           0 :             spew("%-11s$0x%x, %p, %s", legacySSEOpName(name), imm, address, XMMRegName(dst));
    4129           0 :             m_formatter.legacySSEPrefix(ty);
    4130           0 :             m_formatter.twoByteOp(opcode, address, dst);
    4131           0 :             m_formatter.immediate8u(imm);
    4132           0 :             return;
    4133             :         }
    4134             : 
    4135           0 :         spew("%-11s$0x%x, %p, %s, %s", name, imm, address, XMMRegName(src0), XMMRegName(dst));
    4136           0 :         m_formatter.twoByteOpVex(ty, opcode, address, src0, dst);
    4137           0 :         m_formatter.immediate8u(imm);
    4138             :     }
    4139             : 
    4140          58 :     void twoByteOpInt32Simd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4141             :                             RegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
    4142             :     {
    4143          58 :         if (useLegacySSEEncoding(src0, dst)) {
    4144          58 :             if (IsXMMReversedOperands(opcode))
    4145           0 :                 spew("%-11s%s, %s", legacySSEOpName(name), XMMRegName(dst), GPReg32Name(rm));
    4146             :             else
    4147          58 :                 spew("%-11s%s, %s", legacySSEOpName(name), GPReg32Name(rm), XMMRegName(dst));
    4148          58 :             m_formatter.legacySSEPrefix(ty);
    4149          58 :             m_formatter.twoByteOp(opcode, rm, dst);
    4150          58 :             return;
    4151             :         }
    4152             : 
    4153           0 :         if (src0 == invalid_xmm) {
    4154           0 :             if (IsXMMReversedOperands(opcode))
    4155           0 :                 spew("%-11s%s, %s", name, XMMRegName(dst), GPReg32Name(rm));
    4156             :             else
    4157           0 :                 spew("%-11s%s, %s", name, GPReg32Name(rm), XMMRegName(dst));
    4158             :         } else {
    4159           0 :             spew("%-11s%s, %s, %s", name, GPReg32Name(rm), XMMRegName(src0), XMMRegName(dst));
    4160             :         }
    4161           0 :         m_formatter.twoByteOpVex(ty, opcode, rm, src0, dst);
    4162             :     }
    4163             : 
    4164          26 :     void twoByteOpSimdInt32(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4165             :                             XMMRegisterID rm, RegisterID dst)
    4166             :     {
    4167          26 :         if (useLegacySSEEncodingForOtherOutput()) {
    4168          26 :             if (IsXMMReversedOperands(opcode))
    4169           0 :                 spew("%-11s%s, %s", legacySSEOpName(name), GPReg32Name(dst), XMMRegName(rm));
    4170          26 :             else if (opcode == OP2_MOVD_EdVd)
    4171           0 :                 spew("%-11s%s, %s", legacySSEOpName(name), XMMRegName((XMMRegisterID)dst), GPReg32Name((RegisterID)rm));
    4172             :             else
    4173          26 :                 spew("%-11s%s, %s", legacySSEOpName(name), XMMRegName(rm), GPReg32Name(dst));
    4174          26 :             m_formatter.legacySSEPrefix(ty);
    4175          26 :             m_formatter.twoByteOp(opcode, (RegisterID)rm, dst);
    4176          26 :             return;
    4177             :         }
    4178             : 
    4179           0 :         if (IsXMMReversedOperands(opcode))
    4180           0 :             spew("%-11s%s, %s", name, GPReg32Name(dst), XMMRegName(rm));
    4181           0 :         else if (opcode == OP2_MOVD_EdVd)
    4182           0 :             spew("%-11s%s, %s", name, XMMRegName((XMMRegisterID)dst), GPReg32Name((RegisterID)rm));
    4183             :         else
    4184           0 :             spew("%-11s%s, %s", name, XMMRegName(rm), GPReg32Name(dst));
    4185           0 :         m_formatter.twoByteOpVex(ty, opcode, (RegisterID)rm, invalid_xmm, dst);
    4186             :     }
    4187             : 
    4188           0 :     void twoByteOpImmSimdInt32(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4189             :                                uint32_t imm, XMMRegisterID rm, RegisterID dst)
    4190             :     {
    4191           0 :         if (useLegacySSEEncodingForOtherOutput()) {
    4192           0 :             spew("%-11s$0x%x, %s, %s", legacySSEOpName(name), imm, XMMRegName(rm), GPReg32Name(dst));
    4193           0 :             m_formatter.legacySSEPrefix(ty);
    4194           0 :             m_formatter.twoByteOp(opcode, (RegisterID)rm, dst);
    4195           0 :             m_formatter.immediate8u(imm);
    4196           0 :             return;
    4197             :         }
    4198             : 
    4199           0 :         spew("%-11s$0x%x, %s, %s", name, imm, XMMRegName(rm), GPReg32Name(dst));
    4200           0 :         m_formatter.twoByteOpVex(ty, opcode, (RegisterID)rm, invalid_xmm, dst);
    4201           0 :         m_formatter.immediate8u(imm);
    4202             :     }
    4203             : 
    4204           0 :     void twoByteOpImmInt32Simd(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4205             :                                uint32_t imm, RegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
    4206             :     {
    4207           0 :         if (useLegacySSEEncodingForOtherOutput()) {
    4208           0 :             spew("%-11s$0x%x, %s, %s", legacySSEOpName(name), imm, GPReg32Name(rm), XMMRegName(dst));
    4209           0 :             m_formatter.legacySSEPrefix(ty);
    4210           0 :             m_formatter.twoByteOp(opcode, rm, dst);
    4211           0 :             m_formatter.immediate8u(imm);
    4212           0 :             return;
    4213             :         }
    4214             : 
    4215           0 :         spew("%-11s$0x%x, %s, %s", name, imm, GPReg32Name(rm), XMMRegName(dst));
    4216           0 :         m_formatter.twoByteOpVex(ty, opcode, rm, src0, dst);
    4217           0 :         m_formatter.immediate8u(imm);
    4218             :     }
    4219             : 
    4220          38 :     void twoByteOpSimdFlags(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4221             :                             XMMRegisterID rm, XMMRegisterID reg)
    4222             :     {
    4223          38 :         if (useLegacySSEEncodingForOtherOutput()) {
    4224          38 :             spew("%-11s%s, %s", legacySSEOpName(name), XMMRegName(rm), XMMRegName(reg));
    4225          38 :             m_formatter.legacySSEPrefix(ty);
    4226          38 :             m_formatter.twoByteOp(opcode, (RegisterID)rm, reg);
    4227          38 :             return;
    4228             :         }
    4229             : 
    4230           0 :         spew("%-11s%s, %s", name, XMMRegName(rm), XMMRegName(reg));
    4231           0 :         m_formatter.twoByteOpVex(ty, opcode, (RegisterID)rm, invalid_xmm, (XMMRegisterID)reg);
    4232             :     }
    4233             : 
    4234             :     void twoByteOpSimdFlags(const char* name, VexOperandType ty, TwoByteOpcodeID opcode,
    4235             :                             int32_t offset, RegisterID base, XMMRegisterID reg)
    4236             :     {
    4237             :         if (useLegacySSEEncodingForOtherOutput()) {
    4238             :             spew("%-11s" MEM_ob ", %s", legacySSEOpName(name),
    4239             :                  ADDR_ob(offset, base), XMMRegName(reg));
    4240             :             m_formatter.legacySSEPrefix(ty);
    4241             :             m_formatter.twoByteOp(opcode, offset, base, reg);
    4242             :             return;
    4243             :         }
    4244             : 
    4245             :         spew("%-11s" MEM_ob ", %s", name,
    4246             :              ADDR_ob(offset, base), XMMRegName(reg));
    4247             :         m_formatter.twoByteOpVex(ty, opcode, offset, base, invalid_xmm, (XMMRegisterID)reg);
    4248             :     }
    4249             : 
    4250           0 :     void threeByteOpSimd(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4251             :                          ThreeByteEscape escape,
    4252             :                          XMMRegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
    4253             :     {
    4254           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4255           0 :             spew("%-11s%s, %s", legacySSEOpName(name), XMMRegName(rm), XMMRegName(dst));
    4256           0 :             m_formatter.legacySSEPrefix(ty);
    4257           0 :             m_formatter.threeByteOp(opcode, escape, (RegisterID)rm, dst);
    4258           0 :             return;
    4259             :         }
    4260             : 
    4261           0 :         spew("%-11s%s, %s, %s", name, XMMRegName(rm), XMMRegName(src0), XMMRegName(dst));
    4262           0 :         m_formatter.threeByteOpVex(ty, opcode, escape, (RegisterID)rm, src0, dst);
    4263             :     }
    4264             : 
    4265           0 :     void threeByteOpImmSimd(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4266             :                             ThreeByteEscape escape,
    4267             :                             uint32_t imm, XMMRegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
    4268             :     {
    4269           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4270           0 :             spew("%-11s$0x%x, %s, %s", legacySSEOpName(name), imm, XMMRegName(rm), XMMRegName(dst));
    4271           0 :             m_formatter.legacySSEPrefix(ty);
    4272           0 :             m_formatter.threeByteOp(opcode, escape, (RegisterID)rm, dst);
    4273           0 :             m_formatter.immediate8u(imm);
    4274           0 :             return;
    4275             :         }
    4276             : 
    4277           0 :         spew("%-11s$0x%x, %s, %s, %s", name, imm, XMMRegName(rm), XMMRegName(src0), XMMRegName(dst));
    4278           0 :         m_formatter.threeByteOpVex(ty, opcode, escape, (RegisterID)rm, src0, dst);
    4279           0 :         m_formatter.immediate8u(imm);
    4280             :     }
    4281             : 
    4282           0 :     void threeByteOpSimd(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4283             :                          ThreeByteEscape escape,
    4284             :                          int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    4285             :     {
    4286           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4287           0 :             spew("%-11s" MEM_ob ", %s", legacySSEOpName(name),
    4288           0 :                  ADDR_ob(offset, base), XMMRegName(dst));
    4289           0 :             m_formatter.legacySSEPrefix(ty);
    4290           0 :             m_formatter.threeByteOp(opcode, escape, offset, base, dst);
    4291           0 :             return;
    4292             :         }
    4293             : 
    4294           0 :         spew("%-11s" MEM_ob ", %s, %s", name,
    4295           0 :              ADDR_ob(offset, base), XMMRegName(src0), XMMRegName(dst));
    4296           0 :         m_formatter.threeByteOpVex(ty, opcode, escape, offset, base, src0, dst);
    4297             :     }
    4298             : 
    4299           0 :     void threeByteOpImmSimd(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4300             :                             ThreeByteEscape escape,
    4301             :                             uint32_t imm, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    4302             :     {
    4303           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4304           0 :             spew("%-11s$0x%x, " MEM_ob ", %s", legacySSEOpName(name), imm,
    4305           0 :                  ADDR_ob(offset, base), XMMRegName(dst));
    4306           0 :             m_formatter.legacySSEPrefix(ty);
    4307           0 :             m_formatter.threeByteOp(opcode, escape, offset, base, dst);
    4308           0 :             m_formatter.immediate8u(imm);
    4309           0 :             return;
    4310             :         }
    4311             : 
    4312           0 :         spew("%-11s$0x%x, " MEM_ob ", %s, %s", name, imm, ADDR_ob(offset, base),
    4313           0 :              XMMRegName(src0), XMMRegName(dst));
    4314           0 :         m_formatter.threeByteOpVex(ty, opcode, escape, offset, base, src0, dst);
    4315           0 :         m_formatter.immediate8u(imm);
    4316             :     }
    4317             : 
    4318           0 :     void threeByteOpSimd(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4319             :                          ThreeByteEscape escape,
    4320             :                          const void* address, XMMRegisterID src0, XMMRegisterID dst)
    4321             :     {
    4322           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4323           0 :             spew("%-11s%p, %s", legacySSEOpName(name), address, XMMRegName(dst));
    4324           0 :             m_formatter.legacySSEPrefix(ty);
    4325           0 :             m_formatter.threeByteOp(opcode, escape, address, dst);
    4326           0 :             return;
    4327             :         }
    4328             : 
    4329           0 :         spew("%-11s%p, %s, %s", name, address, XMMRegName(src0), XMMRegName(dst));
    4330           0 :         m_formatter.threeByteOpVex(ty, opcode, escape, address, src0, dst);
    4331             :     }
    4332             : 
    4333           0 :     void threeByteOpImmInt32Simd(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4334             :                                  ThreeByteEscape escape, uint32_t imm,
    4335             :                                  RegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
    4336             :     {
    4337           0 :         if (useLegacySSEEncoding(src0, dst)) {
    4338           0 :             spew("%-11s$0x%x, %s, %s", legacySSEOpName(name), imm, GPReg32Name(src1), XMMRegName(dst));
    4339           0 :             m_formatter.legacySSEPrefix(ty);
    4340           0 :             m_formatter.threeByteOp(opcode, escape, src1, dst);
    4341           0 :             m_formatter.immediate8u(imm);
    4342           0 :             return;
    4343             :         }
    4344             : 
    4345           0 :         spew("%-11s$0x%x, %s, %s, %s", name, imm, GPReg32Name(src1), XMMRegName(src0), XMMRegName(dst));
    4346           0 :         m_formatter.threeByteOpVex(ty, opcode, escape, src1, src0, dst);
    4347           0 :         m_formatter.immediate8u(imm);
    4348             :     }
    4349             : 
    4350             :     void threeByteOpImmInt32Simd(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4351             :                                  ThreeByteEscape escape, uint32_t imm,
    4352             :                                  int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    4353             :     {
    4354             :         if (useLegacySSEEncoding(src0, dst)) {
    4355             :             spew("%-11s$0x%x, " MEM_ob ", %s", legacySSEOpName(name), imm, ADDR_ob(offset, base), XMMRegName(dst));
    4356             :             m_formatter.legacySSEPrefix(ty);
    4357             :             m_formatter.threeByteOp(opcode, escape, offset, base, dst);
    4358             :             m_formatter.immediate8u(imm);
    4359             :             return;
    4360             :         }
    4361             : 
    4362             :         spew("%-11s$0x%x, " MEM_ob ", %s, %s", name, imm, ADDR_ob(offset, base), XMMRegName(src0), XMMRegName(dst));
    4363             :         m_formatter.threeByteOpVex(ty, opcode, escape, offset, base, src0, dst);
    4364             :         m_formatter.immediate8u(imm);
    4365             :     }
    4366             : 
    4367           0 :     void threeByteOpImmSimdInt32(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4368             :                                  ThreeByteEscape escape, uint32_t imm,
    4369             :                                  XMMRegisterID src, RegisterID dst)
    4370             :     {
    4371           0 :         if (useLegacySSEEncodingForOtherOutput()) {
    4372           0 :             spew("%-11s$0x%x, %s, %s", legacySSEOpName(name), imm, XMMRegName(src), GPReg32Name(dst));
    4373           0 :             m_formatter.legacySSEPrefix(ty);
    4374           0 :             m_formatter.threeByteOp(opcode, escape, (RegisterID)src, dst);
    4375           0 :             m_formatter.immediate8u(imm);
    4376           0 :             return;
    4377             :         }
    4378             : 
    4379           0 :         if (opcode == OP3_PEXTRD_EdVdqIb)
    4380           0 :             spew("%-11s$0x%x, %s, %s", name, imm, XMMRegName((XMMRegisterID)dst), GPReg32Name((RegisterID)src));
    4381             :         else
    4382           0 :             spew("%-11s$0x%x, %s, %s", name, imm, XMMRegName(src), GPReg32Name(dst));
    4383           0 :         m_formatter.threeByteOpVex(ty, opcode, escape, (RegisterID)src, invalid_xmm, dst);
    4384           0 :         m_formatter.immediate8u(imm);
    4385             :     }
    4386             : 
    4387             :     void threeByteOpImmSimdInt32(const char* name, VexOperandType ty, ThreeByteOpcodeID opcode,
    4388             :                                  ThreeByteEscape escape, uint32_t imm,
    4389             :                                  int32_t offset, RegisterID base, RegisterID dst)
    4390             :     {
    4391             :         if (useLegacySSEEncodingForOtherOutput()) {
    4392             :             spew("%-11s$0x%x, " MEM_ob ", %s", legacySSEOpName(name), imm, ADDR_ob(offset, base), GPReg32Name(dst));
    4393             :             m_formatter.legacySSEPrefix(ty);
    4394             :             m_formatter.threeByteOp(opcode, escape, offset, base, dst);
    4395             :             m_formatter.immediate8u(imm);
    4396             :             return;
    4397             :         }
    4398             : 
    4399             :         spew("%-11s$0x%x, " MEM_ob ", %s", name, imm, ADDR_ob(offset, base), GPReg32Name(dst));
    4400             :         m_formatter.threeByteOpVex(ty, opcode, escape, offset, base, invalid_xmm, dst);
    4401             :         m_formatter.immediate8u(imm);
    4402             :     }
    4403             : 
    4404             :     // Blendv is a three-byte op, but the VEX encoding has a different opcode
    4405             :     // than the SSE encoding, so we handle it specially.
    4406           0 :     void vblendvOpSimd(XMMRegisterID mask, XMMRegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
    4407             :     {
    4408           0 :         if (useLegacySSEEncodingForVblendv(mask, src0, dst)) {
    4409           0 :             spew("blendvps   %s, %s", XMMRegName(rm), XMMRegName(dst));
    4410             :             // Even though a "ps" instruction, vblendv is encoded with the "pd" prefix.
    4411           0 :             m_formatter.legacySSEPrefix(VEX_PD);
    4412           0 :             m_formatter.threeByteOp(OP3_BLENDVPS_VdqWdq, ESCAPE_3A, (RegisterID)rm, dst);
    4413           0 :             return;
    4414             :         }
    4415             : 
    4416           0 :         spew("vblendvps  %s, %s, %s, %s",
    4417           0 :              XMMRegName(mask), XMMRegName(rm), XMMRegName(src0), XMMRegName(dst));
    4418             :         // Even though a "ps" instruction, vblendv is encoded with the "pd" prefix.
    4419           0 :         m_formatter.vblendvOpVex(VEX_PD, OP3_VBLENDVPS_VdqWdq, ESCAPE_3A,
    4420           0 :                                  mask, (RegisterID)rm, src0, dst);
    4421             :     }
    4422             : 
    4423             :     void vblendvOpSimd(XMMRegisterID mask, int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
    4424             :     {
    4425             :         if (useLegacySSEEncodingForVblendv(mask, src0, dst)) {
    4426             :             spew("blendvps   " MEM_ob ", %s", ADDR_ob(offset, base), XMMRegName(dst));
    4427             :             // Even though a "ps" instruction, vblendv is encoded with the "pd" prefix.
    4428             :             m_formatter.legacySSEPrefix(VEX_PD);
    4429             :             m_formatter.threeByteOp(OP3_BLENDVPS_VdqWdq, ESCAPE_3A, offset, base, dst);
    4430             :             return;
    4431             :         }
    4432             : 
    4433             :         spew("vblendvps  %s, " MEM_ob ", %s, %s",
    4434             :              XMMRegName(mask), ADDR_ob(offset, base), XMMRegName(src0), XMMRegName(dst));
    4435             :         // Even though a "ps" instruction, vblendv is encoded with the "pd" prefix.
    4436             :         m_formatter.vblendvOpVex(VEX_PD, OP3_VBLENDVPS_VdqWdq, ESCAPE_3A,
    4437             :                                  mask, offset, base, src0, dst);
    4438             :     }
    4439             : 
    4440           0 :     void shiftOpImmSimd(const char* name, TwoByteOpcodeID opcode, ShiftID shiftKind,
    4441             :                         uint32_t imm, XMMRegisterID src, XMMRegisterID dst)
    4442             :     {
    4443           0 :         if (useLegacySSEEncoding(src, dst)) {
    4444           0 :             spew("%-11s$%d, %s", legacySSEOpName(name), imm, XMMRegName(dst));
    4445           0 :             m_formatter.legacySSEPrefix(VEX_PD);
    4446           0 :             m_formatter.twoByteOp(opcode, (RegisterID)dst, (int)shiftKind);
    4447           0 :             m_formatter.immediate8u(imm);
    4448           0 :             return;
    4449             :         }
    4450             : 
    4451           0 :         spew("%-11s$%d, %s, %s", name, imm, XMMRegName(src), XMMRegName(dst));
    4452           0 :         m_formatter.twoByteOpVex(VEX_PD, opcode, (RegisterID)dst, src, (int)shiftKind);
    4453           0 :         m_formatter.immediate8u(imm);
    4454             :     }
    4455             : 
    4456        9006 :     class X86InstructionFormatter {
    4457             : 
    4458             :     public:
    4459             :         // Legacy prefix bytes:
    4460             :         //
    4461             :         // These are emmitted prior to the instruction.
    4462             : 
    4463         306 :         void prefix(OneByteOpcodeID pre)
    4464             :         {
    4465         306 :             m_buffer.putByte(pre);
    4466         306 :         }
    4467             : 
    4468      331428 :         void legacySSEPrefix(VexOperandType ty)
    4469             :         {
    4470      331428 :             switch (ty) {
    4471      331162 :               case VEX_PS: break;
    4472         158 :               case VEX_PD: prefix(PRE_SSE_66); break;
    4473           0 :               case VEX_SS: prefix(PRE_SSE_F3); break;
    4474         108 :               case VEX_SD: prefix(PRE_SSE_F2); break;
    4475             :             }
    4476      331428 :         }
    4477             : 
    4478             :         // Word-sized operands / no operand instruction formatters.
    4479             :         //
    4480             :         // In addition to the opcode, the following operand permutations are supported:
    4481             :         //   * None - instruction takes no operands.
    4482             :         //   * One register - the low three bits of the RegisterID are added into the opcode.
    4483             :         //   * Two registers - encode a register form ModRm (for all ModRm formats, the reg field is passed first, and a GroupOpcodeID may be passed in its place).
    4484             :         //   * Three argument ModRM - a register, and a register and an offset describing a memory operand.
    4485             :         //   * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
    4486             :         //
    4487             :         // For 32-bit x86 targets, the address operand may also be provided as a
    4488             :         // void*.  On 64-bit targets REX prefixes will be planted as necessary,
    4489             :         // where high numbered registers are used.
    4490             :         //
    4491             :         // The twoByteOp methods plant two-byte Intel instructions sequences
    4492             :         // (first opcode byte 0x0F).
    4493             : 
    4494       83106 :         void oneByteOp(OneByteOpcodeID opcode)
    4495             :         {
    4496       83106 :             m_buffer.ensureSpace(MaxInstructionSize);
    4497       83106 :             m_buffer.putByteUnchecked(opcode);
    4498       83106 :         }
    4499             : 
    4500      266679 :         void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
    4501             :         {
    4502      266679 :             m_buffer.ensureSpace(MaxInstructionSize);
    4503      266683 :             emitRexIfNeeded(0, 0, reg);
    4504      266680 :             m_buffer.putByteUnchecked(opcode + (reg & 7));
    4505      266682 :         }
    4506             : 
    4507       15772 :         void oneByteOp(OneByteOpcodeID opcode, RegisterID rm, int reg)
    4508             :         {
    4509       15772 :             m_buffer.ensureSpace(MaxInstructionSize);
    4510       15772 :             emitRexIfNeeded(reg, 0, rm);
    4511       15772 :             m_buffer.putByteUnchecked(opcode);
    4512       15772 :             registerModRM(rm, reg);
    4513       15772 :         }
    4514             : 
    4515       44931 :         void oneByteOp(OneByteOpcodeID opcode, int32_t offset, RegisterID base, int reg)
    4516             :         {
    4517       44931 :             m_buffer.ensureSpace(MaxInstructionSize);
    4518       44931 :             emitRexIfNeeded(reg, 0, base);
    4519       44931 :             m_buffer.putByteUnchecked(opcode);
    4520       44931 :             memoryModRM(offset, base, reg);
    4521       44931 :         }
    4522             : 
    4523             :         void oneByteOp_disp32(OneByteOpcodeID opcode, int32_t offset, RegisterID base, int reg)
    4524             :         {
    4525             :             m_buffer.ensureSpace(MaxInstructionSize);
    4526             :             emitRexIfNeeded(reg, 0, base);
    4527             :             m_buffer.putByteUnchecked(opcode);
    4528             :             memoryModRM_disp32(offset, base, reg);
    4529             :         }
    4530             : 
    4531          51 :         void oneByteOp(OneByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID index, int scale, int reg)
    4532             :         {
    4533          51 :             m_buffer.ensureSpace(MaxInstructionSize);
    4534          51 :             emitRexIfNeeded(reg, index, base);
    4535          51 :             m_buffer.putByteUnchecked(opcode);
    4536          51 :             memoryModRM(offset, base, index, scale, reg);
    4537          51 :         }
    4538             : 
    4539             :         void oneByteOp_disp32(OneByteOpcodeID opcode, int32_t offset, RegisterID index, int scale, int reg)
    4540             :         {
    4541             :             m_buffer.ensureSpace(MaxInstructionSize);
    4542             :             emitRexIfNeeded(reg, index, 0);
    4543             :             m_buffer.putByteUnchecked(opcode);
    4544             :             memoryModRM_disp32(offset, index, scale, reg);
    4545             :         }
    4546             : 
    4547           0 :         void oneByteOp(OneByteOpcodeID opcode, const void* address, int reg)
    4548             :         {
    4549           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4550           0 :             emitRexIfNeeded(reg, 0, 0);
    4551           0 :             m_buffer.putByteUnchecked(opcode);
    4552           0 :             memoryModRM_disp32(address, reg);
    4553           0 :         }
    4554             : 
    4555             :         void oneByteOp_disp32(OneByteOpcodeID opcode, const void* address, int reg)
    4556             :         {
    4557             :             m_buffer.ensureSpace(MaxInstructionSize);
    4558             :             emitRexIfNeeded(reg, 0, 0);
    4559             :             m_buffer.putByteUnchecked(opcode);
    4560             :             memoryModRM_disp32(address, reg);
    4561             :         }
    4562             : #ifdef JS_CODEGEN_X64
    4563       19127 :         void oneByteRipOp(OneByteOpcodeID opcode, int ripOffset, int reg)
    4564             :         {
    4565       19127 :             m_buffer.ensureSpace(MaxInstructionSize);
    4566       19127 :             emitRexIfNeeded(reg, 0, 0);
    4567       19127 :             m_buffer.putByteUnchecked(opcode);
    4568       19127 :             putModRm(ModRmMemoryNoDisp, noBase, reg);
    4569       19127 :             m_buffer.putIntUnchecked(ripOffset);
    4570       19127 :         }
    4571             : 
    4572             :         void oneByteRipOp64(OneByteOpcodeID opcode, int ripOffset, int reg)
    4573             :         {
    4574             :             m_buffer.ensureSpace(MaxInstructionSize);
    4575             :             emitRexW(reg, 0, 0);
    4576             :             m_buffer.putByteUnchecked(opcode);
    4577             :             putModRm(ModRmMemoryNoDisp, noBase, reg);
    4578             :             m_buffer.putIntUnchecked(ripOffset);
    4579             :         }
    4580             : 
    4581           0 :         void twoByteRipOp(TwoByteOpcodeID opcode, int ripOffset, int reg)
    4582             :         {
    4583           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4584           0 :             emitRexIfNeeded(reg, 0, 0);
    4585           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4586           0 :             m_buffer.putByteUnchecked(opcode);
    4587           0 :             putModRm(ModRmMemoryNoDisp, noBase, reg);
    4588           0 :             m_buffer.putIntUnchecked(ripOffset);
    4589           0 :         }
    4590             : 
    4591           0 :         void twoByteRipOpVex(VexOperandType ty, TwoByteOpcodeID opcode, int ripOffset,
    4592             :                              XMMRegisterID src0, XMMRegisterID reg)
    4593             :         {
    4594           0 :             int r = (reg >> 3), x = 0, b = 0;
    4595           0 :             int m = 1; // 0x0F
    4596           0 :             int w = 0, v = src0, l = 0;
    4597           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4598           0 :             putModRm(ModRmMemoryNoDisp, noBase, reg);
    4599           0 :             m_buffer.putIntUnchecked(ripOffset);
    4600           0 :         }
    4601             : #endif
    4602             : 
    4603       59786 :         void twoByteOp(TwoByteOpcodeID opcode)
    4604             :         {
    4605       59786 :             m_buffer.ensureSpace(MaxInstructionSize);
    4606       59785 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4607       59785 :             m_buffer.putByteUnchecked(opcode);
    4608       59785 :         }
    4609             : 
    4610         182 :         void twoByteOp(TwoByteOpcodeID opcode, RegisterID rm, int reg)
    4611             :         {
    4612         182 :             m_buffer.ensureSpace(MaxInstructionSize);
    4613         182 :             emitRexIfNeeded(reg, 0, rm);
    4614         182 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4615         182 :             m_buffer.putByteUnchecked(opcode);
    4616         182 :             registerModRM(rm, reg);
    4617         182 :         }
    4618             : 
    4619           0 :         void twoByteOpVex(VexOperandType ty, TwoByteOpcodeID opcode,
    4620             :                           RegisterID rm, XMMRegisterID src0, int reg)
    4621             :         {
    4622           0 :             int r = (reg >> 3), x = 0, b = (rm >> 3);
    4623           0 :             int m = 1; // 0x0F
    4624           0 :             int w = 0, v = src0, l = 0;
    4625           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4626           0 :             registerModRM(rm, reg);
    4627           0 :         }
    4628             : 
    4629      331440 :         void twoByteOp(TwoByteOpcodeID opcode, int32_t offset, RegisterID base, int reg)
    4630             :         {
    4631      331440 :             m_buffer.ensureSpace(MaxInstructionSize);
    4632      331452 :             emitRexIfNeeded(reg, 0, base);
    4633      331453 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4634      331470 :             m_buffer.putByteUnchecked(opcode);
    4635      331465 :             memoryModRM(offset, base, reg);
    4636      331428 :         }
    4637             : 
    4638           0 :         void twoByteOpVex(VexOperandType ty, TwoByteOpcodeID opcode,
    4639             :                           int32_t offset, RegisterID base, XMMRegisterID src0, int reg)
    4640             :         {
    4641           0 :             int r = (reg >> 3), x = 0, b = (base >> 3);
    4642           0 :             int m = 1; // 0x0F
    4643           0 :             int w = 0, v = src0, l = 0;
    4644           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4645           0 :             memoryModRM(offset, base, reg);
    4646           0 :         }
    4647             : 
    4648             :         void twoByteOp_disp32(TwoByteOpcodeID opcode, int32_t offset, RegisterID base, int reg)
    4649             :         {
    4650             :             m_buffer.ensureSpace(MaxInstructionSize);
    4651             :             emitRexIfNeeded(reg, 0, base);
    4652             :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4653             :             m_buffer.putByteUnchecked(opcode);
    4654             :             memoryModRM_disp32(offset, base, reg);
    4655             :         }
    4656             : 
    4657             :         void twoByteOpVex_disp32(VexOperandType ty, TwoByteOpcodeID opcode,
    4658             :                                  int32_t offset, RegisterID base, XMMRegisterID src0, int reg)
    4659             :         {
    4660             :             int r = (reg >> 3), x = 0, b = (base >> 3);
    4661             :             int m = 1; // 0x0F
    4662             :             int w = 0, v = src0, l = 0;
    4663             :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4664             :             memoryModRM_disp32(offset, base, reg);
    4665             :         }
    4666             : 
    4667         605 :         void twoByteOp(TwoByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID index, int scale, int reg)
    4668             :         {
    4669         605 :             m_buffer.ensureSpace(MaxInstructionSize);
    4670         605 :             emitRexIfNeeded(reg, index, base);
    4671         605 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4672         605 :             m_buffer.putByteUnchecked(opcode);
    4673         605 :             memoryModRM(offset, base, index, scale, reg);
    4674         605 :         }
    4675             : 
    4676           0 :         void twoByteOpVex(VexOperandType ty, TwoByteOpcodeID opcode,
    4677             :                           int32_t offset, RegisterID base, RegisterID index, int scale,
    4678             :                           XMMRegisterID src0, int reg)
    4679             :         {
    4680           0 :             int r = (reg >> 3), x = (index >> 3), b = (base >> 3);
    4681           0 :             int m = 1; // 0x0F
    4682           0 :             int w = 0, v = src0, l = 0;
    4683           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4684           0 :             memoryModRM(offset, base, index, scale, reg);
    4685           0 :         }
    4686             : 
    4687           0 :         void twoByteOp(TwoByteOpcodeID opcode, const void* address, int reg)
    4688             :         {
    4689           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4690           0 :             emitRexIfNeeded(reg, 0, 0);
    4691           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4692           0 :             m_buffer.putByteUnchecked(opcode);
    4693           0 :             memoryModRM(address, reg);
    4694           0 :         }
    4695             : 
    4696           0 :         void twoByteOpVex(VexOperandType ty, TwoByteOpcodeID opcode,
    4697             :                           const void* address, XMMRegisterID src0, int reg)
    4698             :         {
    4699           0 :             int r = (reg >> 3), x = 0, b = 0;
    4700           0 :             int m = 1; // 0x0F
    4701           0 :             int w = 0, v = src0, l = 0;
    4702           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4703           0 :             memoryModRM(address, reg);
    4704           0 :         }
    4705             : 
    4706           0 :         void threeByteOp(ThreeByteOpcodeID opcode, ThreeByteEscape escape, RegisterID rm, int reg)
    4707             :         {
    4708           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4709           0 :             emitRexIfNeeded(reg, 0, rm);
    4710           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4711           0 :             m_buffer.putByteUnchecked(escape);
    4712           0 :             m_buffer.putByteUnchecked(opcode);
    4713           0 :             registerModRM(rm, reg);
    4714           0 :         }
    4715             : 
    4716           0 :         void threeByteOpVex(VexOperandType ty, ThreeByteOpcodeID opcode, ThreeByteEscape escape,
    4717             :                             RegisterID rm, XMMRegisterID src0, int reg)
    4718             :         {
    4719           0 :             int r = (reg >> 3), x = 0, b = (rm >> 3);
    4720           0 :             int m = 0, w = 0, v = src0, l = 0;
    4721           0 :             switch (escape) {
    4722           0 :               case ESCAPE_38: m = 2; break;
    4723           0 :               case ESCAPE_3A: m = 3; break;
    4724           0 :               default: MOZ_CRASH("unexpected escape");
    4725             :             }
    4726           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4727           0 :             registerModRM(rm, reg);
    4728           0 :         }
    4729             : 
    4730           0 :         void threeByteOp(ThreeByteOpcodeID opcode, ThreeByteEscape escape, int32_t offset, RegisterID base, int reg)
    4731             :         {
    4732           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4733           0 :             emitRexIfNeeded(reg, 0, base);
    4734           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4735           0 :             m_buffer.putByteUnchecked(escape);
    4736           0 :             m_buffer.putByteUnchecked(opcode);
    4737           0 :             memoryModRM(offset, base, reg);
    4738           0 :         }
    4739             : 
    4740           0 :         void threeByteOpVex(VexOperandType ty, ThreeByteOpcodeID opcode, ThreeByteEscape escape,
    4741             :                             int32_t offset, RegisterID base, XMMRegisterID src0, int reg)
    4742             :         {
    4743           0 :             int r = (reg >> 3), x = 0, b = (base >> 3);
    4744           0 :             int m = 0, w = 0, v = src0, l = 0;
    4745           0 :             switch (escape) {
    4746           0 :               case ESCAPE_38: m = 2; break;
    4747           0 :               case ESCAPE_3A: m = 3; break;
    4748           0 :               default: MOZ_CRASH("unexpected escape");
    4749             :             }
    4750           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4751           0 :             memoryModRM(offset, base, reg);
    4752           0 :         }
    4753             : 
    4754           0 :         void threeByteOp(ThreeByteOpcodeID opcode, ThreeByteEscape escape, const void* address, int reg)
    4755             :         {
    4756           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4757           0 :             emitRexIfNeeded(reg, 0, 0);
    4758           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4759           0 :             m_buffer.putByteUnchecked(escape);
    4760           0 :             m_buffer.putByteUnchecked(opcode);
    4761           0 :             memoryModRM(address, reg);
    4762           0 :         }
    4763             : 
    4764           0 :         void threeByteOpVex(VexOperandType ty, ThreeByteOpcodeID opcode, ThreeByteEscape escape,
    4765             :                             const void* address, XMMRegisterID src0, int reg)
    4766             :         {
    4767           0 :             int r = (reg >> 3), x = 0, b = 0;
    4768           0 :             int m = 0, w = 0, v = src0, l = 0;
    4769           0 :             switch (escape) {
    4770           0 :               case ESCAPE_38: m = 2; break;
    4771           0 :               case ESCAPE_3A: m = 3; break;
    4772           0 :               default: MOZ_CRASH("unexpected escape");
    4773             :             }
    4774           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4775           0 :             memoryModRM(address, reg);
    4776           0 :         }
    4777             : 
    4778           0 :         void vblendvOpVex(VexOperandType ty, ThreeByteOpcodeID opcode, ThreeByteEscape escape,
    4779             :                           XMMRegisterID mask, RegisterID rm, XMMRegisterID src0, int reg)
    4780             :         {
    4781           0 :             int r = (reg >> 3), x = 0, b = (rm >> 3);
    4782           0 :             int m = 0, w = 0, v = src0, l = 0;
    4783           0 :             switch (escape) {
    4784           0 :               case ESCAPE_38: m = 2; break;
    4785           0 :               case ESCAPE_3A: m = 3; break;
    4786           0 :               default: MOZ_CRASH("unexpected escape");
    4787             :             }
    4788           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4789           0 :             registerModRM(rm, reg);
    4790           0 :             immediate8u(mask << 4);
    4791           0 :         }
    4792             : 
    4793             :         void vblendvOpVex(VexOperandType ty, ThreeByteOpcodeID opcode, ThreeByteEscape escape,
    4794             :                           XMMRegisterID mask, int32_t offset, RegisterID base, XMMRegisterID src0, int reg)
    4795             :         {
    4796             :             int r = (reg >> 3), x = 0, b = (base >> 3);
    4797             :             int m = 0, w = 0, v = src0, l = 0;
    4798             :             switch (escape) {
    4799             :               case ESCAPE_38: m = 2; break;
    4800             :               case ESCAPE_3A: m = 3; break;
    4801             :               default: MOZ_CRASH("unexpected escape");
    4802             :             }
    4803             :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4804             :             memoryModRM(offset, base, reg);
    4805             :             immediate8u(mask << 4);
    4806             :         }
    4807             : 
    4808             : #ifdef JS_CODEGEN_X64
    4809             :         // Quad-word-sized operands:
    4810             :         //
    4811             :         // Used to format 64-bit operantions, planting a REX.w prefix.  When
    4812             :         // planting d64 or f64 instructions, not requiring a REX.w prefix, the
    4813             :         // normal (non-'64'-postfixed) formatters should be used.
    4814             : 
    4815           0 :         void oneByteOp64(OneByteOpcodeID opcode)
    4816             :         {
    4817           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4818           0 :             emitRexW(0, 0, 0);
    4819           0 :             m_buffer.putByteUnchecked(opcode);
    4820           0 :         }
    4821             : 
    4822       62253 :         void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
    4823             :         {
    4824       62253 :             m_buffer.ensureSpace(MaxInstructionSize);
    4825       62253 :             emitRexW(0, 0, reg);
    4826       62254 :             m_buffer.putByteUnchecked(opcode + (reg & 7));
    4827       62251 :         }
    4828             : 
    4829      146031 :         void oneByteOp64(OneByteOpcodeID opcode, RegisterID rm, int reg)
    4830             :         {
    4831      146031 :             m_buffer.ensureSpace(MaxInstructionSize);
    4832      146031 :             emitRexW(reg, 0, rm);
    4833      146034 :             m_buffer.putByteUnchecked(opcode);
    4834      146035 :             registerModRM(rm, reg);
    4835      146034 :         }
    4836             : 
    4837       75843 :         void oneByteOp64(OneByteOpcodeID opcode, int32_t offset, RegisterID base, int reg)
    4838             :         {
    4839       75843 :             m_buffer.ensureSpace(MaxInstructionSize);
    4840       75843 :             emitRexW(reg, 0, base);
    4841       75845 :             m_buffer.putByteUnchecked(opcode);
    4842       75845 :             memoryModRM(offset, base, reg);
    4843       75845 :         }
    4844             : 
    4845             :         void oneByteOp64_disp32(OneByteOpcodeID opcode, int32_t offset, RegisterID base, int reg)
    4846             :         {
    4847             :             m_buffer.ensureSpace(MaxInstructionSize);
    4848             :             emitRexW(reg, 0, base);
    4849             :             m_buffer.putByteUnchecked(opcode);
    4850             :             memoryModRM_disp32(offset, base, reg);
    4851             :         }
    4852             : 
    4853         535 :         void oneByteOp64(OneByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID index, int scale, int reg)
    4854             :         {
    4855         535 :             m_buffer.ensureSpace(MaxInstructionSize);
    4856         535 :             emitRexW(reg, index, base);
    4857         535 :             m_buffer.putByteUnchecked(opcode);
    4858         535 :             memoryModRM(offset, base, index, scale, reg);
    4859         535 :         }
    4860             : 
    4861           0 :         void oneByteOp64(OneByteOpcodeID opcode, const void* address, int reg)
    4862             :         {
    4863           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4864           0 :             emitRexW(reg, 0, 0);
    4865           0 :             m_buffer.putByteUnchecked(opcode);
    4866           0 :             memoryModRM(address, reg);
    4867           0 :         }
    4868             : 
    4869          61 :         void twoByteOp64(TwoByteOpcodeID opcode, RegisterID rm, int reg)
    4870             :         {
    4871          61 :             m_buffer.ensureSpace(MaxInstructionSize);
    4872          61 :             emitRexW(reg, 0, rm);
    4873          61 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4874          61 :             m_buffer.putByteUnchecked(opcode);
    4875          61 :             registerModRM(rm, reg);
    4876          61 :         }
    4877             : 
    4878           0 :         void twoByteOp64(TwoByteOpcodeID opcode, int offset, RegisterID base, int reg)
    4879             :         {
    4880           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4881           0 :             emitRexW(reg, 0, base);
    4882           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4883           0 :             m_buffer.putByteUnchecked(opcode);
    4884           0 :             memoryModRM(offset, base, reg);
    4885           0 :         }
    4886             : 
    4887           0 :         void twoByteOp64(TwoByteOpcodeID opcode, int offset, RegisterID base, RegisterID index, int scale, int reg)
    4888             :         {
    4889           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4890           0 :             emitRexW(reg, index, base);
    4891           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4892           0 :             m_buffer.putByteUnchecked(opcode);
    4893           0 :             memoryModRM(offset, base, index, scale, reg);
    4894           0 :         }
    4895             : 
    4896             :         void twoByteOp64(TwoByteOpcodeID opcode, const void* address, int reg)
    4897             :         {
    4898             :             m_buffer.ensureSpace(MaxInstructionSize);
    4899             :             emitRexW(reg, 0, 0);
    4900             :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    4901             :             m_buffer.putByteUnchecked(opcode);
    4902             :             memoryModRM(address, reg);
    4903             :         }
    4904             : 
    4905           0 :         void twoByteOpVex64(VexOperandType ty, TwoByteOpcodeID opcode,
    4906             :                             RegisterID rm, XMMRegisterID src0, XMMRegisterID reg)
    4907             :         {
    4908           0 :             int r = (reg >> 3), x = 0, b = (rm >> 3);
    4909           0 :             int m = 1; // 0x0F
    4910           0 :             int w = 1, v = src0, l = 0;
    4911           0 :             threeOpVex(ty, r, x, b, m, w, v, l, opcode);
    4912           0 :             registerModRM(rm, reg);
    4913           0 :         }
    4914             : #endif
    4915             : 
    4916             :         // Byte-operands:
    4917             :         //
    4918             :         // These methods format byte operations.  Byte operations differ from
    4919             :         // the normal formatters in the circumstances under which they will
    4920             :         // decide to emit REX prefixes.  These should be used where any register
    4921             :         // operand signifies a byte register.
    4922             :         //
    4923             :         // The disctinction is due to the handling of register numbers in the
    4924             :         // range 4..7 on x86-64.  These register numbers may either represent
    4925             :         // the second byte of the first four registers (ah..bh) or the first
    4926             :         // byte of the second four registers (spl..dil).
    4927             :         //
    4928             :         // Address operands should still be checked using regRequiresRex(),
    4929             :         // while byteRegRequiresRex() is provided to check byte register
    4930             :         // operands.
    4931             : 
    4932         135 :         void oneByteOp8(OneByteOpcodeID opcode)
    4933             :         {
    4934         135 :             m_buffer.ensureSpace(MaxInstructionSize);
    4935         135 :             m_buffer.putByteUnchecked(opcode);
    4936         135 :         }
    4937             : 
    4938           0 :         void oneByteOp8(OneByteOpcodeID opcode, RegisterID r)
    4939             :         {
    4940           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4941           0 :             emitRexIf(byteRegRequiresRex(r), 0, 0, r);
    4942           0 :             m_buffer.putByteUnchecked(opcode + (r & 7));
    4943           0 :         }
    4944             : 
    4945       13442 :         void oneByteOp8(OneByteOpcodeID opcode, RegisterID rm, GroupOpcodeID groupOp)
    4946             :         {
    4947       13442 :             m_buffer.ensureSpace(MaxInstructionSize);
    4948       13442 :             emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
    4949       13442 :             m_buffer.putByteUnchecked(opcode);
    4950       13442 :             registerModRM(rm, groupOp);
    4951       13442 :         }
    4952             : 
    4953             :         // Like oneByteOp8, but never emits a REX prefix.
    4954           0 :         void oneByteOp8_norex(OneByteOpcodeID opcode, HRegisterID rm, GroupOpcodeID groupOp)
    4955             :         {
    4956           0 :             MOZ_ASSERT(!regRequiresRex(RegisterID(rm)));
    4957           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    4958           0 :             m_buffer.putByteUnchecked(opcode);
    4959           0 :             registerModRM(RegisterID(rm), groupOp);
    4960           0 :         }
    4961             : 
    4962           8 :         void oneByteOp8(OneByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID reg)
    4963             :         {
    4964           8 :             m_buffer.ensureSpace(MaxInstructionSize);
    4965           8 :             emitRexIf(byteRegRequiresRex(reg), reg, 0, base);
    4966           8 :             m_buffer.putByteUnchecked(opcode);
    4967           8 :             memoryModRM(offset, base, reg);
    4968           8 :         }
    4969             : 
    4970             :         void oneByteOp8_disp32(OneByteOpcodeID opcode, int32_t offset, RegisterID base,
    4971             :                                RegisterID reg)
    4972             :         {
    4973             :             m_buffer.ensureSpace(MaxInstructionSize);
    4974             :             emitRexIf(byteRegRequiresRex(reg), reg, 0, base);
    4975             :             m_buffer.putByteUnchecked(opcode);
    4976             :             memoryModRM_disp32(offset, base, reg);
    4977             :         }
    4978             : 
    4979           3 :         void oneByteOp8(OneByteOpcodeID opcode, int32_t offset, RegisterID base,
    4980             :                         RegisterID index, int scale, RegisterID reg)
    4981             :         {
    4982           3 :             m_buffer.ensureSpace(MaxInstructionSize);
    4983           3 :             emitRexIf(byteRegRequiresRex(reg), reg, index, base);
    4984           3 :             m_buffer.putByteUnchecked(opcode);
    4985           3 :             memoryModRM(offset, base, index, scale, reg);
    4986           3 :         }
    4987             : 
    4988             :         void oneByteOp8(OneByteOpcodeID opcode, const void* address, RegisterID reg)
    4989             :         {
    4990             :             m_buffer.ensureSpace(MaxInstructionSize);
    4991             :             emitRexIf(byteRegRequiresRex(reg), reg, 0, 0);
    4992             :             m_buffer.putByteUnchecked(opcode);
    4993             :             memoryModRM_disp32(address, reg);
    4994             :         }
    4995             : 
    4996             :         void twoByteOp8(TwoByteOpcodeID opcode, RegisterID rm, RegisterID reg)
    4997             :         {
    4998             :             m_buffer.ensureSpace(MaxInstructionSize);
    4999             :             emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
    5000             :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    5001             :             m_buffer.putByteUnchecked(opcode);
    5002             :             registerModRM(rm, reg);
    5003             :         }
    5004             : 
    5005           0 :         void twoByteOp8(TwoByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID reg)
    5006             :         {
    5007           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    5008           0 :             emitRexIf(byteRegRequiresRex(reg)|regRequiresRex(base), reg, 0, base);
    5009           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    5010           0 :             m_buffer.putByteUnchecked(opcode);
    5011           0 :             memoryModRM(offset, base, reg);
    5012           0 :         }
    5013             : 
    5014           0 :         void twoByteOp8(TwoByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID index,
    5015             :                         int scale, RegisterID reg)
    5016             :         {
    5017           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    5018           0 :             emitRexIf(byteRegRequiresRex(reg)|regRequiresRex(base)|regRequiresRex(index),
    5019           0 :                       reg, index, base);
    5020           0 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    5021           0 :             m_buffer.putByteUnchecked(opcode);
    5022           0 :             memoryModRM(offset, base, index, scale, reg);
    5023           0 :         }
    5024             : 
    5025             :         // Like twoByteOp8 but doesn't add a REX prefix if the destination reg
    5026             :         // is in esp..edi. This may be used when the destination is not an 8-bit
    5027             :         // register (as in a movzbl instruction), so it doesn't need a REX
    5028             :         // prefix to disambiguate it from ah..bh.
    5029          61 :         void twoByteOp8_movx(TwoByteOpcodeID opcode, RegisterID rm, RegisterID reg)
    5030             :         {
    5031          61 :             m_buffer.ensureSpace(MaxInstructionSize);
    5032          61 :             emitRexIf(regRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
    5033          61 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    5034          61 :             m_buffer.putByteUnchecked(opcode);
    5035          61 :             registerModRM(rm, reg);
    5036          61 :         }
    5037             : 
    5038         186 :         void twoByteOp8(TwoByteOpcodeID opcode, RegisterID rm, GroupOpcodeID groupOp)
    5039             :         {
    5040         186 :             m_buffer.ensureSpace(MaxInstructionSize);
    5041         186 :             emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
    5042         186 :             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    5043         186 :             m_buffer.putByteUnchecked(opcode);
    5044         186 :             registerModRM(rm, groupOp);
    5045         186 :         }
    5046             : 
    5047             :         // Immediates:
    5048             :         //
    5049             :         // An immedaite should be appended where appropriate after an op has
    5050             :         // been emitted.  The writes are unchecked since the opcode formatters
    5051             :         // above will have ensured space.
    5052             : 
    5053             :         // A signed 8-bit immediate.
    5054       75134 :         MOZ_ALWAYS_INLINE void immediate8s(int32_t imm)
    5055             :         {
    5056       75134 :             MOZ_ASSERT(CAN_SIGN_EXTEND_8_32(imm));
    5057       75134 :             m_buffer.putByteUnchecked(imm);
    5058       75134 :         }
    5059             : 
    5060             :         // An unsigned 8-bit immediate.
    5061        7488 :         MOZ_ALWAYS_INLINE void immediate8u(uint32_t imm)
    5062             :         {
    5063        7488 :             MOZ_ASSERT(CAN_ZERO_EXTEND_8_32(imm));
    5064        7488 :             m_buffer.putByteUnchecked(int32_t(imm));
    5065        7488 :         }
    5066             : 
    5067             :         // An 8-bit immediate with is either signed or unsigned, for use in
    5068             :         // instructions which actually only operate on 8 bits.
    5069       13581 :         MOZ_ALWAYS_INLINE void immediate8(int32_t imm)
    5070             :         {
    5071       13581 :             m_buffer.putByteUnchecked(imm);
    5072       13581 :         }
    5073             : 
    5074             :         // A signed 16-bit immediate.
    5075             :         MOZ_ALWAYS_INLINE void immediate16s(int32_t imm)
    5076             :         {
    5077             :             MOZ_ASSERT(CAN_SIGN_EXTEND_16_32(imm));
    5078             :             m_buffer.putShortUnchecked(imm);
    5079             :         }
    5080             : 
    5081             :         // An unsigned 16-bit immediate.
    5082        1036 :         MOZ_ALWAYS_INLINE void immediate16u(int32_t imm)
    5083             :         {
    5084        1036 :             MOZ_ASSERT(CAN_ZERO_EXTEND_16_32(imm));
    5085        1036 :             m_buffer.putShortUnchecked(imm);
    5086        1036 :         }
    5087             : 
    5088             :         // A 16-bit immediate with is either signed or unsigned, for use in
    5089             :         // instructions which actually only operate on 16 bits.
    5090           4 :         MOZ_ALWAYS_INLINE void immediate16(int32_t imm)
    5091             :         {
    5092           4 :             m_buffer.putShortUnchecked(imm);
    5093           4 :         }
    5094             : 
    5095       53309 :         MOZ_ALWAYS_INLINE void immediate32(int32_t imm)
    5096             :         {
    5097       53309 :             m_buffer.putIntUnchecked(imm);
    5098       53308 :         }
    5099             : 
    5100       81378 :         MOZ_ALWAYS_INLINE void immediate64(int64_t imm)
    5101             :         {
    5102       81378 :             m_buffer.putInt64Unchecked(imm);
    5103       81374 :         }
    5104             : 
    5105             :         MOZ_ALWAYS_INLINE MOZ_MUST_USE JmpSrc
    5106       66977 :         immediateRel32()
    5107             :         {
    5108       66977 :             m_buffer.putIntUnchecked(0);
    5109       66975 :             return JmpSrc(m_buffer.size());
    5110             :         }
    5111             : 
    5112             :         // Data:
    5113             : 
    5114           0 :         void jumpTablePointer(uintptr_t ptr)
    5115             :         {
    5116           0 :             m_buffer.ensureSpace(sizeof(uintptr_t));
    5117             : #ifdef JS_CODEGEN_X64
    5118           0 :             m_buffer.putInt64Unchecked(ptr);
    5119             : #else
    5120             :             m_buffer.putIntUnchecked(ptr);
    5121             : #endif
    5122           0 :         }
    5123             : 
    5124           0 :         void doubleConstant(double d)
    5125             :         {
    5126           0 :             m_buffer.ensureSpace(sizeof(double));
    5127           0 :             m_buffer.putInt64Unchecked(mozilla::BitwiseCast<uint64_t>(d));
    5128           0 :         }
    5129             : 
    5130           0 :         void floatConstant(float f)
    5131             :         {
    5132           0 :             m_buffer.ensureSpace(sizeof(float));
    5133           0 :             m_buffer.putIntUnchecked(mozilla::BitwiseCast<uint32_t>(f));
    5134           0 :         }
    5135             : 
    5136           0 :         void simd128Constant(const void* data)
    5137             :         {
    5138           0 :             const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
    5139           0 :             m_buffer.ensureSpace(16);
    5140           0 :             for (size_t i = 0; i < 16; ++i)
    5141           0 :                 m_buffer.putByteUnchecked(bytes[i]);
    5142           0 :         }
    5143             : 
    5144             :         void int64Constant(int64_t i)
    5145             :         {
    5146             :             m_buffer.ensureSpace(sizeof(int64_t));
    5147             :             m_buffer.putInt64Unchecked(i);
    5148             :         }
    5149             : 
    5150             :         void int32Constant(int32_t i)
    5151             :         {
    5152             :             m_buffer.ensureSpace(sizeof(int32_t));
    5153             :             m_buffer.putIntUnchecked(i);
    5154             :         }
    5155             : 
    5156             :         // Administrative methods:
    5157             : 
    5158      569941 :         size_t size() const { return m_buffer.size(); }
    5159        4499 :         const unsigned char* buffer() const { return m_buffer.buffer(); }
    5160      142599 :         unsigned char* data() { return m_buffer.data(); }
    5161      256035 :         bool oom() const { return m_buffer.oom(); }
    5162       25908 :         bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
    5163             : 
    5164           0 :         void disableProtection() { m_buffer.disableProtection(); }
    5165             :         void enableProtection() { m_buffer.enableProtection(); }
    5166             :         void setLowerBoundForProtection(size_t size)
    5167             :         {
    5168             :             m_buffer.setLowerBoundForProtection(size);
    5169             :         }
    5170             :         void unprotectRegion(unsigned char* first, size_t size)
    5171             :         {
    5172             :             m_buffer.unprotectRegion(first, size);
    5173             :         }
    5174             :         void reprotectRegion(unsigned char* first, size_t size)
    5175             :         {
    5176             :             m_buffer.reprotectRegion(first, size);
    5177             :         }
    5178             : 
    5179           0 :         MOZ_MUST_USE bool append(const unsigned char* values, size_t size)
    5180             :         {
    5181           0 :             return m_buffer.append(values, size);
    5182             :         }
    5183             : 
    5184             :     private:
    5185             : 
    5186             :         // Internals; ModRm and REX formatters.
    5187             : 
    5188             :         // Byte operand register spl & above requir a REX prefix, which precludes
    5189             :         // use of the h registers in the same instruction.
    5190       13700 :         static bool byteRegRequiresRex(RegisterID reg)
    5191             :         {
    5192             : #ifdef JS_CODEGEN_X64
    5193       13700 :             return reg >= rsp;
    5194             : #else
    5195             :             return false;
    5196             : #endif
    5197             :         }
    5198             : 
    5199             :         // For non-byte sizes, registers r8 & above always require a REX prefix.
    5200     1726036 :         static bool regRequiresRex(RegisterID reg)
    5201             :         {
    5202             : #ifdef JS_CODEGEN_X64
    5203     1726036 :             return reg >= r8;
    5204             : #else
    5205             :             return false;
    5206             : #endif
    5207             :         }
    5208             : 
    5209             : #ifdef JS_CODEGEN_X64
    5210             :         // Format a REX prefix byte.
    5211      537224 :         void emitRex(bool w, int r, int x, int b)
    5212             :         {
    5213      537224 :             m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
    5214      537267 :         }
    5215             : 
    5216             :         // Used to plant a REX byte with REX.w set (for 64-bit operations).
    5217      284709 :         void emitRexW(int r, int x, int b)
    5218             :         {
    5219      284709 :             emitRex(true, r, x, b);
    5220      284724 :         }
    5221             : 
    5222             :         // Used for operations with byte operands - use byteRegRequiresRex() to
    5223             :         // check register operands, regRequiresRex() to check other registers
    5224             :         // (i.e. address base & index).
    5225             :         //
    5226             :         // NB: WebKit's use of emitRexIf() is limited such that the
    5227             :         // reqRequiresRex() checks are not needed. SpiderMonkey extends
    5228             :         // oneByteOp8 and twoByteOp8 functionality such that r, x, and b
    5229             :         // can all be used.
    5230      692485 :         void emitRexIf(bool condition, int r, int x, int b)
    5231             :         {
    5232     1371447 :             if (condition ||
    5233     1202512 :                 regRequiresRex(RegisterID(r)) ||
    5234     1739610 :                 regRequiresRex(RegisterID(x)) ||
    5235      523559 :                 regRequiresRex(RegisterID(b)))
    5236             :             {
    5237      252550 :                 emitRex(false, r, x, b);
    5238             :             }
    5239      692506 :         }
    5240             : 
    5241             :         // Used for word sized operations, will plant a REX prefix if necessary
    5242             :         // (if any register is r8 or above).
    5243      678742 :         void emitRexIfNeeded(int r, int x, int b)
    5244             :         {
    5245      678742 :             emitRexIf(false, r, x, b);
    5246      678711 :         }
    5247             : #else
    5248             :         // No REX prefix bytes on 32-bit x86.
    5249             :         void emitRexIf(bool condition, int, int, int)
    5250             :         {
    5251             :             MOZ_ASSERT(!condition, "32-bit x86 should never use a REX prefix");
    5252             :         }
    5253             :         void emitRexIfNeeded(int, int, int) {}
    5254             : #endif
    5255             : 
    5256      648253 :         void putModRm(ModRmMode mode, RegisterID rm, int reg)
    5257             :         {
    5258      648253 :             m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
    5259      648269 :         }
    5260             : 
    5261      338420 :         void putModRmSib(ModRmMode mode, RegisterID base, RegisterID index, int scale, int reg)
    5262             :         {
    5263      338420 :             MOZ_ASSERT(mode != ModRmRegister);
    5264             : 
    5265      338420 :             putModRm(mode, hasSib, reg);
    5266      338429 :             m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
    5267      338439 :         }
    5268             : 
    5269      175739 :         void registerModRM(RegisterID rm, int reg)
    5270             :         {
    5271      175739 :             putModRm(ModRmRegister, rm, reg);
    5272      175737 :         }
    5273             : 
    5274      452251 :         void memoryModRM(int32_t offset, RegisterID base, int reg)
    5275             :         {
    5276             :             // A base of esp or r12 would be interpreted as a sib, so force a
    5277             :             // sib with no index & put the base in there.
    5278             : #ifdef JS_CODEGEN_X64
    5279      452251 :             if ((base == hasSib) || (base == hasSib2))
    5280             : #else
    5281             :             if (base == hasSib)
    5282             : #endif
    5283             :             {
    5284      674425 :                 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
    5285       23624 :                     putModRmSib(ModRmMemoryNoDisp, base, noIndex, 0, reg);
    5286      313608 :                 else if (CAN_SIGN_EXTEND_8_32(offset)) {
    5287      158689 :                     putModRmSib(ModRmMemoryDisp8, base, noIndex, 0, reg);
    5288      158696 :                     m_buffer.putByteUnchecked(offset);
    5289             :                 } else {
    5290      154923 :                     putModRmSib(ModRmMemoryDisp32, base, noIndex, 0, reg);
    5291      154927 :                     m_buffer.putIntUnchecked(offset);
    5292             :                 }
    5293             :             } else {
    5294             : #ifdef JS_CODEGEN_X64
    5295      115019 :                 if (!offset && (base != noBase) && (base != noBase2))
    5296             : #else
    5297             :                 if (!offset && (base != noBase))
    5298             : #endif
    5299       57564 :                     putModRm(ModRmMemoryNoDisp, base, reg);
    5300       57455 :                 else if (CAN_SIGN_EXTEND_8_32(offset)) {
    5301       48466 :                     putModRm(ModRmMemoryDisp8, base, reg);
    5302       48466 :                     m_buffer.putByteUnchecked(offset);
    5303             :                 } else {
    5304        8989 :                     putModRm(ModRmMemoryDisp32, base, reg);
    5305        8989 :                     m_buffer.putIntUnchecked(offset);
    5306             :                 }
    5307             :             }
    5308      452212 :         }
    5309             : 
    5310             :         void memoryModRM_disp32(int32_t offset, RegisterID base, int reg)
    5311             :         {
    5312             :             // A base of esp or r12 would be interpreted as a sib, so force a
    5313             :             // sib with no index & put the base in there.
    5314             : #ifdef JS_CODEGEN_X64
    5315             :             if ((base == hasSib) || (base == hasSib2))
    5316             : #else
    5317             :             if (base == hasSib)
    5318             : #endif
    5319             :             {
    5320             :                 putModRmSib(ModRmMemoryDisp32, base, noIndex, 0, reg);
    5321             :                 m_buffer.putIntUnchecked(offset);
    5322             :             } else {
    5323             :                 putModRm(ModRmMemoryDisp32, base, reg);
    5324             :                 m_buffer.putIntUnchecked(offset);
    5325             :             }
    5326             :         }
    5327             : 
    5328        1194 :         void memoryModRM(int32_t offset, RegisterID base, RegisterID index, int scale, int reg)
    5329             :         {
    5330        1194 :             MOZ_ASSERT(index != noIndex);
    5331             : 
    5332             : #ifdef JS_CODEGEN_X64
    5333        1194 :             if (!offset && (base != noBase) && (base != noBase2))
    5334             : #else
    5335             :             if (!offset && (base != noBase))
    5336             : #endif
    5337         461 :                 putModRmSib(ModRmMemoryNoDisp, base, index, scale, reg);
    5338         733 :             else if (CAN_SIGN_EXTEND_8_32(offset)) {
    5339         729 :                 putModRmSib(ModRmMemoryDisp8, base, index, scale, reg);
    5340         729 :                 m_buffer.putByteUnchecked(offset);
    5341             :             } else {
    5342           4 :                 putModRmSib(ModRmMemoryDisp32, base, index, scale, reg);
    5343           4 :                 m_buffer.putIntUnchecked(offset);
    5344             :             }
    5345        1194 :         }
    5346             : 
    5347             :         void memoryModRM_disp32(int32_t offset, RegisterID index, int scale, int reg)
    5348             :         {
    5349             :             MOZ_ASSERT(index != noIndex);
    5350             : 
    5351             :             // NB: the base-less memoryModRM overloads generate different code
    5352             :             // then the base-full memoryModRM overloads in the base == noBase
    5353             :             // case. The base-less overloads assume that the desired effective
    5354             :             // address is:
    5355             :             //
    5356             :             //   reg := [scaled index] + disp32
    5357             :             //
    5358             :             // which means the mod needs to be ModRmMemoryNoDisp. The base-full
    5359             :             // overloads pass ModRmMemoryDisp32 in all cases and thus, when
    5360             :             // base == noBase (== ebp), the effective address is:
    5361             :             //
    5362             :             //   reg := [scaled index] + disp32 + [ebp]
    5363             :             //
    5364             :             // See Intel developer manual, Vol 2, 2.1.5, Table 2-3.
    5365             :             putModRmSib(ModRmMemoryNoDisp, noBase, index, scale, reg);
    5366             :             m_buffer.putIntUnchecked(offset);
    5367             :         }
    5368             : 
    5369           0 :         void memoryModRM_disp32(const void* address, int reg)
    5370             :         {
    5371           0 :             int32_t disp = AddressImmediate(address);
    5372             : 
    5373             : #ifdef JS_CODEGEN_X64
    5374             :             // On x64-64, non-RIP-relative absolute mode requires a SIB.
    5375           0 :             putModRmSib(ModRmMemoryNoDisp, noBase, noIndex, 0, reg);
    5376             : #else
    5377             :             // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
    5378             :             putModRm(ModRmMemoryNoDisp, noBase, reg);
    5379             : #endif
    5380           0 :             m_buffer.putIntUnchecked(disp);
    5381           0 :         }
    5382             : 
    5383           0 :         void memoryModRM(const void* address, int reg)
    5384             :         {
    5385           0 :             memoryModRM_disp32(address, reg);
    5386           0 :         }
    5387             : 
    5388           0 :         void threeOpVex(VexOperandType p, int r, int x, int b, int m, int w, int v, int l,
    5389             :                         int opcode)
    5390             :         {
    5391           0 :             m_buffer.ensureSpace(MaxInstructionSize);
    5392             : 
    5393           0 :             if (v == invalid_xmm)
    5394           0 :                 v = XMMRegisterID(0);
    5395             : 
    5396           0 :             if (x == 0 && b == 0 && m == 1 && w == 0) {
    5397             :                 // Two byte VEX.
    5398           0 :                 m_buffer.putByteUnchecked(PRE_VEX_C5);
    5399           0 :                 m_buffer.putByteUnchecked(((r << 7) | (v << 3) | (l << 2) | p) ^ 0xf8);
    5400             :             } else {
    5401             :                 // Three byte VEX.
    5402           0 :                 m_buffer.putByteUnchecked(PRE_VEX_C4);
    5403           0 :                 m_buffer.putByteUnchecked(((r << 7) | (x << 6) | (b << 5) | m) ^ 0xe0);
    5404           0 :                 m_buffer.putByteUnchecked(((w << 7) | (v << 3) | (l << 2) | p) ^ 0x78);
    5405             :             }
    5406             : 
    5407           0 :             m_buffer.putByteUnchecked(opcode);
    5408           0 :         }
    5409             : 
    5410             :         AssemblerBuffer m_buffer;
    5411             :     } m_formatter;
    5412             : 
    5413             :     bool useVEX_;
    5414             : };
    5415             : 
    5416             : } // namespace X86Encoding
    5417             : 
    5418             : } // namespace jit
    5419             : } // namespace js
    5420             : 
    5421             : #endif /* jit_x86_shared_BaseAssembler_x86_shared_h */

Generated by: LCOV version 1.13