Re: [PATCH V8 06/10] powerpc, lib: Add new branch analysis support functions

2015-06-10 Thread Anshuman Khandual
On 06/10/2015 11:03 AM, Daniel Axtens wrote:
 
 +static int instr_is_branch_xlform(unsigned int instr)
 +{
 +return branch_opcode(instr) == 19;
 +}
 Why do these not return bool? The functions below do.

Yeah they can, will change it.

 +
 +bool instr_is_indirect_func_call(unsigned int instr)
 +{
 +/* XL-form instruction with LR set */
 +if (instr_is_branch_xlform(instr)  is_branch_link_set(instr))
 +return true;
 +
 +return false;
 +}

 Both of these functions could be made into a single 'return' statement,
 right?

Yeah, right.

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH V8 06/10] powerpc, lib: Add new branch analysis support functions

2015-06-09 Thread Daniel Axtens

 +static int instr_is_branch_xlform(unsigned int instr)
 +{
 + return branch_opcode(instr) == 19;
 +}
Why do these not return bool? The functions below do.
 +
 +static int is_xlform_lr(unsigned int instr)
 +{
 + return (instr  XL_FORM_LR) == XL_FORM_LR;
 +}
 +
 +static int is_bo_always(unsigned int instr)
 +{
 + return (instr  BO_ALWAYS) == BO_ALWAYS;
 +}
 +
 +static int is_branch_link_set(unsigned int instr)
 +{
 + return (instr  BRANCH_SET_LINK) == BRANCH_SET_LINK;
 +}
 +
 +bool instr_is_return_branch(unsigned int instr)
 +{
 + /*
 +  * Conditional and unconditional branch to LR register
 +  * without seting the link register.
setting
 +  */
 + if (is_xlform_lr(instr)  !is_branch_link_set(instr))
 + return true;
 +
 + return false;
 +}
 +




 +bool instr_is_func_call(unsigned int instr)
 +{
 + /* LR should be set */
 + if (is_branch_link_set(instr))
 + return true;
 +
 + return false;
 +}
 +
 +bool instr_is_indirect_func_call(unsigned int instr)
 +{
 + /* XL-form instruction with LR set */
 + if (instr_is_branch_xlform(instr)  is_branch_link_set(instr))
 + return true;
 +
 + return false;
 +}
Both of these functions could be made into a single 'return' statement,
right?
 +
  int instr_is_relative_branch(unsigned int instr)
  {
   if (instr  BRANCH_ABSOLUTE)



signature.asc
Description: This is a digitally signed message part
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V8 06/10] powerpc, lib: Add new branch analysis support functions

2015-06-08 Thread Anshuman Khandual
Generic powerpc branch analysis support added in the code patching
library which will help the subsequent patch on SW based filtering
of branch records in perf.

Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/code-patching.h | 15 
 arch/powerpc/lib/code-patching.c | 66 
 2 files changed, 81 insertions(+)

diff --git a/arch/powerpc/include/asm/code-patching.h 
b/arch/powerpc/include/asm/code-patching.h
index 840a550..0a6f0d8 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -22,6 +22,16 @@
 #define BRANCH_SET_LINK0x1
 #define BRANCH_ABSOLUTE0x2
 
+#define XL_FORM_LR  0x4C20
+#define XL_FORM_CTR 0x4C000420
+#define XL_FORM_TAR 0x4C000460
+
+#define BO_ALWAYS0x0280
+#define BO_CTR   0x0200
+#define BO_CRBI_OFF  0x0080
+#define BO_CRBI_ON   0x0180
+#define BO_CRBI_HINT 0x0040
+
 unsigned int create_branch(const unsigned int *addr,
   unsigned long target, int flags);
 unsigned int create_cond_branch(const unsigned int *addr,
@@ -99,4 +109,9 @@ static inline unsigned long ppc_global_function_entry(void 
*func)
 #endif
 }
 
+bool instr_is_return_branch(unsigned int instr);
+bool instr_is_conditional_branch(unsigned int instr);
+bool instr_is_func_call(unsigned int instr);
+bool instr_is_indirect_func_call(unsigned int instr);
+
 #endif /* _ASM_POWERPC_CODE_PATCHING_H */
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index d5edbeb..15b7b88 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -87,6 +87,72 @@ static int instr_is_branch_bform(unsigned int instr)
return branch_opcode(instr) == 16;
 }
 
+static int instr_is_branch_xlform(unsigned int instr)
+{
+   return branch_opcode(instr) == 19;
+}
+
+static int is_xlform_lr(unsigned int instr)
+{
+   return (instr  XL_FORM_LR) == XL_FORM_LR;
+}
+
+static int is_bo_always(unsigned int instr)
+{
+   return (instr  BO_ALWAYS) == BO_ALWAYS;
+}
+
+static int is_branch_link_set(unsigned int instr)
+{
+   return (instr  BRANCH_SET_LINK) == BRANCH_SET_LINK;
+}
+
+bool instr_is_return_branch(unsigned int instr)
+{
+   /*
+* Conditional and unconditional branch to LR register
+* without seting the link register.
+*/
+   if (is_xlform_lr(instr)  !is_branch_link_set(instr))
+   return true;
+
+   return false;
+}
+
+bool instr_is_conditional_branch(unsigned int instr)
+{
+   /* I-form instruction - excluded */
+   if (instr_is_branch_iform(instr))
+   return false;
+
+   /* B-form or XL-form instruction */
+   if (instr_is_branch_bform(instr) || instr_is_branch_xlform(instr))  {
+
+   /* Not branch always */
+   if (!is_bo_always(instr))
+   return true;
+   }
+   return false;
+}
+
+bool instr_is_func_call(unsigned int instr)
+{
+   /* LR should be set */
+   if (is_branch_link_set(instr))
+   return true;
+
+   return false;
+}
+
+bool instr_is_indirect_func_call(unsigned int instr)
+{
+   /* XL-form instruction with LR set */
+   if (instr_is_branch_xlform(instr)  is_branch_link_set(instr))
+   return true;
+
+   return false;
+}
+
 int instr_is_relative_branch(unsigned int instr)
 {
if (instr  BRANCH_ABSOLUTE)
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev