• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- subzero/unittest/AssemblerX8632/X87.cpp ----------------------------===//
2 //
3 //                        The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "AssemblerX8632/TestUtil.h"
10 
11 namespace Ice {
12 namespace X8632 {
13 namespace Test {
14 namespace {
15 
TEST_F(AssemblerX8632LowLevelTest,Fld)16 TEST_F(AssemblerX8632LowLevelTest, Fld) {
17   __ fld(IceType_f32,
18          Address(GPRRegister::Encoded_Reg_ebp, 1, AssemblerFixup::NoFixup));
19   __ fld(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000,
20                               AssemblerFixup::NoFixup));
21 
22   constexpr size_t ByteCount = 9;
23   ASSERT_EQ(ByteCount, codeBytesSize());
24 
25   constexpr uint8_t Fld32Opcode = 0xd9;
26   constexpr uint8_t Fld32ModRM = (/*mod*/ 1 << 6) | (/*reg*/ 0 << 3) |
27                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
28   constexpr uint8_t Fld64Opcode = 0xdd;
29   constexpr uint8_t Fld64ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 0 << 3) |
30                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
31   verifyBytes<ByteCount>(codeBytes(), Fld32Opcode, Fld32ModRM, 0x01,
32                          Fld64Opcode, Fld64ModRM, 0x00, 0x00, 0x01, 0x00);
33 }
34 
TEST_F(AssemblerX8632LowLevelTest,FstpAddr)35 TEST_F(AssemblerX8632LowLevelTest, FstpAddr) {
36   __ fstp(IceType_f32,
37           Address(GPRRegister::Encoded_Reg_ebp, 1, AssemblerFixup::NoFixup));
38   __ fstp(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000,
39                                AssemblerFixup::NoFixup));
40 
41   constexpr size_t ByteCount = 9;
42   ASSERT_EQ(ByteCount, codeBytesSize());
43 
44   constexpr uint8_t Fld32Opcode = 0xd9;
45   constexpr uint8_t Fld32ModRM = (/*mod*/ 1 << 6) | (/*reg*/ 3 << 3) |
46                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
47   constexpr uint8_t Fld64Opcode = 0xdd;
48   constexpr uint8_t Fld64ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 3 << 3) |
49                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
50   verifyBytes<ByteCount>(codeBytes(), Fld32Opcode, Fld32ModRM, 0x01,
51                          Fld64Opcode, Fld64ModRM, 0x00, 0x00, 0x01, 0x00);
52 }
53 
TEST_F(AssemblerX8632LowLevelTest,Fincstp)54 TEST_F(AssemblerX8632LowLevelTest, Fincstp) {
55   __ fincstp();
56 
57   constexpr size_t ByteCount = 2;
58   ASSERT_EQ(ByteCount, codeBytesSize());
59 
60   verifyBytes<ByteCount>(codeBytes(), 0xD9, 0XF7);
61 }
62 
TEST_F(AssemblerX8632LowLevelTest,FnstcwAddr)63 TEST_F(AssemblerX8632LowLevelTest, FnstcwAddr) {
64   __ fnstcw(
65       Address(GPRRegister::Encoded_Reg_ebp, 0x12345, AssemblerFixup::NoFixup));
66 
67   constexpr size_t ByteCount = 6;
68   ASSERT_EQ(ByteCount, codeBytesSize());
69 
70   constexpr uint8_t Opcode = 0xd9;
71   constexpr uint8_t ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 7 << 3) |
72                             (/*rm*/ GPRRegister::Encoded_Reg_ebp);
73   verifyBytes<ByteCount>(codeBytes(), Opcode, ModRM, 0x45, 0x23, 0x01, 0x00);
74 }
75 
TEST_F(AssemblerX8632LowLevelTest,FldcwAddr)76 TEST_F(AssemblerX8632LowLevelTest, FldcwAddr) {
77   __ fldcw(
78       Address(GPRRegister::Encoded_Reg_ebp, 0x12345, AssemblerFixup::NoFixup));
79 
80   constexpr size_t ByteCount = 6;
81   ASSERT_EQ(ByteCount, codeBytesSize());
82 
83   constexpr uint8_t Opcode = 0xd9;
84   constexpr uint8_t ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 5 << 3) |
85                             (/*rm*/ GPRRegister::Encoded_Reg_ebp);
86   verifyBytes<ByteCount>(codeBytes(), Opcode, ModRM, 0x45, 0x23, 0x01, 0x00);
87 }
88 
TEST_F(AssemblerX8632Test,FstpSt)89 TEST_F(AssemblerX8632Test, FstpSt) {
90 #define TestFstpSt(Size, MemorySize, Type)                                     \
91   do {                                                                         \
92     const uint32_t T1 = allocate##MemorySize();                                \
93     const Type OldValue1 = -1.0f;                                              \
94     const uint32_t T2 = allocate##MemorySize();                                \
95     const Type OldValue2 = -2.0f;                                              \
96     const uint32_t T3 = allocate##MemorySize();                                \
97     const Type OldValue3 = -3.0f;                                              \
98     const uint32_t T4 = allocate##MemorySize();                                \
99     const Type OldValue4 = -4.0f;                                              \
100     const uint32_t T5 = allocate##MemorySize();                                \
101     const Type OldValue5 = -5.0f;                                              \
102     const uint32_t T6 = allocate##MemorySize();                                \
103     const Type OldValue6 = -6.0f;                                              \
104     const uint32_t T7 = allocate##MemorySize();                                \
105     const Type OldValue7 = -7.0f;                                              \
106                                                                                \
107     const uint32_t N7 = allocate##MemorySize();                                \
108     constexpr Type NewValue7 = 777.77f;                                        \
109     const uint32_t N6 = allocate##MemorySize();                                \
110     constexpr Type NewValue6 = 666.66f;                                        \
111     const uint32_t N5 = allocate##MemorySize();                                \
112     constexpr Type NewValue5 = 555.55f;                                        \
113     const uint32_t N4 = allocate##MemorySize();                                \
114     constexpr Type NewValue4 = 444.44f;                                        \
115     const uint32_t N3 = allocate##MemorySize();                                \
116     constexpr Type NewValue3 = 333.33f;                                        \
117     const uint32_t N2 = allocate##MemorySize();                                \
118     constexpr Type NewValue2 = 222.22f;                                        \
119     const uint32_t N1 = allocate##MemorySize();                                \
120     constexpr Type NewValue1 = 111.11f;                                        \
121                                                                                \
122     __ fincstp();                                                              \
123     __ fincstp();                                                              \
124     __ fincstp();                                                              \
125     __ fincstp();                                                              \
126     __ fincstp();                                                              \
127     __ fincstp();                                                              \
128     __ fincstp();                                                              \
129                                                                                \
130     __ fld(IceType_f##Size, dwordAddress(N7));                                 \
131     __ fstp(X87STRegister::Encoded_X87ST_7);                                   \
132     __ fld(IceType_f##Size, dwordAddress(N6));                                 \
133     __ fstp(X87STRegister::Encoded_X87ST_6);                                   \
134     __ fld(IceType_f##Size, dwordAddress(N5));                                 \
135     __ fstp(X87STRegister::Encoded_X87ST_5);                                   \
136     __ fld(IceType_f##Size, dwordAddress(N4));                                 \
137     __ fstp(X87STRegister::Encoded_X87ST_4);                                   \
138     __ fld(IceType_f##Size, dwordAddress(N3));                                 \
139     __ fstp(X87STRegister::Encoded_X87ST_3);                                   \
140     __ fld(IceType_f##Size, dwordAddress(N2));                                 \
141     __ fstp(X87STRegister::Encoded_X87ST_2);                                   \
142     __ fld(IceType_f##Size, dwordAddress(N1));                                 \
143     __ fstp(X87STRegister::Encoded_X87ST_1);                                   \
144                                                                                \
145     __ fstp(IceType_f##Size, dwordAddress(T1));                                \
146     __ fstp(IceType_f##Size, dwordAddress(T2));                                \
147     __ fstp(IceType_f##Size, dwordAddress(T3));                                \
148     __ fstp(IceType_f##Size, dwordAddress(T4));                                \
149     __ fstp(IceType_f##Size, dwordAddress(T5));                                \
150     __ fstp(IceType_f##Size, dwordAddress(T6));                                \
151     __ fstp(IceType_f##Size, dwordAddress(T7));                                \
152                                                                                \
153     AssembledTest test = assemble();                                           \
154     test.set##MemorySize##To(T1, OldValue1);                                   \
155     test.set##MemorySize##To(N1, NewValue1);                                   \
156     test.set##MemorySize##To(T2, OldValue2);                                   \
157     test.set##MemorySize##To(N2, NewValue2);                                   \
158     test.set##MemorySize##To(T3, OldValue3);                                   \
159     test.set##MemorySize##To(N3, NewValue3);                                   \
160     test.set##MemorySize##To(T4, OldValue4);                                   \
161     test.set##MemorySize##To(N4, NewValue4);                                   \
162     test.set##MemorySize##To(T5, OldValue5);                                   \
163     test.set##MemorySize##To(N5, NewValue5);                                   \
164     test.set##MemorySize##To(T6, OldValue6);                                   \
165     test.set##MemorySize##To(N6, NewValue6);                                   \
166     test.set##MemorySize##To(T7, OldValue7);                                   \
167     test.set##MemorySize##To(N7, NewValue7);                                   \
168                                                                                \
169     test.run();                                                                \
170                                                                                \
171     ASSERT_FLOAT_EQ(NewValue1, test.contentsOf##MemorySize<Type>(T1))          \
172         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
173     ASSERT_FLOAT_EQ(NewValue1, test.contentsOf##MemorySize<Type>(N1))          \
174         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
175     ASSERT_FLOAT_EQ(NewValue2, test.contentsOf##MemorySize<Type>(T2))          \
176         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
177     ASSERT_FLOAT_EQ(NewValue2, test.contentsOf##MemorySize<Type>(N2))          \
178         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
179     ASSERT_FLOAT_EQ(NewValue3, test.contentsOf##MemorySize<Type>(T3))          \
180         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
181     ASSERT_FLOAT_EQ(NewValue3, test.contentsOf##MemorySize<Type>(N3))          \
182         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
183     ASSERT_FLOAT_EQ(NewValue4, test.contentsOf##MemorySize<Type>(T4))          \
184         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
185     ASSERT_FLOAT_EQ(NewValue4, test.contentsOf##MemorySize<Type>(N4))          \
186         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
187     ASSERT_FLOAT_EQ(NewValue5, test.contentsOf##MemorySize<Type>(T5))          \
188         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
189     ASSERT_FLOAT_EQ(NewValue5, test.contentsOf##MemorySize<Type>(N5))          \
190         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
191     ASSERT_FLOAT_EQ(NewValue6, test.contentsOf##MemorySize<Type>(T6))          \
192         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
193     ASSERT_FLOAT_EQ(NewValue6, test.contentsOf##MemorySize<Type>(N6))          \
194         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
195     ASSERT_FLOAT_EQ(NewValue7, test.contentsOf##MemorySize<Type>(T7))          \
196         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
197     ASSERT_FLOAT_EQ(NewValue7, test.contentsOf##MemorySize<Type>(N7))          \
198         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
199                                                                                \
200     reset();                                                                   \
201   } while (0)
202 
203   TestFstpSt(32, Dword, float);
204   TestFstpSt(64, Qword, double);
205 
206 #undef TestFstpSt
207 }
208 
TEST_F(AssemblerX8632Test,Fild)209 TEST_F(AssemblerX8632Test, Fild) {
210 #define TestFild(OperandType, Size, MemorySize, FpType, IntType)               \
211   do {                                                                         \
212     const uint32_t T0 = allocate##MemorySize();                                \
213     constexpr IntType V0 = 0x1234;                                             \
214                                                                                \
215     __ fild##OperandType(dwordAddress(T0));                                    \
216     __ fstp(IceType_f##Size, dwordAddress(T0));                                \
217                                                                                \
218     AssembledTest test = assemble();                                           \
219                                                                                \
220     test.set##MemorySize##To(T0, V0);                                          \
221     test.run();                                                                \
222                                                                                \
223     ASSERT_FLOAT_EQ(static_cast<FpType>(V0),                                   \
224                     test.contentsOf##MemorySize<FpType>(T0))                   \
225         << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType           \
226            ", " #IntType ")";                                                  \
227                                                                                \
228     reset();                                                                   \
229   } while (0)
230 
231   TestFild(s, 32, Dword, float, uint32_t);
232   TestFild(l, 64, Qword, double, uint64_t);
233 #undef TestFild
234 }
235 
TEST_F(AssemblerX8632Test,Fistp)236 TEST_F(AssemblerX8632Test, Fistp) {
237 #define TestFistp(OperandType, Size, MemorySize, FpType, IntType)              \
238   do {                                                                         \
239     const uint32_t T0 = allocate##MemorySize();                                \
240     constexpr IntType V0 = 0x1234;                                             \
241     const uint32_t T1 = allocate##MemorySize();                                \
242     constexpr IntType V1 = 0xFFFF;                                             \
243                                                                                \
244     __ fild##OperandType(dwordAddress(T0));                                    \
245     __ fistp##OperandType(dwordAddress(T1));                                   \
246                                                                                \
247     AssembledTest test = assemble();                                           \
248                                                                                \
249     test.set##MemorySize##To(T0, V0);                                          \
250     test.set##MemorySize##To(T1, V1);                                          \
251     test.run();                                                                \
252                                                                                \
253     ASSERT_EQ(static_cast<IntType>(V0),                                        \
254               test.contentsOf##MemorySize<IntType>(T0))                        \
255         << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType           \
256            ", " #IntType ")";                                                  \
257     ASSERT_EQ(static_cast<IntType>(V0),                                        \
258               test.contentsOf##MemorySize<IntType>(T1))                        \
259         << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType           \
260            ", " #IntType ")";                                                  \
261                                                                                \
262     reset();                                                                   \
263   } while (0)
264 
265   TestFistp(s, 32, Dword, float, uint32_t);
266   TestFistp(l, 64, Qword, double, uint64_t);
267 #undef TestFistp
268 }
269 
270 } // end of anonymous namespace
271 } // end of namespace Test
272 } // end of namespace X8632
273 } // end of namespace Ice
274