I'm trying to zero test a word pointed by ix with index.
Here is the source assembly:
ld a, (ix + Entity.isOffScreenFlags.low)
or (ix + Entity.isOffScreenFlags.high)
And the compiling Wiz code:
a = ((ix + 9) as u8);
a |= ((ix + 10) as u8);
It works :slight_smile:
When using an struct instance though, it fails:
a = >:monster.isOffScreenFlags;
a |= <:monster.isOffScreenFlags;
(some possible options ommited)
error: could not generate code for assignment =
note: got: a = *(((ix + 9) + 1) as *u8)
note: possible options:
a = *((ix + {-128..127}) as *u8)a = *((iy + {-128..127}) as *u8)
note: assignment must be rewritten some other way
error: could not generate code for statement
error: could not generate code for bitwise or |
note: got: a |= *(((ix + 9) + 0) as *u8)
note: possible options:
a |= *((ix + {-128..127}) as *u8)a |= *((iy + {-128..127}) as *u8)
note: expression must be rewritten some other way
Let me know if I am doing something wrong or it is not implemented yet.
The same issue happens for nested struct members.
struct Word { low : u8, high : u8 }
// ...
a = monster.isOffScreenFlags.low;
a |= monster.isOffScreenFlags.high;
This happens in both cases, because struct member access and those byte-access operators use the same logic internally to get an offset.
Wiz isn't folding those constant adds together. As shown in the error message, you get *((ix + offset1) + offset2), but we should simplify this by using associativity of addition to constant fold and make this *(ix + dd) form. We don't typically rearrange evaluation order like this when runtime expressions are involved on one-or-both sides of a binary operator (to preserve intent closer to the original source in the generated machine code, and so stuff can rely on runtime effects like generating carries happening), but we know that addition is commutative and associative, and we're folding constant leaf nodes together, and ONLY doing it within stuff that uses structs or byte/word-access operators, so I think it's okay.
The same issue happens for nested struct members.
This happens in both cases, because struct member access and those byte-access operators use the same logic internally to get an offset.
Wiz isn't folding those constant adds together. As shown in the error message, you get
*((ix + offset1) + offset2)
, but we should simplify this by using associativity of addition to constant fold and make this*(ix + dd)
form. We don't typically rearrange evaluation order like this when runtime expressions are involved on one-or-both sides of a binary operator (to preserve intent closer to the original source in the generated machine code, and so stuff can rely on runtime effects like generating carries happening), but we know that addition is commutative and associative, and we're folding constant leaf nodes together, and ONLY doing it within stuff that uses structs or byte/word-access operators, so I think it's okay.