diff options
Diffstat (limited to 'arch/powerpc/include/asm/code-patching.h')
-rw-r--r-- | arch/powerpc/include/asm/code-patching.h | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 378b70545a32..947d4ae062f5 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -51,8 +51,26 @@ static inline bool is_offset_in_cond_branch_range(long offset) return offset >= -0x8000 && offset <= 0x7fff && !(offset & 0x3); } -int create_branch(ppc_inst_t *instr, const u32 *addr, - unsigned long target, int flags); +static inline int create_branch(ppc_inst_t *instr, const u32 *addr, + unsigned long target, int flags) +{ + long offset; + + *instr = ppc_inst(0); + offset = target; + if (! (flags & BRANCH_ABSOLUTE)) + offset = offset - (unsigned long)addr; + + /* Check we can represent the target in the instruction format */ + if (!is_offset_in_branch_range(offset)) + return 1; + + /* Mask out the flags and target, so they don't step on each other. */ + *instr = ppc_inst(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC)); + + return 0; +} + int create_cond_branch(ppc_inst_t *instr, const u32 *addr, unsigned long target, int flags); int patch_branch(u32 *addr, unsigned long target, int flags); |