20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.lir.amd64;
24
25 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
26 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
27 import static jdk.vm.ci.code.ValueUtil.asRegister;
28
29 import java.lang.reflect.Array;
30 import java.lang.reflect.Field;
31
32 import org.graalvm.compiler.asm.Label;
33 import org.graalvm.compiler.asm.amd64.AMD64Address;
34 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
35 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
36 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
37 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
38 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
39 import org.graalvm.compiler.core.common.LIRKind;
40 import org.graalvm.compiler.lir.LIRInstructionClass;
41 import org.graalvm.compiler.lir.Opcode;
42 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
43 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
44
45 import jdk.vm.ci.amd64.AMD64;
46 import jdk.vm.ci.amd64.AMD64.CPUFeature;
47 import jdk.vm.ci.amd64.AMD64Kind;
48 import jdk.vm.ci.code.Register;
49 import jdk.vm.ci.code.TargetDescription;
50 import jdk.vm.ci.meta.JavaKind;
51 import jdk.vm.ci.meta.Value;
52 import sun.misc.Unsafe;
53
54 /**
55 * Emits code which compares two arrays of the same length. If the CPU supports any vector
56 * instructions specialized code is emitted to leverage these instructions.
57 */
58 @Opcode("ARRAY_EQUALS")
59 public final class AMD64ArrayEqualsOp extends AMD64LIRInstruction {
115 this.vectorTemp2 = Value.ILLEGAL;
116 }
117 }
118
119 @Override
120 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
121 Register result = asRegister(resultValue);
122 Register array1 = asRegister(temp1);
123 Register array2 = asRegister(temp2);
124 Register length = asRegister(temp3);
125
126 Label trueLabel = new Label();
127 Label falseLabel = new Label();
128 Label done = new Label();
129
130 // Load array base addresses.
131 masm.leaq(array1, new AMD64Address(asRegister(array1Value), arrayBaseOffset));
132 masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset));
133
134 // Get array length in bytes.
135 masm.imull(length, asRegister(lengthValue), arrayIndexScale);
136 masm.movl(result, length); // copy
137
138 if (supportsAVX2(crb.target)) {
139 emitAVXCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
140 } else if (supportsSSE41(crb.target)) {
141 emitSSE41Compare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
142 }
143
144 emit8ByteCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
145 emitTailCompares(masm, result, array1, array2, length, trueLabel, falseLabel);
146
147 // Return true
148 masm.bind(trueLabel);
149 masm.movl(result, 1);
150 masm.jmpb(done);
151
152 // Return false
153 masm.bind(falseLabel);
154 masm.xorl(result, result);
155
156 // That's it
157 masm.bind(done);
158 }
159
160 /**
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.lir.amd64;
24
25 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
26 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
27 import static jdk.vm.ci.code.ValueUtil.asRegister;
28
29 import java.lang.reflect.Array;
30 import java.lang.reflect.Field;
31
32 import org.graalvm.compiler.asm.Label;
33 import org.graalvm.compiler.asm.amd64.AMD64Address;
34 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
35 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
36 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
37 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
38 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
39 import org.graalvm.compiler.core.common.LIRKind;
40 import org.graalvm.compiler.core.common.NumUtil;
41 import org.graalvm.compiler.lir.LIRInstructionClass;
42 import org.graalvm.compiler.lir.Opcode;
43 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
44 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
45
46 import jdk.vm.ci.amd64.AMD64;
47 import jdk.vm.ci.amd64.AMD64.CPUFeature;
48 import jdk.vm.ci.amd64.AMD64Kind;
49 import jdk.vm.ci.code.Register;
50 import jdk.vm.ci.code.TargetDescription;
51 import jdk.vm.ci.meta.JavaKind;
52 import jdk.vm.ci.meta.Value;
53 import sun.misc.Unsafe;
54
55 /**
56 * Emits code which compares two arrays of the same length. If the CPU supports any vector
57 * instructions specialized code is emitted to leverage these instructions.
58 */
59 @Opcode("ARRAY_EQUALS")
60 public final class AMD64ArrayEqualsOp extends AMD64LIRInstruction {
116 this.vectorTemp2 = Value.ILLEGAL;
117 }
118 }
119
120 @Override
121 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
122 Register result = asRegister(resultValue);
123 Register array1 = asRegister(temp1);
124 Register array2 = asRegister(temp2);
125 Register length = asRegister(temp3);
126
127 Label trueLabel = new Label();
128 Label falseLabel = new Label();
129 Label done = new Label();
130
131 // Load array base addresses.
132 masm.leaq(array1, new AMD64Address(asRegister(array1Value), arrayBaseOffset));
133 masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset));
134
135 // Get array length in bytes.
136 masm.movl(length, asRegister(lengthValue));
137
138 if (arrayIndexScale > 1) {
139 masm.shll(length, NumUtil.log2Ceil(arrayIndexScale)); // scale length
140 }
141
142 masm.movl(result, length); // copy
143
144 if (supportsAVX2(crb.target)) {
145 emitAVXCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
146 } else if (supportsSSE41(crb.target)) {
147 // this code is used for AVX as well because our backend correctly ensures that
148 // VEX-prefixed instructions are emitted if AVX is supported
149 emitSSE41Compare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
150 }
151
152 emit8ByteCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
153 emitTailCompares(masm, result, array1, array2, length, trueLabel, falseLabel);
154
155 // Return true
156 masm.bind(trueLabel);
157 masm.movl(result, 1);
158 masm.jmpb(done);
159
160 // Return false
161 masm.bind(falseLabel);
162 masm.xorl(result, result);
163
164 // That's it
165 masm.bind(done);
166 }
167
168 /**
|