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

Side by Side Diff: src/IceAssemblerX86Base.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: Rebase 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
« no previous file with comments | « src/IceAssemblerX8632.h ('k') | src/IceAssemblerX86BaseImpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===// 1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 } 64 }
65 bool is_uint16() const { 65 bool is_uint16() const {
66 return fixup_ == nullptr && Utils::IsUint(16, value_); 66 return fixup_ == nullptr && Utils::IsUint(16, value_);
67 } 67 }
68 68
69 private: 69 private:
70 const int32_t value_; 70 const int32_t value_;
71 AssemblerFixup *fixup_ = nullptr; 71 AssemblerFixup *fixup_ = nullptr;
72 }; 72 };
73 73
74 class Label { 74 /// X86 allows near and far jumps.
75 class Label final : public Ice::Label {
75 Label(const Label &) = delete; 76 Label(const Label &) = delete;
76 Label &operator=(const Label &) = delete; 77 Label &operator=(const Label &) = delete;
77 78
78 public: 79 public:
79 Label() { 80 Label() = default;
80 if (BuildDefs::asserts()) { 81 ~Label() = default;
81 for (int i = 0; i < kMaxUnresolvedBranches; i++) { 82
82 unresolved_near_positions_[i] = -1; 83 void finalCheck() const override {
83 } 84 Ice::Label::finalCheck();
84 } 85 assert(!hasNear());
85 } 86 }
86 87
87 ~Label() = default; 88 /// Returns the position of an earlier branch instruction which assumes that
88 89 /// this label is "near", and bumps iterator to the next near position.
89 void FinalCheck() const { 90 intptr_t getNearPosition() {
90 // Assert if label is being destroyed with unresolved branches pending. 91 assert(hasNear());
91 assert(!IsLinked()); 92 intptr_t Pos = UnresolvedNearPositions.back();
92 assert(!HasNear()); 93 UnresolvedNearPositions.pop_back();
94 return Pos;
93 } 95 }
94 96
95 // TODO(jvoung): why are labels offset by this? 97 bool hasNear() const { return !UnresolvedNearPositions.empty(); }
96 static const uint32_t kWordSize = sizeof(uint32_t); 98 bool isUnused() const override {
97 99 return Ice::Label::isUnused() && !hasNear();
98 // Returns the position for bound labels (branches that come after this
99 // are considered backward branches). Cannot be used for unused or linked
100 // labels.
101 intptr_t Position() const {
102 assert(IsBound());
103 return -position_ - kWordSize;
104 } 100 }
105 101
106 // Returns the position of an earlier branch instruction that was linked 102 private:
107 // to this label (branches that use this are considered forward branches). 103 void nearLinkTo(intptr_t position) {
108 // The linked instructions form a linked list, of sorts, using the 104 assert(!isBound());
109 // instruction's displacement field for the location of the next 105 UnresolvedNearPositions.push_back(position);
110 // instruction that is also linked to this label.
111 intptr_t LinkPosition() const {
112 assert(IsLinked());
113 return position_ - kWordSize;
114 } 106 }
115 107
116 // Returns the position of an earlier branch instruction which 108 llvm::SmallVector<intptr_t, 20> UnresolvedNearPositions;
117 // assumes that this label is "near", and bumps iterator to the
118 // next near position.
119 intptr_t NearPosition() {
120 assert(HasNear());
121 return unresolved_near_positions_[--num_unresolved_];
122 }
123
124 bool IsBound() const { return position_ < 0; }
125 bool IsLinked() const { return position_ > 0; }
126 bool IsUnused() const { return (position_ == 0) && (num_unresolved_ == 0); }
127 bool HasNear() const { return num_unresolved_ != 0; }
128
129 private:
130 void BindTo(intptr_t position) {
131 assert(!IsBound());
132 assert(!HasNear());
133 position_ = -position - kWordSize;
134 assert(IsBound());
135 }
136
137 void LinkTo(intptr_t position) {
138 assert(!IsBound());
139 position_ = position + kWordSize;
140 assert(IsLinked());
141 }
142
143 void NearLinkTo(intptr_t position) {
144 assert(!IsBound());
145 assert(num_unresolved_ < kMaxUnresolvedBranches);
146 unresolved_near_positions_[num_unresolved_++] = position;
147 }
148
149 static constexpr int kMaxUnresolvedBranches = 20;
150
151 intptr_t position_ = 0;
152 intptr_t num_unresolved_ = 0;
153 // TODO(stichnot,jvoung): Can this instead be
154 // llvm::SmallVector<intptr_t, kMaxUnresolvedBranches> ?
155 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
156 109
157 template <class> friend class AssemblerX86Base; 110 template <class> friend class AssemblerX86Base;
158 }; 111 };
159 112
160 template <class Machine> class AssemblerX86Base : public Assembler { 113 template <class Machine> class AssemblerX86Base : public Assembler {
161 AssemblerX86Base(const AssemblerX86Base &) = delete; 114 AssemblerX86Base(const AssemblerX86Base &) = delete;
162 AssemblerX86Base &operator=(const AssemblerX86Base &) = delete; 115 AssemblerX86Base &operator=(const AssemblerX86Base &) = delete;
163 116
164 protected: 117 protected:
165 AssemblerX86Base(AssemblerKind Kind, bool use_far_branches) 118 AssemblerX86Base(AssemblerKind Kind, bool use_far_branches)
166 : Assembler(Kind) { 119 : Assembler(Kind) {
167 // This mode is only needed and implemented for MIPS and ARM. 120 // This mode is only needed and implemented for MIPS and ARM.
168 assert(!use_far_branches); 121 assert(!use_far_branches);
169 (void)use_far_branches; 122 (void)use_far_branches;
170 } 123 }
171 124
172 public: 125 public:
173 using Traits = MachineTraits<Machine>; 126 using Traits = MachineTraits<Machine>;
174 127
175 ~AssemblerX86Base() override; 128 ~AssemblerX86Base() override;
176 129
177 static const bool kNearJump = true; 130 static const bool kNearJump = true;
178 static const bool kFarJump = false; 131 static const bool kFarJump = false;
179 132
180 void alignFunction() override; 133 void alignFunction() override;
181 134
182 SizeT getBundleAlignLog2Bytes() const override { return 5; } 135 SizeT getBundleAlignLog2Bytes() const override { return 5; }
183 136
184 const char *getNonExecPadDirective() const override { return ".p2align"; } 137 const char *getAlignDirective() const override { return ".p2align"; }
185 138
186 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { 139 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override {
187 static const uint8_t Padding[] = {0xF4}; 140 static const uint8_t Padding[] = {0xF4};
188 return llvm::ArrayRef<uint8_t>(Padding, 1); 141 return llvm::ArrayRef<uint8_t>(Padding, 1);
189 } 142 }
190 143
191 void padWithNop(intptr_t Padding) override { 144 void padWithNop(intptr_t Padding) override {
192 while (Padding > MAX_NOP_SIZE) { 145 while (Padding > MAX_NOP_SIZE) {
193 nop(MAX_NOP_SIZE); 146 nop(MAX_NOP_SIZE);
194 Padding -= MAX_NOP_SIZE; 147 Padding -= MAX_NOP_SIZE;
195 } 148 }
196 if (Padding) 149 if (Padding)
197 nop(Padding); 150 nop(Padding);
198 } 151 }
199 152
200 Label *GetOrCreateCfgNodeLabel(SizeT NodeNumber); 153 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) override;
201 void bindCfgNodeLabel(SizeT NodeNumber) override; 154 void bindCfgNodeLabel(SizeT NodeNumber) override;
202 Label *GetOrCreateLocalLabel(SizeT Number); 155 Label *getOrCreateLocalLabel(SizeT Number);
203 void BindLocalLabel(SizeT Number); 156 void bindLocalLabel(SizeT Number);
204 157
205 bool fixupIsPCRel(FixupKind Kind) const override { 158 bool fixupIsPCRel(FixupKind Kind) const override {
206 // Currently assuming this is the only PC-rel relocation type used. 159 // Currently assuming this is the only PC-rel relocation type used.
207 // TODO(jpp): Traits.PcRelTypes.count(Kind) != 0 160 // TODO(jpp): Traits.PcRelTypes.count(Kind) != 0
208 return Kind == Traits::PcRelFixup; 161 return Kind == Traits::PcRelFixup;
209 } 162 }
210 163
211 // Operations to emit GPR instructions (and dispatch on operand type). 164 // Operations to emit GPR instructions (and dispatch on operand type).
212 typedef void (AssemblerX86Base::*TypedEmitGPR)(Type, 165 typedef void (AssemblerX86Base::*TypedEmitGPR)(Type,
213 typename Traits::GPRRegister); 166 typename Traits::GPRRegister);
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 void emitGenericShift(int rm, Type Ty, 872 void emitGenericShift(int rm, Type Ty,
920 const typename Traits::Operand &operand, 873 const typename Traits::Operand &operand,
921 typename Traits::GPRRegister shifter); 874 typename Traits::GPRRegister shifter);
922 875
923 typedef std::vector<Label *> LabelVector; 876 typedef std::vector<Label *> LabelVector;
924 // A vector of pool-allocated x86 labels for CFG nodes. 877 // A vector of pool-allocated x86 labels for CFG nodes.
925 LabelVector CfgNodeLabels; 878 LabelVector CfgNodeLabels;
926 // A vector of pool-allocated x86 labels for Local labels. 879 // A vector of pool-allocated x86 labels for Local labels.
927 LabelVector LocalLabels; 880 LabelVector LocalLabels;
928 881
929 Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels); 882 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
930 883
931 // The arith_int() methods factor out the commonality between the encodings of 884 // The arith_int() methods factor out the commonality between the encodings of
932 // add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag 885 // add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag
933 // parameter is statically asserted to be less than 8. 886 // parameter is statically asserted to be less than 8.
934 template <uint32_t Tag> 887 template <uint32_t Tag>
935 void arith_int(Type Ty, typename Traits::GPRRegister reg, 888 void arith_int(Type Ty, typename Traits::GPRRegister reg,
936 const Immediate &imm); 889 const Immediate &imm);
937 890
938 template <uint32_t Tag> 891 template <uint32_t Tag>
939 void arith_int(Type Ty, typename Traits::GPRRegister reg0, 892 void arith_int(Type Ty, typename Traits::GPRRegister reg0,
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 emitUint8(0x66); 1038 emitUint8(0x66);
1086 } 1039 }
1087 1040
1088 } // end of namespace X86Internal 1041 } // end of namespace X86Internal
1089 1042
1090 } // end of namespace Ice 1043 } // end of namespace Ice
1091 1044
1092 #include "IceAssemblerX86BaseImpl.h" 1045 #include "IceAssemblerX86BaseImpl.h"
1093 1046
1094 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H 1047 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H
OLDNEW
« no previous file with comments | « src/IceAssemblerX8632.h ('k') | src/IceAssemblerX86BaseImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698