| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
| * vim: set ts=8 sts=4 et sw=4 tw=99: |
| * This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| #ifndef jit_x86_BaseAssembler_x86_h |
| #define jit_x86_BaseAssembler_x86_h |
| |
| #include "jit/x86-shared/BaseAssembler-x86-shared.h" |
| |
| namespace js { |
| namespace jit { |
| |
| namespace X86Encoding { |
| |
| class BaseAssemblerX86 : public BaseAssembler |
| { |
| public: |
| |
| // Arithmetic operations: |
| |
| void adcl_ir(int32_t imm, RegisterID dst) |
| { |
| spew("adcl $%d, %s", imm, GPReg32Name(dst)); |
| MOZ_ASSERT(CAN_SIGN_EXTEND_8_32(imm)); |
| m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_ADC); |
| m_formatter.immediate8s(imm); |
| } |
| |
| void adcl_im(int32_t imm, const void* addr) |
| { |
| spew("adcl %d, %p", imm, addr); |
| if (CAN_SIGN_EXTEND_8_32(imm)) { |
| m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADC); |
| m_formatter.immediate8s(imm); |
| } else { |
| m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADC); |
| m_formatter.immediate32(imm); |
| } |
| } |
| |
| void adcl_rr(RegisterID src, RegisterID dst) |
| { |
| spew("adcl %s, %s", GPReg32Name(src), GPReg32Name(dst)); |
| m_formatter.oneByteOp(OP_ADC_GvEv, src, dst); |
| } |
| |
| using BaseAssembler::andl_im; |
| void andl_im(int32_t imm, const void* addr) |
| { |
| spew("andl $0x%x, %p", imm, addr); |
| if (CAN_SIGN_EXTEND_8_32(imm)) { |
| m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_AND); |
| m_formatter.immediate8s(imm); |
| } else { |
| m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_AND); |
| m_formatter.immediate32(imm); |
| } |
| } |
| |
| using BaseAssembler::orl_im; |
| void orl_im(int32_t imm, const void* addr) |
| { |
| spew("orl $0x%x, %p", imm, addr); |
| if (CAN_SIGN_EXTEND_8_32(imm)) { |
| m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_OR); |
| m_formatter.immediate8s(imm); |
| } else { |
| m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_OR); |
| m_formatter.immediate32(imm); |
| } |
| } |
| |
| using BaseAssembler::subl_im; |
| void subl_im(int32_t imm, const void* addr) |
| { |
| spew("subl $%d, %p", imm, addr); |
| if (CAN_SIGN_EXTEND_8_32(imm)) { |
| m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_SUB); |
| m_formatter.immediate8s(imm); |
| } else { |
| m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_SUB); |
| m_formatter.immediate32(imm); |
| } |
| } |
| |
| void shldl_irr(int32_t imm, RegisterID src, RegisterID dst) |
| { |
| MOZ_ASSERT(imm < 32); |
| spew("shldl $%d, %s, %s", imm, GPReg32Name(src), GPReg32Name(dst)); |
| m_formatter.twoByteOp8(OP2_SHLD, dst, src); |
| m_formatter.immediate8u(imm); |
| } |
| |
| void shrdl_irr(int32_t imm, RegisterID src, RegisterID dst) |
| { |
| MOZ_ASSERT(imm < 32); |
| spew("shrdl $%d, %s, %s", imm, GPReg32Name(src), GPReg32Name(dst)); |
| m_formatter.twoByteOp8(OP2_SHRD, dst, src); |
| m_formatter.immediate8u(imm); |
| } |
| |
| // SSE operations: |
| |
| using BaseAssembler::vcvtsi2sd_mr; |
| void vcvtsi2sd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vcvtsi2sd", VEX_SD, OP2_CVTSI2SD_VsdEd, address, src0, dst); |
| } |
| |
| using BaseAssembler::vmovaps_mr; |
| void vmovaps_mr(const void* address, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vmovaps", VEX_PS, OP2_MOVAPS_VsdWsd, address, invalid_xmm, dst); |
| } |
| |
| using BaseAssembler::vmovdqa_mr; |
| void vmovdqa_mr(const void* address, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vmovdqa", VEX_PD, OP2_MOVDQ_VdqWdq, address, invalid_xmm, dst); |
| } |
| |
| void vhaddpd_rr(XMMRegisterID src, XMMRegisterID dst) |
| { |
| twoByteOpSimdFlags("vhaddpd", VEX_PD, OP2_HADDPD, src, dst); |
| } |
| |
| void vsubpd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, src1, src0, dst); |
| } |
| void vsubpd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, offset, base, src0, dst); |
| } |
| void vsubpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, address, src0, dst); |
| } |
| |
| void vpunpckldq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) { |
| twoByteOpSimd("vpunpckldq", VEX_PD, OP2_PUNPCKLDQ, src1, src0, dst); |
| } |
| void vpunpckldq_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vpunpckldq", VEX_PD, OP2_PUNPCKLDQ, offset, base, src0, dst); |
| } |
| void vpunpckldq_mr(const void* addr, XMMRegisterID src0, XMMRegisterID dst) |
| { |
| twoByteOpSimd("vpunpckldq", VEX_PD, OP2_PUNPCKLDQ, addr, src0, dst); |
| } |
| |
| // Misc instructions: |
| |
| void pusha() |
| { |
| spew("pusha"); |
| m_formatter.oneByteOp(OP_PUSHA); |
| } |
| |
| void popa() |
| { |
| spew("popa"); |
| m_formatter.oneByteOp(OP_POPA); |
| } |
| }; |
| |
| typedef BaseAssemblerX86 BaseAssemblerSpecific; |
| |
| } // namespace X86Encoding |
| |
| } // namespace jit |
| } // namespace js |
| |
| #endif /* jit_x86_BaseAssembler_x86_h */ |