Skip to content

Commit ab39b74

Browse files
elijahtaylorvargaz
authored andcommittedApr 7, 2013
NaCl ARM work, first pass
1 parent 1e726ce commit ab39b74

File tree

9 files changed

+204
-12
lines changed

9 files changed

+204
-12
lines changed
 

‎configure.in

+31
Original file line numberDiff line numberDiff line change
@@ -2586,6 +2586,15 @@ case "$host" in
25862586
NESTED_LIBGC_FLAGS="$NESTED_LIBGC_FLAGS -DHAVE_ARMV6"
25872587
fi
25882588
;;
2589+
# TODO: make proper support for NaCl host.
2590+
# arm*-*nacl)
2591+
# TARGET=ARM;
2592+
# arch_target=arm;
2593+
# ACCESS_UNALIGNED="no"
2594+
# JIT_SUPPORTED=yes
2595+
# sgen_supported=true
2596+
# AOT_SUPPORTED="no"
2597+
# ;;
25892598
s390-*-linux*)
25902599
TARGET=S390;
25912600
arch_target=s390;
@@ -2650,6 +2659,28 @@ if test "x$host" != "x$target"; then
26502659
AC_DEFINE(__mono_ilp32__, 1, [64 bit mode with 4 byte longs and pointers])
26512660
sizeof_register=8
26522661
;;
2662+
# TODO: make proper support for NaCl target.
2663+
# arm*-*nacl)
2664+
# TARGET=ARM
2665+
# arch_target=arm
2666+
# AC_DEFINE(TARGET_ARM, 1, [...])
2667+
# ACCESS_UNALIGNED="no"
2668+
# JIT_SUPPORTED=yes
2669+
# sizeof_register=4
2670+
# CPPFLAGS="$CPPFLAGS \
2671+
# -DARM_FPU_VFP=1 -D__ARM_EABI__ \
2672+
# -D__arm__ \
2673+
# -D__portable_native_client__ \
2674+
# -DARM_FPU_VFP=1 \
2675+
# -Dtimezone=_timezone \
2676+
# -DDISABLE_SOCKETS \
2677+
# -DDISABLE_ATTACH \
2678+
# -DUSE_NEWLIB"
2679+
# jit_wanted=true
2680+
# Can't use tls, since it depends on the runtime detection of tls offsets
2681+
# in mono-compiler.h
2682+
# with_tls=pthread
2683+
# ;;
26532684
i686-*-nacl)
26542685
TARGET=X86
26552686
arch_target=x86

‎libgc/include/private/gc_locks.h

+12-1
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,22 @@
223223
# define GC_CLEAR_DEFINED
224224
# endif /* ALPHA */
225225
# ifdef ARM32
226+
#ifdef __native_client__
227+
#define NACL_ALIGN() ".align 4\n"
228+
#define MASK_REGISTER(reg) "bic " reg ", " reg ", #0xc0000000\n"
229+
#else
230+
#define NACL_ALIGN()
231+
#define MASK_REGISTER(reg)
232+
#endif
226233
inline static int GC_test_and_set(volatile unsigned int *addr) {
227234
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__)
228235
int ret, tmp;
229236
__asm__ __volatile__ (
230237
"1:\n"
238+
NACL_ALIGN()
239+
MASK_REGISTER("%3")
231240
"ldrex %0, [%3]\n"
241+
MASK_REGISTER("%3")
232242
"strex %1, %2, [%3]\n"
233243
"teq %1, #0\n"
234244
"bne 1b\n"
@@ -242,7 +252,8 @@
242252
* bus because there are no SMP ARM machines. If/when there are,
243253
* this code will likely need to be updated. */
244254
/* See linuxthreads/sysdeps/arm/pt-machine.h in glibc-2.1 */
245-
__asm__ __volatile__("swp %0, %1, [%2]"
255+
__asm__ __volatile__(MASK_REGISTER("%2")
256+
"swp %0, %1, [%2]"
246257
: "=&r"(oldval)
247258
: "r"(1), "r"(addr)
248259
: "memory");

‎libgc/include/private/gcconfig.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@
7676
# endif
7777
# if defined(__arm__) || defined(__thumb__)
7878
# define ARM32
79-
# if !defined(LINUX) && !defined(NETBSD) && !defined(DARWIN)
79+
# if defined(NACL)
80+
# define mach_type_known
81+
# elif !defined(LINUX) && !defined(NETBSD) && !defined(DARWIN)
8082
# define NOSYS
8183
# define mach_type_known
8284
# endif
@@ -1926,8 +1928,12 @@
19261928
# endif
19271929

19281930
# ifdef ARM32
1929-
# define CPP_WORDSZ 32
1931+
# if defined( NACL )
1932+
# define MACH_TYPE "NACL"
1933+
# else
19301934
# define MACH_TYPE "ARM32"
1935+
# endif
1936+
# define CPP_WORDSZ 32
19311937
# define ALIGNMENT 4
19321938
# ifdef NETBSD
19331939
# define OS_TYPE "NETBSD"

‎libgc/pthread_stop_world.c

+16
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,22 @@ static void pthread_stop_world()
537537
__asm__ __volatile__ ("add $16, %esp");\
538538
} while (0)
539539

540+
#elif __arm__
541+
542+
#define NACL_STORE_REGS() \
543+
do { \
544+
__asm__ __volatile__ ("push {r4-r12,lr}");\
545+
__asm__ __volatile__ ("mov r0, %0" : : "r" (&nacl_gc_thread_self->stop_info.stack_ptr)); \
546+
__asm__ __volatile__ ("bic r0, r0, #0xc0000000");\
547+
__asm__ __volatile__ ("str sp, [r0]");\
548+
memcpy(nacl_gc_thread_self->stop_info.reg_storage, nacl_gc_thread_self->stop_info.stack_ptr, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\
549+
__asm__ __volatile__ ("add sp, sp, #40");\
550+
__asm__ __volatile__ ("bic sp, sp, #0xc0000000");\
551+
} while (0)
552+
#else
553+
554+
#error "Please port NACL_STORE_REGS"
555+
540556
#endif
541557

542558
void nacl_pre_syscall_hook()

‎mono/mini/exceptions-arm.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
493493
return FALSE;
494494
}
495495

496+
#if MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
496497
void
497498
mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
498499
{
@@ -504,6 +505,7 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
504505
{
505506
mono_monoctx_to_sigctx (mctx, ctx);
506507
}
508+
#endif /* MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX */
507509

508510
/*
509511
* handle_exception:
@@ -546,7 +548,7 @@ get_handle_signal_exception_addr (void)
546548
gboolean
547549
mono_arch_handle_exception (void *ctx, gpointer obj)
548550
{
549-
#if defined(MONO_CROSS_COMPILE)
551+
#if defined(MONO_CROSS_COMPILE) || !defined(MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX)
550552
g_assert_not_reached ();
551553
#elif defined(MONO_ARCH_USE_SIGACTION)
552554
arm_ucontext *sigctx = ctx;
@@ -598,6 +600,8 @@ mono_arch_ip_from_context (void *sigctx)
598600
{
599601
#ifdef MONO_CROSS_COMPILE
600602
g_assert_not_reached ();
603+
#elif defined(__native_client__)
604+
g_assert_not_reached ();
601605
#else
602606
arm_ucontext *my_uc = sigctx;
603607
return (void*) UCONTEXT_REG_PC (my_uc);

‎mono/mini/mini-arm.c

+39-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "mono/arch/arm/arm-fpa-codegen.h"
2626
#include "mono/arch/arm/arm-vfp-codegen.h"
2727

28-
#if defined(__ARM_EABI__) && defined(__linux__) && !defined(PLATFORM_ANDROID)
28+
#if defined(__ARM_EABI__) && defined(__linux__) && !defined(PLATFORM_ANDROID) && !defined(__native_client__)
2929
#define HAVE_AEABI_READ_TP 1
3030
#endif
3131

@@ -51,6 +51,29 @@
5151
#define IS_SOFT_FLOAT 0
5252
#endif
5353

54+
#ifdef __native_client_codegen__
55+
const guint kNaClAlignment = kNaClAlignmentARM;
56+
const guint kNaClAlignmentMask = kNaClAlignmentMaskARM;
57+
gint8 nacl_align_byte = -1; /* 0xff */
58+
59+
guint8 *
60+
mono_arch_nacl_pad (guint8 *code, int pad)
61+
{
62+
/* Not yet properly implemented. */
63+
g_assert_not_reached ();
64+
return code;
65+
}
66+
67+
guint8 *
68+
mono_arch_nacl_skip_nops (guint8 *code)
69+
{
70+
/* Not yet properly implemented. */
71+
g_assert_not_reached ();
72+
return code;
73+
}
74+
75+
#endif /* __native_client_codegen__ */
76+
5477
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
5578

5679
#if __APPLE__
@@ -198,8 +221,8 @@ mono_arch_fregname (int reg)
198221
return "unknown";
199222
}
200223

201-
#ifndef DISABLE_JIT
202224

225+
#ifndef DISABLE_JIT
203226
static guint8*
204227
emit_big_add (guint8 *code, int dreg, int sreg, int imm)
205228
{
@@ -762,11 +785,14 @@ void
762785
mono_arch_init (void)
763786
{
764787
InitializeCriticalSection (&mini_arch_mutex);
765-
788+
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
766789
if (mini_get_debug_options ()->soft_breakpoints) {
767790
single_step_func_wrapper = create_function_wrapper (debugger_agent_single_step_from_context);
768791
breakpoint_func_wrapper = create_function_wrapper (debugger_agent_breakpoint_from_context);
769792
} else {
793+
#else
794+
{
795+
#endif
770796
ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
771797
bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
772798
mono_mprotect (bp_trigger_page, mono_pagesize (), 0);
@@ -988,6 +1014,11 @@ mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv)
9881014
void
9891015
mono_arch_flush_icache (guint8 *code, gint size)
9901016
{
1017+
#if defined(__native_client__)
1018+
// For Native Client we don't have to flush i-cache here,
1019+
// as it's being done by dyncode interface.
1020+
#else
1021+
9911022
#ifdef MONO_CROSS_COMPILE
9921023
#elif __APPLE__
9931024
sys_icache_invalidate (code, size);
@@ -1014,6 +1045,7 @@ mono_arch_flush_icache (guint8 *code, gint size)
10141045
: "r" (code), "r" (code + size), "r" (0)
10151046
: "r0", "r1", "r3" );
10161047
#endif
1048+
#endif /* !__native_client__ */
10171049
}
10181050

10191051
typedef enum {
@@ -6353,6 +6385,8 @@ mono_arch_get_trampolines (gboolean aot)
63536385
return mono_arm_get_exception_trampolines (aot);
63546386
}
63556387

6388+
6389+
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
63566390
/*
63576391
* mono_arch_set_breakpoint:
63586392
*
@@ -6539,6 +6573,8 @@ mono_arch_skip_single_step (MonoContext *ctx)
65396573
MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 4);
65406574
}
65416575

6576+
#endif /* MONO_ARCH_SOFT_DEBUG_SUPPORTED */
6577+
65426578
/*
65436579
* mono_arch_get_seq_point_info:
65446580
*

‎mono/mini/mini-arm.h

+18-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
#include <mono/utils/mono-context.h>
1010
#include <glib.h>
1111

12+
#ifdef __native_client_codegen__
13+
#define kNaClAlignmentARM 16
14+
#define kNaClAlignmentMaskARM (kNaClAlignmentARM - 1)
15+
#define kNaClLengthOfCallImm 4
16+
#endif
17+
1218
#if defined(ARM_FPU_NONE) || (defined(__ARM_EABI__) && !defined(ARM_FPU_VFP) && !defined(ARM_FPU_VFP_HARD))
1319
#define MONO_ARCH_SOFT_FLOAT 1
1420
#endif
@@ -188,6 +194,11 @@ typedef struct MonoCompileArch {
188194
#define ARM_LAST_ARG_REG 3
189195

190196
#define MONO_ARCH_USE_SIGACTION 1
197+
198+
#if defined(__native_client__)
199+
#undef MONO_ARCH_USE_SIGACTION
200+
#endif
201+
191202
#define MONO_ARCH_NEED_DIV_CHECK 1
192203

193204
#define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
@@ -221,8 +232,14 @@ typedef struct MonoCompileArch {
221232
#define MONO_ARCH_GSHAREDVT_SUPPORTED 1
222233
#define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1
223234

235+
#if defined(__native_client__)
236+
#undef MONO_ARCH_SOFT_DEBUG_SUPPORTED
237+
#undef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
238+
#undef MONO_ARCH_HAVE_CONTEXT_SET_INT_REG
239+
#endif
240+
224241
/* Matches the HAVE_AEABI_READ_TP define in mini-arm.c */
225-
#if defined(__ARM_EABI__) && defined(__linux__) && !defined(TARGET_ANDROID)
242+
#if defined(__ARM_EABI__) && defined(__linux__) && !defined(TARGET_ANDROID) && !defined(__native_client__)
226243
#define MONO_ARCH_HAVE_TLS_GET 1
227244
#endif
228245

@@ -274,4 +291,3 @@ mono_arm_load_jumptable_entry (guint8 *code, gpointer *jte, ARMReg reg) MONO_INT
274291
#endif
275292

276293
#endif /* __MONO_MINI_ARM_H__ */
277-

‎mono/mini/mini-ops.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ MINI_OP(OP_GC_PARAM_SLOT_LIVENESS_DEF, "gc_param_slot_liveness_def", NONE, NONE,
925925
/* #if defined(__native_client_codegen__) || defined(__native_client__) */
926926
/* We have to define these in terms of the TARGET defines, not NaCl defines */
927927
/* because genmdesc.pl doesn't have multiple defines per platform. */
928-
#if defined(TARGET_AMD64) || defined(TARGET_X86)
928+
#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM)
929929
MINI_OP(OP_NACL_GC_SAFE_POINT, "nacl_gc_safe_point", IREG, NONE, NONE)
930930
#endif
931931

‎mono/utils/atomic.h

+74-2
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,14 @@ static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
733733

734734
#elif defined(__arm__)
735735

736+
#ifdef __native_client__
737+
#define MASK_REGISTER(reg, cond) "bic" cond " " reg ", " reg ", #0xc0000000\n"
738+
#define NACL_ALIGN() ".align 4\n"
739+
#else
740+
#define MASK_REGISTER(reg, cond)
741+
#define NACL_ALIGN()
742+
#endif
743+
736744
/*
737745
* Atomic operations on ARM doesn't contain memory barriers, and the runtime code
738746
* depends on this, so we add them explicitly.
@@ -743,11 +751,16 @@ static inline gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 ex
743751
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7S__)
744752
gint32 ret, tmp;
745753
__asm__ __volatile__ ( "1:\n"
754+
NACL_ALIGN()
746755
"dmb\n"
747756
"mov %0, #0\n"
757+
NACL_ALIGN()
758+
MASK_REGISTER("%2", "al")
748759
"ldrex %1, [%2]\n"
749760
"teq %1, %3\n"
750761
"it eq\n"
762+
NACL_ALIGN()
763+
MASK_REGISTER("%2", "eq")
751764
"strexeq %0, %4, [%2]\n"
752765
"teq %0, #0\n"
753766
"bne 1b\n"
@@ -761,12 +774,18 @@ static inline gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 ex
761774
gint32 a, b;
762775

763776
__asm__ __volatile__ ( "0:\n\t"
777+
NACL_ALIGN()
778+
MASK_REGISTER("%2", "al")
764779
"ldr %1, [%2]\n\t"
765780
"cmp %1, %4\n\t"
766781
"mov %0, %1\n\t"
767782
"bne 1f\n\t"
783+
NACL_ALIGN()
784+
MASK_REGISTER("%2", "al")
768785
"swp %0, %3, [%2]\n\t"
769786
"cmp %0, %1\n\t"
787+
NACL_ALIGN()
788+
MASK_REGISTER("%2", "ne")
770789
"swpne %3, %0, [%2]\n\t"
771790
"bne 0b\n\t"
772791
"1:"
@@ -785,10 +804,15 @@ static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest
785804
__asm__ __volatile__ (
786805
"dmb\n"
787806
"1:\n"
807+
NACL_ALIGN()
788808
"mov %0, #0\n"
809+
NACL_ALIGN()
810+
MASK_REGISTER("%2", "al")
789811
"ldrex %1, [%2]\n"
790812
"teq %1, %3\n"
791813
"it eq\n"
814+
NACL_ALIGN()
815+
MASK_REGISTER("%2", "eq")
792816
"strexeq %0, %4, [%2]\n"
793817
"teq %0, #0\n"
794818
"bne 1b\n"
@@ -802,12 +826,18 @@ static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest
802826
gpointer a, b;
803827

804828
__asm__ __volatile__ ( "0:\n\t"
829+
NACL_ALIGN()
830+
MASK_REGISTER("%2", "al")
805831
"ldr %1, [%2]\n\t"
806832
"cmp %1, %4\n\t"
807833
"mov %0, %1\n\t"
808834
"bne 1f\n\t"
835+
NACL_ALIGN()
836+
MASK_REGISTER("%2", "eq")
809837
"swpeq %0, %3, [%2]\n\t"
810838
"cmp %0, %1\n\t"
839+
NACL_ALIGN()
840+
MASK_REGISTER("%2", "ne")
811841
"swpne %3, %0, [%2]\n\t"
812842
"bne 0b\n\t"
813843
"1:"
@@ -826,8 +856,12 @@ static inline gint32 InterlockedIncrement(volatile gint32 *dest)
826856
__asm__ __volatile__ (
827857
"dmb\n"
828858
"1:\n"
859+
NACL_ALIGN()
860+
MASK_REGISTER("%2", "al")
829861
"ldrex %0, [%2]\n"
830862
"add %0, %0, %3\n"
863+
NACL_ALIGN()
864+
MASK_REGISTER("%2", "al")
831865
"strex %1, %0, [%2]\n"
832866
"teq %1, #0\n"
833867
"bne 1b\n"
@@ -841,10 +875,16 @@ static inline gint32 InterlockedIncrement(volatile gint32 *dest)
841875
gint32 a, b, c;
842876

843877
__asm__ __volatile__ ( "0:\n\t"
878+
NACL_ALIGN()
879+
MASK_REGISTER("%3", "al")
844880
"ldr %0, [%3]\n\t"
845881
"add %1, %0, %4\n\t"
882+
NACL_ALIGN()
883+
MASK_REGISTER("%3", "al")
846884
"swp %2, %1, [%3]\n\t"
847885
"cmp %0, %2\n\t"
886+
NACL_ALIGN()
887+
MASK_REGISTER("%3", "ne")
848888
"swpne %1, %2, [%3]\n\t"
849889
"bne 0b"
850890
: "=&r" (a), "=&r" (b), "=&r" (c)
@@ -862,8 +902,12 @@ static inline gint32 InterlockedDecrement(volatile gint32 *dest)
862902
__asm__ __volatile__ (
863903
"dmb\n"
864904
"1:\n"
905+
NACL_ALIGN()
906+
MASK_REGISTER("%2", "al")
865907
"ldrex %0, [%2]\n"
866908
"sub %0, %0, %3\n"
909+
NACL_ALIGN()
910+
MASK_REGISTER("%2", "al")
867911
"strex %1, %0, [%2]\n"
868912
"teq %1, #0\n"
869913
"bne 1b\n"
@@ -877,10 +921,16 @@ static inline gint32 InterlockedDecrement(volatile gint32 *dest)
877921
gint32 a, b, c;
878922

879923
__asm__ __volatile__ ( "0:\n\t"
924+
NACL_ALIGN()
925+
MASK_REGISTER("%3", "al")
880926
"ldr %0, [%3]\n\t"
881927
"add %1, %0, %4\n\t"
928+
NACL_ALIGN()
929+
MASK_REGISTER("%3", "al")
882930
"swp %2, %1, [%3]\n\t"
883931
"cmp %0, %2\n\t"
932+
NACL_ALIGN()
933+
MASK_REGISTER("%3", "ne")
884934
"swpne %1, %2, [%3]\n\t"
885935
"bne 0b"
886936
: "=&r" (a), "=&r" (b), "=&r" (c)
@@ -898,7 +948,11 @@ static inline gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
898948
__asm__ __volatile__ (
899949
"dmb\n"
900950
"1:\n"
951+
NACL_ALIGN()
952+
MASK_REGISTER("%3", "al")
901953
"ldrex %0, [%3]\n"
954+
NACL_ALIGN()
955+
MASK_REGISTER("%3", "al")
902956
"strex %1, %2, [%3]\n"
903957
"teq %1, #0\n"
904958
"bne 1b\n"
@@ -910,7 +964,9 @@ static inline gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
910964
#else
911965
gint32 a;
912966

913-
__asm__ __volatile__ ( "swp %0, %2, [%1]"
967+
__asm__ __volatile__ ( NACL_ALIGN()
968+
MASK_REGISTER("%1", "al")
969+
"swp %0, %2, [%1]"
914970
: "=&r" (a)
915971
: "r" (dest), "r" (exch));
916972

@@ -925,7 +981,11 @@ static inline gpointer InterlockedExchangePointer(volatile gpointer *dest, gpoin
925981
__asm__ __volatile__ (
926982
"dmb\n"
927983
"1:\n"
984+
NACL_ALIGN()
985+
MASK_REGISTER("%3", "al")
928986
"ldrex %0, [%3]\n"
987+
NACL_ALIGN()
988+
MASK_REGISTER("%3", "al")
929989
"strex %1, %2, [%3]\n"
930990
"teq %1, #0\n"
931991
"bne 1b\n"
@@ -937,7 +997,9 @@ static inline gpointer InterlockedExchangePointer(volatile gpointer *dest, gpoin
937997
#else
938998
gpointer a;
939999

940-
__asm__ __volatile__ ( "swp %0, %2, [%1]"
1000+
__asm__ __volatile__ ( NACL_ALIGN()
1001+
MASK_REGISTER("%1", "al")
1002+
"swp %0, %2, [%1]"
9411003
: "=&r" (a)
9421004
: "r" (dest), "r" (exch));
9431005

@@ -952,8 +1014,12 @@ static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
9521014
__asm__ __volatile__ (
9531015
"dmb\n"
9541016
"1:\n"
1017+
NACL_ALIGN()
1018+
MASK_REGISTER("%3", "al")
9551019
"ldrex %0, [%3]\n"
9561020
"add %1, %0, %4\n"
1021+
NACL_ALIGN()
1022+
MASK_REGISTER("%3", "al")
9571023
"strex %2, %1, [%3]\n"
9581024
"teq %2, #0\n"
9591025
"bne 1b\n"
@@ -967,10 +1033,16 @@ static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
9671033
int a, b, c;
9681034

9691035
__asm__ __volatile__ ( "0:\n\t"
1036+
NACL_ALIGN()
1037+
MASK_REGISTER("%3", "al")
9701038
"ldr %0, [%3]\n\t"
9711039
"add %1, %0, %4\n\t"
1040+
NACL_ALIGN()
1041+
MASK_REGISTER("%3", "al")
9721042
"swp %2, %1, [%3]\n\t"
9731043
"cmp %0, %2\n\t"
1044+
NACL_ALIGN()
1045+
MASK_REGISTER("%3", "ne")
9741046
"swpne %1, %2, [%3]\n\t"
9751047
"bne 0b"
9761048
: "=&r" (a), "=&r" (b), "=&r" (c)

0 commit comments

Comments
 (0)
Please sign in to comment.