001/*
002 * Copyright (c) 2014, 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.hotspot.sparc;
024
025import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
026import static jdk.internal.jvmci.code.ValueUtil.*;
027import static jdk.internal.jvmci.meta.LIRKind.*;
028import static jdk.internal.jvmci.sparc.SPARC.*;
029import jdk.internal.jvmci.code.*;
030import jdk.internal.jvmci.meta.*;
031
032import com.oracle.graal.asm.sparc.*;
033import com.oracle.graal.hotspot.*;
034import com.oracle.graal.lir.*;
035import com.oracle.graal.lir.asm.*;
036import com.oracle.graal.lir.sparc.*;
037
038/**
039 * Emits code that enters a stack frame which is tailored to call the C++ method
040 * {@link HotSpotBackend#UNPACK_FRAMES Deoptimization::unpack_frames}.
041 */
042@Opcode("ENTER_UNPACK_FRAMES_STACK_FRAME")
043final class SPARCHotSpotEnterUnpackFramesStackFrameOp extends SPARCLIRInstruction {
044    public static final LIRInstructionClass<SPARCHotSpotEnterUnpackFramesStackFrameOp> TYPE = LIRInstructionClass.create(SPARCHotSpotEnterUnpackFramesStackFrameOp.class);
045
046    private final Register thread;
047    private final int threadLastJavaSpOffset;
048    private final int threadLastJavaPcOffset;
049    @Alive(REG) AllocatableValue framePc;
050    @Alive(REG) AllocatableValue senderSp;
051    @Temp(REG) AllocatableValue scratch;
052    @Temp(REG) AllocatableValue callerReturnPc;
053
054    SPARCHotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue scratch,
055                    PlatformKind wordKind) {
056        super(TYPE);
057        this.thread = thread;
058        this.threadLastJavaSpOffset = threadLastJavaSpOffset;
059        this.threadLastJavaPcOffset = threadLastJavaPcOffset;
060        this.framePc = framePc;
061        this.senderSp = senderSp;
062        this.scratch = scratch;
063        callerReturnPc = o7.asValue(value(wordKind));
064    }
065
066    @Override
067    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
068        final int totalFrameSize = crb.frameMap.totalFrameSize();
069        Register framePcRegister = asRegister(framePc);
070        Register senderSpRegister = asRegister(senderSp);
071        Register scratchRegister = asRegister(scratch);
072
073        // Save final sender SP to O5_savedSP.
074        masm.mov(senderSpRegister, o5);
075
076        // Load final frame PC.
077        masm.mov(framePcRegister, asRegister(callerReturnPc));
078
079        // Allocate a full sized frame.
080        masm.save(sp, -totalFrameSize, sp);
081
082        masm.mov(i0, o0);
083        masm.mov(i1, o1);
084        masm.mov(i2, o2);
085        masm.mov(i3, o3);
086        masm.mov(i4, o4);
087
088        // Set up last Java values.
089        masm.add(sp, STACK_BIAS, scratchRegister);
090        masm.stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset));
091
092        // Clear last Java PC.
093        masm.stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset));
094
095        /*
096         * Safe thread register manually since we are not using LEAF_SP for {@link
097         * DeoptimizationStub#UNPACK_FRAMES}.
098         */
099        masm.mov(thread, l7);
100    }
101
102    @Override
103    public boolean leavesRegisterWindow() {
104        return true;
105    }
106}