| 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 |