< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java

Print this page


   1 /*
   2  * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */


  63 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VORPS;
  64 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSD;
  65 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSS;
  66 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VXORPD;
  67 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VXORPS;
  68 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.BYTE;
  69 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD;
  70 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PD;
  71 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PS;
  72 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD;
  73 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD;
  74 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS;
  75 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.WORD;
  76 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
  77 import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue;
  78 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
  79 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
  80 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
  81 import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.DREM;
  82 import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.FREM;
  83 import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp.BinaryIntrinsicOpcode.POW;
  84 import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.COS;
  85 import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.EXP;
  86 import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.LOG;
  87 import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.LOG10;
  88 import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.SIN;
  89 import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.TAN;
  90 
  91 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
  92 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
  93 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp;
  94 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MROp;
  95 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMIOp;
  96 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
  97 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift;
  98 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
  99 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRMOp;
 100 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRVMOp;
 101 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
 102 import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
 103 import org.graalvm.compiler.asm.amd64.AVXKind;
 104 import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
 105 import org.graalvm.compiler.core.common.LIRKind;
 106 import org.graalvm.compiler.core.common.NumUtil;
 107 import org.graalvm.compiler.core.common.calc.FloatConvert;
 108 import org.graalvm.compiler.debug.GraalError;
 109 import org.graalvm.compiler.lir.ConstantValue;
 110 import org.graalvm.compiler.lir.LIRFrameState;
 111 import org.graalvm.compiler.lir.LIRValueUtil;
 112 import org.graalvm.compiler.lir.Variable;
 113 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
 114 import org.graalvm.compiler.lir.amd64.AMD64Arithmetic.FPDivRemOp;
 115 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
 116 import org.graalvm.compiler.lir.amd64.AMD64Binary;
 117 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
 118 import org.graalvm.compiler.lir.amd64.AMD64ClearRegisterOp;
 119 import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp;
 120 import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp;





 121 import org.graalvm.compiler.lir.amd64.AMD64Move;
 122 import org.graalvm.compiler.lir.amd64.AMD64MulDivOp;
 123 import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
 124 import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
 125 import org.graalvm.compiler.lir.amd64.AMD64Unary;
 126 import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary;
 127 import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary.AVXBinaryOp;
 128 import org.graalvm.compiler.lir.amd64.vector.AMD64VectorUnary;
 129 import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;
 130 import org.graalvm.compiler.lir.gen.LIRGenerator;
 131 
 132 import jdk.vm.ci.amd64.AMD64;
 133 import jdk.vm.ci.amd64.AMD64.CPUFeature;
 134 import jdk.vm.ci.amd64.AMD64Kind;
 135 import jdk.vm.ci.code.CodeUtil;
 136 import jdk.vm.ci.code.Register;
 137 import jdk.vm.ci.code.RegisterValue;
 138 import jdk.vm.ci.code.TargetDescription;
 139 import jdk.vm.ci.meta.AllocatableValue;
 140 import jdk.vm.ci.meta.Constant;
 141 import jdk.vm.ci.meta.JavaConstant;
 142 import jdk.vm.ci.meta.JavaKind;
 143 import jdk.vm.ci.meta.PlatformKind;
 144 import jdk.vm.ci.meta.VMConstant;
 145 import jdk.vm.ci.meta.Value;
 146 import jdk.vm.ci.meta.ValueKind;
 147 
 148 /**
 149  * This class implements the AMD64 specific portion of the LIR generator.
 150  */
 151 public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implements AMD64ArithmeticLIRGeneratorTool {
 152 
 153     private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD));
 154 
 155     public AMD64ArithmeticLIRGenerator(AllocatableValue nullRegisterValue, Maths maths) {
 156         this.nullRegisterValue = nullRegisterValue;
 157         this.maths = maths == null ? new Maths() {
 158         } : maths;
 159     }
 160 
 161     private final AllocatableValue nullRegisterValue;
 162     private final Maths maths;
 163 
 164     /**
 165      * Interface for emitting LIR for selected {@link Math} routines. A {@code null} return value
 166      * for any method in this interface means the caller must emit the LIR itself.
 167      */
 168     public interface Maths {
 169 
 170         @SuppressWarnings("unused")
 171         default Variable emitLog(LIRGenerator gen, Value input, boolean base10) {
 172             return null;
 173         }
 174 
 175         @SuppressWarnings("unused")
 176         default Variable emitCos(LIRGenerator gen, Value input) {
 177             return null;
 178         }
 179 
 180         @SuppressWarnings("unused")
 181         default Variable emitSin(LIRGenerator gen, Value input) {
 182             return null;
 183         }
 184 
 185         @SuppressWarnings("unused")
 186         default Variable emitTan(LIRGenerator gen, Value input) {
 187             return null;
 188         }
 189     }
 190 
 191     @Override
 192     public Variable emitNegate(Value inputVal) {
 193         AllocatableValue input = asAllocatable(inputVal);
 194         Variable result = getLIRGen().newVariable(LIRKind.combine(input));
 195         boolean isAvx = supportAVX();
 196         switch ((AMD64Kind) input.getPlatformKind()) {
 197             case DWORD:
 198                 getLIRGen().append(new AMD64Unary.MOp(NEG, DWORD, result, input));
 199                 break;
 200             case QWORD:
 201                 getLIRGen().append(new AMD64Unary.MOp(NEG, QWORD, result, input));
 202                 break;
 203             case SINGLE:
 204                 JavaConstant floatMask = JavaConstant.forFloat(Float.intBitsToFloat(0x80000000));
 205                 if (isAvx) {
 206                     getLIRGen().append(new AVXBinaryOp(VXORPS, getRegisterSize(result), result, asAllocatable(input), asAllocatable(getLIRGen().emitJavaConstant(floatMask))));
 207                 } else {
 208                     getLIRGen().append(new AMD64Binary.DataTwoOp(SSEOp.XOR, PS, result, input, floatMask, 16));
 209                 }


 764             case DWORD:
 765                 return emitShift(SHR, DWORD, a, b);
 766             case QWORD:
 767                 return emitShift(SHR, QWORD, a, b);
 768             default:
 769                 throw GraalError.shouldNotReachHere();
 770         }
 771     }
 772 
 773     public Variable emitRol(Value a, Value b) {
 774         switch ((AMD64Kind) a.getPlatformKind()) {
 775             case DWORD:
 776                 return emitShift(ROL, DWORD, a, b);
 777             case QWORD:
 778                 return emitShift(ROL, QWORD, a, b);
 779             default:
 780                 throw GraalError.shouldNotReachHere();
 781         }
 782     }
 783 

 784     public Variable emitRor(Value a, Value b) {
 785         switch ((AMD64Kind) a.getPlatformKind()) {
 786             case DWORD:
 787                 return emitShift(ROR, DWORD, a, b);
 788             case QWORD:
 789                 return emitShift(ROR, QWORD, a, b);
 790             default:
 791                 throw GraalError.shouldNotReachHere();
 792         }
 793     }
 794 
 795     private AllocatableValue emitConvertOp(LIRKind kind, AMD64RMOp op, OperandSize size, Value input) {
 796         Variable result = getLIRGen().newVariable(kind);
 797         getLIRGen().append(new AMD64Unary.RMOp(op, size, result, asAllocatable(input)));
 798         return result;
 799     }
 800 
 801     private AllocatableValue emitConvertOp(LIRKind kind, AMD64MROp op, OperandSize size, Value input) {
 802         Variable result = getLIRGen().newVariable(kind);
 803         getLIRGen().append(new AMD64Unary.MROp(op, size, result, asAllocatable(input)));


1086     }
1087 
1088     @Override
1089     public Value emitMathSqrt(Value input) {
1090         Variable result = getLIRGen().newVariable(LIRKind.combine(input));
1091         switch ((AMD64Kind) input.getPlatformKind()) {
1092             case SINGLE:
1093                 getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SS, result, asAllocatable(input)));
1094                 break;
1095             case DOUBLE:
1096                 getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SD, result, asAllocatable(input)));
1097                 break;
1098             default:
1099                 throw GraalError.shouldNotReachHere();
1100         }
1101         return result;
1102     }
1103 
1104     @Override
1105     public Value emitMathLog(Value input, boolean base10) {
1106         LIRGenerator gen = getLIRGen();
1107         Variable result = maths.emitLog(gen, input, base10);
1108         if (result == null) {
1109             result = gen.newVariable(LIRKind.combine(input));
1110             AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
1111             gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), base10 ? LOG10 : LOG, result, asAllocatable(input), stackSlot));
1112         }
1113         return result;
1114     }
1115 
1116     @Override
1117     public Value emitMathCos(Value input) {
1118         LIRGenerator gen = getLIRGen();
1119         Variable result = maths.emitCos(gen, input);
1120         if (result == null) {
1121             result = gen.newVariable(LIRKind.combine(input));
1122             AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
1123             gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), COS, result, asAllocatable(input), stackSlot));
1124         }
1125         return result;
1126     }
1127 
1128     @Override
1129     public Value emitMathSin(Value input) {
1130         LIRGenerator gen = getLIRGen();
1131         Variable result = maths.emitSin(gen, input);
1132         if (result == null) {
1133             result = gen.newVariable(LIRKind.combine(input));
1134             AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
1135             gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), SIN, result, asAllocatable(input), stackSlot));
1136         }
1137         return result;
1138     }
1139 
1140     @Override
1141     public Value emitMathTan(Value input) {
1142         LIRGenerator gen = getLIRGen();
1143         Variable result = maths.emitTan(gen, input);
1144         if (result == null) {
1145             result = gen.newVariable(LIRKind.combine(input));
1146             AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
1147             gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), TAN, result, asAllocatable(input), stackSlot));
1148         }
1149         return result;
1150     }
1151 
1152     @Override
1153     public Value emitMathExp(Value input) {
1154         Variable result = getLIRGen().newVariable(LIRKind.combine(input));
1155         AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
1156         getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), EXP, result, asAllocatable(input), stackSlot));
1157         return result;
1158     }
1159 
1160     @Override
1161     public Value emitMathPow(Value input1, Value input2) {
1162         Variable result = getLIRGen().newVariable(LIRKind.combine(input1));
1163         getLIRGen().append(new AMD64MathIntrinsicBinaryOp(getAMD64LIRGen(), POW, result, asAllocatable(input1), asAllocatable(input2)));
1164         return result;
1165     }
1166 
1167     protected AMD64LIRGenerator getAMD64LIRGen() {
1168         return (AMD64LIRGenerator) getLIRGen();
1169     }
1170 
1171     @Override
1172     public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
1173         AMD64AddressValue loadAddress = getAMD64LIRGen().asAddressValue(address);
1174         Variable result = getLIRGen().newVariable(getLIRGen().toRegisterKind(kind));
1175         switch ((AMD64Kind) kind.getPlatformKind()) {
1176             case BYTE:
1177                 getLIRGen().append(new AMD64Unary.MemoryOp(MOVSXB, DWORD, result, loadAddress, state));
1178                 break;
1179             case WORD:
1180                 getLIRGen().append(new AMD64Unary.MemoryOp(MOVSX, DWORD, result, loadAddress, state));
1181                 break;
1182             case DWORD:
1183                 getLIRGen().append(new AMD64Unary.MemoryOp(MOV, DWORD, result, loadAddress, state));
1184                 break;


   1 /*
   2  * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */


  63 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VORPS;
  64 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSD;
  65 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSS;
  66 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VXORPD;
  67 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VXORPS;
  68 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.BYTE;
  69 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD;
  70 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PD;
  71 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PS;
  72 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD;
  73 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD;
  74 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS;
  75 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.WORD;
  76 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
  77 import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue;
  78 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
  79 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
  80 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
  81 import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.DREM;
  82 import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.FREM;







  83 
  84 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
  85 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
  86 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp;
  87 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MROp;
  88 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMIOp;
  89 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
  90 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift;
  91 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
  92 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRMOp;
  93 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRVMOp;
  94 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
  95 import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
  96 import org.graalvm.compiler.asm.amd64.AVXKind;
  97 import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
  98 import org.graalvm.compiler.core.common.LIRKind;
  99 import org.graalvm.compiler.core.common.NumUtil;
 100 import org.graalvm.compiler.core.common.calc.FloatConvert;
 101 import org.graalvm.compiler.debug.GraalError;
 102 import org.graalvm.compiler.lir.ConstantValue;
 103 import org.graalvm.compiler.lir.LIRFrameState;
 104 import org.graalvm.compiler.lir.LIRValueUtil;
 105 import org.graalvm.compiler.lir.Variable;
 106 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
 107 import org.graalvm.compiler.lir.amd64.AMD64Arithmetic.FPDivRemOp;
 108 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
 109 import org.graalvm.compiler.lir.amd64.AMD64Binary;
 110 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
 111 import org.graalvm.compiler.lir.amd64.AMD64ClearRegisterOp;
 112 import org.graalvm.compiler.lir.amd64.AMD64MathCosOp;
 113 import org.graalvm.compiler.lir.amd64.AMD64MathExpOp;
 114 import org.graalvm.compiler.lir.amd64.AMD64MathLog10Op;
 115 import org.graalvm.compiler.lir.amd64.AMD64MathLogOp;
 116 import org.graalvm.compiler.lir.amd64.AMD64MathPowOp;
 117 import org.graalvm.compiler.lir.amd64.AMD64MathSinOp;
 118 import org.graalvm.compiler.lir.amd64.AMD64MathTanOp;
 119 import org.graalvm.compiler.lir.amd64.AMD64Move;
 120 import org.graalvm.compiler.lir.amd64.AMD64MulDivOp;
 121 import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
 122 import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
 123 import org.graalvm.compiler.lir.amd64.AMD64Unary;
 124 import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary;
 125 import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary.AVXBinaryOp;
 126 import org.graalvm.compiler.lir.amd64.vector.AMD64VectorUnary;
 127 import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;

 128 
 129 import jdk.vm.ci.amd64.AMD64;
 130 import jdk.vm.ci.amd64.AMD64.CPUFeature;
 131 import jdk.vm.ci.amd64.AMD64Kind;
 132 import jdk.vm.ci.code.CodeUtil;
 133 import jdk.vm.ci.code.Register;
 134 import jdk.vm.ci.code.RegisterValue;
 135 import jdk.vm.ci.code.TargetDescription;
 136 import jdk.vm.ci.meta.AllocatableValue;
 137 import jdk.vm.ci.meta.Constant;
 138 import jdk.vm.ci.meta.JavaConstant;
 139 import jdk.vm.ci.meta.JavaKind;
 140 import jdk.vm.ci.meta.PlatformKind;
 141 import jdk.vm.ci.meta.VMConstant;
 142 import jdk.vm.ci.meta.Value;
 143 import jdk.vm.ci.meta.ValueKind;
 144 
 145 /**
 146  * This class implements the AMD64 specific portion of the LIR generator.
 147  */
 148 public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implements AMD64ArithmeticLIRGeneratorTool {
 149 
 150     private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD));
 151 
 152     public AMD64ArithmeticLIRGenerator(AllocatableValue nullRegisterValue) {
 153         this.nullRegisterValue = nullRegisterValue;


 154     }
 155 
 156     private final AllocatableValue nullRegisterValue;




























 157 
 158     @Override
 159     public Variable emitNegate(Value inputVal) {
 160         AllocatableValue input = asAllocatable(inputVal);
 161         Variable result = getLIRGen().newVariable(LIRKind.combine(input));
 162         boolean isAvx = supportAVX();
 163         switch ((AMD64Kind) input.getPlatformKind()) {
 164             case DWORD:
 165                 getLIRGen().append(new AMD64Unary.MOp(NEG, DWORD, result, input));
 166                 break;
 167             case QWORD:
 168                 getLIRGen().append(new AMD64Unary.MOp(NEG, QWORD, result, input));
 169                 break;
 170             case SINGLE:
 171                 JavaConstant floatMask = JavaConstant.forFloat(Float.intBitsToFloat(0x80000000));
 172                 if (isAvx) {
 173                     getLIRGen().append(new AVXBinaryOp(VXORPS, getRegisterSize(result), result, asAllocatable(input), asAllocatable(getLIRGen().emitJavaConstant(floatMask))));
 174                 } else {
 175                     getLIRGen().append(new AMD64Binary.DataTwoOp(SSEOp.XOR, PS, result, input, floatMask, 16));
 176                 }


 731             case DWORD:
 732                 return emitShift(SHR, DWORD, a, b);
 733             case QWORD:
 734                 return emitShift(SHR, QWORD, a, b);
 735             default:
 736                 throw GraalError.shouldNotReachHere();
 737         }
 738     }
 739 
 740     public Variable emitRol(Value a, Value b) {
 741         switch ((AMD64Kind) a.getPlatformKind()) {
 742             case DWORD:
 743                 return emitShift(ROL, DWORD, a, b);
 744             case QWORD:
 745                 return emitShift(ROL, QWORD, a, b);
 746             default:
 747                 throw GraalError.shouldNotReachHere();
 748         }
 749     }
 750 
 751     @Override
 752     public Variable emitRor(Value a, Value b) {
 753         switch ((AMD64Kind) a.getPlatformKind()) {
 754             case DWORD:
 755                 return emitShift(ROR, DWORD, a, b);
 756             case QWORD:
 757                 return emitShift(ROR, QWORD, a, b);
 758             default:
 759                 throw GraalError.shouldNotReachHere();
 760         }
 761     }
 762 
 763     private AllocatableValue emitConvertOp(LIRKind kind, AMD64RMOp op, OperandSize size, Value input) {
 764         Variable result = getLIRGen().newVariable(kind);
 765         getLIRGen().append(new AMD64Unary.RMOp(op, size, result, asAllocatable(input)));
 766         return result;
 767     }
 768 
 769     private AllocatableValue emitConvertOp(LIRKind kind, AMD64MROp op, OperandSize size, Value input) {
 770         Variable result = getLIRGen().newVariable(kind);
 771         getLIRGen().append(new AMD64Unary.MROp(op, size, result, asAllocatable(input)));


1054     }
1055 
1056     @Override
1057     public Value emitMathSqrt(Value input) {
1058         Variable result = getLIRGen().newVariable(LIRKind.combine(input));
1059         switch ((AMD64Kind) input.getPlatformKind()) {
1060             case SINGLE:
1061                 getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SS, result, asAllocatable(input)));
1062                 break;
1063             case DOUBLE:
1064                 getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SD, result, asAllocatable(input)));
1065                 break;
1066             default:
1067                 throw GraalError.shouldNotReachHere();
1068         }
1069         return result;
1070     }
1071 
1072     @Override
1073     public Value emitMathLog(Value input, boolean base10) {
1074         if (base10) {
1075             return new AMD64MathLog10Op().emitLIRWrapper(getLIRGen(), input);
1076         } else {
1077             return new AMD64MathLogOp().emitLIRWrapper(getLIRGen(), input);


1078         }

1079     }
1080 
1081     @Override
1082     public Value emitMathCos(Value input) {
1083         return new AMD64MathCosOp().emitLIRWrapper(getLIRGen(), input);







1084     }
1085 
1086     @Override
1087     public Value emitMathSin(Value input) {
1088         return new AMD64MathSinOp().emitLIRWrapper(getLIRGen(), input);







1089     }
1090 
1091     @Override
1092     public Value emitMathTan(Value input) {
1093         return new AMD64MathTanOp().emitLIRWrapper(getLIRGen(), input);







1094     }
1095 
1096     @Override
1097     public Value emitMathExp(Value input) {
1098         return new AMD64MathExpOp().emitLIRWrapper(getLIRGen(), input);



1099     }
1100 
1101     @Override
1102     public Value emitMathPow(Value x, Value y) {
1103         return new AMD64MathPowOp().emitLIRWrapper(getLIRGen(), x, y);


1104     }
1105 
1106     protected AMD64LIRGenerator getAMD64LIRGen() {
1107         return (AMD64LIRGenerator) getLIRGen();
1108     }
1109 
1110     @Override
1111     public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
1112         AMD64AddressValue loadAddress = getAMD64LIRGen().asAddressValue(address);
1113         Variable result = getLIRGen().newVariable(getLIRGen().toRegisterKind(kind));
1114         switch ((AMD64Kind) kind.getPlatformKind()) {
1115             case BYTE:
1116                 getLIRGen().append(new AMD64Unary.MemoryOp(MOVSXB, DWORD, result, loadAddress, state));
1117                 break;
1118             case WORD:
1119                 getLIRGen().append(new AMD64Unary.MemoryOp(MOVSX, DWORD, result, loadAddress, state));
1120                 break;
1121             case DWORD:
1122                 getLIRGen().append(new AMD64Unary.MemoryOp(MOV, DWORD, result, loadAddress, state));
1123                 break;


< prev index next >