001/*
002 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.lir.amd64;
024
025import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
026import static jdk.internal.jvmci.code.ValueUtil.*;
027
028import java.util.*;
029
030import jdk.internal.jvmci.code.*;
031
032import com.oracle.graal.asm.amd64.*;
033import com.oracle.graal.lir.*;
034import com.oracle.graal.lir.asm.*;
035
036/**
037 * Restores registers from stack slots.
038 */
039@Opcode("RESTORE_REGISTER")
040public class AMD64RestoreRegistersOp extends AMD64LIRInstruction {
041    public static final LIRInstructionClass<AMD64RestoreRegistersOp> TYPE = LIRInstructionClass.create(AMD64RestoreRegistersOp.class);
042
043    /**
044     * The slots from which the registers are restored.
045     */
046    @Use(STACK) protected final StackSlotValue[] slots;
047
048    /**
049     * The operation that saved the registers restored by this operation.
050     */
051    private final AMD64SaveRegistersOp save;
052
053    public AMD64RestoreRegistersOp(StackSlotValue[] values, AMD64SaveRegistersOp save) {
054        this(TYPE, values, save);
055    }
056
057    protected AMD64RestoreRegistersOp(LIRInstructionClass<? extends AMD64RestoreRegistersOp> c, StackSlotValue[] values, AMD64SaveRegistersOp save) {
058        super(c);
059        assert Arrays.asList(values).stream().allMatch(ValueUtil::isVirtualStackSlot);
060        this.slots = values;
061        this.save = save;
062    }
063
064    protected Register[] getSavedRegisters() {
065        return save.savedRegisters;
066    }
067
068    protected void restoreRegister(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, StackSlot input) {
069        RegisterValue result = register.asValue(input.getLIRKind());
070        AMD64Move.move(crb, masm, result, input);
071    }
072
073    @Override
074    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
075        Register[] savedRegisters = getSavedRegisters();
076        for (int i = 0; i < savedRegisters.length; i++) {
077            if (savedRegisters[i] != null) {
078                assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i];
079                restoreRegister(crb, masm, savedRegisters[i], asStackSlot(slots[i]));
080            }
081        }
082    }
083}