# HG changeset patch # User Christian Wimmer # Date 1326404807 28800 # Node ID c9ab0ffaddddea75ec0279e2312a6280d127574a # Parent cdcd26f86af51f270cda5dd43b9f091b5838d263 Unify and simplify conversion LIR instructions diff -r cdcd26f86af5 -r c9ab0ffadddd graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java Thu Jan 12 13:46:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64; - -import static com.oracle.max.cri.ci.CiValueUtil.*; - -import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; - -public enum AMD64ConvertFIOpcode implements LIROpcode { - F2I, D2I; - - public LIRInstruction create(CiValue result, CiValue x) { - CiValue[] inputs = new CiValue[] {x}; - CiValue[] outputs = new CiValue[] {result}; - - return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) { - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - emit(tasm, masm, output(0), input(0)); - } - }; - } - - private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) { - AMD64ConvertFSlowPath slowPath; - switch (this) { - case F2I: - masm.cvttss2sil(asIntReg(result), asFloatReg(x)); - slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(x), false, false); - break; - case D2I: - masm.cvttsd2sil(asIntReg(result), asDoubleReg(x)); - slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asDoubleReg(x), true, false); - break; - default: - throw Util.shouldNotReachHere(); - } - tasm.slowPaths.add(slowPath); - - masm.cmp32(asIntReg(result), Integer.MIN_VALUE); - masm.jcc(ConditionFlag.equal, slowPath.start); - masm.bind(slowPath.continuation); - } -} diff -r cdcd26f86af5 -r c9ab0ffadddd graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java Thu Jan 12 13:46:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64; - -import static com.oracle.max.cri.ci.CiValueUtil.*; - -import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; - -public enum AMD64ConvertFLOpcode implements LIROpcode { - F2L, D2L; - - public LIRInstruction create(CiValue result, CiValue x, CiValue scratch) { - CiValue[] inputs = new CiValue[] {x}; - CiValue[] temps = new CiValue[] {scratch}; - CiValue[] outputs = new CiValue[] {result}; - - return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, temps) { - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - emit(tasm, masm, output(0), input(0), temp(0)); - } - }; - } - - private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue scratch) { - AMD64ConvertFSlowPath slowPath; - switch (this) { - case F2L: - masm.cvttss2siq(asLongReg(result), asFloatReg(x)); - slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asFloatReg(x), false, true); - break; - case D2L: - masm.cvttsd2siq(asLongReg(result), asDoubleReg(x)); - slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asDoubleReg(x), true, true); - break; - default: - throw Util.shouldNotReachHere(); - } - tasm.slowPaths.add(slowPath); - - CiRegister tmp = asLongReg(scratch); - masm.movq(tmp, java.lang.Long.MIN_VALUE); - masm.cmpq(asLongReg(result), tmp); - masm.jcc(ConditionFlag.equal, slowPath.start); - masm.bind(slowPath.continuation); - } -} diff -r cdcd26f86af5 -r c9ab0ffadddd graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFSlowPath.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFSlowPath.java Thu Jan 12 13:46:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64; - -import com.oracle.max.asm.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.asm.target.amd64.AMD64Assembler.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.lir.*; - -class AMD64ConvertFSlowPath implements LIR.SlowPath { - - public final Label start = new Label(); - public final Label continuation = new Label(); - - private final CiRegister result; - private final CiRegister input; - private final AMD64MacroAssembler masm; - private final boolean inputIsDouble; - private final boolean resultIsLong; - - public AMD64ConvertFSlowPath(AMD64MacroAssembler masm, CiRegister result, CiRegister input, boolean inputIsDouble, boolean resultIsLong) { - this.masm = masm; - this.result = result; - this.input = input; - this.inputIsDouble = inputIsDouble; - this.resultIsLong = resultIsLong; - } - - @Override - public void emitCode(TargetMethodAssembler tasm) { - masm.bind(start); - if (inputIsDouble) { - masm.ucomisd(input, tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); - } else { - masm.ucomiss(input, tasm.asFloatConstRef(CiConstant.FLOAT_0)); - } - Label nan = new Label(); - masm.jcc(ConditionFlag.parity, nan); - masm.jcc(ConditionFlag.below, continuation); - - // input is > 0 -> return maxInt - // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff - if (resultIsLong) { - masm.decrementq(result, 1); - } else { - masm.decrementl(result, 1); - } - masm.jmp(continuation); - - // input is NaN -> return 0 - masm.bind(nan); - masm.xorptr(result, result); - masm.jmp(continuation); - } -} diff -r cdcd26f86af5 -r c9ab0ffadddd graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertOpcode.java Thu Jan 12 13:46:26 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertOpcode.java Thu Jan 12 13:46:47 2012 -0800 @@ -26,7 +26,9 @@ import java.util.*; +import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.*; +import com.oracle.max.asm.target.amd64.AMD64Assembler.*; import com.oracle.max.cri.ci.*; import com.oracle.max.graal.compiler.asm.*; import com.oracle.max.graal.compiler.lir.*; @@ -35,8 +37,8 @@ public enum AMD64ConvertOpcode implements LIROpcode { I2L, L2I, I2B, I2C, I2S, F2D, D2F, - I2F, I2D, - L2F, L2D, + I2F, I2D, F2I, D2I, + L2F, L2D, F2L, D2L, MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L; public LIRInstruction create(CiValue result, CiValue x) { @@ -84,6 +86,22 @@ case I2D: masm.cvtsi2sdl(asDoubleReg(result), asIntReg(x)); break; case L2F: masm.cvtsi2ssq(asFloatReg(result), asLongReg(x)); break; case L2D: masm.cvtsi2sdq(asDoubleReg(result), asLongReg(x)); break; + case F2I: + masm.cvttss2sil(asIntReg(result), asFloatReg(x)); + emitFixup(tasm, masm, result, x); + break; + case D2I: + masm.cvttsd2sil(asIntReg(result), asDoubleReg(x)); + emitFixup(tasm, masm, result, x); + break; + case F2L: + masm.cvttss2siq(asLongReg(result), asFloatReg(x)); + emitFixup(tasm, masm, result, x); + break; + case D2L: + masm.cvttsd2siq(asLongReg(result), asDoubleReg(x)); + emitFixup(tasm, masm, result, x); + break; case MOV_I2F: masm.movdl(asFloatReg(result), asIntReg(x)); break; case MOV_L2D: masm.movdq(asDoubleReg(result), asLongReg(x)); break; case MOV_F2I: masm.movdl(asIntReg(result), asFloatReg(x)); break; @@ -91,4 +109,55 @@ default: throw Util.shouldNotReachHere(); } } + + private static void emitFixup(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) { + FixupSlowPath slowPath = new FixupSlowPath(result, x); + tasm.slowPaths.add(slowPath); + switch (result.kind) { + case Int: masm.cmpl(asIntReg(result), Integer.MIN_VALUE); break; + case Long: masm.cmpq(asLongReg(result), tasm.asLongConstRef(CiConstant.forLong(java.lang.Long.MIN_VALUE))); break; + default: throw Util.shouldNotReachHere(); + } + masm.jcc(ConditionFlag.equal, slowPath.start); + masm.bind(slowPath.continuation); + } + + private static class FixupSlowPath extends AMD64SlowPath { + public final Label start = new Label(); + public final Label continuation = new Label(); + private final CiValue result; + private final CiValue x; + + public FixupSlowPath(CiValue result, CiValue x) { + this.result = result; + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + masm.bind(start); + switch (x.kind) { + case Float: masm.ucomiss(asFloatReg(x), tasm.asFloatConstRef(CiConstant.FLOAT_0)); break; + case Double: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); break; + default: throw Util.shouldNotReachHere(); + } + Label nan = new Label(); + masm.jcc(ConditionFlag.parity, nan); + masm.jcc(ConditionFlag.below, continuation); + + // input is > 0 -> return maxInt + // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff + switch (result.kind) { + case Int: masm.decrementl(asIntReg(result), 1); break; + case Long: masm.decrementq(asLongReg(result), 1); break; + default: throw Util.shouldNotReachHere(); + } + masm.jmp(continuation); + + // input is NaN -> return 0 + masm.bind(nan); + masm.xorptr(asRegister(result), asRegister(result)); + masm.jmp(continuation); + } + } } diff -r cdcd26f86af5 -r c9ab0ffadddd graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Thu Jan 12 13:46:26 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Thu Jan 12 13:46:47 2012 -0800 @@ -27,8 +27,6 @@ import static com.oracle.max.graal.compiler.target.amd64.AMD64ArithmeticOpcode.*; import static com.oracle.max.graal.compiler.target.amd64.AMD64CompareOpcode.*; import static com.oracle.max.graal.compiler.target.amd64.AMD64CompareToIntOpcode.*; -import static com.oracle.max.graal.compiler.target.amd64.AMD64ConvertFIOpcode.*; -import static com.oracle.max.graal.compiler.target.amd64.AMD64ConvertFLOpcode.*; import static com.oracle.max.graal.compiler.target.amd64.AMD64ConvertOpcode.*; import static com.oracle.max.graal.compiler.target.amd64.AMD64DivOpcode.*; import static com.oracle.max.graal.compiler.target.amd64.AMD64LogicFloatOpcode.*; @@ -429,8 +427,8 @@ case D2I: append(D2I.create(result, input)); break; case L2F: append(L2F.create(result, input)); break; case L2D: append(L2D.create(result, input)); break; - case F2L: append(F2L.create(result, input, newVariable(CiKind.Long))); break; - case D2L: append(D2L.create(result, input, newVariable(CiKind.Long))); break; + case F2L: append(F2L.create(result, input)); break; + case D2L: append(D2L.create(result, input)); break; case MOV_I2F: append(MOV_I2F.create(result, input)); break; case MOV_L2D: append(MOV_L2D.create(result, input)); break; case MOV_F2I: append(MOV_F2I.create(result, input)); break;