Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/jit/x86-shared/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 243 kB image not shown  

Quelle  BaseAssembler-x86-shared.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 *
 * ***** BEGIN LICENSE BLOCK *****
 * Copyright (C) 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */


#ifndef jit_x86_shared_BaseAssembler_x86_shared_h
#define jit_x86_shared_BaseAssembler_x86_shared_h

#include "mozilla/IntegerPrintfMacros.h"

#include "jit/x86-shared/AssemblerBuffer-x86-shared.h"
#include "jit/x86-shared/Encoding-x86-shared.h"
#include "jit/x86-shared/Patching-x86-shared.h"
#include "wasm/WasmTypeDecls.h"

namespace js {
namespace jit {

namespace X86Encoding {

class BaseAssembler;

class BaseAssembler : public GenericAssembler {
 public:
  BaseAssembler() : useVEX_(true) {}

  void disableVEX() { useVEX_ = false; }

  size_t size() const { return m_formatter.size(); }
  const unsigned char* buffer() const { return m_formatter.buffer(); }
  unsigned char* data() { return m_formatter.data(); }
  bool oom() const { return m_formatter.oom(); }
  bool reserve(size_t size) { return m_formatter.reserve(size); }
  bool swapBuffer(wasm::Bytes& other) { return m_formatter.swapBuffer(other); }

  void nop() {
    spew("nop");
    m_formatter.oneByteOp(OP_NOP);
  }

  void comment(const char* msg) { spew("; %s", msg); }

  static void patchFiveByteNopToCall(uint8_t* callsite, uint8_t* target) {
    // Note: the offset is relative to the address of the instruction after
    // the call which is five bytes.
    uint8_t* inst = callsite - sizeof(int32_t) - 1;
    // The nop can be already patched as call, overriding the call.
    // See also nop_five.
    MOZ_ASSERT(inst[0] == OP_NOP_0F || inst[0] == OP_CALL_rel32);
    MOZ_ASSERT_IF(inst[0] == OP_NOP_0F,
                  inst[1] == OP_NOP_1F || inst[2] == OP_NOP_44 ||
                      inst[3] == OP_NOP_00 || inst[4] == OP_NOP_00);
    inst[0] = OP_CALL_rel32;
    SetRel32(callsite, target);
  }

  static void patchCallToFiveByteNop(uint8_t* callsite) {
    // See also patchFiveByteNopToCall and nop_five.
    uint8_t* inst = callsite - sizeof(int32_t) - 1;
    // The call can be already patched as nop.
    if (inst[0] == OP_NOP_0F) {
      MOZ_ASSERT(inst[1] == OP_NOP_1F || inst[2] == OP_NOP_44 ||
                 inst[3] == OP_NOP_00 || inst[4] == OP_NOP_00);
      return;
    }
    MOZ_ASSERT(inst[0] == OP_CALL_rel32);
    inst[0] = OP_NOP_0F;
    inst[1] = OP_NOP_1F;
    inst[2] = OP_NOP_44;
    inst[3] = OP_NOP_00;
    inst[4] = OP_NOP_00;
  }

  /*
   * The nop multibytes sequences are directly taken from the Intel's
   * architecture software developer manual.
   * They are defined for sequences of sizes from 1 to 9 included.
   */

  void nop_one() { m_formatter.oneByteOp(OP_NOP); }

  void nop_two() {
    m_formatter.oneByteOp(OP_NOP_66);
    m_formatter.oneByteOp(OP_NOP);
  }

  void nop_three() {
    m_formatter.oneByteOp(OP_NOP_0F);
    m_formatter.oneByteOp(OP_NOP_1F);
    m_formatter.oneByteOp(OP_NOP_00);
  }

  void nop_four() {
    m_formatter.oneByteOp(OP_NOP_0F);
    m_formatter.oneByteOp(OP_NOP_1F);
    m_formatter.oneByteOp(OP_NOP_40);
    m_formatter.oneByteOp(OP_NOP_00);
  }

  void nop_five() {
    m_formatter.oneByteOp(OP_NOP_0F);
    m_formatter.oneByteOp(OP_NOP_1F);
    m_formatter.oneByteOp(OP_NOP_44);
    m_formatter.oneByteOp(OP_NOP_00);
    m_formatter.oneByteOp(OP_NOP_00);
  }

  void nop_six() {
    m_formatter.oneByteOp(OP_NOP_66);
    nop_five();
  }

  void nop_seven() {
    m_formatter.oneByteOp(OP_NOP_0F);
    m_formatter.oneByteOp(OP_NOP_1F);
    m_formatter.oneByteOp(OP_NOP_80);
    for (int i = 0; i < 4; ++i) {
      m_formatter.oneByteOp(OP_NOP_00);
    }
  }

  void nop_eight() {
    m_formatter.oneByteOp(OP_NOP_0F);
    m_formatter.oneByteOp(OP_NOP_1F);
    m_formatter.oneByteOp(OP_NOP_84);
    for (int i = 0; i < 5; ++i) {
      m_formatter.oneByteOp(OP_NOP_00);
    }
  }

  void nop_nine() {
    m_formatter.oneByteOp(OP_NOP_66);
    nop_eight();
  }

  void insert_nop(int size) {
    switch (size) {
      case 1:
        nop_one();
        break;
      case 2:
        nop_two();
        break;
      case 3:
        nop_three();
        break;
      case 4:
        nop_four();
        break;
      case 5:
        nop_five();
        break;
      case 6:
        nop_six();
        break;
      case 7:
        nop_seven();
        break;
      case 8:
        nop_eight();
        break;
      case 9:
        nop_nine();
        break;
      case 10:
        nop_three();
        nop_seven();
        break;
      case 11:
        nop_four();
        nop_seven();
        break;
      case 12:
        nop_six();
        nop_six();
        break;
      case 13:
        nop_six();
        nop_seven();
        break;
      case 14:
        nop_seven();
        nop_seven();
        break;
      case 15:
        nop_one();
        nop_seven();
        nop_seven();
        break;
      default:
        MOZ_CRASH("Unhandled alignment");
    }
  }

  // Stack operations:

  void push_r(RegisterID reg) {
    spew("push %s", GPRegName(reg));
    m_formatter.oneByteOp(OP_PUSH_EAX, reg);
  }

  void pop_r(RegisterID reg) {
    spew("pop %s", GPRegName(reg));
    m_formatter.oneByteOp(OP_POP_EAX, reg);
  }

  void push_i(int32_t imm) {
    spew("push $%s0x%x", PRETTYHEX(imm));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_PUSH_Ib);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_PUSH_Iz);
      m_formatter.immediate32(imm);
    }
  }

  void push_i32(int32_t imm) {
    spew("push $%s0x%04x", PRETTYHEX(imm));
    m_formatter.oneByteOp(OP_PUSH_Iz);
    m_formatter.immediate32(imm);
  }

  void push_m(int32_t offset, RegisterID base) {
    spew("push " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_PUSH);
  }
  void push_m(int32_t offset, RegisterID base, RegisterID index, int scale) {
    spew("push " MEM_obs, ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, index, scale,
                          GROUP5_OP_PUSH);
  }

  void pop_m(int32_t offset, RegisterID base) {
    spew("pop " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP1A_Ev, offset, base, GROUP1A_OP_POP);
  }

  void push_flags() {
    spew("pushf");
    m_formatter.oneByteOp(OP_PUSHFLAGS);
  }

  void pop_flags() {
    spew("popf");
    m_formatter.oneByteOp(OP_POPFLAGS);
  }

  // Arithmetic operations:

  void addl_rr(RegisterID src, RegisterID dst) {
    spew("addl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_ADD_GvEv, src, dst);
  }

  void addw_rr(RegisterID src, RegisterID dst) {
    spew("addw %s, %s", GPReg16Name(src), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_ADD_GvEv, src, dst);
  }

  void addl_mr(int32_t offset, RegisterID base, RegisterID dst) {
    spew("addl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_ADD_GvEv, offset, base, dst);
  }

  void addl_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("addl %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, src);
  }

  void addl_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("addl %s, " MEM_obs, GPReg32Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, index, scale, src);
  }

  void addl_ir(int32_t imm, RegisterID dst) {
    spew("addl $%d, %s", imm, GPReg32Name(dst));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_ADD);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_ADD_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD);
      }
      m_formatter.immediate32(imm);
    }
  }

  void addw_ir(int32_t imm, RegisterID dst) {
    spew("addw $%d, %s", int16_t(imm), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD);
    m_formatter.immediate16(imm);
  }

  void addl_i32r(int32_t imm, RegisterID dst) {
    // 32-bit immediate always, for patching.
    spew("addl $0x%04x, %s", uint32_t(imm), GPReg32Name(dst));
    if (dst == rax) {
      m_formatter.oneByteOp(OP_ADD_EAXIv);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD);
    }
    m_formatter.immediate32(imm);
  }

  void addl_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("addl $%d, " MEM_ob, imm, ADDR_ob(offset, base));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_ADD);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_ADD);
      m_formatter.immediate32(imm);
    }
  }

  void addl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("addl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_ADD);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_ADD);
      m_formatter.immediate32(imm);
    }
  }

  void addl_im(int32_t imm, const void* addr) {
    spew("addl $%d, %p", imm, addr);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADD);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADD);
      m_formatter.immediate32(imm);
    }
  }
  void addw_im(int32_t imm, const void* addr) {
    spew("addw $%d, %p", int16_t(imm), addr);
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADD);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADD);
      m_formatter.immediate16(imm);
    }
  }

  void addw_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("addw $%d, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_ADD);
    m_formatter.immediate16(imm);
  }

  void addw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("addw $%d, " MEM_obs, int16_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                          GROUP1_OP_ADD);
    m_formatter.immediate16(imm);
  }

  void addw_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("addw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, src);
  }

  void addw_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("addw %s, " MEM_obs, GPReg16Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, index, scale, src);
  }

  void addb_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("addb $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_ADD);
    m_formatter.immediate8(imm);
  }

  void addb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("addb $%d, " MEM_obs, int8_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale,
                          GROUP1_OP_ADD);
    m_formatter.immediate8(imm);
  }

  void addb_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("addb %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp8(OP_ADD_EbGb, offset, base, src);
  }

  void addb_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("addb %s, " MEM_obs, GPReg8Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp8(OP_ADD_EbGb, offset, base, index, scale, src);
  }

  void subb_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("subb $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_SUB);
    m_formatter.immediate8(imm);
  }

  void subb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("subb $%d, " MEM_obs, int8_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale,
                          GROUP1_OP_SUB);
    m_formatter.immediate8(imm);
  }

  void subb_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("subb %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp8(OP_SUB_EbGb, offset, base, src);
  }

  void subb_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("subb %s, " MEM_obs, GPReg8Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp8(OP_SUB_EbGb, offset, base, index, scale, src);
  }

  void andb_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("andb $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_AND);
    m_formatter.immediate8(imm);
  }

  void andb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("andb $%d, " MEM_obs, int8_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale,
                          GROUP1_OP_AND);
    m_formatter.immediate8(imm);
  }

  void andb_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("andb %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp8(OP_AND_EbGb, offset, base, src);
  }

  void andb_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("andb %s, " MEM_obs, GPReg8Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp8(OP_AND_EbGb, offset, base, index, scale, src);
  }

  void orb_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("orb $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_OR);
    m_formatter.immediate8(imm);
  }

  void orb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
              int scale) {
    spew("orb $%d, " MEM_obs, int8_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale,
                          GROUP1_OP_OR);
    m_formatter.immediate8(imm);
  }

  void orb_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("orb %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp8(OP_OR_EbGb, offset, base, src);
  }

  void orb_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index,
              int scale) {
    spew("orb %s, " MEM_obs, GPReg8Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp8(OP_OR_EbGb, offset, base, index, scale, src);
  }

  void xorb_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("xorb $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, GROUP1_OP_XOR);
    m_formatter.immediate8(imm);
  }

  void xorb_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("xorb $%d, " MEM_obs, int8_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_GROUP1_EbIb, offset, base, index, scale,
                          GROUP1_OP_XOR);
    m_formatter.immediate8(imm);
  }

  void xorb_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("xorb %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp8(OP_XOR_EbGb, offset, base, src);
  }

  void xorb_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("xorb %s, " MEM_obs, GPReg8Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp8(OP_XOR_EbGb, offset, base, index, scale, src);
  }

  void lock_xaddb_rm(RegisterID srcdest, int32_t offset, RegisterID base) {
    spew("lock xaddb %s, " MEM_ob, GPReg8Name(srcdest), ADDR_ob(offset, base));
    m_formatter.oneByteOp(PRE_LOCK);
    m_formatter.twoByteOp8(OP2_XADD_EbGb, offset, base, srcdest);
  }

  void lock_xaddb_rm(RegisterID srcdest, int32_t offset, RegisterID base,
                     RegisterID index, int scale) {
    spew("lock xaddb %s, " MEM_obs, GPReg8Name(srcdest),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(PRE_LOCK);
    m_formatter.twoByteOp8(OP2_XADD_EbGb, offset, base, index, scale, srcdest);
  }

  void lock_xaddl_rm(RegisterID srcdest, int32_t offset, RegisterID base) {
    spew("lock xaddl %s, " MEM_ob, GPReg32Name(srcdest), ADDR_ob(offset, base));
    m_formatter.oneByteOp(PRE_LOCK);
    m_formatter.twoByteOp(OP2_XADD_EvGv, offset, base, srcdest);
  }

  void lock_xaddl_rm(RegisterID srcdest, int32_t offset, RegisterID base,
                     RegisterID index, int scale) {
    spew("lock xaddl %s, " MEM_obs, GPReg32Name(srcdest),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(PRE_LOCK);
    m_formatter.twoByteOp(OP2_XADD_EvGv, offset, base, index, scale, srcdest);
  }

  void vpmaddubsw_rr(XMMRegisterID src1, XMMRegisterID src0,
                     XMMRegisterID dst) {
    threeByteOpSimd("vpmaddubsw", VEX_PD, OP3_PMADDUBSW_VdqWdq, ESCAPE_38, src1,
                    src0, dst);
  }
  void vpmaddubsw_mr(const void* address, XMMRegisterID src0,
                     XMMRegisterID dst) {
    threeByteOpSimd("vpmaddubsw", VEX_PD, OP3_PMADDUBSW_VdqWdq, ESCAPE_38,
                    address, src0, dst);
  }

  void vpaddb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddb", VEX_PD, OP2_PADDB_VdqWdq, src1, src0, dst);
  }
  void vpaddb_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vpaddb", VEX_PD, OP2_PADDB_VdqWdq, offset, base, src0, dst);
  }
  void vpaddb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddb", VEX_PD, OP2_PADDB_VdqWdq, address, src0, dst);
  }

  void vpaddsb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddsb", VEX_PD, OP2_PADDSB_VdqWdq, src1, src0, dst);
  }
  void vpaddsb_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                  XMMRegisterID dst) {
    twoByteOpSimd("vpaddsb", VEX_PD, OP2_PADDSB_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpaddsb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddsb", VEX_PD, OP2_PADDSB_VdqWdq, address, src0, dst);
  }

  void vpaddusb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddusb", VEX_PD, OP2_PADDUSB_VdqWdq, src1, src0, dst);
  }
  void vpaddusb_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                   XMMRegisterID dst) {
    twoByteOpSimd("vpaddusb", VEX_PD, OP2_PADDUSB_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpaddusb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddusb", VEX_PD, OP2_PADDUSB_VdqWdq, address, src0, dst);
  }

  void vpaddw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddw", VEX_PD, OP2_PADDW_VdqWdq, src1, src0, dst);
  }
  void vpaddw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vpaddw", VEX_PD, OP2_PADDW_VdqWdq, offset, base, src0, dst);
  }
  void vpaddw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddw", VEX_PD, OP2_PADDW_VdqWdq, address, src0, dst);
  }

  void vpaddsw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddsw", VEX_PD, OP2_PADDSW_VdqWdq, src1, src0, dst);
  }
  void vpaddsw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                  XMMRegisterID dst) {
    twoByteOpSimd("vpaddsw", VEX_PD, OP2_PADDSW_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpaddsw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddsw", VEX_PD, OP2_PADDSW_VdqWdq, address, src0, dst);
  }

  void vpaddusw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddusw", VEX_PD, OP2_PADDUSW_VdqWdq, src1, src0, dst);
  }
  void vpaddusw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                   XMMRegisterID dst) {
    twoByteOpSimd("vpaddusw", VEX_PD, OP2_PADDUSW_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpaddusw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddusw", VEX_PD, OP2_PADDUSW_VdqWdq, address, src0, dst);
  }

  void vpaddd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddd", VEX_PD, OP2_PADDD_VdqWdq, src1, src0, dst);
  }
  void vpaddd_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vpaddd", VEX_PD, OP2_PADDD_VdqWdq, offset, base, src0, dst);
  }
  void vpaddd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddd", VEX_PD, OP2_PADDD_VdqWdq, address, src0, dst);
  }

  void vpaddq_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpaddq", VEX_PD, OP2_PADDQ_VdqWdq, address, src0, dst);
  }

  void vpsubb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubb", VEX_PD, OP2_PSUBB_VdqWdq, src1, src0, dst);
  }
  void vpsubb_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vpsubb", VEX_PD, OP2_PSUBB_VdqWdq, offset, base, src0, dst);
  }
  void vpsubb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubb", VEX_PD, OP2_PSUBB_VdqWdq, address, src0, dst);
  }

  void vpsubsb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubsb", VEX_PD, OP2_PSUBSB_VdqWdq, src1, src0, dst);
  }
  void vpsubsb_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                  XMMRegisterID dst) {
    twoByteOpSimd("vpsubsb", VEX_PD, OP2_PSUBSB_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpsubsb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubsb", VEX_PD, OP2_PSUBSB_VdqWdq, address, src0, dst);
  }

  void vpsubusb_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubusb", VEX_PD, OP2_PSUBUSB_VdqWdq, src1, src0, dst);
  }
  void vpsubusb_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                   XMMRegisterID dst) {
    twoByteOpSimd("vpsubusb", VEX_PD, OP2_PSUBUSB_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpsubusb_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubusb", VEX_PD, OP2_PSUBUSB_VdqWdq, address, src0, dst);
  }

  void vpsubw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubw", VEX_PD, OP2_PSUBW_VdqWdq, src1, src0, dst);
  }
  void vpsubw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vpsubw", VEX_PD, OP2_PSUBW_VdqWdq, offset, base, src0, dst);
  }
  void vpsubw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubw", VEX_PD, OP2_PSUBW_VdqWdq, address, src0, dst);
  }

  void vpsubsw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubsw", VEX_PD, OP2_PSUBSW_VdqWdq, src1, src0, dst);
  }
  void vpsubsw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                  XMMRegisterID dst) {
    twoByteOpSimd("vpsubsw", VEX_PD, OP2_PSUBSW_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpsubsw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubsw", VEX_PD, OP2_PSUBSW_VdqWdq, address, src0, dst);
  }

  void vpsubusw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubusw", VEX_PD, OP2_PSUBUSW_VdqWdq, src1, src0, dst);
  }
  void vpsubusw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                   XMMRegisterID dst) {
    twoByteOpSimd("vpsubusw", VEX_PD, OP2_PSUBUSW_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpsubusw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubusw", VEX_PD, OP2_PSUBUSW_VdqWdq, address, src0, dst);
  }

  void vpsubd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubd", VEX_PD, OP2_PSUBD_VdqWdq, src1, src0, dst);
  }
  void vpsubd_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vpsubd", VEX_PD, OP2_PSUBD_VdqWdq, offset, base, src0, dst);
  }
  void vpsubd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubd", VEX_PD, OP2_PSUBD_VdqWdq, address, src0, dst);
  }

  void vpsubq_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpsubq", VEX_PD, OP2_PSUBQ_VdqWdq, address, src0, dst);
  }

  void vpmuldq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    threeByteOpSimd("vpmuldq", VEX_PD, OP3_PMULDQ_VdqWdq, ESCAPE_38, src1, src0,
                    dst);
  }

  void vpmuludq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmuludq", VEX_PD, OP2_PMULUDQ_VdqWdq, src1, src0, dst);
  }
  void vpmuludq_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                   XMMRegisterID dst) {
    twoByteOpSimd("vpmuludq", VEX_PD, OP2_PMULUDQ_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpmuludq_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmuludq", VEX_PD, OP2_PMULUDQ_VdqWdq, address, src0, dst);
  }

  void vpmaddwd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmaddwd", VEX_PD, OP2_PMADDWD_VdqWdq, src1, src0, dst);
  }
  void vpmaddwd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmaddwd", VEX_PD, OP2_PMADDWD_VdqWdq, address, src0, dst);
  }

  void vpmullw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmullw", VEX_PD, OP2_PMULLW_VdqWdq, src1, src0, dst);
  }
  void vpmulhw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmulhw", VEX_PD, OP2_PMULHW_VdqWdq, src1, src0, dst);
  }
  void vpmulhuw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmulhuw", VEX_PD, OP2_PMULHUW_VdqWdq, src1, src0, dst);
  }
  void vpmullw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                  XMMRegisterID dst) {
    twoByteOpSimd("vpmullw", VEX_PD, OP2_PMULLW_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpmulhw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                  XMMRegisterID dst) {
    twoByteOpSimd("vpmulhw", VEX_PD, OP2_PMULHW_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpmulhuw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                   XMMRegisterID dst) {
    twoByteOpSimd("vpmulhuw", VEX_PD, OP2_PMULHUW_VdqWdq, offset, base, src0,
                  dst);
  }
  void vpmullw_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vpmullw", VEX_PD, OP2_PMULLW_VdqWdq, address, src0, dst);
  }

  void vpmulld_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    threeByteOpSimd("vpmulld", VEX_PD, OP3_PMULLD_VdqWdq, ESCAPE_38, src1, src0,
                    dst);
  }
  void vpmulld_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                  XMMRegisterID dst) {
    threeByteOpSimd("vpmulld", VEX_PD, OP3_PMULLD_VdqWdq, ESCAPE_38, offset,
                    base, src0, dst);
  }
  void vpmulld_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    threeByteOpSimd("vpmulld", VEX_PD, OP3_PMULLD_VdqWdq, ESCAPE_38, address,
                    src0, dst);
  }
  void vpmulhrsw_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    threeByteOpSimd("vpmulhrsw", VEX_PD, OP3_PMULHRSW_VdqWdq, ESCAPE_38, src1,
                    src0, dst);
  }
  void vpmulhrsw_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                    XMMRegisterID dst) {
    threeByteOpSimd("vpmulhrsw", VEX_PD, OP3_PMULHRSW_VdqWdq, ESCAPE_38, offset,
                    base, src0, dst);
  }

  void vaddps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, src1, src0, dst);
  }
  void vaddps_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, offset, base, src0, dst);
  }
  void vaddps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, address, src0, dst);
  }

  void vsubps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, src1, src0, dst);
  }
  void vsubps_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, offset, base, src0, dst);
  }
  void vsubps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, address, src0, dst);
  }

  void vmulps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, src1, src0, dst);
  }
  void vmulps_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, offset, base, src0, dst);
  }
  void vmulps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, address, src0, dst);
  }

  void vdivps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, src1, src0, dst);
  }
  void vdivps_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, offset, base, src0, dst);
  }
  void vdivps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, address, src0, dst);
  }

  void vmaxps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, src1, src0, dst);
  }
  void vmaxps_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, offset, base, src0, dst);
  }
  void vmaxps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, address, src0, dst);
  }

  void vmaxpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vmaxpd", VEX_PD, OP2_MAXPD_VpdWpd, src1, src0, dst);
  }

  void vminps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, src1, src0, dst);
  }
  void vminps_mr(int32_t offset, RegisterID base, XMMRegisterID src0,
                 XMMRegisterID dst) {
    twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, offset, base, src0, dst);
  }
  void vminps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, address, src0, dst);
  }

  void vminpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vminpd", VEX_PD, OP2_MINPD_VpdWpd, src1, src0, dst);
  }
  void vminpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vminpd", VEX_PD, OP2_MINPD_VpdWpd, address, src0, dst);
  }

  void vaddpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vaddpd", VEX_PD, OP2_ADDPD_VpdWpd, src1, src0, dst);
  }
  void vaddpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vaddpd", VEX_PD, OP2_ADDPD_VpdWpd, address, src0, dst);
  }

  void vsubpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPD_VpdWpd, src1, src0, dst);
  }
  void vsubpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPD_VpdWpd, address, src0, dst);
  }

  void vmulpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vmulpd", VEX_PD, OP2_MULPD_VpdWpd, src1, src0, dst);
  }
  void vmulpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vmulpd", VEX_PD, OP2_MULPD_VpdWpd, address, src0, dst);
  }

  void vdivpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vdivpd", VEX_PD, OP2_DIVPD_VpdWpd, src1, src0, dst);
  }
  void vdivpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) {
    twoByteOpSimd("vdivpd", VEX_PD, OP2_DIVPD_VpdWpd, address, src0, dst);
  }

  void andl_rr(RegisterID src, RegisterID dst) {
    spew("andl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_AND_GvEv, src, dst);
  }

  void andw_rr(RegisterID src, RegisterID dst) {
    spew("andw %s, %s", GPReg16Name(src), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_AND_GvEv, src, dst);
  }

  void andl_mr(int32_t offset, RegisterID base, RegisterID dst) {
    spew("andl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_AND_GvEv, offset, base, dst);
  }

  void andl_mr(int32_t offset, RegisterID base, RegisterID index, int scale,
               RegisterID dst) {
    spew("andl " MEM_obs ", %s", ADDR_obs(offset, base, index, scale),
         GPReg32Name(dst));
    m_formatter.oneByteOp(OP_AND_GvEv, offset, base, index, scale, dst);
  }

  void andl_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("andl %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_AND_EvGv, offset, base, src);
  }

  void andw_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("andw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_AND_EvGv, offset, base, src);
  }

  void andl_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("andl %s, " MEM_obs, GPReg32Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_AND_EvGv, offset, base, index, scale, src);
  }

  void andw_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("andw %s, " MEM_obs, GPReg16Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_AND_EvGv, offset, base, index, scale, src);
  }

  void andl_ir(int32_t imm, RegisterID dst) {
    spew("andl $0x%x, %s", uint32_t(imm), GPReg32Name(dst));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_AND);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_AND_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_AND);
      }
      m_formatter.immediate32(imm);
    }
  }

  void andw_ir(int32_t imm, RegisterID dst) {
    spew("andw $0x%x, %s", uint16_t(imm), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_AND);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_AND_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_AND);
      }
      m_formatter.immediate16(imm);
    }
  }

  void andl_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("andl $0x%x, " MEM_ob, uint32_t(imm), ADDR_ob(offset, base));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_AND);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_AND);
      m_formatter.immediate32(imm);
    }
  }

  void andw_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("andw $0x%x, " MEM_ob, uint16_t(imm), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_AND);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_AND);
      m_formatter.immediate16(imm);
    }
  }

  void andl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("andl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_AND);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_AND);
      m_formatter.immediate32(imm);
    }
  }

  void andw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("andw $%d, " MEM_obs, int16_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_AND);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_AND);
      m_formatter.immediate16(imm);
    }
  }

  void fld_m(int32_t offset, RegisterID base) {
    spew("fld " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FLD);
  }
  void fld32_m(int32_t offset, RegisterID base) {
    spew("fld " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FLD);
  }
  void faddp() {
    spew("addp ");
    m_formatter.oneByteOp(OP_FPU6_ADDP);
    m_formatter.oneByteOp(OP_ADDP_ST0_ST1);
  }
  void fisttp_m(int32_t offset, RegisterID base) {
    spew("fisttp " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FISTTP);
  }
  void fistp_m(int32_t offset, RegisterID base) {
    spew("fistp " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FILD, offset, base, FPU6_OP_FISTP);
  }
  void fstp_m(int32_t offset, RegisterID base) {
    spew("fstp " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FSTP);
  }
  void fstp32_m(int32_t offset, RegisterID base) {
    spew("fstp32 " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FSTP);
  }
  void fnstcw_m(int32_t offset, RegisterID base) {
    spew("fnstcw " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FISTP);
  }
  void fldcw_m(int32_t offset, RegisterID base) {
    spew("fldcw " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6_F32, offset, base, FPU6_OP_FLDCW);
  }
  void fnstsw_m(int32_t offset, RegisterID base) {
    spew("fnstsw " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_FPU6, offset, base, FPU6_OP_FISTP);
  }

  void negl_r(RegisterID dst) {
    spew("negl %s", GPReg32Name(dst));
    m_formatter.oneByteOp(OP_GROUP3_Ev, dst, GROUP3_OP_NEG);
  }

  void negl_m(int32_t offset, RegisterID base) {
    spew("negl " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP3_Ev, offset, base, GROUP3_OP_NEG);
  }

  void notl_r(RegisterID dst) {
    spew("notl %s", GPReg32Name(dst));
    m_formatter.oneByteOp(OP_GROUP3_Ev, dst, GROUP3_OP_NOT);
  }

  void notl_m(int32_t offset, RegisterID base) {
    spew("notl " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP3_Ev, offset, base, GROUP3_OP_NOT);
  }

  void orl_rr(RegisterID src, RegisterID dst) {
    spew("orl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_OR_GvEv, src, dst);
  }

  void orw_rr(RegisterID src, RegisterID dst) {
    spew("orw %s, %s", GPReg16Name(src), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_OR_GvEv, src, dst);
  }

  void orl_mr(int32_t offset, RegisterID base, RegisterID dst) {
    spew("orl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_OR_GvEv, offset, base, dst);
  }

  void orl_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("orl %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_OR_EvGv, offset, base, src);
  }

  void orw_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("orw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_OR_EvGv, offset, base, src);
  }

  void orl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index,
              int scale) {
    spew("orl %s, " MEM_obs, GPReg32Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_OR_EvGv, offset, base, index, scale, src);
  }

  void orw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index,
              int scale) {
    spew("orw %s, " MEM_obs, GPReg16Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_OR_EvGv, offset, base, index, scale, src);
  }

  void orl_ir(int32_t imm, RegisterID dst) {
    spew("orl $0x%x, %s", uint32_t(imm), GPReg32Name(dst));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_OR);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_OR_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_OR);
      }
      m_formatter.immediate32(imm);
    }
  }

  void orw_ir(int32_t imm, RegisterID dst) {
    spew("orw $0x%x, %s", uint16_t(imm), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_OR);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_OR_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_OR);
      }
      m_formatter.immediate16(imm);
    }
  }

  void orl_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("orl $0x%x, " MEM_ob, uint32_t(imm), ADDR_ob(offset, base));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_OR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_OR);
      m_formatter.immediate32(imm);
    }
  }

  void orw_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("orw $0x%x, " MEM_ob, uint16_t(imm), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_OR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_OR);
      m_formatter.immediate16(imm);
    }
  }

  void orl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
              int scale) {
    spew("orl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_OR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_OR);
      m_formatter.immediate32(imm);
    }
  }

  void orw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
              int scale) {
    spew("orw $%d, " MEM_obs, int16_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_OR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_OR);
      m_formatter.immediate16(imm);
    }
  }

  void sbbl_rr(RegisterID src, RegisterID dst) {
    spew("sbbl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_SBB_GvEv, src, dst);
  }

  void subl_rr(RegisterID src, RegisterID dst) {
    spew("subl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_SUB_GvEv, src, dst);
  }

  void subw_rr(RegisterID src, RegisterID dst) {
    spew("subw %s, %s", GPReg16Name(src), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_SUB_GvEv, src, dst);
  }

  void subl_mr(int32_t offset, RegisterID base, RegisterID dst) {
    spew("subl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_SUB_GvEv, offset, base, dst);
  }

  void subl_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("subl %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, src);
  }

  void subw_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("subw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, src);
  }

  void subl_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("subl %s, " MEM_obs, GPReg32Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, index, scale, src);
  }

  void subw_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("subw %s, " MEM_obs, GPReg16Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, index, scale, src);
  }

  size_t subl_ir(int32_t imm, RegisterID dst) {
    spew("subl $%d, %s", imm, GPReg32Name(dst));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_SUB);
      m_formatter.immediate8s(imm);
      return 1;
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_SUB_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_SUB);
      }
      m_formatter.immediate32(imm);
      return 4;
    }
  }

  void subw_ir(int32_t imm, RegisterID dst) {
    spew("subw $%d, %s", int16_t(imm), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_SUB);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_SUB_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_SUB);
      }
      m_formatter.immediate16(imm);
    }
  }

  size_t subl_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("subl $%d, " MEM_ob, imm, ADDR_ob(offset, base));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_SUB);
      m_formatter.immediate8s(imm);
      return 1;
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_SUB);
      m_formatter.immediate32(imm);
      return 4;
    }
  }

  void subw_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("subw $%d, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_SUB);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_SUB);
      m_formatter.immediate16(imm);
    }
  }

  size_t subl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
                 int scale) {
    spew("subl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_SUB);
      m_formatter.immediate8s(imm);
      return 1;
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_SUB);
      m_formatter.immediate32(imm);
      return 1;
    }
  }

  void subw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("subw $%d, " MEM_obs, int16_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_SUB);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_SUB);
      m_formatter.immediate16(imm);
    }
  }

  void xorl_rr(RegisterID src, RegisterID dst) {
    spew("xorl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_XOR_GvEv, src, dst);
  }

  void xorw_rr(RegisterID src, RegisterID dst) {
    spew("xorw %s, %s", GPReg16Name(src), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_XOR_GvEv, src, dst);
  }

  void xorl_mr(int32_t offset, RegisterID base, RegisterID dst) {
    spew("xorl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    m_formatter.oneByteOp(OP_XOR_GvEv, offset, base, dst);
  }

  void xorl_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("xorl %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, src);
  }

  void xorw_rm(RegisterID src, int32_t offset, RegisterID base) {
    spew("xorw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, src);
  }

  void xorl_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("xorl %s, " MEM_obs, GPReg32Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, index, scale, src);
  }

  void xorw_rm(RegisterID src, int32_t offset, RegisterID base,
               RegisterID index, int scale) {
    spew("xorw %s, " MEM_obs, GPReg16Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, index, scale, src);
  }

  void xorl_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("xorl $0x%x, " MEM_ob, uint32_t(imm), ADDR_ob(offset, base));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_XOR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_XOR);
      m_formatter.immediate32(imm);
    }
  }

  void xorw_im(int32_t imm, int32_t offset, RegisterID base) {
    spew("xorw $0x%x, " MEM_ob, uint16_t(imm), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_XOR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_XOR);
      m_formatter.immediate16(imm);
    }
  }

  void xorl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("xorl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_XOR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_XOR);
      m_formatter.immediate32(imm);
    }
  }

  void xorw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index,
               int scale) {
    spew("xorw $%d, " MEM_obs, int16_t(imm),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale,
                            GROUP1_OP_XOR);
      m_formatter.immediate8s(imm);
    } else {
      m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale,
                            GROUP1_OP_XOR);
      m_formatter.immediate16(imm);
    }
  }

  void xorl_ir(int32_t imm, RegisterID dst) {
    spew("xorl $%d, %s", imm, GPReg32Name(dst));
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_XOR);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_XOR_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_XOR);
      }
      m_formatter.immediate32(imm);
    }
  }

  void xorw_ir(int32_t imm, RegisterID dst) {
    spew("xorw $%d, %s", int16_t(imm), GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (CAN_SIGN_EXTEND_8_32(imm)) {
      m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_XOR);
      m_formatter.immediate8s(imm);
    } else {
      if (dst == rax) {
        m_formatter.oneByteOp(OP_XOR_EAXIv);
      } else {
        m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_XOR);
      }
      m_formatter.immediate16(imm);
    }
  }

  void bswapl_r(RegisterID dst) {
    spew("bswap %s", GPReg32Name(dst));
    m_formatter.twoByteOp(OP2_BSWAP, dst);
  }

  void sarl_ir(int32_t imm, RegisterID dst) {
    MOZ_ASSERT(imm < 32);
    spew("sarl $%d, %s", imm, GPReg32Name(dst));
    if (imm == 1) {
      m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_SAR);
    } else {
      m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_SAR);
      m_formatter.immediate8u(imm);
    }
  }

  void sarl_CLr(RegisterID dst) {
    spew("sarl %%cl, %s", GPReg32Name(dst));
    m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_SAR);
  }

  void shrl_ir(int32_t imm, RegisterID dst) {
    MOZ_ASSERT(imm < 32);
    spew("shrl $%d, %s", imm, GPReg32Name(dst));
    if (imm == 1) {
      m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_SHR);
    } else {
      m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_SHR);
      m_formatter.immediate8u(imm);
    }
  }

  void shrl_CLr(RegisterID dst) {
    spew("shrl %%cl, %s", GPReg32Name(dst));
    m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_SHR);
  }

  void shrdl_CLr(RegisterID src, RegisterID dst) {
    spew("shrdl %%cl, %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.twoByteOp(OP2_SHRD_GvEv, dst, src);
  }

  void shldl_CLr(RegisterID src, RegisterID dst) {
    spew("shldl %%cl, %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.twoByteOp(OP2_SHLD_GvEv, dst, src);
  }

  void shll_ir(int32_t imm, RegisterID dst) {
    MOZ_ASSERT(imm < 32);
    spew("shll $%d, %s", imm, GPReg32Name(dst));
    if (imm == 1) {
      m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_SHL);
    } else {
      m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_SHL);
      m_formatter.immediate8u(imm);
    }
  }

  void shll_CLr(RegisterID dst) {
    spew("shll %%cl, %s", GPReg32Name(dst));
    m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_SHL);
  }

  void roll_ir(int32_t imm, RegisterID dst) {
    MOZ_ASSERT(imm < 32);
    spew("roll $%d, %s", imm, GPReg32Name(dst));
    if (imm == 1) {
      m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_ROL);
    } else {
      m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_ROL);
      m_formatter.immediate8u(imm);
    }
  }
  void rolw_ir(int32_t imm, RegisterID dst) {
    MOZ_ASSERT(imm < 32);
    spew("roll $%d, %s", imm, GPReg16Name(dst));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    if (imm == 1) {
      m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_ROL);
    } else {
      m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_ROL);
      m_formatter.immediate8u(imm);
    }
  }
  void roll_CLr(RegisterID dst) {
    spew("roll %%cl, %s", GPReg32Name(dst));
    m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_ROL);
  }

  void rorl_ir(int32_t imm, RegisterID dst) {
    MOZ_ASSERT(imm < 32);
    spew("rorl $%d, %s", imm, GPReg32Name(dst));
    if (imm == 1) {
      m_formatter.oneByteOp(OP_GROUP2_Ev1, dst, GROUP2_OP_ROR);
    } else {
      m_formatter.oneByteOp(OP_GROUP2_EvIb, dst, GROUP2_OP_ROR);
      m_formatter.immediate8u(imm);
    }
  }
  void rorl_CLr(RegisterID dst) {
    spew("rorl %%cl, %s", GPReg32Name(dst));
    m_formatter.oneByteOp(OP_GROUP2_EvCL, dst, GROUP2_OP_ROR);
  }

  void bsrl_rr(RegisterID src, RegisterID dst) {
    spew("bsrl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.twoByteOp(OP2_BSR_GvEv, src, dst);
  }

  void bsfl_rr(RegisterID src, RegisterID dst) {
    spew("bsfl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.twoByteOp(OP2_BSF_GvEv, src, dst);
  }

  void lzcntl_rr(RegisterID src, RegisterID dst) {
    spew("lzcntl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.legacySSEPrefix(VEX_SS);
    m_formatter.twoByteOp(OP2_LZCNT_GvEv, src, dst);
  }

  void tzcntl_rr(RegisterID src, RegisterID dst) {
    spew("tzcntl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.legacySSEPrefix(VEX_SS);
    m_formatter.twoByteOp(OP2_TZCNT_GvEv, src, dst);
  }

  void popcntl_rr(RegisterID src, RegisterID dst) {
    spew("popcntl %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.legacySSEPrefix(VEX_SS);
    m_formatter.twoByteOp(OP2_POPCNT_GvEv, src, dst);
  }

  void imull_rr(RegisterID src, RegisterID dst) {
    spew("imull %s, %s", GPReg32Name(src), GPReg32Name(dst));
    m_formatter.twoByteOp(OP2_IMUL_GvEv, src, dst);
  }

  void imull_r(RegisterID multiplier) {
    spew("imull %s", GPReg32Name(multiplier));
    m_formatter.oneByteOp(OP_GROUP3_Ev, multiplier, GROUP3_OP_IMUL);
  }

  void imull_mr(int32_t offset, RegisterID base, RegisterID dst) {
    spew("imull " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
    m_formatter.twoByteOp(OP2_IMUL_GvEv, offset, base, dst);
  }

  void imull_ir(int32_t value, RegisterID src, RegisterID dst) {
    spew("imull $%d, %s, %s", value, GPReg32Name(src), GPReg32Name(dst));
    if (CAN_SIGN_EXTEND_8_32(value)) {
      m_formatter.oneByteOp(OP_IMUL_GvEvIb, src, dst);
      m_formatter.immediate8s(value);
    } else {
      m_formatter.oneByteOp(OP_IMUL_GvEvIz, src, dst);
      m_formatter.immediate32(value);
    }
  }

  void mull_r(RegisterID multiplier) {
    spew("mull %s", GPReg32Name(multiplier));
    m_formatter.oneByteOp(OP_GROUP3_Ev, multiplier, GROUP3_OP_MUL);
  }

  void idivl_r(RegisterID divisor) {
    spew("idivl %s", GPReg32Name(divisor));
    m_formatter.oneByteOp(OP_GROUP3_Ev, divisor, GROUP3_OP_IDIV);
  }

  void divl_r(RegisterID divisor) {
    spew("div %s", GPReg32Name(divisor));
    m_formatter.oneByteOp(OP_GROUP3_Ev, divisor, GROUP3_OP_DIV);
  }

  void prefix_lock() {
    spew("lock");
    m_formatter.oneByteOp(PRE_LOCK);
  }

  void prefix_16_for_32() {
    spew("[16-bit operands next]");
    m_formatter.prefix(PRE_OPERAND_SIZE);
  }

  void incl_m32(int32_t offset, RegisterID base) {
    spew("incl " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_INC);
  }

  void decl_m32(int32_t offset, RegisterID base) {
    spew("decl " MEM_ob, ADDR_ob(offset, base));
    m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_DEC);
  }

  // Note that CMPXCHG performs comparison against REG = %al/%ax/%eax/%rax.
  // If %REG == [%base+offset], then %src -> [%base+offset].
  // Otherwise, [%base+offset] -> %REG.
  // For the 8-bit operations src must also be an 8-bit register.

  void cmpxchgb(RegisterID src, int32_t offset, RegisterID base) {
    spew("cmpxchgb %s, " MEM_ob, GPReg8Name(src), ADDR_ob(offset, base));
    m_formatter.twoByteOp8(OP2_CMPXCHG_GvEb, offset, base, src);
  }
  void cmpxchgb(RegisterID src, int32_t offset, RegisterID base,
                RegisterID index, int scale) {
    spew("cmpxchgb %s, " MEM_obs, GPReg8Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.twoByteOp8(OP2_CMPXCHG_GvEb, offset, base, index, scale, src);
  }
  void cmpxchgw(RegisterID src, int32_t offset, RegisterID base) {
    spew("cmpxchgw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, offset, base, src);
  }
  void cmpxchgw(RegisterID src, int32_t offset, RegisterID base,
                RegisterID index, int scale) {
    spew("cmpxchgw %s, " MEM_obs, GPReg16Name(src),
         ADDR_obs(offset, base, index, scale));
    m_formatter.prefix(PRE_OPERAND_SIZE);
    m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, offset, base, index, scale, src);
  }
  void cmpxchgl(RegisterID src, int32_t offset, RegisterID base) {
    spew("cmpxchgl %s, " MEM_ob, GPReg32Name(src), ADDR_ob(offset, base));
    m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, offset, base, src);
  }
  void cmpxchgl(RegisterID src, int32_t offset, RegisterID base,
                RegisterID index, int scale) {
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=94 H=100 G=96

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.