Powers of two never reach the multiplier
mul is the only multiply instruction Thumb has, and gcc avoids it whenever the constant is a power of two. A shift does the same job in one instruction, with none of mul's register constraints and none of its extra cycles.
Here is y * 32:
0 lsl r0, r1, #5
2 bx lr
The factor is hiding in the shift amount: 2 to the power 5 is 32. Reading it back is always that, and the shift form has a three-operand encoding, so the value can be read from one register and written to another without any preparatory copy.
The interesting part is what happens around the shift. Here is y - x * 4:
0 lsl r0, #2
2 sub r0, r1, r0
4 bx lr
The product is built in r0 — two-operand this time, because x was already there and is not needed afterwards — and then the reverse-subtract form takes it away from y. That sub rD, rN, rD shape is the direction marker from earlier in the chapter, and it survives having a product on one side.
A listing with several shifts in a row is usually several scaled values waiting to be combined, one shift each. Take each lsl on its own, convert it to its factor, then read the instruction that joins them. Whether a given shift comes out two-operand or three-operand depends only on whether the value being scaled is still needed afterwards.
Your target scales two different values before combining them.
Your task
Write func_08057d4c to reproduce the target assembly.