You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
104: Fix asm::delay not clobbering count register r=dkhayes117 a=adamgreig
I noticed that a small example using two `asm::delay()` calls worked fine in debug mode but not in release mode. Eventually `@jamesmunns` spotted that the count register wasn't being reloaded between calls:
```
# loads a2 with real_cyc
400001ce: 02faf637 lui a2,0x2faf
400001d2: 0816061b addiw a2,a2,129
# turn on led
400001d6: c10c sw a1,0(a0)
# count down (delay impl)
400001d8: 167d addi a2,a2,-1
400001da: fe7d bnez a2,400001d8 <.LBB0_8+0x30>
# turn off led
400001dc: 00052023 sw zero,0(a0) # 2000000 <.Lline_table_start0+0x1fff7a4>
# count down again (delay impl, note a2 not reloaded)
400001e0: 167d addi a2,a2,-1
400001e2: fe7d bnez a2,400001e0 <.LBB0_8+0x38>
# loop back to start
400001e4: bfcd j 400001d6 <.LBB0_8+0x2e>
```
By changing the register spec to `inout`, Rust knows the register is modified and reloads it next time. I added the nomem and nostack options too since the instructions don't touch memory or stack, to match the cortex-m impl. This change fixes codegen for my example:
```
400001ce: 02faf637 lui a2,0x2faf
400001d2: 0816061b addiw a2,a2,129
400001d6: c10c sw a1,0(a0)
400001d8: 86b2 mv a3,a2
400001da: 16fd addi a3,a3,-1
400001dc: fefd bnez a3,400001da <.LBB0_8+0x32>
400001de: 00052023 sw zero,0(a0) # 2000000 <.Lline_table_start0+0x1fff779>
400001e2: 86b2 mv a3,a2
400001e4: 16fd addi a3,a3,-1
400001e6: fefd bnez a3,400001e4 <.LBB0_8+0x3c>
400001e8: b7fd j 400001d6 <.LBB0_8+0x2e>
```
Co-authored-by: Adam Greig <[email protected]>
0 commit comments