Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
bors[bot] and adamgreig committed Jul 16, 2022
2 parents b0b0695 + cdd70bb commit d50928b
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Fixed

- Fix `asm::delay()` to ensure count register is always reloaded

## [v0.8.0] - 2022-04-20

### Added
Expand Down
3 changes: 2 additions & 1 deletion src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ pub unsafe fn delay(cycles: u32) {
"1:",
"addi {0}, {0}, -1",
"bne {0}, zero, 1b",
in(reg) real_cyc
inout(reg) real_cyc => _,
options(nomem, nostack),
)
}

Expand Down

0 comments on commit d50928b

Please sign in to comment.