diff a/src/hotspot/cpu/riscv/gc/g1/g1_riscv.ad b/src/hotspot/cpu/riscv/gc/g1/g1_riscv.ad
--- a/src/hotspot/cpu/riscv/gc/g1/g1_riscv.ad
+++ b/src/hotspot/cpu/riscv/gc/g1/g1_riscv.ad
@@ -1,7 +1,7 @@
 //
-// Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
 // Copyright (c) 2024, Huawei Technologies Co., Ltd. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License version 2 only, as
@@ -72,10 +72,130 @@
   g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, xthread, tmp1, tmp2, new_val_may_be_null);
 }
 
 %}
 
+
+// TODO 8350865 (same applies to g1StoreLSpecialTwoOops)
+// - Do not set/overwrite barrier data here, also handle G1C2BarrierPostNotNull
+
+instruct g1StoreLSpecialOneOopOff0(indirect mem, iRegLNoSp src, immI0 off, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, rFlagsReg cr)
+%{
+  predicate(UseG1GC);
+  match(Set mem (StoreLSpecial mem (Binary src off)));
+  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
+  ins_cost(STORE_COST);
+  format %{ "sd  $src, $mem\t# g1StoreLSpecialOneOopOff0" %}
+  ins_encode %{
+    guarantee($mem$$disp == 0, "impossible encoding");
+    ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
+
+    write_barrier_pre(masm, this,
+                      $mem$$Register /* obj */,
+                      $tmp1$$Register /* pre_val */,
+                      $tmp2$$Register /* tmp1 */,
+                      $tmp3$$Register /* tmp2 */,
+                      RegSet::of($mem$$Register, $src$$Register) /* preserve */);
+
+    __ sd($src$$Register, Address($mem$$Register));
+
+    // Extract the narrow oop field value
+    __ zext($tmp1$$Register, $src$$Register, 32);
+    __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
+    write_barrier_post(masm, this,
+                       $mem$$Register /* store_addr */,
+                       $tmp1$$Register /* new_val */,
+                       $tmp2$$Register /* tmp1 */,
+                       $tmp3$$Register /* tmp2 */);
+  %}
+  ins_pipe(istore_reg_mem);
+%}
+
+instruct g1StoreLSpecialOneOopOff4(indirect mem, iRegLNoSp src, immI_4 off, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4, rFlagsReg cr)
+%{
+  predicate(UseG1GC);
+  match(Set mem (StoreLSpecial mem (Binary src off)));
+  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
+  ins_cost(STORE_COST);
+  format %{ "sd  $src, $mem\t# g1StoreLSpecialOneOopOff4" %}
+  ins_encode %{
+    guarantee($mem$$disp == 0, "impossible encoding");
+    ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
+
+    // Adjust address to point to narrow oop
+    __ add($tmp4$$Register, $mem$$Register, 4);
+    write_barrier_pre(masm, this,
+                      $tmp4$$Register /* obj */,
+                      $tmp1$$Register /* pre_val */,
+                      $tmp2$$Register /* tmp1 */,
+                      $tmp3$$Register /* tmp2 */,
+                      RegSet::of($mem$$Register, $src$$Register, $tmp4$$Register) /* preserve */);
+
+    __ sd($src$$Register, Address($mem$$Register));
+
+    // Shift long value to extract the narrow oop field value and zero-extend it
+    __ srli($tmp1$$Register, $src$$Register, 32);
+    __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
+    write_barrier_post(masm, this,
+                       $tmp4$$Register /* store_addr */,
+                       $tmp1$$Register /* new_val */,
+                       $tmp2$$Register /* tmp1 */,
+                       $tmp3$$Register /* tmp2 */);
+  %}
+  ins_pipe(istore_reg_mem);
+%}
+
+instruct g1StoreLSpecialTwoOops(indirect mem, iRegLNoSp src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4, rFlagsReg cr)
+%{
+  predicate(UseG1GC);
+  match(Set mem (StoreLSpecial mem src));
+  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
+  ins_cost(STORE_COST);
+  format %{ "sd  $src, $mem\t# g1StoreLSpecialTwoOops" %}
+  ins_encode %{
+    guarantee($mem$$disp == 0, "impossible encoding");
+    ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
+
+    write_barrier_pre(masm, this,
+                      $mem$$Register /* obj */,
+                      $tmp1$$Register /* pre_val */,
+                      $tmp2$$Register /* tmp1 */,
+                      $tmp3$$Register /* tmp2 */,
+                      RegSet::of($mem$$Register, $src$$Register) /* preserve */);
+    // Adjust address to point to the second narrow oop in the long value
+    __ add($tmp4$$Register, $mem$$Register, 4);
+    write_barrier_pre(masm, this,
+                      $tmp4$$Register /* obj */,
+                      $tmp1$$Register /* pre_val */,
+                      $tmp2$$Register /* tmp1 */,
+                      $tmp3$$Register /* tmp2 */,
+                      RegSet::of($mem$$Register, $src$$Register, $tmp4$$Register) /* preserve */);
+
+    __ sd($src$$Register, Address($mem$$Register));
+
+    // Zero-extend first narrow oop to long
+    __ zext($tmp1$$Register, $src$$Register, 32);
+    __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
+    write_barrier_post(masm, this,
+                       $mem$$Register /* store_addr */,
+                       $tmp1$$Register /* new_val */,
+                       $tmp2$$Register /* tmp1 */,
+                       $tmp3$$Register /* tmp2 */);
+
+    // Shift long value to extract the second narrow oop field value
+    __ srli($tmp1$$Register, $src$$Register, 32);
+    __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
+    write_barrier_post(masm, this,
+                       $tmp4$$Register /* store_addr */,
+                       $tmp1$$Register /* new_val */,
+                       $tmp2$$Register /* tmp1 */,
+                       $tmp3$$Register /* tmp2 */);
+  %}
+  ins_pipe(istore_reg_mem);
+%}
+
+
 instruct g1StoreP(indirect mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, rFlagsReg cr)
 %{
   predicate(UseG1GC && n->as_Store()->barrier_data() != 0);
   match(Set mem (StoreP mem src));
   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
