Fix byte_cas to work on non-word aligned addresses

(cherry picked from commit 1279d12eb94b7664fc839d4ef7f30c7d6b20e603)

Change-Id: I307f65f20609bca8ec9c9f9a0ea4725c7ab8ad74
diff --git a/runtime/gc/accounting/card_table-inl.h b/runtime/gc/accounting/card_table-inl.h
index 45ab214..7bd53df 100644
--- a/runtime/gc/accounting/card_table-inl.h
+++ b/runtime/gc/accounting/card_table-inl.h
@@ -29,14 +29,15 @@
 
 static inline bool byte_cas(byte old_value, byte new_value, byte* address) {
   // Little endian means most significant byte is on the left.
-  const size_t shift = reinterpret_cast<uintptr_t>(address) % sizeof(uintptr_t);
+  const size_t shift_in_bytes = reinterpret_cast<uintptr_t>(address) % sizeof(uintptr_t);
   // Align the address down.
-  address -= shift;
+  address -= shift_in_bytes;
+  const size_t shift_in_bits = shift_in_bytes * kBitsPerByte;
   int32_t* word_address = reinterpret_cast<int32_t*>(address);
   // Word with the byte we are trying to cas cleared.
-  const int32_t cur_word = *word_address & ~(0xFF << shift);
-  const int32_t old_word = cur_word | (static_cast<int32_t>(old_value) << shift);
-  const int32_t new_word = cur_word | (static_cast<int32_t>(new_value) << shift);
+  const int32_t cur_word = *word_address & ~(0xFF << shift_in_bits);
+  const int32_t old_word = cur_word | (static_cast<int32_t>(old_value) << shift_in_bits);
+  const int32_t new_word = cur_word | (static_cast<int32_t>(new_value) << shift_in_bits);
   bool success = android_atomic_cas(old_word, new_word, word_address) == 0;
   return success;
 }