Patch supports Intel(R) AVX/AVX2 MOV Instruction
This patch enhances the existing ART-Compiler
to generate Intel(R) AVX/AVX2 MOV Instructions for
doing SIMD Operations on Intel(R) Architecture CPUs.
It also provides the framework for AVX/AVX2 Instruction
encoding and dissassembly
BUG: 127881558
Test: run-test gtest
Change-Id: I9386aecc134941a2d907f9ec6b2d5522ec5ff8b5
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index ff13ea3..471b314 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -19,6 +19,7 @@
#include <vector>
+#include "arch/x86_64/instruction_set_features_x86_64.h"
#include "base/arena_containers.h"
#include "base/array_ref.h"
#include "base/bit_utils.h"
@@ -353,8 +354,12 @@
class X86_64Assembler final : public Assembler {
public:
- explicit X86_64Assembler(ArenaAllocator* allocator)
- : Assembler(allocator), constant_area_(allocator) {}
+ explicit X86_64Assembler(ArenaAllocator* allocator,
+ const X86_64InstructionSetFeatures* instruction_set_features = nullptr)
+ : Assembler(allocator),
+ constant_area_(allocator),
+ has_AVX_(instruction_set_features != nullptr ? instruction_set_features->HasAVX(): false),
+ has_AVX2_(instruction_set_features != nullptr ? instruction_set_features->HasAVX2() : false) {}
virtual ~X86_64Assembler() {}
/*
@@ -415,6 +420,12 @@
void movaps(const Address& dst, XmmRegister src); // store aligned
void movups(const Address& dst, XmmRegister src); // store unaligned
+ void vmovaps(XmmRegister dst, XmmRegister src); // move
+ void vmovaps(XmmRegister dst, const Address& src); // load aligned
+ void vmovaps(const Address& dst, XmmRegister src); // store aligned
+ void vmovups(XmmRegister dst, const Address& src); // load unaligned
+ void vmovups(const Address& dst, XmmRegister src); // store unaligned
+
void movss(XmmRegister dst, const Address& src);
void movss(const Address& dst, XmmRegister src);
void movss(XmmRegister dst, XmmRegister src);
@@ -447,6 +458,12 @@
void movapd(const Address& dst, XmmRegister src); // store aligned
void movupd(const Address& dst, XmmRegister src); // store unaligned
+ void vmovapd(XmmRegister dst, XmmRegister src); // move
+ void vmovapd(XmmRegister dst, const Address& src); // load aligned
+ void vmovapd(const Address& dst, XmmRegister src); // store aligned
+ void vmovupd(XmmRegister dst, const Address& src); // load unaligned
+ void vmovupd(const Address& dst, XmmRegister src); // store unaligned
+
void movsd(XmmRegister dst, const Address& src);
void movsd(const Address& dst, XmmRegister src);
void movsd(XmmRegister dst, XmmRegister src);
@@ -471,6 +488,12 @@
void movdqa(const Address& dst, XmmRegister src); // store aligned
void movdqu(const Address& dst, XmmRegister src); // store unaligned
+ void vmovdqa(XmmRegister dst, XmmRegister src); // move
+ void vmovdqa(XmmRegister dst, const Address& src); // load aligned
+ void vmovdqa(const Address& dst, XmmRegister src); // store aligned
+ void vmovdqu(XmmRegister dst, const Address& src); // load unaligned
+ void vmovdqu(const Address& dst, XmmRegister src); // store unaligned
+
void paddb(XmmRegister dst, XmmRegister src); // no addr variant (for now)
void psubb(XmmRegister dst, XmmRegister src);
@@ -909,6 +932,8 @@
}
}
+ bool CpuHasAVXorAVX2FeatureFlag();
+
private:
void EmitUint8(uint8_t value);
void EmitInt32(int32_t value);
@@ -956,12 +981,22 @@
void EmitOptionalByteRegNormalizingRex32(CpuRegister dst, CpuRegister src);
void EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const Operand& operand);
- // Emit a 3 byte VEX Prefix
- uint8_t EmitVexByteZero(bool is_two_byte);
- uint8_t EmitVexByte1(bool r, bool x, bool b, int mmmmm);
- uint8_t EmitVexByte2(bool w , int l , X86_64ManagedRegister operand, int pp);
-
+ uint8_t EmitVexPrefixByteZero(bool is_twobyte_form);
+ uint8_t EmitVexPrefixByteOne(bool R, bool X, bool B, int SET_VEX_M);
+ uint8_t EmitVexPrefixByteOne(bool R,
+ X86_64ManagedRegister operand,
+ int SET_VEX_L,
+ int SET_VEX_PP);
+ uint8_t EmitVexPrefixByteTwo(bool W,
+ X86_64ManagedRegister operand,
+ int SET_VEX_L,
+ int SET_VEX_PP);
+ uint8_t EmitVexPrefixByteTwo(bool W,
+ int SET_VEX_L,
+ int SET_VEX_PP);
ConstantArea constant_area_;
+ bool has_AVX_; // x86 256bit SIMD AVX.
+ bool has_AVX2_; // x86 256bit SIMD AVX 2.0.
DISALLOW_COPY_AND_ASSIGN(X86_64Assembler);
};