Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Unified Diff: src/IceAssemblerX86Base.h

Issue 1216033004: Move X8632-specific Assembler stuff to Machine Traits. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceAssemblerX8632.cpp ('k') | src/IceAssemblerX86BaseImpl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceAssemblerX86Base.h
diff --git a/src/IceAssemblerX86Base.h b/src/IceAssemblerX86Base.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6516f607d31e915f0fd7f44fc68d1aa56064859
--- /dev/null
+++ b/src/IceAssemblerX86Base.h
@@ -0,0 +1,959 @@
+//===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===//
+//
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Modified by the Subzero authors.
+//
+//===----------------------------------------------------------------------===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AssemblerX86 template class for x86, the base of all
+// X86 assemblers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEASSEMBLERX86BASE_H
+#define SUBZERO_SRC_ICEASSEMBLERX86BASE_H
+
+#include "IceAssembler.h"
+#include "IceDefs.h"
+#include "IceOperand.h"
+#include "IceTypes.h"
+#include "IceUtils.h"
+
+namespace Ice {
+
+namespace X86Internal {
+
+template <class Machine> class AssemblerX86Base;
+template <class Machine> struct MachineTraits;
+
+constexpr int MAX_NOP_SIZE = 8;
+
+class Immediate {
+ Immediate(const Immediate &) = delete;
+ Immediate &operator=(const Immediate &) = delete;
+
+public:
+ explicit Immediate(int32_t value) : value_(value) {}
+
+ Immediate(RelocOffsetT offset, AssemblerFixup *fixup)
+ : value_(offset), fixup_(fixup) {
+ // Use the Offset in the "value" for now. If we decide to process fixups,
+ // we'll need to patch that offset with the true value.
+ }
+
+ int32_t value() const { return value_; }
+ AssemblerFixup *fixup() const { return fixup_; }
+
+ bool is_int8() const {
+ // We currently only allow 32-bit fixups, and they usually have value = 0,
+ // so if fixup_ != nullptr, it shouldn't be classified as int8/16.
+ return fixup_ == nullptr && Utils::IsInt(8, value_);
+ }
+ bool is_uint8() const {
+ return fixup_ == nullptr && Utils::IsUint(8, value_);
+ }
+ bool is_uint16() const {
+ return fixup_ == nullptr && Utils::IsUint(16, value_);
+ }
+
+private:
+ const int32_t value_;
+ AssemblerFixup *fixup_ = nullptr;
+};
+
+class Label {
+ Label(const Label &) = delete;
+ Label &operator=(const Label &) = delete;
+
+public:
+ Label() {
+ if (BuildDefs::asserts()) {
+ for (int i = 0; i < kMaxUnresolvedBranches; i++) {
+ unresolved_near_positions_[i] = -1;
+ }
+ }
+ }
+
+ ~Label() = default;
+
+ void FinalCheck() const {
+ // Assert if label is being destroyed with unresolved branches pending.
+ assert(!IsLinked());
+ assert(!HasNear());
+ }
+
+ // TODO(jvoung): why are labels offset by this?
+ static const uint32_t kWordSize = sizeof(uint32_t);
+
+ // Returns the position for bound labels (branches that come after this
+ // are considered backward branches). Cannot be used for unused or linked
+ // labels.
+ intptr_t Position() const {
+ assert(IsBound());
+ return -position_ - kWordSize;
+ }
+
+ // Returns the position of an earlier branch instruction that was linked
+ // to this label (branches that use this are considered forward branches).
+ // The linked instructions form a linked list, of sorts, using the
+ // instruction's displacement field for the location of the next
+ // instruction that is also linked to this label.
+ intptr_t LinkPosition() const {
+ assert(IsLinked());
+ return position_ - kWordSize;
+ }
+
+ // Returns the position of an earlier branch instruction which
+ // assumes that this label is "near", and bumps iterator to the
+ // next near position.
+ intptr_t NearPosition() {
+ assert(HasNear());
+ return unresolved_near_positions_[--num_unresolved_];
+ }
+
+ bool IsBound() const { return position_ < 0; }
+ bool IsLinked() const { return position_ > 0; }
+ bool IsUnused() const { return (position_ == 0) && (num_unresolved_ == 0); }
+ bool HasNear() const { return num_unresolved_ != 0; }
+
+private:
+ void BindTo(intptr_t position) {
+ assert(!IsBound());
+ assert(!HasNear());
+ position_ = -position - kWordSize;
+ assert(IsBound());
+ }
+
+ void LinkTo(intptr_t position) {
+ assert(!IsBound());
+ position_ = position + kWordSize;
+ assert(IsLinked());
+ }
+
+ void NearLinkTo(intptr_t position) {
+ assert(!IsBound());
+ assert(num_unresolved_ < kMaxUnresolvedBranches);
+ unresolved_near_positions_[num_unresolved_++] = position;
+ }
+
+ static constexpr int kMaxUnresolvedBranches = 20;
+
+ intptr_t position_ = 0;
+ intptr_t num_unresolved_ = 0;
+ // TODO(stichnot,jvoung): Can this instead be
+ // llvm::SmallVector<intptr_t, kMaxUnresolvedBranches> ?
+ intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
+
+ template <class> friend class AssemblerX86Base;
+};
+
+template <class Machine> class AssemblerX86Base : public Assembler {
+ AssemblerX86Base(const AssemblerX86Base &) = delete;
+ AssemblerX86Base &operator=(const AssemblerX86Base &) = delete;
+
+protected:
+ AssemblerX86Base(AssemblerKind Kind, bool use_far_branches)
+ : Assembler(Kind) {
+ // This mode is only needed and implemented for MIPS and ARM.
+ assert(!use_far_branches);
+ (void)use_far_branches;
+ }
+
+public:
+ using Traits = MachineTraits<Machine>;
+
+ ~AssemblerX86Base() override;
+
+ static const bool kNearJump = true;
+ static const bool kFarJump = false;
+
+ void alignFunction() override;
+
+ SizeT getBundleAlignLog2Bytes() const override { return 5; }
+
+ const char *getNonExecPadDirective() const override { return ".p2align"; }
+
+ llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override {
+ static const uint8_t Padding[] = {0xF4};
+ return llvm::ArrayRef<uint8_t>(Padding, 1);
+ }
+
+ void padWithNop(intptr_t Padding) override {
+ while (Padding > MAX_NOP_SIZE) {
+ nop(MAX_NOP_SIZE);
+ Padding -= MAX_NOP_SIZE;
+ }
+ if (Padding)
+ nop(Padding);
+ }
+
+ Label *GetOrCreateCfgNodeLabel(SizeT NodeNumber);
+ void bindCfgNodeLabel(SizeT NodeNumber) override;
+ Label *GetOrCreateLocalLabel(SizeT Number);
+ void BindLocalLabel(SizeT Number);
+
+ bool fixupIsPCRel(FixupKind Kind) const override {
+ // Currently assuming this is the only PC-rel relocation type used.
+ // TODO(jpp): Traits.PcRelTypes.count(Kind) != 0
+ return Kind == Traits::PcRelFixup;
+ }
+
+ // Operations to emit GPR instructions (and dispatch on operand type).
+ typedef void (AssemblerX86Base::*TypedEmitGPR)(Type,
+ typename Traits::GPRRegister);
+ typedef void (AssemblerX86Base::*TypedEmitAddr)(
+ Type, const typename Traits::Address &);
+ struct GPREmitterOneOp {
+ TypedEmitGPR Reg;
+ TypedEmitAddr Addr;
+ };
+
+ typedef void (AssemblerX86Base::*TypedEmitGPRGPR)(
+ Type, typename Traits::GPRRegister, typename Traits::GPRRegister);
+ typedef void (AssemblerX86Base::*TypedEmitGPRAddr)(
+ Type, typename Traits::GPRRegister, const typename Traits::Address &);
+ typedef void (AssemblerX86Base::*TypedEmitGPRImm)(
+ Type, typename Traits::GPRRegister, const Immediate &);
+ struct GPREmitterRegOp {
+ TypedEmitGPRGPR GPRGPR;
+ TypedEmitGPRAddr GPRAddr;
+ TypedEmitGPRImm GPRImm;
+ };
+
+ struct GPREmitterShiftOp {
+ // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are not.
+ // In practice, we always normalize the Dest to a Register first.
+ TypedEmitGPRGPR GPRGPR;
+ TypedEmitGPRImm GPRImm;
+ };
+
+ typedef void (AssemblerX86Base::*TypedEmitGPRGPRImm)(
+ Type, typename Traits::GPRRegister, typename Traits::GPRRegister,
+ const Immediate &);
+ struct GPREmitterShiftD {
+ // Technically AddrGPR and AddrGPRImm are also allowed, but in practice
+ // we always normalize Dest to a Register first.
+ TypedEmitGPRGPR GPRGPR;
+ TypedEmitGPRGPRImm GPRGPRImm;
+ };
+
+ typedef void (AssemblerX86Base::*TypedEmitAddrGPR)(
+ Type, const typename Traits::Address &, typename Traits::GPRRegister);
+ typedef void (AssemblerX86Base::*TypedEmitAddrImm)(
+ Type, const typename Traits::Address &, const Immediate &);
+ struct GPREmitterAddrOp {
+ TypedEmitAddrGPR AddrGPR;
+ TypedEmitAddrImm AddrImm;
+ };
+
+ // Operations to emit XMM instructions (and dispatch on operand type).
+ typedef void (AssemblerX86Base::*TypedEmitXmmXmm)(
+ Type, typename Traits::XmmRegister, typename Traits::XmmRegister);
+ typedef void (AssemblerX86Base::*TypedEmitXmmAddr)(
+ Type, typename Traits::XmmRegister, const typename Traits::Address &);
+ struct XmmEmitterRegOp {
+ TypedEmitXmmXmm XmmXmm;
+ TypedEmitXmmAddr XmmAddr;
+ };
+
+ typedef void (AssemblerX86Base::*EmitXmmXmm)(typename Traits::XmmRegister,
+ typename Traits::XmmRegister);
+ typedef void (AssemblerX86Base::*EmitXmmAddr)(
+ typename Traits::XmmRegister, const typename Traits::Address &);
+ typedef void (AssemblerX86Base::*EmitAddrXmm)(
+ const typename Traits::Address &, typename Traits::XmmRegister);
+ struct XmmEmitterMovOps {
+ EmitXmmXmm XmmXmm;
+ EmitXmmAddr XmmAddr;
+ EmitAddrXmm AddrXmm;
+ };
+
+ typedef void (AssemblerX86Base::*TypedEmitXmmImm)(
+ Type, typename Traits::XmmRegister, const Immediate &);
+
+ struct XmmEmitterShiftOp {
+ TypedEmitXmmXmm XmmXmm;
+ TypedEmitXmmAddr XmmAddr;
+ TypedEmitXmmImm XmmImm;
+ };
+
+ // Cross Xmm/GPR cast instructions.
+ template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp {
+ typedef void (AssemblerX86Base::*TypedEmitRegs)(Type, DReg_t, SReg_t);
+ typedef void (AssemblerX86Base::*TypedEmitAddr)(
+ Type, DReg_t, const typename Traits::Address &);
+
+ TypedEmitRegs RegReg;
+ TypedEmitAddr RegAddr;
+ };
+
+ // Three operand (potentially) cross Xmm/GPR instructions.
+ // The last operand must be an immediate.
+ template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter {
+ typedef void (AssemblerX86Base::*TypedEmitRegRegImm)(Type, DReg_t, SReg_t,
+ const Immediate &);
+ typedef void (AssemblerX86Base::*TypedEmitRegAddrImm)(
+ Type, DReg_t, const typename Traits::Address &, const Immediate &);
+
+ TypedEmitRegRegImm RegRegImm;
+ TypedEmitRegAddrImm RegAddrImm;
+ };
+
+ /*
+ * Emit Machine Instructions.
+ */
+ void call(typename Traits::GPRRegister reg);
+ void call(const typename Traits::Address &address);
+ void call(const ConstantRelocatable *label);
+ void call(const Immediate &abs_address);
+
+ static const intptr_t kCallExternalLabelSize = 5;
+
+ void pushl(typename Traits::GPRRegister reg);
+
+ void popl(typename Traits::GPRRegister reg);
+ void popl(const typename Traits::Address &address);
+
+ void pushal();
+ void popal();
+
+ void setcc(typename Traits::Cond::BrCond condition,
+ typename Traits::ByteRegister dst);
+ void setcc(typename Traits::Cond::BrCond condition,
+ const typename Traits::Address &address);
+
+ void mov(Type Ty, typename Traits::GPRRegister dst, const Immediate &src);
+ void mov(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+
+ void mov(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+ void mov(Type Ty, const typename Traits::Address &dst,
+ typename Traits::GPRRegister src);
+ void mov(Type Ty, const typename Traits::Address &dst, const Immediate &imm);
+
+ void movzx(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void movzx(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+ void movsx(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void movsx(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+
+ void lea(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+
+ void cmov(Type Ty, typename Traits::Cond::BrCond cond,
+ typename Traits::GPRRegister dst, typename Traits::GPRRegister src);
+ void cmov(Type Ty, typename Traits::Cond::BrCond cond,
+ typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+
+ void rep_movsb();
+
+ void movss(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void movss(Type Ty, const typename Traits::Address &dst,
+ typename Traits::XmmRegister src);
+ void movss(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+
+ void movd(typename Traits::XmmRegister dst, typename Traits::GPRRegister src);
+ void movd(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void movd(typename Traits::GPRRegister dst, typename Traits::XmmRegister src);
+ void movd(const typename Traits::Address &dst,
+ typename Traits::XmmRegister src);
+
+ void movq(typename Traits::XmmRegister dst, typename Traits::XmmRegister src);
+ void movq(const typename Traits::Address &dst,
+ typename Traits::XmmRegister src);
+ void movq(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void addss(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void addss(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void subss(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void subss(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void mulss(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void mulss(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void divss(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void divss(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void movaps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+
+ void movups(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void movups(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void movups(const typename Traits::Address &dst,
+ typename Traits::XmmRegister src);
+
+ void padd(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void padd(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void pand(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pand(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void pandn(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pandn(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void pmull(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pmull(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void pmuludq(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pmuludq(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void por(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void por(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void psub(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void psub(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void pxor(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pxor(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void psll(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void psll(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void psll(Type Ty, typename Traits::XmmRegister dst, const Immediate &src);
+
+ void psra(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void psra(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void psra(Type Ty, typename Traits::XmmRegister dst, const Immediate &src);
+ void psrl(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void psrl(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void psrl(Type Ty, typename Traits::XmmRegister dst, const Immediate &src);
+
+ void addps(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void addps(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void subps(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void subps(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void divps(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void divps(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void mulps(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void mulps(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void minps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void maxps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void andps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void andps(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void orps(typename Traits::XmmRegister dst, typename Traits::XmmRegister src);
+
+ void blendvps(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void blendvps(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void pblendvb(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pblendvb(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void cmpps(typename Traits::XmmRegister dst, typename Traits::XmmRegister src,
+ typename Traits::Cond::CmppsCond CmpCondition);
+ void cmpps(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src,
+ typename Traits::Cond::CmppsCond CmpCondition);
+
+ void sqrtps(typename Traits::XmmRegister dst);
+ void rsqrtps(typename Traits::XmmRegister dst);
+ void reciprocalps(typename Traits::XmmRegister dst);
+ void movhlps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void movlhps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void unpcklps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void unpckhps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void unpcklpd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void unpckhpd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+
+ void set1ps(typename Traits::XmmRegister dst,
+ typename Traits::GPRRegister tmp, const Immediate &imm);
+ void shufps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src, const Immediate &mask);
+
+ void minpd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void maxpd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void sqrtpd(typename Traits::XmmRegister dst);
+ void shufpd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src, const Immediate &mask);
+
+ void pshufd(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src, const Immediate &mask);
+ void pshufd(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src, const Immediate &mask);
+ void shufps(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src, const Immediate &mask);
+ void shufps(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src, const Immediate &mask);
+
+ void cvtdq2ps(Type, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void cvtdq2ps(Type, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void cvttps2dq(Type, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void cvttps2dq(Type, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void cvtsi2ss(Type DestTy, typename Traits::XmmRegister dst,
+ typename Traits::GPRRegister src);
+ void cvtsi2ss(Type DestTy, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void cvtfloat2float(Type SrcTy, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void cvtfloat2float(Type SrcTy, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ void cvttss2si(Type SrcTy, typename Traits::GPRRegister dst,
+ typename Traits::XmmRegister src);
+ void cvttss2si(Type SrcTy, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+
+ void ucomiss(Type Ty, typename Traits::XmmRegister a,
+ typename Traits::XmmRegister b);
+ void ucomiss(Type Ty, typename Traits::XmmRegister a,
+ const typename Traits::Address &b);
+
+ void movmskpd(typename Traits::GPRRegister dst,
+ typename Traits::XmmRegister src);
+ void movmskps(typename Traits::GPRRegister dst,
+ typename Traits::XmmRegister src);
+
+ void sqrtss(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void sqrtss(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+
+ void xorpd(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void xorpd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void xorps(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void xorps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+
+ void andpd(typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void andpd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+
+ void orpd(typename Traits::XmmRegister dst, typename Traits::XmmRegister src);
+
+ void insertps(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src, const Immediate &imm);
+ void insertps(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src, const Immediate &imm);
+
+ void pinsr(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::GPRRegister src, const Immediate &imm);
+ void pinsr(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src, const Immediate &imm);
+
+ void pextr(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::XmmRegister src, const Immediate &imm);
+ void pextr(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src, const Immediate &imm);
+
+ void pmovsxdq(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+
+ void pcmpeq(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pcmpeq(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+ void pcmpgt(Type Ty, typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src);
+ void pcmpgt(Type Ty, typename Traits::XmmRegister dst,
+ const typename Traits::Address &src);
+
+ enum RoundingMode {
+ kRoundToNearest = 0x0,
+ kRoundDown = 0x1,
+ kRoundUp = 0x2,
+ kRoundToZero = 0x3
+ };
+ void roundsd(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src, RoundingMode mode);
+
+ void fld(Type Ty, const typename Traits::Address &src);
+ void fstp(Type Ty, const typename Traits::Address &dst);
+ void fstp(typename Traits::X87STRegister st);
+
+ void fnstcw(const typename Traits::Address &dst);
+ void fldcw(const typename Traits::Address &src);
+
+ void fistpl(const typename Traits::Address &dst);
+ void fistps(const typename Traits::Address &dst);
+ void fildl(const typename Traits::Address &src);
+ void filds(const typename Traits::Address &src);
+
+ void fincstp();
+
+ void cmp(Type Ty, typename Traits::GPRRegister reg0,
+ typename Traits::GPRRegister reg1);
+ void cmp(Type Ty, typename Traits::GPRRegister reg,
+ const typename Traits::Address &address);
+ void cmp(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void cmp(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void cmp(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void test(Type Ty, typename Traits::GPRRegister reg0,
+ typename Traits::GPRRegister reg1);
+ void test(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void test(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void test(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void And(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void And(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &address);
+ void And(Type Ty, typename Traits::GPRRegister dst, const Immediate &imm);
+ void And(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void And(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void Or(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void Or(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &address);
+ void Or(Type Ty, typename Traits::GPRRegister dst, const Immediate &imm);
+ void Or(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void Or(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void Xor(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void Xor(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &address);
+ void Xor(Type Ty, typename Traits::GPRRegister dst, const Immediate &imm);
+ void Xor(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void Xor(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void add(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void add(Type Ty, typename Traits::GPRRegister reg,
+ const typename Traits::Address &address);
+ void add(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void add(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void add(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void adc(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void adc(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &address);
+ void adc(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void adc(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void adc(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void sub(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void sub(Type Ty, typename Traits::GPRRegister reg,
+ const typename Traits::Address &address);
+ void sub(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void sub(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void sub(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void sbb(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void sbb(Type Ty, typename Traits::GPRRegister reg,
+ const typename Traits::Address &address);
+ void sbb(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void sbb(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+ void sbb(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+
+ void cbw();
+ void cwd();
+ void cdq();
+
+ void div(Type Ty, typename Traits::GPRRegister reg);
+ void div(Type Ty, const typename Traits::Address &address);
+
+ void idiv(Type Ty, typename Traits::GPRRegister reg);
+ void idiv(Type Ty, const typename Traits::Address &address);
+
+ void imul(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void imul(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void imul(Type Ty, typename Traits::GPRRegister reg,
+ const typename Traits::Address &address);
+
+ void imul(Type Ty, typename Traits::GPRRegister reg);
+ void imul(Type Ty, const typename Traits::Address &address);
+
+ void mul(Type Ty, typename Traits::GPRRegister reg);
+ void mul(Type Ty, const typename Traits::Address &address);
+
+ void incl(typename Traits::GPRRegister reg);
+ void incl(const typename Traits::Address &address);
+
+ void decl(typename Traits::GPRRegister reg);
+ void decl(const typename Traits::Address &address);
+
+ void rol(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void rol(Type Ty, typename Traits::GPRRegister operand,
+ typename Traits::GPRRegister shifter);
+ void rol(Type Ty, const typename Traits::Address &operand,
+ typename Traits::GPRRegister shifter);
+
+ void shl(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void shl(Type Ty, typename Traits::GPRRegister operand,
+ typename Traits::GPRRegister shifter);
+ void shl(Type Ty, const typename Traits::Address &operand,
+ typename Traits::GPRRegister shifter);
+
+ void shr(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void shr(Type Ty, typename Traits::GPRRegister operand,
+ typename Traits::GPRRegister shifter);
+ void shr(Type Ty, const typename Traits::Address &operand,
+ typename Traits::GPRRegister shifter);
+
+ void sar(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm);
+ void sar(Type Ty, typename Traits::GPRRegister operand,
+ typename Traits::GPRRegister shifter);
+ void sar(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister shifter);
+
+ void shld(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void shld(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src, const Immediate &imm);
+ void shld(Type Ty, const typename Traits::Address &operand,
+ typename Traits::GPRRegister src);
+ void shrd(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void shrd(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src, const Immediate &imm);
+ void shrd(Type Ty, const typename Traits::Address &dst,
+ typename Traits::GPRRegister src);
+
+ void neg(Type Ty, typename Traits::GPRRegister reg);
+ void neg(Type Ty, const typename Traits::Address &addr);
+ void notl(typename Traits::GPRRegister reg);
+
+ void bsf(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void bsf(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+ void bsr(Type Ty, typename Traits::GPRRegister dst,
+ typename Traits::GPRRegister src);
+ void bsr(Type Ty, typename Traits::GPRRegister dst,
+ const typename Traits::Address &src);
+
+ void bswap(Type Ty, typename Traits::GPRRegister reg);
+
+ void bt(typename Traits::GPRRegister base,
+ typename Traits::GPRRegister offset);
+
+ void ret();
+ void ret(const Immediate &imm);
+
+ // 'size' indicates size in bytes and must be in the range 1..8.
+ void nop(int size = 1);
+ void int3();
+ void hlt();
+ void ud2();
+
+ void j(typename Traits::Cond::BrCond condition, Label *label,
+ bool near = kFarJump);
+ void j(typename Traits::Cond::BrCond condition,
+ const ConstantRelocatable *label);
+
+ void jmp(typename Traits::GPRRegister reg);
+ void jmp(Label *label, bool near = kFarJump);
+ void jmp(const ConstantRelocatable *label);
+
+ void mfence();
+
+ void lock();
+ void cmpxchg(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg, bool Locked);
+ void cmpxchg8b(const typename Traits::Address &address, bool Locked);
+ void xadd(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg, bool Locked);
+ void xchg(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+
+ void emitSegmentOverride(uint8_t prefix);
+
+ intptr_t preferredLoopAlignment() { return 16; }
+ void align(intptr_t alignment, intptr_t offset);
+ void bind(Label *label);
+
+ intptr_t CodeSize() const { return Buffer.size(); }
+
+private:
+ inline void emitUint8(uint8_t value);
+ inline void emitInt16(int16_t value);
+ inline void emitInt32(int32_t value);
+ inline void emitRegisterOperand(int rm, int reg);
+ inline void emitXmmRegisterOperand(int rm, typename Traits::XmmRegister reg);
+ inline void emitFixup(AssemblerFixup *fixup);
+ inline void emitOperandSizeOverride();
+
+ void emitOperand(int rm, const typename Traits::Operand &operand);
+ void emitImmediate(Type ty, const Immediate &imm);
+ void emitComplexI8(int rm, const typename Traits::Operand &operand,
+ const Immediate &immediate);
+ void emitComplex(Type Ty, int rm, const typename Traits::Operand &operand,
+ const Immediate &immediate);
+ void emitLabel(Label *label, intptr_t instruction_size);
+ void emitLabelLink(Label *label);
+ void emitNearLabelLink(Label *label);
+
+ void emitGenericShift(int rm, Type Ty, typename Traits::GPRRegister reg,
+ const Immediate &imm);
+ void emitGenericShift(int rm, Type Ty,
+ const typename Traits::Operand &operand,
+ typename Traits::GPRRegister shifter);
+
+ typedef std::vector<Label *> LabelVector;
+ // A vector of pool-allocated x86 labels for CFG nodes.
+ LabelVector CfgNodeLabels;
+ // A vector of pool-allocated x86 labels for Local labels.
+ LabelVector LocalLabels;
+
+ Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels);
+
+ // The arith_int() methods factor out the commonality between the encodings of
+ // add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag
+ // parameter is statically asserted to be less than 8.
+ template <uint32_t Tag>
+ void arith_int(Type Ty, typename Traits::GPRRegister reg,
+ const Immediate &imm);
+
+ template <uint32_t Tag>
+ void arith_int(Type Ty, typename Traits::GPRRegister reg0,
+ typename Traits::GPRRegister reg1);
+
+ template <uint32_t Tag>
+ void arith_int(Type Ty, typename Traits::GPRRegister reg,
+ const typename Traits::Address &address);
+
+ template <uint32_t Tag>
+ void arith_int(Type Ty, const typename Traits::Address &address,
+ typename Traits::GPRRegister reg);
+
+ template <uint32_t Tag>
+ void arith_int(Type Ty, const typename Traits::Address &address,
+ const Immediate &imm);
+};
+
+template <class Machine>
+inline void AssemblerX86Base<Machine>::emitUint8(uint8_t value) {
+ Buffer.emit<uint8_t>(value);
+}
+
+template <class Machine>
+inline void AssemblerX86Base<Machine>::emitInt16(int16_t value) {
+ Buffer.emit<int16_t>(value);
+}
+
+template <class Machine>
+inline void AssemblerX86Base<Machine>::emitInt32(int32_t value) {
+ Buffer.emit<int32_t>(value);
+}
+
+template <class Machine>
+inline void AssemblerX86Base<Machine>::emitRegisterOperand(int rm, int reg) {
+ assert(rm >= 0 && rm < 8);
+ Buffer.emit<uint8_t>(0xC0 + (rm << 3) + reg);
+}
+
+template <class Machine>
+inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand(
+ int rm, typename Traits::XmmRegister reg) {
+ emitRegisterOperand(rm, static_cast<typename Traits::GPRRegister>(reg));
+}
+
+template <class Machine>
+inline void AssemblerX86Base<Machine>::emitFixup(AssemblerFixup *fixup) {
+ Buffer.emitFixup(fixup);
+}
+
+template <class Machine>
+inline void AssemblerX86Base<Machine>::emitOperandSizeOverride() {
+ emitUint8(0x66);
+}
+
+} // end of namespace X86Internal
+
+namespace X8632 {
+using Immediate = ::Ice::X86Internal::Immediate;
+using Label = ::Ice::X86Internal::Label;
+} // end of namespace X8632
+} // end of namespace Ice
+
+#include "IceAssemblerX86BaseImpl.h"
+
+#endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H
« no previous file with comments | « src/IceAssemblerX8632.cpp ('k') | src/IceAssemblerX86BaseImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698