Instruction Set Migration at Warehouse Scale

· Communications of the ACM ·

26 min read Original article ↗

Migrating large codebases to a new instruction set architecture (ISA) is a major engineering challenge. Examples include Apple’s migration from PowerPC to x86 and later to Arm,3 as well as the adoption of Arm by major hyperscalers (such as Amazon, Google, and Microsoft). While there are anecdotal claims regarding the complexity and efforts required1,26,28 and several historical records of such migrations,23,33,34 to our knowledge, there is no systematic analysis of what these ISA migrations entail today and how they are impacted by modern technologies, such as improved software-engineering tools and AI. In this article, we perform such a systematic analysis for the migration of a multibillion-line codebase from x86 to Arm at Google.

When source code is available, as is often the case via open source or within large organizations, recompilation is preferred over techniques such as binary translation.a Contemporary ISAs are generally well-supported in upstream compilers, runtime libraries, and the Linux kernel. As a result, modern compilers mostly “just work” for a new ISA, and previous ISA additions have smoothed the path to packages supporting cross-compilation by default. For example, 98% of Debian packages build for RISC-V, although it only became an official Debian architecture in 2023.9

Perhaps surprisingly, this does not mean ISA migration is no longer a challenge in the presence of source code. We find that modern ISA migration involves many usually-simple, repetitive tasks such as updating build scripts or fixing floating-point issues. In contrast to historical migrations, the volume of simple changes is much higher today. This creates challenges but also presents opportunities for automation, including with AI. We focus on three research questions:

  1. What are the tasks involved in a modern ISA migration?

  2. Which tasks can be successfully automated with conventional methods?

  3. How can modern AI help automation, and what tasks remain challenging?

To answer these questions, we provide what we believe is a first-ever detailed breakdown and taxonomy of large-scale ISA migration tasks. Using state-of-the-art LLMs, we analyze and categorize a corpus of 38,156 commits that constitute our real-world migration. We quantitatively evaluate the capability of current tools, including AI models, to perform these tasks automatically. We systematically identify the strengths and weaknesses of current automated tools and highlight areas of future work and improvement. We believe this work highlights research opportunities for the academic community and revisits longstanding assumptions around ISA migrations.

Specifically, we contribute the following insights:

  • The complexity of ISA migrations involves a number of different tasks, many related to rewriting build and configuration files.

  • Many of these tasks are highly automatable.

  • Many of the tasks that are not automatable only need to be performed once when going from a single ISA to multiarch.

  • Of the remaining tasks, many can be performed by modern AI, but some challenges remain.

Background and Related Work

There are several reasons why organizations have performed large-scale ISA migrations. First, many ISAs have gone extinct over the years (e.g., Alpha, MIPS, SPARC, Itanium, VAX). Second, the proliferation of Android and iOS apps drove many codebases to be ported to Arm. Third, Apple Macs went through successive migrations from PowerPC to x86 to Arm. Finally, major cloud hyperscalers have also been migrating large codebases from x86 to Arm.

In this context, migration not only refers to getting software to build on a new architecture, but also to reaching parity in terms of performance, security, and stability. While ISA migrations go back more than 30 to 40 years,23,33,34 modern migrations are vastly larger and more dependency-heavy than these historical examples. The most closely related academic work falls into two categories.

First, there is a significant amount of work on static and dynamic binary ISA translation13,32 to address the long tail of a software ecosystem. Such systems are eventually deprecated to avoid carrying forward technical debt, as seen with Apple’s planned phaseout of Rosetta.1 In cloud computing, where compute is commoditized, recompiling onto the new ISA maximizes performance and efficiency. We thus forewent binary translation altogether.

Second, there is extensive research on automatically applying edits to code, such as for performance optimization,21 fixing security issues,17 or correcting bugs.4 As we will see, these are common tasks that are part of a successful ISA migration.

Google’s x86 to Arm Journey

We now analyze Google’s multi-year effort to port a substantial portion of Google’s server application ecosystem from x86 to Arm, enabling simultaneous support for both. We start by describing Google’s environment and provide a step-by-step analysis of our ISA migration.

Google’s software ecosystem.  Google’s codebase is organized as a monorepo containing billions of lines of code.29 Individual applications and libraries reside in various directories. These directories also contain metadata files, e.g., to indicate code owners or configure continuous integration (CI) testing.38 An overview figure of this internal ecosystem can be found in Henderson et al.15

Building with Bazel.  Builds use Bazel,6 a highly configurable build system. BUILD and bzl files describe how binaries, libraries, and tests are built from source files. Most code is covered by our primary continuous integration system, “TAP” [Test Automation Platform],19,24 which gates releases similarly to GitHub Actions or GitLab CI. Bazel’s builds and tests (including TAP) run on a shared set of machines called Forge,37 which provides a distributed build execution and caching service. Forge’s scale and cache enable Google to compile everything needed for a binary from scratch on every build, including fundamental dependencies such as the Python interpreter.

Creating releases with Blueprints.  Google distinguishes between compiled binaries and release packages (internally referred to as “MPMs” for the Midas Package Manager that stores them globally).6 These packages are bundles of binaries and static assets ready to be deployed in Google’s clusters, akin to Debian packages or container images. Releases are defined by “Blueprint” files, which serve as release configuration manifests (similar to Helm charts or Kubernetes manifests)25 to specify dependencies, environment settings, and build flags. An automated continuous delivery system called Rapid5 consumes these manifests, runs CI tests, and builds release packages.

Multiarch support.  Google’s fleet has supported dozens of CPUs over the years, and services run on machines that can be as much as 10 years old. During development, engineers can configure builds and testing across multiple architectures (e.g., Arm, K8, Haswell) in their Blueprints. Multiple architectures are also supported at release time, producing multiarch MPMs. Unless an owner adds specific constraints, a job can be scheduled on any machine with an architecture-compatible MPM, and owners expect to run on a mix of different kinds of machines with different performance profiles simultaneously.

Shifting down and large-scale changes.  Google has moved to a “shift down” approach to development,11 where developers only focus on one level of the stack and other issues are abstracted and/or automated for them. For example, the CI pipelines (e.g. Bazel, TAP, and Rapid) mean developers do not generally need to worry about the specifics of build systems or releases. In addition, a healthy automated testing culture means everyone can change code throughout the monorepo without frequent breakages. This enables large-scale changes (LSCs),38 monorepo-wide revisions that can change code owned by many teams over thousands of files at once. Low-risk LSCs can be approved centrally and submitted efficiently without asking individual teams. To manage code edits across many reviewers, Google has developed Rosie,38 an automated change-orchestration tool, which allows engineers to create a very large commit and shard it into tens, hundreds, or thousands of smaller commits split up by the owner.

Life cycle of an ISA migration.  Migrating an individual package from single-arch to multiarch support requires several steps:

  1. Test: Fix tests (and builds) that break when run with the new ISA.

  2. Set up multiarch CI: Modify the corresponding Blueprint files to ensure no additional regressions are introduced (often simultaneous with the next step).

  3. Configure releases: Modify Blueprint files to make releases multiarch by default.

  4. Roll out new binaries: Run the multiarch packages on machines of the new ISA and assess performance and stability, addressing issues as needed.

  5. Full production: Allow production jobs to be scheduled freely on machines of the new ISA.

While these steps are the same for all packages, the issues encountered within each step vary widely across applications and throughout the different phases of our ISA migration from x86 to Arm. This often involves creating performance-optimized code for the new platform, which can happen in parallel to these steps. We observe parallels to Uber’s reported porting workflow.22

Phase 1: Large users.  We started our Arm migration with a small set of large users, such as the Spanner,8 BigQuery,20 and Bigtable7 big data systems. These migrations were hands-on with a small team and required weekly meetings and tracking bugs. Once tests passed, rollout was manual, with very careful performance and load testing, and gradual scheduling constraint removal on a per-job basis. This first-phase work was done, by and large, by people rather than automation or AI.

During this phase, a number of issues in these workloads surfaced and were addressed. Examples include: x86-specific intrinsics; long double, which differs between x86 and Arm, with cross-platform equivalents; brittle tests (e.g., due to exact floating-point equality checks); x86-specific flags; memory ordering issues hidden by x86; out-of-memory errors, often due to heap limits being tuned for x86; multiarch release packages exceeding the capacity limits of our infrastructure; unsupported dependencies, and loading of unsupported dynamic libraries; jobs not getting scheduled due to legacy x86-only scheduling constraints, such as requiring AVX2 instruction support to target newer machines.

This list was surprising to the teams involved. Initially, teams perceived porting these mature codebases to Arm as a herculean task fraught with toolchain difficulties. However, as we gained experience, most issues involved simple changes, many of them in configuration files. At the same time, these changes were surprisingly pervasive, as evident by the 38,156 commits generated.

Generally, we found that the modifications required for software to compile and run on Arm differ from initial expectations. For example, while a package might completely fail to build initially, simple manual fixes to a number of shared dependencies often unblock many builds at once. We also made a few (≈10) systematic, automated changes, such as steering nearly all applications away from long double for numeric stability across architectures.

Phase 2: Everybody else.  To take full advantage of Arm in datacenters, migrating only the largest workloads is insufficient. To maximize the use of available capacity, the cluster scheduler needs to be able to schedule workloads flexibly across platforms, packing workloads large and small onto machines. If only a small subset of services can run on Arm, it will result in underutilization of those machines. We note that the distribution of workloads at Google is very flat: Although our top 50 binaries are very large, they only represent ≈60% of running compute.16 Addressing this long tail requires porting more than 100,000 packages and billions of lines of code. This makes the Phase 1 approach of working directly with customer teams infeasible. In fact, even just talking to each team would be prohibitively expensive. The second phase of the x86 to Arm migration therefore focused on automating and scaling the migration of these workloads, while minimizing involvement from the teams themselves. We found that effectively using Arm hardware did not require porting all workloads. It is this phase of Google’s x86 to Arm migration that we mostly focus on. So far, we have ported about 60,000 packages, accounting for around 75% of Google’s server CPU cycles. In this phase, we ramped down engineers working on individual tests or configurations, as it was not scalable. Instead, we used a range of human-operated conventional automation tools for a large fraction of commits. Toward the tail end of the process, LLM-generated changes via CogniPort began to emerge, though our analysis in the next section almost entirely focuses on the time before then. We will now describe this phase in more detail, as well as our automation process.

Analyzing an ISA Migration

To fully understand what is involved in an ISA migration, we now analyze the full range of tasks involved in Google’s x86 to Arm migration (Research Question 1). As a monorepo, any change—be it to code, configurations, or documentation—is tracked as a commit in our repository’s history. Further,  relevant commits marked with a keyword indicated they were part of this migration, allowing us to extract them after the fact. We thus identified a relevant set of 38,156 commits. The contents of the changes included code and fixes written almost entirely by humans and conventional (non-AI) automated migration tools, using large-scale changes. The vast majority of the dataset predates the rise of agentic coding tools.

Analyzing these commits manually would have been cost-prohibitive. Instead, we used a variant of Gemini 2.5 Flash18 (the latest model available at the time) to analyze these commits at scale:

  1. We passed the commit messages and code diffs into the LLM’s 1M token context window in groups of 100 at a time, and picked 20 categories for each batch.

  2. We passed all ≈400×20 categories into the context window and asked Gemini to consolidate them into 50.

  3. We adjusted the model outputs by hand for a final list of 16 categories (Figure 1).b

  4. We ran Gemini again to apply labels to all of the commits, sorting them into these 16 categories (as well as an additional “Uncategorized“ category for outliers, to improve stability). Figure 2 shows examples of each category.

Figure 1.  Categories of commits in Google’s x86 to Arm migration. LoC per commit shows median, fifth, and 95th percentile. Automation shows the fraction of commits/LoC generated using large-scale changes.

Figure 2.  Specific code examples for each category.

At 38,156 commits, it is impractical to verify that every categorization is correct. We have examined ≈100 exemplars, and they appear correctly categorized.

Commits fall into four overarching groups: code changes, test changes, build and configuration files, and supporting processes and tools. In total, our commits updated around 700K lines of code. While the vast majority (84%) of commits are related to updating build or configuration files (Category 8), these commits account for only 19% of lines of codes updated. We also see a substantial number of lines (17%) spent on migration tooling. A large portion of this work is only required once and can be reused in future ISA migrations.

Code-related changes (Categories 1–5) only account for 1% of commits and less than 4% of lines of code, refuting the conventional wisdom26 that code translation accounts for most of an ISA migration. Later in this article, we analyze how automatable these commits are.

We also analyze the timeline of our ISA migration (Figure 3). We observe that at the start of the migration, most commits were in tooling and test adaptation, aligned with Phase 1. Over time, a larger fraction of commits centered around code adaptation, which can be seen as a phase when there is still a need to update code in common dependencies and address common issues in code and tests. Eventually, the fraction of these kinds of commits declined, and in the final phase of the process, almost all commits are configuration files and supporting processes. We also observe that in this later phase, the number of merged commits rapidly increased, capturing the scale-up of the migration.

Figure 3.  Categories of commits over time.

Why so many configuration changes? Automated and manual flag flips enabled the Arm variant across tens of thousands of projects with simple releases. For projects with complex release testing or evaluation, reconfiguring needed more hands-on (or agentic) labor across multiple commits.

Finally, we want to understand how these different categories of commits differ from one another. We observe that median commits in most categories are less than 20 LoC, with many single-line commits. However, we also observe very large individual commits that change 10,000+ LoC and skew the averages. We manually inspected these commits to understand their origin and found these commits do not typically represent more work since they are conceptually similar to large numbers of simple, one-line commits. Overall, there are 19 commits that cumulatively account for 238,289 LoC (32.4%) of total lines changed and that are trivial. Examples include:

  • Remove a porting tool once it was no longer used—57K LoC (Category 12)

  • Update a list of microbenchmark targets—23K LoC (Category 11)

  • Add several very large test vectors for a coverage tool—15K LoC (Category 6)

In summary, we find most commits related to migration are small; larger commits often change very large lists or configurations and are not inherently complex. Finally, we observe that some of the commits (particularly in “Supporting Processes & Tools”) could likely be reused in a subsequent multiarch migration.

Automating ISA Migrations

Now that we have established the tasks that are part of an ISA migration, we can explore how automatable each of these tasks is (Research Question 2) and how novel automation approaches can facilitate them.

ISA migration automation at Google.  We already employ a number of (non-AI) automation tools at Google today, which automated a large portion of the ISA migration process (83.82% of commits and 14.15% of LoCs).

Large-scale changes.  A key piece to ISA migration automation is Rosie, a preexisting tool that allows us to programmatically generate large numbers of commits and shepherd them into the monorepo. Rosie orchestrates the testing, mailing, code review, and submission of each individual commit. Rosie managed a total of 31,984 commits, but these changes represented only 14.15% of the total lines changed in our dataset. Figure 1 shows the fraction of each category that was generated using automated tools. For one of the major large-scale automated migrations, we introduced the concept of variant projects to the continuous integration (CI) and continuous deployment (CD) infrastructure,15 which enabled the following single-line addition to configure Arm CI and CD in a Blueprint file:

Sanitizers and fuzzers.  While not limited to ISA migrations, fuzzers and LLVM sanitizers such as AddressSanitizer,30 MemorySanitizer,35 and ThreadSanitizer31 are key enablers of our migration. Even before Arm adoption, Google routinely ran all TAP tests with these tools enabled, which turn latent errors such as memory corruption, memory leaks, or race conditions into debuggable faults. Application owners regularly triage and fix these faults, sidestepping many common differences in execution between x86 and Arm (e.g., a data race may be hidden by x86’s TSO memory model). Catching these kinds of issues ahead of time avoids debugging non-deterministic behavior when recompiling to a new ISA.

ThreadSanitizer (TSan), in particular, has proven to be effective in managing the memory model differences between Arm and x86. TSan can detect threading issues in nearly all code except for rare, lock-free algorithms. Programs typically use language-provided synchronization primitives, which fall under TSan’s purview and have the same guarantees on both x86 and Arm. Code that has passed TSan is extremely likely to use synchronization primitives correctly.

Although we saw few threading issues across the codebase, some made it through due to code that is not tested or not testable with TSan. Thread-related issues in such code were not easily detectable until we scaled up deployment significantly and saw a pattern of issues, such as crashes. One such issue was a bug in core JVM code27 caused by a thread race. In our production experience, running at full scale provides high confidence that no issues remain.

Continuous health monitoring platform (CHAMP).  The final step in our automation is CHAMP, an automated canary analysis and qualification system that monitors applications running on Arm hardware. It continuously monitors health metrics to detect whether behavior differs from x86 instances of the job (e.g., significantly higher RPC error rates or crashes). If so, it automatically marks the job as ineligible for Arm, files a bug for its owners to follow up, and tries again in 30 days. Following Google’s production principles, it scales up the fraction of Arm instances of the application incrementally to limit service-level objective risk. CHAMP is less important for new microarchitecture deployments (either x86 or Arm), as the behavior, performance differences, and associated issues are relatively minor. However, it was highly effective during the Arm migration and helped assure service owners who felt deploying to a new ISA was risky.

Using CHAMP, it is no longer necessary to manually shepherd every binary through qualification. Instead, after updating project configurations to build Arm releases, rollout is now automatic.

Reliability of the automation approach.  Combined, these tools allow for a mostly automated approach where LSCs enable Arm for different builds and releases, which are then automatically qualified using CHAMP. To understand the stability of this approach, we analyze LSCs targeting a particular standardized release management system that covers 49.6% of all binaries at Google. These LSCs modified release configurations to bring this system’s percentage of Arm-qualified applications from 4.8% to (at the time of writing) 78.89%. The rate of applications that were rolled back in early testing was 1.8% (which dropped to 1% after fixing bugs), and less than 0.8% in the final phase.

Early in the migration, after ≈300 release packages, we had a 5% refusal rate (code owners deciding not to migrate). During scale-up, this dropped to 0.6% after ≈600 additional packages. In the final phase, the commits were globally approved with no refusal. We found that acceptance rate was strongly influenced by careful workload targeting, users gaining trust in the automation, and messaging that anticipated worries and objections.

The remaining binaries that have not yet been migrated fall into various categories: ready and awaiting migration, uses complex and bespoke testing, has broken tests that have not been repaired yet, on its way to deprecation, uses unmigrated dependencies, is burdened by non-Arm-specific technical debt, has hardware requirements that current Arm servers don’t yet fulfill, to name a few. Some small portion of jobs are completely ISA-specific, but the vast majority are possible to migrate, and changes to fix them would be classified into our existing 16 commit categories. All of this remains future work for this ongoing project.

Automation of ISA Migrations with AI

While LSCs and CHAMP automate a large part of the process, there are limits to this approach. They can edit build and configuration files, as well as automatically qualify Arm binaries for deployment. However, standard LSCs are fixed-function pipelines. They are not flexible to respond to unexpected errors or other issues that occur at any stage of the process, be it during testing or in production.

Modern generative AI techniques represent an opportunity to automate the remainder of the ISA migration process. We built an agent called CogniPort, which aims to close this gap. CogniPort operates on build and test errors. If an Arm binary does not build or a test fails at any point in the process, the agent can step in to fix the problem automatically.

The agent consists of three nested agentic loops (Figure 4). Each loop uses an LLM to perform one step of reasoning followed by a tool invocation—that is, a function call. The tool’s outputs are then attached to the agent’s context. There are tools for building and returning logs, running test(s) and returning logs, heuristically fixing build file errors, searching through code, modifying code, and exiting the loop (finish).

Figure 4.  Agentic flow and the success rate of the agent.

The outermost agent loop is an orchestrator that repeatedly calls the build fixer agent and/or the test fixer agent depending on the state of the workspace. The build fixer agent tries to build a given target and makes modifications to files until the target builds successfully. The test fixer agent runs a given test and makes modifications until the test passes. In both cases, the agent can time out via a step limit or give up early by calling finish.

To evaluate the agent, we took historic commits from our dataset, reverted them, and then checked whether the agent fixed the introduced error(s). Note that not all our categories are suitable for this approach—it only applies to Code and Test Adaptation (categories 1-7). We further narrowed down our dataset to commits that can be cleanly reverted and that have identifiable build or test targets. This resulted in a benchmark set of 234 commits in categories 1, 2, 3, 6, and 7. We ran the agent twice for each commit: once with Gemini 3 Flash fine-tuned on a corpus of internal data (including code and documentation)18,c and again with out-of-the-box Gemini 3.1 Pro. We saw a best-of-both success rate of 73.5%. Test fixes, platform-specific conditionals, and assembly code porting had the highest success rates. Test Execution Environment was the most difficult but still had a success rate of 56%, with our fine-tuned model performing the best.

Note that we consider these results directional: While we analyzed an arbitrary subset of outputs to ensure result validity and confirm the absence of recitation from training, the evaluation is not perfect and may miss cases where, for example, a fix is incorrect but not caught by a test or where there is other information leakage (e.g., a subsequent commit made the original fix easier, or reverting only the commit itself makes it easier to root-cause an issue than if the entire fix was reverted).

Discussion and Research Challenges

Overall, we see that ISA migrations involve a wide range of different tasks shown in our taxonomy (Research Question 1). Many of these tasks are highly automatable. Build file and configuration changes are almost fully automatable, while code changes and tests are partially automatable with conventional techniques (Research Question 2). In addition, many areas scale across architectures and do not require additional work for each ISA. This includes multiarch support for build and test infrastructure, spinning up a new hardware platform whether or not it is a new ISA (e.g., categories 11 and 15), and deprecating old code (category 14).

We have released multiarch binaries covering 75% of server compute at Google, a cross-cutting, representative set of code. Historically, such a migration would have consumed immense human effort. Tools like CHAMP and Rosie combined with broad-based testing, liberal use of sanitizers, and focusing on simplifying the process enabled a large fraction of this migration to be automated. CogniPort and similar AI tools will further accelerate the process, making giant codebase migrations tractable at a fraction of the effort. This raises the question: What are the remaining challenges, and are there research opportunities in closing the remaining gaps (Research Question 3)?

By manually inspecting outputs, we find that categories such as build and configuration files, intrinsic and assembly code porting, and test logic are already largely automatable. However, category 7 (Test Execution Environment) proved to be significantly harder. While the details of these challenges are unique to ISA migrations, the root causes are similar to quality issues that arise when using agents to automate general software development. They are rooted in LLM context-window limitations and information-retrieval challenges.

At Google, we found that imperfect AI-based code generation combined with our extensive test and monitoring infrastructure and human code review is sufficient to reliably land large numbers of changes in production, even with a <50% success rate at the model level. For example, a system called ECO21 has been used to submit thousands of AI-generated code optimizations and less than 0.5% of commits had to be rolled back. The 73.5% CogniPort success rate in our study is already better than rates reported in the ECO paper. Techniques such as information retrieval on past commits (which ECO uses) and spec-driven development (SDD)12 to make agents more robust could both help further. Even so, we find that a number of open challenges remain:

  • ISA-Specific Vector Code: Writing ISA-specific, performant vector and matrix code is difficult. Previous research showed limited success.36 However, we and others14 observe that modern LLMs are starting to show promise on writing vector intrinsics.

  • Deep Performance Optimizations: This sometimes requires major refactors and algorithmic changes. Existing performance-focused AI tools, such as ECO, will also help.

  • Difficult Corner Cases: We saw a number of corner cases that require obscure knowledge beyond the code itself. For example, we saw commits that worked around an Arm compiler bug, addressed a hash function behaving differently on Arm and x86, and fixed bugs that were not triggered until the code ran on Arm.

  • Performance Tuning: Hyperparameters and feedback directed optimization (FDO) profiles sometimes must be regenerated for a new platform. An agent could configure testing harnesses, run workloads, and measure performance.

Meanwhile, we also found a number of examples not directly related to ISA migration tasks and that may not be completely automatable:

  • Multiarch tooling: A significant portion of this work includes implementing the automation itself (e.g., CHAMP), as well as simulation tools and dashboards. However, AI agents are rapidly advancing their capability to implement these components.

  • Resource provisioning: These are configuration changes that help human engineers manage physical hardware in datacenters and can include strategic or business judgement.

Our results demonstrate that the rapid adoption of agentic infrastructure by software engineers, including at Google, will also address ISA migration challenges. Future ISA migrations may require a limited amount of manual work, mostly focused on making new hardware available and adding the new ISA to our existing multiarch tooling and automation.

Conclusion

By analyzing a large-scale ISA migration at Google, we refute longstanding assumptions about such migrations. First, even in the presence of source code, migrations are not straightforward and involve a large range of multifaceted tasks, with no single task dominating. Second, many of these tasks are highly automatable, particularly using modern AI techniques. Finally, AI agents are rapidly improving, expanding the breadth of tasks that can be automated.

Acknowledgments

We thank Arvind Sundararajan, Dushyant Acharya, Ahmed Alansary, Shelah Ameli, Owen Anderson, Sterling Augustine, Sushmita Azad, Nupur Baghel, Antoine Baudoux, Patrick Bellasi, Vincent Belliard, Kyle Berman, Paul Bethe, Gopu Bhaskar, Raymond ’Princess Sparklefists’ Blum, Marshall Bockrath, Harsha Vardhan Bonthalala, Lexi Bromfield, Jean-Luc Brouillet, Eric Burnett, Marcelo Cataldo, John Cater, Kristine Chen, David Cheng, Ilya Cherny, Saahithi Chillara, Rob Chilton, Chandrakanth Chittappa, Brian Chiu, Daniele Codecasa, Eduardo Colaço, Pavithra Dankanikote, Nicolo Davis, Rumeet Dhindsa, Zhuoran Diao, Bartosz Dolecki, Ian Dolzhanskii, Pat Doyle, Elian Dumitru, Ali Esmaeeli, Samuel Foss, Ákos Frohner, Neeharika Gonuguntla, Shruti Gorappa, Russell Gottfried, Manoj Gupta, Benjamin Gwin, Yanyan Han, Jitendra Harlalka, Milad Hashemi, Tim Henderson, Daisy Hollman, Jung Woo Hong, Jiawei Huang, Jin Huang, Talha Imran, Victoria Juan, Pranav Kant, Lera Kharatyan, Joonsung Kim, Danial Klimkin, Justin King, Sree Kodakara, Avi Kondareddy, Danila Kutenin, Gregory Kwok, Pavel Labath, Leon Lee, Sungkwang Lee, Li Li, Sha Li, Xu Li, Zhongqi Li, Jianyi Liang, Kevin Liston, Haiming Liu, Li Liu, David Lo, Sean Luchen, Albert Ma, Laura Macaddino, Anthony Mai, Jennifer Mansur, Simon Marchuk, David Margolin, Alexander Midlash, Dominic Mitchell, Karthik Mohan, Albert Morgese, Maksym Motornyy, Katherine Nadell, Ngan Nguyen, Denis Nikitin, Stoyan Nikolov, Nicolas Noble, Chester Obi, Andri Orap, Habib Pagarkar, Dasha Patroucheva, Sabuj Pattanayek, Vaishakhi Pilankar, Saranyan Vangal Rajagopalan, Daniel Rall, Majid Rasouli, Salonik Resch, Alberto Rojas, Annie Rong, Jesse Rosenstock, Michal Sapinski, Yashnarendra Saraf, Aaron Schooley, Alexander Schrepfer, Manish Shah, Alexander Shaposhnikov, Stan Shebs, Guangyu Shi, Oscar Shi, Santanu Sinha, Anna Sjövall, Ben Smith, Justin Smith, Jairaj Solanke, Fangrui Song, Raman Subramanian, Xenia Tay, Toni Thompson, Dima Tsumarau, Cassie(Yitong) Wang, Tommy Wang, Shu-Chun Weng, DJ Whang, Hailong Xiao, Andy Xu, and Jason Yuan for their contributions to Google’s Arm porting efforts and the work described herein.