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