diff options
author | Vladimir Marko <vmarko@google.com> | 2013-12-03 15:25:24 +0000 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2013-12-03 18:32:29 +0000 |
commit | 70b797d998f2a28e39f7d6ffc8a07c9cbc47da14 (patch) | |
tree | e5607068be133899ff9111e33327e0c2aa525cd1 | |
parent | 057c74a3a2d50d1247d4e6472763ca6f59060762 (diff) | |
download | art-70b797d998f2a28e39f7d6ffc8a07c9cbc47da14.tar.gz art-70b797d998f2a28e39f7d6ffc8a07c9cbc47da14.tar.bz2 art-70b797d998f2a28e39f7d6ffc8a07c9cbc47da14.zip |
Unsafe.compareAndSwapLong() intrinsic for x86.
Change-Id: Idbc5371a62dfdd84485a657d4548990519200205
-rw-r--r-- | compiler/dex/compiler_enums.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/x86/assemble_x86.cc | 6 | ||||
-rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 21 | ||||
-rw-r--r-- | compiler/dex/quick/x86/target_x86.cc | 4 | ||||
-rw-r--r-- | compiler/dex/quick/x86/x86_dex_file_method_inliner.cc | 4 | ||||
-rw-r--r-- | compiler/dex/quick/x86/x86_lir.h | 2 | ||||
-rw-r--r-- | disassembler/disassembler_x86.cc | 7 |
8 files changed, 42 insertions, 4 deletions
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h index 56facfd889..d73f148dcf 100644 --- a/compiler/dex/compiler_enums.h +++ b/compiler/dex/compiler_enums.h @@ -374,6 +374,7 @@ enum OpFeatureFlags { kRegUseA, kRegUseC, kRegUseD, + kRegUseB, kRegUseFPCSList0, kRegUseFPCSList2, kRegUseList0, diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 92e21ffdf7..9d35667b51 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -71,6 +71,7 @@ typedef uint32_t CodeOffset; // Native code offset in bytes. #define REG_USEA (1ULL << kRegUseA) #define REG_USEC (1ULL << kRegUseC) #define REG_USED (1ULL << kRegUseD) +#define REG_USEB (1ULL << kRegUseB) #define REG_USE_FPCS_LIST0 (1ULL << kRegUseFPCSList0) #define REG_USE_FPCS_LIST2 (1ULL << kRegUseFPCSList2) #define REG_USE_LIST0 (1ULL << kRegUseList0) diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc index 0b7b2bd94f..96dc6ee7d1 100644 --- a/compiler/dex/quick/x86/assemble_x86.cc +++ b/compiler/dex/quick/x86/assemble_x86.cc @@ -246,7 +246,9 @@ ENCODING_MAP(Cmp, IS_LOAD, 0, 0, UNARY_ENCODING_MAP(Idivmod, 0x7, 0, SETS_CCODES, DaR, kRegRegReg, IS_UNARY_OP | REG_USE0, DaM, kRegRegMem, IS_BINARY_OP | REG_USE0, DaA, kRegRegArray, IS_QUAD_OP | REG_USE01, 0, REG_DEFA_USEA, REG_DEFAD_USEAD, REG_DEFAD_USEAD, "ah:al,ax,", "dx:ax,dx:ax,", "edx:eax,edx:eax,"), #undef UNARY_ENCODING_MAP - { kX86Bswap32R, kRegOpcode, IS_UNARY_OP | REG_DEF0_USE0, { 0, 0, 0x0F, 0xC8, 0, 0, 0, 0 }, "Bswap32R", "!0r" }, + { kX86Bswap32R, kRegOpcode, IS_UNARY_OP | REG_DEF0_USE0, { 0, 0, 0x0F, 0xC8, 0, 0, 0, 0 }, "Bswap32R", "!0r" }, + { kX86Push32R, kRegOpcode, IS_UNARY_OP | REG_USE0 | IS_STORE, { 0, 0, 0x50, 0, 0, 0, 0, 0 }, "Push32R", "!0r" }, + { kX86Pop32R, kRegOpcode, IS_UNARY_OP | REG_DEF0 | IS_LOAD, { 0, 0, 0x58, 0, 0, 0, 0, 0 }, "Pop32R", "!0r" }, #define EXT_0F_ENCODING_MAP(opname, prefix, opcode, reg_def) \ { kX86 ## opname ## RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE01, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0 }, #opname "RR", "!0r,!1r" }, \ @@ -308,6 +310,8 @@ ENCODING_MAP(Cmp, IS_LOAD, 0, 0, { kX86CmpxchgAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014 | REG_DEFA_USEA | SETS_CCODES, { 0, 0, 0x0F, 0xB1, 0, 0, 0, 0 }, "Cmpxchg", "[!0r+!1r<<!2d+!3d],!4r" }, { kX86LockCmpxchgMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02 | REG_DEFA_USEA | SETS_CCODES, { 0xF0, 0, 0x0F, 0xB1, 0, 0, 0, 0 }, "Lock Cmpxchg", "[!0r+!1d],!2r" }, { kX86LockCmpxchgAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014 | REG_DEFA_USEA | SETS_CCODES, { 0xF0, 0, 0x0F, 0xB1, 0, 0, 0, 0 }, "Lock Cmpxchg", "[!0r+!1r<<!2d+!3d],!4r" }, + { kX86LockCmpxchg8bM, kMem, IS_STORE | IS_BINARY_OP | REG_USE0 | REG_DEFAD_USEAD | REG_USEC | REG_USEB | SETS_CCODES, { 0xF0, 0, 0x0F, 0xC7, 0, 1, 0, 0 }, "Lock Cmpxchg8b", "[!0r+!1d]" }, + { kX86LockCmpxchg8bA, kArray, IS_STORE | IS_QUAD_OP | REG_USE01 | REG_DEFAD_USEAD | REG_USEC | REG_USEB | SETS_CCODES, { 0xF0, 0, 0x0F, 0xC7, 0, 1, 0, 0 }, "Lock Cmpxchg8b", "[!0r+!1r<<!2d+!3d]" }, EXT_0F_ENCODING_MAP(Movzx8, 0x00, 0xB6, REG_DEF0), EXT_0F_ENCODING_MAP(Movzx16, 0x00, 0xB7, REG_DEF0), diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index b65fe549c9..0133a0afaf 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -293,7 +293,26 @@ bool X86Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) { // If is_long, high half is in info->args[7] if (is_long) { - LOG(FATAL) << "CAS64: Not implemented"; + FlushAllRegs(); + LockCallTemps(); + NewLIR1(kX86Push32R, rDI); + MarkTemp(rDI); + LockTemp(rDI); + NewLIR1(kX86Push32R, rSI); + MarkTemp(rSI); + LockTemp(rSI); + LoadValueDirectFixed(rl_src_obj, rDI); + LoadValueDirectFixed(rl_src_offset, rSI); + LoadValueDirectWideFixed(rl_src_expected, rAX, rDX); + LoadValueDirectWideFixed(rl_src_new_value, rBX, rCX); + NewLIR4(kX86LockCmpxchg8bA, rDI, rSI, 0, 0); + FreeTemp(rSI); + UnmarkTemp(rSI); + NewLIR1(kX86Pop32R, rSI); + FreeTemp(rDI); + UnmarkTemp(rDI); + NewLIR1(kX86Pop32R, rDI); + FreeCallTemps(); } else { // EAX must hold expected for CMPXCHG. Neither rl_new_value, nor r_ptr may be in EAX. FlushReg(r0); diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index 878fa769b6..b7a607fa40 100644 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -165,6 +165,10 @@ void X86Mir2Lir::SetupTargetResourceMasks(LIR* lir, uint64_t flags) { if (flags & REG_USED) { SetupRegMask(&lir->u.m.use_mask, rDX); } + + if (flags & REG_USEB) { + SetupRegMask(&lir->u.m.use_mask, rBX); + } } /* For dumping instructions */ diff --git a/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc b/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc index f0e76c9e5e..88e933f868 100644 --- a/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc +++ b/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc @@ -66,8 +66,8 @@ const DexFileMethodInliner::IntrinsicDef X86DexFileMethodInliner::kIntrinsicMeth INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas, kIntrinsicFlagNone), - // INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas, - // kIntrinsicFlagIsLong), + INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas, + kIntrinsicFlagIsLong), INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas, kIntrinsicFlagIsObject), diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h index bbcae92f7d..5fe76fe2f9 100644 --- a/compiler/dex/quick/x86/x86_lir.h +++ b/compiler/dex/quick/x86/x86_lir.h @@ -314,6 +314,7 @@ enum X86OpCode { UnaryOpcode(kX86Divmod, DaR, DaM, DaA), UnaryOpcode(kX86Idivmod, DaR, DaM, DaA), kX86Bswap32R, + kX86Push32R, kX86Pop32R, #undef UnaryOpcode #define Binary0fOpCode(opcode) \ opcode ## RR, opcode ## RM, opcode ## RA @@ -355,6 +356,7 @@ enum X86OpCode { Binary0fOpCode(kX86Imul32), // 32bit multiply kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR, // compare and exchange kX86LockCmpxchgMR, kX86LockCmpxchgAR, // locked compare and exchange + kX86LockCmpxchg8bM, kX86LockCmpxchg8bA, // locked compare and exchange Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 9ed65cd80a..8781c7a274 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -520,6 +520,13 @@ DISASSEMBLER_ENTRY(cmp, case 0xB7: opcode << "movzxw"; has_modrm = true; load = true; break; case 0xBE: opcode << "movsxb"; has_modrm = true; load = true; break; case 0xBF: opcode << "movsxw"; has_modrm = true; load = true; break; + case 0xC7: + static const char* x0FxC7_opcodes[] = { "unknown-0f-c7", "cmpxchg8b", "unknown-0f-c7", "unknown-0f-c7", "unknown-0f-c7", "unknown-0f-c7", "unknown-0f-c7", "unknown-0f-c7" }; + modrm_opcodes = x0FxC7_opcodes; + has_modrm = true; + reg_is_opcode = true; + store = true; + break; case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: opcode << "bswap"; reg_in_opcode = true; |