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

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 550113002: [turbofan] Tests and fixes for ARM64 load/store with immediate offset. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Updated patch after changes arround ptrdiff_t. Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/instruction-selector-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
11 11
12 enum ImmediateMode { 12 enum ImmediateMode {
13 kArithmeticImm, // 12 bit unsigned immediate shifted left 0 or 12 bits 13 kArithmeticImm, // 12 bit unsigned immediate shifted left 0 or 12 bits
14 kShift32Imm, // 0 - 31 14 kShift32Imm, // 0 - 31
15 kShift64Imm, // 0 - 63 15 kShift64Imm, // 0 - 63
16 kLogical32Imm, 16 kLogical32Imm,
17 kLogical64Imm, 17 kLogical64Imm,
18 kLoadStoreImm, // unsigned 9 bit or signed 7 bit 18 kLoadStoreImm8, // signed 8 bit or 12 bit unsigned scaled by access size
19 kLoadStoreImm16,
20 kLoadStoreImm32,
21 kLoadStoreImm64,
19 kNoImmediate 22 kNoImmediate
20 }; 23 };
21 24
22 25
23 // Adds Arm64-specific methods for generating operands. 26 // Adds Arm64-specific methods for generating operands.
24 class Arm64OperandGenerator FINAL : public OperandGenerator { 27 class Arm64OperandGenerator FINAL : public OperandGenerator {
25 public: 28 public:
26 explicit Arm64OperandGenerator(InstructionSelector* selector) 29 explicit Arm64OperandGenerator(InstructionSelector* selector)
27 : OperandGenerator(selector) {} 30 : OperandGenerator(selector) {}
28 31
(...skipping 18 matching lines...) Expand all
47 case kLogical64Imm: 50 case kLogical64Imm:
48 return Assembler::IsImmLogical(static_cast<uint64_t>(value), 64, 51 return Assembler::IsImmLogical(static_cast<uint64_t>(value), 64,
49 &ignored, &ignored, &ignored); 52 &ignored, &ignored, &ignored);
50 case kArithmeticImm: 53 case kArithmeticImm:
51 // TODO(dcarney): -values can be handled by instruction swapping 54 // TODO(dcarney): -values can be handled by instruction swapping
52 return Assembler::IsImmAddSub(value); 55 return Assembler::IsImmAddSub(value);
53 case kShift32Imm: 56 case kShift32Imm:
54 return 0 <= value && value < 32; 57 return 0 <= value && value < 32;
55 case kShift64Imm: 58 case kShift64Imm:
56 return 0 <= value && value < 64; 59 return 0 <= value && value < 64;
57 case kLoadStoreImm: 60 case kLoadStoreImm8:
58 return (0 <= value && value < (1 << 9)) || 61 return IsLoadStoreImmediate(value, LSByte);
59 (-(1 << 6) <= value && value < (1 << 6)); 62 case kLoadStoreImm16:
63 return IsLoadStoreImmediate(value, LSHalfword);
64 case kLoadStoreImm32:
65 return IsLoadStoreImmediate(value, LSWord);
66 case kLoadStoreImm64:
67 return IsLoadStoreImmediate(value, LSDoubleWord);
60 case kNoImmediate: 68 case kNoImmediate:
61 return false; 69 return false;
62 } 70 }
63 return false; 71 return false;
64 } 72 }
73
74 private:
75 bool IsLoadStoreImmediate(int64_t value, LSDataSize size) {
76 return Assembler::IsImmLSScaled(value, size) ||
77 Assembler::IsImmLSUnscaled(value);
78 }
65 }; 79 };
66 80
67 81
68 static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, 82 static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
69 Node* node) { 83 Node* node) {
70 Arm64OperandGenerator g(selector); 84 Arm64OperandGenerator g(selector);
71 selector->Emit(opcode, g.DefineAsRegister(node), 85 selector->Emit(opcode, g.DefineAsRegister(node),
72 g.UseRegister(node->InputAt(0)), 86 g.UseRegister(node->InputAt(0)),
73 g.UseRegister(node->InputAt(1))); 87 g.UseRegister(node->InputAt(1)));
74 } 88 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 149 }
136 150
137 151
138 void InstructionSelector::VisitLoad(Node* node) { 152 void InstructionSelector::VisitLoad(Node* node) {
139 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); 153 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
140 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); 154 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
141 Arm64OperandGenerator g(this); 155 Arm64OperandGenerator g(this);
142 Node* base = node->InputAt(0); 156 Node* base = node->InputAt(0);
143 Node* index = node->InputAt(1); 157 Node* index = node->InputAt(1);
144 ArchOpcode opcode; 158 ArchOpcode opcode;
159 ImmediateMode immediate_mode = kNoImmediate;
145 switch (rep) { 160 switch (rep) {
146 case kRepFloat32: 161 case kRepFloat32:
147 opcode = kArm64LdrS; 162 opcode = kArm64LdrS;
163 immediate_mode = kLoadStoreImm32;
148 break; 164 break;
149 case kRepFloat64: 165 case kRepFloat64:
150 opcode = kArm64LdrD; 166 opcode = kArm64LdrD;
167 immediate_mode = kLoadStoreImm64;
151 break; 168 break;
152 case kRepBit: // Fall through. 169 case kRepBit: // Fall through.
153 case kRepWord8: 170 case kRepWord8:
154 opcode = typ == kTypeInt32 ? kArm64Ldrsb : kArm64Ldrb; 171 opcode = typ == kTypeInt32 ? kArm64Ldrsb : kArm64Ldrb;
172 immediate_mode = kLoadStoreImm8;
155 break; 173 break;
156 case kRepWord16: 174 case kRepWord16:
157 opcode = typ == kTypeInt32 ? kArm64Ldrsh : kArm64Ldrh; 175 opcode = typ == kTypeInt32 ? kArm64Ldrsh : kArm64Ldrh;
176 immediate_mode = kLoadStoreImm16;
158 break; 177 break;
159 case kRepWord32: 178 case kRepWord32:
160 opcode = kArm64LdrW; 179 opcode = kArm64LdrW;
180 immediate_mode = kLoadStoreImm32;
161 break; 181 break;
162 case kRepTagged: // Fall through. 182 case kRepTagged: // Fall through.
163 case kRepWord64: 183 case kRepWord64:
164 opcode = kArm64Ldr; 184 opcode = kArm64Ldr;
185 immediate_mode = kLoadStoreImm64;
165 break; 186 break;
166 default: 187 default:
167 UNREACHABLE(); 188 UNREACHABLE();
168 return; 189 return;
169 } 190 }
170 if (g.CanBeImmediate(index, kLoadStoreImm)) { 191 if (g.CanBeImmediate(index, immediate_mode)) {
171 Emit(opcode | AddressingModeField::encode(kMode_MRI), 192 Emit(opcode | AddressingModeField::encode(kMode_MRI),
172 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); 193 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
173 } else { 194 } else {
174 Emit(opcode | AddressingModeField::encode(kMode_MRR), 195 Emit(opcode | AddressingModeField::encode(kMode_MRR),
175 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); 196 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
176 } 197 }
177 } 198 }
178 199
179 200
180 void InstructionSelector::VisitStore(Node* node) { 201 void InstructionSelector::VisitStore(Node* node) {
(...skipping 10 matching lines...) Expand all
191 // and pass them here instead of using fixed regs 212 // and pass them here instead of using fixed regs
192 // TODO(dcarney): handle immediate indices. 213 // TODO(dcarney): handle immediate indices.
193 InstructionOperand* temps[] = {g.TempRegister(x11), g.TempRegister(x12)}; 214 InstructionOperand* temps[] = {g.TempRegister(x11), g.TempRegister(x12)};
194 Emit(kArm64StoreWriteBarrier, NULL, g.UseFixed(base, x10), 215 Emit(kArm64StoreWriteBarrier, NULL, g.UseFixed(base, x10),
195 g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps), 216 g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps),
196 temps); 217 temps);
197 return; 218 return;
198 } 219 }
199 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); 220 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
200 ArchOpcode opcode; 221 ArchOpcode opcode;
222 ImmediateMode immediate_mode = kNoImmediate;
201 switch (rep) { 223 switch (rep) {
202 case kRepFloat32: 224 case kRepFloat32:
203 opcode = kArm64StrS; 225 opcode = kArm64StrS;
226 immediate_mode = kLoadStoreImm32;
204 break; 227 break;
205 case kRepFloat64: 228 case kRepFloat64:
206 opcode = kArm64StrD; 229 opcode = kArm64StrD;
230 immediate_mode = kLoadStoreImm64;
207 break; 231 break;
208 case kRepBit: // Fall through. 232 case kRepBit: // Fall through.
209 case kRepWord8: 233 case kRepWord8:
210 opcode = kArm64Strb; 234 opcode = kArm64Strb;
235 immediate_mode = kLoadStoreImm8;
211 break; 236 break;
212 case kRepWord16: 237 case kRepWord16:
213 opcode = kArm64Strh; 238 opcode = kArm64Strh;
239 immediate_mode = kLoadStoreImm16;
214 break; 240 break;
215 case kRepWord32: 241 case kRepWord32:
216 opcode = kArm64StrW; 242 opcode = kArm64StrW;
243 immediate_mode = kLoadStoreImm32;
217 break; 244 break;
218 case kRepTagged: // Fall through. 245 case kRepTagged: // Fall through.
219 case kRepWord64: 246 case kRepWord64:
220 opcode = kArm64Str; 247 opcode = kArm64Str;
248 immediate_mode = kLoadStoreImm64;
221 break; 249 break;
222 default: 250 default:
223 UNREACHABLE(); 251 UNREACHABLE();
224 return; 252 return;
225 } 253 }
226 if (g.CanBeImmediate(index, kLoadStoreImm)) { 254 if (g.CanBeImmediate(index, immediate_mode)) {
227 Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, 255 Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
228 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 256 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
229 } else { 257 } else {
230 Emit(opcode | AddressingModeField::encode(kMode_MRR), NULL, 258 Emit(opcode | AddressingModeField::encode(kMode_MRR), NULL,
231 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); 259 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
232 } 260 }
233 } 261 }
234 262
235 263
236 void InstructionSelector::VisitWord32And(Node* node) { 264 void InstructionSelector::VisitWord32And(Node* node) {
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 // Caller clean up of stack for C-style calls. 689 // Caller clean up of stack for C-style calls.
662 if (is_c_frame && aligned_push_count > 0) { 690 if (is_c_frame && aligned_push_count > 0) {
663 DCHECK(deoptimization == NULL && continuation == NULL); 691 DCHECK(deoptimization == NULL && continuation == NULL);
664 Emit(kArchDrop | MiscField::encode(aligned_push_count), NULL); 692 Emit(kArchDrop | MiscField::encode(aligned_push_count), NULL);
665 } 693 }
666 } 694 }
667 695
668 } // namespace compiler 696 } // namespace compiler
669 } // namespace internal 697 } // namespace internal
670 } // namespace v8 698 } // namespace v8
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698