Mercurial > hg > graal-compiler
changeset 22788:26bbed810326
Split ArithmeticLIRGenerator and LIRGenerator code to allow independent subclasses
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64ArithmeticLIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -0,0 +1,896 @@ +/* + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.amd64; + +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NEG; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NOT; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSF; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSR; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.LZCNT; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOV; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZX; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZXB; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.POPCNT; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TZCNT; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROL; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROR; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SAR; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHL; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHR; +import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD; +import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PD; +import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PS; +import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD; +import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD; +import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS; +import static com.oracle.graal.lir.LIRValueUtil.asConstantValue; +import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant; +import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant; +import static com.oracle.graal.lir.amd64.AMD64Arithmetic.DREM; +import static com.oracle.graal.lir.amd64.AMD64Arithmetic.FREM; +import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.COS; +import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG; +import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG10; +import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.SIN; +import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.TAN; +import jdk.internal.jvmci.amd64.AMD64; +import jdk.internal.jvmci.amd64.AMD64Kind; +import jdk.internal.jvmci.code.CodeUtil; +import jdk.internal.jvmci.code.Register; +import jdk.internal.jvmci.code.RegisterValue; +import jdk.internal.jvmci.common.JVMCIError; +import jdk.internal.jvmci.meta.AllocatableValue; +import jdk.internal.jvmci.meta.JavaConstant; +import jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.meta.PlatformKind; +import jdk.internal.jvmci.meta.Value; + +import com.oracle.graal.asm.NumUtil; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift; +import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize; +import com.oracle.graal.asm.amd64.AMD64Assembler.SSEOp; +import com.oracle.graal.compiler.common.calc.FloatConvert; +import com.oracle.graal.lir.ConstantValue; +import com.oracle.graal.lir.LIRFrameState; +import com.oracle.graal.lir.Variable; +import com.oracle.graal.lir.amd64.AMD64AddressValue; +import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp; +import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGeneratorTool; +import com.oracle.graal.lir.amd64.AMD64Binary; +import com.oracle.graal.lir.amd64.AMD64ClearRegisterOp; +import com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp; +import com.oracle.graal.lir.amd64.AMD64MulDivOp; +import com.oracle.graal.lir.amd64.AMD64ShiftOp; +import com.oracle.graal.lir.amd64.AMD64SignExtendOp; +import com.oracle.graal.lir.amd64.AMD64Unary; +import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; + +/** + * This class implements the AMD64 specific portion of the LIR generator. + */ +public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implements AMD64ArithmeticLIRGeneratorTool { + + private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD)); + + @Override + public Variable emitNegate(Value inputVal) { + AllocatableValue input = getLIRGen().asAllocatable(inputVal); + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + switch ((AMD64Kind) input.getPlatformKind()) { + case DWORD: + getLIRGen().append(new AMD64Unary.MOp(NEG, DWORD, result, input)); + break; + case QWORD: + getLIRGen().append(new AMD64Unary.MOp(NEG, QWORD, result, input)); + break; + case SINGLE: + getLIRGen().append(new AMD64Binary.DataOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16)); + break; + case DOUBLE: + getLIRGen().append(new AMD64Binary.DataOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16)); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return result; + } + + @Override + public Variable emitNot(Value inputVal) { + AllocatableValue input = getLIRGen().asAllocatable(inputVal); + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + switch ((AMD64Kind) input.getPlatformKind()) { + case DWORD: + getLIRGen().append(new AMD64Unary.MOp(NOT, DWORD, result, input)); + break; + case QWORD: + getLIRGen().append(new AMD64Unary.MOp(NOT, QWORD, result, input)); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return result; + } + + private Variable emitBinary(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, Value a, Value b, boolean setFlags) { + if (isJavaConstant(b)) { + return emitBinaryConst(resultKind, op, size, commutative, getLIRGen().asAllocatable(a), asConstantValue(b), setFlags); + } else if (commutative && isJavaConstant(a)) { + return emitBinaryConst(resultKind, op, size, commutative, getLIRGen().asAllocatable(b), asConstantValue(a), setFlags); + } else { + return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, getLIRGen().asAllocatable(a), getLIRGen().asAllocatable(b)); + } + } + + private Variable emitBinary(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, Value a, Value b) { + if (isJavaConstant(b)) { + return emitBinaryConst(resultKind, op, size, getLIRGen().asAllocatable(a), asJavaConstant(b)); + } else if (commutative && isJavaConstant(a)) { + return emitBinaryConst(resultKind, op, size, getLIRGen().asAllocatable(b), asJavaConstant(a)); + } else { + return emitBinaryVar(resultKind, op, size, commutative, getLIRGen().asAllocatable(a), getLIRGen().asAllocatable(b)); + } + } + + private Variable emitBinaryConst(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, ConstantValue b, boolean setFlags) { + long value = b.getJavaConstant().asLong(); + if (NumUtil.isInt(value)) { + Variable result = getLIRGen().newVariable(resultKind); + int constant = (int) value; + + if (!setFlags) { + AMD64MOp mop = getMOp(op, constant); + if (mop != null) { + getLIRGen().append(new AMD64Unary.MOp(mop, size, result, a)); + return result; + } + } + + getLIRGen().append(new AMD64Binary.ConstOp(op, size, result, a, constant)); + return result; + } else { + return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, a, getLIRGen().asAllocatable(b)); + } + } + + private static AMD64MOp getMOp(AMD64BinaryArithmetic op, int constant) { + if (constant == 1) { + if (op.equals(AMD64BinaryArithmetic.ADD)) { + return AMD64MOp.INC; + } + if (op.equals(AMD64BinaryArithmetic.SUB)) { + return AMD64MOp.DEC; + } + } else if (constant == -1) { + if (op.equals(AMD64BinaryArithmetic.ADD)) { + return AMD64MOp.DEC; + } + if (op.equals(AMD64BinaryArithmetic.SUB)) { + return AMD64MOp.INC; + } + } + return null; + } + + private Variable emitBinaryConst(LIRKind resultKind, AMD64RMOp op, OperandSize size, AllocatableValue a, JavaConstant b) { + Variable result = getLIRGen().newVariable(resultKind); + getLIRGen().append(new AMD64Binary.DataOp(op, size, result, a, b)); + return result; + } + + private Variable emitBinaryVar(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, AllocatableValue a, AllocatableValue b) { + Variable result = getLIRGen().newVariable(resultKind); + if (commutative) { + getLIRGen().append(new AMD64Binary.CommutativeOp(op, size, result, a, b)); + } else { + getLIRGen().append(new AMD64Binary.Op(op, size, result, a, b)); + } + return result; + } + + @Override + protected boolean isNumericInteger(PlatformKind kind) { + return ((AMD64Kind) kind).isInteger(); + } + + @Override + public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitBinary(resultKind, ADD, DWORD, true, a, b, setFlags); + case QWORD: + return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags); + case SINGLE: + return emitBinary(resultKind, SSEOp.ADD, SS, true, a, b); + case DOUBLE: + return emitBinary(resultKind, SSEOp.ADD, SD, true, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitBinary(resultKind, SUB, DWORD, false, a, b, setFlags); + case QWORD: + return emitBinary(resultKind, SUB, QWORD, false, a, b, setFlags); + case SINGLE: + return emitBinary(resultKind, SSEOp.SUB, SS, false, a, b); + case DOUBLE: + return emitBinary(resultKind, SSEOp.SUB, SD, false, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + private Variable emitIMULConst(OperandSize size, AllocatableValue a, ConstantValue b) { + long value = b.getJavaConstant().asLong(); + if (NumUtil.isInt(value)) { + int imm = (int) value; + AMD64RMIOp op; + if (NumUtil.isByte(imm)) { + op = AMD64RMIOp.IMUL_SX; + } else { + op = AMD64RMIOp.IMUL; + } + + Variable ret = getLIRGen().newVariable(LIRKind.combine(a, b)); + getLIRGen().append(new AMD64Binary.RMIOp(op, size, ret, a, imm)); + return ret; + } else { + return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, a, getLIRGen().asAllocatable(b)); + } + } + + private Variable emitIMUL(OperandSize size, Value a, Value b) { + if (isJavaConstant(b)) { + return emitIMULConst(size, getLIRGen().asAllocatable(a), asConstantValue(b)); + } else if (isJavaConstant(a)) { + return emitIMULConst(size, getLIRGen().asAllocatable(b), asConstantValue(a)); + } else { + return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, getLIRGen().asAllocatable(a), getLIRGen().asAllocatable(b)); + } + } + + @Override + public Variable emitMul(Value a, Value b, boolean setFlags) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitIMUL(DWORD, a, b); + case QWORD: + return emitIMUL(QWORD, a, b); + case SINGLE: + return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SS, true, a, b); + case DOUBLE: + return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SD, true, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + private RegisterValue moveToReg(Register reg, Value v) { + RegisterValue ret = reg.asValue(v.getLIRKind()); + getLIRGen().emitMove(ret, v); + return ret; + } + + private Value emitMulHigh(AMD64MOp opcode, OperandSize size, Value a, Value b) { + AMD64MulDivOp mulHigh = getLIRGen().append(new AMD64MulDivOp(opcode, size, LIRKind.combine(a, b), moveToReg(AMD64.rax, a), getLIRGen().asAllocatable(b))); + return getLIRGen().emitMove(mulHigh.getHighResult()); + } + + @Override + public Value emitMulHigh(Value a, Value b) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitMulHigh(AMD64MOp.IMUL, DWORD, a, b); + case QWORD: + return emitMulHigh(AMD64MOp.IMUL, QWORD, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Value emitUMulHigh(Value a, Value b) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitMulHigh(AMD64MOp.MUL, DWORD, a, b); + case QWORD: + return emitMulHigh(AMD64MOp.MUL, QWORD, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + public Value emitBinaryMemory(AMD64RMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { + Variable result = getLIRGen().newVariable(LIRKind.combine(a)); + getLIRGen().append(new AMD64Binary.MemoryOp(op, size, result, a, location, state)); + return result; + } + + protected Value emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, AMD64AddressValue address, LIRFrameState state) { + Variable result = getLIRGen().newVariable(LIRKind.value(kind)); + getLIRGen().append(new AMD64Unary.MemoryOp(op, size, result, address, state)); + return result; + } + + protected Value emitZeroExtendMemory(AMD64Kind memoryKind, int resultBits, AMD64AddressValue address, LIRFrameState state) { + // Issue a zero extending load of the proper bit size and set the result to + // the proper kind. + Variable result = getLIRGen().newVariable(LIRKind.value(resultBits == 32 ? AMD64Kind.DWORD : AMD64Kind.QWORD)); + switch (memoryKind) { + case BYTE: + getLIRGen().append(new AMD64Unary.MemoryOp(MOVZXB, DWORD, result, address, state)); + break; + case WORD: + getLIRGen().append(new AMD64Unary.MemoryOp(MOVZX, DWORD, result, address, state)); + break; + case DWORD: + getLIRGen().append(new AMD64Unary.MemoryOp(MOV, DWORD, result, address, state)); + break; + case QWORD: + getLIRGen().append(new AMD64Unary.MemoryOp(MOV, QWORD, result, address, state)); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return result; + } + + private AMD64MulDivOp emitIDIV(OperandSize size, Value a, Value b, LIRFrameState state) { + LIRKind kind = LIRKind.combine(a, b); + + AMD64SignExtendOp sx = getLIRGen().append(new AMD64SignExtendOp(size, kind, moveToReg(AMD64.rax, a))); + return getLIRGen().append(new AMD64MulDivOp(AMD64MOp.IDIV, size, kind, sx.getHighResult(), sx.getLowResult(), getLIRGen().asAllocatable(b), state)); + } + + private AMD64MulDivOp emitDIV(OperandSize size, Value a, Value b, LIRFrameState state) { + LIRKind kind = LIRKind.combine(a, b); + + RegisterValue rax = moveToReg(AMD64.rax, a); + RegisterValue rdx = AMD64.rdx.asValue(kind); + getLIRGen().append(new AMD64ClearRegisterOp(size, rdx)); + return getLIRGen().append(new AMD64MulDivOp(AMD64MOp.DIV, size, kind, rdx, rax, getLIRGen().asAllocatable(b), state)); + } + + public Value[] emitIntegerDivRem(Value a, Value b, LIRFrameState state) { + AMD64MulDivOp op; + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + op = emitIDIV(DWORD, a, b, state); + break; + case QWORD: + op = emitIDIV(QWORD, a, b, state); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return new Value[]{getLIRGen().emitMove(op.getQuotient()), getLIRGen().emitMove(op.getRemainder())}; + } + + @Override + public Value emitDiv(Value a, Value b, LIRFrameState state) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + AMD64MulDivOp op = emitIDIV(DWORD, a, b, state); + return getLIRGen().emitMove(op.getQuotient()); + case QWORD: + AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state); + return getLIRGen().emitMove(lop.getQuotient()); + case SINGLE: + return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SS, false, a, b); + case DOUBLE: + return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SD, false, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Value emitRem(Value a, Value b, LIRFrameState state) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + AMD64MulDivOp op = emitIDIV(DWORD, a, b, state); + return getLIRGen().emitMove(op.getRemainder()); + case QWORD: + AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state); + return getLIRGen().emitMove(lop.getRemainder()); + case SINGLE: { + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b)); + getLIRGen().append(new FPDivRemOp(FREM, result, getLIRGen().load(a), getLIRGen().load(b))); + return result; + } + case DOUBLE: { + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b)); + getLIRGen().append(new FPDivRemOp(DREM, result, getLIRGen().load(a), getLIRGen().load(b))); + return result; + } + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Variable emitUDiv(Value a, Value b, LIRFrameState state) { + AMD64MulDivOp op; + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + op = emitDIV(DWORD, a, b, state); + break; + case QWORD: + op = emitDIV(QWORD, a, b, state); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return getLIRGen().emitMove(op.getQuotient()); + } + + @Override + public Variable emitURem(Value a, Value b, LIRFrameState state) { + AMD64MulDivOp op; + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + op = emitDIV(DWORD, a, b, state); + break; + case QWORD: + op = emitDIV(QWORD, a, b, state); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return getLIRGen().emitMove(op.getRemainder()); + } + + @Override + public Variable emitAnd(Value a, Value b) { + LIRKind resultKind = LIRKind.combine(a, b); + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitBinary(resultKind, AND, DWORD, true, a, b, false); + case QWORD: + return emitBinary(resultKind, AND, QWORD, true, a, b, false); + case SINGLE: + return emitBinary(resultKind, SSEOp.AND, PS, true, a, b); + case DOUBLE: + return emitBinary(resultKind, SSEOp.AND, PD, true, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Variable emitOr(Value a, Value b) { + LIRKind resultKind = LIRKind.combine(a, b); + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitBinary(resultKind, OR, DWORD, true, a, b, false); + case QWORD: + return emitBinary(resultKind, OR, QWORD, true, a, b, false); + case SINGLE: + return emitBinary(resultKind, SSEOp.OR, PS, true, a, b); + case DOUBLE: + return emitBinary(resultKind, SSEOp.OR, PD, true, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Variable emitXor(Value a, Value b) { + LIRKind resultKind = LIRKind.combine(a, b); + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitBinary(resultKind, XOR, DWORD, true, a, b, false); + case QWORD: + return emitBinary(resultKind, XOR, QWORD, true, a, b, false); + case SINGLE: + return emitBinary(resultKind, SSEOp.XOR, PS, true, a, b); + case DOUBLE: + return emitBinary(resultKind, SSEOp.XOR, PD, true, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + private Variable emitShift(AMD64Shift op, OperandSize size, Value a, Value b) { + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b).changeType(a.getPlatformKind())); + AllocatableValue input = getLIRGen().asAllocatable(a); + if (isJavaConstant(b)) { + JavaConstant c = asJavaConstant(b); + if (c.asLong() == 1) { + getLIRGen().append(new AMD64Unary.MOp(op.m1Op, size, result, input)); + } else { + /* + * c is implicitly masked to 5 or 6 bits by the CPU, so casting it to (int) is + * always correct, even without the NumUtil.is32bit() test. + */ + getLIRGen().append(new AMD64Binary.ConstOp(op.miOp, size, result, input, (int) c.asLong())); + } + } else { + getLIRGen().emitMove(RCX_I, b); + getLIRGen().append(new AMD64ShiftOp(op.mcOp, size, result, input, RCX_I)); + } + return result; + } + + @Override + public Variable emitShl(Value a, Value b) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitShift(SHL, DWORD, a, b); + case QWORD: + return emitShift(SHL, QWORD, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Variable emitShr(Value a, Value b) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitShift(SAR, DWORD, a, b); + case QWORD: + return emitShift(SAR, QWORD, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Variable emitUShr(Value a, Value b) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitShift(SHR, DWORD, a, b); + case QWORD: + return emitShift(SHR, QWORD, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + public Variable emitRol(Value a, Value b) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitShift(ROL, DWORD, a, b); + case QWORD: + return emitShift(ROL, QWORD, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + public Variable emitRor(Value a, Value b) { + switch ((AMD64Kind) a.getPlatformKind()) { + case DWORD: + return emitShift(ROR, DWORD, a, b); + case QWORD: + return emitShift(ROR, QWORD, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + private AllocatableValue emitConvertOp(LIRKind kind, AMD64RMOp op, OperandSize size, Value input) { + Variable result = getLIRGen().newVariable(kind); + getLIRGen().append(new AMD64Unary.RMOp(op, size, result, getLIRGen().asAllocatable(input))); + return result; + } + + private AllocatableValue emitConvertOp(LIRKind kind, AMD64MROp op, OperandSize size, Value input) { + Variable result = getLIRGen().newVariable(kind); + getLIRGen().append(new AMD64Unary.MROp(op, size, result, getLIRGen().asAllocatable(input))); + return result; + } + + @Override + public Value emitReinterpret(LIRKind to, Value inputVal) { + LIRKind from = inputVal.getLIRKind(); + if (to.equals(from)) { + return inputVal; + } + + AllocatableValue input = getLIRGen().asAllocatable(inputVal); + /* + * Conversions between integer to floating point types require moves between CPU and FPU + * registers. + */ + AMD64Kind fromKind = (AMD64Kind) from.getPlatformKind(); + switch ((AMD64Kind) to.getPlatformKind()) { + case DWORD: + switch (fromKind) { + case SINGLE: + return emitConvertOp(to, AMD64MROp.MOVD, DWORD, input); + } + break; + case QWORD: + switch (fromKind) { + case DOUBLE: + return emitConvertOp(to, AMD64MROp.MOVQ, QWORD, input); + } + break; + case SINGLE: + switch (fromKind) { + case DWORD: + return emitConvertOp(to, AMD64RMOp.MOVD, DWORD, input); + } + break; + case DOUBLE: + switch (fromKind) { + case QWORD: + return emitConvertOp(to, AMD64RMOp.MOVQ, QWORD, input); + } + break; + } + throw JVMCIError.shouldNotReachHere(); + } + + public Value emitFloatConvert(FloatConvert op, Value input) { + switch (op) { + case D2F: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSD2SS, SD, input); + case D2I: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSD2SI, DWORD, input); + case D2L: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSD2SI, QWORD, input); + case F2D: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSS2SD, SS, input); + case F2I: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSS2SI, DWORD, input); + case F2L: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSS2SI, QWORD, input); + case I2D: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, DWORD, input); + case I2F: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, DWORD, input); + case L2D: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, QWORD, input); + case L2F: + return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, QWORD, input); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + @Override + public Value emitNarrow(Value inputVal, int bits) { + if (inputVal.getPlatformKind() == AMD64Kind.QWORD && bits <= 32) { + // TODO make it possible to reinterpret Long as Int in LIR without move + return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), AMD64RMOp.MOV, DWORD, inputVal); + } else { + return inputVal; + } + } + + @Override + public Value emitSignExtend(Value inputVal, int fromBits, int toBits) { + assert fromBits <= toBits && toBits <= 64; + if (fromBits == toBits) { + return inputVal; + } else if (toBits > 32) { + // sign extend to 64 bits + switch (fromBits) { + case 8: + return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXB, QWORD, inputVal); + case 16: + return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSX, QWORD, inputVal); + case 32: + return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXD, QWORD, inputVal); + default: + throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); + } + } else { + // sign extend to 32 bits (smaller values are internally represented as 32 bit values) + switch (fromBits) { + case 8: + return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSXB, DWORD, inputVal); + case 16: + return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSX, DWORD, inputVal); + case 32: + return inputVal; + default: + throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); + } + } + } + + @Override + public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) { + assert fromBits <= toBits && toBits <= 64; + if (fromBits == toBits) { + return inputVal; + } else if (fromBits > 32) { + assert inputVal.getPlatformKind() == AMD64Kind.QWORD; + Variable result = getLIRGen().newVariable(LIRKind.combine(inputVal)); + long mask = CodeUtil.mask(fromBits); + getLIRGen().append(new AMD64Binary.DataOp(AND.getRMOpcode(QWORD), QWORD, result, getLIRGen().asAllocatable(inputVal), JavaConstant.forLong(mask))); + return result; + } else { + LIRKind resultKind = LIRKind.combine(inputVal); + if (toBits > 32) { + resultKind = resultKind.changeType(AMD64Kind.QWORD); + } else { + resultKind = resultKind.changeType(AMD64Kind.DWORD); + } + + /* + * Always emit DWORD operations, even if the resultKind is Long. On AMD64, all DWORD + * operations implicitly set the upper half of the register to 0, which is what we want + * anyway. Compared to the QWORD oparations, the encoding of the DWORD operations is + * sometimes one byte shorter. + */ + switch (fromBits) { + case 8: + return emitConvertOp(resultKind, MOVZXB, DWORD, inputVal); + case 16: + return emitConvertOp(resultKind, MOVZX, DWORD, inputVal); + case 32: + return emitConvertOp(resultKind, MOV, DWORD, inputVal); + } + + // odd bit count, fall back on manual masking + Variable result = getLIRGen().newVariable(resultKind); + JavaConstant mask; + if (toBits > 32) { + mask = JavaConstant.forLong(CodeUtil.mask(fromBits)); + } else { + mask = JavaConstant.forInt((int) CodeUtil.mask(fromBits)); + } + getLIRGen().append(new AMD64Binary.DataOp(AND.getRMOpcode(DWORD), DWORD, result, getLIRGen().asAllocatable(inputVal), mask)); + return result; + } + } + + @Override + public Variable emitBitCount(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); + assert ((AMD64Kind) value.getPlatformKind()).isInteger(); + if (value.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64Unary.RMOp(POPCNT, QWORD, result, getLIRGen().asAllocatable(value))); + } else { + getLIRGen().append(new AMD64Unary.RMOp(POPCNT, DWORD, result, getLIRGen().asAllocatable(value))); + } + return result; + } + + @Override + public Variable emitBitScanForward(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); + getLIRGen().append(new AMD64Unary.RMOp(BSF, QWORD, result, getLIRGen().asAllocatable(value))); + return result; + } + + @Override + public Variable emitBitScanReverse(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); + assert ((AMD64Kind) value.getPlatformKind()).isInteger(); + if (value.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64Unary.RMOp(BSR, QWORD, result, getLIRGen().asAllocatable(value))); + } else { + getLIRGen().append(new AMD64Unary.RMOp(BSR, DWORD, result, getLIRGen().asAllocatable(value))); + } + return result; + } + + @Override + public Value emitCountLeadingZeros(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); + assert ((AMD64Kind) value.getPlatformKind()).isInteger(); + if (value.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64Unary.RMOp(LZCNT, QWORD, result, getLIRGen().asAllocatable(value))); + } else { + getLIRGen().append(new AMD64Unary.RMOp(LZCNT, DWORD, result, getLIRGen().asAllocatable(value))); + } + return result; + } + + @Override + public Value emitCountTrailingZeros(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); + assert ((AMD64Kind) value.getPlatformKind()).isInteger(); + if (value.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64Unary.RMOp(TZCNT, QWORD, result, getLIRGen().asAllocatable(value))); + } else { + getLIRGen().append(new AMD64Unary.RMOp(TZCNT, DWORD, result, getLIRGen().asAllocatable(value))); + } + return result; + } + + @Override + public Value emitMathAbs(Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + switch ((AMD64Kind) input.getPlatformKind()) { + case SINGLE: + getLIRGen().append(new AMD64Binary.DataOp(SSEOp.AND, PS, result, getLIRGen().asAllocatable(input), JavaConstant.forFloat(Float.intBitsToFloat(0x7FFFFFFF)), 16)); + break; + case DOUBLE: + getLIRGen().append(new AMD64Binary.DataOp(SSEOp.AND, PD, result, getLIRGen().asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)), 16)); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return result; + } + + @Override + public Value emitMathSqrt(Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + switch ((AMD64Kind) input.getPlatformKind()) { + case SINGLE: + getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SS, result, getLIRGen().asAllocatable(input))); + break; + case DOUBLE: + getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SD, result, getLIRGen().asAllocatable(input))); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return result; + } + + @Override + public Value emitMathLog(Value input, boolean base10) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + getLIRGen().append(new AMD64MathIntrinsicOp(base10 ? LOG10 : LOG, result, getLIRGen().asAllocatable(input))); + return result; + } + + @Override + public Value emitMathCos(Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + getLIRGen().append(new AMD64MathIntrinsicOp(COS, result, getLIRGen().asAllocatable(input))); + return result; + } + + @Override + public Value emitMathSin(Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + getLIRGen().append(new AMD64MathIntrinsicOp(SIN, result, getLIRGen().asAllocatable(input))); + return result; + } + + @Override + public Value emitMathTan(Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + getLIRGen().append(new AMD64MathIntrinsicOp(TAN, result, getLIRGen().asAllocatable(input))); + return result; + } +}
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -23,34 +23,14 @@ package com.oracle.graal.compiler.amd64; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.CMP; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NEG; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NOT; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSF; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSR; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.LZCNT; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOV; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSD; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSS; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZX; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZXB; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.POPCNT; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TEST; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TESTB; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TZCNT; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROL; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROR; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SAR; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHL; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHR; import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.BYTE; import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD; import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PD; @@ -62,13 +42,6 @@ import static com.oracle.graal.lir.LIRValueUtil.asConstantValue; import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant; import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant; -import static com.oracle.graal.lir.amd64.AMD64Arithmetic.DREM; -import static com.oracle.graal.lir.amd64.AMD64Arithmetic.FREM; -import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.COS; -import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG; -import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG10; -import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.SIN; -import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.TAN; import static jdk.internal.jvmci.code.ValueUtil.isAllocatableValue; import static jdk.internal.jvmci.code.ValueUtil.isRegister; import static jdk.internal.jvmci.code.ValueUtil.isStackSlotValue; @@ -80,7 +53,6 @@ import jdk.internal.jvmci.amd64.AMD64Kind; import jdk.internal.jvmci.code.Architecture; import jdk.internal.jvmci.code.CallingConvention; -import jdk.internal.jvmci.code.CodeUtil; import jdk.internal.jvmci.code.Register; import jdk.internal.jvmci.code.RegisterConfig; import jdk.internal.jvmci.code.RegisterValue; @@ -96,18 +68,13 @@ import jdk.internal.jvmci.meta.Value; import com.oracle.graal.asm.NumUtil; -import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic; import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp; -import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp; import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp; -import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp; import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp; -import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize; import com.oracle.graal.asm.amd64.AMD64Assembler.SSEOp; import com.oracle.graal.compiler.common.calc.Condition; -import com.oracle.graal.compiler.common.calc.FloatConvert; import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; import com.oracle.graal.compiler.common.spi.LIRKindTool; import com.oracle.graal.compiler.common.util.Util; @@ -120,14 +87,10 @@ import com.oracle.graal.lir.SwitchStrategy; import com.oracle.graal.lir.Variable; import com.oracle.graal.lir.amd64.AMD64AddressValue; -import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp; -import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGenerator; import com.oracle.graal.lir.amd64.AMD64ArrayEqualsOp; -import com.oracle.graal.lir.amd64.AMD64Binary; import com.oracle.graal.lir.amd64.AMD64BinaryConsumer; import com.oracle.graal.lir.amd64.AMD64ByteSwapOp; import com.oracle.graal.lir.amd64.AMD64Call; -import com.oracle.graal.lir.amd64.AMD64ClearRegisterOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp; @@ -136,7 +99,6 @@ import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp; import com.oracle.graal.lir.amd64.AMD64LIRInstruction; -import com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp; import com.oracle.graal.lir.amd64.AMD64Move; import com.oracle.graal.lir.amd64.AMD64Move.AMD64PushPopStackMove; import com.oracle.graal.lir.amd64.AMD64Move.AMD64StackMove; @@ -148,9 +110,6 @@ import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp; import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp; -import com.oracle.graal.lir.amd64.AMD64MulDivOp; -import com.oracle.graal.lir.amd64.AMD64ShiftOp; -import com.oracle.graal.lir.amd64.AMD64SignExtendOp; import com.oracle.graal.lir.amd64.AMD64Unary; import com.oracle.graal.lir.framemap.FrameMapBuilder; import com.oracle.graal.lir.gen.LIRGenerationResult; @@ -161,9 +120,7 @@ /** * This class implements the AMD64 specific portion of the LIR generator. */ -public abstract class AMD64LIRGenerator extends LIRGenerator implements AMD64ArithmeticLIRGenerator { - - private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD)); +public abstract class AMD64LIRGenerator extends LIRGenerator { private AMD64SpillMoveFactory moveFactory; private Map<PlatformKind.Key, RegisterBackupPair> categorized; @@ -196,8 +153,8 @@ } } - public AMD64LIRGenerator(LIRKindTool lirKindTool, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) { - super(lirKindTool, providers, cc, lirGenRes); + public AMD64LIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) { + super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes); } public SpillMoveFactory getSpillMoveFactory() { @@ -727,679 +684,6 @@ } @Override - public Variable emitNegate(Value inputVal) { - AllocatableValue input = asAllocatable(inputVal); - Variable result = newVariable(LIRKind.combine(input)); - switch ((AMD64Kind) input.getPlatformKind()) { - case DWORD: - append(new AMD64Unary.MOp(NEG, DWORD, result, input)); - break; - case QWORD: - append(new AMD64Unary.MOp(NEG, QWORD, result, input)); - break; - case SINGLE: - append(new AMD64Binary.DataOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16)); - break; - case DOUBLE: - append(new AMD64Binary.DataOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16)); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return result; - } - - @Override - public Variable emitNot(Value inputVal) { - AllocatableValue input = asAllocatable(inputVal); - Variable result = newVariable(LIRKind.combine(input)); - switch ((AMD64Kind) input.getPlatformKind()) { - case DWORD: - append(new AMD64Unary.MOp(NOT, DWORD, result, input)); - break; - case QWORD: - append(new AMD64Unary.MOp(NOT, QWORD, result, input)); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return result; - } - - private Variable emitBinary(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, Value a, Value b, boolean setFlags) { - if (isJavaConstant(b)) { - return emitBinaryConst(resultKind, op, size, commutative, asAllocatable(a), asConstantValue(b), setFlags); - } else if (commutative && isJavaConstant(a)) { - return emitBinaryConst(resultKind, op, size, commutative, asAllocatable(b), asConstantValue(a), setFlags); - } else { - return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, asAllocatable(a), asAllocatable(b)); - } - } - - private Variable emitBinary(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, Value a, Value b) { - if (isJavaConstant(b)) { - return emitBinaryConst(resultKind, op, size, asAllocatable(a), asJavaConstant(b)); - } else if (commutative && isJavaConstant(a)) { - return emitBinaryConst(resultKind, op, size, asAllocatable(b), asJavaConstant(a)); - } else { - return emitBinaryVar(resultKind, op, size, commutative, asAllocatable(a), asAllocatable(b)); - } - } - - private Variable emitBinaryConst(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, ConstantValue b, boolean setFlags) { - long value = b.getJavaConstant().asLong(); - if (NumUtil.isInt(value)) { - Variable result = newVariable(resultKind); - int constant = (int) value; - - if (!setFlags) { - AMD64MOp mop = getMOp(op, constant); - if (mop != null) { - append(new AMD64Unary.MOp(mop, size, result, a)); - return result; - } - } - - append(new AMD64Binary.ConstOp(op, size, result, a, constant)); - return result; - } else { - return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, a, asAllocatable(b)); - } - } - - private static AMD64MOp getMOp(AMD64BinaryArithmetic op, int constant) { - if (constant == 1) { - if (op.equals(AMD64BinaryArithmetic.ADD)) { - return AMD64MOp.INC; - } - if (op.equals(AMD64BinaryArithmetic.SUB)) { - return AMD64MOp.DEC; - } - } else if (constant == -1) { - if (op.equals(AMD64BinaryArithmetic.ADD)) { - return AMD64MOp.DEC; - } - if (op.equals(AMD64BinaryArithmetic.SUB)) { - return AMD64MOp.INC; - } - } - return null; - } - - private Variable emitBinaryConst(LIRKind resultKind, AMD64RMOp op, OperandSize size, AllocatableValue a, JavaConstant b) { - Variable result = newVariable(resultKind); - append(new AMD64Binary.DataOp(op, size, result, a, b)); - return result; - } - - private Variable emitBinaryVar(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, AllocatableValue a, AllocatableValue b) { - Variable result = newVariable(resultKind); - if (commutative) { - append(new AMD64Binary.CommutativeOp(op, size, result, a, b)); - } else { - append(new AMD64Binary.Op(op, size, result, a, b)); - } - return result; - } - - @Override - protected boolean isNumericInteger(PlatformKind kind) { - return ((AMD64Kind) kind).isInteger(); - } - - @Override - public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitBinary(resultKind, ADD, DWORD, true, a, b, setFlags); - case QWORD: - return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags); - case SINGLE: - return emitBinary(resultKind, SSEOp.ADD, SS, true, a, b); - case DOUBLE: - return emitBinary(resultKind, SSEOp.ADD, SD, true, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitBinary(resultKind, SUB, DWORD, false, a, b, setFlags); - case QWORD: - return emitBinary(resultKind, SUB, QWORD, false, a, b, setFlags); - case SINGLE: - return emitBinary(resultKind, SSEOp.SUB, SS, false, a, b); - case DOUBLE: - return emitBinary(resultKind, SSEOp.SUB, SD, false, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private Variable emitIMULConst(OperandSize size, AllocatableValue a, ConstantValue b) { - long value = b.getJavaConstant().asLong(); - if (NumUtil.isInt(value)) { - int imm = (int) value; - AMD64RMIOp op; - if (NumUtil.isByte(imm)) { - op = AMD64RMIOp.IMUL_SX; - } else { - op = AMD64RMIOp.IMUL; - } - - Variable ret = newVariable(LIRKind.combine(a, b)); - append(new AMD64Binary.RMIOp(op, size, ret, a, imm)); - return ret; - } else { - return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, a, asAllocatable(b)); - } - } - - private Variable emitIMUL(OperandSize size, Value a, Value b) { - if (isJavaConstant(b)) { - return emitIMULConst(size, asAllocatable(a), asConstantValue(b)); - } else if (isJavaConstant(a)) { - return emitIMULConst(size, asAllocatable(b), asConstantValue(a)); - } else { - return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, asAllocatable(a), asAllocatable(b)); - } - } - - @Override - public Variable emitMul(Value a, Value b, boolean setFlags) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitIMUL(DWORD, a, b); - case QWORD: - return emitIMUL(QWORD, a, b); - case SINGLE: - return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SS, true, a, b); - case DOUBLE: - return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SD, true, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private RegisterValue moveToReg(Register reg, Value v) { - RegisterValue ret = reg.asValue(v.getLIRKind()); - emitMove(ret, v); - return ret; - } - - private Value emitMulHigh(AMD64MOp opcode, OperandSize size, Value a, Value b) { - AMD64MulDivOp mulHigh = append(new AMD64MulDivOp(opcode, size, LIRKind.combine(a, b), moveToReg(AMD64.rax, a), asAllocatable(b))); - return emitMove(mulHigh.getHighResult()); - } - - @Override - public Value emitMulHigh(Value a, Value b) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitMulHigh(AMD64MOp.IMUL, DWORD, a, b); - case QWORD: - return emitMulHigh(AMD64MOp.IMUL, QWORD, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Value emitUMulHigh(Value a, Value b) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitMulHigh(AMD64MOp.MUL, DWORD, a, b); - case QWORD: - return emitMulHigh(AMD64MOp.MUL, QWORD, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - public Value emitBinaryMemory(AMD64RMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { - Variable result = newVariable(LIRKind.combine(a)); - append(new AMD64Binary.MemoryOp(op, size, result, a, location, state)); - return result; - } - - protected Value emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, AMD64AddressValue address, LIRFrameState state) { - Variable result = newVariable(LIRKind.value(kind)); - append(new AMD64Unary.MemoryOp(op, size, result, address, state)); - return result; - } - - protected Value emitZeroExtendMemory(AMD64Kind memoryKind, int resultBits, AMD64AddressValue address, LIRFrameState state) { - // Issue a zero extending load of the proper bit size and set the result to - // the proper kind. - Variable result = newVariable(LIRKind.value(resultBits == 32 ? AMD64Kind.DWORD : AMD64Kind.QWORD)); - switch (memoryKind) { - case BYTE: - append(new AMD64Unary.MemoryOp(MOVZXB, DWORD, result, address, state)); - break; - case WORD: - append(new AMD64Unary.MemoryOp(MOVZX, DWORD, result, address, state)); - break; - case DWORD: - append(new AMD64Unary.MemoryOp(MOV, DWORD, result, address, state)); - break; - case QWORD: - append(new AMD64Unary.MemoryOp(MOV, QWORD, result, address, state)); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return result; - } - - private AMD64MulDivOp emitIDIV(OperandSize size, Value a, Value b, LIRFrameState state) { - LIRKind kind = LIRKind.combine(a, b); - - AMD64SignExtendOp sx = append(new AMD64SignExtendOp(size, kind, moveToReg(AMD64.rax, a))); - return append(new AMD64MulDivOp(AMD64MOp.IDIV, size, kind, sx.getHighResult(), sx.getLowResult(), asAllocatable(b), state)); - } - - private AMD64MulDivOp emitDIV(OperandSize size, Value a, Value b, LIRFrameState state) { - LIRKind kind = LIRKind.combine(a, b); - - RegisterValue rax = moveToReg(AMD64.rax, a); - RegisterValue rdx = AMD64.rdx.asValue(kind); - append(new AMD64ClearRegisterOp(size, rdx)); - return append(new AMD64MulDivOp(AMD64MOp.DIV, size, kind, rdx, rax, asAllocatable(b), state)); - } - - public Value[] emitIntegerDivRem(Value a, Value b, LIRFrameState state) { - AMD64MulDivOp op; - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - op = emitIDIV(DWORD, a, b, state); - break; - case QWORD: - op = emitIDIV(QWORD, a, b, state); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return new Value[]{emitMove(op.getQuotient()), emitMove(op.getRemainder())}; - } - - @Override - public Value emitDiv(Value a, Value b, LIRFrameState state) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - AMD64MulDivOp op = emitIDIV(DWORD, a, b, state); - return emitMove(op.getQuotient()); - case QWORD: - AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state); - return emitMove(lop.getQuotient()); - case SINGLE: - return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SS, false, a, b); - case DOUBLE: - return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SD, false, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Value emitRem(Value a, Value b, LIRFrameState state) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - AMD64MulDivOp op = emitIDIV(DWORD, a, b, state); - return emitMove(op.getRemainder()); - case QWORD: - AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state); - return emitMove(lop.getRemainder()); - case SINGLE: { - Variable result = newVariable(LIRKind.combine(a, b)); - append(new FPDivRemOp(FREM, result, load(a), load(b))); - return result; - } - case DOUBLE: { - Variable result = newVariable(LIRKind.combine(a, b)); - append(new FPDivRemOp(DREM, result, load(a), load(b))); - return result; - } - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Variable emitUDiv(Value a, Value b, LIRFrameState state) { - AMD64MulDivOp op; - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - op = emitDIV(DWORD, a, b, state); - break; - case QWORD: - op = emitDIV(QWORD, a, b, state); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return emitMove(op.getQuotient()); - } - - @Override - public Variable emitURem(Value a, Value b, LIRFrameState state) { - AMD64MulDivOp op; - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - op = emitDIV(DWORD, a, b, state); - break; - case QWORD: - op = emitDIV(QWORD, a, b, state); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return emitMove(op.getRemainder()); - } - - @Override - public Variable emitAnd(Value a, Value b) { - LIRKind resultKind = LIRKind.combine(a, b); - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitBinary(resultKind, AND, DWORD, true, a, b, false); - case QWORD: - return emitBinary(resultKind, AND, QWORD, true, a, b, false); - case SINGLE: - return emitBinary(resultKind, SSEOp.AND, PS, true, a, b); - case DOUBLE: - return emitBinary(resultKind, SSEOp.AND, PD, true, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Variable emitOr(Value a, Value b) { - LIRKind resultKind = LIRKind.combine(a, b); - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitBinary(resultKind, OR, DWORD, true, a, b, false); - case QWORD: - return emitBinary(resultKind, OR, QWORD, true, a, b, false); - case SINGLE: - return emitBinary(resultKind, SSEOp.OR, PS, true, a, b); - case DOUBLE: - return emitBinary(resultKind, SSEOp.OR, PD, true, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Variable emitXor(Value a, Value b) { - LIRKind resultKind = LIRKind.combine(a, b); - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitBinary(resultKind, XOR, DWORD, true, a, b, false); - case QWORD: - return emitBinary(resultKind, XOR, QWORD, true, a, b, false); - case SINGLE: - return emitBinary(resultKind, SSEOp.XOR, PS, true, a, b); - case DOUBLE: - return emitBinary(resultKind, SSEOp.XOR, PD, true, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private Variable emitShift(AMD64Shift op, OperandSize size, Value a, Value b) { - Variable result = newVariable(LIRKind.combine(a, b).changeType(a.getPlatformKind())); - AllocatableValue input = asAllocatable(a); - if (isJavaConstant(b)) { - JavaConstant c = asJavaConstant(b); - if (c.asLong() == 1) { - append(new AMD64Unary.MOp(op.m1Op, size, result, input)); - } else { - /* - * c is implicitly masked to 5 or 6 bits by the CPU, so casting it to (int) is - * always correct, even without the NumUtil.is32bit() test. - */ - append(new AMD64Binary.ConstOp(op.miOp, size, result, input, (int) c.asLong())); - } - } else { - emitMove(RCX_I, b); - append(new AMD64ShiftOp(op.mcOp, size, result, input, RCX_I)); - } - return result; - } - - @Override - public Variable emitShl(Value a, Value b) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitShift(SHL, DWORD, a, b); - case QWORD: - return emitShift(SHL, QWORD, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Variable emitShr(Value a, Value b) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitShift(SAR, DWORD, a, b); - case QWORD: - return emitShift(SAR, QWORD, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Variable emitUShr(Value a, Value b) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitShift(SHR, DWORD, a, b); - case QWORD: - return emitShift(SHR, QWORD, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - public Variable emitRol(Value a, Value b) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitShift(ROL, DWORD, a, b); - case QWORD: - return emitShift(ROL, QWORD, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - public Variable emitRor(Value a, Value b) { - switch ((AMD64Kind) a.getPlatformKind()) { - case DWORD: - return emitShift(ROR, DWORD, a, b); - case QWORD: - return emitShift(ROR, QWORD, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private AllocatableValue emitConvertOp(LIRKind kind, AMD64RMOp op, OperandSize size, Value input) { - Variable result = newVariable(kind); - append(new AMD64Unary.RMOp(op, size, result, asAllocatable(input))); - return result; - } - - private AllocatableValue emitConvertOp(LIRKind kind, AMD64MROp op, OperandSize size, Value input) { - Variable result = newVariable(kind); - append(new AMD64Unary.MROp(op, size, result, asAllocatable(input))); - return result; - } - - @Override - public Value emitReinterpret(LIRKind to, Value inputVal) { - LIRKind from = inputVal.getLIRKind(); - if (to.equals(from)) { - return inputVal; - } - - AllocatableValue input = asAllocatable(inputVal); - /* - * Conversions between integer to floating point types require moves between CPU and FPU - * registers. - */ - AMD64Kind fromKind = (AMD64Kind) from.getPlatformKind(); - switch ((AMD64Kind) to.getPlatformKind()) { - case DWORD: - switch (fromKind) { - case SINGLE: - return emitConvertOp(to, AMD64MROp.MOVD, DWORD, input); - } - break; - case QWORD: - switch (fromKind) { - case DOUBLE: - return emitConvertOp(to, AMD64MROp.MOVQ, QWORD, input); - } - break; - case SINGLE: - switch (fromKind) { - case DWORD: - return emitConvertOp(to, AMD64RMOp.MOVD, DWORD, input); - } - break; - case DOUBLE: - switch (fromKind) { - case QWORD: - return emitConvertOp(to, AMD64RMOp.MOVQ, QWORD, input); - } - break; - } - throw JVMCIError.shouldNotReachHere(); - } - - public Value emitFloatConvert(FloatConvert op, Value input) { - switch (op) { - case D2F: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSD2SS, SD, input); - case D2I: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSD2SI, DWORD, input); - case D2L: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSD2SI, QWORD, input); - case F2D: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSS2SD, SS, input); - case F2I: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSS2SI, DWORD, input); - case F2L: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSS2SI, QWORD, input); - case I2D: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, DWORD, input); - case I2F: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, DWORD, input); - case L2D: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, QWORD, input); - case L2F: - return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, QWORD, input); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - @Override - public Value emitNarrow(Value inputVal, int bits) { - if (inputVal.getPlatformKind() == AMD64Kind.QWORD && bits <= 32) { - // TODO make it possible to reinterpret Long as Int in LIR without move - return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), AMD64RMOp.MOV, DWORD, inputVal); - } else { - return inputVal; - } - } - - @Override - public Value emitSignExtend(Value inputVal, int fromBits, int toBits) { - assert fromBits <= toBits && toBits <= 64; - if (fromBits == toBits) { - return inputVal; - } else if (toBits > 32) { - // sign extend to 64 bits - switch (fromBits) { - case 8: - return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXB, QWORD, inputVal); - case 16: - return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSX, QWORD, inputVal); - case 32: - return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXD, QWORD, inputVal); - default: - throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); - } - } else { - // sign extend to 32 bits (smaller values are internally represented as 32 bit values) - switch (fromBits) { - case 8: - return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSXB, DWORD, inputVal); - case 16: - return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSX, DWORD, inputVal); - case 32: - return inputVal; - default: - throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); - } - } - } - - @Override - public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) { - assert fromBits <= toBits && toBits <= 64; - if (fromBits == toBits) { - return inputVal; - } else if (fromBits > 32) { - assert inputVal.getPlatformKind() == AMD64Kind.QWORD; - Variable result = newVariable(LIRKind.combine(inputVal)); - long mask = CodeUtil.mask(fromBits); - append(new AMD64Binary.DataOp(AND.getRMOpcode(QWORD), QWORD, result, asAllocatable(inputVal), JavaConstant.forLong(mask))); - return result; - } else { - LIRKind resultKind = LIRKind.combine(inputVal); - if (toBits > 32) { - resultKind = resultKind.changeType(AMD64Kind.QWORD); - } else { - resultKind = resultKind.changeType(AMD64Kind.DWORD); - } - - /* - * Always emit DWORD operations, even if the resultKind is Long. On AMD64, all DWORD - * operations implicitly set the upper half of the register to 0, which is what we want - * anyway. Compared to the QWORD oparations, the encoding of the DWORD operations is - * sometimes one byte shorter. - */ - switch (fromBits) { - case 8: - return emitConvertOp(resultKind, MOVZXB, DWORD, inputVal); - case 16: - return emitConvertOp(resultKind, MOVZX, DWORD, inputVal); - case 32: - return emitConvertOp(resultKind, MOV, DWORD, inputVal); - } - - // odd bit count, fall back on manual masking - Variable result = newVariable(resultKind); - JavaConstant mask; - if (toBits > 32) { - mask = JavaConstant.forLong(CodeUtil.mask(fromBits)); - } else { - mask = JavaConstant.forInt((int) CodeUtil.mask(fromBits)); - } - append(new AMD64Binary.DataOp(AND.getRMOpcode(DWORD), DWORD, result, asAllocatable(inputVal), mask)); - return result; - } - } - - @Override public void emitMembar(int barriers) { int necessaryBarriers = target().arch.requiredBarriers(barriers); if (target().isMP && necessaryBarriers != 0) { @@ -1420,119 +704,6 @@ } @Override - public Variable emitBitCount(Value value) { - Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); - assert ((AMD64Kind) value.getPlatformKind()).isInteger(); - if (value.getPlatformKind() == AMD64Kind.QWORD) { - append(new AMD64Unary.RMOp(POPCNT, QWORD, result, asAllocatable(value))); - } else { - append(new AMD64Unary.RMOp(POPCNT, DWORD, result, asAllocatable(value))); - } - return result; - } - - @Override - public Variable emitBitScanForward(Value value) { - Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); - append(new AMD64Unary.RMOp(BSF, QWORD, result, asAllocatable(value))); - return result; - } - - @Override - public Variable emitBitScanReverse(Value value) { - Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); - assert ((AMD64Kind) value.getPlatformKind()).isInteger(); - if (value.getPlatformKind() == AMD64Kind.QWORD) { - append(new AMD64Unary.RMOp(BSR, QWORD, result, asAllocatable(value))); - } else { - append(new AMD64Unary.RMOp(BSR, DWORD, result, asAllocatable(value))); - } - return result; - } - - public Value emitCountLeadingZeros(Value value) { - Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); - assert ((AMD64Kind) value.getPlatformKind()).isInteger(); - if (value.getPlatformKind() == AMD64Kind.QWORD) { - append(new AMD64Unary.RMOp(LZCNT, QWORD, result, asAllocatable(value))); - } else { - append(new AMD64Unary.RMOp(LZCNT, DWORD, result, asAllocatable(value))); - } - return result; - } - - public Value emitCountTrailingZeros(Value value) { - Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD)); - assert ((AMD64Kind) value.getPlatformKind()).isInteger(); - if (value.getPlatformKind() == AMD64Kind.QWORD) { - append(new AMD64Unary.RMOp(TZCNT, QWORD, result, asAllocatable(value))); - } else { - append(new AMD64Unary.RMOp(TZCNT, DWORD, result, asAllocatable(value))); - } - return result; - } - - @Override - public Value emitMathAbs(Value input) { - Variable result = newVariable(LIRKind.combine(input)); - switch ((AMD64Kind) input.getPlatformKind()) { - case SINGLE: - append(new AMD64Binary.DataOp(SSEOp.AND, PS, result, asAllocatable(input), JavaConstant.forFloat(Float.intBitsToFloat(0x7FFFFFFF)), 16)); - break; - case DOUBLE: - append(new AMD64Binary.DataOp(SSEOp.AND, PD, result, asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)), 16)); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return result; - } - - @Override - public Value emitMathSqrt(Value input) { - Variable result = newVariable(LIRKind.combine(input)); - switch ((AMD64Kind) input.getPlatformKind()) { - case SINGLE: - append(new AMD64Unary.RMOp(SSEOp.SQRT, SS, result, asAllocatable(input))); - break; - case DOUBLE: - append(new AMD64Unary.RMOp(SSEOp.SQRT, SD, result, asAllocatable(input))); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return result; - } - - @Override - public Value emitMathLog(Value input, boolean base10) { - Variable result = newVariable(LIRKind.combine(input)); - append(new AMD64MathIntrinsicOp(base10 ? LOG10 : LOG, result, asAllocatable(input))); - return result; - } - - @Override - public Value emitMathCos(Value input) { - Variable result = newVariable(LIRKind.combine(input)); - append(new AMD64MathIntrinsicOp(COS, result, asAllocatable(input))); - return result; - } - - @Override - public Value emitMathSin(Value input) { - Variable result = newVariable(LIRKind.combine(input)); - append(new AMD64MathIntrinsicOp(SIN, result, asAllocatable(input))); - return result; - } - - @Override - public Value emitMathTan(Value input) { - Variable result = newVariable(LIRKind.combine(input)); - append(new AMD64MathIntrinsicOp(TAN, result, asAllocatable(input))); - return result; - } - - @Override public Variable emitByteSwap(Value input) { Variable result = newVariable(LIRKind.combine(input)); append(new AMD64ByteSwapOp(result, input)); @@ -1571,5 +742,4 @@ protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { append(new TableSwitchOp(lowKey, defaultTarget, targets, key, newVariable(LIRKind.value(target().arch.getWordKind())), newVariable(key.getLIRKind()))); } - }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Thu Oct 08 15:58:13 2015 -0700 @@ -84,7 +84,7 @@ if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) { FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode; if (otherDivRem.getX() == divRem.getX() && otherDivRem.getY() == divRem.getY() && !hasOperand(otherDivRem)) { - Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode)); + Value[] results = ((AMD64ArithmeticLIRGenerator) gen.getArithmetic()).emitIntegerDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode)); if (divRem instanceof IntegerDivNode) { setResult(divRem, results[0]); setResult(otherDivRem, results[1]);
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java Thu Oct 08 15:58:13 2015 -0700 @@ -196,7 +196,7 @@ return builder -> { AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress()); LIRFrameState state = getState(access); - return getLIRGeneratorTool().emitConvertMemoryOp(kind, op, size, address, state); + return getArithmeticLIRGenerator().emitConvertMemoryOp(kind, op, size, address, state); }; } @@ -276,7 +276,7 @@ @MatchRule("(Or (LeftShift=lshift value Constant) (UnsignedRightShift=rshift value Constant))") public ComplexMatchResult rotateLeftConstant(LeftShiftNode lshift, UnsignedRightShiftNode rshift) { if ((lshift.getShiftAmountMask() & (lshift.getY().asJavaConstant().asInt() + rshift.getY().asJavaConstant().asInt())) == 0) { - return builder -> getLIRGeneratorTool().emitRol(operand(lshift.getX()), operand(lshift.getY())); + return builder -> getArithmeticLIRGenerator().emitRol(operand(lshift.getX()), operand(lshift.getY())); } return null; } @@ -284,7 +284,7 @@ @MatchRule("(Or (LeftShift value (Sub Constant=delta shiftAmount)) (UnsignedRightShift value shiftAmount))") public ComplexMatchResult rotateRightVariable(ValueNode value, ConstantNode delta, ValueNode shiftAmount) { if (delta.asJavaConstant().asLong() == 0 || delta.asJavaConstant().asLong() == 32) { - return builder -> getLIRGeneratorTool().emitRor(operand(value), operand(shiftAmount)); + return builder -> getArithmeticLIRGenerator().emitRor(operand(value), operand(shiftAmount)); } return null; } @@ -292,13 +292,14 @@ @MatchRule("(Or (LeftShift value shiftAmount) (UnsignedRightShift value (Sub Constant=delta shiftAmount)))") public ComplexMatchResult rotateLeftVariable(ValueNode value, ValueNode shiftAmount, ConstantNode delta) { if (delta.asJavaConstant().asLong() == 0 || delta.asJavaConstant().asLong() == 32) { - return builder -> getLIRGeneratorTool().emitRol(operand(value), operand(shiftAmount)); + return builder -> getArithmeticLIRGenerator().emitRol(operand(value), operand(shiftAmount)); } return null; } private ComplexMatchResult binaryRead(AMD64RMOp op, OperandSize size, ValueNode value, Access access) { - return builder -> getLIRGeneratorTool().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), getState(access)); + return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), + getState(access)); } @MatchRule("(Add value Read=access)") @@ -386,7 +387,7 @@ @MatchRule("(ZeroExtend FloatingRead=access)") public ComplexMatchResult zeroExtend(ZeroExtendNode root, Access access) { AMD64Kind memoryKind = getMemoryKind(access); - return builder -> getLIRGeneratorTool().emitZeroExtendMemory(memoryKind, root.getResultBits(), (AMD64AddressValue) operand(access.getAddress()), getState(access)); + return builder -> getArithmeticLIRGenerator().emitZeroExtendMemory(memoryKind, root.getResultBits(), (AMD64AddressValue) operand(access.getAddress()), getState(access)); } @MatchRule("(FloatConvert Read=access)") @@ -432,4 +433,8 @@ public AMD64LIRGenerator getLIRGeneratorTool() { return (AMD64LIRGenerator) gen; } + + protected AMD64ArithmeticLIRGenerator getArithmeticLIRGenerator() { + return (AMD64ArithmeticLIRGenerator) getLIRGeneratorTool().getArithmetic(); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -0,0 +1,670 @@ +/* + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.sparc; + +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Add; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Addcc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.And; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Mulx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sdivx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sllx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sra; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srax; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srl; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sub; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Subcc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Udivx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Xnor; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtos; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fstod; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fxtod; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.UMulxhi; +import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant; +import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant; +import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.BSF; +import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IBSR; +import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LBSR; +import static jdk.internal.jvmci.code.CodeUtil.mask; +import static jdk.internal.jvmci.meta.JavaConstant.forLong; +import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; +import jdk.internal.jvmci.common.JVMCIError; +import jdk.internal.jvmci.meta.AllocatableValue; +import jdk.internal.jvmci.meta.JavaConstant; +import jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.meta.PlatformKind; +import jdk.internal.jvmci.meta.Value; +import jdk.internal.jvmci.sparc.SPARC; +import jdk.internal.jvmci.sparc.SPARC.CPUFeature; +import jdk.internal.jvmci.sparc.SPARCKind; + +import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s; +import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs; +import com.oracle.graal.compiler.common.calc.FloatConvert; +import com.oracle.graal.lir.ConstantValue; +import com.oracle.graal.lir.LIRFrameState; +import com.oracle.graal.lir.Variable; +import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.sparc.SPARCArithmetic; +import com.oracle.graal.lir.sparc.SPARCArithmetic.FloatConvertOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp.MulHigh; +import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp.Rem; +import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCIMulccOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCLMulccOp; +import com.oracle.graal.lir.sparc.SPARCBitManipulationOp; +import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp; +import com.oracle.graal.lir.sparc.SPARCOP3Op; +import com.oracle.graal.lir.sparc.SPARCOPFOp; + +/** + * This class implements the SPARC specific portion of the LIR generator. + */ +public class SPARCArithmeticLIRGenerator extends ArithmeticLIRGenerator { + + @Override + public SPARCLIRGenerator getLIRGen() { + return (SPARCLIRGenerator) super.getLIRGen(); + } + + @Override + public Variable emitBitCount(Value operand) { + Variable result = getLIRGen().newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); + Value usedOperand = operand; + if (operand.getPlatformKind() == SPARCKind.WORD) { // Zero extend + usedOperand = getLIRGen().newVariable(operand.getLIRKind()); + getLIRGen().append(new SPARCOP3Op(Op3s.Srl, operand, SPARC.g0.asValue(), usedOperand)); + } + getLIRGen().append(new SPARCOP3Op(Op3s.Popc, SPARC.g0.asValue(), usedOperand, result)); + return result; + } + + @Override + public Variable emitBitScanForward(Value operand) { + Variable result = getLIRGen().newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); + getLIRGen().append(new SPARCBitManipulationOp(BSF, result, getLIRGen().asAllocatable(operand), getLIRGen())); + return result; + } + + @Override + public Variable emitBitScanReverse(Value operand) { + Variable result = getLIRGen().newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); + if (operand.getPlatformKind() == SPARCKind.DWORD) { + getLIRGen().append(new SPARCBitManipulationOp(LBSR, result, getLIRGen().asAllocatable(operand), getLIRGen())); + } else { + getLIRGen().append(new SPARCBitManipulationOp(IBSR, result, getLIRGen().asAllocatable(operand), getLIRGen())); + } + return result; + } + + @Override + public Value emitMathAbs(Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + SPARCKind kind = (SPARCKind) input.getPlatformKind(); + Opfs opf; + switch (kind) { + case SINGLE: + opf = Opfs.Fabss; + break; + case DOUBLE: + opf = Opfs.Fabsd; + break; + default: + throw JVMCIError.shouldNotReachHere("Input kind: " + kind); + } + getLIRGen().append(new SPARCOPFOp(opf, g0.asValue(), input, result)); + return result; + } + + @Override + public Value emitMathSqrt(Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + SPARCKind kind = (SPARCKind) input.getPlatformKind(); + Opfs opf; + switch (kind) { + case SINGLE: + opf = Opfs.Fsqrts; + break; + case DOUBLE: + opf = Opfs.Fsqrtd; + break; + default: + throw JVMCIError.shouldNotReachHere("Input kind: " + kind); + } + getLIRGen().append(new SPARCOPFOp(opf, g0.asValue(), input, result)); + return result; + } + + @Override + public Value emitNegate(Value input) { + PlatformKind inputKind = input.getPlatformKind(); + if (isNumericInteger(inputKind)) { + return emitUnary(Sub, input); + } else { + return emitUnary(inputKind.equals(DOUBLE) ? Fnegd : Fnegs, input); + } + } + + @Override + public Value emitNot(Value input) { + return emitUnary(Xnor, input); + } + + private Variable emitUnary(Opfs opf, Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + getLIRGen().append(new SPARCOPFOp(opf, g0.asValue(), input, result)); + return result; + } + + private Variable emitUnary(Op3s op3, Value input) { + Variable result = getLIRGen().newVariable(LIRKind.combine(input)); + getLIRGen().append(SPARCOP3Op.newUnary(op3, input, result)); + return result; + } + + private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b) { + return emitBinary(resultKind, opf, a, b, null); + } + + private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b, LIRFrameState state) { + Variable result = getLIRGen().newVariable(resultKind); + if (opf.isCommutative() && isJavaConstant(a) && getLIRGen().canInlineConstant(asJavaConstant(a))) { + getLIRGen().append(new SPARCOPFOp(opf, b, a, result, state)); + } else { + getLIRGen().append(new SPARCOPFOp(opf, a, b, result, state)); + } + return result; + } + + private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, int b) { + return emitBinary(resultKind, op3, a, new ConstantValue(LIRKind.value(WORD), JavaConstant.forInt(b))); + } + + private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b) { + return emitBinary(resultKind, op3, a, b, null); + } + + private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b, LIRFrameState state) { + Variable result = getLIRGen().newVariable(resultKind); + if (op3.isCommutative() && isJavaConstant(a) && getLIRGen().canInlineConstant(asJavaConstant(a))) { + getLIRGen().append(new SPARCOP3Op(op3, getLIRGen().load(b), a, result, state)); + } else { + getLIRGen().append(new SPARCOP3Op(op3, getLIRGen().load(a), b, result, state)); + } + return result; + } + + @Override + protected boolean isNumericInteger(PlatformKind kind) { + return ((SPARCKind) kind).isInteger(); + } + + @Override + public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { + if (isNumericInteger(a.getPlatformKind())) { + return emitBinary(resultKind, setFlags ? Addcc : Add, a, b); + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Faddd : Fadds, a, b); + } + } + + @Override + public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { + if (isNumericInteger(a.getPlatformKind())) { + return emitBinary(resultKind, setFlags ? Subcc : Sub, a, b); + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Opfs.Fsubd : Opfs.Fsubs, a, b); + } + } + + @Override + public Variable emitMul(Value a, Value b, boolean setFlags) { + LIRKind resultKind = LIRKind.combine(a, b); + PlatformKind aKind = a.getPlatformKind(); + if (isNumericInteger(aKind)) { + if (setFlags) { + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b)); + if (aKind == DWORD) { + getLIRGen().append(new SPARCLMulccOp(result, getLIRGen().load(a), getLIRGen().load(b), getLIRGen())); + } else if (aKind == WORD) { + getLIRGen().append(new SPARCIMulccOp(result, getLIRGen().load(a), getLIRGen().load(b))); + } else { + throw JVMCIError.shouldNotReachHere(); + } + return result; + } else { + return emitBinary(resultKind, setFlags ? Op3s.Mulscc : Op3s.Mulx, a, b); + } + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Fmuld : Fmuls, a, b); + } + } + + @Override + public Value emitMulHigh(Value a, Value b) { + MulHigh opcode; + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: + opcode = MulHigh.IMUL; + break; + case DWORD: + opcode = MulHigh.LMUL; + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return emitMulHigh(opcode, a, b); + } + + @Override + public Value emitUMulHigh(Value a, Value b) { + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: + Value aExtended = emitBinary(LIRKind.combine(a), Srl, a, 0); + Value bExtended = emitBinary(LIRKind.combine(b), Srl, b, 0); + Value result = emitBinary(LIRKind.combine(a, b), Mulx, aExtended, bExtended); + return emitBinary(LIRKind.combine(a, b), Srax, result, WORD.getSizeInBits()); + case DWORD: + return emitBinary(LIRKind.combine(a, b), UMulxhi, a, b); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + private Value emitMulHigh(MulHigh opcode, Value a, Value b) { + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b)); + MulHighOp mulHigh = new MulHighOp(opcode, getLIRGen().load(a), getLIRGen().load(b), result, getLIRGen().newVariable(LIRKind.combine(a, b))); + getLIRGen().append(mulHigh); + return result; + } + + @Override + public Value emitDiv(Value a, Value b, LIRFrameState state) { + LIRKind resultKind = LIRKind.combine(a, b); + PlatformKind aKind = a.getPlatformKind(); + PlatformKind bKind = b.getPlatformKind(); + if (isJavaConstant(b) && asJavaConstant(b).isDefaultForKind()) { // Div by zero + Value zero = SPARC.g0.asValue(LIRKind.value(SPARCKind.WORD)); + return emitBinary(resultKind, Op3s.Sdivx, zero, zero, state); + } else if (isNumericInteger(aKind)) { + Value fixedA = emitSignExtend(a, aKind.getSizeInBytes() * 8, 64); + Value fixedB = emitSignExtend(b, bKind.getSizeInBytes() * 8, 64); + return emitBinary(resultKind, Op3s.Sdivx, fixedA, fixedB, state); + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Opfs.Fdivd : Opfs.Fdivs, a, b, state); + } + } + + @Override + public Value emitRem(Value a, Value b, LIRFrameState state) { + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b)); + Value aLoaded; + Value bLoaded; + Variable q1; // Intermediate values + Variable q2; + Variable q3; + Variable q4; + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + switch (aKind) { + case WORD: + q1 = emitBinary(result.getLIRKind(), Sra, a, g0.asValue(LIRKind.value(WORD))); + q2 = emitBinary(q1.getLIRKind(), Sdivx, q1, b, state); + q3 = emitBinary(q2.getLIRKind(), Op3s.Mulx, q2, b); + result = emitSub(q1, q3, false); + break; + case DWORD: + aLoaded = getLIRGen().load(a); // Reuse the loaded value + q1 = emitBinary(result.getLIRKind(), Sdivx, aLoaded, b, state); + q2 = emitBinary(result.getLIRKind(), Mulx, q1, b); + result = emitSub(aLoaded, q2, false); + break; + case SINGLE: + aLoaded = getLIRGen().load(a); + bLoaded = getLIRGen().load(b); + q1 = emitBinary(result.getLIRKind(), Fdivs, aLoaded, bLoaded, state); + q2 = getLIRGen().newVariable(LIRKind.value(aKind)); + getLIRGen().append(new FloatConvertOp(FloatConvertOp.FloatConvert.F2I, q1, q2)); + q3 = emitUnary(Fitos, q2); + q4 = emitBinary(LIRKind.value(aKind), Fmuls, q3, bLoaded); + result = emitSub(aLoaded, q4, false); + break; + case DOUBLE: + aLoaded = getLIRGen().load(a); + bLoaded = getLIRGen().load(b); + q1 = emitBinary(result.getLIRKind(), Fdivd, aLoaded, bLoaded, state); + q2 = getLIRGen().newVariable(LIRKind.value(aKind)); + getLIRGen().append(new FloatConvertOp(FloatConvertOp.FloatConvert.D2L, q1, q2)); + q3 = emitUnary(Fxtod, q2); + q4 = emitBinary(result.getLIRKind(), Fmuld, q3, bLoaded); + result = emitSub(aLoaded, q4, false); + break; + default: + throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); + } + return result; + } + + @Override + public Value emitURem(Value a, Value b, LIRFrameState state) { + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b)); + Variable scratch1 = getLIRGen().newVariable(LIRKind.combine(a, b)); + Variable scratch2 = getLIRGen().newVariable(LIRKind.combine(a, b)); + Rem opcode; + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: + opcode = Rem.IUREM; + break; + case DWORD: + opcode = Rem.LUREM; + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + getLIRGen().append(new RemOp(opcode, result, getLIRGen().load(a), getLIRGen().load(b), scratch1, scratch2, state)); + return result; + + } + + @Override + public Value emitUDiv(Value a, Value b, LIRFrameState state) { + Value actualA = a; + Value actualB = b; + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: + actualA = emitZeroExtend(actualA, 32, 64); + actualB = emitZeroExtend(actualB, 32, 64); + break; + case DWORD: + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return emitBinary(LIRKind.combine(actualA, actualB), Udivx, actualA, actualB, state); + } + + @Override + public Variable emitAnd(Value a, Value b) { + LIRKind resultKind = LIRKind.combine(a, b); + return emitBinary(resultKind, Op3s.And, a, b); + } + + @Override + public Variable emitOr(Value a, Value b) { + LIRKind resultKind = LIRKind.combine(a, b); + return emitBinary(resultKind, Op3s.Or, a, b); + } + + @Override + public Variable emitXor(Value a, Value b) { + LIRKind resultKind = LIRKind.combine(a, b); + return emitBinary(resultKind, Op3s.Xor, a, b); + } + + @Override + public Variable emitShl(Value a, Value b) { + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); + Op3s op; + switch (aKind) { + case WORD: + op = Op3s.Sll; + break; + case DWORD: + op = Op3s.Sllx; + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return emitBinary(resultKind, op, a, b); + } + + @Override + public Variable emitShr(Value a, Value b) { + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); + Op3s op; + switch (aKind) { + case WORD: + op = Op3s.Sra; + break; + case DWORD: + op = Op3s.Srax; + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return emitBinary(resultKind, op, a, b); + } + + @Override + public Variable emitUShr(Value a, Value b) { + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); + Op3s op; + switch (aKind) { + case WORD: + op = Op3s.Srl; + break; + case DWORD: + op = Op3s.Srlx; + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return emitBinary(resultKind, op, a, b); + } + + private AllocatableValue emitConvertMove(LIRKind kind, AllocatableValue input) { + Variable result = getLIRGen().newVariable(kind); + getLIRGen().emitMove(result, input); + return result; + } + + @Override + public Value emitFloatConvert(FloatConvert op, Value inputVal) { + AllocatableValue input = getLIRGen().asAllocatable(inputVal); + Value result; + switch (op) { + case D2F: + result = getLIRGen().newVariable(LIRKind.combine(inputVal).changeType(SINGLE)); + getLIRGen().append(new SPARCOPFOp(Fdtos, inputVal, result)); + break; + case F2D: + result = getLIRGen().newVariable(LIRKind.combine(inputVal).changeType(DOUBLE)); + getLIRGen().append(new SPARCOPFOp(Fstod, inputVal, result)); + break; + case I2F: { + AllocatableValue intEncodedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE)); + result = getLIRGen().newVariable(intEncodedFloatReg.getLIRKind()); + moveBetweenFpGp(intEncodedFloatReg, input); + getLIRGen().append(new SPARCOPFOp(Fitos, intEncodedFloatReg, result)); + break; + } + case I2D: { + // Unfortunately we must do int -> float -> double because fitod has float + // and double encoding in one instruction + AllocatableValue convertedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE)); + result = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE)); + moveBetweenFpGp(convertedFloatReg, input); + getLIRGen().append(new SPARCOPFOp(Fitod, convertedFloatReg, result)); + break; + } + case L2D: { + AllocatableValue longEncodedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE)); + moveBetweenFpGp(longEncodedDoubleReg, input); + AllocatableValue convertedDoubleReg = getLIRGen().newVariable(longEncodedDoubleReg.getLIRKind()); + getLIRGen().append(new SPARCOPFOp(Fxtod, longEncodedDoubleReg, convertedDoubleReg)); + result = convertedDoubleReg; + break; + } + case D2I: { + AllocatableValue convertedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE)); + getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2I, input, convertedFloatReg)); + AllocatableValue convertedIntReg = getLIRGen().newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD)); + moveBetweenFpGp(convertedIntReg, convertedFloatReg); + result = convertedIntReg; + break; + } + case F2L: { + AllocatableValue convertedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE)); + getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2L, input, convertedDoubleReg)); + AllocatableValue convertedLongReg = getLIRGen().newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD)); + moveBetweenFpGp(convertedLongReg, convertedDoubleReg); + result = convertedLongReg; + break; + } + case F2I: { + AllocatableValue convertedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE)); + getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2I, input, convertedFloatReg)); + AllocatableValue convertedIntReg = getLIRGen().newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD)); + moveBetweenFpGp(convertedIntReg, convertedFloatReg); + result = convertedIntReg; + break; + } + case D2L: { + AllocatableValue convertedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE)); + getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2L, input, convertedDoubleReg)); + AllocatableValue convertedLongReg = getLIRGen().newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD)); + moveBetweenFpGp(convertedLongReg, convertedDoubleReg); + result = convertedLongReg; + break; + } + case L2F: { + AllocatableValue convertedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE)); + result = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE)); + moveBetweenFpGp(convertedDoubleReg, input); + getLIRGen().append(new SPARCOPFOp(Opfs.Fxtos, convertedDoubleReg, result)); + break; + } + default: + throw JVMCIError.shouldNotReachHere(); + } + return result; + } + + private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) { + AllocatableValue tempSlot; + if (getLIRGen().getArchitecture().getFeatures().contains(CPUFeature.VIS3)) { + tempSlot = AllocatableValue.ILLEGAL; + } else { + tempSlot = getLIRGen().getTempSlot(LIRKind.value(DWORD)); + } + getLIRGen().append(new MoveFpGp(dst, src, tempSlot)); + } + + @Override + public Value emitNarrow(Value inputVal, int bits) { + if (inputVal.getPlatformKind() == DWORD && bits <= 32) { + LIRKind resultKind = LIRKind.combine(inputVal).changeType(WORD); + Variable result = getLIRGen().newVariable(resultKind); + getLIRGen().emitMove(result, inputVal); + return result; + } else { + return inputVal; + } + } + + @Override + public Value emitSignExtend(Value inputVal, int fromBits, int toBits) { + assert fromBits <= toBits && toBits <= DWORD.getSizeInBits(); + LIRKind shiftKind = LIRKind.value(WORD); + LIRKind resultKind = LIRKind.combine(inputVal).changeType(toBits > 32 ? DWORD : WORD); + Value result; + int shiftCount = DWORD.getSizeInBits() - fromBits; + if (fromBits == toBits) { + result = inputVal; + } else if (isJavaConstant(inputVal)) { + JavaConstant javaConstant = asJavaConstant(inputVal); + long constant; + if (javaConstant.isNull()) { + constant = 0; + } else { + constant = javaConstant.asLong(); + } + return new ConstantValue(resultKind, JavaConstant.forLong((constant << shiftCount) >> shiftCount)); + } else if (fromBits == WORD.getSizeInBits() && toBits == DWORD.getSizeInBits()) { + result = getLIRGen().newVariable(resultKind); + getLIRGen().append(new SPARCOP3Op(Sra, inputVal, SPARC.g0.asValue(LIRKind.value(WORD)), result)); + } else { + Variable tmp = getLIRGen().newVariable(resultKind.changeType(DWORD)); + result = getLIRGen().newVariable(resultKind); + getLIRGen().append(new SPARCOP3Op(Sllx, inputVal, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), tmp)); + getLIRGen().append(new SPARCOP3Op(Srax, tmp, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), result)); + } + return result; + } + + @Override + public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) { + assert fromBits <= toBits && toBits <= 64; + if (fromBits == toBits) { + return inputVal; + } + Variable result = getLIRGen().newVariable(LIRKind.combine(inputVal).changeType(toBits > WORD.getSizeInBits() ? DWORD : WORD)); + if (fromBits == 32) { + getLIRGen().append(new SPARCOP3Op(Srl, inputVal, g0.asValue(), result)); + } else { + Value mask = getLIRGen().emitConstant(LIRKind.value(DWORD), forLong(mask(fromBits))); + getLIRGen().append(new SPARCOP3Op(And, inputVal, mask, result)); + } + return result; + } + + @Override + public AllocatableValue emitReinterpret(LIRKind to, Value inputVal) { + SPARCKind fromKind = (SPARCKind) inputVal.getPlatformKind(); + SPARCKind toKind = (SPARCKind) to.getPlatformKind(); + AllocatableValue input = getLIRGen().asAllocatable(inputVal); + Variable result = getLIRGen().newVariable(to); + // These cases require a move between CPU and FPU registers: + if (fromKind.isFloat() != toKind.isFloat()) { + moveBetweenFpGp(result, input); + return result; + } else { + // Otherwise, just emit an ordinary move instruction. + // Instructions that move or generate 32-bit register values also set the upper 32 + // bits of the register to zero. + // Consequently, there is no need for a special zero-extension move. + return emitConvertMove(to, input); + } + } +}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -27,48 +27,14 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.FMOVSCC; import static com.oracle.graal.asm.sparc.SPARCAssembler.MOVicc; import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.Fcc0; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Add; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Addcc; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.And; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Mulx; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sdivx; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sllx; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sra; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srax; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srl; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sub; import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Subcc; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Udivx; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Xnor; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmpd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmps; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtos; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegs; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fstod; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fxtod; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.UMulxhi; import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant; import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant; -import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.BSF; -import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IBSR; -import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LBSR; -import static jdk.internal.jvmci.code.CodeUtil.mask; import static jdk.internal.jvmci.code.ValueUtil.isStackSlotValue; -import static jdk.internal.jvmci.meta.JavaConstant.forLong; -import static jdk.internal.jvmci.sparc.SPARC.g0; -import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE; import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE; -import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import jdk.internal.jvmci.code.CallingConvention; import jdk.internal.jvmci.code.StackSlotValue; import jdk.internal.jvmci.common.JVMCIError; @@ -80,7 +46,6 @@ import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; import jdk.internal.jvmci.sparc.SPARC; -import jdk.internal.jvmci.sparc.SPARC.CPUFeature; import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.sparc.SPARCAssembler; @@ -90,7 +55,6 @@ import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s; import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs; import com.oracle.graal.compiler.common.calc.Condition; -import com.oracle.graal.compiler.common.calc.FloatConvert; import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; import com.oracle.graal.compiler.common.spi.LIRKindTool; import com.oracle.graal.lir.ConstantValue; @@ -106,16 +70,7 @@ import com.oracle.graal.lir.gen.LIRGenerator; import com.oracle.graal.lir.gen.SpillMoveFactoryBase; import com.oracle.graal.lir.sparc.SPARCAddressValue; -import com.oracle.graal.lir.sparc.SPARCArithmetic; -import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp; -import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp.MulHigh; -import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp; -import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp.Rem; -import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCIMulccOp; -import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCLMulccOp; -import com.oracle.graal.lir.sparc.SPARCArithmetic.FloatConvertOp; import com.oracle.graal.lir.sparc.SPARCArrayEqualsOp; -import com.oracle.graal.lir.sparc.SPARCBitManipulationOp; import com.oracle.graal.lir.sparc.SPARCByteSwapOp; import com.oracle.graal.lir.sparc.SPARCCall; import com.oracle.graal.lir.sparc.SPARCControlFlow; @@ -134,11 +89,9 @@ import com.oracle.graal.lir.sparc.SPARCMove.LoadOp; import com.oracle.graal.lir.sparc.SPARCMove.MembarOp; import com.oracle.graal.lir.sparc.SPARCMove.Move; -import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp; import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; import com.oracle.graal.lir.sparc.SPARCOP3Op; -import com.oracle.graal.lir.sparc.SPARCOPFOp; import com.oracle.graal.phases.util.Providers; /** @@ -168,8 +121,8 @@ } } - public SPARCLIRGenerator(LIRKindTool lirKindTool, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) { - super(lirKindTool, providers, cc, lirGenRes); + public SPARCLIRGenerator(LIRKindTool lirKindTool, SPARCArithmeticLIRGenerator arithmeticLIRGen, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) { + super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes); } public SpillMoveFactory getSpillMoveFactory() { @@ -373,7 +326,7 @@ if (from == to) { return v; } else { - return emitSignExtend(v, fromBytes, toBytes); + return arithmeticLIRGen.emitSignExtend(v, fromBytes, toBytes); } } } @@ -477,10 +430,10 @@ int compareBytes = cmpKind.getSizeInBytes(); // SPARC compares 32 or 64 bits if (compareBytes < left.getPlatformKind().getSizeInBytes()) { - left = emitSignExtend(left, compareBytes * 8, DWORD.getSizeInBytes() * 8); + left = arithmeticLIRGen.emitSignExtend(left, compareBytes * 8, DWORD.getSizeInBytes() * 8); } if (compareBytes < right.getPlatformKind().getSizeInBytes()) { - right = emitSignExtend(right, compareBytes * 8, DWORD.getSizeInBytes() * 8); + right = arithmeticLIRGen.emitSignExtend(right, compareBytes * 8, DWORD.getSizeInBytes() * 8); } append(SPARCOP3Op.newBinaryVoid(Subcc, left, right)); return mirrored; @@ -548,72 +501,12 @@ append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(LIRKind.value(target().arch.getWordKind())))); } - @Override - public Variable emitBitCount(Value operand) { - Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); - Value usedOperand = operand; - if (operand.getPlatformKind() == SPARCKind.WORD) { // Zero extend - usedOperand = newVariable(operand.getLIRKind()); - append(new SPARCOP3Op(Op3s.Srl, operand, SPARC.g0.asValue(), usedOperand)); - } - append(new SPARCOP3Op(Op3s.Popc, SPARC.g0.asValue(), usedOperand, result)); - return result; - } - - @Override - public Variable emitBitScanForward(Value operand) { - Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); - append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand), this)); - return result; - } - - @Override - public Variable emitBitScanReverse(Value operand) { - Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); - if (operand.getPlatformKind() == SPARCKind.DWORD) { - append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand), this)); - } else { - append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand), this)); - } - return result; + protected StackSlotValue getTempSlot(LIRKind kind) { + return getResult().getFrameMapBuilder().allocateSpillSlot(kind); } - @Override - public Value emitMathAbs(Value input) { - Variable result = newVariable(LIRKind.combine(input)); - SPARCKind kind = (SPARCKind) input.getPlatformKind(); - Opfs opf; - switch (kind) { - case SINGLE: - opf = Opfs.Fabss; - break; - case DOUBLE: - opf = Opfs.Fabsd; - break; - default: - throw JVMCIError.shouldNotReachHere("Input kind: " + kind); - } - append(new SPARCOPFOp(opf, g0.asValue(), input, result)); - return result; - } - - @Override - public Value emitMathSqrt(Value input) { - Variable result = newVariable(LIRKind.combine(input)); - SPARCKind kind = (SPARCKind) input.getPlatformKind(); - Opfs opf; - switch (kind) { - case SINGLE: - opf = Opfs.Fsqrts; - break; - case DOUBLE: - opf = Opfs.Fsqrtd; - break; - default: - throw JVMCIError.shouldNotReachHere("Input kind: " + kind); - } - append(new SPARCOPFOp(opf, g0.asValue(), input, result)); - return result; + protected SPARC getArchitecture() { + return (SPARC) target().arch; } @Override @@ -631,512 +524,6 @@ } @Override - public Value emitNegate(Value input) { - PlatformKind inputKind = input.getPlatformKind(); - if (isNumericInteger(inputKind)) { - return emitUnary(Sub, input); - } else { - return emitUnary(inputKind.equals(DOUBLE) ? Fnegd : Fnegs, input); - } - } - - @Override - public Value emitNot(Value input) { - return emitUnary(Xnor, input); - } - - private Variable emitUnary(Opfs opf, Value input) { - Variable result = newVariable(LIRKind.combine(input)); - append(new SPARCOPFOp(opf, g0.asValue(), input, result)); - return result; - } - - private Variable emitUnary(Op3s op3, Value input) { - Variable result = newVariable(LIRKind.combine(input)); - append(SPARCOP3Op.newUnary(op3, input, result)); - return result; - } - - private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b) { - return emitBinary(resultKind, opf, a, b, null); - } - - private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b, LIRFrameState state) { - Variable result = newVariable(resultKind); - if (opf.isCommutative() && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) { - append(new SPARCOPFOp(opf, b, a, result, state)); - } else { - append(new SPARCOPFOp(opf, a, b, result, state)); - } - return result; - } - - private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, int b) { - return emitBinary(resultKind, op3, a, new ConstantValue(LIRKind.value(WORD), JavaConstant.forInt(b))); - } - - private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b) { - return emitBinary(resultKind, op3, a, b, null); - } - - private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b, LIRFrameState state) { - Variable result = newVariable(resultKind); - if (op3.isCommutative() && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) { - append(new SPARCOP3Op(op3, load(b), a, result, state)); - } else { - append(new SPARCOP3Op(op3, load(a), b, result, state)); - } - return result; - } - - @Override - protected boolean isNumericInteger(PlatformKind kind) { - return ((SPARCKind) kind).isInteger(); - } - - @Override - public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { - if (isNumericInteger(a.getPlatformKind())) { - return emitBinary(resultKind, setFlags ? Addcc : Add, a, b); - } else { - boolean isDouble = a.getPlatformKind().equals(DOUBLE); - return emitBinary(resultKind, isDouble ? Faddd : Fadds, a, b); - } - } - - @Override - public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { - if (isNumericInteger(a.getPlatformKind())) { - return emitBinary(resultKind, setFlags ? Subcc : Sub, a, b); - } else { - boolean isDouble = a.getPlatformKind().equals(DOUBLE); - return emitBinary(resultKind, isDouble ? Opfs.Fsubd : Opfs.Fsubs, a, b); - } - } - - @Override - public Variable emitMul(Value a, Value b, boolean setFlags) { - LIRKind resultKind = LIRKind.combine(a, b); - PlatformKind aKind = a.getPlatformKind(); - if (isNumericInteger(aKind)) { - if (setFlags) { - Variable result = newVariable(LIRKind.combine(a, b)); - if (aKind == DWORD) { - append(new SPARCLMulccOp(result, load(a), load(b), this)); - } else if (aKind == WORD) { - append(new SPARCIMulccOp(result, load(a), load(b))); - } else { - throw JVMCIError.shouldNotReachHere(); - } - return result; - } else { - return emitBinary(resultKind, setFlags ? Op3s.Mulscc : Op3s.Mulx, a, b); - } - } else { - boolean isDouble = a.getPlatformKind().equals(DOUBLE); - return emitBinary(resultKind, isDouble ? Fmuld : Fmuls, a, b); - } - } - - @Override - public Value emitMulHigh(Value a, Value b) { - MulHigh opcode; - switch (((SPARCKind) a.getPlatformKind())) { - case WORD: - opcode = MulHigh.IMUL; - break; - case DWORD: - opcode = MulHigh.LMUL; - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return emitMulHigh(opcode, a, b); - } - - @Override - public Value emitUMulHigh(Value a, Value b) { - switch (((SPARCKind) a.getPlatformKind())) { - case WORD: - Value aExtended = emitBinary(LIRKind.combine(a), Srl, a, 0); - Value bExtended = emitBinary(LIRKind.combine(b), Srl, b, 0); - Value result = emitBinary(LIRKind.combine(a, b), Mulx, aExtended, bExtended); - return emitBinary(LIRKind.combine(a, b), Srax, result, WORD.getSizeInBits()); - case DWORD: - return emitBinary(LIRKind.combine(a, b), UMulxhi, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private Value emitMulHigh(MulHigh opcode, Value a, Value b) { - Variable result = newVariable(LIRKind.combine(a, b)); - MulHighOp mulHigh = new MulHighOp(opcode, load(a), load(b), result, newVariable(LIRKind.combine(a, b))); - append(mulHigh); - return result; - } - - @Override - public Value emitDiv(Value a, Value b, LIRFrameState state) { - LIRKind resultKind = LIRKind.combine(a, b); - PlatformKind aKind = a.getPlatformKind(); - PlatformKind bKind = b.getPlatformKind(); - if (isJavaConstant(b) && asJavaConstant(b).isDefaultForKind()) { // Div by zero - Value zero = SPARC.g0.asValue(LIRKind.value(SPARCKind.WORD)); - return emitBinary(resultKind, Op3s.Sdivx, zero, zero, state); - } else if (isNumericInteger(aKind)) { - Value fixedA = emitSignExtend(a, aKind.getSizeInBytes() * 8, 64); - Value fixedB = emitSignExtend(b, bKind.getSizeInBytes() * 8, 64); - return emitBinary(resultKind, Op3s.Sdivx, fixedA, fixedB, state); - } else { - boolean isDouble = a.getPlatformKind().equals(DOUBLE); - return emitBinary(resultKind, isDouble ? Opfs.Fdivd : Opfs.Fdivs, a, b, state); - } - } - - @Override - public Value emitRem(Value a, Value b, LIRFrameState state) { - Variable result = newVariable(LIRKind.combine(a, b)); - Value aLoaded; - Value bLoaded; - Variable q1; // Intermediate values - Variable q2; - Variable q3; - Variable q4; - SPARCKind aKind = (SPARCKind) a.getPlatformKind(); - switch (aKind) { - case WORD: - q1 = emitBinary(result.getLIRKind(), Sra, a, g0.asValue(LIRKind.value(WORD))); - q2 = emitBinary(q1.getLIRKind(), Sdivx, q1, b, state); - q3 = emitBinary(q2.getLIRKind(), Op3s.Mulx, q2, b); - result = emitSub(q1, q3, false); - break; - case DWORD: - aLoaded = load(a); // Reuse the loaded value - q1 = emitBinary(result.getLIRKind(), Sdivx, aLoaded, b, state); - q2 = emitBinary(result.getLIRKind(), Mulx, q1, b); - result = emitSub(aLoaded, q2, false); - break; - case SINGLE: - aLoaded = load(a); - bLoaded = load(b); - q1 = emitBinary(result.getLIRKind(), Fdivs, aLoaded, bLoaded, state); - q2 = newVariable(LIRKind.value(aKind)); - append(new FloatConvertOp(FloatConvertOp.FloatConvert.F2I, q1, q2)); - q3 = emitUnary(Fitos, q2); - q4 = emitBinary(LIRKind.value(aKind), Fmuls, q3, bLoaded); - result = emitSub(aLoaded, q4, false); - break; - case DOUBLE: - aLoaded = load(a); - bLoaded = load(b); - q1 = emitBinary(result.getLIRKind(), Fdivd, aLoaded, bLoaded, state); - q2 = newVariable(LIRKind.value(aKind)); - append(new FloatConvertOp(FloatConvertOp.FloatConvert.D2L, q1, q2)); - q3 = emitUnary(Fxtod, q2); - q4 = emitBinary(result.getLIRKind(), Fmuld, q3, bLoaded); - result = emitSub(aLoaded, q4, false); - break; - default: - throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); - } - return result; - } - - @Override - public Value emitURem(Value a, Value b, LIRFrameState state) { - Variable result = newVariable(LIRKind.combine(a, b)); - Variable scratch1 = newVariable(LIRKind.combine(a, b)); - Variable scratch2 = newVariable(LIRKind.combine(a, b)); - Rem opcode; - switch (((SPARCKind) a.getPlatformKind())) { - case WORD: - opcode = Rem.IUREM; - break; - case DWORD: - opcode = Rem.LUREM; - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - append(new RemOp(opcode, result, load(a), load(b), scratch1, scratch2, state)); - return result; - - } - - @Override - public Value emitUDiv(Value a, Value b, LIRFrameState state) { - Value actualA = a; - Value actualB = b; - switch (((SPARCKind) a.getPlatformKind())) { - case WORD: - actualA = emitZeroExtend(actualA, 32, 64); - actualB = emitZeroExtend(actualB, 32, 64); - break; - case DWORD: - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return emitBinary(LIRKind.combine(actualA, actualB), Udivx, actualA, actualB, state); - } - - @Override - public Variable emitAnd(Value a, Value b) { - LIRKind resultKind = LIRKind.combine(a, b); - return emitBinary(resultKind, Op3s.And, a, b); - } - - @Override - public Variable emitOr(Value a, Value b) { - LIRKind resultKind = LIRKind.combine(a, b); - return emitBinary(resultKind, Op3s.Or, a, b); - } - - @Override - public Variable emitXor(Value a, Value b) { - LIRKind resultKind = LIRKind.combine(a, b); - return emitBinary(resultKind, Op3s.Xor, a, b); - } - - @Override - public Variable emitShl(Value a, Value b) { - SPARCKind aKind = (SPARCKind) a.getPlatformKind(); - LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); - Op3s op; - switch (aKind) { - case WORD: - op = Op3s.Sll; - break; - case DWORD: - op = Op3s.Sllx; - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return emitBinary(resultKind, op, a, b); - } - - @Override - public Variable emitShr(Value a, Value b) { - SPARCKind aKind = (SPARCKind) a.getPlatformKind(); - LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); - Op3s op; - switch (aKind) { - case WORD: - op = Op3s.Sra; - break; - case DWORD: - op = Op3s.Srax; - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return emitBinary(resultKind, op, a, b); - } - - @Override - public Variable emitUShr(Value a, Value b) { - SPARCKind aKind = (SPARCKind) a.getPlatformKind(); - LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); - Op3s op; - switch (aKind) { - case WORD: - op = Op3s.Srl; - break; - case DWORD: - op = Op3s.Srlx; - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - return emitBinary(resultKind, op, a, b); - } - - private AllocatableValue emitConvertMove(LIRKind kind, AllocatableValue input) { - Variable result = newVariable(kind); - emitMove(result, input); - return result; - } - - @Override - public Value emitFloatConvert(FloatConvert op, Value inputVal) { - AllocatableValue input = asAllocatable(inputVal); - Value result; - switch (op) { - case D2F: - result = newVariable(LIRKind.combine(inputVal).changeType(SINGLE)); - append(new SPARCOPFOp(Fdtos, inputVal, result)); - break; - case F2D: - result = newVariable(LIRKind.combine(inputVal).changeType(DOUBLE)); - append(new SPARCOPFOp(Fstod, inputVal, result)); - break; - case I2F: { - AllocatableValue intEncodedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); - result = newVariable(intEncodedFloatReg.getLIRKind()); - moveBetweenFpGp(intEncodedFloatReg, input); - append(new SPARCOPFOp(Fitos, intEncodedFloatReg, result)); - break; - } - case I2D: { - // Unfortunately we must do int -> float -> double because fitod has float - // and double encoding in one instruction - AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); - result = newVariable(LIRKind.combine(input).changeType(DOUBLE)); - moveBetweenFpGp(convertedFloatReg, input); - append(new SPARCOPFOp(Fitod, convertedFloatReg, result)); - break; - } - case L2D: { - AllocatableValue longEncodedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); - moveBetweenFpGp(longEncodedDoubleReg, input); - AllocatableValue convertedDoubleReg = newVariable(longEncodedDoubleReg.getLIRKind()); - append(new SPARCOPFOp(Fxtod, longEncodedDoubleReg, convertedDoubleReg)); - result = convertedDoubleReg; - break; - } - case D2I: { - AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); - append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2I, input, convertedFloatReg)); - AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD)); - moveBetweenFpGp(convertedIntReg, convertedFloatReg); - result = convertedIntReg; - break; - } - case F2L: { - AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); - append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2L, input, convertedDoubleReg)); - AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD)); - moveBetweenFpGp(convertedLongReg, convertedDoubleReg); - result = convertedLongReg; - break; - } - case F2I: { - AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); - append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2I, input, convertedFloatReg)); - AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD)); - moveBetweenFpGp(convertedIntReg, convertedFloatReg); - result = convertedIntReg; - break; - } - case D2L: { - AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); - append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2L, input, convertedDoubleReg)); - AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD)); - moveBetweenFpGp(convertedLongReg, convertedDoubleReg); - result = convertedLongReg; - break; - } - case L2F: { - AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); - result = newVariable(LIRKind.combine(input).changeType(SINGLE)); - moveBetweenFpGp(convertedDoubleReg, input); - append(new SPARCOPFOp(Opfs.Fxtos, convertedDoubleReg, result)); - break; - } - default: - throw JVMCIError.shouldNotReachHere(); - } - return result; - } - - private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) { - AllocatableValue tempSlot; - if (getArchitecture().getFeatures().contains(CPUFeature.VIS3)) { - tempSlot = AllocatableValue.ILLEGAL; - } else { - tempSlot = getTempSlot(LIRKind.value(DWORD)); - } - append(new MoveFpGp(dst, src, tempSlot)); - } - - protected StackSlotValue getTempSlot(LIRKind kind) { - return getResult().getFrameMapBuilder().allocateSpillSlot(kind); - } - - protected SPARC getArchitecture() { - return (SPARC) target().arch; - } - - @Override - public Value emitNarrow(Value inputVal, int bits) { - if (inputVal.getPlatformKind() == DWORD && bits <= 32) { - LIRKind resultKind = LIRKind.combine(inputVal).changeType(WORD); - Variable result = newVariable(resultKind); - emitMove(result, inputVal); - return result; - } else { - return inputVal; - } - } - - @Override - public Value emitSignExtend(Value inputVal, int fromBits, int toBits) { - assert fromBits <= toBits && toBits <= DWORD.getSizeInBits(); - LIRKind shiftKind = LIRKind.value(WORD); - LIRKind resultKind = LIRKind.combine(inputVal).changeType(toBits > 32 ? DWORD : WORD); - Value result; - int shiftCount = DWORD.getSizeInBits() - fromBits; - if (fromBits == toBits) { - result = inputVal; - } else if (isJavaConstant(inputVal)) { - JavaConstant javaConstant = asJavaConstant(inputVal); - long constant; - if (javaConstant.isNull()) { - constant = 0; - } else { - constant = javaConstant.asLong(); - } - return new ConstantValue(resultKind, JavaConstant.forLong((constant << shiftCount) >> shiftCount)); - } else if (fromBits == WORD.getSizeInBits() && toBits == DWORD.getSizeInBits()) { - result = newVariable(resultKind); - append(new SPARCOP3Op(Sra, inputVal, SPARC.g0.asValue(LIRKind.value(WORD)), result)); - } else { - Variable tmp = newVariable(resultKind.changeType(DWORD)); - result = newVariable(resultKind); - append(new SPARCOP3Op(Sllx, inputVal, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), tmp)); - append(new SPARCOP3Op(Srax, tmp, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), result)); - } - return result; - } - - @Override - public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) { - assert fromBits <= toBits && toBits <= 64; - if (fromBits == toBits) { - return inputVal; - } - Variable result = newVariable(LIRKind.combine(inputVal).changeType(toBits > WORD.getSizeInBits() ? DWORD : WORD)); - if (fromBits == 32) { - append(new SPARCOP3Op(Srl, inputVal, g0.asValue(), result)); - } else { - Value mask = emitConstant(LIRKind.value(DWORD), forLong(mask(fromBits))); - append(new SPARCOP3Op(And, inputVal, mask, result)); - } - return result; - } - - @Override - public AllocatableValue emitReinterpret(LIRKind to, Value inputVal) { - SPARCKind fromKind = (SPARCKind) inputVal.getPlatformKind(); - SPARCKind toKind = (SPARCKind) to.getPlatformKind(); - AllocatableValue input = asAllocatable(inputVal); - Variable result = newVariable(to); - // These cases require a move between CPU and FPU registers: - if (fromKind.isFloat() != toKind.isFloat()) { - moveBetweenFpGp(result, input); - return result; - } else { - // Otherwise, just emit an ordinary move instruction. - // Instructions that move or generate 32-bit register values also set the upper 32 - // bits of the register to zero. - // Consequently, there is no need for a special zero-extension move. - return emitConvertMove(to, input); - } - } - - @Override public void emitMembar(int barriers) { int necessaryBarriers = target().arch.requiredBarriers(barriers); if (target().isMP && necessaryBarriers != 0) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeMatchRules.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeMatchRules.java Thu Oct 08 15:58:13 2015 -0700 @@ -88,7 +88,7 @@ SPARCKind localToKind = toKind; return builder -> { Value v = getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access)); - return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v); + return getArithmeticLIRGenerator().emitReinterpret(LIRKind.value(localToKind), v); }; } @@ -123,7 +123,7 @@ return builder -> { // Loads are always zero extending load Value v = getLIRGeneratorTool().emitLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access)); - return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v); + return getArithmeticLIRGenerator().emitReinterpret(LIRKind.value(localToKind), v); }; } @@ -143,4 +143,8 @@ public SPARCLIRGenerator getLIRGeneratorTool() { return (SPARCLIRGenerator) super.getLIRGeneratorTool(); } + + protected SPARCArithmeticLIRGenerator getArithmeticLIRGenerator() { + return (SPARCArithmeticLIRGenerator) getLIRGeneratorTool().getArithmetic(); + } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Thu Oct 08 15:58:13 2015 -0700 @@ -105,7 +105,6 @@ import com.oracle.graal.nodes.cfg.ControlFlowGraph; import com.oracle.graal.nodes.extended.IntegerSwitchNode; import com.oracle.graal.nodes.extended.SwitchNode; -import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; import com.oracle.graal.nodes.spi.LIRLowerable; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; import com.oracle.graal.nodes.spi.NodeValueMap; @@ -427,8 +426,6 @@ } if (node instanceof LIRLowerable) { ((LIRLowerable) node).generate(this); - } else if (node instanceof ArithmeticLIRLowerable) { - ((ArithmeticLIRLowerable) node).generate(this, gen); } else { throw JVMCIError.shouldNotReachHere("node is not LIRLowerable: " + node); }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Oct 08 15:58:13 2015 -0700 @@ -50,6 +50,7 @@ import com.oracle.graal.asm.amd64.AMD64Address; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.asm.amd64.AMD64MacroAssembler; +import com.oracle.graal.compiler.amd64.AMD64ArithmeticLIRGenerator; import com.oracle.graal.compiler.amd64.AMD64NodeMatchRules; import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig; import com.oracle.graal.compiler.gen.BytecodeLIRBuilder; @@ -96,7 +97,7 @@ @Override public LIRGeneratorTool newLIRGenerator(CallingConvention cc, LIRGenerationResult lirGenRes) { - return new AMD64HotSpotLIRGenerator(getProviders(), config(), cc, lirGenRes); + return new AMD64HotSpotLIRGenerator(new AMD64ArithmeticLIRGenerator(), getProviders(), config(), cc, lirGenRes); } @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -66,6 +66,7 @@ import com.oracle.graal.asm.amd64.AMD64Address.Scale; import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp; import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize; +import com.oracle.graal.compiler.amd64.AMD64ArithmeticLIRGenerator; import com.oracle.graal.compiler.amd64.AMD64LIRGenerator; import com.oracle.graal.compiler.common.GraalOptions; import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; @@ -112,12 +113,13 @@ final HotSpotVMConfig config; private HotSpotLockStack lockStack; - protected AMD64HotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { - this(new AMD64HotSpotLIRKindTool(), providers, config, cc, lirGenRes); + protected AMD64HotSpotLIRGenerator(AMD64ArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { + this(new AMD64HotSpotLIRKindTool(), arithmeticLIRGen, providers, config, cc, lirGenRes); } - protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { - super(lirKindTool, providers, cc, lirGenRes); + protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, + LIRGenerationResult lirGenRes) { + super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes); assert config.basicLockSize == 8; this.config = config; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Thu Oct 08 15:58:13 2015 -0700 @@ -64,6 +64,7 @@ import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; +import com.oracle.graal.compiler.sparc.SPARCArithmeticLIRGenerator; import com.oracle.graal.compiler.sparc.SPARCNodeMatchRules; import com.oracle.graal.debug.Debug; import com.oracle.graal.debug.DebugMetric; @@ -135,7 +136,7 @@ @Override public LIRGeneratorTool newLIRGenerator(CallingConvention cc, LIRGenerationResult lirGenRes) { - return new SPARCHotSpotLIRGenerator(getProviders(), config(), cc, lirGenRes); + return new SPARCHotSpotLIRGenerator(new SPARCArithmeticLIRGenerator(), getProviders(), config(), cc, lirGenRes); } @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -98,6 +98,7 @@ import com.oracle.graal.compiler.common.calc.Condition; import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; import com.oracle.graal.compiler.common.spi.LIRKindTool; +import com.oracle.graal.compiler.sparc.SPARCArithmeticLIRGenerator; import com.oracle.graal.compiler.sparc.SPARCLIRGenerator; import com.oracle.graal.hotspot.HotSpotBackend; import com.oracle.graal.hotspot.HotSpotForeignCallLinkage; @@ -132,12 +133,13 @@ private HotSpotLockStack lockStack; private LIRFrameState currentRuntimeCallInfo; - public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { - this(new SPARCHotSpotLIRKindTool(), providers, config, cc, lirGenRes); + public SPARCHotSpotLIRGenerator(SPARCArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { + this(new SPARCHotSpotLIRKindTool(), arithmeticLIRGen, providers, config, cc, lirGenRes); } - protected SPARCHotSpotLIRGenerator(LIRKindTool lirKindTool, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { - super(lirKindTool, providers, cc, lirGenRes); + protected SPARCHotSpotLIRGenerator(LIRKindTool lirKindTool, SPARCArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, + LIRGenerationResult lirGenRes) { + super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes); assert config.basicLockSize == 8; this.config = config; }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArithmeticLIRGenerator.java Thu Oct 08 14:58:22 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.amd64; - -import jdk.internal.jvmci.meta.Value; - -/** - * This interface can be used to generate AMD64 LIR for arithmetic operations. - */ -public interface AMD64ArithmeticLIRGenerator { - - Value emitMathLog(Value input, boolean base10); - - Value emitMathCos(Value input); - - Value emitMathSin(Value input); - - Value emitMathTan(Value input); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArithmeticLIRGeneratorTool.java Thu Oct 08 15:58:13 2015 -0700 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.amd64; + +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; + +import jdk.internal.jvmci.meta.Value; + +/** + * This interface can be used to generate AMD64 LIR for arithmetic operations. + */ +public interface AMD64ArithmeticLIRGeneratorTool extends ArithmeticLIRGeneratorTool { + + Value emitMathLog(Value input, boolean base10); + + Value emitMathCos(Value input); + + Value emitMathSin(Value input); + + Value emitMathTan(Value input); + + Value emitCountLeadingZeros(Value value); + + Value emitCountTrailingZeros(Value value); +}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGenerator.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,71 +22,111 @@ */ package com.oracle.graal.lir.gen; +import jdk.internal.jvmci.meta.AllocatableValue; import jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; -import com.oracle.graal.compiler.common.calc.FloatConvert; -import com.oracle.graal.compiler.common.type.Stamp; -import com.oracle.graal.lir.LIRFrameState; +import com.oracle.graal.lir.Variable; /** - * This interface can be used to generate LIR for arithmetic operations. - * - * The setFlags flag in emitAdd, emitSub and emitMul indicates, that the instruction must set the - * flags register to be used for a later branch. (On AMD64, the condition codes are set in every - * arithmetic instruction, but other architectures optionally set the flags register) If setFlags is - * set, the instruction must set the flags register; if false, the instruction may or may not set - * the flags register. + * This class traverses the HIR instructions and generates LIR instructions from them. */ -public interface ArithmeticLIRGenerator { +public abstract class ArithmeticLIRGenerator implements ArithmeticLIRGeneratorTool { + + LIRGenerator lirGen; - LIRKind getLIRKind(Stamp stamp); + public LIRGenerator getLIRGen() { + return lirGen; + } - Value emitNegate(Value input); + // automatic derived reference handling - Value emitAdd(Value a, Value b, boolean setFlags); - - Value emitSub(Value a, Value b, boolean setFlags); + protected abstract boolean isNumericInteger(PlatformKind kind); - Value emitMul(Value a, Value b, boolean setFlags); - - Value emitMulHigh(Value a, Value b); + protected abstract Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags); - Value emitUMulHigh(Value a, Value b); - - Value emitDiv(Value a, Value b, LIRFrameState state); + @Override + public final Variable emitAdd(Value aVal, Value bVal, boolean setFlags) { + LIRKind resultKind; + Value a = aVal; + Value b = bVal; - Value emitRem(Value a, Value b, LIRFrameState state); - - Value emitUDiv(Value a, Value b, LIRFrameState state); + if (isNumericInteger(a.getPlatformKind())) { + LIRKind aKind = a.getLIRKind(); + LIRKind bKind = b.getLIRKind(); + assert a.getPlatformKind() == b.getPlatformKind(); - Value emitURem(Value a, Value b, LIRFrameState state); - - Value emitNot(Value input); - - Value emitAnd(Value a, Value b); + if (aKind.isUnknownReference()) { + resultKind = aKind; + } else if (bKind.isUnknownReference()) { + resultKind = bKind; + } else if (aKind.isValue() && bKind.isValue()) { + resultKind = aKind; + } else if (aKind.isValue()) { + if (bKind.isDerivedReference()) { + resultKind = bKind; + } else { + AllocatableValue allocatable = getLIRGen().asAllocatable(b); + resultKind = bKind.makeDerivedReference(allocatable); + b = allocatable; + } + } else if (bKind.isValue()) { + if (aKind.isDerivedReference()) { + resultKind = aKind; + } else { + AllocatableValue allocatable = getLIRGen().asAllocatable(a); + resultKind = aKind.makeDerivedReference(allocatable); + a = allocatable; + } + } else { + resultKind = aKind.makeUnknownReference(); + } + } else { + resultKind = LIRKind.combine(a, b); + } - Value emitOr(Value a, Value b); - - Value emitXor(Value a, Value b); + return emitAdd(resultKind, a, b, setFlags); + } - Value emitShl(Value a, Value b); - - Value emitShr(Value a, Value b); + protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags); - Value emitUShr(Value a, Value b); - - Value emitFloatConvert(FloatConvert op, Value inputVal); + @Override + public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) { + LIRKind resultKind; + Value a = aVal; + Value b = bVal; - Value emitReinterpret(LIRKind to, Value inputVal); + if (isNumericInteger(a.getPlatformKind())) { + LIRKind aKind = a.getLIRKind(); + LIRKind bKind = b.getLIRKind(); + assert a.getPlatformKind() == b.getPlatformKind(); - Value emitNarrow(Value inputVal, int bits); + if (aKind.isUnknownReference()) { + resultKind = aKind; + } else if (bKind.isUnknownReference()) { + resultKind = bKind; + } - Value emitSignExtend(Value inputVal, int fromBits, int toBits); - - Value emitZeroExtend(Value inputVal, int fromBits, int toBits); + if (aKind.isValue() && bKind.isValue()) { + resultKind = aKind; + } else if (bKind.isValue()) { + if (aKind.isDerivedReference()) { + resultKind = aKind; + } else { + AllocatableValue allocatable = getLIRGen().asAllocatable(a); + resultKind = aKind.makeDerivedReference(allocatable); + a = allocatable; + } + } else if (aKind.isDerivedReference() && bKind.isDerivedReference() && aKind.getDerivedReferenceBase().equals(bKind.getDerivedReferenceBase())) { + resultKind = LIRKind.value(a.getPlatformKind()); + } else { + resultKind = aKind.makeUnknownReference(); + } + } else { + resultKind = LIRKind.combine(a, b); + } - Value emitMathAbs(Value input); - - Value emitMathSqrt(Value input); + return emitSub(resultKind, a, b, setFlags); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGeneratorTool.java Thu Oct 08 15:58:13 2015 -0700 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.gen; + +import jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.meta.Value; + +import com.oracle.graal.compiler.common.calc.FloatConvert; +import com.oracle.graal.lir.LIRFrameState; + +/** + * This interface can be used to generate LIR for arithmetic operations. + * + * The setFlags flag in emitAdd, emitSub and emitMul indicates, that the instruction must set the + * flags register to be used for a later branch. (On AMD64, the condition codes are set in every + * arithmetic instruction, but other architectures optionally set the flags register) If setFlags is + * set, the instruction must set the flags register; if false, the instruction may or may not set + * the flags register. + */ +public interface ArithmeticLIRGeneratorTool { + + Value emitNegate(Value input); + + Value emitAdd(Value a, Value b, boolean setFlags); + + Value emitSub(Value a, Value b, boolean setFlags); + + Value emitMul(Value a, Value b, boolean setFlags); + + Value emitMulHigh(Value a, Value b); + + Value emitUMulHigh(Value a, Value b); + + Value emitDiv(Value a, Value b, LIRFrameState state); + + Value emitRem(Value a, Value b, LIRFrameState state); + + Value emitUDiv(Value a, Value b, LIRFrameState state); + + Value emitURem(Value a, Value b, LIRFrameState state); + + Value emitNot(Value input); + + Value emitAnd(Value a, Value b); + + Value emitOr(Value a, Value b); + + Value emitXor(Value a, Value b); + + Value emitShl(Value a, Value b); + + Value emitShr(Value a, Value b); + + Value emitUShr(Value a, Value b); + + Value emitFloatConvert(FloatConvert op, Value inputVal); + + Value emitReinterpret(LIRKind to, Value inputVal); + + Value emitNarrow(Value inputVal, int bits); + + Value emitSignExtend(Value inputVal, int fromBits, int toBits); + + Value emitZeroExtend(Value inputVal, int fromBits, int toBits); + + Value emitMathAbs(Value input); + + Value emitMathSqrt(Value input); + + Value emitBitCount(Value operand); + + Value emitBitScanForward(Value operand); + + Value emitBitScanReverse(Value operand); +}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Thu Oct 08 15:58:13 2015 -0700 @@ -95,11 +95,22 @@ private LIRGenerationResult res; - public LIRGenerator(LIRKindTool lirKindTool, CodeGenProviders providers, CallingConvention cc, LIRGenerationResult res) { + protected final ArithmeticLIRGenerator arithmeticLIRGen; + + public LIRGenerator(LIRKindTool lirKindTool, ArithmeticLIRGenerator arithmeticLIRGen, CodeGenProviders providers, CallingConvention cc, LIRGenerationResult res) { this.lirKindTool = lirKindTool; + this.arithmeticLIRGen = arithmeticLIRGen; this.res = res; this.providers = providers; this.cc = cc; + + assert arithmeticLIRGen.lirGen == null; + arithmeticLIRGen.lirGen = this; + } + + @Override + public ArithmeticLIRGeneratorTool getArithmetic() { + return arithmeticLIRGen; } @Override @@ -126,7 +137,7 @@ return providers.getForeignCalls(); } - protected LIRKindTool getLIRKindTool() { + public LIRKindTool getLIRKindTool() { return lirKindTool; } @@ -194,7 +205,7 @@ * @return True if the constant can be used directly, false if the constant needs to be in a * register. */ - protected abstract boolean canInlineConstant(JavaConstant c); + public abstract boolean canInlineConstant(JavaConstant c); public Value loadNonConst(Value value) { if (isJavaConstant(value) && !canInlineConstant(asJavaConstant(value))) { @@ -426,92 +437,4 @@ public LIRInstruction createMultiBenchmarkCounter(String[] names, String[] groups, Value[] increments) { throw JVMCIError.unimplemented(); } - - // automatic derived reference handling - - protected abstract boolean isNumericInteger(PlatformKind kind); - - protected abstract Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags); - - public final Variable emitAdd(Value aVal, Value bVal, boolean setFlags) { - LIRKind resultKind; - Value a = aVal; - Value b = bVal; - - if (isNumericInteger(a.getPlatformKind())) { - LIRKind aKind = a.getLIRKind(); - LIRKind bKind = b.getLIRKind(); - assert a.getPlatformKind() == b.getPlatformKind(); - - if (aKind.isUnknownReference()) { - resultKind = aKind; - } else if (bKind.isUnknownReference()) { - resultKind = bKind; - } else if (aKind.isValue() && bKind.isValue()) { - resultKind = aKind; - } else if (aKind.isValue()) { - if (bKind.isDerivedReference()) { - resultKind = bKind; - } else { - AllocatableValue allocatable = asAllocatable(b); - resultKind = bKind.makeDerivedReference(allocatable); - b = allocatable; - } - } else if (bKind.isValue()) { - if (aKind.isDerivedReference()) { - resultKind = aKind; - } else { - AllocatableValue allocatable = asAllocatable(a); - resultKind = aKind.makeDerivedReference(allocatable); - a = allocatable; - } - } else { - resultKind = aKind.makeUnknownReference(); - } - } else { - resultKind = LIRKind.combine(a, b); - } - - return emitAdd(resultKind, a, b, setFlags); - } - - protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags); - - public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) { - LIRKind resultKind; - Value a = aVal; - Value b = bVal; - - if (isNumericInteger(a.getPlatformKind())) { - LIRKind aKind = a.getLIRKind(); - LIRKind bKind = b.getLIRKind(); - assert a.getPlatformKind() == b.getPlatformKind(); - - if (aKind.isUnknownReference()) { - resultKind = aKind; - } else if (bKind.isUnknownReference()) { - resultKind = bKind; - } - - if (aKind.isValue() && bKind.isValue()) { - resultKind = aKind; - } else if (bKind.isValue()) { - if (aKind.isDerivedReference()) { - resultKind = aKind; - } else { - AllocatableValue allocatable = asAllocatable(a); - resultKind = aKind.makeDerivedReference(allocatable); - a = allocatable; - } - } else if (aKind.isDerivedReference() && bKind.isDerivedReference() && aKind.getDerivedReferenceBase().equals(bKind.getDerivedReferenceBase())) { - resultKind = LIRKind.value(a.getPlatformKind()); - } else { - resultKind = aKind.makeUnknownReference(); - } - } else { - resultKind = LIRKind.combine(a, b); - } - - return emitSub(resultKind, a, b, setFlags); - } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Thu Oct 08 15:58:13 2015 -0700 @@ -43,13 +43,14 @@ import com.oracle.graal.compiler.common.spi.CodeGenProviders; import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; import com.oracle.graal.compiler.common.spi.ForeignCallsProvider; +import com.oracle.graal.compiler.common.type.Stamp; import com.oracle.graal.lir.LIRFrameState; import com.oracle.graal.lir.LIRInstruction; import com.oracle.graal.lir.LabelRef; import com.oracle.graal.lir.SwitchStrategy; import com.oracle.graal.lir.Variable; -public interface LIRGeneratorTool extends ArithmeticLIRGenerator, BenchmarkCounterFactory { +public interface LIRGeneratorTool extends BenchmarkCounterFactory { /** * Factory for creating spill moves. @@ -74,6 +75,8 @@ } + ArithmeticLIRGeneratorTool getArithmetic(); + CodeGenProviders getProviders(); TargetDescription target(); @@ -228,26 +231,11 @@ CallingConvention getCallingConvention(); - Variable emitBitCount(Value operand); - - Variable emitBitScanForward(Value operand); - - Variable emitBitScanReverse(Value operand); - Variable emitByteSwap(Value operand); Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length); void emitBlackhole(Value operand); - @SuppressWarnings("unused") - default Value emitCountLeadingZeros(Value value) { - throw JVMCIError.unimplemented(); - } - - @SuppressWarnings("unused") - default Value emitCountTrailingZeros(Value value) { - throw JVMCIError.unimplemented(); - } - + LIRKind getLIRKind(Stamp stamp); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AbsNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AbsNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -26,11 +26,11 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Abs; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * Absolute value. @@ -56,7 +56,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitMathAbs(nodeValueMap.operand(getValue()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -32,11 +32,11 @@ import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = "+") public class AddNode extends BinaryArithmeticNode<Add> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> { @@ -112,7 +112,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { Value op1 = nodeValueMap.operand(getX()); assert op1 != null : getX() + ", this=" + this; Value op2 = nodeValueMap.operand(getY());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -35,11 +35,11 @@ import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; import com.oracle.graal.nodes.util.GraphUtil; @NodeInfo(shortName = "&") @@ -106,7 +106,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitAnd(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -32,11 +32,11 @@ import com.oracle.graal.compiler.common.type.Stamp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = "/") public final class DivNode extends BinaryArithmeticNode<Div> { @@ -94,7 +94,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitDiv(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null)); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -32,13 +32,13 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.FloatConvertOp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; import com.oracle.graal.nodes.spi.Lowerable; import com.oracle.graal.nodes.spi.LoweringTool; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * A {@code FloatConvert} converts between integers and floating point numbers according to Java @@ -117,7 +117,8 @@ tool.getLowerer().lower(this, tool); } - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + @Override + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitFloatConvert(getFloatConvert(), nodeValueMap.operand(getValue()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -119,7 +119,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -79,7 +79,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(getX()), gen.operand(getY()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitRem(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -28,11 +28,11 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.ShiftOp.Shl; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = "<<") public final class LeftShiftNode extends ShiftNode<Shl> { @@ -86,7 +86,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitShl(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -34,11 +34,11 @@ import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = "*") public class MulNode extends BinaryArithmeticNode<Mul> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> { @@ -97,7 +97,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { Value op1 = nodeValueMap.operand(getX()); Value op2 = nodeValueMap.operand(getY()); if (!getY().isConstant() && !BinaryArithmeticNode.livesLonger(this, getY(), nodeValueMap)) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -29,10 +29,10 @@ import com.oracle.graal.compiler.common.type.PrimitiveStamp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * The {@code NarrowNode} converts an integer to a narrower integer. @@ -109,7 +109,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitNarrow(nodeValueMap.operand(getValue()), getResultBits())); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -26,10 +26,10 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Neg; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * The {@code NegateNode} node negates its operand. @@ -60,7 +60,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitNegate(nodeValueMap.operand(getValue()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -26,11 +26,11 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Not; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * Binary negation of long or integer values. @@ -57,7 +57,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitNot(nodeValueMap.operand(getValue()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -34,11 +34,11 @@ import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; import com.oracle.graal.nodes.util.GraphUtil; @NodeInfo(shortName = "|") @@ -93,7 +93,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitOr(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -34,12 +34,12 @@ import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * The {@code ReinterpretNode} class represents a reinterpreting conversion that changes the stamp @@ -90,9 +90,9 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { - LIRKind kind = gen.getLIRKind(stamp()); - nodeValueMap.setResult(this, gen.emitReinterpret(kind, nodeValueMap.operand(getValue()))); + public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) { + LIRKind kind = builder.getLIRGeneratorTool().getLIRKind(stamp()); + builder.setResult(this, gen.emitReinterpret(kind, builder.operand(getValue()))); } public static ValueNode reinterpret(JavaKind toKind, ValueNode value) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RemNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RemNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -25,12 +25,12 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Rem; import com.oracle.graal.graph.NodeClass; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.spi.Lowerable; import com.oracle.graal.nodes.spi.LoweringTool; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = "%") public final class RemNode extends BinaryArithmeticNode<Rem> implements Lowerable { @@ -47,7 +47,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitRem(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null)); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -29,11 +29,11 @@ import com.oracle.graal.compiler.common.type.IntegerStamp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = ">>") public final class RightShiftNode extends ShiftNode<Shr> { @@ -99,7 +99,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitShr(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()))); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -30,10 +30,10 @@ import com.oracle.graal.compiler.common.type.PrimitiveStamp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * The {@code SignExtendNode} converts an integer to a wider integer using sign extension. @@ -105,7 +105,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitSignExtend(nodeValueMap.operand(getValue()), getInputBits(), getResultBits())); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SqrtNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SqrtNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -25,11 +25,11 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Sqrt; import com.oracle.graal.graph.NodeClass; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * Square root. @@ -44,7 +44,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitMathSqrt(nodeValueMap.operand(getValue()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -33,11 +33,11 @@ import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; import com.oracle.graal.nodes.util.GraphUtil; @NodeInfo(shortName = "-") @@ -156,7 +156,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitSub(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), false)); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -76,7 +76,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitUDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitUDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -75,7 +75,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitURem(gen.operand(getX()), gen.operand(getY()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitURem(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -29,11 +29,11 @@ import com.oracle.graal.compiler.common.type.IntegerStamp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = ">>>") public final class UnsignedRightShiftNode extends ShiftNode<UShr> { @@ -87,7 +87,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitUShr(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()))); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -34,11 +34,11 @@ import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; import com.oracle.graal.nodes.util.GraphUtil; @NodeInfo(shortName = "^") @@ -94,7 +94,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitXor(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -34,10 +34,10 @@ import com.oracle.graal.compiler.common.type.Stamp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * The {@code ZeroExtendNode} converts an integer to a wider integer using zero extension. @@ -119,7 +119,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitZeroExtend(nodeValueMap.operand(getValue()), getInputBits(), getResultBits())); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java Thu Oct 08 15:58:13 2015 -0700 @@ -22,10 +22,14 @@ */ package com.oracle.graal.nodes.spi; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodes.ArithmeticOperation; -public interface ArithmeticLIRLowerable extends ArithmeticOperation { +public interface ArithmeticLIRLowerable extends ArithmeticOperation, LIRLowerable { - void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen); + default void generate(NodeLIRBuilderTool builder) { + generate(builder, builder.getLIRGeneratorTool().getArithmetic()); + } + + void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen); }
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -25,25 +25,26 @@ import jdk.internal.jvmci.code.CodeUtil; import jdk.internal.jvmci.meta.JavaConstant; import jdk.internal.jvmci.meta.JavaKind; -import jdk.internal.jvmci.meta.Value; import com.oracle.graal.compiler.common.type.IntegerStamp; import com.oracle.graal.compiler.common.type.PrimitiveStamp; import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; +import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGeneratorTool; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.UnaryNode; -import com.oracle.graal.nodes.spi.LIRLowerable; +import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * Count the number of leading zeros using the {@code lzcntq} or {@code lzcntl} instructions. */ @NodeInfo -public final class AMD64CountLeadingZerosNode extends UnaryNode implements LIRLowerable { +public final class AMD64CountLeadingZerosNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass<AMD64CountLeadingZerosNode> TYPE = NodeClass.create(AMD64CountLeadingZerosNode.class); public AMD64CountLeadingZerosNode(ValueNode value) { @@ -83,8 +84,7 @@ } @Override - public void generate(NodeLIRBuilderTool gen) { - Value result = gen.getLIRGeneratorTool().emitCountLeadingZeros(gen.operand(getValue())); - gen.setResult(this, result); + public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) { + builder.setResult(this, ((AMD64ArithmeticLIRGeneratorTool) gen).emitCountLeadingZeros(builder.operand(getValue()))); } }
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -25,25 +25,26 @@ import jdk.internal.jvmci.code.CodeUtil; import jdk.internal.jvmci.meta.JavaConstant; import jdk.internal.jvmci.meta.JavaKind; -import jdk.internal.jvmci.meta.Value; import com.oracle.graal.compiler.common.type.IntegerStamp; import com.oracle.graal.compiler.common.type.PrimitiveStamp; import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; +import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGeneratorTool; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.UnaryNode; -import com.oracle.graal.nodes.spi.LIRLowerable; +import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * Count the number of trailing zeros using the {@code tzcntq} or {@code tzcntl} instructions. */ @NodeInfo -public final class AMD64CountTrailingZerosNode extends UnaryNode implements LIRLowerable { +public final class AMD64CountTrailingZerosNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass<AMD64CountTrailingZerosNode> TYPE = NodeClass.create(AMD64CountTrailingZerosNode.class); public AMD64CountTrailingZerosNode(ValueNode value) { @@ -79,8 +80,7 @@ } @Override - public void generate(NodeLIRBuilderTool gen) { - Value result = gen.getLIRGeneratorTool().emitCountTrailingZeros(gen.operand(getValue())); - gen.setResult(this, result); + public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) { + builder.setResult(this, ((AMD64ArithmeticLIRGeneratorTool) gen).emitCountTrailingZeros(builder.operand(getValue()))); } }
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -26,13 +26,13 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.FloatConvertOp; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.FloatConvertNode; import com.oracle.graal.nodes.calc.UnaryArithmeticNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** * This node has the semantics of the AMD64 floating point conversions. It is used in the lowering @@ -56,7 +56,8 @@ return this; } - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + @Override + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { nodeValueMap.setResult(this, gen.emitFloatConvert(op, nodeValueMap.operand(getValue()))); } }
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64MathIntrinsicNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64MathIntrinsicNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -31,14 +31,14 @@ import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGenerator; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGeneratorTool; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.UnaryNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo public final class AMD64MathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable { @@ -81,8 +81,8 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator lirGen) { - AMD64ArithmeticLIRGenerator gen = (AMD64ArithmeticLIRGenerator) lirGen; + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool lirGen) { + AMD64ArithmeticLIRGeneratorTool gen = (AMD64ArithmeticLIRGeneratorTool) lirGen; Value input = nodeValueMap.operand(getValue()); Value result; switch (operation()) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -25,22 +25,22 @@ import jdk.internal.jvmci.code.CodeUtil; import jdk.internal.jvmci.meta.JavaConstant; import jdk.internal.jvmci.meta.JavaKind; -import jdk.internal.jvmci.meta.Value; import com.oracle.graal.compiler.common.type.IntegerStamp; import com.oracle.graal.compiler.common.type.PrimitiveStamp; import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.UnaryNode; -import com.oracle.graal.nodes.spi.LIRLowerable; +import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo -public final class BitCountNode extends UnaryNode implements LIRLowerable { +public final class BitCountNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass<BitCountNode> TYPE = NodeClass.create(BitCountNode.class); @@ -67,8 +67,7 @@ } @Override - public void generate(NodeLIRBuilderTool gen) { - Value result = gen.getLIRGeneratorTool().emitBitCount(gen.operand(getValue())); - gen.setResult(this, result); + public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) { + builder.setResult(this, gen.emitBitCount(builder.operand(getValue()))); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -25,18 +25,18 @@ import jdk.internal.jvmci.code.CodeUtil; import jdk.internal.jvmci.meta.JavaConstant; import jdk.internal.jvmci.meta.JavaKind; -import jdk.internal.jvmci.meta.Value; import com.oracle.graal.compiler.common.type.IntegerStamp; import com.oracle.graal.compiler.common.type.PrimitiveStamp; import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.UnaryNode; -import com.oracle.graal.nodes.spi.LIRLowerable; +import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** @@ -44,7 +44,7 @@ * input is zero. */ @NodeInfo -public final class BitScanForwardNode extends UnaryNode implements LIRLowerable { +public final class BitScanForwardNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass<BitScanForwardNode> TYPE = NodeClass.create(BitScanForwardNode.class); @@ -125,8 +125,7 @@ public static native int unsafeScan(int v); @Override - public void generate(NodeLIRBuilderTool gen) { - Value result = gen.getLIRGeneratorTool().emitBitScanForward(gen.operand(getValue())); - gen.setResult(this, result); + public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) { + builder.setResult(this, gen.emitBitScanForward(builder.operand(getValue()))); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -25,18 +25,18 @@ import jdk.internal.jvmci.code.CodeUtil; import jdk.internal.jvmci.meta.JavaConstant; import jdk.internal.jvmci.meta.JavaKind; -import jdk.internal.jvmci.meta.Value; import com.oracle.graal.compiler.common.type.IntegerStamp; import com.oracle.graal.compiler.common.type.PrimitiveStamp; import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.UnaryNode; -import com.oracle.graal.nodes.spi.LIRLowerable; +import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; /** @@ -44,7 +44,7 @@ * input is zero. */ @NodeInfo -public final class BitScanReverseNode extends UnaryNode implements LIRLowerable { +public final class BitScanReverseNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass<BitScanReverseNode> TYPE = NodeClass.create(BitScanReverseNode.class); @@ -121,9 +121,8 @@ public static native int unsafeScan(long v); @Override - public void generate(NodeLIRBuilderTool gen) { - Value result = gen.getLIRGeneratorTool().emitBitScanReverse(gen.operand(getValue())); - gen.setResult(this, result); + public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) { + builder.setResult(this, gen.emitBitScanReverse(builder.operand(getValue()))); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -28,6 +28,7 @@ import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; +import com.oracle.graal.lir.gen.LIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.FixedWithNextNode; import com.oracle.graal.nodes.StateSplit; @@ -66,23 +67,24 @@ * @see com.oracle.graal.replacements.DefaultJavaLoweringProvider#createUnsafeRead */ @Override - public void generate(NodeLIRBuilderTool gen) { - LIRKind kind = gen.getLIRGeneratorTool().target().getLIRKind(readKind); - Value loaded = gen.getLIRGeneratorTool().emitLoad(kind, gen.operand(address), null); + public void generate(NodeLIRBuilderTool builder) { + LIRGeneratorTool gen = builder.getLIRGeneratorTool(); + LIRKind kind = gen.target().getLIRKind(readKind); + Value loaded = gen.emitLoad(kind, builder.operand(address), null); switch (readKind) { case Byte: - loaded = gen.getLIRGeneratorTool().emitSignExtend(loaded, 8, 32); + loaded = gen.getArithmetic().emitSignExtend(loaded, 8, 32); break; case Short: - loaded = gen.getLIRGeneratorTool().emitSignExtend(loaded, 16, 32); + loaded = gen.getArithmetic().emitSignExtend(loaded, 16, 32); break; case Boolean: - loaded = gen.getLIRGeneratorTool().emitZeroExtend(loaded, 8, 32); + loaded = gen.getArithmetic().emitZeroExtend(loaded, 8, 32); break; case Char: - loaded = gen.getLIRGeneratorTool().emitZeroExtend(loaded, 16, 32); + loaded = gen.getArithmetic().emitZeroExtend(loaded, 16, 32); break; } - gen.setResult(this, loaded); + builder.setResult(this, loaded); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -41,6 +41,6 @@ @Override protected Value generateArithmetic(NodeLIRBuilderTool gen) { - return gen.getLIRGeneratorTool().emitAdd(gen.operand(getX()), gen.operand(getY()), true); + return gen.getLIRGeneratorTool().getArithmetic().emitAdd(gen.operand(getX()), gen.operand(getY()), true); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -41,6 +41,6 @@ @Override protected Value generateArithmetic(NodeLIRBuilderTool gen) { - return gen.getLIRGeneratorTool().emitMul(gen.operand(getX()), gen.operand(getY()), true); + return gen.getLIRGeneratorTool().getArithmetic().emitMul(gen.operand(getX()), gen.operand(getY()), true); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulHighNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulHighNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -31,13 +31,13 @@ import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.BinaryNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = "*H") public final class IntegerMulHighNode extends BinaryNode implements ArithmeticLIRLowerable { @@ -87,7 +87,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { Value a = nodeValueMap.operand(getX()); Value b = nodeValueMap.operand(getY()); nodeValueMap.setResult(this, gen.emitMulHigh(a, b));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -41,6 +41,6 @@ @Override protected Value generateArithmetic(NodeLIRBuilderTool gen) { - return gen.getLIRGeneratorTool().emitSub(gen.operand(getX()), gen.operand(getY()), true); + return gen.getLIRGeneratorTool().getArithmetic().emitSub(gen.operand(getX()), gen.operand(getY()), true); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/UnsignedMulHighNode.java Thu Oct 08 14:58:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/UnsignedMulHighNode.java Thu Oct 08 15:58:13 2015 -0700 @@ -31,13 +31,13 @@ import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; -import com.oracle.graal.lir.gen.ArithmeticLIRGenerator; +import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.BinaryNode; import com.oracle.graal.nodes.spi.ArithmeticLIRLowerable; -import com.oracle.graal.nodes.spi.NodeValueMap; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; @NodeInfo(shortName = "|*H|") public final class UnsignedMulHighNode extends BinaryNode implements ArithmeticLIRLowerable { @@ -92,7 +92,7 @@ } @Override - public void generate(NodeValueMap nodeValueMap, ArithmeticLIRGenerator gen) { + public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { Value a = nodeValueMap.operand(getX()); Value b = nodeValueMap.operand(getY()); nodeValueMap.setResult(this, gen.emitUMulHigh(a, b));