Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// | 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// |
| 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 // | 5 // |
| 6 // Modified by the Subzero authors. | 6 // Modified by the Subzero authors. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // The Subzero Code Generator | 10 // The Subzero Code Generator |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst, | 292 void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst, |
| 293 const Immediate &imm) { | 293 const Immediate &imm) { |
| 294 assert(Ty != IceType_i64 && "i64 not supported yet."); | 294 assert(Ty != IceType_i64 && "i64 not supported yet."); |
| 295 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 295 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 296 if (Ty == IceType_i16) | 296 if (Ty == IceType_i16) |
| 297 emitOperandSizeOverride(); | 297 emitOperandSizeOverride(); |
| 298 emitAddrSizeOverridePrefix(); | 298 emitAddrSizeOverridePrefix(); |
| 299 emitRex(Ty, dst, RexRegIrrelevant); | 299 emitRex(Ty, dst, RexRegIrrelevant); |
| 300 if (isByteSizedType(Ty)) { | 300 if (isByteSizedType(Ty)) { |
| 301 emitUint8(0xC6); | 301 emitUint8(0xC6); |
| 302 emitOperand(0, dst); | 302 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
|
Jim Stichnoth
2016/01/23 01:57:46
What do you think about using typeWidthInBytes(Ty)
John
2016/01/26 19:44:25
Discussed offline. keeping as is.
| |
| 303 emitOperand(0, dst, OffsetFromNextInstruction); | |
| 303 emitUint8(imm.value() & 0xFF); | 304 emitUint8(imm.value() & 0xFF); |
| 304 } else { | 305 } else { |
| 305 emitUint8(0xC7); | 306 emitUint8(0xC7); |
| 306 emitOperand(0, dst); | 307 const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4; |
| 308 emitOperand(0, dst, OffsetFromNextInstruction); | |
| 307 emitImmediate(Ty, imm); | 309 emitImmediate(Ty, imm); |
| 308 } | 310 } |
| 309 } | 311 } |
| 310 | 312 |
| 311 template <typename TraitsType> | 313 template <typename TraitsType> |
| 312 template <typename T> | 314 template <typename T> |
| 313 typename std::enable_if<T::Is64Bit, void>::type | 315 typename std::enable_if<T::Is64Bit, void>::type |
| 314 AssemblerX86Base<TraitsType>::movabs(const GPRRegister Dst, uint64_t Imm64) { | 316 AssemblerX86Base<TraitsType>::movabs(const GPRRegister Dst, uint64_t Imm64) { |
| 315 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 317 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 316 const bool NeedsRexW = (Imm64 & ~0xFFFFFFFFull) != 0; | 318 const bool NeedsRexW = (Imm64 & ~0xFFFFFFFFull) != 0; |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1422 void AssemblerX86Base<TraitsType>::cmpps(Type Ty, XmmRegister dst, | 1424 void AssemblerX86Base<TraitsType>::cmpps(Type Ty, XmmRegister dst, |
| 1423 const Address &src, | 1425 const Address &src, |
| 1424 CmppsCond CmpCondition) { | 1426 CmppsCond CmpCondition) { |
| 1425 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1427 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1426 if (Ty == IceType_f64) | 1428 if (Ty == IceType_f64) |
| 1427 emitUint8(0x66); | 1429 emitUint8(0x66); |
| 1428 emitAddrSizeOverridePrefix(); | 1430 emitAddrSizeOverridePrefix(); |
| 1429 emitRex(RexTypeIrrelevant, src, dst); | 1431 emitRex(RexTypeIrrelevant, src, dst); |
| 1430 emitUint8(0x0F); | 1432 emitUint8(0x0F); |
| 1431 emitUint8(0xC2); | 1433 emitUint8(0xC2); |
| 1432 emitOperand(gprEncoding(dst), src); | 1434 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 1435 emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction); | |
| 1433 emitUint8(CmpCondition); | 1436 emitUint8(CmpCondition); |
| 1434 } | 1437 } |
| 1435 | 1438 |
| 1436 template <typename TraitsType> | 1439 template <typename TraitsType> |
| 1437 void AssemblerX86Base<TraitsType>::sqrtps(XmmRegister dst) { | 1440 void AssemblerX86Base<TraitsType>::sqrtps(XmmRegister dst) { |
| 1438 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1441 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1439 emitRexRB(RexTypeIrrelevant, dst, dst); | 1442 emitRexRB(RexTypeIrrelevant, dst, dst); |
| 1440 emitUint8(0x0F); | 1443 emitUint8(0x0F); |
| 1441 emitUint8(0x51); | 1444 emitUint8(0x51); |
| 1442 emitXmmRegisterOperand(dst, dst); | 1445 emitXmmRegisterOperand(dst, dst); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1544 template <typename TraitsType> | 1547 template <typename TraitsType> |
| 1545 void AssemblerX86Base<TraitsType>::pshufd(Type /* Ty */, XmmRegister dst, | 1548 void AssemblerX86Base<TraitsType>::pshufd(Type /* Ty */, XmmRegister dst, |
| 1546 const Address &src, | 1549 const Address &src, |
| 1547 const Immediate &imm) { | 1550 const Immediate &imm) { |
| 1548 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1551 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1549 emitUint8(0x66); | 1552 emitUint8(0x66); |
| 1550 emitAddrSizeOverridePrefix(); | 1553 emitAddrSizeOverridePrefix(); |
| 1551 emitRex(RexTypeIrrelevant, src, dst); | 1554 emitRex(RexTypeIrrelevant, src, dst); |
| 1552 emitUint8(0x0F); | 1555 emitUint8(0x0F); |
| 1553 emitUint8(0x70); | 1556 emitUint8(0x70); |
| 1554 emitOperand(gprEncoding(dst), src); | 1557 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 1558 emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction); | |
| 1555 assert(imm.is_uint8()); | 1559 assert(imm.is_uint8()); |
| 1556 emitUint8(imm.value()); | 1560 emitUint8(imm.value()); |
| 1557 } | 1561 } |
| 1558 | 1562 |
| 1559 template <typename TraitsType> | 1563 template <typename TraitsType> |
| 1560 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst, | 1564 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst, |
| 1561 XmmRegister src, | 1565 XmmRegister src, |
| 1562 const Immediate &imm) { | 1566 const Immediate &imm) { |
| 1563 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1567 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1564 emitRexRB(RexTypeIrrelevant, dst, src); | 1568 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1565 emitUint8(0x0F); | 1569 emitUint8(0x0F); |
| 1566 emitUint8(0xC6); | 1570 emitUint8(0xC6); |
| 1567 emitXmmRegisterOperand(dst, src); | 1571 emitXmmRegisterOperand(dst, src); |
| 1568 assert(imm.is_uint8()); | 1572 assert(imm.is_uint8()); |
| 1569 emitUint8(imm.value()); | 1573 emitUint8(imm.value()); |
| 1570 } | 1574 } |
| 1571 | 1575 |
| 1572 template <typename TraitsType> | 1576 template <typename TraitsType> |
| 1573 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst, | 1577 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst, |
| 1574 const Address &src, | 1578 const Address &src, |
| 1575 const Immediate &imm) { | 1579 const Immediate &imm) { |
| 1576 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1580 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1577 emitAddrSizeOverridePrefix(); | 1581 emitAddrSizeOverridePrefix(); |
| 1578 emitRex(RexTypeIrrelevant, src, dst); | 1582 emitRex(RexTypeIrrelevant, src, dst); |
| 1579 emitUint8(0x0F); | 1583 emitUint8(0x0F); |
| 1580 emitUint8(0xC6); | 1584 emitUint8(0xC6); |
| 1581 emitOperand(gprEncoding(dst), src); | 1585 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 1586 emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction); | |
| 1582 assert(imm.is_uint8()); | 1587 assert(imm.is_uint8()); |
| 1583 emitUint8(imm.value()); | 1588 emitUint8(imm.value()); |
| 1584 } | 1589 } |
| 1585 | 1590 |
| 1586 template <typename TraitsType> | 1591 template <typename TraitsType> |
| 1587 void AssemblerX86Base<TraitsType>::sqrtpd(XmmRegister dst) { | 1592 void AssemblerX86Base<TraitsType>::sqrtpd(XmmRegister dst) { |
| 1588 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1593 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1589 emitUint8(0x66); | 1594 emitUint8(0x66); |
| 1590 emitRexRB(RexTypeIrrelevant, dst, dst); | 1595 emitRexRB(RexTypeIrrelevant, dst, dst); |
| 1591 emitUint8(0x0F); | 1596 emitUint8(0x0F); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1823 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1828 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1824 assert(imm.is_uint8()); | 1829 assert(imm.is_uint8()); |
| 1825 assert(isVectorFloatingType(Ty)); | 1830 assert(isVectorFloatingType(Ty)); |
| 1826 (void)Ty; | 1831 (void)Ty; |
| 1827 emitUint8(0x66); | 1832 emitUint8(0x66); |
| 1828 emitAddrSizeOverridePrefix(); | 1833 emitAddrSizeOverridePrefix(); |
| 1829 emitRex(RexTypeIrrelevant, src, dst); | 1834 emitRex(RexTypeIrrelevant, src, dst); |
| 1830 emitUint8(0x0F); | 1835 emitUint8(0x0F); |
| 1831 emitUint8(0x3A); | 1836 emitUint8(0x3A); |
| 1832 emitUint8(0x21); | 1837 emitUint8(0x21); |
| 1833 emitOperand(gprEncoding(dst), src); | 1838 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 1839 emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction); | |
| 1834 emitUint8(imm.value()); | 1840 emitUint8(imm.value()); |
| 1835 } | 1841 } |
| 1836 | 1842 |
| 1837 template <typename TraitsType> | 1843 template <typename TraitsType> |
| 1838 void AssemblerX86Base<TraitsType>::pinsr(Type Ty, XmmRegister dst, | 1844 void AssemblerX86Base<TraitsType>::pinsr(Type Ty, XmmRegister dst, |
| 1839 GPRRegister src, | 1845 GPRRegister src, |
| 1840 const Immediate &imm) { | 1846 const Immediate &imm) { |
| 1841 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1847 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1842 assert(imm.is_uint8()); | 1848 assert(imm.is_uint8()); |
| 1843 emitUint8(0x66); | 1849 emitUint8(0x66); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1862 emitUint8(0x66); | 1868 emitUint8(0x66); |
| 1863 emitAddrSizeOverridePrefix(); | 1869 emitAddrSizeOverridePrefix(); |
| 1864 emitRex(RexTypeIrrelevant, src, dst); | 1870 emitRex(RexTypeIrrelevant, src, dst); |
| 1865 emitUint8(0x0F); | 1871 emitUint8(0x0F); |
| 1866 if (Ty == IceType_i16) { | 1872 if (Ty == IceType_i16) { |
| 1867 emitUint8(0xC4); | 1873 emitUint8(0xC4); |
| 1868 } else { | 1874 } else { |
| 1869 emitUint8(0x3A); | 1875 emitUint8(0x3A); |
| 1870 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); | 1876 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); |
| 1871 } | 1877 } |
| 1872 emitOperand(gprEncoding(dst), src); | 1878 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 1879 emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction); | |
| 1873 emitUint8(imm.value()); | 1880 emitUint8(imm.value()); |
| 1874 } | 1881 } |
| 1875 | 1882 |
| 1876 template <typename TraitsType> | 1883 template <typename TraitsType> |
| 1877 void AssemblerX86Base<TraitsType>::pextr(Type Ty, GPRRegister dst, | 1884 void AssemblerX86Base<TraitsType>::pextr(Type Ty, GPRRegister dst, |
| 1878 XmmRegister src, | 1885 XmmRegister src, |
| 1879 const Immediate &imm) { | 1886 const Immediate &imm) { |
| 1880 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1887 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1881 assert(imm.is_uint8()); | 1888 assert(imm.is_uint8()); |
| 1882 if (Ty == IceType_i16) { | 1889 if (Ty == IceType_i16) { |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2237 void AssemblerX86Base<TraitsType>::test(Type Ty, const Address &addr, | 2244 void AssemblerX86Base<TraitsType>::test(Type Ty, const Address &addr, |
| 2238 const Immediate &immediate) { | 2245 const Immediate &immediate) { |
| 2239 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2246 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2240 // If the immediate is short, we only test the byte addr to keep the encoding | 2247 // If the immediate is short, we only test the byte addr to keep the encoding |
| 2241 // short. | 2248 // short. |
| 2242 if (immediate.is_uint8()) { | 2249 if (immediate.is_uint8()) { |
| 2243 // Use zero-extended 8-bit immediate. | 2250 // Use zero-extended 8-bit immediate. |
| 2244 emitAddrSizeOverridePrefix(); | 2251 emitAddrSizeOverridePrefix(); |
| 2245 emitRex(Ty, addr, RexRegIrrelevant); | 2252 emitRex(Ty, addr, RexRegIrrelevant); |
| 2246 emitUint8(0xF6); | 2253 emitUint8(0xF6); |
| 2247 emitOperand(0, addr); | 2254 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 2255 emitOperand(0, addr, OffsetFromNextInstruction); | |
| 2248 emitUint8(immediate.value() & 0xFF); | 2256 emitUint8(immediate.value() & 0xFF); |
| 2249 } else { | 2257 } else { |
| 2250 if (Ty == IceType_i16) | 2258 if (Ty == IceType_i16) |
| 2251 emitOperandSizeOverride(); | 2259 emitOperandSizeOverride(); |
| 2252 emitAddrSizeOverridePrefix(); | 2260 emitAddrSizeOverridePrefix(); |
| 2253 emitRex(Ty, addr, RexRegIrrelevant); | 2261 emitRex(Ty, addr, RexRegIrrelevant); |
| 2254 emitUint8(0xF7); | 2262 emitUint8(0xF7); |
| 2255 emitOperand(0, addr); | 2263 const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4; |
| 2264 emitOperand(0, addr, OffsetFromNextInstruction); | |
| 2256 emitImmediate(Ty, immediate); | 2265 emitImmediate(Ty, immediate); |
| 2257 } | 2266 } |
| 2258 } | 2267 } |
| 2259 | 2268 |
| 2260 template <typename TraitsType> | 2269 template <typename TraitsType> |
| 2261 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst, | 2270 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst, |
| 2262 GPRRegister src) { | 2271 GPRRegister src) { |
| 2263 arith_int<4>(Ty, dst, src); | 2272 arith_int<4>(Ty, dst, src); |
| 2264 } | 2273 } |
| 2265 | 2274 |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2646 const Address &address, | 2655 const Address &address, |
| 2647 const Immediate &imm) { | 2656 const Immediate &imm) { |
| 2648 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2657 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2649 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2658 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2650 if (Ty == IceType_i16) | 2659 if (Ty == IceType_i16) |
| 2651 emitOperandSizeOverride(); | 2660 emitOperandSizeOverride(); |
| 2652 emitAddrSizeOverridePrefix(); | 2661 emitAddrSizeOverridePrefix(); |
| 2653 emitRex(Ty, address, dst); | 2662 emitRex(Ty, address, dst); |
| 2654 if (imm.is_int8()) { | 2663 if (imm.is_int8()) { |
| 2655 emitUint8(0x6B); | 2664 emitUint8(0x6B); |
| 2656 emitOperand(gprEncoding(dst), address); | 2665 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 2666 emitOperand(gprEncoding(dst), address, OffsetFromNextInstruction); | |
| 2657 emitUint8(imm.value() & 0xFF); | 2667 emitUint8(imm.value() & 0xFF); |
| 2658 } else { | 2668 } else { |
| 2659 emitUint8(0x69); | 2669 emitUint8(0x69); |
| 2660 emitOperand(gprEncoding(dst), address); | 2670 const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4; |
| 2671 emitOperand(gprEncoding(dst), address, OffsetFromNextInstruction); | |
| 2661 emitImmediate(Ty, imm); | 2672 emitImmediate(Ty, imm); |
| 2662 } | 2673 } |
| 2663 } | 2674 } |
| 2664 | 2675 |
| 2665 template <typename TraitsType> | 2676 template <typename TraitsType> |
| 2666 void AssemblerX86Base<TraitsType>::mul(Type Ty, GPRRegister reg) { | 2677 void AssemblerX86Base<TraitsType>::mul(Type Ty, GPRRegister reg) { |
| 2667 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2678 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2668 if (Ty == IceType_i16) | 2679 if (Ty == IceType_i16) |
| 2669 emitOperandSizeOverride(); | 2680 emitOperandSizeOverride(); |
| 2670 emitRexB(Ty, reg); | 2681 emitRexB(Ty, reg); |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3339 while (L->hasNear()) { | 3350 while (L->hasNear()) { |
| 3340 intptr_t Position = L->getNearPosition(); | 3351 intptr_t Position = L->getNearPosition(); |
| 3341 const intptr_t Offset = Bound - (Position + 1); | 3352 const intptr_t Offset = Bound - (Position + 1); |
| 3342 assert(Utils::IsInt(8, Offset)); | 3353 assert(Utils::IsInt(8, Offset)); |
| 3343 Buffer.store<int8_t>(Position, Offset); | 3354 Buffer.store<int8_t>(Position, Offset); |
| 3344 } | 3355 } |
| 3345 L->bindTo(Bound); | 3356 L->bindTo(Bound); |
| 3346 } | 3357 } |
| 3347 | 3358 |
| 3348 template <typename TraitsType> | 3359 template <typename TraitsType> |
| 3349 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand) { | 3360 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand, |
| 3361 RelocOffsetT Addend) { | |
| 3350 assert(rm >= 0 && rm < 8); | 3362 assert(rm >= 0 && rm < 8); |
| 3351 const intptr_t length = operand.length_; | 3363 const intptr_t length = operand.length_; |
| 3352 assert(length > 0); | 3364 assert(length > 0); |
| 3353 intptr_t displacement_start = 1; | 3365 intptr_t displacement_start = 1; |
| 3354 // Emit the ModRM byte updated with the given RM value. | 3366 // Emit the ModRM byte updated with the given RM value. |
| 3355 assert((operand.encoding_[0] & 0x38) == 0); | 3367 assert((operand.encoding_[0] & 0x38) == 0); |
| 3356 emitUint8(operand.encoding_[0] + (rm << 3)); | 3368 emitUint8(operand.encoding_[0] + (rm << 3)); |
| 3357 // Whenever the addressing mode is not register indirect, using esp == 0x4 | 3369 // Whenever the addressing mode is not register indirect, using esp == 0x4 |
| 3358 // as the register operation indicates an SIB byte follows. | 3370 // as the register operation indicates an SIB byte follows. |
| 3359 if (((operand.encoding_[0] & 0xc0) != 0xc0) && | 3371 if (((operand.encoding_[0] & 0xc0) != 0xc0) && |
| 3360 ((operand.encoding_[0] & 0x07) == 0x04)) { | 3372 ((operand.encoding_[0] & 0x07) == 0x04)) { |
| 3361 emitUint8(operand.encoding_[1]); | 3373 emitUint8(operand.encoding_[1]); |
| 3362 displacement_start = 2; | 3374 displacement_start = 2; |
| 3363 } | 3375 } |
| 3364 // Emit the displacement and the fixup that affects it, if any. | 3376 // Emit the displacement and the fixup that affects it, if any. |
| 3365 if (operand.fixup()) { | 3377 AssemblerFixup *Fixup = operand.fixup(); |
| 3366 emitFixup(operand.fixup()); | 3378 if (Fixup != nullptr) { |
| 3379 emitFixup(Fixup); | |
| 3367 assert(length - displacement_start == 4); | 3380 assert(length - displacement_start == 4); |
| 3381 if (fixupIsPCRel(Fixup->kind())) { | |
| 3382 Fixup->set_addend(-Addend); | |
| 3383 int32_t Offset; | |
| 3384 memmove(&Offset, &operand.encoding_[displacement_start], sizeof(Offset)); | |
| 3385 Offset -= Addend; | |
| 3386 emitInt32(Offset); | |
| 3387 return; | |
| 3388 } | |
| 3368 } | 3389 } |
| 3369 for (intptr_t i = displacement_start; i < length; i++) { | 3390 for (intptr_t i = displacement_start; i < length; i++) { |
| 3370 emitUint8(operand.encoding_[i]); | 3391 emitUint8(operand.encoding_[i]); |
| 3371 } | 3392 } |
| 3372 } | 3393 } |
| 3373 | 3394 |
| 3374 template <typename TraitsType> | 3395 template <typename TraitsType> |
| 3375 void AssemblerX86Base<TraitsType>::emitImmediate(Type Ty, | 3396 void AssemblerX86Base<TraitsType>::emitImmediate(Type Ty, |
| 3376 const Immediate &imm) { | 3397 const Immediate &imm) { |
| 3398 auto *const Fixup = imm.fixup(); | |
|
Jim Stichnoth
2016/01/23 01:57:46
Fortunately I didn't have to scan too far from her
John
2016/01/26 19:44:25
My arguments for auto here:
1) the following line
| |
| 3377 if (Ty == IceType_i16) { | 3399 if (Ty == IceType_i16) { |
| 3378 assert(!imm.fixup()); | 3400 assert(Fixup == nullptr); |
| 3379 emitInt16(imm.value()); | 3401 emitInt16(imm.value()); |
| 3380 } else { | 3402 return; |
| 3381 if (imm.fixup()) { | |
| 3382 emitFixup(imm.fixup()); | |
| 3383 } | |
| 3384 emitInt32(imm.value()); | |
| 3385 } | 3403 } |
| 3404 | |
| 3405 if (Fixup != nullptr) { | |
| 3406 emitFixup(Fixup); | |
| 3407 } | |
| 3408 emitInt32(imm.value()); | |
| 3386 } | 3409 } |
| 3387 | 3410 |
| 3388 template <typename TraitsType> | 3411 template <typename TraitsType> |
| 3389 void AssemblerX86Base<TraitsType>::emitComplexI8(int rm, const Operand &operand, | 3412 void AssemblerX86Base<TraitsType>::emitComplexI8(int rm, const Operand &operand, |
| 3390 const Immediate &immediate) { | 3413 const Immediate &immediate) { |
| 3391 assert(rm >= 0 && rm < 8); | 3414 assert(rm >= 0 && rm < 8); |
| 3392 assert(immediate.is_int8()); | 3415 assert(immediate.is_int8()); |
| 3393 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { | 3416 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { |
| 3394 // Use short form if the destination is al. | 3417 // Use short form if the destination is al. |
| 3395 emitUint8(0x04 + (rm << 3)); | 3418 emitUint8(0x04 + (rm << 3)); |
| 3396 emitUint8(immediate.value() & 0xFF); | 3419 emitUint8(immediate.value() & 0xFF); |
| 3397 } else { | 3420 } else { |
| 3398 // Use sign-extended 8-bit immediate. | 3421 // Use sign-extended 8-bit immediate. |
| 3399 emitUint8(0x80); | 3422 emitUint8(0x80); |
| 3400 emitOperand(rm, operand); | 3423 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 3424 emitOperand(rm, operand, OffsetFromNextInstruction); | |
| 3401 emitUint8(immediate.value() & 0xFF); | 3425 emitUint8(immediate.value() & 0xFF); |
| 3402 } | 3426 } |
| 3403 } | 3427 } |
| 3404 | 3428 |
| 3405 template <typename TraitsType> | 3429 template <typename TraitsType> |
| 3406 void AssemblerX86Base<TraitsType>::emitComplex(Type Ty, int rm, | 3430 void AssemblerX86Base<TraitsType>::emitComplex(Type Ty, int rm, |
| 3407 const Operand &operand, | 3431 const Operand &operand, |
| 3408 const Immediate &immediate) { | 3432 const Immediate &immediate) { |
| 3409 assert(rm >= 0 && rm < 8); | 3433 assert(rm >= 0 && rm < 8); |
| 3410 if (immediate.is_int8()) { | 3434 if (immediate.is_int8()) { |
| 3411 // Use sign-extended 8-bit immediate. | 3435 // Use sign-extended 8-bit immediate. |
| 3412 emitUint8(0x83); | 3436 emitUint8(0x83); |
| 3413 emitOperand(rm, operand); | 3437 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 3438 emitOperand(rm, operand, OffsetFromNextInstruction); | |
| 3414 emitUint8(immediate.value() & 0xFF); | 3439 emitUint8(immediate.value() & 0xFF); |
| 3415 } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { | 3440 } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { |
| 3416 // Use short form if the destination is eax. | 3441 // Use short form if the destination is eax. |
| 3417 emitUint8(0x05 + (rm << 3)); | 3442 emitUint8(0x05 + (rm << 3)); |
| 3418 emitImmediate(Ty, immediate); | 3443 emitImmediate(Ty, immediate); |
| 3419 } else { | 3444 } else { |
| 3420 emitUint8(0x81); | 3445 emitUint8(0x81); |
| 3421 emitOperand(rm, operand); | 3446 const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4; |
| 3447 emitOperand(rm, operand, OffsetFromNextInstruction); | |
| 3422 emitImmediate(Ty, immediate); | 3448 emitImmediate(Ty, immediate); |
| 3423 } | 3449 } |
| 3424 } | 3450 } |
| 3425 | 3451 |
| 3426 template <typename TraitsType> | 3452 template <typename TraitsType> |
| 3427 void AssemblerX86Base<TraitsType>::emitLabel(Label *label, | 3453 void AssemblerX86Base<TraitsType>::emitLabel(Label *label, |
| 3428 intptr_t instruction_size) { | 3454 intptr_t instruction_size) { |
| 3429 if (label->isBound()) { | 3455 if (label->isBound()) { |
| 3430 intptr_t offset = label->getPosition() - Buffer.size(); | 3456 intptr_t offset = label->getPosition() - Buffer.size(); |
| 3431 assert(offset <= 0); | 3457 assert(offset <= 0); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 3461 // same processor behavior regardless of whether it's an immediate (masked to | 3487 // same processor behavior regardless of whether it's an immediate (masked to |
| 3462 // 8 bits) or in register cl (essentially ecx masked to 8 bits). | 3488 // 8 bits) or in register cl (essentially ecx masked to 8 bits). |
| 3463 if (Ty == IceType_i16) | 3489 if (Ty == IceType_i16) |
| 3464 emitOperandSizeOverride(); | 3490 emitOperandSizeOverride(); |
| 3465 emitRexB(Ty, reg); | 3491 emitRexB(Ty, reg); |
| 3466 if (imm.value() == 1) { | 3492 if (imm.value() == 1) { |
| 3467 emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); | 3493 emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); |
| 3468 emitOperand(rm, Operand(reg)); | 3494 emitOperand(rm, Operand(reg)); |
| 3469 } else { | 3495 } else { |
| 3470 emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1); | 3496 emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1); |
| 3471 emitOperand(rm, Operand(reg)); | 3497 static constexpr RelocOffsetT OffsetFromNextInstruction = 1; |
| 3498 emitOperand(rm, Operand(reg), OffsetFromNextInstruction); | |
| 3472 emitUint8(imm.value() & 0xFF); | 3499 emitUint8(imm.value() & 0xFF); |
| 3473 } | 3500 } |
| 3474 } | 3501 } |
| 3475 | 3502 |
| 3476 template <typename TraitsType> | 3503 template <typename TraitsType> |
| 3477 void AssemblerX86Base<TraitsType>::emitGenericShift(int rm, Type Ty, | 3504 void AssemblerX86Base<TraitsType>::emitGenericShift(int rm, Type Ty, |
| 3478 const Operand &operand, | 3505 const Operand &operand, |
| 3479 GPRRegister shifter) { | 3506 GPRRegister shifter) { |
| 3480 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3507 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3481 assert(shifter == Traits::Encoded_Reg_Counter); | 3508 assert(shifter == Traits::Encoded_Reg_Counter); |
| 3482 (void)shifter; | 3509 (void)shifter; |
| 3483 if (Ty == IceType_i16) | 3510 if (Ty == IceType_i16) |
| 3484 emitOperandSizeOverride(); | 3511 emitOperandSizeOverride(); |
| 3485 emitRexB(Ty, operand.rm()); | 3512 emitRexB(Ty, operand.rm()); |
| 3486 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 3513 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
| 3487 emitOperand(rm, operand); | 3514 emitOperand(rm, operand); |
| 3488 } | 3515 } |
| 3489 | 3516 |
| 3490 } // end of namespace X86NAMESPACE | 3517 } // end of namespace X86NAMESPACE |
| 3491 } // end of namespace Ice | 3518 } // end of namespace Ice |
| OLD | NEW |