changeset 16064:03eda0a202e9

Better fix for prefix byte for AMD64 byte instructions
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 06 Jun 2014 11:06:42 -0700
parents 1d2c8c963d98
children f59498d6e8b1
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java src/cpu/x86/vm/assembler_x86.cpp src/cpu/x86/vm/assembler_x86.hpp
diffstat 3 files changed, 20 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Fri Jun 06 18:18:04 2014 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Fri Jun 06 11:06:42 2014 -0700
@@ -185,7 +185,7 @@
     }
 
     private void emitArithImm8(int op, Register dst, int imm8) {
-        int encode = prefixAndEncode(op, dst.encoding, true);
+        int encode = prefixAndEncode(op, false, dst.encoding, true);
         emitByte(0x80);
         emitByte(0xC0 | encode);
         emitByte(imm8);
@@ -560,7 +560,7 @@
     }
 
     public final void cmpb(Register dst, Register src) {
-        int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+        int encode = prefixAndEncode(dst.encoding, true, src.encoding, true);
         emitByte(0x3A);
         emitByte(0xC0 | encode);
     }
@@ -1137,7 +1137,7 @@
     }
 
     public final void movsbl(Register dst, Register src) {
-        int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+        int encode = prefixAndEncode(dst.encoding, false, src.encoding, true);
         emitByte(0x0F);
         emitByte(0xBE);
         emitByte(0xC0 | encode);
@@ -2042,17 +2042,17 @@
     }
 
     private int prefixAndEncode(int dstEnc, int srcEnc) {
-        return prefixAndEncode(dstEnc, srcEnc, false);
+        return prefixAndEncode(dstEnc, false, srcEnc, false);
     }
 
-    private int prefixAndEncode(int dstEncoding, int srcEncoding, boolean byteinst) {
+    private int prefixAndEncode(int dstEncoding, boolean dstIsByte, int srcEncoding, boolean srcIsByte) {
         int srcEnc = srcEncoding;
         int dstEnc = dstEncoding;
         if (dstEnc < 8) {
             if (srcEnc >= 8) {
                 emitByte(Prefix.REXB);
                 srcEnc -= 8;
-            } else if (byteinst && (srcEnc >= 4 || dstEnc >= 4)) {
+            } else if ((srcIsByte && srcEnc >= 4) || (dstIsByte && dstEnc >= 4)) {
                 emitByte(Prefix.REX);
             }
         } else {
--- a/src/cpu/x86/vm/assembler_x86.cpp	Fri Jun 06 18:18:04 2014 +0200
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Jun 06 11:06:42 2014 -0700
@@ -1824,7 +1824,7 @@
 
 void Assembler::movsbl(Register dst, Register src) { // movsxb
   NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
-  int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
+  int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
   emit_int8(0x0F);
   emit_int8((unsigned char)0xBE);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1916,8 +1916,13 @@
 }
 
 void Assembler::movzbl(Register dst, Register src) { // movzxb
-  NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
-  int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
+#ifdef _LP64
+  // Requires the REX.W prefix to be able to access source register rsi and rdi
+  int encode = prefixq_and_encode(dst->encoding(), src->encoding());
+#else
+  assert(src->has_byte_register(), "must have byte register");
+  int encode = prefix_and_encode(dst->encoding(), src->encoding());
+#endif
   emit_int8(0x0F);
   emit_int8((unsigned char)0xB6);
   emit_int8(0xC0 | encode);
@@ -4562,12 +4567,12 @@
   return reg_enc;
 }
 
-int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) {
+int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte) {
   if (dst_enc < 8) {
     if (src_enc >= 8) {
       prefix(REX_B);
       src_enc -= 8;
-    } else if (byteinst && (src_enc >= 4 || dst_enc >= 4)) {
+    } else if ((src_is_byte && src_enc >= 4) || (dst_is_byte && dst_enc >= 4)) {
       prefix(REX);
     }
   } else {
--- a/src/cpu/x86/vm/assembler_x86.hpp	Fri Jun 06 18:18:04 2014 +0200
+++ b/src/cpu/x86/vm/assembler_x86.hpp	Fri Jun 06 11:06:42 2014 -0700
@@ -556,7 +556,10 @@
   int prefix_and_encode(int reg_enc, bool byteinst = false);
   int prefixq_and_encode(int reg_enc);
 
-  int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false);
+  int prefix_and_encode(int dst_enc, int src_enc) {
+    return prefix_and_encode(dst_enc, false, src_enc, false);
+  }
+  int prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte);
   int prefixq_and_encode(int dst_enc, int src_enc);
 
   void prefix(Register reg);