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

Side by Side Diff: src/IceAssemblerX86BaseImpl.h

Issue 1257283004: Iasm and obj lowering for advanced switch lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 4 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 13 matching lines...) Expand all
24 #include "IceCfg.h" 24 #include "IceCfg.h"
25 #include "IceOperand.h" 25 #include "IceOperand.h"
26 26
27 namespace Ice { 27 namespace Ice {
28 namespace X86Internal { 28 namespace X86Internal {
29 29
30 template <class Machine> 30 template <class Machine>
31 AssemblerX86Base<Machine>::~AssemblerX86Base<Machine>() { 31 AssemblerX86Base<Machine>::~AssemblerX86Base<Machine>() {
32 if (BuildDefs::asserts()) { 32 if (BuildDefs::asserts()) {
33 for (const Label *Label : CfgNodeLabels) { 33 for (const Label *Label : CfgNodeLabels) {
34 Label->FinalCheck(); 34 Label->finalCheck();
35 } 35 }
36 for (const Label *Label : LocalLabels) { 36 for (const Label *Label : LocalLabels) {
37 Label->FinalCheck(); 37 Label->finalCheck();
38 } 38 }
39 } 39 }
40 } 40 }
41 41
42 template <class Machine> void AssemblerX86Base<Machine>::alignFunction() { 42 template <class Machine> void AssemblerX86Base<Machine>::alignFunction() {
43 SizeT Align = 1 << getBundleAlignLog2Bytes(); 43 const SizeT Align = 1 << getBundleAlignLog2Bytes();
44 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); 44 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
45 const SizeT HltSize = 1; 45 constexpr SizeT HltSize = 1;
46 while (BytesNeeded > 0) { 46 while (BytesNeeded > 0) {
47 hlt(); 47 hlt();
48 BytesNeeded -= HltSize; 48 BytesNeeded -= HltSize;
49 } 49 }
50 } 50 }
51 51
52 template <class Machine> 52 template <class Machine>
53 Label *AssemblerX86Base<Machine>::GetOrCreateLabel(SizeT Number, 53 Label *AssemblerX86Base<Machine>::getOrCreateLabel(SizeT Number,
54 LabelVector &Labels) { 54 LabelVector &Labels) {
55 Label *L = nullptr; 55 Label *L = nullptr;
56 if (Number == Labels.size()) { 56 if (Number == Labels.size()) {
57 L = new (this->allocate<Label>()) Label(); 57 L = new (this->allocate<Label>()) Label();
58 Labels.push_back(L); 58 Labels.push_back(L);
59 return L; 59 return L;
60 } 60 }
61 if (Number > Labels.size()) { 61 if (Number > Labels.size()) {
62 Labels.resize(Number + 1); 62 Labels.resize(Number + 1);
63 } 63 }
64 L = Labels[Number]; 64 L = Labels[Number];
65 if (!L) { 65 if (!L) {
66 L = new (this->allocate<Label>()) Label(); 66 L = new (this->allocate<Label>()) Label();
67 Labels[Number] = L; 67 Labels[Number] = L;
68 } 68 }
69 return L; 69 return L;
70 } 70 }
71 71
72 template <class Machine> 72 template <class Machine>
73 Label *AssemblerX86Base<Machine>::GetOrCreateCfgNodeLabel(SizeT NodeNumber) { 73 Label *AssemblerX86Base<Machine>::getOrCreateCfgNodeLabel(SizeT NodeNumber) {
74 return GetOrCreateLabel(NodeNumber, CfgNodeLabels); 74 return getOrCreateLabel(NodeNumber, CfgNodeLabels);
75 } 75 }
76 76
77 template <class Machine> 77 template <class Machine>
78 Label *AssemblerX86Base<Machine>::GetOrCreateLocalLabel(SizeT Number) { 78 Label *AssemblerX86Base<Machine>::getOrCreateLocalLabel(SizeT Number) {
79 return GetOrCreateLabel(Number, LocalLabels); 79 return getOrCreateLabel(Number, LocalLabels);
80 } 80 }
81 81
82 template <class Machine> 82 template <class Machine>
83 void AssemblerX86Base<Machine>::bindCfgNodeLabel(SizeT NodeNumber) { 83 void AssemblerX86Base<Machine>::bindCfgNodeLabel(SizeT NodeNumber) {
84 assert(!getPreliminary()); 84 assert(!getPreliminary());
85 Label *L = GetOrCreateCfgNodeLabel(NodeNumber); 85 Label *L = getOrCreateCfgNodeLabel(NodeNumber);
86 this->bind(L); 86 this->bind(L);
87 } 87 }
88 88
89 template <class Machine> 89 template <class Machine>
90 void AssemblerX86Base<Machine>::BindLocalLabel(SizeT Number) { 90 void AssemblerX86Base<Machine>::BindLocalLabel(SizeT Number) {
91 Label *L = GetOrCreateLocalLabel(Number); 91 Label *L = getOrCreateLocalLabel(Number);
92 if (!getPreliminary()) 92 if (!getPreliminary())
93 this->bind(L); 93 this->bind(L);
94 } 94 }
95 95
96 template <class Machine> 96 template <class Machine>
97 void AssemblerX86Base<Machine>::call(typename Traits::GPRRegister reg) { 97 void AssemblerX86Base<Machine>::call(typename Traits::GPRRegister reg) {
98 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 98 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
99 emitUint8(0xFF); 99 emitUint8(0xFF);
100 emitRegisterOperand(2, reg); 100 emitRegisterOperand(2, reg);
101 } 101 }
(...skipping 2671 matching lines...) Expand 10 before | Expand all | Expand 10 after
2773 template <class Machine> void AssemblerX86Base<Machine>::ud2() { 2773 template <class Machine> void AssemblerX86Base<Machine>::ud2() {
2774 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2774 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2775 emitUint8(0x0F); 2775 emitUint8(0x0F);
2776 emitUint8(0x0B); 2776 emitUint8(0x0B);
2777 } 2777 }
2778 2778
2779 template <class Machine> 2779 template <class Machine>
2780 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition, 2780 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition,
2781 Label *label, bool near) { 2781 Label *label, bool near) {
2782 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2782 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2783 if (label->IsBound()) { 2783 if (label->isBound()) {
2784 static const int kShortSize = 2; 2784 static const int kShortSize = 2;
2785 static const int kLongSize = 6; 2785 static const int kLongSize = 6;
2786 intptr_t offset = label->Position() - Buffer.size(); 2786 intptr_t offset = label->getPosition() - Buffer.size();
2787 assert(offset <= 0); 2787 assert(offset <= 0);
2788 if (Utils::IsInt(8, offset - kShortSize)) { 2788 if (Utils::IsInt(8, offset - kShortSize)) {
2789 // TODO(stichnot): Here and in jmp(), we may need to be more 2789 // TODO(stichnot): Here and in jmp(), we may need to be more
2790 // conservative about the backward branch distance if the branch 2790 // conservative about the backward branch distance if the branch
2791 // instruction is within a bundle_lock sequence, because the 2791 // instruction is within a bundle_lock sequence, because the
2792 // distance may increase when padding is added. This isn't an 2792 // distance may increase when padding is added. This isn't an
2793 // issue for branches outside a bundle_lock, because if padding 2793 // issue for branches outside a bundle_lock, because if padding
2794 // is added, the retry may change it to a long backward branch 2794 // is added, the retry may change it to a long backward branch
2795 // without affecting any of the bookkeeping. 2795 // without affecting any of the bookkeeping.
2796 emitUint8(0x70 + condition); 2796 emitUint8(0x70 + condition);
(...skipping 26 matching lines...) Expand all
2823 template <class Machine> 2823 template <class Machine>
2824 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) { 2824 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) {
2825 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2825 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2826 emitUint8(0xFF); 2826 emitUint8(0xFF);
2827 emitRegisterOperand(4, reg); 2827 emitRegisterOperand(4, reg);
2828 } 2828 }
2829 2829
2830 template <class Machine> 2830 template <class Machine>
2831 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) { 2831 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) {
2832 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2832 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2833 if (label->IsBound()) { 2833 if (label->isBound()) {
2834 static const int kShortSize = 2; 2834 static const int kShortSize = 2;
2835 static const int kLongSize = 5; 2835 static const int kLongSize = 5;
2836 intptr_t offset = label->Position() - Buffer.size(); 2836 intptr_t offset = label->getPosition() - Buffer.size();
2837 assert(offset <= 0); 2837 assert(offset <= 0);
2838 if (Utils::IsInt(8, offset - kShortSize)) { 2838 if (Utils::IsInt(8, offset - kShortSize)) {
2839 emitUint8(0xEB); 2839 emitUint8(0xEB);
2840 emitUint8((offset - kShortSize) & 0xFF); 2840 emitUint8((offset - kShortSize) & 0xFF);
2841 } else { 2841 } else {
2842 emitUint8(0xE9); 2842 emitUint8(0xE9);
2843 emitInt32(offset - kLongSize); 2843 emitInt32(offset - kLongSize);
2844 } 2844 }
2845 } else if (near) { 2845 } else if (near) {
2846 emitUint8(0xEB); 2846 emitUint8(0xEB);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 bytes_needed -= MAX_NOP_SIZE; 2952 bytes_needed -= MAX_NOP_SIZE;
2953 } 2953 }
2954 if (bytes_needed) { 2954 if (bytes_needed) {
2955 nop(bytes_needed); 2955 nop(bytes_needed);
2956 } 2956 }
2957 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); 2957 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0);
2958 } 2958 }
2959 2959
2960 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) { 2960 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) {
2961 intptr_t bound = Buffer.size(); 2961 intptr_t bound = Buffer.size();
2962 assert(!label->IsBound()); // Labels can only be bound once. 2962 assert(!label->isBound()); // Labels can only be bound once.
2963 while (label->IsLinked()) { 2963 while (label->isLinked()) {
2964 intptr_t position = label->LinkPosition(); 2964 intptr_t position = label->getLinkPosition();
2965 intptr_t next = Buffer.load<int32_t>(position); 2965 intptr_t next = Buffer.load<int32_t>(position);
2966 Buffer.store<int32_t>(position, bound - (position + 4)); 2966 Buffer.store<int32_t>(position, bound - (position + 4));
2967 label->position_ = next; 2967 label->Position = next;
2968 } 2968 }
2969 while (label->HasNear()) { 2969 while (label->hasNear()) {
2970 intptr_t position = label->NearPosition(); 2970 intptr_t position = label->getNearPosition();
2971 intptr_t offset = bound - (position + 1); 2971 intptr_t offset = bound - (position + 1);
2972 assert(Utils::IsInt(8, offset)); 2972 assert(Utils::IsInt(8, offset));
2973 Buffer.store<int8_t>(position, offset); 2973 Buffer.store<int8_t>(position, offset);
2974 } 2974 }
2975 label->BindTo(bound); 2975 label->bindTo(bound);
2976 } 2976 }
2977 2977
2978 template <class Machine> 2978 template <class Machine>
2979 void AssemblerX86Base<Machine>::emitOperand( 2979 void AssemblerX86Base<Machine>::emitOperand(
2980 int rm, const typename Traits::Operand &operand) { 2980 int rm, const typename Traits::Operand &operand) {
2981 assert(rm >= 0 && rm < 8); 2981 assert(rm >= 0 && rm < 8);
2982 const intptr_t length = operand.length_; 2982 const intptr_t length = operand.length_;
2983 assert(length > 0); 2983 assert(length > 0);
2984 // Emit the ModRM byte updated with the given RM value. 2984 // Emit the ModRM byte updated with the given RM value.
2985 assert((operand.encoding_[0] & 0x38) == 0); 2985 assert((operand.encoding_[0] & 0x38) == 0);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3041 } else { 3041 } else {
3042 emitUint8(0x81); 3042 emitUint8(0x81);
3043 emitOperand(rm, operand); 3043 emitOperand(rm, operand);
3044 emitImmediate(Ty, immediate); 3044 emitImmediate(Ty, immediate);
3045 } 3045 }
3046 } 3046 }
3047 3047
3048 template <class Machine> 3048 template <class Machine>
3049 void AssemblerX86Base<Machine>::emitLabel(Label *label, 3049 void AssemblerX86Base<Machine>::emitLabel(Label *label,
3050 intptr_t instruction_size) { 3050 intptr_t instruction_size) {
3051 if (label->IsBound()) { 3051 if (label->isBound()) {
3052 intptr_t offset = label->Position() - Buffer.size(); 3052 intptr_t offset = label->getPosition() - Buffer.size();
3053 assert(offset <= 0); 3053 assert(offset <= 0);
3054 emitInt32(offset - instruction_size); 3054 emitInt32(offset - instruction_size);
3055 } else { 3055 } else {
3056 emitLabelLink(label); 3056 emitLabelLink(label);
3057 } 3057 }
3058 } 3058 }
3059 3059
3060 template <class Machine> 3060 template <class Machine>
3061 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) { 3061 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) {
3062 assert(!Label->IsBound()); 3062 assert(!Label->isBound());
3063 intptr_t Position = Buffer.size(); 3063 intptr_t Position = Buffer.size();
3064 emitInt32(Label->position_); 3064 emitInt32(Label->Position);
3065 if (!getPreliminary()) 3065 if (!getPreliminary())
3066 Label->LinkTo(Position); 3066 Label->linkTo(Position);
3067 } 3067 }
3068 3068
3069 template <class Machine> 3069 template <class Machine>
3070 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *label) { 3070 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *label) {
3071 assert(!label->IsBound()); 3071 assert(!label->isBound());
3072 intptr_t position = Buffer.size(); 3072 intptr_t position = Buffer.size();
3073 emitUint8(0); 3073 emitUint8(0);
3074 if (!getPreliminary()) 3074 if (!getPreliminary())
3075 label->NearLinkTo(position); 3075 label->nearLinkTo(position);
3076 } 3076 }
3077 3077
3078 template <class Machine> 3078 template <class Machine>
3079 void AssemblerX86Base<Machine>::emitGenericShift( 3079 void AssemblerX86Base<Machine>::emitGenericShift(
3080 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) { 3080 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) {
3081 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3081 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3082 assert(imm.is_int8()); 3082 assert(imm.is_int8());
3083 if (Ty == IceType_i16) 3083 if (Ty == IceType_i16)
3084 emitOperandSizeOverride(); 3084 emitOperandSizeOverride();
3085 if (imm.value() == 1) { 3085 if (imm.value() == 1) {
(...skipping 14 matching lines...) Expand all
3100 assert(shifter == Traits::Encoded_Reg_Counter); 3100 assert(shifter == Traits::Encoded_Reg_Counter);
3101 (void)shifter; 3101 (void)shifter;
3102 if (Ty == IceType_i16) 3102 if (Ty == IceType_i16)
3103 emitOperandSizeOverride(); 3103 emitOperandSizeOverride();
3104 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); 3104 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
3105 emitOperand(rm, operand); 3105 emitOperand(rm, operand);
3106 } 3106 }
3107 3107
3108 } // end of namespace X86Internal 3108 } // end of namespace X86Internal
3109 } // end of namespace Ice 3109 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698