# HG changeset patch # User Lukas Stadler # Date 1376654365 -7200 # Node ID 01269a181628b6821991c55e12c3797d2c1e8559 # Parent a3ea9012c0de16d2e2b1792c2e77892c4b288a94 add bitwise "not" operation diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Fri Aug 16 13:59:25 2013 +0200 @@ -1189,6 +1189,12 @@ emitByte(0xD8 | encode); } + public final void notl(Register dst) { + int encode = prefixAndEncode(dst.encoding); + emitByte(0xF7); + emitByte(0xD0 | encode); + } + public final void ensureUniquePC() { nop(); } @@ -2212,6 +2218,12 @@ emitByte(0xD8 | encode); } + public final void notq(Register dst) { + int encode = prefixqAndEncode(dst.encoding); + emitByte(0xF7); + emitByte(0xD0 | encode); + } + public final void orq(Register dst, int imm32) { prefixqAndEncode(dst.encoding); emitArith(0x81, 0xC8, dst, imm32); diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Aug 16 13:59:25 2013 +0200 @@ -359,6 +359,23 @@ return result; } + @Override + public Variable emitNot(Value inputVal) { + AllocatableValue input = asAllocatable(inputVal); + Variable result = newVariable(input.getKind()); + switch (input.getKind()) { + case Int: + append(new Unary1Op(INOT, result, input)); + break; + case Long: + append(new Unary1Op(LNOT, result, input)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; + } + private Variable emitBinary(AMD64Arithmetic op, boolean commutative, Value a, Value b) { if (isConstant(b)) { return emitBinaryConst(op, commutative, asAllocatable(a), asConstant(b)); diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Fri Aug 16 13:59:25 2013 +0200 @@ -300,6 +300,20 @@ } + @Override + public Variable emitNot(Value input) { + Variable result = newVariable(input.getKind()); + switch (input.getKind()) { + case Int: + append(new Op1Stack(INOT, result, input)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; + + } + public Variable emitTestAddressAdd(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Aug 16 13:59:25 2013 +0200 @@ -315,6 +315,22 @@ } @Override + public Variable emitNot(Value input) { + Variable result = newVariable(input.getKind()); + switch (input.getKind()) { + case Int: + append(new Op1Stack(INOT, result, input)); + break; + case Long: + append(new Op1Stack(LNOT, result, input)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; + } + + @Override public Variable emitAdd(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Aug 16 13:59:25 2013 +0200 @@ -468,6 +468,22 @@ return result; } + @Override + public Value emitNot(Value input) { + Variable result = newVariable(input.getKind()); + switch (input.getKind().getStackKind()) { + case Int: + append(new Op1Stack(INOT, result, input)); + break; + case Long: + append(new Op1Stack(LNOT, result, input)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; + } + private Variable emitBinary(SPARCArithmetic op, boolean commutative, Value a, Value b) { if (isConstant(b)) { return emitBinaryConst(op, commutative, asAllocatable(a), asConstant(b)); diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Aug 16 13:59:25 2013 +0200 @@ -276,4 +276,10 @@ append(new StoreOp(kind, storeAddress, input, state)); } } + + @Override + public Value emitNot(Value input) { + GraalInternalError.shouldNotReachHere("binary negation not implemented"); + return null; + } } diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Fri Aug 16 13:59:25 2013 +0200 @@ -42,7 +42,7 @@ LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, - INEG, LNEG, + INEG, LNEG, INOT, LNOT, SQRT, I2L, L2I, I2B, I2C, I2S, F2D, D2F, @@ -364,6 +364,12 @@ case LNEG: masm.negq(asLongReg(result)); break; + case INOT: + masm.notl(asIntReg(result)); + break; + case LNOT: + masm.notq(asLongReg(result)); + break; case L2I: masm.andl(asIntReg(result), 0xFFFFFFFF); break; diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java Fri Aug 16 13:59:25 2013 +0200 @@ -44,7 +44,7 @@ IMIN, LMIN, IUMIN, LUMIN, IREM, LREM, FREM, DREM, IUREM, LUREM, ICARRY, LCARRY, IUCARRY, LUCARRY, - IAND, LAND, INEG, I2B, I2S, I2L, + IAND, LAND, INEG, INOT, I2B, I2S, I2L, F2D, F2I, F2L, D2F, I2F, I2D, D2I, L2F, D2L, MOV_F2I, MOV_D2L, L2D, MOV_I2F, MOV_L2D, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, @@ -233,6 +233,7 @@ case SQRT: masm.emitArg1("sqrt", dst, src); break; case UNDEF: masm.undefined("undefined node"); break; case CALL: masm.undefined("undefined node CALL"); break; + case INOT: masm.emitArg1("not", dst, src); break; default: throw GraalInternalError.shouldNotReachHere(); } diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Aug 16 13:59:25 2013 +0200 @@ -37,7 +37,7 @@ LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, - INEG, LNEG, FNEG, DNEG, + INEG, LNEG, FNEG, DNEG, INOT, LNOT, I2L, L2I, I2B, I2C, I2S, F2D, D2F, I2F, I2D, F2I, D2I, @@ -270,6 +270,12 @@ case INEG: masm.neg_s32(asIntReg(dst), asIntReg(src)); break; + case INOT: + masm.not_s32(asIntReg(dst), asIntReg(src)); + break; + case LNOT: + masm.not_s64(asLongReg(dst), asLongReg(src)); + break; case I2L: masm.cvt_s64_s32(asLongReg(dst), asIntReg(src)); break; diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Aug 16 13:59:25 2013 +0200 @@ -39,7 +39,7 @@ LADD, LSUB, LMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, - INEG, LNEG, FNEG, DNEG, + INEG, LNEG, FNEG, DNEG, INOT, LNOT, I2L, L2I, I2B, I2C, I2S, F2D, D2F, I2F, I2D, F2I, D2I, @@ -525,6 +525,12 @@ case INEG: new Neg(asIntReg(src), asIntReg(dst)).emit(masm); break; + case INOT: + new Not(asIntReg(src), asIntReg(dst)).emit(masm); + break; + case LNOT: + new Not(asLongReg(src), asLongReg(dst)).emit(masm); + break; case I2L: new Signx(asIntReg(src), asLongReg(dst)).emit(masm); break; diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Fri Aug 16 13:59:25 2013 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2009, 2011, 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.nodes.calc; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Binary negation of long or integer values. + */ +public final class NotNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable { + + @Input private ValueNode x; + + public ValueNode x() { + return x; + } + + @Override + public boolean inferStamp() { + return updateStamp(StampTool.not(x().stamp())); + } + + /** + * Creates new NegateNode instance. + * + * @param x the instruction producing the value that is input to this instruction + */ + public NotNode(ValueNode x) { + super(StampTool.not(x.stamp())); + assert x.kind() == Kind.Int || x.kind() == Kind.Long; + this.x = x; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (x().isConstant()) { + switch (x().kind()) { + case Int: + return ConstantNode.forInt(~x().asConstant().asInt(), graph()); + case Long: + return ConstantNode.forLong(~x().asConstant().asLong(), graph()); + } + } + if (x() instanceof NotNode) { + return ((NotNode) x()).x(); + } + return this; + } + + @Override + public void generate(ArithmeticLIRGenerator gen) { + gen.setResult(this, gen.emitNot(gen.operand(x()))); + } +} diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Fri Aug 16 13:59:25 2013 +0200 @@ -60,12 +60,16 @@ int c = y().asConstant().asInt(); if (c == 0) { return x(); + } else if (c == -1) { + return graph().unique(new NotNode(x())); } } else { assert kind() == Kind.Long; long c = y().asConstant().asLong(); if (c == 0) { return x(); + } else if (c == -1) { + return graph().unique(new NotNode(x())); } } return BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); diff -r a3ea9012c0de -r 01269a181628 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java Fri Aug 16 13:30:28 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java Fri Aug 16 13:59:25 2013 +0200 @@ -52,6 +52,8 @@ Value emitURem(Value a, Value b, DeoptimizingNode deopting); + Value emitNot(Value input); + Value emitAnd(Value a, Value b); Value emitOr(Value a, Value b);