# HG changeset patch # User Christian Wimmer # Date 1402078002 25200 # Node ID 03eda0a202e9e78db0b5aaba912ca312ea2e2543 # Parent 1d2c8c963d98499733673103d4783468c2041756 Better fix for prefix byte for AMD64 byte instructions diff -r 1d2c8c963d98 -r 03eda0a202e9 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 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 { diff -r 1d2c8c963d98 -r 03eda0a202e9 src/cpu/x86/vm/assembler_x86.cpp --- 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 { diff -r 1d2c8c963d98 -r 03eda0a202e9 src/cpu/x86/vm/assembler_x86.hpp --- 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);