mirror of https://github.com/nmlgc/ReC98.git
[Research] Discover how pointer constness affects pointer parameter codegen
In most cases, this discovery will mean that we have to bite the bullet and remove `const` from pointer parameters if the generated ASM wouldn't match otherwise. That by itself doesn't really simplify the code, but at least we get to remove a single bloated `reinterpret_cast` from one function call already. Part of P0278, funded by Yanga.
This commit is contained in:
parent
5359bff77b
commit
c96952f47b
|
@ -362,8 +362,14 @@ certain local variables as `word`s when they aren't.
|
|||
|
||||
### Pushing pointers
|
||||
|
||||
When passing a `near` pointer to a function that takes a `far` one, the
|
||||
segment argument is sometimes `PUSH`ed immediately, before evaluating the
|
||||
Passing `far` pointers to subscripted array elements requires code to calculate
|
||||
the offset. Turbo C++ emits this calculation (and not the `PUSH` itself) either
|
||||
before or after the segment is `PUSH`ed. If either
|
||||
|
||||
1. the pointer is `near`, or
|
||||
2. the parameter is a near or far `const *`,
|
||||
|
||||
the segment argument is always pushed immediately, before evaluating the
|
||||
offset:
|
||||
|
||||
```c++
|
||||
|
@ -375,11 +381,14 @@ struct s100 {
|
|||
|
||||
extern s100 structs[5];
|
||||
|
||||
void __cdecl process(s100 *element);
|
||||
void __cdecl process_mut(s100 *element);
|
||||
void __cdecl process_const(const s100 *element);
|
||||
|
||||
void foo(int i) {
|
||||
process((s100 near *)(&structs[i])); // PUSH DS; (AX = offset); PUSH AX;
|
||||
process((s100 far *)(&structs[i])); // (AX = offset); PUSH DS; PUSH AX;
|
||||
process_mut((s100 near *)(&structs[i])); // PUSH DS; (AX = offset); PUSH AX;
|
||||
process_mut((s100 far *)(&structs[i])); // (AX = offset); PUSH DS; PUSH AX;
|
||||
process_const((s100 near *)(&structs[i])); // PUSH DS; (AX = offset); PUSH AX;
|
||||
process_const((s100 far *)(&structs[i])); // PUSH DS; (AX = offset); PUSH AX;
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -603,7 +603,7 @@ static const int SCOREDAT_NOT_CLEARED = (SCOREDAT_CLEARED - 10);
|
|||
void regist_menu(
|
||||
score_t score,
|
||||
int16_t stage_num_or_scoredat_constant,
|
||||
const sshiftjis_t route[SCOREDAT_ROUTE_LEN + 1]
|
||||
sshiftjis_t route[SCOREDAT_ROUTE_LEN + 1]
|
||||
)
|
||||
{
|
||||
scoredat_name_z_t names[SCOREDAT_PLACES];
|
||||
|
|
|
@ -18,5 +18,5 @@
|
|||
void regist_menu(
|
||||
score_t score,
|
||||
int16_t stage_num_or_scoredat_constant,
|
||||
const sshiftjis_t route[SCOREDAT_ROUTE_LEN + 1]
|
||||
sshiftjis_t route[SCOREDAT_ROUTE_LEN + 1]
|
||||
);
|
||||
|
|
|
@ -1006,8 +1006,7 @@ int main(void)
|
|||
}
|
||||
resident->score = score;
|
||||
|
||||
// ZUN bloat: Unnecessary cast.
|
||||
regist_menu(score, (stage_id + 1), reinterpret_cast<const sshiftjis_t *>(
|
||||
regist_menu(score, (stage_id + 1), (
|
||||
!stage_on_route(stage_id) ? SCOREDAT_ROUTE_SHRINE :
|
||||
(route == ROUTE_MAKAI) ? SCOREDAT_ROUTE_MAKAI : SCOREDAT_ROUTE_JIGOKU
|
||||
));
|
||||
|
|
Loading…
Reference in New Issue