task: juggling function outputs between registers
This commit is contained in:
parent
0ccfd0156f
commit
a3f73278b1
|
@ -368,12 +368,12 @@ fn dither-pgm-unordered-monochrome _src: (addr image), _dest: (addr image) {
|
|||
curr-int <- shift-left 0x10 # we have 32 bits; we'll use 16 bits for the fraction and leave 8 for unanticipated overflow
|
||||
var error/esi: int <- _read-dithering-error errors, x, y, src-width
|
||||
error <- add curr-int
|
||||
$_dither-pgm-unordered-monochrome:update-error: {
|
||||
$dither-pgm-unordered-monochrome:update-error: {
|
||||
compare error, 0x800000
|
||||
{
|
||||
break-if->=
|
||||
_write-raw-buffer dest-data, x, y, src-width, 0/black
|
||||
break $_dither-pgm-unordered-monochrome:update-error
|
||||
break $dither-pgm-unordered-monochrome:update-error
|
||||
}
|
||||
_write-raw-buffer dest-data, x, y, src-width, 1/white
|
||||
error <- subtract 0xff0000
|
||||
|
|
|
@ -354,6 +354,48 @@ the precise register a function header specifies. The return value can even be
|
|||
a literal integer or in memory somewhere. The `return` is really just a `copy`
|
||||
to the appropriate register(s). This is why the second example above is legal.
|
||||
|
||||
## Task 9: juggling registers between function calls
|
||||
|
||||
Here's a program:
|
||||
|
||||
```
|
||||
fn f -> _/eax: int {
|
||||
return 2
|
||||
}
|
||||
|
||||
fn g -> _/eax: int {
|
||||
return 3
|
||||
}
|
||||
|
||||
fn add-f-and-g -> _/eax: int {
|
||||
var x/eax: int <- f
|
||||
var y/eax: int <- g
|
||||
x <- add y
|
||||
return x
|
||||
}
|
||||
```
|
||||
|
||||
What's wrong with this program? How can you fix it and pass all tests by
|
||||
modifying just function `add-f-and-g`?
|
||||
|
||||
By convention, most functions in Mu return their results in register `eax`.
|
||||
That creates a fair bit of contention for this register, and we often end up
|
||||
having to move the output of a function call around to some other location to
|
||||
free up space for the next function we need to call.
|
||||
|
||||
An alternative approach would be to distribute the load between registers so
|
||||
that different functions use different output registers. That would reduce the
|
||||
odds of conflict, but not eradicate them entirely. It would also add some
|
||||
difficulty in calling functions; now you have to remember what register they
|
||||
write their outputs to. It's unclear if the benefits of this alternative
|
||||
outweigh the costs, so Mu follows long-established conventions in other
|
||||
Assembly languages. I do, however, violate the `eax` convention in some cases
|
||||
where a helper function is only narrowly useful in a single sort of
|
||||
circumstance and registers are at a premium. See, for example, the definition
|
||||
of the helper `_read-dithering-error` [when rendering images](http://akkartik.github.io/mu/html/511image.mu.html).
|
||||
The leading underscore indicates that it's an internal detail of
|
||||
`render-image`, and not really intended to be called by itself.
|
||||
|
||||
## Task 10: operating with fractional numbers
|
||||
|
||||
All our variables so far have had type `int` (integer), but there are limits
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
fn f -> _/eax: int {
|
||||
return 2
|
||||
}
|
||||
|
||||
fn g -> _/eax: int {
|
||||
return 3
|
||||
}
|
||||
|
||||
fn add-f-and-g -> _/eax: int {
|
||||
var _x/eax: int <- f
|
||||
var x/ecx: int <- copy _x
|
||||
var y/eax: int <- g
|
||||
x <- add y
|
||||
return x
|
||||
}
|
||||
|
||||
fn test-add-f-and-g {
|
||||
var result/eax: int <- add-f-and-g
|
||||
check-ints-equal result, 5, "F - test-add-f-and-g\n"
|
||||
}
|
||||
|
||||
fn main {
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
fn f -> _/eax: int {
|
||||
return 2
|
||||
}
|
||||
|
||||
fn g -> _/eax: int {
|
||||
return 3
|
||||
}
|
||||
|
||||
fn add-f-and-g -> _/eax: int {
|
||||
var x/eax: int <- f
|
||||
var y/eax: int <- g
|
||||
x <- add y
|
||||
return x
|
||||
}
|
||||
|
||||
fn test-add-f-and-g {
|
||||
var result/eax: int <- add-f-and-g
|
||||
check-ints-equal result, 5, "F - test-add-f-and-g\n"
|
||||
}
|
||||
|
||||
fn main {
|
||||
}
|
Loading…
Reference in New Issue