1 /*
   2  * Copyright (c) 2011, 2014, 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 package com.oracle.graal.lir.gen;
  24 
  25 import com.oracle.graal.api.code.*;
  26 import com.oracle.graal.api.meta.*;
  27 import com.oracle.graal.compiler.common.*;
  28 import com.oracle.graal.compiler.common.calc.*;
  29 import com.oracle.graal.compiler.common.cfg.*;
  30 import com.oracle.graal.compiler.common.spi.*;
  31 import com.oracle.graal.lir.*;
  32 
  33 public interface LIRGeneratorTool extends ArithmeticLIRGenerator {
  34 
  35     CodeGenProviders getProviders();
  36 
  37     TargetDescription target();
  38 
  39     MetaAccessProvider getMetaAccess();
  40 
  41     CodeCacheProvider getCodeCache();
  42 
  43     ForeignCallsProvider getForeignCalls();
  44 
  45     AbstractBlock<?> getCurrentBlock();
  46 
  47     LIRGenerationResult getResult();
  48 
  49     boolean hasBlockEnd(AbstractBlock<?> block);
  50 
  51     void doBlockStart(AbstractBlock<?> block);
  52 
  53     void doBlockEnd(AbstractBlock<?> block);
  54 
  55     Value emitLoadConstant(LIRKind kind, Constant constant);
  56 
  57     Value emitLoad(LIRKind kind, Value address, LIRFrameState state);
  58 
  59     void emitStore(LIRKind kind, Value address, Value input, LIRFrameState state);
  60 
  61     void emitNullCheck(Value address, LIRFrameState state);
  62 
  63     Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue);
  64 
  65     /**
  66      * Emit an atomic read-and-add instruction.
  67      *
  68      * @param address address of the value to be read and written
  69      * @param delta the value to be added
  70      */
  71     default Value emitAtomicReadAndAdd(Value address, Value delta) {
  72         throw GraalInternalError.unimplemented();
  73     }
  74 
  75     /**
  76      * Emit an atomic read-and-write instruction.
  77      *
  78      * @param address address of the value to be read and written
  79      * @param newValue the new value to be written
  80      */
  81     default Value emitAtomicReadAndWrite(Value address, Value newValue) {
  82         throw GraalInternalError.unimplemented();
  83     }
  84 
  85     void emitDeoptimize(Value actionAndReason, Value failedSpeculation, LIRFrameState state);
  86 
  87     Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args);
  88 
  89     RegisterAttributes attributes(Register register);
  90 
  91     /**
  92      * Create a new {@link Variable}.
  93      *
  94      * @param kind The type of the value that will be stored in this {@link Variable}. See
  95      *            {@link LIRKind} for documentation on what to pass here. Note that in most cases,
  96      *            simply passing {@link Value#getLIRKind()} is wrong.
  97      * @return A new {@link Variable}.
  98      */
  99     Variable newVariable(LIRKind kind);
 100 
 101     Variable emitMove(Value input);
 102 
 103     void emitMove(AllocatableValue dst, Value src);
 104 
 105     /**
 106      * Emits an op that loads the address of some raw data.
 107      *
 108      * @param dst the variable into which the address is loaded
 109      * @param data the data to be installed with the generated code
 110      */
 111     void emitData(AllocatableValue dst, byte[] data);
 112 
 113     Value emitAddress(Value base, long displacement, Value index, int scale);
 114 
 115     Value emitAddress(StackSlot slot);
 116 
 117     void emitMembar(int barriers);
 118 
 119     void emitUnwind(Value operand);
 120 
 121     /**
 122      * Called just before register allocation is performed on the LIR owned by this generator.
 123      * Overriding implementations of this method must call the overridden method.
 124      */
 125     void beforeRegisterAllocation();
 126 
 127     void emitIncomingValues(Value[] params);
 128 
 129     /**
 130      * Emits a return instruction. Implementations need to insert a move if the input is not in the
 131      * correct location.
 132      */
 133     void emitReturn(Value input);
 134 
 135     AllocatableValue asAllocatable(Value value);
 136 
 137     Variable load(Value value);
 138 
 139     Value loadNonConst(Value value);
 140 
 141     /**
 142      * Returns true if the redundant move elimination optimization should be done after register
 143      * allocation.
 144      */
 145     boolean canEliminateRedundantMoves();
 146 
 147     /**
 148      * Determines if only oop maps are required for the code generated from the LIR.
 149      */
 150     boolean needOnlyOopMaps();
 151 
 152     /**
 153      * Gets the ABI specific operand used to return a value of a given kind from a method.
 154      *
 155      * @param kind the kind of value being returned
 156      * @return the operand representing the ABI defined location used return a value of kind
 157      *         {@code kind}
 158      */
 159     AllocatableValue resultOperandFor(LIRKind kind);
 160 
 161     void append(LIRInstruction op);
 162 
 163     void emitJump(LabelRef label);
 164 
 165     void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
 166                     double trueDestinationProbability);
 167 
 168     void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability);
 169 
 170     void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability);
 171 
 172     Variable emitConditionalMove(PlatformKind cmpKind, Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
 173 
 174     Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue);
 175 
 176     void emitStrategySwitch(JavaConstant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value);
 177 
 178     void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget);
 179 
 180     CallingConvention getCallingConvention();
 181 
 182     Value emitBitCount(Value operand);
 183 
 184     Value emitBitScanForward(Value operand);
 185 
 186     Value emitBitScanReverse(Value operand);
 187 
 188     Value emitByteSwap(Value operand);
 189 
 190     Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length);
 191 
 192     @SuppressWarnings("unused")
 193     default Value emitCountLeadingZeros(Value value) {
 194         throw GraalInternalError.unimplemented();
 195     }
 196 
 197     @SuppressWarnings("unused")
 198     default Value emitCountTrailingZeros(Value value) {
 199         throw GraalInternalError.unimplemented();
 200     }
 201 
 202 }