src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorUnary.java
changeset 51436 091c0d22e735
parent 50858 2d3e99a72541
child 59095 03fbcd06b4c0
equal deleted inserted replaced
51435:72c82bd05971 51436:091c0d22e735
    22  */
    22  */
    23 
    23 
    24 
    24 
    25 package org.graalvm.compiler.lir.amd64.vector;
    25 package org.graalvm.compiler.lir.amd64.vector;
    26 
    26 
    27 import jdk.vm.ci.meta.AllocatableValue;
       
    28 import jdk.vm.ci.meta.Value;
       
    29 import org.graalvm.compiler.asm.amd64.AMD64Address;
       
    30 import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler;
       
    31 import org.graalvm.compiler.asm.amd64.AVXKind;
       
    32 import org.graalvm.compiler.lir.LIRFrameState;
       
    33 import org.graalvm.compiler.lir.LIRInstructionClass;
       
    34 import org.graalvm.compiler.lir.Opcode;
       
    35 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
       
    36 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
       
    37 
       
    38 import static jdk.vm.ci.code.ValueUtil.asRegister;
    27 import static jdk.vm.ci.code.ValueUtil.asRegister;
    39 import static jdk.vm.ci.code.ValueUtil.isRegister;
    28 import static jdk.vm.ci.code.ValueUtil.isRegister;
    40 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
    29 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
    41 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
    30 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
    42 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
    31 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
    43 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
    32 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
    44 import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
    33 import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
    45 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
    34 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
    46 
    35 
       
    36 import org.graalvm.compiler.asm.amd64.AMD64Address;
       
    37 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp;
       
    38 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
       
    39 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
       
    40 import org.graalvm.compiler.asm.amd64.AVXKind;
       
    41 import org.graalvm.compiler.lir.LIRFrameState;
       
    42 import org.graalvm.compiler.lir.LIRInstructionClass;
       
    43 import org.graalvm.compiler.lir.Opcode;
       
    44 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
       
    45 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
       
    46 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
       
    47 
       
    48 import jdk.vm.ci.meta.AllocatableValue;
       
    49 import jdk.vm.ci.meta.Value;
       
    50 
    47 public class AMD64VectorUnary {
    51 public class AMD64VectorUnary {
    48 
    52 
    49     public static final class AVXUnaryOp extends AMD64VectorLIRInstruction {
    53     public static final class AVXUnaryOp extends AMD64LIRInstruction {
    50         public static final LIRInstructionClass<AVXUnaryOp> TYPE = LIRInstructionClass.create(AVXUnaryOp.class);
    54         public static final LIRInstructionClass<AVXUnaryOp> TYPE = LIRInstructionClass.create(AVXUnaryOp.class);
    51 
    55 
    52         @Opcode private final AMD64VectorAssembler.VexRMOp opcode;
    56         @Opcode private final VexRMOp opcode;
    53         private final AVXKind.AVXSize size;
    57         private final AVXKind.AVXSize size;
    54 
    58 
    55         @Def({REG}) protected AllocatableValue result;
    59         @Def({REG}) protected AllocatableValue result;
    56         @Use({REG, STACK}) protected AllocatableValue input;
    60         @Use({REG, STACK}) protected AllocatableValue input;
    57 
    61 
    58         public AVXUnaryOp(AMD64VectorAssembler.VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue input) {
    62         public AVXUnaryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue input) {
    59             super(TYPE);
    63             super(TYPE);
    60             this.opcode = opcode;
    64             this.opcode = opcode;
    61             this.size = size;
    65             this.size = size;
    62             this.result = result;
    66             this.result = result;
    63             this.input = input;
    67             this.input = input;
    64         }
    68         }
    65 
    69 
    66         @Override
    70         @Override
    67         public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) {
    71         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
    68             if (isRegister(input)) {
    72             if (isRegister(input)) {
    69                 opcode.emit(vasm, size, asRegister(result), asRegister(input));
    73                 opcode.emit(masm, size, asRegister(result), asRegister(input));
    70             } else {
    74             } else {
    71                 opcode.emit(vasm, size, asRegister(result), (AMD64Address) crb.asAddress(input));
    75                 opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input));
    72             }
    76             }
    73         }
    77         }
    74     }
    78     }
    75 
    79 
    76     public static final class AVXUnaryMemoryOp extends AMD64VectorLIRInstruction {
    80     public static final class AVXUnaryMemoryOp extends AMD64LIRInstruction {
    77         public static final LIRInstructionClass<AVXUnaryMemoryOp> TYPE = LIRInstructionClass.create(AVXUnaryMemoryOp.class);
    81         public static final LIRInstructionClass<AVXUnaryMemoryOp> TYPE = LIRInstructionClass.create(AVXUnaryMemoryOp.class);
    78 
    82 
    79         @Opcode private final AMD64VectorAssembler.VexRMOp opcode;
    83         @Opcode private final VexRMOp opcode;
    80         private final AVXKind.AVXSize size;
    84         private final AVXKind.AVXSize size;
    81 
    85 
    82         @Def({REG}) protected AllocatableValue result;
    86         @Def({REG}) protected AllocatableValue result;
    83         @Use({COMPOSITE}) protected AMD64AddressValue input;
    87         @Use({COMPOSITE}) protected AMD64AddressValue input;
    84         @State protected LIRFrameState state;
    88         @State protected LIRFrameState state;
    85 
    89 
    86         public AVXUnaryMemoryOp(AMD64VectorAssembler.VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
    90         public AVXUnaryMemoryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
    87             super(TYPE);
    91             super(TYPE);
    88             this.opcode = opcode;
    92             this.opcode = opcode;
    89             this.size = size;
    93             this.size = size;
    90             this.result = result;
    94             this.result = result;
    91             this.input = input;
    95             this.input = input;
    92             this.state = state;
    96             this.state = state;
    93         }
    97         }
    94 
    98 
    95         @Override
    99         @Override
    96         public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) {
   100         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
    97             if (state != null) {
   101             if (state != null) {
    98                 crb.recordImplicitException(vasm.position(), state);
   102                 crb.recordImplicitException(masm.position(), state);
    99             }
   103             }
   100             opcode.emit(vasm, size, asRegister(result), input.toAddress());
   104             opcode.emit(masm, size, asRegister(result), input.toAddress());
   101         }
   105         }
   102     }
   106     }
   103 
   107 
   104     public static final class AVXBroadcastOp extends AMD64VectorLIRInstruction {
   108     public static final class AVXBroadcastOp extends AMD64LIRInstruction {
   105         public static final LIRInstructionClass<AVXBroadcastOp> TYPE = LIRInstructionClass.create(AVXBroadcastOp.class);
   109         public static final LIRInstructionClass<AVXBroadcastOp> TYPE = LIRInstructionClass.create(AVXBroadcastOp.class);
   106 
   110 
   107         @Opcode private final AMD64VectorAssembler.VexRMOp opcode;
   111         @Opcode private final VexRMOp opcode;
   108         private final AVXKind.AVXSize size;
   112         private final AVXKind.AVXSize size;
   109 
   113 
   110         @Def({REG}) protected AllocatableValue result;
   114         @Def({REG}) protected AllocatableValue result;
   111         @Use({REG, STACK, CONST}) protected Value input;
   115         @Use({REG, STACK, CONST}) protected Value input;
   112 
   116 
   113         public AVXBroadcastOp(AMD64VectorAssembler.VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, Value input) {
   117         public AVXBroadcastOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, Value input) {
   114             super(TYPE);
   118             super(TYPE);
   115             this.opcode = opcode;
   119             this.opcode = opcode;
   116             this.size = size;
   120             this.size = size;
   117             this.result = result;
   121             this.result = result;
   118             this.input = input;
   122             this.input = input;
   119         }
   123         }
   120 
   124 
   121         @Override
   125         @Override
   122         public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) {
   126         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
   123             if (isRegister(input)) {
   127             if (isRegister(input)) {
   124                 opcode.emit(vasm, size, asRegister(result), asRegister(input));
   128                 opcode.emit(masm, size, asRegister(result), asRegister(input));
   125             } else if (isConstantValue(input)) {
   129             } else if (isConstantValue(input)) {
   126                 int align = input.getPlatformKind().getSizeInBytes();
   130                 int align = input.getPlatformKind().getSizeInBytes();
   127                 AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(asConstant(input), align);
   131                 AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(asConstant(input), align);
   128                 opcode.emit(vasm, size, asRegister(result), address);
   132                 opcode.emit(masm, size, asRegister(result), address);
   129             } else {
   133             } else {
   130                 opcode.emit(vasm, size, asRegister(result), (AMD64Address) crb.asAddress(input));
   134                 opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input));
   131             }
   135             }
   132         }
   136         }
   133     }
   137     }
   134 
   138 
   135     public static final class AVXConvertMemoryOp extends AMD64VectorLIRInstruction {
   139     public static final class AVXConvertMemoryOp extends AMD64LIRInstruction {
   136         public static final LIRInstructionClass<AVXConvertMemoryOp> TYPE = LIRInstructionClass.create(AVXConvertMemoryOp.class);
   140         public static final LIRInstructionClass<AVXConvertMemoryOp> TYPE = LIRInstructionClass.create(AVXConvertMemoryOp.class);
   137 
   141 
   138         @Opcode private final AMD64VectorAssembler.VexRVMOp opcode;
   142         @Opcode private final VexRVMOp opcode;
   139         private final AVXKind.AVXSize size;
   143         private final AVXKind.AVXSize size;
   140 
   144 
   141         @Def({REG}) protected AllocatableValue result;
   145         @Def({REG}) protected AllocatableValue result;
   142         @Use({COMPOSITE}) protected AMD64AddressValue input;
   146         @Use({COMPOSITE}) protected AMD64AddressValue input;
   143         @State protected LIRFrameState state;
   147         @State protected LIRFrameState state;
   144 
   148 
   145         public AVXConvertMemoryOp(AMD64VectorAssembler.VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
   149         public AVXConvertMemoryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
   146             super(TYPE);
   150             super(TYPE);
   147             this.opcode = opcode;
   151             this.opcode = opcode;
   148             this.size = size;
   152             this.size = size;
   149             this.result = result;
   153             this.result = result;
   150             this.input = input;
   154             this.input = input;
   151             this.state = state;
   155             this.state = state;
   152         }
   156         }
   153 
   157 
   154         @Override
   158         @Override
   155         public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) {
   159         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
   156             if (state != null) {
   160             if (state != null) {
   157                 crb.recordImplicitException(vasm.position(), state);
   161                 crb.recordImplicitException(masm.position(), state);
   158             }
   162             }
   159             opcode.emit(vasm, size, asRegister(result), asRegister(result), input.toAddress());
   163             opcode.emit(masm, size, asRegister(result), asRegister(result), input.toAddress());
   160         }
   164         }
   161     }
   165     }
   162 
   166 
   163     public static final class AVXConvertOp extends AMD64VectorLIRInstruction {
   167     public static final class AVXConvertOp extends AMD64LIRInstruction {
   164         public static final LIRInstructionClass<AVXConvertOp> TYPE = LIRInstructionClass.create(AVXConvertOp.class);
   168         public static final LIRInstructionClass<AVXConvertOp> TYPE = LIRInstructionClass.create(AVXConvertOp.class);
   165 
   169 
   166         @Opcode private final AMD64VectorAssembler.VexRVMOp opcode;
   170         @Opcode private final VexRVMOp opcode;
   167         @Def({REG}) protected AllocatableValue result;
   171         @Def({REG}) protected AllocatableValue result;
   168         @Use({REG, STACK}) protected AllocatableValue input;
   172         @Use({REG, STACK}) protected AllocatableValue input;
   169 
   173 
   170         public AVXConvertOp(AMD64VectorAssembler.VexRVMOp opcode, AllocatableValue result, AllocatableValue input) {
   174         public AVXConvertOp(VexRVMOp opcode, AllocatableValue result, AllocatableValue input) {
   171             super(TYPE);
   175             super(TYPE);
   172             this.opcode = opcode;
   176             this.opcode = opcode;
   173             this.result = result;
   177             this.result = result;
   174             this.input = input;
   178             this.input = input;
   175         }
   179         }
   176 
   180 
   177         @Override
   181         @Override
   178         public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) {
   182         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
   179             if (isRegister(input)) {
   183             if (isRegister(input)) {
   180                 if (!asRegister(input).equals(asRegister(result))) {
   184                 if (!asRegister(input).equals(asRegister(result))) {
   181                     // clear result register to avoid unnecessary dependency
   185                     // clear result register to avoid unnecessary dependency
   182                     AMD64VectorAssembler.VexRVMOp.VXORPD.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result));
   186                     VexRVMOp.VXORPD.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result));
   183                 }
   187                 }
   184                 opcode.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(input));
   188                 opcode.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(input));
   185             } else {
   189             } else {
   186                 AMD64VectorAssembler.VexRVMOp.VXORPD.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result));
   190                 VexRVMOp.VXORPD.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result));
   187                 opcode.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), (AMD64Address) crb.asAddress(input));
   191                 opcode.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), (AMD64Address) crb.asAddress(input));
   188             }
   192             }
   189         }
   193         }
   190     }
   194     }
   191 }
   195 }