< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
Print this page
*** 31,49 ****
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue;
import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
! import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.spi.LIRKindTool;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.ConstantValue;
--- 31,51 ----
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue;
import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
+ import static org.graalvm.compiler.lir.LIRValueUtil.isIntConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
! import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
import org.graalvm.compiler.core.common.LIRKind;
+ import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.spi.LIRKindTool;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.ConstantValue;
*** 56,72 ****
--- 58,78 ----
import org.graalvm.compiler.lir.SwitchStrategy;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
import org.graalvm.compiler.lir.amd64.AMD64ArrayEqualsOp;
+ import org.graalvm.compiler.lir.amd64.AMD64Binary;
import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
import org.graalvm.compiler.lir.amd64.AMD64ByteSwapOp;
import org.graalvm.compiler.lir.amd64.AMD64Call;
+ import org.graalvm.compiler.lir.amd64.AMD64ControlFlow;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondMoveOp;
+ import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+ import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64Move;
import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;
*** 255,266 ****
append(new JumpOp(label));
}
@Override
public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
! boolean mirrored = emitCompare(cmpKind, left, right);
! Condition finalCondition = mirrored ? cond.mirror() : cond;
if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
} else {
append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability));
}
--- 261,271 ----
append(new JumpOp(label));
}
@Override
public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
! Condition finalCondition = emitCompare(cmpKind, left, right, cond);
if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
} else {
append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability));
}
*** 288,305 ****
append(new BranchOp(Condition.EQ, trueDestination, falseDestination, trueDestinationProbability));
}
@Override
public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
! boolean mirrored = emitCompare(cmpKind, left, right);
! Condition finalCondition = mirrored ? cond.mirror() : cond;
! Variable result = newVariable(trueValue.getValueKind());
! if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
! append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
} else {
! append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue)));
}
return result;
}
@Override
--- 293,356 ----
append(new BranchOp(Condition.EQ, trueDestination, falseDestination, trueDestinationProbability));
}
@Override
public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
! boolean isFloatComparison = cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE;
! Condition finalCondition = cond;
! Value finalTrueValue = trueValue;
! Value finalFalseValue = falseValue;
! if (isFloatComparison) {
! // eliminate the parity check in case of a float comparison
! Value finalLeft = left;
! Value finalRight = right;
! if (unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition)) {
! if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.mirror())) {
! finalCondition = finalCondition.mirror();
! finalLeft = right;
! finalRight = left;
! } else if (finalCondition != Condition.EQ && finalCondition != Condition.NE) {
! // negating EQ and NE does not make any sense as we would need to negate
! // unorderedIsTrue as well (otherwise, we would no longer fulfill the Java
! // NaN semantics)
! assert unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate());
! finalCondition = finalCondition.negate();
! finalTrueValue = falseValue;
! finalFalseValue = trueValue;
! }
! }
! emitRawCompare(cmpKind, finalLeft, finalRight);
! } else {
! finalCondition = emitCompare(cmpKind, left, right, cond);
! }
!
! boolean isParityCheckNecessary = isFloatComparison && unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition);
! Variable result = newVariable(finalTrueValue.getValueKind());
! if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 1) && isIntConstant(finalFalseValue, 0)) {
! if (isFloatComparison) {
! append(new FloatCondSetOp(result, finalCondition));
! } else {
! append(new CondSetOp(result, finalCondition));
! }
! } else if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 0) && isIntConstant(finalFalseValue, 1)) {
! if (isFloatComparison) {
! if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate())) {
! append(new FloatCondSetOp(result, finalCondition.negate()));
! } else {
! append(new FloatCondSetOp(result, finalCondition));
! Variable negatedResult = newVariable(result.getValueKind());
! append(new AMD64Binary.ConstOp(AMD64BinaryArithmetic.XOR, OperandSize.get(result.getPlatformKind()), negatedResult, result, 1));
! result = negatedResult;
! }
} else {
! append(new CondSetOp(result, finalCondition.negate()));
! }
! } else if (isFloatComparison) {
! append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(finalTrueValue), load(finalFalseValue)));
! } else {
! append(new CondMoveOp(result, finalCondition, load(finalTrueValue), loadNonConst(finalFalseValue)));
}
return result;
}
@Override
*** 392,418 ****
* This method emits the compare instruction, and may reorder the operands. It returns true if
* it did so.
*
* @param a the left operand of the comparison
* @param b the right operand of the comparison
* @return true if the left and right operands were switched, false otherwise
*/
! private boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
! Variable left;
! Value right;
! boolean mirrored;
if (LIRValueUtil.isVariable(b)) {
! left = load(b);
! right = loadNonConst(a);
! mirrored = true;
! } else {
! left = load(a);
! right = loadNonConst(b);
! mirrored = false;
}
! ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, left, right);
! return mirrored;
}
@Override
public void emitMembar(int barriers) {
int necessaryBarriers = target().arch.requiredBarriers(barriers);
--- 443,467 ----
* This method emits the compare instruction, and may reorder the operands. It returns true if
* it did so.
*
* @param a the left operand of the comparison
* @param b the right operand of the comparison
+ * @param cond the condition of the comparison
* @return true if the left and right operands were switched, false otherwise
*/
! private Condition emitCompare(PlatformKind cmpKind, Value a, Value b, Condition cond) {
if (LIRValueUtil.isVariable(b)) {
! emitRawCompare(cmpKind, b, a);
! return cond.mirror();
! } else {
! emitRawCompare(cmpKind, a, b);
! return cond;
}
! }
!
! private void emitRawCompare(PlatformKind cmpKind, Value left, Value right) {
! ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, load(left), loadNonConst(right));
}
@Override
public void emitMembar(int barriers) {
int necessaryBarriers = target().arch.requiredBarriers(barriers);
< prev index next >