  Mapping programs from one architecture to another plays a key role in
technologies such as binary translation, decompilation, emulation,
virtualization, and application migration. Although multicore architectures are
ubiquitous, the state-of-the-art translation tools do not handle concurrency
primitives correctly. Doing so is rather challenging because of the subtle
differences in the concurrency models between architectures.
  In response, we address various aspects of the challenge. First, we develop
correct and efficient translations between the concurrency models of two
mainstream architecture families: x86 and ARM (versions 7 and 8). We develop
direct mappings between x86 and ARMv8 and ARMv7, and fence elimination
algorithms to eliminate redundant fences after direct mapping. Although our
mapping utilizes ARMv8 as an intermediate model for mapping between x86 and
ARMv7, we argue that it should not be used as an intermediate model in a
decompiler because it disallows common compiler transformations.
  Second, we propose and implement a technique for inserting memory fences for
safely migrating programs between different architectures. Our technique checks
robustness against x86 and ARM, and inserts fences upon robustness violations.
Our experiments demonstrate that in most of the programs both our techniques
introduce significantly fewer fences compared to naive schemes for porting
applications across these architectures.
