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

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: 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/IceAssemblerX86Base.h ('k') | src/IceCfg.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/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 emitRexB(RexTypeIrrelevant, reg); 99 emitRexB(RexTypeIrrelevant, reg);
100 emitUint8(0xFF); 100 emitUint8(0xFF);
101 emitRegisterOperand(2, gprEncoding(reg)); 101 emitRegisterOperand(2, gprEncoding(reg));
(...skipping 2840 matching lines...) Expand 10 before | Expand all | Expand 10 after
2942 template <class Machine> void AssemblerX86Base<Machine>::ud2() { 2942 template <class Machine> void AssemblerX86Base<Machine>::ud2() {
2943 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2943 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2944 emitUint8(0x0F); 2944 emitUint8(0x0F);
2945 emitUint8(0x0B); 2945 emitUint8(0x0B);
2946 } 2946 }
2947 2947
2948 template <class Machine> 2948 template <class Machine>
2949 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition, 2949 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition,
2950 Label *label, bool near) { 2950 Label *label, bool near) {
2951 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2951 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2952 if (label->IsBound()) { 2952 if (label->isBound()) {
2953 static const int kShortSize = 2; 2953 static const int kShortSize = 2;
2954 static const int kLongSize = 6; 2954 static const int kLongSize = 6;
2955 intptr_t offset = label->Position() - Buffer.size(); 2955 intptr_t offset = label->getPosition() - Buffer.size();
2956 assert(offset <= 0); 2956 assert(offset <= 0);
2957 if (Utils::IsInt(8, offset - kShortSize)) { 2957 if (Utils::IsInt(8, offset - kShortSize)) {
2958 // TODO(stichnot): Here and in jmp(), we may need to be more 2958 // TODO(stichnot): Here and in jmp(), we may need to be more
2959 // conservative about the backward branch distance if the branch 2959 // conservative about the backward branch distance if the branch
2960 // instruction is within a bundle_lock sequence, because the 2960 // instruction is within a bundle_lock sequence, because the
2961 // distance may increase when padding is added. This isn't an 2961 // distance may increase when padding is added. This isn't an
2962 // issue for branches outside a bundle_lock, because if padding 2962 // issue for branches outside a bundle_lock, because if padding
2963 // is added, the retry may change it to a long backward branch 2963 // is added, the retry may change it to a long backward branch
2964 // without affecting any of the bookkeeping. 2964 // without affecting any of the bookkeeping.
2965 emitUint8(0x70 + condition); 2965 emitUint8(0x70 + condition);
(...skipping 27 matching lines...) Expand all
2993 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) { 2993 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) {
2994 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2994 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2995 emitRexB(RexTypeIrrelevant, reg); 2995 emitRexB(RexTypeIrrelevant, reg);
2996 emitUint8(0xFF); 2996 emitUint8(0xFF);
2997 emitRegisterOperand(4, gprEncoding(reg)); 2997 emitRegisterOperand(4, gprEncoding(reg));
2998 } 2998 }
2999 2999
3000 template <class Machine> 3000 template <class Machine>
3001 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) { 3001 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) {
3002 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3002 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3003 if (label->IsBound()) { 3003 if (label->isBound()) {
3004 static const int kShortSize = 2; 3004 static const int kShortSize = 2;
3005 static const int kLongSize = 5; 3005 static const int kLongSize = 5;
3006 intptr_t offset = label->Position() - Buffer.size(); 3006 intptr_t offset = label->getPosition() - Buffer.size();
3007 assert(offset <= 0); 3007 assert(offset <= 0);
3008 if (Utils::IsInt(8, offset - kShortSize)) { 3008 if (Utils::IsInt(8, offset - kShortSize)) {
3009 emitUint8(0xEB); 3009 emitUint8(0xEB);
3010 emitUint8((offset - kShortSize) & 0xFF); 3010 emitUint8((offset - kShortSize) & 0xFF);
3011 } else { 3011 } else {
3012 emitUint8(0xE9); 3012 emitUint8(0xE9);
3013 emitInt32(offset - kLongSize); 3013 emitInt32(offset - kLongSize);
3014 } 3014 }
3015 } else if (near) { 3015 } else if (near) {
3016 emitUint8(0xEB); 3016 emitUint8(0xEB);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3126 bytes_needed -= MAX_NOP_SIZE; 3126 bytes_needed -= MAX_NOP_SIZE;
3127 } 3127 }
3128 if (bytes_needed) { 3128 if (bytes_needed) {
3129 nop(bytes_needed); 3129 nop(bytes_needed);
3130 } 3130 }
3131 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); 3131 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0);
3132 } 3132 }
3133 3133
3134 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) { 3134 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) {
3135 intptr_t bound = Buffer.size(); 3135 intptr_t bound = Buffer.size();
3136 assert(!label->IsBound()); // Labels can only be bound once. 3136 assert(!label->isBound()); // Labels can only be bound once.
3137 while (label->IsLinked()) { 3137 while (label->isLinked()) {
3138 intptr_t position = label->LinkPosition(); 3138 intptr_t position = label->getLinkPosition();
3139 intptr_t next = Buffer.load<int32_t>(position); 3139 intptr_t next = Buffer.load<int32_t>(position);
3140 Buffer.store<int32_t>(position, bound - (position + 4)); 3140 Buffer.store<int32_t>(position, bound - (position + 4));
3141 label->position_ = next; 3141 label->Position = next;
3142 } 3142 }
3143 while (label->HasNear()) { 3143 while (label->hasNear()) {
3144 intptr_t position = label->NearPosition(); 3144 intptr_t position = label->getNearPosition();
3145 intptr_t offset = bound - (position + 1); 3145 intptr_t offset = bound - (position + 1);
3146 assert(Utils::IsInt(8, offset)); 3146 assert(Utils::IsInt(8, offset));
3147 Buffer.store<int8_t>(position, offset); 3147 Buffer.store<int8_t>(position, offset);
3148 } 3148 }
3149 label->BindTo(bound); 3149 label->bindTo(bound);
3150 } 3150 }
3151 3151
3152 template <class Machine> 3152 template <class Machine>
3153 void AssemblerX86Base<Machine>::emitOperand( 3153 void AssemblerX86Base<Machine>::emitOperand(
3154 int rm, const typename Traits::Operand &operand) { 3154 int rm, const typename Traits::Operand &operand) {
3155 assert(rm >= 0 && rm < 8); 3155 assert(rm >= 0 && rm < 8);
3156 const intptr_t length = operand.length_; 3156 const intptr_t length = operand.length_;
3157 assert(length > 0); 3157 assert(length > 0);
3158 // Emit the ModRM byte updated with the given RM value. 3158 // Emit the ModRM byte updated with the given RM value.
3159 assert((operand.encoding_[0] & 0x38) == 0); 3159 assert((operand.encoding_[0] & 0x38) == 0);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 } else { 3215 } else {
3216 emitUint8(0x81); 3216 emitUint8(0x81);
3217 emitOperand(rm, operand); 3217 emitOperand(rm, operand);
3218 emitImmediate(Ty, immediate); 3218 emitImmediate(Ty, immediate);
3219 } 3219 }
3220 } 3220 }
3221 3221
3222 template <class Machine> 3222 template <class Machine>
3223 void AssemblerX86Base<Machine>::emitLabel(Label *label, 3223 void AssemblerX86Base<Machine>::emitLabel(Label *label,
3224 intptr_t instruction_size) { 3224 intptr_t instruction_size) {
3225 if (label->IsBound()) { 3225 if (label->isBound()) {
3226 intptr_t offset = label->Position() - Buffer.size(); 3226 intptr_t offset = label->getPosition() - Buffer.size();
3227 assert(offset <= 0); 3227 assert(offset <= 0);
3228 emitInt32(offset - instruction_size); 3228 emitInt32(offset - instruction_size);
3229 } else { 3229 } else {
3230 emitLabelLink(label); 3230 emitLabelLink(label);
3231 } 3231 }
3232 } 3232 }
3233 3233
3234 template <class Machine> 3234 template <class Machine>
3235 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) { 3235 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) {
3236 assert(!Label->IsBound()); 3236 assert(!Label->isBound());
3237 intptr_t Position = Buffer.size(); 3237 intptr_t Position = Buffer.size();
3238 emitInt32(Label->position_); 3238 emitInt32(Label->Position);
3239 if (!getPreliminary()) 3239 if (!getPreliminary())
3240 Label->LinkTo(Position); 3240 Label->linkTo(Position);
3241 } 3241 }
3242 3242
3243 template <class Machine> 3243 template <class Machine>
3244 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *label) { 3244 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *label) {
3245 assert(!label->IsBound()); 3245 assert(!label->isBound());
3246 intptr_t position = Buffer.size(); 3246 intptr_t position = Buffer.size();
3247 emitUint8(0); 3247 emitUint8(0);
3248 if (!getPreliminary()) 3248 if (!getPreliminary())
3249 label->NearLinkTo(position); 3249 label->nearLinkTo(position);
3250 } 3250 }
3251 3251
3252 template <class Machine> 3252 template <class Machine>
3253 void AssemblerX86Base<Machine>::emitGenericShift( 3253 void AssemblerX86Base<Machine>::emitGenericShift(
3254 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) { 3254 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) {
3255 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3255 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3256 assert(imm.is_int8()); 3256 assert(imm.is_int8());
3257 if (Ty == IceType_i16) 3257 if (Ty == IceType_i16)
3258 emitOperandSizeOverride(); 3258 emitOperandSizeOverride();
3259 emitRexB(Ty, reg); 3259 emitRexB(Ty, reg);
(...skipping 16 matching lines...) Expand all
3276 (void)shifter; 3276 (void)shifter;
3277 if (Ty == IceType_i16) 3277 if (Ty == IceType_i16)
3278 emitOperandSizeOverride(); 3278 emitOperandSizeOverride();
3279 emitRexB(Ty, operand.rm()); 3279 emitRexB(Ty, operand.rm());
3280 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); 3280 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
3281 emitOperand(rm, operand); 3281 emitOperand(rm, operand);
3282 } 3282 }
3283 3283
3284 } // end of namespace X86Internal 3284 } // end of namespace X86Internal
3285 } // end of namespace Ice 3285 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerX86Base.h ('k') | src/IceCfg.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698