OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/assembler.h" | 5 #include "src/assembler.h" |
6 #include "src/macro-assembler.h" | 6 #include "src/macro-assembler.h" |
7 #include "src/register-configuration.h" | 7 #include "src/register-configuration.h" |
8 | 8 |
9 #include "src/wasm/wasm-module.h" | 9 #include "src/wasm/wasm-module.h" |
10 | 10 |
11 #include "src/compiler/linkage.h" | 11 #include "src/compiler/linkage.h" |
12 | 12 |
13 #include "src/zone.h" | 13 #include "src/zone.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 // TODO(titzer): this should not be in the WASM namespace. | 17 // TODO(titzer): this should not be in the WASM namespace. |
18 namespace wasm { | 18 namespace wasm { |
19 | 19 |
20 using compiler::LocationSignature; | 20 using compiler::LocationSignature; |
21 using compiler::CallDescriptor; | 21 using compiler::CallDescriptor; |
22 using compiler::LinkageLocation; | 22 using compiler::LinkageLocation; |
23 | 23 |
24 namespace { | 24 namespace { |
| 25 |
25 MachineType MachineTypeFor(LocalType type) { | 26 MachineType MachineTypeFor(LocalType type) { |
26 switch (type) { | 27 switch (type) { |
27 case kAstI32: | 28 case kAstI32: |
28 return MachineType::Int32(); | 29 return MachineType::Int32(); |
29 case kAstI64: | 30 case kAstI64: |
30 return MachineType::Int64(); | 31 return MachineType::Int64(); |
31 case kAstF64: | 32 case kAstF64: |
32 return MachineType::Float64(); | 33 return MachineType::Float64(); |
33 case kAstF32: | 34 case kAstF32: |
34 return MachineType::Float32(); | 35 return MachineType::Float32(); |
35 case kAstS128: | 36 case kAstS128: |
36 return MachineType::Simd128(); | 37 return MachineType::Simd128(); |
37 default: | 38 default: |
38 UNREACHABLE(); | 39 UNREACHABLE(); |
39 return MachineType::AnyTagged(); | 40 return MachineType::AnyTagged(); |
40 } | 41 } |
41 } | 42 } |
42 | 43 |
| 44 LinkageLocation regloc(Register reg, MachineType type) { |
| 45 return LinkageLocation::ForRegister(reg.code(), type); |
| 46 } |
43 | 47 |
44 // Platform-specific configuration for C calling convention. | 48 LinkageLocation regloc(DoubleRegister reg, MachineType type) { |
45 LinkageLocation regloc(Register reg) { | 49 return LinkageLocation::ForRegister(reg.code(), type); |
46 return LinkageLocation::ForRegister(reg.code()); | 50 } |
| 51 |
| 52 LinkageLocation stackloc(int i, MachineType type) { |
| 53 return LinkageLocation::ForCallerFrameSlot(i, type); |
47 } | 54 } |
48 | 55 |
49 | 56 |
50 LinkageLocation regloc(DoubleRegister reg) { | |
51 return LinkageLocation::ForRegister(reg.code()); | |
52 } | |
53 | |
54 | |
55 LinkageLocation stackloc(int i) { | |
56 return LinkageLocation::ForCallerFrameSlot(i); | |
57 } | |
58 | |
59 | |
60 #if V8_TARGET_ARCH_IA32 | 57 #if V8_TARGET_ARCH_IA32 |
61 // =========================================================================== | 58 // =========================================================================== |
62 // == ia32 =================================================================== | 59 // == ia32 =================================================================== |
63 // =========================================================================== | 60 // =========================================================================== |
64 #define GP_PARAM_REGISTERS eax, edx, ecx, ebx, esi | 61 #define GP_PARAM_REGISTERS eax, edx, ecx, ebx, esi |
65 #define GP_RETURN_REGISTERS eax, edx | 62 #define GP_RETURN_REGISTERS eax, edx |
66 #define FP_PARAM_REGISTERS xmm1, xmm2, xmm3, xmm4, xmm5, xmm6 | 63 #define FP_PARAM_REGISTERS xmm1, xmm2, xmm3, xmm4, xmm5, xmm6 |
67 #define FP_RETURN_REGISTERS xmm1, xmm2 | 64 #define FP_RETURN_REGISTERS xmm1, xmm2 |
68 | 65 |
69 #elif V8_TARGET_ARCH_X64 | 66 #elif V8_TARGET_ARCH_X64 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 // Allocate a floating point register/stack location. | 177 // Allocate a floating point register/stack location. |
181 if (fp_offset < fp_count) { | 178 if (fp_offset < fp_count) { |
182 DoubleRegister reg = fp_regs[fp_offset++]; | 179 DoubleRegister reg = fp_regs[fp_offset++]; |
183 #if V8_TARGET_ARCH_ARM | 180 #if V8_TARGET_ARCH_ARM |
184 // Allocate floats using a double register, but modify the code to | 181 // Allocate floats using a double register, but modify the code to |
185 // reflect how ARM FP registers alias. | 182 // reflect how ARM FP registers alias. |
186 // TODO(bbudge) Modify wasm linkage to allow use of all float regs. | 183 // TODO(bbudge) Modify wasm linkage to allow use of all float regs. |
187 if (type == kAstF32) { | 184 if (type == kAstF32) { |
188 int float_reg_code = reg.code() * 2; | 185 int float_reg_code = reg.code() * 2; |
189 DCHECK(float_reg_code < RegisterConfiguration::kMaxFPRegisters); | 186 DCHECK(float_reg_code < RegisterConfiguration::kMaxFPRegisters); |
190 return regloc(DoubleRegister::from_code(float_reg_code)); | 187 return regloc(DoubleRegister::from_code(float_reg_code), |
| 188 MachineTypeFor(type)); |
191 } | 189 } |
192 #endif | 190 #endif |
193 return regloc(reg); | 191 return regloc(reg, MachineTypeFor(type)); |
194 } else { | 192 } else { |
195 int offset = -1 - stack_offset; | 193 int offset = -1 - stack_offset; |
196 stack_offset += Words(type); | 194 stack_offset += Words(type); |
197 return stackloc(offset); | 195 return stackloc(offset, MachineTypeFor(type)); |
198 } | 196 } |
199 } else { | 197 } else { |
200 // Allocate a general purpose register/stack location. | 198 // Allocate a general purpose register/stack location. |
201 if (gp_offset < gp_count) { | 199 if (gp_offset < gp_count) { |
202 return regloc(gp_regs[gp_offset++]); | 200 return regloc(gp_regs[gp_offset++], MachineTypeFor(type)); |
203 } else { | 201 } else { |
204 int offset = -1 - stack_offset; | 202 int offset = -1 - stack_offset; |
205 stack_offset += Words(type); | 203 stack_offset += Words(type); |
206 return stackloc(offset); | 204 return stackloc(offset, MachineTypeFor(type)); |
207 } | 205 } |
208 } | 206 } |
209 } | 207 } |
210 bool IsFloatingPoint(LocalType type) { | 208 bool IsFloatingPoint(LocalType type) { |
211 return type == kAstF32 || type == kAstF64; | 209 return type == kAstF32 || type == kAstF64; |
212 } | 210 } |
213 int Words(LocalType type) { | 211 int Words(LocalType type) { |
214 if (kPointerSize < 8 && (type == kAstI64 || type == kAstF64)) { | 212 if (kPointerSize < 8 && (type == kAstI64 || type == kAstF64)) { |
215 return 2; | 213 return 2; |
216 } | 214 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 | 263 |
266 Allocator params(kGPParamRegisters, kGPParamRegistersCount, kFPParamRegisters, | 264 Allocator params(kGPParamRegisters, kGPParamRegistersCount, kFPParamRegisters, |
267 kFPParamRegistersCount); | 265 kFPParamRegistersCount); |
268 | 266 |
269 return params; | 267 return params; |
270 } | 268 } |
271 | 269 |
272 // General code uses the above configuration data. | 270 // General code uses the above configuration data. |
273 CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, | 271 CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, |
274 FunctionSig* fsig) { | 272 FunctionSig* fsig) { |
275 MachineSignature::Builder msig(zone, fsig->return_count(), | |
276 fsig->parameter_count()); | |
277 LocationSignature::Builder locations(zone, fsig->return_count(), | 273 LocationSignature::Builder locations(zone, fsig->return_count(), |
278 fsig->parameter_count()); | 274 fsig->parameter_count()); |
279 | 275 |
280 Allocator rets = GetReturnRegisters(); | 276 Allocator rets = GetReturnRegisters(); |
281 | 277 |
282 // Add return location(s). | 278 // Add return location(s). |
283 const int return_count = static_cast<int>(locations.return_count_); | 279 const int return_count = static_cast<int>(locations.return_count_); |
284 for (int i = 0; i < return_count; i++) { | 280 for (int i = 0; i < return_count; i++) { |
285 LocalType ret = fsig->GetReturn(i); | 281 LocalType ret = fsig->GetReturn(i); |
286 msig.AddReturn(MachineTypeFor(ret)); | |
287 locations.AddReturn(rets.Next(ret)); | 282 locations.AddReturn(rets.Next(ret)); |
288 } | 283 } |
289 | 284 |
290 Allocator params = GetParameterRegisters(); | 285 Allocator params = GetParameterRegisters(); |
291 | 286 |
292 // Add register and/or stack parameter(s). | 287 // Add register and/or stack parameter(s). |
293 const int parameter_count = static_cast<int>(fsig->parameter_count()); | 288 const int parameter_count = static_cast<int>(fsig->parameter_count()); |
294 for (int i = 0; i < parameter_count; i++) { | 289 for (int i = 0; i < parameter_count; i++) { |
295 LocalType param = fsig->GetParam(i); | 290 LocalType param = fsig->GetParam(i); |
296 msig.AddParam(MachineTypeFor(param)); | |
297 locations.AddParam(params.Next(param)); | 291 locations.AddParam(params.Next(param)); |
298 } | 292 } |
299 | 293 |
300 const RegList kCalleeSaveRegisters = 0; | 294 const RegList kCalleeSaveRegisters = 0; |
301 const RegList kCalleeSaveFPRegisters = 0; | 295 const RegList kCalleeSaveFPRegisters = 0; |
302 | 296 |
303 // The target for WASM calls is always a code object. | 297 // The target for WASM calls is always a code object. |
304 MachineType target_type = MachineType::AnyTagged(); | 298 MachineType target_type = MachineType::AnyTagged(); |
305 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 299 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type); |
306 | 300 |
307 return new (zone) CallDescriptor( // -- | 301 return new (zone) CallDescriptor( // -- |
308 CallDescriptor::kCallCodeObject, // kind | 302 CallDescriptor::kCallCodeObject, // kind |
309 target_type, // target MachineType | 303 target_type, // target MachineType |
310 target_loc, // target location | 304 target_loc, // target location |
311 msig.Build(), // machine_sig | |
312 locations.Build(), // location_sig | 305 locations.Build(), // location_sig |
313 params.stack_offset, // stack_parameter_count | 306 params.stack_offset, // stack_parameter_count |
314 compiler::Operator::kNoProperties, // properties | 307 compiler::Operator::kNoProperties, // properties |
315 kCalleeSaveRegisters, // callee-saved registers | 308 kCalleeSaveRegisters, // callee-saved registers |
316 kCalleeSaveFPRegisters, // callee-saved fp regs | 309 kCalleeSaveFPRegisters, // callee-saved fp regs |
317 CallDescriptor::kUseNativeStack, // flags | 310 CallDescriptor::kUseNativeStack, // flags |
318 "wasm-call"); | 311 "wasm-call"); |
319 } | 312 } |
320 | 313 |
321 CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor( | 314 CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor( |
322 Zone* zone, CallDescriptor* descriptor) { | 315 Zone* zone, CallDescriptor* descriptor) { |
323 const MachineSignature* signature = descriptor->GetMachineSignature(); | 316 size_t parameter_count = descriptor->ParameterCount(); |
324 size_t parameter_count = signature->parameter_count(); | 317 size_t return_count = descriptor->ReturnCount(); |
325 size_t return_count = signature->return_count(); | 318 for (size_t i = 0; i < descriptor->ParameterCount(); i++) { |
326 for (size_t i = 0; i < signature->parameter_count(); i++) { | 319 if (descriptor->GetParameterType(i) == MachineType::Int64()) { |
327 if (signature->GetParam(i) == MachineType::Int64()) { | |
328 // For each int64 input we get two int32 inputs. | 320 // For each int64 input we get two int32 inputs. |
329 parameter_count++; | 321 parameter_count++; |
330 } | 322 } |
331 } | 323 } |
332 for (size_t i = 0; i < signature->return_count(); i++) { | 324 for (size_t i = 0; i < descriptor->ReturnCount(); i++) { |
333 if (signature->GetReturn(i) == MachineType::Int64()) { | 325 if (descriptor->GetReturnType(i) == MachineType::Int64()) { |
334 // For each int64 return we get two int32 returns. | 326 // For each int64 return we get two int32 returns. |
335 return_count++; | 327 return_count++; |
336 } | 328 } |
337 } | 329 } |
338 if (parameter_count == signature->parameter_count() && | 330 if (parameter_count == descriptor->ParameterCount() && |
339 return_count == signature->return_count()) { | 331 return_count == descriptor->ReturnCount()) { |
340 // If there is no int64 parameter or return value, we can just return the | 332 // If there is no int64 parameter or return value, we can just return the |
341 // original descriptor. | 333 // original descriptor. |
342 return descriptor; | 334 return descriptor; |
343 } | 335 } |
344 | 336 |
345 MachineSignature::Builder msig(zone, return_count, parameter_count); | |
346 LocationSignature::Builder locations(zone, return_count, parameter_count); | 337 LocationSignature::Builder locations(zone, return_count, parameter_count); |
347 | 338 |
348 Allocator rets = GetReturnRegisters(); | 339 Allocator rets = GetReturnRegisters(); |
349 | 340 |
350 for (size_t i = 0; i < signature->return_count(); i++) { | 341 for (size_t i = 0; i < descriptor->ReturnCount(); i++) { |
351 if (signature->GetReturn(i) == MachineType::Int64()) { | 342 if (descriptor->GetReturnType(i) == MachineType::Int64()) { |
352 // For each int64 return we get two int32 returns. | 343 // For each int64 return we get two int32 returns. |
353 msig.AddReturn(MachineType::Int32()); | |
354 msig.AddReturn(MachineType::Int32()); | |
355 locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); | 344 locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); |
356 locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); | 345 locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); |
357 } else { | 346 } else { |
358 msig.AddReturn(signature->GetReturn(i)); | 347 locations.AddReturn( |
359 locations.AddReturn(rets.Next(signature->GetReturn(i).representation())); | 348 rets.Next(descriptor->GetReturnType(i).representation())); |
360 } | 349 } |
361 } | 350 } |
362 | 351 |
363 Allocator params = GetParameterRegisters(); | 352 Allocator params = GetParameterRegisters(); |
364 | 353 |
365 for (size_t i = 0; i < signature->parameter_count(); i++) { | 354 for (size_t i = 0; i < descriptor->ParameterCount(); i++) { |
366 if (signature->GetParam(i) == MachineType::Int64()) { | 355 if (descriptor->GetParameterType(i) == MachineType::Int64()) { |
367 // For each int64 input we get two int32 inputs. | 356 // For each int64 input we get two int32 inputs. |
368 msig.AddParam(MachineType::Int32()); | |
369 msig.AddParam(MachineType::Int32()); | |
370 locations.AddParam(params.Next(MachineRepresentation::kWord32)); | 357 locations.AddParam(params.Next(MachineRepresentation::kWord32)); |
371 locations.AddParam(params.Next(MachineRepresentation::kWord32)); | 358 locations.AddParam(params.Next(MachineRepresentation::kWord32)); |
372 } else { | 359 } else { |
373 msig.AddParam(signature->GetParam(i)); | 360 locations.AddParam( |
374 locations.AddParam(params.Next(signature->GetParam(i).representation())); | 361 params.Next(descriptor->GetParameterType(i).representation())); |
375 } | 362 } |
376 } | 363 } |
377 | 364 |
378 return new (zone) CallDescriptor( // -- | 365 return new (zone) CallDescriptor( // -- |
379 descriptor->kind(), // kind | 366 descriptor->kind(), // kind |
380 descriptor->GetInputType(0), // target MachineType | 367 descriptor->GetInputType(0), // target MachineType |
381 descriptor->GetInputLocation(0), // target location | 368 descriptor->GetInputLocation(0), // target location |
382 msig.Build(), // machine_sig | |
383 locations.Build(), // location_sig | 369 locations.Build(), // location_sig |
384 params.stack_offset, // stack_parameter_count | 370 params.stack_offset, // stack_parameter_count |
385 descriptor->properties(), // properties | 371 descriptor->properties(), // properties |
386 descriptor->CalleeSavedRegisters(), // callee-saved registers | 372 descriptor->CalleeSavedRegisters(), // callee-saved registers |
387 descriptor->CalleeSavedFPRegisters(), // callee-saved fp regs | 373 descriptor->CalleeSavedFPRegisters(), // callee-saved fp regs |
388 descriptor->flags(), // flags | 374 descriptor->flags(), // flags |
389 descriptor->debug_name()); | 375 descriptor->debug_name()); |
390 | 376 |
391 return descriptor; | 377 return descriptor; |
392 } | 378 } |
393 | 379 |
394 } // namespace wasm | 380 } // namespace wasm |
395 } // namespace internal | 381 } // namespace internal |
396 } // namespace v8 | 382 } // namespace v8 |
OLD | NEW |