From owner-freebsd-sparc64@FreeBSD.ORG Sat Mar 1 01:16:50 2014 Return-Path: Delivered-To: freebsd-sparc64@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D5137834; Sat, 1 Mar 2014 01:16:50 +0000 (UTC) Received: from h2.funkthat.com (gate2.funkthat.com [208.87.223.18]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 817BC1D75; Sat, 1 Mar 2014 01:16:50 +0000 (UTC) Received: from h2.funkthat.com (localhost [127.0.0.1]) by h2.funkthat.com (8.14.3/8.14.3) with ESMTP id s211GiuG083921 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 28 Feb 2014 17:16:44 -0800 (PST) (envelope-from jmg@h2.funkthat.com) Received: (from jmg@localhost) by h2.funkthat.com (8.14.3/8.14.3/Submit) id s211GhWN083920; Fri, 28 Feb 2014 17:16:43 -0800 (PST) (envelope-from jmg) Date: Fri, 28 Feb 2014 17:16:43 -0800 From: John-Mark Gurney To: Dimitry Andric , Craig Butler Subject: Re: HEADS UP: sparc64 backend for llvm/clang imported Message-ID: <20140301011643.GV47921@funkthat.com> Mail-Followup-To: Dimitry Andric , Craig Butler , freebsd-current@freebsd.org, freebsd-sparc64@freebsd.org, rdivacky@FreeBSD.org References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="wRRV7LY7NUeQGEoC" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.3i X-Operating-System: FreeBSD 7.2-RELEASE i386 X-PGP-Fingerprint: 54BA 873B 6515 3F10 9E88 9322 9CB1 8F74 6D3F A396 X-Files: The truth is out there X-URL: http://resnet.uoregon.edu/~gurney_j/ X-Resume: http://resnet.uoregon.edu/~gurney_j/resume.html X-TipJar: bitcoin:13Qmb6AeTgQecazTWph4XasEsP7nGRbAPE X-to-the-FBI-CIA-and-NSA: HI! HOW YA DOIN? can i haz chizburger? X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.2 (h2.funkthat.com [127.0.0.1]); Fri, 28 Feb 2014 17:16:44 -0800 (PST) Cc: rdivacky@freebsd.org, freebsd-current@freebsd.org, freebsd-sparc64@freebsd.org X-BeenThere: freebsd-sparc64@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Porting FreeBSD to the Sparc List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 01 Mar 2014 01:16:50 -0000 --wRRV7LY7NUeQGEoC Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Dimitry Andric wrote this message on Fri, Feb 28, 2014 at 20:22 +0100: > In r262613 I have merged the clang-sparc64 branch back to head. This > imports an updated sparc64 backend for llvm and clang, allowing clang to > bootstrap itself on sparc64, and to completely build world. To be able > to build the GENERIC kernel, there is still one patch to be finalized, > see below. > > If you have any sparc64 hardware, and are not afraid to encounter rough > edges, please try out building and running your system with clang. To > do so, update to at least r262613, and enable the following options in > e.g. src.conf, or in your build environment: > > WITH_CLANG=y > WITH_CLANG_IS_CC=y > WITH_LIBCPLUSPLUS=y (optional) > > Alternatively, if you would rather keep gcc as /usr/bin/cc for the > moment, build world using just WITH_CLANG, enabling clang to be built > (by gcc) and installed. After installworld, you can then set CC=clang, > CXX=clang++ and CPP=clang-cpp for building another world. > > For building the sparc64 kernel, there is one open issue left, which is > that sys/sparc64/include/pcpu.h uses global register variables, and this > is not supported by clang. A preliminary patch for this is attached, > but it may or may not blow up your system, please beware! > > The patch changes the pcpu and curpcb global register variables into > inline functions, similar to what is done on other architectures. > However, the current approach is not optimal, and the emitted code is > slightly different from what gcc outputs. Any improvements to this > patch are greatly appreciated! > > Last but not least, thanks go out to Roman Divacky for his work with > llvm/clang upstream in getting the sparc64 backend into shape. Ok, I have a new pcpu patch to try. I have only compile tested it. It is available here: https://www.funkthat.com/~jmg/sparc64.pcpu.patch I've also attached it. Craig, do you mind testing it? This patch also removes curpcb as it appears to not be used by any sparc64 C code. A GENERIC kernel compiles fine, and fxr only turns up curpcb used in machdep code, and no references to it under sparc64. This is not a proper solution in that it can mean counters/stats can be copied/moved to other cpus overwriting the previous values if a race happens... We use PCPU_SET(mem, PCPU_GET(mem) + val) for PCPU_ADD, not great, but it's no worse than what we were previously using.. Until we get a proper fix which involves mapping all the cpu's PCPU data on all CPUs, this will have to sufice.. This patch is based upon, I believe, a patch from Marius and possibly modified by rdivacky. Thanks for testing.. -- John-Mark Gurney Voice: +1 415 225 5579 "All that I will do, has been done, All that I have, has not." --wRRV7LY7NUeQGEoC Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="sparc64.pcpu.patch" Index: pcpu.h =================================================================== --- pcpu.h (revision 261863) +++ pcpu.h (working copy) @@ -70,11 +70,82 @@ struct pcb; struct pcpu; -register struct pcb *curpcb __asm__(__XSTRING(PCB_REG)); -register struct pcpu *pcpup __asm__(__XSTRING(PCPU_REG)); +/* + * Evaluates to the byte offset of the per-cpu variable name. + */ +#define __pcpu_offset(name) \ + __offsetof(struct pcpu, name) -#define PCPU_GET(member) (pcpup->pc_ ## member) +/* + * Evaluates to the type of the per-cpu variable name. + */ +#define __pcpu_type(name) \ + __typeof(((struct pcpu *)0)->name) +#define __PCPU_GET(name) __extension__ ({ \ + __pcpu_type(name) __res; \ + \ + switch (sizeof(__res)) { \ + case 1: \ + __asm __volatile("ldub [%" __XSTRING(PCPU_REG) "+ %1], %0" \ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + case 2: \ + __asm __volatile("lduh [%" __XSTRING(PCPU_REG) "+ %1], %0"\ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + case 4: \ + __asm __volatile("ld [%" __XSTRING(PCPU_REG) "+ %1], %0"\ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + case 8: \ + __asm __volatile("ldd [%" __XSTRING(PCPU_REG) "+ %1], %0"\ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + default: \ + /* XXX - what to put here? */; \ + } \ + __res; \ + }) + +#define __PCPU_SET(name, val) __extension__ ({ \ + __pcpu_type(name) __val; \ + \ + __val = (val); \ + switch (sizeof(__val)) { \ + case 1: \ + __asm __volatile("stub %0, [%" __XSTRING(PCPU_REG) "+ %1]" \ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + case 2: \ + __asm __volatile("stuh %0, [%" __XSTRING(PCPU_REG) "+ %1]"\ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + case 4: \ + __asm __volatile("st %0, [%" __XSTRING(PCPU_REG) "+ %1]"\ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + case 8: \ + __asm __volatile("std %0, [%" __XSTRING(PCPU_REG) "+ %1]"\ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + default: \ + /* XXX - what to put here? */; \ + } \ + __val; \ + }) + +#define __PCPU_PTR(name) __extension__ ({ \ + __pcpu_type(name) *__p; \ + struct pcpu *__pcpu; \ + \ + __asm __volatile("mov %" __XSTRING(PCPU_REG) ", %0" \ + : "=r" (__pcpu)); \ + __p = &__pcpu->name; \ + \ + __p; \ +}) + static __inline __pure2 struct thread * __curthread(void) { @@ -89,10 +160,11 @@ * XXX The implementation of this operation should be made atomic * with respect to preemption. */ -#define PCPU_ADD(member, value) (pcpup->pc_ ## member += (value)) +#define PCPU_GET(member) __PCPU_GET(pc_ ## member) +#define PCPU_ADD(member, value) PCPU_SET(member, PCPU_GET(member) + (value)) #define PCPU_INC(member) PCPU_ADD(member, 1) -#define PCPU_PTR(member) (&pcpup->pc_ ## member) -#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value)) +#define PCPU_PTR(member) __PCPU_PTR(pc_ ## member) +#define PCPU_SET(member,value) __PCPU_SET(pc_ ## member, (value)) #endif /* _KERNEL */ --wRRV7LY7NUeQGEoC--