MIPS: Add is_jr_ra_ins() to end the loop early
For those leaf functions, they are likely to have no stack operations. Add is_jr_ra_ins() to determine whether jr ra has been touched before the frame_size is found. Without this patch, the get frame_size operation may be out of range and get the frame_size from the next nested function. There is no POOL32A format in uapi/asm/inst.h, so some bits here use the format of r_format instead. e.g. --------------------------------------------------------------------- | format | 31:26 | 25:21 | 20:16 | 15:6 | 5:0 | -----------------+---------+-------+-------+------------+------------ | pool32a_format | pool32a | rt | rs | jalrc | pool32axf | -----------------+---------+-------+-------+------------+------------ | r_format | opcode | rs | rt | rd:5, re:5 | func | --------------------------------------------------------------------- Signed-off-by: Jinyang He <hejinyang@loongson.cn> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
This commit is contained in:
Родитель
2d62f64bcc
Коммит
50886234e8
|
@ -188,6 +188,36 @@ struct mips_frame_info {
|
|||
#define J_TARGET(pc,target) \
|
||||
(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
|
||||
|
||||
static inline int is_jr_ra_ins(union mips_instruction *ip)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
/*
|
||||
* jr16 ra
|
||||
* jr ra
|
||||
*/
|
||||
if (mm_insn_16bit(ip->word >> 16)) {
|
||||
if (ip->mm16_r5_format.opcode == mm_pool16c_op &&
|
||||
ip->mm16_r5_format.rt == mm_jr16_op &&
|
||||
ip->mm16_r5_format.imm == 31)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ip->r_format.opcode == mm_pool32a_op &&
|
||||
ip->r_format.func == mm_pool32axf_op &&
|
||||
((ip->u_format.uimmediate >> 6) & GENMASK(9, 0)) == mm_jalr_op &&
|
||||
ip->r_format.rt == 31)
|
||||
return 1;
|
||||
return 0;
|
||||
#else
|
||||
if (ip->r_format.opcode == spec_op &&
|
||||
ip->r_format.func == jr_op &&
|
||||
ip->r_format.rs == 31)
|
||||
return 1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
|
@ -400,7 +430,9 @@ static int get_frame_info(struct mips_frame_info *info)
|
|||
last_insn_size = 4;
|
||||
}
|
||||
|
||||
if (!info->frame_size) {
|
||||
if (is_jr_ra_ins(ip)) {
|
||||
break;
|
||||
} else if (!info->frame_size) {
|
||||
is_sp_move_ins(&insn, &info->frame_size);
|
||||
continue;
|
||||
} else if (!saw_jump && is_jump_ins(ip)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче