Skip to content

Commit

Permalink
MIPS: Refactor handling of stack pointer in get_frame_info
Browse files Browse the repository at this point in the history
Commit 34c2f66 ("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>
  • Loading branch information
Matt Redfearn authored and Ralf Baechle committed Sep 6, 2017
1 parent 41885b0 commit 56dfb70
Showing 1 changed file with 30 additions and 31 deletions.
61 changes: 30 additions & 31 deletions arch/mips/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,11 @@ static inline int is_jump_ins(union mips_instruction *ip)
#endif
}

static inline int is_sp_move_ins(union mips_instruction *ip)
static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size)
{
#ifdef CONFIG_CPU_MICROMIPS
unsigned short tmp;

/*
* addiusp -imm
* addius5 sp,-imm
Expand All @@ -325,20 +327,39 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
* microMIPS is not more fun...
*/
if (mm_insn_16bit(ip->word >> 16)) {
return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
ip->mm16_r3_format.simmediate & mm_addiusp_func) ||
(ip->mm16_r5_format.opcode == mm_pool16d_op &&
ip->mm16_r5_format.rt == 29);
if (ip->mm16_r3_format.opcode == mm_pool16d_op &&
ip->mm16_r3_format.simmediate & mm_addiusp_func) {
tmp = ip->mm_b0_format.simmediate >> 1;
tmp = ((tmp & 0x1ff) ^ 0x100) - 0x100;
if ((tmp + 2) < 4) /* 0x0,0x1,0x1fe,0x1ff are special */
tmp ^= 0x100;
*frame_size = -(signed short)(tmp << 2);
return 1;
}
if (ip->mm16_r5_format.opcode == mm_pool16d_op &&
ip->mm16_r5_format.rt == 29) {
tmp = ip->mm16_r5_format.imm >> 1;
*frame_size = -(signed short)(tmp & 0xf);
return 1;
}
return 0;
}

return ip->mm_i_format.opcode == mm_addiu32_op &&
ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
if (ip->mm_i_format.opcode == mm_addiu32_op &&
ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29) {
*frame_size = -ip->i_format.simmediate;
return 1;
}
#else
/* addiu/daddiu sp,sp,-imm */
if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
return 0;
if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op)

if (ip->i_format.opcode == addiu_op ||
ip->i_format.opcode == daddiu_op) {
*frame_size = -ip->i_format.simmediate;
return 1;
}
#endif
return 0;
}
Expand Down Expand Up @@ -375,29 +396,7 @@ static int get_frame_info(struct mips_frame_info *info)
}

if (!info->frame_size) {
if (is_sp_move_ins(&insn))
{
#ifdef CONFIG_CPU_MICROMIPS
if (mm_insn_16bit(insn.word >> 16))
{
unsigned short tmp;

if (ip->mm16_r3_format.simmediate & mm_addiusp_func)
{
tmp = ip->mm_b0_format.simmediate >> 1;
tmp = ((tmp & 0x1ff) ^ 0x100) - 0x100;
/* 0x0,0x1,0x1fe,0x1ff are special */
if ((tmp + 2) < 4)
tmp ^= 0x100;
info->frame_size = -(signed short)(tmp << 2);
} else {
tmp = (ip->mm16_r5_format.imm >> 1);
info->frame_size = -(signed short)(tmp & 0xf);
}
} else
#endif
info->frame_size = - ip->i_format.simmediate;
}
is_sp_move_ins(&insn, &info->frame_size);
continue;
} else if (!saw_jump && is_jump_ins(ip)) {
/*
Expand Down

0 comments on commit 56dfb70

Please sign in to comment.