changeset 14962:e4a5b8904695

Support for short and byte compare in AMD64 backend.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 03 Apr 2014 19:25:11 +0200
parents d87e4eae76c4
children 0c2e34446bd7
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.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.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java
diffstat 11 files changed, 197 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Thu Apr 03 19:25:11 2014 +0200
@@ -183,6 +183,27 @@
         return r.encoding & 0x7;
     }
 
+    private void emitArithImm8(int op, Register dst, int imm8) {
+        int encode = prefixAndEncode(op, dst.encoding, true);
+        emitByte(0x80);
+        emitByte(0xC0 | encode);
+        emitByte(imm8);
+    }
+
+    private void emitArithImm16(int op, Register dst, int imm16) {
+        emitByte(0x66);
+        int encode = prefixAndEncode(op, dst.encoding);
+        if (isByte(imm16)) {
+            emitByte(0x83); // imm8 sign extend
+            emitByte(0xC0 | encode);
+            emitByte(imm16 & 0xFF);
+        } else {
+            emitByte(0x81);
+            emitByte(0xC0 | encode);
+            emitShort(imm16);
+        }
+    }
+
     private void emitArithImm32(int op, Register dst, int imm32) {
         int encode = prefixAndEncode(op, dst.encoding);
         if (isByte(imm32)) {
@@ -214,6 +235,27 @@
     }
 
     // immediate-to-memory forms
+    private void emitArithImm8(int op, AMD64Address adr, int imm8) {
+        prefix(adr);
+        emitByte(0x80);
+        emitOperandHelper(op, adr);
+        emitByte(imm8);
+    }
+
+    private void emitArithImm16(int op, AMD64Address adr, int imm16) {
+        emitByte(0x66);
+        prefix(adr);
+        if (isByte(imm16)) {
+            emitByte(0x83); // imm8 sign extend
+            emitOperandHelper(op, adr);
+            emitByte(imm16 & 0xFF);
+        } else {
+            emitByte(0x81);
+            emitOperandHelper(op, adr);
+            emitShort(imm16);
+        }
+    }
+
     private void emitArithImm32(int op, AMD64Address adr, int imm32) {
         prefix(adr);
         if (isByte(imm32)) {
@@ -512,6 +554,48 @@
         emitOperandHelper(dst, src);
     }
 
+    public final void cmpb(Register dst, int imm8) {
+        emitArithImm8(7, dst, imm8);
+    }
+
+    public final void cmpb(Register dst, Register src) {
+        int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+        emitByte(0x3A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cmpb(Register dst, AMD64Address src) {
+        prefix(src, dst, true);
+        emitByte(0x3A);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cmpb(AMD64Address dst, int imm8) {
+        emitArithImm8(7, dst, imm8);
+    }
+
+    public final void cmpw(Register dst, int imm16) {
+        emitArithImm16(7, dst, imm16);
+    }
+
+    public final void cmpw(Register dst, Register src) {
+        emitByte(0x66);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x3B);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cmpw(Register dst, AMD64Address src) {
+        emitByte(0x66);
+        prefix(src, dst);
+        emitByte(0x3B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cmpw(AMD64Address dst, int imm16) {
+        emitArithImm16(7, dst, imm16);
+    }
+
     public final void cmpl(Register dst, int imm32) {
         emitArithImm32(7, dst, imm32);
     }
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Thu Apr 03 19:25:11 2014 +0200
@@ -401,9 +401,9 @@
         LabelRef falseDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), falseBlock, 1);
 
         if (negate) {
-            gen.emitCompareBranch(a, b, cond, false, falseDestination, trueDestination, 1 - probability);
+            gen.emitCompareBranch(a.getKind(), a, b, cond, false, falseDestination, trueDestination, 1 - probability);
         } else {
-            gen.emitCompareBranch(a, b, cond, false, trueDestination, falseDestination, probability);
+            gen.emitCompareBranch(a.getKind(), a, b, cond, false, trueDestination, falseDestination, probability);
         }
     }
 
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu Apr 03 19:25:11 2014 +0200
@@ -246,8 +246,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
-        boolean mirrored = emitCompare(left, right);
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
+        boolean mirrored = emitCompare(cmpKind, left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         switch (left.getKind().getStackKind()) {
             case Int:
@@ -276,8 +276,8 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        boolean mirrored = emitCompare(left, right);
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        boolean mirrored = emitCompare(cmpKind, left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
 
         Variable result = newVariable(trueValue.getKind());
@@ -314,8 +314,16 @@
         }
     }
 
-    protected void emitCompareOp(Variable left, Value right) {
-        switch (left.getKind().getStackKind()) {
+    protected void emitCompareOp(PlatformKind cmpKind, Variable left, Value right) {
+        switch ((Kind) cmpKind) {
+            case Byte:
+            case Boolean:
+                append(new CompareOp(BCMP, left, right));
+                break;
+            case Short:
+            case Char:
+                append(new CompareOp(SCMP, left, right));
+                break;
             case Int:
                 append(new CompareOp(ICMP, left, right));
                 break;
@@ -337,8 +345,16 @@
     }
 
     protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Value value, LIRFrameState state) {
-        assert kind == value.getKind();
+        assert kind.getStackKind() == value.getKind().getStackKind();
         switch (kind) {
+            case Byte:
+            case Boolean:
+                append(new CompareMemoryOp(BCMP, kind, address, value, state));
+                break;
+            case Short:
+            case Char:
+                append(new CompareMemoryOp(SCMP, kind, address, value, state));
+                break;
             case Int:
                 append(new CompareMemoryOp(ICMP, kind, address, value, state));
                 break;
@@ -353,6 +369,14 @@
     protected void emitCompareRegMemoryOp(Kind kind, Value value, AMD64AddressValue address, LIRFrameState state) {
         AMD64Compare opcode = null;
         switch (kind) {
+            case Byte:
+            case Boolean:
+                opcode = BCMP;
+                break;
+            case Short:
+            case Char:
+                opcode = SCMP;
+                break;
             case Int:
                 opcode = ICMP;
                 break;
@@ -382,7 +406,7 @@
      * @param b the right operand of the comparison
      * @return true if the left and right operands were switched, false otherwise
      */
-    private boolean emitCompare(Value a, Value b) {
+    private boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
         Variable left;
         Value right;
         boolean mirrored;
@@ -395,7 +419,7 @@
             right = loadNonConst(b);
             mirrored = false;
         }
-        emitCompareOp(left, right);
+        emitCompareOp(cmpKind, left, right);
         return mirrored;
     }
 
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java	Thu Apr 03 19:25:11 2014 +0200
@@ -458,19 +458,11 @@
                     return false;
                 }
             }
-            if (kind != kind.getStackKind()) {
-                Debug.log("Skipping constant compares for stack kinds");
-                return false;
-            }
             ensureEvaluated(other);
             gen.getLIRGenerator().emitCompareMemoryConOp(kind, makeAddress(access), constant, getState(access));
             mirrored = uncast(right) == access;
         } else {
-            if (kind != kind.getStackKind()) {
-                // Register compares only work for stack kinds
-                Debug.log("Register compares only work for stack kinds");
-                return false;
-            } else if (kind == Kind.Object) {
+            if (kind == Kind.Object) {
                 // Can't compare against objects since they require encode/decode
                 Debug.log("Skipping compares for Object kinds");
                 return false;
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Thu Apr 03 19:25:11 2014 +0200
@@ -193,7 +193,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability) {
         // We don't have to worry about mirroring the condition on HSAIL.
         Condition finalCondition = cond;
         Variable result = newVariable(left.getKind());
@@ -224,7 +225,7 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         Condition finalCondition = cond;
         Variable result = newVariable(trueValue.getKind());
         Kind kind = left.getKind().getStackKind();
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Thu Apr 03 19:25:11 2014 +0200
@@ -265,7 +265,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability) {
         switch (left.getKind().getStackKind()) {
             case Int:
                 append(new CompareOp(ICMP, cond, left, right, nextPredRegNum));
@@ -305,7 +306,7 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
 
         Condition finalCondition = LIRValueUtil.isVariable(right) ? cond.mirror() : cond;
 
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Thu Apr 03 19:25:11 2014 +0200
@@ -233,7 +233,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         Kind kind = left.getKind().getStackKind();
@@ -278,7 +279,7 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Thu Apr 03 19:25:11 2014 +0200
@@ -364,13 +364,14 @@
 
     public abstract void emitJump(LabelRef label);
 
-    public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability);
+    public abstract void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability);
 
     public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability);
 
     public abstract void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability);
 
-    public abstract Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
+    public abstract Variable emitConditionalMove(PlatformKind cmpKind, Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
 
     public abstract Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue);
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Thu Apr 03 19:25:11 2014 +0200
@@ -520,11 +520,13 @@
     }
 
     private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        gen.emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
+        PlatformKind kind = gen.getPlatformKind(node.object().stamp());
+        gen.emitCompareBranch(kind, operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
     public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        gen.emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
+        PlatformKind kind = gen.getPlatformKind(compare.x().stamp());
+        gen.emitCompareBranch(kind, operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
     public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
@@ -546,10 +548,12 @@
     public Variable emitConditional(LogicNode node, Value trueValue, Value falseValue) {
         if (node instanceof IsNullNode) {
             IsNullNode isNullNode = (IsNullNode) node;
-            return gen.emitConditionalMove(operand(isNullNode.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue);
+            PlatformKind kind = gen.getPlatformKind(isNullNode.object().stamp());
+            return gen.emitConditionalMove(kind, operand(isNullNode.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue);
         } else if (node instanceof CompareNode) {
             CompareNode compare = (CompareNode) node;
-            return gen.emitConditionalMove(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
+            PlatformKind kind = gen.getPlatformKind(compare.x().stamp());
+            return gen.emitConditionalMove(kind, operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
         } else if (node instanceof LogicConstantNode) {
             return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
         } else if (node instanceof IntegerTestNode) {
@@ -635,7 +639,8 @@
             if (keyCount == 1) {
                 assert defaultTarget != null;
                 double probability = x.probability(x.keySuccessor(0));
-                gen.emitCompareBranch(gen.load(operand(x.value())), x.keyAt(0), Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
+                PlatformKind kind = gen.getPlatformKind(x.value().stamp());
+                gen.emitCompareBranch(kind, gen.load(operand(x.value())), x.keyAt(0), Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
             } else {
                 LabelRef[] keyTargets = new LabelRef[keyCount];
                 Constant[] keyConstants = new Constant[keyCount];
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Thu Apr 03 19:25:11 2014 +0200
@@ -34,6 +34,8 @@
 import com.oracle.graal.lir.asm.*;
 
 public enum AMD64Compare {
+    BCMP,
+    SCMP,
     ICMP,
     LCMP,
     ACMP,
@@ -59,8 +61,10 @@
         @Override
         protected void verify() {
             super.verify();
-            assert (name().startsWith("I") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
-                            (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
+            assert (name().startsWith("B") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
+                            (name().startsWith("S") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
+                            (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) ||
+                            (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
                             (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double);
         }
     }
@@ -82,6 +86,12 @@
         public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (isRegister(y)) {
                 switch (opcode) {
+                    case BCMP:
+                        masm.cmpb(asIntReg(y), address.toAddress());
+                        break;
+                    case SCMP:
+                        masm.cmpw(asIntReg(y), address.toAddress());
+                        break;
                     case ICMP:
                         masm.cmpl(asIntReg(y), address.toAddress());
                         break;
@@ -102,6 +112,12 @@
                 }
             } else if (isConstant(y)) {
                 switch (opcode) {
+                    case BCMP:
+                        masm.cmpb(address.toAddress(), crb.asIntConst(y));
+                        break;
+                    case SCMP:
+                        masm.cmpw(address.toAddress(), crb.asIntConst(y));
+                        break;
                     case ICMP:
                         masm.cmpl(address.toAddress(), crb.asIntConst(y));
                         break;
@@ -128,6 +144,12 @@
     public static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, AMD64Compare opcode, Value x, Value y) {
         if (isRegister(x) && isRegister(y)) {
             switch (opcode) {
+                case BCMP:
+                    masm.cmpb(asIntReg(x), asIntReg(y));
+                    break;
+                case SCMP:
+                    masm.cmpw(asIntReg(x), asIntReg(y));
+                    break;
                 case ICMP:
                     masm.cmpl(asIntReg(x), asIntReg(y));
                     break;
@@ -149,6 +171,20 @@
         } else if (isRegister(x) && isConstant(y)) {
             boolean isZero = ((Constant) y).isDefaultForKind();
             switch (opcode) {
+                case BCMP:
+                    if (isZero) {
+                        masm.testl(asIntReg(x), asIntReg(x));
+                    } else {
+                        masm.cmpb(asIntReg(x), crb.asIntConst(y));
+                    }
+                    break;
+                case SCMP:
+                    if (isZero) {
+                        masm.testl(asIntReg(x), asIntReg(x));
+                    } else {
+                        masm.cmpw(asIntReg(x), crb.asIntConst(y));
+                    }
+                    break;
                 case ICMP:
                     if (isZero) {
                         masm.testl(asIntReg(x), asIntReg(x));
@@ -181,6 +217,12 @@
             }
         } else if (isRegister(x) && isStackSlot(y)) {
             switch (opcode) {
+                case BCMP:
+                    masm.cmpb(asIntReg(x), (AMD64Address) crb.asByteAddr(y));
+                    break;
+                case SCMP:
+                    masm.cmpw(asIntReg(x), (AMD64Address) crb.asShortAddr(y));
+                    break;
                 case ICMP:
                     masm.cmpl(asIntReg(x), (AMD64Address) crb.asIntAddr(y));
                     break;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Thu Apr 03 14:01:39 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Thu Apr 03 19:25:11 2014 +0200
@@ -37,7 +37,7 @@
 
 /**
  * Fills in a {@link CompilationResult} as its code is being assembled.
- * 
+ *
  * @see CompilationResultBuilderFactory
  */
 public class CompilationResultBuilder {
@@ -264,6 +264,16 @@
         return recordDataReferenceInCode((Constant) value, 8);
     }
 
+    public AbstractAddress asByteAddr(Value value) {
+        assert value.getKind() == Kind.Byte || value.getKind() == Kind.Boolean;
+        return asAddress(value);
+    }
+
+    public AbstractAddress asShortAddr(Value value) {
+        assert value.getKind() == Kind.Short || value.getKind() == Kind.Char;
+        return asAddress(value);
+    }
+
     public AbstractAddress asIntAddr(Value value) {
         assert value.getKind() == Kind.Int;
         return asAddress(value);