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

Side by Side Diff: src/IceAssemblerX86BaseImpl.h

Issue 1616103002: Subzero. X8664. Enables RIP-based addressing mode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: make presubmit happy. Created 4 years, 11 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 unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceAssemblerX86Base.h ('k') | src/IceFixups.h » ('j') | src/IceTargetLoweringX8664.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698