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

Unified Diff: unittest/AssemblerX8632/X87.cpp

Issue 1224173006: Adds the x86-64 assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments; make format Created 5 years, 5 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 | « unittest/AssemblerX8632/TestUtil.h ('k') | unittest/AssemblerX8632/XmmArith.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: unittest/AssemblerX8632/X87.cpp
diff --git a/unittest/AssemblerX8632/X87.cpp b/unittest/AssemblerX8632/X87.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3f38a16c19907593b2f3fdd3d3a48a01b34436b
--- /dev/null
+++ b/unittest/AssemblerX8632/X87.cpp
@@ -0,0 +1,267 @@
+//===- subzero/unittest/AssemblerX8632/X87.cpp ----------------------------===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "AssemblerX8632/TestUtil.h"
+
+namespace Ice {
+namespace X8632 {
+namespace Test {
+namespace {
+
+TEST_F(AssemblerX8632LowLevelTest, Fld) {
+ __ fld(IceType_f32, Address(GPRRegister::Encoded_Reg_ebp, 1));
+ __ fld(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000));
+
+ constexpr size_t ByteCount = 9;
+ ASSERT_EQ(ByteCount, codeBytesSize());
+
+ constexpr uint8_t Fld32Opcode = 0xd9;
+ constexpr uint8_t Fld32ModRM = (/*mod*/ 1 << 6) | (/*reg*/ 0 << 3) |
+ (/*rm*/ GPRRegister::Encoded_Reg_ebp);
+ constexpr uint8_t Fld64Opcode = 0xdd;
+ constexpr uint8_t Fld64ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 0 << 3) |
+ (/*rm*/ GPRRegister::Encoded_Reg_ebp);
+ verifyBytes<ByteCount>(codeBytes(), Fld32Opcode, Fld32ModRM, 0x01,
+ Fld64Opcode, Fld64ModRM, 0x00, 0x00, 0x01, 0x00);
+}
+
+TEST_F(AssemblerX8632LowLevelTest, FstpAddr) {
+ __ fstp(IceType_f32, Address(GPRRegister::Encoded_Reg_ebp, 1));
+ __ fstp(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000));
+
+ constexpr size_t ByteCount = 9;
+ ASSERT_EQ(ByteCount, codeBytesSize());
+
+ constexpr uint8_t Fld32Opcode = 0xd9;
+ constexpr uint8_t Fld32ModRM = (/*mod*/ 1 << 6) | (/*reg*/ 3 << 3) |
+ (/*rm*/ GPRRegister::Encoded_Reg_ebp);
+ constexpr uint8_t Fld64Opcode = 0xdd;
+ constexpr uint8_t Fld64ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 3 << 3) |
+ (/*rm*/ GPRRegister::Encoded_Reg_ebp);
+ verifyBytes<ByteCount>(codeBytes(), Fld32Opcode, Fld32ModRM, 0x01,
+ Fld64Opcode, Fld64ModRM, 0x00, 0x00, 0x01, 0x00);
+}
+
+TEST_F(AssemblerX8632LowLevelTest, Fincstp) {
+ __ fincstp();
+
+ constexpr size_t ByteCount = 2;
+ ASSERT_EQ(ByteCount, codeBytesSize());
+
+ verifyBytes<ByteCount>(codeBytes(), 0xD9, 0XF7);
+}
+
+TEST_F(AssemblerX8632LowLevelTest, FnstcwAddr) {
+ __ fnstcw(Address(GPRRegister::Encoded_Reg_ebp, 0x12345));
+
+ constexpr size_t ByteCount = 6;
+ ASSERT_EQ(ByteCount, codeBytesSize());
+
+ constexpr uint8_t Opcode = 0xd9;
+ constexpr uint8_t ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 7 << 3) |
+ (/*rm*/ GPRRegister::Encoded_Reg_ebp);
+ verifyBytes<ByteCount>(codeBytes(), Opcode, ModRM, 0x45, 0x23, 0x01, 0x00);
+}
+
+TEST_F(AssemblerX8632LowLevelTest, FldcwAddr) {
+ __ fldcw(Address(GPRRegister::Encoded_Reg_ebp, 0x12345));
+
+ constexpr size_t ByteCount = 6;
+ ASSERT_EQ(ByteCount, codeBytesSize());
+
+ constexpr uint8_t Opcode = 0xd9;
+ constexpr uint8_t ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 5 << 3) |
+ (/*rm*/ GPRRegister::Encoded_Reg_ebp);
+ verifyBytes<ByteCount>(codeBytes(), Opcode, ModRM, 0x45, 0x23, 0x01, 0x00);
+}
+
+TEST_F(AssemblerX8632Test, FstpSt) {
+#define TestFstpSt(Size, MemorySize, Type) \
+ do { \
+ const uint32_t T1 = allocate##MemorySize(); \
+ const Type OldValue1 = -1.0f; \
+ const uint32_t T2 = allocate##MemorySize(); \
+ const Type OldValue2 = -2.0f; \
+ const uint32_t T3 = allocate##MemorySize(); \
+ const Type OldValue3 = -3.0f; \
+ const uint32_t T4 = allocate##MemorySize(); \
+ const Type OldValue4 = -4.0f; \
+ const uint32_t T5 = allocate##MemorySize(); \
+ const Type OldValue5 = -5.0f; \
+ const uint32_t T6 = allocate##MemorySize(); \
+ const Type OldValue6 = -6.0f; \
+ const uint32_t T7 = allocate##MemorySize(); \
+ const Type OldValue7 = -7.0f; \
+ \
+ const uint32_t N7 = allocate##MemorySize(); \
+ constexpr Type NewValue7 = 777.77f; \
+ const uint32_t N6 = allocate##MemorySize(); \
+ constexpr Type NewValue6 = 666.66f; \
+ const uint32_t N5 = allocate##MemorySize(); \
+ constexpr Type NewValue5 = 555.55f; \
+ const uint32_t N4 = allocate##MemorySize(); \
+ constexpr Type NewValue4 = 444.44f; \
+ const uint32_t N3 = allocate##MemorySize(); \
+ constexpr Type NewValue3 = 333.33f; \
+ const uint32_t N2 = allocate##MemorySize(); \
+ constexpr Type NewValue2 = 222.22f; \
+ const uint32_t N1 = allocate##MemorySize(); \
+ constexpr Type NewValue1 = 111.11f; \
+ \
+ __ fincstp(); \
+ __ fincstp(); \
+ __ fincstp(); \
+ __ fincstp(); \
+ __ fincstp(); \
+ __ fincstp(); \
+ __ fincstp(); \
+ \
+ __ fld(IceType_f##Size, dwordAddress(N7)); \
+ __ fstp(X87STRegister::Encoded_X87ST_7); \
+ __ fld(IceType_f##Size, dwordAddress(N6)); \
+ __ fstp(X87STRegister::Encoded_X87ST_6); \
+ __ fld(IceType_f##Size, dwordAddress(N5)); \
+ __ fstp(X87STRegister::Encoded_X87ST_5); \
+ __ fld(IceType_f##Size, dwordAddress(N4)); \
+ __ fstp(X87STRegister::Encoded_X87ST_4); \
+ __ fld(IceType_f##Size, dwordAddress(N3)); \
+ __ fstp(X87STRegister::Encoded_X87ST_3); \
+ __ fld(IceType_f##Size, dwordAddress(N2)); \
+ __ fstp(X87STRegister::Encoded_X87ST_2); \
+ __ fld(IceType_f##Size, dwordAddress(N1)); \
+ __ fstp(X87STRegister::Encoded_X87ST_1); \
+ \
+ __ fstp(IceType_f##Size, dwordAddress(T1)); \
+ __ fstp(IceType_f##Size, dwordAddress(T2)); \
+ __ fstp(IceType_f##Size, dwordAddress(T3)); \
+ __ fstp(IceType_f##Size, dwordAddress(T4)); \
+ __ fstp(IceType_f##Size, dwordAddress(T5)); \
+ __ fstp(IceType_f##Size, dwordAddress(T6)); \
+ __ fstp(IceType_f##Size, dwordAddress(T7)); \
+ \
+ AssembledTest test = assemble(); \
+ test.set##MemorySize##To(T1, OldValue1); \
+ test.set##MemorySize##To(N1, NewValue1); \
+ test.set##MemorySize##To(T2, OldValue2); \
+ test.set##MemorySize##To(N2, NewValue2); \
+ test.set##MemorySize##To(T3, OldValue3); \
+ test.set##MemorySize##To(N3, NewValue3); \
+ test.set##MemorySize##To(T4, OldValue4); \
+ test.set##MemorySize##To(N4, NewValue4); \
+ test.set##MemorySize##To(T5, OldValue5); \
+ test.set##MemorySize##To(N5, NewValue5); \
+ test.set##MemorySize##To(T6, OldValue6); \
+ test.set##MemorySize##To(N6, NewValue6); \
+ test.set##MemorySize##To(T7, OldValue7); \
+ test.set##MemorySize##To(N7, NewValue7); \
+ \
+ test.run(); \
+ \
+ ASSERT_FLOAT_EQ(NewValue1, test.contentsOf##MemorySize<Type>(T1)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue1, test.contentsOf##MemorySize<Type>(N1)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue2, test.contentsOf##MemorySize<Type>(T2)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue2, test.contentsOf##MemorySize<Type>(N2)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue3, test.contentsOf##MemorySize<Type>(T3)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue3, test.contentsOf##MemorySize<Type>(N3)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue4, test.contentsOf##MemorySize<Type>(T4)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue4, test.contentsOf##MemorySize<Type>(N4)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue5, test.contentsOf##MemorySize<Type>(T5)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue5, test.contentsOf##MemorySize<Type>(N5)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue6, test.contentsOf##MemorySize<Type>(T6)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue6, test.contentsOf##MemorySize<Type>(N6)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue7, test.contentsOf##MemorySize<Type>(T7)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ ASSERT_FLOAT_EQ(NewValue7, test.contentsOf##MemorySize<Type>(N7)) \
+ << "(" #Size ", " #MemorySize ", " #Type ")"; \
+ \
+ reset(); \
+ } while (0)
+
+ TestFstpSt(32, Dword, float);
+ TestFstpSt(64, Qword, double);
+
+#undef TestFstpSt
+}
+
+TEST_F(AssemblerX8632Test, Fild) {
+#define TestFild(OperandType, Size, MemorySize, FpType, IntType) \
+ do { \
+ const uint32_t T0 = allocate##MemorySize(); \
+ constexpr IntType V0 = 0x1234; \
+ \
+ __ fild##OperandType(dwordAddress(T0)); \
+ __ fstp(IceType_f##Size, dwordAddress(T0)); \
+ \
+ AssembledTest test = assemble(); \
+ \
+ test.set##MemorySize##To(T0, V0); \
+ test.run(); \
+ \
+ ASSERT_FLOAT_EQ(static_cast<FpType>(V0), \
+ test.contentsOf##MemorySize<FpType>(T0)) \
+ << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType \
+ ", " #IntType ")"; \
+ \
+ reset(); \
+ } while (0)
+
+ TestFild(s, 32, Dword, float, uint32_t);
+ TestFild(l, 64, Qword, double, uint64_t);
+#undef TestFild
+}
+
+TEST_F(AssemblerX8632Test, Fistp) {
+#define TestFistp(OperandType, Size, MemorySize, FpType, IntType) \
+ do { \
+ const uint32_t T0 = allocate##MemorySize(); \
+ constexpr IntType V0 = 0x1234; \
+ const uint32_t T1 = allocate##MemorySize(); \
+ constexpr IntType V1 = 0xFFFF; \
+ \
+ __ fild##OperandType(dwordAddress(T0)); \
+ __ fistp##OperandType(dwordAddress(T1)); \
+ \
+ AssembledTest test = assemble(); \
+ \
+ test.set##MemorySize##To(T0, V0); \
+ test.set##MemorySize##To(T1, V1); \
+ test.run(); \
+ \
+ ASSERT_EQ(static_cast<IntType>(V0), \
+ test.contentsOf##MemorySize<IntType>(T0)) \
+ << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType \
+ ", " #IntType ")"; \
+ ASSERT_EQ(static_cast<IntType>(V0), \
+ test.contentsOf##MemorySize<IntType>(T1)) \
+ << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType \
+ ", " #IntType ")"; \
+ \
+ reset(); \
+ } while (0)
+
+ TestFistp(s, 32, Dword, float, uint32_t);
+ TestFistp(l, 64, Qword, double, uint64_t);
+#undef TestFistp
+}
+
+} // end of anonymous namespace
+} // end of namespace Test
+} // end of namespace X8632
+} // end of namespace Ice
« no previous file with comments | « unittest/AssemblerX8632/TestUtil.h ('k') | unittest/AssemblerX8632/XmmArith.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698