summaryrefslogtreecommitdiff
path: root/arch/powerpc/include/asm/code-patching.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include/asm/code-patching.h')
-rw-r--r--arch/powerpc/include/asm/code-patching.h22
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);