MIPS: Refactor handling of stack pointer in get_frame_info

Commit 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
added handling of microMIPS instructions to manipulate the stack
pointer. The code that was added violates code style rules with long
lines caused by lots of nested conditionals.

The added code interprets (inline) any known stack pointer manipulation
instruction to find the stack frame size. Handling the microMIPS cases
added quite a bit of complication to this function.

Refactor is_sp_move_ins to perform the interpretation of the immediate
as the instruction manipulating the stack pointer is found. This reduces
the amount of indentation required in get_frame_info, and more closely
matches the operation of is_ra_save_ins.

Suggested-by: Maciej W. Rozycki <macro@imgtec.com>
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Cc: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16958/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Matt Redfearn and committed by
Ralf Baechle
56dfb700 41885b02

+30 -31
+30 -31
arch/mips/kernel/process.c
··· 313 313 #endif 314 314 } 315 315 316 - static inline int is_sp_move_ins(union mips_instruction *ip) 316 + static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size) 317 317 { 318 318 #ifdef CONFIG_CPU_MICROMIPS 319 + unsigned short tmp; 320 + 319 321 /* 320 322 * addiusp -imm 321 323 * addius5 sp,-imm ··· 327 325 * microMIPS is not more fun... 328 326 */ 329 327 if (mm_insn_16bit(ip->word >> 16)) { 330 - return (ip->mm16_r3_format.opcode == mm_pool16d_op && 331 - ip->mm16_r3_format.simmediate & mm_addiusp_func) || 332 - (ip->mm16_r5_format.opcode == mm_pool16d_op && 333 - ip->mm16_r5_format.rt == 29); 328 + if (ip->mm16_r3_format.opcode == mm_pool16d_op && 329 + ip->mm16_r3_format.simmediate & mm_addiusp_func) { 330 + tmp = ip->mm_b0_format.simmediate >> 1; 331 + tmp = ((tmp & 0x1ff) ^ 0x100) - 0x100; 332 + if ((tmp + 2) < 4) /* 0x0,0x1,0x1fe,0x1ff are special */ 333 + tmp ^= 0x100; 334 + *frame_size = -(signed short)(tmp << 2); 335 + return 1; 336 + } 337 + if (ip->mm16_r5_format.opcode == mm_pool16d_op && 338 + ip->mm16_r5_format.rt == 29) { 339 + tmp = ip->mm16_r5_format.imm >> 1; 340 + *frame_size = -(signed short)(tmp & 0xf); 341 + return 1; 342 + } 343 + return 0; 334 344 } 335 345 336 - return ip->mm_i_format.opcode == mm_addiu32_op && 337 - ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; 346 + if (ip->mm_i_format.opcode == mm_addiu32_op && 347 + ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29) { 348 + *frame_size = -ip->i_format.simmediate; 349 + return 1; 350 + } 338 351 #else 339 352 /* addiu/daddiu sp,sp,-imm */ 340 353 if (ip->i_format.rs != 29 || ip->i_format.rt != 29) 341 354 return 0; 342 - if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) 355 + 356 + if (ip->i_format.opcode == addiu_op || 357 + ip->i_format.opcode == daddiu_op) { 358 + *frame_size = -ip->i_format.simmediate; 343 359 return 1; 360 + } 344 361 #endif 345 362 return 0; 346 363 } ··· 396 375 } 397 376 398 377 if (!info->frame_size) { 399 - if (is_sp_move_ins(&insn)) 400 - { 401 - #ifdef CONFIG_CPU_MICROMIPS 402 - if (mm_insn_16bit(insn.word >> 16)) 403 - { 404 - unsigned short tmp; 405 - 406 - if (ip->mm16_r3_format.simmediate & mm_addiusp_func) 407 - { 408 - tmp = ip->mm_b0_format.simmediate >> 1; 409 - tmp = ((tmp & 0x1ff) ^ 0x100) - 0x100; 410 - /* 0x0,0x1,0x1fe,0x1ff are special */ 411 - if ((tmp + 2) < 4) 412 - tmp ^= 0x100; 413 - info->frame_size = -(signed short)(tmp << 2); 414 - } else { 415 - tmp = (ip->mm16_r5_format.imm >> 1); 416 - info->frame_size = -(signed short)(tmp & 0xf); 417 - } 418 - } else 419 - #endif 420 - info->frame_size = - ip->i_format.simmediate; 421 - } 378 + is_sp_move_ins(&insn, &info->frame_size); 422 379 continue; 423 380 } else if (!saw_jump && is_jump_ins(ip)) { 424 381 /*