Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Caml-list] Native compiler support for m68k?

2 views
Skip to first unread message

Richard Zidlicky

unread,
Aug 20, 2003, 8:14:49 AM8/20/03
to caml...@inria.fr
Hi,

I recently got interested into OCaml and thought about
resurrecting the native m68k compiler for m68k, is the old
bitrotten code available somewhere?

Richard

-------------------
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners

Xavier Leroy

unread,
Aug 20, 2003, 11:07:15 AM8/20/03
to Richard Zidlicky, caml...@inria.fr
> I recently got interested into OCaml and thought about
> resurrecting the native m68k compiler for m68k, is the old
> bitrotten code available somewhere?

Yes, you can find it in release 2.04 (the last stable release before
m68k support was deprecated):
http://caml.inria.fr/distrib/ocaml-2.04/ocaml-2.04.tar.gz

Have fun,

- Xavier Leroy

Gleb N. Semenov

unread,
Aug 20, 2003, 1:55:22 PM8/20/03
to caml...@inria.fr
Xavier Leroy wrote:
>
> > I recently got interested into OCaml and thought about
> > resurrecting the native m68k compiler for m68k, is the old
> > bitrotten code available somewhere?
>
> Yes, you can find it in release 2.04 (the last stable release before
> m68k support was deprecated):
> http://caml.inria.fr/distrib/ocaml-2.04/ocaml-2.04.tar.gz
>
> Have fun,
>
> - Xavier Leroy
>

In such case what about ocaml port for palm pilot?

Regards!
GNS


--
Gleb N. Semenov 111621, Muromskaya St. 21, apt. 2, Moscow, Russia
gl...@ahome.ru phone: +7(095)700.0172

Xavier Leroy

unread,
Aug 21, 2003, 11:00:15 AM8/21/03
to gl...@ahome.ru, sem...@jet.msk.su, caml...@inria.fr
> In such case what about ocaml port for palm pilot?

François Rouaix did a Palm port of Caml Light (the "lean and mean"
ancestor of OCaml) a long time ago.

The main problem was that the data segment of a Palm OS program had to
fit in 64K, which is quite tight for Caml Light and definitely not
enough for OCaml. (The remainder of the RAM was either read-only code
blocks, or PalmOS "databases" that must be accessed through system calls.=
)
I don't know if this limitation was lifted in later versions of PalmOS.

Problem number 2 is that text-only apps aren't very usable on a
handheld, so you'd need to interface a large chunk of the GUI toolkit.

- Xavier Leroy

-------------------
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.inr=
ia.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr=

Daniel M. Albro

unread,
Aug 21, 2003, 3:36:26 PM8/21/03
to caml-list

It is doable, though. Look at LispMe (http://www.lispme.de), a
Scheme interpreter for PalmOS. The author got around the memory
problems by finding a way to use databases as the memory space of the
interpreter. Also, the newer ARM-based Palm devices should have fewer
limitations. Moreover, since the LispMe source is available, most
likely any GUI code you wanted could be lifted from that. I'm not
volunteering, of course, but I think it would be doable (I've looked at
the problem in connection with thinking about writing a Prolog
interpreter for PalmOS).

- Dan Albro

Xavier Leroy wrote:

>>In such case what about ocaml port for palm pilot?
>
>
> François Rouaix did a Palm port of Caml Light (the "lean and mean"
> ancestor of OCaml) a long time ago.
>
> The main problem was that the data segment of a Palm OS program had to
> fit in 64K, which is quite tight for Caml Light and definitely not
> enough for OCaml. (The remainder of the RAM was either read-only code

> blocks, or PalmOS "databases" that must be accessed through system call=
s.)


> I don't know if this limitation was lifted in later versions of PalmOS.
>
> Problem number 2 is that text-only apps aren't very usable on a
> handheld, so you'd need to interface a large chunk of the GUI toolkit.
>
> - Xavier Leroy
>
> -------------------

> To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.i=
nria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.=
fr/FAQ/

Richard Zidlicky

unread,
Aug 24, 2003, 4:11:40 PM8/24/03
to Xavier Leroy, sven....@wanadoo.fr, caml...@inria.fr
On Wed, Aug 20, 2003 at 02:32:38PM +0200, Xavier Leroy wrote:
> > I recently got interested into OCaml and thought about
> > resurrecting the native m68k compiler for m68k, is the old
> > bitrotten code available somewhere?
>
> Yes, you can find it in release 2.04 (the last stable release before
> m68k support was deprecated):
> http://caml.inria.fr/distrib/ocaml-2.04/ocaml-2.04.tar.gz

ok, I got 2.0.4 working for m68k-linux, not very hard.
Speed is quite impressive, fib is faster than gcc code ?!

One thing that I need to verify is the interaction of the native
compiler and the strange m68k-linux ABI which is different from
SUN or BSD. The unusual part of m68k-linux ABI is that functions
returning pointer return their value in register a0, while integer
types are retuned in d0.

How does the code generated by the native compiler interact
with c-ABI functions?

Richard

Xavier Leroy

unread,
Aug 26, 2003, 9:48:12 AM8/26/03
to Richard Zidlicky, sven....@wanadoo.fr, caml...@inria.fr
> ok, I got 2.0.4 working for m68k-linux, not very hard.
> Speed is quite impressive, fib is faster than gcc code ?!

Sure: gcc passes all parameters on the stack, ocamlopt passes the
first ones in registers.

> One thing that I need to verify is the interaction of the native
> compiler and the strange m68k-linux ABI which is different from
> SUN or BSD. The unusual part of m68k-linux ABI is that functions
> returning pointer return their value in register a0, while integer
> types are retuned in d0.
>
> How does the code generated by the native compiler interact
> with c-ABI functions?

C functions that can be called by Caml code must be declared with
return type "value", which is "long". So, the C compiler will arrange
for the result to be in D0, which is where ocamlopt-generated code
expects to find it.

- Xavier Leroy

Richard Zidlicky

unread,
Aug 30, 2003, 6:25:20 AM8/30/03
to Xavier Leroy, caml...@inria.fr
Hi,

a short update, adapting to 3.06 was not very difficult but
somehow triggered a few bugs in the code.

Simple examples like "fib" work fine, ocamlc.opt crashes in
parsing/linenum.ml so I am slowly adding debugging support to
code generation to find out details.

One of the bugs had to do with register reloading, pseudos
that was allocated hard register in previous version ended
up as stack slots (somehow a0 often isn't used for allocation
where it previously was). Emitting code didn't take this
possibility into account in some places generating assembly
code.. most likely the register constraints aren't good enough.

Does anyone have a test suite? What kind of problems had other
architectures between 2.04 and 3.06?

Richard

Richard Zidlicky

unread,
Sep 5, 2003, 6:04:33 PM9/5/03
to Xavier Leroy, caml...@inria.fr
Hi,

I have had some progress recently, ocamlc.opt works and
even produces working code now.

The remaining problem is a bit tougher though, not quite
deterministic it appears: running
./ocamlopt.opt -I stdlib fib.ml
segfaults in either
Queue__take_87
Cmmgen__transl_all_functions_1418
*or*
Reload__fundecl_338
Asmgen__regalloc_175

80% of the time it crashes in fundecl.

What could be the source of such indeterministic behaviour?
gc?

Richard

Byron Hale

unread,
Sep 5, 2003, 8:55:13 PM9/5/03
to caml...@inria.fr
Processor overheating could cause random behavior. Apparently some
processors operate marginally and will overheat on long, tight loops.

Byron

At 11:58 PM 9/5/2003 +0200, you wrote:
>Hi,
>
>I have had some progress recently, ocamlc.opt works and
>even produces working code now.
>
>The remaining problem is a bit tougher though, not quite
>deterministic it appears: running
> ./ocamlopt.opt -I stdlib fib.ml
>segfaults in either
> Queue__take_87
> Cmmgen__transl_all_functions_1418
>*or*
> Reload__fundecl_338
> Asmgen__regalloc_175
>
>80% of the time it crashes in fundecl.
>
>What could be the source of such indeterministic behaviour?
>gc?
>
>Richard

Benjamin Geer

unread,
Sep 6, 2003, 6:03:37 AM9/6/03
to Richard Zidlicky, caml...@inria.fr
Richard Zidlicky wrote:
> What could be the source of such indeterministic behaviour?

There's some useful information here on how to find out whether you have
a hardware problem:

http://www-106.ibm.com/developerworks/library/l-hw1/
http://www.bitwizard.nl/sig11/

Ben

David MENTRE

unread,
Sep 7, 2003, 9:42:33 AM9/7/03
to Richard Zidlicky, caml...@inria.fr
Richard Zidlicky <r...@linux-m68k.org> writes:

> What could be the source of such indeterministic behaviour?
> gc?

I would guess it is related to GC or bad memory allocation (in case of C
code).

As far as I remember, OCaml GC is using usual libc malloc and free, so
you could activate libc checks to help find the bug (see mcheck(), there
is also an environment variable I don't remember). You could also take a
look at libefence.

Other things that might help is to zeroing data structures before
releasing them to free(). Sometimes, you reuse a datastructure that is
has been freed.

To make the port, what have you modified? Only Caml code or also C code?

My .2 euros,
Yours,
d.
--
David Mentré <dme...@linux-france.org>
http://www.linux-france.org/~dmentre/david-mentre-public-key.asc
GnuPG key fingerprint: A7CD 7357 3EC4 1163 745B 7FD3 FB3E AD7C 2A18 BE9=
E

-------------------
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.inr=
ia.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr=

Damien Doligez

unread,
Sep 8, 2003, 5:54:24 AM9/8/03
to caml...@inria.fr
On Friday, September 5, 2003, at 11:58 PM, Richard Zidlicky wrote:

> What could be the source of such indeterministic behaviour?

There is at least one source of nondeterminism in the compiler:
the generation of temporary file names. And it can be influenced
by the contents of the /tmp directory, especially when a previous
compiler run has crashed and left its temporary files there...
There may be other sources of nondeterminism, but I can't think
of any off the top of my head.

> gc?

No, the GC is completely deterministic (thank God).

-- Damien

Christophe Raffalli

unread,
Sep 8, 2003, 4:43:15 PM9/8/03
to Damien Doligez, caml...@inria.fr

in the following kind code :

let l = ... a function building a long list ... in
let l' = List.map fn l in (* or fold or anything similar *)
... no more reference to l ...

Once the beginning of l has been read to compute l' (assuming List.map
starts from the beginning of l) is the GC able to collect the beginning
of l ?

If not how to write the code to ensure this behaviour of the GC ?


--
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christoph...@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI
---------------------------------------------
IMPORTANT: this mail is signed using PGP/MIME
At least Enigmail/Mozilla, mutt or evolution
can check this signature
---------------------------------------------

Pierre Weis

unread,
Sep 9, 2003, 5:34:31 AM9/9/03
to Christophe Raffalli, Damien....@inria.fr, caml...@inria.fr
> in the following kind code :
>
> let l = ... a function building a long list ... in
> let l' = List.map fn l in (* or fold or anything similar *)
> ... no more reference to l ...
>
> Once the beginning of l has been read to compute l' (assuming List.map
> starts from the beginning of l) is the GC able to collect the beginning
> of l ?

No it cannot since, AFAIK, l is not freed (i.e. assigned to 0) into
the stack (or local environment) before you leave the block where your
code occurs (normally the activation block of the function where it
appears in).

> If not how to write the code to ensure this behaviour of the GC ?
>

> Christophe Raffalli

Do not use let bindings, write function applications or function
compositions instead.
(Instead of writing
let l1 = f l0 in
let l2 = g l1 in
h l2
write
let i l = h (g (f l)) in
i l0)

Alternatively, use explicit references to lists and free them
explicitely in your code ! This is tractable when the flow of control
of the code is simple enough (for instance in the case of a
clear succession of passes where data from previous passes are clearly
unused in the following steps).

Hope this helps,

Pierre Weis

INRIA, Projet Cristal, Pierr...@inria.fr, http://pauillac.inria.fr/~weis/

Christophe Raffalli

unread,
Sep 9, 2003, 6:42:39 AM9/9/03
to Pierre Weis, Damien....@inria.fr, caml...@inria.fr
Pierre Weis wrote:
>>in the following kind code :
>>
>>let l = ... a function building a long list ... in
>>let l' = List.map fn l in (* or fold or anything similar *)
>>... no more reference to l ...
>>
>>Once the beginning of l has been read to compute l' (assuming List.map
>>starts from the beginning of l) is the GC able to collect the beginning
>>of l ?

And

let l' =


let l = ... a function building a long list ... in

List.map fn l
in

should work then (it is simpler to read than composition) ?

Xavier Leroy

unread,
Sep 11, 2003, 11:30:58 AM9/11/03
to Christophe Raffalli, caml...@inria.fr
> in the following kind code :
>
> let l = ... a function building a long list ... in
> let l' = List.map fn l in (* or fold or anything similar *)
> ... no more reference to l ...
>
> Once the beginning of l has been read to compute l' (assuming List.map
> starts from the beginning of l) is the GC able to collect the beginning
> of l ?

Short answer: with ocamlc, no. With ocamlopt, yes.

Longer answer: in the bytecoded implementation, every value in the VM
stack is a GC root. "let x = e in e'" pushes the value of e on the
stack just before evaluating e', and pops it at the end of e'. So,
the value of e remains a live GC root throughout the evaluation of e'.

In the native-code implementation, not all machine stack entries are
GC roots, but only the stack slots that hold a variable of type
address that is live at the point where the GC is called. ("Live"
here is in the sense of liveness analysis of local variables.)
In your example, "l" is not live across the call to "List.map fn l".

> If not how to write the code to ensure this behaviour of the GC ?

As other mentioned, removing the outer "let" gives the desired GC
behavior even in bytecode:

List.map fn l (... list builder ...)

In the OCaml sources, you can find this strange-looking idiom:

let (++) x f = f x

Pparse.file ppf inputfile Parse.implementation ast_impl_magic_number
++ print_if ppf Clflags.dump_parsetree Printast.implementation
++ Typemod.type_implementation sourcefile prefixname modulename env
++ Translmod.transl_implementation modulename
++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
++ Simplif.simplify_lambda
++ print_if ppf Clflags.dump_lambda Printlambda.lambda
++ Bytegen.compile_implementation modulename
++ print_if ppf Clflags.dump_instr Printinstr.instrlist
++ Emitcode.to_file oc modulename;

which is a nicer way of writing

Emitcode.to_file oc modulename
(print_if ....
(Bytegen.compile_implementation ...
(print_if ...
(...
))))

and gives better GC behavior than the obvious:

let x1 = Pparse.file ppf inputfile Parse.implementation ast_impl_magic_number in
let x2 = print_if ppf Clflags.dump_parsetree Printast.implementation p x1 in
let x3 = Typemod.type_implementation sourcefile prefixname modulename env x2 in
...

- Xavier Leroy

0 new messages