OLD | NEW |
1 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// | 1 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// |
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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 | 72 |
73 Label *AssemblerX86::GetOrCreateCfgNodeLabel(SizeT NodeNumber) { | 73 Label *AssemblerX86::GetOrCreateCfgNodeLabel(SizeT NodeNumber) { |
74 return GetOrCreateLabel(NodeNumber, CfgNodeLabels); | 74 return GetOrCreateLabel(NodeNumber, CfgNodeLabels); |
75 } | 75 } |
76 | 76 |
77 Label *AssemblerX86::GetOrCreateLocalLabel(SizeT Number) { | 77 Label *AssemblerX86::GetOrCreateLocalLabel(SizeT Number) { |
78 return GetOrCreateLabel(Number, LocalLabels); | 78 return GetOrCreateLabel(Number, LocalLabels); |
79 } | 79 } |
80 | 80 |
81 void AssemblerX86::BindCfgNodeLabel(SizeT NodeNumber) { | 81 void AssemblerX86::BindCfgNodeLabel(SizeT NodeNumber) { |
| 82 assert(!getPreliminary()); |
82 Label *L = GetOrCreateCfgNodeLabel(NodeNumber); | 83 Label *L = GetOrCreateCfgNodeLabel(NodeNumber); |
83 this->Bind(L); | 84 this->Bind(L); |
84 } | 85 } |
85 | 86 |
86 void AssemblerX86::BindLocalLabel(SizeT Number) { | 87 void AssemblerX86::BindLocalLabel(SizeT Number) { |
87 Label *L = GetOrCreateLocalLabel(Number); | 88 Label *L = GetOrCreateLocalLabel(Number); |
88 this->Bind(L); | 89 if (!getPreliminary()) |
| 90 this->Bind(L); |
89 } | 91 } |
90 | 92 |
91 void AssemblerX86::call(GPRRegister reg) { | 93 void AssemblerX86::call(GPRRegister reg) { |
92 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 94 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
93 EmitUint8(0xFF); | 95 EmitUint8(0xFF); |
94 EmitRegisterOperand(2, reg); | 96 EmitRegisterOperand(2, reg); |
95 } | 97 } |
96 | 98 |
97 void AssemblerX86::call(const Address &address) { | 99 void AssemblerX86::call(const Address &address) { |
98 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 100 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
(...skipping 2123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 } | 2224 } |
2223 | 2225 |
2224 void AssemblerX86::j(CondX86::BrCond condition, Label *label, bool near) { | 2226 void AssemblerX86::j(CondX86::BrCond condition, Label *label, bool near) { |
2225 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2227 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2226 if (label->IsBound()) { | 2228 if (label->IsBound()) { |
2227 static const int kShortSize = 2; | 2229 static const int kShortSize = 2; |
2228 static const int kLongSize = 6; | 2230 static const int kLongSize = 6; |
2229 intptr_t offset = label->Position() - buffer_.Size(); | 2231 intptr_t offset = label->Position() - buffer_.Size(); |
2230 assert(offset <= 0); | 2232 assert(offset <= 0); |
2231 if (Utils::IsInt(8, offset - kShortSize)) { | 2233 if (Utils::IsInt(8, offset - kShortSize)) { |
| 2234 // TODO(stichnot): Here and in jmp(), we may need to be more |
| 2235 // conservative about the backward branch distance if the branch |
| 2236 // instruction is within a bundle_lock sequence, because the |
| 2237 // distance may increase when padding is added. This isn't an |
| 2238 // issue for branches outside a bundle_lock, because if padding |
| 2239 // is added, the retry may change it to a long backward branch |
| 2240 // without affecting any of the bookkeeping. |
2232 EmitUint8(0x70 + condition); | 2241 EmitUint8(0x70 + condition); |
2233 EmitUint8((offset - kShortSize) & 0xFF); | 2242 EmitUint8((offset - kShortSize) & 0xFF); |
2234 } else { | 2243 } else { |
2235 EmitUint8(0x0F); | 2244 EmitUint8(0x0F); |
2236 EmitUint8(0x80 + condition); | 2245 EmitUint8(0x80 + condition); |
2237 EmitInt32(offset - kLongSize); | 2246 EmitInt32(offset - kLongSize); |
2238 } | 2247 } |
2239 } else if (near) { | 2248 } else if (near) { |
2240 EmitUint8(0x70 + condition); | 2249 EmitUint8(0x70 + condition); |
2241 EmitNearLabelLink(label); | 2250 EmitNearLabelLink(label); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2456 EmitInt32(offset - instruction_size); | 2465 EmitInt32(offset - instruction_size); |
2457 } else { | 2466 } else { |
2458 EmitLabelLink(label); | 2467 EmitLabelLink(label); |
2459 } | 2468 } |
2460 } | 2469 } |
2461 | 2470 |
2462 void AssemblerX86::EmitLabelLink(Label *label) { | 2471 void AssemblerX86::EmitLabelLink(Label *label) { |
2463 assert(!label->IsBound()); | 2472 assert(!label->IsBound()); |
2464 intptr_t position = buffer_.Size(); | 2473 intptr_t position = buffer_.Size(); |
2465 EmitInt32(label->position_); | 2474 EmitInt32(label->position_); |
2466 label->LinkTo(position); | 2475 if (!getPreliminary()) |
| 2476 label->LinkTo(position); |
2467 } | 2477 } |
2468 | 2478 |
2469 void AssemblerX86::EmitNearLabelLink(Label *label) { | 2479 void AssemblerX86::EmitNearLabelLink(Label *label) { |
2470 assert(!label->IsBound()); | 2480 assert(!label->IsBound()); |
2471 intptr_t position = buffer_.Size(); | 2481 intptr_t position = buffer_.Size(); |
2472 EmitUint8(0); | 2482 EmitUint8(0); |
2473 label->NearLinkTo(position); | 2483 if (!getPreliminary()) |
| 2484 label->NearLinkTo(position); |
2474 } | 2485 } |
2475 | 2486 |
2476 void AssemblerX86::EmitGenericShift(int rm, Type Ty, GPRRegister reg, | 2487 void AssemblerX86::EmitGenericShift(int rm, Type Ty, GPRRegister reg, |
2477 const Immediate &imm) { | 2488 const Immediate &imm) { |
2478 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2489 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2479 assert(imm.is_int8()); | 2490 assert(imm.is_int8()); |
2480 if (Ty == IceType_i16) | 2491 if (Ty == IceType_i16) |
2481 EmitOperandSizeOverride(); | 2492 EmitOperandSizeOverride(); |
2482 if (imm.value() == 1) { | 2493 if (imm.value() == 1) { |
2483 EmitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); | 2494 EmitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); |
(...skipping 11 matching lines...) Expand all Loading... |
2495 assert(shifter == RegX8632::Encoded_Reg_ecx); | 2506 assert(shifter == RegX8632::Encoded_Reg_ecx); |
2496 (void)shifter; | 2507 (void)shifter; |
2497 if (Ty == IceType_i16) | 2508 if (Ty == IceType_i16) |
2498 EmitOperandSizeOverride(); | 2509 EmitOperandSizeOverride(); |
2499 EmitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 2510 EmitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
2500 EmitOperand(rm, operand); | 2511 EmitOperand(rm, operand); |
2501 } | 2512 } |
2502 | 2513 |
2503 } // end of namespace x86 | 2514 } // end of namespace x86 |
2504 } // end of namespace Ice | 2515 } // end of namespace Ice |
OLD | NEW |