All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32()
@ 2015-03-17 15:09 Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 1/9] bt-sdp: fix broken uuids power-of-2 calculation Stefan Hajnoczi
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi

v2:
 * Audit coccinelle patch and split out two cases where ctz32(0) == 32 must be
   handled [Peter]
 * Cc qemu-stable@nongnu.org on first patch [Eric]

MinGW does not always provide ffs(3).  My MinGW 4.9.2 cannot link QEMU when
./configure --enable-debug was used due to the missing ffs(3) function.

In the past we already got rid of ffsl(3) calls, so getting rid of ffs(3) is a
logical next step.

This series replaces ffs(3) calls with ctz32().  Their semantics differ as follows:

1. ffs(0) == 0 but ctz32(0) == 32

2. Otherwise, ffs(val) - 1 == ctz32(val)

The first patch fixes a bug that was discovered when auditing ffs(3) callers.

The final patch adds checkpatch.pl support to prevent ffs(3), ffsl(3), and
ffsll(3) from being introduced into the codebase again in the future.

Note that there are instances of 64-bit values being passed to ffs(3).  I have
mechanically converted them to ctz32() and not worried about whether the
original code is buggy or not.

Stefan Hajnoczi (9):
  bt-sdp: fix broken uuids power-of-2 calculation
  hw/arm/nseries: convert ffs(3) to ctz32()
  uninorth: convert ffs(3) to ctz32()
  Convert (ffs(val) - 1) to ctz32(val)
  Convert ffs() != 0 callers to ctz32()
  sd: convert sd_normal_command() ffs(3) call to ctz32()
  omap_intc: convert ffs(3) to ctz32() in omap_inth_sir_update()
  os-win32: drop ffs(3) prototype
  checkpatch: complain about ffs(3) calls

 block.c                     |  2 +-
 block/qcow2-refcount.c      |  2 +-
 block/qcow2.c               |  4 ++--
 block/qed.c                 |  4 ++--
 block/rbd.c                 |  2 +-
 block/sheepdog.c            |  2 +-
 hw/acpi/pcihp.c             |  2 +-
 hw/arm/nseries.c            |  5 ++++-
 hw/arm/omap1.c              |  6 ++----
 hw/arm/pxa2xx_gpio.c        |  2 +-
 hw/arm/strongarm.c          |  4 ++--
 hw/bt/sdp.c                 |  2 +-
 hw/char/virtio-serial-bus.c |  8 ++++----
 hw/display/tc6393xb.c       |  2 +-
 hw/gpio/max7310.c           |  2 +-
 hw/gpio/omap_gpio.c         | 13 +++++--------
 hw/gpio/zaurus.c            |  2 +-
 hw/i2c/omap_i2c.c           | 10 +++++++---
 hw/intc/allwinner-a10-pic.c |  8 ++++----
 hw/intc/omap_intc.c         |  7 ++++---
 hw/pci-host/bonito.c        |  2 +-
 hw/pci-host/uninorth.c      |  5 ++++-
 hw/pci/msi.c                | 12 ++++++------
 hw/pci/pcie_aer.c           |  2 +-
 hw/pci/shpc.c               | 10 +++++-----
 hw/pci/slotid_cap.c         |  2 +-
 hw/ppc/ppce500_spin.c       |  2 +-
 hw/scsi/megasas.c           |  2 +-
 hw/sd/sd.c                  |  3 ++-
 include/hw/pci/pci.h        | 16 ++++++++--------
 include/hw/pci/pcie_regs.h  | 18 +++++++++---------
 include/sysemu/os-win32.h   |  3 ---
 kvm-all.c                   |  8 ++++----
 scripts/checkpatch.pl       | 11 +++++++++++
 target-ppc/cpu.h            |  4 ++--
 35 files changed, 102 insertions(+), 87 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 1/9] bt-sdp: fix broken uuids power-of-2 calculation
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 2/9] hw/arm/nseries: convert ffs(3) to ctz32() Stefan Hajnoczi
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Andrzej Zaborowski, Markus Armbruster,
	qemu-stable, Stefan Hajnoczi

The binary search in sdp_uuid_match() only works when the number of
elements to search is a power of two.

  lo = record->uuid;
  hi = record->uuids;
  while (hi >>= 1)
      if (lo[hi] <= val)
          lo += hi;

  return *lo == val;

I noticed that the record->uuids calculation in
sdp_service_record_build() was suspect:

  record->uuids = 1 << ffs(record->uuids - 1);

Unlike most ffs(val) - 1 users, the expression is ffs(val - 1)!

Actually ffs() is the wrong function to use for power-of-2.  Use
pow2ceil() to achieve the correct effect.  Now the record->uuid[] array
is sized correctly and the binary search in sdp_uuid_match() should
work.

I'm not sure how to run/test this code.

Cc: Andrzej Zaborowski <balrog@zabor.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/bt/sdp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c
index 218e075..c903747 100644
--- a/hw/bt/sdp.c
+++ b/hw/bt/sdp.c
@@ -707,7 +707,7 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
         len += sdp_attr_max_size(&def->attributes[record->attributes ++].data,
                         &record->uuids);
     }
-    record->uuids = 1 << ffs(record->uuids - 1);
+    record->uuids = pow2ceil(record->uuids);
     record->attribute_list =
             g_malloc0(record->attributes * sizeof(*record->attribute_list));
     record->uuid =
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 2/9] hw/arm/nseries: convert ffs(3) to ctz32()
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 1/9] bt-sdp: fix broken uuids power-of-2 calculation Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 3/9] uninorth: " Stefan Hajnoczi
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Andrzej Zaborowski, Markus Armbruster, Stefan Hajnoczi

It is not clear from the code how a 0 parameter should be handled by the
hardware.  Keep the same behavior as ffs(0) - 1 == -1.

Cc: Andrzej Zaborowski <balrog@zabor.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/arm/nseries.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 4d7be5e..606941a 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -579,7 +579,10 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
 
     case 0x26:	/* GAMSET */
         if (!s->pm) {
-            s->gamma = ffs(s->param[0] & 0xf) - 1;
+            s->gamma = ctz32(s->param[0] & 0xf);
+            if (s->gamma == 32) {
+                s->gamma = -1; /* XXX: should this be 0? */
+            }
         } else if (s->pm < 0) {
             s->pm = 1;
         }
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 3/9] uninorth: convert ffs(3) to ctz32()
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 1/9] bt-sdp: fix broken uuids power-of-2 calculation Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 2/9] hw/arm/nseries: convert ffs(3) to ctz32() Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 4/9] Convert (ffs(val) - 1) to ctz32(val) Stefan Hajnoczi
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi, Alexander Graf

It is not clear from the code how a 0 parameter should be handled by the
hardware.  Keep the same behavior as ffs(0) - 1 == -1.

Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/pci-host/uninorth.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index 53f2b59..f0144eb 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -92,7 +92,10 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
         uint32_t slot, func;
 
         /* Grab CFA0 style values */
-        slot = ffs(reg & 0xfffff800) - 1;
+        slot = ctz32(reg & 0xfffff800);
+        if (slot == 32) {
+            slot = -1; /* XXX: should this be 0? */
+        }
         func = (reg >> 8) & 7;
 
         /* ... and then convert them to x86 format */
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 4/9] Convert (ffs(val) - 1) to ctz32(val)
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
                   ` (2 preceding siblings ...)
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 3/9] uninorth: " Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 5/9] Convert ffs() != 0 callers to ctz32() Stefan Hajnoczi
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi

This commit was generated mechanically by coccinelle from the following
semantic patch:

@@
expression val;
@@
- (ffs(val) - 1)
+ ctz32(val)

The call sites have been audited to ensure the ffs(0) - 1 == -1 case
never occurs (due to input validation, asserts, etc).  Therefore we
don't need to worry about the fact that ctz32(0) == 32.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c                    |  2 +-
 block/qcow2-refcount.c     |  2 +-
 block/qcow2.c              |  4 ++--
 block/qed.c                |  4 ++--
 block/rbd.c                |  2 +-
 block/sheepdog.c           |  2 +-
 hw/acpi/pcihp.c            |  2 +-
 hw/arm/pxa2xx_gpio.c       |  2 +-
 hw/arm/strongarm.c         |  4 ++--
 hw/display/tc6393xb.c      |  2 +-
 hw/gpio/max7310.c          |  2 +-
 hw/gpio/zaurus.c           |  2 +-
 hw/pci-host/bonito.c       |  2 +-
 hw/pci/msi.c               | 12 ++++++------
 hw/pci/pcie_aer.c          |  2 +-
 hw/pci/shpc.c              | 10 +++++-----
 hw/pci/slotid_cap.c        |  2 +-
 hw/ppc/ppce500_spin.c      |  2 +-
 hw/scsi/megasas.c          |  2 +-
 include/hw/pci/pci.h       | 16 ++++++++--------
 include/hw/pci/pcie_regs.h | 18 +++++++++---------
 target-ppc/cpu.h           |  4 ++--
 22 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/block.c b/block.c
index 191a847..2eab818 100644
--- a/block.c
+++ b/block.c
@@ -5421,7 +5421,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity,
         return NULL;
     }
     bitmap = g_new0(BdrvDirtyBitmap, 1);
-    bitmap->bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
+    bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
     QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
     return bitmap;
 }
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index dc8d186..8804419 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -2438,7 +2438,7 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
     if (ret < 0) {
         return ret;
     } else if (ret > 0) {
-        int metadata_ol_bitnr = ffs(ret) - 1;
+        int metadata_ol_bitnr = ctz32(ret);
         assert(metadata_ol_bitnr < QCOW2_OL_MAX_BITNR);
 
         qcow2_signal_corruption(bs, true, offset, size, "Preventing invalid "
diff --git a/block/qcow2.c b/block/qcow2.c
index 32bdf75..5abca2e 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1788,7 +1788,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
 {
     /* Calculate cluster_bits */
     int cluster_bits;
-    cluster_bits = ffs(cluster_size) - 1;
+    cluster_bits = ctz32(cluster_size);
     if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
         (1 << cluster_bits) != cluster_size)
     {
@@ -2096,7 +2096,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
         goto finish;
     }
 
-    refcount_order = ffs(refcount_bits) - 1;
+    refcount_order = ctz32(refcount_bits);
 
     ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
                         cluster_size, prealloc, opts, version, refcount_order,
diff --git a/block/qed.c b/block/qed.c
index 892b13c..9d90888 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -436,9 +436,9 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
 
     s->table_nelems = (s->header.cluster_size * s->header.table_size) /
                       sizeof(uint64_t);
-    s->l2_shift = ffs(s->header.cluster_size) - 1;
+    s->l2_shift = ctz32(s->header.cluster_size);
     s->l2_mask = s->table_nelems - 1;
-    s->l1_shift = s->l2_shift + ffs(s->table_nelems) - 1;
+    s->l1_shift = s->l2_shift + ctz32(s->table_nelems);
 
     /* Header size calculation must not overflow uint32_t */
     if (s->header.header_size > UINT32_MAX / s->header.cluster_size) {
diff --git a/block/rbd.c b/block/rbd.c
index f3ab2dd..fbe87e0 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -325,7 +325,7 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
             error_setg(errp, "obj size too small");
             return -EINVAL;
         }
-        obj_order = ffs(objsize) - 1;
+        obj_order = ctz32(objsize);
     }
 
     clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
diff --git a/block/sheepdog.c b/block/sheepdog.c
index c14172c..2d5f06a 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1716,7 +1716,7 @@ static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt)
         if ((object_size - 1) & object_size) {    /* not a power of 2? */
             return -EINVAL;
         }
-        obj_order = ffs(object_size) - 1;
+        obj_order = ctz32(object_size);
         if (obj_order < 20 || obj_order > 31) {
             return -EINVAL;
         }
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 612fec0..77e1126 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -120,7 +120,7 @@ static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
 static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
 {
     BusChild *kid, *next;
-    int slot = ffs(slots) - 1;
+    int slot = ctz32(slots);
     PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
 
     if (!bus) {
diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c
index 354ccf1..c89c804 100644
--- a/hw/arm/pxa2xx_gpio.c
+++ b/hw/arm/pxa2xx_gpio.c
@@ -137,7 +137,7 @@ static void pxa2xx_gpio_handler_update(PXA2xxGPIOInfo *s) {
         level = s->olevel[i] & s->dir[i];
 
         for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) {
-            bit = ffs(diff) - 1;
+            bit = ctz32(diff);
             line = bit + 32 * i;
             qemu_set_irq(s->handler[line], (level >> bit) & 1);
         }
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 3206345..035d328 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -526,7 +526,7 @@ static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s)
     level = s->olevel & s->dir;
 
     for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
-        bit = ffs(diff) - 1;
+        bit = ctz32(diff);
         qemu_set_irq(s->handler[bit], (level >> bit) & 1);
     }
 
@@ -743,7 +743,7 @@ static void strongarm_ppc_handler_update(StrongARMPPCInfo *s)
     level = s->olevel & s->dir;
 
     for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
-        bit = ffs(diff) - 1;
+        bit = ctz32(diff);
         qemu_set_irq(s->handler[bit], (level >> bit) & 1);
     }
 
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index 4306adc..66b7ade 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -171,7 +171,7 @@ static void tc6393xb_gpio_handler_update(TC6393xbState *s)
     level = s->gpio_level & s->gpio_dir;
 
     for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
-        bit = ffs(diff) - 1;
+        bit = ctz32(diff);
         qemu_set_irq(s->handler[bit], (level >> bit) & 1);
     }
 
diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c
index 7fbf313..2f59b13 100644
--- a/hw/gpio/max7310.c
+++ b/hw/gpio/max7310.c
@@ -96,7 +96,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
     case 0x01:	/* Output port */
         for (diff = (data ^ s->level) & ~s->direction; diff;
                         diff &= ~(1 << line)) {
-            line = ffs(diff) - 1;
+            line = ctz32(diff);
             if (s->handler[line])
                 qemu_set_irq(s->handler[line], (data >> line) & 1);
         }
diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c
index 9408342..24a7727 100644
--- a/hw/gpio/zaurus.c
+++ b/hw/gpio/zaurus.c
@@ -65,7 +65,7 @@ static inline void scoop_gpio_handler_update(ScoopInfo *s) {
     level = s->gpio_level & s->gpio_dir;
 
     for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
-        bit = ffs(diff) - 1;
+        bit = ctz32(diff);
         qemu_set_irq(s->handler[bit], (level >> bit) & 1);
     }
 
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 8bdd569..1fe43e0 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -427,7 +427,7 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr)
     cfgaddr |= (s->regs[BONITO_PCIMAP_CFG] & 0xffff) << 16;
 
     idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> BONITO_PCICONF_IDSEL_OFFSET;
-    devno = ffs(idsel) - 1;
+    devno = ctz32(idsel);
     funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET;
     regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;
 
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index 52d2313..9fadbc6 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -72,7 +72,7 @@ static inline uint8_t msi_cap_sizeof(uint16_t flags)
 static inline unsigned int msi_nr_vectors(uint16_t flags)
 {
     return 1U <<
-        ((flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1));
+        ((flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE));
 }
 
 static inline uint8_t msi_flags_off(const PCIDevice* dev)
@@ -175,9 +175,9 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
     assert(nr_vectors > 0);
     assert(nr_vectors <= PCI_MSI_VECTORS_MAX);
     /* the nr of MSI vectors is up to 32 */
-    vectors_order = ffs(nr_vectors) - 1;
+    vectors_order = ctz32(nr_vectors);
 
-    flags = vectors_order << (ffs(PCI_MSI_FLAGS_QMASK) - 1);
+    flags = vectors_order << ctz32(PCI_MSI_FLAGS_QMASK);
     if (msi64bit) {
         flags |= PCI_MSI_FLAGS_64BIT;
     }
@@ -354,12 +354,12 @@ void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
      * just don't crash the host
      */
     log_num_vecs =
-        (flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
+        (flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE);
     log_max_vecs =
-        (flags & PCI_MSI_FLAGS_QMASK) >> (ffs(PCI_MSI_FLAGS_QMASK) - 1);
+        (flags & PCI_MSI_FLAGS_QMASK) >> ctz32(PCI_MSI_FLAGS_QMASK);
     if (log_num_vecs > log_max_vecs) {
         flags &= ~PCI_MSI_FLAGS_QSIZE;
-        flags |= log_max_vecs << (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
+        flags |= log_max_vecs << ctz32(PCI_MSI_FLAGS_QSIZE);
         pci_set_word(dev->config + msi_flags_off(dev), flags);
     }
 
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 5a25c32..aeba034 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -410,7 +410,7 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
 static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
 {
     uint8_t *aer_cap = dev->config + dev->exp.aer_cap;
-    uint8_t first_bit = ffs(err->status) - 1;
+    uint8_t first_bit = ctz32(err->status);
     uint32_t errcap = pci_get_long(aer_cap + PCI_ERR_CAP);
     int i;
 
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 759910f..a706486 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -61,7 +61,7 @@
 /* Same slot state masks are used for command and status registers */
 #define SHPC_SLOT_STATE_MASK     0x03
 #define SHPC_SLOT_STATE_SHIFT \
-    (ffs(SHPC_SLOT_STATE_MASK) - 1)
+    ctz32(SHPC_SLOT_STATE_MASK)
 
 #define SHPC_STATE_NO       0x0
 #define SHPC_STATE_PWRONLY  0x1
@@ -70,10 +70,10 @@
 
 #define SHPC_SLOT_PWR_LED_MASK   0xC
 #define SHPC_SLOT_PWR_LED_SHIFT \
-    (ffs(SHPC_SLOT_PWR_LED_MASK) - 1)
+    ctz32(SHPC_SLOT_PWR_LED_MASK)
 #define SHPC_SLOT_ATTN_LED_MASK  0x30
 #define SHPC_SLOT_ATTN_LED_SHIFT \
-    (ffs(SHPC_SLOT_ATTN_LED_MASK) - 1)
+    ctz32(SHPC_SLOT_ATTN_LED_MASK)
 
 #define SHPC_LED_NO     0x0
 #define SHPC_LED_ON     0x1
@@ -136,7 +136,7 @@ static int roundup_pow_of_two(int x)
 static uint16_t shpc_get_status(SHPCDevice *shpc, int slot, uint16_t msk)
 {
     uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot);
-    return (pci_get_word(status) & msk) >> (ffs(msk) - 1);
+    return (pci_get_word(status) & msk) >> ctz32(msk);
 }
 
 static void shpc_set_status(SHPCDevice *shpc,
@@ -144,7 +144,7 @@ static void shpc_set_status(SHPCDevice *shpc,
 {
     uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot);
     pci_word_test_and_clear_mask(status, msk);
-    pci_word_test_and_set_mask(status, value << (ffs(msk) - 1));
+    pci_word_test_and_set_mask(status, value << ctz32(msk));
 }
 
 static void shpc_interrupt_update(PCIDevice *d)
diff --git a/hw/pci/slotid_cap.c b/hw/pci/slotid_cap.c
index 62f7bae..1c01d34 100644
--- a/hw/pci/slotid_cap.c
+++ b/hw/pci/slotid_cap.c
@@ -3,7 +3,7 @@
 #include "qemu/error-report.h"
 
 #define SLOTID_CAP_LENGTH 4
-#define SLOTID_NSLOTS_SHIFT (ffs(PCI_SID_ESR_NSLOTS) - 1)
+#define SLOTID_NSLOTS_SHIFT ctz32(PCI_SID_ESR_NSLOTS)
 
 int slotid_cap_init(PCIDevice *d, int nslots,
                     uint8_t chassis,
diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
index d49f2b8..a99f7b0 100644
--- a/hw/ppc/ppce500_spin.c
+++ b/hw/ppc/ppce500_spin.c
@@ -74,7 +74,7 @@ static void spin_reset(void *opaque)
 /* Create -kernel TLB entries for BookE, linearly spanning 256MB.  */
 static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
 {
-    return (ffs(size >> 10) - 1) >> 1;
+    return ctz32(size >> 10) >> 1;
 }
 
 static void mmubooke_create_initial_mapping(CPUPPCState *env,
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index bf83b65..5ce39da 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -807,7 +807,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
                                MFI_INFO_LDOPS_READ_POLICY);
     info.max_strips_per_io = cpu_to_le16(s->fw_sge);
     info.stripe_sz_ops.min = 3;
-    info.stripe_sz_ops.max = ffs(MEGASAS_MAX_SECTORS + 1) - 1;
+    info.stripe_sz_ops.max = ctz32(MEGASAS_MAX_SECTORS + 1);
     info.properties.pred_fail_poll_interval = cpu_to_le16(300);
     info.properties.intr_throttle_cnt = cpu_to_le16(16);
     info.properties.intr_throttle_timeout = cpu_to_le16(50);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index be2d9b8..f669d5c 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -568,7 +568,7 @@ static inline void
 pci_set_byte_by_mask(uint8_t *config, uint8_t mask, uint8_t reg)
 {
     uint8_t val = pci_get_byte(config);
-    uint8_t rval = reg << (ffs(mask) - 1);
+    uint8_t rval = reg << ctz32(mask);
     pci_set_byte(config, (~mask & val) | (mask & rval));
 }
 
@@ -576,14 +576,14 @@ static inline uint8_t
 pci_get_byte_by_mask(uint8_t *config, uint8_t mask)
 {
     uint8_t val = pci_get_byte(config);
-    return (val & mask) >> (ffs(mask) - 1);
+    return (val & mask) >> ctz32(mask);
 }
 
 static inline void
 pci_set_word_by_mask(uint8_t *config, uint16_t mask, uint16_t reg)
 {
     uint16_t val = pci_get_word(config);
-    uint16_t rval = reg << (ffs(mask) - 1);
+    uint16_t rval = reg << ctz32(mask);
     pci_set_word(config, (~mask & val) | (mask & rval));
 }
 
@@ -591,14 +591,14 @@ static inline uint16_t
 pci_get_word_by_mask(uint8_t *config, uint16_t mask)
 {
     uint16_t val = pci_get_word(config);
-    return (val & mask) >> (ffs(mask) - 1);
+    return (val & mask) >> ctz32(mask);
 }
 
 static inline void
 pci_set_long_by_mask(uint8_t *config, uint32_t mask, uint32_t reg)
 {
     uint32_t val = pci_get_long(config);
-    uint32_t rval = reg << (ffs(mask) - 1);
+    uint32_t rval = reg << ctz32(mask);
     pci_set_long(config, (~mask & val) | (mask & rval));
 }
 
@@ -606,14 +606,14 @@ static inline uint32_t
 pci_get_long_by_mask(uint8_t *config, uint32_t mask)
 {
     uint32_t val = pci_get_long(config);
-    return (val & mask) >> (ffs(mask) - 1);
+    return (val & mask) >> ctz32(mask);
 }
 
 static inline void
 pci_set_quad_by_mask(uint8_t *config, uint64_t mask, uint64_t reg)
 {
     uint64_t val = pci_get_quad(config);
-    uint64_t rval = reg << (ffs(mask) - 1);
+    uint64_t rval = reg << ctz32(mask);
     pci_set_quad(config, (~mask & val) | (mask & rval));
 }
 
@@ -621,7 +621,7 @@ static inline uint64_t
 pci_get_quad_by_mask(uint8_t *config, uint64_t mask)
 {
     uint64_t val = pci_get_quad(config);
-    return (val & mask) >> (ffs(mask) - 1);
+    return (val & mask) >> ctz32(mask);
 }
 
 PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 652d9fc..85e53e5 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -27,34 +27,34 @@
 
 /* PCI_EXP_FLAGS */
 #define PCI_EXP_FLAGS_VER2              2 /* for now, supports only ver. 2 */
-#define PCI_EXP_FLAGS_IRQ_SHIFT         (ffs(PCI_EXP_FLAGS_IRQ) - 1)
-#define PCI_EXP_FLAGS_TYPE_SHIFT        (ffs(PCI_EXP_FLAGS_TYPE) - 1)
+#define PCI_EXP_FLAGS_IRQ_SHIFT         ctz32(PCI_EXP_FLAGS_IRQ)
+#define PCI_EXP_FLAGS_TYPE_SHIFT        ctz32(PCI_EXP_FLAGS_TYPE)
 
 
 /* PCI_EXP_LINK{CAP, STA} */
 /* link speed */
 #define PCI_EXP_LNK_LS_25               1
 
-#define PCI_EXP_LNK_MLW_SHIFT           (ffs(PCI_EXP_LNKCAP_MLW) - 1)
+#define PCI_EXP_LNK_MLW_SHIFT           ctz32(PCI_EXP_LNKCAP_MLW)
 #define PCI_EXP_LNK_MLW_1               (1 << PCI_EXP_LNK_MLW_SHIFT)
 
 /* PCI_EXP_LINKCAP */
-#define PCI_EXP_LNKCAP_ASPMS_SHIFT      (ffs(PCI_EXP_LNKCAP_ASPMS) - 1)
+#define PCI_EXP_LNKCAP_ASPMS_SHIFT      ctz32(PCI_EXP_LNKCAP_ASPMS)
 #define PCI_EXP_LNKCAP_ASPMS_0S         (1 << PCI_EXP_LNKCAP_ASPMS_SHIFT)
 
-#define PCI_EXP_LNKCAP_PN_SHIFT         (ffs(PCI_EXP_LNKCAP_PN) - 1)
+#define PCI_EXP_LNKCAP_PN_SHIFT         ctz32(PCI_EXP_LNKCAP_PN)
 
-#define PCI_EXP_SLTCAP_PSN_SHIFT        (ffs(PCI_EXP_SLTCAP_PSN) - 1)
+#define PCI_EXP_SLTCAP_PSN_SHIFT        ctz32(PCI_EXP_SLTCAP_PSN)
 
 #define PCI_EXP_SLTCTL_IND_RESERVED     0x0
 #define PCI_EXP_SLTCTL_IND_ON           0x1
 #define PCI_EXP_SLTCTL_IND_BLINK        0x2
 #define PCI_EXP_SLTCTL_IND_OFF          0x3
-#define PCI_EXP_SLTCTL_AIC_SHIFT        (ffs(PCI_EXP_SLTCTL_AIC) - 1)
+#define PCI_EXP_SLTCTL_AIC_SHIFT        ctz32(PCI_EXP_SLTCTL_AIC)
 #define PCI_EXP_SLTCTL_AIC_OFF                          \
     (PCI_EXP_SLTCTL_IND_OFF << PCI_EXP_SLTCTL_AIC_SHIFT)
 
-#define PCI_EXP_SLTCTL_PIC_SHIFT        (ffs(PCI_EXP_SLTCTL_PIC) - 1)
+#define PCI_EXP_SLTCTL_PIC_SHIFT        ctz32(PCI_EXP_SLTCTL_PIC)
 #define PCI_EXP_SLTCTL_PIC_OFF                          \
     (PCI_EXP_SLTCTL_IND_OFF << PCI_EXP_SLTCTL_PIC_SHIFT)
 #define PCI_EXP_SLTCTL_PIC_ON                          \
@@ -109,7 +109,7 @@
 
 #define PCI_ERR_ROOT_IRQ_MAX            32
 #define PCI_ERR_ROOT_IRQ                0xf8000000
-#define PCI_ERR_ROOT_IRQ_SHIFT          (ffs(PCI_ERR_ROOT_IRQ) - 1)
+#define PCI_ERR_ROOT_IRQ_SHIFT          ctz32(PCI_ERR_ROOT_IRQ)
 #define PCI_ERR_ROOT_STATUS_REPORT_MASK (PCI_ERR_ROOT_COR_RCV |         \
                                          PCI_ERR_ROOT_MULTI_COR_RCV |   \
                                          PCI_ERR_ROOT_UNCOR_RCV |       \
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f15815f..c05c503 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2251,8 +2251,8 @@ static inline ppcmas_tlb_t *booke206_get_tlbm(CPUPPCState *env, const int tlbn,
 {
     int r;
     uint32_t ways = booke206_tlb_ways(env, tlbn);
-    int ways_bits = ffs(ways) - 1;
-    int tlb_bits = ffs(booke206_tlb_size(env, tlbn)) - 1;
+    int ways_bits = ctz32(ways);
+    int tlb_bits = ctz32(booke206_tlb_size(env, tlbn));
     int i;
 
     way &= ways - 1;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 5/9] Convert ffs() != 0 callers to ctz32()
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
                   ` (3 preceding siblings ...)
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 4/9] Convert (ffs(val) - 1) to ctz32(val) Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 6/9] sd: convert sd_normal_command() ffs(3) call " Stefan Hajnoczi
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi

There are a number of ffs(3) callers that do roughly:

  bit = ffs(val);
  if (bit) {
      do_something(bit - 1);
  }

This pattern can be converted to ctz32() like this:

  zeroes = ctz32(val);
  if (zeroes != 32) {
      do_something(zeroes);
  }

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/arm/omap1.c              |  6 ++----
 hw/char/virtio-serial-bus.c |  8 ++++----
 hw/gpio/omap_gpio.c         | 13 +++++--------
 hw/i2c/omap_i2c.c           | 10 +++++++---
 hw/intc/allwinner-a10-pic.c |  8 ++++----
 kvm-all.c                   |  8 ++++----
 6 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index abb183c..fbd4695 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -1989,8 +1989,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr,
     case 0x04:	/* OUTPUT_REG */
         diff = (s->outputs ^ value) & ~s->dir;
         s->outputs = value;
-        while ((ln = ffs(diff))) {
-            ln --;
+        while ((ln = ctz32(diff)) != 32) {
             if (s->handler[ln])
                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
             diff &= ~(1 << ln);
@@ -2002,8 +2001,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr,
         s->dir = value;
 
         value = s->outputs & ~s->dir;
-        while ((ln = ffs(diff))) {
-            ln --;
+        while ((ln = ctz32(diff)) != 32) {
             if (s->handler[ln])
                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
             diff &= ~(1 << ln);
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index c86814f..17273a8 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -783,12 +783,12 @@ static uint32_t find_free_port_id(VirtIOSerial *vser)
 
     max_nr_ports = vser->serial.max_virtserial_ports;
     for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        uint32_t map, bit;
+        uint32_t map, zeroes;
 
         map = vser->ports_map[i];
-        bit = ffs(~map);
-        if (bit) {
-            return (bit - 1) + i * 32;
+        zeroes = ctz32(~map);
+        if (zeroes != 32) {
+            return zeroes + i * 32;
         }
     }
     return VIRTIO_CONSOLE_BAD_ID;
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
index 938782a..78c2436 100644
--- a/hw/gpio/omap_gpio.c
+++ b/hw/gpio/omap_gpio.c
@@ -124,8 +124,7 @@ static void omap_gpio_write(void *opaque, hwaddr addr,
     case 0x04:	/* DATA_OUTPUT */
         diff = (s->outputs ^ value) & ~s->dir;
         s->outputs = value;
-        while ((ln = ffs(diff))) {
-            ln --;
+        while ((ln = ctz32(diff)) != 32) {
             if (s->handler[ln])
                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
             diff &= ~(1 << ln);
@@ -137,8 +136,7 @@ static void omap_gpio_write(void *opaque, hwaddr addr,
         s->dir = value;
 
         value = s->outputs & ~s->dir;
-        while ((ln = ffs(diff))) {
-            ln --;
+        while ((ln = ctz32(diff)) != 32) {
             if (s->handler[ln])
                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
             diff &= ~(1 << ln);
@@ -252,8 +250,7 @@ static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
 
     s->outputs ^= diff;
     diff &= ~s->dir;
-    while ((ln = ffs(diff))) {
-        ln --;
+    while ((ln = ctz32(diff)) != 32) {
         qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
         diff &= ~(1 << ln);
     }
@@ -441,8 +438,8 @@ static void omap2_gpio_module_write(void *opaque, hwaddr addr,
         s->dir = value;
 
         value = s->outputs & ~s->dir;
-        while ((ln = ffs(diff))) {
-            diff &= ~(1 <<-- ln);
+        while ((ln = ctz32(diff)) != 32) {
+            diff &= ~(1 << ln);
             qemu_set_irq(s->handler[ln], (value >> ln) & 1);
         }
 
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index d63278d..b6f544a 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -171,9 +171,13 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
     case 0x0c:	/* I2C_IV */
         if (s->revision >= OMAP2_INTR_REV)
             break;
-        ret = ffs(s->stat & s->mask);
-        if (ret)
-            s->stat ^= 1 << (ret - 1);
+        ret = ctz32(s->stat & s->mask);
+        if (ret != 32) {
+            s->stat ^= 1 << ret;
+            ret++;
+        } else {
+            ret = 0;
+        }
         omap_i2c_interrupts_update(s);
         return ret;
 
diff --git a/hw/intc/allwinner-a10-pic.c b/hw/intc/allwinner-a10-pic.c
index de820b9..eed7621 100644
--- a/hw/intc/allwinner-a10-pic.c
+++ b/hw/intc/allwinner-a10-pic.c
@@ -23,7 +23,7 @@
 static void aw_a10_pic_update(AwA10PICState *s)
 {
     uint8_t i;
-    int irq = 0, fiq = 0, pending;
+    int irq = 0, fiq = 0, zeroes;
 
     s->vector = 0;
 
@@ -32,9 +32,9 @@ static void aw_a10_pic_update(AwA10PICState *s)
         fiq |= s->select[i] & s->irq_pending[i] & ~s->mask[i];
 
         if (!s->vector) {
-            pending = ffs(s->irq_pending[i] & ~s->mask[i]);
-            if (pending) {
-                s->vector = (i * 32 + pending - 1) * 4;
+            zeroes = ctz32(s->irq_pending[i] & ~s->mask[i]);
+            if (zeroes != 32) {
+                s->vector = (i * 32 + zeroes) * 4;
             }
         }
     }
diff --git a/kvm-all.c b/kvm-all.c
index 55025cc..003312f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1121,18 +1121,18 @@ static int kvm_irqchip_get_virq(KVMState *s)
 {
     uint32_t *word = s->used_gsi_bitmap;
     int max_words = ALIGN(s->gsi_count, 32) / 32;
-    int i, bit;
+    int i, zeroes;
     bool retry = true;
 
 again:
     /* Return the lowest unused GSI in the bitmap */
     for (i = 0; i < max_words; i++) {
-        bit = ffs(~word[i]);
-        if (!bit) {
+        zeroes = ctz32(~word[i]);
+        if (zeroes == 32) {
             continue;
         }
 
-        return bit - 1 + i * 32;
+        return zeroes + i * 32;
     }
     if (!s->direct_msi && retry) {
         retry = false;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 6/9] sd: convert sd_normal_command() ffs(3) call to ctz32()
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
                   ` (4 preceding siblings ...)
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 5/9] Convert ffs() != 0 callers to ctz32() Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 7/9] omap_intc: convert ffs(3) to ctz32() in omap_inth_sir_update() Stefan Hajnoczi
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Peter Crosthwaite, Markus Armbruster, Stefan Hajnoczi

ffs() cannot be replaced with ctz32() when the argument might be zero,
because ffs(0) returns 0 while ctz32(0) returns 32.

The ffs(3) call in sd_normal_command() is a special case though.  It can
be converted to ctz32() + 1 because the argument is never zero:

  if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
      ~~~~~~~~~~~~~~~
            ^--------------- req.arg cannot be zero

Cc: Markus Armbruster <armbru@redhat.com>
Cc: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/sd/sd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index f955265..8abf0c9 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -796,8 +796,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
             sd->vhs = 0;
 
             /* No response if not exactly one VHS bit is set.  */
-            if (!(req.arg >> 8) || (req.arg >> ffs(req.arg & ~0xff)))
+            if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
                 return sd->spi ? sd_r7 : sd_r0;
+            }
 
             /* Accept.  */
             sd->vhs = req.arg;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 7/9] omap_intc: convert ffs(3) to ctz32() in omap_inth_sir_update()
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
                   ` (5 preceding siblings ...)
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 6/9] sd: convert sd_normal_command() ffs(3) call " Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 8/9] os-win32: drop ffs(3) prototype Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 9/9] checkpatch: complain about ffs(3) calls Stefan Hajnoczi
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi

The loop previously terminated on ffs(0) == 0, now it terminates on
ctz32(0) + 1 == 33.

Other than this change, ffs() is simply replaced with ctz32() + 1.

Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/intc/omap_intc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
index ad3931c..0cf2d2d 100644
--- a/hw/intc/omap_intc.c
+++ b/hw/intc/omap_intc.c
@@ -72,14 +72,15 @@ static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
     for (j = 0; j < s->nbanks; ++j) {
         level = s->bank[j].irqs & ~s->bank[j].mask &
                 (is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq);
-        for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,
-                        level >>= f) {
+        for (f = ctz32(level) + 1, i = f - 1, level >>= f - 1;
+             f != 33;
+             i += f, level >>= f) {
             p = s->bank[j].priority[i];
             if (p <= p_intr) {
                 p_intr = p;
                 sir_intr = 32 * j + i;
             }
-            f = ffs(level >> 1);
+            f = ctz32(level >> 1) + 1;
         }
     }
     s->sir_intr[is_fiq] = sir_intr;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 8/9] os-win32: drop ffs(3) prototype
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
                   ` (6 preceding siblings ...)
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 7/9] omap_intc: convert ffs(3) to ctz32() in omap_inth_sir_update() Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 9/9] checkpatch: complain about ffs(3) calls Stefan Hajnoczi
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi

The lack of ffs(3) in the MinGW headers is a hint that we shouldn't rely
on it.  MinGW 4.9.2 does not make it available for linking when QEMU's
./configure --enable-debug is used (release builds are fine though).

Now that all QEMU code has been switched to ctz32() there is no need for
ffs(3).

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/sysemu/os-win32.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index 9cc9e08..4035c4f 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -72,9 +72,6 @@
 #define sigsetjmp(env, savemask) setjmp(env)
 #define siglongjmp(env, val) longjmp(env, val)
 
-/* Declaration of ffs() is missing in MinGW's strings.h. */
-int ffs(int i);
-
 /* Missing POSIX functions. Don't use MinGW-w64 macros. */
 #undef gmtime_r
 struct tm *gmtime_r(const time_t *timep, struct tm *result);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 9/9] checkpatch: complain about ffs(3) calls
  2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
                   ` (7 preceding siblings ...)
  2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 8/9] os-win32: drop ffs(3) prototype Stefan Hajnoczi
@ 2015-03-17 15:09 ` Stefan Hajnoczi
  8 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-03-17 15:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi

The ffs(3) family of functions is not portable.  MinGW doesn't always
provide the function.

Use ctz32() or ctz64() instead.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 scripts/checkpatch.pl | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 5df61f9..7f0aae9 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2911,6 +2911,17 @@ sub process {
 		if ($rawline =~ /\b(?:Qemu|QEmu)\b/) {
 			WARN("use QEMU instead of Qemu or QEmu\n" . $herecurr);
 		}
+
+# check for non-portable ffs() calls that have portable alternatives in QEMU
+		if ($line =~ /\bffs\(/) {
+			ERROR("use ctz32() instead of ffs()\n" . $herecurr);
+		}
+		if ($line =~ /\bffsl\(/) {
+			ERROR("use ctz32() or ctz64() instead of ffsl()\n" . $herecurr);
+		}
+		if ($line =~ /\bffsll\(/) {
+			ERROR("use ctz64() instead of ffsll()\n" . $herecurr);
+		}
 	}
 
 	# If we have no input at all, then there is nothing to report on
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-03-17 15:32 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-17 15:09 [Qemu-devel] [PATCH v2 0/9] Convert ffs(3) to ctz32() Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 1/9] bt-sdp: fix broken uuids power-of-2 calculation Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 2/9] hw/arm/nseries: convert ffs(3) to ctz32() Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 3/9] uninorth: " Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 4/9] Convert (ffs(val) - 1) to ctz32(val) Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 5/9] Convert ffs() != 0 callers to ctz32() Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 6/9] sd: convert sd_normal_command() ffs(3) call " Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 7/9] omap_intc: convert ffs(3) to ctz32() in omap_inth_sir_update() Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 8/9] os-win32: drop ffs(3) prototype Stefan Hajnoczi
2015-03-17 15:09 ` [Qemu-devel] [PATCH v2 9/9] checkpatch: complain about ffs(3) calls Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.