package org.graalvm.compiler.replacements.amd64;
import static org.graalvm.compiler.replacements.NodeIntrinsificationProvider.INJECTED_TARGET;
import org.graalvm.compiler.api.replacements.ClassSubstitution;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.core.common.SuppressFBWarnings;
import org.graalvm.compiler.replacements.nodes.BitScanForwardNode;
import org.graalvm.compiler.replacements.nodes.BitScanReverseNode;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.code.TargetDescription;
@ClassSubstitution(Integer.class)
public class AMD64IntegerSubstitutions {
@Fold
static boolean lzcnt(@Fold.InjectedParameter TargetDescription target) {
AMD64 arch = (AMD64) target.arch;
return arch.getFeatures().contains(AMD64.CPUFeature.LZCNT) && arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction);
}
@Fold
static boolean tzcnt(@Fold.InjectedParameter TargetDescription target) {
AMD64 arch = (AMD64) target.arch;
return arch.getFeatures().contains(AMD64.CPUFeature.BMI1) && arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction);
}
@MethodSubstitution
@SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected")
public static int numberOfLeadingZeros(int i) {
if (lzcnt(INJECTED_TARGET)) {
return AMD64CountLeadingZerosNode.countLeadingZeros(i);
}
if (i == 0) {
return 32;
}
return 31 - BitScanReverseNode.unsafeScan(i);
}
@MethodSubstitution