-
Notifications
You must be signed in to change notification settings - Fork 150
Matching Tricks
In this section I invite anyone to put tricks they have found work during getting the last few % of a function.
If you need 8 fewer bytes in your stack size and your function contains an inline such as GET_JOBJ, you can get those 8 bytes by manually inlining
Example:
gobj->hsd_obj instead of GET_JOBJ
If you have an arithmetic operation such as a * (b - c), and you want to swap the register order of the *, you will have to store b - c in a variable. This will take up stack space, but is required to swap the register order.
Example:
tmp = b - c
result = tmp * aThis can be two things:
- If it is after a comparison with a number, it is likely a switch statement
- If it is after a comparison with another variable (and is of the format bgt b or something like that), it is likely a ternary. Try using the MIN, MAX or CLAMP defines, but if these don't work, create your own ternary
Examples:
Instead of:
if (lbl_80479A98.x4 < 3) {
if (lbl_80479A98.x4 < 0) {
} else {
lbl_80479A98.x18 = 1;
}
}It is
switch (lbl_80479A98.x4) {
case 0:
case 1:
case 2:
lbl_80479A98.x18 = 1;
}
Instead of:
var_r4 = lbl_80479A98.xC;
temp_r0 = lbl_80479A98.x8 - lbl_80479A98.x10;
if (temp_r0 < var_r4) {
} else {
var_r4 = temp_r0;
}
lbl_80479A98.x8 = var_r4;It is
lbl_80479A98.x8 =
((lbl_80479A98.x8 - lbl_80479A98.x10) < (lbl_80479A98.xC))
? (lbl_80479A98.xC)
: (lbl_80479A98.x8 - lbl_80479A98.x10);When copying multiple contiguous fields, MWCC uses int stores/loads, regardless of the types of the fields being copied. So these expressions produce different assembly:
// uses stw/lwz
Vec3 v = foo;
// uses stfs/lfs
Vec3 v;
v.x = foo.x;
v.y = foo.y;
v.z = foo.z;MWCC only unrolls loops if the counter is exactly type int -- it will not work for s32, even though these should be equivalent.
if(v != 0.0f)
1bb8: lfs f1,grI1_804DB5C8@sda21(0) // 0.0f
1bbc: lfs f2,0xf0(r31) // variable, v
1bc0: fcmpu cr0,f2,f1 // cmp both
if(v)
1bb8: lfs f1,grI1_804DB5C8@sda21(0) // 0.0f
1bbc: lfs f2,0xf0(r31) // variable, v
1bc0: fcmpu cr0,f1,f2 // cmp both