Search in sources :

Example 6 with Label

use of org.graalvm.compiler.asm.Label in project graal by oracle.

the class AMD64ArrayEqualsOp method emitCode.

@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
    Register result = asRegister(resultValue);
    Register array1 = asRegister(temp1);
    Register array2 = asRegister(temp2);
    Register length = asRegister(temp3);
    Label trueLabel = new Label();
    Label falseLabel = new Label();
    Label done = new Label();
    // Load array base addresses.
    masm.leaq(array1, new AMD64Address(asRegister(array1Value), arrayBaseOffset));
    masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset));
    // Get array length in bytes.
    masm.movl(length, asRegister(lengthValue));
    if (arrayIndexScale > 1) {
        // scale length
        masm.shll(length, NumUtil.log2Ceil(arrayIndexScale));
    }
    // copy
    masm.movl(result, length);
    if (supportsAVX2(crb.target)) {
        emitAVXCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
    } else if (supportsSSE41(crb.target)) {
        // this code is used for AVX as well because our backend correctly ensures that
        // VEX-prefixed instructions are emitted if AVX is supported
        emitSSE41Compare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
    }
    emit8ByteCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
    emitTailCompares(masm, result, array1, array2, length, trueLabel, falseLabel);
    // Return true
    masm.bind(trueLabel);
    masm.movl(result, 1);
    masm.jmpb(done);
    // Return false
    masm.bind(falseLabel);
    masm.xorl(result, result);
    // That's it
    masm.bind(done);
}
Also used : Register(jdk.vm.ci.code.Register) ValueUtil.asRegister(jdk.vm.ci.code.ValueUtil.asRegister) Label(org.graalvm.compiler.asm.Label) AMD64Address(org.graalvm.compiler.asm.amd64.AMD64Address)

Example 7 with Label

use of org.graalvm.compiler.asm.Label in project graal by oracle.

the class AMD64ArrayEqualsOp method emitFloatCompare.

/**
 * Emits code to compare if two floats are bitwise equal or both NaN.
 */
private void emitFloatCompare(AMD64MacroAssembler masm, Register base1, Register base2, Register index, int offset, Label falseLabel, boolean skipBitwiseCompare) {
    AMD64Address address1 = new AMD64Address(base1, index, Scale.Times1, offset);
    AMD64Address address2 = new AMD64Address(base2, index, Scale.Times1, offset);
    Label bitwiseEqual = new Label();
    if (!skipBitwiseCompare) {
        // Bitwise compare
        Register temp = asRegister(temp4);
        if (kind == JavaKind.Float) {
            masm.movl(temp, address1);
            masm.cmpl(temp, address2);
        } else {
            masm.movq(temp, address1);
            masm.cmpq(temp, address2);
        }
        masm.jccb(ConditionFlag.Equal, bitwiseEqual);
    }
    emitNaNCheck(masm, address1, falseLabel);
    emitNaNCheck(masm, address2, falseLabel);
    masm.bind(bitwiseEqual);
}
Also used : Register(jdk.vm.ci.code.Register) ValueUtil.asRegister(jdk.vm.ci.code.ValueUtil.asRegister) Label(org.graalvm.compiler.asm.Label) AMD64Address(org.graalvm.compiler.asm.amd64.AMD64Address)

Example 8 with Label

use of org.graalvm.compiler.asm.Label in project graal by oracle.

the class AMD64ArrayEqualsOp method emitFloatCompareWithinRange.

/**
 * Emits code to compare float equality within a range.
 */
private void emitFloatCompareWithinRange(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register base1, Register base2, Register index, int offset, Label falseLabel, int range) {
    assert kind.isNumericFloat();
    Label loop = new Label();
    Register i = asRegister(temp5);
    masm.movq(i, range);
    masm.negq(i);
    // Align the main loop
    masm.align(crb.target.wordSize * 2);
    masm.bind(loop);
    emitFloatCompare(masm, base1, base2, index, offset, falseLabel, kind.getByteCount() == range);
    masm.addq(index, kind.getByteCount());
    masm.addq(i, kind.getByteCount());
    masm.jccb(ConditionFlag.NotZero, loop);
    // Floats within the range are equal, revert change to the register index
    masm.subq(index, range);
}
Also used : Register(jdk.vm.ci.code.Register) ValueUtil.asRegister(jdk.vm.ci.code.ValueUtil.asRegister) Label(org.graalvm.compiler.asm.Label)

Example 9 with Label

use of org.graalvm.compiler.asm.Label in project graal by oracle.

the class AMD64ArrayEqualsOp method emitSSE41Compare.

/**
 * Emits code that uses SSE4.1 128-bit (16-byte) vector compares.
 */
private void emitSSE41Compare(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) {
    assert supportsSSE41(crb.target);
    Register vector1 = asRegister(vectorTemp1, AMD64Kind.DOUBLE);
    Register vector2 = asRegister(vectorTemp2, AMD64Kind.DOUBLE);
    Label loop = new Label();
    Label compareTail = new Label();
    boolean requiresNaNCheck = kind.isNumericFloat();
    Label loopCheck = new Label();
    Label nanCheck = new Label();
    // Compare 16-byte vectors
    // tail count (in bytes)
    masm.andl(result, SSE4_1_VECTOR_SIZE - 1);
    // vector count (in bytes)
    masm.andl(length, ~(SSE4_1_VECTOR_SIZE - 1));
    masm.jcc(ConditionFlag.Zero, compareTail);
    masm.leaq(array1, new AMD64Address(array1, length, Scale.Times1, 0));
    masm.leaq(array2, new AMD64Address(array2, length, Scale.Times1, 0));
    masm.negq(length);
    // Align the main loop
    masm.align(crb.target.wordSize * 2);
    masm.bind(loop);
    masm.movdqu(vector1, new AMD64Address(array1, length, Scale.Times1, 0));
    masm.movdqu(vector2, new AMD64Address(array2, length, Scale.Times1, 0));
    masm.pxor(vector1, vector2);
    masm.ptest(vector1, vector1);
    masm.jcc(ConditionFlag.NotZero, requiresNaNCheck ? nanCheck : falseLabel);
    masm.bind(loopCheck);
    masm.addq(length, SSE4_1_VECTOR_SIZE);
    masm.jcc(ConditionFlag.NotZero, loop);
    masm.testl(result, result);
    masm.jcc(ConditionFlag.Zero, trueLabel);
    if (requiresNaNCheck) {
        Label unalignedCheck = new Label();
        masm.jmpb(unalignedCheck);
        masm.bind(nanCheck);
        emitFloatCompareWithinRange(crb, masm, array1, array2, length, 0, falseLabel, SSE4_1_VECTOR_SIZE);
        masm.jmpb(loopCheck);
        masm.bind(unalignedCheck);
    }
    /*
         * Compare the remaining bytes with an unaligned memory load aligned to the end of the
         * array.
         */
    masm.movdqu(vector1, new AMD64Address(array1, result, Scale.Times1, -SSE4_1_VECTOR_SIZE));
    masm.movdqu(vector2, new AMD64Address(array2, result, Scale.Times1, -SSE4_1_VECTOR_SIZE));
    masm.pxor(vector1, vector2);
    masm.ptest(vector1, vector1);
    if (requiresNaNCheck) {
        masm.jcc(ConditionFlag.Zero, trueLabel);
        emitFloatCompareWithinRange(crb, masm, array1, array2, result, -SSE4_1_VECTOR_SIZE, falseLabel, SSE4_1_VECTOR_SIZE);
    } else {
        masm.jcc(ConditionFlag.NotZero, falseLabel);
    }
    masm.jmp(trueLabel);
    masm.bind(compareTail);
    masm.movl(length, result);
}
Also used : Register(jdk.vm.ci.code.Register) ValueUtil.asRegister(jdk.vm.ci.code.ValueUtil.asRegister) Label(org.graalvm.compiler.asm.Label) AMD64Address(org.graalvm.compiler.asm.amd64.AMD64Address)

Example 10 with Label

use of org.graalvm.compiler.asm.Label in project graal by oracle.

the class AArch64ArrayEqualsOp method emit8ByteCompare.

/**
 * Emits code that uses 8-byte vector compares.
 */
private void emit8ByteCompare(CompilationResultBuilder crb, AArch64MacroAssembler masm, Register result, Register array1, Register array2, Register length, Label breakLabel, Register rscratch1) {
    Label loop = new Label();
    Label compareTail = new Label();
    Register temp = asRegister(temp4);
    // tail count (in bytes)
    masm.and(64, result, result, VECTOR_SIZE - 1);
    // vector count (in bytes)
    masm.ands(64, length, length, ~(VECTOR_SIZE - 1));
    masm.branchConditionally(ConditionFlag.EQ, compareTail);
    masm.lea(array1, AArch64Address.createRegisterOffsetAddress(array1, length, false));
    masm.lea(array2, AArch64Address.createRegisterOffsetAddress(array2, length, false));
    masm.sub(64, length, zr, length);
    // Align the main loop
    masm.align(crb.target.wordSize * 2);
    masm.bind(loop);
    masm.ldr(64, temp, AArch64Address.createRegisterOffsetAddress(array1, length, false));
    masm.ldr(64, rscratch1, AArch64Address.createRegisterOffsetAddress(array2, length, false));
    masm.eor(64, rscratch1, temp, rscratch1);
    masm.cbnz(64, rscratch1, breakLabel);
    masm.add(64, length, length, VECTOR_SIZE);
    masm.cbnz(64, length, loop);
    masm.cbz(64, result, breakLabel);
    /*
         * Compare the remaining bytes with an unaligned memory load aligned to the end of the
         * array.
         */
    masm.lea(array1, AArch64Address.createUnscaledImmediateAddress(array1, -VECTOR_SIZE));
    masm.lea(array2, AArch64Address.createUnscaledImmediateAddress(array2, -VECTOR_SIZE));
    masm.ldr(64, temp, AArch64Address.createRegisterOffsetAddress(array1, result, false));
    masm.ldr(64, rscratch1, AArch64Address.createRegisterOffsetAddress(array2, result, false));
    masm.eor(64, rscratch1, temp, rscratch1);
    masm.jmp(breakLabel);
    masm.bind(compareTail);
}
Also used : ScratchRegister(org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister) Register(jdk.vm.ci.code.Register) ValueUtil.asRegister(jdk.vm.ci.code.ValueUtil.asRegister) Label(org.graalvm.compiler.asm.Label)

Aggregations

Label (org.graalvm.compiler.asm.Label)34 Register (jdk.vm.ci.code.Register)27 ValueUtil.asRegister (jdk.vm.ci.code.ValueUtil.asRegister)23 AMD64Address (org.graalvm.compiler.asm.amd64.AMD64Address)15 ArrayDataPointerConstant (org.graalvm.compiler.lir.asm.ArrayDataPointerConstant)7 ScratchRegister (org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister)5 SPARCAddress (org.graalvm.compiler.asm.sparc.SPARCAddress)4 RegisterConfig (jdk.vm.ci.code.RegisterConfig)3 CompressEncoding (org.graalvm.compiler.core.common.CompressEncoding)3 FrameMap (org.graalvm.compiler.lir.framemap.FrameMap)3 TruffleCallBoundaryInstrumentation (org.graalvm.compiler.truffle.compiler.hotspot.TruffleCallBoundaryInstrumentation)3 AArch64MacroAssembler (org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler)2 AMD64MacroAssembler (org.graalvm.compiler.asm.amd64.AMD64MacroAssembler)2 SPARCMacroAssembler (org.graalvm.compiler.asm.sparc.SPARCMacroAssembler)2 ScratchRegister (org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister)2 CallingConvention (jdk.vm.ci.code.CallingConvention)1 ValueUtil.isRegister (jdk.vm.ci.code.ValueUtil.isRegister)1 AArch64HotSpotRegisterConfig (jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig)1 AArch64Address (org.graalvm.compiler.asm.aarch64.AArch64Address)1 Scale (org.graalvm.compiler.asm.amd64.AMD64Address.Scale)1