changeset 11355:01269a181628

add bitwise "not" operation
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 16 Aug 2013 13:59:25 +0200
parents a3ea9012c0de
children 90201030d3cf
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java
diffstat 13 files changed, 187 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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));
--- 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()) {
--- 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()) {
--- 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));
--- 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;
+    }
 }
--- 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;
--- 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();
             }
--- 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;
--- 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;
--- /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())));
+    }
+}
--- 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());
--- 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);