< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCSaveRegistersOp.java
Print this page
rev 56282 : [mq]: graal
*** 1,7 ****
/*
! * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 24,95 ****
package org.graalvm.compiler.lir.sparc;
import static jdk.vm.ci.code.ValueUtil.asStackSlot;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
- import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
import static org.graalvm.compiler.lir.sparc.SPARCDelayedControlTransfer.DUMMY;
- import java.util.Arrays;
-
import jdk.internal.vm.compiler.collections.EconomicSet;
import org.graalvm.compiler.asm.sparc.SPARCAddress;
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
import org.graalvm.compiler.lir.LIRInstructionClass;
- import org.graalvm.compiler.lir.LIRValueUtil;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
- import org.graalvm.compiler.lir.framemap.FrameMap;
import jdk.vm.ci.code.Register;
- import jdk.vm.ci.code.RegisterSaveLayout;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.sparc.SPARC;
/**
* Saves registers to stack slots.
*/
@Opcode("SAVE_REGISTER")
! public class SPARCSaveRegistersOp extends SPARCLIRInstruction implements SaveRegistersOp {
public static final LIRInstructionClass<SPARCSaveRegistersOp> TYPE = LIRInstructionClass.create(SPARCSaveRegistersOp.class);
public static final Register RETURN_REGISTER_STORAGE = SPARC.d62;
public static final SizeEstimate SIZE = SizeEstimate.create(32);
! /**
! * The registers (potentially) saved by this operation.
! */
! protected final Register[] savedRegisters;
!
! /**
! * The slots to which the registers are saved.
! */
! @Def(STACK) protected final AllocatableValue[] slots;
!
! /**
! * Specifies if {@link #remove(EconomicSet)} should have an effect.
! */
! protected final boolean supportsRemove;
/**
*
* @param savedRegisters the registers saved by this operation which may be subject to
* {@linkplain #remove(EconomicSet) pruning}
* @param savedRegisterLocations the slots to which the registers are saved
- * @param supportsRemove determines if registers can be {@linkplain #remove(EconomicSet) pruned}
*/
! public SPARCSaveRegistersOp(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations, boolean supportsRemove) {
! super(TYPE, SIZE);
! assert Arrays.asList(savedRegisterLocations).stream().allMatch(LIRValueUtil::isVirtualStackSlot);
! this.savedRegisters = savedRegisters;
! this.slots = savedRegisterLocations;
! this.supportsRemove = supportsRemove;
}
@Override
! public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
// Can be used with VIS3
// new Movxtod(SPARC.i0, RETURN_REGISTER_STORAGE).emit(masm);
// We abuse the first stackslot for transferring i0 to return_register_storage
// assert slots.length >= 1;
SPARCAddress slot0Address = (SPARCAddress) crb.asAddress(slots[0]);
--- 24,73 ----
package org.graalvm.compiler.lir.sparc;
import static jdk.vm.ci.code.ValueUtil.asStackSlot;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import static org.graalvm.compiler.lir.sparc.SPARCDelayedControlTransfer.DUMMY;
import jdk.internal.vm.compiler.collections.EconomicSet;
import org.graalvm.compiler.asm.sparc.SPARCAddress;
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.sparc.SPARC;
/**
* Saves registers to stack slots.
*/
@Opcode("SAVE_REGISTER")
! public class SPARCSaveRegistersOp extends SaveRegistersOp implements SPARCLIRInstructionMixin {
public static final LIRInstructionClass<SPARCSaveRegistersOp> TYPE = LIRInstructionClass.create(SPARCSaveRegistersOp.class);
public static final Register RETURN_REGISTER_STORAGE = SPARC.d62;
public static final SizeEstimate SIZE = SizeEstimate.create(32);
! private final SPARCLIRInstructionMixinStore store;
/**
*
* @param savedRegisters the registers saved by this operation which may be subject to
* {@linkplain #remove(EconomicSet) pruning}
* @param savedRegisterLocations the slots to which the registers are saved
*/
! public SPARCSaveRegistersOp(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations) {
! super(TYPE, savedRegisters, savedRegisterLocations);
! this.store = new SPARCLIRInstructionMixinStore(SIZE);
}
@Override
! public void emitCode(CompilationResultBuilder crb) {
! SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
// Can be used with VIS3
// new Movxtod(SPARC.i0, RETURN_REGISTER_STORAGE).emit(masm);
// We abuse the first stackslot for transferring i0 to return_register_storage
// assert slots.length >= 1;
SPARCAddress slot0Address = (SPARCAddress) crb.asAddress(slots[0]);
*** 107,180 ****
SPARCMove.emitStore(input, slotAddress, slot.getPlatformKind(), DUMMY, null, crb, masm);
}
}
}
- public AllocatableValue[] getSlots() {
- return slots;
- }
-
@Override
! public boolean supportsRemove() {
! return supportsRemove;
! }
!
! @Override
! public int remove(EconomicSet<Register> doNotSave) {
! if (!supportsRemove) {
! throw new UnsupportedOperationException();
! }
! return prune(doNotSave, savedRegisters);
! }
!
! static int prune(EconomicSet<Register> toRemove, Register[] registers) {
! int pruned = 0;
! for (int i = 0; i < registers.length; i++) {
! if (registers[i] != null) {
! if (toRemove.contains(registers[i])) {
! registers[i] = null;
! pruned++;
! }
! }
! }
! return pruned;
! }
!
! @Override
! public RegisterSaveLayout getMap(FrameMap frameMap) {
! int total = 0;
! for (int i = 0; i < savedRegisters.length; i++) {
! if (savedRegisters[i] != null) {
! total++;
! }
! }
! Register[] keys = new Register[total];
! int[] values = new int[total];
! if (total != 0) {
! int mapIndex = 0;
! for (int i = 0; i < savedRegisters.length; i++) {
! if (savedRegisters[i] != null) {
! keys[mapIndex] = savedRegisters[i];
! assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i];
! StackSlot slot = asStackSlot(slots[i]);
! values[mapIndex] = indexForStackSlot(frameMap, slot);
! mapIndex++;
! }
! }
! assert mapIndex == total;
! }
! return new RegisterSaveLayout(keys, values);
! }
!
! /**
! * Computes the index of a stack slot relative to slot 0. This is also the bit index of stack
! * slots in the reference map.
! *
! * @param slot a stack slot
! * @return the index of the stack slot
! */
! private static int indexForStackSlot(FrameMap frameMap, StackSlot slot) {
! assert frameMap.offsetForStackSlot(slot) % frameMap.getTarget().wordSize == 0;
! int value = frameMap.offsetForStackSlot(slot) / frameMap.getTarget().wordSize;
! return value;
}
}
--- 85,94 ----
SPARCMove.emitStore(input, slotAddress, slot.getPlatformKind(), DUMMY, null, crb, masm);
}
}
}
@Override
! public SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore() {
! return store;
}
}
< prev index next >