switch becomes a comparison tree
SFA's race objects are driven by a phase integer and a big switch. With a handful of small, contiguous cases MWCC does not build a jump table — it emits a binary search of cmpwi/branch, which is one of the most disorienting shapes to read back into a clean switch. The jump table only appears once the case count grows (roughly five or more dense, contiguous labels); below that threshold you get the comparison tree, so don't expect a table on every switch.
typedef struct { int phase; f32 timer; } RaceState;
typedef struct { RaceState* state; } RaceObject;
extern void GameBit_Set(int bit, int val);
extern int GameBit_Get(int bit);
extern int timerCountDown(f32* t);
extern void s16toFloat(f32* t, int frames);
Watch how the dispatch pivots on 2, then narrows:
lwz r0, 0(r31) # s->phase
cmpwi r0, 2
beq- .case2
bge- .hi # phase >= 3
cmpwi r0, 0
beq- .case0
bge- .case1 # phase == 1
b .default
.hi:
cmpwi r0, 4
bge- .default
b .case3 # phase == 3
The body of each case is ordinary: GameBit_Get/Set calls, a stw to update phase, and in case 2 a timerCountDown guard. A useful habit here: rather than reverse-engineering the comparison tree by hand, write the plain switch with the cases in numeric order and a default, and MWCC regenerates this exact pivot structure for you.
Your task
Write race_advance taking a RaceObject* obj. Switch on s->phase with cases 0 through 3 and a default, reading s from obj->state. Match the comparison tree and all per-case behaviour shown in the assembly above.