297 * We exclude the argument registers from the zeroing LIR instruction since it violates |
297 * We exclude the argument registers from the zeroing LIR instruction since it violates |
298 * the LIR semantics of @Temp that values must not be live. Note that the emitted |
298 * the LIR semantics of @Temp that values must not be live. Note that the emitted |
299 * machine instruction actually zeros _all_ XMM registers which is fine since we know |
299 * machine instruction actually zeros _all_ XMM registers which is fine since we know |
300 * that their upper half is not used. |
300 * that their upper half is not used. |
301 */ |
301 */ |
302 append(new AMD64VZeroUpper(arguments)); |
302 append(new AMD64VZeroUpper(arguments, getRegisterConfig())); |
303 } |
303 } |
304 super.emitForeignCallOp(linkage, result, arguments, temps, info); |
304 super.emitForeignCallOp(linkage, result, arguments, temps, info); |
305 } |
305 } |
306 |
306 |
307 /** |
307 /** |
308 * @param savedRegisters the registers saved by this operation which may be subject to pruning |
308 * @param savedRegisters the registers saved by this operation which may be subject to pruning |
309 * @param savedRegisterLocations the slots to which the registers are saved |
309 * @param savedRegisterLocations the slots to which the registers are saved |
310 * @param supportsRemove determines if registers can be pruned |
|
311 */ |
310 */ |
312 protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations, boolean supportsRemove) { |
311 protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations) { |
313 AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove); |
312 AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations); |
314 append(save); |
313 append(save); |
315 return save; |
314 return save; |
316 } |
315 } |
317 |
316 |
318 /** |
317 /** |
328 } |
327 } |
329 |
328 |
330 /** |
329 /** |
331 * Adds a node to the graph that saves all allocatable registers to the stack. |
330 * Adds a node to the graph that saves all allocatable registers to the stack. |
332 * |
331 * |
333 * @param supportsRemove determines if registers can be pruned |
|
334 * @return the register save node |
332 * @return the register save node |
335 */ |
333 */ |
336 private AMD64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters, boolean supportsRemove) { |
334 private AMD64SaveRegistersOp emitSaveAllRegisters() { |
|
335 Register[] savedRegisters = getSaveableRegisters(); |
337 AllocatableValue[] savedRegisterLocations = new AllocatableValue[savedRegisters.length]; |
336 AllocatableValue[] savedRegisterLocations = new AllocatableValue[savedRegisters.length]; |
338 for (int i = 0; i < savedRegisters.length; i++) { |
337 for (int i = 0; i < savedRegisters.length; i++) { |
339 savedRegisterLocations[i] = allocateSaveRegisterLocation(savedRegisters[i]); |
338 savedRegisterLocations[i] = allocateSaveRegisterLocation(savedRegisters[i]); |
340 } |
339 } |
341 return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove); |
340 return emitSaveRegisters(savedRegisters, savedRegisterLocations); |
|
341 } |
|
342 |
|
343 protected Register[] getSaveableRegisters() { |
|
344 return getResult().getRegisterAllocationConfig().getAllocatableRegisters().toArray(); |
342 } |
345 } |
343 |
346 |
344 protected void emitRestoreRegisters(AMD64SaveRegistersOp save) { |
347 protected void emitRestoreRegisters(AMD64SaveRegistersOp save) { |
345 append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save)); |
348 append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save)); |
346 } |
349 } |
367 HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage; |
370 HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage; |
368 boolean destroysRegisters = hotspotLinkage.destroysRegisters(); |
371 boolean destroysRegisters = hotspotLinkage.destroysRegisters(); |
369 |
372 |
370 AMD64SaveRegistersOp save = null; |
373 AMD64SaveRegistersOp save = null; |
371 Stub stub = getStub(); |
374 Stub stub = getStub(); |
372 if (destroysRegisters) { |
375 if (destroysRegisters && stub != null && stub.shouldSaveRegistersAroundCalls()) { |
373 if (stub != null && stub.preservesRegisters()) { |
376 save = emitSaveAllRegisters(); |
374 Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray(); |
|
375 save = emitSaveAllRegisters(savedRegisters, true); |
|
376 } |
|
377 } |
377 } |
378 |
378 |
379 Variable result; |
379 Variable result; |
380 LIRFrameState debugInfo = null; |
380 LIRFrameState debugInfo = null; |
381 if (hotspotLinkage.needsDebugInfo()) { |
381 if (hotspotLinkage.needsDebugInfo()) { |
390 append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), config.threadLastJavaPcOffset(), thread)); |
390 append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), config.threadLastJavaPcOffset(), thread)); |
391 } else { |
391 } else { |
392 result = super.emitForeignCall(hotspotLinkage, debugInfo, args); |
392 result = super.emitForeignCall(hotspotLinkage, debugInfo, args); |
393 } |
393 } |
394 |
394 |
395 if (destroysRegisters) { |
395 if (save != null) { |
396 if (stub != null) { |
396 HotSpotLIRGenerationResult generationResult = getResult(); |
397 if (stub.preservesRegisters()) { |
397 LIRFrameState key = currentRuntimeCallInfo; |
398 HotSpotLIRGenerationResult generationResult = getResult(); |
398 if (key == null) { |
399 LIRFrameState key = currentRuntimeCallInfo; |
399 key = LIRFrameState.NO_STATE; |
400 if (key == null) { |
|
401 key = LIRFrameState.NO_STATE; |
|
402 } |
|
403 assert !generationResult.getCalleeSaveInfo().containsKey(key); |
|
404 generationResult.getCalleeSaveInfo().put(key, save); |
|
405 emitRestoreRegisters(save); |
|
406 } |
|
407 } |
400 } |
|
401 assert !generationResult.getCalleeSaveInfo().containsKey(key); |
|
402 generationResult.getCalleeSaveInfo().put(key, save); |
|
403 emitRestoreRegisters(save); |
408 } |
404 } |
409 |
405 |
410 return result; |
406 return result; |
411 } |
407 } |
412 |
408 |