From 0d4ad3e7e28fcda587c71f29d637976be7488c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Sun, 16 Jun 2019 00:00:06 +0000 Subject: [PATCH] x86 asm: move POPCNT in from x86-assembly-cheat --- README.adoc | 3 +++ userland/arch/x86_64/popcnt.S | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 userland/arch/x86_64/popcnt.S diff --git a/README.adoc b/README.adoc index 1890029..c968556 100644 --- a/README.adoc +++ b/README.adoc @@ -12427,6 +12427,9 @@ Do a BT and then swap the value of the tested bit. * link:userland/arch/x86_64/setcc.S[SETcc] + Set a a byte of a register to 0 or 1 depending on the cc condition. +* link:userland/arch/x86_64/popcnt.S[POPCNT] ++ +Count the number of 1 bits. * link:userland/arch/x86_64/test.S[TEST] + Like <> but does AND instead of SUB: diff --git a/userland/arch/x86_64/popcnt.S b/userland/arch/x86_64/popcnt.S new file mode 100644 index 0000000..dc0da8a --- /dev/null +++ b/userland/arch/x86_64/popcnt.S @@ -0,0 +1,37 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-bit-and-byte-instructions */ + +#include + +LKMC_PROLOGUE + mov $0, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $0) + + mov $1, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $1) + + mov $2, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $1) + + mov $3, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $2) + + mov $4, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $1) + + mov $5, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $2) + + mov $6, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $2) + + mov $7, %rbx + popcnt %rbx, %rax + LKMC_ASSERT_EQ(%rax, $3) +LKMC_EPILOGUE