1 /*
2  * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.lir.sparc;
26 
27 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.BPCC;
28 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Annul.NOT_ANNUL;
29 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.BranchPredict.PREDICT_TAKEN;
30 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.CC.Xcc;
31 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag.Always;
32 
33 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
34 import org.graalvm.compiler.lir.LIRInstructionClass;
35 import org.graalvm.compiler.lir.LabelRef;
36 import org.graalvm.compiler.lir.StandardOp.JumpOp;
37 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
38 
39 public final class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer, SPARCLIRInstructionMixin {
40     public static final LIRInstructionClass<SPARCJumpOp> TYPE = LIRInstructionClass.create(SPARCJumpOp.class);
41     public static final SizeEstimate SIZE = SizeEstimate.create(2);
42 
43     private boolean emitDone = false;
44     private int delaySlotPosition = -1;
45     private final SPARCLIRInstructionMixinStore store;
46 
SPARCJumpOp(LabelRef destination)47     public SPARCJumpOp(LabelRef destination) {
48         super(TYPE, destination);
49         this.store = new SPARCLIRInstructionMixinStore(SIZE);
50     }
51 
52     @Override
emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm)53     public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
54         assert !emitDone;
55         if (!crb.isSuccessorEdge(destination())) {
56             BPCC.emit(masm, Xcc, Always, NOT_ANNUL, PREDICT_TAKEN, destination().label());
57             delaySlotPosition = masm.position();
58         }
59         emitDone = true;
60     }
61 
62     @Override
emitCode(CompilationResultBuilder crb)63     public void emitCode(CompilationResultBuilder crb) {
64         if (!crb.isSuccessorEdge(destination())) {
65             if (!emitDone) {
66                 SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
67                 masm.jmp(destination().label());
68             } else {
69                 int disp = crb.asm.position() - delaySlotPosition;
70                 assert disp == 4 : disp;
71             }
72         }
73     }
74 
75     @Override
resetState()76     public void resetState() {
77         delaySlotPosition = -1;
78         emitDone = false;
79     }
80 
81     @Override
getSPARCLIRInstructionStore()82     public SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore() {
83         return store;
84     }
85 }
86