The problem is that branches on Sparc are delayed -- the next instruction after the branch will be executed before the branch actually executes. So when you have:
bcs away
mov %l0, %i0
when the C flag is set and this branch is taken, the mov
will still execute, overwriting the value in %i0
(the value before the last add that set C) with %l0
(the value after the add -- 0).
If you stick a nop in here:
bcs away
nop
mov %l0, %i0
it should give you the value you want.