changeset 5874:f0d4304243ff

Add intrinsics for (Long|Integer).(reverseBytes|numberOf(Trail|Lead)ingZeros) Add tests for those methods
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 24 Jul 2012 17:32:42 +0200
parents d4d5af0234b7
children 000fb0550afe
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/LongBits.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/IntegerSnippets.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/LongSnippets.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64BitScanOp.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64ByteSwapOp.java
diffstat 11 files changed, 566 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Mon Jul 23 16:50:10 2012 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Tue Jul 24 17:32:42 2012 +0200
@@ -438,4 +438,23 @@
         }
     }
 
+    public int bits() {
+        switch (this) {
+            case Boolean:
+                return 1;
+            case Byte:
+                return 8;
+            case Char:
+                return 16;
+            case Short:
+                return 16;
+            case Jsr:
+            case Int:
+                return 32;
+            case Long:
+                return 64;
+            default:
+                throw new IllegalArgumentException("illegal call to bits on " + this);
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/LongBits.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 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.graal.jtt.jdk;
+
+import org.junit.*;
+
+
+public class LongBits {
+    @SuppressWarnings("unused")
+    private static long init = Long.reverseBytes(42);
+    private long original = 0x0102030405060708L;
+    private long reversed = 0x0807060504030201L;
+    private long v = 0b1000L;
+    private long zero = 0L;
+
+    public long test(long o) {
+        return Long.reverseBytes(o);
+    }
+
+    public int test2(long o) {
+        return Long.numberOfLeadingZeros(o);
+    }
+
+    public int test3(long o) {
+        return Long.numberOfTrailingZeros(o);
+    }
+
+    @Test
+    public void run0() {
+        Assert.assertEquals(reversed, test(original));
+    }
+
+    @Test
+    public void run1() {
+        Assert.assertEquals(3, test3(v));
+    }
+
+    @Test
+    public void run2() {
+        Assert.assertEquals(60, test2(v));
+    }
+
+    @Test
+    public void run3() {
+        Assert.assertEquals(64, test3(zero));
+    }
+
+    @Test
+    public void run4() {
+        Assert.assertEquals(64, test2(zero));
+    }
+
+    @Test
+    public void run5() {
+        Assert.assertEquals(reversed, test(0x0102030405060708L));
+    }
+
+    @Test
+    public void run6() {
+        Assert.assertEquals(3, test3(0b1000L));
+    }
+
+    @Test
+    public void run7() {
+        Assert.assertEquals(60, test2(0b1000L));
+    }
+
+    @Test
+    public void run8() {
+        Assert.assertEquals(64, test3(0L));
+    }
+
+    @Test
+    public void run9() {
+        Assert.assertEquals(64, test2(0L));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Mon Jul 23 16:50:10 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Tue Jul 24 17:32:42 2012 +0200
@@ -102,6 +102,16 @@
         return new IntegerStamp(kind, lowerBound, upperBound, mask);
     }
 
+    public static Stamp forInteger(Kind kind, long lowerBound, long upperBound) {
+        long mask;
+        if (lowerBound < 0) {
+            mask = IntegerStamp.defaultMask(kind);
+        } else {
+            mask = -1 >>> Long.numberOfLeadingZeros(upperBound);
+        }
+        return forInteger(kind, lowerBound, upperBound, mask);
+    }
+
     public static Stamp forFloat(Kind kind, double lowerBound, double upperBound, boolean nonNaN) {
         return new FloatStamp(kind, lowerBound, upperBound, nonNaN);
     }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Mon Jul 23 16:50:10 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Tue Jul 24 17:32:42 2012 +0200
@@ -34,6 +34,8 @@
             installer.install(DoubleSnippets.class);
             installer.install(FloatSnippets.class);
             installer.install(NodeClassSnippets.class);
+            installer.install(LongSnippets.class);
+            installer.install(IntegerSnippets.class);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/IntegerSnippets.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 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.graal.snippets;
+
+import com.oracle.graal.snippets.nodes.*;
+
+@ClassSubstitution(Integer.class)
+public class IntegerSnippets implements SnippetsInterface{
+
+    public static int reverseBytes(int i) {
+        return ReverseBytesNode.reverse(i);
+    }
+
+    public static int numberOfLeadingZeros(int i) {
+        if (i == 0) {
+            return 32;
+        }
+        return 31 - BitScanReverseNode.scan(i);
+    }
+
+    public static int numberOfTrailingZeros(int i) {
+        if (i == 0) {
+            return 32;
+        }
+        return BitScanForwardNode.scan(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/LongSnippets.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 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.graal.snippets;
+
+import com.oracle.graal.snippets.nodes.*;
+
+@ClassSubstitution(Long.class)
+public class LongSnippets implements SnippetsInterface{
+
+    public static long reverseBytes(long i) {
+        return ReverseBytesNode.reverse(i);
+    }
+
+    public static int numberOfLeadingZeros(long i) {
+        if (i == 0) {
+            return 64;
+        }
+        return 63 - BitScanReverseNode.scan(i);
+    }
+
+    public static int numberOfTrailingZeros(long i) {
+        if (i == 0) {
+            return 64;
+        }
+        return BitScanForwardNode.scan(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012, 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.graal.snippets.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.target.amd64.*;
+import com.oracle.graal.snippets.target.amd64.AMD64BitScanOp.IntrinsicOpcode;
+
+
+public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+    @Input private ValueNode value;
+
+    public BitScanForwardNode(ValueNode value) {
+        super(StampFactory.forInteger(Kind.Int, 0, value.kind().bits()));
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            long v = value.asConstant().asLong();
+            if (kind().isInt()) {
+                return ConstantNode.forInt(Integer.numberOfTrailingZeros((int) v), graph());
+            } else if (kind().isLong()) {
+                return ConstantNode.forLong(Long.numberOfTrailingZeros(v), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static int scan(@SuppressWarnings("unused") int v) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @NodeIntrinsic
+    public static int scan(@SuppressWarnings("unused") long v) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(Kind.Int);
+        gen.append(new AMD64BitScanOp(IntrinsicOpcode.BSF, result, gen.operand(value)));
+        gen.setResult(this, result);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012, 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.graal.snippets.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.target.amd64.*;
+import com.oracle.graal.snippets.target.amd64.AMD64BitScanOp.IntrinsicOpcode;
+
+
+public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+    @Input private ValueNode value;
+
+    public BitScanReverseNode(ValueNode value) {
+        super(StampFactory.forInteger(Kind.Int, 0, value.kind().bits()));
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            long v = value.asConstant().asLong();
+            if (kind().isInt()) {
+                return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros((int) v), graph());
+            } else if (kind().isLong()) {
+                return ConstantNode.forLong(63 - Long.numberOfLeadingZeros(v), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static int scan(@SuppressWarnings("unused") int v) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @NodeIntrinsic
+    public static int scan(@SuppressWarnings("unused") long v) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(Kind.Int);
+        gen.append(new AMD64BitScanOp(IntrinsicOpcode.BSR, result, gen.operand(value)));
+        gen.setResult(this, result);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 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.graal.snippets.nodes;
+
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.target.amd64.*;
+
+
+public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+    @Input private ValueNode value;
+
+    public ReverseBytesNode(ValueNode value) {
+        super(StampFactory.forKind(value.kind()));
+        assert kind().isInt() || kind().isLong();
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            long v = value.asConstant().asLong();
+            if (kind().isInt()) {
+                return ConstantNode.forInt(Integer.reverseBytes((int) v), graph());
+            } else if (kind().isLong()) {
+                return ConstantNode.forLong(Long.reverseBytes(v), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static int reverse(@SuppressWarnings("unused") int v) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @NodeIntrinsic
+    public static long reverse(@SuppressWarnings("unused") long v) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(value.kind());
+        gen.append(new AMD64ByteSwapOp(result, gen.operand(value)));
+        gen.setResult(this, result);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64BitScanOp.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 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.graal.snippets.target.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+
+
+public class AMD64BitScanOp extends AMD64LIRInstruction {
+    public enum IntrinsicOpcode  {
+        BSF,
+        BSR;
+    }
+
+    @Opcode private final IntrinsicOpcode opcode;
+    @Def protected Value result;
+    @Use({OperandFlag.REG, OperandFlag.ADDR}) protected Value input;
+
+    public AMD64BitScanOp(IntrinsicOpcode opcode, Value result, Value input) {
+        this.opcode = opcode;
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        switch(opcode) {
+            case BSF:
+                if (ValueUtil.isAddress(input)) {
+                    masm.bsfq(ValueUtil.asIntReg(result), ValueUtil.asAddress(input));
+                } else {
+                    masm.bsfq(ValueUtil.asIntReg(result), ValueUtil.asRegister(input));
+                }
+                break;
+            case BSR:
+                if (ValueUtil.isAddress(input)) {
+                    masm.bsrq(ValueUtil.asIntReg(result), ValueUtil.asAddress(input));
+                } else {
+                    masm.bsrq(ValueUtil.asIntReg(result), ValueUtil.asRegister(input));
+                }
+                break;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64ByteSwapOp.java	Tue Jul 24 17:32:42 2012 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 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.graal.snippets.target.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+
+@Opcode("BSWAP")
+public class AMD64ByteSwapOp extends AMD64LIRInstruction {
+    @Def({OperandFlag.REG, OperandFlag.HINT}) protected Value result;
+    @Use protected Value input;
+
+    public AMD64ByteSwapOp(Value result, Value input) {
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        AMD64Move.move(tasm, masm, result, input);
+        switch(input.kind) {
+            case Int:
+                masm.bswapl(ValueUtil.asIntReg(result));
+                break;
+            case Long:
+                masm.bswapq(ValueUtil.asLongReg(result));
+        }
+    }
+}