@@ -1475,36 +1475,33 @@ class StubGenerator: public StubCodeGenerator {
14751475 // We don't care about atomicity because the address and size are not aligned, So we are
14761476 // free to fill the memory with best possible ways.
14771477 static void do_setmemory_atomic_loop_mvc (Register dest, Register size, Register byteVal,
1478- MacroAssembler *_masm) {
1479-
1478+ MacroAssembler *_masm) {
14801479 NearLabel L_loop, L_tail, L_mvc;
14811480
1482- __ z_cghi (size, 256 );
1483- __ z_brc (Assembler::bcondLow, L_tail); // size is <256
1481+ __ z_aghi (size, -1 ); // -1 because first byte is preset by stc
1482+ __ z_bcr (Assembler::bcondLow, Z_R14); // result < 0 means size == 0 => return
1483+ __ z_stc (byteVal, Address (dest)); // initialize first byte
1484+ __ z_bcr (Assembler::bcondEqual, Z_R14); // result == 0 means size == 1 => return
14841485
1485- // handle size >= 256
1486+ // handle complete 256 byte blocks
14861487 __ bind (L_loop);
1487- __ z_stc (byteVal, Address (dest));
1488- __ z_mvc (1 , 254 , dest, 0 , dest);
1489- __ z_aghi (dest, 256 ); // increment the address by 256
1490- __ z_aghi (size, -256 );
1491- __ z_cghi (size, 256 );
1492- __ z_brh (L_loop);
1488+ __ z_aghi (size, -256 ); // decrement remaining #bytes
1489+ __ z_brl (L_tail); // skip loop if no full 256 byte block left
1490+
1491+ __ z_mvc (1 , 255 , dest, 0 , dest); // propagate byte from dest[0+i*256] to dest[1+i*256]
1492+ __ z_bcr (Assembler::bcondEqual, Z_R14); // remaining size == 0 => return (mvc does not touch CC)
14931493
1494- __ z_ltr (size, size);
1495- __ z_bcr (Assembler::bcondZero, Z_R14); // size is 0
1494+ __ z_aghi (dest, 256 ); // increment target address
1495+ __ z_bru (L_loop);
14961496
1497+ // handle remaining bytes. We know 0 < size < 256
14971498 __ bind (L_tail);
1498- __ z_stc (byteVal, Address (dest));
1499- __ z_aghi (size, -2 ); // aghi will set the condition code for "size==zero", "size<zero", "size>zero"
1500- __ z_bcr (Assembler::bcondLow, Z_R14); // size < 0
1499+ __ z_aghi (size, +256 -1 ); // prepare size value for mvc via exrl
15011500 __ z_exrl (size, L_mvc);
1502-
15031501 __ z_br (Z_R14);
15041502
15051503 __ bind (L_mvc);
1506- __ z_mvc (1 , 0 , dest, 0 , dest); // mvc template, needs to be generated, not executed
1507-
1504+ __ z_mvc (1 , 0 , dest, 0 , dest); // mvc template, needs to be generated, not executed
15081505 }
15091506
15101507 static void do_setmemory_atomic_loop (int elem_size, Register dest, Register size, Register byteVal,
0 commit comments