The 72 concentrated candidates, and a float-constant ambiguity
Looking at the 72 candidates with fewer than 16 distinct immediates, the sets are full of values that look like lui high halves: 0x3f80 is the high half of 1.0f, and 0xff40/0xff70/0xff80/0xffc0 are negative high halves. 0xc0 << 16 is 0x00c00000, a small float. So 0xc0 in these functions may be a float constant rather than a chunk offset. The neighbour control cannot tell the difference, because 0xb8 and 0xc8 are equally plausible float high halves and are rare for their own reasons. Also recorded, and explicitly not as a finding: exactly 1 of 394 candidates contains another chunk offset, and none of the 72 does. That sounds like evidence of moby-specificity and is not -- the other chunk offsets are 0x1e80 and above and are globally rare (0 to 2 functions each, measured in3ea5ab7), so their absence here is exactly what rarity predicts. What survives is the enrichment fact froma2f8c92. What does not survive is reading 0xc0 as a chunk offset. There are now two live explanations, a moby chunk reference and a float constant, and only disassembly separates them. Cheapest test: 0x3a8060, 148 bytes, six immediates. If the lui carrying 0xc0 is paired with an ori it is a float; if it feeds an addiu computing base + 0xc0 it is the chunk. 284 passing with the disc present, clippy clean.
This commit is contained in:
@@ -2129,3 +2129,45 @@ test that will catch them being thrown away again.
|
||||
|
||||
Still true and still worth saying: presence of an immediate is not proof the chunk
|
||||
is read there. It is proof the constant is used, which is all either test asserts.
|
||||
|
||||
|
||||
### The 72 concentrated candidates, and an ambiguity that has to be stated
|
||||
|
||||
Sorted by fewest distinct immediates, the 72 candidates under 16 immediates look
|
||||
like this (first 14, immediate sets truncated):
|
||||
|
||||
0x2dc3e0 220b 6 imm 0x10 0x20 0x30 0x90 0xc0 0xff70
|
||||
0x310748 240b 6 imm 0x10 0x40 0xa0 0xc0 0x4480 0xff60
|
||||
0x31ed88 292b 6 imm 0x40 0x70 0x80 0xc0 0x3f80 0xff40
|
||||
0x3a8060 148b 6 imm 0x40 0xc0 0xd0 0xe0 0x3f80 0xffc0
|
||||
0x2e8de0 696b 8 imm 0x01 0x0f 0xc0 0x0fdc 0x3fc9 0xf000 0xff40 0xffff
|
||||
0x3114e0 160b 8 imm 0x01 0x10 0x30 0x40 0x80 0xc0 0x3a80 0xff80
|
||||
|
||||
Two observations, and the second is a problem.
|
||||
|
||||
**First: none of these contains another chunk offset.** Across all 394 candidates,
|
||||
exactly one contains any other level-0 chunk offset, and none of the 72 does.
|
||||
|
||||
**Second, and this is why the first is not the finding it looks like:** the other
|
||||
chunk offsets are `0x1e80`, `0x27c0`, `0x2910`, `0x2ee0`, `0x3960`, `0x3e20` --
|
||||
all above `0xff`, and globally rare (0 to 2 functions each, measured in
|
||||
`3ea5ab7`). Their absence here is exactly what rarity predicts and carries no
|
||||
information. "Only 1 of 394 references another chunk" sounds like evidence of
|
||||
moby-specificity and is not; it restates that those offsets are rare everywhere.
|
||||
|
||||
**The real ambiguity:** these immediate sets are full of values that look like
|
||||
`lui` high halves. `0x3f80` is the high half of `1.0f`. `0xff70`, `0xff40`,
|
||||
`0xffc0`, `0xff80` are negative high halves. `0xc0 << 16` is `0x00c00000`, a small
|
||||
float. So `0xc0` in these functions may be a **float constant high half**, not a
|
||||
chunk offset at all -- and the neighbour control would not catch that, because
|
||||
`0xb8` and `0xc8` are equally plausible float high halves and they are rare for
|
||||
their own reasons.
|
||||
|
||||
What survives: `0xc0` is used far more than adjacent constants of the same
|
||||
magnitude, at every set size. What does **not** survive is the reading of it as a
|
||||
chunk offset. That now has two live explanations -- a moby chunk reference, or a
|
||||
float constant -- and only disassembly separates them.
|
||||
|
||||
`0x3a8060` at 148 bytes with six immediates is the cheapest thing to disassemble
|
||||
and would settle it: if the `lui` at that site is paired with an `ori` it is a
|
||||
float, and if it feeds an `addiu` computing `base + 0xc0` it is the chunk.
|
||||
|
||||
Reference in New Issue
Block a user