< 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 >