gemini: add ordering field for rmw
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index e38e60c..631500f 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -1382,15 +1382,15 @@
                                         BinaryenExpressionRef value,
                                         BinaryenType type,
                                         const char* memoryName) {
-  return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeAtomicRMW(AtomicRMWOp(op),
-                     bytes,
-                     offset,
-                     (Expression*)ptr,
-                     (Expression*)value,
-                     Type(type),
-                     getMemoryName(module, memoryName)));
+  return Builder(*(Module*)module)
+    .makeAtomicRMW(AtomicRMWOp(op),
+                   bytes,
+                   offset,
+                   (Expression*)ptr,
+                   (Expression*)value,
+                   Type(type),
+                   Name(memoryName),
+                   MemoryOrder::SeqCst);
 }
 BinaryenExpressionRef BinaryenAtomicCmpxchg(BinaryenModuleRef module,
                                             BinaryenIndex bytes,
diff --git a/src/ir/properties.h b/src/ir/properties.h
index e1865be..e28a519 100644
--- a/src/ir/properties.h
+++ b/src/ir/properties.h
@@ -507,8 +507,11 @@
   if (auto* store = curr->dynCast<Store>()) {
     return store->order;
   }
-  if (curr->is<AtomicRMW>() || curr->is<AtomicWait>() ||
-      curr->is<AtomicNotify>() || curr->is<AtomicFence>()) {
+  if (auto* rmw = curr->dynCast<AtomicRMW>()) {
+    return rmw->order;
+  }
+  if (curr->is<AtomicWait>() || curr->is<AtomicNotify>() ||
+      curr->is<AtomicFence>()) {
     return MemoryOrder::SeqCst;
   }
   return MemoryOrder::Unordered;
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index 1ac3a7c..82083ca 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -575,7 +575,8 @@
                          Type,
                          int,
                          MemoryIdxT*,
-                         MemargT) {
+                         MemargT,
+                         MemoryOrder) {
     return Ok{};
   }
   Result<> makeAtomicCmpxchg(
@@ -2274,11 +2275,12 @@
                          Type type,
                          int bytes,
                          Name* mem,
-                         Memarg memarg) {
+                         Memarg memarg,
+                         MemoryOrder order) {
     auto m = getMemory(pos, mem);
     CHECK_ERR(m);
-    return withLoc(pos,
-                   irBuilder.makeAtomicRMW(op, bytes, memarg.offset, type, *m));
+    return withLoc(
+      pos, irBuilder.makeAtomicRMW(op, bytes, memarg.offset, type, *m, order));
   }
 
   Result<> makeAtomicCmpxchg(Index pos,
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 7712264..d9ef5d4 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -1818,7 +1818,7 @@
   auto arg = memarg(ctx, bytes);
   CHECK_ERR(arg);
   return ctx.makeAtomicRMW(
-    pos, annotations, op, type, bytes, mem.getPtr(), *arg);
+    pos, annotations, op, type, bytes, mem.getPtr(), *arg, MemoryOrder::SeqCst);
 }
 
 template<typename Ctx>
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 22e48ef..1aeaf9c 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -4770,7 +4770,8 @@
       ptr,
       value,
       type,
-      wasm.memories[0]->name);
+      wasm.memories[0]->name,
+      MemoryOrder::SeqCst);
   } else {
     auto* expected = make(type);
     auto* replacement = make(type);
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 104b838..0d09fa6 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -466,7 +466,8 @@
                            Expression* ptr,
                            Expression* value,
                            Type type,
-                           Name memory) {
+                           Name memory,
+                           MemoryOrder order) {
     auto* ret = wasm.allocator.alloc<AtomicRMW>();
     ret->op = op;
     ret->bytes = bytes;
@@ -474,8 +475,9 @@
     ret->ptr = ptr;
     ret->value = value;
     ret->type = type;
-    ret->finalize();
     ret->memory = memory;
+    ret->order = order;
+    ret->finalize();
     return ret;
   }
   AtomicCmpxchg* makeAtomicCmpxchg(unsigned bytes,
diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def
index 8cb5df6..143528b 100644
--- a/src/wasm-delegations-fields.def
+++ b/src/wasm-delegations-fields.def
@@ -375,6 +375,7 @@
 DELEGATE_FIELD_INT(AtomicRMW, op)
 DELEGATE_FIELD_INT(AtomicRMW, bytes)
 DELEGATE_FIELD_ADDRESS(AtomicRMW, offset)
+DELEGATE_FIELD_INT(AtomicRMW, order)
 DELEGATE_FIELD_NAME_KIND(AtomicRMW, memory, ModuleItemKind::Memory)
 DELEGATE_FIELD_CASE_END(AtomicRMW)
 
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h
index bbc21af..5f06ddd 100644
--- a/src/wasm-ir-builder.h
+++ b/src/wasm-ir-builder.h
@@ -160,8 +160,12 @@
     unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
   Result<> makeAtomicStore(
     unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
-  Result<> makeAtomicRMW(
-    AtomicRMWOp op, unsigned bytes, Address offset, Type type, Name mem);
+  Result<> makeAtomicRMW(AtomicRMWOp op,
+                         unsigned bytes,
+                         Address offset,
+                         Type type,
+                         Name mem,
+                         MemoryOrder order);
   Result<>
   makeAtomicCmpxchg(unsigned bytes, Address offset, Type type, Name mem);
   Result<> makeAtomicWait(Type type, Address offset, Name mem);
diff --git a/src/wasm.h b/src/wasm.h
index ab6323b..07f015c 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1035,6 +1035,7 @@
   Expression* ptr;
   Expression* value;
   Name memory;
+  MemoryOrder order = MemoryOrder::SeqCst;
 
   void finalize();
 };
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 96fd205..2c73040 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3704,31 +3704,38 @@
 #define RMW(op)                                                                \
   case BinaryConsts::I32AtomicRMW##op: {                                       \
     auto [mem, align, offset, memoryOrder] = getRMWMemarg();                   \
-    return builder.makeAtomicRMW(RMW##op, 4, offset, Type::i32, mem);          \
+    return builder.makeAtomicRMW(                                              \
+      RMW##op, 4, offset, Type::i32, mem, MemoryOrder::SeqCst);                \
   }                                                                            \
   case BinaryConsts::I32AtomicRMW##op##8U: {                                   \
     auto [mem, align, offset, memoryOrder] = getRMWMemarg();                   \
-    return builder.makeAtomicRMW(RMW##op, 1, offset, Type::i32, mem);          \
+    return builder.makeAtomicRMW(                                              \
+      RMW##op, 1, offset, Type::i32, mem, MemoryOrder::SeqCst);                \
   }                                                                            \
   case BinaryConsts::I32AtomicRMW##op##16U: {                                  \
     auto [mem, align, offset, memoryOrder] = getRMWMemarg();                   \
-    return builder.makeAtomicRMW(RMW##op, 2, offset, Type::i32, mem);          \
+    return builder.makeAtomicRMW(                                              \
+      RMW##op, 2, offset, Type::i32, mem, MemoryOrder::SeqCst);                \
   }                                                                            \
   case BinaryConsts::I64AtomicRMW##op: {                                       \
     auto [mem, align, offset, memoryOrder] = getRMWMemarg();                   \
-    return builder.makeAtomicRMW(RMW##op, 8, offset, Type::i64, mem);          \
+    return builder.makeAtomicRMW(                                              \
+      RMW##op, 8, offset, Type::i64, mem, MemoryOrder::SeqCst);                \
   }                                                                            \
   case BinaryConsts::I64AtomicRMW##op##8U: {                                   \
     auto [mem, align, offset, memoryOrder] = getRMWMemarg();                   \
-    return builder.makeAtomicRMW(RMW##op, 1, offset, Type::i64, mem);          \
+    return builder.makeAtomicRMW(                                              \
+      RMW##op, 1, offset, Type::i64, mem, MemoryOrder::SeqCst);                \
   }                                                                            \
   case BinaryConsts::I64AtomicRMW##op##16U: {                                  \
     auto [mem, align, offset, memoryOrder] = getRMWMemarg();                   \
-    return builder.makeAtomicRMW(RMW##op, 2, offset, Type::i64, mem);          \
+    return builder.makeAtomicRMW(                                              \
+      RMW##op, 2, offset, Type::i64, mem, MemoryOrder::SeqCst);                \
   }                                                                            \
   case BinaryConsts::I64AtomicRMW##op##32U: {                                  \
     auto [mem, align, offset, memoryOrder] = getRMWMemarg();                   \
-    return builder.makeAtomicRMW(RMW##op, 4, offset, Type::i64, mem);          \
+    return builder.makeAtomicRMW(                                              \
+      RMW##op, 4, offset, Type::i64, mem, MemoryOrder::SeqCst);                \
   }
 
           RMW(Add);
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index 57a2469..0144c8d 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -1075,7 +1075,7 @@
     tryy->name = scope.label;
     tryy->finalize(tryy->type);
     push(maybeWrapForLabel(tryy));
-  } else if (Try * tryy;
+  } else if (Try* tryy;
              (tryy = scope.getCatch()) || (tryy = scope.getCatchAll())) {
     auto index = scope.getIndex();
     setCatchBody(tryy, *expr, index);
@@ -1503,14 +1503,18 @@
   return Ok{};
 }
 
-Result<> IRBuilder::makeAtomicRMW(
-  AtomicRMWOp op, unsigned bytes, Address offset, Type type, Name mem) {
+Result<> IRBuilder::makeAtomicRMW(AtomicRMWOp op,
+                                  unsigned bytes,
+                                  Address offset,
+                                  Type type,
+                                  Name mem,
+                                  MemoryOrder order) {
   AtomicRMW curr;
   curr.memory = mem;
   curr.type = type;
   CHECK_ERR(visitAtomicRMW(&curr));
-  push(
-    builder.makeAtomicRMW(op, bytes, offset, curr.ptr, curr.value, type, mem));
+  push(builder.makeAtomicRMW(
+    op, bytes, offset, curr.ptr, curr.value, type, mem, order));
   return Ok{};
 }
 
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 4e79976..6cf82bb 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1108,11 +1108,17 @@
                  curr,
                  "Atomic load should be i32 or i64");
   }
-  if (curr->order == MemoryOrder::AcqRel) {
-    shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
-                 curr,
-                 "Acquire/release operations require relaxed atomics "
-                 "[--enable-relaxed-atomics]");
+  switch (curr->order) {
+    case MemoryOrder::AcqRel: {
+      shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
+                   curr,
+                   "Acquire/release operations require relaxed atomics "
+                   "[--enable-relaxed-atomics]");
+      break;
+    }
+    case MemoryOrder::Unordered:
+    case MemoryOrder::SeqCst:
+      break;
   }
   if (curr->type == Type::v128) {
     shouldBeTrue(getModule()->features.hasSIMD(),
@@ -1147,11 +1153,17 @@
                  curr,
                  "Atomic store should be i32 or i64");
   }
-  if (curr->order == MemoryOrder::AcqRel) {
-    shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
-                 curr,
-                 "Acquire/release operations require relaxed atomics "
-                 "[--enable-relaxed-atomics]");
+  switch (curr->order) {
+    case MemoryOrder::AcqRel: {
+      shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
+                   curr,
+                   "Acquire/release operations require relaxed atomics "
+                   "[--enable-relaxed-atomics]");
+      break;
+    }
+    case MemoryOrder::Unordered:
+    case MemoryOrder::SeqCst:
+      break;
   }
   if (curr->valueType == Type::v128) {
     shouldBeTrue(getModule()->features.hasSIMD(),
@@ -1185,6 +1197,24 @@
   shouldBeTrue(getModule()->features.hasAtomics(),
                curr,
                "Atomic operations require threads [--enable-threads]");
+
+  switch (curr->order) {
+    case MemoryOrder::AcqRel: {
+      shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
+                   curr,
+                   "Acquire/release operations require relaxed atomics "
+                   "[--enable-relaxed-atomics]");
+      break;
+    }
+    // Unordered RMW should be impossible unless there's a bug in the code.
+    case MemoryOrder::Unordered: {
+      WASM_UNREACHABLE("Atomic RMW can't be unordered");
+      break;
+    }
+    case MemoryOrder::SeqCst:
+      break;
+  }
+
   validateMemBytes(curr->bytes, curr->type, curr);
   shouldBeEqualOrFirstIsUnreachable(
     curr->ptr->type,