src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java

Print this page


   1 /*
   2  * Copyright (c) 2013, 2016, 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  */


  59 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag.LessUnsigned;
  60 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag.NotEqual;
  61 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Subcc;
  62 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
  63 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
  64 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
  65 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
  66 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
  67 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
  68 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
  69 import static org.graalvm.compiler.lir.sparc.SPARCMove.const2reg;
  70 import static org.graalvm.compiler.lir.sparc.SPARCOP3Op.emitOp3;
  71 import static jdk.vm.ci.code.ValueUtil.asRegister;
  72 import static jdk.vm.ci.sparc.SPARC.CPU;
  73 import static jdk.vm.ci.sparc.SPARC.g0;
  74 import static jdk.vm.ci.sparc.SPARCKind.WORD;
  75 import static jdk.vm.ci.sparc.SPARCKind.XWORD;
  76 
  77 import java.util.ArrayList;
  78 import java.util.EnumSet;
  79 import java.util.HashMap;
  80 import java.util.List;
  81 import java.util.Map;
  82 
  83 import org.graalvm.compiler.asm.Assembler;
  84 import org.graalvm.compiler.asm.Assembler.LabelHint;
  85 import org.graalvm.compiler.asm.Label;
  86 import org.graalvm.compiler.asm.NumUtil;
  87 import org.graalvm.compiler.asm.sparc.SPARCAssembler;
  88 import org.graalvm.compiler.asm.sparc.SPARCAssembler.BranchPredict;
  89 import org.graalvm.compiler.asm.sparc.SPARCAssembler.CC;
  90 import org.graalvm.compiler.asm.sparc.SPARCAssembler.CMOV;
  91 import org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag;
  92 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
  93 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
  94 import org.graalvm.compiler.core.common.calc.Condition;
  95 import org.graalvm.compiler.debug.GraalError;
  96 import org.graalvm.compiler.lir.LIRInstructionClass;
  97 import org.graalvm.compiler.lir.LabelRef;
  98 import org.graalvm.compiler.lir.Opcode;
  99 import org.graalvm.compiler.lir.StandardOp;
 100 import org.graalvm.compiler.lir.SwitchStrategy;
 101 import org.graalvm.compiler.lir.SwitchStrategy.BaseSwitchClosure;
 102 import org.graalvm.compiler.lir.Variable;
 103 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;


 104 
 105 import jdk.vm.ci.code.Register;
 106 import jdk.vm.ci.meta.AllocatableValue;
 107 import jdk.vm.ci.meta.Constant;
 108 import jdk.vm.ci.meta.JavaConstant;
 109 import jdk.vm.ci.meta.PlatformKind;
 110 import jdk.vm.ci.meta.Value;
 111 import jdk.vm.ci.sparc.SPARC.CPUFeature;
 112 import jdk.vm.ci.sparc.SPARCKind;
 113 
 114 public class SPARCControlFlow {
 115     // This describes the maximum offset between the first emitted (load constant in to scratch,
 116     // if does not fit into simm5 of cbcond) instruction and the final branch instruction
 117     private static final int maximumSelfOffsetInstructions = 2;
 118 
 119     public static final class ReturnOp extends SPARCBlockEndOp {
 120         public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
 121         public static final SizeEstimate SIZE = SizeEstimate.create(2);
 122 
 123         @Use({REG, ILLEGAL}) protected Value x;


 127             this.x = x;
 128         }
 129 
 130         @Override
 131         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 132             emitCodeHelper(crb, masm);
 133         }
 134 
 135         public static void emitCodeHelper(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 136             masm.ret();
 137             // On SPARC we always leave the frame (in the delay slot).
 138             crb.frameContext.leave(crb);
 139         }
 140     }
 141 
 142     public static final class CompareBranchOp extends SPARCBlockEndOp implements SPARCDelayedControlTransfer {
 143         public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class);
 144         public static final SizeEstimate SIZE = SizeEstimate.create(3);
 145         static final EnumSet<SPARCKind> SUPPORTED_KINDS = EnumSet.of(XWORD, WORD);
 146 
 147         @Use({REG}) protected Value x;
 148         @Use({REG, CONST}) protected Value y;
 149         private ConditionFlag conditionFlag;
 150         protected final LabelRef trueDestination;
 151         protected LabelHint trueDestinationHint;
 152         protected final LabelRef falseDestination;
 153         protected LabelHint falseDestinationHint;
 154         protected final SPARCKind kind;
 155         protected final boolean unorderedIsTrue;
 156         private boolean emitted = false;
 157         private int delaySlotPosition = -1;
 158         private double trueDestinationProbability;
 159 
 160         public CompareBranchOp(Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, SPARCKind kind, boolean unorderedIsTrue, double trueDestinationProbability) {

 161             super(TYPE, SIZE);
 162             this.x = x;
 163             this.y = y;
 164             this.trueDestination = trueDestination;
 165             this.falseDestination = falseDestination;
 166             this.kind = kind;
 167             this.unorderedIsTrue = unorderedIsTrue;
 168             this.trueDestinationProbability = trueDestinationProbability;
 169             conditionFlag = fromCondition(kind.isInteger(), condition, unorderedIsTrue);
 170         }
 171 
 172         @Override
 173         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 174             if (emitted) { // Only if delayed control transfer is used we must check this
 175                 assert masm.position() - delaySlotPosition == 4 : "Only one instruction can be stuffed into the delay slot";
 176             }
 177             if (!emitted) {
 178                 requestHints(masm);
 179                 int targetPosition = getTargetPosition(masm);
 180                 if (canUseShortBranch(crb, masm, targetPosition)) {


 409             BPCC.emit(masm, cc, actualConditionFlag, NOT_ANNUL, predictTaken, actualTarget);
 410         }
 411         if (withDelayedNop) {
 412             masm.nop();  // delay slot
 413         }
 414         if (needJump) {
 415             masm.jmp(falseDestination.label());
 416         }
 417         return true;
 418     }
 419 
 420     public static class StrategySwitchOp extends SPARCBlockEndOp {
 421         public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class);
 422         protected Constant[] keyConstants;
 423         private final LabelRef[] keyTargets;
 424         private LabelRef defaultTarget;
 425         @Alive({REG}) protected Value key;
 426         @Alive({REG, ILLEGAL}) protected Value constantTableBase;
 427         @Temp({REG}) protected Value scratch;
 428         protected final SwitchStrategy strategy;
 429         private final Map<Label, LabelHint> labelHints;
 430         private final List<Label> conditionalLabels = new ArrayList<>();
 431 
 432         public StrategySwitchOp(Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) {
 433             this(TYPE, constantTableBase, strategy, keyTargets, defaultTarget, key, scratch);
 434         }
 435 
 436         protected StrategySwitchOp(LIRInstructionClass<? extends StrategySwitchOp> c, Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key,
 437                         Value scratch) {

 438             super(c);
 439             this.strategy = strategy;
 440             this.keyConstants = strategy.getKeyConstants();
 441             this.keyTargets = keyTargets;
 442             this.defaultTarget = defaultTarget;
 443             this.constantTableBase = constantTableBase;
 444             this.key = key;
 445             this.scratch = scratch;
 446             this.labelHints = new HashMap<>();
 447             assert keyConstants.length == keyTargets.length;
 448             assert keyConstants.length == strategy.keyProbabilities.length;
 449         }
 450 
 451         @Override
 452         public void emitCode(final CompilationResultBuilder crb, final SPARCMacroAssembler masm) {
 453             final Register keyRegister = asRegister(key);
 454             final Register constantBaseRegister = AllocatableValue.ILLEGAL.equals(constantTableBase) ? g0 : asRegister(constantTableBase);
 455             strategy.run(new SwitchClosure(keyRegister, constantBaseRegister, crb, masm));
 456         }
 457 
 458         public class SwitchClosure extends BaseSwitchClosure {
 459             private int conditionalLabelPointer = 0;
 460 
 461             protected final Register keyRegister;
 462             protected final Register constantBaseRegister;
 463             protected final CompilationResultBuilder crb;
 464             protected final SPARCMacroAssembler masm;
 465 
 466             protected SwitchClosure(Register keyRegister, Register constantBaseRegister, CompilationResultBuilder crb, SPARCMacroAssembler masm) {


   1 /*
   2  * Copyright (c) 2013, 2017, 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  */


  59 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag.LessUnsigned;
  60 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag.NotEqual;
  61 import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Subcc;
  62 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
  63 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
  64 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
  65 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
  66 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
  67 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
  68 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
  69 import static org.graalvm.compiler.lir.sparc.SPARCMove.const2reg;
  70 import static org.graalvm.compiler.lir.sparc.SPARCOP3Op.emitOp3;
  71 import static jdk.vm.ci.code.ValueUtil.asRegister;
  72 import static jdk.vm.ci.sparc.SPARC.CPU;
  73 import static jdk.vm.ci.sparc.SPARC.g0;
  74 import static jdk.vm.ci.sparc.SPARCKind.WORD;
  75 import static jdk.vm.ci.sparc.SPARCKind.XWORD;
  76 
  77 import java.util.ArrayList;
  78 import java.util.EnumSet;

  79 import java.util.List;


  80 import org.graalvm.compiler.asm.Assembler;
  81 import org.graalvm.compiler.asm.Assembler.LabelHint;
  82 import org.graalvm.compiler.asm.Label;
  83 import org.graalvm.compiler.core.common.NumUtil;
  84 import org.graalvm.compiler.asm.sparc.SPARCAssembler;
  85 import org.graalvm.compiler.asm.sparc.SPARCAssembler.BranchPredict;
  86 import org.graalvm.compiler.asm.sparc.SPARCAssembler.CC;
  87 import org.graalvm.compiler.asm.sparc.SPARCAssembler.CMOV;
  88 import org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag;
  89 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
  90 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
  91 import org.graalvm.compiler.core.common.calc.Condition;
  92 import org.graalvm.compiler.debug.GraalError;
  93 import org.graalvm.compiler.lir.LIRInstructionClass;
  94 import org.graalvm.compiler.lir.LabelRef;
  95 import org.graalvm.compiler.lir.Opcode;
  96 import org.graalvm.compiler.lir.StandardOp;
  97 import org.graalvm.compiler.lir.SwitchStrategy;
  98 import org.graalvm.compiler.lir.SwitchStrategy.BaseSwitchClosure;
  99 import org.graalvm.compiler.lir.Variable;
 100 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 101 import org.graalvm.util.Equivalence;
 102 import org.graalvm.util.EconomicMap;
 103 
 104 import jdk.vm.ci.code.Register;
 105 import jdk.vm.ci.meta.AllocatableValue;
 106 import jdk.vm.ci.meta.Constant;
 107 import jdk.vm.ci.meta.JavaConstant;
 108 import jdk.vm.ci.meta.PlatformKind;
 109 import jdk.vm.ci.meta.Value;
 110 import jdk.vm.ci.sparc.SPARC.CPUFeature;
 111 import jdk.vm.ci.sparc.SPARCKind;
 112 
 113 public class SPARCControlFlow {
 114     // This describes the maximum offset between the first emitted (load constant in to scratch,
 115     // if does not fit into simm5 of cbcond) instruction and the final branch instruction
 116     private static final int maximumSelfOffsetInstructions = 2;
 117 
 118     public static final class ReturnOp extends SPARCBlockEndOp {
 119         public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
 120         public static final SizeEstimate SIZE = SizeEstimate.create(2);
 121 
 122         @Use({REG, ILLEGAL}) protected Value x;


 126             this.x = x;
 127         }
 128 
 129         @Override
 130         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 131             emitCodeHelper(crb, masm);
 132         }
 133 
 134         public static void emitCodeHelper(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 135             masm.ret();
 136             // On SPARC we always leave the frame (in the delay slot).
 137             crb.frameContext.leave(crb);
 138         }
 139     }
 140 
 141     public static final class CompareBranchOp extends SPARCBlockEndOp implements SPARCDelayedControlTransfer {
 142         public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class);
 143         public static final SizeEstimate SIZE = SizeEstimate.create(3);
 144         static final EnumSet<SPARCKind> SUPPORTED_KINDS = EnumSet.of(XWORD, WORD);
 145 
 146         @Use({REG}) protected AllocatableValue x;
 147         @Use({REG, CONST}) protected Value y;
 148         private ConditionFlag conditionFlag;
 149         protected final LabelRef trueDestination;
 150         protected LabelHint trueDestinationHint;
 151         protected final LabelRef falseDestination;
 152         protected LabelHint falseDestinationHint;
 153         protected final SPARCKind kind;
 154         protected final boolean unorderedIsTrue;
 155         private boolean emitted = false;
 156         private int delaySlotPosition = -1;
 157         private double trueDestinationProbability;
 158 
 159         public CompareBranchOp(AllocatableValue x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, SPARCKind kind, boolean unorderedIsTrue,
 160                         double trueDestinationProbability) {
 161             super(TYPE, SIZE);
 162             this.x = x;
 163             this.y = y;
 164             this.trueDestination = trueDestination;
 165             this.falseDestination = falseDestination;
 166             this.kind = kind;
 167             this.unorderedIsTrue = unorderedIsTrue;
 168             this.trueDestinationProbability = trueDestinationProbability;
 169             conditionFlag = fromCondition(kind.isInteger(), condition, unorderedIsTrue);
 170         }
 171 
 172         @Override
 173         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 174             if (emitted) { // Only if delayed control transfer is used we must check this
 175                 assert masm.position() - delaySlotPosition == 4 : "Only one instruction can be stuffed into the delay slot";
 176             }
 177             if (!emitted) {
 178                 requestHints(masm);
 179                 int targetPosition = getTargetPosition(masm);
 180                 if (canUseShortBranch(crb, masm, targetPosition)) {


 409             BPCC.emit(masm, cc, actualConditionFlag, NOT_ANNUL, predictTaken, actualTarget);
 410         }
 411         if (withDelayedNop) {
 412             masm.nop();  // delay slot
 413         }
 414         if (needJump) {
 415             masm.jmp(falseDestination.label());
 416         }
 417         return true;
 418     }
 419 
 420     public static class StrategySwitchOp extends SPARCBlockEndOp {
 421         public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class);
 422         protected Constant[] keyConstants;
 423         private final LabelRef[] keyTargets;
 424         private LabelRef defaultTarget;
 425         @Alive({REG}) protected Value key;
 426         @Alive({REG, ILLEGAL}) protected Value constantTableBase;
 427         @Temp({REG}) protected Value scratch;
 428         protected final SwitchStrategy strategy;
 429         private final EconomicMap<Label, LabelHint> labelHints;
 430         private final List<Label> conditionalLabels = new ArrayList<>();
 431 
 432         public StrategySwitchOp(Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, AllocatableValue key, Variable scratch) {
 433             this(TYPE, constantTableBase, strategy, keyTargets, defaultTarget, key, scratch);
 434         }
 435 
 436         protected StrategySwitchOp(LIRInstructionClass<? extends StrategySwitchOp> c, Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget,
 437                         AllocatableValue key,
 438                         Variable scratch) {
 439             super(c);
 440             this.strategy = strategy;
 441             this.keyConstants = strategy.getKeyConstants();
 442             this.keyTargets = keyTargets;
 443             this.defaultTarget = defaultTarget;
 444             this.constantTableBase = constantTableBase;
 445             this.key = key;
 446             this.scratch = scratch;
 447             this.labelHints = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
 448             assert keyConstants.length == keyTargets.length;
 449             assert keyConstants.length == strategy.keyProbabilities.length;
 450         }
 451 
 452         @Override
 453         public void emitCode(final CompilationResultBuilder crb, final SPARCMacroAssembler masm) {
 454             final Register keyRegister = asRegister(key);
 455             final Register constantBaseRegister = AllocatableValue.ILLEGAL.equals(constantTableBase) ? g0 : asRegister(constantTableBase);
 456             strategy.run(new SwitchClosure(keyRegister, constantBaseRegister, crb, masm));
 457         }
 458 
 459         public class SwitchClosure extends BaseSwitchClosure {
 460             private int conditionalLabelPointer = 0;
 461 
 462             protected final Register keyRegister;
 463             protected final Register constantBaseRegister;
 464             protected final CompilationResultBuilder crb;
 465             protected final SPARCMacroAssembler masm;
 466 
 467             protected SwitchClosure(Register keyRegister, Register constantBaseRegister, CompilationResultBuilder crb, SPARCMacroAssembler masm) {


src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File