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 | 7 |
8 #include "src/wasm/wasm-module.h" | 8 #include "src/wasm/wasm-module.h" |
9 | 9 |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 // two words. | 184 // two words. |
185 if (kPointerSize < 8 && | 185 if (kPointerSize < 8 && |
186 (type == kAstI64 || type == kAstF64 || type == kAstF32)) { | 186 (type == kAstI64 || type == kAstF64 || type == kAstF32)) { |
187 return 2; | 187 return 2; |
188 } | 188 } |
189 return 1; | 189 return 1; |
190 } | 190 } |
191 }; | 191 }; |
192 } // namespace | 192 } // namespace |
193 | 193 |
194 | 194 static Allocator GetReturnRegisters() { |
195 // General code uses the above configuration data. | |
196 CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, | |
197 FunctionSig* fsig) { | |
198 MachineSignature::Builder msig(zone, fsig->return_count(), | |
199 fsig->parameter_count()); | |
200 LocationSignature::Builder locations(zone, fsig->return_count(), | |
201 fsig->parameter_count()); | |
202 | |
203 #ifdef GP_RETURN_REGISTERS | 195 #ifdef GP_RETURN_REGISTERS |
204 static const Register kGPReturnRegisters[] = {GP_RETURN_REGISTERS}; | 196 static const Register kGPReturnRegisters[] = {GP_RETURN_REGISTERS}; |
205 static const int kGPReturnRegistersCount = | 197 static const int kGPReturnRegistersCount = |
206 static_cast<int>(arraysize(kGPReturnRegisters)); | 198 static_cast<int>(arraysize(kGPReturnRegisters)); |
207 #else | 199 #else |
208 static const Register* kGPReturnRegisters = nullptr; | 200 static const Register* kGPReturnRegisters = nullptr; |
209 static const int kGPReturnRegistersCount = 0; | 201 static const int kGPReturnRegistersCount = 0; |
210 #endif | 202 #endif |
211 | 203 |
212 #ifdef FP_RETURN_REGISTERS | 204 #ifdef FP_RETURN_REGISTERS |
213 static const DoubleRegister kFPReturnRegisters[] = {FP_RETURN_REGISTERS}; | 205 static const DoubleRegister kFPReturnRegisters[] = {FP_RETURN_REGISTERS}; |
214 static const int kFPReturnRegistersCount = | 206 static const int kFPReturnRegistersCount = |
215 static_cast<int>(arraysize(kFPReturnRegisters)); | 207 static_cast<int>(arraysize(kFPReturnRegisters)); |
216 #else | 208 #else |
217 static const DoubleRegister* kFPReturnRegisters = nullptr; | 209 static const DoubleRegister* kFPReturnRegisters = nullptr; |
218 static const int kFPReturnRegistersCount = 0; | 210 static const int kFPReturnRegistersCount = 0; |
219 #endif | 211 #endif |
220 | 212 |
221 Allocator rets(kGPReturnRegisters, kGPReturnRegistersCount, | 213 Allocator rets(kGPReturnRegisters, kGPReturnRegistersCount, |
222 kFPReturnRegisters, kFPReturnRegistersCount); | 214 kFPReturnRegisters, kFPReturnRegistersCount); |
223 | 215 |
224 // Add return location(s). | 216 return rets; |
225 const int return_count = static_cast<int>(locations.return_count_); | 217 } |
226 for (int i = 0; i < return_count; i++) { | |
227 LocalType ret = fsig->GetReturn(i); | |
228 msig.AddReturn(MachineTypeFor(ret)); | |
229 locations.AddReturn(rets.Next(ret)); | |
230 } | |
231 | 218 |
| 219 static Allocator GetParameterRegisters() { |
232 #ifdef GP_PARAM_REGISTERS | 220 #ifdef GP_PARAM_REGISTERS |
233 static const Register kGPParamRegisters[] = {GP_PARAM_REGISTERS}; | 221 static const Register kGPParamRegisters[] = {GP_PARAM_REGISTERS}; |
234 static const int kGPParamRegistersCount = | 222 static const int kGPParamRegistersCount = |
235 static_cast<int>(arraysize(kGPParamRegisters)); | 223 static_cast<int>(arraysize(kGPParamRegisters)); |
236 #else | 224 #else |
237 static const Register* kGPParamRegisters = nullptr; | 225 static const Register* kGPParamRegisters = nullptr; |
238 static const int kGPParamRegistersCount = 0; | 226 static const int kGPParamRegistersCount = 0; |
239 #endif | 227 #endif |
240 | 228 |
241 #ifdef FP_PARAM_REGISTERS | 229 #ifdef FP_PARAM_REGISTERS |
242 static const DoubleRegister kFPParamRegisters[] = {FP_PARAM_REGISTERS}; | 230 static const DoubleRegister kFPParamRegisters[] = {FP_PARAM_REGISTERS}; |
243 static const int kFPParamRegistersCount = | 231 static const int kFPParamRegistersCount = |
244 static_cast<int>(arraysize(kFPParamRegisters)); | 232 static_cast<int>(arraysize(kFPParamRegisters)); |
245 #else | 233 #else |
246 static const DoubleRegister* kFPParamRegisters = nullptr; | 234 static const DoubleRegister* kFPParamRegisters = nullptr; |
247 static const int kFPParamRegistersCount = 0; | 235 static const int kFPParamRegistersCount = 0; |
248 #endif | 236 #endif |
249 | 237 |
250 Allocator params(kGPParamRegisters, kGPParamRegistersCount, kFPParamRegisters, | 238 Allocator params(kGPParamRegisters, kGPParamRegistersCount, kFPParamRegisters, |
251 kFPParamRegistersCount); | 239 kFPParamRegistersCount); |
252 | 240 |
| 241 return params; |
| 242 } |
| 243 |
| 244 // General code uses the above configuration data. |
| 245 CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, |
| 246 FunctionSig* fsig) { |
| 247 MachineSignature::Builder msig(zone, fsig->return_count(), |
| 248 fsig->parameter_count()); |
| 249 LocationSignature::Builder locations(zone, fsig->return_count(), |
| 250 fsig->parameter_count()); |
| 251 |
| 252 Allocator rets = GetReturnRegisters(); |
| 253 |
| 254 // Add return location(s). |
| 255 const int return_count = static_cast<int>(locations.return_count_); |
| 256 for (int i = 0; i < return_count; i++) { |
| 257 LocalType ret = fsig->GetReturn(i); |
| 258 msig.AddReturn(MachineTypeFor(ret)); |
| 259 locations.AddReturn(rets.Next(ret)); |
| 260 } |
| 261 |
| 262 Allocator params = GetParameterRegisters(); |
| 263 |
253 // Add register and/or stack parameter(s). | 264 // Add register and/or stack parameter(s). |
254 const int parameter_count = static_cast<int>(fsig->parameter_count()); | 265 const int parameter_count = static_cast<int>(fsig->parameter_count()); |
255 for (int i = 0; i < parameter_count; i++) { | 266 for (int i = 0; i < parameter_count; i++) { |
256 LocalType param = fsig->GetParam(i); | 267 LocalType param = fsig->GetParam(i); |
257 msig.AddParam(MachineTypeFor(param)); | 268 msig.AddParam(MachineTypeFor(param)); |
258 locations.AddParam(params.Next(param)); | 269 locations.AddParam(params.Next(param)); |
259 } | 270 } |
260 | 271 |
261 const RegList kCalleeSaveRegisters = 0; | 272 const RegList kCalleeSaveRegisters = 0; |
262 const RegList kCalleeSaveFPRegisters = 0; | 273 const RegList kCalleeSaveFPRegisters = 0; |
263 | 274 |
264 // The target for WASM calls is always a code object. | 275 // The target for WASM calls is always a code object. |
265 MachineType target_type = MachineType::AnyTagged(); | 276 MachineType target_type = MachineType::AnyTagged(); |
266 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 277 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); |
267 | 278 |
268 return new (zone) CallDescriptor( // -- | 279 return new (zone) CallDescriptor( // -- |
269 CallDescriptor::kCallCodeObject, // kind | 280 CallDescriptor::kCallCodeObject, // kind |
270 target_type, // target MachineType | 281 target_type, // target MachineType |
271 target_loc, // target location | 282 target_loc, // target location |
272 msig.Build(), // machine_sig | 283 msig.Build(), // machine_sig |
273 locations.Build(), // location_sig | 284 locations.Build(), // location_sig |
274 params.stack_offset, // stack_parameter_count | 285 params.stack_offset, // stack_parameter_count |
275 compiler::Operator::kNoProperties, // properties | 286 compiler::Operator::kNoProperties, // properties |
276 kCalleeSaveRegisters, // callee-saved registers | 287 kCalleeSaveRegisters, // callee-saved registers |
277 kCalleeSaveFPRegisters, // callee-saved fp regs | 288 kCalleeSaveFPRegisters, // callee-saved fp regs |
278 CallDescriptor::kUseNativeStack, // flags | 289 CallDescriptor::kUseNativeStack, // flags |
279 "c-call"); | 290 "wasm-call"); |
280 } | 291 } |
| 292 |
| 293 CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor( |
| 294 Zone* zone, CallDescriptor* descriptor) { |
| 295 const MachineSignature* signature = descriptor->GetMachineSignature(); |
| 296 size_t parameter_count = signature->parameter_count(); |
| 297 size_t return_count = signature->return_count(); |
| 298 for (size_t i = 0; i < signature->parameter_count(); i++) { |
| 299 if (signature->GetParam(i) == MachineType::Int64()) { |
| 300 // For each int64 input we get two int32 inputs. |
| 301 parameter_count++; |
| 302 } |
| 303 } |
| 304 for (size_t i = 0; i < signature->return_count(); i++) { |
| 305 if (signature->GetReturn(i) == MachineType::Int64()) { |
| 306 // For each int64 return we get two int32 returns. |
| 307 return_count++; |
| 308 } |
| 309 } |
| 310 if (parameter_count == signature->parameter_count() && |
| 311 return_count == signature->return_count()) { |
| 312 // If there is no int64 parameter or return value, we can just return the |
| 313 // original descriptor. |
| 314 return descriptor; |
| 315 } |
| 316 |
| 317 MachineSignature::Builder msig(zone, return_count, parameter_count); |
| 318 LocationSignature::Builder locations(zone, return_count, parameter_count); |
| 319 |
| 320 Allocator rets = GetReturnRegisters(); |
| 321 |
| 322 for (size_t i = 0; i < signature->return_count(); i++) { |
| 323 if (signature->GetReturn(i) == MachineType::Int64()) { |
| 324 // For each int64 return we get two int32 returns. |
| 325 msig.AddReturn(MachineType::Int32()); |
| 326 msig.AddReturn(MachineType::Int32()); |
| 327 locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); |
| 328 locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); |
| 329 } else { |
| 330 msig.AddReturn(signature->GetReturn(i)); |
| 331 locations.AddReturn(rets.Next(signature->GetReturn(i).representation())); |
| 332 } |
| 333 } |
| 334 |
| 335 Allocator params = GetParameterRegisters(); |
| 336 |
| 337 for (size_t i = 0; i < signature->parameter_count(); i++) { |
| 338 if (signature->GetParam(i) == MachineType::Int64()) { |
| 339 // For each int64 input we get two int32 inputs. |
| 340 msig.AddParam(MachineType::Int32()); |
| 341 msig.AddParam(MachineType::Int32()); |
| 342 locations.AddParam(params.Next(MachineRepresentation::kWord32)); |
| 343 locations.AddParam(params.Next(MachineRepresentation::kWord32)); |
| 344 } else { |
| 345 msig.AddParam(signature->GetParam(i)); |
| 346 locations.AddParam(params.Next(signature->GetParam(i).representation())); |
| 347 } |
| 348 } |
| 349 |
| 350 return new (zone) CallDescriptor( // -- |
| 351 descriptor->kind(), // kind |
| 352 descriptor->GetInputType(0), // target MachineType |
| 353 descriptor->GetInputLocation(0), // target location |
| 354 msig.Build(), // machine_sig |
| 355 locations.Build(), // location_sig |
| 356 params.stack_offset, // stack_parameter_count |
| 357 descriptor->properties(), // properties |
| 358 descriptor->CalleeSavedRegisters(), // callee-saved registers |
| 359 descriptor->CalleeSavedFPRegisters(), // callee-saved fp regs |
| 360 descriptor->flags(), // flags |
| 361 descriptor->debug_name()); |
| 362 |
| 363 return descriptor; |
| 364 } |
| 365 |
281 } // namespace wasm | 366 } // namespace wasm |
282 } // namespace internal | 367 } // namespace internal |
283 } // namespace v8 | 368 } // namespace v8 |
OLD | NEW |