about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2017-01-09 17:22:49 +0100
committerAjax <commial@gmail.com>2017-01-09 17:27:36 +0100
commit5a8bb06aa4f359b1091d0bc10e86524264b60c3d (patch)
treec9c80ddb9a66ef572d09ef1fe15159b9094df329
parentedf8a67791cd7e3255cce048f2deb1bea436485c (diff)
downloadmiasm-5a8bb06aa4f359b1091d0bc10e86524264b60c3d.tar.gz
miasm-5a8bb06aa4f359b1091d0bc10e86524264b60c3d.zip
LLVM: use llvm.ctpop for 'parity' operation
-rw-r--r--miasm2/jitter/llvmconvert.py20
1 files changed, 15 insertions, 5 deletions
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index 4031d8f2..32d4764c 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -197,10 +197,11 @@ class LLVMContext_JIT(LLVMContext):
     def add_op(self):
         "Add operations functions"
 
-        p8 = llvm_ir.PointerType(LLVMType.IntType(8))
+        i8 = LLVMType.IntType(8)
+        p8 = llvm_ir.PointerType(i8)
         itype = LLVMType.IntType(64)
-        self.add_fc({"parity": {"ret": LLVMType.IntType(1),
-                                "args": [itype]}})
+        self.add_fc({"llvm.ctpop.i8": {"ret": i8,
+                                       "args": [i8]}})
         self.add_fc({"rot_left": {"ret": itype,
                                   "args": [itype,
                                            itype,
@@ -381,8 +382,7 @@ class LLVMFunction():
 
     # Operation translation
     ## Basics
-    op_translate = {'parity': 'parity',
-                    'cpuid': 'cpuid',
+    op_translate = {'cpuid': 'cpuid',
     }
     ## Add the size as first argument
     op_translate_with_size = {'<<<': 'rot_left',
@@ -711,6 +711,16 @@ class LLVMFunction():
                 self.update_cache(expr, ret)
                 return ret
 
+            if op == "parity":
+                assert len(expr.args) == 1
+                arg = self.add_ir(expr.args[0])
+                truncated = builder.trunc(arg, LLVMType.IntType(8))
+                bitcount = builder.call(self.mod.get_global("llvm.ctpop.i8"),
+                                        [truncated])
+                ret = builder.not_(builder.trunc(bitcount, LLVMType.IntType(1)))
+                self.update_cache(expr, ret)
+                return ret
+
             if op == "segm":
                 fc_ptr = self.mod.get_global("segm2addr")