# HG changeset patch # User Doug Simon # Date 1416857544 -3600 # Node ID fe0db662e9820ad3ee25132b89b2d3c982b61785 # Parent 9e944c7eaded211d826f07e15ac77fcee071a185 adds ability for substitution guards to have a constructor with an Architecture argument added extra flags enum to AMD64 to drive code emission features (currently contains UseCountLeadingZerosInstruction and UseCountTrailingZerosInstruction) moved lzcnt/tzcnt nodes and substitutions to com.oracle.graal.replacements.amd64 Contributed-by: Igor Veresov diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java --- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Mon Nov 24 17:29:51 2014 +0100 +++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Mon Nov 24 20:32:24 2014 +0100 @@ -138,9 +138,20 @@ private final EnumSet features; - public AMD64(EnumSet features) { + /** + * Set of flags to control code emission. + */ + public static enum Flag { + UseCountLeadingZerosInstruction, + UseCountTrailingZerosInstruction + } + + private final EnumSet flags; + + public AMD64(EnumSet features, EnumSet flags) { super("AMD64", 8, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + (xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT), 8); this.features = features; + this.flags = flags; assert features.contains(CPUFeature.SSE2) : "minimum config for x64"; } @@ -148,6 +159,10 @@ return features; } + public EnumSet getFlags() { + return flags; + } + @Override public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { if (!(platformKind instanceof Kind)) { diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SubstitutionGuard.java --- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SubstitutionGuard.java Mon Nov 24 17:29:51 2014 +0100 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SubstitutionGuard.java Mon Nov 24 20:32:24 2014 +0100 @@ -26,6 +26,12 @@ /** * Guards the installation of substitutions for {@link ClassSubstitution} and * {@link MethodSubstitution}. + *

+ * Implementor must have a single public constructor with one of the following signatures: + *

    + *
  • {@code Guard(Architecture)}
  • + *
  • {@code Guard()} (an implicit constructor is OK as well)
  • + *
*/ public interface SubstitutionGuard { diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Nov 24 17:29:51 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Nov 24 20:32:24 2014 +0100 @@ -40,7 +40,7 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory { protected Architecture createArchitecture(HotSpotVMConfig config) { - return new AMD64(computeFeatures(config)); + return new AMD64(computeFeatures(config), computeFlags(config)); } protected EnumSet computeFeatures(HotSpotVMConfig config) { @@ -91,6 +91,17 @@ return features; } + protected EnumSet computeFlags(HotSpotVMConfig config) { + EnumSet flags = EnumSet.noneOf(AMD64.Flag.class); + if (config.useCountLeadingZerosInstruction) { + flags.add(AMD64.Flag.UseCountLeadingZerosInstruction); + } + if (config.useCountTrailingZerosInstruction) { + flags.add(AMD64.Flag.UseCountTrailingZerosInstruction); + } + return flags; + } + protected TargetDescription createTarget(HotSpotVMConfig config) { final int stackFrameAlignment = 16; final int implicitNullCheckLimit = 4096; @@ -240,15 +251,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Nov 24 17:29:51 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Nov 24 20:32:24 2014 +0100 @@ -34,8 +34,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.replacements.IntegerSubstitutions; -import com.oracle.graal.replacements.LongSubstitutions; import com.oracle.graal.word.phases.*; /** diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CountLeadingZerosNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CountLeadingZerosNode.java Mon Nov 24 17:29:51 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.replacements; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -/** - * Count the number of leading zeros. - */ -@NodeInfo -public class CountLeadingZerosNode extends UnaryNode implements LIRLowerable { - - public static CountLeadingZerosNode create(ValueNode value) { - return new CountLeadingZerosNode(value); - } - - protected CountLeadingZerosNode(ValueNode value) { - super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); - assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; - } - - @Override - public boolean inferStamp() { - IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); - long mask = CodeUtil.mask(valueStamp.getBits()); - int min = Long.numberOfLeadingZeros(valueStamp.upMask() & mask); - int max = Long.numberOfLeadingZeros(valueStamp.downMask() & mask); - return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); - } - - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { - if (forValue.isConstant()) { - JavaConstant c = forValue.asJavaConstant(); - if (forValue.getKind() == Kind.Int) { - return ConstantNode.forInt(Integer.numberOfLeadingZeros(c.asInt())); - } else { - return ConstantNode.forInt(Long.numberOfLeadingZeros(c.asLong())); - } - } - return this; - } - - /** - * Raw intrinsic for lzcntq instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(long v); - - /** - * Raw intrinsic for lzcntl instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(int v); - - @Override - public void generate(NodeLIRBuilderTool gen) { - Value result = gen.getLIRGeneratorTool().emitCountLeadingZeros(gen.operand(getValue())); - gen.setResult(this, result); - } -} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CountTrailingZerosNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CountTrailingZerosNode.java Mon Nov 24 17:29:51 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.replacements; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -/** - * Count the number of trailing zeros. - */ -@NodeInfo -public class CountTrailingZerosNode extends UnaryNode implements LIRLowerable { - - public static CountTrailingZerosNode create(ValueNode value) { - return new CountTrailingZerosNode(value); - } - - protected CountTrailingZerosNode(ValueNode value) { - super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); - assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; - } - - @Override - public boolean inferStamp() { - IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); - long mask = CodeUtil.mask(valueStamp.getBits()); - int min = Long.numberOfTrailingZeros(valueStamp.upMask() & mask); - int max = Long.numberOfTrailingZeros(valueStamp.downMask() & mask); - return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); - } - - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { - if (forValue.isConstant()) { - JavaConstant c = forValue.asJavaConstant(); - if (forValue.getKind() == Kind.Int) { - return ConstantNode.forInt(Integer.numberOfTrailingZeros(c.asInt())); - } else { - return ConstantNode.forInt(Long.numberOfTrailingZeros(c.asLong())); - } - } - return this; - } - - /** - * Raw intrinsic for tzcntq instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(long v); - - /** - * Raw intrinsic for tzcntl instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(int v); - - @Override - public void generate(NodeLIRBuilderTool gen) { - Value result = gen.getLIRGeneratorTool().emitCountTrailingZeros(gen.operand(getValue())); - gen.setResult(this, result); - } -} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Mon Nov 24 17:29:51 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Mon Nov 24 20:32:24 2014 +0100 @@ -67,7 +67,5 @@ replacements.registerSubstitutions(CompositeValueClass.class, CompositeValueClassSubstitutions.class); replacements.registerSubstitutions(new NamedType("com.sun.crypto.provider.AESCrypt"), AESCryptSubstitutions.class); replacements.registerSubstitutions(new NamedType("com.sun.crypto.provider.CipherBlockChaining"), CipherBlockChainingSubstitutions.class); - replacements.registerSubstitutions(Integer.class, IntegerSubstitutions.class); - replacements.registerSubstitutions(Long.class, LongSubstitutions.class); } } diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotspotGuards.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotspotGuards.java Mon Nov 24 17:29:51 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.graal.hotspot.replacements; - -import com.oracle.graal.api.replacements.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; - -public class HotspotGuards { - public static class CountLeadingZerosSupported implements SubstitutionGuard { - public boolean execute() { - return runtime().getConfig().useCountLeadingZerosInstruction; - } - } - - public static class CountTrailingZerosSupported implements SubstitutionGuard { - public boolean execute() { - return runtime().getConfig().useCountTrailingZerosInstruction; - } - } -} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/IntegerSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/IntegerSubstitutions.java Mon Nov 24 17:29:51 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.graal.hotspot.replacements; - -import com.oracle.graal.api.replacements.*; - -@ClassSubstitution(Integer.class) -public class IntegerSubstitutions { - - @MethodSubstitution(guard = HotspotGuards.CountLeadingZerosSupported.class) - public static int numberOfLeadingZeros(int i) { - return CountLeadingZerosNode.count(i); - } - - @MethodSubstitution(guard = HotspotGuards.CountTrailingZerosSupported.class) - public static int numberOfTrailingZeros(int i) { - return CountTrailingZerosNode.count(i); - } -} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LongSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LongSubstitutions.java Mon Nov 24 17:29:51 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.graal.hotspot.replacements; - -import com.oracle.graal.api.replacements.*; - -@ClassSubstitution(Long.class) -public class LongSubstitutions { - - @MethodSubstitution(guard = HotspotGuards.CountLeadingZerosSupported.class) - public static int numberOfLeadingZeros(long i) { - return CountLeadingZerosNode.count(i); - } - - @MethodSubstitution(guard = HotspotGuards.CountTrailingZerosSupported.class) - public static int numberOfTrailingZeros(long i) { - return CountTrailingZerosNode.count(i); - } -} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java Mon Nov 24 20:32:24 2014 +0100 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.amd64; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Count the number of leading zeros. + */ +@NodeInfo +public class AMD64CountLeadingZerosNode extends UnaryNode implements LIRLowerable { + + public static AMD64CountLeadingZerosNode create(ValueNode value) { + return new AMD64CountLeadingZerosNode(value); + } + + protected AMD64CountLeadingZerosNode(ValueNode value) { + super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); + assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; + } + + @Override + public boolean inferStamp() { + IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); + long mask = CodeUtil.mask(valueStamp.getBits()); + int min = Long.numberOfLeadingZeros(valueStamp.upMask() & mask); + int max = Long.numberOfLeadingZeros(valueStamp.downMask() & mask); + return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + JavaConstant c = forValue.asJavaConstant(); + if (forValue.getKind() == Kind.Int) { + return ConstantNode.forInt(Integer.numberOfLeadingZeros(c.asInt())); + } else { + return ConstantNode.forInt(Long.numberOfLeadingZeros(c.asLong())); + } + } + return this; + } + + /** + * Raw intrinsic for lzcntq instruction. + * + * @param v + * @return number of trailing zeros + */ + @NodeIntrinsic + public static native int count(long v); + + /** + * Raw intrinsic for lzcntl instruction. + * + * @param v + * @return number of trailing zeros + */ + @NodeIntrinsic + public static native int count(int v); + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value result = gen.getLIRGeneratorTool().emitCountLeadingZeros(gen.operand(getValue())); + gen.setResult(this, result); + } +} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java Mon Nov 24 20:32:24 2014 +0100 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.amd64; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Count the number of trailing zeros. + */ +@NodeInfo +public class AMD64CountTrailingZerosNode extends UnaryNode implements LIRLowerable { + + public static AMD64CountTrailingZerosNode create(ValueNode value) { + return new AMD64CountTrailingZerosNode(value); + } + + protected AMD64CountTrailingZerosNode(ValueNode value) { + super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); + assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; + } + + @Override + public boolean inferStamp() { + IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); + long mask = CodeUtil.mask(valueStamp.getBits()); + int min = Long.numberOfTrailingZeros(valueStamp.upMask() & mask); + int max = Long.numberOfTrailingZeros(valueStamp.downMask() & mask); + return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + JavaConstant c = forValue.asJavaConstant(); + if (forValue.getKind() == Kind.Int) { + return ConstantNode.forInt(Integer.numberOfTrailingZeros(c.asInt())); + } else { + return ConstantNode.forInt(Long.numberOfTrailingZeros(c.asLong())); + } + } + return this; + } + + /** + * Raw intrinsic for tzcntq instruction. + * + * @param v + * @return number of trailing zeros + */ + @NodeIntrinsic + public static native int count(long v); + + /** + * Raw intrinsic for tzcntl instruction. + * + * @param v + * @return number of trailing zeros + */ + @NodeIntrinsic + public static native int count(int v); + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value result = gen.getLIRGeneratorTool().emitCountTrailingZeros(gen.operand(getValue())); + gen.setResult(this, result); + } +} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Guards.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Guards.java Mon Nov 24 20:32:24 2014 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.replacements.amd64; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.amd64.*; + +public class AMD64Guards { + public static class CountLeadingZerosSupported implements SubstitutionGuard { + private AMD64 arch; + + public CountLeadingZerosSupported(Architecture arch) { + this.arch = (AMD64) arch; + } + + public boolean execute() { + return arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction); + } + } + + public static class CountTrailingZerosSupported implements SubstitutionGuard { + private AMD64 arch; + + public CountTrailingZerosSupported(Architecture arch) { + this.arch = (AMD64) arch; + } + + public boolean execute() { + return arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction); + } + } +} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64IntegerSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64IntegerSubstitutions.java Mon Nov 24 20:32:24 2014 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.replacements.amd64; + +import com.oracle.graal.api.replacements.*; + +@ClassSubstitution(Integer.class) +public class AMD64IntegerSubstitutions { + + @MethodSubstitution(guard = AMD64Guards.CountLeadingZerosSupported.class) + public static int numberOfLeadingZeros(int i) { + return AMD64CountLeadingZerosNode.count(i); + } + + @MethodSubstitution(guard = AMD64Guards.CountTrailingZerosSupported.class) + public static int numberOfTrailingZeros(int i) { + return AMD64CountTrailingZerosNode.count(i); + } +} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64LongSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64LongSubstitutions.java Mon Nov 24 20:32:24 2014 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.replacements.amd64; + +import com.oracle.graal.api.replacements.*; + +@ClassSubstitution(Long.class) +public class AMD64LongSubstitutions { + + @MethodSubstitution(guard = AMD64Guards.CountLeadingZerosSupported.class) + public static int numberOfLeadingZeros(long i) { + return AMD64CountLeadingZerosNode.count(i); + } + + @MethodSubstitution(guard = AMD64Guards.CountTrailingZerosSupported.class) + public static int numberOfTrailingZeros(long i) { + return AMD64CountTrailingZerosNode.count(i); + } +} diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java Mon Nov 24 17:29:51 2014 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java Mon Nov 24 20:32:24 2014 +0100 @@ -44,6 +44,8 @@ if (Intrinsify.getValue()) { replacements.registerSubstitutions(Arrays.class, ArraysSubstitutions.class); replacements.registerSubstitutions(String.class, StringSubstitutions.class); + replacements.registerSubstitutions(Integer.class, AMD64IntegerSubstitutions.class); + replacements.registerSubstitutions(Long.class, AMD64LongSubstitutions.class); } } diff -r 9e944c7eaded -r fe0db662e982 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Nov 24 17:29:51 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Nov 24 20:32:24 2014 +0100 @@ -303,13 +303,27 @@ return assumptions; } - private static SubstitutionGuard getGuard(Class guardClass) { + private SubstitutionGuard getGuard(Class guardClass) { if (guardClass != SubstitutionGuard.class) { + Constructor[] constructors = guardClass.getConstructors(); + if (constructors.length != 1) { + throw new GraalInternalError("Substitution guard " + guardClass.getSimpleName() + " must have a single public constructor"); + } + Constructor constructor = constructors[0]; + Class[] paramTypes = constructor.getParameterTypes(); + // Check for supported constructor signatures try { - return guardClass.newInstance(); + if (constructor.getParameterCount() == 1 && paramTypes[0] == Architecture.class) { + // Guard(Architecture) + return (SubstitutionGuard) constructor.newInstance(target.arch); + } else if (constructor.getParameterCount() == 0) { + // Guard() + return (SubstitutionGuard) constructor.newInstance(); + } } catch (Exception e) { throw new GraalInternalError(e); } + throw new GraalInternalError("Unsupported constructor signature in substitution guard: " + constructor); } return null; } diff -r 9e944c7eaded -r fe0db662e982 mx/suite.py --- a/mx/suite.py Mon Nov 24 17:29:51 2014 +0100 +++ b/mx/suite.py Mon Nov 24 20:32:24 2014 +0100 @@ -632,7 +632,10 @@ "com.oracle.graal.replacements.amd64" : { "subDir" : "graal", "sourceDirs" : ["src"], - "dependencies" : ["com.oracle.graal.replacements"], + "dependencies" : [ + "com.oracle.graal.replacements", + "com.oracle.graal.amd64", + ], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "annotationProcessors" : ["com.oracle.graal.service.processor"],