From owner-freebsd-arch@FreeBSD.ORG Tue Feb 14 09:58:10 2006 Return-Path: X-Original-To: arch@freebsd.org Delivered-To: freebsd-arch@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C4BEB16A420; Tue, 14 Feb 2006 09:58:10 +0000 (GMT) (envelope-from keramida@ceid.upatras.gr) Received: from igloo.linux.gr (igloo.linux.gr [62.1.205.36]) by mx1.FreeBSD.org (Postfix) with ESMTP id 19CDF43D49; Tue, 14 Feb 2006 09:58:08 +0000 (GMT) (envelope-from keramida@ceid.upatras.gr) Received: from flame.pc (aris.bedc.ondsl.gr [62.103.39.226]) (authenticated bits=128) by igloo.linux.gr (8.13.5/8.13.5/Debian-3) with ESMTP id k1E9vSwG002619 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 14 Feb 2006 11:57:32 +0200 Received: from flame.pc (flame [127.0.0.1]) by flame.pc (8.13.4/8.13.4) with ESMTP id k1E9vKkc001451; Tue, 14 Feb 2006 11:57:20 +0200 (EET) (envelope-from keramida@ceid.upatras.gr) Received: (from keramida@localhost) by flame.pc (8.13.4/8.13.4/Submit) id k1E9vI2k001450; Tue, 14 Feb 2006 11:57:18 +0200 (EET) (envelope-from keramida@ceid.upatras.gr) Date: Tue, 14 Feb 2006 11:57:18 +0200 From: Giorgos Keramidas To: "M. Warner Losh" Message-ID: <20060214095718.GC967@flame.pc> References: <43F04494.4030900@freebsd.org> <20060213.094336.118368793.imp@bsdimp.com> <20060214083530.K22079@epsplex.bde.org> <20060213.210510.89039143.imp@bsdimp.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060213.210510.89039143.imp@bsdimp.com> X-Hellug-MailScanner: Found to be clean X-Hellug-MailScanner-SpamCheck: not spam, SpamAssassin (score=-3.34, required 5, autolearn=not spam, ALL_TRUSTED -1.80, AWL 0.86, BAYES_00 -2.60, DNS_FROM_RFC_ABUSE 0.20) X-Hellug-MailScanner-From: keramida@ceid.upatras.gr Cc: arch@freebsd.org, stefanf@freebsd.org, cperciva@freebsd.org, des@des.no Subject: Re: [releng_6 tinderbox] failure on sparc64/sparc64 X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Feb 2006 09:58:11 -0000 On 2006-02-13 21:05, "M. Warner Losh" wrote: > In message: <20060214083530.K22079@epsplex.bde.org> > Bruce Evans writes: > : > It won't matter given how I'm going to fix this problem... > : > : Why not just access the object as an array of unsigned chars as someone > : wrote? Write it out 1 unsigned char at a time for the simple version. > : This avoids the complications. > > Because it has to be fed to the hardware 4 bytes at a time. That's still possible, using an intermediate unsigned char buffer, or if that's too much to ask (i.e. because keeping a duplicate copy of the 'foo' structure is a waste of memory), using a 4-byte scratch buffer and iterating over an (unsigned char *) pointer through `foo'. I think, that given a `foo' struct defined as: struct foo { uint32_t a; uint16_t b; uint16_t c; uint8_t d; uint8_t e; }; You are always allowed to use an (unsigned char *) pointer to iterate through its bytes, as in: #include #include #include #include struct foo { uint32_t a; uint16_t b; uint16_t c; uint8_t d; uint8_t e; }; int main(void) { struct foo foo; size_t k; memset(&foo, 0, sizeof(foo)); foo.a = 1; foo.b = 2; foo.c = 3; foo.d = 4; foo.e = 5; for (k = 0; k < sizeof(foo); k++) printf("%s%02x", k ? " " : "", *((unsigned char *)&foo + k)); putchar('\n'); return EXIT_SUCCESS; } This prints padding bytes correctly here, even with: $ CFLAGS='-std=c99 -pedantic' make WARNS=6 foo.c [...] $ ./foo 01 00 00 00 02 00 03 00 04 05 00 00 $ Then, if there's a 4-byte constraint, a single uint32_t can be used as a 'buffer': #include #include #include #include struct foo { uint32_t a; uint16_t b; uint16_t c; uint8_t d; uint8_t e; }; int main(void) { struct foo foo; size_t k, nbytes; uint32_t x; memset(&foo, 0, sizeof(foo)); foo.a = 1; foo.b = 2; foo.c = 3; foo.d = 4; foo.e = 5; for (k = 0; k < sizeof(foo); k++) printf("%s%02x", k ? " " : "", *((unsigned char *)&foo + k)); putchar('\n'); for (k = 0; k < sizeof(foo); k += 4) { nbytes = sizeof(uint32_t); if (sizeof(foo) - k < nbytes) { nbytes = sizeof(foo) - k; memset(&x, 0, sizeof(x)); } memcpy(&x, ((unsigned char *)&foo + k), nbytes); printf("%s%zdb/%08x", k ? " " : "", nbytes, x); } putchar('\n'); return EXIT_SUCCESS; } and it seems to work as expected here on a little-endian machine: $ ./foo 01 00 00 00 02 00 03 00 04 05 00 00 4b/00000001 4b/00030002 4b/00000504 This probably works much better than trying to cast the original into an array of uint32_t objects too :)