Make wide-volatile loads and stores atomic.

This implements the four wide-volatile instructions added in a previous
change, and modifies the verifier to substitute the opcodes into the
instruction stream when appropriate.

For mterp, the ARM wide get/put instructions now have conditional code
that replaces ldrd/strd with a call to the quasiatomic functions.  The
C version does essentially the same thing.  ARMv4T lacks ldrd/stdrd, and
uses separate implementations for the wide field accesses, so those were
updated as well.  x86 will just use stubs.

The JIT should punt these to the interpreter.

Change-Id: Ife88559ed1a698c3267d43c454896f6b12081c0f
Also:
 - We don't seem to be using the negative widths in the instruction
   table.  Not sure they're useful anymore.
 - Tabs -> spaces in x86-atom throw-verification-error impl.
diff --git a/vm/oo/Object.h b/vm/oo/Object.h
index be2c9f2..5ceb42c 100644
--- a/vm/oo/Object.h
+++ b/vm/oo/Object.h
@@ -21,6 +21,8 @@
 #ifndef _DALVIK_OO_OBJECT
 #define _DALVIK_OO_OBJECT
 
+#include <Atomic.h>
+
 #include <stddef.h>
 
 /* fwd decl */
@@ -713,6 +715,10 @@
 INLINE Object* dvmGetFieldObject(const Object* obj, int offset) {
     return ((JValue*)BYTE_OFFSET(obj, offset))->l;
 }
+INLINE s8 dvmGetFieldLongVolatile(const Object* obj, int offset) {
+    const s8* addr = BYTE_OFFSET(obj, offset);
+    return android_quasiatomic_read_64((s8*)addr);
+}
 
 INLINE void dvmSetFieldBoolean(Object* obj, int offset, bool val) {
     ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
@@ -741,6 +747,10 @@
 INLINE void dvmSetFieldObject(Object* obj, int offset, Object* val) {
     ((JValue*)BYTE_OFFSET(obj, offset))->l = val;
 }
+INLINE void dvmSetFieldLongVolatile(Object* obj, int offset, s8 val) {
+    s8* addr = BYTE_OFFSET(obj, offset);
+    android_quasiatomic_swap_64(val, addr);
+}
 
 /*
  * Static field access functions.
@@ -776,6 +786,10 @@
 INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) {
     return sfield->value.l;
 }
+INLINE s8 dvmGetStaticFieldLongVolatile(const StaticField* sfield) {
+    const s8* addr = &sfield->value.j;
+    return android_quasiatomic_read_64((s8*)addr);
+}
 
 INLINE void dvmSetStaticFieldBoolean(StaticField* sfield, bool val) {
     sfield->value.i = val;
@@ -804,6 +818,10 @@
 INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) {
     sfield->value.l = val;
 }
+INLINE void dvmSetStaticFieldLongVolatile(StaticField* sfield, s8 val) {
+    s8* addr = &sfield->value.j;
+    android_quasiatomic_swap_64(val, addr);
+}
 
 /*
  * Helpers.
@@ -859,6 +877,9 @@
 INLINE bool dvmIsFinalField(const Field* field) {
     return (field->accessFlags & ACC_FINAL) != 0;
 }
+INLINE bool dvmIsVolatileField(const Field* field) {
+    return (field->accessFlags & ACC_VOLATILE) != 0;
+}
 
 INLINE bool dvmIsInterfaceClass(const ClassObject* clazz) {
     return (clazz->accessFlags & ACC_INTERFACE) != 0;