< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ControlFlow.java
Print this page
rev 56282 : [mq]: graal
*** 1,7 ****
/*
! * Copyright (c) 2013, 2018, 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.
--- 1,7 ----
/*
! * Copyright (c) 2013, 2019, 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.
*** 43,52 ****
--- 43,53 ----
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.debug.GraalError;
import org.graalvm.compiler.lir.ConstantValue;
+ import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.LabelRef;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.StandardOp;
import org.graalvm.compiler.lir.StandardOp.BlockEndOp;
*** 146,159 ****
protected void emitBranch(CompilationResultBuilder crb, AArch64MacroAssembler masm, LabelRef target, boolean negate) {
AArch64Kind kind = (AArch64Kind) this.value.getPlatformKind();
assert kind.isInteger();
int size = kind.getSizeInBytes() * Byte.SIZE;
! if (negate) {
! masm.cbnz(size, asRegister(this.value), target.label());
} else {
! masm.cbz(size, asRegister(this.value), target.label());
}
}
}
public static class BitTestAndBranchOp extends AbstractBranchOp implements StandardOp.BranchOp {
--- 147,175 ----
protected void emitBranch(CompilationResultBuilder crb, AArch64MacroAssembler masm, LabelRef target, boolean negate) {
AArch64Kind kind = (AArch64Kind) this.value.getPlatformKind();
assert kind.isInteger();
int size = kind.getSizeInBytes() * Byte.SIZE;
! Label label = target.label();
! boolean isFarBranch = isFarBranch(this, 21, crb, masm, label);
! boolean useCbnz;
! if (isFarBranch) {
! useCbnz = !negate;
! label = new Label();
! } else {
! useCbnz = negate;
! }
!
! if (useCbnz) {
! masm.cbnz(size, asRegister(this.value), label);
} else {
! masm.cbz(size, asRegister(this.value), label);
! }
!
! if (isFarBranch) {
! masm.jmp(target.label());
! masm.bind(label);
}
}
}
public static class BitTestAndBranchOp extends AbstractBranchOp implements StandardOp.BranchOp {
*** 170,193 ****
@Override
protected void emitBranch(CompilationResultBuilder crb, AArch64MacroAssembler masm, LabelRef target, boolean negate) {
ConditionFlag cond = negate ? ConditionFlag.NE : ConditionFlag.EQ;
Label label = target.label();
! boolean isFarBranch;
!
! if (label.isBound()) {
! // The label.position() is a byte based index. The TBZ instruction has 14 bits for
! // the offset and AArch64 instruction is 4 bytes aligned. So TBZ can encode 16 bits
! // signed offset.
! isFarBranch = !NumUtil.isSignedNbit(16, masm.position() - label.position());
! } else {
! // Max range of tbz is +-2^13 instructions. We estimate that each LIR instruction
! // emits 2 AArch64 instructions on average. Thus we test for maximum 2^12 LIR
! // instruction offset.
! int maxLIRDistance = (1 << 12);
! isFarBranch = !crb.labelWithinRange(this, label, maxLIRDistance);
! }
if (isFarBranch) {
cond = cond.negate();
label = new Label();
}
--- 186,196 ----
@Override
protected void emitBranch(CompilationResultBuilder crb, AArch64MacroAssembler masm, LabelRef target, boolean negate) {
ConditionFlag cond = negate ? ConditionFlag.NE : ConditionFlag.EQ;
Label label = target.label();
! boolean isFarBranch = isFarBranch(this, 14, crb, masm, label);
if (isFarBranch) {
cond = cond.negate();
label = new Label();
}
*** 390,395 ****
--- 393,414 ----
AArch64Move.move(crb, masm, asAllocatableValue(scratchValue), c);
masm.cmp(size, asRegister(key), asRegister(scratchValue));
}
}
+ private static boolean isFarBranch(LIRInstruction instruction, int offsetBits, CompilationResultBuilder crb, AArch64MacroAssembler masm, Label label) {
+ boolean isFarBranch;
+ if (label.isBound()) {
+ // The label.position() is a byte based index. The instruction instruction has
+ // offsetBits bits for the offset and AArch64 instruction is 4 bytes aligned. So
+ // instruction can encode offsetBits+2 bits signed offset.
+ isFarBranch = !NumUtil.isSignedNbit(offsetBits + 2, masm.position() - label.position());
+ } else {
+ // Max range of instruction is 2^offsetBits instructions. We estimate that each LIR
+ // instruction emits 2 AArch64 instructions on average. Thus we test for maximum
+ // 2^(offsetBits-2) LIR instruction offset.
+ int maxLIRDistance = (1 << (offsetBits - 2));
+ isFarBranch = !crb.labelWithinRange(instruction, label, maxLIRDistance);
+ }
+ return isFarBranch;
+ }
}
< prev index next >