[Skiboot] [RFC, PATCH] libflash: Provide an internal parity implementation, to remove libgcc dependency

Jeremy Kerr jk at ozlabs.org
Mon Feb 23 19:54:01 AEDT 2015


In commit 8f5b8616, we introduced a dependency on libgcc, for the
__builtin_parityl() function in commit 6cfaa3ba.

However, if we're building with a biarch compiler, we may not have a
libgcc available.

This commit removes the __builtin_parityl() call, and replaces with the
equivalent instructions, and removes the dependency on libgcc.

Although this is untested, I have confirmed that the __builtin_parityl()
functions emits the same instructions (on power7 and power8, with
gcc-4.9) as we're using in the parity() function.

Signed-off-by: Jeremy Kerr <jk at ozlabs.org>

---
 Makefile.main  |    5 ++---
 libflash/ecc.c |   14 +++++++++++++-
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/Makefile.main b/Makefile.main
index 665baf4..b5376fc 100644
--- a/Makefile.main
+++ b/Makefile.main
@@ -120,7 +120,6 @@ OBJS += $(LIBPORE)
 endif
 OBJS += $(LIBC) $(CCAN) $(DEVSRC_OBJ)
 OBJS_NO_VER = $(OBJS)
-EXTRA_LIBS = -Wl,-lgcc
 ALL_OBJS = $(OBJS) version.o
 
 ALL_OBJS_1 = $(ALL_OBJS) asm/dummy_map.o
@@ -130,12 +129,12 @@ $(TARGET).lid: $(TARGET).elf
 	$(call Q,OBJCOPY, $(OBJCOPY) -O binary -S $^ $@, $@)
 
 $(TARGET).tmp.elf: $(ALL_OBJS_1) $(TARGET).lds $(KERNEL)
-	$(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_1) $(EXTRA_LIBS) -o $@, $@)
+	$(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_1) -o $@, $@)
 
 asm/real_map.o : $(TARGET).tmp.map
 
 $(TARGET).elf: $(ALL_OBJS_2) $(TARGET).lds $(KERNEL)
-	$(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_2) $(EXTRA_LIBS) -o $@, $@)
+	$(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_2) -o $@, $@)
 
 $(SUBDIRS):
 	$(call Q,MKDIR,mkdir $@, $@)
diff --git a/libflash/ecc.c b/libflash/ecc.c
index 9293743..3d94594 100644
--- a/libflash/ecc.c
+++ b/libflash/ecc.c
@@ -88,6 +88,18 @@ static uint8_t syndromematrix[] = {
         UE, UE, UE, UE,  4, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE,
 };
 
+static uint8_t parity(uint64_t data)
+{
+	uint8_t p;
+
+	asm volatile(
+		"popcntb %1,%0\n"
+		"prtyd   %1,%1\n"
+		: "=r"(p) : "r"(data));
+
+	return p;
+}
+
 /**
  * Create the ECC field corresponding to a 8-byte data field
  *
@@ -100,7 +112,7 @@ static uint8_t eccgenerate(uint64_t data)
         uint8_t result = 0;
 
         for (i = 0; i < 8; i++)
-		result |= __builtin_parityl(eccmatrix[i] & data) << i;
+		result |= parity(eccmatrix[i] & data) << i;
 
         return result;
 }


More information about the Skiboot mailing list