[Openmcl-devel] CCL on a Raspberry pi

Gary Byers gb at clozure.com
Fri Jul 27 08:03:42 PDT 2012

On Sat, 21 Jul 2012, Gary Byers wrote:

> Late-breaking news:

That was -so- r14523 ...  As of r14525 in the trunk, CCL should run under
Linux on ARMv6 machines (like the Raspberry Pi) as well as ARMv7-a.  Thanks
to Ron Garrett for letting me use his Raspberry Pi for testing.)

- the other day, I said that I was leaning towards spinning off a separate
   ARMv6-specific version.  Sanity prevailed, and it seemed to make more sense
   to have a single ARM version that ran on ARMv6 and ARMv7(a) machines and
   to simply refrain from using ARMv7-specific instructions in most cases
   (and to only use them conditionally in other cases.)

- the FASL file version changed (for ARM), as did the version number which
   controls kernel/image compatibility.  If you're updating an existing svn
   tree, be sure that you pick up the new binaries (by using the "tf" conflict
   resolution option if possible, or by doing "svn revert" otherwise.)  Failure
   to observe this may cause bootstrapping problems and complaining about that
   will result in a US$4 fine.

- the lisp kernel was built on a Debian "squeeze" system and my model of things
   is that it should run on ARMv6 systems as well as ARMv7 (but see below about
   "armhf" issues.)  For a number of reasons, the ARM toolchain world is and has
   been a moving target and I can't be sure that something I build here will run
   on all distributions that it "should" run on; if it doesn't run on yours, the
   first thing to try is to rebuild the kernel locally.

- traditionally, ARM Linux systems have used a C ABI in which floating-point
   arguments were passed in general-purpose registers or stack locations and
   floating-point results were returned in general-purpose registers;
   this convention allowed the same C code to "work" regardless of whether
   or not floating-point hardware was present.  This was known as the "soft
   float ABI".

   Linux distributions are moving toward (or have moved to) a newer ABI in which
   the presence of an FPU is assumed and in which many FP arguments and
   FP results are passed/returned in floating-point registers; since transferring
   FP values to/from the stack and GPRs can be expensive, this ABI often yields
   substantial performance gains for floating-point-intensive C code.  This is
   known as the "hard float ABI" and the term "armhf" is often used to indicate
   support for that ABI.

   The two ABI's can't be mixed: object and dynamic files compiled for one
   ABI can't be linked with files compiled for the other.  Some distributions
   are still exclusively soft-float, some are exclusively hard-float, and
   some (Ubuntu 12.04, for example) can be made to support both ABIs (and provide
   two incompatible sets of system libraries.)

   From CCL's point of view, this (only) affects how foreign function calls and
   callbacks that have floating-point arguments and/or results are implemented.
   Since it's likely that both ABIs will coexist (in some sense or another) for
   at least the next few years, we generally want to support both ABIs
   as transparently as possible.  This is partially implemented in the trunk.

   The CCL kernel can be built as either a soft- or hard-float application (despite
   the fact that the kernel itself barely does any floating-point arithmetic).
   The file ccl/lisp-kernel/linuxarm/float_abi.mk is included in the linuxarm
   kernel Makefile.  It defines FLOAT_ABI to be one of "softfp" or "hard", with
   the other value commented out; as distributed, the file defines FLOAT_ABI
   to be "softfp".  If you want to build a "hard-float" version of the CCL
   kernel, it's necessary to change the defined value of FLOAT_ABI in this
   file and then do:

$ cd lisp-kernel/linuxarm
$ make clean                    # delete existing .o files
$ make

   and that should produce a ccl/armcl executable that uses (and can use libraries
   that use) the hard-float ABI.

   How the CCL kernel is built affects the calling convention that libraries that
   the CCL kernel are linked against use.  Lisp code is only affected by the
   float-abi change when calling or being called by C code and when FP arguments/
   results are involved.  There isn't much such code in CCL itself (things like SIN
   may be partially implemented by calling #_sin or #_sinf and that's true for
   10-20 other math functions) and even for applications that make heavy use of
   FP-intensive foreign code (OpenGL might be one case), the actual FFI code is likely
   to be a very small part of the entire heap image; it wouldn't make sense to have
   separate hard- and soft-float CCL images; the plan is to instead try to support
   both ABIs (at least until the soft-float ABI fades away.)

   For calls to foreign functions where float args/results are involved, we can
   basically compile both the soft- and hard-float case and select one of them
   at runtime.  (#_sin x) becomes something like:

   (external-call "sin" :double-float x :double-float)

   and that becomes something like:

   (if *hard-float-abi-in-use* ; based on how the lisp kernel was built
     (external-call-using-hard-float-abi "sin" ...)
     (external-call-using-soft-float-abi "sin" ...))

   That's implemented in the trunk and it seems to work well.  (I think that
   there are still some cases where calls involving more than 16 single-floats
   or more than 8 double-floats aren't handled correctly, but otherwise ...)

   That's the good news.  The bad news is that something analogous has to
   happen for callbacks involving floats, and the necessary changes haven't
   been made yet.  (So callbacks involving floats will only behave correctly
   when the soft-float ABI is in effect.)

None of the above (the hard vs soft-float ABI isssues) have anything to do
with ARMv7 vs ARMv6.  Both architectures can support either ABI.

More information about the Openmcl-devel mailing list