< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java

Print this page




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


< prev index next >