RE: GHC FFI Return Type Bug

Sigbjorn Am confused by your answer. | > char fooble ( ... ) | > { | > return 'z'; | > } | > | > on an x86, 'z' will be returned at the lowest 8 bits in %eax. What I | > don't know is, is the C compiler obliged to clear the upper 24 bits of | > %eax, or does that onus fall on the callee? | | Yes, the callee is required to narrow <expr> in 'return | <expr>;' to fit that of the specified return type -- see 9.8 | of Harbison and Steele. So, a C compiler that cause f() to | return 0x7fffffff for the following, | | unsigned char g() | { | return 0x7fffffff; | } | | unsigned int f() | { | return g(); | } | | is in the wrong. [Notice that narrowing for signed integral | types is undefined in ISO C, but most current-day compilers | implement such narrowing ops the same way, i.e., by masking | off excess bits.] So we don't need to worry about doing the masking on the Haskell side, right? | > Also, I don't even know where to look for the specification | of details | > of the C calling conventions. Anyone got a clue? | > | | Harbison & Steele Chapters 6 and 9 cover the conversion rules | that apply to functions (and other expressions). As you no | doubt already know, lower-level details are the domain of a | platform's ABI. | | Sounds to me like unboxed sized Words and Ints is the | (unavoidable) way to go. Why would we need these unless we *did* need to worry about masking on the Haskell side? Pls clarify. J

"Julian Seward (Intl Vendor)"
| > char fooble ( ... ) | > { | > return 'z'; | > } | > | > on an x86, 'z' will be returned at the lowest 8 bits in %eax. What I
| > don't know is, is the C compiler obliged to clear the upper 24 bits of | > %eax, or does that onus fall on the callee? | | Yes, the callee is required to narrow <expr> in 'return | <expr>;' to fit that of the specified return type -- see 9.8 | of Harbison and Steele. |
...
So we don't need to worry about doing the masking on the Haskell side, right?
Yes, that's been my understanding. But, as Carl Witty rightly points out, a distinction can be made between narrowing down the result value and the transmission of the narrowed result back to the caller. Carl's example doesn't fully convince me though, since the masking done in the code for "g" is patently redundant ("f" does mask out the upper 3 bytes of %eax upon return). However, the example given in the original bug report can be made to emit code that doesn't mask %eax (via "gcc-2.96 -O" on an i686-pc-linux). Another data point is that MSVC also emits code that masks. So, indications are that you actually do need to mask on an x86, but I've got no supporting documentation. If anyone is able to dig up more info and/or know someone that could answer this one decisively, I'd interested to hear of their findings. --sigbjorn btw, the document specifying the x86 ABI, located via http://uwsg.iu.edu/hypermail/linux/kernel/0011.1/0596.html , doesn't cover this as far as I've been able to tell.

Here's another data point on this topic - I asked around inside
of MS, and the consensus is that the contents of the unused portions
of EAX is undefined upon return (upper 3 bytes for byte-sized return
values, upper 2 for 16-bit values). This is invariant of x86 calling
convention on Win32 (cdecl,stdcall,fastcall). Still no known doc/spec
which spells this out.
==> GHC's NCG and C backends need to know the sizes of the
unboxed Ints and Words involved in CCalls to generate correct
code.
--sigbjorn
----- Original Message -----
From: "Sigbjorn Finne"
"Julian Seward (Intl Vendor)"
writes: | > char fooble ( ... ) | > { | > return 'z'; | > } | > | > on an x86, 'z' will be returned at the lowest 8 bits in %eax. What I
| > don't know is, is the C compiler obliged to clear the upper 24 bits of | > %eax, or does that onus fall on the callee? | | Yes, the callee is required to narrow <expr> in 'return | <expr>;' to fit that of the specified return type -- see 9.8 | of Harbison and Steele. |
...
So we don't need to worry about doing the masking on the Haskell side, right?
Yes, that's been my understanding. But, as Carl Witty rightly points out, a distinction can be made between narrowing down the result value and the transmission of the narrowed result back to the caller.
Carl's example doesn't fully convince me though, since the masking done in the code for "g" is patently redundant ("f" does mask out the upper 3 bytes of %eax upon return). However, the example given in the original bug report can be made to emit code that doesn't mask %eax (via "gcc-2.96 -O" on an i686-pc-linux). Another data point is that MSVC also emits code that masks.
So, indications are that you actually do need to mask on an x86, but I've got no supporting documentation. If anyone is able to dig up more info and/or know someone that could answer this one decisively, I'd interested to hear of their findings.
--sigbjorn
btw, the document specifying the x86 ABI, located via
http://uwsg.iu.edu/hypermail/linux/kernel/0011.1/0596.html
, doesn't cover this as far as I've been able to tell.
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
participants (2)
-
Julian Seward (Intl Vendor)
-
Sigbjorn Finne