Base address plus a scaled index
tbl[i] from a global array is two ideas you've already met, bolted together. Build the address, then run a scaled, indexed load. Arrays don't sit in small data, so the base is still the @ha/@l pair. Scale i by the element size and let lwzx ("load word zero, indexed") grab the element off base-plus-index:
lis r4, tbl@ha # high half of &tbl
slwi r0, r3, 2 # r0 = i * 4 (sizeof(int) == 4)
addi r3, r4, tbl@l # r3 = &tbl (add low half)
lwzx r3, r3, r0 # r3 = *(&tbl + i*4) = tbl[i]
blr
R_PPC_ADDR16_HA tbl
R_PPC_ADDR16_LO tbl
slwi r0, r3, 2 shifts left by 2. That's a multiply by 4, which is the size of an int. After it, lwzx rD, rA, rB reads from rA + rB, the base plus that scaled offset, no displacement field anywhere. And those two R_PPC_ADDR16 relocations give it away as a global array rather than a small-data scalar.
One detail worth a second look. The slwi sits between the lis and the addi, even though it has no part in forming the base. That's scheduling, not meaning. Its scaling doesn't depend on the address pair, so MWCC drops it into the gap to hide the lis latency. Real CodeWarrior output reorders things like this constantly, so don't read anything into it.
Your task
extern int gScores[]; is provided. Write getScore, taking an int i, so it compiles to the indexed array load above.